velt/task
API referenceCancellation with TypeScript's AbortController / AbortSignal (global, as in Node; this module exports them too), timeouts, task scopes (structured concurrency) and task placement. fetch takes a signal. For a walkthrough, read the guide.
Exports
body with a TaskScope and settles only once the body and every task it spawned with scope.spawn have finished, so no child outlives the scope.timeoutp, unless it does not settle within ms milliseconds: then TimeoutError.currentWorkerThe worker running this task, from 0 to workerCount() - 1; 0 outside a task (a synchronous main).workerCountHow many workers run tasks: fixed for the process (VELT_THREADS, else the number of cores; 1 on WebAssembly), with either scheduler.AbortControllerThe sending half: abort() aborts its signal.AbortErrorThrown by throwIfAborted(): the signal's reason is the message.TaskScopeA running taskScope: spawns its child tasks and carries the signal that cancels them.AbortSignalThe receiving half: tells work that it should stop.TimeoutErrorThrown by timeout(p, ms) when p does not settle in time, and by throwIfAborted() on a signal that an AbortSignal.timeout aborted.ScopeOptionstaskScope's options.SpawnOptionsThe options of spawn(p, options): worker pins the task to that worker (0 to workerCount() - 1), where it starts and stays.Re-exported from velt/task/scope
async function taskScope<T, E>(
body: (scope: TaskScope<E>) => Promise<T> throws E,
options: ScopeOptions = {},
): Promise<T> throws EStructured concurrency: runs body with a TaskScope and settles only once the body and
every task it spawned with scope.spawn have finished, so no child outlives the scope. The
scope fails with the first error in time, of the body or of any child (even one nobody
awaited, or whose error the body caught), and otherwise returns the body's result. With
cancelOnError (the default), that first error aborts scope.signal, so the other children
can stop; their AbortErrors come later and don't replace it.
Re-exported from velt/task/timeout
async function timeout<T, E>(
p: Promise<T, E>,
ms: i64,
): Promise<T> throws E | TimeoutErrorp, unless it does not settle within ms milliseconds: then TimeoutError. p is raced
directly, so after a timeout it is abandoned like a Promise.race loser: a runtime wait
(signal.whenAborted(), a timer) is dropped, and a started task keeps running, its
rejection handled (pass it a signal to stop it). When p wins, the timer is cancelled at
once, so nothing is left waiting.
Re-exported from velt/task/workers
function currentWorker(): i64The worker running this task, from 0 to workerCount() - 1; 0 outside a task (a
synchronous main). A task stays on its worker with the per-core scheduler (which a program
that pins a task gets); otherwise it may move at any await.
Re-exported from velt/task/workers
function workerCount(): i64How many workers run tasks: fixed for the process (VELT_THREADS, else the number of cores;
1 on WebAssembly), with either scheduler. Calling it doesn't change the scheduler: only
pinning a task (spawn(p, { worker })) selects the per-core one.
Re-exported from velt/task/controller
The sending half: abort() aborts its signal.
Parameter ofvelt/timeTickerStop.constructor
constructor()No doc comment yetget signal(): AbortSignalThe controller's signal (the same object every time, like JS).
abort(reason: string = DEFAULT_REASON)Aborts the signal (a no-op if it already is).
[ [INSPECT]()How console.log shows the controller, like Node: its signal.
Re-exported from velt/task/errors
class AbortError extends ErrorThrown by throwIfAborted(): the signal's reason is the message.
Returned byvelt/net/httpBodyStream.[Symbol.asyncIterator]fetchRequest.textResponse.textThrown byAbortSignal.throwIfAbortedUsed byTimeoutErrorvelt/ioReadableStream.[BYTE_CHUNKS]
constructor(reason: string)No doc comment yetRe-exported from velt/task/scope
class TaskScope<E>A running taskScope: spawns its child tasks and carries the signal that cancels them. E
is the error type of the scope, its body and its children.
Parameter oftaskScope
constructor(group: shared<Mutex<GroupObj>>, sig: AbortSignal, errors: FirstError<E>, cancelOnError: bool)Made by taskScope (GroupObj is internal).
get signal(): AbortSignalThe scope's signal: aborted when the body or a child fails (with cancelOnError), on
cancel(), and when the scope's task is cancelled. Pass it to the children so they stop
cooperatively.
spawn<T>(p: Promise<T, E>): Promise<T, E>Adds p as a child task of the scope (spawn(p); a call starts on this task, as any
promise value); the scope waits for it. A promise that cannot fail (Promise<T>) is
accepted too.
cancel(reason: string = DEFAULT_REASON)Aborts the scope's signal.
Re-exported from velt/task/signal
The receiving half: tells work that it should stop.
Parameter ofTaskScope.constructorvelt/netTcpStream.readableWithinReturned byAbortController.signalTaskScope.signalvelt/devjoinStopvelt/net/httpRequest.signalUsed byvelt/net/httpRequestInit.signal
constructor(cell: SignalCell)Made by AbortController, taskScope and the static constructors (SignalCell is
internal).
get aborted(): boolWhether abort() was called (or the timeout elapsed).
get reason(): stringThe reason passed to abort() ("" while not aborted).
throwIfAborted() throws AbortErrorThrows if the signal is aborted: TimeoutError if an AbortSignal.timeout aborted it,
otherwise AbortError with the reason as its message.
whenAborted(): Promise<void>Resolves once the signal is aborted (never, if it never is). Race it directly against
work: Promise.race([work(), signal.whenAborted()]).
static timeout(ms: i64): AbortSignalA signal that aborts by itself after ms milliseconds (reason "timed out after <ms> ms";
throwIfAborted() throws TimeoutError).
static any(signals: AbortSignal[]): AbortSignalA signal that aborts as soon as any of signals does, with its reason. It keeps those
signals alive until then.
[ [INSPECT]()How console.log shows the signal, like Node: AbortSignal { aborted: false }.
Re-exported from velt/task/timeout
class TimeoutError extends AbortErrorThrown by timeout(p, ms) when p does not settle in time, and by throwIfAborted() on a
signal that an AbortSignal.timeout aborted.
Thrown bytimeout
ms: i64No doc comment yetconstructor(ms: i64)No doc comment yetRe-exported from velt/task/scope
type ScopeOptions = { cancelOnError?: bool }taskScope's options. cancelOnError: abort scope.signal when the body or a child fails
(default true).
Parameter oftaskScope
Re-exported from velt/task/workers
type SpawnOptions = { worker?: i64 }The options of spawn(p, options): worker pins the task to that worker (0 to
workerCount() - 1), where it starts and stays.