@@ -1998,6 +1998,61 @@ option. In the code example above, data will be in a single chunk if the file
19981998has less then 64 KiB of data because no ` highWaterMark ` option is provided to
19991999[ ` fs.createReadStream() ` ] [ ] .
20002000
2001+ ##### ` readable[Symbol.for('Stream.toAsyncStreamable')]() `
2002+
2003+ <!-- YAML
2004+ added: REPLACEME
2005+ -->
2006+
2007+ > Stability: 1 - Experimental
2008+
2009+ * Returns: {AsyncIterable} An ` AsyncIterable<Uint8Array[]> ` that yields
2010+ batched chunks from the stream.
2011+
2012+ When the ` --experimental-stream-iter ` flag is enabled, ` Readable ` streams
2013+ implement the [ ` Stream.toAsyncStreamable ` ] [ ] protocol, enabling efficient
2014+ consumption by the [ ` stream/iter ` ] [ ] API.
2015+
2016+ This provides a batched async iterator that drains the stream's internal
2017+ buffer into ` Uint8Array[] ` batches, amortizing the per-chunk Promise overhead
2018+ of the standard ` Symbol.asyncIterator ` path. For byte-mode streams, chunks
2019+ are yielded directly as ` Buffer ` instances (which are ` Uint8Array ` subclasses).
2020+ For object-mode or encoded streams, each chunk is normalized to ` Uint8Array `
2021+ before batching.
2022+
2023+ The returned iterator is tagged as a trusted source, so [ ` from() ` ] [ stream-iter-from ]
2024+ passes it through without additional normalization.
2025+
2026+ ``` mjs
2027+ import { Readable } from ' node:stream' ;
2028+ import { text , from } from ' node:stream/iter' ;
2029+
2030+ const readable = new Readable ({
2031+ read () { this .push (' hello' ); this .push (null ); },
2032+ });
2033+
2034+ // Readable is automatically consumed via toAsyncStreamable
2035+ console .log (await text (from (readable))); // 'hello'
2036+ ```
2037+
2038+ ``` cjs
2039+ const { Readable } = require (' node:stream' );
2040+ const { text , from } = require (' node:stream/iter' );
2041+
2042+ async function run () {
2043+ const readable = new Readable ({
2044+ read () { this .push (' hello' ); this .push (null ); },
2045+ });
2046+
2047+ console .log (await text (from (readable))); // 'hello'
2048+ }
2049+
2050+ run ().catch (console .error );
2051+ ```
2052+
2053+ Without the ` --experimental-stream-iter ` flag, calling this method throws
2054+ [ ` ERR_STREAM_ITER_MISSING_FLAG ` ] [ ] .
2055+
20012056##### ` readable[Symbol.asyncDispose]() `
20022057
20032058<!-- YAML
@@ -3152,6 +3207,101 @@ Readable.from([
31523207]);
31533208```
31543209
3210+ ### ` stream.Readable.fromStreamIter(source[, options]) `
3211+
3212+ <!-- YAML
3213+ added: REPLACEME
3214+ -->
3215+
3216+ > Stability: 1 - Experimental
3217+
3218+ * ` source ` {AsyncIterable} An ` AsyncIterable<Uint8Array[]> ` source, such as
3219+ the return value of [ ` pull() ` ] [ ] or [ ` from() ` ] [ stream-iter-from ] .
3220+ * ` options ` {Object}
3221+ * ` highWaterMark ` {number} The internal buffer size in bytes before
3222+ backpressure is applied. ** Default:** ` 65536 ` (64 KB).
3223+ * ` signal ` {AbortSignal} An optional signal that can be used to abort
3224+ the readable, destroying the stream and cleaning up the source iterator.
3225+ * Returns: {stream.Readable}
3226+
3227+ Creates a byte-mode {stream.Readable} from an ` AsyncIterable<Uint8Array[]> `
3228+ (the native batch format used by the [ ` stream/iter ` ] [ ] API). Each
3229+ ` Uint8Array ` in a yielded batch is pushed as a separate chunk into the
3230+ Readable.
3231+
3232+ This method requires the ` --experimental-stream-iter ` CLI flag.
3233+
3234+ ``` mjs
3235+ import { Readable } from ' node:stream' ;
3236+ import { createWriteStream } from ' node:fs' ;
3237+ import { from , pull } from ' node:stream/iter' ;
3238+ import { compressGzip } from ' node:zlib/iter' ;
3239+
3240+ // Bridge a stream/iter pipeline to a classic Readable
3241+ const source = pull (from (' hello world' ), compressGzip ());
3242+ const readable = Readable .fromStreamIter (source);
3243+
3244+ readable .pipe (createWriteStream (' output.gz' ));
3245+ ```
3246+
3247+ ``` cjs
3248+ const { Readable } = require (' node:stream' );
3249+ const { createWriteStream } = require (' node:fs' );
3250+ const { from , pull } = require (' node:stream/iter' );
3251+ const { compressGzip } = require (' node:zlib/iter' );
3252+
3253+ const source = pull (from (' hello world' ), compressGzip ());
3254+ const readable = Readable .fromStreamIter (source);
3255+
3256+ readable .pipe (createWriteStream (' output.gz' ));
3257+ ```
3258+
3259+ ### ` stream.Readable.fromStreamIterSync(source[, options]) `
3260+
3261+ <!-- YAML
3262+ added: REPLACEME
3263+ -->
3264+
3265+ > Stability: 1 - Experimental
3266+
3267+ * ` source ` {Iterable} An ` Iterable<Uint8Array[]> ` source, such as the
3268+ return value of [ ` pullSync() ` ] [ ] or [ ` fromSync() ` ] [ ] .
3269+ * ` options ` {Object}
3270+ * ` highWaterMark ` {number} The internal buffer size in bytes before
3271+ backpressure is applied. ** Default:** ` 65536 ` (64 KB).
3272+ * Returns: {stream.Readable}
3273+
3274+ Creates a byte-mode {stream.Readable} from a synchronous
3275+ ` Iterable<Uint8Array[]> ` (the native batch format used by the
3276+ [ ` stream/iter ` ] [ ] sync API). Each ` Uint8Array ` in a yielded batch is
3277+ pushed as a separate chunk into the Readable.
3278+
3279+ The ` _read() ` method pulls from the iterator synchronously, so data is
3280+ available immediately via ` readable.read() ` without waiting for async
3281+ callbacks.
3282+
3283+ This method requires the ` --experimental-stream-iter ` CLI flag.
3284+
3285+ ``` mjs
3286+ import { Readable } from ' node:stream' ;
3287+ import { fromSync } from ' node:stream/iter' ;
3288+
3289+ const source = fromSync (' hello world' );
3290+ const readable = Readable .fromStreamIterSync (source);
3291+
3292+ console .log (readable .read ().toString ()); // 'hello world'
3293+ ```
3294+
3295+ ``` cjs
3296+ const { Readable } = require (' node:stream' );
3297+ const { fromSync } = require (' node:stream/iter' );
3298+
3299+ const source = fromSync (' hello world' );
3300+ const readable = Readable .fromStreamIterSync (source);
3301+
3302+ console .log (readable .read ().toString ()); // 'hello world'
3303+ ```
3304+
31553305### ` stream.Readable.fromWeb(readableStream[, options]) `
31563306
31573307<!-- YAML
@@ -4997,17 +5147,22 @@ contain multi-byte characters.
49975147[` ' finish' ` ]: #event-finish
49985148[` ' readable' ` ]: #event-readable
49995149[` Duplex` ]: #class-streamduplex
5150+ [` ERR_STREAM_ITER_MISSING_FLAG ` ]: errors.md#err_stream_iter_missing_flag
50005151[` EventEmitter` ]: events.md#class-eventemitter
50015152[` Readable` ]: #class-streamreadable
5153+ [` Stream .toAsyncStreamable ` ]: stream_iter.md#streamtoasyncstreamable
50025154[` Symbol .hasInstance ` ]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance
50035155[` Transform` ]: #class-streamtransform
50045156[` Writable` ]: #class-streamwritable
5157+ [` fromSync ()` ]: stream_iter.md#fromsyncinput
50055158[` fs .createReadStream ()` ]: fs.md#fscreatereadstreampath-options
50065159[` fs .createWriteStream ()` ]: fs.md#fscreatewritestreampath-options
50075160[` net .Socket ` ]: net.md#class-netsocket
50085161[` process .stderr ` ]: process.md#processstderr
50095162[` process .stdin ` ]: process.md#processstdin
50105163[` process .stdout ` ]: process.md#processstdout
5164+ [` pull ()` ]: stream_iter.md#pullsource-transforms-options
5165+ [` pullSync ()` ]: stream_iter.md#pullsyncsource-transforms-options
50115166[` readable ._read ()` ]: #readable_readsize
50125167[` readable .compose (stream)` ]: #readablecomposestream-options
50135168[` readable .map ` ]: #readablemapfn-options
@@ -5024,6 +5179,7 @@ contain multi-byte characters.
50245179[` stream .uncork ()` ]: #writableuncork
50255180[` stream .unpipe ()` ]: #readableunpipedestination
50265181[` stream .wrap ()` ]: #readablewrapstream
5182+ [` stream/ iter` ]: stream_iter.md
50275183[` writable ._final ()` ]: #writable_finalcallback
50285184[` writable ._write ()` ]: #writable_writechunk-encoding-callback
50295185[` writable ._writev ()` ]: #writable_writevchunks-callback
@@ -5052,6 +5208,7 @@ contain multi-byte characters.
50525208[stream-end]: #writableendchunk-encoding-callback
50535209[stream-finished]: #streamfinishedstream-options-callback
50545210[stream-finished-promise]: #streamfinishedstream-options
5211+ [stream-iter-from]: stream_iter.md#frominput
50555212[stream-pause]: #readablepause
50565213[stream-pipeline]: #streampipelinesource-transforms-destination-callback
50575214[stream-pipeline-promise]: #streampipelinesource-transforms-destination-options
0 commit comments