@statelyai/graph 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +63 -144
  2. package/dist/{algorithms-CnTmuX9t.mjs → algorithms-oVD9PYil.mjs} +219 -31
  3. package/dist/algorithms.d.mts +91 -3
  4. package/dist/algorithms.mjs +2 -2
  5. package/dist/{converter-C5DlzzHs.mjs → converter-B5CUD0r9.mjs} +2 -2
  6. package/dist/formats/adjacency-list/index.d.mts +1 -1
  7. package/dist/formats/adjacency-list/index.mjs +1 -1
  8. package/dist/formats/converter/index.d.mts +2 -2
  9. package/dist/formats/converter/index.mjs +1 -1
  10. package/dist/formats/cytoscape/index.d.mts +1 -1
  11. package/dist/formats/cytoscape/index.mjs +1 -1
  12. package/dist/formats/d3/index.d.mts +1 -1
  13. package/dist/formats/d3/index.mjs +1 -1
  14. package/dist/formats/dot/index.d.mts +1 -1
  15. package/dist/formats/dot/index.mjs +1 -1
  16. package/dist/formats/edge-list/index.d.mts +1 -1
  17. package/dist/formats/edge-list/index.mjs +1 -1
  18. package/dist/formats/elk/index.d.mts +61 -0
  19. package/dist/formats/elk/index.mjs +176 -0
  20. package/dist/formats/gexf/index.d.mts +1 -1
  21. package/dist/formats/gexf/index.mjs +1 -1
  22. package/dist/formats/gml/index.d.mts +1 -1
  23. package/dist/formats/gml/index.mjs +1 -1
  24. package/dist/formats/graphml/index.d.mts +1 -1
  25. package/dist/formats/graphml/index.mjs +148 -56
  26. package/dist/formats/jgf/index.d.mts +1 -1
  27. package/dist/formats/jgf/index.mjs +1 -1
  28. package/dist/formats/mermaid/index.d.mts +51 -33
  29. package/dist/formats/mermaid/index.mjs +315 -31
  30. package/dist/formats/tgf/index.d.mts +1 -1
  31. package/dist/formats/tgf/index.mjs +1 -1
  32. package/dist/formats/xyflow/index.d.mts +1 -1
  33. package/dist/index.d.mts +100 -3
  34. package/dist/index.mjs +366 -10
  35. package/dist/queries.d.mts +1 -1
  36. package/dist/queries.mjs +1 -1
  37. package/dist/schemas.d.mts +39 -4
  38. package/dist/schemas.mjs +27 -5
  39. package/dist/{types-Bq_fmLwW.d.mts → types-DF-HNw50.d.mts} +65 -13
  40. package/package.json +7 -1
  41. package/schemas/edge.schema.json +32 -1
  42. package/schemas/graph.schema.json +114 -4
  43. package/schemas/node.schema.json +45 -2
  44. /package/dist/{adjacency-list-Bv4tfiM3.mjs → adjacency-list-fldj-QAL.mjs} +0 -0
  45. /package/dist/{edge-list-R1SUbHwe.mjs → edge-list-Br05wXMg.mjs} +0 -0
  46. /package/dist/{indexing-DitHphT7.mjs → indexing-DyfgLuzw.mjs} +0 -0
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as TraversalOptions, E as VisualGraphConfig, O as VisualNode, S as TransitionOptions, T as VisualGraph, _ as MSTOptions, a as EntitiesConfig, b as PathOptions, c as Graph, d as GraphEdge, f as GraphFormatConverter, g as GraphStep, h as GraphPath, i as EdgeConfig, l as GraphConfig, m as GraphPatch, n as DeleteNodeOptions, o as EntitiesUpdate, p as GraphNode, r as EdgeChange, s as EntityRect, t as AllPairsShortestPathsOptions, u as GraphDiff, v as NodeChange, w as VisualEdge, x as SinglePathOptions, y as NodeConfig } from "./types-Bq_fmLwW.mjs";
2
- import { bfs, dfs, genCycles, genPostorders, genPreorders, genShortestPaths, genSimplePaths, getAllPairsShortestPaths, getConnectedComponents, getCycles, getMinimumSpanningTree, getPostorder, getPostorders, getPreorder, getPreorders, getShortestPath, getShortestPaths, getSimplePath, getSimplePaths, getStronglyConnectedComponents, getTopologicalSort, hasPath, isAcyclic, isConnected, isTree, joinPaths } from "./algorithms.mjs";
1
+ import { A as VisualNode, C as SinglePathOptions, D as VisualGraph, E as VisualEdge, M as WalkOptions, N as WeightedWalkOptions, O as VisualGraphConfig, S as PathOptions, T as TraversalOptions, _ as GraphPath, a as EdgeChange, b as NodeChange, c as EntitiesUpdate, d as GraphConfig, f as GraphDiff, g as GraphPatch, h as GraphNode, i as DeleteNodeOptions, j as WalkContext, l as EntityRect, m as GraphFormatConverter, n as AllPairsShortestPathsOptions, o as EdgeConfig, p as GraphEdge, r as CoverageStats, s as EntitiesConfig, t as AStarOptions, u as Graph, v as GraphStep, w as TransitionOptions, x as NodeConfig, y as MSTOptions } from "./types-DF-HNw50.mjs";
2
+ import { bfs, dfs, genCycles, genPostorders, genPreorders, genShortestPaths, genSimplePaths, getAStarPath, getAllPairsShortestPaths, getConnectedComponents, getCycles, getMinimumSpanningTree, getPostorder, getPostorders, getPreorder, getPreorders, getShortestPath, getShortestPaths, getSimplePath, getSimplePaths, getStronglyConnectedComponents, getTopologicalSort, hasPath, isAcyclic, isConnected, isTree, joinPaths } from "./algorithms.mjs";
3
3
  import { createFormatConverter } from "./formats/converter/index.mjs";
