@sebastianwessel/isostate 0.4.0 → 0.6.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.
Files changed (89) hide show
  1. package/dist/animation/animation-engine.d.ts +3 -0
  2. package/dist/animation/animation-engine.d.ts.map +1 -1
  3. package/dist/animation/controller.d.ts +36 -2
  4. package/dist/animation/controller.d.ts.map +1 -1
  5. package/dist/assets/software-architecture/IMAGEGEN-PROMPTS.md +66 -0
  6. package/dist/assets/software-architecture/LICENSE +21 -0
  7. package/dist/assets/software-architecture/NOTICE.md +17 -0
  8. package/dist/assets/software-architecture/README.md +105 -0
  9. package/dist/assets/software-architecture/agentic/AGENT-VISUAL-PROMPTS.md +42 -0
  10. package/dist/assets/software-architecture/agentic/HANDOFF-PROMPTS.md +19 -0
  11. package/dist/assets/software-architecture/agentic/PROCESS-VISUAL-PROMPTS.md +109 -0
  12. package/dist/assets/software-architecture/agentic/agents-sprites.png +0 -0
  13. package/dist/assets/software-architecture/agentic/ai-capabilities-sprites.png +0 -0
  14. package/dist/assets/software-architecture/agentic/ai-to-human-handoff.png +0 -0
  15. package/dist/assets/software-architecture/agentic/channels-sprites.png +0 -0
  16. package/dist/assets/software-architecture/agentic/human-to-ai-handoff.png +0 -0
  17. package/dist/assets/software-architecture/agentic/humans-sprites.png +0 -0
  18. package/dist/assets/software-architecture/agentic/infrastructure-sprites.png +0 -0
  19. package/dist/assets/software-architecture/agentic/lifecycle-sprites.png +0 -0
  20. package/dist/assets/software-architecture/agentic/orchestration-sprites.png +0 -0
  21. package/dist/assets/software-architecture/agentic/providers-sprites.png +0 -0
  22. package/dist/assets/software-architecture/agentic/servicenow-sprites.png +0 -0
  23. package/dist/assets/software-architecture/architecture/architecture-sprites.png +0 -0
  24. package/dist/assets/software-architecture/manifest.json +2095 -0
  25. package/dist/assets/software-architecture/workflow/workflow-process-sprites.png +0 -0
  26. package/dist/browser/isostate.runtime.js +4 -4
  27. package/dist/browser/isostate.runtime.js.map +12 -10
  28. package/dist/chunks/errors-2yA81Vfb.js +23 -0
  29. package/dist/chunks/{errors-DyqEkrm5.js.map → errors-2yA81Vfb.js.map} +1 -1
  30. package/dist/chunks/index-WmsNtuaZ.js +1685 -0
  31. package/dist/chunks/index-WmsNtuaZ.js.map +1 -0
  32. package/dist/chunks/rendering-engine-DLaM1XbU.js +1425 -0
  33. package/dist/chunks/rendering-engine-DLaM1XbU.js.map +1 -0
  34. package/dist/chunks/scene-parser-BNXXIAqj.js +3033 -0
  35. package/dist/chunks/scene-parser-BNXXIAqj.js.map +1 -0
  36. package/dist/chunks/sha256-BkgWUdh1.js +123 -0
  37. package/dist/chunks/sha256-BkgWUdh1.js.map +1 -0
  38. package/dist/dsl/browser.js +3 -3
  39. package/dist/dsl/index.js +3 -3
  40. package/dist/dsl/scene-parser.d.ts.map +1 -1
  41. package/dist/dsl/scene-validator.d.ts.map +1 -1
  42. package/dist/dsl/workflow-effects-validation.d.ts +8 -0
  43. package/dist/dsl/workflow-effects-validation.d.ts.map +1 -0
  44. package/dist/editor-support/adapter.d.ts.map +1 -1
  45. package/dist/editor-support/index.js +347 -394
  46. package/dist/editor-support/index.js.map +1 -1
  47. package/dist/index.d.ts +4 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +438 -40
  50. package/dist/index.js.map +1 -1
  51. package/dist/rendering/animation-css.d.ts.map +1 -1
  52. package/dist/rendering/rendering-engine.d.ts +11 -0
  53. package/dist/rendering/rendering-engine.d.ts.map +1 -1
  54. package/dist/rendering/scene-effects.d.ts +15 -0
  55. package/dist/rendering/scene-effects.d.ts.map +1 -0
  56. package/dist/rendering/theme.d.ts +4 -0
  57. package/dist/rendering/theme.d.ts.map +1 -1
  58. package/dist/runtime/diagnostics-overlay.d.ts +29 -0
  59. package/dist/runtime/diagnostics-overlay.d.ts.map +1 -0
  60. package/dist/runtime/export.d.ts +27 -0
  61. package/dist/runtime/export.d.ts.map +1 -0
  62. package/dist/runtime/index.d.ts +1 -0
  63. package/dist/runtime/index.d.ts.map +1 -1
  64. package/dist/runtime/index.js +4 -4
  65. package/dist/runtime/interactivity.d.ts +56 -0
  66. package/dist/runtime/interactivity.d.ts.map +1 -0
  67. package/dist/runtime/mount-scene.d.ts +11 -10
  68. package/dist/runtime/mount-scene.d.ts.map +1 -1
  69. package/dist/types/asset-registry.d.ts +1 -0
  70. package/dist/types/asset-registry.d.ts.map +1 -1
  71. package/dist/types/errors.d.ts.map +1 -1
  72. package/dist/types/index.d.ts +1 -1
  73. package/dist/types/index.d.ts.map +1 -1
  74. package/dist/types/node.d.ts +54 -1
  75. package/dist/types/node.d.ts.map +1 -1
  76. package/dist/types/runtime-bundle.d.ts +35 -0
  77. package/dist/types/runtime-bundle.d.ts.map +1 -1
  78. package/dist/types/scene.d.ts +2 -0
  79. package/dist/types/scene.d.ts.map +1 -1
  80. package/package.json +9 -8
  81. package/dist/chunks/errors-DyqEkrm5.js +0 -29
  82. package/dist/chunks/index-C3qcXbPI.js +0 -1542
  83. package/dist/chunks/index-C3qcXbPI.js.map +0 -1
  84. package/dist/chunks/rendering-engine-BUUV3Qq-.js +0 -1124
  85. package/dist/chunks/rendering-engine-BUUV3Qq-.js.map +0 -1
  86. package/dist/chunks/scene-parser-B9SPDLYs.js +0 -2688
  87. package/dist/chunks/scene-parser-B9SPDLYs.js.map +0 -1
  88. package/dist/chunks/sha256-4JuurR-b.js +0 -69
  89. package/dist/chunks/sha256-4JuurR-b.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,51 +1,449 @@
