@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
@@ -1,10 +1,12 @@
1
- import { C as TraversalOptions, _ as MSTOptions, b as PathOptions, c as Graph, h as GraphPath, p as GraphNode, t as AllPairsShortestPathsOptions, x as SinglePathOptions } from "./types-Bq_fmLwW.mjs";
1
+ import { C as SinglePathOptions, S as PathOptions, T as TraversalOptions, _ as GraphPath, h as GraphNode, n as AllPairsShortestPathsOptions, t as AStarOptions, u as Graph, y as MSTOptions } from "./types-DF-HNw50.mjs";
2
2
 
3
3
  //#region src/algorithms.d.ts
4
4
 
5
5
  /**
6
6
  * Breadth-first traversal generator yielding nodes level by level.
7
7
  *
8
+ * **O(V + E)** time, **O(V)** space.
9
+ *
8
10
  * @example
9
11
  * ```ts
10
12
  * import { createGraph, bfs } from '@statelyai/graph';
@@ -23,6 +25,8 @@ declare function bfs<N>(graph: Graph<N>, startId: string): Generator<GraphNode<N
23
25
  /**
24
26
  * Depth-first traversal generator yielding nodes as visited.
25
27
  *
28
+ * **O(V + E)** time, **O(V)** space.
29
+ *
26
30
  * @example
27
31
  * ```ts
28
32
  * import { createGraph, dfs } from '@statelyai/graph';
@@ -41,6 +45,8 @@ declare function dfs<N>(graph: Graph<N>, startId: string): Generator<GraphNode<N
41
45
  /**
42
46
  * Checks whether the graph contains no cycles.
43
47
  *
48
+ * **O(V + E)** time.
49
+ *
44
50
  * @example
45
51
  * ```ts
46
52
  * import { createGraph, isAcyclic } from '@statelyai/graph';
@@ -58,6 +64,8 @@ declare function isAcyclic(graph: Graph): boolean;
58
64
  * Returns connected components as arrays of nodes.
59
65
  * Treats all edges as undirected for connectivity.
60
66
  *
67
+ * **O(V + E)** time.
68
+ *
61
69
  * @example
62
70
  * ```ts
63
71
  * import { createGraph, getConnectedComponents } from '@statelyai/graph';
@@ -75,6 +83,8 @@ declare function getConnectedComponents<N>(graph: Graph<N>): GraphNode<N>[][];
75
83
  /**
76
84
  * Returns a topological ordering of nodes, or `null` if the graph is cyclic.
77
85
  *
86
+ * **O(V + E)** time (Kahn's algorithm).
87
+ *
78
88
  * @example
79
89
  * ```ts
80
90
  * import { createGraph, getTopologicalSort } from '@statelyai/graph';
@@ -95,6 +105,8 @@ declare function getTopologicalSort<N>(graph: Graph<N>): GraphNode<N>[] | null;
95
105
  /**
96
106
  * Checks whether a path exists between two nodes.
97
107
  *
108
+ * **O(V + E)** time (BFS) or **O((V + E) log V)** (Dijkstra when weighted).
109
+ *
98
110
  * @example
99
111
  * ```ts
100
112
  * import { createGraph, hasPath } from '@statelyai/graph';
@@ -112,6 +124,8 @@ declare function hasPath(graph: Graph, sourceId: string, targetId: string): bool
112
124
  /**
113
125
  * Checks whether the graph is connected (all nodes reachable from any node).
114
126
  *
127
+ * **O(V + E)** time.
128
+ *
115
129
  * @example
116
130
  * ```ts
117
131
  * import { createGraph, isConnected } from '@statelyai/graph';
@@ -128,6 +142,8 @@ declare function isConnected(graph: Graph): boolean;
128
142
  /**
129
143
  * Checks whether the graph is a tree (connected and acyclic).
130
144
  *
145
+ * **O(V + E)** time.
146
+ *
131
147
  * @example
132
148
  * ```ts
133
149
  * import { createGraph, isTree } from '@statelyai/graph';
@@ -148,6 +164,9 @@ declare function isTree(graph: Graph): boolean;
148
164
  * Lazily yields all shortest paths from a source node.
149
165
  * Use `getShortestPaths` for the full array.
150
166
  *
167
+ * **O(V + E)** time (BFS) or **O((V + E) log V)** (Dijkstra when weighted),
168
+ * plus **O(P)** per path yielded where P is the path length.
169
+ *
151
170
  * @example
152
171
  * ```ts
153
172
  * import { createGraph, genShortestPaths } from '@statelyai/graph';
@@ -171,6 +190,8 @@ declare function genShortestPaths<N, E>(graph: Graph<N, E>, opts?: PathOptions<E
171
190
  * Returns all shortest paths from a source node as an array.
172
191
  * Delegates to `genShortestPaths` internally.
173
192
  *
193
+ * **O(V + E)** time (BFS) or **O((V + E) log V)** (Dijkstra when weighted).
194
+ *
174
195
  * @example
175
196
  * ```ts
176
197
  * import { createGraph, getShortestPaths } from '@statelyai/graph';
@@ -192,6 +213,8 @@ declare function getShortestPaths<N, E>(graph: Graph<N, E>, opts?: PathOptions<E
192
213
  /**
193
214
  * Returns a single shortest path from source to target, or `undefined` if unreachable.
194
215
  *
216
+ * **O(V + E)** time (BFS) or **O((V + E) log V)** (Dijkstra when weighted).
217
+ *
195
218
  * @example
196
219
  * ```ts
197
220
  * import { createGraph, getShortestPath } from '@statelyai/graph';
@@ -214,6 +237,8 @@ declare function getShortestPath<N, E>(graph: Graph<N, E>, opts: SinglePathOptio
214
237
  * Returns all simple (acyclic) paths from a source node as an array.
215
238
  * Delegates to `genSimplePaths` internally.
216
239
  *
240
+ * **O(V!)** worst-case (exponential in dense graphs).
241
+ *
217
242
  * @example
218
243
  * ```ts
219
244
  * import { createGraph, getSimplePaths } from '@statelyai/graph';
@@ -237,6 +262,8 @@ declare function getSimplePaths<N, E>(graph: Graph<N, E>, opts?: PathOptions<E>)
237
262
  * Lazily yields all simple (acyclic) paths from a source node via DFS backtracking.
238
263
  * Use `getSimplePaths` for the full array.
239
264
  *
265
+ * **O(V!)** worst-case (exponential in dense graphs).
266
+ *
240
267
  * @example
241
268
  * ```ts
242
269
  * import { createGraph, genSimplePaths } from '@statelyai/graph';
@@ -261,6 +288,8 @@ declare function genSimplePaths<N, E>(graph: Graph<N, E>, opts?: PathOptions<E>)
261
288
  /**
262
289
  * Returns a single simple (acyclic) path from source to target, or `undefined` if unreachable.
263
290
  *
291
+ * **O(V + E)** typical, **O(V!)** worst-case.
292
+ *
264
293
  * @example
265
294
  * ```ts
266
295
  * import { createGraph, getSimplePath } from '@statelyai/graph';
@@ -283,6 +312,8 @@ declare function getSimplePath<N, E>(graph: Graph<N, E>, opts: SinglePathOptions
283
312
  * Returns strongly connected components using Tarjan's algorithm.
284
313
  * Only meaningful for directed graphs.
285
314
  *
315
+ * **O(V + E)** time.
316
+ *
286
317
  * @example
287
318
  * ```ts
288
319
  * import { createGraph, getStronglyConnectedComponents } from '@statelyai/graph';
@@ -305,6 +336,8 @@ declare function getStronglyConnectedComponents<N>(graph: Graph<N>): GraphNode<N
305
336
  * Returns all elementary cycles as an array of paths.
306
337
  * Delegates to `genCycles` internally.
307
338
  *
339
+ * **O((V + E) · C)** where C is the number of elementary cycles (can be exponential).
340
+ *
308
341
  * @example
309
342
  * ```ts
310
343
  * import { createGraph, getCycles } from '@statelyai/graph';
@@ -326,6 +359,8 @@ declare function getCycles<N, E>(graph: Graph<N, E>): GraphPath<N, E>[];
326
359
  * Lazily yields elementary cycles one at a time.
327
360
  * Use `getCycles` for the full array.
328
361
  *
362
+ * **O((V + E) · C)** where C is the number of elementary cycles (can be exponential).
363
+ *
329
364
  * @example
330
365
  * ```ts
331
366
  * import { createGraph, genCycles } from '@statelyai/graph';
@@ -348,6 +383,8 @@ declare function genCycles<N, E>(graph: Graph<N, E>): Generator<GraphPath<N, E>>
348
383
  * Returns a single canonical preorder (DFS visit-order) sequence.
349
384
  * Visits neighbors in the order they appear in the adjacency list.
350
385
  *
386
+ * **O(V + E)** time.
387
+ *
351
388
  * @example
352
389
  * ```ts
353
390
  * import { createGraph, getPreorder } from '@statelyai/graph';
@@ -370,6 +407,8 @@ declare function getPreorder<N>(graph: Graph<N>, opts?: TraversalOptions): Graph
370
407
  * Returns a single canonical postorder (DFS finish-order) sequence.
371
408
  * Visits neighbors in the order they appear in the adjacency list.
372
409
  *
410
+ * **O(V + E)** time.
411
+ *
373
412
  * @example
374
413
  * ```ts
375
414
  * import { createGraph, getPostorder } from '@statelyai/graph';
@@ -391,6 +430,8 @@ declare function getPostorder<N>(graph: Graph<N>, opts?: TraversalOptions): Grap
391
430
  /**
392
431
  * Returns all possible preorder sequences as an array. Can be exponential -- prefer `genPreorders`.
393
432
  *
433
+ * **O(V! · V)** worst-case (exponential).
434
+ *
394
435
  * @example
395
436
  * ```ts
396
437
  * import { createGraph, getPreorders } from '@statelyai/graph';
@@ -412,6 +453,8 @@ declare function getPreorders<N>(graph: Graph<N>, opts?: TraversalOptions): Grap
412
453
  /**
413
454
  * Returns all possible postorder sequences as an array. Can be exponential -- prefer `genPostorders`.
414
455
  *
456
+ * **O(V! · V)** worst-case (exponential).
457
+ *
415
458
  * @example
416
459
  * ```ts
417
460
  * import { createGraph, getPostorders } from '@statelyai/graph';
@@ -435,6 +478,8 @@ declare function getPostorders<N>(graph: Graph<N>, opts?: TraversalOptions): Gra
435
478
  * Different neighbor exploration orders yield different sequences.
436
479
  * Use `getPreorder()` for a single canonical ordering.
437
480
  *
481
+ * **O(V! · V)** worst-case (exponential).
482
+ *
438
483
  * @example
439
484
  * ```ts
440
485
  * import { createGraph, genPreorders } from '@statelyai/graph';
@@ -460,6 +505,8 @@ declare function genPreorders<N>(graph: Graph<N>, opts?: TraversalOptions): Gene
460
505
  * Different neighbor exploration orders yield different sequences.
461
506
  * Use `getPostorder()` for a single canonical ordering.
462
507
  *
508
+ * **O(V! · V)** worst-case (exponential).
509
+ *
463
510
  * @example
464
511
  * ```ts
465
512
  * import { createGraph, genPostorders } from '@statelyai/graph';
@@ -485,6 +532,8 @@ declare function genPostorders<N>(graph: Graph<N>, opts?: TraversalOptions): Gen
485
532
  * Only meaningful for connected undirected graphs (or the component reachable
486
533
  * from an arbitrary start node in directed graphs).
487
534
  *
535
+ * **O(E log E)** using either edge sorting (Kruskal) or a min-heap (Prim).
536
+ *
488
537
  * @example
489
538
  * ```ts
490
539
  * import { createGraph, getMinimumSpanningTree } from '@statelyai/graph';
@@ -509,7 +558,9 @@ declare function getMinimumSpanningTree<N, E>(graph: Graph<N, E>, opts?: MSTOpti
509
558
  /**
510
559
  * Returns shortest paths between all pairs of nodes.
511
560
  * Algorithm 'dijkstra' (default): runs getShortestPaths per source node.
512
- * Algorithm 'floyd-warshall': classic O(V^3) dynamic programming.
561
+ * Algorithm 'floyd-warshall': classic dynamic programming.
562
+ *
563
+ * **O(V · (V + E) log V)** (Dijkstra) or **O(V³)** (Floyd-Warshall).
513
564
  *
514
565
  * @example
515
566
  * ```ts
@@ -528,6 +579,43 @@ declare function getMinimumSpanningTree<N, E>(graph: Graph<N, E>, opts?: MSTOpti
528
579
  * ```
529
580
  */
