@statelyai/graph 0.12.0 → 1.0.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 +26 -16
- package/dist/{adjacency-list-Ca0VjKIf.mjs → adjacency-list-VsUaH9SJ.mjs} +2 -2
- package/dist/{algorithms-BHHg7lGq.mjs → algorithms-Ba7o7niK.mjs} +35 -31
- package/dist/{algorithms-BlM-qoJb.d.mts → algorithms-fTqmvhzP.d.mts} +1 -1
- package/dist/algorithms.d.mts +1 -1
- package/dist/algorithms.mjs +1 -1
- package/dist/{converter-Dspillnn.mjs → converter-udLITX36.mjs} +2 -2
- package/dist/{edge-list-gKe8-iRa.mjs → edge-list-DP4otyPU.mjs} +1 -1
- package/dist/format-support.d.mts +6 -0
- package/dist/format-support.mjs +68 -33
- package/dist/formats/adjacency-list/index.d.mts +1 -1
- package/dist/formats/adjacency-list/index.mjs +1 -1
- package/dist/formats/converter/index.d.mts +1 -60
- package/dist/formats/converter/index.mjs +1 -1
- package/dist/formats/cytoscape/index.d.mts +1 -1
- package/dist/formats/cytoscape/index.mjs +19 -3
- package/dist/formats/d2/index.d.mts +109 -0
- package/dist/formats/d2/index.mjs +1086 -0
- package/dist/formats/d3/index.d.mts +8 -1
- package/dist/formats/d3/index.mjs +35 -7
- package/dist/formats/dot/index.d.mts +1 -1
- package/dist/formats/dot/index.mjs +3 -3
- package/dist/formats/edge-list/index.d.mts +1 -1
- package/dist/formats/edge-list/index.mjs +1 -1
- package/dist/formats/elk/index.d.mts +1 -1
- package/dist/formats/elk/index.mjs +86 -23
- package/dist/formats/gexf/index.d.mts +1 -1
- package/dist/formats/gexf/index.mjs +102 -4
- package/dist/formats/gml/index.d.mts +1 -1
- package/dist/formats/gml/index.mjs +43 -16
- package/dist/formats/graphml/index.d.mts +1 -1
- package/dist/formats/graphml/index.mjs +11 -4
- package/dist/formats/jgf/index.d.mts +1 -1
- package/dist/formats/jgf/index.mjs +19 -3
- package/dist/formats/mermaid/index.d.mts +2 -1
- package/dist/formats/mermaid/index.mjs +48 -18
- package/dist/formats/tgf/index.d.mts +1 -1
- package/dist/formats/tgf/index.mjs +2 -2
- package/dist/formats/xyflow/index.d.mts +2 -1
- package/dist/formats/xyflow/index.mjs +97 -40
- package/dist/index-CHoriXZD.d.mts +638 -0
- package/dist/index-D9Kj6Fe3.d.mts +61 -0
- package/dist/index.d.mts +6 -631
- package/dist/index.mjs +8 -7
- package/dist/{indexing-CJc-ul8e.mjs → indexing-DR8M1vBy.mjs} +18 -4
- package/dist/mode-D8OnHFBk.mjs +15 -0
- package/dist/queries-BlkA1HAN.d.mts +516 -0
- package/dist/queries.d.mts +1 -514
- package/dist/queries.mjs +17 -15
- package/dist/schemas.d.mts +29 -17
- package/dist/schemas.mjs +139 -6
- package/dist/{types-CnZ01raw.d.mts → types-3-FS9NV2.d.mts} +30 -7
- package/package.json +2 -1
- package/schemas/edge.schema.json +11 -0
- package/schemas/graph.schema.json +25 -3
- package/schemas/node.schema.json +7 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as getEdgeMode } from "../../mode-D8OnHFBk.mjs";
|
|
2
|
+
import { n as createFormatConverter } from "../../converter-udLITX36.mjs";
|
|
2
3
|
import { XMLBuilder, XMLParser } from "fast-xml-parser";
|
|
3
4
|
|
|
4
5
|
//#region src/formats/graphml/index.ts
|
|
@@ -175,7 +176,9 @@ function toGraphML(graph) {
|
|
|
175
176
|
...data.length > 0 && { data }
|
|
176
177
|
};
|
|
177
178
|
});
|
|
179
|
+
const graphDirected = graph.mode !== "undirected";
|
|
178
180
|
const edges = graph.edges.map((edge) => {
|
|
181
|
+
const edgeDirected = getEdgeMode(graph, edge) !== "undirected";
|
|
179
182
|
const data = [];
|
|
180
183
|
if (edge.label) data.push({
|
|
181
184
|
"@_key": "label",
|
|
@@ -225,6 +228,7 @@ function toGraphML(graph) {
|
|
|
225
228
|
"@_id": edge.id,
|
|
226
229
|
"@_source": edge.sourceId,
|
|
227
230
|
"@_target": edge.targetId,
|
|
231
|
+
...edgeDirected !== graphDirected && { "@_directed": edgeDirected ? "true" : "false" },
|
|
228
232
|
...data.length > 0 && { data }
|
|
229
233
|
};
|
|
230
234
|
});
|
|
@@ -255,7 +259,7 @@ function toGraphML(graph) {
|
|
|
255
259
|
key: keys,
|
|
256
260
|
graph: {
|
|
257
261
|
"@_id": graph.id,
|
|
258
|
-
"@_edgedefault": graph.
|
|
262
|
+
"@_edgedefault": graph.mode === "undirected" ? "undirected" : "directed",
|
|
259
263
|
...graphData.length > 0 && { data: graphData },
|
|
260
264
|
node: nodes,
|
|
261
265
|
edge: edges
|
|
@@ -265,7 +269,8 @@ function toGraphML(graph) {
|
|
|
265
269
|
return new XMLBuilder({
|
|
266
270
|
ignoreAttributes: false,
|
|
267
271
|
format: true,
|
|
268
|
-
suppressEmptyNode: true
|
|
272
|
+
suppressEmptyNode: true,
|
|
273
|
+
suppressBooleanAttributes: false
|
|
269
274
|
}).build(obj);
|
|
270
275
|
}
|
|
271
276
|
function fromGraphML(xml) {
|
|
@@ -331,11 +336,13 @@ function fromGraphML(xml) {
|
|
|
331
336
|
if (dataMap.style !== void 0) edge.style = tryParseJSON(dataMap.style);
|
|
332
337
|
if (dataMap.sourcePort !== void 0) edge.sourcePort = dataMap.sourcePort;
|
|
333
338
|
if (dataMap.targetPort !== void 0) edge.targetPort = dataMap.targetPort;
|
|
339
|
+
const directedAttr = edgeEl["@_directed"];
|
|
340
|
+
if (directedAttr !== void 0) edge.mode = String(directedAttr) === "false" ? "undirected" : "directed";
|
|
334
341
|
return edge;
|
|
335
342
|
});
|
|
336
343
|
const graph = {
|
|
337
344
|
id: String(graphEl["@_id"] ?? ""),
|
|
338
|
-
|
|
345
|
+
mode: graphType,
|
|
339
346
|
initialNodeId: graphDataMap.graphInitialNodeId ?? null,
|
|
340
347
|
nodes,
|
|
341
348
|
edges,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as createFormatConverter } from "../../converter-
|
|
1
|
+
import { n as createFormatConverter } from "../../converter-udLITX36.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/formats/jgf/index.ts
|
|
4
4
|
/**
|
|
@@ -23,9 +23,10 @@ function toJGF(graph) {
|
|
|
23
23
|
if (graph.initialNodeId) metadata.initialNodeId = graph.initialNodeId;
|
|
24
24
|
if (graph.data !== void 0) metadata.data = graph.data;
|
|
25
25
|
if (graph.direction) metadata.direction = graph.direction;
|
|
26
|
+
if (graph.style !== void 0) metadata.style = graph.style;
|
|
26
27
|
return { graph: {
|
|
27
28
|
id: graph.id || void 0,
|
|
28
|
-
directed: graph.
|
|
29
|
+
directed: graph.mode !== "undirected",
|
|
29
30
|
...Object.keys(metadata).length > 0 && { metadata },
|
|
30
31
|
nodes: graph.nodes.map((n) => {
|
|
31
32
|
const meta = {};
|
|
@@ -38,6 +39,7 @@ function toJGF(graph) {
|
|
|
38
39
|
if (n.height !== void 0) meta.height = n.height;
|
|
39
40
|
if (n.shape) meta.shape = n.shape;
|
|
40
41
|
if (n.color) meta.color = n.color;
|
|
42
|
+
if (n.style !== void 0) meta.style = n.style;
|
|
41
43
|
if (n.ports !== void 0) meta.ports = n.ports;
|
|
42
44
|
return {
|
|
43
45
|
id: n.id,
|
|
@@ -48,7 +50,13 @@ function toJGF(graph) {
|
|
|
48
50
|
edges: graph.edges.map((e) => {
|
|
49
51
|
const meta = {};
|
|
50
52
|
if (e.data !== void 0) meta.data = e.data;
|
|
53
|
+
if (e.weight !== void 0) meta.weight = e.weight;
|
|
54
|
+
if (e.x !== void 0) meta.x = e.x;
|
|
55
|
+
if (e.y !== void 0) meta.y = e.y;
|
|
56
|
+
if (e.width !== void 0) meta.width = e.width;
|
|
57
|
+
if (e.height !== void 0) meta.height = e.height;
|
|
51
58
|
if (e.color) meta.color = e.color;
|
|
59
|
+
if (e.style !== void 0) meta.style = e.style;
|
|
52
60
|
if (e.sourcePort !== void 0) meta.sourcePort = e.sourcePort;
|
|
53
61
|
if (e.targetPort !== void 0) meta.targetPort = e.targetPort;
|
|
54
62
|
return {
|
|
@@ -85,10 +93,11 @@ function fromJGF(jgf) {
|
|
|
85
93
|
if (!Array.isArray(g.edges)) throw new Error("JGF: \"graph.edges\" must be an array");
|
|
86
94
|
return {
|
|
87
95
|
id: g.id ?? "",
|
|
88
|
-
|
|
96
|
+
mode: g.directed === false ? "undirected" : "directed",
|
|
89
97
|
initialNodeId: g.metadata?.initialNodeId ?? null,
|
|
90
98
|
data: g.metadata?.data,
|
|
91
99
|
...g.metadata?.direction && { direction: g.metadata.direction },
|
|
100
|
+
...g.metadata?.style !== void 0 && { style: g.metadata.style },
|
|
92
101
|
nodes: g.nodes.map((n) => ({
|
|
93
102
|
type: "node",
|
|
94
103
|
id: n.id,
|
|
@@ -102,6 +111,7 @@ function fromJGF(jgf) {
|
|
|
102
111
|
...n.metadata?.height !== void 0 && { height: n.metadata.height },
|
|
103
112
|
...n.metadata?.shape && { shape: n.metadata.shape },
|
|
104
113
|
...n.metadata?.color && { color: n.metadata.color },
|
|
114
|
+
...n.metadata?.style !== void 0 && { style: n.metadata.style },
|
|
105
115
|
...n.metadata?.ports !== void 0 && { ports: n.metadata.ports }
|
|
106
116
|
})),
|
|
107
117
|
edges: g.edges.map((e, i) => ({
|
|
@@ -111,7 +121,13 @@ function fromJGF(jgf) {
|
|
|
111
121
|
targetId: e.target,
|
|
112
122
|
label: e.label ?? "",
|
|
113
123
|
data: e.metadata?.data,
|
|
124
|
+
...e.metadata?.weight !== void 0 && { weight: e.metadata.weight },
|
|
125
|
+
...e.metadata?.x !== void 0 && { x: e.metadata.x },
|
|
126
|
+
...e.metadata?.y !== void 0 && { y: e.metadata.y },
|
|
127
|
+
...e.metadata?.width !== void 0 && { width: e.metadata.width },
|
|
128
|
+
...e.metadata?.height !== void 0 && { height: e.metadata.height },
|
|
114
129
|
...e.metadata?.color && { color: e.metadata.color },
|
|
130
|
+
...e.metadata?.style !== void 0 && { style: e.metadata.style },
|
|
115
131
|
...e.metadata?.sourcePort !== void 0 && { sourcePort: e.metadata.sourcePort },
|
|
116
132
|
...e.metadata?.targetPort !== void 0 && { targetPort: e.metadata.targetPort }
|
|
117
133
|
}))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { h as GraphFormatConverter, u as Graph } from "../../types-
|
|
1
|
+
import { h as GraphFormatConverter, u as Graph } from "../../types-3-FS9NV2.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/formats/mermaid/sequence.d.ts
|
|
4
4
|
interface SequenceNodeData {
|
|
@@ -165,6 +165,7 @@ interface StateNodeData {
|
|
|
165
165
|
notes?: Array<{
|
|
166
166
|
position: 'left' | 'right';
|
|
167
167
|
text: string;
|
|
168
|
+
format?: 'inline' | 'block';
|
|
168
169
|
}>;
|
|
169
170
|
isStart?: boolean;
|
|
170
171
|
isEnd?: boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as createFormatConverter } from "../../converter-
|
|
1
|
+
import { n as createFormatConverter } from "../../converter-udLITX36.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/formats/mermaid/shared.ts
|
|
4
4
|
const MERMAID_TO_DIRECTION = {
|
|
@@ -497,7 +497,7 @@ function fromMermaidSequence(input) {
|
|
|
497
497
|
}
|
|
498
498
|
return {
|
|
499
499
|
id: "",
|
|
500
|
-
|
|
500
|
+
mode: "directed",
|
|
501
501
|
initialNodeId: null,
|
|
502
502
|
nodes: Array.from(nodeMap.values()),
|
|
503
503
|
edges,
|
|
@@ -1292,7 +1292,7 @@ function fromMermaidFlowchart(input) {
|
|
|
1292
1292
|
}
|
|
1293
1293
|
return {
|
|
1294
1294
|
id: "",
|
|
1295
|
-
|
|
1295
|
+
mode: "directed",
|
|
1296
1296
|
initialNodeId: null,
|
|
1297
1297
|
nodes: Array.from(nodeMap.values()),
|
|
1298
1298
|
edges,
|
|
@@ -1415,10 +1415,16 @@ function fromMermaidState(input) {
|
|
|
1415
1415
|
const parentStack = [null];
|
|
1416
1416
|
const regionCounters = /* @__PURE__ */ new Map();
|
|
1417
1417
|
function ensureNode(id) {
|
|
1418
|
-
|
|
1418
|
+
const parentId = parentStack[parentStack.length - 1];
|
|
1419
|
+
const existing = nodeMap.get(id);
|
|
1420
|
+
if (existing) {
|
|
1421
|
+
if (parentId && existing.parentId === null && existing.id !== parentId) existing.parentId = parentId;
|
|
1422
|
+
return existing;
|
|
1423
|
+
}
|
|
1424
|
+
nodeMap.set(id, {
|
|
1419
1425
|
type: "node",
|
|
1420
1426
|
id,
|
|
1421
|
-
parentId
|
|
1427
|
+
parentId,
|
|
1422
1428
|
initialNodeId: null,
|
|
1423
1429
|
label: id,
|
|
1424
1430
|
data: {}
|
|
@@ -1462,6 +1468,15 @@ function fromMermaidState(input) {
|
|
|
1462
1468
|
parentStack.push(stateId);
|
|
1463
1469
|
continue;
|
|
1464
1470
|
}
|
|
1471
|
+
const compositeStateAsMatch = line.match(/^state\s+"([^"]+)"\s+as\s+(\S+)\s*\{\s*$/);
|
|
1472
|
+
if (compositeStateAsMatch) {
|
|
1473
|
+
const description = compositeStateAsMatch[1];
|
|
1474
|
+
const stateId = compositeStateAsMatch[2];
|
|
1475
|
+
const node = ensureNode(stateId);
|
|
1476
|
+
node.data.description = description;
|
|
1477
|
+
parentStack.push(stateId);
|
|
1478
|
+
continue;
|
|
1479
|
+
}
|
|
1465
1480
|
const stereotypeMatch = line.match(/^state\s+(\S+)\s+<<(choice|fork|join)>>\s*$/);
|
|
1466
1481
|
if (stereotypeMatch) {
|
|
1467
1482
|
const stateId = stereotypeMatch[1];
|
|
@@ -1542,16 +1557,27 @@ function fromMermaidState(input) {
|
|
|
1542
1557
|
}
|
|
1543
1558
|
continue;
|
|
1544
1559
|
}
|
|
1545
|
-
const noteMatch = line.match(/^note\s+(left|right)\s+of\s+(\S+)\s
|
|
1560
|
+
const noteMatch = line.match(/^note\s+(left|right)\s+of\s+(\S+)\s*(?::\s*(.*))?$/i);
|
|
1546
1561
|
if (noteMatch) {
|
|
1547
1562
|
const position = noteMatch[1].toLowerCase();
|
|
1548
1563
|
const stateId = noteMatch[2];
|
|
1549
|
-
const
|
|
1564
|
+
const inlineText = noteMatch[3]?.trim();
|
|
1565
|
+
const text = inlineText && inlineText.length > 0 ? inlineText : (() => {
|
|
1566
|
+
const content = [];
|
|
1567
|
+
while (i + 1 < lines.length) {
|
|
1568
|
+
i++;
|
|
1569
|
+
const noteLine = lines[i].trim();
|
|
1570
|
+
if (/^end\s+note$/i.test(noteLine)) break;
|
|
1571
|
+
content.push(noteLine);
|
|
1572
|
+
}
|
|
1573
|
+
return content.join("\n").trim();
|
|
1574
|
+
})();
|
|
1550
1575
|
const node = ensureNode(stateId);
|
|
1551
1576
|
if (!node.data.notes) node.data.notes = [];
|
|
1552
1577
|
node.data.notes.push({
|
|
1553
1578
|
position,
|
|
1554
|
-
text
|
|
1579
|
+
text,
|
|
1580
|
+
format: inlineText && inlineText.length > 0 ? "inline" : "block"
|
|
1555
1581
|
});
|
|
1556
1582
|
continue;
|
|
1557
1583
|
}
|
|
@@ -1649,7 +1675,7 @@ function fromMermaidState(input) {
|
|
|
1649
1675
|
}
|
|
1650
1676
|
return {
|
|
1651
1677
|
id: "",
|
|
1652
|
-
|
|
1678
|
+
mode: "directed",
|
|
1653
1679
|
initialNodeId: null,
|
|
1654
1680
|
nodes: Array.from(nodeMap.values()),
|
|
1655
1681
|
edges,
|
|
@@ -1687,9 +1713,9 @@ function toMermaidState(graph) {
|
|
|
1687
1713
|
if (node.data?.isStart || node.data?.isEnd) continue;
|
|
1688
1714
|
if (node.id.includes("_region_")) continue;
|
|
1689
1715
|
if (node.data?.stateType && node.data.stateType !== "parallel") lines.push(`${indent}state ${node.id} <<${node.data.stateType}>>`);
|
|
1690
|
-
if (node.data?.description) lines.push(`${indent}state "${escapeMermaidLabel(node.data.description)}" as ${node.id}`);
|
|
1691
1716
|
if (isParent.has(node.id)) {
|
|
1692
|
-
|
|
1717
|
+
const stateDecl = node.data?.description ? `state "${escapeMermaidLabel(node.data.description)}" as ${node.id} {` : `state ${node.id} {`;
|
|
1718
|
+
lines.push(`${indent}${stateDecl}`);
|
|
1693
1719
|
if (node.data?.direction) {
|
|
1694
1720
|
const mDir = DIRECTION_TO_MERMAID[node.data.direction];
|
|
1695
1721
|
if (mDir) lines.push(`${indent} direction ${mDir}`);
|
|
@@ -1702,8 +1728,12 @@ function toMermaidState(graph) {
|
|
|
1702
1728
|
}
|
|
1703
1729
|
} else writeNodes(node.id, indent + " ");
|
|
1704
1730
|
lines.push(`${indent}}`);
|
|
1705
|
-
}
|
|
1706
|
-
if (node.data?.notes) for (const note of node.data.notes)
|
|
1731
|
+
} else if (node.data?.description) lines.push(`${indent}state "${escapeMermaidLabel(node.data.description)}" as ${node.id}`);
|
|
1732
|
+
if (node.data?.notes) for (const note of node.data.notes) if (note.format === "block" || note.text.includes("\n")) {
|
|
1733
|
+
lines.push(`${indent}note ${note.position} of ${node.id}`);
|
|
1734
|
+
for (const noteLine of note.text.split("\n")) lines.push(`${indent} ${escapeMermaidLabel(noteLine)}`);
|
|
1735
|
+
lines.push(`${indent}end note`);
|
|
1736
|
+
} else lines.push(`${indent}note ${note.position} of ${node.id} : ${escapeMermaidLabel(note.text)}`);
|
|
1707
1737
|
}
|
|
1708
1738
|
}
|
|
1709
1739
|
writeNodes(null, " ");
|
|
@@ -2023,7 +2053,7 @@ function fromMermaidClass(input) {
|
|
|
2023
2053
|
}
|
|
2024
2054
|
return {
|
|
2025
2055
|
id: "",
|
|
2026
|
-
|
|
2056
|
+
mode: "directed",
|
|
2027
2057
|
initialNodeId: null,
|
|
2028
2058
|
nodes: Array.from(nodeMap.values()),
|
|
2029
2059
|
edges,
|
|
@@ -2221,7 +2251,7 @@ function fromMermaidER(input) {
|
|
|
2221
2251
|
}
|
|
2222
2252
|
return {
|
|
2223
2253
|
id: "",
|
|
2224
|
-
|
|
2254
|
+
mode: "directed",
|
|
2225
2255
|
initialNodeId: null,
|
|
2226
2256
|
nodes: Array.from(nodeMap.values()),
|
|
2227
2257
|
edges,
|
|
@@ -2379,7 +2409,7 @@ function fromMermaidMindmap(input) {
|
|
|
2379
2409
|
}
|
|
2380
2410
|
return {
|
|
2381
2411
|
id: "",
|
|
2382
|
-
|
|
2412
|
+
mode: "directed",
|
|
2383
2413
|
initialNodeId: null,
|
|
2384
2414
|
nodes: Array.from(nodeMap.values()),
|
|
2385
2415
|
edges,
|
|
@@ -2578,7 +2608,7 @@ function fromMermaidBlock(input) {
|
|
|
2578
2608
|
}
|
|
2579
2609
|
return {
|
|
2580
2610
|
id: "",
|
|
2581
|
-
|
|
2611
|
+
mode: "directed",
|
|
2582
2612
|
initialNodeId: null,
|
|
2583
2613
|
nodes: Array.from(nodeMap.values()),
|
|
2584
2614
|
edges,
|
|
@@ -2690,7 +2720,7 @@ function fromMermaidIshikawa(input) {
|
|
|
2690
2720
|
}
|
|
2691
2721
|
return {
|
|
2692
2722
|
id: "",
|
|
2693
|
-
|
|
2723
|
+
mode: "directed",
|
|
2694
2724
|
initialNodeId: null,
|
|
2695
2725
|
nodes,
|
|
2696
2726
|
edges,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as createFormatConverter } from "../../converter-
|
|
1
|
+
import { n as createFormatConverter } from "../../converter-udLITX36.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/formats/tgf/index.ts
|
|
4
4
|
/**
|
|
@@ -81,7 +81,7 @@ function fromTGF(tgf) {
|
|
|
81
81
|
}
|
|
82
82
|
return {
|
|
83
83
|
id: "",
|
|
84
|
-
|
|
84
|
+
mode: "directed",
|
|
85
85
|
initialNodeId: null,
|
|
86
86
|
nodes,
|
|
87
87
|
edges,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { F as VisualGraphFormatConverter, M as VisualGraph } from "../../types-3-FS9NV2.mjs";
|
|
2
2
|
import { EdgeBase, NodeBase } from "@xyflow/system";
|
|
3
3
|
|
|
4
4
|
//#region src/formats/xyflow/index.d.ts
|
|
@@ -9,6 +9,7 @@ type XYFlowEdge<TEdgeData extends Record<string, unknown> = Record<string, unkno
|
|
|
9
9
|
interface XYFlow<TNodeData extends Record<string, unknown> = Record<string, unknown>, TEdgeData extends Record<string, unknown> = Record<string, unknown>> {
|
|
10
10
|
nodes: XYFlowNode<TNodeData>[];
|
|
11
11
|
edges: XYFlowEdge<TEdgeData>[];
|
|
12
|
+
data?: Record<string, unknown>;
|
|
12
13
|
}
|
|
13
14
|
/**
|
|
14
15
|
* Converts a visual graph to xyflow (React Flow / Svelte Flow) format.
|
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
//#region src/formats/xyflow/index.ts
|
|
2
|
+
const STATELYAI_METADATA_KEY = "__statelyai";
|
|
3
|
+
function toDataObject(value) {
|
|
4
|
+
return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : {};
|
|
5
|
+
}
|
|
6
|
+
function withMetadata(value, metadata) {
|
|
7
|
+
return {
|
|
8
|
+
...toDataObject(value),
|
|
9
|
+
[STATELYAI_METADATA_KEY]: {
|
|
10
|
+
...value !== void 0 && { data: value },
|
|
11
|
+
...metadata
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function readMetadata(value) {
|
|
16
|
+
if (!value || typeof value !== "object") return void 0;
|
|
17
|
+
const metadata = value[STATELYAI_METADATA_KEY];
|
|
18
|
+
return metadata && typeof metadata === "object" ? metadata : void 0;
|
|
19
|
+
}
|
|
20
|
+
function readUserData(value) {
|
|
21
|
+
const metadata = readMetadata(value);
|
|
22
|
+
if (metadata && "data" in metadata) return metadata.data;
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
2
25
|
/**
|
|
3
26
|
* Converts a visual graph to xyflow (React Flow / Svelte Flow) format.
|
|
4
27
|
*
|
|
@@ -21,6 +44,14 @@
|
|
|
21
44
|
*/
|
|
22
45
|
function toXYFlow(graph) {
|
|
23
46
|
return {
|
|
47
|
+
data: { [STATELYAI_METADATA_KEY]: { graph: {
|
|
48
|
+
id: graph.id,
|
|
49
|
+
mode: graph.mode,
|
|
50
|
+
initialNodeId: graph.initialNodeId,
|
|
51
|
+
data: graph.data,
|
|
52
|
+
direction: graph.direction,
|
|
53
|
+
style: graph.style
|
|
54
|
+
} } },
|
|
24
55
|
nodes: graph.nodes.map((n) => {
|
|
25
56
|
const node = {
|
|
26
57
|
id: n.id,
|
|
@@ -28,12 +59,18 @@ function toXYFlow(graph) {
|
|
|
28
59
|
x: n.x,
|
|
29
60
|
y: n.y
|
|
30
61
|
},
|
|
31
|
-
data: n.data
|
|
62
|
+
data: withMetadata(n.data, { node: {
|
|
63
|
+
initialNodeId: n.initialNodeId,
|
|
64
|
+
label: n.label,
|
|
65
|
+
color: n.color,
|
|
66
|
+
style: n.style,
|
|
67
|
+
ports: n.ports
|
|
68
|
+
} })
|
|
32
69
|
};
|
|
33
70
|
if (n.parentId) node.parentId = n.parentId;
|
|
34
71
|
if (n.shape) node.type = n.shape;
|
|
35
|
-
if (n.width) node.width = n.width;
|
|
36
|
-
if (n.height) node.height = n.height;
|
|
72
|
+
if (n.width !== void 0) node.width = n.width;
|
|
73
|
+
if (n.height !== void 0) node.height = n.height;
|
|
37
74
|
return node;
|
|
38
75
|
}),
|
|
39
76
|
edges: graph.edges.map((e) => {
|
|
@@ -44,11 +81,17 @@ function toXYFlow(graph) {
|
|
|
44
81
|
};
|
|
45
82
|
if (e.sourcePort) edge.sourceHandle = e.sourcePort;
|
|
46
83
|
if (e.targetPort) edge.targetHandle = e.targetPort;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
84
|
+
edge.data = withMetadata(e.data, { edge: {
|
|
85
|
+
label: e.label,
|
|
86
|
+
weight: e.weight,
|
|
87
|
+
color: e.color,
|
|
88
|
+
style: e.style,
|
|
89
|
+
x: e.x,
|
|
90
|
+
y: e.y,
|
|
91
|
+
width: e.width,
|
|
92
|
+
height: e.height
|
|
93
|
+
} });
|
|
94
|
+
if (e.label) edge.data.label = e.label;
|
|
52
95
|
return edge;
|
|
53
96
|
})
|
|
54
97
|
};
|
|
@@ -73,39 +116,53 @@ function fromXYFlow(flow) {
|
|
|
73
116
|
if (!flow || typeof flow !== "object") throw new Error("XYFlow: expected an object");
|
|
74
117
|
if (!Array.isArray(flow.nodes)) throw new Error("XYFlow: \"nodes\" must be an array");
|
|
75
118
|
if (!Array.isArray(flow.edges)) throw new Error("XYFlow: \"edges\" must be an array");
|
|
119
|
+
const graphMetadata = readMetadata(flow.data)?.graph;
|
|
76
120
|
return {
|
|
77
|
-
id: "",
|
|
78
|
-
|
|
79
|
-
initialNodeId: null,
|
|
80
|
-
data: void 0,
|
|
81
|
-
direction: "down",
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
121
|
+
id: graphMetadata?.id?.toString() ?? "",
|
|
122
|
+
mode: graphMetadata?.mode ?? "directed",
|
|
123
|
+
initialNodeId: graphMetadata && "initialNodeId" in graphMetadata ? graphMetadata.initialNodeId : null,
|
|
124
|
+
data: graphMetadata && "data" in graphMetadata ? graphMetadata.data : void 0,
|
|
125
|
+
direction: graphMetadata?.direction ?? "down",
|
|
126
|
+
...graphMetadata?.style !== void 0 && { style: graphMetadata.style },
|
|
127
|
+
nodes: flow.nodes.map((n) => {
|
|
128
|
+
const metadata = readMetadata(n.data)?.node;
|
|
129
|
+
return {
|
|
130
|
+
type: "node",
|
|
131
|
+
id: n.id,
|
|
132
|
+
parentId: n.parentId ?? null,
|
|
133
|
+
initialNodeId: metadata && "initialNodeId" in metadata ? metadata.initialNodeId : null,
|
|
134
|
+
label: metadata && "label" in metadata ? metadata.label : "",
|
|
135
|
+
data: readUserData(n.data),
|
|
136
|
+
x: n.position.x,
|
|
137
|
+
y: n.position.y,
|
|
138
|
+
width: n.measured?.width ?? n.width ?? n.initialWidth ?? 0,
|
|
139
|
+
height: n.measured?.height ?? n.height ?? n.initialHeight ?? 0,
|
|
140
|
+
...n.type && { shape: n.type },
|
|
141
|
+
...metadata?.color !== void 0 && { color: metadata.color },
|
|
142
|
+
...metadata?.style !== void 0 && { style: metadata.style },
|
|
143
|
+
...metadata?.ports !== void 0 && { ports: metadata.ports }
|
|
144
|
+
};
|
|
145
|
+
}),
|
|
146
|
+
edges: flow.edges.map((e, i) => {
|
|
147
|
+
const metadata = readMetadata(e.data)?.edge;
|
|
148
|
+
return {
|
|
149
|
+
type: "edge",
|
|
150
|
+
id: e.id ?? `e${i}`,
|
|
151
|
+
sourceId: e.source,
|
|
152
|
+
targetId: e.target,
|
|
153
|
+
label: metadata && "label" in metadata ? metadata.label : e.data?.label?.toString() ?? "",
|
|
154
|
+
...e.sourceHandle && { sourcePort: e.sourceHandle },
|
|
155
|
+
...e.targetHandle && { targetPort: e.targetHandle },
|
|
156
|
+
data: readUserData(e.data),
|
|
157
|
+
x: metadata?.x ?? 0,
|
|
158
|
+
y: metadata?.y ?? 0,
|
|
159
|
+
width: metadata?.width ?? 0,
|
|
160
|
+
height: metadata?.height ?? 0,
|
|
161
|
+
...metadata?.weight !== void 0 && { weight: metadata.weight },
|
|
162
|
+
...metadata?.color !== void 0 && { color: metadata.color },
|
|
163
|
+
...metadata?.style !== void 0 && { style: metadata.style }
|
|
164
|
+
};
|
|
165
|
+
})
|
|
109
166
|
};
|
|
110
167
|
}
|
|
111
168
|
/**
|