@statelyai/graph 0.1.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/README.md +65 -15
- package/dist/{adjacency-list-CXpOCibq.mjs → adjacency-list-ITO40kmn.mjs} +34 -1
- package/dist/{algorithms-R35X6ro4.mjs → algorithms-NWSB2RWj.mjs} +753 -19
- package/dist/algorithms.d.mts +488 -11
- package/dist/algorithms.mjs +2 -2
- package/dist/converter-CchokMDg.mjs +67 -0
- package/dist/edge-list-CgX6bBIF.mjs +71 -0
- package/dist/formats/adjacency-list/index.d.mts +44 -0
- package/dist/formats/adjacency-list/index.mjs +3 -0
- package/dist/formats/converter/index.d.mts +61 -0
- package/dist/formats/converter/index.mjs +3 -0
- package/dist/formats/cytoscape/index.d.mts +83 -0
- package/dist/formats/cytoscape/index.mjs +135 -0
- package/dist/formats/d3/index.d.mts +68 -0
- package/dist/formats/d3/index.mjs +111 -0
- package/dist/formats/dot/index.d.mts +63 -0
- package/dist/formats/dot/index.mjs +288 -0
- package/dist/formats/edge-list/index.d.mts +43 -0
- package/dist/formats/edge-list/index.mjs +3 -0
- package/dist/formats/gexf/index.d.mts +9 -0
- package/dist/formats/gexf/index.mjs +249 -0
- package/dist/formats/gml/index.d.mts +65 -0
- package/dist/formats/gml/index.mjs +291 -0
- package/dist/formats/graphml/index.d.mts +9 -0
- package/dist/{graphml-CUTNRXqd.mjs → formats/graphml/index.mjs} +18 -4
- package/dist/formats/jgf/index.d.mts +79 -0
- package/dist/formats/jgf/index.mjs +134 -0
- package/dist/formats/mermaid/index.d.mts +381 -0
- package/dist/formats/mermaid/index.mjs +2237 -0
- package/dist/formats/tgf/index.d.mts +54 -0
- package/dist/formats/tgf/index.mjs +111 -0
- package/dist/index.d.mts +332 -21
- package/dist/index.mjs +117 -13
- package/dist/{indexing-BHg1VhqN.mjs → indexing-eNDrXdDA.mjs} +31 -2
- package/dist/queries.d.mts +430 -9
- package/dist/queries.mjs +472 -9
- package/dist/{types-XV3S5Jnh.d.mts → types-BDXC1O5b.d.mts} +37 -2
- package/package.json +43 -17
- package/dist/adjacency-list-DW-lAUe8.d.mts +0 -10
- package/dist/dot-BRtq3e3c.mjs +0 -59
- package/dist/dot-HmJeUMsj.d.mts +0 -6
- package/dist/edge-list-BRujEnnU.mjs +0 -39
- package/dist/edge-list-CJmfoNu2.d.mts +0 -10
- package/dist/formats/adjacency-list.d.mts +0 -2
- package/dist/formats/adjacency-list.mjs +0 -3
- package/dist/formats/dot.d.mts +0 -2
- package/dist/formats/dot.mjs +0 -3
- package/dist/formats/edge-list.d.mts +0 -2
- package/dist/formats/edge-list.mjs +0 -3
- package/dist/formats/graphml.d.mts +0 -2
- package/dist/formats/graphml.mjs +0 -3
- package/dist/graphml-CMjPzSfY.d.mts +0 -7
package/README.md
CHANGED
|
@@ -4,6 +4,18 @@ A TypeScript graph library built on plain JSON objects. Supports directed/undire
|
|
|
4
4
|
|
|
5
5
|
Made from our experience at [stately.ai](https://stately.ai), where we build visual tools for complex systems.
|
|
6
6
|
|
|
7
|
+
## Why this library?
|
|
8
|
+
|
|
9
|
+
Graph file formats (GEXF, GraphML) define how to _store_ graphs. Visualization libraries (Cytoscape.js, D3) define how to _render_ them. Neither gives you a good way to _work with_ them in between.
|
|
10
|
+
|
|
11
|
+
This library is the computational layer: plain JSON objects in, algorithms and mutations, plain JSON objects out. No classes, no DOM, no rendering engine — just data and functions.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
GEXF file → fromGEXF() → Graph → run algorithms, mutate → toCytoscapeJSON() → render
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Your `Graph` is a plain object that survives `JSON.stringify`, `structuredClone`, `postMessage`, and `localStorage` without adapters. Format converters are the I/O ports — read from any supported format, do your work, export to whatever your renderer or database expects.
|
|
18
|
+
|
|
7
19
|
## Install
|
|
8
20
|
|
|
9
21
|
```bash
|
|
@@ -77,22 +89,41 @@ const diagram = createVisualGraph({
|
|
|
77
89
|
});
|
|
78
90
|
```
|
|
79
91
|
|
|
80
|
-
###
|
|
92
|
+
### Format Conversion
|
|
81
93
|
|
|
82
94
|
```ts
|
|
83
|
-
import {
|
|
95
|
+
import { toCytoscapeJSON } from '@statelyai/graph/cytoscape';
|
|
96
|
+
import { fromJGF } from '@statelyai/graph/jgf';
|
|
97
|
+
import { toD3Graph } from '@statelyai/graph/d3';
|
|
98
|
+
import { toDOT } from '@statelyai/graph/dot';
|
|
99
|
+
import { toGraphML } from '@statelyai/graph/graphml';
|
|
100
|
+
import { fromGEXF } from '@statelyai/graph/gexf';
|
|
101
|
+
|
|
102
|
+
// Export to web visualization libraries
|
|
103
|
+
const cytoData = toCytoscapeJSON(graph); // Cytoscape.js JSON (compound graphs preserved)
|
|
104
|
+
const d3Data = toD3Graph(graph); // D3.js { nodes, links }
|
|
105
|
+
|
|
106
|
+
// Export to text formats
|
|
107
|
+
const dot = toDOT(graph); // Graphviz DOT
|
|
108
|
+
const xml = toGraphML(graph); // GraphML XML
|
|
109
|
+
|
|
110
|
+
// Import from any format
|
|
111
|
+
const g1 = fromJGF(jsonGraphData); // JSON Graph Format
|
|
112
|
+
const g2 = fromGEXF(gexfXmlString); // GEXF (Gephi)
|
|
113
|
+
```
|
|
84
114
|
|
|
85
|
-
|
|
86
|
-
// Logs a Graphviz DOT string
|
|
115
|
+
Each bidirectional format also has a converter object for a unified interface:
|
|
87
116
|
|
|
88
|
-
|
|
89
|
-
|
|
117
|
+
```ts
|
|
118
|
+
import { createFormatConverter } from '@statelyai/graph';
|
|
119
|
+
import { cytoscapeConverter } from '@statelyai/graph/cytoscape';
|
|
90
120
|
|
|
91
|
-
|
|
92
|
-
|
|
121
|
+
// Use a built-in converter
|
|
122
|
+
const cyto = cytoscapeConverter.to(graph);
|
|
123
|
+
const back = cytoscapeConverter.from(cyto);
|
|
93
124
|
|
|
94
|
-
|
|
95
|
-
|
|
125
|
+
// Create your own
|
|
126
|
+
const myConverter = createFormatConverter(myToFn, myFromFn);
|
|
96
127
|
```
|
|
97
128
|
|
|
98
129
|
## API
|
|
@@ -176,15 +207,34 @@ console.log(toEdgeList(graph));
|
|
|
176
207
|
|
|
177
208
|
Generator variants: `genShortestPaths`, `genSimplePaths`, `genCycles`, `genPreorders`, `genPostorders`.
|
|
178
209
|
|
|
179
|
-
### Transforms
|
|
210
|
+
### Transforms
|
|
180
211
|
|
|
181
212
|
| Function | Description |
|
|
182
213
|
|----------|-------------|
|
|
183
214
|
| `flatten(graph)` | Decompose hierarchy into flat leaf-node graph |
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
215
|
+
|
|
216
|
+
### Formats
|
|
217
|
+
|
|
218
|
+
Import format converters from subpaths (for example, `@statelyai/graph/dot` or `@statelyai/graph/mermaid`).
|
|
219
|
+
|
|
220
|
+
| Format | Export | Import | Compound? | Notes |
|
|
221
|
+
|--------|--------|--------|-----------|-------|
|
|
222
|
+
| **Cytoscape.js JSON** | `toCytoscapeJSON` | `fromCytoscapeJSON` | Yes | `parent` maps to `parentId` |
|
|
223
|
+
| **D3.js JSON** | `toD3Graph` | `fromD3Graph` | No | `{ nodes, links }` for force layouts |
|
|
224
|
+
| **JSON Graph Format** | `toJGF` | `fromJGF` | Yes | Formal spec, metadata-extensible |
|
|
225
|
+
| **GEXF** | `toGEXF` | `fromGEXF` | Yes | Gephi native, `pid` hierarchy, viz module |
|
|
226
|
+
| **GraphML** | `toGraphML` | `fromGraphML` | Yes | XML standard, requires `fast-xml-parser` |
|
|
227
|
+
| **GML** | `toGML` | `fromGML` | Yes | Nested node blocks for hierarchy |
|
|
228
|
+
| **TGF** | `toTGF` | `fromTGF` | No | Minimal (id + label only) |
|
|
229
|
+
| **DOT** | `toDOT` | `fromDOT` | Yes (subgraphs) | Graphviz DOT (`dotparser` peer dep) |
|
|
230
|
+
| **Mermaid** | `toMermaid*` | `fromMermaid*` | Varies by diagram | Sequence, flowchart, state, class, ER, mindmap, block |
|
|
231
|
+
| **Adjacency list** | `toAdjacencyList` | `fromAdjacencyList` | No | `Record<string, string[]>` |
|
|
232
|
+
| **Edge list** | `toEdgeList` | `fromEdgeList` | No | `[source, target][]` |
|
|
233
|
+
|
|
234
|
+
Optional peer deps by format:
|
|
235
|
+
- `@statelyai/graph/gexf` and `@statelyai/graph/graphml` use `fast-xml-parser`
|
|
236
|
+
- `@statelyai/graph/dot` uses `dotparser`
|
|
237
|
+
- Other formats are dependency-free
|
|
188
238
|
|
|
189
239
|
## License
|
|
190
240
|
|
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
//#region src/formats/adjacency-list.ts
|
|
1
|
+
//#region src/formats/adjacency-list/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* Converts a graph to an adjacency list representation.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { createGraph, toAdjacencyList } from '@statelyai/graph';
|
|
8
|
+
*
|
|
9
|
+
* const graph = createGraph({
|
|
10
|
+
* nodes: { a: {}, b: {}, c: {} },
|
|
11
|
+
* edges: [{ source: 'a', target: 'b' }, { source: 'a', target: 'c' }],
|
|
12
|
+
* });
|
|
13
|
+
*
|
|
14
|
+
* toAdjacencyList(graph);
|
|
15
|
+
* // { a: ['b', 'c'], b: [], c: [] }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
2
18
|
function toAdjacencyList(graph) {
|
|
3
19
|
const adj = {};
|
|
4
20
|
for (const node of graph.nodes) adj[node.id] = [];
|
|
@@ -8,6 +24,23 @@ function toAdjacencyList(graph) {
|
|
|
8
24
|
}
|
|
9
25
|
return adj;
|
|
10
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Parses an adjacency list into a graph.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { fromAdjacencyList } from '@statelyai/graph';
|
|
33
|
+
*
|
|
34
|
+
* const graph = fromAdjacencyList({
|
|
35
|
+
* a: ['b', 'c'],
|
|
36
|
+
* b: ['c'],
|
|
37
|
+
* c: [],
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* graph.nodes; // [{id: 'a', ...}, {id: 'b', ...}, {id: 'c', ...}]
|
|
41
|
+
* graph.edges; // [{sourceId: 'a', targetId: 'b', ...}, ...]
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
11
44
|
function fromAdjacencyList(adj, options) {
|
|
12
45
|
const directed = options?.directed ?? true;
|
|
13
46
|
const seen = /* @__PURE__ */ new Set();
|