A single async task with error-aware utilities like retries and timeouts.
acquireRelease<R,T,E,>(unnamed 0: { acquire: (signal?: AbortSignal) => Promise<R>; release: (resource: R) => Promise<void>; use: (resource: R) => Task<T, E>; }): Task<T, E>
Acquires a resource, runs a task that uses it, and releases it regardless of success or failure. Useful for resource lifecycle management when the use computation is a composed Task chain.
The acquire function receives an optional AbortSignal that is active when
the task is run with a signal. The release function always runs and does
not receive a signal — cleanup should not be cancellable.
Runs multiple tasks and collects results. Rejects on the first failure.
Runs multiple tasks and collects all results without throwing.
Runs tasks sequentially, passing the successful value from one to the next. If any task fails, the chain is short-circuited and the error is returned.
Return types -> parameter type inference is supported up to an arbitrary 7 tasks. If you need more, you can just chain two chains.
Example usage:
Task.chain([ () => Task.of(() => 1), (prev) => Task.of(() => prev + 1), (prev) => Task.of(() => `Result: ${prev}`), ]).tap((result) => { console.log(result) // "Result: 2" }).run()
mergeExternalSignals(outer: AbortSignal,inner: AbortSignal,): { signal: AbortSignal; cleanup: () => void; }
of<R,E,>(task: (signal?: AbortSignal) => Promisable<R>): Task<R, E>
Creates a Task from a sync or async function. The function receives an optional AbortSignal that is active when the task is run with a signal via withSignal or run.
Note: the error type E is unchecked and represents the expected error
shape rather than a runtime guarantee.
runTask: (signal?: AbortSignal) => Promise<T>
delayWithSignal(ms: number,signal?: AbortSignal,): Promise<void>
Chains another task based on the successful value.
Chains another task based on the error value.
Maps the successful value. Errors are passed through unchanged.
Maps the error value. Successful values are passed through unchanged.
mergeSignals(outer: AbortSignal,inner?: AbortSignal,): { signal: AbortSignal; cleanup: () => void; }
Recovers from errors by mapping them to a successful value.
recoverWhen<E2 extends E,U,>(guard: (error: E) => error is E2,fn: (error: E2) => Promisable<U>,): Task<T | U, Exclude<E, E2>>
Recovers from specific error types by mapping them to a successful value.
retry(options: { attempts: number; delay?: number | ((attempt: number,error: E,) => number); when?: (error: E) => boolean; }): Task<T, E>
Retries the task when the predicate returns true.
runWithSignal(signal?: AbortSignal): Promise<T>
Throws the specified error types if encountered, propagating them to the caller.
Fails if the task does not complete within the specified time.
tryFlatMap<U,F,>(): Task<U, E>
Chains another task based on the successful value, with error handling for the mapper. If the mapper fails, errFn can recover by returning a success value.
Maps successful values with fn and transforms errors with errFn. Both
receive the original value so you can contextualize the mapping.
withSignal(signal: AbortSignal): Task<T, E>
Wraps the task with an external abort signal.