UNPKG

lfi

Version:

A lazy functional iteration library supporting sync, async, and concurrent iteration.

1,787 lines (1,695 loc) 171 kB
/** @internal */ type MaybePromiseLike<Value> = Value | PromiseLike<Value> /** @internal */ type StrictNegative<Numeric extends number> = Numeric extends 0 ? never : `${Numeric}` extends `-${string}` ? Numeric : never /** @internal */ type NonNegative<Numeric extends number> = Numeric extends 0 ? Numeric : StrictNegative<Numeric> extends never ? Numeric : never /** @internal */ type StrictInteger<Numeric extends number> = `${Numeric}` extends `${bigint}` ? Numeric : never /** @internal */ type CheckNumericLiteral< Numeric extends number, LiteralNumber extends number, > = number extends Numeric ? Numeric : LiteralNumber /** @internal */ type Integer<Numeric extends number> = CheckNumericLiteral< Numeric, StrictInteger<Numeric> > /** @internal */ type NonNegativeInteger<Numeric extends number> = CheckNumericLiteral< Numeric, NonNegative<StrictInteger<Numeric>> > /** @internal */ type PositiveInteger<Numeric extends number> = CheckNumericLiteral< Numeric, NonNegative<StrictInteger<Numeric>> > /** @internal */ type Curried<Parameters extends readonly any[], Return> = < PartialParameters extends Partial<Parameters>, >( ...args: PartialParameters ) => PartialParameters extends Parameters ? Return : Parameters extends readonly [ ...TupleOfSameLength<PartialParameters>, ...infer RemainingParameters, ] ? RemainingParameters extends any[] ? Curried<RemainingParameters, Return> : never : never /** @internal */ type TupleOfSameLength<Tuple extends readonly any[]> = Extract< { [Key in keyof Tuple]: any }, readonly any[] > /** * Returns a curried version of `fn`. * * @example * ```js * function slothLog(a, b, c) { * console.log(`${a} Sloth ${b} Sloth ${c}`) * } * * const curriedSlothLog = curry(slothLog) * * console.log(curriedSlothLog.name) * //=> slothLog * * console.log(curriedSlothLog.length) * //=> 3 * * curriedSlothLog(`Hello`, `World`, `!`) * curriedSlothLog(`Hello`)(`World`, `!`) * curriedSlothLog(`Hello`, `World`)(`!`) * curriedSlothLog(`Hello`)(`World`)(`!`) * //=> Hello Sloth World Sloth ! * //=> Hello Sloth World Sloth ! * //=> Hello Sloth World Sloth ! * //=> Hello Sloth World Sloth ! * ``` * * @category Core * @since v0.0.1 */ declare const curry: <Parameters extends readonly any[], Return>( fn: (...args: Parameters) => Return, ) => Curried<Parameters, Return> /** * Returns the result of piping `value` through the given functions. * * @example * ```js * console.log( * pipe( * `sloth`, * name => `${name.toUpperCase()}!`, * text => [text, text, text], * array => array.join(` `), * ), * ) * // => SLOTH! SLOTH! SLOTH! * ``` * * @category Core * @since v0.0.1 */ declare const pipe: { <Value>(value: Value): Value <A, B>(value: A, fn: (a: A) => B): B <A, B, C>(value: A, fn1: (a: A) => B, fn2: (b: B) => C): C <A, B, C, D>( value: A, fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, ): D <A, B, C, D, E>( value: A, fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, ): E <A, B, C, D, E, F>( value: A, fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F, ): F <A, B, C, D, E, F, G>( value: A, fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F, fn6: (f: F) => G, ): G <A, B, C, D, E, F, G, H>( value: A, fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F, fn6: (f: F) => G, fn7: (g: G) => H, ): H <A, B, C, D, E, F, G, H, I>( value: A, fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F, fn6: (f: F) => G, fn7: (g: G) => H, fn8: (h: H) => I, ): I <A, B, C, D, E, F, G, H, I, J>( value: A, fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F, fn6: (f: F) => G, fn7: (g: G) => H, fn8: (h: H) => I, fn9: (i: I) => J, ): J } /** * Returns a function that takes a single parameter and pipes it through the * given functions. * * @example * ```js * const screamify = compose( * name => `${name.toUpperCase()}!`, * text => [text, text, text], * array => array.join(` `), * ) * * console.log(screamify(`sloth`)) * // => SLOTH! SLOTH! SLOTH! * ``` * * @category Core * @since v0.0.2 */ declare const compose: { (): <Value>(value: Value) => Value <A, B>(fn: (a: A) => B): (value: A) => B <A, B, C>(fn1: (a: A) => B, fn2: (b: B) => C): (value: A) => C <A, B, C, D>( fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, ): (value: A) => D <A, B, C, D, E>( fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, ): (value: A) => E <A, B, C, D, E, F>( fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F, ): (value: A) => F <A, B, C, D, E, F, G>( fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F, fn6: (f: F) => G, ): (value: A) => G <A, B, C, D, E, F, G, H>( fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F, fn6: (f: F) => G, fn7: (g: G) => H, ): (value: A) => H <A, B, C, D, E, F, G, H, I>( fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F, fn6: (f: F) => G, fn7: (g: G) => H, fn8: (h: H) => I, ): (value: A) => I <A, B, C, D, E, F, G, H, I, J>( fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F, fn6: (f: F) => G, fn7: (g: G) => H, fn8: (h: H) => I, fn9: (i: I) => J, ): (value: A) => J } /** * Returns an async iterable wrapper around `iterable`. * * Note that when passing a concur iterable the returned async iterable may have * to buffer the values produced by the concur iterable because values may not * be read from the async iterable as quickly as they are produced by the concur * iterable. This is a fundamental problem because concur iterables are "push" * based while async iterables are "pull" based, which creates backpressure. * * @example * ```js * const asyncIterable = asAsync([`sloth`, `more sloth`, `even more sloth`]) * * console.log(typeof asyncIterable[Symbol.asyncIterator]) * //=> function * * for await (const value of asyncIterable) { * console.log(value) * } * //=> sloth * //=> more sloth * //=> even more sloth * ``` * * @category Core * @since v0.0.2 */ declare const asAsync: <Value>( iterable: Iterable<Value> | AsyncIterable<Value> | ConcurIterable<Value>, ) => AsyncIterable<Value> /** * Represents a potentially lazy collection of values, each of type `Value`, * that can be iterated over concurrently. * * The collection can be iterated by invoking the concur iterable with an * `apply` callback. The callback is applied to each value in the collection, * potentially asynchronously, in some order. * * Invoking the concur iterable returns a promise that resolves when `apply` * has been applied to each value in the concur iterable and each result * returned by `apply` is awaited. * * It is like an event emitter that accepts only one event handler and returns a * promise that resolves when all events have been emitted and handled. * * @example * ```js * const slothNamesConcurIterable = pipe( * asConcur(['sloth-names1.txt', 'sloth-names2.txt']), * mapConcur(filename => fs.promises.readFile(filename, `utf8`)), * flatMapConcur(content => content.split(`\n`)), * ) * ``` * * @category Core * @since v0.0.2 */ type ConcurIterable<Value> = ( apply: ConcurIterableApply<Value>, ) => Promise<void> /** * The callback invoked for each value of a {@link ConcurIterable}. * * @category Core * @since v2.0.0 */ type ConcurIterableApply<Value> = ( value: Value, ) => MaybePromiseLike<void> /** * Returns a concur iterable wrapper around `iterable`. * * @example * ```js * const concurIterable = asConcur([`sloth`, `more sloth`, `even more sloth`]) * * await forEachConcur(console.log, concurIterable) * //=> sloth * //=> more sloth * //=> even more sloth * ``` * * @category Core * @since v0.0.2 */ declare const asConcur: <Value>( iterable: Iterable<Value> | AsyncIterable<Value> | ConcurIterable<Value>, ) => ConcurIterable<Value> /** * An iterable that contains zero values. * * Can be used as an iterable of any type. * * Like `[]`, but opaque. * * @example * ```js * console.log([...empty]) * //=> [] * ``` * * @category Core * @since v0.0.1 */ declare const empty: Iterable<any> /** * An async iterable that contains zero values. * * Can be used as an async iterable of any type. * * Like `[]`, but for async iterables. * * @example * ```js * console.log(await pipe(emptyAsync, reduceAsync(toArray()))) * //=> [] * ``` * * @category Core * @since v0.0.1 */ declare const emptyAsync: AsyncIterable<any> /** * A concur iterable that contains zero values. * * Can be used as a concur iterable of any type. * * Like `[]`, but for concur iterables. * * @example * ```js * console.log(await pipe(emptyConcur, reduceConcur(toArray()))) * //=> [] * ``` * * @category Core * @since v0.0.2 */ declare const emptyConcur: ConcurIterable<any> /** * Returns an iterable equivalent, but not referentially equal, to `iterable`. * * @category Core * @since v2.0.0 */ declare const opaque: <Value>(iterable: Iterable<Value>) => Iterable<Value> /** * Returns an async iterable equivalent, but not referentially equal, to * `asyncIterable`. * * @category Core * @since v2.0.0 */ declare const opaqueAsync: <Value>( asyncIterable: AsyncIterable<Value>, ) => AsyncIterable<Value> /** * Returns an concur iterable equivalent, but not referentially equal, to * `concurIterable`. * * @category Core * @since v2.0.0 */ declare const opaqueConcur: <Value>( concurIterable: ConcurIterable<Value>, ) => ConcurIterable<Value> /** * An iterable containing exactly zero or one values. * * @category Optionals * @since v2.0.0 */ type Optional<Value> = Iterable<Value> /** * An async iterable containing exactly zero or one values. * * @category Optionals * @since v2.0.0 */ type AsyncOptional<Value> = AsyncIterable<Value> /** * A concur iterable containing exactly zero or one values. * * @category Optionals * @since v2.0.0 */ type ConcurOptional<Value> = ConcurIterable<Value> /** * Returns the only value in `iterable` if it contains exactly one value. * Otherwise, returns the result of invoking `fn`. * * @example * ```js * console.log(pipe([`sloth`], or(() => `Never called`))) * //=> sloth * * console.log(pipe([], or(() => `I get called!`))) * //=> I get called! * * console.log(pipe([1, `sloth`, 3], or(() => `I also get called!`))) * //=> I also get called! * ``` * * @category Optionals * @since v0.0.1 */ declare const or: { <Value>(fn: () => Value): (iterable: Iterable<Value>) => Value <Value>(fn: () => Value, iterable: Iterable<Value>): Value } /** * Returns a promise that resolves to the only value in `asyncIterable` if it * contains exactly one value. Otherwise, returns a promise that resolves to * the awaited result of invoking `fn`. * * @example * ```js * console.log(await pipe(asAsync([`sloth`]), orAsync(() => `Never called`))) * //=> sloth * * console.log(await pipe(emptyAsync, orAsync(() => `I get called!`))) * //=> I get called! * * console.log( * await pipe( * asAsync([1, `sloth`, 3]), * orAsync(() => `I also get called!`), * ), * ) * //=> I also get called! * ``` * * @category Optionals * @since v0.0.1 */ declare const orAsync: { <Value>( fn: () => MaybePromiseLike<Value>, ): (asyncIterable: AsyncIterable<Value>) => Promise<Value> <Value>( fn: () => MaybePromiseLike<Value>, asyncIterable: AsyncIterable<Value>, ): Promise<Value> } /** * Returns a promise that resolves to the only value in `concurIterable` if it * contains exactly one value. Otherwise, returns a promise that resolves to * the awaited result of invoking `fn`. * * @example * ```js * console.log(await pipe(asConcur([`sloth`]), orConcur(() => `Never called`))) * //=> sloth * * console.log(await pipe(emptyConcur, orConcur(() => `I get called!`))) * //=> I get called! * * console.log( * await pipe( * asConcur([1, `sloth`, 3]), * orConcur(() => `I also get called!`), * ), * ) * //=> I also get called! * ``` * * @category Optionals * @since v0.0.2 */ declare const orConcur: { <Value>( fn: () => MaybePromiseLike<Value>, ): (concurIterable: ConcurIterable<Value>) => Promise<Value> <Value>( fn: () => MaybePromiseLike<Value>, concurIterable: ConcurIterable<Value>, ): Promise<Value> } /** * Returns the only value in `iterable` if it contains exactly one value. * Otherwise, throws an error. * * @example * ```js * console.log(get([`sloth`])) * //=> sloth * * try { * console.log(get([])) * } catch { * console.log(`Oh no! It was empty...`) * } * //=> Oh no! It was empty... * * try { * console.log(get([1, `sloth`, 3])) * } catch { * console.log(`Oh no! It had more than one value...`) * } * //=> Oh no! It had more than one value... * ``` * * @category Optionals * @since v0.0.1 */ declare const get: <Value>(iterable: Iterable<Value>) => Value /** * Returns a promise that resolves to the only value in `asyncIterable` if it * contains exactly one value. Otherwise, returns a promise that rejects. * * @example * ```js * console.log(await getAsync(asAsync([`sloth`]))) * //=> sloth * * try { * console.log(await getAsync(emptyAsync)) * } catch { * console.log(`Oh no! It was empty...`) * } * //=> Oh no! It was empty... * * try { * console.log(await getAsync(asAsync([1, `sloth`, 3]))) * } catch { * console.log(`Oh no! It had more than one value...`) * } * //=> Oh no! It had more than one value... * ``` * * @category Optionals * @since v0.0.1 */ declare const getAsync: <Value>( asyncIterable: AsyncIterable<Value>, ) => Promise<Value> /** * Returns a promise that resolves to the only value in `concurIterable` if it * contains exactly one value. Otherwise, returns a promise that rejects. * * @example * ```js * console.log(await getConcur(asConcur([`sloth`]))) * //=> sloth * * try { * console.log(await getConcur(emptyConcur)) * } catch { * console.log(`Oh no! It was empty...`) * } * //=> Oh no! It was empty... * * try { * console.log(await getConcur(asConcur([1, `sloth`, 3]))) * } catch { * console.log(`Oh no! It had more than one value...`) * } * //=> Oh no! It had more than one value... * ``` * * @category Optionals * @since v0.0.2 */ declare const getConcur: <Value>( concurIterable: ConcurIterable<Value>, ) => Promise<Value> /** * Returns a pair of iterables. If `iterable` is empty, then both of the * returned iterables are empty. Otherwise, the first iterable contains the * first value of `iterable` and the second iterable contains the rest of the * values of `iterable`. The second iterable can only be iterated once. * * @example * ```js * const slothActivities = [`sleeping`, `yawning`, `eating`] * const [first, rest] = next(slothActivities) * * console.log(get(first)) * //=> sleeping * * console.log([...rest]) * //=> [ 'yawning', 'eating' ] * * const badThingsAboutSloths = [] * const [first2, rest2] = next(badThingsAboutSloths) * * console.log(count(first2)) * //=> 0 * * console.log(count(rest2)) * //=> 0 * ``` * * @category Optionals * @since v0.0.1 */ declare const next: <Value>( iterable: Iterable<Value>, ) => [Optional<Value>, Iterable<Value>] /** * Returns a promise that resolves to a pair of async iterables. If * `asyncIterable` is empty, then both of the returned async iterables are * empty. Otherwise, the first async iterable contains the first value of * `asyncIterable` and the second async iterable contains the rest of the values * of `asyncIterable`. The second async iterable can only be iterated once. * * @example * ```js * const slothActivities = asAsync([`sleeping`, `yawning`, `eating`]) * const [first, rest] = await nextAsync(slothActivities) * * console.log(await getAsync(first)) * //=> sleeping * * console.log(await reduceAsync(toArray(), rest)) * //=> [ 'yawning', 'eating' ] * * const badThingsAboutSloths = emptyAsync * const [first2, rest2] = await nextAsync(badThingsAboutSloths) * * console.log(await countAsync(first2)) * //=> 0 * * console.log(await countAsync(rest2)) * //=> 0 * ``` * * @category Optionals * @since v0.0.1 */ declare const nextAsync: <Value>( asyncIterable: AsyncIterable<Value>, ) => Promise<[AsyncOptional<Value>, AsyncIterable<Value>]> /** * A reducer that reduces by combining pairs of values using function * application. * * @category Reducers * @since v2.0.0 */ type FunctionReducer<Value = unknown> = ( acc: Value, value: Value, ) => Value /** * A reducer that reduces by combining pairs of values using * {@link RawOptionalReducerWithoutFinish.add}. * * @category Reducers * @since v2.0.0 */ type RawOptionalReducerWithoutFinish<Value = unknown, This = unknown> = { add: (this: This, acc: Value, value: Value) => Value } /** * A reducer that reduces by combining pairs of values using * {@link RawOptionalReducerWithFinish.add} and then tranforming the final value * using {@link RawOptionalReducerWithFinish.finish}. * * @category Reducers * @since v2.0.0 */ type RawOptionalReducerWithFinish< Value = unknown, Finished = Value, This = unknown, > = RawOptionalReducerWithoutFinish<Value, This> & { finish: (this: This, acc: Value) => Finished } /** * A reducer that reduces by combining pairs of values using * {@link OptionalReducer.add} and then tranforming the final value using * {@link OptionalReducer.finish}. * * @category Reducers * @since v2.0.0 */ type OptionalReducer< Value = unknown, Finished = Value, > = RawOptionalReducerWithFinish<Value, Finished> /** * A reducer that reduces by creating an initial accumulator using * {@link RawReducerWithoutFinish.create} and then adding values to the * accumulator values using {@link RawReducerWithoutFinish.add}. * * @category Reducers * @since v2.0.0 */ type RawReducerWithoutFinish< Value = unknown, Acc = Value, This = unknown, > = { create: (this: This) => Acc add: (this: This, acc: Acc, value: Value) => Acc } /** * A reducer that reduces by creating an initial accumulator using * {@link RawReducerWithFinish.create}, then adding values to the accumulator * values using {@link RawReducerWithFinish.add}, and then tranforming the final * accumulator using {@link RawReducerWithFinish.finish}. * * @category Reducers * @since v2.0.0 */ type RawReducerWithFinish< Value = unknown, Acc = Value, Finished = Acc, This = unknown, > = RawReducerWithoutFinish<Value, Acc, This> & { finish: (this: This, acc: Acc) => Finished } /** * A reducer that reduces by creating an initial accumulator using * {@link Reducer.create}, then adding values to the accumulator values using * {@link Reducer.add}, and then tranforming the final accumulator using * {@link Reducer.finish}. * * @category Reducers * @since v2.0.0 */ type Reducer< Value = unknown, Acc = Value, Finished = Acc, > = RawReducerWithFinish<Value, Acc, Finished> /** * A keyed reducer that reduces by creating an initial accumulator using * {@link RawKeyedReducer.create} and then adding key-value pairs to the * accumulator values using {@link RawKeyedReducer.add}. The accumulator can be * queried for values by key using {@link RawKeyedReducer.get}. * * @category Reducers * @since v2.0.0 */ type RawKeyedReducer< Key = unknown, Value = unknown, Acc = [Key, Value], This = unknown, > = RawReducerWithoutFinish<readonly [Key, Value], Acc, This> & { get: (this: This, acc: Acc, key: Key) => Value | typeof NO_ENTRY } /** * A keyed reducer that reduces by creating an initial accumulator using * {@link KeyedReducer.create} and then adding key-value pairs to the * accumulator values using {@link KeyedReducer.add}. The accumulator can be * queried for values by key using {@link KeyedReducer.get}. * * @category Reducers * @since v2.0.0 */ type KeyedReducer< Key = unknown, Value = unknown, Acc = [Key, Value], > = RawKeyedReducer<Key, Value, Acc> /** * An async reducer that reduces by combining pairs of values using function * application. * * @category Reducers * @since v2.0.0 */ type AsyncFunctionReducer<Value = unknown> = ( acc: Value, value: Value, ) => MaybePromiseLike<Value> /** * An async reducer that reduces by combining pairs of values using * {@link RawAsyncOptionalReducerWithoutFinish.add}. * * @category Reducers * @since v2.0.0 */ type RawAsyncOptionalReducerWithoutFinish< Value = unknown, This = unknown, > = { add: (this: This, acc: Value, value: Value) => MaybePromiseLike<Value> } /** * An async reducer that reduces by combining pairs of values using * {@link RawAsyncOptionalReducerWithFinish.add} and then tranforming the final * value using {@link RawAsyncOptionalReducerWithFinish.finish}. * * @category Reducers * @since v2.0.0 */ type RawAsyncOptionalReducerWithFinish< Value = unknown, Finished = Value, This = unknown, > = RawAsyncOptionalReducerWithoutFinish<Value, This> & { finish: (this: This, acc: Value) => MaybePromiseLike<Finished> } /** * An async reducer that reduces by combining pairs of values using * {@link AsyncOptionalReducer.add} and then tranforming the final value using * {@link AsyncOptionalReducer.finish}. * * @category Reducers * @since v2.0.0 */ type AsyncOptionalReducer< Value = unknown, Finished = Value, > = RawAsyncOptionalReducerWithFinish<Value, Finished> /** * An async reducer that reduces by creating an initial accumulator using * {@link RawAsyncReducerWithoutFinish.create} and then adding values to the * accumulator values using {@link RawAsyncReducerWithoutFinish.add}. The async * reducer is optionally able to combine pairs of accumulators using * {@link RawAsyncReducerWithoutFinish.combine}. * * @category Reducers * @since v2.0.0 */ type RawAsyncReducerWithoutFinish< Value = unknown, Acc = Value, This = unknown, > = { create: (this: This) => MaybePromiseLike<Acc> add: (this: This, acc: Acc, value: Value) => MaybePromiseLike<Acc> combine?: (this: This, acc1: Acc, acc2: Acc) => MaybePromiseLike<Acc> } /** * An async reducer that reduces by creating an initial accumulator using * {@link RawAsyncReducerWithFinish.create}, then adding values to the * accumulator values using {@link RawAsyncReducerWithFinish.add}, and then * tranforming the final accumulator using * {@link RawAsyncReducerWithFinish.finish}. The async * reducer is optionally able to combine pairs of accumulators using * {@link RawAsyncReducerWithFinish.combine}. * * @category Reducers * @since v2.0.0 */ type RawAsyncReducerWithFinish< Value = unknown, Acc = Value, Finished = Acc, This = unknown, > = RawAsyncReducerWithoutFinish<Value, Acc, This> & { finish: (this: This, acc: Acc) => MaybePromiseLike<Finished> } /** * An async reducer that reduces by creating an initial accumulator using * {@link AsyncReducer.create}, then adding values to the accumulator values * using {@link AsyncReducer.add}, and then tranforming the final accumulator * using {@link AsyncReducer.finish}. The async reducer is optionally able to * combine pairs of accumulators using {@link AsyncReducer.combine}. * * @category Reducers * @since v2.0.0 */ type AsyncReducer< Value = unknown, Acc = Value, Finished = Acc, > = RawAsyncReducerWithFinish<Value, Acc, Finished> /** * An async keyed reducer that reduces by creating an initial accumulator using * {@link RawAsyncKeyedReducer.create} and then adding key-value pairs to the * accumulator values using {@link RawAsyncKeyedReducer.add}. The async keyed * reducer is optionally able to combine pairs of accumulators using * {@link RawAsyncKeyedReducer.combine}. The accumulator can be queried for * values by key using {@link RawAsyncKeyedReducer.get}. * * @category Reducers * @since v2.0.0 */ type RawAsyncKeyedReducer< Key = unknown, Value = unknown, Acc = [Key, Value], This = unknown, > = RawAsyncReducerWithoutFinish<readonly [Key, Value], Acc, This> & { get: ( this: This, acc: Acc, key: Key, ) => MaybePromiseLike<Value | typeof NO_ENTRY> } /** * An async keyed reducer that reduces by creating an initial accumulator using * {@link AsyncKeyedReducer.create} and then adding key-value pairs to the * accumulator values using {@link AsyncKeyedReducer.add}. The async keyed * reducer is optionally able to combine pairs of accumulators using * {@link AsyncKeyedReducer.combine}. The accumulator can be queried for values * by key using {@link AsyncKeyedReducer.get}. * * @category Reducers * @since v2.0.0 */ type AsyncKeyedReducer< Key = unknown, Value = unknown, Acc = [Key, Value], > = RawAsyncKeyedReducer<Key, Value, Acc> /** * A unique value representing the lack of an entry for some key in a * {@link KeyedReducer} or {@link AsyncKeyedReducer}. * * Keyed reducers use this instead of `null` or `undefined` because they are * valid values. Furthermore, introducing a `has` method for the purpose of * disambiguation would be less performant due to the need to perform the lookup * twice when the entry exists: `has` followed by `get` for the same key. * * @category Reducers * @since v2.0.0 */ declare const NO_ENTRY: unique symbol /** * Returns a {@link Reducer} or {@link OptionalReducer} equivalent to `reducer` * except its final value is transformed using `fn`. * * @category Reducers * @since v2.0.0 */ declare const mapReducer: { <Value, Acc, From, To, This>( fn: (value: From) => To, reducer: Readonly<RawReducerWithFinish<Value, Acc, From, This>>, ): Reducer<Value, Acc, To> <From, To>( fn: (value: From) => To, ): <Value, Acc, This>( reducer: Readonly<RawReducerWithFinish<Value, Acc, From, This>>, ) => Reducer<Value, Acc, To> <Value, From, To, This>( fn: (value: From) => To, reducer: Readonly<RawReducerWithoutFinish<Value, From, This>>, ): Reducer<Value, To> <From, To>( fn: (value: From) => To, ): <Value, This>( reducer: Readonly<RawReducerWithoutFinish<Value, From, This>>, ) => Reducer<Value, To> <Value, From, To, This>( fn: (value: From) => To, reducer: Readonly<RawOptionalReducerWithFinish<Value, From, This>>, ): OptionalReducer<Value, To> <From, To>( fn: (value: From) => To, ): <Value, This>( reducer: Readonly<RawOptionalReducerWithFinish<Value, From, This>>, ) => OptionalReducer<Value, To> <From, To, This>( fn: (value: From) => To, reducer: Readonly<RawOptionalReducerWithoutFinish<From, This>>, ): OptionalReducer<To> <From, To>( fn: (value: From) => To, ): <This>( reducer: Readonly<RawOptionalReducerWithoutFinish<From, This>>, ) => OptionalReducer<To> <From, To>( fn: (value: From) => To, reducer: FunctionReducer<From>, ): OptionalReducer<To> <From, To>( fn: (value: From) => To, ): (reducer: FunctionReducer<From>) => OptionalReducer<To> } /** * Returns an {@link AsyncReducer} equivalent to `reducer` except its final * value is transformed using `fn`. * * @category Reducers * @since v2.0.0 */ declare const mapAsyncReducer: { <Value, Acc, From, To, This>( fn: (value: From) => MaybePromiseLike<To>, asyncReducer: Readonly<RawAsyncReducerWithFinish<Value, Acc, From, This>>, ): AsyncReducer<Value, Acc, To> <From, To>( fn: (value: From) => MaybePromiseLike<To>, ): <Value, Acc, This>( asyncReducer: Readonly<RawAsyncReducerWithFinish<Value, Acc, From, This>>, ) => AsyncReducer<Value, Acc, To> <Value, From, To, This>( fn: (value: From) => MaybePromiseLike<To>, asyncReducer: Readonly<RawAsyncReducerWithoutFinish<Value, From, This>>, ): AsyncReducer<Value, To> <From, To>( fn: (value: From) => MaybePromiseLike<To>, ): <Value, This>( asyncReducer: Readonly<RawAsyncReducerWithoutFinish<Value, From, This>>, ) => AsyncReducer<Value, To> <Value, From, To, This>( fn: (value: From) => MaybePromiseLike<To>, asyncReducer: Readonly< RawAsyncOptionalReducerWithFinish<Value, From, This> >, ): AsyncOptionalReducer<Value, To> <From, To>( fn: (value: From) => MaybePromiseLike<To>, ): <Value, This>( asyncReducer: Readonly< RawAsyncOptionalReducerWithFinish<Value, From, This> >, ) => AsyncOptionalReducer<Value, To> <From, To, This>( fn: (value: From) => MaybePromiseLike<To>, asyncReducer: Readonly<RawAsyncOptionalReducerWithoutFinish<From, This>>, ): AsyncOptionalReducer<To> <From, To>( fn: (value: From) => MaybePromiseLike<To>, ): <This>( asyncReducer: Readonly<RawAsyncOptionalReducerWithoutFinish<From, This>>, ) => AsyncOptionalReducer<To> <From, To>( fn: (value: From) => MaybePromiseLike<To>, asyncReducer: AsyncFunctionReducer<From>, ): AsyncOptionalReducer<To> <From, To>( fn: (value: From) => MaybePromiseLike<To>, ): (asyncReducer: AsyncFunctionReducer<From>) => AsyncOptionalReducer<To> } /** * Returns a non-raw version of `reducer`. * * @category Reducers * @since v2.0.0 */ declare const normalizeReducer: { <Key, Value, Acc, This>( reducer: Readonly<RawKeyedReducer<Key, Value, Acc, This>>, ): KeyedReducer<Key, Value, Acc> <Value, Acc, Finished, This>( reducer: Readonly<RawReducerWithFinish<Value, Acc, Finished, This>>, ): Reducer<Value, Acc, Finished> <Value, Acc, This>( reducer: Readonly<RawReducerWithoutFinish<Value, Acc, This>>, ): Reducer<Value, Acc> <Value, Finished, This>( reducer: Readonly<RawOptionalReducerWithFinish<Value, Finished, This>>, ): OptionalReducer<Value, Finished> <Value, This>( reducer: Readonly<RawOptionalReducerWithoutFinish<Value, This>>, ): OptionalReducer<Value> <Value>(reducer: FunctionReducer<Value>): OptionalReducer<Value> <Key, Value, Acc, This>( reducer: Readonly<RawAsyncKeyedReducer<Key, Value, Acc, This>>, ): AsyncKeyedReducer<Key, Value, Acc> <Value, Acc, Finished, This>( reducer: Readonly<RawAsyncReducerWithFinish<Value, Acc, Finished, This>>, ): AsyncReducer<Value, Acc, Finished> <Value, Acc, This>( reducer: Readonly<RawAsyncReducerWithoutFinish<Value, Acc, This>>, ): AsyncReducer<Value, Acc> <Value, Finished, This>( reducer: Readonly<RawAsyncOptionalReducerWithFinish<Value, Finished, This>>, ): AsyncOptionalReducer<Value, Finished> <Value, This>( reducer: Readonly<RawAsyncOptionalReducerWithoutFinish<Value, This>>, ): AsyncOptionalReducer<Value> <Value>(reducer: AsyncFunctionReducer<Value>): AsyncOptionalReducer<Value> } /** * Returns the result of reducing `iterable` using `reducer`. * * An initial accumulator is created using {@link Reducer.create}. Then each * value in `iterable` is added to the accumulator and the current accumulator * is updated using {@link Reducer.add}. Finally, the resulting accumulator is * transformed using {@link Reducer.finish} if specified. * * If `reducer` is an optional reducer (no {@link Reducer.create} method), then * an empty iterable is returned if `iterable` is empty. Otherwise, an iterable * containing the result of reducing using the first value of the iterable as * the initial accumulator is returned. * * Like `Array.prototype.reduce`, but for iterables. * * @example * ```js * console.log( * pipe( * [`Hello`, `Sloth!`, `What`, `an`, `interesting`, `program!`], * reduce((a, b) => `${a} ${b}`), * get, * ), * ) * //=> Hello Sloth! What an interesting program! * * console.log( * pipe( * [`Hello`, `Sloth!`, `What`, `an`, `interesting`, `program!`], * reduce({ create: () => ``, add: (a, b) => `${a} ${b}` }), * ), * ) * //=> Hello Sloth! What an interesting program! * ``` * * @category Reducers * @since v0.0.1 */ declare const reduce: { <Value, Acc, Finished, This>( reducer: Readonly<RawReducerWithFinish<Value, Acc, Finished, This>>, iterable: Iterable<Value>, ): Finished <Value, Acc, Finished, This>( reducer: Readonly<RawReducerWithFinish<Value, Acc, Finished, This>>, ): (iterable: Iterable<Value>) => Finished <Value, Acc, This>( reducer: Readonly<RawReducerWithoutFinish<Value, Acc, This>>, iterable: Iterable<Value>, ): Acc <Value, Acc, This>( reducer: Readonly<RawReducerWithoutFinish<Value, Acc, This>>, ): (iterable: Iterable<Value>) => Acc <Value, Finished, This>( reducer: Readonly<RawOptionalReducerWithFinish<Value, Finished, This>>, iterable: Iterable<Value>, ): Optional<Finished> <Value, Finished, This>( reducer: Readonly<RawOptionalReducerWithFinish<Value, Finished, This>>, ): (iterable: Iterable<Value>) => Optional<Finished> <Value, This>( reducer: Readonly<RawOptionalReducerWithoutFinish<Value, This>>, iterable: Iterable<Value>, ): Optional<Value> <Value, This>( reducer: Readonly<RawOptionalReducerWithoutFinish<Value, This>>, ): (iterable: Iterable<Value>) => Optional<Value> <Value>( reducer: FunctionReducer<Value>, iterable: Iterable<Value>, ): Optional<Value> <Value>( reducer: FunctionReducer<Value>, ): (iterable: Iterable<Value>) => Optional<Value> } /** * Returns the result of reducing the `asyncIterable` using `asyncReducer`. * * Informally, an initial accumulator is created using * {@link AsyncReducer.create}. Then each value in `asyncIterable` is added to * the accumulator and the current accumulator is updated using * {@link AsyncReducer.add}. Finally, the resulting accumulator is transformed * using {@link AsyncReducer.finish} if specified. Multiple accumulators may be * created, added to, and then combined if supported via * {@link AsyncReducer.combine} and the next value of `asyncIterable` is ready * before promises from {@link AsyncReducer.add} resolve. * * If `asyncReducer` is an async optional reducer (no * {@link AsyncReducer.create} method), then an empty async iterable is returned * if `asyncIterable` is empty. Otherwise, an async iterable containing the * result of reducing using the first value of the async iterable as the initial * accumulator is returned. * * Like `Array.prototype.reduce`, but for async iterables. * * @example * ```js * console.log( * await pipe( * asAsync([`Hello`, `World!`, `What`, `an`, `interesting`, `program!`]), * reduceAsync((a, b) => `${a} ${b}`), * getAsync, * ), * ) * //=> Hello World! What an interesting program! * * console.log( * await pipe( * asAsync([`Hello`, `World!`, `What`, `an`, `interesting`, `program!`]), * reduceAsync({ create: () => ``, add: (a, b) => `${a} ${b}` }), * ), * ) * //=> Hello World! What an interesting program! * ``` * * @category Reducers * @since v0.0.1 */ declare const reduceAsync: { <Value, Acc, Finished, This>( asyncReducer: | RawAsyncReducerWithFinish<Value, Acc, Finished, This> | RawReducerWithFinish<Value, Acc, Finished, This>, asyncIterable: AsyncIterable<Value>, ): Promise<Finished> <Value, Acc, Finished, This>( asyncReducer: | RawAsyncReducerWithFinish<Value, Acc, Finished, This> | RawReducerWithFinish<Value, Acc, Finished, This>, ): (asyncIterable: AsyncIterable<Value>) => Promise<Finished> <Value, Acc, This>( asyncReducer: | RawAsyncReducerWithoutFinish<Value, Acc, This> | RawReducerWithoutFinish<Value, Acc, This>, asyncIterable: AsyncIterable<Value>, ): Promise<Acc> <Value, Acc, This>( asyncReducer: | RawAsyncReducerWithoutFinish<Value, Acc, This> | RawReducerWithoutFinish<Value, Acc, This>, ): (asyncIterable: AsyncIterable<Value>) => Promise<Acc> <Value, Finished, This>( asyncReducer: | RawAsyncOptionalReducerWithFinish<Value, Finished, This> | RawOptionalReducerWithFinish<Value, Finished, This>, asyncIterable: AsyncIterable<Value>, ): AsyncOptional<Finished> <Value, Finished, This>( asyncReducer: | RawAsyncOptionalReducerWithFinish<Value, Finished, This> | RawOptionalReducerWithFinish<Value, Finished, This>, ): (asyncIterable: AsyncIterable<Value>) => AsyncOptional<Finished> <Value, This>( asyncReducer: | RawAsyncOptionalReducerWithoutFinish<Value, This> | RawOptionalReducerWithoutFinish<Value, This>, asyncIterable: AsyncIterable<Value>, ): AsyncOptional<Value> <Value, This>( asyncReducer: | RawAsyncOptionalReducerWithoutFinish<Value, This> | RawOptionalReducerWithoutFinish<Value, This>, ): (asyncIterable: AsyncIterable<Value>) => AsyncOptional<Value> <Value>( asyncReducer: AsyncFunctionReducer<Value> | FunctionReducer<Value>, asyncIterable: AsyncIterable<Value>, ): AsyncOptional<Value> <Value>( asyncReducer: AsyncFunctionReducer<Value> | FunctionReducer<Value>, ): (asyncIterable: AsyncIterable<Value>) => AsyncOptional<Value> } /** * Returns the result of reducing the `concurIterable` using `asyncReducer`. * * Informally, an initial accumulator is created using * {@link AsyncReducer.create}. Then each value in `concurIterable` is added to * the accumulator and the current accumulator is updated using * {@link AsyncReducer.add}. Finally, the resulting accumulator is transformed * using {@link AsyncReducer.finish} if specified. Multiple accumulators may be * created, added to, and then combined if supported via * {@link AsyncReducer.combine} and the next value of `concurIterable` is ready * before promises from {@link AsyncReducer.add} resolve. * * If `asyncReducer` is an async optional reducer (no * {@link AsyncReducer.create} method), then an empty concur iterable is * returned if `concurIterable` is empty. Otherwise, an concur iterable * containing the result of reducing using the first value of the concur * iterable as the initial accumulator is returned. * * Like `Array.prototype.reduce`, but for concur iterables. * * @example * ```js * console.log( * await pipe( * asAsync([`Hello`, `World!`, `What`, `an`, `interesting`, `program!`]), * reduceAsync((a, b) => `${a} ${b}`), * getAsync, * ), * ) * //=> Hello World! What an interesting program! * * console.log( * await pipe( * asAsync([`Hello`, `World!`, `What`, `an`, `interesting`, `program!`]), * reduceAsync({ create: () => ``, add: (a, b) => `${a} ${b}` }), * ), * ) * //=> Hello World! What an interesting program! * ``` * * @category Reducers * @since v0.0.1 */ declare const reduceConcur: { <Value, Acc, Finished, This>( asyncReducer: | RawAsyncReducerWithFinish<Value, Acc, Finished, This> | RawReducerWithFinish<Value, Acc, Finished, This>, concurIterable: ConcurIterable<Value>, ): Promise<Finished> <Value, Acc, Finished, This>( asyncReducer: | RawAsyncReducerWithFinish<Value, Acc, Finished, This> | RawReducerWithFinish<Value, Acc, Finished, This>, ): (concurIterable: ConcurIterable<Value>) => Promise<Finished> <Value, Acc, This>( asyncReducer: | RawAsyncReducerWithoutFinish<Value, Acc, This> | RawReducerWithoutFinish<Value, Acc, This>, concurIterable: ConcurIterable<Value>, ): Promise<Acc> <Value, Acc, This>( asyncReducer: | RawAsyncReducerWithoutFinish<Value, Acc, This> | RawReducerWithoutFinish<Value, Acc, This>, ): (concurIterable: ConcurIterable<Value>) => Promise<Acc> <Value, Finished, This>( asyncReducer: | RawAsyncOptionalReducerWithFinish<Value, Finished, This> | RawOptionalReducerWithFinish<Value, Finished, This>, concurIterable: ConcurIterable<Value>, ): ConcurOptional<Finished> <Value, Finished, This>( asyncReducer: | RawAsyncOptionalReducerWithFinish<Value, Finished, This> | RawOptionalReducerWithFinish<Value, Finished, This>, ): (concurIterable: ConcurIterable<Value>) => ConcurOptional<Finished> <Value, This>( asyncReducer: | RawAsyncOptionalReducerWithoutFinish<Value, This> | RawOptionalReducerWithoutFinish<Value, This>, concurIterable: ConcurIterable<Value>, ): ConcurOptional<Value> <Value, This>( asyncReducer: | RawAsyncOptionalReducerWithoutFinish<Value, This> | RawOptionalReducerWithoutFinish<Value, This>, ): (concurIterable: ConcurIterable<Value>) => ConcurOptional<Value> <Value>( asyncReducer: FunctionReducer<Value> | AsyncFunctionReducer<Value>, concurIterable: ConcurIterable<Value>, ): ConcurOptional<Value> <Value>( asyncReducer: AsyncFunctionReducer<Value> | FunctionReducer<Value>, ): (concurIterable: ConcurIterable<Value>) => ConcurOptional<Value> } /** * Returns a {@link Reducer} that collects values to an `Array`. * * @example * ```js * console.log( * pipe( * cycle([`sloth`, `more sloth`]), * take(4), * reduce(toArray()), * ), * ) * //=> [ 'sloth', 'more sloth', 'sloth', 'more sloth' ] * ``` * * @category Collections * @since v0.0.1 */ declare const toArray: <Value>() => Reducer<Value, Value[]> /** * Returns a {@link Reducer} that collects values to a `Set`. * * @example * ```js * console.log( * pipe( * cycle([`sloth`, `more sloth`]), * take(4), * reduce(toArray()), * ), * ) * //=> Set(2) { 'sloth', 'more sloth' } * ``` * * @category Collections * @since v0.0.1 */ declare const toSet: <Value>() => Reducer<Value, Set<Value>> /** * Returns a {@link Reducer} that collects objects to a `WeakSet`. * * @example * ```js * console.log( * pipe( * cycle([`sloth`, `more sloth`]), * take(4), * map(string => ({ sloth: string })), * reduce(toWeakSet()), * ), * ) * //=> WeakSet { <items unknown> } * ``` * * @category Collections * @since v0.0.1 */ declare const toWeakSet: <Value extends object>() => Reducer< Value, WeakSet<Value> > /** * Returns a {@link KeyedReducer} that collects key-value pairs to an object. * * In the case of pairs with duplicate keys, the value of the last one wins. * * @example * ```js * console.log( * pipe( * [`sloth`, `more sloth`, `even more sloth`], * map(string => [string, string.length]), * reduce(toObject()), * ), * ) * //=> { sloth: 5, 'more sloth': 10, 'even more sloth': 15 } * ``` * * @category Collections * @since v0.0.1 */ declare const toObject: <Key extends keyof never, Value>() => RawKeyedReducer< Key, Value, Record<Key, Value> > /** * Returns a {@link KeyedReducer} that collects key-value pairs to a `Map`. * * In the case of pairs with duplicate keys, the value of the last one wins. * * @example * ```js * console.log( * pipe( * [`sloth`, `more sloth`, `even more sloth`], * map(string => [string, string.length]), * reduce(toMap()), * ), * ) * //=> Map(3) { 'sloth' => 5, 'more sloth' => 10, 'even more sloth' => 15 } * ``` * * @category Collections * @since v0.0.1 */ declare const toMap: <Key, Value>() => RawKeyedReducer< Key, Value, Map<Key, Value> > /** * Returns a {@link KeyedReducer} that collects key-value pairs to a `WeakMap`. * * In the case of pairs with duplicate keys, the value of the last one wins. * * @example * ```js * console.log( * pipe( * [`sloth`, `more sloth`, `even more sloth`], * map(string => [{ sloth: string }, string.length]), * reduce(toWeakMap()), * ), * ) * //=> WeakMap { <items unknown> } * ``` * * @category Collections * @since v0.0.1 */ declare const toWeakMap: <Key extends object, Value>() => RawKeyedReducer< Key, Value, WeakMap<Key, Value> > /** * Returns a {@link Reducer} that reduces key-value pairs using `outerReducer` * and reduces values with the same key using `innerReducer`. * * @example * ```js * console.log( * pipe( * [`sloth`, `some sloth`, `sleep`, `more sloth`, `even more sloth`], * map(string => [string.length, string]), * reduce(toGrouped(toArray(), toMap())), * ), * ) * //=> Map(3) { * //=> 5 => [ 'sloth', 'sleep' ], * //=> 10 => [ 'some sloth', 'more sloth' ], * //=> 15 => [ 'even more sloth' ] * //=> } * ``` * * @category Collections * @since v2.0.0 */ declare const toGrouped: { <Key, Value, InnerAcc, InnerFinished, InnerThis, OuterAcc, OuterThis>( innerReducer: Readonly< RawReducerWithFinish<Value, InnerAcc, InnerFinished, InnerThis> >, outerReducer: Readonly< RawKeyedReducer<Key, InnerAcc | InnerFinished, OuterAcc, OuterThis> >, ): Reducer<readonly [Key, Value], never, OuterAcc> <Value, InnerAcc, InnerFinished, InnerThis>( innerReducer: Readonly< RawReducerWithFinish<Value, InnerAcc, InnerFinished, InnerThis> >, ): <Key, OuterAcc, OuterThis>( outerReducer: Readonly< RawKeyedReducer<Key, InnerAcc | InnerFinished, OuterAcc, OuterThis> >, ) => Reducer<readonly [Key, Value], never, OuterAcc> <Key, Value, InnerAcc, InnerThis, OuterAcc, OuterThis>( innerReducer: Readonly<RawReducerWithoutFinish<Value, InnerAcc, InnerThis>>, outerReducer: Readonly<RawKeyedReducer<Key, InnerAcc, OuterAcc, OuterThis>>, ): Reducer<readonly [Key, Value], never, OuterAcc> <Value, InnerAcc, InnerThis>( innerReducer: Readonly<RawReducerWithoutFinish<Value, InnerAcc, InnerThis>>, ): <Key, OuterAcc, OuterThis>( outerReducer: Readonly<RawKeyedReducer<Key, InnerAcc, OuterAcc, OuterThis>>, ) => Reducer<readonly [Key, Value], never, OuterAcc> <Key, Value, InnerFinished, InnerThis, OuterAcc, OuterThis>( innerReducer: Readonly< RawOptionalReducerWithFinish<Value, InnerFinished, InnerThis> >, outerReducer: Readonly< RawKeyedReducer<Key, Value | InnerFinished, OuterAcc, OuterThis> >, ): Reducer<readonly [Key, Value], never, OuterAcc> <Value, InnerFinished, InnerThis>( innerReducer: Readonly< RawOptionalReducerWithFinish<Value, InnerFinished, InnerThis> >, ): <Key, OuterAcc, OuterThis>( outerReducer: Readonly< RawKeyedReducer<Key, Value | InnerFinished, OuterAcc, OuterThis> >, ) => Reducer<readonly [Key, Value], never, OuterAcc> <Key, Value, InnerThis, OuterAcc, OuterThis>( innerReducer: Readonly<RawOptionalReducerWithoutFinish<Value, InnerThis>>, outerReducer: Readonly<RawKeyedReducer<Key, Value, OuterAcc, OuterThis>>, ): Reducer<readonly [Key, Value], never, OuterAcc> <Value, InnerThis>( innerReducer: Readonly<RawOptionalReducerWithoutFinish<Value, InnerThis>>, ): <Key, OuterAcc, OuterThis>( outerReducer: Readonly<RawKeyedReducer<Key, Value, OuterAcc, OuterThis>>, ) => Reducer<readonly [Key, Value], never, OuterAcc> <Key, Value, OuterAcc, OuterThis>( innerReducer: FunctionReducer<Value>, outerReducer: Readonly<RawKeyedReducer<Key, Value, OuterAcc, OuterThis>>, ): Reducer<readonly [Key, Value], never, OuterAcc> <Value>( innerReducer: FunctionReducer<Value>, ): <Key, OuterAcc, OuterThis>( outerReducer: Readonly<RawKeyedReducer<Key, Value, OuterAcc, OuterThis>>, ) => Reducer<readonly [Key, Value], never, OuterAcc> } /** * Returns a {@link Reducer} or {@link OptionalReducer} that reduces values to * an object or array of the same shape as `reducers` using all of the reducers * in `reducers`. * * Returns an {@link OptionalReducer} if at least one of the input reducers is * an {@link OptionalReducer}. Otherwise, returns a {@link Reducer}. * * @example * ```js * console.log( * pipe( * [`sloth`, `some sloth`, `sleep`, `more sloth`, `even more sloth`], * map(string => string.length), * reduce(toMultiple([toSet(), toCount(), toJoin(`,`)])), * ), * ) * //=> [ Set(3) { 5, 10, 15 }, 5, '5,10,5,10,15' ] * * console.log( * pipe( * [`sloth`, `some sloth`, `sleep`, `more sloth`, `even more sloth`], * map(string => string.length), * reduce( * toMultiple({ * set: toSet(), * count: toCount(), * string: toJoin(`,`), * }), * ), * ), * ) * //=> { set: Set(3) { 5, 10, 15 }, count: 5, string: '5,10,5,10,15' } * ``` * * @category Collections * @since v2.0.0 */ declare const toMultiple: { < Value, Reducers extends | readonly [RawReducerWithoutFinish<Value, any>] | readonly RawReducerWithoutFinish<Value, any>[] | Readonly<Record<keyof never, RawReducerWithoutFinish<Value, any>>>, >( reducers: Reducers, ): Reducer< Value, { -readonly [Key in keyof Reducers]: Reducers[Key] extends RawReducerWithoutFinish< Value, infer Acc > ? Acc : never }, { -readonly [Key in keyof Reducers]: Reducers[Key] extends RawReducerWithFinish< Value, any, infer Finished > ? Finished : Reducers[Key] extends RawReducerWithoutFinish<Value, infer Acc> ? Acc : never } > < Value, Reducers extends | readonly [ | RawReducerWithoutFinish<Value, any> | RawOptionalReducerWithoutFinish<Value> | FunctionReducer<Value>, ] | readonly ( | RawReducerWithoutFinish<Value, any> | RawOptionalReducerWithoutFinish<Value> | FunctionReducer<Value> )[] | Readonly< Reco