PUBLIC API / VERSION 0.1.3
A small, explicit API.
The complete public runtime surface. No hidden adapters, editor components, or framework dependencies.
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.
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
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
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>>;
}
| Type | Contract |
|---|---|
NodeInput | initial: JsonValue; incoming: readonly IncomingValue[] |
IncomingValue | linkId, sourceNodeId, sourcePort, targetPort, value |
NodeContext | runId, nodeId, signal: AbortSignal |
LinkContext | runId, linkId, source, target, signal: AbortSignal |
NodeResult | outputs: Readonly<Record<string, JsonValue>> |
EngineSnapshot | workflowId, runId (nullable), version, status, nodes, links |
ErrorInfo | readonly code: string; readonly message: string |
HistoryEntry | event: EngineEvent; snapshot: EngineSnapshot |
RunOptions | signal?: AbortSignal |
EngineOptions | concurrency?: 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 / code | When to handle |
|---|---|
WorkflowValidationErrorWORKFLOW_VALIDATION_ERROR | Invalid metadata, graph structure, or engine configuration. |
PayloadValidationErrorPAYLOAD_VALIDATION_ERROR | Invalid initial JSON data rejects run(). Invalid output/transform payloads become recorded execution failures. |
EngineBusyErrorENGINE_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.