import type {Bud} from '@roots/bud-framework' import isUndefined from '@roots/bud-support/isUndefined' /** * Pipe callback * * @remarks * The output of this function becomes the input to the next */ interface Callback { (input: T): Promise | T } export interface pipe { (fns: Array>, value?: T): Promise } /** * Pipe a value through an array of functions. The return value of each callback is used as input for the next. * * @remarks * If no value is provided the value is assumed to be the {@link Bud} itself * * {@link sequence} is a non-mutational version of this method. * * @example * ```js * app.pipe( * [ * value => value + 1, * value => value + 1, * ], * 1, // initial value * ) // resulting value is 3 * ``` */ export const pipe: pipe = async function (functions, maybeInitialValue) { return await functions.reduce( async (value, fn) => { try { return await fn(await value) } catch (e) { this.catch(e) return await value } }, Promise.resolve( !isUndefined(maybeInitialValue) ? maybeInitialValue : this, ), ) }