@statelyai/graph 0.1.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 +191 -0
- package/dist/adjacency-list-CXpOCibq.mjs +49 -0
- package/dist/adjacency-list-DW-lAUe8.d.mts +10 -0
- package/dist/algorithms-R35X6ro4.mjs +1197 -0
- package/dist/algorithms.d.mts +82 -0
- package/dist/algorithms.mjs +3 -0
- package/dist/dot-BRtq3e3c.mjs +59 -0
- package/dist/dot-HmJeUMsj.d.mts +6 -0
- package/dist/edge-list-BRujEnnU.mjs +39 -0
- package/dist/edge-list-CJmfoNu2.d.mts +10 -0
- package/dist/formats/adjacency-list.d.mts +2 -0
- package/dist/formats/adjacency-list.mjs +3 -0
- package/dist/formats/dot.d.mts +2 -0
- package/dist/formats/dot.mjs +3 -0
- package/dist/formats/edge-list.d.mts +2 -0
- package/dist/formats/edge-list.mjs +3 -0
- package/dist/formats/graphml.d.mts +2 -0
- package/dist/formats/graphml.mjs +3 -0
- package/dist/graphml-CMjPzSfY.d.mts +7 -0
- package/dist/graphml-CUTNRXqd.mjs +240 -0
- package/dist/index.d.mts +142 -0
- package/dist/index.mjs +356 -0
- package/dist/indexing-BHg1VhqN.mjs +93 -0
- package/dist/queries.d.mts +37 -0
- package/dist/queries.mjs +221 -0
- package/dist/schemas.d.mts +46 -0
- package/dist/schemas.mjs +30 -0
- package/dist/types-XV3S5Jnh.d.mts +219 -0
- package/package.json +77 -0
- package/schemas/edge.schema.json +32 -0
- package/schemas/graph.schema.json +96 -0
- package/schemas/node.schema.json +35 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { b as SinglePathOptions, c as Graph, f as GraphNode, g as MSTOptions, m as GraphPath, t as AllPairsShortestPathsOptions, x as TraversalOptions, y as PathOptions } from "./types-XV3S5Jnh.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/algorithms.d.ts
|
|
4
|
+
declare function bfs<N>(graph: Graph<N>, startId: string): Generator<GraphNode<N>>;
|
|
5
|
+
declare function dfs<N>(graph: Graph<N>, startId: string): Generator<GraphNode<N>>;
|
|
6
|
+
declare function isAcyclic(graph: Graph): boolean;
|
|
7
|
+
declare function getConnectedComponents<N>(graph: Graph<N>): GraphNode<N>[][];
|
|
8
|
+
declare function getTopologicalSort<N>(graph: Graph<N>): GraphNode<N>[] | null;
|
|
9
|
+
declare function hasPath(graph: Graph, sourceId: string, targetId: string): boolean;
|
|
10
|
+
declare function isConnected(graph: Graph): boolean;
|
|
11
|
+
declare function isTree(graph: Graph): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Lazily yields all shortest paths from a source node.
|
|
14
|
+
* Use `getShortestPaths` for the full array.
|
|
15
|
+
*/
|
|
16
|
+
declare function genShortestPaths<N, E>(graph: Graph<N, E>, opts?: PathOptions<E>): Generator<GraphPath<N, E>>;
|
|
17
|
+
declare function getShortestPaths<N, E>(graph: Graph<N, E>, opts?: PathOptions<E>): GraphPath<N, E>[];
|
|
18
|
+
/**
|
|
19
|
+
* Returns a single shortest path from source to target, or undefined if unreachable.
|
|
20
|
+
*/
|
|
21
|
+
declare function getShortestPath<N, E>(graph: Graph<N, E>, opts: SinglePathOptions<E>): GraphPath<N, E> | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Returns all simple (acyclic) paths from a source node.
|
|
24
|
+
* Uses DFS with backtracking.
|
|
25
|
+
*/
|
|
26
|
+
declare function getSimplePaths<N, E>(graph: Graph<N, E>, opts?: PathOptions<E>): GraphPath<N, E>[];
|
|
27
|
+
/**
|
|
28
|
+
* Lazily yields all simple (acyclic) paths from a source node.
|
|
29
|
+
* Use `getSimplePaths` for the full array.
|
|
30
|
+
*/
|
|
31
|
+
declare function genSimplePaths<N, E>(graph: Graph<N, E>, opts?: PathOptions<E>): Generator<GraphPath<N, E>>;
|
|
32
|
+
/**
|
|
33
|
+
* Returns a single simple (acyclic) path from source to target, or undefined if unreachable.
|
|
34
|
+
*/
|
|
35
|
+
declare function getSimplePath<N, E>(graph: Graph<N, E>, opts: SinglePathOptions<E>): GraphPath<N, E> | undefined;
|
|
36
|
+
declare function getStronglyConnectedComponents<N>(graph: Graph<N>): GraphNode<N>[][];
|
|
37
|
+
declare function getCycles<N, E>(graph: Graph<N, E>): GraphPath<N, E>[];
|
|
38
|
+
/**
|
|
39
|
+
* Lazily yields cycles one at a time.
|
|
40
|
+
* Use `getCycles` for the full array.
|
|
41
|
+
*/
|
|
42
|
+
declare function genCycles<N, E>(graph: Graph<N, E>): Generator<GraphPath<N, E>>;
|
|
43
|
+
/**
|
|
44
|
+
* Returns a single canonical preorder (DFS visit-order) sequence.
|
|
45
|
+
* Visits neighbors in the order they appear in the adjacency list.
|
|
46
|
+
*/
|
|
47
|
+
declare function getPreorder<N>(graph: Graph<N>, opts?: TraversalOptions): GraphNode<N>[];
|
|
48
|
+
/**
|
|
49
|
+
* Returns a single canonical postorder (DFS finish-order) sequence.
|
|
50
|
+
* Visits neighbors in the order they appear in the adjacency list.
|
|
51
|
+
*/
|
|
52
|
+
declare function getPostorder<N>(graph: Graph<N>, opts?: TraversalOptions): GraphNode<N>[];
|
|
53
|
+
/** Returns all possible preorder sequences as an array. Can be exponential — prefer `genPreorders`. */
|
|
54
|
+
declare function getPreorders<N>(graph: Graph<N>, opts?: TraversalOptions): GraphNode<N>[][];
|
|
55
|
+
/** Returns all possible postorder sequences as an array. Can be exponential — prefer `genPostorders`. */
|
|
56
|
+
declare function getPostorders<N>(graph: Graph<N>, opts?: TraversalOptions): GraphNode<N>[][];
|
|
57
|
+
/**
|
|
58
|
+
* Lazily yields all possible preorder (DFS visit-order) sequences.
|
|
59
|
+
* Different neighbor exploration orders yield different sequences.
|
|
60
|
+
* Use `getPreorder()` for a single canonical ordering.
|
|
61
|
+
*/
|
|
62
|
+
declare function genPreorders<N>(graph: Graph<N>, opts?: TraversalOptions): Generator<GraphNode<N>[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Lazily yields all possible postorder (DFS finish-order) sequences.
|
|
65
|
+
* Different neighbor exploration orders yield different sequences.
|
|
66
|
+
* Use `getPostorder()` for a single canonical ordering.
|
|
67
|
+
*/
|
|
68
|
+
declare function genPostorders<N>(graph: Graph<N>, opts?: TraversalOptions): Generator<GraphNode<N>[]>;
|
|
69
|
+
/**
|
|
70
|
+
* Returns a minimum spanning tree of the graph.
|
|
71
|
+
* Only meaningful for connected undirected graphs (or the component reachable
|
|
72
|
+
* from an arbitrary start node in directed graphs).
|
|
73
|
+
*/
|
|
74
|
+
declare function getMinimumSpanningTree<N, E>(graph: Graph<N, E>, opts?: MSTOptions<E>): Graph<N, E>;
|
|
75
|
+
/**
|
|
76
|
+
* Returns shortest paths between all pairs of nodes.
|
|
77
|
+
* Algorithm 'dijkstra' (default): runs getShortestPaths per source node.
|
|
78
|
+
* Algorithm 'floyd-warshall': classic O(V³) dynamic programming.
|
|
79
|
+
*/
|
|
80
|
+
declare function getAllPairsShortestPaths<N, E>(graph: Graph<N, E>, opts?: AllPairsShortestPathsOptions<E>): GraphPath<N, E>[];
|
|
81
|
+
//#endregion
|
|
82
|
+
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 };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { C as isAcyclic, 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-R35X6ro4.mjs";
|
|
2
|
+
|
|
3
|
+
export { bfs, dfs, genCycles, genPostorders, genPreorders, genShortestPaths, genSimplePaths, getAllPairsShortestPaths, getConnectedComponents, getCycles, getMinimumSpanningTree, getPostorder, getPostorders, getPreorder, getPreorders, getShortestPath, getShortestPaths, getSimplePath, getSimplePaths, getStronglyConnectedComponents, getTopologicalSort, hasPath, isAcyclic, isConnected, isTree };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//#region src/formats/dot.ts
|
|
2
|
+
/** Escape a DOT identifier */
|
|
3
|
+
function escapeId(id) {
|
|
4
|
+
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(id)) return id;
|
|
5
|
+
return `"${id.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
6
|
+
}
|
|
7
|
+
/** Escape a DOT label string */
|
|
8
|
+
function escapeLabel(label) {
|
|
9
|
+
return label.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
10
|
+
}
|
|
11
|
+
const DIRECTION_TO_RANKDIR = {
|
|
12
|
+
down: "TB",
|
|
13
|
+
up: "BT",
|
|
14
|
+
right: "LR",
|
|
15
|
+
left: "RL"
|
|
16
|
+
};
|
|
17
|
+
const SHAPE_TO_DOT = {
|
|
18
|
+
rectangle: "box",
|
|
19
|
+
ellipse: "ellipse",
|
|
20
|
+
circle: "circle",
|
|
21
|
+
diamond: "diamond",
|
|
22
|
+
hexagon: "hexagon",
|
|
23
|
+
cylinder: "cylinder",
|
|
24
|
+
parallelogram: "parallelogram"
|
|
25
|
+
};
|
|
26
|
+
function toDOT(graph) {
|
|
27
|
+
const isDirected = graph.type === "directed";
|
|
28
|
+
const keyword = isDirected ? "digraph" : "graph";
|
|
29
|
+
const edgeOp = isDirected ? "->" : "--";
|
|
30
|
+
const lines = [];
|
|
31
|
+
lines.push(`${keyword} ${escapeId(graph.id)} {`);
|
|
32
|
+
if (graph.direction) {
|
|
33
|
+
const rankdir = DIRECTION_TO_RANKDIR[graph.direction] ?? "TB";
|
|
34
|
+
lines.push(` rankdir=${rankdir};`);
|
|
35
|
+
}
|
|
36
|
+
for (const node of graph.nodes) {
|
|
37
|
+
const attrs = [];
|
|
38
|
+
if (node.label) attrs.push(`label="${escapeLabel(node.label)}"`);
|
|
39
|
+
if (node.shape) {
|
|
40
|
+
const dotShape = SHAPE_TO_DOT[node.shape] ?? node.shape;
|
|
41
|
+
attrs.push(`shape=${dotShape}`);
|
|
42
|
+
}
|
|
43
|
+
if (node.color) attrs.push(`fillcolor="${escapeLabel(node.color)}" style=filled`);
|
|
44
|
+
if (attrs.length > 0) lines.push(` ${escapeId(node.id)} [${attrs.join(", ")}];`);
|
|
45
|
+
else lines.push(` ${escapeId(node.id)};`);
|
|
46
|
+
}
|
|
47
|
+
for (const edge of graph.edges) {
|
|
48
|
+
const attrs = [];
|
|
49
|
+
if (edge.label) attrs.push(`label="${escapeLabel(edge.label)}"`);
|
|
50
|
+
if (edge.color) attrs.push(`color="${escapeLabel(edge.color)}"`);
|
|
51
|
+
const attrStr = attrs.length > 0 ? ` [${attrs.join(", ")}]` : "";
|
|
52
|
+
lines.push(` ${escapeId(edge.sourceId)} ${edgeOp} ${escapeId(edge.targetId)}${attrStr};`);
|
|
53
|
+
}
|
|
54
|
+
lines.push("}");
|
|
55
|
+
return lines.join("\n");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
export { toDOT as t };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/formats/edge-list.ts
|
|
2
|
+
function toEdgeList(graph) {
|
|
3
|
+
return graph.edges.map((e) => [e.sourceId, e.targetId]);
|
|
4
|
+
}
|
|
5
|
+
function fromEdgeList(edges, options) {
|
|
6
|
+
const directed = options?.directed ?? true;
|
|
7
|
+
const nodeIds = /* @__PURE__ */ new Set();
|
|
8
|
+
for (const [source, target] of edges) {
|
|
9
|
+
nodeIds.add(source);
|
|
10
|
+
nodeIds.add(target);
|
|
11
|
+
}
|
|
12
|
+
const nodes = [...nodeIds].map((id) => ({
|
|
13
|
+
type: "node",
|
|
14
|
+
id,
|
|
15
|
+
parentId: null,
|
|
16
|
+
initialNodeId: null,
|
|
17
|
+
label: "",
|
|
18
|
+
data: void 0
|
|
19
|
+
}));
|
|
20
|
+
const edgeObjects = edges.map(([sourceId, targetId], i) => ({
|
|
21
|
+
type: "edge",
|
|
22
|
+
id: `e${i}`,
|
|
23
|
+
sourceId,
|
|
24
|
+
targetId,
|
|
25
|
+
label: "",
|
|
26
|
+
data: void 0
|
|
27
|
+
}));
|
|
28
|
+
return {
|
|
29
|
+
id: options?.id ?? "",
|
|
30
|
+
type: directed ? "directed" : "undirected",
|
|
31
|
+
initialNodeId: null,
|
|
32
|
+
nodes,
|
|
33
|
+
edges: edgeObjects,
|
|
34
|
+
data: void 0
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
export { toEdgeList as n, fromEdgeList as t };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { c as Graph } from "./types-XV3S5Jnh.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/formats/edge-list.d.ts
|
|
4
|
+
declare function toEdgeList(graph: Graph): [string, string][];
|
|
5
|
+
declare function fromEdgeList(edges: [string, string][], options?: {
|
|
6
|
+
directed?: boolean;
|
|
7
|
+
id?: string;
|
|
8
|
+
}): Graph;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { toEdgeList as n, fromEdgeList as t };
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { XMLBuilder, XMLParser } from "fast-xml-parser";
|
|
2
|
+
|
|
3
|
+
//#region src/formats/graphml.ts
|
|
4
|
+
const GRAPHML_NS = "http://graphml.graphdrawing.org/xmlns";
|
|
5
|
+
function toGraphML(graph) {
|
|
6
|
+
const keys = [
|
|
7
|
+
{
|
|
8
|
+
"@_id": "label",
|
|
9
|
+
"@_for": "all",
|
|
10
|
+
"@_attr.name": "label",
|
|
11
|
+
"@_attr.type": "string"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"@_id": "parentId",
|
|
15
|
+
"@_for": "node",
|
|
16
|
+
"@_attr.name": "parentId",
|
|
17
|
+
"@_attr.type": "string"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"@_id": "data",
|
|
21
|
+
"@_for": "all",
|
|
22
|
+
"@_attr.name": "data",
|
|
23
|
+
"@_attr.type": "string"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"@_id": "graphData",
|
|
27
|
+
"@_for": "graph",
|
|
28
|
+
"@_attr.name": "data",
|
|
29
|
+
"@_attr.type": "string"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"@_id": "x",
|
|
33
|
+
"@_for": "all",
|
|
34
|
+
"@_attr.name": "x",
|
|
35
|
+
"@_attr.type": "double"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"@_id": "y",
|
|
39
|
+
"@_for": "all",
|
|
40
|
+
"@_attr.name": "y",
|
|
41
|
+
"@_attr.type": "double"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"@_id": "width",
|
|
45
|
+
"@_for": "all",
|
|
46
|
+
"@_attr.name": "width",
|
|
47
|
+
"@_attr.type": "double"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"@_id": "height",
|
|
51
|
+
"@_for": "all",
|
|
52
|
+
"@_attr.name": "height",
|
|
53
|
+
"@_attr.type": "double"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"@_id": "shape",
|
|
57
|
+
"@_for": "node",
|
|
58
|
+
"@_attr.name": "shape",
|
|
59
|
+
"@_attr.type": "string"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"@_id": "color",
|
|
63
|
+
"@_for": "all",
|
|
64
|
+
"@_attr.name": "color",
|
|
65
|
+
"@_attr.type": "string"
|
|
66
|
+
}
|
|
67
|
+
];
|
|
68
|
+
const nodes = graph.nodes.map((n) => {
|
|
69
|
+
const data = [];
|
|
70
|
+
if (n.label) data.push({
|
|
71
|
+
"@_key": "label",
|
|
72
|
+
"#text": n.label
|
|
73
|
+
});
|
|
74
|
+
if (n.parentId !== null) data.push({
|
|
75
|
+
"@_key": "parentId",
|
|
76
|
+
"#text": n.parentId
|
|
77
|
+
});
|
|
78
|
+
if (n.data !== void 0) data.push({
|
|
79
|
+
"@_key": "data",
|
|
80
|
+
"#text": JSON.stringify(n.data)
|
|
81
|
+
});
|
|
82
|
+
if (n.x !== void 0) data.push({
|
|
83
|
+
"@_key": "x",
|
|
84
|
+
"#text": n.x
|
|
85
|
+
});
|
|
86
|
+
if (n.y !== void 0) data.push({
|
|
87
|
+
"@_key": "y",
|
|
88
|
+
"#text": n.y
|
|
89
|
+
});
|
|
90
|
+
if (n.width !== void 0) data.push({
|
|
91
|
+
"@_key": "width",
|
|
92
|
+
"#text": n.width
|
|
93
|
+
});
|
|
94
|
+
if (n.height !== void 0) data.push({
|
|
95
|
+
"@_key": "height",
|
|
96
|
+
"#text": n.height
|
|
97
|
+
});
|
|
98
|
+
if (n.shape) data.push({
|
|
99
|
+
"@_key": "shape",
|
|
100
|
+
"#text": n.shape
|
|
101
|
+
});
|
|
102
|
+
if (n.color) data.push({
|
|
103
|
+
"@_key": "color",
|
|
104
|
+
"#text": n.color
|
|
105
|
+
});
|
|
106
|
+
return {
|
|
107
|
+
"@_id": n.id,
|
|
108
|
+
...data.length > 0 && { data }
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
const edges = graph.edges.map((e) => {
|
|
112
|
+
const data = [];
|
|
113
|
+
if (e.label) data.push({
|
|
114
|
+
"@_key": "label",
|
|
115
|
+
"#text": e.label
|
|
116
|
+
});
|
|
117
|
+
if (e.data !== void 0) data.push({
|
|
118
|
+
"@_key": "data",
|
|
119
|
+
"#text": JSON.stringify(e.data)
|
|
120
|
+
});
|
|
121
|
+
if (e.x !== void 0) data.push({
|
|
122
|
+
"@_key": "x",
|
|
123
|
+
"#text": e.x
|
|
124
|
+
});
|
|
125
|
+
if (e.y !== void 0) data.push({
|
|
126
|
+
"@_key": "y",
|
|
127
|
+
"#text": e.y
|
|
128
|
+
});
|
|
129
|
+
if (e.width !== void 0) data.push({
|
|
130
|
+
"@_key": "width",
|
|
131
|
+
"#text": e.width
|
|
132
|
+
});
|
|
133
|
+
if (e.height !== void 0) data.push({
|
|
134
|
+
"@_key": "height",
|
|
135
|
+
"#text": e.height
|
|
136
|
+
});
|
|
137
|
+
if (e.color) data.push({
|
|
138
|
+
"@_key": "color",
|
|
139
|
+
"#text": e.color
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
"@_id": e.id,
|
|
143
|
+
"@_source": e.sourceId,
|
|
144
|
+
"@_target": e.targetId,
|
|
145
|
+
...data.length > 0 && { data }
|
|
146
|
+
};
|
|
147
|
+
});
|
|
148
|
+
const graphData = [];
|
|
149
|
+
if (graph.data !== void 0) graphData.push({
|
|
150
|
+
"@_key": "graphData",
|
|
151
|
+
"#text": JSON.stringify(graph.data)
|
|
152
|
+
});
|
|
153
|
+
const obj = {
|
|
154
|
+
"?xml": {
|
|
155
|
+
"@_version": "1.0",
|
|
156
|
+
"@_encoding": "UTF-8"
|
|
157
|
+
},
|
|
158
|
+
graphml: {
|
|
159
|
+
"@_xmlns": GRAPHML_NS,
|
|
160
|
+
key: keys,
|
|
161
|
+
graph: {
|
|
162
|
+
"@_id": graph.id,
|
|
163
|
+
"@_edgedefault": graph.type === "directed" ? "directed" : "undirected",
|
|
164
|
+
...graphData.length > 0 && { data: graphData },
|
|
165
|
+
node: nodes,
|
|
166
|
+
edge: edges
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
return new XMLBuilder({
|
|
171
|
+
ignoreAttributes: false,
|
|
172
|
+
format: true,
|
|
173
|
+
suppressEmptyNode: true
|
|
174
|
+
}).build(obj);
|
|
175
|
+
}
|
|
176
|
+
function fromGraphML(xml) {
|
|
177
|
+
const graphEl = new XMLParser({
|
|
178
|
+
ignoreAttributes: false,
|
|
179
|
+
isArray: (name) => [
|
|
180
|
+
"node",
|
|
181
|
+
"edge",
|
|
182
|
+
"data",
|
|
183
|
+
"key"
|
|
184
|
+
].includes(name)
|
|
185
|
+
}).parse(xml).graphml.graph;
|
|
186
|
+
const graphType = graphEl["@_edgedefault"] === "undirected" ? "undirected" : "directed";
|
|
187
|
+
let graphData = void 0;
|
|
188
|
+
if (graphEl.data) {
|
|
189
|
+
for (const d of asArray(graphEl.data)) if (d["@_key"] === "graphData") graphData = tryParseJSON(String(d["#text"]));
|
|
190
|
+
}
|
|
191
|
+
const nodes = asArray(graphEl.node).map((n) => {
|
|
192
|
+
const dataMap = parseDataElements(n.data);
|
|
193
|
+
return {
|
|
194
|
+
type: "node",
|
|
195
|
+
id: String(n["@_id"]),
|
|
196
|
+
parentId: dataMap.parentId ?? null,
|
|
197
|
+
initialNodeId: dataMap.initialNodeId ?? null,
|
|
198
|
+
label: dataMap.label ?? "",
|
|
199
|
+
data: dataMap.data !== void 0 ? tryParseJSON(dataMap.data) : void 0
|
|
200
|
+
};
|
|
201
|
+
});
|
|
202
|
+
const edges = asArray(graphEl.edge).map((e) => {
|
|
203
|
+
const dataMap = parseDataElements(e.data);
|
|
204
|
+
return {
|
|
205
|
+
type: "edge",
|
|
206
|
+
id: String(e["@_id"]),
|
|
207
|
+
sourceId: String(e["@_source"]),
|
|
208
|
+
targetId: String(e["@_target"]),
|
|
209
|
+
label: dataMap.label ?? "",
|
|
210
|
+
data: dataMap.data !== void 0 ? tryParseJSON(dataMap.data) : void 0
|
|
211
|
+
};
|
|
212
|
+
});
|
|
213
|
+
return {
|
|
214
|
+
id: String(graphEl["@_id"] ?? ""),
|
|
215
|
+
type: graphType,
|
|
216
|
+
initialNodeId: null,
|
|
217
|
+
nodes,
|
|
218
|
+
edges,
|
|
219
|
+
data: graphData
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function asArray(val) {
|
|
223
|
+
if (val === void 0) return [];
|
|
224
|
+
return Array.isArray(val) ? val : [val];
|
|
225
|
+
}
|
|
226
|
+
function parseDataElements(dataEls) {
|
|
227
|
+
const map = {};
|
|
228
|
+
for (const d of asArray(dataEls)) if (d && d["@_key"]) map[d["@_key"]] = String(d["#text"] ?? "");
|
|
229
|
+
return map;
|
|
230
|
+
}
|
|
231
|
+
function tryParseJSON(str) {
|
|
232
|
+
try {
|
|
233
|
+
return JSON.parse(str);
|
|
234
|
+
} catch {
|
|
235
|
+
return str;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
//#endregion
|
|
240
|
+
export { toGraphML as n, fromGraphML as t };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { C as VisualGraph, S as VisualEdge, T as VisualNode, _ as NodeChange, a as EntitiesConfig, b as SinglePathOptions, c as Graph, d as GraphEdge, f as GraphNode, g as MSTOptions, h as GraphStep, i as EdgeConfig, l as GraphConfig, m as GraphPath, n as DeleteNodeOptions, o as EntitiesUpdate, p as GraphPatch, r as EdgeChange, s as EntityRect, t as AllPairsShortestPathsOptions, u as GraphDiff, v as NodeConfig, w as VisualGraphConfig, x as TraversalOptions, y as PathOptions } from "./types-XV3S5Jnh.mjs";
|
|
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 } from "./algorithms.mjs";
|
|
3
|
+
import { n as toAdjacencyList, t as fromAdjacencyList } from "./adjacency-list-DW-lAUe8.mjs";
|
|
4
|
+
import { t as toDOT } from "./dot-HmJeUMsj.mjs";
|
|
5
|
+
import { n as toEdgeList, t as fromEdgeList } from "./edge-list-CJmfoNu2.mjs";
|
|
6
|
+
import { n as toGraphML, t as fromGraphML } from "./graphml-CMjPzSfY.mjs";
|
|
7
|
+
import { EdgeSchema, GraphSchema, NodeSchema } from "./schemas.mjs";
|
|
8
|
+
import { getAncestors, getChildren, getDegree, getDepth, getDescendants, getEdgeBetween, getEdgesOf, getInDegree, getInEdges, getLCA, getNeighbors, getOutDegree, getOutEdges, getParent, getPredecessors, getRoots, getSiblings, getSinks, getSources, getSuccessors, isCompound, isLeaf } from "./queries.mjs";
|
|
9
|
+
|
|
10
|
+
//#region src/graph.d.ts
|
|
11
|
+
/** Create a graph from a config. Resolves defaults for all fields. */
|
|
12
|
+
declare function createGraph<N = any, E = any, G = any>(config?: GraphConfig<N, E, G>): Graph<N, E, G>;
|
|
13
|
+
/** Create a visual graph with required position/size on all nodes and edges. */
|
|
14
|
+
declare function createVisualGraph<N = any, E = any, G = any>(config?: VisualGraphConfig<N, E, G>): VisualGraph<N, E, G>;
|
|
15
|
+
/** Get a node by id, or `undefined` if not found. */
|
|
16
|
+
declare function getNode<N>(graph: Graph<N>, id: string): GraphNode<N> | undefined;
|
|
17
|
+
/** Get an edge by id, or `undefined` if not found. */
|
|
18
|
+
declare function getEdge<E>(graph: Graph<any, E>, id: string): GraphEdge<E> | undefined;
|
|
19
|
+
/** Check if a node exists in the graph. */
|
|
20
|
+
declare function hasNode(graph: Graph, id: string): boolean;
|
|
21
|
+
/** Check if an edge exists in the graph. */
|
|
22
|
+
declare function hasEdge(graph: Graph, id: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* **Mutable.** Add a node to the graph. Mutates `graph.nodes` in place.
|
|
25
|
+
* @returns The resolved node that was added.
|
|
26
|
+
*/
|
|
27
|
+
declare function addNode<N>(graph: Graph<N>, config: NodeConfig<N>): GraphNode<N>;
|
|
28
|
+
/**
|
|
29
|
+
* **Mutable.** Add an edge to the graph. Mutates `graph.edges` in place.
|
|
30
|
+
* @returns The resolved edge that was added.
|
|
31
|
+
*/
|
|
32
|
+
declare function addEdge<E>(graph: Graph<any, E>, config: EdgeConfig<E>): GraphEdge<E>;
|
|
33
|
+
/**
|
|
34
|
+
* **Mutable.** Delete a node and its connected edges. Mutates `graph.nodes`
|
|
35
|
+
* and `graph.edges` in place.
|
|
36
|
+
*
|
|
37
|
+
* By default, children are deleted recursively.
|
|
38
|
+
* With `{ reparent: true }`, children are re-parented to the deleted node's parent.
|
|
39
|
+
*/
|
|
40
|
+
declare function deleteNode(graph: Graph, id: string, opts?: DeleteNodeOptions): void;
|
|
41
|
+
/**
|
|
42
|
+
* **Mutable.** Delete an edge. Mutates `graph.edges` in place.
|
|
43
|
+
*/
|
|
44
|
+
declare function deleteEdge(graph: Graph, id: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* **Mutable.** Update a node in place.
|
|
47
|
+
* @returns The updated node.
|
|
48
|
+
*/
|
|
49
|
+
declare function updateNode<N>(graph: Graph<N>, id: string, update: Partial<Omit<NodeConfig<N>, 'id'>>): GraphNode<N>;
|
|
50
|
+
/**
|
|
51
|
+
* **Mutable.** Update an edge in place.
|
|
52
|
+
* @returns The updated edge.
|
|
53
|
+
*/
|
|
54
|
+
declare function updateEdge<E>(graph: Graph<any, E>, id: string, update: Partial<Omit<EdgeConfig<E>, 'id'>>): GraphEdge<E>;
|
|
55
|
+
/**
|
|
56
|
+
* **Mutable.** Add multiple nodes and edges to the graph.
|
|
57
|
+
* Nodes are added first, then edges (so edges can reference new nodes).
|
|
58
|
+
*/
|
|
59
|
+
declare function addEntities<N, E>(graph: Graph<N, E>, entities: EntitiesConfig<N, E>): void;
|
|
60
|
+
/**
|
|
61
|
+
* **Mutable.** Delete entities by id(s). Automatically detects whether each id
|
|
62
|
+
* is a node or edge. Node deletions cascade to children and connected edges.
|
|
63
|
+
*/
|
|
64
|
+
declare function deleteEntities(graph: Graph, ids: string | string[], opts?: DeleteNodeOptions): void;
|
|
65
|
+
/**
|
|
66
|
+
* **Mutable.** Update multiple nodes and edges in place.
|
|
67
|
+
* Each entry must include an `id` to identify which entity to update.
|
|
68
|
+
*/
|
|
69
|
+
declare function updateEntities<N, E>(graph: Graph<N, E>, updates: EntitiesUpdate<N, E>): void;
|
|
70
|
+
/**
|
|
71
|
+
* OOP wrapper around a plain `Graph` object.
|
|
72
|
+
* Delegates to the standalone mutable functions.
|
|
73
|
+
*/
|
|
74
|
+
declare class GraphInstance<N = any, E = any, G = any> {
|
|
75
|
+
graph: Graph<N, E, G>;
|
|
76
|
+
constructor(config?: GraphConfig<N, E, G>);
|
|
77
|
+
/** Wrap an existing plain graph object. */
|
|
78
|
+
static from<N = any, E = any, G = any>(graph: Graph<N, E, G>): GraphInstance<N, E, G>;
|
|
79
|
+
get id(): string;
|
|
80
|
+
get type(): "directed" | "undirected";
|
|
81
|
+
get nodes(): GraphNode<N>[];
|
|
82
|
+
get edges(): GraphEdge<E>[];
|
|
83
|
+
get data(): G;
|
|
84
|
+
getNode(id: string): GraphNode<N> | undefined;
|
|
85
|
+
getEdge(id: string): GraphEdge<E> | undefined;
|
|
86
|
+
hasNode(id: string): boolean;
|
|
87
|
+
hasEdge(id: string): boolean;
|
|
88
|
+
addNode(config: NodeConfig<N>): GraphNode<N>;
|
|
89
|
+
addEdge(config: EdgeConfig<E>): GraphEdge<E>;
|
|
90
|
+
deleteNode(id: string, opts?: DeleteNodeOptions): void;
|
|
91
|
+
deleteEdge(id: string): void;
|
|
92
|
+
updateNode(id: string, update: Partial<Omit<NodeConfig<N>, 'id'>>): GraphNode<N>;
|
|
93
|
+
updateEdge(id: string, update: Partial<Omit<EdgeConfig<E>, 'id'>>): GraphEdge<E>;
|
|
94
|
+
addEntities(entities: EntitiesConfig<N, E>): void;
|
|
95
|
+
deleteEntities(ids: string | string[], opts?: DeleteNodeOptions): void;
|
|
96
|
+
updateEntities(updates: EntitiesUpdate<N, E>): void;
|
|
97
|
+
toJSON(): Graph<N, E, G>;
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/indexing.d.ts
|
|
101
|
+
/** Clear the cached index. Call this if you mutate graph.nodes/edges directly. */
|
|
102
|
+
declare function invalidateIndex(graph: Graph): void;
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/diff.d.ts
|
|
105
|
+
/** Compute a structured diff from graph `a` to graph `b` by matching IDs. */
|
|
106
|
+
declare function getDiff<N, E>(a: Graph<N, E>, b: Graph<N, E>): GraphDiff<N, E>;
|
|
107
|
+
/** Check if a diff has zero changes. */
|
|
108
|
+
declare function isEmptyDiff(diff: GraphDiff): boolean;
|
|
109
|
+
/** Invert a diff: swap added↔removed, swap old↔new in updates. */
|
|
110
|
+
declare function invertDiff<N, E>(diff: GraphDiff<N, E>): GraphDiff<N, E>;
|
|
111
|
+
/**
|
|
112
|
+
* Compute an ordered patch list from graph `a` to graph `b`.
|
|
113
|
+
* Order: delete edges → delete nodes → add nodes → add edges → update nodes → update edges.
|
|
114
|
+
*/
|
|
115
|
+
declare function getPatches<N, E>(a: Graph<N, E>, b: Graph<N, E>): GraphPatch<N, E>[];
|
|
116
|
+
/**
|
|
117
|
+
* **Mutable.** Apply patches to a graph in order.
|
|
118
|
+
* Delegates to addNode/deleteNode/updateNode/addEdge/deleteEdge/updateEdge.
|
|
119
|
+
*/
|
|
120
|
+
declare function applyPatches<N, E>(graph: Graph<N, E>, patches: GraphPatch<N, E>[]): void;
|
|
121
|
+
/**
|
|
122
|
+
* Flatten a structured diff into an ordered patch list.
|
|
123
|
+
* Order: add nodes → update edges → delete edges → delete nodes → add edges → update nodes.
|
|
124
|
+
* This avoids cascading deletes removing edges that are being updated,
|
|
125
|
+
* and ensures new nodes exist before edges reference them.
|
|
126
|
+
*/
|
|
127
|
+
declare function toPatches<N, E>(diff: GraphDiff<N, E>): GraphPatch<N, E>[];
|
|
128
|
+
/** Group a patch list into a structured diff. */
|
|
129
|
+
declare function toDiff<N, E>(patches: GraphPatch<N, E>[]): GraphDiff<N, E>;
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/transforms.d.ts
|
|
132
|
+
/**
|
|
133
|
+
* Flattens a hierarchical graph into a flat graph with only leaf nodes.
|
|
134
|
+
*
|
|
135
|
+
* - Edges targeting a compound node resolve to its initial child (recursively).
|
|
136
|
+
* - Edges originating from a compound node expand to all leaf descendants.
|
|
137
|
+
* - Only leaf nodes (nodes with no children) appear in the result.
|
|
138
|
+
* - Duplicate edges (same source + target) are deduplicated.
|
|
139
|
+
*/
|
|
140
|
+
declare function flatten<N, E, G>(graph: Graph<N, E, G>): Graph<N, E, G>;
|
|
141
|
+
//#endregion
|
|
142
|
+
export { type AllPairsShortestPathsOptions, type DeleteNodeOptions, type EdgeChange, type EdgeConfig, EdgeSchema, type EntitiesConfig, type EntitiesUpdate, type Graph, type GraphConfig, type GraphDiff, type GraphEdge, GraphInstance, type GraphNode, type GraphPatch, type GraphPath, GraphSchema, type GraphStep, type MSTOptions, type NodeChange, type NodeConfig, NodeSchema, type PathOptions, type EntityRect as Positioned, type SinglePathOptions, type TraversalOptions, type VisualEdge, type VisualGraph, type VisualGraphConfig, type VisualNode, addEdge, addEntities, addNode, applyPatches, bfs, createGraph, createVisualGraph, deleteEdge, deleteEntities, deleteNode, dfs, flatten, fromAdjacencyList, fromEdgeList, fromGraphML, genCycles, genPostorders, genPreorders, genShortestPaths, genSimplePaths, getAllPairsShortestPaths, getAncestors, getChildren, getConnectedComponents, getCycles, getDegree, getDepth, getDescendants, getDiff, getEdge, getEdgeBetween, getEdgesOf, getInDegree, getInEdges, getLCA, getMinimumSpanningTree, getNeighbors, getNode, getOutDegree, getOutEdges, getParent, getPatches, getPostorder, getPostorders, getPredecessors, getPreorder, getPreorders, getRoots, getShortestPath, getShortestPaths, getSiblings, getSimplePath, getSimplePaths, getSinks, getSources, getStronglyConnectedComponents, getSuccessors, getTopologicalSort, hasEdge, hasNode, hasPath, invalidateIndex, invertDiff, isAcyclic, isCompound, isConnected, isEmptyDiff, isLeaf, isTree, toAdjacencyList, toDOT, toDiff, toEdgeList, toGraphML, toPatches, updateEdge, updateEntities, updateNode };
|