530
581
  declare function getAllPairsShortestPaths<N, E>(graph: Graph<N, E>, opts?: AllPairsShortestPathsOptions<E>): GraphPath<N, E>[];
582
+ /**
583
+ * Returns a shortest path using A* search with an admissible heuristic.
584
+ * More efficient than Dijkstra when a good heuristic is available.
585
+ *
586
+ * **O((V + E) log V)** time with a good heuristic; degrades to Dijkstra
587
+ * with `heuristic: () => 0`.
588
+ *
589
+ * @example
590
+ * ```ts
591
+ * import { createGraph, getAStarPath } from '@statelyai/graph';
592
+ *
593
+ * const graph = createGraph({
594
+ * nodes: [
595
+ * { id: 'a', x: 0, y: 0 },
596
+ * { id: 'b', x: 1, y: 0 },
597
+ * { id: 'c', x: 1, y: 1 },
598
+ * ],
599
+ * edges: [
600
+ * { id: 'ab', sourceId: 'a', targetId: 'b', weight: 1 },
601
+ * { id: 'bc', sourceId: 'b', targetId: 'c', weight: 1 },
602
+ * { id: 'ac', sourceId: 'a', targetId: 'c', weight: 3 },
603
+ * ],
604
+ * });
605
+ *
606
+ * const path = getAStarPath(graph, {
607
+ * from: 'a',
608
+ * to: 'c',
609
+ * heuristic: (nodeId) => {
610
+ * const node = graph.nodes.find(n => n.id === nodeId)!;
611
+ * const target = graph.nodes.find(n => n.id === 'c')!;
612
+ * return Math.abs(node.x! - target.x!) + Math.abs(node.y! - target.y!);
613
+ * },
614
+ * });
615
+ * // path: a -> b -> c (weight 2, cheaper than direct a -> c)
616
+ * ```
617
+ */
618
+ declare function getAStarPath<N, E>(graph: Graph<N, E>, opts: AStarOptions<E>): GraphPath<N, E> | undefined;
531
619
  /**
532
620
  * Joins two paths end-to-end. The last node of the head path must equal
533
621
  * the source of the tail path (the overlap node).
@@ -556,4 +644,4 @@ declare function getAllPairsShortestPaths<N, E>(graph: Graph<N, E>, opts?: AllPa
556
644
  */
