redtuma

Workflows

Workflows are deterministic, multi-step pipelines: branching, parallelism, loops, and human-in-the-loop suspend/resume — composed from typed steps.

Steps and control flow

workflow.ts
import { createWorkflow, createStep } from '@redtuma/core/workflows'

const double = createStep({
  id: 'double',
  execute: ({ inputData }) => (inputData as number) * 2,
})

const wf = createWorkflow({ id: 'pipeline' })
  .then(double)
  .branch([
    [({ inputData }) => inputData > 100, bigStep],
    [() => true, smallStep],
  ])
  .commit()

const result = await wf.createRun().start({ inputData: 21 })
result.status   // 'success' | 'suspended' | 'failed'
result.result   // output of the last step

Builder methods: then, branch, parallel, dountil, foreach, map. Call commit() before running.

Suspend & resume

A step can suspend to wait for human input. The run returns suspended with the step id, then you resume it with data.

const gate = createStep({
  id: 'approval',
  execute: ({ resumeData, suspend }) => {
    if (resumeData === undefined) suspend({ reason: 'needs approval' })
    return resumeData
  },
})

const run = createWorkflow({ id: 'hitl' }).then(gate).commit().createRun()

const a = await run.start({ inputData: 'x' })  // status: 'suspended'
const b = await run.resume({ step: 'approval', resumeData: { ok: true } })

Durable resume

Persist a suspended run and resume it later — even on a different server instance. Snapshots round-trip through any Store.

const snapshot = run.getSnapshot()        // serializable
await store.persistSnapshot(key, snapshot)

// later, on another instance:
const snap = await store.loadSnapshot(key)
const result = await workflow.createRun().restore(snap).resume({ step, resumeData })
When you serve workflows with the deployer and a Store is configured, suspend/resume is persisted automatically — required for stateless edge deploys.