@thi.ng/dot 2.1.49 → 2.1.50
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/CHANGELOG.md +1 -1
- package/api.js +0 -1
- package/package.json +8 -5
- package/serialize.js +96 -93
package/CHANGELOG.md
CHANGED
package/api.js
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/dot",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.50",
|
|
4
4
|
"description": "Graphviz document abstraction & serialization to DOT format",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
"author": "Karsten Schmidt (https://thi.ng)",
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "yarn
|
|
27
|
+
"build": "yarn build:esbuild && yarn build:decl",
|
|
28
|
+
"build:decl": "tsc --declaration --emitDeclarationOnly",
|
|
29
|
+
"build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
|
|
28
30
|
"clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc",
|
|
29
31
|
"doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
|
|
30
32
|
"doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
|
|
@@ -33,11 +35,12 @@
|
|
|
33
35
|
"test": "bun test"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
36
|
-
"@thi.ng/api": "^8.9.
|
|
37
|
-
"@thi.ng/checks": "^3.4.
|
|
38
|
+
"@thi.ng/api": "^8.9.12",
|
|
39
|
+
"@thi.ng/checks": "^3.4.12"
|
|
38
40
|
},
|
|
39
41
|
"devDependencies": {
|
|
40
42
|
"@microsoft/api-extractor": "^7.38.3",
|
|
43
|
+
"esbuild": "^0.19.8",
|
|
41
44
|
"rimraf": "^5.0.5",
|
|
42
45
|
"tools": "^0.0.1",
|
|
43
46
|
"typedoc": "^0.25.4",
|
|
@@ -82,5 +85,5 @@
|
|
|
82
85
|
"status": "beta",
|
|
83
86
|
"year": 2018
|
|
84
87
|
},
|
|
85
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "5e7bafedfc3d53bc131469a28de31dd8e5b4a3ff\n"
|
|
86
89
|
}
|
package/serialize.js
CHANGED
|
@@ -4,110 +4,113 @@ const nextSubgraphID = () => "cluster" + nextID++;
|
|
|
4
4
|
const wrapQ = (x) => `"${x}"`;
|
|
5
5
|
const escape = (x) => String(x).replace(/\"/g, `\\"`).replace(/\n/g, "\\n");
|
|
6
6
|
const formatGraphAttribs = (attribs, acc) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
acc.push(`${a}="${escape(v)}";`);
|
|
7
|
+
for (let a in attribs) {
|
|
8
|
+
let v = attribs[a];
|
|
9
|
+
switch (a) {
|
|
10
|
+
case "bgcolor":
|
|
11
|
+
case "color":
|
|
12
|
+
case "fillcolor":
|
|
13
|
+
case "fontcolor":
|
|
14
|
+
isArray(v) && (v = v.join(","));
|
|
15
|
+
break;
|
|
16
|
+
case "edge":
|
|
17
|
+
acc.push(`edge[${formatAttribs(v)}];`);
|
|
18
|
+
continue;
|
|
19
|
+
case "node":
|
|
20
|
+
acc.push(`node[${formatAttribs(v)}];`);
|
|
21
|
+
continue;
|
|
22
|
+
default:
|
|
23
|
+
break;
|
|
26
24
|
}
|
|
27
|
-
|
|
25
|
+
acc.push(`${a}="${escape(v)}";`);
|
|
26
|
+
}
|
|
27
|
+
return acc;
|
|
28
28
|
};
|
|
29
29
|
const formatAttribs = (attribs) => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
break;
|
|
44
|
-
case "url":
|
|
45
|
-
a = "URL";
|
|
46
|
-
break;
|
|
47
|
-
case "ins":
|
|
48
|
-
case "outs":
|
|
49
|
-
case "src":
|
|
50
|
-
case "dest":
|
|
51
|
-
case "srcPort":
|
|
52
|
-
case "destPort":
|
|
53
|
-
continue;
|
|
54
|
-
default:
|
|
30
|
+
const acc = [];
|
|
31
|
+
for (let a in attribs) {
|
|
32
|
+
let v = attribs[a];
|
|
33
|
+
switch (a) {
|
|
34
|
+
case "color":
|
|
35
|
+
case "fillcolor":
|
|
36
|
+
case "fontcolor":
|
|
37
|
+
isArray(v) && (v = v.join(","));
|
|
38
|
+
break;
|
|
39
|
+
case "label":
|
|
40
|
+
if (attribs.ins || attribs.outs) {
|
|
41
|
+
v = formatPortLabel(attribs, v);
|
|
55
42
|
}
|
|
56
|
-
|
|
43
|
+
break;
|
|
44
|
+
case "url":
|
|
45
|
+
a = "URL";
|
|
46
|
+
break;
|
|
47
|
+
case "ins":
|
|
48
|
+
case "outs":
|
|
49
|
+
case "src":
|
|
50
|
+
case "dest":
|
|
51
|
+
case "srcPort":
|
|
52
|
+
case "destPort":
|
|
53
|
+
continue;
|
|
54
|
+
default:
|
|
57
55
|
}
|
|
58
|
-
|
|
56
|
+
acc.push(`${a}="${escape(v)}"`);
|
|
57
|
+
}
|
|
58
|
+
return acc.join(", ");
|
|
59
59
|
};
|
|
60
60
|
const formatPorts = (ports) => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
const acc = [];
|
|
62
|
+
for (let i in ports) {
|
|
63
|
+
acc.push(`<${i}> ${escape(ports[i])}`);
|
|
64
|
+
}
|
|
65
|
+
return `{ ${acc.join(" | ")} }`;
|
|
66
66
|
};
|
|
67
67
|
const formatPortLabel = (node, label) => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
const acc = [];
|
|
69
|
+
node.ins && acc.push(formatPorts(node.ins));
|
|
70
|
+
acc.push(escape(label));
|
|
71
|
+
node.outs && acc.push(formatPorts(node.outs));
|
|
72
|
+
return acc.join(" | ");
|
|
73
73
|
};
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
const serializeNode = (id, n) => {
|
|
75
|
+
const attribs = formatAttribs(n);
|
|
76
|
+
return attribs.length ? `"${id}"[${attribs}];` : `"${id}";`;
|
|
77
77
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
78
|
+
const serializeEdge = (e, directed = true) => {
|
|
79
|
+
const acc = [wrapQ(e.src)];
|
|
80
|
+
e.srcPort != null && acc.push(":", wrapQ(e.srcPort));
|
|
81
|
+
acc.push(directed ? " -> " : " -- ");
|
|
82
|
+
acc.push(wrapQ(e.dest));
|
|
83
|
+
e.destPort != null && acc.push(":", wrapQ(e.destPort));
|
|
84
|
+
const attribs = formatAttribs(e);
|
|
85
|
+
attribs.length && acc.push("[", attribs, "]");
|
|
86
|
+
acc.push(";");
|
|
87
|
+
return acc.join("");
|
|
88
88
|
};
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
89
|
+
const serializeGraph = (graph, isSub = false) => {
|
|
90
|
+
const directed = graph.directed !== false;
|
|
91
|
+
const acc = isSub ? [`subgraph ${graph.id || nextSubgraphID()} {`] : [`${directed ? "di" : ""}graph ${graph.id || "g"} {`];
|
|
92
|
+
if (graph.include) {
|
|
93
|
+
acc.push(graph.include);
|
|
94
|
+
}
|
|
95
|
+
if (graph.attribs) {
|
|
96
|
+
formatGraphAttribs(graph.attribs, acc);
|
|
97
|
+
}
|
|
98
|
+
for (let id in graph.nodes) {
|
|
99
|
+
acc.push(serializeNode(id, graph.nodes[id]));
|
|
100
|
+
}
|
|
101
|
+
for (let e of graph.edges) {
|
|
102
|
+
acc.push(serializeEdge(e, directed));
|
|
103
|
+
}
|
|
104
|
+
if (graph.sub) {
|
|
105
|
+
for (let sub of graph.sub) {
|
|
106
|
+
acc.push(serializeGraph(sub, true));
|
|
102
107
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
acc.push("}");
|
|
112
|
-
return acc.join("\n");
|
|
108
|
+
}
|
|
109
|
+
acc.push("}");
|
|
110
|
+
return acc.join("\n");
|
|
111
|
+
};
|
|
112
|
+
export {
|
|
113
|
+
serializeEdge,
|
|
114
|
+
serializeGraph,
|
|
115
|
+
serializeNode
|
|
113
116
|
};
|