UNPKG

@reactivex/ix-esnext-esm

Version:

The Interactive Extensions for JavaScript

89 lines (87 loc) 2.83 kB
import { AsyncIterableX } from './asynciterablex'; const NON_FLOWING = 0; const READABLE = 1; const ENDED = 2; const ERRORED = 3; export class ReadableStreamAsyncIterable extends AsyncIterableX { constructor(stream, size) { super(); this._stream = stream; this._defaultSize = size; this._state = NON_FLOWING; this._error = null; this._rejectFns = new Set(); const onError = (err) => { this._state = ERRORED; this._error = err; for (const rejectFn of this._rejectFns) { rejectFn(err); } }; const onEnd = () => { this._state = ENDED; }; this._stream['once']('error', onError); this._stream['once']('end', onEnd); } [Symbol.asyncIterator]() { return this; } async next(size = this._defaultSize) { if (this._state === NON_FLOWING) { await Promise.race([this._waitReadable(), this._waitEnd()]); return await this.next(size); } if (this._state === ENDED) { return { done: true, value: undefined }; } if (this._state === ERRORED) { throw this._error; } const value = this._stream['read'](size); if (value !== null) { return { done: false, value }; } else { this._state = NON_FLOWING; return await this.next(size); } } _waitReadable() { return new Promise((resolve, reject) => { const onReadable = () => { this._state = READABLE; this._rejectFns.delete(reject); resolve(); }; this._rejectFns.add(reject); this._stream['once']('readable', onReadable); }); } _waitEnd() { if (!this._endPromise) { this._endPromise = new Promise((resolve, reject) => { const onEnd = () => { this._state = ENDED; this._rejectFns.delete(reject); resolve(); }; this._rejectFns.add(reject); this._stream['once']('end', onEnd); }); } return this._endPromise; } } /** * Creates a new async-iterable from a Node.js stream. * * @export * @param {NodeJS.ReadableStream} stream The Node.js stream to convert to an async-iterable. * @param {number} [size] The size of the buffers for the stream. * @returns {(AsyncIterableX<string | Buffer>)} An async-iterable containing data from the stream either in string or Buffer format. */ export function fromNodeStream(stream, size) { return new ReadableStreamAsyncIterable(stream, size); } //# sourceMappingURL=fromnodestream.mjs.map