UNPKG

@rimbu/stream

Version:

Efficient structure representing a sequence of elements, with powerful operations for TypeScript

654 lines 23.7 kB
var _AsyncReduceIterator_instance, _AsyncTransformerFastIterator_done, _AsyncTransformerFastIterator_instance, _AsyncTransformerFastIterator_currentValues; import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib"; import { Token } from '@rimbu/base'; import { AsyncOptLazy, CollectFun, TraverseState, } from '@rimbu/common'; import { AsyncTransformer, } from '@rimbu/stream/async'; import { closeIters, fromAsyncStreamSource, } from '@rimbu/stream/async-custom'; /** * A frozen `IteratorResult` that represents the completed asynchronous iterator state. * This value is reused to avoid repeated allocations in async iterator implementations. */ export const fixedDoneAsyncIteratorResult = Object.freeze(Promise.resolve(Object.freeze({ done: true, value: undefined, }))); /** * Returns true if the given `iterator` implements the `AsyncFastIterator` interface. * @param iterator - the async iterator instance to test */ export function isAsyncFastIterator(iterator) { return `fastNext` in iterator; } /** * An `AsyncFastIterator` that is already exhausted and never yields values. * Its `fastNext` method always resolves to the provided fallback value. */ export const emptyAsyncFastIterator = Object.freeze({ fastNext(otherwise) { return AsyncOptLazy.toMaybePromise(otherwise); }, next() { return fixedDoneAsyncIteratorResult; }, }); /** * Base class for asynchronous fast iterators that implements `next` in terms of `fastNext`. * Subclasses only need to implement the `fastNext` method. */ export class AsyncFastIteratorBase { async next() { const done = Symbol('Done'); const value = await this.fastNext(done); if (done === value) return fixedDoneAsyncIteratorResult; return { value, done: false }; } } export class AsyncOfIterator extends AsyncFastIteratorBase { constructor(values) { super(); this.values = values; this.index = 0; } fastNext(otherwise) { const index = this.index; const values = this.values; if (index >= values.length) return AsyncOptLazy.toMaybePromise(otherwise); return AsyncOptLazy.toMaybePromise(values[this.index++]); } } export class FromResourceIterator extends AsyncFastIteratorBase { constructor(open, createSource, close, asyncStreamSourceHelpers) { super(); this.open = open; this.createSource = createSource; this.close = close; this.asyncStreamSourceHelpers = asyncStreamSourceHelpers; this.return = async () => { if (close && this.resource) { await close(this.resource); this.resource = undefined; } await this.iterator?.return?.(); this.return = undefined; }; } async fastNext(otherwise) { if (undefined === this.iterator) { const resource = await this.open(); this.resource = resource; const source = await this.createSource(resource); this.iterator = this.asyncStreamSourceHelpers .fromAsyncStreamSource(source)[Symbol.asyncIterator](); } try { return await this.iterator.fastNext(async () => { if (undefined !== this.return) { await this.return(); } return AsyncOptLazy.toMaybePromise(otherwise); }); } catch (err) { if (undefined !== this.return) { await this.return(); } throw err; } } } export class AsyncUnfoldIterator extends AsyncFastIteratorBase { constructor(init, getNext) { super(); this.getNext = getNext; this.index = 0; this.current = init; } async fastNext(otherwise) { const current = this.current; if (Token === current) return AsyncOptLazy.toMaybePromise(otherwise); if (this.index === 0) { this.index++; return current; } const next = await this.getNext(current, this.index++, Token); this.current = next; if (Token === next) return AsyncOptLazy.toMaybePromise(otherwise); return next; } } export class AsyncZipWithIterator extends AsyncFastIteratorBase { constructor(iterables, zipFun, asyncStreamSourceHelpers) { super(); this.iterables = iterables; this.zipFun = zipFun; this.asyncStreamSourceHelpers = asyncStreamSourceHelpers; this.sources = iterables.map((source) => this.asyncStreamSourceHelpers .fromAsyncStreamSource(source)[Symbol.asyncIterator]()); this.sourcesToClose = new Set(this.sources); this.return = () => closeIters(...this.sourcesToClose); } async fastNext(otherwise) { const sources = this.sources; const done = Symbol('Done'); const result = await Promise.all(sources.map((source) => source.fastNext(() => { this.sourcesToClose.delete(source); return done; }))); if (this.sourcesToClose.size !== sources.length) { await closeIters(this); return AsyncOptLazy.toMaybePromise(otherwise); } return this.zipFun(...result); } } export class AsyncZipAllWithItererator extends AsyncFastIteratorBase { constructor(fillValue, iters, zipFun, asyncStreamSourceHelpers) { super(); this.fillValue = fillValue; this.iters = iters; this.zipFun = zipFun; this.asyncStreamSourceHelpers = asyncStreamSourceHelpers; this.sources = iters.map((o) => this.asyncStreamSourceHelpers .fromAsyncStreamSource(o)[Symbol.asyncIterator]()); this.sourcesToClose = new Set(this.sources); this.return = () => closeIters(...this.sourcesToClose); } async fastNext(otherwise) { if (this.sourcesToClose.size === 0) { return AsyncOptLazy.toMaybePromise(otherwise); } const sources = this.sources; const fillValue = this.fillValue; const result = await Promise.all(sources.map((source) => { if (this.sourcesToClose.has(source)) { return source.fastNext(() => { this.sourcesToClose.delete(source); return AsyncOptLazy.toMaybePromise(fillValue); }); } return AsyncOptLazy.toMaybePromise(fillValue); })); if (this.sourcesToClose.size === 0) { return AsyncOptLazy.toMaybePromise(otherwise); } return this.zipFun(...result); } } export class FromAsyncIterator { constructor(source, close) { this.source = source; if (source.return && close) { this.return = () => Promise.all([source.return?.(), close?.()]); } else if (source.return) { this.return = () => source.return?.(); } else if (close) { this.return = close; } } next() { return this.source.next(); } async fastNext(otherwise) { const result = await this.source.next(); if (result.done) { await closeIters(this); return AsyncOptLazy.toMaybePromise(otherwise); } return result.value; } } export class FromIterator extends AsyncFastIteratorBase { constructor(iterator, close) { super(); this.iterator = iterator; if (close !== undefined) { this.return = close; } } async fastNext(otherwise) { const result = this.iterator.next(); if (result.done) { await closeIters(this); return AsyncOptLazy.toMaybePromise(otherwise); } return result.value; } } export class FromPromise extends AsyncFastIteratorBase { constructor(promise, asyncStreamSourceHelpers, close) { super(); this.promise = promise; this.asyncStreamSourceHelpers = asyncStreamSourceHelpers; this.return = async () => { if (close) { await close(); } if (this.iterator) { await this.iterator.return?.(); } }; } async fastNext(otherwise) { if (this.iterator === undefined) { const source = await this.promise(); this.iterator = this.asyncStreamSourceHelpers .fromAsyncStreamSource(source)[Symbol.asyncIterator](); } return this.iterator.fastNext(otherwise); } } export class AsyncPrependIterator extends AsyncFastIteratorBase { constructor(source, item) { super(); this.source = source; this.item = item; this.prependDone = false; this.return = async () => { if (this.prependDone) return closeIters(this.source); }; } fastNext(otherwise) { if (this.prependDone) { return this.source.fastNext(otherwise); } this.prependDone = true; return AsyncOptLazy.toMaybePromise(this.item); } } export class AsyncAppendIterator extends AsyncFastIteratorBase { constructor(source, item) { super(); this.source = source; this.item = item; this.appendDone = false; this.return = async () => { if (!this.appendDone) return closeIters(source); }; } async fastNext(otherwise) { if (this.appendDone) return AsyncOptLazy.toMaybePromise(otherwise); const done = Symbol('Done'); const value = await this.source.fastNext(done); if (done !== value) return value; this.appendDone = true; return AsyncOptLazy.toMaybePromise(this.item); } } export class AsyncIndexedIterator extends AsyncFastIteratorBase { constructor(source, startIndex = 0) { super(); this.source = source; this.startIndex = startIndex; this.index = startIndex; this.return = () => closeIters(source); } async fastNext(otherwise) { const done = Symbol('Done'); const value = await this.source.fastNext(done); if (done === value) { return AsyncOptLazy.toMaybePromise(otherwise); } return [this.index++, value]; } } export class AsyncMapIterator extends AsyncFastIteratorBase { constructor(source, mapFun) { super(); this.source = source; this.mapFun = mapFun; this.state = TraverseState(); this.return = () => closeIters(source); } async fastNext(otherwise) { const state = this.state; const done = Symbol('Done'); const next = await this.source.fastNext(done); if (done === next) { return AsyncOptLazy.toMaybePromise(otherwise); } return this.mapFun(next, state.nextIndex()); } } export class AsyncMapPureIterator extends AsyncFastIteratorBase { constructor(source, mapFun, args) { super(); this.source = source; this.mapFun = mapFun; this.args = args; this.return = () => closeIters(source); } async fastNext(otherwise) { const done = Symbol('Done'); const next = await this.source.fastNext(done); if (done === next) return AsyncOptLazy.toMaybePromise(otherwise); return this.mapFun(next, ...this.args); } } export class AsyncConcatIterator extends AsyncFastIteratorBase { constructor(source, otherSources, asyncStreamSourceHelpers) { super(); this.source = source; this.otherSources = otherSources; this.asyncStreamSourceHelpers = asyncStreamSourceHelpers; this.sourceIndex = 0; this.iterator = source[Symbol.asyncIterator](); this.return = () => closeIters(this.iterator); } async fastNext(otherwise) { const done = Symbol('Done'); let value; const length = this.otherSources.length; const { asyncStreamSourceHelpers } = this; while (done === (value = await this.iterator.fastNext(done))) { if (this.sourceIndex >= length) { return AsyncOptLazy.toMaybePromise(otherwise); } let nextSource = this.otherSources[this.sourceIndex++]; while (asyncStreamSourceHelpers.isEmptyAsyncStreamSourceInstance(nextSource)) { if (this.sourceIndex >= length) { return AsyncOptLazy.toMaybePromise(otherwise); } nextSource = this.otherSources[this.sourceIndex++]; } this.iterator = asyncStreamSourceHelpers .fromAsyncStreamSource(nextSource)[Symbol.asyncIterator](); } return value; } } export class AsyncFilterIterator extends AsyncFastIteratorBase { constructor(source, pred, negate) { super(); this.source = source; this.pred = pred; this.negate = negate; this.state = TraverseState(); this.return = () => closeIters(source); } async fastNext(otherwise) { const state = this.state; if (state.halted) { return AsyncOptLazy.toMaybePromise(otherwise); } const done = Symbol('Done'); let value; const source = this.source; const pred = this.pred; const halt = state.halt; const negate = this.negate; while (!state.halted && done !== (value = await source.fastNext(done))) { const cond = await pred(value, state.nextIndex(), halt); if (cond !== negate) return value; } if (state.halted && done !== value) { await closeIters(this); } return AsyncOptLazy.toMaybePromise(otherwise); } } export class AsyncFilterPureIterator extends AsyncFastIteratorBase { constructor(source, pred, args, negate) { super(); this.source = source; this.pred = pred; this.args = args; this.negate = negate; this.return = () => closeIters(source); } async fastNext(otherwise) { const done = Symbol('Done'); let value; const source = this.source; const pred = this.pred; const args = this.args; const negate = this.negate; while (done !== (value = await source.fastNext(done))) { const cond = await pred(value, ...args); if (cond !== negate) return value; } return AsyncOptLazy.toMaybePromise(otherwise); } } export class AsyncCollectIterator extends AsyncFastIteratorBase { constructor(source, collectFun) { super(); this.source = source; this.collectFun = collectFun; this.state = TraverseState(); this.return = () => closeIters(source); } async fastNext(otherwise) { const state = this.state; if (state.halted) { return AsyncOptLazy.toMaybePromise(otherwise); } const { halt } = state; const done = Symbol('Done'); let value; const source = this.source; const collectFun = this.collectFun; try { while (!state.halted && done !== (value = await source.fastNext(done))) { const result = await collectFun(value, state.nextIndex(), CollectFun.Skip, halt); if (CollectFun.Skip === result) continue; return result; } return AsyncOptLazy.toMaybePromise(otherwise); } finally { if (state.halted && done !== value) { await closeIters(this); } } } } export class AsyncDropWhileIterator extends AsyncFastIteratorBase { constructor(source, pred, negate) { super(); this.source = source; this.pred = pred; this.negate = negate; this.pass = false; this.index = 0; this.return = () => closeIters(source); } async fastNext(otherwise) { const source = this.source; if (this.pass) return source.fastNext(otherwise); const done = Symbol('Done'); let value; const negate = this.negate; while (done !== (value = await source.fastNext(done))) { this.pass = (await this.pred(value, this.index++)) === negate; if (this.pass) return value; } return AsyncOptLazy.toMaybePromise(otherwise); } } export class AsyncTakeIterator extends AsyncFastIteratorBase { constructor(source, amount) { super(); this.source = source; this.amount = amount; this.i = 0; this.return = () => closeIters(source); } async fastNext(otherwise) { if (this.i++ >= this.amount) { await closeIters(this); this.return = undefined; return AsyncOptLazy.toMaybePromise(otherwise); } return this.source.fastNext(otherwise); } } export class AsyncDropIterator extends AsyncFastIteratorBase { constructor(source, amount) { super(); this.source = source; this.amount = amount; this.return = () => closeIters(source); this.remain = amount; } async fastNext(otherwise) { const source = this.source; if (this.remain <= 0) return source.fastNext(otherwise); const done = Symbol('Done'); let value; while (done !== (value = await source.fastNext(done))) { if (this.remain-- <= 0) { return value; } } return AsyncOptLazy.toMaybePromise(otherwise); } } export class AsyncRepeatIterator extends AsyncFastIteratorBase { constructor(source, amount) { super(); this.source = source; this.amount = amount; this.isEmpty = true; this.iterator = source[Symbol.asyncIterator](); this.return = () => closeIters(this.iterator); this.remain = amount; } async fastNext(otherwise) { const done = Symbol('Done'); const iterator = this.iterator; let value = await iterator.fastNext(done); if (done !== value) { this.isEmpty = false; return value; } if (this.isEmpty) { return AsyncOptLazy.toMaybePromise(otherwise); } if (undefined !== this.remain) { this.remain--; if (this.remain <= 0) { return AsyncOptLazy.toMaybePromise(otherwise); } } this.iterator = this.source[Symbol.asyncIterator](); value = await this.iterator.fastNext(done); if (done === value) { return AsyncOptLazy.toMaybePromise(otherwise); } return value; } } export class AsyncReduceIterator extends AsyncFastIteratorBase { constructor(sourceIterator, reducer) { super(); this.sourceIterator = sourceIterator; this.reducer = reducer; _AsyncReduceIterator_instance.set(this, void 0); this.return = async () => { if (undefined !== __classPrivateFieldGet(this, _AsyncReduceIterator_instance, "f") && !__classPrivateFieldGet(this, _AsyncReduceIterator_instance, "f").halted) { await Promise.all([ closeIters(sourceIterator), __classPrivateFieldGet(this, _AsyncReduceIterator_instance, "f").onClose(), ]); } else { await closeIters(sourceIterator); } }; } async fastNext(otherwise) { if (undefined === __classPrivateFieldGet(this, _AsyncReduceIterator_instance, "f")) { __classPrivateFieldSet(this, _AsyncReduceIterator_instance, await this.reducer.compile(), "f"); } const reducerInstance = __classPrivateFieldGet(this, _AsyncReduceIterator_instance, "f"); try { if (reducerInstance.halted) { return (await AsyncOptLazy.toMaybePromise(otherwise)); } const done = Symbol('Done'); const nextInput = await this.sourceIterator.fastNext(done); if (done === nextInput) { __classPrivateFieldGet(this, _AsyncReduceIterator_instance, "f").halt(); return AsyncOptLazy.toMaybePromise(otherwise); } await reducerInstance.next(nextInput); return reducerInstance.getOutput(); } finally { if (reducerInstance.halted) { this.return?.(); this.return = undefined; } } } } _AsyncReduceIterator_instance = new WeakMap(); export class AsyncTransformerFastIterator extends AsyncFastIteratorBase { constructor(sourceIterator, transformer) { super(); this.sourceIterator = sourceIterator; this.transformer = transformer; _AsyncTransformerFastIterator_done.set(this, false); _AsyncTransformerFastIterator_instance.set(this, void 0); _AsyncTransformerFastIterator_currentValues.set(this, void 0); this.return = async () => { if (undefined !== __classPrivateFieldGet(this, _AsyncTransformerFastIterator_instance, "f")) { await Promise.all([ closeIters(sourceIterator), __classPrivateFieldGet(this, _AsyncTransformerFastIterator_instance, "f").onClose(), ]); } else { await closeIters(sourceIterator); } }; } async fastNext(otherwise) { if (__classPrivateFieldGet(this, _AsyncTransformerFastIterator_done, "f")) { return AsyncOptLazy.toPromise(otherwise); } if (undefined === __classPrivateFieldGet(this, _AsyncTransformerFastIterator_instance, "f")) { __classPrivateFieldSet(this, _AsyncTransformerFastIterator_instance, await AsyncTransformer.from(this.transformer).compile(), "f"); } const transformerInstance = __classPrivateFieldGet(this, _AsyncTransformerFastIterator_instance, "f"); const done = Symbol('done'); let nextValue; while (undefined === __classPrivateFieldGet(this, _AsyncTransformerFastIterator_currentValues, "f") || done === (nextValue = await __classPrivateFieldGet(this, _AsyncTransformerFastIterator_currentValues, "f").fastNext(done))) { const nextSource = await this.sourceIterator.fastNext(done); if (done === nextSource) { if (transformerInstance.halted) { return AsyncOptLazy.toMaybePromise(otherwise); } __classPrivateFieldSet(this, _AsyncTransformerFastIterator_done, true, "f"); transformerInstance.halt(); this.return = undefined; } else { await transformerInstance.next(nextSource); } const nextValuesSource = await transformerInstance.getOutput(); __classPrivateFieldSet(this, _AsyncTransformerFastIterator_currentValues, fromAsyncStreamSource(nextValuesSource)[Symbol.asyncIterator](), "f"); } return nextValue; } } _AsyncTransformerFastIterator_done = new WeakMap(), _AsyncTransformerFastIterator_instance = new WeakMap(), _AsyncTransformerFastIterator_currentValues = new WeakMap(); //# sourceMappingURL=async-fast-iterator-base.mjs.map