@oh-just-another/importers 0.57.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.
@@ -0,0 +1,146 @@
1
+ import { DEFAULT_LAYER_ID, addLink, addElement, emptyScene, orderBetween, } from "@oh-just-another/scene";
2
+ import { DEFAULT_EDGE_STYLE, DEFAULT_ELEMENT_STYLES, HUE_TONES, } from "@oh-just-another/tokens";
3
+ import { linkId, elementId } from "@oh-just-another/types";
4
+ import { layoutGraph } from "./layout.js";
5
+ /**
6
+ * Convert a backend-neutral `GraphDocument` into a `Scene`. Runs layout
7
+ * (`layoutGraph`) first, then materialises each node as a built-in shape
8
+ * and each edge as a `straight`-routed connector between named anchors.
9
+ *
10
+ * Scene viewport size is fitted around the layouted bounding box plus a
11
+ * small margin so the result looks centered when handed to the renderer.
12
+ */
13
+ export const graphToScene = (graph) => {
14
+ const { nodes, edges } = layoutGraph(graph);
15
+ let scene = emptyScene();
16
+ let order = orderBetween(null, null);
17
+ // Track shape ids so edge endpoints can reference them later.
18
+ const idMap = new Map();
19
+ for (const n of nodes) {
20
+ const id = elementId(`node-${n.id}`);
21
+ idMap.set(n.id, id);
22
+ const fill = n.fill ?? defaultFill(n.shape);
23
+ const stroke = n.stroke ?? HUE_TONES.light.gray.textHigh;
24
+ // Identity / placement / order — fields every shape variant accepts.
25
+ const base = {
26
+ id,
27
+ layerId: DEFAULT_LAYER_ID,
28
+ position: n.position,
29
+ rotation: 0,
30
+ scale: { x: 1, y: 1 },
31
+ order,
32
+ style: { fill, stroke, strokeWidth: 1.5 },
33
+ };
34
+ order = orderBetween(order, null);
35
+ let shape;
36
+ switch (n.shape ?? "rectangle") {
37
+ case "ellipse":
38
+ case "round":
39
+ shape = { ...base, type: "ellipse", width: n.width, height: n.height };
40
+ break;
41
+ case "diamond":
42
+ shape = {
43
+ ...base,
44
+ type: "polygon",
45
+ points: [
46
+ { x: n.width / 2, y: 0 },
47
+ { x: n.width, y: n.height / 2 },
48
+ { x: n.width / 2, y: n.height },
49
+ { x: 0, y: n.height / 2 },
50
+ ],
51
+ };
52
+ break;
53
+ case "rectangle":
54
+ default:
55
+ shape = { ...base, type: "rectangle", width: n.width, height: n.height };
56
+ break;
57
+ }
58
+ ({ scene } = addElement(scene, shape));
59
+ if (n.label) {
60
+ const textId = elementId(`node-${n.id}-label`);
61
+ const textElement = {
62
+ id: textId,
63
+ layerId: DEFAULT_LAYER_ID,
64
+ type: "text",
65
+ position: { x: n.position.x, y: n.position.y },
66
+ rotation: 0,
67
+ scale: { x: 1, y: 1 },
68
+ order,
69
+ style: {
70
+ fill: HUE_TONES.light.gray.textHigh,
71
+ textAlign: "center",
72
+ textBaseline: "middle",
73
+ },
74
+ text: n.label,
75
+ fontFamily: "system-ui, sans-serif",
76
+ fontSize: 13,
77
+ maxWidth: n.width,
78
+ };
79
+ order = orderBetween(order, null);
80
+ // Center inside the node by writing position to the box centre.
81
+ const centeredLabel = {
82
+ ...textElement,
83
+ position: { x: n.position.x + n.width / 2, y: n.position.y + n.height / 2 },
84
+ };
85
+ ({ scene } = addElement(scene, centeredLabel));
86
+ }
87
+ }
88
+ // Links → straight-line connectors between node anchors.
89
+ let edgeOrder = orderBetween(null, null);
90
+ for (const e of edges) {
91
+ const sourceId = idMap.get(e.source);
92
+ const targetId = idMap.get(e.target);
93
+ if (!sourceId || !targetId)
94
+ continue;
95
+ const id = linkId(`edge-${e.source}-${e.target}`);
96
+ const edgeShape = {
97
+ id,
98
+ layerId: DEFAULT_LAYER_ID,
99
+ from: { kind: "anchor", elementId: sourceId, anchor: { kind: "named", name: "center" } },
100
+ to: { kind: "anchor", elementId: targetId, anchor: { kind: "named", name: "center" } },
101
+ style: { ...DEFAULT_EDGE_STYLE, strokeWidth: 1 },
102
+ order: edgeOrder,
103
+ ...(e.label !== undefined ? { metadata: { label: e.label } } : {}),
104
+ };
105
+ edgeOrder = orderBetween(edgeOrder, null);
106
+ ({ scene } = addLink(scene, edgeShape));
107
+ }
108
+ // Fit the viewport around the laid-out nodes plus a margin so callers
109
+ // get something sensible to render without extra computation.
110
+ const margin = 20;
111
+ let minX = Infinity;
112
+ let minY = Infinity;
113
+ let maxX = -Infinity;
114
+ let maxY = -Infinity;
115
+ for (const n of nodes) {
116
+ if (n.position.x < minX)
117
+ minX = n.position.x;
118
+ if (n.position.y < minY)
119
+ minY = n.position.y;
120
+ if (n.position.x + n.width > maxX)
121
+ maxX = n.position.x + n.width;
122
+ if (n.position.y + n.height > maxY)
123
+ maxY = n.position.y + n.height;
124
+ }
125
+ const width = Number.isFinite(maxX) && Number.isFinite(minX)
126
+ ? Math.ceil(maxX - Math.min(0, minX)) + margin
127
+ : 800;
128
+ const height = Number.isFinite(maxY) && Number.isFinite(minY)
129
+ ? Math.ceil(maxY - Math.min(0, minY)) + margin
130
+ : 600;
131
+ scene = { ...scene, viewport: { ...scene.viewport, size: { width, height } } };
132
+ return scene;
133
+ };
134
+ const defaultFill = (shape) => {
135
+ switch (shape) {
136
+ case "ellipse":
137
+ case "round":
138
+ return DEFAULT_ELEMENT_STYLES.sticky.fill;
139
+ case "diamond":
140
+ return DEFAULT_ELEMENT_STYLES.flowchart.fill;
141
+ case "rectangle":
142
+ default:
143
+ return DEFAULT_ELEMENT_STYLES.rectangle.fill;
144
+ }
145
+ };
146
+ //# sourceMappingURL=to-scene.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to-scene.js","sourceRoot":"","sources":["../src/to-scene.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@oh-just-another/importers",
3
+ "version": "0.57.0",
4
+ "description": "Importers: Mermaid, Graphviz dot, drawio XML → @oh-just-another/scene documents.",
5
+ "license": "MIT",
6
+ "author": "Rustam Garifulin <rustam@n69.in>",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/oh-just-another/diagram.git",
10
+ "directory": "packages/importers"
11
+ },
12
+ "homepage": "https://github.com/oh-just-another/diagram#readme",
13
+ "bugs": "https://github.com/oh-just-another/diagram/issues",
14
+ "keywords": [
15
+ "diagram",
16
+ "canvas",
17
+ "svg",
18
+ "editor",
19
+ "graph",
20
+ "drawing"
21
+ ],
22
+ "type": "module",
23
+ "main": "./dist/index.js",
24
+ "module": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js"
30
+ }
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "README.md",
35
+ "CHANGELOG.md"
36
+ ],
37
+ "sideEffects": false,
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "dependencies": {
42
+ "@dagrejs/dagre": "^1.1.5",
43
+ "@oh-just-another/types": "0.57.0",
44
+ "@oh-just-another/scene": "0.57.0",
45
+ "@oh-just-another/tokens": "0.57.0"
46
+ },
47
+ "scripts": {
48
+ "build": "tsc -b tsconfig.build.json",
49
+ "typecheck": "tsc --noEmit",
50
+ "test": "vitest run",
51
+ "test:watch": "vitest",
52
+ "lint": "eslint src tests",
53
+ "clean": "rm -rf dist *.tsbuildinfo"
54
+ }
55
+ }