@statelyai/graph 0.3.0 → 0.3.1
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/dist/{adjacency-list-A4_Eiwj3.mjs → adjacency-list-ITO40kmn.mjs} +33 -0
- package/dist/{algorithms-DBU7nmIV.mjs → algorithms-NWSB2RWj.mjs} +672 -19
- package/dist/algorithms.d.mts +479 -10
- package/dist/algorithms.mjs +1 -1
- package/dist/converter-CchokMDg.mjs +67 -0
- package/dist/{edge-list-DuHMz8hf.mjs → edge-list-CgX6bBIF.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 +50 -2
- 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 +1 -1
- package/dist/formats/gml/index.d.mts +58 -2
- package/dist/formats/gml/index.mjs +57 -2
- package/dist/formats/graphml/index.d.mts +1 -1
- package/dist/formats/graphml/index.mjs +1 -1
- package/dist/formats/jgf/index.d.mts +51 -2
- package/dist/formats/jgf/index.mjs +51 -2
- package/dist/formats/mermaid/index.d.mts +201 -8
- package/dist/formats/mermaid/index.mjs +361 -22
- package/dist/formats/tgf/index.d.mts +47 -2
- package/dist/formats/tgf/index.mjs +46 -2
- package/dist/index.d.mts +320 -14
- package/dist/index.mjs +115 -7
- package/dist/{indexing-BFFVMnjF.mjs → indexing-eNDrXdDA.mjs} +31 -2
- package/dist/queries.d.mts +353 -8
- package/dist/queries.mjs +352 -8
- package/dist/{types-B6Tpeerk.d.mts → types-BDXC1O5b.d.mts} +1 -1
- package/package.json +1 -1
- package/dist/converter-DnbeyE_p.mjs +0 -33
package/dist/index.d.mts
CHANGED
|
@@ -1,38 +1,135 @@
|
|
|
1
|
-
import { C as TraversalOptions, D as VisualNode, E as VisualGraphConfig, 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-
|
|
1
|
+
import { C as TraversalOptions, D as VisualNode, E as VisualGraphConfig, 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-BDXC1O5b.mjs";
|
|
2
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";
|
|
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
|
|
|
6
6
|
//#region src/graph.d.ts
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Create a graph from a config. Resolves defaults for all fields.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const graph = createGraph({
|
|
14
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
15
|
+
* edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }],
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
8
19
|
declare function createGraph<N = any, E = any, G = any>(config?: GraphConfig<N, E, G>): Graph<N, E, G>;
|
|
9
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Create a visual graph with required position/size on all nodes and edges.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const graph = createVisualGraph({
|
|
26
|
+
* nodes: [{ id: 'a', x: 0, y: 0, width: 100, height: 50 }],
|
|
27
|
+
* edges: [{ id: 'e1', sourceId: 'a', targetId: 'a', x: 0, y: 0, width: 0, height: 0 }],
|
|
28
|
+
* });
|
|
29
|
+
* // graph.nodes[0].x === 0
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
10
32
|
declare function createVisualGraph<N = any, E = any, G = any>(config?: VisualGraphConfig<N, E, G>): VisualGraph<N, E, G>;
|
|
11
33
|
/**
|
|
12
34
|
* Create a graph by BFS exploration of a transition function.
|
|
13
|
-
* Each unique state becomes a node; each (state, event)
|
|
35
|
+
* Each unique state becomes a node; each (state, event) -> nextState becomes an edge.
|
|
14
36
|
*
|
|
15
37
|
* - Node IDs are determined by `serializeState` (default: `JSON.stringify`).
|
|
16
38
|
* - Edge IDs use the format `sourceId|serializedEvent|targetId` for uniqueness
|
|
17
39
|
* and debuggability. Edge labels are just the serialized event string.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* const graph = createGraphFromTransition(
|
|
44
|
+
* (state, event) => {
|
|
45
|
+
* if (state === 'green' && event === 'TIMER') return 'yellow';
|
|
46
|
+
* if (state === 'yellow' && event === 'TIMER') return 'red';
|
|
47
|
+
* if (state === 'red' && event === 'TIMER') return 'green';
|
|
48
|
+
* return state;
|
|
49
|
+
* },
|
|
50
|
+
* {
|
|
51
|
+
* initialState: 'green',
|
|
52
|
+
* events: ['TIMER'],
|
|
53
|
+
* serializeState: (s) => s,
|
|
54
|
+
* serializeEvent: (e) => e,
|
|
55
|
+
* },
|
|
56
|
+
* );
|
|
57
|
+
* // graph.nodes.length === 3
|
|
58
|
+
* ```
|
|
18
59
|
*/
|
|
19
60
|
declare function createGraphFromTransition<TState, TEvent>(transition: (state: TState, event: TEvent) => TState, options: TransitionOptions<TState, TEvent>): Graph<TState, TEvent>;
|
|
20
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* Get a node by id, or `undefined` if not found.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* const graph = createGraph({ nodes: [{ id: 'a' }] });
|
|
67
|
+
* const node = getNode(graph, 'a'); // GraphNode
|
|
68
|
+
* const missing = getNode(graph, 'z'); // undefined
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
21
71
|
declare function getNode<N>(graph: Graph<N>, id: string): GraphNode<N> | undefined;
|
|
22
|
-
/**
|
|
72
|
+
/**
|
|
73
|
+
* Get an edge by id, or `undefined` if not found.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* const graph = createGraph({
|
|
78
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
79
|
+
* edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }],
|
|
80
|
+
* });
|
|
81
|
+
* const edge = getEdge(graph, 'e1'); // GraphEdge
|
|
82
|
+
* const missing = getEdge(graph, 'z'); // undefined
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
23
85
|
declare function getEdge<E>(graph: Graph<any, E>, id: string): GraphEdge<E> | undefined;
|
|
24
|
-
/**
|
|
86
|
+
/**
|
|
87
|
+
* Check if a node exists in the graph.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* const graph = createGraph({ nodes: [{ id: 'a' }] });
|
|
92
|
+
* hasNode(graph, 'a'); // true
|
|
93
|
+
* hasNode(graph, 'z'); // false
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
25
96
|
declare function hasNode(graph: Graph, id: string): boolean;
|
|
26
|
-
/**
|
|
97
|
+
/**
|
|
98
|
+
* Check if an edge exists in the graph.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* const graph = createGraph({
|
|
103
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
104
|
+
* edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }],
|
|
105
|
+
* });
|
|
106
|
+
* hasEdge(graph, 'e1'); // true
|
|
107
|
+
* hasEdge(graph, 'z'); // false
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
27
110
|
declare function hasEdge(graph: Graph, id: string): boolean;
|
|
28
111
|
/**
|
|
29
112
|
* **Mutable.** Add a node to the graph. Mutates `graph.nodes` in place.
|
|
30
113
|
* @returns The resolved node that was added.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* const graph = createGraph();
|
|
118
|
+
* const node = addNode(graph, { id: 'a', label: 'Node A' });
|
|
119
|
+
* // graph.nodes.length === 1
|
|
120
|
+
* ```
|
|
31
121
|
*/
|
|
32
122
|
declare function addNode<N>(graph: Graph<N>, config: NodeConfig<N>): GraphNode<N>;
|
|
33
123
|
/**
|
|
34
124
|
* **Mutable.** Add an edge to the graph. Mutates `graph.edges` in place.
|
|
35
125
|
* @returns The resolved edge that was added.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```ts
|
|
129
|
+
* const graph = createGraph({ nodes: [{ id: 'a' }, { id: 'b' }] });
|
|
130
|
+
* const edge = addEdge(graph, { id: 'e1', sourceId: 'a', targetId: 'b' });
|
|
131
|
+
* // graph.edges.length === 1
|
|
132
|
+
* ```
|
|
36
133
|
*/
|
|
37
134
|
declare function addEdge<E>(graph: Graph<any, E>, config: EdgeConfig<E>): GraphEdge<E>;
|
|
38
135
|
/**
|
|
@@ -41,45 +138,134 @@ declare function addEdge<E>(graph: Graph<any, E>, config: EdgeConfig<E>): GraphE
|
|
|
41
138
|
*
|
|
42
139
|
* By default, children are deleted recursively.
|
|
43
140
|
* With `{ reparent: true }`, children are re-parented to the deleted node's parent.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* const graph = createGraph({
|
|
145
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
146
|
+
* edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }],
|
|
147
|
+
* });
|
|
148
|
+
* deleteNode(graph, 'a');
|
|
149
|
+
* // graph.nodes.length === 1, edge e1 also removed
|
|
150
|
+
* ```
|
|
44
151
|
*/
|
|
45
152
|
declare function deleteNode(graph: Graph, id: string, opts?: DeleteNodeOptions): void;
|
|
46
153
|
/**
|
|
47
154
|
* **Mutable.** Delete an edge. Mutates `graph.edges` in place.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```ts
|
|
158
|
+
* const graph = createGraph({
|
|
159
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
160
|
+
* edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }],
|
|
161
|
+
* });
|
|
162
|
+
* deleteEdge(graph, 'e1');
|
|
163
|
+
* // graph.edges.length === 0
|
|
164
|
+
* ```
|
|
48
165
|
*/
|
|
49
166
|
declare function deleteEdge(graph: Graph, id: string): void;
|
|
50
167
|
/**
|
|
51
168
|
* **Mutable.** Update a node in place.
|
|
52
169
|
* @returns The updated node.
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```ts
|
|
173
|
+
* const graph = createGraph({ nodes: [{ id: 'a', label: 'old' }] });
|
|
174
|
+
* const updated = updateNode(graph, 'a', { label: 'new' });
|
|
175
|
+
* // updated.label === 'new'
|
|
176
|
+
* ```
|
|
53
177
|
*/
|
|
54
178
|
declare function updateNode<N>(graph: Graph<N>, id: string, update: Partial<Omit<NodeConfig<N>, 'id'>>): GraphNode<N>;
|
|
55
179
|
/**
|
|
56
180
|
* **Mutable.** Update an edge in place.
|
|
57
181
|
* @returns The updated edge.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* const graph = createGraph({
|
|
186
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
187
|
+
* edges: [{ id: 'e1', sourceId: 'a', targetId: 'b', label: 'old' }],
|
|
188
|
+
* });
|
|
189
|
+
* const updated = updateEdge(graph, 'e1', { label: 'new' });
|
|
190
|
+
* // updated.label === 'new'
|
|
191
|
+
* ```
|
|
58
192
|
*/
|
|
59
193
|
declare function updateEdge<E>(graph: Graph<any, E>, id: string, update: Partial<Omit<EdgeConfig<E>, 'id'>>): GraphEdge<E>;
|
|
60
194
|
/**
|
|
61
195
|
* **Mutable.** Add multiple nodes and edges to the graph.
|
|
62
196
|
* Nodes are added first, then edges (so edges can reference new nodes).
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```ts
|
|
200
|
+
* const graph = createGraph();
|
|
201
|
+
* addEntities(graph, {
|
|
202
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
203
|
+
* edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }],
|
|
204
|
+
* });
|
|
205
|
+
* // graph.nodes.length === 2, graph.edges.length === 1
|
|
206
|
+
* ```
|
|
63
207
|
*/
|
|
64
208
|
declare function addEntities<N, E>(graph: Graph<N, E>, entities: EntitiesConfig<N, E>): void;
|
|
65
209
|
/**
|
|
66
210
|
* **Mutable.** Delete entities by id(s). Automatically detects whether each id
|
|
67
211
|
* is a node or edge. Node deletions cascade to children and connected edges.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```ts
|
|
215
|
+
* const graph = createGraph({
|
|
216
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
217
|
+
* edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }],
|
|
218
|
+
* });
|
|
219
|
+
* deleteEntities(graph, ['a', 'e1']);
|
|
220
|
+
* // graph.nodes.length === 1, graph.edges.length === 0
|
|
221
|
+
* ```
|
|
68
222
|
*/
|
|
69
223
|
declare function deleteEntities(graph: Graph, ids: string | string[], opts?: DeleteNodeOptions): void;
|
|
70
224
|
/**
|
|
71
225
|
* **Mutable.** Update multiple nodes and edges in place.
|
|
72
226
|
* Each entry must include an `id` to identify which entity to update.
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```ts
|
|
230
|
+
* const graph = createGraph({
|
|
231
|
+
* nodes: [{ id: 'a', label: 'old' }],
|
|
232
|
+
* edges: [{ id: 'e1', sourceId: 'a', targetId: 'a', label: 'old' }],
|
|
233
|
+
* });
|
|
234
|
+
* updateEntities(graph, {
|
|
235
|
+
* nodes: [{ id: 'a', label: 'new' }],
|
|
236
|
+
* edges: [{ id: 'e1', label: 'new' }],
|
|
237
|
+
* });
|
|
238
|
+
* ```
|
|
73
239
|
*/
|
|
74
240
|
declare function updateEntities<N, E>(graph: Graph<N, E>, updates: EntitiesUpdate<N, E>): void;
|
|
75
241
|
/**
|
|
76
242
|
* OOP wrapper around a plain `Graph` object.
|
|
77
243
|
* Delegates to the standalone mutable functions.
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* ```ts
|
|
247
|
+
* const instance = new GraphInstance({
|
|
248
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
249
|
+
* edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }],
|
|
250
|
+
* });
|
|
251
|
+
* instance.addNode({ id: 'c' });
|
|
252
|
+
* instance.hasNode('c'); // true
|
|
253
|
+
* instance.toJSON(); // plain Graph object
|
|
254
|
+
* ```
|
|
78
255
|
*/
|
|
79
256
|
declare class GraphInstance<N = any, E = any, G = any> {
|
|
80
257
|
graph: Graph<N, E, G>;
|
|
81
258
|
constructor(config?: GraphConfig<N, E, G>);
|
|
82
|
-
/**
|
|
259
|
+
/**
|
|
260
|
+
* Wrap an existing plain graph object.
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```ts
|
|
264
|
+
* const graph = createGraph({ nodes: [{ id: 'a' }] });
|
|
265
|
+
* const instance = GraphInstance.from(graph);
|
|
266
|
+
* instance.hasNode('a'); // true
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
83
269
|
static from<N = any, E = any, G = any>(graph: Graph<N, E, G>): GraphInstance<N, E, G>;
|
|
84
270
|
get id(): string;
|
|
85
271
|
get type(): "directed" | "undirected";
|
|
@@ -103,24 +289,99 @@ declare class GraphInstance<N = any, E = any, G = any> {
|
|
|
103
289
|
}
|
|
104
290
|
//#endregion
|
|
105
291
|
//#region src/indexing.d.ts
|
|
106
|
-
/**
|
|
292
|
+
/**
|
|
293
|
+
* Clear the cached index. Call this if you mutate graph.nodes/edges directly.
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```ts
|
|
297
|
+
* import { createGraph, invalidateIndex, getIndex } from '@statelyai/graph';
|
|
298
|
+
*
|
|
299
|
+
* const graph = createGraph({ nodes: [{ id: 'a' }], edges: [] });
|
|
300
|
+
* // manually mutate nodes array
|
|
301
|
+
* graph.nodes.push({ type: 'node', id: 'b', parentId: null, initialNodeId: null, label: '', data: undefined });
|
|
302
|
+
* invalidateIndex(graph); // forces rebuild on next getIndex()
|
|
303
|
+
* ```
|
|
304
|
+
*/
|
|
107
305
|
declare function invalidateIndex(graph: Graph): void;
|
|
108
306
|
//#endregion
|
|
109
307
|
//#region src/diff.d.ts
|
|
110
|
-
/**
|
|
308
|
+
/**
|
|
309
|
+
* Compute a structured diff from graph `a` to graph `b` by matching IDs.
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* ```ts
|
|
313
|
+
* import { createGraph, getDiff } from '@statelyai/graph';
|
|
314
|
+
*
|
|
315
|
+
* const a = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
316
|
+
* const b = createGraph({ nodes: [{ id: 'n1', label: 'hello' }, { id: 'n2' }], edges: [] });
|
|
317
|
+
*
|
|
318
|
+
* const diff = getDiff(a, b);
|
|
319
|
+
* // diff.nodes.added → [{ id: 'n2' }]
|
|
320
|
+
* // diff.nodes.updated → [{ id: 'n1', old: { label: '' }, new: { label: 'hello' } }]
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
111
323
|
declare function getDiff<N, E>(a: Graph<N, E>, b: Graph<N, E>): GraphDiff<N, E>;
|
|
112
|
-
/**
|
|
324
|
+
/**
|
|
325
|
+
* Check if a diff has zero changes.
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* ```ts
|
|
329
|
+
* import { createGraph, getDiff, isEmptyDiff } from '@statelyai/graph';
|
|
330
|
+
*
|
|
331
|
+
* const g = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
332
|
+
* const diff = getDiff(g, g);
|
|
333
|
+
* isEmptyDiff(diff); // true
|
|
334
|
+
* ```
|
|
335
|
+
*/
|
|
113
336
|
declare function isEmptyDiff(diff: GraphDiff): boolean;
|
|
114
|
-
/**
|
|
337
|
+
/**
|
|
338
|
+
* Invert a diff: swap added/removed, swap old/new in updates.
|
|
339
|
+
*
|
|
340
|
+
* @example
|
|
341
|
+
* ```ts
|
|
342
|
+
* import { createGraph, getDiff, invertDiff } from '@statelyai/graph';
|
|
343
|
+
*
|
|
344
|
+
* const a = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
345
|
+
* const b = createGraph({ nodes: [{ id: 'n2' }], edges: [] });
|
|
346
|
+
*
|
|
347
|
+
* const diff = getDiff(a, b);
|
|
348
|
+
* const inv = invertDiff(diff);
|
|
349
|
+
* // inv.nodes.added contains n1 (was removed)
|
|
350
|
+
* // inv.nodes.removed contains n2 (was added)
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
115
353
|
declare function invertDiff<N, E>(diff: GraphDiff<N, E>): GraphDiff<N, E>;
|
|
116
354
|
/**
|
|
117
355
|
* Compute an ordered patch list from graph `a` to graph `b`.
|
|
118
356
|
* Order: delete edges → delete nodes → add nodes → add edges → update nodes → update edges.
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```ts
|
|
360
|
+
* import { createGraph, getPatches } from '@statelyai/graph';
|
|
361
|
+
*
|
|
362
|
+
* const a = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
363
|
+
* const b = createGraph({ nodes: [{ id: 'n1' }, { id: 'n2' }], edges: [] });
|
|
364
|
+
*
|
|
365
|
+
* const patches = getPatches(a, b);
|
|
366
|
+
* // patches → [{ op: 'addNode', node: { id: 'n2' } }]
|
|
367
|
+
* ```
|
|
119
368
|
*/
|
|
120
369
|
declare function getPatches<N, E>(a: Graph<N, E>, b: Graph<N, E>): GraphPatch<N, E>[];
|
|
121
370
|
/**
|
|
122
371
|
* **Mutable.** Apply patches to a graph in order.
|
|
123
372
|
* Delegates to addNode/deleteNode/updateNode/addEdge/deleteEdge/updateEdge.
|
|
373
|
+
*
|
|
374
|
+
* @example
|
|
375
|
+
* ```ts
|
|
376
|
+
* import { createGraph, getPatches, applyPatches } from '@statelyai/graph';
|
|
377
|
+
*
|
|
378
|
+
* const a = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
379
|
+
* const b = createGraph({ nodes: [{ id: 'n1' }, { id: 'n2' }], edges: [] });
|
|
380
|
+
*
|
|
381
|
+
* const patches = getPatches(a, b);
|
|
382
|
+
* applyPatches(a, patches);
|
|
383
|
+
* // a now contains both n1 and n2
|
|
384
|
+
* ```
|
|
124
385
|
*/
|
|
125
386
|
declare function applyPatches<N, E>(graph: Graph<N, E>, patches: GraphPatch<N, E>[]): void;
|
|
126
387
|
/**
|
|
@@ -128,9 +389,35 @@ declare function applyPatches<N, E>(graph: Graph<N, E>, patches: GraphPatch<N, E
|
|
|
128
389
|
* Order: add nodes → update edges → delete edges → delete nodes → add edges → update nodes.
|
|
129
390
|
* This avoids cascading deletes removing edges that are being updated,
|
|
130
391
|
* and ensures new nodes exist before edges reference them.
|
|
392
|
+
*
|
|
393
|
+
* @example
|
|
394
|
+
* ```ts
|
|
395
|
+
* import { createGraph, getDiff, toPatches } from '@statelyai/graph';
|
|
396
|
+
*
|
|
397
|
+
* const a = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
398
|
+
* const b = createGraph({ nodes: [{ id: 'n2' }], edges: [] });
|
|
399
|
+
*
|
|
400
|
+
* const diff = getDiff(a, b);
|
|
401
|
+
* const patches = toPatches(diff);
|
|
402
|
+
* // patches → [{ op: 'addNode', ... }, { op: 'deleteNode', ... }]
|
|
403
|
+
* ```
|
|
131
404
|
*/
|
|
132
405
|
declare function toPatches<N, E>(diff: GraphDiff<N, E>): GraphPatch<N, E>[];
|
|
133
|
-
/**
|
|
406
|
+
/**
|
|
407
|
+
* Group a patch list into a structured diff.
|
|
408
|
+
*
|
|
409
|
+
* @example
|
|
410
|
+
* ```ts
|
|
411
|
+
* import { createGraph, getPatches, toDiff } from '@statelyai/graph';
|
|
412
|
+
*
|
|
413
|
+
* const a = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
414
|
+
* const b = createGraph({ nodes: [{ id: 'n1' }, { id: 'n2' }], edges: [] });
|
|
415
|
+
*
|
|
416
|
+
* const patches = getPatches(a, b);
|
|
417
|
+
* const diff = toDiff(patches);
|
|
418
|
+
* // diff.nodes.added → [{ id: 'n2' }]
|
|
419
|
+
* ```
|
|
420
|
+
*/
|
|
134
421
|
declare function toDiff<N, E>(patches: GraphPatch<N, E>[]): GraphDiff<N, E>;
|
|
135
422
|
//#endregion
|
|
136
423
|
//#region src/transforms.d.ts
|
|
@@ -141,6 +428,25 @@ declare function toDiff<N, E>(patches: GraphPatch<N, E>[]): GraphDiff<N, E>;
|
|
|
141
428
|
* - Edges originating from a compound node expand to all leaf descendants.
|
|
142
429
|
* - Only leaf nodes (nodes with no children) appear in the result.
|
|
143
430
|
* - Duplicate edges (same source + target) are deduplicated.
|
|
431
|
+
*
|
|
432
|
+
* @example
|
|
433
|
+
* ```ts
|
|
434
|
+
* import { createGraph, flatten } from '@statelyai/graph';
|
|
435
|
+
*
|
|
436
|
+
* const graph = createGraph({
|
|
437
|
+
* nodes: [
|
|
438
|
+
* { id: 'parent', initialNodeId: 'child1' },
|
|
439
|
+
* { id: 'child1', parentId: 'parent' },
|
|
440
|
+
* { id: 'child2', parentId: 'parent' },
|
|
441
|
+
* { id: 'other' },
|
|
442
|
+
* ],
|
|
443
|
+
* edges: [{ id: 'e1', sourceId: 'other', targetId: 'parent' }],
|
|
444
|
+
* });
|
|
445
|
+
*
|
|
446
|
+
* const flat = flatten(graph);
|
|
447
|
+
* // flat.nodes → [child1, child2, other] (leaf nodes only)
|
|
448
|
+
* // flat.edges → edge from 'other' → 'child1' (resolved via initialNodeId)
|
|
449
|
+
* ```
|
|
144
450
|
*/
|
|
145
451
|
declare function flatten<N, E, G>(graph: Graph<N, E, G>): Graph<N, E, G>;
|
|
146
452
|
//#endregion
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { o as invalidateIndex, t as getIndex } from "./indexing-
|
|
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-
|
|
1
|
+
import { o as invalidateIndex, t as getIndex } from "./indexing-eNDrXdDA.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-NWSB2RWj.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-
|
|
4
|
+
import { n as createFormatConverter } from "./converter-CchokMDg.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/diff.ts
|
|
7
7
|
function nodeToConfig(node) {
|
|
@@ -67,7 +67,21 @@ const EDGE_COMPARE_KEYS = [
|
|
|
67
67
|
"color",
|
|
68
68
|
"style"
|
|
69
69
|
];
|
|
70
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Compute a structured diff from graph `a` to graph `b` by matching IDs.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* import { createGraph, getDiff } from '@statelyai/graph';
|
|
76
|
+
*
|
|
77
|
+
* const a = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
78
|
+
* const b = createGraph({ nodes: [{ id: 'n1', label: 'hello' }, { id: 'n2' }], edges: [] });
|
|
79
|
+
*
|
|
80
|
+
* const diff = getDiff(a, b);
|
|
81
|
+
* // diff.nodes.added → [{ id: 'n2' }]
|
|
82
|
+
* // diff.nodes.updated → [{ id: 'n1', old: { label: '' }, new: { label: 'hello' } }]
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
71
85
|
function getDiff(a, b) {
|
|
72
86
|
const aNodeMap = new Map(a.nodes.map((n) => [n.id, n]));
|
|
73
87
|
const bNodeMap = new Map(b.nodes.map((n) => [n.id, n]));
|
|
@@ -123,11 +137,37 @@ function getDiff(a, b) {
|
|
|
123
137
|
for (const [id, edgeA] of aEdgeMap) if (!bEdgeMap.has(id)) diff.edges.removed.push(edgeToConfig(edgeA));
|
|
124
138
|
return diff;
|
|
125
139
|
}
|
|
126
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Check if a diff has zero changes.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* import { createGraph, getDiff, isEmptyDiff } from '@statelyai/graph';
|
|
146
|
+
*
|
|
147
|
+
* const g = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
148
|
+
* const diff = getDiff(g, g);
|
|
149
|
+
* isEmptyDiff(diff); // true
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
127
152
|
function isEmptyDiff(diff) {
|
|
128
153
|
return diff.nodes.added.length === 0 && diff.nodes.removed.length === 0 && diff.nodes.updated.length === 0 && diff.edges.added.length === 0 && diff.edges.removed.length === 0 && diff.edges.updated.length === 0;
|
|
129
154
|
}
|
|
130
|
-
/**
|
|
155
|
+
/**
|
|
156
|
+
* Invert a diff: swap added/removed, swap old/new in updates.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* import { createGraph, getDiff, invertDiff } from '@statelyai/graph';
|
|
161
|
+
*
|
|
162
|
+
* const a = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
163
|
+
* const b = createGraph({ nodes: [{ id: 'n2' }], edges: [] });
|
|
164
|
+
*
|
|
165
|
+
* const diff = getDiff(a, b);
|
|
166
|
+
* const inv = invertDiff(diff);
|
|
167
|
+
* // inv.nodes.added contains n1 (was removed)
|
|
168
|
+
* // inv.nodes.removed contains n2 (was added)
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
131
171
|
function invertDiff(diff) {
|
|
132
172
|
return {
|
|
133
173
|
nodes: {
|
|
@@ -153,6 +193,17 @@ function invertDiff(diff) {
|
|
|
153
193
|
/**
|
|
154
194
|
* Compute an ordered patch list from graph `a` to graph `b`.
|
|
155
195
|
* Order: delete edges → delete nodes → add nodes → add edges → update nodes → update edges.
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```ts
|
|
199
|
+
* import { createGraph, getPatches } from '@statelyai/graph';
|
|
200
|
+
*
|
|
201
|
+
* const a = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
202
|
+
* const b = createGraph({ nodes: [{ id: 'n1' }, { id: 'n2' }], edges: [] });
|
|
203
|
+
*
|
|
204
|
+
* const patches = getPatches(a, b);
|
|
205
|
+
* // patches → [{ op: 'addNode', node: { id: 'n2' } }]
|
|
206
|
+
* ```
|
|
156
207
|
*/
|
|
157
208
|
function getPatches(a, b) {
|
|
158
209
|
return toPatches(getDiff(a, b));
|
|
@@ -160,6 +211,18 @@ function getPatches(a, b) {
|
|
|
160
211
|
/**
|
|
161
212
|
* **Mutable.** Apply patches to a graph in order.
|
|
162
213
|
* Delegates to addNode/deleteNode/updateNode/addEdge/deleteEdge/updateEdge.
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```ts
|
|
217
|
+
* import { createGraph, getPatches, applyPatches } from '@statelyai/graph';
|
|
218
|
+
*
|
|
219
|
+
* const a = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
220
|
+
* const b = createGraph({ nodes: [{ id: 'n1' }, { id: 'n2' }], edges: [] });
|
|
221
|
+
*
|
|
222
|
+
* const patches = getPatches(a, b);
|
|
223
|
+
* applyPatches(a, patches);
|
|
224
|
+
* // a now contains both n1 and n2
|
|
225
|
+
* ```
|
|
163
226
|
*/
|
|
164
227
|
function applyPatches(graph, patches) {
|
|
165
228
|
for (const patch of patches) switch (patch.op) {
|
|
@@ -188,6 +251,18 @@ function applyPatches(graph, patches) {
|
|
|
188
251
|
* Order: add nodes → update edges → delete edges → delete nodes → add edges → update nodes.
|
|
189
252
|
* This avoids cascading deletes removing edges that are being updated,
|
|
190
253
|
* and ensures new nodes exist before edges reference them.
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```ts
|
|
257
|
+
* import { createGraph, getDiff, toPatches } from '@statelyai/graph';
|
|
258
|
+
*
|
|
259
|
+
* const a = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
260
|
+
* const b = createGraph({ nodes: [{ id: 'n2' }], edges: [] });
|
|
261
|
+
*
|
|
262
|
+
* const diff = getDiff(a, b);
|
|
263
|
+
* const patches = toPatches(diff);
|
|
264
|
+
* // patches → [{ op: 'addNode', ... }, { op: 'deleteNode', ... }]
|
|
265
|
+
* ```
|
|
191
266
|
*/
|
|
192
267
|
function toPatches(diff) {
|
|
193
268
|
const patches = [];
|
|
@@ -227,7 +302,21 @@ function toPatches(diff) {
|
|
|
227
302
|
}
|
|
228
303
|
return patches;
|
|
229
304
|
}
|
|
230
|
-
/**
|
|
305
|
+
/**
|
|
306
|
+
* Group a patch list into a structured diff.
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* ```ts
|
|
310
|
+
* import { createGraph, getPatches, toDiff } from '@statelyai/graph';
|
|
311
|
+
*
|
|
312
|
+
* const a = createGraph({ nodes: [{ id: 'n1' }], edges: [] });
|
|
313
|
+
* const b = createGraph({ nodes: [{ id: 'n1' }, { id: 'n2' }], edges: [] });
|
|
314
|
+
*
|
|
315
|
+
* const patches = getPatches(a, b);
|
|
316
|
+
* const diff = toDiff(patches);
|
|
317
|
+
* // diff.nodes.added → [{ id: 'n2' }]
|
|
318
|
+
* ```
|
|
319
|
+
*/
|
|
231
320
|
function toDiff(patches) {
|
|
232
321
|
const diff = {
|
|
233
322
|
nodes: {
|
|
@@ -287,6 +376,25 @@ function toDiff(patches) {
|
|
|
287
376
|
* - Edges originating from a compound node expand to all leaf descendants.
|
|
288
377
|
* - Only leaf nodes (nodes with no children) appear in the result.
|
|
289
378
|
* - Duplicate edges (same source + target) are deduplicated.
|
|
379
|
+
*
|
|
380
|
+
* @example
|
|
381
|
+
* ```ts
|
|
382
|
+
* import { createGraph, flatten } from '@statelyai/graph';
|
|
383
|
+
*
|
|
384
|
+
* const graph = createGraph({
|
|
385
|
+
* nodes: [
|
|
386
|
+
* { id: 'parent', initialNodeId: 'child1' },
|
|
387
|
+
* { id: 'child1', parentId: 'parent' },
|
|
388
|
+
* { id: 'child2', parentId: 'parent' },
|
|
389
|
+
* { id: 'other' },
|
|
390
|
+
* ],
|
|
391
|
+
* edges: [{ id: 'e1', sourceId: 'other', targetId: 'parent' }],
|
|
392
|
+
* });
|
|
393
|
+
*
|
|
394
|
+
* const flat = flatten(graph);
|
|
395
|
+
* // flat.nodes → [child1, child2, other] (leaf nodes only)
|
|
396
|
+
* // flat.edges → edge from 'other' → 'child1' (resolved via initialNodeId)
|
|
397
|
+
* ```
|
|
290
398
|
*/
|
|
291
399
|
function flatten(graph) {
|
|
292
400
|
const idx = getIndex(graph);
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
//#region src/indexing.ts
|
|
2
2
|
const indexes = /* @__PURE__ */ new WeakMap();
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Get or lazily build the index for a graph.
|
|
5
|
+
* Auto-rebuilds when node/edge count changes.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createGraph, getIndex } from '@statelyai/graph';
|
|
10
|
+
*
|
|
11
|
+
* const graph = createGraph({
|
|
12
|
+
* nodes: [{ id: 'a' }, { id: 'b' }],
|
|
13
|
+
* edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }],
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* const idx = getIndex(graph);
|
|
17
|
+
* idx.nodeById.get('a'); // 0
|
|
18
|
+
* idx.outEdges.get('a'); // ['e1']
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
4
21
|
function getIndex(graph) {
|
|
5
22
|
let idx = indexes.get(graph);
|
|
6
23
|
if (!idx || idx.nodeCount !== graph.nodes.length || idx.edgeCount !== graph.edges.length) {
|
|
@@ -9,7 +26,19 @@ function getIndex(graph) {
|
|
|
9
26
|
}
|
|
10
27
|
return idx;
|
|
11
28
|
}
|
|
12
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Clear the cached index. Call this if you mutate graph.nodes/edges directly.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { createGraph, invalidateIndex, getIndex } from '@statelyai/graph';
|
|
35
|
+
*
|
|
36
|
+
* const graph = createGraph({ nodes: [{ id: 'a' }], edges: [] });
|
|
37
|
+
* // manually mutate nodes array
|
|
38
|
+
* graph.nodes.push({ type: 'node', id: 'b', parentId: null, initialNodeId: null, label: '', data: undefined });
|
|
39
|
+
* invalidateIndex(graph); // forces rebuild on next getIndex()
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
13
42
|
function invalidateIndex(graph) {
|
|
14
43
|
indexes.delete(graph);
|
|
15
44
|
}
|