Workflows

Long-running stateful processes that survive restarts, time delays, and external signals.

Workflows model long-running business processes that need to survive time, restarts, and retries. They are defined as a series of steps — actions, sleeps, and signal waits — with persistent state.

Defining a Workflow

import { workflow } from "@chimpbase/runtime";

const onboardingWorkflow = workflow({
  name: "customer.onboarding",
  initialState: () => ({ step: "started" }),
  steps: [
    {
      id: "create-account",
      kind: "workflow_action",
      action: "createAccount",
      args: ({ input }) => [{ email: input.email }],
      onResult: ({ state, result }) => ({
        ...state,
        accountId: result.id,
        step: "account-created",
      }),
    },
    {
      id: "wait-for-verification",
      kind: "workflow_wait_for_signal",
      signal: "email.verified",
      timeoutMs: 86_400_000, // 24 hours
      onSignal: ({ state }) => ({ ...state, step: "verified" }),
      onTimeout: "fail",
    },
    {
      id: "send-welcome",
      kind: "workflow_action",
      action: "sendWelcomeEmail",
      args: ({ state }) => [{ accountId: state.accountId }],
    },
  ],
});

Step Types

Action Steps

Execute a registered action as part of the workflow:

{
  id: "step-id",
  kind: "workflow_action",
  action: "actionName",
  args: ({ input, state }) => [actionArgs],
  onResult: ({ state, result }) => newState,
}

Sleep Steps

Pause the workflow for a duration:

{
  id: "wait-24h",
  kind: "workflow_sleep",
  delayMs: 86_400_000,
}

The delay can be dynamic:

{
  id: "dynamic-wait",
  kind: "workflow_sleep",
  delayMs: ({ state }) => state.retryDelayMs,
}

Wait for Signal Steps

Pause until an external signal arrives, with an optional timeout:

{
  id: "wait-approval",
  kind: "workflow_wait_for_signal",
  signal: "order.approved",
  timeoutMs: 3_600_000, // 1 hour
  onSignal: ({ state, payload }) => ({ ...state, approved: true }),
  onTimeout: "continue", // or "fail" or a function
}

Managing Workflows

Starting a Workflow

await ctx.workflow.start("customer.onboarding", {
  workflowId: `onboarding-${customerId}`,
  input: { email: customer.email },
});

Sending Signals

await ctx.workflow.signal(`onboarding-${customerId}`, "email.verified", {
  verifiedAt: new Date().toISOString(),
});

Querying State

const state = await ctx.workflow.get(`onboarding-${customerId}`);

Workflow Versioning

Workflows support versioned contracts for safe schema evolution. The tooling package provides schema sync commands to manage workflow contract changes.

Durability

Workflow state is persisted in the _chimpbase_workflows table. Steps are executed transactionally — if the runtime restarts mid-workflow, it resumes from the last committed step.