* Generates a Stream from a newline-separated ReadableStream * where each item is a JSON value. * * @template Item - The type of items in the stream. * @param {ReadableStream} readableStream - The readable stream to create the stream from. * @param {AbortController} controller - The abort
(readableStream: ReadableStream, controller: AbortController)
| 99 | * @returns {Stream<Item>} - The created stream. |
| 100 | */ |
| 101 | static fromReadableStream<Item>(readableStream: ReadableStream, controller: AbortController) { |
| 102 | let consumed = false; |
| 103 | |
| 104 | async function* iterLines(): AsyncGenerator<string, void, unknown> { |
| 105 | const lineDecoder = new LineDecoder(); |
| 106 | |
| 107 | const iter = readableStreamAsyncIterable<Bytes>(readableStream); |
| 108 | for await (const chunk of iter) { |
| 109 | for (const line of lineDecoder.decode(chunk)) { |
| 110 | yield line; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | for (const line of lineDecoder.flush()) { |
| 115 | yield line; |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | async function* iterator(): AsyncIterator<Item, any, undefined> { |
| 120 | if (consumed) { |
| 121 | throw new Error('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); |
| 122 | } |
| 123 | consumed = true; |
| 124 | let done = false; |
| 125 | try { |
| 126 | for await (const line of iterLines()) { |
| 127 | if (done) continue; |
| 128 | if (line) yield JSON.parse(line); |
| 129 | } |
| 130 | done = true; |
| 131 | } catch (e) { |
| 132 | // If the user calls `stream.controller.abort()`, we should exit without throwing. |
| 133 | if (e instanceof Error && e.name === 'AbortError') return; |
| 134 | throw e; |
| 135 | } finally { |
| 136 | // If the user `break`s, abort the ongoing request. |
| 137 | if (!done) controller.abort(); |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | return new Stream(iterator, controller); |
| 142 | } |
| 143 | |
| 144 | [Symbol.asyncIterator](): AsyncIterator<Item> { |
| 145 | return this.iterator(); |
no outgoing calls
no test coverage detected