Skip to content

Workflow methods

Methods on the Workflow builder. All are immutable — each returns a new Workflow.

.step(name, handler | config)

Adds a sequential step. Accepts either a bare handler or a config object.

Handler form:

typescript
.step('name', async ({ input, prev, steps, signal, complete }) => {
  return { result: 'value' }
})

Step context:

FieldTypeDescription
inputTInputValidated workflow input (same for every step)
prevTPrevReturn value of the previous step (undefined for the first step)
stepsTStepsSoFarFrozen, typed record of all previously completed step results by name
signalAbortSignalAborted on cancellation, lease loss, or step timeout
complete(value?) => neverFinish the workflow early, skipping remaining steps

Config form:

FieldTypeDescription
handler(ctx) => Promise<T>Step handler. Receives the step context above.
retryRetryConfigOptional retry configuration.
timeoutMsnumberOptional timeout per attempt (ms). Takes precedence over retry.timeoutMs.

RetryConfig:

FieldTypeDescription
maxAttemptsnumberMaximum attempts (default 1, no retry)
backoff'linear' | 'exponential'Backoff strategy between retries
initialDelayMsnumberBase delay in ms (default 1000)
timeoutMsnumberTimeout per attempt; step-level timeoutMs wins

The step's return value must be a persistable value. Reusing a name throws DuplicateStepError. See Retry & Timeouts.

.parallel(branches)

Adds a group of concurrent steps. branches is a record of { branchName: handler | config }. All branches run at once; the next step's prev is the merged { [branchName]: output }.

typescript
.parallel({
  a: async ({ prev }) => ({ x: prev.value * 2 }),
  b: {
    retry: { maxAttempts: 3, backoff: 'linear' },
    timeoutMs: 5000,
    handler: async () => await someCall(),
  },
})

Each branch accepts the same handler/config form as .step(). Branch names share the step namespace — duplicates throw DuplicateStepError. At least one branch is required. Calling complete() inside a branch throws ParallelCompleteError. See Parallel Steps.

.onFailure(handler)

Attaches a compensation handler, called when a step fails after exhausting its retries.

typescript
.onFailure(async ({ error, stepName, input }) => {
  // roll back side effects based on how far the run got
})
FieldTypeDescription
errorErrorThe error that caused the failure
stepNamestringThe step (or parallel branch) that failed
inputTInputThe original validated input

The handler runs after the run is already marked failed; errors it throws are swallowed. See Failure Handling.

Released under the MIT License.