1
- export { A as AnimationController, a as AnimationEngine, e as easeInCubic, b as easeInOutCubic, c as easeOutCubic, l as linear, m as mountScene, r as resolveEasing } from './chunks/index-C3qcXbPI.js';
2
- export { A as AssetRegistryImpl, D as DEFAULT_CELL_SIZE, c as applyThemeToElement, d as buildSceneDOM, e as calculateTransform, f as calculateVisualSize, g as composeTheme, h as createAssetRegistry, i as createDefaultRegistry, r as projectToScreen, s as resolveTheme } from './chunks/rendering-engine-BUUV3Qq-.js';
3
- export { A as AnimationError, C as ControllerError, P as ParseError, R as RenderError, V as ValidationErrorClass } from './chunks/errors-DyqEkrm5.js';
4
- import './chunks/sha256-4JuurR-b.js';
1
+ export { A as AnimationController, a as AnimationEngine, e as easeInCubic, b as easeInOutCubic, c as easeOutCubic, l as linear, m as mountScene, r as resolveEasing } from './chunks/index-WmsNtuaZ.js';
2
+ import { g as getResolvedProjectionLayout, a as getResolvedViewBox, f as projectToScreen, e as updateElementTransforms, b as getElementState, h as hideElementAfterExit, u as unhideElementOnReadd, d as getConnectorState } from './chunks/rendering-engine-DLaM1XbU.js';
3
+ export { A as AssetRegistryImpl, D as DEFAULT_CELL_SIZE, i as applyThemeToElement, j as buildSceneDOM, k as calculateTransform, l as calculateVisualSize, m as composeTheme, n as createAssetRegistry, o as createDefaultRegistry, r as resolveTheme } from './chunks/rendering-engine-DLaM1XbU.js';
4
+ import { R as RenderError } from './chunks/errors-2yA81Vfb.js';
5
+ export { A as AnimationError, C as ControllerError, P as ParseError, V as ValidationErrorClass } from './chunks/errors-2yA81Vfb.js';
6
+ import './chunks/sha256-BkgWUdh1.js';
5
7
 