557
645
  declare function joinPaths<N, E>(headPath: GraphPath<N, E>, tailPath: GraphPath<N, E>): GraphPath<N, E>;
558
646
  //#endregion
559
- export { 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 };
647
+ export { 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 };
@@ -1,3 +1,3 @@
1
- import { C as isAcyclic, E as joinPaths, S as hasPath, T as isTree, _ 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, 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 } from "./algorithms-CnTmuX9t.mjs";
1
+ import { C as hasPath, D as joinPaths, E as isTree, S as getTopologicalSort, T as isConnected, _ 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, 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 } from "./algorithms-oVD9PYil.mjs";
2
2
 
3
- export { 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 };
3
+ export { 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 };
@@ -1,5 +1,5 @@
1
- import { n as toAdjacencyList, t as fromAdjacencyList } from "./adjacency-list-Bv4tfiM3.mjs";
2
- import { n as toEdgeList, t as fromEdgeList } from "./edge-list-R1SUbHwe.mjs";
1
+ import { n as toAdjacencyList, t as fromAdjacencyList } from "./adjacency-list-fldj-QAL.mjs";
2
+ import { n as toEdgeList, t as fromEdgeList } from "./edge-list-Br05wXMg.mjs";
3
3
 
4
4
  //#region src/formats/converter/index.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { c as Graph } from "../../types-Bq_fmLwW.mjs";
