browser-readablestream-to-it
Version:
Turns a browser readble stream into an async iterator
75 lines (68 loc) • 1.9 kB
text/typescript
/**
* @packageDocumentation
*
* Allows treating a browser readable stream as an async iterator.
*
* @example
*
* ```javascript
* import toIt from 'browser-readablestream-to-it'
* import all from 'it-all'
*
* const content = [0, 1, 2, 3, 4]
*
* const stream = new ReadableStream({
* start(controller) {
* for (let i = 0; i < content.length; i++) {
* controller.enqueue(content[i])
* }
*
* controller.close()
* }
* })
*
* const arr = await all(toIt(stream))
*
* console.info(arr) // 0, 1, 2, 3, 4
* ```
*
* ## preventCancel
*
* By default a readable stream will have [.cancel](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/cancel) called on it once it has ended or
* reading has stopped prematurely.
*
* To prevent this behaviour, pass `preventCancel: true` as an option:
*
* ```javascript
* const arr = await all(toIt(stream, { preventCancel: true }))
*
* console.info(arr) // 0, 1, 2, 3, 4
* ```
*/
export interface BrowserReadableStreamToItOptions {
preventCancel?: boolean
}
/**
* Turns a browser readable stream into an async iterable. Async iteration over
* returned iterable will lock give stream, preventing any other consumer from
* acquiring a reader. The lock will be released if iteration loop is broken. To
* prevent stream cancelling optional `{ preventCancel: true }` could be passed
* as a second argument.
*/
export default async function * browserReadableStreamToIt <T> (stream: ReadableStream<T>, options: BrowserReadableStreamToItOptions = {}): AsyncGenerator<T, void, undefined> {
const reader = stream.getReader()
try {
while (true) {
const result = await reader.read()
if (result.done) {
return
}
yield result.value
}
} finally {
if (options.preventCancel !== true) {
await reader.cancel()
}
reader.releaseLock()
}
}