{
  "type": "module",
  "source": "doc/api/stream_iter.md",
  "modules": [
    {
      "textRaw": "Iterable Streams",
      "name": "iterable_streams",
      "introduced_in": "v24.20.0",
      "type": "module",
      "stability": 1,
      "stabilityText": "Experimental – Enable this API with the `--experimental-stream-iter` CLI flag.",
      "desc": "<p>The <code>node:stream/iter</code> module provides a streaming API built on iterables\nrather than the event-driven <code>Readable</code>/<code>Writable</code>/<code>Transform</code> class hierarchy,\nor the Web Streams <code>ReadableStream</code>/<code>WritableStream</code>/<code>TransformStream</code> interfaces.</p>\n<p>Streams are represented as <code class=\"type\"><a href=\"https://tc39.github.io/ecma262/#sec-asynciterable-interface\" class=\"type-link\">AsyncIterable</a></code> (async) or <code class=\"type\"><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol\" class=\"type-link\">Iterable</a></code> (sync). There\nare no base classes to extend -- any\nobject implementing the iterable protocol can participate. Transforms are plain\nfunctions or objects with a <code>transform</code> method.</p>\n<p>Data flows in <strong>batches</strong> (<code class=\"type\"><a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array\" class=\"type-link\">Uint8Array</a>[]</code> per iteration) to amortize the cost\nof async operations.</p>\n<p>The module implements the WinterTC <a href=\"https://iter-streams.proposal.wintertc.org/\">Iterable Streams API</a> draft. The\nclassic stream interop functions (<a href=\"#fromreadablereadable\"><code>fromReadable()</code></a>, <a href=\"#fromwritablewritable-options\"><code>fromWritable()</code></a>,\n<a href=\"#toreadablesource-options\"><code>toReadable()</code></a>, <a href=\"#toreadablesyncsource-options\"><code>toReadableSync()</code></a> and <a href=\"#towritablewriter\"><code>toWritable()</code></a>),\n<a href=\"#broadcastfrominput-options\"><code>Broadcast.from()</code></a>, <a href=\"#static-method-sharefrominput-options\"><code>Share.from()</code></a>, <a href=\"#static-method-syncsharefromsyncinput-options\"><code>SyncShare.fromSync()</code></a> and the\nprotocol symbols exported by <code>Stream</code> are Node.js extensions that are not part\nof the draft.</p>\n<pre><code class=\"language-mjs\">import { from, pull, text } from 'node:stream/iter';\nimport { compressGzip, decompressGzip } from 'node:zlib/iter';\n\n// Compress and decompress a string\nconst compressed = pull(from('Hello, world!'), compressGzip());\nconst result = await text(pull(compressed, decompressGzip()));\nconsole.log(result); // 'Hello, world!'\n</code></pre>\n<pre><code class=\"language-cjs\">const { from, pull, text } = require('node:stream/iter');\nconst { compressGzip, decompressGzip } = require('node:zlib/iter');\n\nasync function run() {\n  // Compress and decompress a string\n  const compressed = pull(from('Hello, world!'), compressGzip());\n  const result = await text(pull(compressed, decompressGzip()));\n  console.log(result); // 'Hello, world!'\n}\n\nrun().catch(console.error);\n</code></pre>\n<pre><code class=\"language-mjs\">import { open } from 'node:fs/promises';\nimport { text, pipeTo } from 'node:stream/iter';\nimport { compressGzip, decompressGzip } from 'node:zlib/iter';\n\n// Read a file, compress, write to another file\nconst src = await open('input.txt', 'r');\nconst dst = await open('output.gz', 'w');\nawait pipeTo(src.pull(), compressGzip(), dst.writer({ autoClose: true }));\nawait src.close();\n\n// Read it back\nconst gz = await open('output.gz', 'r');\nconsole.log(await text(gz.pull(decompressGzip(), { autoClose: true })));\n</code></pre>\n<pre><code class=\"language-cjs\">const { open } = require('node:fs/promises');\nconst { text, pipeTo } = require('node:stream/iter');\nconst { compressGzip, decompressGzip } = require('node:zlib/iter');\n\nasync function run() {\n  // Read a file, compress, write to another file\n  const src = await open('input.txt', 'r');\n  const dst = await open('output.gz', 'w');\n  await pipeTo(src.pull(), compressGzip(), dst.writer({ autoClose: true }));\n  await src.close();\n\n  // Read it back\n  const gz = await open('output.gz', 'r');\n  console.log(await text(gz.pull(decompressGzip(), { autoClose: true })));\n}\n\nrun().catch(console.error);\n</code></pre>",
      "modules": [
        {
          "textRaw": "Concepts",
          "name": "concepts",
          "type": "module",
          "modules": [
            {
              "textRaw": "Byte streams",
              "name": "byte_streams",
              "type": "module",
              "desc": "<p>All data in this API is represented as <code class=\"type\"><a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array\" class=\"type-link\">Uint8Array</a></code> bytes. Strings\nare automatically UTF-8 encoded when passed to <code>from()</code>, <code>push()</code>, or\n<code>pipeTo()</code>. This removes ambiguity around encodings and enables zero-copy\ntransfers between streams and native code.</p>",
              "displayName": "Byte streams"
            },
            {
              "textRaw": "Batching",
              "name": "batching",
              "type": "module",
              "desc": "<p>Each iteration yields a <strong>batch</strong> -- an <code class=\"type\"><a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array\" class=\"type-link\">Array</a></code> of <code class=\"type\"><a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array\" class=\"type-link\">Uint8Array</a></code> chunks\n(<code class=\"type\"><a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array\" class=\"type-link\">Uint8Array</a>[]</code>). Batching amortizes the cost of <code>await</code> and <code class=\"type\"><a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise\" class=\"type-link\">Promise</a></code> creation\nacross multiple chunks. A consumer that processes one chunk at a time can\nsimply iterate the inner array:</p>\n<pre><code class=\"language-mjs\">for await (const batch of source) {\n  for (const chunk of batch) {\n    handle(chunk);\n  }\n}\n</code></pre>\n<pre><code class=\"language-cjs\">async function run() {\n  for await (const batch of source) {\n    for (const chunk of batch) {\n      handle(chunk);\n    }\n  }\n}\n</code></pre>",
              "displayName": "Batching"
            },
            {
              "textRaw": "Transforms",
              "name": "transforms",
              "type": "module",
              "desc": "<p>Transforms come in two forms:</p>\n<ul>\n<li>\n<p><strong>Stateless</strong> -- a function <code>(chunks, options) => result</code> called once per\nbatch. Receives <code>Uint8Array[]</code> (or <code>null</code> as the flush signal) and an\n<code>options</code> object. Returns <code class=\"type\"><a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array\" class=\"type-link\">Uint8Array</a>[] | <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#null_type\" class=\"type-link\">null</a> | <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol\" class=\"type-link\">Iterable</a></code>.</p>\n</li>\n<li>\n<p><strong>Stateful</strong> -- an object <code>{ transform(source, options) }</code> where <code>transform</code>\nis a generator (sync or async) that receives the entire upstream iterable\nand an <code>options</code> object, and yields output. This form is used for\ncompression, encryption, and any transform that needs to buffer across\nbatches.</p>\n</li>\n</ul>\n<p>Both forms receive an <code>options</code> parameter with the following property:</p>\n<ul>\n<li><code>options.signal</code> <code class=\"type\"><a href=\"globals.html#class-abortsignal\" class=\"type-link\">AbortSignal</a></code> An AbortSignal that fires when the pipeline\nis cancelled, encounters an error, or the consumer stops reading. Transforms\ncan check <code>signal.aborted</code> or listen for the <code>'abort'</code> event to perform\nearly cleanup.</li>\n</ul>\n<p>The flush signal (<code>null</code>) is sent after the source ends, giving transforms\na chance to emit trailing data (e.g., compression footers).</p>\n<pre><code class=\"language-js\">// Stateless: uppercase transform\nconst upper = (chunks) => {\n  if (chunks === null) return null; // flush\n  return chunks.map((c) => new TextEncoder().encode(\n    new TextDecoder().decode(c).toUpperCase(),\n  ));\n};\n\n// Stateful: line splitter\nconst lines = {\n  transform: async function*(source) {\n    let partial = '';\n    for await (const chunks of source) {\n      if (chunks === null) {\n        if (partial) yield [new TextEncoder().encode(partial)];\n        continue;\n      }\n      for (const chunk of chunks) {\n        const str = partial + new TextDecoder().decode(chunk);\n        const parts = str.split('\\n');\n        partial = parts.pop();\n        for (const line of parts) {\n          yield [new TextEncoder().encode(`${line}\\n`)];\n        }\n      }\n    }\n  },\n};\n</code></pre>",
              "displayName": "Transforms"
            },
            {
              "textRaw": "Pull vs. push",
              "name": "pull_vs._push",
              "type": "module",
              "desc": "<p>The API supports two models:</p>\n<ul>\n<li>\n<p><strong>Pull</strong> -- data flows on demand. <code>pull()</code> and <code>pullSync()</code> create lazy\npipelines that only read from the source when the consumer iterates.</p>\n</li>\n<li>\n<p><strong>Push</strong> -- data is written explicitly. <code>push()</code> creates a writer/readable\npair with backpressure. The writer pushes data in; the readable is consumed\nas an async iterable.</p>\n</li>\n</ul>",
              "displayName": "Pull vs. push"
            },
            {
              "textRaw": "Backpressure",
              "name": "backpressure",
              "type": "module",
              "desc": "<p>Pull streams have natural backpressure -- the consumer drives the pace, so\nthe source is never read faster than the consumer can process. Push streams\nneed explicit backpressure because the producer and consumer run\nindependently. The <code>budget</code> and <code>backpressure</code> options on <code>push()</code>,\n<code>broadcast()</code>, and <code>share()</code> control how this works.</p>",
              "modules": [
                {
                  "textRaw": "The two-buffer model",
                  "name": "the_two-buffer_model",
                  "type": "module",
                  "desc": "<p>Push streams use a two-part buffering system. Think of it like a bucket\n(buffer) being filled through a hose (pending writes), with a float valve\nthat closes when the bucket is full:</p>\n<pre><code class=\"language-text\">                          budget (e.g., 16384)\n                                 |\n    Producer                     v\n       |                    +---------+\n       v                    |         |\n  [ write() ] ----+    +--->| buffer  |---> Consumer pulls\n  [ write() ]     |    |    | (bucket)|     for await (...)\n  [ write() ]     v    |    +---------+\n              +--------+         ^\n              | pending|         |\n              | writes |    float valve\n              | (hose) |    (backpressure)\n              +--------+\n                   ^\n                   |\n          'strict' mode limits this too!\n</code></pre>\n<ul>\n<li>\n<p><strong>Buffer (the bucket)</strong> -- data ready for the consumer, capped at\n<code>budget</code> bytes. When the consumer pulls, it drains all buffered data\nat once into a single batch.</p>\n</li>\n<li>\n<p><strong>Pending writes (the hose)</strong> -- writes waiting for buffer space. After\nthe consumer drains, pending writes are promoted into the now-empty\nbuffer and their promises settle.</p>\n</li>\n</ul>\n<p>How each policy uses these buffers:</p>\n<table>\n<thead>\n<tr>\n<th>Policy</th>\n<th>Buffer limit</th>\n<th>Pending writes limit</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>'strict'</code></td>\n<td><code>budget</code></td>\n<td>1</td>\n</tr>\n<tr>\n<td><code>'unbounded'</code></td>\n<td><code>budget</code></td>\n<td>Unbounded</td>\n</tr>\n<tr>\n<td><code>'drop-oldest'</code></td>\n<td><code>budget</code></td>\n<td>N/A (never waits)</td>\n</tr>\n<tr>\n<td><code>'drop-newest'</code></td>\n<td><code>budget</code></td>\n<td>N/A (never waits)</td>\n</tr>\n</tbody>\n</table>",
                  "displayName": "The two-buffer model"
                },
                {
                  "textRaw": "Strict (default)",
                  "name": "strict_(default)",
                  "type": "module",
                  "desc": "<p>Strict mode catches \"fire-and-forget\" patterns where the producer calls\n<code>write()</code> without awaiting, which would cause unbounded memory growth.\nIt limits the buffer to <code>budget</code> bytes and the pending writes queue\nto a single entry.</p>\n<p>If you properly await each write, you can only ever have one pending\nwrite at a time (yours), so you never hit the pending writes limit.\nUnawaited writes accumulate in the pending queue and throw once it\noverflows:</p>\n<pre><code class=\"language-mjs\">import { push, text } from 'node:stream/iter';\n\nconst { writer, readable } = push({ budget: 16384 });\n\n// Consumer must run concurrently -- without it, the first write\n// that fills the buffer blocks the producer forever.\nconst consuming = text(readable);\n\n// GOOD: awaited writes. The producer waits for the consumer to\n// make room when the buffer is full.\nfor (const item of dataset) {\n  await writer.write(item);\n}\nawait writer.end();\nconsole.log(await consuming);\n</code></pre>\n<pre><code class=\"language-cjs\">const { push, text } = require('node:stream/iter');\n\nasync function run() {\n  const { writer, readable } = push({ budget: 16384 });\n\n  // Consumer must run concurrently -- without it, the first write\n  // that fills the buffer blocks the producer forever.\n  const consuming = text(readable);\n\n  // GOOD: awaited writes. The producer waits for the consumer to\n  // make room when the buffer is full.\n  for (const item of dataset) {\n    await writer.write(item);\n  }\n  await writer.end();\n  console.log(await consuming);\n}\n\nrun().catch(console.error);\n</code></pre>\n<p>Forgetting to <code>await</code> will eventually throw:</p>\n<pre><code class=\"language-js\">// BAD: fire-and-forget. Strict mode throws once both buffers fill.\nfor (const item of dataset) {\n  writer.write(item); // Not awaited -- queues without bound\n}\n// --> throws \"Backpressure violation: too many pending writes\"\n</code></pre>",
                  "displayName": "Strict (default)"
                },
                {
                  "textRaw": "Unbounded",
                  "name": "unbounded",
                  "type": "module",
                  "desc": "<p>Unbounded mode caps buffered bytes at <code>budget</code> but places no limit on the\npending writes queue. Awaited writes block until the consumer makes room,\njust like strict mode. The difference is that unawaited writes silently\nqueue forever instead of throwing -- a potential memory leak if the\nproducer forgets to <code>await</code>.</p>\n<p>This is the mode that existing Node.js classic streams and Web Streams\ndefault to. Use it when you control the producer and know it awaits\nproperly, or when migrating code from those APIs.</p>\n<pre><code class=\"language-mjs\">import { push, text } from 'node:stream/iter';\n\nconst { writer, readable } = push({\n  budget: 16384,\n  backpressure: 'unbounded',\n});\n\nconst consuming = text(readable);\n\n// Safe -- awaited writes block until the consumer reads.\nfor (const item of dataset) {\n  await writer.write(item);\n}\nawait writer.end();\nconsole.log(await consuming);\n</code></pre>\n<pre><code class=\"language-cjs\">const { push, text } = require('node:stream/iter');\n\nasync function run() {\n  const { writer, readable } = push({\n    budget: 16384,\n    backpressure: 'unbounded',\n  });\n\n  const consuming = text(readable);\n\n  // Safe -- awaited writes block until the consumer reads.\n  for (const item of dataset) {\n    await writer.write(item);\n  }\n  await writer.end();\n  console.log(await consuming);\n}\n\nrun().catch(console.error);\n</code></pre>",
                  "displayName": "Unbounded"
                },
                {
                  "textRaw": "Drop-oldest",
                  "name": "drop-oldest",
                  "type": "module",
                  "desc": "<p>Writes never wait. When the slots buffer is full, the oldest buffered\nchunk is evicted to make room for the incoming write. The consumer\nalways sees the most recent data. Useful for live feeds, telemetry, or\nany scenario where stale data is less valuable than current data.</p>\n<pre><code class=\"language-mjs\">import { push } from 'node:stream/iter';\n\n// Keep only the most recent ~16 KB of readings\nconst { writer, readable } = push({\n  budget: 16384,\n  backpressure: 'drop-oldest',\n});\n</code></pre>\n<pre><code class=\"language-cjs\">const { push } = require('node:stream/iter');\n\n// Keep only the most recent ~16 KB of readings\nconst { writer, readable } = push({\n  budget: 16384,\n  backpressure: 'drop-oldest',\n});\n</code></pre>",
                  "displayName": "Drop-oldest"
                },
                {
                  "textRaw": "Drop-newest",
                  "name": "drop-newest",
                  "type": "module",
                  "desc": "<p>Writes never wait. When the slots buffer is full, the incoming write is\nsilently discarded. The consumer processes what is already buffered\nwithout being overwhelmed by new data. Useful for rate-limiting or\nshedding load under pressure.</p>\n<pre><code class=\"language-mjs\">import { push } from 'node:stream/iter';\n\n// Accept up to 16 KB of buffered data; discard anything beyond that\nconst { writer, readable } = push({\n  budget: 16384,\n  backpressure: 'drop-newest',\n});\n</code></pre>\n<pre><code class=\"language-cjs\">const { push } = require('node:stream/iter');\n\n// Accept up to 16 KB of buffered data; discard anything beyond that\nconst { writer, readable } = push({\n  budget: 16384,\n  backpressure: 'drop-newest',\n});\n</code></pre>",
                  "displayName": "Drop-newest"
                }
              ],
              "displayName": "Backpressure"
            },
            {
              "textRaw": "Writer interface",
              "name": "writer_interface",
              "type": "module",
              "desc": "<p>A writer is any object conforming to the Writer interface. Only <code>write()</code> is\nrequired; all other methods are optional.</p>\n<p>Writer arguments use Web IDL conversion semantics. A non-<code>Uint8Array</code> chunk is\nconverted to a <code>USVString</code> and then UTF-8 encoded. <code>writev()</code> and\n<code>writevSync()</code> accept any iterable object whose values can be converted to\nchunks. Writer option dictionaries treat <code>null</code> as an empty dictionary and\nignore unknown members.</p>\n<p>Arguments are converted before the write itself starts. If the conversion runs\nuser code (for example a <code>toString()</code> method, or the iterator of a <code>writev()</code>\nargument) that writes to the same writer, those writes are ordered before the\nwrite whose argument is being converted, and they count against the same\nbackpressure limits.</p>\n<p>After <code>end()</code> or <code>endSync()</code> has been called, and until all buffered data has\nbeen consumed, the writer is <em>closing</em>. While closing, <code>canWrite</code> is <code>null</code>,\n<code>write()</code> and <code>writev()</code> reject with a <code>TypeError</code>, <code>writeSync()</code> and\n<code>writevSync()</code> return <code>false</code>, <code>endSync()</code> returns <code>-1</code>, and calling <code>end()</code>\nagain returns the same promise as the first call.</p>\n<p>Each async method has a synchronous <code>*Sync</code> counterpart designed for a\ntry-fallback pattern: attempt the fast synchronous path first, and fall back\nto the async version only when the synchronous call indicates it could not\ncomplete:</p>\n<pre><code class=\"language-mjs\">if (!writer.writeSync(chunk)) await writer.write(chunk);\nif (!writer.writevSync(chunks)) await writer.writev(chunks);\nif (writer.endSync() &#x3C; 0) await writer.end();\nwriter.fail(err);  // Always synchronous, no fallback needed\n</code></pre>",
              "properties": [
                {
                  "textRaw": "{boolean | null}",
                  "name": "canWrite",
                  "type": "boolean | null",
                  "desc": "<p>Returns <code>true</code> if the slots buffer has physical capacity (buffered data is\nbelow the configured byte budget), <code>false</code> if the budget is exhausted, or\n<code>null</code> if the writer is closed or the consumer has disconnected.</p>\n<p>This reports physical capacity independently of the backpressure policy. With\n<code>'drop-oldest'</code> or <code>'drop-newest'</code>, writes still complete when this is <code>false</code>\nby evicting buffered data or discarding the incoming data, respectively.</p>\n<p>This is a hint, not a guarantee: the state can change between the check and\nthe write. Use <a href=\"#ondraindrainable\"><code>ondrain()</code></a> to wait for capacity rather than polling.</p>"
                }
              ],
              "methods": [
                {
                  "textRaw": "`writer.end([options])`",
                  "name": "end",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`options` {Object}",
                          "name": "options",
                          "type": "Object",
                          "options": [
                            {
                              "textRaw": "`signal` {AbortSignal} Cancel just this operation. The signal cancels only the pending `end()` call; it does not fail the writer itself.",
                              "name": "signal",
                              "type": "AbortSignal",
                              "desc": "Cancel just this operation. The signal cancels only the pending `end()` call; it does not fail the writer itself."
                            }
                          ],
                          "optional": true
                        }
                      ],
                      "return": {
                        "textRaw": "Returns: {Promise} Fulfills with the total number of bytes written.",
                        "name": "return",
                        "type": "Promise",
                        "desc": "Fulfills with the total number of bytes written."
                      }
                    }
                  ],
                  "desc": "<p>Signals that no more data will be written. Writes already waiting for buffer\nspace remain ordered before the end of the stream, while later writes fail. If\ndata is outstanding, the returned promise fulfills after the consumer pulls\n<code>done: true</code> beyond the final batch. If no data is buffered or pending, the\nwriter closes immediately.</p>"
                },
                {
                  "textRaw": "`writer.endSync()`",
                  "name": "endSync",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [],
                      "return": {
                        "textRaw": "Returns: {number} Total bytes written, or `-1` if ending cannot complete synchronously.",
                        "name": "return",
                        "type": "number",
                        "desc": "Total bytes written, or `-1` if ending cannot complete synchronously."
                      }
                    }
                  ],
                  "desc": "<p>Synchronous variant of <code>writer.end()</code>. A return value of <code>-1</code> only indicates\nthat the operation could not complete synchronously; no assumption can be made\nabout whether closing has started or why it could not complete. Use the\ntry-fallback pattern to await completion:</p>\n<pre><code class=\"language-cjs\">const result = writer.endSync();\nif (result &#x3C; 0) {\n  writer.end();\n}\n</code></pre>"
                },
                {
                  "textRaw": "`writer.fail([reason])`",
                  "name": "fail",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`reason` {any}",
                          "name": "reason",
                          "type": "any",
                          "optional": true
                        }
                      ]
                    }
                  ],
                  "desc": "<p>Put the writer into a terminal error state. If the writer is already closed\nor errored, this is a no-op. Unlike <code>write()</code> and <code>end()</code>, <code>fail()</code> is\nunconditionally synchronous because failing a writer is a pure state\ntransition with no async work to perform. The reason is stored and propagated\nwithout modification. If omitted, the reason is <code>undefined</code>.</p>"
                },
                {
                  "textRaw": "`writer[Symbol.asyncDispose]()`",
                  "name": "[Symbol.asyncDispose]",
                  "type": "method",
                  "signatures": [
                    {
                      "params": []
                    }
                  ],
                  "desc": "<p>If the writer is open, calls <code>writer.fail()</code>. If the writer is closing after\n<code>end()</code> or <code>endSync()</code>, waits for buffered data to drain. If the writer is\nalready closed or errored, resolves immediately.</p>"
                },
                {
                  "textRaw": "`writer.write(chunk[, options])`",
                  "name": "write",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`chunk` {Uint8Array | string}",
                          "name": "chunk",
                          "type": "Uint8Array | string"
                        },
                        {
                          "textRaw": "`options` {Object}",
                          "name": "options",
                          "type": "Object",
                          "options": [
                            {
                              "textRaw": "`signal` {AbortSignal} Cancel just this write operation. The signal cancels only the pending `write()` call; it does not fail the writer itself.",
                              "name": "signal",
                              "type": "AbortSignal",
                              "desc": "Cancel just this write operation. The signal cancels only the pending `write()` call; it does not fail the writer itself."
                            }
                          ],
                          "optional": true
                        }
                      ],
                      "return": {
                        "textRaw": "Returns: {Promise} Fulfills with `undefined` when buffer space is available.",
                        "name": "return",
                        "type": "Promise",
                        "desc": "Fulfills with `undefined` when buffer space is available."
                      }
                    }
                  ],
                  "desc": "<p>Write a chunk.</p>"
                },
                {
                  "textRaw": "`writer.writeSync(chunk)`",
                  "name": "writeSync",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`chunk` {Uint8Array | string}",
                          "name": "chunk",
                          "type": "Uint8Array | string"
                        }
                      ],
                      "return": {
                        "textRaw": "Returns: {boolean} `true` if the write was accepted, `false` if the buffer is full.",
                        "name": "return",
                        "type": "boolean",
                        "desc": "`true` if the write was accepted, `false` if the buffer is full."
                      }
                    }
                  ],
                  "desc": "<p>Synchronous write. Does not block; returns <code>false</code> if backpressure is active.</p>"
                },
                {
                  "textRaw": "`writer.writev(chunks[, options])`",
                  "name": "writev",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`chunks` {Iterable} of {Uint8Array | string} values",
                          "name": "chunks",
                          "type": "Iterable",
                          "desc": "of {Uint8Array | string} values"
                        },
                        {
                          "textRaw": "`options` {Object}",
                          "name": "options",
                          "type": "Object",
                          "options": [
                            {
                              "textRaw": "`signal` {AbortSignal} Cancel just this write operation. The signal cancels only the pending `writev()` call; it does not fail the writer itself.",
                              "name": "signal",
                              "type": "AbortSignal",
                              "desc": "Cancel just this write operation. The signal cancels only the pending `writev()` call; it does not fail the writer itself."
                            }
                          ],
                          "optional": true
                        }
                      ],
                      "return": {
                        "textRaw": "Returns: {Promise}",
                        "name": "return",
                        "type": "Promise"
                      }
                    }
                  ],
                  "desc": "<p>Write multiple chunks as a single batch.</p>"
                },
                {
                  "textRaw": "`writer.writevSync(chunks)`",
                  "name": "writevSync",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`chunks` {Iterable} of {Uint8Array | string} values",
                          "name": "chunks",
                          "type": "Iterable",
                          "desc": "of {Uint8Array | string} values"
                        }
                      ],
                      "return": {
                        "textRaw": "Returns: {boolean} `true` if the write was accepted, `false` if the buffer is full.",
                        "name": "return",
                        "type": "boolean",
                        "desc": "`true` if the write was accepted, `false` if the buffer is full."
                      }
                    }
                  ],
                  "desc": "<p>Synchronous batch write.</p>"
                }
              ],
              "displayName": "Writer interface"
            }
          ],
          "displayName": "Concepts"
        },
        {
          "textRaw": "The `stream/iter` module",
          "name": "the_`stream/iter`_module",
          "type": "module",
          "desc": "<p>Most functions are available both as named exports and as properties of the\n<code>Stream</code> namespace object. The classic stream adapters (<code>fromReadable()</code>,\n<code>fromWritable()</code>, <code>toReadable()</code>, <code>toReadableSync()</code>, and <code>toWritable()</code>) and\nthe static helper objects (<code>Broadcast</code>, <code>Share</code>, and <code>SyncShare</code>) are named\nexports only.</p>\n<pre><code class=\"language-mjs\">// Named exports\nimport { from, pull, bytes, Stream } from 'node:stream/iter';\n\n// Namespace access\nStream.from('hello');\n</code></pre>\n<p>Options dictionaries defined by the Iterable Streams API use Web IDL\nconversion semantics. <code>null</code> is treated as an empty dictionary, unknown\nmembers are ignored, and known members are converted to their declared types\nbefore the operation runs. Conversion failures use Node.js error codes such as\n<code>ERR_INVALID_ARG_TYPE</code>, <code>ERR_INVALID_ARG_VALUE</code>, and <code>ERR_OUT_OF_RANGE</code>.</p>\n<pre><code class=\"language-cjs\">// Named exports\nconst { from, pull, bytes, Stream } = require('node:stream/iter');\n\n// Namespace access\nStream.from('hello');\n</code></pre>\n<p>Including the <code>node:</code> prefix on the module specifier is optional.</p>",
          "displayName": "The `stream/iter` module"
        },
        {
          "textRaw": "Sources",
          "name": "sources",
          "type": "module",
          "methods": [
            {
              "textRaw": "`from(input)`",
              "name": "from",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`input` {string | ArrayBuffer | ArrayBufferView | Iterable | AsyncIterable | Object} Must not be `null` or `undefined`.",
                      "name": "input",
                      "type": "string | ArrayBuffer | ArrayBufferView | Iterable | AsyncIterable | Object",
                      "desc": "Must not be `null` or `undefined`."
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {AsyncIterable} whose chunks fulfill with {Uint8Array[]}.",
                    "name": "return",
                    "type": "AsyncIterable",
                    "desc": "whose chunks fulfill with {Uint8Array[]}."
                  }
                }
              ],
              "desc": "<p>Create an async byte stream from the given input. Strings are UTF-8 encoded.\n<code>ArrayBuffer</code> and <code>ArrayBufferView</code> values are wrapped as <code>Uint8Array</code>. Arrays\nand iterables in <code>input</code> are recursively flattened and normalized. Flattened\nvalues may be split across implementation-defined bounded batches.</p>\n<p>Objects implementing <code>Symbol.for('Stream.toAsyncStreamable')</code> or\n<code>Symbol.for('Stream.toStreamable')</code> are converted via those protocols. The\n<code>toAsyncStreamable</code> protocol takes precedence over <code>toStreamable</code>, which takes\nprecedence over the iteration protocols (<code>Symbol.asyncIterator</code>,\n<code>Symbol.iterator</code>).</p>\n<pre><code class=\"language-mjs\">import { Buffer } from 'node:buffer';\nimport { from, text } from 'node:stream/iter';\n\nconsole.log(await text(from('hello')));       // 'hello'\nconsole.log(await text(from(Buffer.from('hello')))); // 'hello'\n</code></pre>\n<pre><code class=\"language-cjs\">const { Buffer } = require('node:buffer');\nconst { from, text } = require('node:stream/iter');\n\nasync function run() {\n  console.log(await text(from('hello')));       // 'hello'\n  console.log(await text(from(Buffer.from('hello')))); // 'hello'\n}\n\nrun().catch(console.error);\n</code></pre>"
            },
            {
              "textRaw": "`fromSync(input)`",
              "name": "fromSync",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`input` {string | ArrayBuffer | ArrayBufferView | Iterable | Object} Must not be `null` or `undefined`.",
                      "name": "input",
                      "type": "string | ArrayBuffer | ArrayBufferView | Iterable | Object",
                      "desc": "Must not be `null` or `undefined`."
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Iterable} whose chunks return {Uint8Array[]}",
                    "name": "return",
                    "type": "Iterable",
                    "desc": "whose chunks return {Uint8Array[]}"
                  }
                }
              ],
              "desc": "<p>Synchronous version of <a href=\"#frominput\"><code>from()</code></a>. Returns a sync iterable. Cannot accept\nasync iterables or promises. Objects implementing\n<code>Symbol.for('Stream.toStreamable')</code> are converted via that protocol (takes\nprecedence over <code>Symbol.iterator</code>). The <code>toAsyncStreamable</code> protocol is\nignored entirely.</p>\n<pre><code class=\"language-mjs\">import { fromSync, textSync } from 'node:stream/iter';\n\nconsole.log(textSync(fromSync('hello'))); // 'hello'\n</code></pre>\n<pre><code class=\"language-cjs\">const { fromSync, textSync } = require('node:stream/iter');\n\nconsole.log(textSync(fromSync('hello'))); // 'hello'\n</code></pre>"
            }
          ],
          "displayName": "Sources"
        },
        {
          "textRaw": "Pipelines",
          "name": "pipelines",
          "type": "module",
          "methods": [
            {
              "textRaw": "`pipeTo(source[, ...transforms], writer[, options])`",
              "name": "pipeTo",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {AsyncIterable | Iterable} The data source.",
                      "name": "source",
                      "type": "AsyncIterable | Iterable",
                      "desc": "The data source."
                    },
                    {
                      "textRaw": "`...transforms` {Function | Object} Zero or more transforms to apply.",
                      "name": "...transforms",
                      "type": "Function | Object",
                      "desc": "Zero or more transforms to apply.",
                      "optional": true
                    },
                    {
                      "textRaw": "`writer` {Object} Destination with `write(chunk)` method.",
                      "name": "writer",
                      "type": "Object",
                      "desc": "Destination with `write(chunk)` method."
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`signal` {AbortSignal} Abort the pipeline. Aborting fails the destination writer unless `preventFail` is `true`.",
                          "name": "signal",
                          "type": "AbortSignal",
                          "desc": "Abort the pipeline. Aborting fails the destination writer unless `preventFail` is `true`."
                        },
                        {
                          "textRaw": "`preventClose` {boolean} If `true`, do not call `writer.end()` when the source ends. **Default:** `false`.",
                          "name": "preventClose",
                          "type": "boolean",
                          "default": "`false`",
                          "desc": "If `true`, do not call `writer.end()` when the source ends."
                        },
                        {
                          "textRaw": "`preventFail` {boolean} If `true`, do not call `writer.fail()` on error. **Default:** `false`.",
                          "name": "preventFail",
                          "type": "boolean",
                          "default": "`false`",
                          "desc": "If `true`, do not call `writer.fail()` on error."
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Promise} Fulfills with the total number of bytes written.",
                    "name": "return",
                    "type": "Promise",
                    "desc": "Fulfills with the total number of bytes written."
                  }
                }
              ],
              "desc": "<p>Pipe a source through transforms into a writer. If the writer has a\n<code>writev(chunks)</code> method, entire batches are passed in a single call (enabling\nscatter/gather I/O).</p>\n<p>If the writer implements the optional <code>*Sync</code> methods (<code>writeSync</code>, <code>writevSync</code>,\n<code>endSync</code>), <code>pipeTo()</code> will attempt to use the synchronous methods\nfirst as a fast path, and fall back to the async versions only when the sync\nmethods indicate they cannot complete (e.g., backpressure or waiting for the\nnext tick). <code>fail()</code> is always called synchronously.</p>\n<pre><code class=\"language-mjs\">import { from, pipeTo } from 'node:stream/iter';\nimport { compressGzip } from 'node:zlib/iter';\nimport { open } from 'node:fs/promises';\n\nconst fh = await open('output.gz', 'w');\nconst totalBytes = await pipeTo(\n  from('Hello, world!'),\n  compressGzip(),\n  fh.writer({ autoClose: true }),\n);\n</code></pre>\n<pre><code class=\"language-cjs\">const { from, pipeTo } = require('node:stream/iter');\nconst { compressGzip } = require('node:zlib/iter');\nconst { open } = require('node:fs/promises');\n\nasync function run() {\n  const fh = await open('output.gz', 'w');\n  const totalBytes = await pipeTo(\n    from('Hello, world!'),\n    compressGzip(),\n    fh.writer({ autoClose: true }),\n  );\n}\n\nrun().catch(console.error);\n</code></pre>"
            },
            {
              "textRaw": "`pipeToSync(source[, ...transforms], writer[, options])`",
              "name": "pipeToSync",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {Iterable} The sync data source.",
                      "name": "source",
                      "type": "Iterable",
                      "desc": "The sync data source."
                    },
                    {
                      "textRaw": "`...transforms` {Function | Object} Zero or more sync transforms.",
                      "name": "...transforms",
                      "type": "Function | Object",
                      "desc": "Zero or more sync transforms.",
                      "optional": true
                    },
                    {
                      "textRaw": "`writer` {Object} Destination with `write(chunk)` method.",
                      "name": "writer",
                      "type": "Object",
                      "desc": "Destination with `write(chunk)` method."
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`failOnIncompleteClose` {boolean} If `true`, call `writer.fail()` when `writer.endSync()` cannot close the writer synchronously. Ignored when `preventFail` is `true`. This option is a Node.js extension. **Default:** `false`.",
                          "name": "failOnIncompleteClose",
                          "type": "boolean",
                          "default": "`false`",
                          "desc": "If `true`, call `writer.fail()` when `writer.endSync()` cannot close the writer synchronously. Ignored when `preventFail` is `true`. This option is a Node.js extension."
                        },
                        {
                          "textRaw": "`preventClose` {boolean} **Default:** `false`.",
                          "name": "preventClose",
                          "type": "boolean",
                          "default": "`false`"
                        },
                        {
                          "textRaw": "`preventFail` {boolean} **Default:** `false`.",
                          "name": "preventFail",
                          "type": "boolean",
                          "default": "`false`"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {number} Total bytes written.",
                    "name": "return",
                    "type": "number",
                    "desc": "Total bytes written."
                  }
                }
              ],
              "desc": "<p>Synchronous version of <a href=\"#pipetosource-transforms-writer-options\"><code>pipeTo()</code></a>. The <code>source</code>, all transforms, and the\n<code>writer</code> must be synchronous. Cannot accept async iterables or promises.</p>\n<p>The <code>writer</code> must have the <code>*Sync</code> methods (<code>writeSync</code>, <code>writevSync</code>,\n<code>endSync</code>) and <code>fail()</code> for this to work.</p>\n<p><code>pipeToSync()</code> never falls back to the asynchronous writer methods. If\n<code>writer.endSync()</code> returns <code>-1</code> because the writer cannot close synchronously\n(for example, a <code>push()</code> writer whose consumer has not read all of the data\nyet), <code>pipeToSync()</code> throws <code>ERR_INVALID_STATE</code>. All of the data was accepted\nby then, so by default the writer is not failed: it can still be closed, for\nexample with <code>await writer.end()</code>. If the writer cannot be closed any other\nway (for example, it has no <code>end()</code> method), or the caller will not close it,\nset <code>failOnIncompleteClose</code> to fail it with the thrown error instead.</p>"
            },
            {
              "textRaw": "`pull(source[, ...transforms][, options])`",
              "name": "pull",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {AsyncIterable | Iterable} The data source.",
                      "name": "source",
                      "type": "AsyncIterable | Iterable",
                      "desc": "The data source."
                    },
                    {
                      "textRaw": "`...transforms` {Function | Object} Zero or more transforms to apply.",
                      "name": "...transforms",
                      "type": "Function | Object",
                      "desc": "Zero or more transforms to apply.",
                      "optional": true
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`signal` {AbortSignal} Abort the pipeline.",
                          "name": "signal",
                          "type": "AbortSignal",
                          "desc": "Abort the pipeline."
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {AsyncIterable} whose chunks fulfill with {Uint8Array[]}",
                    "name": "return",
                    "type": "AsyncIterable",
                    "desc": "whose chunks fulfill with {Uint8Array[]}"
                  }
                }
              ],
              "desc": "<p>Create a lazy async pipeline. Source conversion and streamable protocol\ndispatch occur when <code>pull()</code> is called, but data is not read from <code>source</code>\nuntil the returned iterable is consumed. Transforms are applied in order.</p>\n<p>When <code>signal</code> aborts, the pending read (or the next one) rejects with\n<code>signal.reason</code>, and so does every later read. If <code>signal</code> is already aborted,\n<code>pull()</code> still returns an iterable; reading from it rejects with\n<code>signal.reason</code> without reading from <code>source</code>.</p>\n<pre><code class=\"language-mjs\">import { from, pull, text } from 'node:stream/iter';\n\nconst asciiUpper = (chunks) => {\n  if (chunks === null) return null;\n  return chunks.map((c) => {\n    for (let i = 0; i &#x3C; c.length; i++) {\n      c[i] -= (c[i] >= 97 &#x26;&#x26; c[i] &#x3C;= 122) * 32;\n    }\n    return c;\n  });\n};\n\nconst result = pull(from('hello'), asciiUpper);\nconsole.log(await text(result)); // 'HELLO'\n</code></pre>\n<pre><code class=\"language-cjs\">const { from, pull, text } = require('node:stream/iter');\n\nconst asciiUpper = (chunks) => {\n  if (chunks === null) return null;\n  return chunks.map((c) => {\n    for (let i = 0; i &#x3C; c.length; i++) {\n      c[i] -= (c[i] >= 97 &#x26;&#x26; c[i] &#x3C;= 122) * 32;\n    }\n    return c;\n  });\n};\n\nasync function run() {\n  const result = pull(from('hello'), asciiUpper);\n  console.log(await text(result)); // 'HELLO'\n}\n\nrun().catch(console.error);\n</code></pre>\n<p>Using an <code>AbortSignal</code>:</p>\n<pre><code class=\"language-mjs\">import { pull } from 'node:stream/iter';\n\nconst ac = new AbortController();\nconst result = pull(source, transform, { signal: ac.signal });\nac.abort(); // Pipeline throws AbortError on next iteration\n</code></pre>\n<pre><code class=\"language-cjs\">const { pull } = require('node:stream/iter');\n\nconst ac = new AbortController();\nconst result = pull(source, transform, { signal: ac.signal });\nac.abort(); // Pipeline throws AbortError on next iteration\n</code></pre>"
            },
            {
              "textRaw": "`pullSync(source[, ...transforms])`",
              "name": "pullSync",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {Iterable} The sync data source.",
                      "name": "source",
                      "type": "Iterable",
                      "desc": "The sync data source."
                    },
                    {
                      "textRaw": "`...transforms` {Function | Object} Zero or more sync transforms.",
                      "name": "...transforms",
                      "type": "Function | Object",
                      "desc": "Zero or more sync transforms.",
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Iterable} whose chunks return {Uint8Array[]}",
                    "name": "return",
                    "type": "Iterable",
                    "desc": "whose chunks return {Uint8Array[]}"
                  }
                }
              ],
              "desc": "<p>Synchronous version of <a href=\"#pullsource-transforms-options\"><code>pull()</code></a>. Source conversion and streamable protocol\ndispatch occur when <code>pullSync()</code> is called. All transforms must be synchronous.</p>"
            }
          ],
          "displayName": "Pipelines"
        },
        {
          "textRaw": "Push streams",
          "name": "push_streams",
          "type": "module",
          "methods": [
            {
              "textRaw": "`push([...transforms][, options])`",
              "name": "push",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`...transforms` {Function | Object} Optional transforms applied to the readable side.",
                      "name": "...transforms",
                      "type": "Function | Object",
                      "desc": "Optional transforms applied to the readable side.",
                      "optional": true
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`budget` {number} Maximum number of buffered bytes before backpressure is applied. Must be a positive integer. **Default:** `16384`.",
                          "name": "budget",
                          "type": "number",
                          "default": "`16384`",
                          "desc": "Maximum number of buffered bytes before backpressure is applied. Must be a positive integer."
                        },
                        {
                          "textRaw": "`backpressure` {string} Backpressure policy: `'strict'`, `'unbounded'`, `'drop-oldest'`, or `'drop-newest'`. **Default:** `'strict'`.",
                          "name": "backpressure",
                          "type": "string",
                          "default": "`'strict'`",
                          "desc": "Backpressure policy: `'strict'`, `'unbounded'`, `'drop-oldest'`, or `'drop-newest'`."
                        },
                        {
                          "textRaw": "`signal` {AbortSignal} Abort the stream. The signal remains active while buffered data drains after `writer.end()`; aborting during that time fails the writer and rejects the pending `end()` promise.",
                          "name": "signal",
                          "type": "AbortSignal",
                          "desc": "Abort the stream. The signal remains active while buffered data drains after `writer.end()`; aborting during that time fails the writer and rejects the pending `end()` promise."
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Object}",
                    "name": "return",
                    "type": "Object",
                    "options": [
                      {
                        "textRaw": "`writer` {Writable} The writer side.",
                        "name": "writer",
                        "type": "Writable",
                        "desc": "The writer side."
                      },
                      {
                        "textRaw": "`readable` {AsyncIterable} whose chunks fulfill with {Uint8Array[]}",
                        "name": "readable",
                        "type": "AsyncIterable",
                        "desc": "whose chunks fulfill with {Uint8Array[]}"
                      }
                    ]
                  }
                }
              ],
              "desc": "<p>Create a push stream with backpressure. The writer pushes data in; the\nreadable side is consumed as an async iterable.</p>\n<pre><code class=\"language-mjs\">import { push, text } from 'node:stream/iter';\n\nconst { writer, readable } = push();\n\n// Producer and consumer must run concurrently. With strict backpressure\n// (the default), awaited writes block until the consumer reads.\nconst producing = (async () => {\n  await writer.write('hello');\n  await writer.write(' world');\n  await writer.end();\n})();\n\nconsole.log(await text(readable)); // 'hello world'\nawait producing;\n</code></pre>\n<pre><code class=\"language-cjs\">const { push, text } = require('node:stream/iter');\n\nasync function run() {\n  const { writer, readable } = push();\n\n  // Producer and consumer must run concurrently. With strict backpressure\n  // (the default), awaited writes block until the consumer reads.\n  const producing = (async () => {\n    await writer.write('hello');\n    await writer.write(' world');\n    await writer.end();\n  })();\n\n  console.log(await text(readable)); // 'hello world'\n  await producing;\n}\n\nrun().catch(console.error);\n</code></pre>\n<p>The writer returned by <code>push()</code> conforms to the [Writer interface][].</p>\n<p>Zero-length chunks are accepted without being buffered: they are not delivered\nto the consumer, and <code>writeSync()</code> and <code>write()</code> report success for them even\nwhen backpressure is active.</p>"
            }
          ],
          "displayName": "Push streams"
        },
        {
          "textRaw": "Duplex channels",
          "name": "duplex_channels",
          "type": "module",
          "methods": [
            {
              "textRaw": "`duplex([options])`",
              "name": "duplex",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`budget` {number} Buffer size in bytes for both directions. Must be a positive integer. **Default:** `16384`.",
                          "name": "budget",
                          "type": "number",
                          "default": "`16384`",
                          "desc": "Buffer size in bytes for both directions. Must be a positive integer."
                        },
                        {
                          "textRaw": "`backpressure` {string} Policy for both directions. **Default:** `'strict'`.",
                          "name": "backpressure",
                          "type": "string",
                          "default": "`'strict'`",
                          "desc": "Policy for both directions."
                        },
                        {
                          "textRaw": "`signal` {AbortSignal} Cancellation signal for both channels.",
                          "name": "signal",
                          "type": "AbortSignal",
                          "desc": "Cancellation signal for both channels."
                        },
                        {
                          "textRaw": "`a` {Object} Options specific to the A-to-B direction. Overrides shared options.",
                          "name": "a",
                          "type": "Object",
                          "desc": "Options specific to the A-to-B direction. Overrides shared options.",
                          "options": [
                            {
                              "textRaw": "`budget` {number}",
                              "name": "budget",
                              "type": "number"
                            },
                            {
                              "textRaw": "`backpressure` {string}",
                              "name": "backpressure",
                              "type": "string"
                            }
                          ]
                        },
                        {
                          "textRaw": "`b` {Object} Options specific to the B-to-A direction. Overrides shared options.",
                          "name": "b",
                          "type": "Object",
                          "desc": "Options specific to the B-to-A direction. Overrides shared options.",
                          "options": [
                            {
                              "textRaw": "`budget` {number}",
                              "name": "budget",
                              "type": "number"
                            },
                            {
                              "textRaw": "`backpressure` {string}",
                              "name": "backpressure",
                              "type": "string"
                            }
                          ]
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Array} A pair `[channelA, channelB]` of duplex channels.",
                    "name": "return",
                    "type": "Array",
                    "desc": "A pair `[channelA, channelB]` of duplex channels."
                  }
                }
              ],
              "desc": "<p>Create a pair of connected duplex channels for bidirectional communication,\nsimilar to <code>socketpair()</code>. Data written to one channel's writer appears in\nthe other channel's readable.</p>\n<p>Each channel has:</p>\n<ul>\n<li><code>writer</code> — a [Writer interface][] object for sending data to the peer.</li>\n<li><code>readable</code> — an <code class=\"type\"><a href=\"https://tc39.github.io/ecma262/#sec-asynciterable-interface\" class=\"type-link\">AsyncIterable</a></code> for reading data from the peer.</li>\n<li><code>close()</code> — close this end of the channel (idempotent).</li>\n<li><code>[Symbol.asyncDispose]()</code> — async dispose support for <code>await using</code>.</li>\n</ul>\n<pre><code class=\"language-mjs\">import { duplex, text } from 'node:stream/iter';\n\nconst [client, server] = duplex();\n\n// Server echoes back\nconst serving = (async () => {\n  for await (const chunks of server.readable) {\n    await server.writer.writev(chunks);\n  }\n  await server.writer.end();\n})();\n\nawait client.writer.write('hello');\nawait client.writer.end();\n\nconsole.log(await text(client.readable)); // 'hello'\nawait serving;\n</code></pre>\n<pre><code class=\"language-cjs\">const { duplex, text } = require('node:stream/iter');\n\nasync function run() {\n  const [client, server] = duplex();\n\n  // Server echoes back\n  const serving = (async () => {\n    for await (const chunks of server.readable) {\n      await server.writer.writev(chunks);\n    }\n    await server.writer.end();\n  })();\n\n  await client.writer.write('hello');\n  await client.writer.end();\n\n  console.log(await text(client.readable)); // 'hello'\n  await serving;\n}\n\nrun().catch(console.error);\n</code></pre>"
            }
          ],
          "displayName": "Duplex channels"
        },
        {
          "textRaw": "Consumers",
          "name": "consumers",
          "type": "module",
          "methods": [
            {
              "textRaw": "`array(source[, options])`",
              "name": "array",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {AsyncIterable | Iterable} whose chunks must be {Uint8Array[]}",
                      "name": "source",
                      "type": "AsyncIterable | Iterable",
                      "desc": "whose chunks must be {Uint8Array[]}"
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`signal` {AbortSignal}",
                          "name": "signal",
                          "type": "AbortSignal"
                        },
                        {
                          "textRaw": "`limit` {number} Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown",
                          "name": "limit",
                          "type": "number",
                          "desc": "Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Promise} Fulfills with an array of `Uint8Array` objects.",
                    "name": "return",
                    "type": "Promise",
                    "desc": "Fulfills with an array of `Uint8Array` objects."
                  }
                }
              ],
              "desc": "<p>Collect all chunks as an array of <code>Uint8Array</code> values (without concatenating).</p>"
            },
            {
              "textRaw": "`arrayBuffer(source[, options])`",
              "name": "arrayBuffer",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {AsyncIterable | Iterable} whose chunks must be {Uint8Array[]}",
                      "name": "source",
                      "type": "AsyncIterable | Iterable",
                      "desc": "whose chunks must be {Uint8Array[]}"
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`signal` {AbortSignal}",
                          "name": "signal",
                          "type": "AbortSignal"
                        },
                        {
                          "textRaw": "`limit` {number} Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown",
                          "name": "limit",
                          "type": "number",
                          "desc": "Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Promise} Fulfills with an `ArrayBuffer` object.",
                    "name": "return",
                    "type": "Promise",
                    "desc": "Fulfills with an `ArrayBuffer` object."
                  }
                }
              ],
              "desc": "<p>Collect all bytes into an <code>ArrayBuffer</code>.</p>"
            },
            {
              "textRaw": "`arrayBufferSync(source[, options])`",
              "name": "arrayBufferSync",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {Iterable} whose chunks must be {Uint8Array[]}",
                      "name": "source",
                      "type": "Iterable",
                      "desc": "whose chunks must be {Uint8Array[]}"
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`limit` {number} Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown",
                          "name": "limit",
                          "type": "number",
                          "desc": "Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {ArrayBuffer}",
                    "name": "return",
                    "type": "ArrayBuffer"
                  }
                }
              ],
              "desc": "<p>Synchronous version of <a href=\"#arraybuffersource-options\"><code>arrayBuffer()</code></a>.</p>"
            },
            {
              "textRaw": "`arraySync(source[, options])`",
              "name": "arraySync",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {Iterable} whose chunks must be {Uint8Array[]}",
                      "name": "source",
                      "type": "Iterable",
                      "desc": "whose chunks must be {Uint8Array[]}"
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`limit` {number} Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown",
                          "name": "limit",
                          "type": "number",
                          "desc": "Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Uint8Array[]}",
                    "name": "return",
                    "type": "Uint8Array[]"
                  }
                }
              ],
              "desc": "<p>Synchronous version of <a href=\"#arraysource-options\"><code>array()</code></a>.</p>"
            },
            {
              "textRaw": "`bytes(source[, options])`",
              "name": "bytes",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {AsyncIterable | Iterable} whose chunks must be {Uint8Array[]}",
                      "name": "source",
                      "type": "AsyncIterable | Iterable",
                      "desc": "whose chunks must be {Uint8Array[]}"
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`signal` {AbortSignal}",
                          "name": "signal",
                          "type": "AbortSignal"
                        },
                        {
                          "textRaw": "`limit` {number} Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown",
                          "name": "limit",
                          "type": "number",
                          "desc": "Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Promise} Fulfills with an `Uint8Array` object.",
                    "name": "return",
                    "type": "Promise",
                    "desc": "Fulfills with an `Uint8Array` object."
                  }
                }
              ],
              "desc": "<p>Collect all bytes from a stream into a single <code>Uint8Array</code>.</p>\n<pre><code class=\"language-mjs\">import { from, bytes } from 'node:stream/iter';\n\nconst data = await bytes(from('hello'));\nconsole.log(data); // Uint8Array(5) [ 104, 101, 108, 108, 111 ]\n</code></pre>\n<pre><code class=\"language-cjs\">const { from, bytes } = require('node:stream/iter');\n\nasync function run() {\n  const data = await bytes(from('hello'));\n  console.log(data); // Uint8Array(5) [ 104, 101, 108, 108, 111 ]\n}\n\nrun().catch(console.error);\n</code></pre>"
            },
            {
              "textRaw": "`bytesSync(source[, options])`",
              "name": "bytesSync",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {Iterable} whose chunks must be {Uint8Array[]}",
                      "name": "source",
                      "type": "Iterable",
                      "desc": "whose chunks must be {Uint8Array[]}"
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`limit` {number} Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown",
                          "name": "limit",
                          "type": "number",
                          "desc": "Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Uint8Array}",
                    "name": "return",
                    "type": "Uint8Array"
                  }
                }
              ],
              "desc": "<p>Synchronous version of <a href=\"#bytessource-options\"><code>bytes()</code></a>.</p>"
            },
            {
              "textRaw": "`dump(source[, options])`",
              "name": "dump",
              "type": "method",
              "meta": {
                "added": [
                  "REPLACEME"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {AsyncIterable | Iterable} whose chunks must be {Uint8Array[]}",
                      "name": "source",
                      "type": "AsyncIterable | Iterable",
                      "desc": "whose chunks must be {Uint8Array[]}"
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`signal` {AbortSignal}",
                          "name": "signal",
                          "type": "AbortSignal"
                        },
                        {
                          "textRaw": "`limit` {number} Maximum number of bytes to consume. If the total bytes read exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown",
                          "name": "limit",
                          "type": "number",
                          "desc": "Maximum number of bytes to consume. If the total bytes read exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Promise} Fulfills with `undefined`.",
                    "name": "return",
                    "type": "Promise",
                    "desc": "Fulfills with `undefined`."
                  }
                }
              ],
              "desc": "<p>Read a source to completion, discarding every chunk. Unlike the other\nconsumers, <code>dump()</code> retains nothing. Memory tops-out at a single batch no\nmatter how much data the source produces.</p>\n<p>Use this to consume a stream when the content doesn't matter. For example, A\nQUIC stream only returns flow-control credit to the peer as its data is\nconsumed, so a receiver that does not want the payload must still read it to\ncompletion.</p>\n<p>If the source errors part-way through, the returned promise rejects with that\nerror.</p>\n<p>There is no default <code>limit</code>. <code>dump()</code> reads until the source is exhausted\nunless a limit is specified. When a limit is configured and the source exceeds\nit, the promise rejects and the source is cancelled. A partial dump is never\nreported as success.</p>\n<pre><code class=\"language-mjs\">import { dump, from, pull, tap } from 'node:stream/iter';\n\n// Count the bytes flowing through a stream without retaining any of them.\nlet bytesSeen = 0;\nconst counter = tap((chunks) => {\n  for (const chunk of chunks) bytesSeen += chunk.byteLength;\n});\n\nawait dump(pull(from('hello world'), counter));\nconsole.log(bytesSeen); // 11\n</code></pre>\n<pre><code class=\"language-cjs\">const { dump, from, pull, tap } = require('node:stream/iter');\n\nasync function run() {\n  // Count the bytes flowing through a stream without retaining any of them.\n  let bytesSeen = 0;\n  const counter = tap((chunks) => {\n    for (const chunk of chunks) bytesSeen += chunk.byteLength;\n  });\n\n  await dump(pull(from('hello world'), counter));\n  console.log(bytesSeen); // 11\n}\n\nrun().catch(console.error);\n</code></pre>"
            },
            {
              "textRaw": "`dumpSync(source[, options])`",
              "name": "dumpSync",
              "type": "method",
              "meta": {
                "added": [
                  "REPLACEME"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {Iterable} whose chunks must be {Uint8Array[]}",
                      "name": "source",
                      "type": "Iterable",
                      "desc": "whose chunks must be {Uint8Array[]}"
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`limit` {number} Maximum number of bytes to consume. If the total bytes read exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown",
                          "name": "limit",
                          "type": "number",
                          "desc": "Maximum number of bytes to consume. If the total bytes read exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {undefined}",
                    "name": "return",
                    "type": "undefined"
                  }
                }
              ],
              "desc": "<p>Synchronous version of <a href=\"#drainsource-options\"><code>dump()</code></a>. Throws <code>ERR_INVALID_ARG_TYPE</code> if <code>source</code>\nis not synchronously iterable.</p>"
            },
            {
              "textRaw": "`text(source[, options])`",
              "name": "text",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {AsyncIterable | Iterable} whose chunks must be {Uint8Array[]}",
                      "name": "source",
                      "type": "AsyncIterable | Iterable",
                      "desc": "whose chunks must be {Uint8Array[]}"
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`encoding` {string} Text encoding. **Default:** `'utf-8'`.",
                          "name": "encoding",
                          "type": "string",
                          "default": "`'utf-8'`",
                          "desc": "Text encoding."
                        },
                        {
                          "textRaw": "`signal` {AbortSignal}",
                          "name": "signal",
                          "type": "AbortSignal"
                        },
                        {
                          "textRaw": "`limit` {number} Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown",
                          "name": "limit",
                          "type": "number",
                          "desc": "Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Promise} Fulfills with a `string`.",
                    "name": "return",
                    "type": "Promise",
                    "desc": "Fulfills with a `string`."
                  }
                }
              ],
              "desc": "<p>Collect all bytes and decode as text.</p>\n<pre><code class=\"language-mjs\">import { from, text } from 'node:stream/iter';\n\nconsole.log(await text(from('hello'))); // 'hello'\n</code></pre>\n<pre><code class=\"language-cjs\">const { from, text } = require('node:stream/iter');\n\nasync function run() {\n  console.log(await text(from('hello'))); // 'hello'\n}\n\nrun().catch(console.error);\n</code></pre>"
            },
            {
              "textRaw": "`textSync(source[, options])`",
              "name": "textSync",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {Iterable} whose chunks must be {Uint8Array[]}",
                      "name": "source",
                      "type": "Iterable",
                      "desc": "whose chunks must be {Uint8Array[]}"
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`encoding` {string} **Default:** `'utf-8'`.",
                          "name": "encoding",
                          "type": "string",
                          "default": "`'utf-8'`"
                        },
                        {
                          "textRaw": "`limit` {number} Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown",
                          "name": "limit",
                          "type": "number",
                          "desc": "Maximum number of bytes to consume. If the total bytes collected exceeds limit, an `ERR_OUT_OF_RANGE` error is thrown"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {string}",
                    "name": "return",
                    "type": "string"
                  }
                }
              ],
              "desc": "<p>Synchronous version of <a href=\"#textsource-options\"><code>text()</code></a>.</p>"
            }
          ],
          "displayName": "Consumers"
        },
        {
          "textRaw": "Utilities",
          "name": "utilities",
          "type": "module",
          "methods": [
            {
              "textRaw": "`ondrain(drainable)`",
              "name": "ondrain",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`drainable` {Object} An object implementing the drainable protocol.",
                      "name": "drainable",
                      "type": "Object",
                      "desc": "An object implementing the drainable protocol."
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Promise | null}",
                    "name": "return",
                    "type": "Promise | null"
                  }
                }
              ],
              "desc": "<p>Wait for a drainable writer to regain physical buffer capacity. Returns <code>null</code>\nif the object does not implement the drainable protocol, or a promise that\nfulfills with <code>true</code> when buffered data falls below the byte budget.</p>\n<p>For writers using <code>'drop-oldest'</code> or <code>'drop-newest'</code>, this waits for physical\ncapacity even though writes do not block. This allows producers to avoid data\nloss by waiting before writing.</p>\n<pre><code class=\"language-mjs\">import { push, ondrain, text } from 'node:stream/iter';\n\nconst { writer, readable } = push({ budget: 16384 });\nconst chunk = new Uint8Array(8192);  // 8 KB\nwriter.writeSync(chunk);\nwriter.writeSync(chunk);  // 16 KB total -- buffer full\n\n// Start consuming so the buffer can actually drain\nconst consuming = text(readable);\n\n// Buffer is full -- wait for drain\nconst canWrite = await ondrain(writer);\nif (canWrite) {\n  await writer.write('c');\n}\nawait writer.end();\nawait consuming;\n</code></pre>\n<pre><code class=\"language-cjs\">const { push, ondrain, text } = require('node:stream/iter');\n\nasync function run() {\n  const { writer, readable } = push({ budget: 16384 });\n  const chunk = new Uint8Array(8192);  // 8 KB\n  writer.writeSync(chunk);\n  writer.writeSync(chunk);  // 16 KB total -- buffer full\n\n  // Start consuming so the buffer can actually drain\n  const consuming = text(readable);\n\n  // Buffer is full -- wait for drain\n  const canWrite = await ondrain(writer);\n  if (canWrite) {\n    await writer.write('c');\n  }\n  await writer.end();\n  await consuming;\n}\n\nrun().catch(console.error);\n</code></pre>"
            },
            {
              "textRaw": "`merge(...sources[, options])`",
              "name": "merge",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`...sources` {AsyncIterable | Iterable} whose chunks must be {Uint8Array[]}",
                      "name": "...sources",
                      "type": "AsyncIterable | Iterable",
                      "desc": "whose chunks must be {Uint8Array[]}"
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`signal` {AbortSignal}",
                          "name": "signal",
                          "type": "AbortSignal"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {AsyncIterable} whose chunks fulfill with {Uint8Array[]}",
                    "name": "return",
                    "type": "AsyncIterable",
                    "desc": "whose chunks fulfill with {Uint8Array[]}"
                  }
                }
              ],
              "desc": "<p>Merge multiple async iterables by yielding batches in temporal order\n(whichever source produces data first). All sources are consumed\nconcurrently, with at most one pending <code>next()</code> call per source.</p>\n<p>If a source fails, the returned iterable rejects with its error. <code>merge()</code>\ncalls <code>return()</code> on the other sources but does not wait for it to settle: an\nasync generator source that is suspended in an <code>await</code> only runs its cleanup\nonce that <code>await</code> completes.</p>\n<pre><code class=\"language-mjs\">import { from, merge, text } from 'node:stream/iter';\n\nconst merged = merge(from('hello '), from('world'));\nconsole.log(await text(merged)); // Order depends on timing\n</code></pre>\n<pre><code class=\"language-cjs\">const { from, merge, text } = require('node:stream/iter');\n\nasync function run() {\n  const merged = merge(from('hello '), from('world'));\n  console.log(await text(merged)); // Order depends on timing\n}\n\nrun().catch(console.error);\n</code></pre>"
            },
            {
              "textRaw": "`tap(callback)`",
              "name": "tap",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`callback` {Function} `(chunks, options) => void` Called with each batch and with `null` when the source ends. `options.signal` is the pipeline's {AbortSignal}.",
                      "name": "callback",
                      "type": "Function",
                      "desc": "`(chunks, options) => void` Called with each batch and with `null` when the source ends. `options.signal` is the pipeline's {AbortSignal}."
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Function} A stateless transform.",
                    "name": "return",
                    "type": "Function",
                    "desc": "A stateless transform."
                  }
                }
              ],
              "desc": "<p>Create a pass-through transform that observes batches without modifying them.\nUseful for logging, metrics, or debugging.</p>\n<pre><code class=\"language-mjs\">import { from, pull, text, tap } from 'node:stream/iter';\n\nconst result = pull(\n  from('hello'),\n  tap((chunks) => {\n    if (chunks !== null) console.log('Batch size:', chunks.length);\n  }),\n);\nconsole.log(await text(result));\n</code></pre>\n<pre><code class=\"language-cjs\">const { from, pull, text, tap } = require('node:stream/iter');\n\nasync function run() {\n  const result = pull(\n    from('hello'),\n    tap((chunks) => {\n      if (chunks !== null) console.log('Batch size:', chunks.length);\n    }),\n  );\n  console.log(await text(result));\n}\n\nrun().catch(console.error);\n</code></pre>\n<p><code>tap()</code> intentionally does not prevent in-place modification of the\nchunks by the tapping callback; but return values are ignored.</p>"
            },
            {
              "textRaw": "`tapSync(callback)`",
              "name": "tapSync",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`callback` {Function}",
                      "name": "callback",
                      "type": "Function"
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Function}",
                    "name": "return",
                    "type": "Function"
                  }
                }
              ],
              "desc": "<p>Synchronous version of <a href=\"#tapcallback\"><code>tap()</code></a>.</p>"
            }
          ],
          "displayName": "Utilities"
        },
        {
          "textRaw": "Multi-consumer",
          "name": "multi-consumer",
          "type": "module",
          "methods": [
            {
              "textRaw": "`broadcast([options])`",
              "name": "broadcast",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`budget` {number} Buffer size in bytes. Must be a positive integer. **Default:** `65536`.",
                          "name": "budget",
                          "type": "number",
                          "default": "`65536`",
                          "desc": "Buffer size in bytes. Must be a positive integer."
                        },
                        {
                          "textRaw": "`backpressure` {string} `'strict'`, `'unbounded'`, `'drop-oldest'`, or `'drop-newest'`. **Default:** `'strict'`.",
                          "name": "backpressure",
                          "type": "string",
                          "default": "`'strict'`",
                          "desc": "`'strict'`, `'unbounded'`, `'drop-oldest'`, or `'drop-newest'`."
                        },
                        {
                          "textRaw": "`signal` {AbortSignal}",
                          "name": "signal",
                          "type": "AbortSignal"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Object}",
                    "name": "return",
                    "type": "Object",
                    "options": [
                      {
                        "textRaw": "`writer` {Writable}",
                        "name": "writer",
                        "type": "Writable"
                      },
                      {
                        "textRaw": "`broadcast` {BroadcastChannel}",
                        "name": "broadcast",
                        "type": "BroadcastChannel"
                      }
                    ]
                  }
                }
              ],
              "desc": "<p>Create a push-model multi-consumer broadcast channel. A single writer pushes\ndata to multiple consumers. Each consumer has an independent cursor into a\nshared buffer.</p>\n<pre><code class=\"language-mjs\">import { broadcast, text } from 'node:stream/iter';\n\nconst { writer, broadcast: bc } = broadcast();\n\n// Create consumers before writing\nconst c1 = bc.push();  // Consumer 1\nconst c2 = bc.push();  // Consumer 2\n\n// Producer and consumers must run concurrently. Awaited writes\n// block when the buffer fills until consumers read.\nconst producing = (async () => {\n  await writer.write('hello');\n  await writer.end();\n})();\n\nconst [r1, r2] = await Promise.all([text(c1), text(c2)]);\nconsole.log(r1); // 'hello'\nconsole.log(r2); // 'hello'\nawait producing;\n</code></pre>\n<pre><code class=\"language-cjs\">const { broadcast, text } = require('node:stream/iter');\n\nasync function run() {\n  const { writer, broadcast: bc } = broadcast();\n\n  // Create consumers before writing\n  const c1 = bc.push();  // Consumer 1\n  const c2 = bc.push();  // Consumer 2\n\n  // Producer and consumers must run concurrently. Awaited writes\n  // block when the buffer fills until consumers read.\n  const producing = (async () => {\n    await writer.write('hello');\n    await writer.end();\n  })();\n\n  const [r1, r2] = await Promise.all([text(c1), text(c2)]);\n  console.log(r1); // 'hello'\n  console.log(r2); // 'hello'\n  await producing;\n}\n\nrun().catch(console.error);\n</code></pre>",
              "methods": [
                {
                  "textRaw": "`broadcast.cancel([reason])`",
                  "name": "cancel",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`reason` {any}",
                          "name": "reason",
                          "type": "any",
                          "optional": true
                        }
                      ]
                    }
                  ],
                  "desc": "<p>Cancel the broadcast. If <code>reason</code> is provided, all consumers reject with that\nexact reason. If it is omitted, consumers complete normally.</p>\n<p>Cancelling also closes the paired writer: afterwards its <code>canWrite</code> is <code>null</code>\nand <code>write()</code> rejects with a <code>TypeError</code>. This lets a <a href=\"#broadcastfrominput-options\"><code>Broadcast.from()</code></a>\npump stop pulling from its source.</p>"
                },
                {
                  "textRaw": "`broadcast.push([...transforms][, options])`",
                  "name": "push",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`...transforms` {Function | Object}",
                          "name": "...transforms",
                          "type": "Function | Object",
                          "optional": true
                        },
                        {
                          "textRaw": "`options` {Object}",
                          "name": "options",
                          "type": "Object",
                          "options": [
                            {
                              "textRaw": "`signal` {AbortSignal}",
                              "name": "signal",
                              "type": "AbortSignal"
                            }
                          ],
                          "optional": true
                        }
                      ],
                      "return": {
                        "textRaw": "Returns: {AsyncIterable} whose chunks fulfill with {Uint8Array[]}",
                        "name": "return",
                        "type": "AsyncIterable",
                        "desc": "whose chunks fulfill with {Uint8Array[]}"
                      }
                    }
                  ],
                  "desc": "<p>Create a new consumer. Optional transforms are applied to this consumer's view\nof the data.</p>"
                },
                {
                  "textRaw": "`broadcast[Symbol.dispose]()`",
                  "name": "[Symbol.dispose]",
                  "type": "method",
                  "signatures": [
                    {
                      "params": []
                    }
                  ],
                  "desc": "<p>Alias for <code>broadcast.cancel()</code>.</p>"
                }
              ],
              "properties": [
                {
                  "textRaw": "{number}",
                  "name": "consumerCount",
                  "type": "number",
                  "desc": "<p>The number of active consumers.</p>"
                }
              ]
            },
            {
              "textRaw": "`Broadcast.from(input[, options])`",
              "name": "from",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`input` {AsyncIterable | Iterable | BroadcastChannel}",
                      "name": "input",
                      "type": "AsyncIterable | Iterable | BroadcastChannel"
                    },
                    {
                      "textRaw": "`options` {Object} Same as `broadcast()`.",
                      "name": "options",
                      "type": "Object",
                      "desc": "Same as `broadcast()`.",
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {BroadcastChannel | Object} A `broadcastProtocol` input returns its {BroadcastChannel} directly. Other inputs return `{ writer, broadcast }`.",
                    "name": "return",
                    "type": "BroadcastChannel | Object",
                    "desc": "A `broadcastProtocol` input returns its {BroadcastChannel} directly. Other inputs return `{ writer, broadcast }`."
                  }
                }
              ],
              "desc": "<p>Create a <code class=\"type\"><a href=\"worker_threads.html#class-broadcastchannel-extends-eventtarget\" class=\"type-link\">BroadcastChannel</a></code> from an existing source. The source is consumed\nautomatically and pushed to all subscribers.</p>"
            },
            {
              "textRaw": "`share(source[, options])`",
              "name": "share",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {AsyncIterable} The source to share.",
                      "name": "source",
                      "type": "AsyncIterable",
                      "desc": "The source to share."
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`budget` {number} Buffer size in bytes. Must be a positive integer. **Default:** `65536`.",
                          "name": "budget",
                          "type": "number",
                          "default": "`65536`",
                          "desc": "Buffer size in bytes. Must be a positive integer."
                        },
                        {
                          "textRaw": "`backpressure` {string} `'strict'`, `'unbounded'`, `'drop-oldest'`, or `'drop-newest'`. **Default:** `'strict'`.",
                          "name": "backpressure",
                          "type": "string",
                          "default": "`'strict'`",
                          "desc": "`'strict'`, `'unbounded'`, `'drop-oldest'`, or `'drop-newest'`."
                        },
                        {
                          "textRaw": "`signal` {AbortSignal}",
                          "name": "signal",
                          "type": "AbortSignal"
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Share}",
                    "name": "return",
                    "type": "Share"
                  }
                }
              ],
              "desc": "<p>Create a pull-model multi-consumer shared stream. Unlike <code>broadcast()</code>, the\nsource is only read when a consumer pulls. Multiple consumers share a single\nbuffer.</p>\n<p>A consumer created with <code>share.pull()</code> starts reading at the oldest entry still\nin the buffer. Entries are released once every consumer has read them. When\nevery consumer has detached, the buffered data is kept for consumers that\nattach later, and the source is not closed. Call <code>share.cancel()</code> (or dispose\nthe share) to release the source once it is no longer needed.</p>\n<p>With <code>'strict'</code> backpressure, a consumer that needs to pull from the source\nwhile the buffer is at or above <code>budget</code> is rejected with <code>ERR_OUT_OF_RANGE</code>\nand detached; further reads from that consumer complete with <code>{ done: true }</code>.\nDetaching keeps a consumer that is not retried (for example, one read with\n<code>for await...of</code>, which does not call <code>return()</code> when a read rejects) from\nholding buffered data and blocking the other consumers.</p>\n<p>With <code>'unbounded'</code>, such a consumer waits until the slowest consumer releases\nbudget. With <code>'drop-newest'</code>, the entry pulled from the source is discarded\nand the consumer then waits in the same way, so in both cases a stalled\nconsumer also stalls the consumers that are ahead of it. Only <code>'drop-oldest'</code>\nlets consumers that are ahead continue, by discarding the oldest buffered\nentries that the slowest consumer has not read yet. A batch pulled from the\nsource that is larger than <code>budget</code> is split into smaller entries first, so\neviction keeps the newest chunks that fit within the budget.</p>\n<pre><code class=\"language-mjs\">import { from, share, text } from 'node:stream/iter';\n\nconst shared = share(from('hello'));\n\nconst c1 = shared.pull();\nconst c2 = shared.pull();\n\n// Consume concurrently to avoid deadlock with small buffers.\nconst [r1, r2] = await Promise.all([text(c1), text(c2)]);\nconsole.log(r1); // 'hello'\nconsole.log(r2); // 'hello'\n</code></pre>\n<pre><code class=\"language-cjs\">const { from, share, text } = require('node:stream/iter');\n\nasync function run() {\n  const shared = share(from('hello'));\n\n  const c1 = shared.pull();\n  const c2 = shared.pull();\n\n  // Consume concurrently to avoid deadlock with small buffers.\n  const [r1, r2] = await Promise.all([text(c1), text(c2)]);\n  console.log(r1); // 'hello'\n  console.log(r2); // 'hello'\n}\n\nrun().catch(console.error);\n</code></pre>"
            },
            {
              "textRaw": "`shareSync(source[, options])`",
              "name": "shareSync",
              "type": "method",
              "meta": {
                "added": [
                  "v25.9.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {Iterable} The sync source to share.",
                      "name": "source",
                      "type": "Iterable",
                      "desc": "The sync source to share."
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`budget` {number} Must be a positive integer. **Default:** `65536`.",
                          "name": "budget",
                          "type": "number",
                          "default": "`65536`",
                          "desc": "Must be a positive integer."
                        },
                        {
                          "textRaw": "`backpressure` {string} `'strict'` or `'drop-oldest'`. **Default:** `'strict'`.",
                          "name": "backpressure",
                          "type": "string",
                          "default": "`'strict'`",
                          "desc": "`'strict'` or `'drop-oldest'`."
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {SyncShare}",
                    "name": "return",
                    "type": "SyncShare"
                  }
                }
              ],
              "desc": "<p>Synchronous version of <a href=\"#sharesource-options\"><code>share()</code></a>.</p>\n<p>A synchronous consumer cannot wait for the slowest consumer to release budget,\nand the slowest consumer cannot advance while another consumer's read is\nrunning. <code>'unbounded'</code> and <code>'drop-newest'</code> are therefore not supported and\nthrow <code>ERR_INVALID_ARG_VALUE</code>.</p>"
            }
          ],
          "classes": [
            {
              "textRaw": "Class: `Share`",
              "name": "Share",
              "type": "class",
              "classMethods": [
                {
                  "textRaw": "Static method: `Share.from(input[, options])`",
                  "name": "from",
                  "type": "classMethod",
                  "meta": {
                    "added": [
                      "v25.9.0"
                    ],
                    "changes": []
                  },
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`input` {AsyncIterable | Shareable}",
                          "name": "input",
                          "type": "AsyncIterable | Shareable"
                        },
                        {
                          "textRaw": "`options` {Object} Same as `share()`.",
                          "name": "options",
                          "type": "Object",
                          "desc": "Same as `share()`.",
                          "optional": true
                        }
                      ],
                      "return": {
                        "textRaw": "Returns: {Share}",
                        "name": "return",
                        "type": "Share"
                      }
                    }
                  ],
                  "desc": "<p>Create a <code class=\"type\"><a href=\"stream_iter.html#class-share\" class=\"type-link\">Share</a></code> from an existing source.</p>"
                }
              ],
              "methods": [
                {
                  "textRaw": "`share.cancel([reason])`",
                  "name": "cancel",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`reason` {any}",
                          "name": "reason",
                          "type": "any",
                          "optional": true
                        }
                      ]
                    }
                  ],
                  "desc": "<p>Cancel the share. If <code>reason</code> is provided, all consumers reject with that exact\nreason. If it is omitted, consumers complete normally.</p>"
                },
                {
                  "textRaw": "`share.pull([...transforms][, options])`",
                  "name": "pull",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`...transforms` {Function | Object}",
                          "name": "...transforms",
                          "type": "Function | Object",
                          "optional": true
                        },
                        {
                          "textRaw": "`options` {Object}",
                          "name": "options",
                          "type": "Object",
                          "options": [
                            {
                              "textRaw": "`signal` {AbortSignal}",
                              "name": "signal",
                              "type": "AbortSignal"
                            }
                          ],
                          "optional": true
                        }
                      ],
                      "return": {
                        "textRaw": "Returns: {AsyncIterable} whose chunks fulfill with {Uint8Array[]}",
                        "name": "return",
                        "type": "AsyncIterable",
                        "desc": "whose chunks fulfill with {Uint8Array[]}"
                      }
                    }
                  ],
                  "desc": "<p>Create a new consumer of the shared source.</p>"
                },
                {
                  "textRaw": "`share[Symbol.dispose]()`",
                  "name": "[Symbol.dispose]",
                  "type": "method",
                  "signatures": [
                    {
                      "params": []
                    }
                  ],
                  "desc": "<p>Alias for <code>share.cancel()</code>.</p>"
                }
              ],
              "properties": [
                {
                  "textRaw": "{number}",
                  "name": "consumerCount",
                  "type": "number",
                  "desc": "<p>The number of active consumers.</p>"
                }
              ]
            },
            {
              "textRaw": "Class: `SyncShare`",
              "name": "SyncShare",
              "type": "class",
              "classMethods": [
                {
                  "textRaw": "Static method: `SyncShare.fromSync(input[, options])`",
                  "name": "fromSync",
                  "type": "classMethod",
                  "meta": {
                    "added": [
                      "v25.9.0",
                      "v24.20.0"
                    ],
                    "changes": []
                  },
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`input` {Iterable | SyncShareable}",
                          "name": "input",
                          "type": "Iterable | SyncShareable"
                        },
                        {
                          "textRaw": "`options` {Object}",
                          "name": "options",
                          "type": "Object",
                          "optional": true
                        }
                      ],
                      "return": {
                        "textRaw": "Returns: {SyncShare}",
                        "name": "return",
                        "type": "SyncShare"
                      }
                    }
                  ]
                }
              ],
              "methods": [
                {
                  "textRaw": "`share.cancel([reason])`",
                  "name": "cancel",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`reason` {any}",
                          "name": "reason",
                          "type": "any",
                          "optional": true
                        }
                      ]
                    }
                  ],
                  "desc": "<p>Cancel the share. If <code>reason</code> is provided, all consumers throw that exact\nreason. If it is omitted, consumers complete normally.</p>"
                },
                {
                  "textRaw": "`share.pull([...transforms])`",
                  "name": "pull",
                  "type": "method",
                  "signatures": [
                    {
                      "params": [
                        {
                          "textRaw": "`...transforms` {Function | Object}",
                          "name": "...transforms",
                          "type": "Function | Object",
                          "optional": true
                        }
                      ],
                      "return": {
                        "textRaw": "Returns: {Iterable} whose chunks return {Uint8Array[]}",
                        "name": "return",
                        "type": "Iterable",
                        "desc": "whose chunks return {Uint8Array[]}"
                      }
                    }
                  ],
                  "desc": "<p>Create a new consumer of the shared source.</p>"
                },
                {
                  "textRaw": "`share[Symbol.dispose]()`",
                  "name": "[Symbol.dispose]",
                  "type": "method",
                  "signatures": [
                    {
                      "params": []
                    }
                  ],
                  "desc": "<p>Alias for <code>share.cancel()</code>.</p>"
                }
              ],
              "properties": [
                {
                  "textRaw": "{number}",
                  "name": "consumerCount",
                  "type": "number",
                  "desc": "<p>The number of active consumers.</p>"
                }
              ]
            }
          ],
          "modules": [
            {
              "textRaw": "Interface: `Shareable`",
              "name": "interface:_`shareable`",
              "type": "module",
              "properties": [
                {
                  "textRaw": "{Function} that returns a {Share}.",
                  "name": "[Symbol.for('Stream.shareProtocol')]",
                  "type": "Function",
                  "desc": "that returns a {Share}."
                }
              ],
              "displayName": "Interface: `Shareable`"
            },
            {
              "textRaw": "Interface: `SyncShareable`",
              "name": "interface:_`syncshareable`",
              "type": "module",
              "properties": [
                {
                  "textRaw": "{Function} that returns a {SyncShare}.",
                  "name": "[Symbol.for('Stream.shareSyncProtocol')]",
                  "type": "Function",
                  "desc": "that returns a {SyncShare}."
                }
              ],
              "displayName": "Interface: `SyncShareable`"
            }
          ],
          "displayName": "Multi-consumer"
        },
        {
          "textRaw": "Compression and decompression transforms",
          "name": "compression_and_decompression_transforms",
          "type": "module",
          "desc": "<p>Compression and decompression transforms for use with <code>pull()</code>, <code>pullSync()</code>,\n<code>pipeTo()</code>, and <code>pipeToSync()</code> are available via the <a href=\"zlib.html#iterable-compression\"><code>node:zlib/iter</code></a>\nmodule. See the <a href=\"zlib.html#iterable-compression\"><code>node:zlib/iter</code> documentation</a> for details.</p>",
          "displayName": "Compression and decompression transforms"
        },
        {
          "textRaw": "Classic stream interop",
          "name": "classic_stream_interop",
          "type": "module",
          "desc": "<p>These utility functions bridge between classic\n<a href=\"stream.html#class-streamreadable\"><code>stream.Readable</code></a>/<a href=\"stream.html#class-streamwritable\"><code>stream.Writable</code></a> streams and the <code>stream/iter</code>\nAPI.</p>\n<p>Both <code>fromReadable()</code> and <code>fromWritable()</code> accept duck-typed objects -- they\ndo not require the input to extend <code>stream.Readable</code> or <code>stream.Writable</code>\ndirectly. The minimum contract is described below for each function.</p>",
          "methods": [
            {
              "textRaw": "`fromReadable(readable)`",
              "name": "fromReadable",
              "type": "method",
              "meta": {
                "added": [
                  "v26.1.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "stability": 1,
              "stabilityText": "Experimental",
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`readable` {stream.Readable | Object} A classic Readable stream or a compatible object with `read()`, `pipe()`, `destroy()`, `on()`, and `removeListener()` methods.",
                      "name": "readable",
                      "type": "stream.Readable | Object",
                      "desc": "A classic Readable stream or a compatible object with `read()`, `pipe()`, `destroy()`, `on()`, and `removeListener()` methods."
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {AsyncIterable} whose chunks fulfill with {Uint8Array[]}",
                    "name": "return",
                    "type": "AsyncIterable",
                    "desc": "whose chunks fulfill with {Uint8Array[]}"
                  }
                }
              ],
              "desc": "<p>Converts a classic Readable stream (or duck-typed equivalent) into a\nstream/iter async iterable source that can be passed to <a href=\"#frominput\"><code>from()</code></a>,\n<a href=\"#pullsource-transforms-options\"><code>pull()</code></a>, <a href=\"#textsource-options\"><code>text()</code></a>, etc.</p>\n<p>If the object implements the <a href=\"#streamtoasyncstreamable\"><code>toAsyncStreamable</code></a> protocol (as\n<code>stream.Readable</code> does), that protocol is used. Otherwise, the function\nduck-types on <code>read()</code>, <code>pipe()</code>, <code>destroy()</code>, <code>on()</code>, and <code>removeListener()</code>\n(EventEmitter) and wraps the stream with a batched async iterator.</p>\n<p>The result is cached per instance -- calling <code>fromReadable()</code> twice with the\nsame stream returns the same iterable.</p>\n<p>For object-mode or encoded Readable streams, chunks are automatically\nnormalized to <code>Uint8Array</code>.</p>\n<pre><code class=\"language-mjs\">import { Readable } from 'node:stream';\nimport { fromReadable, text } from 'node:stream/iter';\n\nconst readable = new Readable({\n  read() { this.push('hello world'); this.push(null); },\n});\n\nconst result = await text(fromReadable(readable));\nconsole.log(result); // 'hello world'\n</code></pre>\n<pre><code class=\"language-cjs\">const { Readable } = require('node:stream');\nconst { fromReadable, text } = require('node:stream/iter');\n\nconst readable = new Readable({\n  read() { this.push('hello world'); this.push(null); },\n});\n\nasync function run() {\n  const result = await text(fromReadable(readable));\n  console.log(result); // 'hello world'\n}\nrun();\n</code></pre>"
            },
            {
              "textRaw": "`fromWritable(writable[, options])`",
              "name": "fromWritable",
              "type": "method",
              "meta": {
                "added": [
                  "v26.1.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "stability": 1,
              "stabilityText": "Experimental",
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`writable` {stream.Writable | Object} A classic Writable stream or a compatible object with `write()`, `end()`, `destroy()`, `on()`, and `removeListener()` methods.",
                      "name": "writable",
                      "type": "stream.Writable | Object",
                      "desc": "A classic Writable stream or a compatible object with `write()`, `end()`, `destroy()`, `on()`, and `removeListener()` methods."
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`backpressure` {string} Backpressure policy. **Default:** `'strict'`.",
                          "name": "backpressure",
                          "type": "string",
                          "default": "`'strict'`",
                          "desc": "Backpressure policy.",
                          "options": [
                            {
                              "textRaw": "`'strict'` -- one write may wait while the buffer is full. Further writes are rejected until it is accepted or canceled.",
                              "desc": "`'strict'` -- one write may wait while the buffer is full. Further writes are rejected until it is accepted or canceled."
                            },
                            {
                              "textRaw": "`'unbounded'` -- writes are queued while the buffer is full. Recommended for use with `pipeTo()`.",
                              "desc": "`'unbounded'` -- writes are queued while the buffer is full. Recommended for use with `pipeTo()`."
                            },
                            {
                              "textRaw": "`'drop-newest'` -- writes are silently discarded when the buffer is full.",
                              "desc": "`'drop-newest'` -- writes are silently discarded when the buffer is full."
                            },
                            {
                              "textRaw": "`'drop-oldest'` -- **not supported**. Throws `ERR_INVALID_ARG_VALUE`.",
                              "desc": "`'drop-oldest'` -- **not supported**. Throws `ERR_INVALID_ARG_VALUE`."
                            }
                          ]
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Object} A stream/iter Writer adapter.",
                    "name": "return",
                    "type": "Object",
                    "desc": "A stream/iter Writer adapter."
                  }
                }
              ],
              "desc": "<p>Creates a stream/iter Writer adapter from a classic Writable stream (or\nduck-typed equivalent). The adapter can be passed to <a href=\"#pipetosource-transforms-writer-options\"><code>pipeTo()</code></a> as a\ndestination.</p>\n<p>Since all writes on a classic Writable are fundamentally asynchronous,\nthe synchronous Writer methods (<code>writeSync</code>, <code>writevSync</code>, <code>endSync</code>) always\nreturn <code>false</code> or <code>-1</code>, deferring to the async path. A queued <code>write()</code> or\n<code>writev()</code> can be canceled with its <code>options.signal</code> before it reaches the\nclassic Writable.</p>\n<p>If <code>writer.fail(reason)</code> receives a non-Error reason, the classic Writable is\ndestroyed with an <code>ERR_FALSY_VALUE_REJECTION</code> or <code>ERR_OPERATION_FAILED</code> error.\nIts <code>reason</code> property contains the original value, which remains the Writer's\nstored failure reason.</p>\n<p>The result is cached per instance and backpressure policy -- calling\n<code>fromWritable()</code> twice with the same stream and <code>backpressure</code> option returns\nthe same Writer.</p>\n<p>For duck-typed streams that do not expose <code>writableHighWaterMark</code>,\n<code>writableLength</code>, or similar properties, sensible defaults are used.\nObject-mode writables (if detectable) are rejected since the Writer\ninterface is bytes-only.</p>\n<pre><code class=\"language-mjs\">import { Writable } from 'node:stream';\nimport { from, fromWritable, pipeTo } from 'node:stream/iter';\n\nconst writable = new Writable({\n  write(chunk, encoding, cb) { console.log(chunk.toString()); cb(); },\n});\n\nawait pipeTo(from('hello world'),\n             fromWritable(writable, { backpressure: 'unbounded' }));\n</code></pre>\n<pre><code class=\"language-cjs\">const { Writable } = require('node:stream');\nconst { from, fromWritable, pipeTo } = require('node:stream/iter');\n\nasync function run() {\n  const writable = new Writable({\n    write(chunk, encoding, cb) { console.log(chunk.toString()); cb(); },\n  });\n\n  await pipeTo(from('hello world'),\n               fromWritable(writable, { backpressure: 'unbounded' }));\n}\nrun();\n</code></pre>"
            },
            {
              "textRaw": "`toReadable(source[, options])`",
              "name": "toReadable",
              "type": "method",
              "meta": {
                "added": [
                  "v26.1.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "stability": 1,
              "stabilityText": "Experimental",
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {AsyncIterable} whose chunks must fulfill with {Uint8Array[]} the return value of `pull()` or `from()`.",
                      "name": "source",
                      "type": "AsyncIterable",
                      "desc": "whose chunks must fulfill with {Uint8Array[]} the return value of `pull()` or `from()`."
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`highWaterMark` {number} The internal buffer size in bytes before backpressure is applied. **Default:** `65536` (64 KB).",
                          "name": "highWaterMark",
                          "type": "number",
                          "default": "`65536` (64 KB)",
                          "desc": "The internal buffer size in bytes before backpressure is applied."
                        },
                        {
                          "textRaw": "`signal` {AbortSignal} An optional signal to abort the readable.",
                          "name": "signal",
                          "type": "AbortSignal",
                          "desc": "An optional signal to abort the readable."
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {stream.Readable}",
                    "name": "return",
                    "type": "stream.Readable"
                  }
                }
              ],
              "desc": "<p>Creates a byte-mode <a href=\"stream.html#class-streamreadable\"><code>stream.Readable</code></a> from the <code>source</code>\n(the native batch format used by the stream/iter API). Each <code>Uint8Array</code> in a\nyielded batch is pushed as a separate chunk into the Readable.</p>\n<p>Classic streams cannot represent arbitrary values as emitted errors. A\nnon-Error reason is wrapped in an <code>ERR_FALSY_VALUE_REJECTION</code> or\n<code>ERR_OPERATION_FAILED</code> error whose <code>reason</code> property contains the original\nvalue.</p>\n<pre><code class=\"language-mjs\">import { createWriteStream } from 'node:fs';\nimport { from, pull, toReadable } from 'node:stream/iter';\nimport { compressGzip } from 'node:zlib/iter';\n\nconst source = pull(from('hello world'), compressGzip());\nconst readable = toReadable(source);\n\nreadable.pipe(createWriteStream('output.gz'));\n</code></pre>\n<pre><code class=\"language-cjs\">const { createWriteStream } = require('node:fs');\nconst { from, pull, toReadable } = require('node:stream/iter');\nconst { compressGzip } = require('node:zlib/iter');\n\nconst source = pull(from('hello world'), compressGzip());\nconst readable = toReadable(source);\n\nreadable.pipe(createWriteStream('output.gz'));\n</code></pre>"
            },
            {
              "textRaw": "`toReadableSync(source[, options])`",
              "name": "toReadableSync",
              "type": "method",
              "meta": {
                "added": [
                  "v26.1.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "stability": 1,
              "stabilityText": "Experimental",
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`source` {Iterable} whose chunks must return {Uint8Array[]}, such as the return value of `pullSync()` or `fromSync()`.",
                      "name": "source",
                      "type": "Iterable",
                      "desc": "whose chunks must return {Uint8Array[]}, such as the return value of `pullSync()` or `fromSync()`."
                    },
                    {
                      "textRaw": "`options` {Object}",
                      "name": "options",
                      "type": "Object",
                      "options": [
                        {
                          "textRaw": "`highWaterMark` {number} The internal buffer size in bytes before backpressure is applied. **Default:** `65536` (64 KB).",
                          "name": "highWaterMark",
                          "type": "number",
                          "default": "`65536` (64 KB)",
                          "desc": "The internal buffer size in bytes before backpressure is applied."
                        }
                      ],
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {stream.Readable}",
                    "name": "return",
                    "type": "stream.Readable"
                  }
                }
              ],
              "desc": "<p>Creates a byte-mode <a href=\"stream.html#class-streamreadable\"><code>stream.Readable</code></a> from the <code>source</code>.\nThe <code>_read()</code> method pulls from the iterator\nsynchronously, so data is available immediately via <code>readable.read()</code>.</p>\n<pre><code class=\"language-mjs\">import { fromSync, toReadableSync } from 'node:stream/iter';\n\nconst source = fromSync('hello world');\nconst readable = toReadableSync(source);\n\nconsole.log(readable.read().toString()); // 'hello world'\n</code></pre>\n<pre><code class=\"language-cjs\">const { fromSync, toReadableSync } = require('node:stream/iter');\n\nconst source = fromSync('hello world');\nconst readable = toReadableSync(source);\n\nconsole.log(readable.read().toString()); // 'hello world'\n</code></pre>"
            },
            {
              "textRaw": "`toWritable(writer)`",
              "name": "toWritable",
              "type": "method",
              "meta": {
                "added": [
                  "v26.1.0",
                  "v24.20.0"
                ],
                "changes": []
              },
              "stability": 1,
              "stabilityText": "Experimental",
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`writer` {Object} A stream/iter Writer. Only the `write()` method is required; `end()`, `fail()`, `writeSync()`, `writevSync()`, `endSync()`, and `writev()` are optional.",
                      "name": "writer",
                      "type": "Object",
                      "desc": "A stream/iter Writer. Only the `write()` method is required; `end()`, `fail()`, `writeSync()`, `writevSync()`, `endSync()`, and `writev()` are optional."
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {stream.Writable}",
                    "name": "return",
                    "type": "stream.Writable"
                  }
                }
              ],
              "desc": "<p>Creates a classic <a href=\"stream.html#class-streamwritable\"><code>stream.Writable</code></a> backed by a stream/iter Writer.</p>\n<p>Each <code>_write()</code> / <code>_writev()</code> call attempts the Writer's synchronous method\nfirst (<code>writeSync</code> / <code>writevSync</code>), falling back to the async method if the\nsync path returns <code>false</code>. Similarly, <code>_final()</code> tries <code>endSync()</code>\nbefore <code>end()</code>. When the sync path succeeds, the callback is deferred via\n<code>queueMicrotask</code> to preserve the async resolution contract.</p>\n<p>Classic stream callbacks cannot represent arbitrary values as errors. A\nnon-Error reason is wrapped in an <code>ERR_FALSY_VALUE_REJECTION</code> or\n<code>ERR_OPERATION_FAILED</code> error before it is passed to the callback. The error's\n<code>reason</code> property contains the original value.</p>\n<p>Destroying the Writable before successful completion calls <code>writer.fail()</code>.\nIf <code>fail()</code> is unavailable, <code>Symbol.dispose</code> or <code>Symbol.asyncDispose</code> is used\nwhen implemented by the Writer.</p>\n<p>The Writable uses the default classic stream <code>highWaterMark</code>. Classic stream\nbackpressure bounds writes waiting to reach the underlying Writer, while the\nWriter controls completion of the active <code>_write()</code> or <code>_writev()</code> operation.</p>\n<pre><code class=\"language-mjs\">import { push, toWritable } from 'node:stream/iter';\n\nconst { writer, readable } = push();\nconst writable = toWritable(writer);\n\nwritable.write('hello');\nwritable.end();\n</code></pre>\n<pre><code class=\"language-cjs\">const { push, toWritable } = require('node:stream/iter');\n\nconst { writer, readable } = push();\nconst writable = toWritable(writer);\n\nwritable.write('hello');\nwritable.end();\n</code></pre>"
            }
          ],
          "displayName": "Classic stream interop"
        },
        {
          "textRaw": "Protocol symbols",
          "name": "protocol_symbols",
          "type": "module",
          "desc": "<p>These well-known symbols allow third-party objects to participate in the\nstreaming protocol without importing from <code>node:stream/iter</code> directly.</p>",
          "properties": [
            {
              "textRaw": "`Stream.broadcastProtocol`",
              "name": "broadcastProtocol",
              "type": "property",
              "desc": "<ul>\n<li>Value: <code>Symbol.for('Stream.broadcastProtocol')</code></li>\n</ul>\n<p>The value must be a function. When called by <code>Broadcast.from()</code>, it receives\nthe options passed to <code>Broadcast.from()</code> and must return an object conforming\nto the <code class=\"type\"><a href=\"worker_threads.html#class-broadcastchannel-extends-eventtarget\" class=\"type-link\">BroadcastChannel</a></code> interface. The implementation is fully custom -- it can\nmanage consumers, buffering, and backpressure however it wants.</p>\n<pre><code class=\"language-mjs\">import {\n  broadcast as createBroadcast,\n  Broadcast,\n  text,\n} from 'node:stream/iter';\n\n// This example defers to the built-in Broadcast, but a custom\n// implementation could use any mechanism.\nclass MessageBus {\n  #broadcast;\n  #writer;\n\n  constructor() {\n    const { writer, broadcast } = createBroadcast();\n    this.#writer = writer;\n    this.#broadcast = broadcast;\n  }\n\n  [Symbol.for('Stream.broadcastProtocol')](options) {\n    return this.#broadcast;\n  }\n\n  send(data) {\n    this.#writer.write(new TextEncoder().encode(data));\n  }\n\n  close() {\n    this.#writer.end();\n  }\n}\n\nconst bus = new MessageBus();\nconst broadcast = Broadcast.from(bus);\nconst consumer = broadcast.push();\nbus.send('hello');\nbus.close();\nconsole.log(await text(consumer)); // 'hello'\n</code></pre>\n<pre><code class=\"language-cjs\">const {\n  broadcast: createBroadcast,\n  Broadcast,\n  text,\n} = require('node:stream/iter');\n\n// This example defers to the built-in Broadcast, but a custom\n// implementation could use any mechanism.\nclass MessageBus {\n  #broadcast;\n  #writer;\n\n  constructor() {\n    const { writer, broadcast } = createBroadcast();\n    this.#writer = writer;\n    this.#broadcast = broadcast;\n  }\n\n  [Symbol.for('Stream.broadcastProtocol')](options) {\n    return this.#broadcast;\n  }\n\n  send(data) {\n    this.#writer.write(new TextEncoder().encode(data));\n  }\n\n  close() {\n    this.#writer.end();\n  }\n}\n\nconst bus = new MessageBus();\nconst broadcast = Broadcast.from(bus);\nconst consumer = broadcast.push();\nbus.send('hello');\nbus.close();\ntext(consumer).then(console.log); // 'hello'\n</code></pre>"
            },
            {
              "textRaw": "`Stream.drainableProtocol`",
              "name": "drainableProtocol",
              "type": "property",
              "desc": "<ul>\n<li>Value: <code>Symbol.for('Stream.drainableProtocol')</code></li>\n</ul>\n<p>Implement to make a writer compatible with <code>ondrain()</code>. The method should\nreturn <code>null</code> if no backpressure, or a promise that fulfills with a truthy value\nwhen backpressure clears.</p>\n<pre><code class=\"language-mjs\">import { ondrain } from 'node:stream/iter';\n\nclass CustomWriter {\n  #queue = [];\n  #drain = null;\n  #closed = false;\n  [Symbol.for('Stream.drainableProtocol')]() {\n    if (this.#closed) return null;\n    if (this.#queue.length &#x3C; 3) return Promise.resolve(true);\n    this.#drain ??= Promise.withResolvers();\n    return this.#drain.promise;\n  }\n  write(chunk) {\n    this.#queue.push(chunk);\n  }\n  flush() {\n    this.#queue.length = 0;\n    this.#drain?.resolve(true);\n    this.#drain = null;\n  }\n  close() {\n    this.#closed = true;\n  }\n}\nconst writer = new CustomWriter();\nconst ready = ondrain(writer);\nconsole.log(ready); // Promise { true } -- no backpressure\n</code></pre>\n<pre><code class=\"language-cjs\">const { ondrain } = require('node:stream/iter');\n\nclass CustomWriter {\n  #queue = [];\n  #drain = null;\n  #closed = false;\n\n  [Symbol.for('Stream.drainableProtocol')]() {\n    if (this.#closed) return null;\n    if (this.#queue.length &#x3C; 3) return Promise.resolve(true);\n    this.#drain ??= Promise.withResolvers();\n    return this.#drain.promise;\n  }\n\n  write(chunk) {\n    this.#queue.push(chunk);\n  }\n\n  flush() {\n    this.#queue.length = 0;\n    this.#drain?.resolve(true);\n    this.#drain = null;\n  }\n\n  close() {\n    this.#closed = true;\n  }\n}\n\nconst writer = new CustomWriter();\nconst ready = ondrain(writer);\nconsole.log(ready); // Promise { true } -- no backpressure\n</code></pre>"
            },
            {
              "textRaw": "`Stream.shareProtocol`",
              "name": "shareProtocol",
              "type": "property",
              "desc": "<ul>\n<li>Value: <code>Symbol.for('Stream.shareProtocol')</code></li>\n</ul>\n<p>The value must be a function. When called by <code>Share.from()</code>, it receives the\noptions passed to <code>Share.from()</code> and must return an object conforming to the\n<code class=\"type\"><a href=\"stream_iter.html#class-share\" class=\"type-link\">Share</a></code> interface. The implementation is fully custom -- it can manage the shared\nsource, consumers, buffering, and backpressure however it wants.</p>\n<pre><code class=\"language-mjs\">import { share, Share, text } from 'node:stream/iter';\n\n// This example defers to the built-in share(), but a custom\n// implementation could use any mechanism.\nclass DataPool {\n  #share;\n\n  constructor(source) {\n    this.#share = share(source);\n  }\n\n  [Symbol.for('Stream.shareProtocol')](options) {\n    return this.#share;\n  }\n}\n\nconst pool = new DataPool(\n  (async function* () {\n    yield 'hello';\n  })(),\n);\n\nconst shared = Share.from(pool);\nconst consumer = shared.pull();\nconsole.log(await text(consumer)); // 'hello'\n</code></pre>\n<pre><code class=\"language-cjs\">const { share, Share, text } = require('node:stream/iter');\n\n// This example defers to the built-in share(), but a custom\n// implementation could use any mechanism.\nclass DataPool {\n  #share;\n\n  constructor(source) {\n    this.#share = share(source);\n  }\n\n  [Symbol.for('Stream.shareProtocol')](options) {\n    return this.#share;\n  }\n}\n\nconst pool = new DataPool(\n  (async function* () {\n    yield 'hello';\n  })(),\n);\n\nconst shared = Share.from(pool);\nconst consumer = shared.pull();\ntext(consumer).then(console.log); // 'hello'\n</code></pre>"
            },
            {
              "textRaw": "`Stream.shareSyncProtocol`",
              "name": "shareSyncProtocol",
              "type": "property",
              "desc": "<ul>\n<li>Value: <code>Symbol.for('Stream.shareSyncProtocol')</code></li>\n</ul>\n<p>The value must be a function. When called by <code>SyncShare.fromSync()</code>, it receives\nthe options passed to <code>SyncShare.fromSync()</code> and must return an object conforming\nto the <code class=\"type\"><a href=\"stream_iter.html#class-syncshare\" class=\"type-link\">SyncShare</a></code> interface. The implementation is fully custom -- it can manage\nthe shared source, consumers, and buffering however it wants.</p>\n<pre><code class=\"language-mjs\">import { shareSync, SyncShare, textSync } from 'node:stream/iter';\n\n// This example defers to the built-in shareSync(), but a custom\n// implementation could use any mechanism.\nclass SyncDataPool {\n  #share;\n\n  constructor(source) {\n    this.#share = shareSync(source);\n  }\n\n  [Symbol.for('Stream.shareSyncProtocol')](options) {\n    return this.#share;\n  }\n}\n\nconst encoder = new TextEncoder();\nconst pool = new SyncDataPool(\n  function* () {\n    yield [encoder.encode('hello')];\n  }(),\n);\n\nconst shared = SyncShare.fromSync(pool);\nconst consumer = shared.pull();\nconsole.log(textSync(consumer)); // 'hello'\n</code></pre>\n<pre><code class=\"language-cjs\">const { shareSync, SyncShare, textSync } = require('node:stream/iter');\n\n// This example defers to the built-in shareSync(), but a custom\n// implementation could use any mechanism.\nclass SyncDataPool {\n  #share;\n\n  constructor(source) {\n    this.#share = shareSync(source);\n  }\n\n  [Symbol.for('Stream.shareSyncProtocol')](options) {\n    return this.#share;\n  }\n}\n\nconst encoder = new TextEncoder();\nconst pool = new SyncDataPool(\n  function* () {\n    yield [encoder.encode('hello')];\n  }(),\n);\n\nconst shared = SyncShare.fromSync(pool);\nconst consumer = shared.pull();\nconsole.log(textSync(consumer)); // 'hello'\n</code></pre>"
            },
            {
              "textRaw": "`Stream.toAsyncStreamable`",
              "name": "toAsyncStreamable",
              "type": "property",
              "desc": "<ul>\n<li>Value: <code>Symbol.for('Stream.toAsyncStreamable')</code></li>\n</ul>\n<p>The value must be a function that converts the object into a streamable value.\nWhen the object is passed to <code>from()</code>, this method is called to produce the\nactual data. It may return any value that resolves to a string, <code>Uint8Array</code>,\n<code>AsyncIterable</code>, <code>Iterable</code>, or another streamable object.</p>\n<pre><code class=\"language-mjs\">import { from, text } from 'node:stream/iter';\n\nclass Greeting {\n  #name;\n\n  constructor(name) {\n    this.#name = name;\n  }\n\n  [Symbol.for('Stream.toAsyncStreamable')]() {\n    return `hello ${this.#name}`;\n  }\n}\n\nconst stream = from(new Greeting('world'));\nconsole.log(await text(stream)); // 'hello world'\n</code></pre>\n<pre><code class=\"language-cjs\">const { from, text } = require('node:stream/iter');\n\nclass Greeting {\n  #name;\n\n  constructor(name) {\n    this.#name = name;\n  }\n\n  [Symbol.for('Stream.toAsyncStreamable')]() {\n    return `hello ${this.#name}`;\n  }\n}\n\nconst stream = from(new Greeting('world'));\ntext(stream).then(console.log); // 'hello world'\n</code></pre>"
            },
            {
              "textRaw": "`Stream.toStreamable`",
              "name": "toStreamable",
              "type": "property",
              "desc": "<ul>\n<li>Value: <code>Symbol.for('Stream.toStreamable')</code></li>\n</ul>\n<p>The value must be a function that synchronously converts the object into a\nstreamable value. When the object is passed to <code>fromSync()</code>, this method is\ncalled to produce the actual data. It must synchronously return a streamable\nvalue: a string, <code>Uint8Array</code>, or <code>Iterable</code>.</p>\n<pre><code class=\"language-mjs\">import { fromSync, textSync } from 'node:stream/iter';\n\nclass Greeting {\n  #name;\n\n  constructor(name) {\n    this.#name = name;\n  }\n\n  [Symbol.for('Stream.toStreamable')]() {\n    return `hello ${this.#name}`;\n  }\n}\n\nconst stream = fromSync(new Greeting('world'));\nconsole.log(textSync(stream)); // 'hello world'\n</code></pre>\n<pre><code class=\"language-cjs\">const { fromSync, textSync } = require('node:stream/iter');\n\nclass Greeting {\n  #name;\n\n  constructor(name) {\n    this.#name = name;\n  }\n\n  [Symbol.for('Stream.toStreamable')]() {\n    return `hello ${this.#name}`;\n  }\n}\n\nconst stream = fromSync(new Greeting('world'));\nconsole.log(textSync(stream)); // 'hello world'\n</code></pre>"
            }
          ],
          "displayName": "Protocol symbols"
        }
      ],
      "displayName": "Iterable Streams"
    }
  ]
}