npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@processengine/flows

v2.0.0

Published

Declarative flow DSL and process-state lifecycle runtime for application processes

Downloads

217

Readme

@processengine/flows

npm version CI license node Russian specification

@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, and TERMINAL steps
  • 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:

Place In ProcessEngine

@processengine/mappings   -> data normalization
@processengine/rules      -> business checks
@processengine/decisions  -> decision outcomes
@processengine/flows      -> process structure and lifecycle semantics

flows 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/flows

Public 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 to flowId and flowVersion.
  • plan(preparedFlow, state) returns the current normalized step.
  • reduce(step, state, output) applies a PROCESS result.
  • apply(preparedFlow, state, stepId, effectResult) applies an EFFECT result.
  • resume(preparedFlow, state, stepId, waitResult) resumes a WAIT step.
  • createFlowTrace(state, mode?) materializes canonical basic or verbose trace views from ProcessState.
  • formatFlowDiagnostics(...), formatFlowRuntimeError(...), and formatFlowTrace(...) 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:

  • PROCESS
  • PROCESS/ROUTE
  • PROCESS/SWITCH
  • EFFECT/COMMAND
  • EFFECT/CALL
  • WAIT
  • TERMINAL/COMPLETE
  • TERMINAL/FAIL

Boundary Rules

  • flows owns DSL, validation, prepared artifact, normalized planning, and process-state transitions.
  • process executes only normalized PROCESS steps and does not decide lifecycle transitions.
  • Host owns 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.
  • COMMAND and WAIT remain 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";