import { Narrow, Intersect } from './type'; import { singleton } from './function'; type Function = (...args: unknown[]) => unknown; type ParamNs = FS extends readonly [infer T1 extends Function, ...infer TS extends Function[]] ? [Exclude[I], E>, ...ParamNs] : []; type Context = Intersect unknown ? C : never; }>>; type Returns = { [P in keyof FS]: FS[P] extends FS[number] ? ReturnType : FS[P]; }; type ReturnResults = { readonly [P in keyof FS]: FS[P] extends FS[number] ? Result> : FS[P]; }; type Result = | { readonly value: T; readonly done: true; } | { readonly value: unknown; readonly done: false; }; export function bundle unknown)[]>(...fs: fs): (...bs: ParamNs) => Returns; export function bundle unknown)[]>(...fs: fs): (this: Context, ...bs: ParamNs) => Returns; export function bundle unknown)[]>(...fs: fs): (this: Context, ...bs: ParamNs) => Returns { return function (...bs) { return fs.map((f, i) => f.call(this, bs[i])) as Returns; }; } export function aggregate unknown)[]>(...fs: fs): (a?: Intersect>>) => Returns; export function aggregate unknown)[]>(...fs: fs): (this: Context, a?: Intersect>>) => Returns; export function aggregate unknown)[]>(...fs: fs): (a: Intersect>>) => Returns; export function aggregate unknown)[]>(...fs: fs): (this: Context, a: Intersect>>) => Returns; export function aggregate unknown)[]>(...fs: fs): (this: Context, a: Intersect>>) => Returns { return function (a) { return fs.map(f => f.call(this, a)) as Returns; }; } export function assemble (error?: Error) => void)[]>(...fs: fs): (a?: Intersect>>) => (error?: Error) => ReturnResults>; export function assemble (error?: Error) => void)[]>(...fs: fs): (this: Context, a?: Intersect>>) => (error?: Error) => ReturnResults>; export function assemble (error?: Error) => void)[]>(...fs: fs): (a: Intersect>>) => (error?: Error) => ReturnResults>; export function assemble (error?: Error) => void)[]>(...fs: fs): (this: Context, a: Intersect>>) => (error?: Error) => ReturnResults>; export function assemble (error?: Error) => void)[]>(...fs: fs): (this: Context, a: Intersect>>) => (error?: Error) => ReturnResults> { return function (a) { const gs: ((error?: Error) => void)[] = Array(fs.length); try { for (let i = 0; i < fs.length; ++i) { gs[i] = fs[i].call(this, a); } return singleton((error?: Error) => cancel(gs, error) as ReturnResults>); } catch (reason) { cancel(gs, reason instanceof Error ? reason : new Error('Spica: Arrow: assemble: Wrap the error value', { cause: reason })); throw reason; } }; } function cancel(cancellers: readonly ((error?: Error) => T)[], error?: Error): readonly Result[] { const results: Result[] = Array(cancellers.length); for (let i = 0, g: typeof cancellers[number]; g = cancellers[i]; ++i) { try { results[i] = { value: g(error), done: true }; } catch (reason) { results[i] = { value: reason, done: false }; } } return results; }