UNPKG

ix

Version:

The Interactive Extensions for JavaScript

108 lines (100 loc) 3.46 kB
import { BufferLike } from '../interfaces.js'; import { IterableX } from '../iterable/iterablex.js'; import { Readable, ReadableOptions } from 'stream'; const done = (_: any) => null as any; type SourceIterator<TSource> = Iterator<TSource, any, number | ArrayBufferView | undefined | null>; /** @ignore */ /** @ignore */ export class IterableReadable<T> extends Readable { private _pulling = false; private _objectMode = true; private _iterator: SourceIterator<T> | undefined; constructor(source: Iterable<T>, options?: ReadableOptions) { super(options); this._iterator = source[Symbol.iterator](); this._objectMode = !options || !!options.objectMode; } public _read(size: number) { const it = this._iterator; if (it && !this._pulling && (this._pulling = true)) { this._pulling = this._pull(it, size); } } public _destroy(err: Error | null, cb: (err: Error | null) => void) { const it = this._iterator; this._iterator = undefined; const fn = (it && (err ? it.throw : it.return)) || done; fn.call(it, err); if (cb) { cb(null); } } // eslint-disable-next-line complexity _pull(it: SourceIterator<T>, size: number) { let innerSize = size; const objectMode = this._objectMode; let r: IteratorResult<BufferLike | T> | undefined; while (this.readable && !(r = it.next(innerSize)).done) { if (innerSize != null) { if (objectMode) { innerSize -= 1; } else { innerSize -= Buffer.byteLength(<BufferLike>r.value || ''); } } if (!this.push(r.value) || innerSize <= 0) { break; } } if ((r && r.done) || !this.readable) { this.push(null); if (it.return) { it.return(); } } return !this.readable; } } export function toNodeStream<TSource>(source: Iterable<TSource>): IterableReadable<TSource>; export function toNodeStream<TSource>( source: Iterable<TSource>, options: ReadableOptions & { objectMode: true } ): IterableReadable<TSource>; export function toNodeStream<TSource extends BufferLike>( source: Iterable<TSource>, options: ReadableOptions & { objectMode: false } ): IterableReadable<TSource>; export function toNodeStream<TSource>( source: Iterable<any>, options?: ReadableOptions ): IterableReadable<TSource> { return !options || options.objectMode === true ? new IterableReadable<TSource>(source, options) : new IterableReadable<TSource extends BufferLike ? TSource : any>(source, options); } /** * @ignore */ export function toNodeStreamProto<TSource>(this: Iterable<TSource>): IterableReadable<TSource>; export function toNodeStreamProto<TSource>( this: Iterable<TSource>, options: ReadableOptions | { objectMode: true } ): IterableReadable<TSource>; export function toNodeStreamProto<TSource extends BufferLike>( this: Iterable<TSource>, options: ReadableOptions | { objectMode: false } ): IterableReadable<TSource>; export function toNodeStreamProto<TSource>( this: Iterable<any>, options?: ReadableOptions ): IterableReadable<TSource> { return !options || options.objectMode === true ? new IterableReadable<TSource>(this, options) : new IterableReadable<TSource extends BufferLike ? TSource : any>(this, options); } IterableX.prototype.toNodeStream = toNodeStreamProto; declare module '../iterable/iterablex' { interface IterableX<T> { toNodeStream: typeof toNodeStreamProto; } }