Examples
Event Streaming
What this example shows
Every transition emits a typed event. This example shows how to subscribe, persist an audit stream, and reconstruct a timeline from transition history for replay and debugging.
Loop diagram
1START ----> TRANSITION_1 ----> TRANSITION_2 ----> TERMINAL2 | | |3 +---- emit events on every transition ----+Actors
| Actor | Type | Transitions | Guards | |---|---|---|---| | runtime emitter | automation | all runtime transitions | loop-defined guards | | subscribers | automation | none (read-only stream consumers) | n/a |
Key annotated snippet
1import { LOOP_EVENT_TYPES } from "@loop-engine/events";2import { buildTimeline, replayLoop } from "@loop-engine/observability";3import { aggregateId } from "@loop-engine/core";4 5const audit: Array<{ at: string; type: string; aggregateId: string }> = [];6 7eventBus.subscribe(async (event) => {8 if (9 event.type === LOOP_EVENT_TYPES.LOOP_STARTED ||10 event.type === LOOP_EVENT_TYPES.TRANSITION_EXECUTED ||11 event.type === LOOP_EVENT_TYPES.LOOP_COMPLETED12 ) {13 audit.push({14 at: event.occurredAt,15 type: event.type,16 aggregateId: String(event.aggregateId)17 });18 }19});20 21const id = aggregateId("EXP-1");22const instance = await engine.getState(id);23const history = await engine.getHistory(id);24if (instance) {25 const timeline = buildTimeline(instance, history);26 const replay = replayLoop(definition, history);27 console.log(timeline.durationMs, replay.valid);28}What emitted events look like
1{2 type: "loop.transition.executed",3 loopId: "expense.approval",4 aggregateId: "EXP-1",5 transitionId: "approve",6 fromState: "PENDING_APPROVAL",7 toState: "APPROVED",8 actor: { type: "human", id: "manager@acme.com" },9 occurredAt: "2026-03-13T12:57:01.440Z"10}Try it yourself
1cd loop-examples/event-streaming2pnpm install3pnpm dev