PUBLIC API / VERSION 0.1.3

A small, explicit API.

The complete public runtime surface. No hidden adapters, editor components, or framework dependencies.

imports.tsTypeScript
import {
  Workflow, Engine, ifNode, switchNode,
  WorkflowValidationError, PayloadValidationError, EngineBusyError,
} from "@newvexa/workify";
import type { INode, ILink, IEngine, JsonValue, RunResult } from "@newvexa/workify";

Workflow

Construct a descriptor builder. Read id, name, nodes, and links. An engine validates and captures the complete graph; later builder edits do not affect that engine.

constructor.tsTypeScript
const workflow = new Workflow({ id: "orders", name: "Order processing" });

addNode(node: INode): this

Add a uniquely identified asynchronous node descriptor. Returns the builder.

addLink(link: ILink): this

Connect named source and target ports, optionally transforming the value. Returns the builder.

findNodes(query: NodeQuery): readonly INode[]

Inspect descriptors by text, ID, name, type, categories, or tags.

findLinks(query: LinkQuery): readonly ILink[]

Inspect descriptors by text, ID, name, or source/target node IDs.

search(text: string): SearchResult

Search node and link descriptors together; preserves declaration order.

toDefinition(): WorkflowDefinition

Return an in-memory definition that retains executable functions. Not JSON serialization.

Engine

constructor.tsTypeScript
const engine = new Engine(workflow, { concurrency: 4, historyLimit: 500 });

concurrency defaults to four and limits node executions and link transformations together. historyLimit defaults to 500; zero disables retention.

run(initial: JsonValue, options?: RunOptions): Promise<RunResult>

Execute the captured graph. One active run per instance. options.signal requests cooperative cancellation.

getSnapshot(): EngineSnapshot

Read the immutable current state, stable by reference between transitions. No business payloads.

subscribe(listener: () => void): () => void

Observe state changes. Read getSnapshot() in the listener. Returns an unsubscribe function.

onEvent(listener: (event: EngineEvent) => void): () => void

Observe detailed run, node, and link events. Returns an unsubscribe function.

getHistory(): readonly HistoryEntry[]

Read bounded event/snapshot pairs. Does not replay effects or retain payloads.

clearHistory(): void

Remove retained history entries without changing execution state.

Routing helpers

ifNode(options: IfNodeOptions): INode

Requires id, name, value(input, context), and predicate(value, context). The selected value is emitted on "true" or "false". The predicate must resolve to a boolean.

switchNode(options: SwitchNodeOptions): INode

Requires id, name, cases, value(input, context), and select(value, context). The selector must resolve to a string. Unmatched strings emit on "default"; declared cases must be unique, nonempty, and cannot be "default".

Both helpers accept optional categories and tags. Value and routing callbacks may be asynchronous and receive the node context. Add returned descriptors with workflow.addNode().

Public types

core-contracts.tsTypeScript
type JsonValue = null | boolean | number | string
  | readonly JsonValue[]
  | { readonly [key: string]: JsonValue };

interface INode {
  readonly id: string;
  readonly name: string;
  readonly type: "trigger" | "action" | "logic" | "custom";
  readonly categories?: readonly string[];
  readonly tags?: readonly string[];
  execute(input: NodeInput, context: NodeContext): Promise<NodeResult>;
}

interface ILink {
  readonly id: string;
  readonly name: string;
  readonly source: { readonly nodeId: string; readonly port: string };
  readonly target: { readonly nodeId: string; readonly port: string };
  readonly transform?: (value: JsonValue, context: LinkContext)
    => JsonValue | Promise<JsonValue>;
}

interface RunResult {
  readonly runId: string;
  readonly status: "succeeded" | "failed" | "cancelled";
  readonly snapshot: EngineSnapshot;
  readonly results: Readonly<Record<string, NodeResult>>;
}
TypeContract
NodeInputinitial: JsonValue; incoming: readonly IncomingValue[]
IncomingValuelinkId, sourceNodeId, sourcePort, targetPort, value
NodeContextrunId, nodeId, signal: AbortSignal
LinkContextrunId, linkId, source, target, signal: AbortSignal
NodeResultoutputs: Readonly<Record<string, JsonValue>>
EngineSnapshotworkflowId, runId (nullable), version, status, nodes, links
ErrorInforeadonly code: string; readonly message: string
HistoryEntryevent: EngineEvent; snapshot: EngineSnapshot
RunOptionssignal?: AbortSignal
EngineOptionsconcurrency?: number; historyLimit?: number

The main entry also exports IWorkflow, IEngine, query types, endpoint/definition types, routing option types, node/link state types, and the status unions. These are TypeScript types—not runtime constructors.

Errors

Class / codeWhen to handle
WorkflowValidationError
WORKFLOW_VALIDATION_ERROR
Invalid metadata, graph structure, or engine configuration.
PayloadValidationError
PAYLOAD_VALIDATION_ERROR
Invalid initial JSON data rejects run(). Invalid output/transform payloads become recorded execution failures.
EngineBusyError
ENGINE_BUSY
A second run starts while the first is active or cancellation is draining.

Use try/catch around construction and run(). Error metadata in snapshots contains codes and messages, not the original thrown object.

Documentation for @newvexa/workify 0.1.3Read the full source guide