4
4
  import { getAncestors, getChildren, getDegree, getDepth, getDescendants, getEdgeBetween, getEdgesOf, getInDegree, getInEdges, getLCA, getNeighbors, getOutDegree, getOutEdges, getParent, getPredecessors, getRelativeDistance, getRelativeDistanceMap, getRoots, getSiblings, getSinks, getSources, getSuccessors, isCompound, isLeaf } from "./queries.mjs";
5
5
 
@@ -449,5 +449,102 @@ declare function toDiff<N, E>(patches: GraphPatch<N, E>[]): GraphDiff<N, E>;
449
449
  * ```
450
450
  */
451
451
  declare function flatten<N, E, G>(graph: Graph<N, E, G>): Graph<N, E, G>;
452
+ /**
453
+ * Returns the induced subgraph containing only the given node IDs
454
+ * and edges whose endpoints are both in the set.
455
+ *
456
+ * Parent references to nodes outside the set are removed.
457
+ *
458
+ * @example
459
+ * ```ts
460
+ * import { createGraph, getSubgraph } from '@statelyai/graph';
461
+ *
462
+ * const graph = createGraph({
463
+ * nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
464
+ * edges: [
465
+ * { id: 'ab', sourceId: 'a', targetId: 'b' },
466
+ * { id: 'bc', sourceId: 'b', targetId: 'c' },
467
+ * ],
468
+ * });
469
+ *
470
+ * const sub = getSubgraph(graph, ['a', 'b']);
471
+ * // sub.nodes: [a, b], sub.edges: [ab]
472
+ * ```
473
+ */
474
+ declare function getSubgraph<N, E, G>(graph: Graph<N, E, G>, nodeIds: string[]): Graph<N, E, G>;
475
+ /**
476
+ * Returns a new graph with all edge directions flipped (source ↔ target).
477
+ * Optionally filters which edges to include.
478
+ *
479
+ * @example
480
+ * ```ts
481
+ * import { createGraph, reverseGraph } from '@statelyai/graph';
482
+ *
483
+ * const graph = createGraph({
484
+ * nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
485
+ * edges: [
486
+ * { id: 'ab', sourceId: 'a', targetId: 'b' },
487
+ * { id: 'bc', sourceId: 'b', targetId: 'c' },
488
+ * ],
489
+ * });
490
+ *
491
+ * const rev = reverseGraph(graph);
492
+ * // rev edges: b→a, c→b
493
+ *
494
+ * const filtered = reverseGraph(graph, (e) => e.id !== 'bc');
495
+ * // filtered edges: b→a (only ab reversed, bc excluded)
496
+ * ```
497
+ */
498
+ declare function reverseGraph<N, E, G>(graph: Graph<N, E, G>, filterEdge?: (edge: GraphEdge<E>) => boolean): Graph<N, E, G>;
499
+ //#endregion
500
+ //#region src/walks.d.ts
501
+ /**
502
+ * Random walk. At each node, picks a uniformly random outgoing edge.
503
+ * Yields steps indefinitely (may revisit nodes) until a sink node is reached.
504
+ */
505
+ declare function genRandomWalk<N, E>(graph: Graph<N, E>, options?: WalkOptions<E>): Generator<GraphStep<N, E>>;
506
+ /**
507
+ * Weighted random walk. Edge selection probability proportional to weight.
508
+ */
509
+ declare function genWeightedRandomWalk<N, E>(graph: Graph<N, E>, options?: WeightedWalkOptions<E>): Generator<GraphStep<N, E>>;
510
+ /**
511
+ * Quick random walk targeting unvisited edges.
512
+ * If unvisited outgoing edges exist, picks one randomly.
513
+ * Otherwise, finds shortest path to a node with unvisited outgoing edges.
514
+ */
515
+ declare function genQuickRandomWalk<N, E>(graph: Graph<N, E>, options?: WalkOptions<E>): Generator<GraphStep<N, E>>;
516
+ /**
517
+ * Walk a predefined sequence of edge IDs.
518
+ * Validates each edge exists and connects from the current position.
519
+ */
520
+ declare function genPredefinedWalk<N, E>(graph: Graph<N, E>, edgeIds: string[], options?: Pick<WalkOptions<E>, 'from'>): Generator<GraphStep<N, E>>;
521
+ /**
522
+ * Yield at most `n` steps from the source generator.
523
+ */
524
+ declare function takeSteps<N, E>(gen: Generator<GraphStep<N, E>>, n: number): Generator<GraphStep<N, E>>;
525
+ /**
526
+ * Yield steps until a specific node is reached.
527
+ */
528
+ declare function takeUntilNode<N, E>(gen: Generator<GraphStep<N, E>>, nodeId: string): Generator<GraphStep<N, E>>;
529
+ /**
530
+ * Yield steps until a specific edge is traversed.
531
+ */
532
+ declare function takeUntilEdge<N, E>(gen: Generator<GraphStep<N, E>>, edgeId: string): Generator<GraphStep<N, E>>;
533
+ /**
534
+ * Yield steps until node coverage reaches the target (0–1).
535
+ */
536
+ declare function takeUntilNodeCoverage<N, E>(gen: Generator<GraphStep<N, E>>, graph: Graph<N, E>, coverage: number, options?: {
537
+ from?: string;
538
+ }): Generator<GraphStep<N, E>>;
539
+ /**
540
+ * Yield steps until edge coverage reaches the target (0–1).
541
+ */
542
+ declare function takeUntilEdgeCoverage<N, E>(gen: Generator<GraphStep<N, E>>, graph: Graph<N, E>, coverage: number): Generator<GraphStep<N, E>>;
543
+ /**
544
+ * Compute coverage statistics for a completed walk.
545
+ */
546
+ declare function getCoverage<N, E>(graph: Graph<N, E>, steps: GraphStep<N, E>[], options?: {
547
+ from?: string;
548
+ }): CoverageStats;
452
549
  //#endregion
453
- export { type AllPairsShortestPathsOptions, type DeleteNodeOptions, type EdgeChange, type EdgeConfig, type EntitiesConfig, type EntitiesUpdate, type Graph, type GraphConfig, type GraphDiff, type GraphEdge, type GraphFormatConverter, GraphInstance, type GraphNode, type GraphPatch, type GraphPath, type GraphStep, type MSTOptions, type NodeChange, type NodeConfig, type PathOptions, type EntityRect as Positioned, type SinglePathOptions, type TransitionOptions, type TraversalOptions, type VisualEdge, type VisualGraph, type VisualGraphConfig, type VisualNode, addEdge, addEntities, addNode, applyPatches, bfs, createFormatConverter, createGraph, createGraphFromTransition, createVisualGraph, deleteEdge, deleteEntities, deleteNode, dfs, flatten, genCycles, genPostorders, genPreorders, genShortestPaths, genSimplePaths, getAllPairsShortestPaths, getAncestors, getChildren, getConnectedComponents, getCycles, getDegree, getDepth, getDescendants, getDiff, getEdge, getEdgeBetween, getEdgesOf, getInDegree, getInEdges, getLCA, getMinimumSpanningTree, getNeighbors, getNode, getOutDegree, getOutEdges, getParent, getPatches, getPostorder, getPostorders, getPredecessors, getPreorder, getPreorders, getRelativeDistance, getRelativeDistanceMap, getRoots, getShortestPath, getShortestPaths, getSiblings, getSimplePath, getSimplePaths, getSinks, getSources, getStronglyConnectedComponents, getSuccessors, getTopologicalSort, hasEdge, hasNode, hasPath, invalidateIndex, invertDiff, isAcyclic, isCompound, isConnected, isEmptyDiff, isLeaf, isTree, joinPaths, toDiff, toPatches, updateEdge, updateEntities, updateNode };
550
+ export { type AStarOptions, type AllPairsShortestPathsOptions, type CoverageStats, type DeleteNodeOptions, type EdgeChange, type EdgeConfig, type EntitiesConfig, type EntitiesUpdate, type Graph, type GraphConfig, type GraphDiff, type GraphEdge, type GraphFormatConverter, GraphInstance, type GraphNode, type GraphPatch, type GraphPath, type GraphStep, type MSTOptions, type NodeChange, type NodeConfig, type PathOptions, type EntityRect as Positioned, type SinglePathOptions, type TransitionOptions, type TraversalOptions, type VisualEdge, type VisualGraph, type VisualGraphConfig, type VisualNode, type WalkContext, type WalkOptions, type WeightedWalkOptions, addEdge, addEntities, addNode, applyPatches, bfs, createFormatConverter, createGraph, createGraphFromTransition, createVisualGraph, deleteEdge, deleteEntities, deleteNode, dfs, flatten, genCycles, genPostorders, genPredefinedWalk, genPreorders, genQuickRandomWalk, genRandomWalk, genShortestPaths, genSimplePaths, genWeightedRandomWalk, getAStarPath, getAllPairsShortestPaths, getAncestors, getChildren, getConnectedComponents, getCoverage, getCycles, getDegree, getDepth, getDescendants, getDiff, getEdge, getEdgeBetween, getEdgesOf, getInDegree, getInEdges, getLCA, getMinimumSpanningTree, getNeighbors, getNode, getOutDegree, getOutEdges, getParent, getPatches, getPostorder, getPostorders, getPredecessors, getPreorder, getPreorders, getRelativeDistance, getRelativeDistanceMap, getRoots, getShortestPath, getShortestPaths, getSiblings, getSimplePath, getSimplePaths, getSinks, getSources, getStronglyConnectedComponents, getSubgraph, getSuccessors, getTopologicalSort, hasEdge, hasNode, hasPath, invalidateIndex, invertDiff, isAcyclic, isCompound, isConnected, isEmptyDiff, isLeaf, isTree, joinPaths, reverseGraph, takeSteps, takeUntilEdge, takeUntilEdgeCoverage, takeUntilNode, takeUntilNodeCoverage, toDiff, toPatches, updateEdge, updateEntities, updateNode };
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import { o as invalidateIndex, t as getIndex } from "./indexing-DitHphT7.mjs";
2
- import { A as addNode, B as hasNode, C as isAcyclic, D as GraphInstance, E as joinPaths, F as deleteEntities, H as updateEntities, I as deleteNode, L as getEdge, M as createGraphFromTransition, N as createVisualGraph, O as addEdge, P as deleteEdge, R as getNode, S as hasPath, T as isTree, U as updateNode, V as updateEdge, _ as getShortestPaths, a as genPreorders, b as getStronglyConnectedComponents, c as getAllPairsShortestPaths, d as getMinimumSpanningTree, f as getPostorder, g as getShortestPath, h as getPreorders, i as genPostorders, j as createGraph, k as addEntities, l as getConnectedComponents, m as getPreorder, n as dfs, o as genShortestPaths, p as getPostorders, r as genCycles, s as genSimplePaths, t as bfs, u as getCycles, v as getSimplePath, w as isConnected, x as getTopologicalSort, y as getSimplePaths, z as hasEdge } from "./algorithms-CnTmuX9t.mjs";
1
+ import { o as invalidateIndex, t as getIndex } from "./indexing-DyfgLuzw.mjs";
2
+ import { A as addEntities, B as hasEdge, C as hasPath, D as joinPaths, E as isTree, F as deleteEdge, H as updateEdge, I as deleteEntities, L as deleteNode, M as createGraph, N as createGraphFromTransition, O as GraphInstance, P as createVisualGraph, R as getEdge, S as getTopologicalSort, T as isConnected, U as updateEntities, V as hasNode, W as updateNode, _ as getShortestPath, a as genPreorders, b as getSimplePaths, c as getAStarPath, d as getCycles, f as getMinimumSpanningTree, g as getPreorders, h as getPreorder, i as genPostorders, j as addNode, k as addEdge, l as getAllPairsShortestPaths, m as getPostorders, n as dfs, o as genShortestPaths, p as getPostorder, r as genCycles, s as genSimplePaths, t as bfs, u as getConnectedComponents, v as getShortestPaths, w as isAcyclic, x as getStronglyConnectedComponents, y as getSimplePath, z as getNode } from "./algorithms-oVD9PYil.mjs";
3
3
  import { getAncestors, getChildren, getDegree, getDepth, getDescendants, getEdgeBetween, getEdgesOf, getInDegree, getInEdges, getLCA, getNeighbors, getOutDegree, getOutEdges, getParent, getPredecessors, getRelativeDistance, getRelativeDistanceMap, getRoots, getSiblings, getSinks, getSources, getSuccessors, isCompound, isLeaf } from "./queries.mjs";
4
- import { n as createFormatConverter } from "./converter-C5DlzzHs.mjs";
4
+ import { n as createFormatConverter } from "./converter-B5CUD0r9.mjs";
5
5
 
6
6
  //#region src/diff.ts
7
- function nodeToConfig(node) {
7
+ function nodeToConfig$1(node) {
8
8
  const config = { id: node.id };
9
9
  if (node.parentId) config.parentId = node.parentId;
10
10
  if (node.initialNodeId) config.initialNodeId = node.initialNodeId;
@@ -19,7 +19,7 @@ function nodeToConfig(node) {
19
19
  if (node.style !== void 0) config.style = node.style;
20
20
  return config;
21
21
  }
22
- function edgeToConfig(edge) {
22
+ function edgeToConfig$1(edge) {
23
23
  const config = {
24
24
  id: edge.id,
25
25
  sourceId: edge.sourceId,
@@ -101,7 +101,7 @@ function getDiff(a, b) {
101
101
  };
102
102
  for (const [id, nodeB] of bNodeMap) {
103
103
  const nodeA = aNodeMap.get(id);
104
- if (!nodeA) diff.nodes.added.push(nodeToConfig(nodeB));
104
+ if (!nodeA) diff.nodes.added.push(nodeToConfig$1(nodeB));
105
105
  else {
106
106
  const oldPartial = {};
107
107
  const newPartial = {};
@@ -116,10 +116,10 @@ function getDiff(a, b) {
116
116
  });
117
117
  }
118
118
  }
119
- for (const [id, nodeA] of aNodeMap) if (!bNodeMap.has(id)) diff.nodes.removed.push(nodeToConfig(nodeA));
119
+ for (const [id, nodeA] of aNodeMap) if (!bNodeMap.has(id)) diff.nodes.removed.push(nodeToConfig$1(nodeA));
120
120
  for (const [id, edgeB] of bEdgeMap) {
121
121
  const edgeA = aEdgeMap.get(id);
122
- if (!edgeA) diff.edges.added.push(edgeToConfig(edgeB));
122
+ if (!edgeA) diff.edges.added.push(edgeToConfig$1(edgeB));
123
123
  else {
124
124
  const oldPartial = {};
125
125
  const newPartial = {};
@@ -134,7 +134,7 @@ function getDiff(a, b) {
134
134
  });
135
135
  }
136
136
  }
137
- for (const [id, edgeA] of aEdgeMap) if (!bEdgeMap.has(id)) diff.edges.removed.push(edgeToConfig(edgeA));
137
+ for (const [id, edgeA] of aEdgeMap) if (!bEdgeMap.has(id)) diff.edges.removed.push(edgeToConfig$1(edgeA));
138
138
  return diff;
139
139
  }
140
140
  /**
@@ -455,6 +455,362 @@ function flatten(graph) {
455
455
  data: graph.data
456
456
  });
457
457
  }
458
+ function nodeToConfig(node, nodeIdSet) {
459
+ const config = {
460
+ id: node.id,
461
+ label: node.label,
462
+ data: node.data
463
+ };
464
+ if (node.parentId !== void 0 && node.parentId !== null) config.parentId = nodeIdSet && !nodeIdSet.has(node.parentId) ? void 0 : node.parentId;
465
+ if (node.initialNodeId !== void 0) config.initialNodeId = node.initialNodeId ?? void 0;
466
+ if (node.x !== void 0) config.x = node.x;
467
+ if (node.y !== void 0) config.y = node.y;
468
+ if (node.width !== void 0) config.width = node.width;
469
+ if (node.height !== void 0) config.height = node.height;
470
+ if (node.shape !== void 0) config.shape = node.shape;
471
+ if (node.color !== void 0) config.color = node.color;
472
+ if (node.style !== void 0) config.style = node.style;
473
+ return config;
474
+ }
475
+ function edgeToConfig(edge) {
476
+ const config = {
477
+ id: edge.id,
478
+ sourceId: edge.sourceId,
479
+ targetId: edge.targetId,
480
+ label: edge.label,
481
+ data: edge.data
482
+ };
483
+ if (edge.weight !== void 0) config.weight = edge.weight;
484
+ if (edge.x !== void 0) config.x = edge.x;
485
+ if (edge.y !== void 0) config.y = edge.y;
486
+ if (edge.width !== void 0) config.width = edge.width;
487
+ if (edge.height !== void 0) config.height = edge.height;
488
+ if (edge.color !== void 0) config.color = edge.color;
489
+ if (edge.style !== void 0) config.style = edge.style;
490
+ return config;
491
+ }
492
+ /**
493
+ * Returns the induced subgraph containing only the given node IDs
494
+ * and edges whose endpoints are both in the set.
495
+ *
496
+ * Parent references to nodes outside the set are removed.
497
+ *
498
+ * @example
499
+ * ```ts
500
+ * import { createGraph, getSubgraph } from '@statelyai/graph';
501
+ *
502
+ * const graph = createGraph({
503
+ * nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
504
+ * edges: [
505
+ * { id: 'ab', sourceId: 'a', targetId: 'b' },
506
+ * { id: 'bc', sourceId: 'b', targetId: 'c' },
507
+ * ],
508
+ * });
509
+ *
510
+ * const sub = getSubgraph(graph, ['a', 'b']);
511
+ * // sub.nodes: [a, b], sub.edges: [ab]
512
+ * ```
513
+ */
514
+ function getSubgraph(graph, nodeIds) {
515
+ const nodeIdSet = new Set(nodeIds);
516
+ return createGraph({
517
+ id: graph.id,
518
+ type: graph.type,
519
+ initialNodeId: graph.initialNodeId && nodeIdSet.has(graph.initialNodeId) ? graph.initialNodeId : void 0,
520
+ nodes: graph.nodes.filter((n) => nodeIdSet.has(n.id)).map((n) => nodeToConfig(n, nodeIdSet)),
521
+ edges: graph.edges.filter((e) => nodeIdSet.has(e.sourceId) && nodeIdSet.has(e.targetId)).map(edgeToConfig),
522
+ data: graph.data
523
+ });
524
+ }
525
+ /**
526
+ * Returns a new graph with all edge directions flipped (source ↔ target).
527
+ * Optionally filters which edges to include.
528
+ *
529
+ * @example
530
+ * ```ts
531
+ * import { createGraph, reverseGraph } from '@statelyai/graph';
532
+ *
533
+ * const graph = createGraph({
534
+ * nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
535
+ * edges: [
536
+ * { id: 'ab', sourceId: 'a', targetId: 'b' },
537
+ * { id: 'bc', sourceId: 'b', targetId: 'c' },
538
+ * ],
539
+ * });
540
+ *
541
+ * const rev = reverseGraph(graph);
542
+ * // rev edges: b→a, c→b
543
+ *
544
+ * const filtered = reverseGraph(graph, (e) => e.id !== 'bc');
545
+ * // filtered edges: b→a (only ab reversed, bc excluded)
546
+ * ```
547
+ */
548
+ function reverseGraph(graph, filterEdge) {
549
+ const edges = filterEdge ? graph.edges.filter(filterEdge) : graph.edges;
550
+ return createGraph({
551
+ id: graph.id,
552
+ type: graph.type,
553
+ initialNodeId: graph.initialNodeId ?? void 0,
554
+ nodes: graph.nodes.map((n) => nodeToConfig(n)),
555
+ edges: edges.map((e) => {
556
+ const config = edgeToConfig(e);
557
+ config.sourceId = e.targetId;
558
+ config.targetId = e.sourceId;
559
+ return config;
560
+ }),
561
+ data: graph.data
562
+ });
563
+ }
564
+
565
+ //#endregion
566
+ //#region src/walks.ts
567
+ function mulberry32(seed) {
568
+ let s = seed | 0;
569
+ return () => {
570
+ s = s + 1831565813 | 0;
571
+ let t = Math.imul(s ^ s >>> 15, 1 | s);
572
+ t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
573
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
574
+ };
575
+ }
576
+ function makeRng(seed) {
577
+ return seed !== void 0 ? mulberry32(seed) : Math.random;
578
+ }
579
+ function resolveFrom(graph, from) {
580
+ if (from) return from;
581
+ if (graph.initialNodeId) return graph.initialNodeId;
582
+ const inDeg = /* @__PURE__ */ new Map();
583
+ for (const n of graph.nodes) inDeg.set(n.id, 0);
584
+ for (const e of graph.edges) inDeg.set(e.targetId, (inDeg.get(e.targetId) ?? 0) + 1);
585
+ const roots = [...inDeg.entries()].filter(([, d]) => d === 0);
586
+ if (roots.length === 1) return roots[0][0];
587
+ throw new Error("Cannot determine start node: provide `from`, set graph.initialNodeId, or have exactly one source node.");
588
+ }
589
+ /**
590
+ * Random walk. At each node, picks a uniformly random outgoing edge.
591
+ * Yields steps indefinitely (may revisit nodes) until a sink node is reached.
592
+ */
593
+ function* genRandomWalk(graph, options) {
594
+ const rng = makeRng(options?.seed);
595
+ let currentId = resolveFrom(graph, options?.from);
596
+ const ctx = {
597
+ currentNodeId: currentId,
598
+ visitedNodes: new Set([currentId]),
599
+ visitedEdges: /* @__PURE__ */ new Set(),
600
+ stepCount: 0
601
+ };
602
+ while (true) {
603
+ let edges = getOutEdges(graph, currentId);
604
+ if (options?.filter) edges = edges.filter((e) => options.filter(e, ctx));
605
+ if (edges.length === 0) return;
606
+ const edge = edges[Math.floor(rng() * edges.length)];
607
+ const node = getNode(graph, edge.targetId);
608
+ const step = {
609
+ edge,
610
+ node
611
+ };
612
+ currentId = node.id;
613
+ ctx.currentNodeId = currentId;
614
+ ctx.visitedNodes.add(currentId);
615
+ ctx.visitedEdges.add(edge.id);
616
+ ctx.stepCount++;
617
+ options?.onStep?.(step, ctx);
618
+ yield step;
619
+ }
620
+ }
621
+ /**
622
+ * Weighted random walk. Edge selection probability proportional to weight.
623
+ */
624
+ function* genWeightedRandomWalk(graph, options) {
625
+ const rng = makeRng(options?.seed);
626
+ const getWeight = options?.getWeight ?? ((e) => e.weight ?? 1);
627
+ let currentId = resolveFrom(graph, options?.from);
628
+ const ctx = {
629
+ currentNodeId: currentId,
630
+ visitedNodes: new Set([currentId]),
631
+ visitedEdges: /* @__PURE__ */ new Set(),
632
+ stepCount: 0
633
+ };
634
+ while (true) {
635
+ let edges = getOutEdges(graph, currentId);
636
+ if (options?.filter) edges = edges.filter((e) => options.filter(e, ctx));
637
+ if (edges.length === 0) return;
638
+ const weights = edges.map((e) => Math.max(0, getWeight(e)));
639
+ const total = weights.reduce((a, b) => a + b, 0);
640
+ if (total === 0) return;
641
+ let r = rng() * total;
642
+ let chosen = edges[0];
643
+ for (let i = 0; i < edges.length; i++) {
644
+ r -= weights[i];
645
+ if (r <= 0) {
646
+ chosen = edges[i];
647
+ break;
648
+ }
649
+ }
650
+ const node = getNode(graph, chosen.targetId);
651
+ const step = {
652
+ edge: chosen,
653
+ node
654
+ };
655
+ currentId = node.id;
656
+ ctx.currentNodeId = currentId;
657
+ ctx.visitedNodes.add(currentId);
658
+ ctx.visitedEdges.add(chosen.id);
659
+ ctx.stepCount++;
660
+ options?.onStep?.(step, ctx);
661
+ yield step;
662
+ }
663
+ }
664
+ /**
665
+ * Quick random walk targeting unvisited edges.
666
+ * If unvisited outgoing edges exist, picks one randomly.
667
+ * Otherwise, finds shortest path to a node with unvisited outgoing edges.
668
+ */
669
+ function* genQuickRandomWalk(graph, options) {
670
+ const rng = makeRng(options?.seed);
671
+ let currentId = resolveFrom(graph, options?.from);
672
+ const visitedEdges = /* @__PURE__ */ new Set();
673
+ const allEdgeIds = new Set(graph.edges.map((e) => e.id));
674
+ const ctx = {
675
+ currentNodeId: currentId,
676
+ visitedNodes: new Set([currentId]),
677
+ visitedEdges,
678
+ stepCount: 0
679
+ };
680
+ while (visitedEdges.size < allEdgeIds.size) {
681
+ let edges = getOutEdges(graph, currentId);
682
+ if (options?.filter) edges = edges.filter((e) => options.filter(e, ctx));
683
+ const unvisited = edges.filter((e) => !visitedEdges.has(e.id));
684
+ if (unvisited.length > 0) {
685
+ const edge = unvisited[Math.floor(rng() * unvisited.length)];
686
+ const node = getNode(graph, edge.targetId);
687
+ const step = {
688
+ edge,
689
+ node
690
+ };
691
+ currentId = node.id;
692
+ ctx.currentNodeId = currentId;
693
+ ctx.visitedNodes.add(currentId);
694
+ visitedEdges.add(edge.id);
695
+ ctx.stepCount++;
696
+ options?.onStep?.(step, ctx);
697
+ yield step;
698
+ } else {
699
+ let targetNodeId;
700
+ for (const n of graph.nodes) if (getOutEdges(graph, n.id).some((e) => !visitedEdges.has(e.id))) {
701
+ targetNodeId = n.id;
702
+ break;
703
+ }
704
+ if (!targetNodeId) return;
705
+ const path = getShortestPath(graph, {
706
+ from: currentId,
707
+ to: targetNodeId
708
+ });
709
+ if (!path || path.steps.length === 0) return;
710
+ for (const step of path.steps) {
711
+ currentId = step.node.id;
712
+ ctx.currentNodeId = currentId;
713
+ ctx.visitedNodes.add(currentId);
714
+ visitedEdges.add(step.edge.id);
715
+ ctx.stepCount++;
716
+ options?.onStep?.(step, ctx);
717
+ yield step;
718
+ }
719
+ }
720
+ }
721
+ }
722
+ /**
723
+ * Walk a predefined sequence of edge IDs.
724
+ * Validates each edge exists and connects from the current position.
725
+ */
726
+ function* genPredefinedWalk(graph, edgeIds, options) {
727
+ let currentId = resolveFrom(graph, options?.from);
728
+ for (const edgeId of edgeIds) {
729
+ const edge = graph.edges.find((e) => e.id === edgeId);
730
+ if (!edge) throw new Error(`Edge "${edgeId}" not found in graph.`);
731
+ if (edge.sourceId !== currentId) throw new Error(`Edge "${edgeId}" starts at "${edge.sourceId}" but current position is "${currentId}".`);
732
+ const node = getNode(graph, edge.targetId);
733
+ currentId = node.id;
734
+ yield {
735
+ edge,
736
+ node
737
+ };
738
+ }
739
+ }
740
+ /**
741
+ * Yield at most `n` steps from the source generator.
742
+ */
743
+ function* takeSteps(gen, n) {
744
+ let count = 0;
745
+ for (const step of gen) {
746
+ yield step;
747
+ if (++count >= n) return;
748
+ }
749
+ }
750
+ /**
751
+ * Yield steps until a specific node is reached.
752
+ */
753
+ function* takeUntilNode(gen, nodeId) {
754
+ for (const step of gen) {
755
+ yield step;
756
+ if (step.node.id === nodeId) return;
757
+ }
758
+ }
759
+ /**
760
+ * Yield steps until a specific edge is traversed.
761
+ */
762
+ function* takeUntilEdge(gen, edgeId) {
763
+ for (const step of gen) {
764
+ yield step;
765
+ if (step.edge.id === edgeId) return;
766
+ }
767
+ }
768
+ /**
769
+ * Yield steps until node coverage reaches the target (0–1).
770
+ */
771
+ function* takeUntilNodeCoverage(gen, graph, coverage, options) {
772
+ const totalNodes = graph.nodes.length;
773
+ const target = Math.ceil(coverage * totalNodes);
774
+ const startId = options?.from ?? graph.initialNodeId ?? graph.nodes[0]?.id;
775
+ const visited = new Set(startId ? [startId] : []);
776
+ for (const step of gen) {
777
+ visited.add(step.node.id);
778
+ yield step;
779
+ if (visited.size >= target) return;
780
+ }
781
+ }
782
+ /**
783
+ * Yield steps until edge coverage reaches the target (0–1).
784
+ */
785
+ function* takeUntilEdgeCoverage(gen, graph, coverage) {
786
+ const totalEdges = graph.edges.length;
787
+ const target = Math.ceil(coverage * totalEdges);
788
+ const visited = /* @__PURE__ */ new Set();
789
+ for (const step of gen) {
790
+ visited.add(step.edge.id);
791
+ yield step;
792
+ if (visited.size >= target) return;
793
+ }
794
+ }
795
+ /**
796
+ * Compute coverage statistics for a completed walk.
797
+ */
798
+ function getCoverage(graph, steps, options) {
799
+ const startId = options?.from ?? graph.initialNodeId ?? graph.nodes[0]?.id;
800
+ const visitedNodes = new Set(startId ? [startId] : []);
801
+ const visitedEdges = /* @__PURE__ */ new Set();
802
+ for (const step of steps) {
803
+ visitedNodes.add(step.node.id);
804
+ visitedEdges.add(step.edge.id);
805
+ }
806
+ return {
807
+ nodeCoverage: graph.nodes.length > 0 ? visitedNodes.size / graph.nodes.length : 1,
808
+ edgeCoverage: graph.edges.length > 0 ? visitedEdges.size / graph.edges.length : 1,
809
+ visitedNodes: [...visitedNodes],
810
+ visitedEdges: [...visitedEdges],
811
+ totalSteps: steps.length
812
+ };
813
+ }
458
814
 
459
815
  //#endregion
460
- export { GraphInstance, addEdge, addEntities, addNode, applyPatches, bfs, createFormatConverter, createGraph, createGraphFromTransition, createVisualGraph, deleteEdge, deleteEntities, deleteNode, dfs, flatten, genCycles, genPostorders, genPreorders, genShortestPaths, genSimplePaths, getAllPairsShortestPaths, getAncestors, getChildren, getConnectedComponents, getCycles, getDegree, getDepth, getDescendants, getDiff, getEdge, getEdgeBetween, getEdgesOf, getInDegree, getInEdges, getLCA, getMinimumSpanningTree, getNeighbors, getNode, getOutDegree, getOutEdges, getParent, getPatches, getPostorder, getPostorders, getPredecessors, getPreorder, getPreorders, getRelativeDistance, getRelativeDistanceMap, getRoots, getShortestPath, getShortestPaths, getSiblings, getSimplePath, getSimplePaths, getSinks, getSources, getStronglyConnectedComponents, getSuccessors, getTopologicalSort, hasEdge, hasNode, hasPath, invalidateIndex, invertDiff, isAcyclic, isCompound, isConnected, isEmptyDiff, isLeaf, isTree, joinPaths, toDiff, toPatches, updateEdge, updateEntities, updateNode };
816
+ export { GraphInstance, addEdge, addEntities, addNode, applyPatches, bfs, createFormatConverter, createGraph, createGraphFromTransition, createVisualGraph, deleteEdge, deleteEntities, deleteNode, dfs, flatten, genCycles, genPostorders, genPredefinedWalk, genPreorders, genQuickRandomWalk, genRandomWalk, genShortestPaths, genSimplePaths, genWeightedRandomWalk, getAStarPath, getAllPairsShortestPaths, getAncestors, getChildren, getConnectedComponents, getCoverage, getCycles, getDegree, getDepth, getDescendants, getDiff, getEdge, getEdgeBetween, getEdgesOf, getInDegree, getInEdges, getLCA, getMinimumSpanningTree, getNeighbors, getNode, getOutDegree, getOutEdges, getParent, getPatches, getPostorder, getPostorders, getPredecessors, getPreorder, getPreorders, getRelativeDistance, getRelativeDistanceMap, getRoots, getShortestPath, getShortestPaths, getSiblings, getSimplePath, getSimplePaths, getSinks, getSources, getStronglyConnectedComponents, getSubgraph, getSuccessors, getTopologicalSort, hasEdge, hasNode, hasPath, invalidateIndex, invertDiff, isAcyclic, isCompound, isConnected, isEmptyDiff, isLeaf, isTree, joinPaths, reverseGraph, takeSteps, takeUntilEdge, takeUntilEdgeCoverage, takeUntilNode, takeUntilNodeCoverage, toDiff, toPatches, updateEdge, updateEntities, updateNode };
@@ -1,4 +1,4 @@
1
- import { c as Graph, d as GraphEdge, p as GraphNode } from "./types-Bq_fmLwW.mjs";
1
+ import { h as GraphNode, p as GraphEdge, u as Graph } from "./types-DF-HNw50.mjs";
2
2
 
3
3
  //#region src/queries.d.ts
4
4
 
package/dist/queries.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as getIndex } from "./indexing-DitHphT7.mjs";
1
+ import { t as getIndex } from "./indexing-DyfgLuzw.mjs";
2
2
 
3
3
  //#region src/queries.ts
4
4
  /**
@@ -4,10 +4,17 @@ import * as z from "zod";
4
4
  declare const NodeSchema: z.ZodObject<{
5
5
  type: z.ZodLiteral<"node">;
6
6
  id: z.ZodString;
7
- parentId: z.ZodNullable<z.ZodString>;
8
- initialNodeId: z.ZodNullable<z.ZodString>;
7
+ parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
8
+ initialNodeId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
9
9
  label: z.ZodString;
10
10
  data: z.ZodAny;
11
+ x: z.ZodOptional<z.ZodNumber>;
12
+ y: z.ZodOptional<z.ZodNumber>;
13
+ width: z.ZodOptional<z.ZodNumber>;
14
+ height: z.ZodOptional<z.ZodNumber>;
15
+ shape: z.ZodOptional<z.ZodString>;
16
+ color: z.ZodOptional<z.ZodString>;
17
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
11
18
  }, z.core.$strip>;
12
19
  declare const EdgeSchema: z.ZodObject<{
13
20
  type: z.ZodLiteral<"edge">;
@@ -15,7 +22,14 @@ declare const EdgeSchema: z.ZodObject<{
15
22
  sourceId: z.ZodString;
16
23
  targetId: z.ZodString;
17
24
  label: z.ZodString;
25
+ weight: z.ZodOptional<z.ZodNumber>;
18
26
  data: z.ZodAny;
27
+ x: z.ZodOptional<z.ZodNumber>;
28
+ y: z.ZodOptional<z.ZodNumber>;
29
+ width: z.ZodOptional<z.ZodNumber>;
30
+ height: z.ZodOptional<z.ZodNumber>;
31
+ color: z.ZodOptional<z.ZodString>;
32
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
19
33
  }, z.core.$strip>;
20
34
  declare const GraphSchema: z.ZodObject<{
21
35
  id: z.ZodString;
@@ -27,10 +41,17 @@ declare const GraphSchema: z.ZodObject<{
27
41
  nodes: z.ZodArray<z.ZodObject<{
28
42
  type: z.ZodLiteral<"node">;
29
43
  id: z.ZodString;
30
- parentId: z.ZodNullable<z.ZodString>;
31
- initialNodeId: z.ZodNullable<z.ZodString>;
44
+ parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
45
+ initialNodeId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
32
46
  label: z.ZodString;
33
47
  data: z.ZodAny;
48
+ x: z.ZodOptional<z.ZodNumber>;
49
+ y: z.ZodOptional<z.ZodNumber>;
50
+ width: z.ZodOptional<z.ZodNumber>;
51
+ height: z.ZodOptional<z.ZodNumber>;
52
+ shape: z.ZodOptional<z.ZodString>;
53
+ color: z.ZodOptional<z.ZodString>;
54
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
34
55
  }, z.core.$strip>>;
35
56
  edges: z.ZodArray<z.ZodObject<{
36
57
  type: z.ZodLiteral<"edge">;
@@ -38,9 +59,23 @@ declare const GraphSchema: z.ZodObject<{
38
59
  sourceId: z.ZodString;
39
60
  targetId: z.ZodString;
40
61
  label: z.ZodString;
62
+ weight: z.ZodOptional<z.ZodNumber>;
41
63
  data: z.ZodAny;
64
+ x: z.ZodOptional<z.ZodNumber>;
65
+ y: z.ZodOptional<z.ZodNumber>;
66
+ width: z.ZodOptional<z.ZodNumber>;
67
+ height: z.ZodOptional<z.ZodNumber>;
68
+ color: z.ZodOptional<z.ZodString>;
69
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
42
70
  }, z.core.$strip>>;
43
71
  data: z.ZodAny;
72
+ direction: z.ZodOptional<z.ZodEnum<{
73
+ up: "up";
74
+ down: "down";
75
+ left: "left";
76
+ right: "right";
77
+ }>>;
78
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
44
79
  }, z.core.$strip>;
45
80
  //#endregion
46
81
  export { EdgeSchema, GraphSchema, NodeSchema };