@01.software/sdk 0.4.0 → 0.4.1

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 (39) hide show
  1. package/dist/auth.d.cts +1 -1
  2. package/dist/auth.d.ts +1 -1
  3. package/dist/{const-BpirbGBD.d.cts → const-BsO3aVX_.d.cts} +1 -1
  4. package/dist/{const-qZSQiSSC.d.ts → const-DZyvV9wU.d.ts} +1 -1
  5. package/dist/index.cjs +57 -8
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +6 -6
  8. package/dist/index.d.ts +6 -6
  9. package/dist/index.js +57 -8
  10. package/dist/index.js.map +1 -1
  11. package/dist/{payload-types-CZiaL4Wr.d.cts → payload-types-BsjHfeAF.d.cts} +62 -2
  12. package/dist/{payload-types-CZiaL4Wr.d.ts → payload-types-BsjHfeAF.d.ts} +62 -2
  13. package/dist/realtime.cjs +5 -3
  14. package/dist/realtime.cjs.map +1 -1
  15. package/dist/realtime.d.cts +2 -2
  16. package/dist/realtime.d.ts +2 -2
  17. package/dist/realtime.js +5 -3
  18. package/dist/realtime.js.map +1 -1
  19. package/dist/ui/flow.cjs +264 -36
  20. package/dist/ui/flow.cjs.map +1 -1
  21. package/dist/ui/flow.d.cts +104 -3
  22. package/dist/ui/flow.d.ts +104 -3
  23. package/dist/ui/flow.js +252 -21
  24. package/dist/ui/flow.js.map +1 -1
  25. package/dist/ui/form.d.cts +1 -1
  26. package/dist/ui/form.d.ts +1 -1
  27. package/dist/ui/rich-text.cjs +8 -1
  28. package/dist/ui/rich-text.cjs.map +1 -1
  29. package/dist/ui/rich-text.d.cts +20 -1
  30. package/dist/ui/rich-text.d.ts +20 -1
  31. package/dist/ui/rich-text.js +8 -1
  32. package/dist/ui/rich-text.js.map +1 -1
  33. package/dist/ui/video.d.cts +1 -1
  34. package/dist/ui/video.d.ts +1 -1
  35. package/dist/{webhook-DuTqrH9x.d.ts → webhook-BBWl8O2f.d.ts} +2 -2
  36. package/dist/{webhook-3iL9OEyq.d.cts → webhook-CkL56e65.d.cts} +2 -2
  37. package/dist/webhook.d.cts +3 -3
  38. package/dist/webhook.d.ts +3 -3
  39. package/package.json +2 -1
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { QueryClient } from '@tanstack/react-query';
3
+ import { Edge } from '@xyflow/react';
3
4
 
