Examples
Postgres Persistence
What this example shows
Loop Engine storage is an adapter boundary. This example swaps adapter-memory for adapter-postgres without changing loop definitions or transition logic.
Loop diagram
1START LOOP ----> WRITE INSTANCE (Postgres)2TRANSITION ----> APPEND HISTORY (Postgres)3QUERY STATE ---> READ INSTANCE + READ HISTORYActors
| Actor | Type | Transitions | Guards |
|---|---|---|---|
| service runtime | automation | all business transitions | configured in loop definition |
| reviewer (optional) | human | approval transitions | human-only, policy guards |
Key annotated snippet
1import { createLoopSystem } from "@loop-engine/sdk";2import { postgresStore, createSchema } from "@loop-engine/adapter-postgres";3import { memoryStore } from "@loop-engine/adapter-memory";4import { Pool } from "pg";5 6"cmt">// Version A: in-memory (default local dev)7const memStore = memoryStore();8const memoryRuntime = await createLoopSystem({ loops: [definition], store: memStore });9 10"cmt">// Version B: postgres (durable)11const pool = new Pool({ connectionString: process.env.DATABASE_URL });12await createSchema(pool);13const pgStore = postgresStore(pool);14const postgresRuntime = await createLoopSystem({ loops: [definition], store: pgStore });15 16"cmt">// Loop definitions + transition calls are unchanged across adapters.What emitted events look like
1{2 type: "loop.transition.executed",3 loopId: "expense.approval",4 aggregateId: "EXP-2026-009",5 transitionId: "approve",6 fromState: "PENDING_APPROVAL",7 toState: "APPROVED",8 actor: { type: "human", id: "manager@acme.com" },9 occurredAt: "2026-03-13T12:49:22.290Z"10}Try it yourself
1cd loop-examples/postgres-persistence2pnpm install3pnpm dev