@processengine/flows
v2.0.0
Published
Declarative flow DSL and process-state lifecycle runtime for application processes
Downloads
217
Maintainers
Readme
@processengine/flows
@processengine/flows is the flow lifecycle runtime for the ProcessEngine family.
It validates declarative flows, prepares a transport-safe runtime artifact, plans the current normalized step, and applies state transitions through a strict process-state model.
It is designed for long-lived application processes such as onboarding, request review, fulfillment, and other business scenarios where the team needs:
- a strict boundary between flow semantics and host infrastructure
- explicit
PROCESS,EFFECT,WAIT, andTERMINALsteps - compile-time validation before runtime
- JSON-safe prepared artifacts and runtime contracts
- a process state that stays readable in raw JSON
It is not a BPMN engine, not a workflow platform, not a transport layer, and not a host-side orchestration framework.
Specifications:
- English: SPEC.md
- Russian: SPEC_RU.md
- Compatibility: COMPATIBILITY.md
- Migration: docs/MIGRATION_GUIDE.md
- Persistence integration: docs/INTEGRATION_PERSISTENCE.md
- Scheduler integration: docs/SCHEDULER_GUIDE.md
- Changelog: CHANGELOG.md
Place In ProcessEngine
@processengine/mappings -> data normalization
@processengine/rules -> business checks
@processengine/decisions -> decision outcomes
@processengine/flows -> process structure and lifecycle semanticsflows owns process structure and process-state transitions. It does not execute business artefacts itself and it does not own host infrastructure.
Installation
npm install @processengine/flowsPublic API
import {
validateFlow,
prepareFlow,
createProcessState,
plan,
reduce,
apply,
resume,
createFlowTrace,
formatFlowDiagnostics,
formatFlowRuntimeError,
formatFlowTrace,
} from "@processengine/flows";What each function does:
validateFlow(flow, options)validates DSL and returns diagnostics.prepareFlow(flow, options)returns a separate prepared artifact.createProcessState({ flow, processId, input, meta })creates the canonical initial state bound toflowIdandflowVersion.plan(preparedFlow, state)returns the current normalized step.reduce(step, state, output)applies aPROCESSresult.apply(preparedFlow, state, stepId, effectResult)applies anEFFECTresult.resume(preparedFlow, state, stepId, waitResult)resumes aWAITstep.createFlowTrace(state, mode?)materializes canonicalbasicorverbosetrace views fromProcessState.formatFlowDiagnostics(...),formatFlowRuntimeError(...), andformatFlowTrace(...)format public diagnostics, runtime errors, and trace output for logs or CLI output.
Quick Start
1. Define a flow
import type { FlowDefinition } from "@processengine/flows";
const flow: FlowDefinition = {
id: "request.processing",
version: "2.0.0",
entryStepId: "validate_request",
steps: [
{
id: "validate_request",
type: "PROCESS",
artefactId: "process.validate",
inputRef: "$.context.input",
outputRef: "$.context.facts.shouldContinue",
nextStepId: "route_request",
},
{
id: "route_request",
type: "PROCESS",
subtype: "ROUTE",
factRef: "$.context.facts.shouldContinue",
cases: {
true: "send_command",
false: "complete_fail",
},
defaultNextStepId: "complete_fail",
},
{
id: "send_command",
type: "EFFECT",
subtype: "COMMAND",
artefactId: "effect.remote.submit",
inputRef: "$.context.input",
nextStepId: "wait_for_response",
onErrorStepId: "complete_fail",
},
{
id: "wait_for_response",
type: "WAIT",
sourceStepId: "send_command",
nextStepId: "complete_success",
onErrorStepId: "complete_fail",
onTimeoutStepId: "complete_fail",
},
{
id: "complete_success",
type: "TERMINAL",
subtype: "COMPLETE",
result: {
status: "COMPLETE",
outcome: "REQUEST_COMPLETED",
},
},
{
id: "complete_fail",
type: "TERMINAL",
subtype: "FAIL",
result: {
status: "FAIL",
outcome: "REQUEST_REJECTED",
},
},
],
};2. Validate and prepare
import { prepareFlow, validateFlow } from "@processengine/flows";
const validation = validateFlow(flow, {
registry: {
hasArtefact: () => true,
hasDecisionSet: () => true,
},
strict: true,
});
if (!validation.ok) {
console.error(validation.diagnostics);
process.exit(1);
}
const preparedFlow = prepareFlow(flow, {
registry: {
hasArtefact: () => true,
hasDecisionSet: () => true,
},
strict: true,
});3. Create state
import { createProcessState } from "@processengine/flows";
let state = createProcessState({
flow: preparedFlow,
processId: "request-001",
trace: "basic",
input: {
requestId: "REQ-1",
entityId: "ENTITY-1",
payload: {
amount: 100,
},
},
});4. Run the lifecycle
import { apply, plan, reduce, resume } from "@processengine/flows";
let step = plan(preparedFlow, state);
if (step.type === "PROCESS") {
const output = { ok: true };
state = reduce(step, state, output);
}
step = plan(preparedFlow, state);
if (step.type === "EFFECT") {
state = apply(preparedFlow, state, step.id, {
requestId: "req-1",
correlationKey: "request-001",
result: null,
error: null,
errorCode: null,
});
}
step = plan(preparedFlow, state);
if (step.type === "WAIT") {
state = resume(preparedFlow, state, step.id, {
requestId: "req-2",
result: { status: "SUCCESS" },
error: null,
errorCode: null,
});
}5. Format diagnostics and trace
import {
createFlowTrace,
formatFlowDiagnostics,
formatFlowTrace,
} from "@processengine/flows";
const validation = validateFlow(flow, { strict: false });
console.log(formatFlowDiagnostics(validation.diagnostics));
const trace = createFlowTrace(state);
console.log(formatFlowTrace(trace));DSL Summary
Supported step families:
PROCESSPROCESS/ROUTEPROCESS/SWITCHEFFECT/COMMANDEFFECT/CALLWAITTERMINAL/COMPLETETERMINAL/FAIL
Boundary Rules
flowsowns DSL, validation, prepared artifact, normalized planning, and process-state transitions.processexecutes only normalizedPROCESSsteps and does not decide lifecycle transitions.Hostowns artefact registries, external I/O, persistence, delivery mechanics, correlation, retries, and infrastructure loops.- Host must restore the prepared flow by
(state.flowId, state.flowVersion)for long-lived processes. COMMANDandWAITremain separate steps in the model.plan(...)returns a self-contained normalized step, so Host does not resolve refs from process state.
Schema Export
JSON Schema is available via the package subpath:
import schema from "@processengine/flows/schema";