|
1 | 1 | import { ReadableStream, type Response } from './_shims/index'; |
2 | 2 | import { OpenAIError } from './error'; |
3 | 3 | import { LineDecoder } from './internal/decoders/line'; |
| 4 | +import { ReadableStreamToAsyncIterable } from './internal/stream-utils'; |
4 | 5 |
|
5 | 6 | import { APIError } from './error'; |
6 | 7 |
|
@@ -96,7 +97,7 @@ export class Stream<Item> implements AsyncIterable<Item> { |
96 | 97 | async function* iterLines(): AsyncGenerator<string, void, unknown> { |
97 | 98 | const lineDecoder = new LineDecoder(); |
98 | 99 |
|
99 | | - const iter = readableStreamAsyncIterable<Bytes>(readableStream); |
| 100 | + const iter = ReadableStreamToAsyncIterable<Bytes>(readableStream); |
100 | 101 | for await (const chunk of iter) { |
101 | 102 | for (const line of lineDecoder.decode(chunk)) { |
102 | 103 | yield line; |
@@ -210,7 +211,7 @@ export async function* _iterSSEMessages( |
210 | 211 | const sseDecoder = new SSEDecoder(); |
211 | 212 | const lineDecoder = new LineDecoder(); |
212 | 213 |
|
213 | | - const iter = readableStreamAsyncIterable<Bytes>(response.body); |
| 214 | + const iter = ReadableStreamToAsyncIterable<Bytes>(response.body); |
214 | 215 | for await (const sseChunk of iterSSEChunks(iter)) { |
215 | 216 | for (const line of lineDecoder.decode(sseChunk)) { |
216 | 217 | const sse = sseDecoder.decode(line); |
@@ -363,36 +364,3 @@ function partition(str: string, delimiter: string): [string, string, string] { |
363 | 364 |
|
364 | 365 | return [str, '', '']; |
365 | 366 | } |
366 | | - |
367 | | -/** |
368 | | - * Most browsers don't yet have async iterable support for ReadableStream, |
369 | | - * and Node has a very different way of reading bytes from its "ReadableStream". |
370 | | - * |
371 | | - * This polyfill was pulled from https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490 |
372 | | - */ |
373 | | -export function readableStreamAsyncIterable<T>(stream: any): AsyncIterableIterator<T> { |
374 | | - if (stream[Symbol.asyncIterator]) return stream; |
375 | | - |
376 | | - const reader = stream.getReader(); |
377 | | - return { |
378 | | - async next() { |
379 | | - try { |
380 | | - const result = await reader.read(); |
381 | | - if (result?.done) reader.releaseLock(); // release lock when stream becomes closed |
382 | | - return result; |
383 | | - } catch (e) { |
384 | | - reader.releaseLock(); // release lock when stream becomes errored |
385 | | - throw e; |
386 | | - } |
387 | | - }, |
388 | | - async return() { |
389 | | - const cancelPromise = reader.cancel(); |
390 | | - reader.releaseLock(); |
391 | | - await cancelPromise; |
392 | | - return { done: true, value: undefined }; |
393 | | - }, |
394 | | - [Symbol.asyncIterator]() { |
395 | | - return this; |
396 | | - }, |
397 | | - }; |
398 | | -} |
0 commit comments