@@ -93,6 +93,7 @@ const {
93
93
ArrayBufferViewGetByteOffset,
94
94
ArrayBufferGetByteLength,
95
95
AsyncIterator,
96
+ cloneAsUint8Array,
96
97
copyArrayBuffer,
97
98
customInspect,
98
99
dequeueValue,
@@ -211,6 +212,7 @@ class ReadableStream {
211
212
throw new ERR_INVALID_ARG_VALUE ( 'source' , 'Object' , source ) ;
212
213
this [ kState ] = {
213
214
disturbed : false ,
215
+ reader : undefined ,
214
216
state : 'readable' ,
215
217
storedError : undefined ,
216
218
stream : undefined ,
@@ -1103,7 +1105,6 @@ class ReadableByteStreamController {
1103
1105
chunk ) ;
1104
1106
}
1105
1107
const chunkByteLength = ArrayBufferViewGetByteLength ( chunk ) ;
1106
- const chunkByteOffset = ArrayBufferViewGetByteOffset ( chunk ) ;
1107
1108
const chunkBuffer = ArrayBufferViewGetBuffer ( chunk ) ;
1108
1109
const chunkBufferByteLength = ArrayBufferGetByteLength ( chunkBuffer ) ;
1109
1110
if ( chunkByteLength === 0 || chunkBufferByteLength === 0 ) {
@@ -1114,11 +1115,7 @@ class ReadableByteStreamController {
1114
1115
throw new ERR_INVALID_STATE . TypeError ( 'Controller is already closed' ) ;
1115
1116
if ( this [ kState ] . stream [ kState ] . state !== 'readable' )
1116
1117
throw new ERR_INVALID_STATE . TypeError ( 'ReadableStream is already closed' ) ;
1117
- readableByteStreamControllerEnqueue (
1118
- this ,
1119
- chunkBuffer ,
1120
- chunkByteLength ,
1121
- chunkByteOffset ) ;
1118
+ readableByteStreamControllerEnqueue ( this , chunk ) ;
1122
1119
}
1123
1120
1124
1121
/**
@@ -1416,6 +1413,13 @@ function readableStreamPipeTo(
1416
1413
}
1417
1414
1418
1415
function readableStreamTee ( stream , cloneForBranch2 ) {
1416
+ if ( isReadableByteStreamController ( stream [ kState ] . controller ) ) {
1417
+ return readableByteStreamTee ( stream ) ;
1418
+ }
1419
+ return readableStreamDefaultTee ( stream , cloneForBranch2 ) ;
1420
+ }
1421
+
1422
+ function readableStreamDefaultTee ( stream , cloneForBranch2 ) {
1419
1423
const reader = new ReadableStreamDefaultReader ( stream ) ;
1420
1424
let reading = false ;
1421
1425
let canceled1 = false ;
@@ -1510,6 +1514,282 @@ function readableStreamTee(stream, cloneForBranch2) {
1510
1514
return [ branch1 , branch2 ] ;
1511
1515
}
1512
1516
1517
+ function readableByteStreamTee ( stream ) {
1518
+ assert ( isReadableStream ( stream ) ) ;
1519
+ assert ( isReadableByteStreamController ( stream [ kState ] . controller ) ) ;
1520
+
1521
+ let reader = new ReadableStreamDefaultReader ( stream ) ;
1522
+ let reading = false ;
1523
+ let readAgainForBranch1 = false ;
1524
+ let readAgainForBranch2 = false ;
1525
+ let canceled1 = false ;
1526
+ let canceled2 = false ;
1527
+ let reason1 ;
1528
+ let reason2 ;
1529
+ let branch1 ;
1530
+ let branch2 ;
1531
+ const cancelDeferred = createDeferredPromise ( ) ;
1532
+
1533
+ function forwardReaderError ( thisReader ) {
1534
+ PromisePrototypeThen (
1535
+ thisReader [ kState ] . close . promise ,
1536
+ undefined ,
1537
+ ( error ) => {
1538
+ if ( thisReader !== reader ) {
1539
+ return ;
1540
+ }
1541
+ readableStreamDefaultControllerError ( branch1 [ kState ] . controller , error ) ;
1542
+ readableStreamDefaultControllerError ( branch2 [ kState ] . controller , error ) ;
1543
+ if ( ! canceled1 || ! canceled2 ) {
1544
+ cancelDeferred . resolve ( ) ;
1545
+ }
1546
+ }
1547
+ ) ;
1548
+ }
1549
+
1550
+ function pullWithDefaultReader ( ) {
1551
+ if ( isReadableStreamBYOBReader ( reader ) ) {
1552
+ reader = new ReadableStreamDefaultReader ( stream ) ;
1553
+ forwardReaderError ( reader ) ;
1554
+ }
1555
+
1556
+ const readRequest = {
1557
+ [ kChunk ] ( chunk ) {
1558
+ queueMicrotask ( ( ) => {
1559
+ readAgainForBranch1 = false ;
1560
+ readAgainForBranch2 = false ;
1561
+ const chunk1 = chunk ;
1562
+ let chunk2 = chunk ;
1563
+
1564
+ if ( ! canceled1 && ! canceled2 ) {
1565
+ try {
1566
+ chunk2 = cloneAsUint8Array ( chunk ) ;
1567
+ } catch ( error ) {
1568
+ readableByteStreamControllerError (
1569
+ branch1 [ kState ] . controller ,
1570
+ error
1571
+ ) ;
1572
+ readableByteStreamControllerError (
1573
+ branch2 [ kState ] . controller ,
1574
+ error
1575
+ ) ;
1576
+ cancelDeferred . resolve ( readableStreamCancel ( stream , error ) ) ;
1577
+ return ;
1578
+ }
1579
+ }
1580
+ if ( ! canceled1 ) {
1581
+ readableByteStreamControllerEnqueue (
1582
+ branch1 [ kState ] . controller ,
1583
+ chunk1
1584
+ ) ;
1585
+ }
1586
+ if ( ! canceled2 ) {
1587
+ readableByteStreamControllerEnqueue (
1588
+ branch2 [ kState ] . controller ,
1589
+ chunk2
1590
+ ) ;
1591
+ }
1592
+ reading = false ;
1593
+
1594
+ if ( readAgainForBranch1 ) {
1595
+ pull1Algorithm ( ) ;
1596
+ } else if ( readAgainForBranch2 ) {
1597
+ pull2Algorithm ( ) ;
1598
+ }
1599
+ } ) ;
1600
+ } ,
1601
+ [ kClose ] ( ) {
1602
+ reading = false ;
1603
+
1604
+ if ( ! canceled1 ) {
1605
+ readableByteStreamControllerClose ( branch1 [ kState ] . controller ) ;
1606
+ }
1607
+ if ( ! canceled2 ) {
1608
+ readableByteStreamControllerClose ( branch2 [ kState ] . controller ) ;
1609
+ }
1610
+ if ( branch1 [ kState ] . controller [ kState ] . pendingPullIntos . length > 0 ) {
1611
+ readableByteStreamControllerRespond ( branch1 [ kState ] . controller , 0 ) ;
1612
+ }
1613
+ if ( branch2 [ kState ] . controller [ kState ] . pendingPullIntos . length > 0 ) {
1614
+ readableByteStreamControllerRespond ( branch2 [ kState ] . controller , 0 ) ;
1615
+ }
1616
+ if ( ! canceled1 || ! canceled2 ) {
1617
+ cancelDeferred . resolve ( ) ;
1618
+ }
1619
+ } ,
1620
+ [ kError ] ( ) {
1621
+ reading = false ;
1622
+ } ,
1623
+ } ;
1624
+
1625
+ readableStreamDefaultReaderRead ( reader , readRequest ) ;
1626
+ }
1627
+
1628
+ function pullWithBYOBReader ( view , forBranch2 ) {
1629
+ if ( isReadableStreamDefaultReader ( reader ) ) {
1630
+ reader = new ReadableStreamBYOBReader ( stream ) ;
1631
+ forwardReaderError ( reader ) ;
1632
+ }
1633
+
1634
+ const byobBranch = forBranch2 === true ? branch2 : branch1 ;
1635
+ const otherBranch = forBranch2 === false ? branch2 : branch1 ;
1636
+ const readIntoRequest = {
1637
+ [ kChunk ] ( chunk ) {
1638
+ queueMicrotask ( ( ) => {
1639
+ readAgainForBranch1 = false ;
1640
+ readAgainForBranch2 = false ;
1641
+ const byobCanceled = forBranch2 === true ? canceled2 : canceled1 ;
1642
+ const otherCanceled = forBranch2 === false ? canceled2 : canceled1 ;
1643
+
1644
+ if ( ! otherCanceled ) {
1645
+ let clonedChunk ;
1646
+
1647
+ try {
1648
+ clonedChunk = cloneAsUint8Array ( chunk ) ;
1649
+ } catch ( error ) {
1650
+ readableByteStreamControllerError (
1651
+ byobBranch [ kState ] . controller ,
1652
+ error
1653
+ ) ;
1654
+ readableByteStreamControllerError (
1655
+ otherBranch [ kState ] . controller ,
1656
+ error
1657
+ ) ;
1658
+ cancelDeferred . resolve ( readableStreamCancel ( stream , error ) ) ;
1659
+ return ;
1660
+ }
1661
+ if ( ! byobCanceled ) {
1662
+ readableByteStreamControllerRespondWithNewView (
1663
+ byobBranch [ kState ] . controller ,
1664
+ chunk
1665
+ ) ;
1666
+ }
1667
+
1668
+ readableByteStreamControllerEnqueue (
1669
+ otherBranch [ kState ] . controller ,
1670
+ clonedChunk
1671
+ ) ;
1672
+ } else if ( ! byobCanceled ) {
1673
+ readableByteStreamControllerRespondWithNewView (
1674
+ byobBranch [ kState ] . controller ,
1675
+ chunk
1676
+ ) ;
1677
+ }
1678
+ reading = false ;
1679
+
1680
+ if ( readAgainForBranch1 ) {
1681
+ pull1Algorithm ( ) ;
1682
+ } else if ( readAgainForBranch2 ) {
1683
+ pull2Algorithm ( ) ;
1684
+ }
1685
+ } ) ;
1686
+ } ,
1687
+ [ kClose ] ( chunk ) {
1688
+ reading = false ;
1689
+
1690
+ const byobCanceled = forBranch2 === true ? canceled2 : canceled1 ;
1691
+ const otherCanceled = forBranch2 === false ? canceled2 : canceled1 ;
1692
+
1693
+ if ( ! byobCanceled ) {
1694
+ readableByteStreamControllerClose ( byobBranch [ kState ] . controller ) ;
1695
+ }
1696
+ if ( ! otherCanceled ) {
1697
+ readableByteStreamControllerClose ( otherBranch [ kState ] . controller ) ;
1698
+ }
1699
+ if ( chunk !== undefined ) {
1700
+ if ( ! byobCanceled ) {
1701
+ readableByteStreamControllerRespondWithNewView (
1702
+ byobBranch [ kState ] . controller ,
1703
+ chunk
1704
+ ) ;
1705
+ }
1706
+ if (
1707
+ ! otherCanceled &&
1708
+ otherBranch [ kState ] . controller [ kState ] . pendingPullIntos . length > 0
1709
+ ) {
1710
+ readableByteStreamControllerRespond (
1711
+ otherBranch [ kState ] . controller ,
1712
+ 0
1713
+ ) ;
1714
+ }
1715
+ }
1716
+ if ( ! byobCanceled || ! otherCanceled ) {
1717
+ cancelDeferred . resolve ( ) ;
1718
+ }
1719
+ } ,
1720
+ [ kError ] ( ) {
1721
+ reading = false ;
1722
+ } ,
1723
+ } ;
1724
+ readableStreamBYOBReaderRead ( reader , view , readIntoRequest ) ;
1725
+ }
1726
+
1727
+ function pull1Algorithm ( ) {
1728
+ if ( reading ) {
1729
+ readAgainForBranch1 = true ;
1730
+ return PromiseResolve ( ) ;
1731
+ }
1732
+ reading = true ;
1733
+
1734
+ const byobRequest = branch1 [ kState ] . controller . byobRequest ;
1735
+ if ( byobRequest === null ) {
1736
+ pullWithDefaultReader ( ) ;
1737
+ } else {
1738
+ pullWithBYOBReader ( byobRequest [ kState ] . view , false ) ;
1739
+ }
1740
+ return PromiseResolve ( ) ;
1741
+ }
1742
+
1743
+ function pull2Algorithm ( ) {
1744
+ if ( reading ) {
1745
+ readAgainForBranch2 = true ;
1746
+ return PromiseResolve ( ) ;
1747
+ }
1748
+ reading = true ;
1749
+
1750
+ const byobRequest = branch2 [ kState ] . controller . byobRequest ;
1751
+ if ( byobRequest === null ) {
1752
+ pullWithDefaultReader ( ) ;
1753
+ } else {
1754
+ pullWithBYOBReader ( byobRequest [ kState ] . view , true ) ;
1755
+ }
1756
+ return PromiseResolve ( ) ;
1757
+ }
1758
+
1759
+ function cancel1Algorithm ( reason ) {
1760
+ canceled1 = true ;
1761
+ reason1 = reason ;
1762
+ if ( canceled2 ) {
1763
+ cancelDeferred . resolve ( readableStreamCancel ( stream , [ reason1 , reason2 ] ) ) ;
1764
+ }
1765
+ return cancelDeferred . promise ;
1766
+ }
1767
+
1768
+ function cancel2Algorithm ( reason ) {
1769
+ canceled2 = true ;
1770
+ reason2 = reason ;
1771
+ if ( canceled1 ) {
1772
+ cancelDeferred . resolve ( readableStreamCancel ( stream , [ reason1 , reason2 ] ) ) ;
1773
+ }
1774
+ return cancelDeferred . promise ;
1775
+ }
1776
+
1777
+ branch1 = new ReadableStream ( {
1778
+ type : 'bytes' ,
1779
+ pull : pull1Algorithm ,
1780
+ cancel : cancel1Algorithm ,
1781
+ } ) ;
1782
+ branch2 = new ReadableStream ( {
1783
+ type : 'bytes' ,
1784
+ pull : pull2Algorithm ,
1785
+ cancel : cancel2Algorithm ,
1786
+ } ) ;
1787
+
1788
+ forwardReaderError ( reader ) ;
1789
+
1790
+ return [ branch1 , branch2 ] ;
1791
+ }
1792
+
1513
1793
function readableByteStreamControllerConvertPullIntoDescriptor ( desc ) {
1514
1794
const {
1515
1795
buffer,
@@ -2273,18 +2553,18 @@ function readableByteStreamControllerFillHeadPullIntoDescriptor(
2273
2553
desc . bytesFilled += size ;
2274
2554
}
2275
2555
2276
- function readableByteStreamControllerEnqueue (
2277
- controller ,
2278
- buffer ,
2279
- byteLength ,
2280
- byteOffset ) {
2556
+ function readableByteStreamControllerEnqueue ( controller , chunk ) {
2281
2557
const {
2282
2558
closeRequested,
2283
2559
pendingPullIntos,
2284
2560
queue,
2285
2561
stream,
2286
2562
} = controller [ kState ] ;
2287
2563
2564
+ const buffer = ArrayBufferViewGetBuffer ( chunk ) ;
2565
+ const byteOffset = ArrayBufferViewGetByteOffset ( chunk ) ;
2566
+ const byteLength = ArrayBufferViewGetByteLength ( chunk ) ;
2567
+
2288
2568
if ( closeRequested || stream [ kState ] . state !== 'readable' )
2289
2569
return ;
2290
2570
0 commit comments