@statelyai/graph 2.0.0 → 2.1.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 (73) hide show
  1. package/README.md +67 -19
  2. package/dist/{algorithms-CsGNehct.d.mts → algorithms-D1cgly0g.d.mts} +145 -6
  3. package/dist/{algorithms-DF1pSQGv.mjs → algorithms-DBpH74hR.mjs} +673 -891
  4. package/dist/algorithms.d.mts +2 -2
  5. package/dist/algorithms.mjs +2 -2
  6. package/dist/config-Dt5u1gSf.mjs +793 -0
  7. package/dist/{converter-DyCJJfTe.mjs → converter-DB6Rg6Vd.mjs} +2 -2
  8. package/dist/formats/adjacency-list/index.d.mts +1 -1
  9. package/dist/formats/adjacency-list/index.mjs +1 -1
  10. package/dist/formats/converter/index.d.mts +1 -1
  11. package/dist/formats/converter/index.mjs +1 -1
  12. package/dist/formats/cytoscape/index.d.mts +4 -4
  13. package/dist/formats/cytoscape/index.mjs +8 -4
  14. package/dist/formats/d2/index.d.mts +1 -1
  15. package/dist/formats/d2/index.mjs +1 -1
  16. package/dist/formats/d3/index.d.mts +4 -4
  17. package/dist/formats/d3/index.mjs +8 -4
  18. package/dist/formats/dot/index.d.mts +1 -1
  19. package/dist/formats/dot/index.mjs +1 -1
  20. package/dist/formats/edge-list/index.d.mts +1 -1
  21. package/dist/formats/edge-list/index.mjs +1 -1
  22. package/dist/formats/elk/index.d.mts +1 -1
  23. package/dist/formats/elk/index.mjs +43 -11
  24. package/dist/formats/gexf/index.d.mts +1 -1
  25. package/dist/formats/gexf/index.mjs +22 -2
  26. package/dist/formats/gml/index.d.mts +4 -4
  27. package/dist/formats/gml/index.mjs +8 -4
  28. package/dist/formats/graphml/index.d.mts +1 -1
  29. package/dist/formats/graphml/index.mjs +24 -2
  30. package/dist/formats/jgf/index.d.mts +4 -4
  31. package/dist/formats/jgf/index.mjs +8 -4
  32. package/dist/formats/mermaid/index.d.mts +1 -1
  33. package/dist/formats/mermaid/index.mjs +1 -1
  34. package/dist/formats/tgf/index.d.mts +4 -4
  35. package/dist/formats/tgf/index.mjs +4 -4
  36. package/dist/formats/xyflow/index.d.mts +12 -6
  37. package/dist/formats/xyflow/index.mjs +11 -6
  38. package/dist/{index-D51lJnt2.d.mts → index-BlbSWUvH.d.mts} +1 -1
  39. package/dist/{index-DWmo1mIp.d.mts → index-CNvqxPLJ.d.mts} +82 -14
  40. package/dist/index.d.mts +6 -6
  41. package/dist/index.mjs +152 -17
  42. package/dist/layout/cytoscape.d.mts +66 -0
  43. package/dist/layout/cytoscape.mjs +114 -0
  44. package/dist/layout/d3-force.d.mts +52 -0
  45. package/dist/layout/d3-force.mjs +127 -0
  46. package/dist/layout/d3-hierarchy.d.mts +39 -0
  47. package/dist/layout/d3-hierarchy.mjs +135 -0
  48. package/dist/layout/dagre.d.mts +32 -0
  49. package/dist/layout/dagre.mjs +99 -0
  50. package/dist/layout/elk.d.mts +47 -0
  51. package/dist/layout/elk.mjs +73 -0
  52. package/dist/layout/forceatlas2.d.mts +48 -0
  53. package/dist/layout/forceatlas2.mjs +100 -0
  54. package/dist/layout/graphviz.d.mts +50 -0
  55. package/dist/layout/graphviz.mjs +179 -0
  56. package/dist/layout/index.d.mts +185 -0
  57. package/dist/layout/index.mjs +181 -0
  58. package/dist/layout/webcola.d.mts +40 -0
  59. package/dist/layout/webcola.mjs +104 -0
  60. package/dist/{queries-BfXeTXRf.d.mts → queries-B6quF529.d.mts} +1 -1
  61. package/dist/{queries-KirMDR7e.mjs → queries-BMM0XAv_.mjs} +23 -17
  62. package/dist/queries.d.mts +1 -1
  63. package/dist/queries.mjs +1 -1
  64. package/dist/schemas.d.mts +19 -1
  65. package/dist/schemas.mjs +10 -1
  66. package/dist/{types-DNYdIU21.d.mts → types-BAEQTwK_.d.mts} +46 -3
  67. package/package.json +47 -5
  68. package/schemas/edge.schema.json +27 -0
  69. package/schemas/graph.schema.json +27 -0
  70. /package/dist/{adjacency-list-GeL1Cu-L.mjs → adjacency-list-DQ32Mmhx.mjs} +0 -0
  71. /package/dist/{edge-list-BcZ0h6zz.mjs → edge-list-CA9UTvn2.mjs} +0 -0
  72. /package/dist/{mode-D8OnHFBk.mjs → mode-gu_mhKKs.mjs} +0 -0
  73. /package/dist/{validate-TtH-x3JV.mjs → validate-BsfSOv0S.mjs} +0 -0
