import {flow} from '../../function/work'; import {isError, isOk} from '../../internal/result'; import type {GenericCallback} from '../../models'; import {attempt} from '../index'; import type {Result, UnwrapValue} from '../models'; // #region Types /** * A synchronous _Flow_, a function that attempts to pipe values through a series of functions */ export type AttemptFlow = ( ...args: Parameters ) => Result>; /** * An asynchronous _Flow_, a function that attempts to pipe values through a series of functions */ export type AttemptFlowPromise = ( ...args: Parameters ) => Promise>>; // #endregion // #region Functions // #region Asynchronous /** * Create an asynchronous _Flow_, a function that attempts to pipe a value through a series of functions * * _Available as `attemptAsyncFlow` and `attemptFlow.async`_ * * @returns _Flow_ function */ export function attemptAsyncFlow( fn: Fn, ): AttemptFlowPromise>; /** * Create an asynchronous _Flow_, a function that pipes values through a series of functions * * _Available as `attemptAsyncFlow` and `attemptFlow.async`_ * * @returns _Flow_ function */ export function attemptAsyncFlow( first: First, second: (value: Awaited>>) => Second, ): AttemptFlowPromise; /** * Create an asynchronous _Flow_, a function that pipes values through a series of functions * * _Available as `attemptAsyncFlow` and `attemptFlow.async`_ * * @returns _Flow_ function */ export function attemptAsyncFlow( first: First, second: (value: Awaited>>) => Second, third: (value: Awaited>) => Third, ): AttemptFlowPromise; /** * Create an asynchronous _Flow_, a function that pipes values through a series of functions * * _Available as `attemptAsyncFlow` and `attemptFlow.async`_ * * @returns _Flow_ function */ export function attemptAsyncFlow( first: First, second: (value: Awaited>>) => Second, third: (value: Awaited>) => Third, fourth: (value: Awaited>) => Fourth, ): AttemptFlowPromise; /** * Create an asynchronous _Flow_, a function that pipes values through a series of functions * * _Available as `attemptAsyncFlow` and `attemptFlow.async`_ * * @returns _Flow_ function */ export function attemptAsyncFlow( first: First, second: (value: Awaited>>) => Second, third: (value: Awaited>) => Third, fourth: (value: Awaited>) => Fourth, fifth: (value: Awaited>) => Fifth, ): AttemptFlowPromise; /** * Create an asynchronous _Flow_, a function that pipes values through a series of functions * * _Available as `attemptAsyncFlow` and `attemptFlow.async`_ * * @returns _Flow_ function */ export function attemptAsyncFlow< First extends GenericCallback, Second, Third, Fourth, Fifth, Sixth, >( first: First, second: (value: Awaited>>) => Second, third: (value: Awaited>) => Third, fourth: (value: Awaited>) => Fourth, fifth: (value: Awaited>) => Fifth, sixth: (value: Awaited>) => Sixth, ): AttemptFlowPromise; /** * Create an asynchronous _Flow_, a function that pipes values through a series of functions * * _Available as `attemptAsyncFlow` and `attemptFlow.async`_ * * @returns _Flow_ function */ export function attemptAsyncFlow< First extends GenericCallback, Second, Third, Fourth, Fifth, Sixth, Seventh, >( first: First, second: (value: Awaited>>) => Second, third: (value: Awaited>) => Third, fourth: (value: Awaited>) => Fourth, fifth: (value: Awaited>) => Fifth, sixth: (value: Awaited>) => Sixth, seventh: (value: Awaited>) => Seventh, ): AttemptFlowPromise; /** * Create an asynchronous _Flow_, a function that pipes values through a series of functions * * _Available as `attemptAsyncFlow` and `attemptFlow.async`_ * * @returns _Flow_ function */ export function attemptAsyncFlow< First extends GenericCallback, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, >( first: First, second: (value: Awaited>>) => Second, third: (value: Awaited>) => Third, fourth: (value: Awaited>) => Fourth, fifth: (value: Awaited>) => Fifth, sixth: (value: Awaited>) => Sixth, seventh: (value: Awaited>) => Seventh, eighth: (value: Awaited>) => Eighth, ): AttemptFlowPromise; /** * Create an asynchronous _Flow_, a function that pipes values through a series of functions * * _Available as `attemptAsyncFlow` and `attemptFlow.async`_ * * @returns _Flow_ function */ export function attemptAsyncFlow< First extends GenericCallback, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, >( first: First, second: (value: Awaited>>) => Second, third: (value: Awaited>) => Third, fourth: (value: Awaited>) => Fourth, fifth: (value: Awaited>) => Fifth, sixth: (value: Awaited>) => Sixth, seventh: (value: Awaited>) => Seventh, eighth: (value: Awaited>) => Eighth, ninth: (value: Awaited>) => Ninth, ): AttemptFlowPromise; /** * Create an asynchronous _Flow_, a function that pipes values through a series of functions * * _Available as `attemptAsyncFlow` and `attemptFlow.async`_ * * @returns _Flow_ function */ export function attemptAsyncFlow< First extends GenericCallback, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth, >( first: First, second: (value: Awaited>>) => Second, third: (value: Awaited>) => Third, fourth: (value: Awaited>) => Fourth, fifth: (value: Awaited>) => Fifth, sixth: (value: Awaited>) => Sixth, seventh: (value: Awaited>) => Seventh, eighth: (value: Awaited>) => Eighth, ninth: (value: Awaited>) => Ninth, tenth: (value: Awaited>) => Tenth, ): AttemptFlowPromise; /** * Create an asynchronous _Flow_, a function that pipes values through a series of functions * * _Available as `attemptAsyncFlow` and `attemptFlow.async`_ * * @returns _Flow_ function */ export function attemptAsyncFlow( fn: Fn, ...fns: Array<(value: Awaited>>) => unknown> ): AttemptFlowPromise>; /** * Create an asynchronous _Flow_, a function that pipes values through a series of functions * * _Available as `attemptAsyncFlow` and `attemptFlow.async`_ * * @returns _Flow_ function */ export function attemptAsyncFlow( ...fns: GenericCallback[] ): (...args: unknown[]) => Promise>; export function attemptAsyncFlow( ...fns: GenericCallback[] ): (...args: unknown[]) => Promise> { let Flow: GenericCallback; return (...args: unknown[]) => attempt.async(() => { Flow ??= flow.async(...fns); return Flow( ...args.map(value => { if (isError(value)) { throw value.error; } return isOk(value) ? value.value : value; }), ); }); } // #endregion // #region Synchronous /** * Create a _Flow_, a function that attempts to pipe values through a function * * @returns _Flow_ function */ export function attemptFlow(fn: Fn): AttemptFlow>; /** * Create a _Flow_, a function that attempts to pipe values through a series of functions * * @returns _Flow_ function */ export function attemptFlow( first: First, second: (value: UnwrapValue>) => Second, ): AttemptFlow; /** * Create a _Flow_, a function that attempts to pipe values through a series of functions * * @returns _Flow_ function */ export function attemptFlow( first: First, second: (value: UnwrapValue>) => Second, third: (value: UnwrapValue) => Third, ): AttemptFlow; /** * Create a _Flow_, a function that attempts to pipe values through a series of functions * * @returns _Flow_ function */ export function attemptFlow( first: First, second: (value: UnwrapValue>) => Second, third: (value: UnwrapValue) => Third, fourth: (value: UnwrapValue) => Fourth, ): AttemptFlow; /** * Create a _Flow_, a function that attempts to pipe values through a series of functions * * @returns _Flow_ function */ export function attemptFlow( first: First, second: (value: UnwrapValue>) => Second, third: (value: UnwrapValue) => Third, fourth: (value: UnwrapValue) => Fourth, fifth: (value: UnwrapValue) => Fifth, ): AttemptFlow; /** * Create a _Flow_, a function that attempts to pipe values through a series of functions * * @returns _Flow_ function */ export function attemptFlow( first: First, second: (value: UnwrapValue>) => Second, third: (value: UnwrapValue) => Third, fourth: (value: UnwrapValue) => Fourth, fifth: (value: UnwrapValue) => Fifth, sixth: (value: UnwrapValue) => Sixth, ): AttemptFlow; /** * Create a _Flow_, a function that attempts to pipe values through a series of functions * * @returns _Flow_ function */ export function attemptFlow< First extends GenericCallback, Second, Third, Fourth, Fifth, Sixth, Seventh, >( first: First, second: (value: UnwrapValue>) => Second, third: (value: UnwrapValue) => Third, fourth: (value: UnwrapValue) => Fourth, fifth: (value: UnwrapValue) => Fifth, sixth: (value: UnwrapValue) => Sixth, seventh: (value: UnwrapValue) => Seventh, ): AttemptFlow; /** * Create a _Flow_, a function that attempts to pipe values through a series of functions * * @returns _Flow_ function */ export function attemptFlow< First extends GenericCallback, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, >( first: First, second: (value: UnwrapValue>) => Second, third: (value: UnwrapValue) => Third, fourth: (value: UnwrapValue) => Fourth, fifth: (value: UnwrapValue) => Fifth, sixth: (value: UnwrapValue) => Sixth, seventh: (value: UnwrapValue) => Seventh, eighth: (value: UnwrapValue) => Eighth, ): AttemptFlow; /** * Create a _Flow_, a function that attempts to pipe values through a series of functions * * @returns _Flow_ function */ export function attemptFlow< First extends GenericCallback, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, >( first: First, second: (value: UnwrapValue>) => Second, third: (value: UnwrapValue) => Third, fourth: (value: UnwrapValue) => Fourth, fifth: (value: UnwrapValue) => Fifth, sixth: (value: UnwrapValue) => Sixth, seventh: (value: UnwrapValue) => Seventh, eighth: (value: UnwrapValue) => Eighth, ninth: (value: UnwrapValue) => Ninth, ): AttemptFlow; /** * Create a _Flow_, a function that attempts to pipe values through a series of functions * * @returns _Flow_ function */ export function attemptFlow< First extends GenericCallback, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth, >( first: First, second: (value: UnwrapValue>) => Second, third: (value: UnwrapValue) => Third, fourth: (value: UnwrapValue) => Fourth, fifth: (value: UnwrapValue) => Fifth, sixth: (value: UnwrapValue) => Sixth, seventh: (value: UnwrapValue) => Seventh, eighth: (value: UnwrapValue) => Eighth, ninth: (value: UnwrapValue) => Ninth, tenth: (value: UnwrapValue) => Tenth, ): AttemptFlow; /** * Create a _Flow_, a function that attempts to pipe values through a series of functions * * @returns _Flow_ function */ export function attemptFlow( first: First, ...fns: Array<(value: UnwrapValue>) => unknown> ): AttemptFlow>; /** * Create a _Flow_, a function that attempts to pipe values through a series of functions * * @returns _Flow_ function */ export function attemptFlow(...fns: GenericCallback[]): (...args: unknown[]) => Result; export function attemptFlow(...fns: GenericCallback[]): (...args: unknown[]) => Result { let Flow: GenericCallback; return (...args: unknown[]) => attempt(() => { Flow ??= flow(...fns); return Flow( ...args.map(value => { if (isError(value)) { throw value.error; } return isOk(value) ? value.value : value; }), ); }); } attemptFlow.async = attemptAsyncFlow; // #endregion // #endregion