Pure Workflow Sequencing

State + Console + Exception with seq()

Why it matters

  • `seq()` advances workflow state while keeping data immutable.
  • Console + Exception handlers yield audit trails automatically.
seq()StateConsolematch()pipe() Console.capture()State.with()Exception.tryCatch() Workflow state
Program
// Multi-capability type alias: record-based effect composition
// Order-independent, self-documenting
type WorkflowCaps = Readonly<{
  console: typeof Console.spec;
  state: ReturnType<typeof State.spec<WorkflowState>>;
  exception: typeof Exception.spec;
}>;

const workflow = (): Eff<WorkflowSnapshot, WorkflowCaps> =>
  seq()
    .let(() => State.get<WorkflowState>()) // ctx.v1
    .then((state) => state.stage)
    .then((stage) => nextStage(stage))
    .let((next) => next) // ctx.v2
    .then((next) => ({ stage: next, note: stageNote(next) }))
    .let((event) => event) // ctx.v3
    .tap((event) => Console.op.log(`Stage → ${stageLabel(event.stage)}`))
    .do((event, ctx) => {
      const state = ctx!["v1"] as WorkflowState;
      const history = appendEvent(state.history, event);
      return State.put({ stage: event.stage, history });
    })
    .return((event, ctx) => {
      const state = ctx!["v1"] as WorkflowState;
      return { stage: event.stage, history: appendEvent(state.history, event) };
    });

Awaiting execution

Console output, timeline events and workflow state snapshots will render here after you run the program.

Handlers: Console.capture() · State.with() · Exception.tryCatch()