4
5
  interface DynamicNodeData {
5
6
  nodeTypeSlug: string;
@@ -105,6 +106,39 @@ interface FrameNodeData {
105
106
  borderStyle?: 'dashed' | 'solid' | 'none';
106
107
  opacity?: number;
107
108
  }
109
+ interface FrameNodeSlotProps {
110
+ id: string;
111
+ label: string;
112
+ color?: string;
113
+ padding?: number;
114
+ borderStyle?: 'dashed' | 'solid' | 'none';
115
+ opacity?: number;
116
+ children?: React.ReactNode;
117
+ }
118
+ interface EdgeSlotProps {
119
+ id: string;
120
+ edgeTypeSlug?: string;
121
+ source: string;
122
+ target: string;
123
+ label?: string;
124
+ fields?: Record<string, unknown>;
125
+ edgeTypeDef?: EdgeTypeDef;
126
+ style?: React.CSSProperties;
127
+ }
128
+ interface NodeWrapperSlotProps {
129
+ id: string;
130
+ nodeTypeSlug: string;
131
+ label: string;
132
+ selected?: boolean;
133
+ nodeTypeDef?: NodeTypeDef;
134
+ children: React.ReactNode;
135
+ }
136
+ interface FlowBounds {
137
+ x: number;
138
+ y: number;
139
+ width: number;
140
+ height: number;
141
+ }
108
142
 
109
143
  declare const BUILT_IN_NODE_TYPES: NodeTypeDef[];
110
144
 
@@ -139,6 +173,47 @@ interface UseFlowResult {
139
173
  }
140
174
  declare function useFlow(options: UseFlowOptions): UseFlowResult;
141
175
 
176
+ interface UseFlowDataOptions {
177
+ /** Canvas data from Flow document's `canvas` field */
178
+ data: CanvasData | undefined;
179
+ /** Node type definitions (defaults to built-in types) */
180
+ nodeTypeDefs?: NodeTypeDef[];
181
+ /** Edge type definitions (defaults to built-in types) */
182
+ edgeTypeDefs?: EdgeTypeDef[];
183
+ }
184
+ interface UseFlowDataResult {
185
+ /** Nodes from canvas data */
186
+ nodes: FlowNode[];
187
+ /** Edges from canvas data (typed for @xyflow/react) */
188
+ edges: Edge[];
189
+ /** Map of node type slug to definition */
190
+ nodeTypeDefsMap: Map<string, NodeTypeDef>;
191
+ /** Map of edge type slug to definition */
192
+ edgeTypeDefsMap: Map<string, EdgeTypeDef>;
193
+ }
194
+ /**
195
+ * Pure data transformation hook — extracts nodes, edges, and type definition
196
+ * maps from canvas data without any rendering. Useful for headless usage
197
+ * (custom layouts, analytics, server-side processing).
198
+ */
199
+ declare function useFlowData(options: UseFlowDataOptions): UseFlowDataResult;
200
+
201
+ /**
202
+ * Calculate bounding box for given node IDs.
203
+ * Pure function — usable in SSR, server components, or outside React.
204
+ */
205
+ declare function getNodeBounds(nodes: FlowNode[], nodeIds: string[]): FlowBounds | undefined;
206
+ /**
207
+ * Get all frame nodes with their bounds.
208
+ * Sorted by position (top-left to bottom-right).
209
+ * Builds a single nodeMap to compute absolute positions (O(F) instead of O(F*N)).
210
+ */
211
+ declare function getFrames(nodes: FlowNode[]): Array<{
212
+ id: string;
213
+ label: string;
214
+ bounds: FlowBounds;
215
+ }>;
216
+
142
217
  /**
143
218
  * Renders a Flow canvas in read-only mode.
144
219
  *
@@ -160,7 +235,7 @@ interface FlowRendererProps {
160
235
  nodeTypeDefs?: NodeTypeDef[];
161
236
  /** Edge type definitions for styled edges (color, stroke, markers, animation) */
162
237
  edgeTypeDefs?: EdgeTypeDef[];
163
- /** Show background pattern (default: true) */
238
+ /** Show background pattern (default: false) */
164
239
  background?: boolean;
165
240
  /** Allow user interaction - pan, zoom (default: false for read-only display) */
166
241
  interactive?: boolean;
@@ -170,7 +245,33 @@ interface FlowRendererProps {
170
245
  onNodeClick?: (event: React.MouseEvent, node: FlowNode) => void;
171
246
  /** Called when an edge is clicked */
172
247
  onEdgeClick?: (event: React.MouseEvent, edge: FlowEdge) => void;
248
+ /** S1: Custom frame node renderer. Should be a stable reference (memoize or define outside render). */
249
+ frameRenderer?: React.ComponentType<FrameNodeSlotProps>;
250
+ /** S2: Custom edge renderers by edge type slug. Should be a stable reference (memoize or define outside render). */
251
+ edgeRenderers?: Record<string, React.ComponentType<EdgeSlotProps>>;
252
+ /** S3: Wraps every dynamic node's rendered content. Should be a stable reference (memoize or define outside render). */
253
+ nodeWrapper?: React.ComponentType<NodeWrapperSlotProps>;
254
+ /** S4: Show controls (default: false) */
255
+ controls?: boolean;
256
+ /** S4: Show minimap (default: false) */
257
+ minimap?: boolean;
258
+ /** S4: Custom minimap node color function */
259
+ minimapNodeColor?: (node: FlowNode) => string;
260
+ /** S4: Additional children rendered inside ReactFlow */
261
+ children?: React.ReactNode;
262
+ /** S5: Global override for all dynamic nodes. Should be a stable reference (memoize or define outside render). */
263
+ renderNode?: (props: DynamicNodeSlotProps, defaultRender: React.ReactElement) => React.ReactElement | null;
264
+ /** S6: Called when viewport changes (pan/zoom) */
265
+ onViewportChange?: (viewport: FlowViewport) => void;
266
+ /** S6: Default viewport (used when fitView is false) */
267
+ defaultViewport?: FlowViewport;
268
+ /** S8: Focus on specific bounds */
269
+ bounds?: FlowBounds;
270
+ /** S8: Padding for focus bounds (default: 0.1) */
271
+ focusPadding?: number;
272
+ /** S8: Animate focus transition (true=300ms, number=custom ms, false=instant) */
273
+ focusAnimation?: boolean | number;
173
274
  }
174
- declare function FlowRenderer({ data, className, style, nodeRenderers, nodeTypeDefs, edgeTypeDefs, background, interactive, fitView, onNodeClick, onEdgeClick, }: FlowRendererProps): React.JSX.Element | null;
275
+ declare function FlowRenderer({ data, className, style, nodeRenderers, nodeTypeDefs, edgeTypeDefs, background, interactive, fitView, onNodeClick, onEdgeClick, frameRenderer, edgeRenderers, nodeWrapper, controls, minimap, minimapNodeColor, children, renderNode, onViewportChange, defaultViewport: defaultViewportProp, bounds, focusPadding, focusAnimation, }: FlowRendererProps): React.JSX.Element | null;
175
276
 
176
- export { BUILT_IN_EDGE_TYPES, BUILT_IN_NODE_TYPES, type CanvasData, type DynamicNodeData, type DynamicNodeSlotProps, type EdgeTypeDef, type FlowEdge, type FlowNode, type FlowNodeData, type FlowNodePosition, FlowRenderer, type FlowRendererProps, type FlowViewport, type FrameNodeData, type NodeTypeDef, type NodeTypeFieldDef, type SDKClient, type UseFlowOptions, type UseFlowResult, isDynamicNode, isFrameNode, useFlow };
277
+ export { BUILT_IN_EDGE_TYPES, BUILT_IN_NODE_TYPES, type CanvasData, type DynamicNodeData, type DynamicNodeSlotProps, type EdgeSlotProps, type EdgeTypeDef, type FlowBounds, type FlowEdge, type FlowNode, type FlowNodeData, type FlowNodePosition, FlowRenderer, type FlowRendererProps, type FlowViewport, type FrameNodeData, type FrameNodeSlotProps, type NodeTypeDef, type NodeTypeFieldDef, type NodeWrapperSlotProps, type SDKClient, type UseFlowDataOptions, type UseFlowDataResult, type UseFlowOptions, type UseFlowResult, getFrames, getNodeBounds, isDynamicNode, isFrameNode, useFlow, useFlowData };
package/dist/ui/flow.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { QueryClient } from '@tanstack/react-query';
3
+ import { Edge } from '@xyflow/react';
3
4
 
4
5
  interface DynamicNodeData {
5
6
  nodeTypeSlug: string;
@@ -105,6 +106,39 @@ interface FrameNodeData {
105
106
  borderStyle?: 'dashed' | 'solid' | 'none';
106
107
  opacity?: number;
107
108
  }
109
+ interface FrameNodeSlotProps {
110
+ id: string;
111
+ label: string;
112
+ color?: string;
113
+ padding?: number;
114
+ borderStyle?: 'dashed' | 'solid' | 'none';
115
+ opacity?: number;
116
+ children?: React.ReactNode;
117
+ }
118
+ interface EdgeSlotProps {
119
+ id: string;
120
+ edgeTypeSlug?: string;
121
+ source: string;
122
+ target: string;
123
+ label?: string;
124
+ fields?: Record<string, unknown>;
125
+ edgeTypeDef?: EdgeTypeDef;
126
+ style?: React.CSSProperties;
127
+ }
128
+ interface NodeWrapperSlotProps {
129
+ id: string;
130
+ nodeTypeSlug: string;
131
+ label: string;
132
+ selected?: boolean;
133
+ nodeTypeDef?: NodeTypeDef;
134
+ children: React.ReactNode;
135
+ }
136
+ interface FlowBounds {
137
+ x: number;
138
+ y: number;
139
+ width: number;
140
+ height: number;
141
+ }
108
142
 
109
143
  declare const BUILT_IN_NODE_TYPES: NodeTypeDef[];
110
144
 
@@ -139,6 +173,47 @@ interface UseFlowResult {
139
173
  }
140
174
  declare function useFlow(options: UseFlowOptions): UseFlowResult;
141
175
 
176
+ interface UseFlowDataOptions {
177
+ /** Canvas data from Flow document's `canvas` field */
178
+ data: CanvasData | undefined;
179
+ /** Node type definitions (defaults to built-in types) */
180
+ nodeTypeDefs?: NodeTypeDef[];
181
+ /** Edge type definitions (defaults to built-in types) */
182
+ edgeTypeDefs?: EdgeTypeDef[];
183
+ }
184
+ interface UseFlowDataResult {
185
+ /** Nodes from canvas data */
186
+ nodes: FlowNode[];
187
+ /** Edges from canvas data (typed for @xyflow/react) */
188
+ edges: Edge[];
189
+ /** Map of node type slug to definition */
190
+ nodeTypeDefsMap: Map<string, NodeTypeDef>;
191
+ /** Map of edge type slug to definition */
192
+ edgeTypeDefsMap: Map<string, EdgeTypeDef>;
193
+ }
194
+ /**
195
+ * Pure data transformation hook — extracts nodes, edges, and type definition
196
+ * maps from canvas data without any rendering. Useful for headless usage
197
+ * (custom layouts, analytics, server-side processing).
198
+ */
199
+ declare function useFlowData(options: UseFlowDataOptions): UseFlowDataResult;
200
+
201
+ /**
202
+ * Calculate bounding box for given node IDs.
203
+ * Pure function — usable in SSR, server components, or outside React.
204
+ */
205
+ declare function getNodeBounds(nodes: FlowNode[], nodeIds: string[]): FlowBounds | undefined;
206
+ /**
207
+ * Get all frame nodes with their bounds.
208
+ * Sorted by position (top-left to bottom-right).
209
+ * Builds a single nodeMap to compute absolute positions (O(F) instead of O(F*N)).
210
+ */
211
+ declare function getFrames(nodes: FlowNode[]): Array<{
212
+ id: string;
213
+ label: string;
214
+ bounds: FlowBounds;
215
+ }>;
216
+
142
217
  /**
143
218
  * Renders a Flow canvas in read-only mode.
144
219
  *
@@ -160,7 +235,7 @@ interface FlowRendererProps {
160
235
  nodeTypeDefs?: NodeTypeDef[];
161
236
  /** Edge type definitions for styled edges (color, stroke, markers, animation) */
162
237
  edgeTypeDefs?: EdgeTypeDef[];
163
- /** Show background pattern (default: true) */
238
+ /** Show background pattern (default: false) */
164
239
  background?: boolean;
165
240
  /** Allow user interaction - pan, zoom (default: false for read-only display) */
166
241
  interactive?: boolean;
@@ -170,7 +245,33 @@ interface FlowRendererProps {
170
245
  onNodeClick?: (event: React.MouseEvent, node: FlowNode) => void;
171
246
  /** Called when an edge is clicked */
172
247
  onEdgeClick?: (event: React.MouseEvent, edge: FlowEdge) => void;
248
+ /** S1: Custom frame node renderer. Should be a stable reference (memoize or define outside render). */
249
+ frameRenderer?: React.ComponentType<FrameNodeSlotProps>;
250
+ /** S2: Custom edge renderers by edge type slug. Should be a stable reference (memoize or define outside render). */
251
+ edgeRenderers?: Record<string, React.ComponentType<EdgeSlotProps>>;
252
+ /** S3: Wraps every dynamic node's rendered content. Should be a stable reference (memoize or define outside render). */
253
+ nodeWrapper?: React.ComponentType<NodeWrapperSlotProps>;
254
+ /** S4: Show controls (default: false) */
255
+ controls?: boolean;
256
+ /** S4: Show minimap (default: false) */
257
+ minimap?: boolean;
258
+ /** S4: Custom minimap node color function */
259
+ minimapNodeColor?: (node: FlowNode) => string;
260
+ /** S4: Additional children rendered inside ReactFlow */
261
+ children?: React.ReactNode;
262
+ /** S5: Global override for all dynamic nodes. Should be a stable reference (memoize or define outside render). */
263
+ renderNode?: (props: DynamicNodeSlotProps, defaultRender: React.ReactElement) => React.ReactElement | null;
264
+ /** S6: Called when viewport changes (pan/zoom) */
265
+ onViewportChange?: (viewport: FlowViewport) => void;
266
+ /** S6: Default viewport (used when fitView is false) */
267
+ defaultViewport?: FlowViewport;
268
+ /** S8: Focus on specific bounds */
269
+ bounds?: FlowBounds;
270
+ /** S8: Padding for focus bounds (default: 0.1) */
271
+ focusPadding?: number;
272
+ /** S8: Animate focus transition (true=300ms, number=custom ms, false=instant) */
273
+ focusAnimation?: boolean | number;
173
274
  }
174
- declare function FlowRenderer({ data, className, style, nodeRenderers, nodeTypeDefs, edgeTypeDefs, background, interactive, fitView, onNodeClick, onEdgeClick, }: FlowRendererProps): React.JSX.Element | null;
275
+ declare function FlowRenderer({ data, className, style, nodeRenderers, nodeTypeDefs, edgeTypeDefs, background, interactive, fitView, onNodeClick, onEdgeClick, frameRenderer, edgeRenderers, nodeWrapper, controls, minimap, minimapNodeColor, children, renderNode, onViewportChange, defaultViewport: defaultViewportProp, bounds, focusPadding, focusAnimation, }: FlowRendererProps): React.JSX.Element | null;
175
276
 
176
- export { BUILT_IN_EDGE_TYPES, BUILT_IN_NODE_TYPES, type CanvasData, type DynamicNodeData, type DynamicNodeSlotProps, type EdgeTypeDef, type FlowEdge, type FlowNode, type FlowNodeData, type FlowNodePosition, FlowRenderer, type FlowRendererProps, type FlowViewport, type FrameNodeData, type NodeTypeDef, type NodeTypeFieldDef, type SDKClient, type UseFlowOptions, type UseFlowResult, isDynamicNode, isFrameNode, useFlow };
277
+ export { BUILT_IN_EDGE_TYPES, BUILT_IN_NODE_TYPES, type CanvasData, type DynamicNodeData, type DynamicNodeSlotProps, type EdgeSlotProps, type EdgeTypeDef, type FlowBounds, type FlowEdge, type FlowNode, type FlowNodeData, type FlowNodePosition, FlowRenderer, type FlowRendererProps, type FlowViewport, type FrameNodeData, type FrameNodeSlotProps, type NodeTypeDef, type NodeTypeFieldDef, type NodeWrapperSlotProps, type SDKClient, type UseFlowDataOptions, type UseFlowDataResult, type UseFlowOptions, type UseFlowResult, getFrames, getNodeBounds, isDynamicNode, isFrameNode, useFlow, useFlowData };
package/dist/ui/flow.js CHANGED
@@ -1,5 +1,7 @@
1
1
  "use client";
2
2
  var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
3
5
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
4
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
7
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
@@ -15,6 +17,7 @@ var __spreadValues = (a, b) => {
15
17
  }
16
18
  return a;
17
19
  };
20
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
18
21
  var __async = (__this, __arguments, generator) => {
19
22
  return new Promise((resolve, reject) => {
20
23
  var fulfilled = (value) => {
@@ -42,7 +45,10 @@ import {
42
45
  ReactFlow,
43
46
  ReactFlowProvider,
44
47
  Background,
45
- MarkerType
48
+ Controls,
49
+ MiniMap,
50
+ MarkerType,
51
+ useReactFlow
46
52
  } from "@xyflow/react";
47
53
 
48
54
  // src/ui/Flow/types.ts
@@ -209,6 +215,104 @@ function useFlow(options) {
209
215
  };
210
216
  }
211
217
 
218
+ // src/ui/Flow/useFlowData.ts
219
+ import { useMemo as useMemo2 } from "react";
220
+ function useFlowData(options) {
221
+ const { data, nodeTypeDefs: inputNodeDefs, edgeTypeDefs: inputEdgeDefs } = options;
222
+ const nodeTypeDefsMap = useMemo2(() => {
223
+ const allDefs = inputNodeDefs != null ? inputNodeDefs : BUILT_IN_NODE_TYPES;
224
+ return new Map(allDefs.map((d) => [d.slug, d]));
225
+ }, [inputNodeDefs]);
226
+ const edgeTypeDefsMap = useMemo2(() => {
227
+ const allDefs = inputEdgeDefs != null ? inputEdgeDefs : BUILT_IN_EDGE_TYPES;
228
+ return new Map(allDefs.map((d) => [d.slug, d]));
229
+ }, [inputEdgeDefs]);
230
+ const nodes = useMemo2(() => {
231
+ var _a;
232
+ return (_a = data == null ? void 0 : data.nodes) != null ? _a : [];
233
+ }, [data == null ? void 0 : data.nodes]);
234
+ const edges = useMemo2(() => {
235
+ var _a;
236
+ return (_a = data == null ? void 0 : data.edges) != null ? _a : [];
237
+ }, [data == null ? void 0 : data.edges]);
238
+ return {
239
+ nodes,
240
+ edges,
241
+ nodeTypeDefsMap,
242
+ edgeTypeDefsMap
243
+ };
244
+ }
245
+
246
+ // src/ui/Flow/utils.ts
247
+ function getNodeBounds(nodes, nodeIds) {
248
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
249
+ const idSet = new Set(nodeIds);
250
+ const targetNodes = nodes.filter((n) => idSet.has(n.id));
251
+ if (targetNodes.length === 0) return void 0;
252
+ const nodeMap = new Map(nodes.map((n) => [n.id, n]));
253
+ function getAbsolutePosition(node) {
254
+ let x = node.position.x;
255
+ let y = node.position.y;
256
+ let current = node;
257
+ const visited = /* @__PURE__ */ new Set([node.id]);
258
+ while (current.parentId) {
259
+ const parentId = current.parentId;
260
+ if (visited.has(parentId)) break;
261
+ const parent = nodeMap.get(parentId);
262
+ if (!parent) break;
263
+ visited.add(parent.id);
264
+ x += parent.position.x;
265
+ y += parent.position.y;
266
+ current = parent;
267
+ }
268
+ return { x, y };
269
+ }
270
+ let minX = Infinity;
271
+ let minY = Infinity;
272
+ let maxX = -Infinity;
273
+ let maxY = -Infinity;
274
+ for (const node of targetNodes) {
275
+ const abs = getAbsolutePosition(node);
276
+ const w = (_e = (_d = (_c = (_a = node.style) == null ? void 0 : _a.width) != null ? _c : (_b = node.measured) == null ? void 0 : _b.width) != null ? _d : node.width) != null ? _e : 200;
277
+ const h = (_j = (_i = (_h = (_f = node.style) == null ? void 0 : _f.height) != null ? _h : (_g = node.measured) == null ? void 0 : _g.height) != null ? _i : node.height) != null ? _j : 200;
278
+ minX = Math.min(minX, abs.x);
279
+ minY = Math.min(minY, abs.y);
280
+ maxX = Math.max(maxX, abs.x + w);
281
+ maxY = Math.max(maxY, abs.y + h);
282
+ }
283
+ return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
284
+ }
285
+ function getFrames(nodes) {
286
+ const frames = nodes.filter((n) => n.type === "frame");
287
+ if (frames.length === 0) return [];
288
+ const nodeMap = new Map(nodes.map((n) => [n.id, n]));
289
+ function getAbsolutePosition(node) {
290
+ let x = node.position.x;
291
+ let y = node.position.y;
292
+ let current = node;
293
+ const visited = /* @__PURE__ */ new Set([node.id]);
294
+ while (current.parentId) {
295
+ const parentId = current.parentId;
296
+ if (visited.has(parentId)) break;
297
+ const parent = nodeMap.get(parentId);
298
+ if (!parent) break;
299
+ visited.add(parent.id);
300
+ x += parent.position.x;
301
+ y += parent.position.y;
302
+ current = parent;
303
+ }
304
+ return { x, y };
305
+ }
306
+ return frames.map((f) => {
307
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
308
+ const data = f.data;
309
+ const abs = getAbsolutePosition(f);
310
+ const w = (_e = (_d = (_c = (_a = f.style) == null ? void 0 : _a.width) != null ? _c : (_b = f.measured) == null ? void 0 : _b.width) != null ? _d : f.width) != null ? _e : 200;
311
+ const h = (_j = (_i = (_h = (_f = f.style) == null ? void 0 : _f.height) != null ? _h : (_g = f.measured) == null ? void 0 : _g.height) != null ? _i : f.height) != null ? _j : 200;
312
+ return { id: f.id, label: (_k = data.label) != null ? _k : "", bounds: { x: abs.x, y: abs.y, width: w, height: h } };
313
+ }).sort((a, b) => a.bounds.y - b.bounds.y || a.bounds.x - b.bounds.x);
314
+ }
315
+
212
316
  // src/ui/Flow/index.tsx
213
317
  function sanitizeUrl(url) {
214
318
  if (!url) return url;
@@ -331,14 +435,15 @@ function DefaultFrameNode({ data }) {
331
435
  )
332
436
  );
333
437
  }
334
- function createNodeTypes(nodeRenderers, nodeTypeDefsMap) {
438
+ function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrapper, renderNode) {
335
439
  const types = {};
336
440
  types.dynamic = ((props) => {
337
441
  const d = props.data;
338
442
  const typeDef = nodeTypeDefsMap == null ? void 0 : nodeTypeDefsMap.get(d.nodeTypeSlug);
339
443
  const CustomRenderer = nodeRenderers == null ? void 0 : nodeRenderers[d.nodeTypeSlug];
444
+ let content;
340
445
  if (CustomRenderer) {
341
- return /* @__PURE__ */ React.createElement(
446
+ content = /* @__PURE__ */ React.createElement(
342
447
  CustomRenderer,
343
448
  {
344
449
  id: props.id,
@@ -348,15 +453,94 @@ function createNodeTypes(nodeRenderers, nodeTypeDefsMap) {
348
453
  nodeTypeDef: typeDef
349
454
  }
350
455
  );
456
+ } else if (typeDef) {
457
+ content = /* @__PURE__ */ React.createElement(EnhancedDynamicNode, { data: d, typeDef });
458
+ } else {
459
+ content = /* @__PURE__ */ React.createElement(DefaultDynamicNode, __spreadValues({}, props));
351
460
  }
352
- if (typeDef) {
353
- return /* @__PURE__ */ React.createElement(EnhancedDynamicNode, { data: d, typeDef });
461
+ if (renderNode) {
462
+ const slotProps = {
463
+ id: props.id,
464
+ nodeTypeSlug: d.nodeTypeSlug,
465
+ label: d.label,
466
+ fields: d.fields,
467
+ nodeTypeDef: typeDef
468
+ };
469
+ const result = renderNode(slotProps, content);
470
+ if (result !== null) content = result;
354
471
  }
355
- return /* @__PURE__ */ React.createElement(DefaultDynamicNode, __spreadValues({}, props));
472
+ if (nodeWrapper) {
473
+ const Wrapper = nodeWrapper;
474
+ content = /* @__PURE__ */ React.createElement(
475
+ Wrapper,
476
+ {
477
+ id: props.id,
478
+ nodeTypeSlug: d.nodeTypeSlug,
479
+ label: d.label,
480
+ selected: props.selected,
481
+ nodeTypeDef: typeDef
482
+ },
483
+ content
484
+ );
485
+ }
486
+ return content;
356
487
  });
357
- types.frame = DefaultFrameNode;
488
+ types.frame = frameRenderer ? ((props) => {
489
+ const d = props.data;
490
+ const Renderer = frameRenderer;
491
+ return /* @__PURE__ */ React.createElement(
492
+ Renderer,
493
+ {
494
+ id: props.id,
495
+ label: d.label,
496
+ color: d.color,
497
+ padding: d.padding,
498
+ borderStyle: d.borderStyle,
499
+ opacity: d.opacity
500
+ }
501
+ );
502
+ }) : DefaultFrameNode;
358
503
  return types;
359
504
  }
505
+ function createEdgeTypes(edgeRenderers, edgeTypeDefsMap) {
506
+ if (!edgeRenderers || Object.keys(edgeRenderers).length === 0) return void 0;
507
+ const types = {};
508
+ for (const [slug, Renderer] of Object.entries(edgeRenderers)) {
509
+ types[slug] = ((props) => {
510
+ var _a;
511
+ const def = edgeTypeDefsMap == null ? void 0 : edgeTypeDefsMap.get(slug);
512
+ return /* @__PURE__ */ React.createElement(
513
+ Renderer,
514
+ {
515
+ id: props.id,
516
+ edgeTypeSlug: slug,
517
+ source: props.source,
518
+ target: props.target,
519
+ label: props.label,
520
+ fields: (_a = props.data) == null ? void 0 : _a.fields,
521
+ edgeTypeDef: def,
522
+ style: props.style
523
+ }
524
+ );
525
+ });
526
+ }
527
+ return types;
528
+ }
529
+ function FocusHandler({
530
+ bounds,
531
+ padding,
532
+ animation
533
+ }) {
534
+ const { fitBounds } = useReactFlow();
535
+ const boundsKey = `${bounds.x},${bounds.y},${bounds.width},${bounds.height}`;
536
+ const boundsRef = React.useRef(bounds);
537
+ boundsRef.current = bounds;
538
+ React.useEffect(() => {
539
+ const duration = animation === true ? 300 : typeof animation === "number" ? animation : 0;
540
+ fitBounds(boundsRef.current, { padding, duration });
541
+ }, [boundsKey, padding, animation, fitBounds]);
542
+ return null;
543
+ }
360
544
  var EDGE_TYPE_MAP = {
361
545
  step: "step",
362
546
  smoothstep: "smoothstep",
@@ -403,11 +587,24 @@ function FlowRenderer({
403
587
  nodeRenderers,
404
588
  nodeTypeDefs,
405
589
  edgeTypeDefs,
406
- background = true,
590
+ background = false,
407
591
  interactive = false,
408
592
  fitView = true,
409
593
  onNodeClick,
410
- onEdgeClick
594
+ onEdgeClick,
595
+ frameRenderer,
596
+ edgeRenderers,
597
+ nodeWrapper,
598
+ controls,
599
+ minimap,
600
+ minimapNodeColor,
601
+ children,
602
+ renderNode,
603
+ onViewportChange,
604
+ defaultViewport: defaultViewportProp,
605
+ bounds,
606
+ focusPadding,
607
+ focusAnimation
411
608
  }) {
412
609
  var _a;
413
610
  const nodeTypeDefsMap = React.useMemo(() => {
@@ -419,18 +616,29 @@ function FlowRenderer({
419
616
  return new Map(edgeTypeDefs.map((d) => [d.slug, d]));
420
617
  }, [edgeTypeDefs]);
421
618
  const nodeTypes = React.useMemo(
422
- () => createNodeTypes(nodeRenderers, nodeTypeDefsMap),
423
- [nodeRenderers, nodeTypeDefsMap]
619
+ () => createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrapper, renderNode),
620
+ [nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrapper, renderNode]
424
621
  );
425
- const styledEdges = React.useMemo(
426
- () => {
427
- var _a2;
428
- return applyEdgeStyles((_a2 = data == null ? void 0 : data.edges) != null ? _a2 : [], edgeTypeDefsMap);
429
- },
430
- [data == null ? void 0 : data.edges, edgeTypeDefsMap]
622
+ const customEdgeTypes = React.useMemo(
623
+ () => createEdgeTypes(edgeRenderers, edgeTypeDefsMap),
624
+ [edgeRenderers, edgeTypeDefsMap]
431
625
  );
626
+ const styledEdges = React.useMemo(() => {
627
+ var _a2;
628
+ let edges = applyEdgeStyles((_a2 = data == null ? void 0 : data.edges) != null ? _a2 : [], edgeTypeDefsMap);
629
+ if (edgeRenderers) {
630
+ edges = edges.map((edge) => {
631
+ const slug = edge.edgeTypeSlug;
632
+ if (slug && edgeRenderers[slug]) {
633
+ return __spreadProps(__spreadValues({}, edge), { type: slug });
634
+ }
635
+ return edge;
636
+ });
637
+ }
638
+ return edges;
639
+ }, [data == null ? void 0 : data.edges, edgeTypeDefsMap, edgeRenderers]);
432
640
  if (!data) return null;
433
- const defaultViewport = !fitView && data.viewport ? data.viewport : void 0;
641
+ const resolvedDefaultViewport = defaultViewportProp != null ? defaultViewportProp : !fitView && data.viewport ? data.viewport : void 0;
434
642
  return /* @__PURE__ */ React.createElement(ReactFlowProvider, null, /* @__PURE__ */ React.createElement(
435
643
  "div",
436
644
  {
@@ -443,10 +651,14 @@ function FlowRenderer({
443
651
  nodes: (_a = data.nodes) != null ? _a : [],
444
652
  edges: styledEdges,
445
653
  nodeTypes,
446
- defaultViewport,
654
+ edgeTypes: customEdgeTypes,
655
+ defaultViewport: resolvedDefaultViewport,
447
656
  fitView,
448
657
  onNodeClick,
449
658
  onEdgeClick,
659
+ onMoveEnd: onViewportChange ? ((_, vp) => {
660
+ onViewportChange(vp);
661
+ }) : void 0,
450
662
  nodesDraggable: interactive ? void 0 : false,
451
663
  nodesConnectable: false,
452
664
  elementsSelectable: interactive || !!onNodeClick || !!onEdgeClick,
@@ -455,7 +667,23 @@ function FlowRenderer({
455
667
  zoomOnPinch: interactive,
456
668
  zoomOnDoubleClick: false
457
669
  },
458
- background && /* @__PURE__ */ React.createElement(Background, null)
670
+ background && /* @__PURE__ */ React.createElement(Background, null),
671
+ controls && /* @__PURE__ */ React.createElement(Controls, null),
672
+ minimap && /* @__PURE__ */ React.createElement(
673
+ MiniMap,
674
+ {
675
+ nodeColor: minimapNodeColor
676
+ }
677
+ ),
678
+ bounds && /* @__PURE__ */ React.createElement(
679
+ FocusHandler,
680
+ {
681
+ bounds,
682
+ padding: focusPadding != null ? focusPadding : 0.1,
683
+ animation: focusAnimation != null ? focusAnimation : true
684
+ }
685
+ ),
686
+ children
459
687
  )
460
688
  ));
461
689
  }
@@ -463,8 +691,11 @@ export {
463
691
  BUILT_IN_EDGE_TYPES,
464
692
  BUILT_IN_NODE_TYPES,
465
693
  FlowRenderer,
694
+ getFrames,
695
+ getNodeBounds,
466
696
  isDynamicNode,
467
697
  isFrameNode,
468
- useFlow
698
+ useFlow,
699
+ useFlowData
469
700
  };
470
701
  //# sourceMappingURL=flow.js.map