UNPKG

@rimbu/stream

Version:

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

572 lines 18.2 kB
var _TransformerFastIterator_done, _TransformerFastIterator_currentValues; import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib"; import { Token } from '@rimbu/base'; import { CollectFun, OptLazy, TraverseState } from '@rimbu/common'; import {} from '@rimbu/stream'; import {} from '@rimbu/stream'; import { fromStreamSource, } from '@rimbu/stream/custom'; export const fixedDoneIteratorResult = Object.freeze({ done: true, value: undefined, }); export const emptyFastIterator = Object.freeze({ fastNext(otherwise) { return OptLazy(otherwise); }, next() { return fixedDoneIteratorResult; }, }); export function isFastIterator(iterator) { return `fastNext` in iterator; } /** * A base class for `FastIterator` instances, that takes implements the default `next` * function based on the abstract `fastNext` function. */ export class FastIteratorBase { next() { const done = Symbol('Done'); const value = this.fastNext(done); if (done === value) return fixedDoneIteratorResult; return { value, done: false }; } } export class ReducerFastIterator extends FastIteratorBase { constructor(sourceIterator, reducerInstance) { super(); this.sourceIterator = sourceIterator; this.reducerInstance = reducerInstance; } fastNext(otherwise) { if (this.reducerInstance.halted) { return OptLazy(otherwise); } const done = Symbol('done'); const nextInput = this.sourceIterator.fastNext(done); if (done === nextInput) { this.reducerInstance.halt(); return OptLazy(otherwise); } this.reducerInstance.next(nextInput); return this.reducerInstance.getOutput(); } } export class TransformerFastIterator extends FastIteratorBase { constructor(sourceIterator, transformerInstance) { super(); this.sourceIterator = sourceIterator; this.transformerInstance = transformerInstance; _TransformerFastIterator_done.set(this, false); _TransformerFastIterator_currentValues.set(this, void 0); } fastNext(otherwise) { if (__classPrivateFieldGet(this, _TransformerFastIterator_done, "f")) { return OptLazy(otherwise); } const done = Symbol('done'); let nextValue; while (undefined === __classPrivateFieldGet(this, _TransformerFastIterator_currentValues, "f") || done === (nextValue = __classPrivateFieldGet(this, _TransformerFastIterator_currentValues, "f").fastNext(done))) { if (this.transformerInstance.halted) { __classPrivateFieldSet(this, _TransformerFastIterator_done, true, "f"); return OptLazy(otherwise); } const nextSource = this.sourceIterator.fastNext(done); if (done === nextSource) { if (this.transformerInstance.halted) { __classPrivateFieldSet(this, _TransformerFastIterator_done, true, "f"); return OptLazy(otherwise); } __classPrivateFieldSet(this, _TransformerFastIterator_done, true, "f"); this.transformerInstance.halt(); } else { this.transformerInstance.next(nextSource); } const nextValuesSource = this.transformerInstance.getOutput(); __classPrivateFieldSet(this, _TransformerFastIterator_currentValues, fromStreamSource(nextValuesSource)[Symbol.iterator](), "f"); } return nextValue; } } _TransformerFastIterator_done = new WeakMap(), _TransformerFastIterator_currentValues = new WeakMap(); export class ConcatIterator extends FastIteratorBase { constructor(source, otherSources, streamSourceHelpers) { super(); this.source = source; this.otherSources = otherSources; this.streamSourceHelpers = streamSourceHelpers; this.sourceIndex = 0; this.iterator = source[Symbol.iterator](); } fastNext(otherwise) { const done = Symbol('Done'); let value; const length = this.otherSources.length; const { streamSourceHelpers } = this; while (done === (value = this.iterator.fastNext(done))) { if (this.sourceIndex >= length) return OptLazy(otherwise); let nextSource = this.otherSources[this.sourceIndex++]; while (streamSourceHelpers.isEmptyStreamSourceInstance(nextSource)) { if (this.sourceIndex >= length) { return OptLazy(otherwise); } nextSource = this.otherSources[this.sourceIndex++]; } this.iterator = streamSourceHelpers .fromStreamSource(nextSource)[Symbol.iterator](); } return value; } } export class IndexedIterator extends FastIteratorBase { constructor(source, startIndex) { super(); this.source = source; this.startIndex = startIndex; this.index = this.startIndex; } fastNext(otherwise) { const done = Symbol('Done'); const value = this.source.fastNext(done); if (done === value) { return OptLazy(otherwise); } return [this.index++, value]; } } export class FilterIterator extends FastIteratorBase { constructor(source, pred, negate) { super(); this.source = source; this.pred = pred; this.negate = negate; this.state = TraverseState(); } fastNext(otherwise) { const state = this.state; if (state.halted) return OptLazy(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 = source.fastNext(done))) { if (pred(value, state.nextIndex(), halt) !== negate) return value; } return OptLazy(otherwise); } } export class FilterPureIterator extends FastIteratorBase { constructor(source, pred, args, negate) { super(); this.source = source; this.pred = pred; this.args = args; this.negate = negate; } 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 = source.fastNext(done))) { if (pred(value, ...args) !== negate) return value; } return OptLazy(otherwise); } } export class CollectIterator extends FastIteratorBase { constructor(source, collectFun) { super(); this.source = source; this.collectFun = collectFun; this.state = TraverseState(); } fastNext(otherwise) { const state = this.state; if (state.halted) return OptLazy(otherwise); const { halt } = state; const done = Symbol('Done'); let value; const source = this.source; const collectFun = this.collectFun; while (!state.halted && done !== (value = source.fastNext(done))) { const result = collectFun(value, state.nextIndex(), CollectFun.Skip, halt); if (CollectFun.Skip === result) continue; return result; } return OptLazy(otherwise); } } export class DropWhileIterator extends FastIteratorBase { constructor(source, pred, negate) { super(); this.source = source; this.pred = pred; this.negate = negate; this.pass = false; this.index = 0; } 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 = source.fastNext(done))) { this.pass = this.pred(value, this.index++) === negate; if (this.pass) return value; } return OptLazy(otherwise); } } export class TakeIterator extends FastIteratorBase { constructor(source, amount) { super(); this.source = source; this.amount = amount; this.i = 0; } fastNext(otherwise) { if (this.i++ >= this.amount) return OptLazy(otherwise); return this.source.fastNext(otherwise); } } export class DropIterator extends FastIteratorBase { constructor(source, amount) { super(); this.source = source; this.amount = amount; this.remain = amount; } fastNext(otherwise) { const source = this.source; if (this.remain <= 0) return source.fastNext(otherwise); const done = Symbol('Done'); let value; while (done !== (value = source.fastNext(done))) { if (this.remain-- <= 0) return value; } return OptLazy(otherwise); } } export class RepeatIterator extends FastIteratorBase { constructor(source, amount) { super(); this.source = source; this.amount = amount; this.isEmpty = true; this.iterator = source[Symbol.iterator](); this.remain = amount; } fastNext(otherwise) { const done = Symbol('Done'); let value = this.iterator.fastNext(done); if (done !== value) { this.isEmpty = false; return value; } if (this.isEmpty) return OptLazy(otherwise); if (undefined !== this.remain) { this.remain--; if (this.remain <= 0) return OptLazy(otherwise); } this.iterator = this.source[Symbol.iterator](); value = this.iterator.fastNext(done); if (done === value) return OptLazy(otherwise); return value; } } export class ArrayIterator extends FastIteratorBase { constructor(array, startIndex, endIndex) { super(); this.array = array; this.startIndex = startIndex; this.endIndex = endIndex; this.i = startIndex; } fastNext(otherwise) { if (this.i > this.endIndex) return OptLazy(otherwise); return this.array[this.i++]; } } export class ArrayReverseIterator extends FastIteratorBase { constructor(array, startIndex, endIndex) { super(); this.array = array; this.startIndex = startIndex; this.i = endIndex; } fastNext(otherwise) { if (this.i < this.startIndex) return OptLazy(otherwise); return this.array[this.i--]; } } export class AlwaysIterator extends FastIteratorBase { constructor(value) { super(); this.value = value; } fastNext() { return this.value; } } export class MapApplyIterator extends FastIteratorBase { constructor(source, f, args, streamSourceHelpers) { super(); this.f = f; this.args = args; this.iter = streamSourceHelpers.fromStreamSource(source)[Symbol.iterator](); } fastNext(otherwise) { const done = Symbol(); const next = this.iter.fastNext(done); const args = this.args; if (done === next) return OptLazy(otherwise); return this.f(...next, ...args); } } export class FilterApplyIterator extends FastIteratorBase { constructor(source, pred, args, negate, streamSourceHelpers) { super(); this.pred = pred; this.args = args; this.negate = negate; this.iter = streamSourceHelpers.fromStreamSource(source)[Symbol.iterator](); } fastNext(otherwise) { const done = Symbol(); let next; const pred = this.pred; const iter = this.iter; const args = this.args; const negate = this.negate; while (done !== (next = iter.fastNext(done))) { if (pred(...next, ...args) !== negate) return next; } return OptLazy(otherwise); } } export class RangeUpIterator extends FastIteratorBase { constructor(start = 0, end, delta) { super(); this.start = start; this.end = end; this.delta = delta; this.state = start; } fastNext(otherwise) { if (undefined !== this.end) { if (this.state > this.end) { return OptLazy(otherwise); } } const currentState = this.state; this.state += this.delta; return currentState; } } export class RangeDownIterator extends FastIteratorBase { constructor(start = 0, end, delta) { super(); this.start = start; this.end = end; this.delta = delta; this.state = start; } fastNext(otherwise) { if (undefined !== this.end) { if (this.state < this.end) { return OptLazy(otherwise); } } const currentState = this.state; this.state += this.delta; return currentState; } } export class RandomIterator extends FastIteratorBase { fastNext() { return Math.random(); } } export class RandomIntIterator extends FastIteratorBase { constructor(min, max) { super(); this.min = min; this.max = max; this.width = max - min; } fastNext() { return this.min + Math.round(Math.random() * this.width); } } export class UnfoldIterator extends FastIteratorBase { constructor(init, getNext) { super(); this.getNext = getNext; this.index = 0; this.current = init; } fastNext(otherwise) { const current = this.current; if (Token === current) return OptLazy(otherwise); if (this.index === 0) { this.index++; return current; } const next = this.getNext(current, this.index++, Token); this.current = next; if (Token === next) return OptLazy(otherwise); return next; } } export class ZipWithIterator extends FastIteratorBase { constructor(iterables, zipFun, streamSourceHelpers) { super(); this.iterables = iterables; this.zipFun = zipFun; this.sources = iterables.map((source) => streamSourceHelpers.fromStreamSource(source)[Symbol.iterator]()); } fastNext(otherwise) { const result = []; let sourceIndex = -1; const sources = this.sources; const done = Symbol('Done'); while (++sourceIndex < sources.length) { const value = sources[sourceIndex].fastNext(done); if (done === value) return OptLazy(otherwise); result.push(value); } return this.zipFun(...result); } } export class ZipAllWithItererator extends FastIteratorBase { constructor(fillValue, iters, zipFun, streamSourceHelpers) { super(); this.fillValue = fillValue; this.iters = iters; this.zipFun = zipFun; this.allDone = false; this.sources = iters.map((o) => streamSourceHelpers.fromStreamSource(o)[Symbol.iterator]()); } fastNext(otherwise) { if (this.allDone) return OptLazy(otherwise); const result = []; let sourceIndex = -1; const sources = this.sources; const done = Symbol('Done'); let anyNotDone = false; const fillValue = this.fillValue; while (++sourceIndex < sources.length) { const value = sources[sourceIndex].fastNext(done); if (done === value) { result.push(OptLazy(fillValue)); } else { anyNotDone = true; result.push(value); } } if (!anyNotDone) { this.allDone = true; return OptLazy(otherwise); } return this.zipFun(...result); } } export class PrependIterator extends FastIteratorBase { constructor(source, item) { super(); this.source = source; this.item = item; this.prependDone = false; } fastNext(otherwise) { if (this.prependDone) { return this.source.fastNext(otherwise); } this.prependDone = true; return OptLazy(this.item); } } export class AppendIterator extends FastIteratorBase { constructor(source, item) { super(); this.source = source; this.item = item; this.appendDone = false; } fastNext(otherwise) { if (this.appendDone) return OptLazy(otherwise); const done = Symbol('Done'); const value = this.source.fastNext(done); if (done !== value) return value; this.appendDone = true; return OptLazy(this.item); } } export class MapIterator extends FastIteratorBase { constructor(source, mapFun) { super(); this.source = source; this.mapFun = mapFun; this.state = TraverseState(); } fastNext(otherwise) { const state = this.state; if (state.halted) return OptLazy(otherwise); const done = Symbol('Done'); const next = this.source.fastNext(done); if (done === next) return OptLazy(otherwise); return this.mapFun(next, state.nextIndex()); } } export class MapPureIterator extends FastIteratorBase { constructor(source, mapFun, args) { super(); this.source = source; this.mapFun = mapFun; this.args = args; } fastNext(otherwise) { const done = Symbol('Done'); const next = this.source.fastNext(done); if (done === next) return OptLazy(otherwise); return this.mapFun(next, ...this.args); } } //# sourceMappingURL=fast-iterator-custom.mjs.map