@rimbu/stream
Version:
Efficient structure representing a sequence of elements, with powerful operations for TypeScript
705 lines (704 loc) • 37.5 kB
text/typescript
import { AsyncOptLazy, Eq, ErrBase, type AsyncCollectFun, type MaybePromise } from '@rimbu/common';
import { Reducer, type AsyncStreamSource } from '@rimbu/stream';
/**
* An `AsyncReducer` is a stand-alone asynchronous calculation that takes input values of type I,
* and, when requested, produces an output value of type O.
* @typeparam I - the input value type
* @typeparam O - the output value type
*/
export type AsyncReducer<I, O = I> = AsyncReducer.Impl<I, O, unknown>;
export declare namespace AsyncReducer {
/**
* Convenience type to allow synchronous reducers to be supplied to functions that accept async reducers.
* @typeparam I - the input type
* @typeparam O - the output type
*/
type Accept<I, O> = AsyncReducer<I, O> | Reducer<I, O>;
/**
* The AsyncReducer implementation interface defining the required methods.
* @typeparam I - the input type
* @typeparam O - the output type
* @typeparam S - the state type
*/
interface Impl<I, O, S> {
/**
* The initial state value for the reducer algorithm.
* @param initHalt - a callback function that, if called, indicates that the reducer does not accept any input.
*/
readonly init: (initHalt: () => void) => MaybePromise<S>;
/**
* Returns the next state based on the given input values
* @param state - the current state
* @param elem - the current input value
* @param index - the current input index
* @param halt - a function that, when called, ensures no more values are passed to the reducer
*/
next(state: S, elem: I, index: number, halt: () => void): MaybePromise<S>;
/**
* Returns the output value based on the given `state`
* @param state - the current state
* @param index - the value index
* @param halted - a boolean indicating whether the reducer is halted
*/
stateToResult(state: S, index: number, halted: boolean): MaybePromise<O>;
/**
* An optional function that is called when the reducer will no longer receive values.
* @param state - the final reducer state
* @param error - (optional) if an error has occured, it ix passed here
*/
onClose?: ((state: S, error?: unknown) => MaybePromise<void>) | undefined;
/**
* Returns an `AsyncReducer` instance that only passes values to the reducer that satisy the given `pred` predicate.
* @param pred - a potaentially asynchronous function that returns true if the value should be passed to the reducer based on the following inputs:<br/>
* - value: the current input value<br/>
* - index: the current input index<br/>
* - halt: function that, when called, ensures no more new values are passed to the reducer
* @param options - (optional) an object containing the following properties:<br/>
* - negate: (default: false) when true will invert the given predicate
* @note if the predicate is a type guard, the return type is automatically inferred
* @example
* ```ts
* AsyncReducer
* .createMono(0, async (c, v) => c + v)
* .filterInput(async v => v > 10)
* // this reducer will only sum values larger than 10
* ```
*/
filterInput<IF extends I>(pred: (value: I, index: number, halt: () => void) => value is IF, options?: {
negate?: false | undefined;
}): AsyncReducer<IF, O>;
filterInput<IF extends I>(pred: (value: I, index: number, halt: () => void) => value is IF, options: {
negate: true;
}): AsyncReducer<Exclude<I, IF>, O>;
filterInput(pred: (value: I, index: number, halt: () => void) => MaybePromise<boolean>, options?: {
negate?: boolean | undefined;
}): AsyncReducer<I, O>;
/**
* Returns an `AsyncReducer` instance that converts its input values using given `mapFun` before passing them to the reducer.
* @param mapFun - a potentially asynchronous function that returns a new value to pass to the reducer based on the following inputs:<br/>
* - value: the current input value<br/>
* - index: the current input index
* @typeparam I2 - the new input type
* @example
* ```ts
* AsyncReducer
* .createMono(0, async (c, v) => c + v)
* .mapInput(async v => v * 2)
* // this reducer will double all input values before summing them
* ```
*/
mapInput: <I2>(mapFun: (value: I2, index: number) => MaybePromise<I>) => AsyncReducer<I2, O>;
/**
* Returns an `AsyncReducer` instance that converts its input values using given `flatMapFun` before passing them to the reducer.
* @param flatMapFun - a potentially asynchronous function that returns am arbitrary number of new values to pass to the reducer based on the following inputs:<br/>
* - value: the current input value<br/>
* - index: the current input index
* @typeparam I2 - the new input type
* @example
* ```ts
* AsyncReducer
* .createMono(0, async (c, v) => c + v)
* .flatMapInput(async v => [v, v])
* // this reducer will include all input values twice before summing them
* ```
*/
flatMapInput<I2>(flatMapFun: (value: I2, index: number) => MaybePromise<AsyncStreamSource<I>>): AsyncReducer<I2, O>;
/**
* Returns an `AsyncReducer` instance that converts or filters its input values using given `collectFun` before passing them to the reducer.
* @typeparam I2 - the new input type
* @param collectFun - a (potentially async) function receiving<br/>
* - `value`: the next value<br/>
* - `index`: the value index<br/>
* - `skip`: a token that, when returned, will not add a value to the resulting collection<br/>
* - `halt`: a function that, when called, ensures no next elements are passed
* @example
* ```ts
* AsyncReducer
* .createMono(0, async (c, v) => c + v)
* .collectInput(async (v, _, skip) => v <= 10 ? skip : v * 2)
* // this reducer will double all input values larger thant 10 before summing them,
* // and will skip all values smaller than 10
* ```
*/
collectInput<I2>(collectFun: AsyncCollectFun<I2, I>): AsyncReducer<I2, O>;
/**
* Returns an `AsyncReducer` instance that converts its output values using given `mapFun`.
* @param mapFun - a potentially asynchronous function that takes the current output value and converts it to a new output value
* @typeparam O2 - the new output type
* @example
* ```ts
* AsyncReducer
* .createMono(0, async (c, v) => c + v)
* .mapOutput(async v => String(v))
* // this reducer will convert all its results to string before returning them
* ```
*/
mapOutput<O2>(mapFun: (value: O, index: number, halted: boolean) => MaybePromise<O2>): AsyncReducer<I, O2>;
/**
* Returns an `AsyncReducer` instance that takes at most the given `amount` of input elements, and will ignore subsequent elements.
* @param amount - the amount of elements to accept
* @example
* ```ts
* await AsyncStream
* .from(Stream.range({ end: 10 }))
* .reduce(
* AsyncReducer
* .createMono(0, async (c, v) => c + v)
* .takeInput(2)
* )
* // => 1
* ```
*/
takeInput(amount: number): AsyncReducer<I, O>;
/**
* Returns an `AsyncReducer` instance that skips the first given `amount` of input elements, and will process subsequent elements.
* @param amount - the amount of elements to skip
* @example
* ```ts
* await AsyncStream
* .from(Stream.range({ end: 10 }))
* .reduce(
* AsyncReducer
* .createMono(0, async (c, v) => c + v)
* .dropInput(9)
* )
* // => 19
* ```
*/
dropInput(amount: number): AsyncReducer<I, O>;
/**
* Returns an `AsyncReducer` instance that takes given `amount` of elements starting at given `from` index, and ignores other elements.
* @param from - (default: 0) the index at which to start processing elements
* @param amount - (optional) the amount of elements to process, if not given, processes all elements from the `from` index
* @example
* ```ts
* await AsyncStream
* .from(Stream.range({ end: 10 }))
* .reduce(
* AsyncReducer
* .createMono(0, async (c, v) => c + v)
* .sliceInput(1, 2)
* )
* // => 3
* ```
*/
sliceInput(from?: number | undefined, amount?: number | undefined): AsyncReducer<I, O>;
/**
* Returns an 'AsyncReducer` instance that produces at most `amount` values.
* @param amount - the maximum amount of values to produce.
*/
takeOutput(amount: number): AsyncReducer<I, O>;
/**
* Returns an 'AsyncReducer` instance that produces until the given `pred` predicate returns true for
* the output value.
* @param pred - a potaentially asynchronous function that returns true if the value should be passed to the reducer based on the following inputs:<br/>
* - value: the current input value<br/>
* - index: the current input index<br/>
* - halt: function that, when called, ensures no more new values are passed to the reducer
* @param options - (optional) an object containing the following properties:<br/>
* - negate: (default: false) when true will invert the given predicate
*/
takeOutputUntil(pred: (value: O, index: number) => MaybePromise<boolean>, options?: {
negate?: boolean | undefined;
}): AsyncReducer<I, O>;
/**
* Returns a reducer that applies the given `nextReducers` sequentially after this reducer
* has halted, and moving on to the next provided reducer until it is halted. Optionally, it provides the last output
* value of the previous reducer.
* @param nextReducers - an number of reducers consuming and producing the same types as the current reducer.
* @example
* ```ts
* const result = await AsyncStream.range({ amount: 6 })
* .reduce(
* Reducer.sum
* .takeInput(3)
* .chain(
* v => v > 10 ? Reducer.product : Reducer.sum
* )
* )
* console.log(result)
* // => 21
* ```
*/
chain<O2 extends O>(nextReducers: AsyncStreamSource<AsyncOptLazy<AsyncReducer.Accept<I, O2>, [O2]>>): AsyncReducer<I, O2>;
/**
* Returns a promise that resolves to a 'runnable' instance of the current reducer specification. This instance maintains its own state
* and indices, so that the instance only needs to be provided the input values, and output values can be
* retrieved when needed. The state is kept private.
* @example
* ```ts
* const reducer = AsyncReducer.from(Reducer.sum.mapOutput(v => v * 2));
* const instance = reducer.compile();
* await instance.next(3);
* await instance.next(5);
* console.log(await instance.getOutput());
* // => 16
* ```
*/
compile(): Promise<AsyncReducer.Instance<I, O>>;
}
/**
* A base class that can be used to easily create `AsyncReducer` instances.
* @typeparam I - the input value type
* @typeparam O - the output value type
* @typeparam S - the internal state type
*/
class Base<I, O, S> implements AsyncReducer.Impl<I, O, S> {
readonly init: (initHalt: () => void) => MaybePromise<S>;
readonly next: (state: S, elem: I, index: number, halt: () => void) => MaybePromise<S>;
readonly stateToResult: (state: S, index: number, halted: boolean) => MaybePromise<O>;
readonly onClose?: ((state: S, error?: unknown) => MaybePromise<void>) | undefined;
constructor(init: (initHalt: () => void) => MaybePromise<S>, next: (state: S, elem: I, index: number, halt: () => void) => MaybePromise<S>, stateToResult: (state: S, index: number, halted: boolean) => MaybePromise<O>, onClose?: ((state: S, error?: unknown) => MaybePromise<void>) | undefined);
filterInput(pred: (value: I, index: number, halt: () => void) => MaybePromise<boolean>, options?: {
negate?: boolean | undefined;
}): any;
mapInput<I2>(mapFun: (value: I2, index: number) => MaybePromise<I>): AsyncReducer<I2, O>;
flatMapInput<I2>(flatMapFun: (value: I2, index: number) => MaybePromise<AsyncStreamSource<I>>): AsyncReducer<I2, O>;
collectInput<I2>(collectFun: AsyncCollectFun<I2, I>): AsyncReducer<I2, O>;
mapOutput<O2>(mapFun: (value: O, index: number, halted: boolean) => MaybePromise<O2>): AsyncReducer<I, O2>;
takeOutput(amount: number): AsyncReducer<I, O>;
takeOutputUntil(pred: (value: O, index: number) => MaybePromise<boolean>, options?: {
negate?: boolean;
}): AsyncReducer<I, O>;
takeInput(amount: number): AsyncReducer<I, O>;
dropInput(amount: number): AsyncReducer<I, O>;
sliceInput(from?: number, amount?: number): AsyncReducer<I, O>;
chain<O2 extends O>(nextReducers: AsyncStreamSource<AsyncOptLazy<AsyncReducer.Accept<I, O2>, [O2]>>): AsyncReducer<I, O2>;
compile(): Promise<AsyncReducer.Instance<I, O>>;
}
/**
* An async reducer instance that manages its own state based on the reducer definition that
* was used to create this instance.
* @typeparam I - the input element type
* @typeparam O - the output element type
*/
interface Instance<I, O> {
/**
* Returns true if the reducer instance does not receive any more values, false otherwise.
*/
get halted(): boolean;
/**
* Returns the index of the last received value.
*/
get index(): number;
/**
* Method that, when called, halts the reducer instance so that it will no longer receive values.
*/
halt(): void;
/**
* Sends a new value into the reducer instance.
* @param value - the next input value
*/
next(value: I): MaybePromise<void>;
/**
* Returns the output value based on the current given input values.
*/
getOutput(): MaybePromise<O>;
/**
* Closes any resources that may have been opened.
* @param err - (optional) if an error occurrerd it can be supplied
*/
onClose(err?: unknown): Promise<void>;
}
/**
* The default `AsyncReducer.Impl` implementation.
* @typeparam I - the input element type
* @typeparam O - the output element type
* @typeparam S - the reducer state type
*/
class InstanceImpl<I, O, S> implements AsyncReducer.Instance<I, O> {
#private;
readonly reducer: AsyncReducer.Impl<I, O, S>;
constructor(reducer: AsyncReducer.Impl<I, O, S>);
initialize(): Promise<void>;
halt: () => void;
get halted(): boolean;
get index(): number;
next: (value: I) => Promise<void>;
getOutput(): Promise<O>;
onClose(err?: unknown): Promise<void>;
}
/**
* Returns an `AsyncReducer` with the given options:
* @param init - the optionally lazy and/or promised initial state value
* @param next - returns (potentially asynchronously) the next state value based on the given inputs:<br/>
* - current: the current state<br/>
* - next: the current input value<br/>
* - index: the input index value<br/>
* - halt: function that, when called, ensures no more elements are passed to the reducer
* @param stateToResult - a potentially asynchronous function that converts the current state to an output value
* @param onClose - (optional) a function that will be called when the reducer will no longer receive values
* @typeparam I - the input value type
* @typeparam O - the output value type
* @typeparam S - the internal state type
*/
function create<I, O = I, S = O>(init: (initHalt: () => void) => MaybePromise<S>, next: (current: S, next: I, index: number, halt: () => void) => MaybePromise<S>, stateToResult: (state: S, index: number, halted: boolean) => MaybePromise<O>, onClose?: (state: S, error?: unknown) => MaybePromise<void>): AsyncReducer<I, O>;
/**
* Returns an `AsyncReducer` of which the input, state, and output types are the same.
* @param init - the optionally lazy and/or promised initial state value
* @param next - returns (potentially asynchronously) the next state value based on the given inputs:<br/>
* - current: the current state<br/>
* - next: the current input value<br/>
* - index: the input index value<br/>
* - halt: function that, when called, ensures no more elements are passed to the reducer
* @param stateToResult - a potentially asynchronous function that converts the current state to an output value
* @param onClose - (optional) a function that will be called when the reducer will no longer receive values
* @typeparam T - the overall value type
*/
function createMono<T>(init: (initHalt: () => void) => MaybePromise<T>, next: (current: T, next: T, index: number, halt: () => void) => MaybePromise<T>, stateToResult?: (state: T, index: number, halted: boolean) => MaybePromise<T>, onClose?: (state: T, error?: unknown) => MaybePromise<void>): AsyncReducer<T>;
/**
* Returns an `AsyncReducer` of which the state and output types are the same.
* @param init - the optionally lazy and/or promised initial state value
* @param next - returns (potentially asynchronously) the next state value based on the given inputs:<br/>
* - current: the current state<br/>
* - next: the current input value<br/>
* - index: the input index value<br/>
* - halt: function that, when called, ensures no more elements are passed to the reducer
* @param stateToResult - a potentially asynchronous function that converts the current state to an output value
* @param onClose - (optional) a function that will be called when the reducer will no longer receive values
* @typeparam I - the input value type
* @typeparam O - the output value type
*/
function createOutput<I, O = I>(init: (initHalt: () => void) => MaybePromise<O>, next: (current: O, next: I, index: number, halt: () => void) => MaybePromise<O>, stateToResult?: (state: O, index: number, halted: boolean) => MaybePromise<O>, onClose?: (state: O, error?: unknown) => MaybePromise<void>): AsyncReducer<I, O>;
/**
* Returns an `AsyncReducer` that uses the given `init` and `next` values to fold the input values into
* result values.
* @param init - an (optionally lazy) initial result value
* @param next - a (potentially async) function taking the following arguments:<br/>
* - current - the current result value<br/>
* - value - the next input value<br/>
* - index: the input index value<br/>
* - halt: function that, when called, ensures no more elements are passed to the reducer
* @typeparam T - the input type
* @typeparam R - the output type
*/
function fold<T, R>(init: AsyncOptLazy<R>, next: (current: R, value: T, index: number, halt: () => void) => MaybePromise<R>): AsyncReducer<T, R>;
/**
* Returns an `AsyncReducer` from a given `Reducer` or `AsyncReducer` instance.
* @param reducer - the input reducer to convert
* @typeparam I - the input element type
* @typeparam O - the output element type
*/
function from<I, O>(reducer: AsyncReducer.Accept<I, O>): AsyncReducer<I, O>;
/**
* Returns a `Reducer` that remembers the minimum value of the inputs using the given `compFun` to compare input values
* @param compFun - a comparison function for two input values, returning 0 when equal, positive when greater, negetive when smaller
* @param otherwise - (default: undefineds) a fallback value when there were no input values given
* @typeparam T - the element type
* @typeparam O - the fallback value type
* @example
* ```ts
* const stream = Stream.of('abc', 'a', 'abcde', 'ab')
* console.log(stream.minBy((s1, s2) => s1.length - s2.length))
* // 'a'
* ```
*/
const minBy: {
<T>(compFun: (v1: T, v2: T) => MaybePromise<number>): AsyncReducer<T, T | undefined>;
<T, O>(compFun: (v1: T, v2: T) => MaybePromise<number>, otherwise: AsyncOptLazy<O>): AsyncReducer<T, T | O>;
};
/**
* Returns a `Reducer` that remembers the minimum value of the numberic inputs.
* @param otherwise - (default: undefined) a fallback value when there were no input values given
* @typeparam O - the fallback value type
* @example
* ```ts
* console.log(Stream.of(5, 3, 7, 4).reduce(Reducer.min()))
* // => 3
* ```
*/
const min: {
(): AsyncReducer<number, number | undefined>;
<O>(otherwise: AsyncOptLazy<O>): AsyncReducer<number, number | O>;
};
/**
* Returns a `Reducer` that remembers the maximum value of the inputs using the given `compFun` to compare input values
* @param compFun - a comparison function for two input values, returning 0 when equal, positive when greater, negetive when smaller
* @param otherwise - (default: undefined) a fallback value when there were no input values given
* @typeparam T - the element type
* @typeparam O - the fallback value type
* @example
* ```ts
* const stream = Stream.of('abc', 'a', 'abcde', 'ab')
* console.log(stream.maxBy((s1, s2) => s1.length - s2.length))
* // 'abcde'
* ```
*/
const maxBy: {
<T>(compFun: (v1: T, v2: T) => MaybePromise<number>): AsyncReducer<T, T | undefined>;
<T, O>(compFun: (v1: T, v2: T) => MaybePromise<number>, otherwise: AsyncOptLazy<O>): AsyncReducer<T, T | O>;
};
/**
* Returns a `Reducer` that remembers the maximum value of the numberic inputs.
* @param otherwise - (default: undefined) a fallback value when there were no input values given
* @typeparam O - the fallback value type
* @example
* ```ts
* console.log(Stream.of(5, 3, 7, 4).reduce(Reducer.max()))
* // => 7
* ```
*/
const max: {
(): AsyncReducer<number, number | undefined>;
<O>(otherwise: AsyncOptLazy<O>): AsyncReducer<number, number | O>;
};
/**
* Returns an `AsyncReducer` that remembers the first input value.
* @param otherwise - (default: undefined) a fallback value to output if no input value has been provided
* @typeparam T - the input value type
* @typeparam O - the fallback value type
* @example
* ```ts
* await AsyncStream.from(Stream.range{ amount: 10 })).reduce(AsyncReducer.first())
* // => 0
* ```
*/
const first: {
<T>(): AsyncReducer<T, T | undefined>;
<T, O>(otherwise: AsyncOptLazy<O>): AsyncReducer<T, T | O>;
};
/**
* Returns an `AsyncReducer` that remembers the last input value.
* @param otherwise - (default: undefined) a fallback value to output if no input value has been provided
* @typeparam T - the input value type
* @typeparam O - the fallback value type
* @example
* ```ts
* await AsyncStream.from(Stream.range{ amount: 10 })).reduce(AsyncReducer.last())
* // => 9
* ```
*/
const last: {
<T>(): AsyncReducer<T, T | undefined>;
<T, O>(otherwise: AsyncOptLazy<O>): AsyncReducer<T, T | O>;
};
/**
* Returns an AsyncReducer that only produces an output value when having receives exactly one
* input value, otherwise will return the `otherwise` value or undefined.
* @param otherwise - the fallback value to return when more or less than one value is received.
* @typeparam T - the element type
* @typeparam O - the fallback value type
*/
const single: {
<T>(): AsyncReducer<T, T | undefined>;
<T, O>(otherwise: AsyncOptLazy<O>): AsyncReducer<T, T | O>;
};
/**
* Returns an `AsyncReducer` that ouputs false as long as no input value satisfies given `pred`, true otherwise.
* @typeparam T - the element type
* @param pred - a potentiall async function taking an input value and its index, and returning true if the value satisfies the predicate
* @param options - (optional) an object containing the following properties:<br/>
* - negate: (default: false) when true will invert the given predicate
*/
function some<T>(pred: (value: T, index: number) => MaybePromise<boolean>, options?: {
negate?: boolean | undefined;
}): AsyncReducer<T, boolean>;
/**
* Returns an `AsyncReducer` that ouputs true as long as all input values satisfy the given `pred`, false otherwise.
* @typeparam T - the element type
* @param pred - a potentially async function taking an input value and its index, and returning true if the value satisfies the predicate
* @param options - (optional) an object containing the following properties:<br/>
* - negate: (default: false) when true will invert the given predicate
*/
function every<T>(pred: (value: T, index: number) => MaybePromise<boolean>, options?: {
negate?: boolean | undefined;
}): AsyncReducer<T, boolean>;
/**
* Returns an `AsyncReducer` that ouputs true when the received elements match the given `other` async stream source according to the `eq` instance, false otherwise.
* @typeparam T - the element type
* @param other - an async stream source containg elements to match against
* @param options - (optional) an object containing the following properties:<br/>
* - eq: (default: Eq.objectIs) the `Eq` instance to use to compare elements
* - negate: (default: false) when true will invert the given predicate
*/
function equals<T>(other: AsyncStreamSource<T>, options?: {
eq?: Eq<T> | undefined;
negate?: boolean | undefined;
}): AsyncReducer<T, boolean>;
/**
* An `AsyncReducer` that outputs true if no input values are received, false otherwise.
* @example
* ```ts
* await AsyncStream.of(1, 2, 3).reduce(AsyncReducer.isEmpty))
* // => false
* ```
*/
const isEmpty: AsyncReducer<any, boolean>;
/**
* An `AsyncReducer` that outputs true if one or more input values are received, false otherwise.
* @example
* ```ts
* await AsyncStream.of(1, 2, 3).reduce(AsyncReducer.nonEmpty))
* // => true
* ```
*/
const nonEmpty: AsyncReducer<any, boolean>;
/**
* Returns a `AsyncReducer` that returns true if the first input values match the given `slice` values repeated `amount` times. Otherwise,
* returns false.
* @param slice - a async sequence of elements to match against
* @param options - (optional) an object containing the following properties:<br/>
* - amount: (detaulf: 1) the amount of elements to find
* - eq: (default: Eq.objectIs) the `Eq` instance to use to compare elements
*/
function startsWithSlice<T>(slice: AsyncStreamSource<T>, options?: {
eq?: Eq<T> | undefined;
amount?: number;
}): AsyncReducer<T, boolean>;
/**
* Returns an `AsyncReducer` that returns true if the last input values match the given `slice` values repeated `amount` times. Otherwise,
* returns false.
* @param slice - a async sequence of elements to match against
* @param options - (optional) an object containing the following properties:<br/>
* - amount: (detaulf: 1) the amount of elements to find
* - eq: (default: Eq.objectIs) the `Eq` instance to use to compare elements
*/
function endsWithSlice<T>(slice: AsyncStreamSource<T>, options?: {
eq?: Eq<T> | undefined;
amount?: number;
}): AsyncReducer<T, boolean>;
/**
* Returns an `AsyncReducer` that returns true if the input values contain the given `slice` sequence `amount` times. Otherwise,
* returns false.
* @param slice - a async sequence of elements to match against
* @param options - (optional) an object containing the following properties:<br/>
* - amount: (detaulf: 1) the amount of elements to find
* - eq: (default: Eq.objectIs) the `Eq` instance to use to compare elements
*/
function containsSlice<T>(slice: AsyncStreamSource<T>, options?: {
eq?: Eq<T> | undefined;
amount?: number | undefined;
}): AsyncReducer<T, boolean>;
/**
* Returns an `AsyncReducer` that splits the incoming values into two separate outputs based on the given `pred` predicate. Values for which the predicate is true
* are fed into the `collectorTrue` reducer, and other values are fed into the `collectorFalse` instance. If no collectors are provided the values are collected
* into arrays.
* @param pred - a potentially async predicate receiving the value and its index
* @param options - (optional) an object containing the following properties:<br/>
* - collectorTrue: (default: Reducer.toArray()) a reducer that collects the values for which the predicate is true<br/>
* - collectorFalse: (default: Reducer.toArray()) a reducer that collects the values for which the predicate is false
* @typeparam T - the input element type
* @typeparam RT - the reducer result type for the `collectorTrue` value
* @typeparam RF - the reducer result type for the `collectorFalse` value
* @note if the predicate is a type guard, the return type is automatically inferred
* ```
*/
const partition: {
<T, T2 extends T, RT, RF = RT>(pred: (value: T, index: number) => value is T2, options: {
collectorTrue: AsyncReducer.Accept<T2, RT>;
collectorFalse: AsyncReducer.Accept<Exclude<T, T2>, RF>;
}): AsyncReducer<T, [true: RT, false: RF]>;
<T, T2 extends T>(pred: (value: T, index: number) => value is T2, options?: {
collectorTrue?: undefined;
collectorFalse?: undefined;
}): AsyncReducer<T, [true: T2[], false: Exclude<T, T2>[]]>;
<T, RT, RF = RT>(pred: (value: T, index: number) => MaybePromise<boolean>, options: {
collectorTrue: AsyncReducer.Accept<T, RT>;
collectorFalse: AsyncReducer.Accept<T, RF>;
}): AsyncReducer<T, [true: RT, false: RF]>;
<T>(pred: (value: T, index: number) => MaybePromise<boolean>, options?: {
collectorTrue?: undefined;
collectorFalse?: undefined;
}): AsyncReducer<T, [true: T[], false: T[]]>;
};
/**
* Returns an `AsyncReducer` that uses the `valueToKey` function to calculate a key for each value, and feeds the tuple of the key and the value to the
* `collector` reducer. Finally, it returns the output of the `collector`. If no collector is given, the default collector will return a JS multimap
* of the type `Map<K, V[]>`.
* @param valueToKey - potentially async function taking a value and its index, and returning the corresponding key
* @param options - (optional) an object containing the following properties:<br/>
* - collector: (default: Reducer.toArray()) a reducer that collects the incoming tuple of key and value, and provides the output
* @typeparam T - the input value type
* @typeparam K - the key type
* @typeparam R - the collector output type
* ```
*/
const groupBy: {
<T, K, R, T2 extends readonly [K, T] = [K, T]>(valueToKey: (value: T, index: number) => MaybePromise<K>, options: {
collector: AsyncReducer.Accept<[K, T] | T2, R>;
}): AsyncReducer<T, R>;
<T, K>(valueToKey: (value: T, index: number) => MaybePromise<K>, options?: {
collector?: undefined;
}): AsyncReducer<T, Map<K, T[]>>;
};
/**
* Returns an `AsyncReducer` that feeds incoming values to all reducers in the provided `reducers` source, and halts when the first
* reducer in the array is halted and returns the output of that reducer. Returns the `otherwise` value if no reducer is yet halted.
* @param reducers - a stream source of async reducers that will receive the incoming values
* @param otherwise - a fallback value to return if none of the reducers has been halted
* @typeparam T - the input value type
* @typeparam R - the output value type
* @typeparam O - the fallback value type
*/
const race: {
<T, R, O>(reducers: AsyncReducer.Accept<T, R>[], otherwise: AsyncOptLazy<O>): AsyncReducer<T, R | O>;
<T, R>(reducers: AsyncReducer.Accept<T, R>[]): AsyncReducer<T, R | undefined>;
};
/**
* Type defining the allowed shape of async reducer combinations.
* @typeparam T - the input type
*/
type CombineShape<T> = AsyncReducer.Accept<T, any> | AsyncReducer.CombineShape<T>[] | {
[key: string]: AsyncReducer.CombineShape<T>;
};
/**
* Type defining the result type of an async reducer combination for a given shape.
* @typeparam S - the reducer combination shape
*/
type CombineResult<S extends AsyncReducer.CombineShape<any>> = S extends readonly AsyncReducer.CombineShape<any>[] ? 0 extends S['length'] ? AsyncReducer.CombineResult<S[number]>[] : {
[K in keyof S]: S[K] extends AsyncReducer.CombineShape<any> ? AsyncReducer.CombineResult<S[K]> : never;
} : S extends {
[key: string]: AsyncReducer.CombineShape<any>;
} ? {
[K in keyof S]: AsyncReducer.CombineResult<S[K]>;
} : S extends AsyncReducer.Accept<any, infer R> ? R : never;
class InvalidCombineShapeError extends ErrBase.CustomError {
constructor();
}
class ReducerHaltedError extends ErrBase.CustomError {
constructor();
}
class ReducerClosedError extends ErrBase.CustomError {
constructor();
}
class ReducerNotInitializedError extends ErrBase.CustomError {
constructor();
}
/**
* Returns an `AsyncReducer` that combines multiple input `reducers` according to the given "shape" by providing input values to all of them and collecting the outputs in the shape.
* @typeparam T - the input value type for all the reducers
* @typeparam S - the desired result shape type
* @param shape - a shape defining where reducer outputs will be located in the result. It can consist of a single reducer, an array of shapes, or an object with string keys and shapes as values.
*/
function combine<T, const S extends AsyncReducer.CombineShape<T>>(shape: S & AsyncReducer.CombineShape<T>): AsyncReducer<T, AsyncReducer.CombineResult<S>>;
/**
* Returns an `AsyncReducer` instance that first applies this reducer, and then applies the given `next` reducer to each output produced
* by the previous reducer.
* @typeparam I - the input type of the `reducer1` reducer
* @typeparam O1 - the output type of the `reducer1` reducer
* @typeparam O2 - the output type of the `reducer2` reducer
* @typeparam O3 - the output type of the `reducer3` reducer
* @typeparam O4 - the output type of the `reducer4` reducer
* @typeparam O5 - the output type of the `reducer5` reducer
* @param reducer1 - the next reducer to apply to each output of this reducer.
* @param reducer2 - (optional) the next reducer to apply to each output of this reducer.
* @param reducer3 - (optional) the next reducer to apply to each output of this reducer.
* @param reducer4 - (optional) the next reducer to apply to each output of this reducer.
* @param reducer5 - (optional) the next reducer to apply to each output of this reducer.
* @example
* ```ts
* AsyncStream
* .from(Stream.of(1, 2, 3))
* .reduce(
* AsyncReducer.pipe(Reducer.product, Reducer.sum)
* )
* // => 9
* ```
*/
const pipe: {
<I, O1, O2>(reducer1: AsyncReducer.Accept<I, O1>, reducer2: AsyncReducer.Accept<O1, O2>): AsyncReducer<I, O2>;
<I, O1, O2, O3>(reducer1: AsyncReducer.Accept<I, O1>, reducer2: AsyncReducer.Accept<O1, O2>, reducer3: AsyncReducer.Accept<O2, O3>): AsyncReducer<I, O3>;
<I, O1, O2, O3, O4>(reducer1: AsyncReducer.Accept<I, O1>, reducer2: AsyncReducer.Accept<O1, O2>, reducer3: AsyncReducer.Accept<O2, O3>, reducer4: AsyncReducer.Accept<O2, O4>): AsyncReducer<I, O4>;
<I, O1, O2, O3, O4, O5>(reducer1: AsyncReducer.Accept<I, O1>, reducer2: AsyncReducer.Accept<O1, O2>, reducer3: AsyncReducer.Accept<O2, O3>, reducer4: AsyncReducer.Accept<O2, O4>, reducer5: AsyncReducer.Accept<O2, O5>): AsyncReducer<I, O5>;
};
}