//#region src/types.d.ts /** * Directedness of a graph or an individual edge. * * - `'directed'` — edge points from source to target. * - `'undirected'` — edge has no direction; traversable both ways. * - `'bidirectional'` — edge points both ways (arrows on both ends). * * Set at the graph level as the default ({@link Graph.mode}); individual edges * may override it ({@link GraphEdge.mode}). */ type GraphMode = 'directed' | 'undirected' | 'bidirectional'; interface EntityRect { x: number; y: number; width: number; height: number; } /** A 2D point, used for edge routing waypoints. */ interface Point { x: number; y: number; } /** * How an edge's {@link GraphEdge.points} should be interpreted by renderers: * * - `'polyline'` — straight segments through the points. * - `'orthogonal'` — axis-aligned segments (ELK layered routing). * - `'splines'` — bezier control points (Graphviz convention: 3n+1 chained * cubic curves, tail → head). */ type EdgeRouting = 'polyline' | 'orthogonal' | 'splines'; /** Shared optional visual/style props for nodes, edges, ports. */ interface GraphEntity { x?: number; y?: number; width?: number; height?: number; style?: Record; } /** Visual entity base — required position/size. */ interface VisualGraphEntity { x: number; y: number; width: number; height: number; style?: Record; } type PortDirection = 'in' | 'out' | 'inout'; interface PortConfig extends GraphEntity { name: string; direction?: PortDirection; label?: string; data?: TPortData; } interface GraphPort extends GraphEntity { name: string; direction: PortDirection; label?: string; data: TPortData; } interface VisualPort extends GraphPort { x: number; y: number; width: number; height: number; } interface GraphConfig { id?: string; /** Default directedness for all edges. Defaults to `'directed'`. */ mode?: GraphMode; initialNodeId?: string | null; nodes?: NodeConfig[]; edges?: EdgeConfig[]; data?: TGraphData; direction?: 'up' | 'down' | 'left' | 'right'; style?: Record; } interface NodeConfig extends GraphEntity { id: string; parentId?: string | null; initialNodeId?: string | null; label?: string | null; data?: TNodeData; ports?: PortConfig[]; shape?: string; color?: string; } /** * Note on edge geometry: an edge's `x`/`y`/`width`/`height` are canonically * the **label rect** (top-left + size). Layout adapters write computed edge * label positions here, and engines that need label dimensions as input * (dagre, ELK) read `width`/`height`. The edge's *route* lives in * {@link EdgeConfig.points}. */ interface EdgeConfig extends GraphEntity { /** * The id of the edge. */ id: string; /** * The id of the source node. */ sourceId: string; /** * The id of the target node. */ targetId: string; /** * The label of the edge. */ label?: string | null; /** * Optional numeric weight for the edge. * Used by pathfinding, MST, and other weighted algorithms. * When `getWeight` is not provided, algorithms default to `edge.weight ?? 1`. */ weight?: number; /** Port name on the source node this edge connects from. */ sourcePort?: string; /** Port name on the target node this edge connects to. */ targetPort?: string; /** * Per-edge directedness override. When absent, the edge inherits the graph's * {@link GraphConfig.mode}. */ mode?: GraphMode; /** * Edge route waypoints (including endpoints, tail → head), as computed by a * layout engine. Interpretation is governed by {@link EdgeConfig.routing}. */ points?: Point[]; /** How {@link EdgeConfig.points} should be interpreted. Default: polyline. */ routing?: EdgeRouting; data?: TEdgeData; color?: string; } interface Graph { id: string; /** Default directedness for all edges. */ mode: GraphMode; initialNodeId?: string | null; nodes: GraphNode[]; edges: GraphEdge[]; data: TGraphData; direction?: 'up' | 'down' | 'left' | 'right'; style?: Record; } interface GraphNode extends GraphEntity { type: 'node'; id: string; parentId?: string | null; initialNodeId?: string | null; label?: string | null; data: TNodeData; ports?: GraphPort[]; shape?: string; color?: string; } /** * Note on edge geometry: an edge's `x`/`y`/`width`/`height` are canonically * the **label rect** (top-left + size); the edge's *route* lives in * {@link GraphEdge.points}. See {@link EdgeConfig} for details. */ interface GraphEdge extends GraphEntity { type: 'edge'; id: string; sourceId: string; targetId: string; label?: string | null; /** * Optional numeric weight for the edge. * Used by pathfinding, MST, and other weighted algorithms. * When `getWeight` is not provided, algorithms default to `edge.weight ?? 1`. */ weight?: number; /** Port name on the source node this edge connects from. */ sourcePort?: string; /** Port name on the target node this edge connects to. */ targetPort?: string; /** * Per-edge directedness override. When absent, the edge inherits the graph's * {@link Graph.mode}. */ mode?: GraphMode; /** * Edge route waypoints (including endpoints, tail → head), as computed by a * layout engine. Interpretation is governed by {@link GraphEdge.routing}. */ points?: Point[]; /** How {@link GraphEdge.points} should be interpreted. Default: polyline. */ routing?: EdgeRouting; data: TEdgeData; color?: string; } interface VisualNode extends GraphNode { x: number; y: number; width: number; height: number; ports?: VisualPort[]; } interface VisualEdge extends GraphEdge { x: number; y: number; width: number; height: number; } interface VisualGraph extends Omit, 'nodes' | 'edges'> { nodes: VisualNode[]; edges: VisualEdge[]; direction: 'up' | 'down' | 'left' | 'right'; } interface VisualGraphConfig extends GraphConfig { direction?: 'up' | 'down' | 'left' | 'right'; } interface DeleteNodeOptions { reparent?: boolean; } /** * Update payload for {@link updateNode}/`updateEntities`. * * Optional fields (`x`, `y`, `width`, `height`, `shape`, `color`, `style`, * `ports`) accept `null` to **unset** the field. `undefined` (or omitting the * key) leaves the field unchanged. `null` is used for unsetting so update * payloads stay JSON-serializable. */ interface NodeUpdate { parentId?: string | null; initialNodeId?: string | null; label?: string | null; data?: TNodeData; /** New ports for the node, or `null` to remove all ports. */ ports?: PortConfig[] | null; x?: number | null; y?: number | null; width?: number | null; height?: number | null; shape?: string | null; color?: string | null; style?: Record | null; } /** * Update payload for {@link updateEdge}/`updateEntities`. * * Optional fields (`weight`, `mode`, `sourcePort`, `targetPort`, `x`, `y`, * `width`, `height`, `color`, `style`) accept `null` to **unset** the field. * `undefined` (or omitting the key) leaves the field unchanged. `null` is * used for unsetting so update payloads stay JSON-serializable. */ interface EdgeUpdate { sourceId?: string; targetId?: string; label?: string | null; data?: TEdgeData; weight?: number | null; mode?: GraphMode | null; /** Port name on the source node, or `null` to clear the port reference. */ sourcePort?: string | null; /** Port name on the target node, or `null` to clear the port reference. */ targetPort?: string | null; /** Edge route waypoints, or `null` to clear the route. */ points?: Point[] | null; routing?: EdgeRouting | null; x?: number | null; y?: number | null; width?: number | null; height?: number | null; color?: string | null; style?: Record | null; } interface EntitiesConfig { nodes?: NodeConfig[]; edges?: EdgeConfig[]; } interface EntitiesUpdate { nodes?: (NodeUpdate & { id: string; })[]; edges?: (EdgeUpdate & { id: string; })[]; } interface GraphStep { /** Edge traversed to reach this node */ edge: GraphEdge; /** Node reached after traversing the edge */ node: GraphNode; } interface GraphPath { /** The source node where this path begins. */ source: GraphNode; /** Ordered steps from source to target. * `path.steps.at(-1)?.node` is the final/target node. * Empty steps = source-only path. */ steps: GraphStep[]; } interface PathOptions { /** Source node ID. Default: graph.initialNodeId, else sole inDegree-0 node */ from?: string; /** Target node ID. If omitted → paths to all reachable nodes */ to?: string; /** Edge weight function. Default: `(e) => e.weight ?? 1`. */ getWeight?: (edge: GraphEdge) => number; /** Algorithm to use. Default: 'dijkstra'. Use 'bellman-ford' for negative weights. */ algorithm?: 'dijkstra' | 'bellman-ford'; } interface SinglePathOptions { /** Source node ID. Default: graph.initialNodeId, else sole inDegree-0 node */ from?: string; /** Target node ID. Required for single-path queries. */ to: string; /** Edge weight function. Default: `(e) => e.weight ?? 1`. */ getWeight?: (edge: GraphEdge) => number; /** Algorithm to use. Default: 'dijkstra'. Use 'bellman-ford' for negative weights. */ algorithm?: 'dijkstra' | 'bellman-ford'; } interface AStarOptions { /** Source node ID. */ from: string; /** Target node ID. */ to: string; /** Edge weight function. Default: `(e) => e.weight ?? 1`. */ getWeight?: (edge: GraphEdge) => number; /** * Heuristic function estimating cost from a node to the target. * Must be admissible (never overestimates the actual cost). */ heuristic: (nodeId: string) => number; } interface TraversalOptions { /** Source node ID. Default: graph.initialNodeId, else sole inDegree-0 node */ from?: string; } interface MSTOptions { /** Algorithm to use. Default: 'prim'. */ algorithm?: 'prim' | 'kruskal'; /** Edge weight function. Default: `(e) => e.weight ?? 1`. */ getWeight?: (edge: GraphEdge) => number; } interface AllPairsShortestPathsOptions { /** Algorithm to use. Default: 'dijkstra'. Use 'bellman-ford' for negative weights. */ algorithm?: 'floyd-warshall' | 'dijkstra' | 'bellman-ford'; /** Edge weight function. Default: `(e) => e.weight ?? 1`. */ getWeight?: (edge: GraphEdge) => number; } interface NodeChange { id: string; old: Partial>; new: Partial>; } interface EdgeChange { id: string; old: Partial>; new: Partial>; } interface GraphDiff { nodes: { added: NodeConfig[]; removed: NodeConfig[]; updated: NodeChange[]; }; edges: { added: EdgeConfig[]; removed: EdgeConfig[]; updated: EdgeChange[]; }; } type GraphPatch = { op: 'addNode'; node: NodeConfig; description?: string; } | { op: 'updateNode'; id: string; data: NodeUpdate; description?: string; } | { op: 'deleteNode'; id: string; description?: string; } | { op: 'addEdge'; edge: EdgeConfig; description?: string; } | { op: 'updateEdge'; id: string; data: EdgeUpdate; description?: string; } | { op: 'deleteEdge'; id: string; description?: string; }; /** * A bidirectional converter between `Graph` and a serialized format. * * Implement this interface to create a custom format converter. * * @example * ```ts * const myConverter: GraphFormatConverter = { * to(graph) { return JSON.stringify(graph); }, * from(input) { return JSON.parse(input); }, * }; * ``` */ interface GraphFormatConverter { /** Convert a Graph to the serialized format. */ to(graph: Graph): TSerial; /** Convert from the serialized format to a Graph. */ from(input: TSerial): Graph; } /** * A bidirectional converter between `VisualGraph` and a serialized format. * * Use this for formats that carry position/size data (e.g. xyflow, cytoscape). */ interface VisualGraphFormatConverter { /** Convert a VisualGraph to the serialized format. */ to(graph: VisualGraph): TSerial; /** Convert from the serialized format to a VisualGraph. */ from(input: TSerial): VisualGraph; } interface WalkOptions { /** Start node ID. Default: graph.initialNodeId, else sole inDegree-0 node */ from?: string; /** Seed for deterministic RNG. Omit for Math.random. */ seed?: number; /** Guard: only traverse edges where filter returns true. */ filter?: (edge: GraphEdge, context: WalkContext) => boolean; /** Callback fired after each step. */ onStep?: (step: GraphStep, context: WalkContext) => void; } interface WeightedWalkOptions extends WalkOptions { /** Edge weight function. Default: `(e) => e.weight ?? 1`. */ getWeight?: (edge: GraphEdge) => number; } interface WalkContext { currentNodeId: string; visitedNodes: Set; visitedEdges: Set; stepCount: number; } interface CoverageStats { nodeCoverage: number; edgeCoverage: number; visitedNodes: string[]; visitedEdges: string[]; totalSteps: number; } interface TransitionOptions { /** Initial state to begin BFS exploration from. */ initialState: TState; /** Events to try at each state. Array or function of state. */ events: TEvent[] | ((state: TState) => TEvent[]); /** Serialize state to unique string for node dedup. Default: JSON.stringify */ serializeState?: (state: TState) => string; /** Serialize event to string for edge labels/IDs. Default: JSON.stringify */ serializeEvent?: (event: TEvent) => string; /** Max BFS iterations before throwing. Default: Infinity */ limit?: number; /** When true, node is kept but outgoing transitions are not explored. */ stopWhen?: (state: TState) => boolean; /** Optional graph ID. */ id?: string; } //#endregion export { PortConfig as A, VisualNode as B, GraphStep as C, NodeUpdate as D, NodeConfig as E, VisualEdge as F, WalkContext as H, VisualGraph as I, VisualGraphConfig as L, SinglePathOptions as M, TransitionOptions as N, PathOptions as O, TraversalOptions as P, VisualGraphEntity as R, GraphPort as S, NodeChange as T, WalkOptions as U, VisualPort as V, WeightedWalkOptions as W, GraphFormatConverter as _, EdgeChange as a, GraphPatch as b, EdgeUpdate as c, EntityRect as d, Graph as f, GraphEntity as g, GraphEdge as h, DeleteNodeOptions as i, PortDirection as j, Point as k, EntitiesConfig as l, GraphDiff as m, AllPairsShortestPathsOptions as n, EdgeConfig as o, GraphConfig as p, CoverageStats as r, EdgeRouting as s, AStarOptions as t, EntitiesUpdate as u, GraphMode as v, MSTOptions as w, GraphPath as x, GraphNode as y, VisualGraphFormatConverter as z };