@rimbu/common
Advanced tools
Comparing version 0.10.3 to 0.11.0
@@ -356,3 +356,3 @@ "use strict"; | ||
if (undefined === pred) | ||
return createMono(0, function (_, __, i) { return i + 1; }); | ||
return createOutput(0, function (_, __, i) { return i + 1; }); | ||
return createOutput(0, function (state, next, i) { return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
@@ -684,12 +684,14 @@ return tslib_1.__generator(this, function (_a) { | ||
/** | ||
* Returns a `Reducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in an array. | ||
* Returns an `AsyncReducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in an array. | ||
* @param reducers - 2 or more reducers to combine | ||
* @example | ||
* ```ts | ||
* const red = Reducer.combine(Reducer.sum, Reducer.average) | ||
* console.log(Stream.range({amount: 9 }).reduce(red)) | ||
* const red = AsyncReducer.combineArr(AsyncReducer.sum, AsyncReducer.average) | ||
* | ||
* await AsyncStream.from(Stream.range({ amount: 9 })) | ||
* .reduce(red) | ||
* // => [36, 4] | ||
* ``` | ||
*/ | ||
function combine() { | ||
function combineArr() { | ||
var _this = this; | ||
@@ -758,4 +760,116 @@ var reducers = []; | ||
} | ||
AsyncReducer.combine = combine; | ||
AsyncReducer.combineArr = combineArr; | ||
/** | ||
* Returns an `AsyncReducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in the shape of the given object. | ||
* @typeparam T - the input type for all the reducers | ||
* @typeparam R - the result object shape | ||
* @param reducerObj - an object of keys, and reducers corresponding to those keys | ||
* @example | ||
* ```ts | ||
* const red = AsyncReducer.combineObj({ | ||
* theSum: Reducer.sum, | ||
* theAverage: Reducer.average | ||
* }); | ||
* | ||
* await AsyncStream.from(Stream.range({ amount: 9 })) | ||
* .reduce(red)); | ||
* // => { theSum: 36, theAverage: 4 } | ||
* ``` | ||
*/ | ||
function combineObj(reducerObj) { | ||
var _this = this; | ||
var createState = function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
var entries; | ||
var _this = this; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, Promise.all(Object.entries(reducerObj).map(function (_a) { | ||
var _b = tslib_1.__read(_a, 2), key = _b[0], reducer = _b[1]; | ||
return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
var result; | ||
var _c; | ||
return tslib_1.__generator(this, function (_d) { | ||
switch (_d.label) { | ||
case 0: | ||
_c = { | ||
reducer: reducer, | ||
halted: false, | ||
halt: function () { | ||
result.halted = true; | ||
} | ||
}; | ||
return [4 /*yield*/, internal_1.AsyncOptLazy.toMaybePromise(reducer.init)]; | ||
case 1: | ||
result = (_c.state = _d.sent(), | ||
_c); | ||
return [2 /*return*/, [key, result]]; | ||
} | ||
}); | ||
}); | ||
}))]; | ||
case 1: | ||
entries = _a.sent(); | ||
return [2 /*return*/, Object.fromEntries(entries)]; | ||
} | ||
}); | ||
}); }; | ||
return create(createState, function (allState, next, index, halt) { return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
var anyNotHalted; | ||
var _this = this; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
anyNotHalted = false; | ||
return [4 /*yield*/, Promise.all(Object.values(allState).map(function (red) { return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
var _a; | ||
return tslib_1.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
if (red.halted) { | ||
return [2 /*return*/]; | ||
} | ||
_a = red; | ||
return [4 /*yield*/, red.reducer.next(red.state, next, index, red.halt)]; | ||
case 1: | ||
_a.state = _b.sent(); | ||
if (!red.halted) { | ||
anyNotHalted = true; | ||
} | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); }))]; | ||
case 1: | ||
_a.sent(); | ||
if (!anyNotHalted) { | ||
halt(); | ||
} | ||
return [2 /*return*/, allState]; | ||
} | ||
}); | ||
}); }, function (allState) { return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
var entries; | ||
var _this = this; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, Promise.all(Object.entries(allState).map(function (_a) { | ||
var _b = tslib_1.__read(_a, 2), key = _b[0], st = _b[1]; | ||
return tslib_1.__awaiter(_this, void 0, void 0, function () { var _c; return tslib_1.__generator(this, function (_d) { | ||
switch (_d.label) { | ||
case 0: | ||
_c = [key]; | ||
return [4 /*yield*/, st.reducer.stateToResult(st.state)]; | ||
case 1: return [2 /*return*/, _c.concat([_d.sent()])]; | ||
} | ||
}); }); | ||
}))]; | ||
case 1: | ||
entries = _a.sent(); | ||
return [2 /*return*/, Object.fromEntries(entries)]; | ||
} | ||
}); | ||
}); }); | ||
} | ||
AsyncReducer.combineObj = combineObj; | ||
})(AsyncReducer = exports.AsyncReducer || (exports.AsyncReducer = {})); | ||
//# sourceMappingURL=async-reducer.js.map |
@@ -305,3 +305,3 @@ "use strict"; | ||
if (undefined === pred) | ||
return createMono(0, function (_, __, i) { return i + 1; }); | ||
return createOutput(0, function (_, __, i) { return i + 1; }); | ||
return createOutput(0, function (state, next, i) { | ||
@@ -586,3 +586,3 @@ if (pred === null || pred === void 0 ? void 0 : pred(next, i)) | ||
* ```ts | ||
* const red = Reducer.combine(Reducer.sum, Reducer.average) | ||
* const red = Reducer.combineArr(Reducer.sum, Reducer.average) | ||
* console.log(Stream.range({amount: 9 }).reduce(red)) | ||
@@ -592,3 +592,3 @@ * // => [36, 4] | ||
*/ | ||
function combine() { | ||
function combineArr() { | ||
var reducers = []; | ||
@@ -617,10 +617,13 @@ for (var _i = 0; _i < arguments.length; _i++) { | ||
var red = allState[i]; | ||
if (red.halted) | ||
if (red.halted) { | ||
continue; | ||
} | ||
red.state = red.reducer.next(red.state, next, index, red.halt); | ||
if (!red.halted) | ||
if (!red.halted) { | ||
anyNotHalted = true; | ||
} | ||
} | ||
if (!anyNotHalted) | ||
if (!anyNotHalted) { | ||
halt(); | ||
} | ||
return allState; | ||
@@ -631,4 +634,66 @@ }, function (allState) { | ||
} | ||
Reducer.combine = combine; | ||
Reducer.combineArr = combineArr; | ||
/** | ||
* Returns a `Reducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in the shape of the given object. | ||
* @typeparam T - the input type for all the reducers | ||
* @typeparam R - the result object shape | ||
* @param reducerObj - an object of keys, and reducers corresponding to those keys | ||
* @example | ||
* ```ts | ||
* const red = Reducer.combineObj({ | ||
* theSum: Reducer.sum, | ||
* theAverage: Reducer.average | ||
* }); | ||
* | ||
* Stream.range({ amount: 9 }).reduce(red); | ||
* // => { theSum: 36, theAverage: 4 } | ||
* ``` | ||
*/ | ||
function combineObj(reducerObj) { | ||
var createState = function () { | ||
var allState = {}; | ||
var _loop_1 = function (key) { | ||
var reducer = reducerObj[key]; | ||
var result = { | ||
reducer: reducer, | ||
halted: false, | ||
halt: function () { | ||
result.halted = true; | ||
}, | ||
state: (0, internal_1.OptLazy)(reducer.init), | ||
}; | ||
allState[key] = result; | ||
}; | ||
for (var key in reducerObj) { | ||
_loop_1(key); | ||
} | ||
return allState; | ||
}; | ||
return create(createState, function (allState, next, index, halt) { | ||
var anyNotHalted = false; | ||
for (var key in allState) { | ||
var red = allState[key]; | ||
if (red.halted) { | ||
continue; | ||
} | ||
red.state = red.reducer.next(red.state, next, index, red.halt); | ||
if (!red.halted) { | ||
anyNotHalted = true; | ||
} | ||
} | ||
if (!anyNotHalted) { | ||
halt(); | ||
} | ||
return allState; | ||
}, function (allState) { | ||
var result = {}; | ||
for (var key in allState) { | ||
var st = allState[key]; | ||
result[key] = st.reducer.stateToResult(st.state); | ||
} | ||
return result; | ||
}); | ||
} | ||
Reducer.combineObj = combineObj; | ||
})(Reducer = exports.Reducer || (exports.Reducer = {})); | ||
//# sourceMappingURL=reducer.js.map |
@@ -271,3 +271,3 @@ import { __awaiter } from "tslib"; | ||
if (undefined === pred) | ||
return createMono(0, (_, __, i) => i + 1); | ||
return createOutput(0, (_, __, i) => i + 1); | ||
return createOutput(0, (state, next, i) => __awaiter(this, void 0, void 0, function* () { | ||
@@ -547,12 +547,14 @@ if (yield (pred === null || pred === void 0 ? void 0 : pred(next, i))) | ||
/** | ||
* Returns a `Reducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in an array. | ||
* Returns an `AsyncReducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in an array. | ||
* @param reducers - 2 or more reducers to combine | ||
* @example | ||
* ```ts | ||
* const red = Reducer.combine(Reducer.sum, Reducer.average) | ||
* console.log(Stream.range({amount: 9 }).reduce(red)) | ||
* const red = AsyncReducer.combineArr(AsyncReducer.sum, AsyncReducer.average) | ||
* | ||
* await AsyncStream.from(Stream.range({ amount: 9 })) | ||
* .reduce(red) | ||
* // => [36, 4] | ||
* ``` | ||
*/ | ||
function combine(...reducers) { | ||
function combineArr(...reducers) { | ||
const createState = () => { | ||
@@ -585,4 +587,57 @@ return Promise.all(reducers.map((reducer) => __awaiter(this, void 0, void 0, function* () { | ||
} | ||
AsyncReducer.combine = combine; | ||
AsyncReducer.combineArr = combineArr; | ||
/** | ||
* Returns an `AsyncReducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in the shape of the given object. | ||
* @typeparam T - the input type for all the reducers | ||
* @typeparam R - the result object shape | ||
* @param reducerObj - an object of keys, and reducers corresponding to those keys | ||
* @example | ||
* ```ts | ||
* const red = AsyncReducer.combineObj({ | ||
* theSum: Reducer.sum, | ||
* theAverage: Reducer.average | ||
* }); | ||
* | ||
* await AsyncStream.from(Stream.range({ amount: 9 })) | ||
* .reduce(red)); | ||
* // => { theSum: 36, theAverage: 4 } | ||
* ``` | ||
*/ | ||
function combineObj(reducerObj) { | ||
const createState = () => __awaiter(this, void 0, void 0, function* () { | ||
const entries = yield Promise.all(Object.entries(reducerObj).map(([key, reducer]) => __awaiter(this, void 0, void 0, function* () { | ||
const result = { | ||
reducer, | ||
halted: false, | ||
halt() { | ||
result.halted = true; | ||
}, | ||
state: yield AsyncOptLazy.toMaybePromise(reducer.init), | ||
}; | ||
return [key, result]; | ||
}))); | ||
return Object.fromEntries(entries); | ||
}); | ||
return create(createState, (allState, next, index, halt) => __awaiter(this, void 0, void 0, function* () { | ||
let anyNotHalted = false; | ||
yield Promise.all(Object.values(allState).map((red) => __awaiter(this, void 0, void 0, function* () { | ||
if (red.halted) { | ||
return; | ||
} | ||
red.state = yield red.reducer.next(red.state, next, index, red.halt); | ||
if (!red.halted) { | ||
anyNotHalted = true; | ||
} | ||
}))); | ||
if (!anyNotHalted) { | ||
halt(); | ||
} | ||
return allState; | ||
}), (allState) => __awaiter(this, void 0, void 0, function* () { | ||
const entries = yield Promise.all(Object.entries(allState).map(([key, st]) => __awaiter(this, void 0, void 0, function* () { return [key, yield st.reducer.stateToResult(st.state)]; }))); | ||
return Object.fromEntries(entries); | ||
})); | ||
} | ||
AsyncReducer.combineObj = combineObj; | ||
})(AsyncReducer || (AsyncReducer = {})); | ||
//# sourceMappingURL=async-reducer.js.map |
@@ -288,3 +288,3 @@ import { CollectFun, OptLazy } from './internal'; | ||
if (undefined === pred) | ||
return createMono(0, (_, __, i) => i + 1); | ||
return createOutput(0, (_, __, i) => i + 1); | ||
return createOutput(0, (state, next, i) => { | ||
@@ -568,3 +568,3 @@ if (pred === null || pred === void 0 ? void 0 : pred(next, i)) | ||
* ```ts | ||
* const red = Reducer.combine(Reducer.sum, Reducer.average) | ||
* const red = Reducer.combineArr(Reducer.sum, Reducer.average) | ||
* console.log(Stream.range({amount: 9 }).reduce(red)) | ||
@@ -574,3 +574,3 @@ * // => [36, 4] | ||
*/ | ||
function combine(...reducers) { | ||
function combineArr(...reducers) { | ||
const createState = () => { | ||
@@ -595,15 +595,77 @@ return reducers.map((reducer) => { | ||
const red = allState[i]; | ||
if (red.halted) | ||
if (red.halted) { | ||
continue; | ||
} | ||
red.state = red.reducer.next(red.state, next, index, red.halt); | ||
if (!red.halted) | ||
if (!red.halted) { | ||
anyNotHalted = true; | ||
} | ||
} | ||
if (!anyNotHalted) | ||
if (!anyNotHalted) { | ||
halt(); | ||
} | ||
return allState; | ||
}, (allState) => allState.map((st) => st.reducer.stateToResult(st.state))); | ||
} | ||
Reducer.combine = combine; | ||
Reducer.combineArr = combineArr; | ||
/** | ||
* Returns a `Reducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in the shape of the given object. | ||
* @typeparam T - the input type for all the reducers | ||
* @typeparam R - the result object shape | ||
* @param reducerObj - an object of keys, and reducers corresponding to those keys | ||
* @example | ||
* ```ts | ||
* const red = Reducer.combineObj({ | ||
* theSum: Reducer.sum, | ||
* theAverage: Reducer.average | ||
* }); | ||
* | ||
* Stream.range({ amount: 9 }).reduce(red); | ||
* // => { theSum: 36, theAverage: 4 } | ||
* ``` | ||
*/ | ||
function combineObj(reducerObj) { | ||
const createState = () => { | ||
const allState = {}; | ||
for (const key in reducerObj) { | ||
const reducer = reducerObj[key]; | ||
const result = { | ||
reducer, | ||
halted: false, | ||
halt() { | ||
result.halted = true; | ||
}, | ||
state: OptLazy(reducer.init), | ||
}; | ||
allState[key] = result; | ||
} | ||
return allState; | ||
}; | ||
return create(createState, (allState, next, index, halt) => { | ||
let anyNotHalted = false; | ||
for (const key in allState) { | ||
const red = allState[key]; | ||
if (red.halted) { | ||
continue; | ||
} | ||
red.state = red.reducer.next(red.state, next, index, red.halt); | ||
if (!red.halted) { | ||
anyNotHalted = true; | ||
} | ||
} | ||
if (!anyNotHalted) { | ||
halt(); | ||
} | ||
return allState; | ||
}, (allState) => { | ||
const result = {}; | ||
for (const key in allState) { | ||
const st = allState[key]; | ||
result[key] = st.reducer.stateToResult(st.state); | ||
} | ||
return result; | ||
}); | ||
} | ||
Reducer.combineObj = combineObj; | ||
})(Reducer || (Reducer = {})); | ||
//# sourceMappingURL=reducer.js.map |
@@ -91,3 +91,4 @@ import { AsyncCollectFun, AsyncOptLazy, MaybePromise, Reducer, Eq } from './internal'; | ||
*/ | ||
mapOutput<O2>(mapFun: (value: O) => MaybePromise<O2>): AsyncReducer<I, O2>; | ||
mapOutput<O2>(mapFun: (value: O) => O2): AsyncReducer<I, O2>; | ||
mapOutput<O2>(mapFun: (value: O) => Promise<O2>): AsyncReducer<I, O2>; | ||
/** | ||
@@ -325,3 +326,3 @@ * Returns an `AsyncReducer` instance that takes at most the given `amount` of input elements, and will ignore subsequent elements. | ||
const count: { | ||
(): AsyncReducer<any, number>; | ||
(): AsyncReducer<never, number>; | ||
<T>(pred: (value: T, index: number) => MaybePromise<boolean>): AsyncReducer<T, number>; | ||
@@ -451,3 +452,3 @@ }; | ||
*/ | ||
const isEmpty: AsyncReducer<any, boolean>; | ||
const isEmpty: AsyncReducer<never, boolean>; | ||
/** | ||
@@ -461,3 +462,3 @@ * Returns an `AsyncReducer` that outputs true if one or more input values are received, false otherwise. | ||
*/ | ||
const nonEmpty: AsyncReducer<any, boolean>; | ||
const nonEmpty: AsyncReducer<never, boolean>; | ||
/** | ||
@@ -509,14 +510,38 @@ * Returns an `AsyncReducer` that collects received input values in an array, and returns a copy of that array as an output value when requested. | ||
/** | ||
* Returns a `Reducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in an array. | ||
* Returns an `AsyncReducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in an array. | ||
* @param reducers - 2 or more reducers to combine | ||
* @example | ||
* ```ts | ||
* const red = Reducer.combine(Reducer.sum, Reducer.average) | ||
* console.log(Stream.range({amount: 9 }).reduce(red)) | ||
* const red = AsyncReducer.combineArr(AsyncReducer.sum, AsyncReducer.average) | ||
* | ||
* await AsyncStream.from(Stream.range({ amount: 9 })) | ||
* .reduce(red) | ||
* // => [36, 4] | ||
* ``` | ||
*/ | ||
function combine<T, R extends readonly [unknown, unknown, ...unknown[]]>(...reducers: { | ||
function combineArr<T, R extends readonly [unknown, unknown, ...unknown[]]>(...reducers: { | ||
[K in keyof R]: AsyncReducer<T, R[K]>; | ||
} & AsyncReducer<T, unknown>[]): AsyncReducer<T, R>; | ||
/** | ||
* Returns an `AsyncReducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in the shape of the given object. | ||
* @typeparam T - the input type for all the reducers | ||
* @typeparam R - the result object shape | ||
* @param reducerObj - an object of keys, and reducers corresponding to those keys | ||
* @example | ||
* ```ts | ||
* const red = AsyncReducer.combineObj({ | ||
* theSum: Reducer.sum, | ||
* theAverage: Reducer.average | ||
* }); | ||
* | ||
* await AsyncStream.from(Stream.range({ amount: 9 })) | ||
* .reduce(red)); | ||
* // => { theSum: 36, theAverage: 4 } | ||
* ``` | ||
*/ | ||
function combineObj<T, R extends { | ||
readonly [key: string]: unknown; | ||
}>(reducerObj: { | ||
readonly [K in keyof R]: AsyncReducer<T, R[K]>; | ||
} & Record<string, AsyncReducer<T, unknown>>): AsyncReducer<T, R>; | ||
} |
@@ -325,3 +325,3 @@ import { CollectFun, Eq, OptLazy } from './internal'; | ||
const count: { | ||
(): Reducer<any, number>; | ||
(): Reducer<never, number>; | ||
<T>(pred: (value: T, index: number) => boolean): Reducer<T, number>; | ||
@@ -451,3 +451,3 @@ }; | ||
*/ | ||
const isEmpty: Reducer<any, boolean>; | ||
const isEmpty: Reducer<never, boolean>; | ||
/** | ||
@@ -461,3 +461,3 @@ * Returns a `Reducer` that outputs true if one or more input values are received, false otherwise. | ||
*/ | ||
const nonEmpty: Reducer<any, boolean>; | ||
const nonEmpty: Reducer<never, boolean>; | ||
/** | ||
@@ -516,3 +516,3 @@ * Returns a `Reducer` that collects received input values in an array, and returns a copy of that array as an output value when requested. | ||
* ```ts | ||
* const red = Reducer.combine(Reducer.sum, Reducer.average) | ||
* const red = Reducer.combineArr(Reducer.sum, Reducer.average) | ||
* console.log(Stream.range({amount: 9 }).reduce(red)) | ||
@@ -522,5 +522,26 @@ * // => [36, 4] | ||
*/ | ||
function combine<T, R extends readonly [unknown, unknown, ...unknown[]]>(...reducers: { | ||
function combineArr<T, R extends readonly [unknown, unknown, ...unknown[]]>(...reducers: { | ||
[K in keyof R]: Reducer<T, R[K]>; | ||
} & Reducer<T, unknown>[]): Reducer<T, R>; | ||
/** | ||
* Returns a `Reducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in the shape of the given object. | ||
* @typeparam T - the input type for all the reducers | ||
* @typeparam R - the result object shape | ||
* @param reducerObj - an object of keys, and reducers corresponding to those keys | ||
* @example | ||
* ```ts | ||
* const red = Reducer.combineObj({ | ||
* theSum: Reducer.sum, | ||
* theAverage: Reducer.average | ||
* }); | ||
* | ||
* Stream.range({ amount: 9 }).reduce(red); | ||
* // => { theSum: 36, theAverage: 4 } | ||
* ``` | ||
*/ | ||
function combineObj<T, R extends { | ||
readonly [key: string]: unknown; | ||
}>(reducerObj: { | ||
readonly [K in keyof R]: Reducer<T, R[K]>; | ||
} & Record<string, Reducer<T, unknown>>): Reducer<T, R>; | ||
} |
{ | ||
"name": "@rimbu/common", | ||
"version": "0.10.3", | ||
"version": "0.11.0", | ||
"description": "Common types and objects used in many other Rimbu packages", | ||
@@ -53,2 +53,3 @@ "keywords": [ | ||
"test": "jest", | ||
"test:types": "tsd", | ||
"typecheck": "tsc" | ||
@@ -67,3 +68,3 @@ }, | ||
}, | ||
"gitHead": "c4009664c4e15f367e963d198cacd7c5fc182a4d" | ||
"gitHead": "28454fe17a4e51a42f6107f7b1733270d0d88de5" | ||
} |
@@ -108,3 +108,4 @@ import { | ||
*/ | ||
mapOutput<O2>(mapFun: (value: O) => MaybePromise<O2>): AsyncReducer<I, O2>; | ||
mapOutput<O2>(mapFun: (value: O) => O2): AsyncReducer<I, O2>; | ||
mapOutput<O2>(mapFun: (value: O) => Promise<O2>): AsyncReducer<I, O2>; | ||
/** | ||
@@ -577,3 +578,3 @@ * Returns an `AsyncReducer` instance that takes at most the given `amount` of input elements, and will ignore subsequent elements. | ||
export const count: { | ||
(): AsyncReducer<any, number>; | ||
(): AsyncReducer<never, number>; | ||
<T>(pred: (value: T, index: number) => MaybePromise<boolean>): AsyncReducer< | ||
@@ -585,4 +586,4 @@ T, | ||
pred?: (value: any, index: number) => MaybePromise<boolean> | ||
): AsyncReducer<any, number> => { | ||
if (undefined === pred) return createMono(0, (_, __, i): number => i + 1); | ||
): AsyncReducer<never, number> => { | ||
if (undefined === pred) return createOutput(0, (_, __, i): number => i + 1); | ||
@@ -848,3 +849,3 @@ return createOutput(0, async (state, next, i): Promise<number> => { | ||
*/ | ||
export const isEmpty = createOutput<any, boolean>( | ||
export const isEmpty = createOutput<never, boolean>( | ||
true, | ||
@@ -865,3 +866,3 @@ (_, __, ___, halt): false => { | ||
*/ | ||
export const nonEmpty = createOutput<any, boolean>( | ||
export const nonEmpty = createOutput<never, boolean>( | ||
false, | ||
@@ -963,12 +964,14 @@ (_, __, ___, halt): true => { | ||
/** | ||
* Returns a `Reducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in an array. | ||
* Returns an `AsyncReducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in an array. | ||
* @param reducers - 2 or more reducers to combine | ||
* @example | ||
* ```ts | ||
* const red = Reducer.combine(Reducer.sum, Reducer.average) | ||
* console.log(Stream.range({amount: 9 }).reduce(red)) | ||
* const red = AsyncReducer.combineArr(AsyncReducer.sum, AsyncReducer.average) | ||
* | ||
* await AsyncStream.from(Stream.range({ amount: 9 })) | ||
* .reduce(red) | ||
* // => [36, 4] | ||
* ``` | ||
*/ | ||
export function combine< | ||
export function combineArr< | ||
T, | ||
@@ -1044,2 +1047,109 @@ R extends readonly [unknown, unknown, ...unknown[]] | ||
} | ||
/** | ||
* Returns an `AsyncReducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in the shape of the given object. | ||
* @typeparam T - the input type for all the reducers | ||
* @typeparam R - the result object shape | ||
* @param reducerObj - an object of keys, and reducers corresponding to those keys | ||
* @example | ||
* ```ts | ||
* const red = AsyncReducer.combineObj({ | ||
* theSum: Reducer.sum, | ||
* theAverage: Reducer.average | ||
* }); | ||
* | ||
* await AsyncStream.from(Stream.range({ amount: 9 })) | ||
* .reduce(red)); | ||
* // => { theSum: 36, theAverage: 4 } | ||
* ``` | ||
*/ | ||
export function combineObj<T, R extends { readonly [key: string]: unknown }>( | ||
reducerObj: { readonly [K in keyof R]: AsyncReducer<T, R[K]> } & Record< | ||
string, | ||
AsyncReducer<T, unknown> | ||
> | ||
): AsyncReducer<T, R> { | ||
const createState = async (): Promise< | ||
Record< | ||
keyof R, | ||
{ | ||
reducer: AsyncReducer<T, unknown>; | ||
halted: boolean; | ||
halt(): void; | ||
state: unknown; | ||
} | ||
> | ||
> => { | ||
const entries = await Promise.all( | ||
Object.entries(reducerObj).map(async ([key, reducer]) => { | ||
const result = { | ||
reducer, | ||
halted: false, | ||
halt(): void { | ||
result.halted = true; | ||
}, | ||
state: await AsyncOptLazy.toMaybePromise(reducer.init), | ||
}; | ||
return [key, result] as const; | ||
}) | ||
); | ||
return Object.fromEntries(entries) as any; | ||
}; | ||
return create< | ||
T, | ||
R, | ||
Record< | ||
keyof R, | ||
{ | ||
reducer: AsyncReducer<T, unknown>; | ||
halted: boolean; | ||
halt(): void; | ||
state: unknown; | ||
} | ||
> | ||
>( | ||
createState, | ||
async (allState, next, index, halt) => { | ||
let anyNotHalted = false; | ||
await Promise.all( | ||
Object.values(allState).map(async (red) => { | ||
if (red.halted) { | ||
return; | ||
} | ||
red.state = await red.reducer.next( | ||
red.state, | ||
next, | ||
index, | ||
red.halt | ||
); | ||
if (!red.halted) { | ||
anyNotHalted = true; | ||
} | ||
}) | ||
); | ||
if (!anyNotHalted) { | ||
halt(); | ||
} | ||
return allState; | ||
}, | ||
async (allState) => { | ||
const entries = await Promise.all( | ||
Object.entries(allState).map( | ||
async ([key, st]) => | ||
[key, await st.reducer.stateToResult(st.state)] as const | ||
) | ||
); | ||
return Object.fromEntries(entries) as any; | ||
} | ||
); | ||
} | ||
} |
@@ -504,6 +504,8 @@ import { CollectFun, Eq, OptLazy } from './internal'; | ||
export const count: { | ||
(): Reducer<any, number>; | ||
(): Reducer<never, number>; | ||
<T>(pred: (value: T, index: number) => boolean): Reducer<T, number>; | ||
} = (pred?: (value: any, index: number) => boolean): Reducer<any, number> => { | ||
if (undefined === pred) return createMono(0, (_, __, i): number => i + 1); | ||
} = ( | ||
pred?: (value: unknown, index: number) => boolean | ||
): Reducer<never, number> => { | ||
if (undefined === pred) return createOutput(0, (_, __, i): number => i + 1); | ||
@@ -753,3 +755,3 @@ return createOutput(0, (state, next, i): number => { | ||
*/ | ||
export const isEmpty = createOutput<any, boolean>( | ||
export const isEmpty = createOutput<never, boolean>( | ||
true, | ||
@@ -770,3 +772,3 @@ (_, __, ___, halt): false => { | ||
*/ | ||
export const nonEmpty = createOutput<any, boolean>( | ||
export const nonEmpty = createOutput<never, boolean>( | ||
false, | ||
@@ -872,3 +874,3 @@ (_, __, ___, halt): true => { | ||
* ```ts | ||
* const red = Reducer.combine(Reducer.sum, Reducer.average) | ||
* const red = Reducer.combineArr(Reducer.sum, Reducer.average) | ||
* console.log(Stream.range({amount: 9 }).reduce(red)) | ||
@@ -878,3 +880,3 @@ * // => [36, 4] | ||
*/ | ||
export function combine< | ||
export function combineArr< | ||
T, | ||
@@ -912,12 +914,20 @@ R extends readonly [unknown, unknown, ...unknown[]] | ||
const len = allState.length; | ||
while (++i < len) { | ||
const red = allState[i]; | ||
if (red.halted) continue; | ||
if (red.halted) { | ||
continue; | ||
} | ||
red.state = red.reducer.next(red.state, next, index, red.halt); | ||
if (!red.halted) anyNotHalted = true; | ||
if (!red.halted) { | ||
anyNotHalted = true; | ||
} | ||
} | ||
if (!anyNotHalted) halt(); | ||
if (!anyNotHalted) { | ||
halt(); | ||
} | ||
@@ -930,2 +940,91 @@ return allState; | ||
} | ||
/** | ||
* Returns a `Reducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in the shape of the given object. | ||
* @typeparam T - the input type for all the reducers | ||
* @typeparam R - the result object shape | ||
* @param reducerObj - an object of keys, and reducers corresponding to those keys | ||
* @example | ||
* ```ts | ||
* const red = Reducer.combineObj({ | ||
* theSum: Reducer.sum, | ||
* theAverage: Reducer.average | ||
* }); | ||
* | ||
* Stream.range({ amount: 9 }).reduce(red); | ||
* // => { theSum: 36, theAverage: 4 } | ||
* ``` | ||
*/ | ||
export function combineObj<T, R extends { readonly [key: string]: unknown }>( | ||
reducerObj: { readonly [K in keyof R]: Reducer<T, R[K]> } & Record< | ||
string, | ||
Reducer<T, unknown> | ||
> | ||
): Reducer<T, R> { | ||
const createState = (): Record< | ||
keyof R, | ||
{ | ||
reducer: Reducer<T, unknown>; | ||
halted: boolean; | ||
halt(): void; | ||
state: unknown; | ||
} | ||
> => { | ||
const allState: any = {}; | ||
for (const key in reducerObj) { | ||
const reducer = reducerObj[key]; | ||
const result = { | ||
reducer, | ||
halted: false, | ||
halt(): void { | ||
result.halted = true; | ||
}, | ||
state: OptLazy(reducer.init), | ||
}; | ||
allState[key] = result; | ||
} | ||
return allState; | ||
}; | ||
return create<T, R, ReturnType<typeof createState>>( | ||
createState, | ||
(allState, next, index, halt) => { | ||
let anyNotHalted = false; | ||
for (const key in allState) { | ||
const red = allState[key]; | ||
if (red.halted) { | ||
continue; | ||
} | ||
red.state = red.reducer.next(red.state, next, index, red.halt); | ||
if (!red.halted) { | ||
anyNotHalted = true; | ||
} | ||
} | ||
if (!anyNotHalted) { | ||
halt(); | ||
} | ||
return allState; | ||
}, | ||
(allState) => { | ||
const result: any = {}; | ||
for (const key in allState) { | ||
const st = allState[key]; | ||
result[key] = st.reducer.stateToResult(st.state); | ||
} | ||
return result; | ||
} | ||
); | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
510951
10602