1
+ import { u as Graph } from "../../types-DF-HNw50.mjs";
2
2
 
3
3
  //#region src/formats/adjacency-list/index.d.ts
4
4
 
@@ -1,3 +1,3 @@
1
- import { n as toAdjacencyList, t as fromAdjacencyList } from "../../adjacency-list-Bv4tfiM3.mjs";
1
+ import { n as toAdjacencyList, t as fromAdjacencyList } from "../../adjacency-list-fldj-QAL.mjs";
2
2
 
3
3
  export { fromAdjacencyList, toAdjacencyList };
@@ -1,4 +1,4 @@
1
- import { c as Graph, f as GraphFormatConverter } from "../../types-Bq_fmLwW.mjs";
1
+ import { m as GraphFormatConverter, u as Graph } from "../../types-DF-HNw50.mjs";
2
2
 
3
3
  //#region src/formats/converter/index.d.ts
4
4
 
@@ -18,7 +18,7 @@ import { c as Graph, f as GraphFormatConverter } from "../../types-Bq_fmLwW.mjs"
18
18
  * const graph = yamlConverter.from(yaml);
19
19
  * ```
20
20
  */
21
- declare function createFormatConverter<TSerial>(to: (graph: Graph) => TSerial, from: (input: TSerial) => Graph): GraphFormatConverter<TSerial>;
21
+ declare function createFormatConverter<TSerial, N = any, E = any, G = any>(to: (graph: Graph<N, E, G>) => TSerial, from: (input: TSerial) => Graph<N, E, G>): GraphFormatConverter<TSerial, N, E, G>;
22
22
  /**
23
23
  * Bidirectional converter for adjacency-list format (`Record<string, string[]>`).
24
24
  *
@@ -1,3 +1,3 @@
1
- import { n as createFormatConverter, r as edgeListConverter, t as adjacencyListConverter } from "../../converter-C5DlzzHs.mjs";
1
+ import { n as createFormatConverter, r as edgeListConverter, t as adjacencyListConverter } from "../../converter-B5CUD0r9.mjs";
2
2
 
3
3
  export { adjacencyListConverter, createFormatConverter, edgeListConverter };
@@ -1,4 +1,4 @@
1
- import { c as Graph, f as GraphFormatConverter } from "../../types-Bq_fmLwW.mjs";
1
+ import { m as GraphFormatConverter, u as Graph } from "../../types-DF-HNw50.mjs";
2
2
 
3
3
  //#region src/formats/cytoscape/index.d.ts
4
4
  interface CytoscapeNode {
@@ -1,4 +1,4 @@
1
- import { n as createFormatConverter } from "../../converter-C5DlzzHs.mjs";
1
+ import { n as createFormatConverter } from "../../converter-B5CUD0r9.mjs";
2
2
 
3
3
  //#region src/formats/cytoscape/index.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { c as Graph, f as GraphFormatConverter } from "../../types-Bq_fmLwW.mjs";
1
+ import { m as GraphFormatConverter, u as Graph } from "../../types-DF-HNw50.mjs";
2
2
 
3
3
  //#region src/formats/d3/index.d.ts
4
4
  interface D3Node {
@@ -1,4 +1,4 @@
1
- import { n as createFormatConverter } from "../../converter-C5DlzzHs.mjs";
1
+ import { n as createFormatConverter } from "../../converter-B5CUD0r9.mjs";
2
2
 
3
3
  //#region src/formats/d3/index.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { c as Graph, f as GraphFormatConverter } from "../../types-Bq_fmLwW.mjs";
1
+ import { m as GraphFormatConverter, u as Graph } from "../../types-DF-HNw50.mjs";
2
2
 
3
3
  //#region src/formats/dot/index.d.ts
4
4
 
@@ -1,4 +1,4 @@
1
- import { n as createFormatConverter } from "../../converter-C5DlzzHs.mjs";
1
+ import { n as createFormatConverter } from "../../converter-B5CUD0r9.mjs";
2
2
  import parse from "dotparser";
3
3
 
4
4
  //#region src/formats/dot/index.ts
@@ -1,4 +1,4 @@
1
- import { c as Graph } from "../../types-Bq_fmLwW.mjs";
1
+ import { u as Graph } from "../../types-DF-HNw50.mjs";
2
2
 
3
3
  //#region src/formats/edge-list/index.d.ts
4
4
 
@@ -1,3 +1,3 @@
1
- import { n as toEdgeList, t as fromEdgeList } from "../../edge-list-R1SUbHwe.mjs";
1
+ import { n as toEdgeList, t as fromEdgeList } from "../../edge-list-Br05wXMg.mjs";
2
2
 
3
3
  export { fromEdgeList, toEdgeList };
@@ -0,0 +1,61 @@
1
+ import { D as VisualGraph, k as VisualGraphFormatConverter } from "../../types-DF-HNw50.mjs";
2
+ import { ElkEdge, ElkEdgeSection, ElkExtendedEdge, ElkGraphElement, ElkLabel, ElkNode, ElkNode as ElkNode$1, ElkPoint, ElkPort, ElkPrimitiveEdge, ElkShape, LayoutOptions } from "elkjs/lib/elk-api";
3
+
4
+ //#region src/formats/elk/index.d.ts
5
+
6
+ /**
7
+ * Converts a visual graph to ELK JSON format.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { createVisualGraph } from '@statelyai/graph';
12
+ * import { toELK } from '@statelyai/graph/elk';
13
+ *
14
+ * const graph = createVisualGraph({
15
+ * nodes: [
16
+ * { id: 'a', x: 0, y: 0, width: 100, height: 50 },
17
+ * { id: 'b', x: 200, y: 0, width: 100, height: 50 },
18
+ * ],
19
+ * edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }],
20
+ * });
21
+ *
22
+ * const elk = toELK(graph);
23
+ * // { id: '', children: [...], edges: [...] }
24
+ * ```
25
+ */
26
+ declare function toELK(graph: VisualGraph): ElkNode$1;
27
+ /**
28
+ * Parses an ELK JSON node into a visual graph.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * import { fromELK } from '@statelyai/graph/elk';
33
+ *
34
+ * const graph = fromELK({
35
+ * id: 'root',
36
+ * children: [
37
+ * { id: 'a', x: 0, y: 0, width: 100, height: 50 },
38
+ * { id: 'b', x: 200, y: 0, width: 100, height: 50 },
39
+ * ],
40
+ * edges: [{ id: 'e1', sources: ['a'], targets: ['b'] }],
41
+ * });
42
+ *
43
+ * graph.nodes; // [{id: 'a', x: 0, y: 0, ...}, {id: 'b', x: 200, ...}]
44
+ * graph.edges; // [{sourceId: 'a', targetId: 'b', ...}]
45
+ * ```
46
+ */
47
+ declare function fromELK(elkRoot: ElkNode$1): VisualGraph;
48
+ /**
49
+ * Bidirectional converter for ELK JSON format.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * import { elkConverter } from '@statelyai/graph/elk';
54
+ *
55
+ * const elk = elkConverter.to(graph);
56
+ * const roundTripped = elkConverter.from(elk);
57
+ * ```
58
+ */
59
+ declare const elkConverter: VisualGraphFormatConverter<ElkNode$1>;
60
+ //#endregion
61
+ export { type ElkEdge, type ElkEdgeSection, type ElkExtendedEdge, type ElkGraphElement, type ElkLabel, type ElkNode, type ElkPoint, type ElkPort, type ElkPrimitiveEdge, type ElkShape, type LayoutOptions, elkConverter, fromELK, toELK };
@@ -0,0 +1,176 @@
1
+ import { getChildren } from "../../queries.mjs";
2
+
3
+ //#region src/formats/elk/index.ts
4
+ const DIRECTION_TO_ELK = {
5
+ down: "DOWN",
6
+ up: "UP",
7
+ right: "RIGHT",
8
+ left: "LEFT"
9
+ };
10
+ const ELK_TO_DIRECTION = {
11
+ DOWN: "down",
12
+ UP: "up",
13
+ RIGHT: "right",
14
+ LEFT: "left"
15
+ };
16
+ function convertEdge(edge) {
17
+ const elkEdge = {
18
+ id: edge.id,
19
+ sources: [edge.sourceId],
20
+ targets: [edge.targetId]
21
+ };
22
+ if (edge.label) elkEdge.labels = [{ text: edge.label }];
23
+ return elkEdge;
24
+ }
25
+ function convertNode(graph, node) {
26
+ const elkNode = {
27
+ id: node.id,
28
+ x: node.x,
29
+ y: node.y,
30
+ width: node.width,
31
+ height: node.height
32
+ };
33
+ if (node.label) elkNode.labels = [{ text: node.label }];
34
+ const children = getChildren(graph, node.id);
35
+ if (children.length > 0) {
36
+ elkNode.children = children.map((child) => convertNode(graph, child));
37
+ const descendantIds = /* @__PURE__ */ new Set();
38
+ collectDescendants(graph, node.id, descendantIds);
39
+ const innerEdges = graph.edges.filter((e) => descendantIds.has(e.sourceId) && descendantIds.has(e.targetId));
40
+ if (innerEdges.length > 0) elkNode.edges = innerEdges.map(convertEdge);
41
+ }
42
+ return elkNode;
43
+ }
44
+ function collectDescendants(graph, nodeId, set) {
45
+ const children = getChildren(graph, nodeId);
46
+ for (const child of children) {
47
+ set.add(child.id);
48
+ collectDescendants(graph, child.id, set);
49
+ }
50
+ }
51
+ /**
52
+ * Converts a visual graph to ELK JSON format.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * import { createVisualGraph } from '@statelyai/graph';
57
+ * import { toELK } from '@statelyai/graph/elk';
58
+ *
59
+ * const graph = createVisualGraph({
60
+ * nodes: [
61
+ * { id: 'a', x: 0, y: 0, width: 100, height: 50 },
62
+ * { id: 'b', x: 200, y: 0, width: 100, height: 50 },
63
+ * ],
64
+ * edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }],
65
+ * });
66
+ *
67
+ * const elk = toELK(graph);
68
+ * // { id: '', children: [...], edges: [...] }
69
+ * ```
70
+ */
71
+ function toELK(graph) {
72
+ const root = { id: graph.id };
73
+ const elkDir = DIRECTION_TO_ELK[graph.direction];
74
+ if (elkDir) root.layoutOptions = { "elk.direction": elkDir };
75
+ const roots = getChildren(graph, null);
76
+ if (roots.length > 0) root.children = roots.map((node) => convertNode(graph, node));
77
+ const allInnerEdgeIds = /* @__PURE__ */ new Set();
78
+ for (const node of graph.nodes) if (getChildren(graph, node.id).length > 0) {
79
+ const descendantIds = /* @__PURE__ */ new Set();
80
+ collectDescendants(graph, node.id, descendantIds);
81
+ for (const edge of graph.edges) if (descendantIds.has(edge.sourceId) && descendantIds.has(edge.targetId)) allInnerEdgeIds.add(edge.id);
82
+ }
83
+ const rootEdges = graph.edges.filter((e) => !allInnerEdgeIds.has(e.id));
84
+ if (rootEdges.length > 0) root.edges = rootEdges.map(convertEdge);
85
+ return root;
86
+ }
87
+ function flattenElkNodes(elkNode, parentId, nodes, edges, edgeIdx) {
88
+ if (elkNode.children) for (const child of elkNode.children) {
89
+ const label = child.labels?.[0]?.text ?? "";
90
+ const node = {
91
+ type: "node",
92
+ id: child.id,
93
+ parentId,
94
+ initialNodeId: null,
95
+ label,
96
+ data: void 0,
97
+ x: child.x ?? 0,
98
+ y: child.y ?? 0,
99
+ width: child.width ?? 0,
100
+ height: child.height ?? 0
101
+ };
102
+ nodes.push(node);
103
+ flattenElkNodes(child, child.id, nodes, edges, edgeIdx);
104
+ }
105
+ if (elkNode.edges) for (const elkEdge of elkNode.edges) for (const source of elkEdge.sources) for (const target of elkEdge.targets) {
106
+ const edge = {
107
+ type: "edge",
108
+ id: elkEdge.id ?? `e${edgeIdx.value++}`,
109
+ sourceId: source,
110
+ targetId: target,
111
+ label: elkEdge.labels?.[0]?.text ?? "",
112
+ data: void 0,
113
+ x: 0,
114
+ y: 0,
115
+ width: 0,
116
+ height: 0
117
+ };
118
+ edges.push(edge);
119
+ }
120
+ }
121
+ /**
122
+ * Parses an ELK JSON node into a visual graph.
123
+ *
124
+ * @example
125
+ * ```ts
126
+ * import { fromELK } from '@statelyai/graph/elk';
127
+ *
128
+ * const graph = fromELK({
129
+ * id: 'root',
130
+ * children: [
131
+ * { id: 'a', x: 0, y: 0, width: 100, height: 50 },
132
+ * { id: 'b', x: 200, y: 0, width: 100, height: 50 },
133
+ * ],
134
+ * edges: [{ id: 'e1', sources: ['a'], targets: ['b'] }],
135
+ * });
136
+ *
137
+ * graph.nodes; // [{id: 'a', x: 0, y: 0, ...}, {id: 'b', x: 200, ...}]
138
+ * graph.edges; // [{sourceId: 'a', targetId: 'b', ...}]
139
+ * ```
140
+ */
141
+ function fromELK(elkRoot) {
142
+ const nodes = [];
143
+ const edges = [];
144
+ flattenElkNodes(elkRoot, null, nodes, edges, { value: 0 });
145
+ const seenEdges = /* @__PURE__ */ new Map();
146
+ for (const edge of edges) if (!seenEdges.has(edge.id)) seenEdges.set(edge.id, edge);
147
+ const elkDir = elkRoot.layoutOptions?.["elk.direction"];
148
+ const direction = (elkDir ? ELK_TO_DIRECTION[elkDir] : void 0) ?? "down";
149
+ return {
150
+ id: elkRoot.id,
151
+ type: "directed",
152
+ initialNodeId: null,
153
+ nodes,
154
+ edges: [...seenEdges.values()],
155
+ data: void 0,
156
+ direction
157
+ };
158
+ }
159
+ /**
160
+ * Bidirectional converter for ELK JSON format.
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * import { elkConverter } from '@statelyai/graph/elk';
165
+ *
166
+ * const elk = elkConverter.to(graph);
167
+ * const roundTripped = elkConverter.from(elk);
168
+ * ```
169
+ */
170
+ const elkConverter = {
171
+ to: toELK,
172
+ from: fromELK
173
+ };
174
+
175
+ //#endregion
176
+ export { elkConverter, fromELK, toELK };
@@ -1,4 +1,4 @@
1
- import { c as Graph, f as GraphFormatConverter } from "../../types-Bq_fmLwW.mjs";
1
+ import { m as GraphFormatConverter, u as Graph } from "../../types-DF-HNw50.mjs";
2
2
 
