@@ -129,7 +129,7 @@ class ReadableStream {
129129 }
130130 if ( IsWritableStream ( dest ) === false ) {
131131 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' ) ) ;
133133 }
134134
135135 preventClose = Boolean ( preventClose ) ;
@@ -158,8 +158,72 @@ class ReadableStream {
158158 const branches = ReadableStreamTee ( this , false ) ;
159159 return createArrayFromList ( branches ) ;
160160 }
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+ }
161172}
162173
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+
163227module . exports = {
164228 CreateReadableByteStream,
165229 CreateReadableStream,
@@ -194,7 +258,7 @@ function CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, hi
194258 const controller = Object . create ( ReadableStreamDefaultController . prototype ) ;
195259
196260 SetUpReadableStreamDefaultController (
197- stream , controller , startAlgorithm , pullAlgorithm , cancelAlgorithm , highWaterMark , sizeAlgorithm
261+ stream , controller , startAlgorithm , pullAlgorithm , cancelAlgorithm , highWaterMark , sizeAlgorithm
198262 ) ;
199263
200264 return stream ;
@@ -255,6 +319,18 @@ function IsReadableStreamLocked(stream) {
255319 return true ;
256320}
257321
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+
258334function ReadableStreamPipeTo ( source , dest , preventClose , preventAbort , preventCancel , signal ) {
259335 assert ( IsReadableStream ( source ) === true ) ;
260336 assert ( IsWritableStream ( dest ) === true ) ;
@@ -420,10 +496,9 @@ function ReadableStreamPipeTo(source, dest, preventClose, preventAbort, preventC
420496
421497 function doTheRest ( ) {
422498 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 ) ;
427502 }
428503 }
429504
@@ -931,12 +1006,12 @@ function ReadableStreamReaderGenericRelease(reader) {
9311006
9321007 if ( reader . _ownerReadableStream . _state === 'readable' ) {
9331008 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' ) ) ;
9361011 } else {
9371012 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' ) ) ;
9401015 }
9411016 reader . _closedPromise . catch ( ( ) => { } ) ;
9421017
@@ -1098,8 +1173,7 @@ function ReadableStreamDefaultControllerCallPullIfNeeded(controller) {
10981173 e => {
10991174 ReadableStreamDefaultControllerError ( controller , e ) ;
11001175 }
1101- )
1102- . catch ( rethrowAssertionErrorRejection ) ;
1176+ ) . catch ( rethrowAssertionErrorRejection ) ;
11031177
11041178 return undefined ;
11051179}
@@ -1260,8 +1334,7 @@ function SetUpReadableStreamDefaultController(
12601334 r => {
12611335 ReadableStreamDefaultControllerError ( controller , r ) ;
12621336 }
1263- )
1264- . catch ( rethrowAssertionErrorRejection ) ;
1337+ ) . catch ( rethrowAssertionErrorRejection ) ;
12651338}
12661339
12671340function SetUpReadableStreamDefaultControllerFromUnderlyingSource ( stream , underlyingSource , highWaterMark ,
@@ -1533,8 +1606,7 @@ function ReadableByteStreamControllerCallPullIfNeeded(controller) {
15331606 e => {
15341607 ReadableByteStreamControllerError ( controller , e ) ;
15351608 }
1536- )
1537- . catch ( rethrowAssertionErrorRejection ) ;
1609+ ) . catch ( rethrowAssertionErrorRejection ) ;
15381610
15391611 return undefined ;
15401612}
@@ -1570,7 +1642,7 @@ function ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescripto
15701642 assert ( bytesFilled % elementSize === 0 ) ;
15711643
15721644 return new pullIntoDescriptor . ctor (
1573- pullIntoDescriptor . buffer , pullIntoDescriptor . byteOffset , bytesFilled / elementSize ) ;
1645+ pullIntoDescriptor . buffer , pullIntoDescriptor . byteOffset , bytesFilled / elementSize ) ;
15741646}
15751647
15761648function ReadableByteStreamControllerEnqueueChunkToQueue ( controller , buffer , byteOffset , byteLength ) {
@@ -1994,19 +2066,18 @@ function SetUpReadableByteStreamController(stream, controller, startAlgorithm, p
19942066
19952067 const startResult = startAlgorithm ( ) ;
19962068 Promise . resolve ( startResult ) . then (
1997- ( ) => {
1998- controller . _started = true ;
2069+ ( ) => {
2070+ controller . _started = true ;
19992071
2000- assert ( controller . _pulling === false ) ;
2001- assert ( controller . _pullAgain === false ) ;
2072+ assert ( controller . _pulling === false ) ;
2073+ assert ( controller . _pullAgain === false ) ;
20022074
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 ) ;
20102081}
20112082
20122083function SetUpReadableByteStreamControllerFromUnderlyingSource ( stream , underlyingByteSource , highWaterMark ) {
@@ -2063,6 +2134,10 @@ function streamBrandCheckException(name) {
20632134 return new TypeError ( `ReadableStream.prototype.${ name } can only be used on a ReadableStream` ) ;
20642135}
20652136
2137+ function streamAsyncIteratorBrandCheckException ( name ) {
2138+ return new TypeError ( `ReadableStreamAsyncIterator.${ name } can only be used on a ReadableSteamAsyncIterator` ) ;
2139+ }
2140+
20662141// Helper functions for the readers.
20672142
20682143function readerLockException ( name ) {
0 commit comments