@hazeljs/flow
v1.0.3
Published
Durable execution graph engine - in-memory by default, optional Prisma persistence
Maintainers
Readme
@hazeljs/flow
Durable execution graph engine ("workflow OS kernel"). Fully independent of Hazel core.
Storage: By default the engine uses in-memory storage (no database). For durable persistence, install @prisma/client and use the Prisma storage adapter (see Persistence).
Features
- Flow definitions (nodes + edges)
- Flow runs with stateful execution
- In-memory by default; optional Postgres persistence via Prisma
- Audit event timeline
- Retry/backoff, timeouts
- Idempotency keys
- WAIT state + resume
- Optional Postgres advisory locks when using Prisma storage
Installation
pnpm add @hazeljs/flowNo database or env vars are required for the default in-memory mode.
Usage
Decorator-based (recommended)
import { FlowEngine, Flow, Entry, Node, Edge, buildFlowDefinition } from '@hazeljs/flow';
import type { FlowContext, NodeResult } from '@hazeljs/flow';
@Flow('my-flow', '1.0.0')
class MyFlow {
@Entry()
@Node('start')
@Edge('end')
async start(): Promise<NodeResult> {
return { status: 'ok', output: 1 };
}
@Node('end')
async end(ctx: FlowContext): Promise<NodeResult> {
return { status: 'ok', output: ctx.outputs.start };
}
}
const engine = new FlowEngine();
const def = buildFlowDefinition(MyFlow);
await engine.registerDefinition(def);
const { runId } = await engine.startRun({
flowId: 'my-flow',
version: '1.0.0',
input: {},
});
let run = await engine.getRun(runId);
while (run?.status === 'RUNNING') {
run = await engine.tick(runId);
}Functional builder (alternative)
import { FlowEngine, flow } from '@hazeljs/flow';
const def = flow('my-flow', '1.0.0')
.entry('start')
.node('start', async (ctx) => ({ status: 'ok', output: 1 }))
.node('end', async (ctx) => ({ status: 'ok', output: ctx.outputs.start }))
.edge('start', 'end')
.build();Persistence
By default the engine uses in-memory storage. To persist runs and definitions to Postgres:
- Install Prisma client:
pnpm add @prisma/client - Set
DATABASE_URLand run migrations (from this package’sprisma/schema). - Create the engine with Prisma storage:
import { FlowEngine, buildFlowDefinition } from '@hazeljs/flow';
import { createPrismaStorage, createFlowPrismaClient } from '@hazeljs/flow/prisma';
const prisma = createFlowPrismaClient();
const engine = new FlowEngine({ storage: createPrismaStorage(prisma) });
// ... register definitions, start runs, etc.The migration SQL in prisma/migrations/ is only needed when you use this adapter.
Scripts
prisma:generate- Generate Prisma clientprisma:migrate- Run migrations (dev)prisma:deploy- Deploy migrations (prod)prisma:studio- Open Prisma Studiotest- Run Vitest tests
License
Apache 2.0 © HazelJS
