@3plate/graph-core 0.1.14 → 0.1.16

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/dist/index.d.cts CHANGED
@@ -213,6 +213,12 @@ type EventsOptions<N, E> = {
213
213
  };
214
214
  /** Function to render a node */
215
215
  type RenderNode<N> = (node: N, props?: NodeProps<N>) => HTMLElement;
216
+ /**
217
+ * Function called after a node element has been mounted to the DOM.
218
+ * Use this to integrate framework-specific rendering (e.g. React, Vue) into node content.
219
+ * The returned function, if any, is called when the node is removed.
220
+ */
221
+ type MountNode<N> = (node: N, element: HTMLElement) => (() => void) | void;
216
222
  /** Color mode */
217
223
  type ColorMode = 'light' | 'dark' | 'system';
218
224
  /** Canvas background and general colors */
@@ -265,6 +271,12 @@ type CanvasOptions<N> = {
265
271
  panZoom?: boolean;
266
272
  /** Function to render a node */
267
273
  renderNode?: RenderNode<N>;
274
+ /**
275
+ * Called after a node element is mounted to the DOM.
276
+ * Use this to integrate framework renderers (React, Vue, etc.) into node content.
277
+ * Return a cleanup function to be called when the node is removed.
278
+ */
279
+ mountNode?: MountNode<N>;
268
280
  /** Color mode */
269
281
  colorMode?: ColorMode;
270
282
  /** Theme */
@@ -718,4 +730,4 @@ declare class Playground {
718
730
 
719
731
  declare function graph<N, E>(args?: APIArguments<N, E>): Promise<API<N, E>>;
720
732
 
721
- export { API, type APIArguments, type APIOptions, type CanvasTheme, type ColorMode, type EdgeProps, type EdgeTheme, type EventsOptions, type Example, type ExampleEdge, type ExampleNode, type ExampleOptions, FileSource, type FileSourceArgs, type FileStatus, type FileStatusListener, FileSystemSource, type FileSystemSourceArgs, type HistoryMessage, Ingest, type IngestMessage, type IngestionConfig, type NewEdge, type NewNode, type NodeAlign, type NodeProps, type NodeTheme, type Orientation, Playground, type PlaygroundOptions, type PortProps, type PortStyle, type PortTheme, type RenderNode, type SnapshotMessage, type ThemeVars, type Update, type UpdateMessage, Updater, WebSocketSource, type WebSocketSourceArgs, type WebSocketStatus, type WebSocketStatusListener, graph as default, graph };
733
+ export { API, type APIArguments, type APIOptions, type CanvasOptions, type CanvasTheme, type ColorMode, type EdgeProps, type EdgeTheme, type EventsOptions, type Example, type ExampleEdge, type ExampleNode, type ExampleOptions, FileSource, type FileSourceArgs, type FileStatus, type FileStatusListener, FileSystemSource, type FileSystemSourceArgs, type HistoryMessage, Ingest, type IngestMessage, type IngestionConfig, type MountNode, type NewEdge, type NewNode, type NodeAlign, type NodeProps, type NodeTheme, type Orientation, Playground, type PlaygroundOptions, type PortProps, type PortStyle, type PortTheme, type RenderNode, type SnapshotMessage, type ThemeVars, type Update, type UpdateMessage, Updater, WebSocketSource, type WebSocketSourceArgs, type WebSocketStatus, type WebSocketStatusListener, graph as default, graph };
package/dist/index.d.ts CHANGED
@@ -213,6 +213,12 @@ type EventsOptions<N, E> = {
213
213
  };
214
214
  /** Function to render a node */
215
215
  type RenderNode<N> = (node: N, props?: NodeProps<N>) => HTMLElement;
216
+ /**
217
+ * Function called after a node element has been mounted to the DOM.
218
+ * Use this to integrate framework-specific rendering (e.g. React, Vue) into node content.
219
+ * The returned function, if any, is called when the node is removed.
220
+ */
221
+ type MountNode<N> = (node: N, element: HTMLElement) => (() => void) | void;
216
222
  /** Color mode */
217
223
  type ColorMode = 'light' | 'dark' | 'system';
218
224
  /** Canvas background and general colors */
@@ -265,6 +271,12 @@ type CanvasOptions<N> = {
265
271
  panZoom?: boolean;
266
272
  /** Function to render a node */
267
273
  renderNode?: RenderNode<N>;
274
+ /**
275
+ * Called after a node element is mounted to the DOM.
276
+ * Use this to integrate framework renderers (React, Vue, etc.) into node content.
277
+ * Return a cleanup function to be called when the node is removed.
278
+ */
279
+ mountNode?: MountNode<N>;
268
280
  /** Color mode */
269
281
  colorMode?: ColorMode;
270
282
  /** Theme */
@@ -718,4 +730,4 @@ declare class Playground {
718
730
 
719
731
  declare function graph<N, E>(args?: APIArguments<N, E>): Promise<API<N, E>>;
720
732
 
721
- export { API, type APIArguments, type APIOptions, type CanvasTheme, type ColorMode, type EdgeProps, type EdgeTheme, type EventsOptions, type Example, type ExampleEdge, type ExampleNode, type ExampleOptions, FileSource, type FileSourceArgs, type FileStatus, type FileStatusListener, FileSystemSource, type FileSystemSourceArgs, type HistoryMessage, Ingest, type IngestMessage, type IngestionConfig, type NewEdge, type NewNode, type NodeAlign, type NodeProps, type NodeTheme, type Orientation, Playground, type PlaygroundOptions, type PortProps, type PortStyle, type PortTheme, type RenderNode, type SnapshotMessage, type ThemeVars, type Update, type UpdateMessage, Updater, WebSocketSource, type WebSocketSourceArgs, type WebSocketStatus, type WebSocketStatusListener, graph as default, graph };
733
+ export { API, type APIArguments, type APIOptions, type CanvasOptions, type CanvasTheme, type ColorMode, type EdgeProps, type EdgeTheme, type EventsOptions, type Example, type ExampleEdge, type ExampleNode, type ExampleOptions, FileSource, type FileSourceArgs, type FileStatus, type FileStatusListener, FileSystemSource, type FileSystemSourceArgs, type HistoryMessage, Ingest, type IngestMessage, type IngestionConfig, type MountNode, type NewEdge, type NewNode, type NodeAlign, type NodeProps, type NodeTheme, type Orientation, Playground, type PlaygroundOptions, type PortProps, type PortStyle, type PortTheme, type RenderNode, type SnapshotMessage, type ThemeVars, type Update, type UpdateMessage, Updater, WebSocketSource, type WebSocketSourceArgs, type WebSocketStatus, type WebSocketStatusListener, graph as default, graph };
package/dist/index.js CHANGED
@@ -1337,7 +1337,7 @@ var Layout = class _Layout {
1337
1337
  };
1338
1338
 
1339
1339
  // src/canvas/marker.tsx
1340
- import { jsx } from "jsx-dom/jsx-runtime";
1340
+ import { jsx } from "jsx-dom/jsx-runtime.js";
1341
1341
  function arrow(size, reverse = false, prefix = "") {
1342
1342
  const h = size / 1.5;
1343
1343
  const w = size;
@@ -1965,12 +1965,14 @@ var canvasPos = (x, y) => ({ x, y });
1965
1965
  var graphPos = (x, y) => ({ x, y });
1966
1966
 
1967
1967
  // src/canvas/node.tsx
1968
- import { jsx as jsx2, jsxs } from "jsx-dom/jsx-runtime";
1968
+ import { jsx as jsx2, jsxs } from "jsx-dom/jsx-runtime.js";
1969
1969
  var Node2 = class {
1970
1970
  selected;
1971
1971
  hovered;
1972
1972
  container;
1973
1973
  content;
1974
+ innerContent;
1975
+ cleanup;
1974
1976
  canvas;
1975
1977
  data;
1976
1978
  isDummy;
@@ -1985,10 +1987,13 @@ var Node2 = class {
1985
1987
  const size = canvas.dummyNodeSize;
1986
1988
  } else {
1987
1989
  const render = data.render ?? canvas.renderNode;
1988
- this.content = this.renderContent(render(data.data, data));
1990
+ const innerEl = render(data.data, data);
1991
+ this.innerContent = innerEl;
1992
+ this.content = this.renderContent(innerEl);
1989
1993
  }
1990
1994
  }
1991
1995
  remove() {
1996
+ this.cleanup?.();
1992
1997
  this.container.remove();
1993
1998
  }
1994
1999
  append() {
@@ -2157,7 +2162,7 @@ var Node2 = class {
2157
2162
  };
2158
2163
 
2159
2164
  // src/canvas/seg.tsx
2160
- import { jsx as jsx3, jsxs as jsxs2 } from "jsx-dom/jsx-runtime";
2165
+ import { jsx as jsx3, jsxs as jsxs2 } from "jsx-dom/jsx-runtime.js";
2161
2166
  var Seg2 = class {
2162
2167
  id;
2163
2168
  selected;
@@ -2305,7 +2310,7 @@ var EditMode = class {
2305
2310
  };
2306
2311
 
2307
2312
  // src/canvas/newEdge.tsx
2308
- import { jsx as jsx4, jsxs as jsxs3 } from "jsx-dom/jsx-runtime";
2313
+ import { jsx as jsx4, jsxs as jsxs3 } from "jsx-dom/jsx-runtime.js";
2309
2314
  function renderNewEdge({ start, end }) {
2310
2315
  return /* @__PURE__ */ jsxs3("g", { className: "g3p-new-edge-container", children: [
2311
2316
  /* @__PURE__ */ jsx4(
@@ -2340,7 +2345,7 @@ function renderNewEdge({ start, end }) {
2340
2345
  }
2341
2346
 
2342
2347
  // src/canvas/modal.tsx
2343
- import { jsx as jsx5, jsxs as jsxs4 } from "jsx-dom/jsx-runtime";
2348
+ import { jsx as jsx5, jsxs as jsxs4 } from "jsx-dom/jsx-runtime.js";
2344
2349
  var Modal = class {
2345
2350
  container;
2346
2351
  overlay;
@@ -2794,7 +2799,7 @@ var EditEdgeModal = class _EditEdgeModal extends Modal {
2794
2799
  var styles_default = "/* ==================== Theme Variables ==================== */\n\n/* Light theme (default) */\n:root {\n --g3p-bg: #fafafa;\n --g3p-bg-node: #ffffff;\n --g3p-bg-secondary: #f8fafc;\n --g3p-border: #e2e8f0;\n --g3p-border-hover: #cbd5e1;\n --g3p-border-selected: #3b82f6;\n --g3p-text: #1e293b;\n --g3p-text-muted: #475569;\n --g3p-text-subtle: #64748b;\n --g3p-edge-color: #64748b;\n --g3p-port-bg: #e2e8f0;\n --g3p-port-bg-hover: #cbd5e1;\n --g3p-shadow: rgba(0, 0, 0, 0.15);\n}\n\n/* Dark theme (auto via prefers-color-scheme) */\n@media (prefers-color-scheme: dark) {\n :root {\n --g3p-bg: #1a1a1a;\n --g3p-bg-node: #333333;\n --g3p-bg-secondary: #2a2a2a;\n --g3p-border: #4a4a4a;\n --g3p-border-hover: #5a5a5a;\n --g3p-border-selected: #60a5fa;\n --g3p-text: #f0f0f0;\n --g3p-text-muted: #c0c0c0;\n --g3p-text-subtle: #909090;\n --g3p-edge-color: #b0b0b0;\n --g3p-port-bg: #444444;\n --g3p-port-bg-hover: #555555;\n --g3p-shadow: rgba(0, 0, 0, 0.5);\n }\n}\n\n/* Explicit light mode override */\n.g3p-light {\n --g3p-bg: #fafafa;\n --g3p-bg-node: #ffffff;\n --g3p-bg-secondary: #f8fafc;\n --g3p-border: #e2e8f0;\n --g3p-border-hover: #cbd5e1;\n --g3p-border-selected: #3b82f6;\n --g3p-text: #1e293b;\n --g3p-text-muted: #475569;\n --g3p-text-subtle: #64748b;\n --g3p-edge-color: #64748b;\n --g3p-port-bg: #e2e8f0;\n --g3p-port-bg-hover: #cbd5e1;\n --g3p-shadow: rgba(0, 0, 0, 0.15);\n}\n\n/* Explicit dark mode override */\n.g3p-dark {\n --g3p-bg: #1a1a1a;\n --g3p-bg-node: #333333;\n --g3p-bg-secondary: #2a2a2a;\n --g3p-border: #4a4a4a;\n --g3p-border-hover: #5a5a5a;\n --g3p-border-selected: #60a5fa;\n --g3p-text: #f0f0f0;\n --g3p-text-muted: #c0c0c0;\n --g3p-text-subtle: #909090;\n --g3p-edge-color: #b0b0b0;\n --g3p-port-bg: #444444;\n --g3p-port-bg-hover: #555555;\n --g3p-shadow: rgba(0, 0, 0, 0.5);\n}\n\n/* ==================== Canvas ==================== */\n\n.g3p-canvas-container {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.g3p-canvas-root {\n display: block;\n width: 100%;\n height: 100%;\n user-select: none;\n background: var(--g3p-bg);\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n\n/* ==================== Zoom Controls ==================== */\n\n.g3p-zoom-controls {\n position: absolute;\n bottom: 1rem;\n right: 1rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n background: var(--g3p-bg-node);\n border-radius: 8px;\n padding: 0.5rem;\n box-shadow: 0 2px 8px var(--g3p-shadow);\n z-index: 10;\n}\n\n.g3p-zoom-btn {\n width: 36px;\n height: 36px;\n border: 1px solid var(--g3p-border);\n background: var(--g3p-bg-node);\n border-radius: 6px;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--g3p-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n}\n\n.g3p-zoom-btn:hover {\n background: var(--g3p-bg-secondary);\n border-color: var(--g3p-border-hover);\n color: var(--g3p-text);\n}\n\n.g3p-zoom-btn:active {\n transform: scale(0.95);\n}\n\n.g3p-zoom-reset {\n font-size: 1.1rem;\n}\n\n.g3p-zoom-level {\n text-align: center;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--g3p-text-subtle);\n padding: 0.25rem 0;\n}\n\n/* ==================== Nodes ==================== */\n\n/* Default node content styles */\n.g3p-node-default {\n padding: 8px 12px;\n font: 14px/1.4 system-ui, sans-serif;\n color: var(--g3p-text);\n}\n\n.g3p-node-title {\n font-weight: 500;\n}\n\n.g3p-node-detail {\n font-size: 12px;\n color: var(--g3p-text-muted);\n margin-top: 2px;\n}\n\n.g3p-node-container {\n transition: opacity 0.2s ease;\n}\n\n.g3p-node-border {\n background: var(--g3p-bg-node);\n border: 1px solid var(--g3p-border);\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.15s ease;\n}\n\n.g3p-node-border:hover {\n border-color: var(--g3p-border-hover);\n}\n\n.g3p-node-border.selected {\n outline: 2px solid var(--g3p-border-selected);\n}\n\n.g3p-node-content-wrapper {\n pointer-events: none;\n}\n\n.g3p-node-content {\n pointer-events: auto;\n box-sizing: border-box;\n}\n\n.g3p-node-content>div {\n width: 100%;\n height: 100%;\n}\n\n/* Dummy node styles - these remain SVG since dummies are ellipses */\n.g3p-node-dummy .g3p-node-background {\n fill: var(--g3p-bg-secondary);\n opacity: 0.8;\n}\n\n.g3p-node-dummy {\n stroke: var(--g3p-border-hover);\n stroke-dasharray: 3, 3;\n cursor: default;\n}\n\n/* Port container styles */\n.g3p-node-ports {\n display: flex;\n gap: 4px;\n}\n\n.g3p-node-ports-row {\n flex-direction: row;\n justify-content: center;\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.g3p-node-ports-col {\n flex-direction: column;\n justify-content: center;\n padding-top: 8px;\n padding-bottom: 8px;\n}\n\n/* Port styles */\n.g3p-node-port {\n background: var(--g3p-port-bg);\n border: 1px solid var(--g3p-border-hover);\n padding: 2px 6px;\n font-size: 0.5em;\n color: var(--g3p-text-muted);\n white-space: nowrap;\n transition: all 0.15s ease;\n}\n\n.g3p-node-port:hover {\n background: var(--g3p-port-bg-hover);\n border-color: var(--g3p-text-subtle);\n}\n\n.g3p-node-port-rotated-left {\n writing-mode: vertical-lr;\n}\n\n.g3p-node-port-rotated-right {\n writing-mode: vertical-rl;\n}\n\n/* Outside ports: rounded corners away from the node rectangle, no border on touching side */\n.g3p-node-port-out-top {\n border-radius: 4px 4px 0 0;\n border-bottom: none;\n}\n\n.g3p-node-port-out-bottom {\n border-radius: 0 0 4px 4px;\n border-top: none;\n}\n\n.g3p-node-port-out-left {\n border-radius: 4px 0 0 4px;\n border-right: none;\n}\n\n.g3p-node-port-out-right {\n border-radius: 0 4px 4px 0;\n border-left: none;\n}\n\n/* Inside ports: rounded corners toward the content, no border on outer edge */\n.g3p-node-port-in-top {\n border-radius: 0 0 4px 4px;\n border-top: none;\n}\n\n.g3p-node-port-in-bottom {\n border-radius: 4px 4px 0 0;\n border-bottom: none;\n}\n\n.g3p-node-port-in-left {\n border-radius: 0 4px 4px 0;\n border-left: none;\n}\n\n.g3p-node-port-in-right {\n border-radius: 4px 0 0 4px;\n border-right: none;\n}\n\n/* Port wrapper */\n.g3p-node-with-ports {\n display: flex;\n}\n\n.g3p-node-with-ports-v {\n flex-direction: column;\n}\n\n.g3p-node-with-ports-h {\n flex-direction: row;\n}\n\n/* ==================== Edges (Segments) ==================== */\n\n.g3p-seg-container {\n transition: opacity 0.2s ease;\n}\n\n.g3p-seg-line {\n stroke: var(--g3p-edge-color);\n stroke-width: 1;\n transition: stroke 0.2s ease, stroke-width 0.2s ease;\n}\n\n.g3p-seg-marker {\n fill: var(--g3p-edge-color);\n}\n\n.g3p-seg-line.hovered {\n stroke-width: 2;\n opacity: 1;\n}\n\n.g3p-seg-line.selected {\n stroke: var(--g3p-border-selected);\n stroke-width: 2;\n}\n\n.g3p-seg-hitbox {\n cursor: pointer;\n}\n\n/* ==================== Markers ==================== */\n\n.g3p-marker {\n fill: context-stroke;\n stroke: none;\n}\n\n.g3p-marker-bar {\n fill: none;\n stroke: context-stroke;\n stroke-width: 2;\n}\n\n.g3p-marker.hovered {\n fill: var(--g3p-text-muted);\n}\n\n.g3p-marker.selected {\n fill: var(--g3p-border-selected);\n}\n\n.g3p-marker-bar.hovered {\n stroke: var(--g3p-text-muted);\n}\n\n.g3p-marker-bar.selected {\n stroke: var(--g3p-border-selected);\n}\n\n/* ==================== New Edge (Edit Mode) ==================== */\n\n.g3p-new-edge-container {\n pointer-events: none;\n}\n\n.g3p-new-edge-origin {\n fill: var(--g3p-edge-color, #64748b);\n stroke: none;\n}\n\n.g3p-new-edge-line {\n stroke: var(--g3p-edge-color, #64748b);\n stroke-width: 2;\n stroke-dasharray: 6 4;\n stroke-linecap: round;\n fill: none;\n animation: g3p-dash-animation 0.5s linear infinite;\n}\n\n.g3p-new-edge-end {\n fill: var(--g3p-edge-color, #64748b);\n stroke: white;\n stroke-width: 1.5;\n}\n\n@keyframes g3p-dash-animation {\n to {\n stroke-dashoffset: -10;\n }\n}\n\n/* ==================== Edit Mode Hover States ==================== */\n\n.g3p-node-container.g3p-drop-target .g3p-node-border {\n background: var(--g3p-border-selected);\n color: white;\n}\n\n.g3p-node-port.g3p-drop-target {\n background: var(--g3p-border-selected);\n color: white;\n}\n\n/* ==================== Modals ==================== */\n\n.g3p-modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.g3p-modal-dialog {\n background: var(--g3p-bg-node);\n border: 1px solid var(--g3p-border);\n border-radius: 8px;\n box-shadow: 0 4px 20px var(--g3p-shadow);\n min-width: 280px;\n max-width: 400px;\n}\n\n.g3p-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid var(--g3p-border);\n}\n\n.g3p-modal-title {\n font-weight: 600;\n font-size: 14px;\n color: var(--g3p-text);\n}\n\n.g3p-modal-close {\n background: none;\n border: none;\n font-size: 20px;\n color: var(--g3p-text-muted);\n cursor: pointer;\n padding: 0;\n line-height: 1;\n}\n\n.g3p-modal-close:hover {\n color: var(--g3p-text);\n}\n\n.g3p-modal-body {\n padding: 16px;\n}\n\n.g3p-modal-field {\n margin-bottom: 12px;\n}\n\n.g3p-modal-field:last-child {\n margin-bottom: 0;\n}\n\n.g3p-modal-label {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: var(--g3p-text-muted);\n margin-bottom: 4px;\n}\n\n.g3p-modal-input,\n.g3p-modal-select {\n width: 100%;\n padding: 8px 10px;\n font-size: 13px;\n border: 1px solid var(--g3p-border);\n border-radius: 4px;\n background: var(--g3p-bg);\n color: var(--g3p-text);\n box-sizing: border-box;\n}\n\n.g3p-modal-input:focus,\n.g3p-modal-select:focus {\n outline: none;\n border-color: var(--g3p-border-selected);\n}\n\n.g3p-modal-footer {\n padding: 12px 16px;\n border-top: 1px solid var(--g3p-border);\n}\n\n.g3p-modal-buttons {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.g3p-modal-spacer {\n flex: 1;\n}\n\n.g3p-modal-btn {\n padding: 6px 12px;\n font-size: 13px;\n font-weight: 500;\n border-radius: 4px;\n cursor: pointer;\n border: 1px solid transparent;\n transition: all 0.15s ease;\n}\n\n.g3p-modal-btn-primary {\n background: var(--g3p-border-selected);\n color: white;\n}\n\n.g3p-modal-btn-primary:hover {\n filter: brightness(1.1);\n}\n\n.g3p-modal-btn-secondary {\n background: var(--g3p-bg);\n border-color: var(--g3p-border);\n color: var(--g3p-text);\n}\n\n.g3p-modal-btn-secondary:hover {\n background: var(--g3p-bg-secondary);\n}\n\n.g3p-modal-btn-danger {\n background: #ef4444;\n color: white;\n}\n\n.g3p-modal-btn-danger:hover {\n background: #dc2626;\n}";
2795
2800
 
2796
2801
  // src/canvas/canvas.tsx
2797
- import { jsx as jsx6, jsxs as jsxs5 } from "jsx-dom/jsx-runtime";
2802
+ import { jsx as jsx6, jsxs as jsxs5 } from "jsx-dom/jsx-runtime.js";
2798
2803
  var log10 = logger("canvas");
2799
2804
  var Canvas = class {
2800
2805
  container;
@@ -2929,6 +2934,13 @@ var Canvas = class {
2929
2934
  newNodes.set(data.data, node);
2930
2935
  this.measurement.appendChild(node.content);
2931
2936
  }
2937
+ if (this.mountNode) {
2938
+ for (const node of newNodes.values()) {
2939
+ if (node.innerContent) {
2940
+ node.cleanup = this.mountNode(node.data.data, node.innerContent) ?? void 0;
2941
+ }
2942
+ }
2943
+ }
2932
2944
  await new Promise(requestAnimationFrame);
2933
2945
  const isVertical = this.orientation === "TB" || this.orientation === "BT";
2934
2946
  for (const node of newNodes.values()) {
@@ -3500,7 +3512,7 @@ function themeToCSS(theme, selector, prefix = "") {
3500
3512
  }
3501
3513
 
3502
3514
  // src/canvas/render-node.tsx
3503
- import { jsx as jsx7, jsxs as jsxs6 } from "jsx-dom/jsx-runtime";
3515
+ import { jsx as jsx7, jsxs as jsxs6 } from "jsx-dom/jsx-runtime.js";
3504
3516
  function renderNode(node, props) {
3505
3517
  if (typeof node == "string") node = { id: node };
3506
3518
  const title = node?.title ?? props?.title ?? node?.label ?? node?.name ?? node?.text ?? props?.text ?? node?.id ?? "?";