@draftably/runtime 0.1.0 → 0.3.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 +25 -40
- package/dist/assets/render.worker-dvseyGmC.js +8310 -0
- package/dist/compile-Csfz4rk4.js +7267 -0
- package/dist/element.js +21 -12
- package/dist/{font-data-DbrpaYkG.js → font-data-DLXJur0j.js} +1 -1
- package/dist/graph.js +669 -0
- package/dist/index.js +5 -4
- package/dist/render-Dgo42PR4.js +1146 -0
- package/dist/types/src/dsl/compile.d.ts +13 -0
- package/dist/types/src/dsl/corridors.d.ts +38 -0
- package/dist/types/src/graph-api/core.d.ts +125 -0
- package/dist/types/src/graph-api/cytoscape.d.ts +48 -0
- package/dist/types/src/graph-api/dagre.d.ts +33 -0
- package/dist/types/src/graph-api/elk.d.ts +91 -0
- package/dist/types/src/graph-api/index.d.ts +60 -0
- package/dist/types/src/graph-api/react-flow.d.ts +100 -0
- package/dist/types/src/graph-api/transform.d.ts +6 -0
- package/dist/types/src/model/types.d.ts +9 -0
- package/dist/types/src/runtime/element.d.ts +2 -0
- package/dist/types/src/runtime/viewer.d.ts +5 -0
- package/dist/viewer.css +20 -0
- package/dist/viewer.js +101 -99
- package/package.json +9 -5
- package/dist/assets/render.worker-BpUp6NY_.js +0 -7618
- package/dist/render-BOAZBzVa.js +0 -7633
package/dist/viewer.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { r as ce
|
|
2
|
-
import {
|
|
1
|
+
import { r as ce } from "./render-Dgo42PR4.js";
|
|
2
|
+
import { a as ke } from "./render-Dgo42PR4.js";
|
|
3
|
+
import { F as ee } from "./compile-Csfz4rk4.js";
|
|
4
|
+
import { h as Ae } from "./compile-Csfz4rk4.js";
|
|
3
5
|
const de = "http://www.w3.org/2000/svg", le = new Set(
|
|
4
6
|
"svg title desc metadata defs style marker g a path rect ellipse circle line polyline polygon text tspan".split(
|
|
5
7
|
" "
|
|
@@ -13,25 +15,25 @@ let me = 0;
|
|
|
13
15
|
function ue(y, c) {
|
|
14
16
|
const V = new y.defaultView.DOMParser().parseFromString(c, "image/svg+xml"), s = /* @__PURE__ */ new Map();
|
|
15
17
|
for (const v of Array.from(V.querySelectorAll("text[font-family]"))) {
|
|
16
|
-
const
|
|
17
|
-
if (!Object.values(ee).some((o) => o.family ===
|
|
18
|
+
const l = (v.getAttribute("font-family") ?? "").split(",")[0].trim().replace(/^['"]|['"]$/g, ""), b = v.getAttribute("font-weight") ?? "400";
|
|
19
|
+
if (!Object.values(ee).some((o) => o.family === l && String(o.weight) === b))
|
|
18
20
|
throw new Error("Runtime SVG requested an unknown bundled font face.");
|
|
19
|
-
s.set(`${
|
|
21
|
+
s.set(`${l}:${b}`, { family: l, weight: b });
|
|
20
22
|
}
|
|
21
23
|
return [...s.values()];
|
|
22
24
|
}
|
|
23
25
|
function we(y, c, V) {
|
|
24
26
|
const s = new y.defaultView.DOMParser().parseFromString(c, "image/svg+xml"), v = /* @__PURE__ */ new Map();
|
|
25
|
-
for (const
|
|
26
|
-
const b =
|
|
27
|
+
for (const l of Array.from(s.querySelectorAll("style"))) {
|
|
28
|
+
const b = l.textContent ?? "";
|
|
27
29
|
for (const [, o] of b.matchAll(/@font-face\s*\{([^{}]{1,200000})\}/g)) {
|
|
28
|
-
const
|
|
29
|
-
!
|
|
30
|
+
const f = /font-family\s*:\s*['"]([^'"]+)['"]/i.exec(o)?.[1], w = /font-weight\s*:\s*(\d{1,4})/i.exec(o)?.[1], p = /src\s*:\s*url\((data:font\/woff2;base64,[A-Za-z0-9+/=]+)\)/i.exec(o)?.[1];
|
|
31
|
+
!f || !w || !p || Object.values(ee).some((m) => m.family === f && String(m.weight) === w) && v.set(`${f}:${w}`, { family: f, weight: w, data: p });
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
|
-
return V.map((
|
|
33
|
-
const b = v.get(`${
|
|
34
|
-
if (!b) throw new Error(`Embedded font ${
|
|
34
|
+
return V.map((l) => {
|
|
35
|
+
const b = v.get(`${l.family}:${l.weight}`);
|
|
36
|
+
if (!b) throw new Error(`Embedded font ${l.family} ${l.weight} is missing.`);
|
|
35
37
|
return b;
|
|
36
38
|
});
|
|
37
39
|
}
|
|
@@ -39,37 +41,37 @@ function ge(y, c, V, s = 1e5) {
|
|
|
39
41
|
const v = new y.defaultView.DOMParser().parseFromString(c, "image/svg+xml");
|
|
40
42
|
if (v.querySelector("parsererror") || v.documentElement.localName !== "svg")
|
|
41
43
|
throw new Error("Runtime returned invalid SVG.");
|
|
42
|
-
const
|
|
43
|
-
Array.from(v.querySelectorAll("[id]"), (
|
|
44
|
+
const l = new Set(
|
|
45
|
+
Array.from(v.querySelectorAll("[id]"), (f) => f.getAttribute("id") ?? "")
|
|
44
46
|
);
|
|
45
47
|
let b = 0;
|
|
46
|
-
const o = (
|
|
47
|
-
if (++b > s || !le.has(
|
|
48
|
+
const o = (f) => {
|
|
49
|
+
if (++b > s || !le.has(f.localName))
|
|
48
50
|
throw new Error("Runtime SVG exceeded the allowed drawing vocabulary.");
|
|
49
|
-
const w = y.createElementNS(de,
|
|
50
|
-
for (const { name: p, value:
|
|
51
|
+
const w = y.createElementNS(de, f.localName);
|
|
52
|
+
for (const { name: p, value: m } of Array.from(f.attributes)) {
|
|
51
53
|
if (/^on/i.test(p)) continue;
|
|
52
54
|
if (p === "href") {
|
|
53
|
-
if (
|
|
55
|
+
if (f.localName !== "a") continue;
|
|
54
56
|
try {
|
|
55
|
-
const a = new URL(
|
|
57
|
+
const a = new URL(m, y.baseURI);
|
|
56
58
|
(a.protocol === "http:" || a.protocol === "https:") && w.setAttribute("href", a.href);
|
|
57
59
|
} catch {
|
|
58
60
|
}
|
|
59
61
|
continue;
|
|
60
62
|
}
|
|
61
63
|
if (!fe.has(p) && !/^data-[a-z0-9-]+$/.test(p)) continue;
|
|
62
|
-
const x = [...
|
|
63
|
-
/url\s*\(/i.test(
|
|
64
|
+
const x = [...m.matchAll(/url\(#([^)]*)\)/g)].map((a) => a[1]);
|
|
65
|
+
/url\s*\(/i.test(m) && (x.length === 0 || x.some((a) => !l.has(a))) || p === "aria-labelledby" && m.split(/\s+/).some((a) => !l.has(a)) || w.setAttribute(p, m);
|
|
64
66
|
}
|
|
65
|
-
|
|
66
|
-
for (const p of Array.from(
|
|
67
|
+
f.localName === "a" && w.getAttribute("target") === "_blank" && w.setAttribute("rel", "noopener noreferrer");
|
|
68
|
+
for (const p of Array.from(f.childNodes))
|
|
67
69
|
if (p.nodeType === 1) w.append(o(p));
|
|
68
70
|
else if (p.nodeType === 3) {
|
|
69
|
-
const
|
|
71
|
+
const m = p.nodeValue ?? "";
|
|
70
72
|
w.append(
|
|
71
73
|
y.createTextNode(
|
|
72
|
-
|
|
74
|
+
f.localName === "style" && V ? m.replace(/@font-face\s*\{[^{}]*\}/g, "") : m
|
|
73
75
|
)
|
|
74
76
|
);
|
|
75
77
|
}
|
|
@@ -84,27 +86,27 @@ function K(y, c, V) {
|
|
|
84
86
|
diagnostics: [{ code: c, severity: "error", message: V, itemIds: [] }]
|
|
85
87
|
};
|
|
86
88
|
}
|
|
87
|
-
function
|
|
89
|
+
function be(y, c = {}) {
|
|
88
90
|
const V = y?.ownerDocument?.defaultView;
|
|
89
91
|
if (!V || !(y instanceof V.HTMLElement))
|
|
90
92
|
throw new TypeError("host must be an HTMLElement.");
|
|
91
93
|
if (y.childNodes.length) throw new Error("Viewer host must be empty and exclusively owned.");
|
|
92
94
|
if ((c.execution ?? { mode: "worker" }).mode === "worker" && c.render?.links?.mode === "safe" && c.render.links.resolve)
|
|
93
95
|
throw new TypeError('A link resolver requires execution: { mode: "main" }.');
|
|
94
|
-
const s = y.ownerDocument, v = V,
|
|
95
|
-
|
|
96
|
+
const s = y.ownerDocument, v = V, l = s.createElement("section");
|
|
97
|
+
l.className = "draft-viewer", c.outline !== "visible" && l.classList.add("draft-viewer--outline-hidden"), l.setAttribute("aria-label", c.label ?? "Diagram viewer");
|
|
96
98
|
const b = s.createElement("div");
|
|
97
99
|
b.className = "draft-viewer__toolbar", b.setAttribute("role", "toolbar"), b.setAttribute("aria-label", "Diagram controls");
|
|
98
100
|
const o = s.createElement("div");
|
|
99
101
|
o.className = "draft-viewer__viewport", o.tabIndex = 0, o.setAttribute("aria-label", c.label ?? "Diagram");
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
+
const f = s.createElement("p");
|
|
103
|
+
f.className = "draft-viewer__status", f.setAttribute("role", "status"), f.setAttribute("aria-live", "polite");
|
|
102
104
|
const w = s.createElement("ol");
|
|
103
|
-
w.className = "draft-viewer__outline", w.setAttribute("aria-label", "Diagram outline"),
|
|
105
|
+
w.className = "draft-viewer__outline", w.setAttribute("aria-label", "Diagram outline"), l.append(b, o, f, w), y.append(l);
|
|
104
106
|
const p = `draftViewer${(++me).toString(36)}${Math.random().toString(36).slice(2, 9)}`;
|
|
105
|
-
let
|
|
106
|
-
const
|
|
107
|
-
for (const t of
|
|
107
|
+
let m = 0, x = !1, a = { centerX: 0, centerY: 0, zoom: 1 }, _ = !1, u, C, q, te = 0;
|
|
108
|
+
const N = /* @__PURE__ */ new Map(), U = /* @__PURE__ */ new Map(), B = /* @__PURE__ */ new Map(), L = (e, r) => {
|
|
109
|
+
for (const t of U.get(e) ?? [])
|
|
108
110
|
try {
|
|
109
111
|
t(r);
|
|
110
112
|
} catch {
|
|
@@ -130,19 +132,19 @@ function ve(y, c = {}) {
|
|
|
130
132
|
centerX: t + g / 2,
|
|
131
133
|
centerY: S + n / 2,
|
|
132
134
|
zoom: Math.min(1, re() * 0.92)
|
|
133
|
-
},
|
|
135
|
+
}, _ = !1, R(), L("camera", { camera: { ...a }, reason: e });
|
|
134
136
|
}, P = (e) => {
|
|
135
|
-
a.zoom = Math.max(0.02, Math.min(8, a.zoom * e)),
|
|
137
|
+
a.zoom = Math.max(0.02, Math.min(8, a.zoom * e)), _ = !0, R(), L("camera", { camera: { ...a }, reason: "user" });
|
|
136
138
|
}, ne = () => {
|
|
137
|
-
a.zoom = 1,
|
|
139
|
+
a.zoom = 1, _ = !0, R(), L("camera", { camera: { ...a }, reason: "user" });
|
|
138
140
|
};
|
|
139
141
|
c.toolbar !== !1 && (j("Zoom in", () => P(1.2)), j("Zoom out", () => P(1 / 1.2)), j("Fit diagram", () => Y()), j("Actual size", ne));
|
|
140
142
|
const J = new v.ResizeObserver(() => {
|
|
141
|
-
u && !o.getBoundingClientRect().width || (
|
|
143
|
+
u && !o.getBoundingClientRect().width || (_ ? R() : Y("resize"));
|
|
142
144
|
});
|
|
143
145
|
J.observe(o);
|
|
144
146
|
const X = (e, r) => {
|
|
145
|
-
|
|
147
|
+
f.textContent = r.map((t) => t.message).join(" "), l.classList.add("draft-viewer--stale"), L("diagnostics", { revision: e, diagnostics: r, stale: !!u });
|
|
146
148
|
}, oe = async (e, r) => {
|
|
147
149
|
const t = ue(s, e);
|
|
148
150
|
if (!t.length) return [];
|
|
@@ -161,9 +163,9 @@ function ve(y, c = {}) {
|
|
|
161
163
|
if (!g) throw new Error("The browser cannot load embedded diagram fonts.");
|
|
162
164
|
return Promise.all(
|
|
163
165
|
S.map(async (n) => {
|
|
164
|
-
const h = `${n.family}:${n.weight}`,
|
|
165
|
-
if (
|
|
166
|
-
return { key: h, face:
|
|
166
|
+
const h = `${n.family}:${n.weight}`, F = N.get(h);
|
|
167
|
+
if (F?.status === "loaded" && Array.from(s.fonts).includes(F))
|
|
168
|
+
return { key: h, face: F };
|
|
167
169
|
const d = new g(n.family, `url("${n.data}")`, { weight: n.weight });
|
|
168
170
|
if (await d.load(), d.status !== "loaded")
|
|
169
171
|
throw new Error(`Embedded font ${n.family} ${n.weight} did not load.`);
|
|
@@ -171,34 +173,34 @@ function ve(y, c = {}) {
|
|
|
171
173
|
})
|
|
172
174
|
);
|
|
173
175
|
}, z = (e) => {
|
|
174
|
-
const r =
|
|
175
|
-
|
|
176
|
+
const r = q;
|
|
177
|
+
q = void 0, r && (v.clearTimeout(r.timer), r.cleanup(), r.finish(void 0, e ?? new Error("Viewer render was cancelled."))), C?.terminate(), C = void 0;
|
|
176
178
|
}, ae = (e, r, t) => (c.execution ?? { mode: "worker" }).mode === "main" ? ce(e, { ...r, signal: t }) : new Promise((S, g) => {
|
|
177
179
|
const n = ++te;
|
|
178
180
|
let h = !1;
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
+
const F = () => {
|
|
182
|
+
C && (C.removeEventListener("message", E), C.removeEventListener("error", W), C.removeEventListener("messageerror", G), t?.removeEventListener("abort", H));
|
|
181
183
|
}, d = (k, D) => {
|
|
182
184
|
if (h) return;
|
|
183
185
|
h = !0;
|
|
184
|
-
const i =
|
|
185
|
-
i?.id === n && (
|
|
186
|
+
const i = q;
|
|
187
|
+
i?.id === n && (q = void 0, v.clearTimeout(i.timer), i.cleanup()), D ? g(D) : S(k);
|
|
186
188
|
}, E = (k) => {
|
|
187
189
|
k.data?.id === n && d(k.data.result);
|
|
188
190
|
}, W = (k) => {
|
|
189
191
|
k.preventDefault(), z(new Error(k.message || "Viewer render worker failed."));
|
|
190
|
-
},
|
|
192
|
+
}, G = () => z(new Error("Viewer render worker returned an unreadable result.")), H = () => z(new Error("Viewer render was aborted."));
|
|
191
193
|
try {
|
|
192
|
-
|
|
194
|
+
C ??= c.execution?.mode === "worker" && c.execution.createWorker ? c.execution.createWorker() : new Worker(new URL(
|
|
193
195
|
/* @vite-ignore */
|
|
194
|
-
"" + new URL("assets/render.worker-
|
|
196
|
+
"" + new URL("assets/render.worker-dvseyGmC.js", import.meta.url).href,
|
|
195
197
|
import.meta.url
|
|
196
|
-
), { type: "module" }),
|
|
198
|
+
), { type: "module" }), C.addEventListener("message", E), C.addEventListener("error", W), C.addEventListener("messageerror", G), t?.addEventListener("abort", H, { once: !0 });
|
|
197
199
|
const k = c.execution?.mode === "worker" ? c.execution.timeoutMs ?? 5e3 : 5e3, D = v.setTimeout(
|
|
198
200
|
() => z(new Error("Viewer render worker timed out.")),
|
|
199
201
|
k
|
|
200
202
|
);
|
|
201
|
-
|
|
203
|
+
q = { id: n, timer: D, finish: d, cleanup: F }, C.postMessage({ id: n, source: e, options: r });
|
|
202
204
|
} catch (k) {
|
|
203
205
|
z(
|
|
204
206
|
k instanceof Error ? k : new Error("Viewer render worker could not start.")
|
|
@@ -226,7 +228,7 @@ function ve(y, c = {}) {
|
|
|
226
228
|
scale: a.zoom
|
|
227
229
|
}, o.setPointerCapture(e.pointerId));
|
|
228
230
|
}), o.addEventListener("pointermove", (e) => {
|
|
229
|
-
A && (a.centerX = A.centerX - (e.clientX - A.x) / A.scale, a.centerY = A.centerY - (e.clientY - A.y) / A.scale,
|
|
231
|
+
A && (a.centerX = A.centerX - (e.clientX - A.x) / A.scale, a.centerY = A.centerY - (e.clientY - A.y) / A.scale, _ = !0, R());
|
|
230
232
|
});
|
|
231
233
|
const Q = () => {
|
|
232
234
|
if (A) {
|
|
@@ -250,41 +252,41 @@ function ve(y, c = {}) {
|
|
|
250
252
|
return;
|
|
251
253
|
}
|
|
252
254
|
const S = r?.closest("[data-id]")?.getAttribute("data-id"), g = u?.items.find((n) => n.id === S);
|
|
253
|
-
g && L("itemactivate", { id: g.id, kind: g.kind, input: "pointer", revision:
|
|
255
|
+
g && L("itemactivate", { id: g.id, kind: g.kind, input: "pointer", revision: m });
|
|
254
256
|
}), o.addEventListener("keydown", (e) => {
|
|
255
257
|
e.target !== o || e.altKey || e.ctrlKey || e.metaKey || (e.key === "+" || e.key === "=" ? P(1.2) : e.key === "-" ? P(1 / 1.2) : e.key.toLowerCase() === "f" && Y());
|
|
256
258
|
});
|
|
257
259
|
const se = (e, r) => {
|
|
258
|
-
for (const [t, S] of
|
|
260
|
+
for (const [t, S] of B)
|
|
259
261
|
t !== e && S.resolve({ status: r, revision: t });
|
|
260
262
|
};
|
|
261
263
|
return {
|
|
262
264
|
update: (e, r = {}) => {
|
|
263
|
-
const t = ++
|
|
265
|
+
const t = ++m;
|
|
264
266
|
return x ? Promise.resolve({ status: "destroyed", revision: t }) : (se(t, "superseded"), z(new Error("Viewer update was superseded.")), new Promise((S) => {
|
|
265
267
|
let g = !1;
|
|
266
268
|
const n = (d) => {
|
|
267
269
|
if (g) return;
|
|
268
|
-
g = !0, r.signal?.removeEventListener("abort", h),
|
|
269
|
-
const E = x ? { status: "destroyed", revision: t } : t !==
|
|
270
|
+
g = !0, r.signal?.removeEventListener("abort", h), B.delete(t);
|
|
271
|
+
const E = x ? { status: "destroyed", revision: t } : t !== m ? { status: "superseded", revision: t } : r.signal?.aborted ? { status: "aborted", revision: t } : d;
|
|
270
272
|
S(E);
|
|
271
273
|
}, h = () => {
|
|
272
|
-
t ===
|
|
274
|
+
t === m && (c.execution ?? { mode: "worker" }).mode === "worker" && z(new Error("Viewer render was aborted.")), n({ status: "aborted", revision: t });
|
|
273
275
|
};
|
|
274
|
-
if (
|
|
276
|
+
if (B.set(t, { resolve: n }), r.signal?.aborted) {
|
|
275
277
|
h();
|
|
276
278
|
return;
|
|
277
279
|
}
|
|
278
280
|
r.signal?.addEventListener("abort", h, { once: !0 });
|
|
279
|
-
const
|
|
281
|
+
const F = {
|
|
280
282
|
...c.render ?? {},
|
|
281
283
|
target: "inline",
|
|
282
284
|
idPrefix: p,
|
|
283
285
|
fonts: c.render?.fonts ?? "embed",
|
|
284
286
|
...r.state !== void 0 ? { state: r.state } : {}
|
|
285
287
|
};
|
|
286
|
-
ae(e,
|
|
287
|
-
if (x || t !==
|
|
288
|
+
ae(e, F, r.signal).then(async (d) => {
|
|
289
|
+
if (x || t !== m || r.signal?.aborted) {
|
|
288
290
|
n({ status: "superseded", revision: t });
|
|
289
291
|
return;
|
|
290
292
|
}
|
|
@@ -294,9 +296,9 @@ function ve(y, c = {}) {
|
|
|
294
296
|
}
|
|
295
297
|
let E;
|
|
296
298
|
try {
|
|
297
|
-
E = await oe(d.value.svg,
|
|
299
|
+
E = await oe(d.value.svg, F.fonts ?? "embed");
|
|
298
300
|
} catch (i) {
|
|
299
|
-
if (x || t !==
|
|
301
|
+
if (x || t !== m || r.signal?.aborted) {
|
|
300
302
|
n({
|
|
301
303
|
status: r.signal?.aborted ? "aborted" : "superseded",
|
|
302
304
|
revision: t
|
|
@@ -311,25 +313,25 @@ function ve(y, c = {}) {
|
|
|
311
313
|
X(t, $.diagnostics), n({ status: "error", revision: t, error: $ });
|
|
312
314
|
return;
|
|
313
315
|
}
|
|
314
|
-
if (x || t !==
|
|
316
|
+
if (x || t !== m || r.signal?.aborted) {
|
|
315
317
|
n({ status: "superseded", revision: t });
|
|
316
318
|
return;
|
|
317
319
|
}
|
|
318
320
|
let W;
|
|
319
321
|
try {
|
|
320
|
-
W = ge(s, d.value.svg,
|
|
322
|
+
W = ge(s, d.value.svg, F.fonts !== "host");
|
|
321
323
|
} catch (i) {
|
|
322
|
-
const $ = i instanceof Error ? i.message : "Could not build safe SVG.",
|
|
323
|
-
X(t,
|
|
324
|
+
const $ = i instanceof Error ? i.message : "Could not build safe SVG.", M = K("internal", "DRAFT_VIEWER_DOM", $);
|
|
325
|
+
X(t, M.diagnostics), n({ status: "error", revision: t, error: M });
|
|
324
326
|
return;
|
|
325
327
|
}
|
|
326
|
-
const
|
|
328
|
+
const G = [];
|
|
327
329
|
try {
|
|
328
330
|
for (const i of E)
|
|
329
|
-
|
|
331
|
+
N.has(i.key) || (s.fonts.add(i.face), N.set(i.key, i.face), G.push(i));
|
|
330
332
|
} catch (i) {
|
|
331
|
-
for (const { key:
|
|
332
|
-
s.fonts.delete(Z),
|
|
333
|
+
for (const { key: M, face: Z } of G)
|
|
334
|
+
s.fonts.delete(Z), N.delete(M);
|
|
333
335
|
const $ = K(
|
|
334
336
|
"environment",
|
|
335
337
|
"DRAFT_FONT_UNAVAILABLE",
|
|
@@ -341,10 +343,10 @@ function ve(y, c = {}) {
|
|
|
341
343
|
const H = !!u;
|
|
342
344
|
u = d.value, o.replaceChildren(W), w.replaceChildren(
|
|
343
345
|
...u.items.map((i) => {
|
|
344
|
-
const $ = s.createElement("li"),
|
|
345
|
-
|
|
346
|
+
const $ = s.createElement("li"), M = s.createElement("button");
|
|
347
|
+
M.type = "button";
|
|
346
348
|
const Z = i.label.trim() || (i.kind === "edge" ? `${i.from ?? "?"} to ${i.to ?? "?"}` : i.id);
|
|
347
|
-
return
|
|
349
|
+
return M.textContent = `${i.kind}: ${Z}`, M.dataset.itemId = i.id, M.addEventListener("click", () => {
|
|
348
350
|
L("itemactivate", {
|
|
349
351
|
id: i.id,
|
|
350
352
|
kind: i.kind,
|
|
@@ -352,23 +354,23 @@ function ve(y, c = {}) {
|
|
|
352
354
|
revision: t
|
|
353
355
|
});
|
|
354
356
|
const O = Array.from(o.querySelectorAll("[data-id]")).find(
|
|
355
|
-
(
|
|
357
|
+
(T) => T.getAttribute("data-id") === i.id
|
|
356
358
|
);
|
|
357
359
|
if (O) {
|
|
358
|
-
const
|
|
359
|
-
(
|
|
360
|
-
centerX: a.centerX + (
|
|
361
|
-
centerY: a.centerY + (
|
|
360
|
+
const T = O.getBoundingClientRect(), I = o.getBoundingClientRect();
|
|
361
|
+
(T.width || T.height) && I.width && I.height && (a = {
|
|
362
|
+
centerX: a.centerX + (T.left + T.width / 2 - (I.left + I.width / 2)) / a.zoom,
|
|
363
|
+
centerY: a.centerY + (T.top + T.height / 2 - (I.top + I.height / 2)) / a.zoom,
|
|
362
364
|
zoom: Math.max(1, a.zoom)
|
|
363
|
-
},
|
|
365
|
+
}, _ = !0, R(), L("camera", { camera: { ...a }, reason: "user" }));
|
|
364
366
|
}
|
|
365
|
-
}), $.append(
|
|
367
|
+
}), $.append(M), $;
|
|
366
368
|
})
|
|
367
369
|
);
|
|
368
370
|
const k = new Set(E.map((i) => i.key));
|
|
369
|
-
for (const [i, $] of
|
|
370
|
-
k.has(i) || (s.fonts.delete($),
|
|
371
|
-
|
|
371
|
+
for (const [i, $] of N)
|
|
372
|
+
k.has(i) || (s.fonts.delete($), N.delete(i));
|
|
373
|
+
l.classList.remove("draft-viewer--stale"), f.textContent = d.diagnostics.map((i) => i.message).join(" "), !H || r.camera === "fit" ? Y() : R();
|
|
372
374
|
const D = {
|
|
373
375
|
status: "committed",
|
|
374
376
|
revision: t,
|
|
@@ -377,7 +379,7 @@ function ve(y, c = {}) {
|
|
|
377
379
|
};
|
|
378
380
|
n(D), L("render", { revision: t, value: u }), L("diagnostics", { revision: t, diagnostics: d.diagnostics, stale: !1 });
|
|
379
381
|
}).catch((d) => {
|
|
380
|
-
if (x || t !==
|
|
382
|
+
if (x || t !== m || r.signal?.aborted) {
|
|
381
383
|
n({
|
|
382
384
|
status: r.signal?.aborted ? "aborted" : "superseded",
|
|
383
385
|
revision: t
|
|
@@ -396,12 +398,12 @@ function ve(y, c = {}) {
|
|
|
396
398
|
on(e, r) {
|
|
397
399
|
if (x) return () => {
|
|
398
400
|
};
|
|
399
|
-
const t =
|
|
400
|
-
return t.add(r),
|
|
401
|
+
const t = U.get(e) ?? /* @__PURE__ */ new Set();
|
|
402
|
+
return t.add(r), U.set(e, t), () => t.delete(r);
|
|
401
403
|
},
|
|
402
404
|
getCamera: () => ({ ...a }),
|
|
403
405
|
setCamera(e) {
|
|
404
|
-
x || !Number.isFinite(e.centerX) || !Number.isFinite(e.centerY) || !Number.isFinite(e.zoom) || e.zoom <= 0 || (a = { ...e },
|
|
406
|
+
x || !Number.isFinite(e.centerX) || !Number.isFinite(e.centerY) || !Number.isFinite(e.zoom) || e.zoom <= 0 || (a = { ...e }, _ = !0, R(), L("camera", { camera: { ...a }, reason: "api" }));
|
|
405
407
|
},
|
|
406
408
|
fit: () => {
|
|
407
409
|
x || Y();
|
|
@@ -415,24 +417,24 @@ function ve(y, c = {}) {
|
|
|
415
417
|
},
|
|
416
418
|
destroy() {
|
|
417
419
|
if (!x) {
|
|
418
|
-
if (x = !0,
|
|
420
|
+
if (x = !0, m++, A) {
|
|
419
421
|
try {
|
|
420
422
|
o.releasePointerCapture(A.pointerId);
|
|
421
423
|
} catch {
|
|
422
424
|
}
|
|
423
425
|
A = void 0;
|
|
424
426
|
}
|
|
425
|
-
for (const [e, r] of
|
|
427
|
+
for (const [e, r] of B)
|
|
426
428
|
r.resolve({ status: "destroyed", revision: e });
|
|
427
|
-
|
|
428
|
-
for (const e of
|
|
429
|
-
|
|
429
|
+
B.clear(), z(new Error("Viewer was destroyed."));
|
|
430
|
+
for (const e of N.values()) s.fonts.delete(e);
|
|
431
|
+
N.clear(), J.disconnect(), U.clear(), y.replaceChildren(), u = void 0;
|
|
430
432
|
}
|
|
431
433
|
}
|
|
432
434
|
};
|
|
433
435
|
}
|
|
434
436
|
export {
|
|
435
|
-
|
|
436
|
-
|
|
437
|
+
Ae as fontMetricsVersion,
|
|
438
|
+
be as mountViewer,
|
|
437
439
|
ke as runtimeVersion
|
|
438
440
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@draftably/runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Portable native Draftably SVG rendering, validation, and optional viewer.",
|
|
6
6
|
"type": "module",
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
"types": "./dist/types/src/runtime/element.d.ts",
|
|
27
27
|
"import": "./dist/element.js"
|
|
28
28
|
},
|
|
29
|
+
"./graph": {
|
|
30
|
+
"types": "./dist/types/src/graph-api/index.d.ts",
|
|
31
|
+
"import": "./dist/graph.js"
|
|
32
|
+
},
|
|
29
33
|
"./viewer.css": "./dist/viewer.css",
|
|
30
34
|
"./fonts.css": "./dist/fonts.css",
|
|
31
35
|
"./browser": {
|
|
@@ -34,9 +38,6 @@
|
|
|
34
38
|
},
|
|
35
39
|
"./package.json": "./package.json"
|
|
36
40
|
},
|
|
37
|
-
"scripts": {
|
|
38
|
-
"build": "node ../../scripts/build-runtime.ts"
|
|
39
|
-
},
|
|
40
41
|
"engines": {
|
|
41
42
|
"node": ">=22.21.0"
|
|
42
43
|
},
|
|
@@ -48,5 +49,8 @@
|
|
|
48
49
|
"publishConfig": {
|
|
49
50
|
"access": "public",
|
|
50
51
|
"registry": "https://registry.npmjs.org"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "node ../../scripts/build-runtime.ts"
|
|
51
55
|
}
|
|
52
|
-
}
|
|
56
|
+
}
|