FlowChartExecutor
Constructor
Section titled “Constructor”new FlowChartExecutor(chart: FlowChart)Takes a compiled FlowChart (the return value of .build()). The executor is stateful — call .run() and then read the results.
import { FlowChartExecutor } from 'footprintjs';
const executor = new FlowChartExecutor(chart);await executor.run({ input: { orderId: 'ORD-001', amount: 49.99 } });.run()
Section titled “.run()”Execute the flowchart. Returns a RunResult with the output value (if a .contract() mapper is defined), the final snapshot, and narrative lines.
executor.run(options?: RunOptions): Promise<RunResult>RunOptions
| Field | Type | Description |
|---|---|---|
input | unknown | Business input — frozen, accessible via scope.$getArgs() |
env | ExecutionEnv? | Infrastructure context (signal, timeoutMs, traceId) — accessible via scope.$getEnv() |
await executor.run({ input: { userId: 42 }, env: { traceId: 'req-abc123', timeoutMs: 5000 },});Fluent chaining with .recorder()
Section titled “Fluent chaining with .recorder()”For a one-shot run without a persistent executor, chain recorders directly on the compiled chart:
import { flowChart, narrative, metrics } from 'footprintjs';
const narr = narrative();const metr = metrics();
await chart .recorder(narr) .recorder(metr) .run({ input: { orderId: 'ORD-001', amount: 49.99 } });
console.log(narr.lines().join('\n'));console.log(`Total: ${metr.all().totalDuration}ms`);Attaching recorders
Section titled “Attaching recorders”.attachRecorder()
Section titled “.attachRecorder()”Attach a scope recorder — fires on data operations (reads, writes, commits) during stage execution.
executor.attachRecorder(recorder: Recorder): voidimport { MetricRecorder, DebugRecorder } from 'footprintjs';
executor.attachRecorder(new MetricRecorder());executor.attachRecorder(new DebugRecorder({ verbosity: 'verbose' }));.attachFlowRecorder()
Section titled “.attachFlowRecorder()”Attach a flow recorder — fires on control-flow events (decisions, loops, forks) after each stage completes.
executor.attachFlowRecorder(recorder: FlowRecorder): voidimport { ManifestFlowRecorder } from 'footprintjs';
const manifest = new ManifestFlowRecorder();executor.attachFlowRecorder(manifest);await executor.run();console.log(manifest.getManifest());.enableNarrative()
Section titled “.enableNarrative()”Shorthand: attaches a CombinedNarrativeRecorder that implements both scope and flow recorder interfaces, producing a merged timeline.
executor.enableNarrative(): voidexecutor.enableNarrative();await executor.run();executor.getNarrative().forEach(line => console.log(line));Reading results
Section titled “Reading results”.getNarrative()
Section titled “.getNarrative()”Returns the merged narrative as a string[] — one sentence per event.
executor.getNarrative(): string[]Stage 1: The process began with AssessCredit. Step 1: Write creditScore = 750[Condition]: It evaluated Rule 0 "Strong profile": creditScore 750 gt 700 ✓ → approved.Stage 2: Next, it moved on to Approve. Step 1: Write decision = "Approved".getNarrativeEntries()
Section titled “.getNarrativeEntries()”Returns structured CombinedNarrativeEntry[] with type, depth, stageName, and stageId metadata — useful for building custom UIs.
executor.getNarrativeEntries(): CombinedNarrativeEntry[].getFlowNarrative()
Section titled “.getFlowNarrative()”Returns only the control-flow sentences (stage transitions, decisions, loops) — without data operation lines.
executor.getFlowNarrative(): string[].getSnapshot()
Section titled “.getSnapshot()”Returns the full RuntimeSnapshot — shared state, execution tree, and recorder snapshots at every nesting depth.
executor.getSnapshot(): RuntimeSnapshot | undefinedconst snapshot = executor.getSnapshot();const finalState = snapshot?.sharedState as LoanState;console.log(finalState.decision); // 'Approved'Use getSubtreeSnapshot() to drill into subflows.
Redaction
Section titled “Redaction”.setRedactionPolicy()
Section titled “.setRedactionPolicy()”Protect sensitive fields from leaking into narratives and debug logs. Keys matching the policy are replaced with [REDACTED] in all recorder output.
executor.setRedactionPolicy(policy: RedactionPolicy): voidexecutor.setRedactionPolicy({ keys: ['password', 'ssn', 'cardNumber'],});Try it live
Section titled “Try it live”- Auto-Narrative —
enableNarrative()+getNarrative() - Metrics —
MetricRecorder - Redaction —
setRedactionPolicy()
→ Full guide: Observing with recorders