Key Concepts
The flowchart pattern
Section titled “The flowchart pattern”A footprintjs pipeline is a directed graph of stages. Each stage is an async function that reads and writes to a shared typed scope. Stages are connected sequentially, or via branching (addDeciderFunction) or parallel fan-out (addSelectorFunction).
Intake → ClassifyRisk ──► approved → Approve └──► rejected → RejectThe graph is built once (.build()), then executed many times (.run()). The graph structure is immutable; only the scope state changes per run.
TypedScope — typed shared state
Section titled “TypedScope — typed shared state”TypedScope<T> is a deep Proxy over your state interface. It tracks every read and write, enabling recorders to observe exactly what happened and when.
interface LoanState { creditScore: number; customer: { name: string; zip: string }; tags: string[];}
// Inside a stage:scope.creditScore = 750; // typed writescope.customer.zip = '90210'; // deep writescope.tags.push('vip'); // array copy-on-writeconst score = scope.creditScore; // tracked readTwo observer systems
Section titled “Two observer systems”footprintjs has two separate observer channels that fire at different times:
| Channel | Interface | Fires when |
|---|---|---|
| Scope recorder | Recorder | During stage execution (reads, writes, commits) |
| Flow recorder | FlowRecorder | After stage execution (decisions, forks, loops) |
narrative() implements both interfaces and merges them into a single timeline. You attach it via .recorder(narrative()).
Collect during traversal
Section titled “Collect during traversal”This is why recorders exist: not as a debugging afterthought, but as the primary way to observe pipeline behavior in production.