6
- /** Runtime set of valid entry animation strings */
7
- const ENTRY_ANIMATIONS = new Set([
8
- "fade-in",
9
- "fade-in-grow",
10
- "fall-in",
11
- "rise-from-ground",
12
- "slide-in-left",
13
- "slide-in-right",
14
- "flip-in",
15
- "none",
8
+ const ENTRY_ANIMATIONS = /* @__PURE__ */ new Set([
9
+ "fade-in",
10
+ "fade-in-grow",
11
+ "fall-in",
12
+ "rise-from-ground",
13
+ "slide-in-left",
14
+ "slide-in-right",
15
+ "flip-in",
16
+ "none"
16
17
  ]);
17
- /** Runtime set of valid exit animation strings */
18
- const EXIT_ANIMATIONS = new Set([
19
- "fade-out",
20
- "fade-out-shrink",
21
- "fall-through-ground",
22
- "rise-away",
23
- "slide-out-left",
24
- "slide-out-right",
25
- "flip-out",
26
- "none",
18
+ const EXIT_ANIMATIONS = /* @__PURE__ */ new Set([
19
+ "fade-out",
20
+ "fade-out-shrink",
21
+ "fall-through-ground",
22
+ "rise-away",
23
+ "slide-out-left",
24
+ "slide-out-right",
25
+ "flip-out",
26
+ "none"
27
27
  ]);
28
- /** Runtime set of valid lifecycle status strings */
29
- const LIFECYCLE_STATUSES = new Set(["entering", "present", "exiting", "removed"]);
30
- // ── Type guards ──────────────────────────────────────────────────────────────
31
- /** Narrow a raw string to EntryAnimation. Returns undefined if invalid. */
28
+ const LIFECYCLE_STATUSES = /* @__PURE__ */ new Set(["entering", "present", "exiting", "removed"]);
32
29
  function guardEntryAnimation(v) {
33
- if (typeof v !== "string")
34
- return undefined;
35
- return ENTRY_ANIMATIONS.has(v) ? v : undefined;
30
+ if (typeof v !== "string") return void 0;
31
+ return ENTRY_ANIMATIONS.has(v) ? v : void 0;
36
32
  }
37
- /** Narrow a raw string to ExitAnimation. Returns undefined if invalid. */
38
33
  function guardExitAnimation(v) {
39
- if (typeof v !== "string")
40
- return undefined;
41
- return EXIT_ANIMATIONS.has(v) ? v : undefined;
34
+ if (typeof v !== "string") return void 0;
35
+ return EXIT_ANIMATIONS.has(v) ? v : void 0;
42
36
  }
43
- /** Narrow a raw string to LifecycleStatus. Returns undefined if invalid. */
44
37
  function guardLifecycleStatus(v) {
45
- if (typeof v !== "string")
46
- return undefined;
47
- return LIFECYCLE_STATUSES.has(v) ? v : undefined;
38
+ if (typeof v !== "string") return void 0;
39
+ return LIFECYCLE_STATUSES.has(v) ? v : void 0;
48
40
  }
49
41
 
50
- export { guardEntryAnimation, guardExitAnimation, guardLifecycleStatus };
42
+ const SVG_NS = "http://www.w3.org/2000/svg";
43
+ const DIAGNOSTICS_ATTR = "data-iso-diagnostics";
44
+ const GRID_STROKE = "var(--iso-diag-grid, rgba(37, 99, 235, 0.35))";
45
+ const TEXT_FILL = "var(--iso-diag-text, #1e3a8a)";
46
+ const ANCHOR_FILL = "var(--iso-diag-anchor, #dc2626)";
47
+ const ROUTE_FILL = "var(--iso-diag-route, #059669)";
48
+ const registryBySvg = /* @__PURE__ */ new WeakMap();
49
+ function attachDiagnosticsOverlay(mounted, options = {}) {
50
+ assertMounted(mounted);
51
+ const registry = registryBySvg.get(mounted.svg) ?? {};
52
+ registryBySvg.set(mounted.svg, registry);
53
+ registry.current?.handle.destroy();
54
+ const token = /* @__PURE__ */ Symbol("diagnostics-overlay");
55
+ const group = document.createElementNS(SVG_NS, "g");
56
+ group.setAttribute(DIAGNOSTICS_ATTR, "");
57
+ mounted.svg.appendChild(group);
58
+ const render = () => renderOverlay(group, mounted, options);
59
+ render();
60
+ const unsubscribe = subscribeToLiveUpdates(mounted, render);
61
+ const isCurrent = () => registry.current?.token === token;
62
+ const handle = {
63
+ update() {
64
+ if (!isCurrent()) return;
65
+ render();
66
+ },
67
+ destroy() {
68
+ if (!isCurrent()) return;
69
+ unsubscribe();
70
+ group.parentNode?.removeChild(group);
71
+ registry.current = void 0;
72
+ }
73
+ };
74
+ registry.current = { token, handle };
75
+ return handle;
76
+ }
77
+ function assertMounted(mounted) {
78
+ if (!mounted.svg.isConnected) {
79
+ throw new RenderError("MOUNT_DESTROYED", "Cannot attach a diagnostics overlay to a destroyed mount");
80
+ }
81
+ }
82
+ function subscribeToLiveUpdates(mounted, render) {
83
+ const controller = mounted.controller;
84
+ if (!controller) return () => void 0;
85
+ const onProgressChange = () => render();
86
+ const onCameraChange = () => render();
87
+ controller.on("progress-change", onProgressChange);
88
+ controller.on("camera-change", onCameraChange);
89
+ return () => {
90
+ controller.off("progress-change", onProgressChange);
91
+ controller.off("camera-change", onCameraChange);
92
+ };
93
+ }
94
+ function renderOverlay(group, mounted, options) {
95
+ clearChildren(group);
96
+ const bundle = mounted.engine.bundle;
97
+ if (!bundle) return;
98
+ const layout = getResolvedProjectionLayout(bundle);
99
+ const project = (x, y) => {
100
+ const screen = projectToScreen(
101
+ x,
102
+ y,
103
+ layout.cellSize,
104
+ layout.selectedBounds.minX,
105
+ layout.selectedBounds.minY,
106
+ layout.padding.x,
107
+ layout.padding.y
108
+ );
109
+ return { x: screen.screenX, y: screen.screenY };
110
+ };
111
+ const showGrid = options.grid ?? true;
112
+ const showCoordinates = options.coordinates ?? false;
113
+ const showAnchors = options.anchors ?? true;
114
+ const showRoutes = options.routes ?? true;
115
+ const showReadout = options.readout ?? true;
116
+ if (showGrid) appendGrid(group, bundle, project);
117
+ if (showCoordinates) appendCoordinates(group, bundle, project);
118
+ if (showAnchors) appendAnchors(group, mounted, project);
119
+ if (showRoutes) appendRoutes(group, mounted, project);
120
+ if (showReadout) appendReadout(group, mounted, bundle);
121
+ }
122
+ function appendGrid(group, bundle, project) {
123
+ const [originX, originY] = bundle.floor.origin;
124
+ const [columns, rows] = bundle.floor.size;
125
+ for (let x = 0; x <= columns; x++) {
126
+ appendGridLine(group, project(originX + x, originY), project(originX + x, originY + rows));
127
+ }
128
+ for (let y = 0; y <= rows; y++) {
129
+ appendGridLine(group, project(originX, originY + y), project(originX + columns, originY + y));
130
+ }
131
+ }
132
+ function appendGridLine(group, start, end) {
133
+ const path = document.createElementNS(SVG_NS, "path");
134
+ path.setAttribute("d", `M ${start.x} ${start.y} L ${end.x} ${end.y}`);
135
+ path.setAttribute("stroke", GRID_STROKE);
136
+ path.setAttribute("stroke-width", "1");
137
+ path.setAttribute("fill", "none");
138
+ path.setAttribute("vector-effect", "non-scaling-stroke");
139
+ group.appendChild(path);
140
+ }
141
+ function appendCoordinates(group, bundle, project) {
142
+ const [originX, originY] = bundle.floor.origin;
143
+ const [columns, rows] = bundle.floor.size;
144
+ for (let x = 0; x <= columns; x++) {
145
+ for (let y = 0; y <= rows; y++) {
146
+ const gridX = originX + x;
147
+ const gridY = originY + y;
148
+ const point = project(gridX, gridY);
149
+ const text = document.createElementNS(SVG_NS, "text");
150
+ text.setAttribute("x", String(point.x));
151
+ text.setAttribute("y", String(point.y));
152
+ text.setAttribute("font-size", "8");
153
+ text.setAttribute("fill", TEXT_FILL);
154
+ text.textContent = `${gridX},${gridY}`;
155
+ group.appendChild(text);
156
+ }
157
+ }
158
+ }
159
+ function appendAnchors(group, mounted, project) {
160
+ for (const element of mounted.engine.getFrameUpdates()) {
161
+ if (element.lifecycle === "removed") continue;
162
+ const point = project(element.pos[0] + element.size, element.pos[1] + element.size);
163
+ const circle = document.createElementNS(SVG_NS, "circle");
164
+ circle.setAttribute("cx", String(point.x));
165
+ circle.setAttribute("cy", String(point.y));
166
+ circle.setAttribute("r", "3");
167
+ circle.setAttribute("fill", ANCHOR_FILL);
168
+ group.appendChild(circle);
169
+ }
170
+ }
171
+ function appendRoutes(group, mounted, project) {
172
+ for (const connector of mounted.engine.getConnectorFrameUpdates()) {
173
+ if (connector.lifecycle === "removed") continue;
174
+ for (const [x, y] of connector.route) {
175
+ const point = project(x, y);
176
+ const rect = document.createElementNS(SVG_NS, "rect");
177
+ rect.setAttribute("x", String(point.x - 2));
178
+ rect.setAttribute("y", String(point.y - 2));
179
+ rect.setAttribute("width", "4");
180
+ rect.setAttribute("height", "4");
181
+ rect.setAttribute("fill", ROUTE_FILL);
182
+ group.appendChild(rect);
183
+ }
184
+ }
185
+ }
186
+ function appendReadout(group, mounted, bundle) {
187
+ const viewBox = mounted.controller ? mounted.controller.getCameraState().viewBox : getResolvedViewBox(bundle);
188
+ const progress = mounted.controller ? mounted.controller.getProgress() : mounted.engine.getProgress();
189
+ const sceneId = mounted.controller ? mounted.engine.getCurrentState()?.id : void 0;
190
+ const text = document.createElementNS(SVG_NS, "text");
191
+ text.setAttribute("x", String(viewBox.minX + 4));
192
+ text.setAttribute("y", String(viewBox.minY + 10));
193
+ text.setAttribute("font-size", "10");
194
+ text.setAttribute("fill", TEXT_FILL);
195
+ text.textContent = sceneId ? `scene ${sceneId} \xB7 progress ${roundProgress(progress)}` : `progress ${roundProgress(progress)}`;
196
+ group.appendChild(text);
197
+ }
198
+ function roundProgress(progress) {
199
+ return Math.round(progress * 1e3) / 1e3;
200
+ }
201
+ function clearChildren(node) {
202
+ while (node.firstChild) node.removeChild(node.firstChild);
203
+ }
204
+
205
+ const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
206
+ const XLINK_NAMESPACE = "http://www.w3.org/1999/xlink";
207
+ const DIAGNOSTICS_OVERLAY_SELECTOR = "[data-iso-diagnostics]";
208
+ async function exportSceneSvg(mounted, options = {}) {
209
+ assertNotDestroyed(mounted);
210
+ assertValidSnapshotOptions(options);
211
+ return withRestoredProgress(mounted, options.progress, async () => {
212
+ const clone = prepareClone(mounted.svg, options);
213
+ if (options.inlineAssets ?? true) {
214
+ await inlineImageAssets(clone);
215
+ }
216
+ return serializeSvg(clone);
217
+ });
218
+ }
219
+ async function exportScenePng(mounted, options = {}) {
220
+ assertNotDestroyed(mounted);
221
+ assertValidPngSnapshotOptions(options);
222
+ const scale = options.scale ?? 2;
223
+ return withRestoredProgress(mounted, options.progress, async () => {
224
+ const clone = prepareClone(mounted.svg, options);
225
+ await inlineImageAssets(clone);
226
+ const svgString = serializeSvg(clone);
227
+ const viewBox = readViewBox(clone);
228
+ return rasterize(svgString, viewBox, scale);
229
+ });
230
+ }
231
+ function assertNotDestroyed(mounted) {
232
+ if (!mounted.svg.isConnected) {
233
+ throw new RenderError("EXPORT_TARGET_DESTROYED", "Cannot export a scene whose mount was destroyed");
234
+ }
235
+ }
236
+ function assertValidSnapshotOptions(options) {
237
+ if (options.progress !== void 0 && !isValidProgress(options.progress)) {
238
+ throw new RenderError("EXPORT_INVALID_OPTIONS", "progress must be a finite number within [0, 1]", {
239
+ progress: options.progress
240
+ });
241
+ }
242
+ }
243
+ function assertValidPngSnapshotOptions(options) {
244
+ assertValidSnapshotOptions(options);
245
+ if (options.scale !== void 0 && !isValidScale(options.scale)) {
246
+ throw new RenderError("EXPORT_INVALID_OPTIONS", "scale must be a finite number greater than 0", {
247
+ scale: options.scale
248
+ });
249
+ }
250
+ if (options.inlineAssets === false) {
251
+ throw new RenderError(
252
+ "EXPORT_INVALID_OPTIONS",
253
+ "exportScenePng() always inlines assets; inlineAssets: false is unsupported for PNG export"
254
+ );
255
+ }
256
+ }
257
+ function isValidProgress(progress) {
258
+ return Number.isFinite(progress) && progress >= 0 && progress <= 1;
259
+ }
260
+ function isValidScale(scale) {
261
+ return Number.isFinite(scale) && scale > 0;
262
+ }
263
+ async function withRestoredProgress(mounted, progress, run) {
264
+ if (progress === void 0) {
265
+ return run();
266
+ }
267
+ const previousProgress = mounted.engine.getProgress();
268
+ try {
269
+ mounted.engine.setProgress(progress);
270
+ applyControllerFrame(mounted);
271
+ return await run();
272
+ } finally {
273
+ mounted.engine.setProgress(previousProgress);
274
+ applyControllerFrame(mounted);
275
+ }
276
+ }
277
+ function applyControllerFrame(mounted) {
278
+ const svg = mounted.svg;
279
+ const elementUpdates = mounted.engine.getFrameUpdates().map(
280
+ (update) => ({
281
+ id: update.id,
282
+ asset: update.asset,
283
+ pos: update.pos,
284
+ size: update.size,
285
+ layer: update.layer,
286
+ presence: update.lifecycle,
287
+ enter: update.entry,
288
+ exit: update.exit,
289
+ ambient: update.ambient,
290
+ text: update.text,
291
+ primitive: update.primitive,
292
+ activity: update.activity
293
+ })
294
+ );
295
+ const connectorUpdates = mounted.engine.getConnectorFrameUpdates().map(
296
+ (update) => ({
297
+ id: update.id,
298
+ route: update.route,
299
+ layer: update.layer,
300
+ presence: update.lifecycle,
301
+ style: update.style,
302
+ start: update.start,
303
+ end: update.end,
304
+ direction: update.direction,
305
+ message: update.message,
306
+ enter: update.entry,
307
+ exit: update.exit,
308
+ ambient: update.ambient
309
+ })
310
+ );
311
+ updateElementTransforms(svg, elementUpdates, connectorUpdates);
312
+ applyElementVisibility(svg, elementUpdates);
313
+ applyConnectorVisibility(svg, connectorUpdates);
314
+ }
315
+ function applyElementVisibility(svg, elements) {
316
+ for (const element of elements) {
317
+ const state = getElementState(svg, element.id);
318
+ if (!state) continue;
319
+ if (element.presence === "removed") {
320
+ state.isHidden = true;
321
+ hideElementAfterExit(state.node);
322
+ } else if (state.isHidden) {
323
+ state.isHidden = false;
324
+ unhideElementOnReadd(state.node);
325
+ }
326
+ }
327
+ }
328
+ function applyConnectorVisibility(svg, connectors) {
329
+ for (const connector of connectors) {
330
+ const state = getConnectorState(svg, connector.id);
331
+ if (!state) continue;
332
+ if (connector.presence === "removed") {
333
+ state.isHidden = true;
334
+ hideElementAfterExit(state.node);
335
+ } else if (state.isHidden) {
336
+ state.isHidden = false;
337
+ unhideElementOnReadd(state.node);
338
+ }
339
+ }
340
+ }
341
+ function prepareClone(svg, options) {
342
+ const clone = svg.cloneNode(true);
343
+ const viewBox = readViewBox(clone);
344
+ clone.setAttribute("width", String(viewBox.width));
345
+ clone.setAttribute("height", String(viewBox.height));
346
+ clone.setAttribute("xmlns", SVG_NAMESPACE);
347
+ clone.setAttribute("xmlns:xlink", XLINK_NAMESPACE);
348
+ if (options.background) {
349
+ const rect = document.createElementNS(SVG_NAMESPACE, "rect");
350
+ rect.setAttribute("x", String(viewBox.minX));
351
+ rect.setAttribute("y", String(viewBox.minY));
352
+ rect.setAttribute("width", String(viewBox.width));
353
+ rect.setAttribute("height", String(viewBox.height));
354
+ rect.setAttribute("fill", options.background);
355
+ insertAsFirstChild(clone, rect);
356
+ }
357
+ const diagnosticsOverlay = clone.querySelector(DIAGNOSTICS_OVERLAY_SELECTOR);
358
+ diagnosticsOverlay?.parentNode?.removeChild(diagnosticsOverlay);
359
+ return clone;
360
+ }
361
+ function insertAsFirstChild(parent, child) {
362
+ if (parent.firstChild) {
363
+ parent.insertBefore(child, parent.firstChild);
364
+ } else {
365
+ parent.appendChild(child);
366
+ }
367
+ }
368
+ function readViewBox(svg) {
369
+ const raw = svg.getAttribute("viewBox");
370
+ const parts = (raw ?? "").trim().split(/\s+/).map(Number);
371
+ if (parts.length !== 4 || parts.some((part) => !Number.isFinite(part))) {
372
+ return { minX: 0, minY: 0, width: 0, height: 0 };
373
+ }
374
+ const [minX, minY, width, height] = parts;
375
+ return { minX, minY, width, height };
376
+ }
377
+ async function inlineImageAssets(clone) {
378
+ const images = [...clone.querySelectorAll("image")];
379
+ await Promise.all(images.map((image) => inlineImageHref(image)));
380
+ }
381
+ async function inlineImageHref(image) {
382
+ const href = image.getAttribute("href") ?? image.getAttributeNS(XLINK_NAMESPACE, "href");
383
+ if (!href || href.startsWith("data:")) return;
384
+ const dataUri = await fetchAsDataUri(href);
385
+ image.setAttribute("href", dataUri);
386
+ image.setAttributeNS(XLINK_NAMESPACE, "href", dataUri);
387
+ }
388
+ async function fetchAsDataUri(url) {
389
+ let response;
390
+ try {
391
+ response = await fetch(url);
392
+ } catch {
393
+ throw new RenderError("EXPORT_ASSET_FETCH_FAILED", `Failed to fetch asset for inlining: ${url}`, { url });
394
+ }
395
+ if (!response.ok) {
396
+ throw new RenderError("EXPORT_ASSET_FETCH_FAILED", `Failed to fetch asset for inlining: ${url}`, { url });
397
+ }
398
+ const contentType = response.headers.get("content-type") ?? "application/octet-stream";
399
+ const buffer = await response.arrayBuffer();
400
+ return `data:${contentType};base64,${arrayBufferToBase64(buffer)}`;
401
+ }
402
+ function arrayBufferToBase64(buffer) {
403
+ let binary = "";
404
+ const bytes = new Uint8Array(buffer);
405
+ for (const byte of bytes) binary += String.fromCharCode(byte);
406
+ return btoa(binary);
407
+ }
408
+ function serializeSvg(clone) {
409
+ const serializer = new XMLSerializer();
410
+ return `<?xml version="1.0" encoding="UTF-8"?>
411
+ ${serializer.serializeToString(clone)}`;
412
+ }
413
+ async function rasterize(svgString, viewBox, scale) {
414
+ const width = Math.ceil(viewBox.width * scale);
415
+ const height = Math.ceil(viewBox.height * scale);
416
+ const svgBlob = new Blob([svgString], { type: "image/svg+xml" });
417
+ const objectUrl = URL.createObjectURL(svgBlob);
418
+ try {
419
+ const image = await loadImage(objectUrl);
420
+ const canvas = document.createElement("canvas");
421
+ canvas.width = width;
422
+ canvas.height = height;
423
+ const context = canvas.getContext("2d");
424
+ if (!context) {
425
+ throw new RenderError("EXPORT_RASTERIZE_FAILED", "Canvas 2D context is unavailable");
426
+ }
427
+ context.drawImage(image, 0, 0, width, height);
428
+ const blob = await new Promise((resolve) => {
429
+ canvas.toBlob(resolve, "image/png");
430
+ });
431
+ if (!blob) {
432
+ throw new RenderError("EXPORT_RASTERIZE_FAILED", "Canvas failed to encode PNG output");
433
+ }
434
+ return blob;
435
+ } finally {
436
+ URL.revokeObjectURL(objectUrl);
437
+ }
438
+ }
439
+ function loadImage(src) {
440
+ return new Promise((resolve, reject) => {
441
+ const image = new Image();
442
+ image.onload = () => resolve(image);
443
+ image.onerror = () => reject(new RenderError("EXPORT_RASTERIZE_FAILED", "Failed to load rasterization source image"));
444
+ image.src = src;
445
+ });
446
+ }
447
+
448
+ export { RenderError, attachDiagnosticsOverlay, exportScenePng, exportSceneSvg, guardEntryAnimation, guardExitAnimation, guardLifecycleStatus, projectToScreen };
51
449
  //# sourceMappingURL=index.js.map