@@ -1,4 +1,4 @@
1
- import { d as Graph, m as GraphEdge, v as GraphNode, x as GraphPort } from "./types-DNYdIU21.mjs";
1
+ import { S as GraphPort, f as Graph, h as GraphEdge, y as GraphNode } from "./types-BAEQTwK_.mjs";
2
2
 
3
3
  //#region src/queries.d.ts
4
4
 
@@ -1,4 +1,4 @@
1
- import { t as getEdgeMode } from "./mode-D8OnHFBk.mjs";
1
+ import { t as getEdgeMode } from "./mode-gu_mhKKs.mjs";
2
2
 
3
3
  //#region src/indexing.ts
4
4
  const indexes = /* @__PURE__ */ new WeakMap();
@@ -14,7 +14,8 @@ const indexes = /* @__PURE__ */ new WeakMap();
14
14
  *
15
15
  * @example
16
16
  * ```ts
17
- * import { createGraph, getIndex } from '@statelyai/graph';
17
+ * import { createGraph } from '@statelyai/graph';
18
+ * import { getIndex } from './indexing';
18
19
  *
19
20
  * const graph = createGraph({
20
21
  * nodes: [{ id: 'a' }, { id: 'b' }],
@@ -41,14 +42,15 @@ function getIndex(graph) {
41
42
  *
42
43
  * @example
43
44
  * ```ts
44
- * import { createGraph, invalidateIndex, getIndex } from '@statelyai/graph';
45
+ * import { createGraph, getSuccessors, invalidateIndex } from '@statelyai/graph';
45
46
  *
46
47
  * const graph = createGraph({
47
48
  * nodes: [{ id: 'a' }, { id: 'b' }],
48
49
  * edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }],
49
50
  * });
50
51
  * graph.edges[0].targetId = 'a'; // in-place field mutation
