@rimbu/stream
Version:
Efficient structure representing a sequence of elements, with powerful operations for TypeScript
1,360 lines • 43.6 kB
JavaScript
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