3
3
  //#region src/formats/gexf/index.d.ts
4
4
  declare function toGEXF(graph: Graph): string;
@@ -1,4 +1,4 @@
1
- import { n as createFormatConverter } from "../../converter-C5DlzzHs.mjs";
1
+ import { n as createFormatConverter } from "../../converter-B5CUD0r9.mjs";
2
2
  import { XMLBuilder, XMLParser } from "fast-xml-parser";
3
3
 
4
4
  //#region src/formats/gexf/index.ts
@@ -1,4 +1,4 @@
1
- import { c as Graph, f as GraphFormatConverter } from "../../types-Bq_fmLwW.mjs";
1
+ import { m as GraphFormatConverter, u as Graph } from "../../types-DF-HNw50.mjs";
2
2
 
3
3
  //#region src/formats/gml/index.d.ts
4
4
 
@@ -1,4 +1,4 @@
1
- import { n as createFormatConverter } from "../../converter-C5DlzzHs.mjs";
1
+ import { n as createFormatConverter } from "../../converter-B5CUD0r9.mjs";
2
2
 
3
3
  //#region src/formats/gml/index.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { c as Graph, f as GraphFormatConverter } from "../../types-Bq_fmLwW.mjs";
1
+ import { m as GraphFormatConverter, u as Graph } from "../../types-DF-HNw50.mjs";
2
2
 
3
3
  //#region src/formats/graphml/index.d.ts
4
4
  declare function toGraphML(graph: Graph): string;