51
- * invalidateIndex(graph); // forces rebuild on next getIndex()
52
+ * invalidateIndex(graph); // forces rebuild on next indexed read
53
+ * getSuccessors(graph, 'a');
52
54
  * ```
53
55
  */
54
56
  function invalidateIndex(graph) {
@@ -148,6 +150,19 @@ function indexUpdateEdgeEndpoints(idx, edgeId, oldSourceId, oldTargetId, newSour
148
150
 
149
151
  //#endregion
150
152
  //#region src/queries.ts
153
+ const nonDirectedSelfLoopCache = /* @__PURE__ */ new WeakMap();
154
+ function getNonDirectedSelfLoopCounts(graph, idx) {
155
+ const cached = nonDirectedSelfLoopCache.get(idx);
156
+ if (cached && cached.version === idx.version && cached.mode === graph.mode) return cached.counts;
157
+ const counts = /* @__PURE__ */ new Map();
158
+ for (const edge of graph.edges) if (edge.sourceId === edge.targetId && getEdgeMode(graph, edge) !== "directed") counts.set(edge.sourceId, (counts.get(edge.sourceId) ?? 0) + 1);
159
+ nonDirectedSelfLoopCache.set(idx, {
160
+ version: idx.version,
161
+ mode: graph.mode,
162
+ counts
163
+ });
164
+ return counts;
165
+ }
151
166
  /**
152
167
  * Returns all edges (incoming + outgoing) connected to a node.
153
168
  *
@@ -375,19 +390,10 @@ function getNeighbors(graph, nodeId) {
375
390
  */
376
391
  function getDegree(graph, nodeId) {
377
392
  const idx = getIndex(graph);
378
- const out = idx.outEdges.get(nodeId) ?? [];
379
- const inE = idx.inEdges.get(nodeId) ?? [];
380
- let degree = 0;
381
- const countedNonDirected = /* @__PURE__ */ new Set();
382
- for (const eid of [...out, ...inE]) {
383
- const e = graph.edges[idx.edgeById.get(eid)];
384
- if (getEdgeMode(graph, e) === "directed") degree++;
385
- else if (!countedNonDirected.has(eid)) {
386
- countedNonDirected.add(eid);
387
- degree++;
388
- }
389
- }
390
- return degree;
393
+ const out = idx.outEdges.get(nodeId);
394
+ const inE = idx.inEdges.get(nodeId);
395
+ const selfLoops = getNonDirectedSelfLoopCounts(graph, idx);
396
+ return (out?.length ?? 0) + (inE?.length ?? 0) - (selfLoops.get(nodeId) ?? 0);
391
397
  }
392
398
  /**
393
399
  * Returns the in-degree of a node — the number of edges traversable *into*
@@ -1,2 +1,2 @@
1
- import { C as getSinks, D as isLeaf, E as isCompound, S as getSiblings, T as getSuccessors, _ as getPorts, a as getDescendants, b as getRelativeDistanceMap, c as getEdgesOf, d as getLCA, f as getNeighbors, g as getPort, h as getParent, i as getDepth, l as getInDegree, m as getOutEdges, n as getChildren, o as getEdgesBetween, p as getOutDegree, r as getDegree, s as getEdgesByPort, t as getAncestors, u as getInEdges, v as getPredecessors, w as getSources, x as getRoots, y as getRelativeDistance } from "./queries-BfXeTXRf.mjs";
1
+ import { C as getSinks, D as isLeaf, E as isCompound, S as getSiblings, T as getSuccessors, _ as getPorts, a as getDescendants, b as getRelativeDistanceMap, c as getEdgesOf, d as getLCA, f as getNeighbors, g as getPort, h as getParent, i as getDepth, l as getInDegree, m as getOutEdges, n as getChildren, o as getEdgesBetween, p as getOutDegree, r as getDegree, s as getEdgesByPort, t as getAncestors, u as getInEdges, v as getPredecessors, w as getSources, x as getRoots, y as getRelativeDistance } from "./queries-B6quF529.mjs";
2
2
  export { getAncestors, getChildren, getDegree, getDepth, getDescendants, getEdgesBetween, getEdgesByPort, getEdgesOf, getInDegree, getInEdges, getLCA, getNeighbors, getOutDegree, getOutEdges, getParent, getPort, getPorts, getPredecessors, getRelativeDistance, getRelativeDistanceMap, getRoots, getSiblings, getSinks, getSources, getSuccessors, isCompound, isLeaf };
package/dist/queries.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { C as getSinks, D as isLeaf, E as isCompound, S as getSiblings, T as getSuccessors, _ as getPorts, a as getDescendants, b as getRelativeDistanceMap, c as getEdgesOf, d as getLCA, f as getNeighbors, g as getPort, h as getParent, i as getDepth, l as getInDegree, m as getOutEdges, n as getChildren, o as getEdgesBetween, p as getOutDegree, r as getDegree, s as getEdgesByPort, t as getAncestors, u as getInEdges, v as getPredecessors, w as getSources, x as getRoots, y as getRelativeDistance } from "./queries-KirMDR7e.mjs";
1
+ import { C as getSinks, D as isLeaf, E as isCompound, S as getSiblings, T as getSuccessors, _ as getPorts, a as getDescendants, b as getRelativeDistanceMap, c as getEdgesOf, d as getLCA, f as getNeighbors, g as getPort, h as getParent, i as getDepth, l as getInDegree, m as getOutEdges, n as getChildren, o as getEdgesBetween, p as getOutDegree, r as getDegree, s as getEdgesByPort, t as getAncestors, u as getInEdges, v as getPredecessors, w as getSources, x as getRoots, y as getRelativeDistance } from "./queries-BMM0XAv_.mjs";
2
2
 
3
3
  export { getAncestors, getChildren, getDegree, getDepth, getDescendants, getEdgesBetween, getEdgesByPort, getEdgesOf, getInDegree, getInEdges, getLCA, getNeighbors, getOutDegree, getOutEdges, getParent, getPort, getPorts, getPredecessors, getRelativeDistance, getRelativeDistanceMap, getRoots, getSiblings, getSinks, getSources, getSuccessors, isCompound, isLeaf };
@@ -1,4 +1,4 @@
1
- import { d as Graph, m as GraphEdge, v as GraphNode, x as GraphPort } from "./types-DNYdIU21.mjs";
1
+ import { S as GraphPort, f as Graph, h as GraphEdge, y as GraphNode } from "./types-BAEQTwK_.mjs";
2
2
  import * as z from "zod";
3
3
 
4
4
  //#region src/schemas.d.ts
@@ -61,6 +61,15 @@ declare const EdgeSchema: z.ZodObject<{
61
61
  undirected: "undirected";
62
62
  bidirectional: "bidirectional";
63
63
  }>>;
64
+ points: z.ZodOptional<z.ZodArray<z.ZodObject<{
65
+ x: z.ZodNumber;
66
+ y: z.ZodNumber;
67
+ }, z.core.$strip>>>;
68
+ routing: z.ZodOptional<z.ZodEnum<{
69
+ polyline: "polyline";
70
+ orthogonal: "orthogonal";
71
+ splines: "splines";
72
+ }>>;
64
73
  data: z.ZodAny;
65
74
  x: z.ZodOptional<z.ZodNumber>;
66
75
  y: z.ZodOptional<z.ZodNumber>;
@@ -121,6 +130,15 @@ declare const GraphSchema: z.ZodObject<{
121
130
  undirected: "undirected";
122
131
  bidirectional: "bidirectional";
123
132
  }>>;
133
+ points: z.ZodOptional<z.ZodArray<z.ZodObject<{
134
+ x: z.ZodNumber;
135
+ y: z.ZodNumber;
136
+ }, z.core.$strip>>>;
137
+ routing: z.ZodOptional<z.ZodEnum<{
138
+ polyline: "polyline";
139
+ orthogonal: "orthogonal";
140
+ splines: "splines";
141
+ }>>;
124
142
  data: z.ZodAny;
125
143
  x: z.ZodOptional<z.ZodNumber>;
126
144
  y: z.ZodOptional<z.ZodNumber>;
package/dist/schemas.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as getGraphIssues$1 } from "./validate-TtH-x3JV.mjs";
1
+ import { t as getGraphIssues$1 } from "./validate-BsfSOv0S.mjs";
2
2
  import * as z from "zod";
3
3
 
4
4
  //#region src/schemas.ts
@@ -54,6 +54,15 @@ const EdgeSchema = z.object({
54
54
  sourcePort: z.string().optional(),
55
55
  targetPort: z.string().optional(),
56
56
  mode: ModeSchema.optional(),
57
+ points: z.array(z.object({
58
+ x: z.number(),
59
+ y: z.number()
60
+ })).optional(),
61
+ routing: z.enum([
62
+ "polyline",
63
+ "orthogonal",
64
+ "splines"
65
+ ]).optional(),
57
66
  data: z.any(),
58
67
  x: z.number().optional(),
59
68
  y: z.number().optional(),
@@ -16,6 +16,20 @@ interface EntityRect {
16
16
  width: number;
17
17
  height: number;
18
18
  }
19
+ /** A 2D point, used for edge routing waypoints. */
20
+ interface Point {
21
+ x: number;
22
+ y: number;
23
+ }
24
+ /**
25
+ * How an edge's {@link GraphEdge.points} should be interpreted by renderers:
26
+ *
27
+ * - `'polyline'` — straight segments through the points.
28
+ * - `'orthogonal'` — axis-aligned segments (ELK layered routing).
29
+ * - `'splines'` — bezier control points (Graphviz convention: 3n+1 chained
30
+ * cubic curves, tail → head).
31
+ */
32
+ type EdgeRouting = 'polyline' | 'orthogonal' | 'splines';
19
33
  /** Shared optional visual/style props for nodes, edges, ports. */
20
34
  interface GraphEntity {
21
35
  x?: number;
@@ -55,7 +69,7 @@ interface GraphConfig<TNodeData = any, TEdgeData = any, TGraphData = any, TPortD
55
69
  id?: string;
56
70
  /** Default directedness for all edges. Defaults to `'directed'`. */
57
71
  mode?: GraphMode;
58
- initialNodeId?: string;
72
+ initialNodeId?: string | null;
59
73
  nodes?: NodeConfig<TNodeData, TPortData>[];
60
74
  edges?: EdgeConfig<TEdgeData>[];
61
75
  data?: TGraphData;
@@ -65,13 +79,20 @@ interface GraphConfig<TNodeData = any, TEdgeData = any, TGraphData = any, TPortD
65
79
  interface NodeConfig<TNodeData = any, TPortData = any> extends GraphEntity {
66
80
  id: string;
67
81
  parentId?: string | null;
68
- initialNodeId?: string;
82
+ initialNodeId?: string | null;
69
83
  label?: string | null;
70
84
  data?: TNodeData;
71
85
  ports?: PortConfig<TPortData>[];
72
86
  shape?: string;
73
87
  color?: string;
74
88
  }
89
+ /**
90
+ * Note on edge geometry: an edge's `x`/`y`/`width`/`height` are canonically
91
+ * the **label rect** (top-left + size). Layout adapters write computed edge
92
+ * label positions here, and engines that need label dimensions as input
93
+ * (dagre, ELK) read `width`/`height`. The edge's *route* lives in
94
+ * {@link EdgeConfig.points}.
95
+ */
75
96
  interface EdgeConfig<TEdgeData = any> extends GraphEntity {
76
97
  /**
77
98
  * The id of the edge.
@@ -104,6 +125,13 @@ interface EdgeConfig<TEdgeData = any> extends GraphEntity {
104
125
  * {@link GraphConfig.mode}.
105
126
  */
106
127
  mode?: GraphMode;
128
+ /**
129
+ * Edge route waypoints (including endpoints, tail → head), as computed by a
130
+ * layout engine. Interpretation is governed by {@link EdgeConfig.routing}.
131
+ */
132
+ points?: Point[];
133
+ /** How {@link EdgeConfig.points} should be interpreted. Default: polyline. */
134
+ routing?: EdgeRouting;
107
135
  data?: TEdgeData;
108
136
  color?: string;
109
137
  }
@@ -129,6 +157,11 @@ interface GraphNode<TNodeData = any, TPortData = any> extends GraphEntity {
129
157
  shape?: string;
130
158
  color?: string;
131
159
  }
160
+ /**
161
+ * Note on edge geometry: an edge's `x`/`y`/`width`/`height` are canonically
162
+ * the **label rect** (top-left + size); the edge's *route* lives in
163
+ * {@link GraphEdge.points}. See {@link EdgeConfig} for details.
164
+ */
132
165
  interface GraphEdge<TEdgeData = any> extends GraphEntity {
133
166
  type: 'edge';
134
167
  id: string;
@@ -150,6 +183,13 @@ interface GraphEdge<TEdgeData = any> extends GraphEntity {
150
183
  * {@link Graph.mode}.
151
184
  */
152
185
  mode?: GraphMode;
186
+ /**
187
+ * Edge route waypoints (including endpoints, tail → head), as computed by a
188
+ * layout engine. Interpretation is governed by {@link GraphEdge.routing}.
189
+ */
190
+ points?: Point[];
191
+ /** How {@link GraphEdge.points} should be interpreted. Default: polyline. */
192
+ routing?: EdgeRouting;
153
193
  data: TEdgeData;
154
194
  color?: string;
155
195
  }
@@ -219,6 +259,9 @@ interface EdgeUpdate<TEdgeData = any> {
219
259
  sourcePort?: string | null;
220
260
  /** Port name on the target node, or `null` to clear the port reference. */
221
261
  targetPort?: string | null;
262
+ /** Edge route waypoints, or `null` to clear the route. */
263
+ points?: Point[] | null;
264
+ routing?: EdgeRouting | null;
222
265
  x?: number | null;
223
266
  y?: number | null;
224
267
  width?: number | null;
@@ -424,4 +467,4 @@ interface TransitionOptions<TState, TEvent> {
424
467
  id?: string;
425
468
  }
426
469
  //#endregion
427
- export { SinglePathOptions as A, WalkContext as B, MSTOptions as C, PathOptions as D, NodeUpdate as E, VisualGraphConfig as F, WeightedWalkOptions as H, VisualGraphEntity as I, VisualGraphFormatConverter as L, TraversalOptions as M, VisualEdge as N, PortConfig as O, VisualGraph as P, VisualNode as R, GraphStep as S, NodeConfig as T, WalkOptions as V, GraphMode as _, EdgeChange as a, GraphPath as b, EntitiesConfig as c, Graph as d, GraphConfig as f, GraphFormatConverter as g, GraphEntity as h, DeleteNodeOptions as i, TransitionOptions as j, PortDirection as k, EntitiesUpdate as l, GraphEdge as m, AllPairsShortestPathsOptions as n, EdgeConfig as o, GraphDiff as p, CoverageStats as r, EdgeUpdate as s, AStarOptions as t, EntityRect as u, GraphNode as v, NodeChange as w, GraphPort as x, GraphPatch as y, VisualPort as z };
470
+ 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 };
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@statelyai/graph",
3
3
  "type": "module",
4
- "version": "2.0.0",
4
+ "sideEffects": false,
5
+ "version": "2.1.0",
5
6
  "description": "A TypeScript-first graph library with plain JSON-serializable objects",
6
7
  "author": "David Khourshid <david@stately.ai>",
7
8
  "license": "MIT",
@@ -40,6 +41,15 @@
40
41
  "./mermaid": "./dist/formats/mermaid/index.mjs",
41
42
  "./tgf": "./dist/formats/tgf/index.mjs",
42
43
  "./xyflow": "./dist/formats/xyflow/index.mjs",
44
+ "./layout": "./dist/layout/index.mjs",
45
+ "./layout/cytoscape": "./dist/layout/cytoscape.mjs",
46
+ "./layout/d3-force": "./dist/layout/d3-force.mjs",
47
+ "./layout/d3-hierarchy": "./dist/layout/d3-hierarchy.mjs",
48
+ "./layout/dagre": "./dist/layout/dagre.mjs",
49
+ "./layout/elk": "./dist/layout/elk.mjs",
50
+ "./layout/forceatlas2": "./dist/layout/forceatlas2.mjs",
51
+ "./layout/graphviz": "./dist/layout/graphviz.mjs",
52
+ "./layout/webcola": "./dist/layout/webcola.mjs",
43
53
  "./queries": "./dist/queries.mjs",
44
54
  "./schemas": "./dist/schemas.mjs",
45
55
  "./package.json": "./package.json"
@@ -53,22 +63,27 @@
53
63
  ],
54
64
  "devDependencies": {
55
65
  "@changesets/changelog-github": "^0.5.2",
56
- "@changesets/cli": "^2.29.8",
66
+ "@changesets/cli": "^2.31.0",
67
+ "@dagrejs/dagre": "^3.0.0",
57
68
  "@dagrejs/graphlib": "^4.0.1",
69
+ "@hpcc-js/wasm-graphviz": "^1.22.0",
58
70
  "@types/d3-array": "^3.2.2",
59
71
  "@types/d3-force": "^3.0.10",
72
+ "@types/d3-hierarchy": "^3.1.7",
60
73
  "@types/node": "^25.0.3",
61
74
  "@vitest/coverage-v8": "^4.0.18",
62
75
  "@xyflow/system": "^0.0.75",
63
76
  "bumpp": "^10.3.2",
64
- "cytoscape": "^3.33.1",
77
+ "cytoscape": "^3.34.0",
65
78
  "d3-array": "^3.2.4",
66
79
  "d3-force": "^3.0.0",
80
+ "d3-hierarchy": "^3.1.2",
67
81
  "dotparser": "^1.1.1",
68
82
  "elkjs": "^0.11.1",
69
83
  "fast-xml-parser": "^5.3.4",
70
84
  "graphology": "^0.26.0",
71
85
  "graphology-components": "^1.5.4",
86
+ "graphology-layout-forceatlas2": "^0.10.1",
72
87
  "graphology-metrics": "^2.4.0",
73
88
  "graphology-shortest-path": "^2.1.0",
74
89
  "graphology-types": "^0.24.8",
@@ -76,27 +91,43 @@
76
91
  "ngraph.path": "^1.6.1",
77
92
  "publint": "^0.3.15",
78
93
  "tsdown": "^0.18.1",
79
- "tsx": "^4.21.0",
94
+ "tsx": "^4.22.4",
80
95
  "typescript": "^5.9.3",
81
96
  "vitest": "^4.0.16",
97
+ "webcola": "^3.4.0",
82
98
  "xstate": "^5.28.0",
83
99
  "zod": "^4.3.6"
84
100
  },
85
101
  "peerDependencies": {
102
+ "@dagrejs/dagre": "^3.0.0 || ^4.0.0",
103
+ "@hpcc-js/wasm-graphviz": "^1.0.0",
86
104
  "cytoscape": "^3.0.0",
87
105
  "d3-force": "^3.0.0",
106
+ "d3-hierarchy": "^3.0.0",
88
107
  "dotparser": "^1.0.0",
89
108
  "elkjs": "^0.9.0 || ^0.10.0 || ^0.11.0",
90
109
  "fast-xml-parser": "^5.0.0",
110
+ "graphology": "^0.26.0",
111
+ "graphology-layout-forceatlas2": "^0.10.0",
112
+ "webcola": "^3.4.0",
91
113
  "zod": "^4.0.0"
92
114
  },
93
115
  "peerDependenciesMeta": {
116
+ "@dagrejs/dagre": {
117
+ "optional": true
118
+ },
119
+ "@hpcc-js/wasm-graphviz": {
120
+ "optional": true
121
+ },
94
122
  "cytoscape": {
95
123
  "optional": true
96
124
  },
97
125
  "d3-force": {
98
126
  "optional": true
99
127
  },
128
+ "d3-hierarchy": {
129
+ "optional": true
130
+ },
100
131
  "dotparser": {
101
132
  "optional": true
102
133
  },
@@ -106,6 +137,15 @@
106
137
  "fast-xml-parser": {
107
138
  "optional": true
108
139
  },
140
+ "graphology": {
141
+ "optional": true
142
+ },
143
+ "graphology-layout-forceatlas2": {
144
+ "optional": true
145
+ },
146
+ "webcola": {
147
+ "optional": true
148
+ },
109
149
  "zod": {
110
150
  "optional": true
111
151
  }
@@ -117,8 +157,10 @@
117
157
  "fix:generated": "pnpm generate-schema",
118
158
  "test": "vitest",
119
159
  "typecheck": "tsc --noEmit",
160
+ "typecheck:repo": "tsc --project tsconfig.repo.json",
120
161
  "check:generated": "tsx scripts/generate-json-schema.ts --check",
121
- "verify": "pnpm typecheck && pnpm check:generated && pnpm test -- --run && pnpm build && pnpm validate:package",
162
+ "check:conventions": "tsx scripts/check-conventions.ts",
163
+ "verify": "pnpm typecheck && pnpm typecheck:repo && pnpm check:generated && pnpm check:conventions && pnpm test -- --run && pnpm build && pnpm validate:package",
122
164
  "validate:package": "publint && tsx scripts/smoke-package.ts",
123
165
  "generate-schema": "tsx scripts/generate-json-schema.ts",
124
166
  "changeset": "changeset",
@@ -42,6 +42,33 @@
42
42
  "bidirectional"
43
43
  ]
44
44
  },
45
+ "points": {
46
+ "type": "array",
47
+ "items": {
48
+ "type": "object",
49
+ "properties": {
50
+ "x": {
51
+ "type": "number"
52
+ },
53
+ "y": {
54
+ "type": "number"
55
+ }
56
+ },
57
+ "required": [
58
+ "x",
59
+ "y"
60
+ ],
61
+ "additionalProperties": false
62
+ }
63
+ },
64
+ "routing": {
65
+ "type": "string",
66
+ "enum": [
67
+ "polyline",
68
+ "orthogonal",
69
+ "splines"
70
+ ]
71
+ },
45
72
  "data": {},
46
73
  "x": {
47
74
  "type": "number"
@@ -217,6 +217,33 @@
217
217
  "bidirectional"
218
218
  ]
219
219
  },
220
+ "points": {
221
+ "type": "array",
222
+ "items": {
223
+ "type": "object",
224
+ "properties": {
225
+ "x": {
226
+ "type": "number"
227
+ },
228
+ "y": {
229
+ "type": "number"
230
+ }
231
+ },
232
+ "required": [
233
+ "x",
234
+ "y"
235
+ ],
236
+ "additionalProperties": false
237
+ }
238
+ },
239
+ "routing": {
240
+ "type": "string",
241
+ "enum": [
242
+ "polyline",
243
+ "orthogonal",
244
+ "splines"
245
+ ]
246
+ },
220
247
  "data": {},
221
248
  "x": {
222
249
  "type": "number"
File without changes