Graph Introspection
domain.graph and pipeline.graph expose the static structure of your domain or pipeline as a GraphDescriptor object. Use it to inspect nodes and edges, run path queries, or feed a visualizer. This page covers reading the graph; rendering it as Mermaid or DOT is in State Graph Visualizer.
Reading the graph descriptor
Section titled “Reading the graph descriptor”import { defineDomain, when, on, terminal } from '@tde.io/plexis';
const order = defineDomain('order', () => { when('pending', () => { on('submit', target('processing')); }); when('processing', () => { on('fulfill', target('fulfilled')); }); when('fulfilled', terminal()); return { context: {}, initial: 'pending' };});
const descriptor = order.graph.describe();// {// id: 'order',// kind: 'domain',// nodes: [...],// edges: [...],// entryNodes: [{ kind: 'domain-phase', nodeId: 'pending', ... }],// terminalNodes: [{ kind: 'domain-phase', nodeId: 'fulfilled', ... }],// attachments: []// }
console.log(descriptor.nodes.map((n) => n.id));// ['pending', 'processing', 'fulfilled']
console.log(descriptor.edges.map((e) => `${e.from.nodeId} --${e.event}--> ${e.to.nodeId}`));// ['pending --submit--> processing', 'processing --fulfill--> fulfilled']Inspecting individual nodes
Section titled “Inspecting individual nodes”domain.graph.node(id) returns the GraphNode for a named phase or pipeline node.
const node = order.graph.node('processing');// { ref: { kind: 'domain-phase', nodeId: 'processing' }, id: 'processing', terminal: false }domain.graph.inbound(id) and domain.graph.outbound(id) return the edges that arrive at or depart from a node:
const inbound = order.graph.inbound('processing');// edges where to.nodeId === 'processing' → [the 'submit' event edge]
const outbound = order.graph.outbound('processing');// edges where from.nodeId === 'processing' → [the 'fulfill' event edge]Path queries
Section titled “Path queries”Path queries traverse the graph to find routes between two nodes.
// All paths from 'pending' to 'fulfilled'const paths = order.graph.pathsFrom('pending');paths.forEach((p) => { console.log(p.nodes.map((r) => r.nodeId).join(' → '));});// 'pending → processing → fulfilled'
// Nodes reachable from 'pending'const reachable = order.graph.reachableFrom('pending');console.log(reachable.map((n) => n.id));// ['pending', 'processing', 'fulfilled']pathsTo(id) gives paths that end at the given node; pathsFrom(id) gives paths that start there. Both accept a PathQueryOptions object to control maxDepth, cycle handling, and direction.
Pipeline graphs
Section titled “Pipeline graphs”Pipelines have the same graph API under pipeline.graph:
import { definePipeline, node, action, fork, target, terminal } from '@tde.io/plexis';
const process = definePipeline('process', () => { node('validate', () => { fork('accept', target('accept'), (ctx) => ctx.valid); fork('reject', target('reject'), (ctx) => !ctx.valid); }); node('accept', terminal()); node('reject', terminal()); return { initial: 'validate' };});
const g = process.graph.describe();console.log(g.terminalNodes.map((n) => n.nodeId));// ['accept', 'reject']Observing runtime-traversed paths
Section titled “Observing runtime-traversed paths”domain.graph also exposes observedPathsTo(id) and observedPathsFrom(id), which return only paths the domain has actually traversed at runtime (based on the tracer). These are useful for coverage analysis and debugging.
await order.follow('submit');
const observed = order.graph.observedPathsFrom('pending');// returns the actual path taken so farFor the full DomainGraph and PipelineGraph types, see the Domain Instance reference and Pipeline Instance reference. To render a GraphDescriptor as a diagram, see State Graph Visualizer.