@@ -129,7 +129,7 @@ class ReadableStream {
129
129
}
130
130
if ( IsWritableStream ( dest ) === false ) {
131
131
return Promise . reject (
132
- new TypeError ( 'ReadableStream.prototype.pipeTo\'s first argument must be a WritableStream' ) ) ;
132
+ new TypeError ( 'ReadableStream.prototype.pipeTo\'s first argument must be a WritableStream' ) ) ;
133
133
}
134
134
135
135
preventClose = Boolean ( preventClose ) ;
@@ -158,8 +158,72 @@ class ReadableStream {
158
158
const branches = ReadableStreamTee ( this , false ) ;
159
159
return createArrayFromList ( branches ) ;
160
160
}
161
+
162
+ getIterator ( { preventCancel = false } = { } ) {
163
+ if ( IsReadableStream ( this ) === false ) {
164
+ throw streamBrandCheckException ( 'getIterator' ) ;
165
+ }
166
+ const reader = AcquireReadableStreamDefaultReader ( this ) ;
167
+ const iterator = Object . create ( ReadableStreamAsyncIteratorPrototype ) ;
168
+ iterator . _asyncIteratorReader = reader ;
169
+ iterator . _preventCancel = Boolean ( preventCancel ) ;
170
+ return iterator ;
171
+ }
161
172
}
162
173
174
+ const AsyncIteratorPrototype = Object . getPrototypeOf ( Object . getPrototypeOf ( async function * ( ) { } ) . prototype ) ;
175
+ const ReadableStreamAsyncIteratorPrototype = Object . setPrototypeOf ( {
176
+ next ( ) {
177
+ if ( IsReadableStreamAsyncIterator ( this ) === false ) {
178
+ return Promise . reject ( streamAsyncIteratorBrandCheckException ( 'next' ) ) ;
179
+ }
180
+ const reader = this . _asyncIteratorReader ;
181
+ if ( reader . _ownerReadableStream === undefined ) {
182
+ return Promise . reject ( readerLockException ( 'iterate' ) ) ;
183
+ }
184
+ return ReadableStreamDefaultReaderRead ( reader ) . then ( result => {
185
+ assert ( typeIsObject ( result ) ) ;
186
+ const value = result . value ;
187
+ const done = result . done ;
188
+ assert ( typeof done === 'boolean' ) ;
189
+ if ( done ) {
190
+ ReadableStreamReaderGenericRelease ( reader ) ;
191
+ }
192
+ return ReadableStreamCreateReadResult ( value , done , true ) ;
193
+ } ) ;
194
+ } ,
195
+
196
+ return ( value ) {
197
+ if ( IsReadableStreamAsyncIterator ( this ) === false ) {
198
+ return Promise . reject ( streamAsyncIteratorBrandCheckException ( 'next' ) ) ;
199
+ }
200
+ const reader = this . _asyncIteratorReader ;
201
+ if ( reader . _ownerReadableStream === undefined ) {
202
+ return Promise . reject ( readerLockException ( 'finish iterating' ) ) ;
203
+ }
204
+ if ( reader . _readRequests . length > 0 ) {
205
+ return Promise . reject ( new TypeError (
206
+ 'Tried to release a reader lock when that reader has pending read() calls un-settled' ) ) ;
207
+ }
208
+ if ( this . _preventCancel === false ) {
209
+ const result = ReadableStreamReaderGenericCancel ( reader , value ) ;
210
+ ReadableStreamReaderGenericRelease ( reader ) ;
211
+ return result . then ( ( ) => ReadableStreamCreateReadResult ( value , true , true ) ) ;
212
+ }
213
+ ReadableStreamReaderGenericRelease ( reader ) ;
214
+ return Promise . resolve ( ReadableStreamCreateReadResult ( value , true , true ) ) ;
215
+ }
216
+ } , AsyncIteratorPrototype ) ;
217
+ Object . defineProperty ( ReadableStreamAsyncIteratorPrototype , 'next' , { enumerable : false } ) ;
218
+ Object . defineProperty ( ReadableStreamAsyncIteratorPrototype , 'return' , { enumerable : false } ) ;
219
+
220
+ Object . defineProperty ( ReadableStream . prototype , Symbol . asyncIterator , {
221
+ value : ReadableStream . prototype . getIterator ,
222
+ enumerable : false ,
223
+ writable : true ,
224
+ configurable : true
225
+ } ) ;
226
+
163
227
module . exports = {
164
228
CreateReadableByteStream,
165
229
CreateReadableStream,
@@ -194,7 +258,7 @@ function CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, hi
194
258
const controller = Object . create ( ReadableStreamDefaultController . prototype ) ;
195
259
196
260
SetUpReadableStreamDefaultController (
197
- stream , controller , startAlgorithm , pullAlgorithm , cancelAlgorithm , highWaterMark , sizeAlgorithm
261
+ stream , controller , startAlgorithm , pullAlgorithm , cancelAlgorithm , highWaterMark , sizeAlgorithm
198
262
) ;
199
263
200
264
return stream ;
@@ -255,6 +319,18 @@ function IsReadableStreamLocked(stream) {
255
319
return true ;
256
320
}
257
321
322
+ function IsReadableStreamAsyncIterator ( x ) {
323
+ if ( ! typeIsObject ( x ) ) {
324
+ return false ;
325
+ }
326
+
327
+ if ( ! Object . prototype . hasOwnProperty . call ( x , '_asyncIteratorReader' ) ) {
328
+ return false ;
329
+ }
330
+
331
+ return true ;
332
+ }
333
+
258
334
function ReadableStreamPipeTo ( source , dest , preventClose , preventAbort , preventCancel , signal ) {
259
335
assert ( IsReadableStream ( source ) === true ) ;
260
336
assert ( IsWritableStream ( dest ) === true ) ;
@@ -420,10 +496,9 @@ function ReadableStreamPipeTo(source, dest, preventClose, preventAbort, preventC
420
496
421
497
function doTheRest ( ) {
422
498
action ( ) . then (
423
- ( ) => finalize ( originalIsError , originalError ) ,
424
- newError => finalize ( true , newError )
425
- )
426
- . catch ( rethrowAssertionErrorRejection ) ;
499
+ ( ) => finalize ( originalIsError , originalError ) ,
500
+ newError => finalize ( true , newError )
501
+ ) . catch ( rethrowAssertionErrorRejection ) ;
427
502
}
428
503
}
429
504
@@ -931,12 +1006,12 @@ function ReadableStreamReaderGenericRelease(reader) {
931
1006
932
1007
if ( reader . _ownerReadableStream . _state === 'readable' ) {
933
1008
defaultReaderClosedPromiseReject (
934
- reader ,
935
- new TypeError ( 'Reader was released and can no longer be used to monitor the stream\'s closedness' ) ) ;
1009
+ reader ,
1010
+ new TypeError ( 'Reader was released and can no longer be used to monitor the stream\'s closedness' ) ) ;
936
1011
} else {
937
1012
defaultReaderClosedPromiseResetToRejected (
938
- reader ,
939
- new TypeError ( 'Reader was released and can no longer be used to monitor the stream\'s closedness' ) ) ;
1013
+ reader ,
1014
+ new TypeError ( 'Reader was released and can no longer be used to monitor the stream\'s closedness' ) ) ;
940
1015
}
941
1016
reader . _closedPromise . catch ( ( ) => { } ) ;
942
1017
@@ -1098,8 +1173,7 @@ function ReadableStreamDefaultControllerCallPullIfNeeded(controller) {
1098
1173
e => {
1099
1174
ReadableStreamDefaultControllerError ( controller , e ) ;
1100
1175
}
1101
- )
1102
- . catch ( rethrowAssertionErrorRejection ) ;
1176
+ ) . catch ( rethrowAssertionErrorRejection ) ;
1103
1177
1104
1178
return undefined ;
1105
1179
}
@@ -1260,8 +1334,7 @@ function SetUpReadableStreamDefaultController(
1260
1334
r => {
1261
1335
ReadableStreamDefaultControllerError ( controller , r ) ;
1262
1336
}
1263
- )
1264
- . catch ( rethrowAssertionErrorRejection ) ;
1337
+ ) . catch ( rethrowAssertionErrorRejection ) ;
1265
1338
}
1266
1339
1267
1340
function SetUpReadableStreamDefaultControllerFromUnderlyingSource ( stream , underlyingSource , highWaterMark ,
@@ -1533,8 +1606,7 @@ function ReadableByteStreamControllerCallPullIfNeeded(controller) {
1533
1606
e => {
1534
1607
ReadableByteStreamControllerError ( controller , e ) ;
1535
1608
}
1536
- )
1537
- . catch ( rethrowAssertionErrorRejection ) ;
1609
+ ) . catch ( rethrowAssertionErrorRejection ) ;
1538
1610
1539
1611
return undefined ;
1540
1612
}
@@ -1570,7 +1642,7 @@ function ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescripto
1570
1642
assert ( bytesFilled % elementSize === 0 ) ;
1571
1643
1572
1644
return new pullIntoDescriptor . ctor (
1573
- pullIntoDescriptor . buffer , pullIntoDescriptor . byteOffset , bytesFilled / elementSize ) ;
1645
+ pullIntoDescriptor . buffer , pullIntoDescriptor . byteOffset , bytesFilled / elementSize ) ;
1574
1646
}
1575
1647
1576
1648
function ReadableByteStreamControllerEnqueueChunkToQueue ( controller , buffer , byteOffset , byteLength ) {
@@ -1994,19 +2066,18 @@ function SetUpReadableByteStreamController(stream, controller, startAlgorithm, p
1994
2066
1995
2067
const startResult = startAlgorithm ( ) ;
1996
2068
Promise . resolve ( startResult ) . then (
1997
- ( ) => {
1998
- controller . _started = true ;
2069
+ ( ) => {
2070
+ controller . _started = true ;
1999
2071
2000
- assert ( controller . _pulling === false ) ;
2001
- assert ( controller . _pullAgain === false ) ;
2072
+ assert ( controller . _pulling === false ) ;
2073
+ assert ( controller . _pullAgain === false ) ;
2002
2074
2003
- ReadableByteStreamControllerCallPullIfNeeded ( controller ) ;
2004
- } ,
2005
- r => {
2006
- ReadableByteStreamControllerError ( controller , r ) ;
2007
- }
2008
- )
2009
- . catch ( rethrowAssertionErrorRejection ) ;
2075
+ ReadableByteStreamControllerCallPullIfNeeded ( controller ) ;
2076
+ } ,
2077
+ r => {
2078
+ ReadableByteStreamControllerError ( controller , r ) ;
2079
+ }
2080
+ ) . catch ( rethrowAssertionErrorRejection ) ;
2010
2081
}
2011
2082
2012
2083
function SetUpReadableByteStreamControllerFromUnderlyingSource ( stream , underlyingByteSource , highWaterMark ) {
@@ -2063,6 +2134,10 @@ function streamBrandCheckException(name) {
2063
2134
return new TypeError ( `ReadableStream.prototype.${ name } can only be used on a ReadableStream` ) ;
2064
2135
}
2065
2136
2137
+ function streamAsyncIteratorBrandCheckException ( name ) {
2138
+ return new TypeError ( `ReadableStreamAsyncIterator.${ name } can only be used on a ReadableSteamAsyncIterator` ) ;
2139
+ }
2140
+
2066
2141
// Helper functions for the readers.
2067
2142
2068
2143
function readerLockException ( name ) {
0 commit comments