froebel
Version:
TypeScript utility library
74 lines (61 loc) • 1.97 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.applyPipe = void 0;
var _isPromise = _interopRequireDefault(require("./isPromise"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Given a list of functions returns a function that will execute the given
* functions one after another, always passing the result of the previous
* function as an argument to the next function.
*
* If one of the given functions returns a promise, the promise will be resolved
* before being passed to the next function.
*
* @example
* ```
* const join = (...chars: string[]) => chars.join('')
* pipe(join, parseInt)('1', '2', '3') // -> 123
*
* const square = (n: number) => n ** 2
*
* // this is equivalent to: square(square(square(2)))
* pipe(square, square, square)(2) // -> 256
*
* // also works with promises:
* fetchNumber :: async () => Promise<number>
* pipe(fetchNumber, n => n.toString()) // async () => Promise<string>
* ```
*/
const pipe = (...funs) => (...args) => {
let nextArgs = args;
for (let i = 0; i < funs.length; i++) {
const [result] = nextArgs = [funs[i](...nextArgs)];
if ((0, _isPromise.default)(result)) return resolveAsync(result, funs.slice(i + 1));
}
return nextArgs[0];
};
var _default = pipe;
/**
* Like `pipe` but takes an argument as its first parameter and invokes the pipe
* with it.
*
* Note: unlike in `pipe`, the first function of the pipe must take exactly one
* argument.
*
* @see {@link pipe}
*
* @example
* ```
* applyPipe(2, double, square, half) // -> 8
* ```
*/
exports.default = _default;
const applyPipe = (arg, ...funs) => pipe(...funs)(arg);
exports.applyPipe = applyPipe;
const resolveAsync = async (result, funs) => {
for (const fun of funs) result = fun(await result);
return await result;
};
module.exports = Object.assign(exports.default || {}, exports);