UNPKG

@rimbu/stream

Version:

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

1,360 lines 43.6 kB
var _a; import { RimbuError } from '@rimbu/base'; import { AsyncOptLazy, Comp, Eq, TraverseState, } from '@rimbu/common'; import { Transformer } from '@rimbu/stream'; import { AsyncReducer, AsyncTransformer, } from '@rimbu/stream/async'; import { AsyncAppendIterator, AsyncCollectIterator, AsyncConcatIterator, AsyncDropIterator, AsyncDropWhileIterator, AsyncFilterIterator, AsyncFilterPureIterator, AsyncIndexedIterator, AsyncMapIterator, AsyncMapPureIterator, AsyncOfIterator, AsyncPrependIterator, AsyncReduceIterator, AsyncRepeatIterator, AsyncTakeIterator, AsyncTransformerFastIterator, AsyncUnfoldIterator, AsyncZipAllWithItererator, AsyncZipWithIterator, FromAsyncIterator, FromIterator, FromPromise, FromResourceIterator, closeIters, emptyAsyncFastIterator, isAsyncFastIterator, } from '@rimbu/stream/async-custom'; import { StreamConstructorsImpl, isEmptyStreamSourceInstance, } from '@rimbu/stream/custom'; export class AsyncStreamBase { asyncStream() { return this; } async equals(other, options = {}) { const { eq = Eq.objectIs, negate = false } = options; const it1 = this[Symbol.asyncIterator](); const it2 = fromAsyncStreamSource(other)[Symbol.asyncIterator](); const done = Symbol('Done'); while (true) { const [v1, v2] = await Promise.all([ it1.fastNext(done), it2.fastNext(done), ]); if (done === v1) { if (done === v2) return true; await closeIters(it2); return false; } if (done === v2) { await closeIters(it1); return false; } if (eq(v1, v2) === negate) { await closeIters(it1, it2); return false; } } } assumeNonEmpty() { return this; } asNormal() { return this; } prepend(value) { return new AsyncPrependStream(this, value).assumeNonEmpty(); } append(value) { return new AsyncAppendStream(this, value).assumeNonEmpty(); } async forEach(f, options = {}) { const { state = TraverseState() } = options; if (state.halted) return; const done = Symbol('Done'); let value; const iterator = this[Symbol.asyncIterator](); const { halt } = state; try { while (!state.halted && done !== (value = await iterator.fastNext(done))) { await f(value, state.nextIndex(), halt); } } finally { if (done !== value) await closeIters(iterator); } } async forEachPure(f, ...args) { const done = Symbol('Done'); let value; const iterator = this[Symbol.asyncIterator](); try { while (done !== (value = await iterator.fastNext(done))) { await f(value, ...args); } } finally { if (done !== value) { await closeIters(iterator); } } } indexed(options = {}) { const { startIndex = 0 } = options; return new AsyncIndexedStream(this, startIndex); } filter(pred, options = {}) { const { negate = false } = options; return new AsyncFilterStream(this, pred, negate); } filterPure(options, ...args) { const { pred, negate = false } = options; return new AsyncFilterPureStream(this, pred, args, negate); } withOnly(values) { if (values.length <= 0) { return this; } const set = new Set(values); return this.filterPure({ pred: (v) => set.has(v) }); } without(values) { if (values.length <= 0) { return this; } const set = new Set(values); return this.filterPure({ pred: (v) => set.has(v), negate: true }); } map(mapFun) { return new AsyncMapStream(this, mapFun); } mapPure(mapFun, ...args) { return new AsyncMapPureStream(this, mapFun, args); } collect(collectFun) { return new AsyncCollectStream(this, collectFun); } flatMap(flatMapFun) { return this.transform(AsyncTransformer.flatMap(flatMapFun)); } flatZip(flatMapFun) { return this.transform(AsyncTransformer.flatZip(flatMapFun)); } transform(transformer) { return new AsyncTransformerStream(this, transformer); } async first(otherwise) { const done = Symbol('done'); const iter = this[Symbol.asyncIterator](); let value = done; try { value = await iter.fastNext(done); if (done === value) { return AsyncOptLazy.toPromise(otherwise); } return value; } finally { if (done !== value) { await closeIters(iter); } } } async last(otherwise) { const done = Symbol('Done'); const iterator = this[Symbol.asyncIterator](); try { let value = done; let lastValue = done; while (done !== (value = await iterator.fastNext(done))) { lastValue = value; } if (done === lastValue) { return AsyncOptLazy.toPromise(otherwise); } return lastValue; } catch (err) { await closeIters(iterator); throw err; } } async single(otherwise) { const iterator = this[Symbol.asyncIterator](); const done = Symbol('Done'); let value = done; try { value = await iterator.fastNext(done); if (done !== value) { const resultValue = value; if (done === (value = await iterator.fastNext(done))) { return resultValue; } } return AsyncOptLazy.toPromise(otherwise); } finally { if (done !== value) { await closeIters(iterator); } } } async count() { let result = 0; const done = Symbol('Done'); const iterator = this[Symbol.asyncIterator](); try { while (done !== (await iterator.fastNext(done))) { result++; } return result; } catch (err) { await closeIters(iterator); throw err; } } async countElement(value, options = {}) { const { eq = Eq.objectIs, negate = false } = options; const done = Symbol('Done'); const iterator = this[Symbol.asyncIterator](); try { let result = 0; let current; while (done !== (current = await iterator.fastNext(done))) { if (eq(value, current) !== negate) { result++; } } return result; } catch (err) { await closeIters(iterator); throw err; } } async find(pred, options = {}) { const { occurrance = 1, negate = false, otherwise } = options; if (occurrance <= 0) return AsyncOptLazy.toPromise(otherwise); const done = Symbol('Done'); const iterator = this[Symbol.asyncIterator](); let value; let remain = occurrance; let index = 0; try { while (done !== (value = await iterator.fastNext(done))) { const cond = await pred(value, index++); if (cond !== negate && --remain <= 0) { return value; } } return AsyncOptLazy.toPromise(otherwise); } finally { if (done !== value) { await closeIters(iterator); } } } async elementAt(index, otherwise) { if (index < 0) return AsyncOptLazy.toPromise(otherwise); const done = Symbol('Done'); const iterator = this[Symbol.asyncIterator](); let value; let i = 0; try { while (i <= index && done !== (value = await iterator.fastNext(done))) { if (i === index) { return value; } i++; } return AsyncOptLazy.toPromise(otherwise); } finally { if (done !== value) { await closeIters(iterator); } } } indicesWhere(pred, options = {}) { return this.transform(AsyncTransformer.indicesWhere(pred, options)); } indicesOf(searchValue, options = {}) { return this.transform(Transformer.indicesOf(searchValue, options)); } async indexWhere(pred, options = {}) { const { occurrance = 1, negate = false } = options; if (occurrance <= 0) { return undefined; } const done = Symbol('Done'); let value; const iterator = this[Symbol.asyncIterator](); let index = 0; let occ = 0; try { while (done !== (value = await iterator.fastNext(done))) { const i = index++; const cond = await pred(value, i); if (cond === !negate) { occ++; if (occ >= occurrance) { return i; } } } return undefined; } finally { if (done !== value) { await closeIters(iterator); } } } async indexOf(searchValue, options = {}) { const { occurrance = 1, eq = Eq.objectIs, negate = false } = options; if (occurrance <= 0) return undefined; const done = Symbol('Done'); let value; const iterator = this[Symbol.asyncIterator](); let index = 0; let occ = 0; try { while (done !== (value = await iterator.fastNext(done))) { const i = index++; if (eq(value, searchValue) !== negate) { occ++; if (occ >= occurrance) { return i; } } } return undefined; } finally { if (done !== value) { await closeIters(iterator); } } } async some(pred, options = {}) { return undefined !== (await this.indexWhere(pred, options)); } async every(pred, options = {}) { const { negate = false } = options; return undefined === (await this.indexWhere(pred, { negate: !negate })); } async contains(searchValue, options = {}) { const { amount = 1 } = options; if (amount <= 0) { return true; } const { eq = Eq.objectIs, negate = false } = options; return (undefined !== (await this.indexOf(searchValue, { occurrance: amount, eq, negate }))); } async containsSlice(source, options = {}) { return this.reduce(AsyncReducer.containsSlice(source, options)); } takeWhile(pred, options = {}) { const { negate = false } = options; return this.filter(async (value, index, halt) => { const result = (await pred(value, index)) !== negate; if (!result) { halt(); } return result; }); } dropWhile(pred, options = {}) { const { negate = false } = options; return new AsyncDropWhileStream(this, pred, negate); } take(amount) { if (amount <= 0) { return emptyAsyncStream; } return new AsyncTakeStream(this, amount); } drop(amount) { if (amount <= 0) { return this; } return new AsyncDropStream(this, amount); } repeat(amount) { if (undefined !== amount && amount <= 1) { return this; } return new AsyncFromStream(() => new AsyncRepeatIterator(this, amount)); } concat(...others) { if (others.every(isEmptyAsyncStreamSourceInstance)) return this; return new AsyncConcatStream(this, others); } min(otherwise) { return this.minBy(Comp.defaultComp().compare, otherwise); } async minBy(compare, otherwise) { const done = Symbol('Done'); const iterator = this[Symbol.asyncIterator](); let result; let value; try { result = await iterator.fastNext(done); if (done === result) return AsyncOptLazy.toPromise(otherwise); while (done !== (value = await iterator.fastNext(done))) { if (compare(value, result) < 0) result = value; } return result; } catch (err) { await closeIters(iterator); throw err; } } max(otherwise) { return this.maxBy(Comp.defaultComp().compare, otherwise); } async maxBy(compare, otherwise) { const done = Symbol('Done'); const iterator = this[Symbol.asyncIterator](); try { let result = await iterator.fastNext(done); if (done === result) { return AsyncOptLazy.toPromise(otherwise); } let value; while (done !== (value = await iterator.fastNext(done))) { if (compare(value, result) > 0) result = value; } return result; } catch (err) { await closeIters(iterator); throw err; } } intersperse(sep) { if (isEmptyAsyncStreamSourceInstance(sep)) { return this; } return this.transform(AsyncTransformer.intersperse(sep)); } async join({ sep = '', start = '', end = '', valueToString = String, ifEmpty = undefined, } = {}) { const done = Symbol('Done'); const iterator = this[Symbol.asyncIterator](); let value = await iterator.fastNext(done); try { if (done === value) { if (undefined !== ifEmpty) return ifEmpty; return start.concat(end); } let result = start.concat(valueToString(value)); while (done !== (value = await iterator.fastNext(done))) { result = result.concat(sep, valueToString(value)); } return result.concat(end); } catch (err) { await closeIters(iterator); throw err; } } mkGroup({ sep = emptyAsyncStream, start = emptyAsyncStream, end = emptyAsyncStream, } = {}) { return fromAsyncStreamSource(start).concat(this.intersperse(sep), end); } splitWhere(pred, options = {}) { return this.transform(AsyncTransformer.splitWhere(pred, options)); } splitOn(sepElem, options = {}) { return this.transform(AsyncTransformer.splitOn(sepElem, options)); } splitOnSlice(sepSlice, options = {}) { return this.transform(AsyncTransformer.splitOnSlice(sepSlice, options)); } distinctPrevious(options = {}) { return this.transform(Transformer.distinctPrevious(options)); } window(windowSize, options = {}) { return this.transform(AsyncTransformer.window(windowSize, options)); } partition(pred, options = {}) { return this.reduce(AsyncReducer.partition(pred, options)); } groupBy(valueToKey, options = {}) { return this.reduce(AsyncReducer.groupBy(valueToKey, options)); } async fold(init, next) { return this.reduce(AsyncReducer.fold(init, next)); } foldStream(init, next) { return this.reduceStream(AsyncReducer.fold(init, next)); } async reduce(shape) { const reducerInstance = (await AsyncReducer.combine(shape).compile()); const done = Symbol('Done'); let value = done; const iter = this[Symbol.asyncIterator](); try { while (!reducerInstance.halted && done !== (value = await iter.fastNext(done))) { await reducerInstance.next(value); } return await reducerInstance.getOutput(); } finally { await closeIters(iter); await reducerInstance.onClose(); } } reduceStream(shape) { const reducer = AsyncReducer.combine(shape); return new AsyncReduceStream(this, reducer); } async toArray() { const iterator = this[Symbol.asyncIterator](); const result = []; const done = Symbol('Done'); let value; try { while (done !== (value = await iterator.fastNext(done))) { result.push(value); } return result; } catch (err) { await closeIters(iterator); throw err; } } toString() { return `AsyncStream(...<potentially empty>)`; } async toJSON() { return { dataType: 'AsyncStream', value: await this.toArray(), }; } } export class AsyncFromStream extends AsyncStreamBase { constructor(createIterator) { super(); this[_a] = undefined; this[Symbol.asyncIterator] = createIterator; } } _a = Symbol.asyncIterator; class AsyncPrependStream extends AsyncStreamBase { constructor(source, item) { super(); this.source = source; this.item = item; } [Symbol.asyncIterator]() { return new AsyncPrependIterator(this.source[Symbol.asyncIterator](), this.item); } async first() { return AsyncOptLazy.toPromise(this.item); } async last() { return this.source.last(this.item); } async count() { return (await this.source.count()) + 1; } async forEach(f, options = {}) { const { state = TraverseState() } = options; if (state.halted) return; await f(await AsyncOptLazy.toMaybePromise(this.item), state.nextIndex(), state.halt); if (state.halted) return; await this.source.forEach(f, { state }); } mapPure(mapFun, ...args) { return new AsyncPrependStream(this.source.mapPure(mapFun, ...args), async () => mapFun(await AsyncOptLazy.toMaybePromise(this.item), ...args)); } take(amount) { if (amount <= 0) { return emptyAsyncStream; } if (amount === 1) { return AsyncStreamConstructorsImpl.of(this.item); } return new AsyncPrependStream(this.source.take(amount - 1), this.item); } drop(amount) { if (amount <= 0) { return this; } if (amount === 1) { return this.source; } return this.source.drop(amount - 1); } async minBy(compare) { const token = Symbol(); const result = await this.source.minBy(compare, token); const itemValue = await AsyncOptLazy.toMaybePromise(this.item); if (token === result) { return itemValue; } return compare(result, itemValue) <= 0 ? result : itemValue; } async maxBy(compare) { const token = Symbol(); const result = await this.source.maxBy(compare, token); const itemValue = await AsyncOptLazy.toMaybePromise(this.item); if (token === result) { return itemValue; } return compare(result, itemValue) > 0 ? result : itemValue; } async toArray() { const result = await this.source.toArray(); result.unshift(await AsyncOptLazy.toMaybePromise(this.item)); return result; } } class AsyncAppendStream extends AsyncStreamBase { constructor(source, item) { super(); this.source = source; this.item = item; } [Symbol.asyncIterator]() { return new AsyncAppendIterator(this.source[Symbol.asyncIterator](), this.item); } first() { return this.source.first(this.item); } last() { return AsyncOptLazy.toPromise(this.item); } async count() { return (await this.source.count()) + 1; } async forEach(f, options = {}) { const { state = TraverseState() } = options; if (state.halted) return; await this.source.forEach(f, { state }); if (state.halted) return; await f(await AsyncOptLazy.toMaybePromise(this.item), state.nextIndex(), state.halt); } mapPure(mapFun, ...args) { return new AsyncAppendStream(this.source.mapPure(mapFun, ...args), async () => mapFun(await AsyncOptLazy.toMaybePromise(this.item), ...args)); } async minBy(compare) { const token = Symbol(); const result = await this.source.minBy(compare, token); const itemValue = await AsyncOptLazy.toMaybePromise(this.item); if (token === result) { return itemValue; } return compare(result, itemValue) <= 0 ? result : itemValue; } async maxBy(compare) { const token = Symbol(); const result = await this.source.maxBy(compare, token); const itemValue = await AsyncOptLazy.toMaybePromise(this.item); if (token === result) { return itemValue; } return compare(result, itemValue) > 0 ? result : itemValue; } async toArray() { const result = await this.source.toArray(); result.push(await AsyncOptLazy.toMaybePromise(this.item)); return result; } } class AsyncIndexedStream extends AsyncStreamBase { constructor(source, startIndex) { super(); this.source = source; this.startIndex = startIndex; } [Symbol.asyncIterator]() { return new AsyncIndexedIterator(this.source[Symbol.asyncIterator](), this.startIndex); } count() { return this.source.count(); } } class AsyncMapStream extends AsyncStreamBase { constructor(source, mapFun) { super(); this.source = source; this.mapFun = mapFun; } [Symbol.asyncIterator]() { return new AsyncMapIterator(this.source[Symbol.asyncIterator](), this.mapFun); } async first(otherwise) { const done = Symbol('Done'); const value = await this.source.first(done); if (done === value) return AsyncOptLazy.toPromise(otherwise); return this.mapFun(value, 0); } async last(otherwise) { const done = Symbol('Done'); const value = await this.source.last(done); if (done === value) return AsyncOptLazy.toPromise(otherwise); return this.mapFun(value, 0); } async count() { return this.source.count(); } async elementAt(index, otherwise) { const done = Symbol('Done'); const value = await this.source.elementAt(index, done); if (done === value) return AsyncOptLazy.toPromise(otherwise); return this.mapFun(value, index); } map(mapFun) { return new AsyncMapStream(this.source, async (value, index) => mapFun(await this.mapFun(value, index), index)); } take(amount) { if (amount <= 0) { return emptyAsyncStream; } return new AsyncMapStream(this.source.take(amount), this.mapFun); } drop(amount) { if (amount <= 0) { return this; } return new AsyncMapStream(this.source.drop(amount), this.mapFun); } } class AsyncMapPureStream extends AsyncStreamBase { constructor(source, mapFun, args) { super(); this.source = source; this.mapFun = mapFun; this.args = args; } [Symbol.asyncIterator]() { return new AsyncMapPureIterator(this.source[Symbol.asyncIterator](), this.mapFun, this.args); } async first(otherwise) { const done = Symbol('Done'); const value = await this.source.first(done); if (done === value) return AsyncOptLazy.toPromise(otherwise); return this.mapFun(value, ...this.args); } async last(otherwise) { const done = Symbol('Done'); const value = await this.source.last(done); if (done === value) return AsyncOptLazy.toPromise(otherwise); return this.mapFun(value, ...this.args); } async count() { return this.source.count(); } async elementAt(index, otherwise) { const done = Symbol('Done'); const value = await this.source.elementAt(index, done); if (done === value) return AsyncOptLazy.toPromise(otherwise); return this.mapFun(value, ...this.args); } mapPure(mapFun, ...args) { return new AsyncMapPureStream(this.source, async (value, ...args) => mapFun(await this.mapFun(value, ...this.args), ...args), args); } take(amount) { if (amount <= 0) { return emptyAsyncStream; } return new AsyncMapPureStream(this.source.take(amount), this.mapFun, this.args); } drop(amount) { if (amount <= 0) { return this; } return new AsyncMapPureStream(this.source.drop(amount), this.mapFun, this.args); } } class AsyncConcatStream extends AsyncStreamBase { constructor(source, otherSources) { super(); this.source = source; this.otherSources = otherSources; } [Symbol.asyncIterator]() { return new AsyncConcatIterator(this.source, this.otherSources, asyncStreamSourceHelpers); } async forEach(f, options = {}) { const { state = TraverseState() } = options; if (state.halted) return; await this.source.forEach(f, { state }); let sourceIndex = -1; const sources = this.otherSources; const length = sources.length; while (!state.halted && ++sourceIndex < length) { const source = sources[sourceIndex]; if (!isEmptyAsyncStreamSourceInstance(source)) { await fromAsyncStreamSource(source).forEach(f, { state }); } } } async forEachPure(f, ...args) { await this.source.forEachPure(f, ...args); let sourceIndex = -1; const sources = this.otherSources; const length = sources.length; while (++sourceIndex < length) { const source = sources[sourceIndex]; if (!isEmptyAsyncStreamSourceInstance(source)) { await fromAsyncStreamSource(source).forEachPure(f, ...args); } } } async last(otherwise) { const sources = this.otherSources; let sourceIndex = sources.length; while (--sourceIndex >= 0) { const source = sources[sourceIndex]; if (!isEmptyAsyncStreamSourceInstance(source)) { const done = Symbol('Done'); const value = await fromAsyncStreamSource(source).last(done); if (done !== value) return value; } } return this.source.last(otherwise); } async count() { let result = await this.source.count(); const sources = this.otherSources; const length = sources.length; let sourceIndex = -1; while (++sourceIndex < length) { const source = sources[sourceIndex]; if (!isEmptyAsyncStreamSourceInstance(source)) { result += await fromAsyncStreamSource(source).count(); } } return result; } filterPure(options, ...args) { return new AsyncConcatStream(this.source.filterPure(options, ...args), this.otherSources.map((source) => fromAsyncStreamSource(source).filterPure(options, ...args))); } mapPure(mapFun, ...args) { return new AsyncConcatStream(this.source.mapPure(mapFun, ...args), this.otherSources.map((source) => fromAsyncStreamSource(source).mapPure(mapFun, ...args))); } concat(...others2) { return new AsyncConcatStream(this.source, this.otherSources.concat(others2)); } async toArray() { let result = await this.source.toArray(); let sourceIndex = -1; const sources = this.otherSources; const length = sources.length; while (++sourceIndex < length) { const source = sources[sourceIndex]; if (!isEmptyAsyncStreamSourceInstance(source)) { result = result.concat(await fromAsyncStreamSource(source).toArray()); } } return result; } } class AsyncFilterStream extends AsyncStreamBase { constructor(source, pred, negate = false) { super(); this.source = source; this.pred = pred; this.negate = negate; } [Symbol.asyncIterator]() { return new AsyncFilterIterator(this.source[Symbol.asyncIterator](), this.pred, this.negate); } filterPure(options, ...args) { const { pred, negate = false } = options; const { pred: thisPred, negate: thisNegate } = this; return new AsyncFilterStream(this.source, async (value, index, halt) => (await thisPred(value, index, halt)) !== thisNegate && (await pred(value, ...args)) !== negate); } mapPure(mapFun, ...args) { const { pred, negate } = this; return new AsyncCollectStream(this.source, async (value, index, skip, halt) => (await pred(value, index, halt)) !== negate ? mapFun(value, ...args) : skip); } } class AsyncFilterPureStream extends AsyncStreamBase { constructor(source, pred, args, negate = false) { super(); this.source = source; this.pred = pred; this.args = args; this.negate = negate; } [Symbol.asyncIterator]() { return new AsyncFilterPureIterator(this.source[Symbol.asyncIterator](), this.pred, this.args, this.negate); } filterPure(options, ...args) { const { pred, negate = false } = options; const thisPred = this.pred; const thisArgs = this.args; const thisNegate = this.negate; return new AsyncFilterPureStream(this.source, async (value, ...args) => { return ((await thisPred(value, ...thisArgs)) !== thisNegate && (await pred(value, ...args)) !== negate); }, args); } mapPure(mapFun, ...args) { const { pred, negate, args: thisArgs } = this; return new AsyncCollectStream(this.source, async (value, _, skip) => (await pred(value, ...thisArgs)) !== negate ? mapFun(value, ...args) : skip); } } class AsyncCollectStream extends AsyncStreamBase { constructor(source, collectFun) { super(); this.source = source; this.collectFun = collectFun; } [Symbol.asyncIterator]() { return new AsyncCollectIterator(this.source[Symbol.asyncIterator](), this.collectFun); } filterPure(options, ...args) { const { pred, negate = false } = options; const { collectFun } = this; return new AsyncCollectStream(this.source, async (value, index, skip, halt) => { const result = await collectFun(value, index, skip, halt); if (skip === result || (await pred(result, ...args)) === negate) { return skip; } return result; }); } mapPure(mapFun, ...args) { const { collectFun } = this; return new AsyncCollectStream(this.source, async (value, index, skip, halt) => { const result = await collectFun(value, index, skip, halt); if (skip === result) { return skip; } return mapFun(result, ...args); }); } } class AsyncDropWhileStream extends AsyncStreamBase { constructor(source, pred, negate) { super(); this.source = source; this.pred = pred; this.negate = negate; } [Symbol.asyncIterator]() { return new AsyncDropWhileIterator(this.source[Symbol.asyncIterator](), this.pred, this.negate); } } class AsyncTakeStream extends AsyncStreamBase { constructor(source, amount) { super(); this.source = source; this.amount = amount; } [Symbol.asyncIterator]() { return new AsyncTakeIterator(this.source[Symbol.asyncIterator](), this.amount); } take(amount) { if (amount <= 0) { return emptyAsyncStream; } if (amount >= this.amount) { return this; } return this.source.take(amount); } } class AsyncDropStream extends AsyncStreamBase { constructor(source, amount) { super(); this.source = source; this.amount = amount; } [Symbol.asyncIterator]() { return new AsyncDropIterator(this.source[Symbol.asyncIterator](), this.amount); } drop(amount) { if (amount <= 0) { return this; } return this.source.drop(this.amount + amount); } } class AsyncReduceStream extends AsyncStreamBase { constructor(source, reducer) { super(); this.source = source; this.reducer = reducer; } [Symbol.asyncIterator]() { return new AsyncReduceIterator(this.source[Symbol.asyncIterator](), this.reducer); } } export class AsyncTransformerStream extends AsyncStreamBase { constructor(source, transformer) { super(); this.source = source; this.transformer = transformer; } [Symbol.asyncIterator]() { return new AsyncTransformerFastIterator(this.source[Symbol.asyncIterator](), this.transformer); } } export class AsyncOfStream extends AsyncStreamBase { constructor(values) { super(); this.values = values; } [Symbol.asyncIterator]() { return new AsyncOfIterator(this.values); } } export function isAsyncStream(obj) { return obj instanceof AsyncStreamBase; } class AsyncEmptyStream extends AsyncStreamBase { [Symbol.asyncIterator]() { return emptyAsyncFastIterator; } asyncStream() { return this; } async equals(other) { if (other === this) return true; const done = Symbol('done'); return (done === fromAsyncStreamSource(other)[Symbol.asyncIterator]().fastNext(done)); } prepend(value) { return AsyncStreamConstructorsImpl.of(value); } append(value) { return AsyncStreamConstructorsImpl.of(value); } assumeNonEmpty() { RimbuError.throwEmptyCollectionAssumedNonEmptyError(); } async forEach() { // } async forEachPure() { // } indexed() { return this; } map() { return this; } mapPure() { return this; } flatMap() { return this; } flatZip() { return this; } transform(transformer) { return fromAsyncStreamSource(async () => { const instance = await transformer.compile(); return instance.getOutput(); }); } filter() { return this; } filterPure() { return this; } collect() { return this; } first(otherwise) { return AsyncOptLazy.toPromise(otherwise); } last(otherwise) { return AsyncOptLazy.toPromise(otherwise); } single(otherwise) { return AsyncOptLazy.toPromise(otherwise); } async count() { return 0; } async countElement() { return 0; } async countNotElement() { return 0; } find(pred, options = {}) { const { otherwise } = options; return AsyncOptLazy.toPromise(otherwise); } elementAt(index, otherwise) { return AsyncOptLazy.toPromise(otherwise); } indicesWhere() { return this; } indicesOf() { return this; } async indexWhere() { return undefined; } async indexOf() { return undefined; } async some() { return false; } async every() { return true; } async contains() { return false; } async containsSlice() { return false; } takeWhile() { return this; } dropWhile() { return this; } take() { return this; } drop() { return this; } repeat() { return this; } concat(...others) { if (others.every(isEmptyAsyncStreamSourceInstance)) return this; const [source1, source2, ...sources] = others; if (undefined === source2) return source1; return fromAsyncStreamSource(source1).concat(source2, ...sources); } min(otherwise) { return AsyncOptLazy.toPromise(otherwise); } minBy(compare, otherwise) { return AsyncOptLazy.toPromise(otherwise); } max(otherwise) { return AsyncOptLazy.toPromise(otherwise); } maxBy(compare, otherwise) { return AsyncOptLazy.toPromise(otherwise); } intersperse() { return this; } async join({ start = '', end = '', ifEmpty = undefined, } = {}) { return undefined !== ifEmpty ? ifEmpty : start.concat(end); } mkGroup({ start = emptyAsyncStream, end = emptyAsyncStream, } = {}) { return fromAsyncStreamSource(start).concat(end); } splitOn() { return this; } splitWhere() { return this; } splitOnSlice() { return this; } distinctPrevious() { return this; } window() { return this; } fold(init) { return AsyncOptLazy.toPromise(init); } foldStream() { return this; } async reduce(shape) { const reducer = AsyncReducer.combine(shape); const instance = await reducer.compile(); return instance.getOutput(); } reduceStream() { return this; } async toArray() { return []; } toString() { return `AsyncStream(<empty>)`; } async toJSON() { return { dataType: 'AsyncStream', value: [], }; } } export class FromSource extends AsyncStreamBase { constructor(source, close) { super(); this.source = source; this.close = close; } [Symbol.asyncIterator]() { return asyncStreamSourceToIterator(this.source, this.close); } } export class FromResource extends AsyncStreamBase { constructor(open, createSource, close) { super(); this.open = open; this.createSource = createSource; this.close = close; } [Symbol.asyncIterator]() { return new FromResourceIterator(this.open, this.createSource, this.close, asyncStreamSourceHelpers); } } export const emptyAsyncStream = Object.freeze(new AsyncEmptyStream()); export function isEmptyAsyncStreamSourceInstance(source) { return (source === emptyAsyncStream || isEmptyStreamSourceInstance(source)); } export function asyncStreamSourceToIterator(source, close) { if (source instanceof Function) { return new FromPromise(source, asyncStreamSourceHelpers, close); } if (isEmptyAsyncStreamSourceInstance(source)) { return emptyAsyncFastIterator; } if (typeof source === 'string') { return new FromIterator(source[Symbol.iterator](), close); } if (typeof source === 'object') { if (Symbol.asyncIterator in source) { const iterator = source[Symbol.asyncIterator](); if (isAsyncFastIterator(iterator)) { if (undefined === close) { return iterator; } if (undefined === iterator.return) { iterator.return = close; return iterator; } const oldReturn = iterator.return; iterator.return = () => Promise.all([oldReturn, close]); return iterator; } return new FromAsyncIterator(iterator, close); } if (`asyncStream` in source) { return asyncStreamSourceToIterator(source.asyncStream(), close); } if (Symbol.iterator in source) { return new FromIterator(source[Symbol.iterator](), close); } } throw Error('unknown async stream source'); } // prettier-ignore export const fromAsyncStreamSource = (source) => { if (undefined === source) return emptyAsyncStream; if (isAsyncStream(source)) return source; if (isEmptyAsyncStreamSourceInstance(source)) return emptyAsyncStream; return new FromSource(source); }; const asyncStreamSourceHelpers = { fromAsyncStreamSource, isEmptyAsyncStreamSourceInstance, }; export const AsyncStreamConstructorsImpl = Object.freeze({ of(...values) { return new AsyncOfStream(values); }, from(...sources) { const [first, ...rest] = sources; if (rest.length <= 0) { return fromAsyncStreamSource(first); } const [rest1, ...restOther] = rest; return fromAsyncStreamSource(first).concat(rest1, ...restOther); }, fromResource(options) { const { open, createSource, close } = options; return new FromResource(open, createSource, close); }, zipWith(...sources) { return (zipFun) => { if (sources.some(isEmptyAsyncStreamSourceInstance)) { return emptyAsyncStream; } return new AsyncFromStream(() => new AsyncZipWithIterator(sources, zipFun, asyncStreamSourceHelpers)); }; }, zip(...sources) { return AsyncStreamConstructorsImpl.zipWith(...sources)(Array); }, zipAllWith(...sources) { return (fillValue, zipFun) => { if (sources.every(isEmptyAsyncStreamSourceInstance)) { return emptyAsyncStream; } return new AsyncFromStream(() => new AsyncZipAllWithItererator(fillValue, sources, zipFun, asyncStreamSourceHelpers)); }; }, zipAll(fillValue, ...sources) { return AsyncStreamConstructorsImpl.zipAllWith(...sources)(fillValue, Array); }, flatten(source) { return fromAsyncStreamSource(source).flatMap((s) => s); }, unzip(source, options) { const { length } = options; if (isEmptyAsyncStreamSourceInstance(source)) { return StreamConstructorsImpl.of(emptyAsyncStream) .repeat(length) .toArray(); } const result = []; let i = -1; while (++i < length) { const index = i; result[i] = source.map((t) => t[index]); } return result; }, empty() { return emptyAsyncStream; }, always(value) { return AsyncStreamConstructorsImpl.of(value).repeat(); }, unfold(init, next) { return new AsyncFromStream(() => new AsyncUnfoldIterator(init, next)); }, }); //# sourceMappingURL=async-stream-custom.mjs.map