@statelyai/graph 0.3.0 → 0.4.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.
- package/README.md +12 -11
- package/dist/{adjacency-list-A4_Eiwj3.mjs → adjacency-list-Bv4tfiM3.mjs} +33 -0
- package/dist/{algorithms-DBU7nmIV.mjs → algorithms-CnTmuX9t.mjs} +682 -24
- package/dist/algorithms.d.mts +479 -10
- package/dist/algorithms.mjs +1 -1
- package/dist/converter-C5DlzzHs.mjs +67 -0
- package/dist/{edge-list-DuHMz8hf.mjs → edge-list-R1SUbHwe.mjs} +32 -0
- package/dist/formats/adjacency-list/index.d.mts +35 -1
- package/dist/formats/adjacency-list/index.mjs +1 -1
- package/dist/formats/converter/index.d.mts +37 -3
- package/dist/formats/converter/index.mjs +1 -1
- package/dist/formats/cytoscape/index.d.mts +50 -2
- package/dist/formats/cytoscape/index.mjs +53 -5
- package/dist/formats/d3/index.d.mts +48 -2
- package/dist/formats/d3/index.mjs +48 -2
- package/dist/formats/dot/index.d.mts +56 -2
- package/dist/formats/dot/index.mjs +55 -2
- package/dist/formats/edge-list/index.d.mts +34 -1
- package/dist/formats/edge-list/index.mjs +1 -1
- package/dist/formats/gexf/index.d.mts +1 -1
- package/dist/formats/gexf/index.mjs +5 -5
- package/dist/formats/gml/index.d.mts +58 -2
- package/dist/formats/gml/index.mjs +59 -4
- package/dist/formats/graphml/index.d.mts +1 -1
- package/dist/formats/graphml/index.mjs +2 -2
- package/dist/formats/jgf/index.d.mts +51 -2
- package/dist/formats/jgf/index.mjs +54 -5
- package/dist/formats/mermaid/index.d.mts +201 -8
- package/dist/formats/mermaid/index.mjs +365 -26
- package/dist/formats/tgf/index.d.mts +47 -2
- package/dist/formats/tgf/index.mjs +46 -2
- package/dist/formats/xyflow/index.d.mts +73 -0
- package/dist/formats/xyflow/index.mjs +133 -0
- package/dist/index.d.mts +320 -14
- package/dist/index.mjs +117 -9
- package/dist/{indexing-BFFVMnjF.mjs → indexing-DitHphT7.mjs} +37 -7
- package/dist/queries.d.mts +353 -8
- package/dist/queries.mjs +359 -15
- package/dist/{types-B6Tpeerk.d.mts → types-Bq_fmLwW.d.mts} +15 -4
- package/package.json +3 -1
- package/dist/converter-DnbeyE_p.mjs +0 -33
package/dist/algorithms.d.mts
CHANGED
|
@@ -1,81 +1,531 @@
|
|
|
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-
|
|
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";
|
|
2
2
|
|
|
3
3
|
//#region src/algorithms.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Breadth-first traversal generator yielding nodes level by level.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { createGraph, bfs } from '@statelyai/graph';
|
|
11
|
+
*
|
|
12
|
+
* const graph = createGraph({
|
|
13
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
14
|
+
* edges: [{ id: 'ab', sourceId: 'a', targetId: 'b' }, { id: 'bc', sourceId: 'b', targetId: 'c' }],
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* for (const node of bfs(graph, 'a')) {
|
|
18
|
+
* console.log(node.id); // 'a', 'b', 'c'
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
4
22
|
declare function bfs<N>(graph: Graph<N>, startId: string): Generator<GraphNode<N>>;
|
|
23
|
+
/**
|
|
24
|
+
* Depth-first traversal generator yielding nodes as visited.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { createGraph, dfs } from '@statelyai/graph';
|
|
29
|
+
*
|
|
30
|
+
* const graph = createGraph({
|
|
31
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
32
|
+
* edges: [{ id: 'ab', sourceId: 'a', targetId: 'b' }, { id: 'bc', sourceId: 'b', targetId: 'c' }],
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* for (const node of dfs(graph, 'a')) {
|
|
36
|
+
* console.log(node.id); // 'a', 'b', 'c'
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
5
40
|
declare function dfs<N>(graph: Graph<N>, startId: string): Generator<GraphNode<N>>;
|
|
41
|
+
/**
|
|
42
|
+
* Checks whether the graph contains no cycles.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* import { createGraph, isAcyclic } from '@statelyai/graph';
|
|
47
|
+
*
|
|
48
|
+
* const dag = createGraph({
|
|
49
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
50
|
+
* edges: [{ id: 'ab', sourceId: 'a', targetId: 'b' }],
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* isAcyclic(dag); // true
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
6
56
|
declare function isAcyclic(graph: Graph): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Returns connected components as arrays of nodes.
|
|
59
|
+
* Treats all edges as undirected for connectivity.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { createGraph, getConnectedComponents } from '@statelyai/graph';
|
|
64
|
+
*
|
|
65
|
+
* const graph = createGraph({
|
|
66
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
67
|
+
* edges: [{ id: 'ab', sourceId: 'a', targetId: 'b' }],
|
|
68
|
+
* });
|
|
69
|
+
*
|
|
70
|
+
* const components = getConnectedComponents(graph);
|
|
71
|
+
* // [[nodeA, nodeB], [nodeC]]
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
7
74
|
declare function getConnectedComponents<N>(graph: Graph<N>): GraphNode<N>[][];
|
|
75
|
+
/**
|
|
76
|
+
* Returns a topological ordering of nodes, or `null` if the graph is cyclic.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* import { createGraph, getTopologicalSort } from '@statelyai/graph';
|
|
81
|
+
*
|
|
82
|
+
* const graph = createGraph({
|
|
83
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
84
|
+
* edges: [
|
|
85
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
86
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c' },
|
|
87
|
+
* ],
|
|
88
|
+
* });
|
|
89
|
+
*
|
|
90
|
+
* const sorted = getTopologicalSort(graph);
|
|
91
|
+
* // [nodeA, nodeB, nodeC]
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
8
94
|
declare function getTopologicalSort<N>(graph: Graph<N>): GraphNode<N>[] | null;
|
|
95
|
+
/**
|
|
96
|
+
* Checks whether a path exists between two nodes.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* import { createGraph, hasPath } from '@statelyai/graph';
|
|
101
|
+
*
|
|
102
|
+
* const graph = createGraph({
|
|
103
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
104
|
+
* edges: [{ id: 'ab', sourceId: 'a', targetId: 'b' }],
|
|
105
|
+
* });
|
|
106
|
+
*
|
|
107
|
+
* hasPath(graph, 'a', 'b'); // true
|
|
108
|
+
* hasPath(graph, 'a', 'c'); // false
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
9
111
|
declare function hasPath(graph: Graph, sourceId: string, targetId: string): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Checks whether the graph is connected (all nodes reachable from any node).
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* import { createGraph, isConnected } from '@statelyai/graph';
|
|
118
|
+
*
|
|
119
|
+
* const graph = createGraph({
|
|
120
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
121
|
+
* edges: [{ id: 'ab', sourceId: 'a', targetId: 'b' }],
|
|
122
|
+
* });
|
|
123
|
+
*
|
|
124
|
+
* isConnected(graph); // true
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
10
127
|
declare function isConnected(graph: Graph): boolean;
|
|
128
|
+
/**
|
|
129
|
+
* Checks whether the graph is a tree (connected and acyclic).
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* import { createGraph, isTree } from '@statelyai/graph';
|
|
134
|
+
*
|
|
135
|
+
* const tree = createGraph({
|
|
136
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
137
|
+
* edges: [
|
|
138
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
139
|
+
* { id: 'ac', sourceId: 'a', targetId: 'c' },
|
|
140
|
+
* ],
|
|
141
|
+
* });
|
|
142
|
+
*
|
|
143
|
+
* isTree(tree); // true
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
11
146
|
declare function isTree(graph: Graph): boolean;
|
|
12
147
|
/**
|
|
13
148
|
* Lazily yields all shortest paths from a source node.
|
|
14
149
|
* Use `getShortestPaths` for the full array.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* import { createGraph, genShortestPaths } from '@statelyai/graph';
|
|
154
|
+
*
|
|
155
|
+
* const graph = createGraph({
|
|
156
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
157
|
+
* edges: [
|
|
158
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
159
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c' },
|
|
160
|
+
* ],
|
|
161
|
+
* initialNodeId: 'a',
|
|
162
|
+
* });
|
|
163
|
+
*
|
|
164
|
+
* for (const path of genShortestPaths(graph)) {
|
|
165
|
+
* console.log(path.steps.map(s => s.node.id));
|
|
166
|
+
* }
|
|
167
|
+
* ```
|
|
15
168
|
*/
|
|
16
169
|
declare function genShortestPaths<N, E>(graph: Graph<N, E>, opts?: PathOptions<E>): Generator<GraphPath<N, E>>;
|
|
170
|
+
/**
|
|
171
|
+
* Returns all shortest paths from a source node as an array.
|
|
172
|
+
* Delegates to `genShortestPaths` internally.
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```ts
|
|
176
|
+
* import { createGraph, getShortestPaths } from '@statelyai/graph';
|
|
177
|
+
*
|
|
178
|
+
* const graph = createGraph({
|
|
179
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
180
|
+
* edges: [
|
|
181
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
182
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c' },
|
|
183
|
+
* ],
|
|
184
|
+
* initialNodeId: 'a',
|
|
185
|
+
* });
|
|
186
|
+
*
|
|
187
|
+
* const paths = getShortestPaths(graph);
|
|
188
|
+
* // paths to 'b' and 'c' from 'a'
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
17
191
|
declare function getShortestPaths<N, E>(graph: Graph<N, E>, opts?: PathOptions<E>): GraphPath<N, E>[];
|
|
18
192
|
/**
|
|
19
|
-
* Returns a single shortest path from source to target, or undefined if unreachable.
|
|
193
|
+
* Returns a single shortest path from source to target, or `undefined` if unreachable.
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```ts
|
|
197
|
+
* import { createGraph, getShortestPath } from '@statelyai/graph';
|
|
198
|
+
*
|
|
199
|
+
* const graph = createGraph({
|
|
200
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
201
|
+
* edges: [
|
|
202
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
203
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c' },
|
|
204
|
+
* ],
|
|
205
|
+
* initialNodeId: 'a',
|
|
206
|
+
* });
|
|
207
|
+
*
|
|
208
|
+
* const path = getShortestPath(graph, { to: 'c' });
|
|
209
|
+
* // path.steps -> [{node: nodeB, edge: ...}, {node: nodeC, edge: ...}]
|
|
210
|
+
* ```
|
|
20
211
|
*/
|
|
21
212
|
declare function getShortestPath<N, E>(graph: Graph<N, E>, opts: SinglePathOptions<E>): GraphPath<N, E> | undefined;
|
|
22
213
|
/**
|
|
23
|
-
* Returns all simple (acyclic) paths from a source node.
|
|
24
|
-
*
|
|
214
|
+
* Returns all simple (acyclic) paths from a source node as an array.
|
|
215
|
+
* Delegates to `genSimplePaths` internally.
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```ts
|
|
219
|
+
* import { createGraph, getSimplePaths } from '@statelyai/graph';
|
|
220
|
+
*
|
|
221
|
+
* const graph = createGraph({
|
|
222
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
223
|
+
* edges: [
|
|
224
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
225
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c' },
|
|
226
|
+
* { id: 'ac', sourceId: 'a', targetId: 'c' },
|
|
227
|
+
* ],
|
|
228
|
+
* initialNodeId: 'a',
|
|
229
|
+
* });
|
|
230
|
+
*
|
|
231
|
+
* const paths = getSimplePaths(graph, { to: 'c' });
|
|
232
|
+
* // two paths: a->b->c and a->c
|
|
233
|
+
* ```
|
|
25
234
|
*/
|
|
26
235
|
declare function getSimplePaths<N, E>(graph: Graph<N, E>, opts?: PathOptions<E>): GraphPath<N, E>[];
|
|
27
236
|
/**
|
|
28
|
-
* Lazily yields all simple (acyclic) paths from a source node.
|
|
237
|
+
* Lazily yields all simple (acyclic) paths from a source node via DFS backtracking.
|
|
29
238
|
* Use `getSimplePaths` for the full array.
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```ts
|
|
242
|
+
* import { createGraph, genSimplePaths } from '@statelyai/graph';
|
|
243
|
+
*
|
|
244
|
+
* const graph = createGraph({
|
|
245
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
246
|
+
* edges: [
|
|
247
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
248
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c' },
|
|
249
|
+
* { id: 'ac', sourceId: 'a', targetId: 'c' },
|
|
250
|
+
* ],
|
|
251
|
+
* initialNodeId: 'a',
|
|
252
|
+
* });
|
|
253
|
+
*
|
|
254
|
+
* for (const path of genSimplePaths(graph, { to: 'c' })) {
|
|
255
|
+
* console.log(path.steps.map(s => s.node.id));
|
|
256
|
+
* // ['b', 'c'] or ['c']
|
|
257
|
+
* }
|
|
258
|
+
* ```
|
|
30
259
|
*/
|
|
31
260
|
declare function genSimplePaths<N, E>(graph: Graph<N, E>, opts?: PathOptions<E>): Generator<GraphPath<N, E>>;
|
|
32
261
|
/**
|
|
33
|
-
* Returns a single simple (acyclic) path from source to target, or undefined if unreachable.
|
|
262
|
+
* Returns a single simple (acyclic) path from source to target, or `undefined` if unreachable.
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```ts
|
|
266
|
+
* import { createGraph, getSimplePath } from '@statelyai/graph';
|
|
267
|
+
*
|
|
268
|
+
* const graph = createGraph({
|
|
269
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
270
|
+
* edges: [
|
|
271
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
272
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c' },
|
|
273
|
+
* ],
|
|
274
|
+
* initialNodeId: 'a',
|
|
275
|
+
* });
|
|
276
|
+
*
|
|
277
|
+
* const path = getSimplePath(graph, { to: 'c' });
|
|
278
|
+
* // path.steps -> [{node: nodeB, edge: ...}, {node: nodeC, edge: ...}]
|
|
279
|
+
* ```
|
|
34
280
|
*/
|
|
35
281
|
declare function getSimplePath<N, E>(graph: Graph<N, E>, opts: SinglePathOptions<E>): GraphPath<N, E> | undefined;
|
|
282
|
+
/**
|
|
283
|
+
* Returns strongly connected components using Tarjan's algorithm.
|
|
284
|
+
* Only meaningful for directed graphs.
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```ts
|
|
288
|
+
* import { createGraph, getStronglyConnectedComponents } from '@statelyai/graph';
|
|
289
|
+
*
|
|
290
|
+
* const graph = createGraph({
|
|
291
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
292
|
+
* edges: [
|
|
293
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
294
|
+
* { id: 'ba', sourceId: 'b', targetId: 'a' },
|
|
295
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c' },
|
|
296
|
+
* ],
|
|
297
|
+
* });
|
|
298
|
+
*
|
|
299
|
+
* const sccs = getStronglyConnectedComponents(graph);
|
|
300
|
+
* // [[nodeA, nodeB], [nodeC]]
|
|
301
|
+
* ```
|
|
302
|
+
*/
|
|
36
303
|
declare function getStronglyConnectedComponents<N>(graph: Graph<N>): GraphNode<N>[][];
|
|
304
|
+
/**
|
|
305
|
+
* Returns all elementary cycles as an array of paths.
|
|
306
|
+
* Delegates to `genCycles` internally.
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* ```ts
|
|
310
|
+
* import { createGraph, getCycles } from '@statelyai/graph';
|
|
311
|
+
*
|
|
312
|
+
* const graph = createGraph({
|
|
313
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
314
|
+
* edges: [
|
|
315
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
316
|
+
* { id: 'ba', sourceId: 'b', targetId: 'a' },
|
|
317
|
+
* ],
|
|
318
|
+
* });
|
|
319
|
+
*
|
|
320
|
+
* const cycles = getCycles(graph);
|
|
321
|
+
* // one cycle: a -> b -> a
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
37
324
|
declare function getCycles<N, E>(graph: Graph<N, E>): GraphPath<N, E>[];
|
|
38
325
|
/**
|
|
39
|
-
* Lazily yields cycles one at a time.
|
|
326
|
+
* Lazily yields elementary cycles one at a time.
|
|
40
327
|
* Use `getCycles` for the full array.
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```ts
|
|
331
|
+
* import { createGraph, genCycles } from '@statelyai/graph';
|
|
332
|
+
*
|
|
333
|
+
* const graph = createGraph({
|
|
334
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
335
|
+
* edges: [
|
|
336
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
337
|
+
* { id: 'ba', sourceId: 'b', targetId: 'a' },
|
|
338
|
+
* ],
|
|
339
|
+
* });
|
|
340
|
+
*
|
|
341
|
+
* for (const cycle of genCycles(graph)) {
|
|
342
|
+
* console.log(cycle.steps.map(s => s.node.id)); // ['b', 'a']
|
|
343
|
+
* }
|
|
344
|
+
* ```
|
|
41
345
|
*/
|
|
42
346
|
declare function genCycles<N, E>(graph: Graph<N, E>): Generator<GraphPath<N, E>>;
|
|
43
347
|
/**
|
|
44
348
|
* Returns a single canonical preorder (DFS visit-order) sequence.
|
|
45
349
|
* Visits neighbors in the order they appear in the adjacency list.
|
|
350
|
+
*
|
|
351
|
+
* @example
|
|
352
|
+
* ```ts
|
|
353
|
+
* import { createGraph, getPreorder } from '@statelyai/graph';
|
|
354
|
+
*
|
|
355
|
+
* const graph = createGraph({
|
|
356
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
357
|
+
* edges: [
|
|
358
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
359
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c' },
|
|
360
|
+
* ],
|
|
361
|
+
* initialNodeId: 'a',
|
|
362
|
+
* });
|
|
363
|
+
*
|
|
364
|
+
* const order = getPreorder(graph);
|
|
365
|
+
* // [nodeA, nodeB, nodeC]
|
|
366
|
+
* ```
|
|
46
367
|
*/
|
|
47
368
|
declare function getPreorder<N>(graph: Graph<N>, opts?: TraversalOptions): GraphNode<N>[];
|
|
48
369
|
/**
|
|
49
370
|
* Returns a single canonical postorder (DFS finish-order) sequence.
|
|
50
371
|
* Visits neighbors in the order they appear in the adjacency list.
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```ts
|
|
375
|
+
* import { createGraph, getPostorder } from '@statelyai/graph';
|
|
376
|
+
*
|
|
377
|
+
* const graph = createGraph({
|
|
378
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
379
|
+
* edges: [
|
|
380
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
381
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c' },
|
|
382
|
+
* ],
|
|
383
|
+
* initialNodeId: 'a',
|
|
384
|
+
* });
|
|
385
|
+
*
|
|
386
|
+
* const order = getPostorder(graph);
|
|
387
|
+
* // [nodeC, nodeB, nodeA]
|
|
388
|
+
* ```
|
|
51
389
|
*/
|
|
52
390
|
declare function getPostorder<N>(graph: Graph<N>, opts?: TraversalOptions): GraphNode<N>[];
|
|
53
|
-
/**
|
|
391
|
+
/**
|
|
392
|
+
* Returns all possible preorder sequences as an array. Can be exponential -- prefer `genPreorders`.
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* ```ts
|
|
396
|
+
* import { createGraph, getPreorders } from '@statelyai/graph';
|
|
397
|
+
*
|
|
398
|
+
* const graph = createGraph({
|
|
399
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
400
|
+
* edges: [
|
|
401
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
402
|
+
* { id: 'ac', sourceId: 'a', targetId: 'c' },
|
|
403
|
+
* ],
|
|
404
|
+
* initialNodeId: 'a',
|
|
405
|
+
* });
|
|
406
|
+
*
|
|
407
|
+
* const allOrders = getPreorders(graph);
|
|
408
|
+
* // [[nodeA, nodeB, nodeC], [nodeA, nodeC, nodeB]]
|
|
409
|
+
* ```
|
|
410
|
+
*/
|
|
54
411
|
declare function getPreorders<N>(graph: Graph<N>, opts?: TraversalOptions): GraphNode<N>[][];
|
|
55
|
-
/**
|
|
412
|
+
/**
|
|
413
|
+
* Returns all possible postorder sequences as an array. Can be exponential -- prefer `genPostorders`.
|
|
414
|
+
*
|
|
415
|
+
* @example
|
|
416
|
+
* ```ts
|
|
417
|
+
* import { createGraph, getPostorders } from '@statelyai/graph';
|
|
418
|
+
*
|
|
419
|
+
* const graph = createGraph({
|
|
420
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
421
|
+
* edges: [
|
|
422
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
423
|
+
* { id: 'ac', sourceId: 'a', targetId: 'c' },
|
|
424
|
+
* ],
|
|
425
|
+
* initialNodeId: 'a',
|
|
426
|
+
* });
|
|
427
|
+
*
|
|
428
|
+
* const allOrders = getPostorders(graph);
|
|
429
|
+
* // [[nodeB, nodeC, nodeA], [nodeC, nodeB, nodeA]]
|
|
430
|
+
* ```
|
|
431
|
+
*/
|
|
56
432
|
declare function getPostorders<N>(graph: Graph<N>, opts?: TraversalOptions): GraphNode<N>[][];
|
|
57
433
|
/**
|
|
58
434
|
* Lazily yields all possible preorder (DFS visit-order) sequences.
|
|
59
435
|
* Different neighbor exploration orders yield different sequences.
|
|
60
436
|
* Use `getPreorder()` for a single canonical ordering.
|
|
437
|
+
*
|
|
438
|
+
* @example
|
|
439
|
+
* ```ts
|
|
440
|
+
* import { createGraph, genPreorders } from '@statelyai/graph';
|
|
441
|
+
*
|
|
442
|
+
* const graph = createGraph({
|
|
443
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
444
|
+
* edges: [
|
|
445
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
446
|
+
* { id: 'ac', sourceId: 'a', targetId: 'c' },
|
|
447
|
+
* ],
|
|
448
|
+
* initialNodeId: 'a',
|
|
449
|
+
* });
|
|
450
|
+
*
|
|
451
|
+
* for (const order of genPreorders(graph)) {
|
|
452
|
+
* console.log(order.map(n => n.id));
|
|
453
|
+
* // ['a', 'b', 'c'] or ['a', 'c', 'b']
|
|
454
|
+
* }
|
|
455
|
+
* ```
|
|
61
456
|
*/
|
|
62
457
|
declare function genPreorders<N>(graph: Graph<N>, opts?: TraversalOptions): Generator<GraphNode<N>[]>;
|
|
63
458
|
/**
|
|
64
459
|
* Lazily yields all possible postorder (DFS finish-order) sequences.
|
|
65
460
|
* Different neighbor exploration orders yield different sequences.
|
|
66
461
|
* Use `getPostorder()` for a single canonical ordering.
|
|
462
|
+
*
|
|
463
|
+
* @example
|
|
464
|
+
* ```ts
|
|
465
|
+
* import { createGraph, genPostorders } from '@statelyai/graph';
|
|
466
|
+
*
|
|
467
|
+
* const graph = createGraph({
|
|
468
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
469
|
+
* edges: [
|
|
470
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
471
|
+
* { id: 'ac', sourceId: 'a', targetId: 'c' },
|
|
472
|
+
* ],
|
|
473
|
+
* initialNodeId: 'a',
|
|
474
|
+
* });
|
|
475
|
+
*
|
|
476
|
+
* for (const order of genPostorders(graph)) {
|
|
477
|
+
* console.log(order.map(n => n.id));
|
|
478
|
+
* // ['b', 'c', 'a'] or ['c', 'b', 'a']
|
|
479
|
+
* }
|
|
480
|
+
* ```
|
|
67
481
|
*/
|
|
68
482
|
declare function genPostorders<N>(graph: Graph<N>, opts?: TraversalOptions): Generator<GraphNode<N>[]>;
|
|
69
483
|
/**
|
|
70
484
|
* Returns a minimum spanning tree of the graph.
|
|
71
485
|
* Only meaningful for connected undirected graphs (or the component reachable
|
|
72
486
|
* from an arbitrary start node in directed graphs).
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* ```ts
|
|
490
|
+
* import { createGraph, getMinimumSpanningTree } from '@statelyai/graph';
|
|
491
|
+
*
|
|
492
|
+
* const graph = createGraph({
|
|
493
|
+
* type: 'undirected',
|
|
494
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
495
|
+
* edges: [
|
|
496
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b', data: { weight: 1 } },
|
|
497
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c', data: { weight: 2 } },
|
|
498
|
+
* { id: 'ac', sourceId: 'a', targetId: 'c', data: { weight: 3 } },
|
|
499
|
+
* ],
|
|
500
|
+
* });
|
|
501
|
+
*
|
|
502
|
+
* const mst = getMinimumSpanningTree(graph, {
|
|
503
|
+
* getWeight: (e) => e.data.weight,
|
|
504
|
+
* });
|
|
505
|
+
* // mst has edges 'ab' and 'bc' (total weight 3)
|
|
506
|
+
* ```
|
|
73
507
|
*/
|
|
74
508
|
declare function getMinimumSpanningTree<N, E>(graph: Graph<N, E>, opts?: MSTOptions<E>): Graph<N, E>;
|
|
75
509
|
/**
|
|
76
510
|
* Returns shortest paths between all pairs of nodes.
|
|
77
511
|
* Algorithm 'dijkstra' (default): runs getShortestPaths per source node.
|
|
78
|
-
* Algorithm 'floyd-warshall': classic O(V
|
|
512
|
+
* Algorithm 'floyd-warshall': classic O(V^3) dynamic programming.
|
|
513
|
+
*
|
|
514
|
+
* @example
|
|
515
|
+
* ```ts
|
|
516
|
+
* import { createGraph, getAllPairsShortestPaths } from '@statelyai/graph';
|
|
517
|
+
*
|
|
518
|
+
* const graph = createGraph({
|
|
519
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
520
|
+
* edges: [
|
|
521
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
522
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c' },
|
|
523
|
+
* ],
|
|
524
|
+
* });
|
|
525
|
+
*
|
|
526
|
+
* const allPaths = getAllPairsShortestPaths(graph);
|
|
527
|
+
* // paths for every reachable (source, target) pair
|
|
528
|
+
* ```
|
|
79
529
|
*/
|
|
80
530
|
declare function getAllPairsShortestPaths<N, E>(graph: Graph<N, E>, opts?: AllPairsShortestPathsOptions<E>): GraphPath<N, E>[];
|
|
81
531
|
/**
|
|
@@ -84,6 +534,25 @@ declare function getAllPairsShortestPaths<N, E>(graph: Graph<N, E>, opts?: AllPa
|
|
|
84
534
|
*
|
|
85
535
|
* Steps are concatenated: head.steps ++ tail.steps (tail already starts
|
|
86
536
|
* from the overlap node, so no slicing is needed).
|
|
537
|
+
*
|
|
538
|
+
* @example
|
|
539
|
+
* ```ts
|
|
540
|
+
* import { createGraph, getShortestPath, joinPaths } from '@statelyai/graph';
|
|
541
|
+
*
|
|
542
|
+
* const graph = createGraph({
|
|
543
|
+
* nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
544
|
+
* edges: [
|
|
545
|
+
* { id: 'ab', sourceId: 'a', targetId: 'b' },
|
|
546
|
+
* { id: 'bc', sourceId: 'b', targetId: 'c' },
|
|
547
|
+
* ],
|
|
548
|
+
* initialNodeId: 'a',
|
|
549
|
+
* });
|
|
550
|
+
*
|
|
551
|
+
* const ab = getShortestPath(graph, { to: 'b' })!;
|
|
552
|
+
* const bc = getShortestPath(graph, { from: 'b', to: 'c' })!;
|
|
553
|
+
* const ac = joinPaths(ab, bc);
|
|
554
|
+
* // ac: a -> b -> c
|
|
555
|
+
* ```
|
|
87
556
|
*/
|
|
88
557
|
declare function joinPaths<N, E>(headPath: GraphPath<N, E>, tailPath: GraphPath<N, E>): GraphPath<N, E>;
|
|
89
558
|
//#endregion
|
package/dist/algorithms.mjs
CHANGED
|
@@ -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-
|
|
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";
|
|
2
2
|
|
|
3
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 };
|
|
@@ -0,0 +1,67 @@
|
|
|
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";
|
|
3
|
+
|
|
4
|
+
//#region src/formats/converter/index.ts
|
|
5
|
+
/**
|
|
6
|
+
* Create a `GraphFormatConverter` from a pair of `to`/`from` functions.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { createFormatConverter } from '@statelyai/graph';
|
|
11
|
+
*
|
|
12
|
+
* const yamlConverter = createFormatConverter(
|
|
13
|
+
* (graph) => toYAML(graph),
|
|
14
|
+
* (yaml) => fromYAML(yaml),
|
|
15
|
+
* );
|
|
16
|
+
*
|
|
17
|
+
* const yaml = yamlConverter.to(graph);
|
|
18
|
+
* const graph = yamlConverter.from(yaml);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
function createFormatConverter(to, from) {
|
|
22
|
+
return {
|
|
23
|
+
to,
|
|
24
|
+
from
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Bidirectional converter for adjacency-list format (`Record<string, string[]>`).
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { adjacencyListConverter, createGraph } from '@statelyai/graph';
|
|
33
|
+
*
|
|
34
|
+
* const graph = createGraph({
|
|
35
|
+
* nodes: { a: {}, b: {} },
|
|
36
|
+
* edges: [{ source: 'a', target: 'b' }],
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* const adj = adjacencyListConverter.to(graph);
|
|
40
|
+
* // { a: ['b'], b: [] }
|
|
41
|
+
*
|
|
42
|
+
* const roundTripped = adjacencyListConverter.from(adj);
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
const adjacencyListConverter = createFormatConverter(toAdjacencyList, fromAdjacencyList);
|
|
46
|
+
/**
|
|
47
|
+
* Bidirectional converter for edge-list format (`[source, target][]`).
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { edgeListConverter, createGraph } from '@statelyai/graph';
|
|
52
|
+
*
|
|
53
|
+
* const graph = createGraph({
|
|
54
|
+
* nodes: { a: {}, b: {} },
|
|
55
|
+
* edges: [{ source: 'a', target: 'b' }],
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* const edges = edgeListConverter.to(graph);
|
|
59
|
+
* // [['a', 'b']]
|
|
60
|
+
*
|
|
61
|
+
* const roundTripped = edgeListConverter.from(edges);
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
const edgeListConverter = createFormatConverter(toEdgeList, fromEdgeList);
|
|
65
|
+
|
|
66
|
+
//#endregion
|
|
67
|
+
export { createFormatConverter as n, edgeListConverter as r, adjacencyListConverter as t };
|
|
@@ -1,7 +1,39 @@
|
|
|
1
1
|
//#region src/formats/edge-list/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* Converts a graph to an edge list of `[source, target]` tuples.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { createGraph, toEdgeList } from '@statelyai/graph';
|
|
8
|
+
*
|
|
9
|
+
* const graph = createGraph({
|
|
10
|
+
* nodes: { a: {}, b: {}, c: {} },
|
|
11
|
+
* edges: [{ source: 'a', target: 'b' }, { source: 'b', target: 'c' }],
|
|
12
|
+
* });
|
|
13
|
+
*
|
|
14
|
+
* toEdgeList(graph);
|
|
15
|
+
* // [['a', 'b'], ['b', 'c']]
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
2
18
|
function toEdgeList(graph) {
|
|
3
19
|
return graph.edges.map((e) => [e.sourceId, e.targetId]);
|
|
4
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Parses an edge list of `[source, target]` tuples into a graph.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { fromEdgeList } from '@statelyai/graph';
|
|
27
|
+
*
|
|
28
|
+
* const graph = fromEdgeList([
|
|
29
|
+
* ['a', 'b'],
|
|
30
|
+
* ['b', 'c'],
|
|
31
|
+
* ]);
|
|
32
|
+
*
|
|
33
|
+
* graph.nodes; // [{id: 'a', ...}, {id: 'b', ...}, {id: 'c', ...}]
|
|
34
|
+
* graph.edges; // [{sourceId: 'a', targetId: 'b', ...}, ...]
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
5
37
|
function fromEdgeList(edges, options) {
|
|
6
38
|
const directed = options?.directed ?? true;
|
|
7
39
|
const nodeIds = /* @__PURE__ */ new Set();
|