@01.software/sdk 0.5.1 → 0.5.3
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/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/{const-CDpRB7XK.d.cts → const-C9I6r5Wa.d.cts} +1 -1
- package/dist/{const-DQIDvvB-.d.ts → const-JbuUTzeh.d.ts} +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/{payload-types-C-keX5go.d.cts → payload-types-D8fN_vZR.d.cts} +17 -1
- package/dist/{payload-types-C-keX5go.d.ts → payload-types-D8fN_vZR.d.ts} +17 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/{server-B80o7igg.d.cts → server-StNHlSjW.d.cts} +5 -1
- package/dist/{server-B80o7igg.d.ts → server-StNHlSjW.d.ts} +5 -1
- package/dist/ui/code-block.cjs +5 -1
- package/dist/ui/code-block.cjs.map +1 -1
- package/dist/ui/code-block.js +5 -1
- package/dist/ui/code-block.js.map +1 -1
- package/dist/ui/flow/server.cjs +101 -34
- package/dist/ui/flow/server.cjs.map +1 -1
- package/dist/ui/flow/server.d.cts +1 -1
- package/dist/ui/flow/server.d.ts +1 -1
- package/dist/ui/flow/server.js +101 -34
- package/dist/ui/flow/server.js.map +1 -1
- package/dist/ui/flow.cjs +718 -180
- package/dist/ui/flow.cjs.map +1 -1
- package/dist/ui/flow.d.cts +77 -11
- package/dist/ui/flow.d.ts +77 -11
- package/dist/ui/flow.js +705 -167
- package/dist/ui/flow.js.map +1 -1
- package/dist/ui/form.d.cts +1 -1
- package/dist/ui/form.d.ts +1 -1
- package/dist/ui/video.d.cts +1 -1
- package/dist/ui/video.d.ts +1 -1
- package/dist/{webhook-DseJdRFT.d.ts → webhook-BkwMrrL1.d.ts} +2 -2
- package/dist/{webhook-Dqe2_xMx.d.cts → webhook-Dbx-pRib.d.cts} +2 -2
- package/dist/webhook.d.cts +3 -3
- package/dist/webhook.d.ts +3 -3
- package/package.json +5 -3
package/dist/ui/flow.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ui/Flow/types.ts","../../src/ui/Flow/built-in-node-types.ts","../../src/ui/Flow/built-in-edge-types.ts","../../src/ui/Flow/useFlow.ts","../../src/core/query/query-keys.ts","../../src/ui/Flow/prefetchFlow.ts","../../src/ui/Flow/useFlowData.ts","../../src/ui/Flow/utils.ts","../../src/ui/Flow/template-compiler.ts","../../src/ui/Flow/FlowRenderer.tsx","../../src/ui/Flow/node-types-factory.tsx","../../src/ui/Flow/node-renderers.tsx","../../src/ui/Flow/edge-styles.ts","../../src/ui/Flow/focus-handler.tsx"],"sourcesContent":["import type React from 'react'\n\n// ── Dynamic node data ──\n\nexport interface DynamicNodeData {\n nodeTypeSlug: string\n label: string\n fields: Record<string, unknown>\n}\n\nexport type FlowNodeData = (DynamicNodeData | FrameNodeData) &\n Record<string, unknown>\n\n// ── Canvas types (mirrors @xyflow/react but standalone) ──\n\nexport interface FlowNodePosition {\n x: number\n y: number\n}\n\nexport interface FlowNode {\n id: string\n type?: string\n position: FlowNodePosition\n data: FlowNodeData\n parentId?: string\n style?: React.CSSProperties\n width?: number\n height?: number\n measured?: { width?: number; height?: number }\n draggable?: boolean\n selectable?: boolean\n [key: string]: unknown\n}\n\nexport interface FlowEdge {\n id: string\n source: string\n target: string\n sourceHandle?: string | null\n targetHandle?: string | null\n type?: string\n style?: React.CSSProperties\n animated?: boolean\n markerStart?: unknown\n markerEnd?: unknown\n edgeTypeSlug?: string\n fields?: Record<string, unknown>\n [key: string]: unknown\n}\n\nexport interface FlowViewport {\n x: number\n y: number\n zoom: number\n}\n\nexport interface CanvasData {\n nodes: FlowNode[]\n edges: FlowEdge[]\n viewport: FlowViewport\n}\n\n// ── Node type definitions (mirrors console's NodeTypeDef) ──\n\nexport interface NodeTypeFieldDef {\n name: string\n label: string\n fieldType:\n | 'text'\n | 'textarea'\n | 'number'\n | 'url'\n | 'color'\n | 'image'\n | 'select'\n | 'toggle'\n options?: { label: string; value: string }[]\n defaultValue?: string\n required?: boolean\n}\n\nexport interface NodeTypeDef {\n slug: string\n name: string\n color: string\n defaultSize: { width: number; height: number }\n fields: NodeTypeFieldDef[]\n transparentBackground?: boolean\n template?: string | null\n customCSS?: string | null\n}\n\n// ── Edge type definitions (mirrors console's EdgeTypeDef) ──\n\nexport interface EdgeTypeDef {\n slug: string\n name: string\n color: string\n strokeWidth: number\n animated: boolean\n lineStyle: string\n markerStart: string\n markerEnd: string\n fields: NodeTypeFieldDef[]\n}\n\n// ── Type guards ──\n\nexport function isDynamicNode(\n node: FlowNode,\n): node is FlowNode & { data: DynamicNodeData } {\n return node.type === 'dynamic'\n}\n\nexport function isFrameNode(\n node: FlowNode,\n): node is FlowNode & { data: FrameNodeData } {\n return node.type === 'frame'\n}\n\n// ── Component slot props ──\n\nexport interface DynamicNodeSlotProps {\n id: string\n nodeTypeSlug: string\n label: string\n fields: Record<string, unknown>\n nodeTypeDef?: NodeTypeDef\n /** Whether this node is currently selected */\n selected?: boolean\n /** Measured node width (undefined before first measurement) */\n width?: number\n /** Measured node height (undefined before first measurement) */\n height?: number\n /** The default rendering (template or field-based). Allows custom renderers to wrap/extend instead of replacing entirely. */\n defaultRender?: React.ReactElement\n}\n\n// ── Frame node data ──\n\nexport interface FrameNodeData {\n label: string\n color?: string\n padding?: number\n borderStyle?: 'dashed' | 'solid' | 'none'\n opacity?: number\n}\n\n// S1: Frame renderer slot\nexport interface FrameNodeSlotProps {\n id: string\n label: string\n color?: string\n padding?: number\n borderStyle?: 'dashed' | 'solid' | 'none'\n opacity?: number\n width?: number\n height?: number\n children?: React.ReactNode\n}\n\n// S2: Edge renderer slot\nexport interface EdgeSlotProps {\n id: string\n edgeTypeSlug?: string\n source: string\n target: string\n label?: string\n fields?: Record<string, unknown>\n edgeTypeDef?: EdgeTypeDef\n style?: React.CSSProperties\n}\n\n// S3: Node wrapper slot\nexport interface NodeWrapperSlotProps {\n id: string\n nodeTypeSlug: string\n label: string\n selected?: boolean\n nodeTypeDef?: NodeTypeDef\n children: React.ReactNode\n}\n\n// S8: Viewport focus\nexport interface FlowBounds {\n x: number\n y: number\n width: number\n height: number\n}\n","import type { NodeTypeDef } from './types'\n\nexport const BUILT_IN_NODE_TYPES: NodeTypeDef[] = [\n {\n slug: 'text',\n name: 'Text',\n color: '#e5e7eb',\n defaultSize: { width: 200, height: 200 },\n fields: [{ name: 'body', label: 'Body', fieldType: 'textarea' }],\n },\n {\n slug: 'image',\n name: 'Image',\n color: '#e5e7eb',\n transparentBackground: true,\n defaultSize: { width: 200, height: 200 },\n fields: [\n { name: 'image', label: 'Image', fieldType: 'image' },\n { name: 'alt', label: 'Alt Text', fieldType: 'text' },\n { name: 'caption', label: 'Caption', fieldType: 'text' },\n ],\n },\n]\n","import type { EdgeTypeDef } from './types'\n\nexport const BUILT_IN_EDGE_TYPES: EdgeTypeDef[] = [\n {\n slug: 'default',\n name: 'Default',\n color: '',\n strokeWidth: 2,\n animated: false,\n lineStyle: 'default',\n markerStart: 'none',\n markerEnd: 'arrow',\n fields: [],\n },\n]\n","'use client'\n\nimport { useQuery, type QueryClient } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport type { CanvasData, NodeTypeDef, EdgeTypeDef } from './types'\nimport { BUILT_IN_NODE_TYPES } from './built-in-node-types'\nimport { BUILT_IN_EDGE_TYPES } from './built-in-edge-types'\nimport { collectionKeys } from '../../core/query/query-keys'\n\n// ── Client interface ──\n// Structurally compatible with both Client and ServerClient.\n// Lists only the collections useFlow actually queries so the generic\n// `from<T extends PublicCollection>` on the real clients satisfies this.\n\ntype FlowCollection = 'flows' | 'flow-node-types' | 'flow-edge-types'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyFn = (...args: any[]) => any\n\nexport interface SDKClient {\n from(collection: FlowCollection): {\n find: AnyFn\n findById: AnyFn\n }\n queryClient: QueryClient\n}\n\n// ── Options & Result ──\n\nexport interface UseFlowOptions {\n /** SDK client instance (Client or ServerClient) */\n client: SDKClient\n /** Flow slug (URL-friendly identifier) */\n slug?: string\n /** Flow document ID (UUID) */\n id?: string\n /** Enable/disable data fetching (default: true) */\n enabled?: boolean\n}\n\nexport interface UseFlowResult {\n data: CanvasData | undefined\n nodeTypeDefs: NodeTypeDef[]\n edgeTypeDefs: EdgeTypeDef[]\n flow: Record<string, unknown> | undefined\n isLoading: boolean\n error: Error | null\n}\n\n// ── Helpers ──\n\nfunction toNodeTypeDef(doc: Record<string, unknown>): NodeTypeDef {\n return {\n slug: String(doc.slug ?? ''),\n name: String(doc.title ?? ''),\n color: String(doc.color ?? '#e5e7eb'),\n defaultSize: (doc.defaultSize as NodeTypeDef['defaultSize']) ?? {\n width: 200,\n height: 200,\n },\n fields: Array.isArray(doc.fields)\n ? (doc.fields as NodeTypeDef['fields'])\n : [],\n transparentBackground: Boolean(doc.transparentBackground),\n template: (doc.template as string) ?? null,\n customCSS: (doc.customCSS as string) ?? null,\n }\n}\n\nfunction toEdgeTypeDef(doc: Record<string, unknown>): EdgeTypeDef {\n return {\n slug: String(doc.slug ?? ''),\n name: String(doc.title ?? ''),\n color: String(doc.color ?? ''),\n strokeWidth: (doc.strokeWidth as number) ?? 2,\n animated: (doc.animated as boolean) ?? false,\n lineStyle: String(doc.lineStyle ?? 'default'),\n markerStart: String(doc.markerStart ?? 'none'),\n markerEnd: String(doc.markerEnd ?? 'arrow'),\n fields: Array.isArray(doc.fields)\n ? (doc.fields as EdgeTypeDef['fields'])\n : [],\n }\n}\n\n// ── Hook ──\n\nexport function useFlow(options: UseFlowOptions): UseFlowResult {\n const { client, slug, id, enabled = true } = options\n const hasIdentifier = !!(slug || id)\n const identifier = id ?? slug ?? ''\n\n // Fetch flow document\n const flowQuery = useQuery<Record<string, unknown>>(\n {\n queryKey: collectionKeys('flows').detail(identifier),\n queryFn: async () => {\n if (id) {\n return client.from('flows').findById(id)\n }\n const result = await client.from('flows').find({\n where: { slug: { equals: slug } },\n limit: 1,\n })\n const doc = result.docs[0]\n if (!doc) throw new Error(`Flow not found: ${slug}`)\n return doc\n },\n enabled: enabled && hasIdentifier,\n },\n client.queryClient,\n )\n\n // Fetch tenant's custom node types\n const nodeTypesQuery = useQuery<Record<string, unknown>[]>(\n {\n queryKey: collectionKeys('flow-node-types').lists(),\n queryFn: async () => {\n const result = await client.from('flow-node-types').find({ limit: 100 })\n return result.docs\n },\n enabled,\n },\n client.queryClient,\n )\n\n // Fetch tenant's custom edge types\n const edgeTypesQuery = useQuery<Record<string, unknown>[]>(\n {\n queryKey: collectionKeys('flow-edge-types').lists(),\n queryFn: async () => {\n const result = await client.from('flow-edge-types').find({ limit: 100 })\n return result.docs\n },\n enabled,\n },\n client.queryClient,\n )\n\n // Merge built-in + API node types\n const nodeTypeDefs = useMemo<NodeTypeDef[]>(() => {\n const apiDefs = (nodeTypesQuery.data ?? []).map(toNodeTypeDef)\n const builtInSlugs = new Set(BUILT_IN_NODE_TYPES.map((t) => t.slug))\n const customDefs = apiDefs.filter((d) => !builtInSlugs.has(d.slug))\n return [...BUILT_IN_NODE_TYPES, ...customDefs]\n }, [nodeTypesQuery.data])\n\n // Merge built-in + API edge types\n const edgeTypeDefs = useMemo<EdgeTypeDef[]>(() => {\n const apiDefs = (edgeTypesQuery.data ?? []).map(toEdgeTypeDef)\n const builtInSlugs = new Set(BUILT_IN_EDGE_TYPES.map((t) => t.slug))\n const customDefs = apiDefs.filter((d) => !builtInSlugs.has(d.slug))\n return [...BUILT_IN_EDGE_TYPES, ...customDefs]\n }, [edgeTypesQuery.data])\n\n const flow = flowQuery.data\n const canvas = flow?.canvas as CanvasData | undefined\n\n return {\n data: canvas,\n nodeTypeDefs,\n edgeTypeDefs,\n flow,\n isLoading:\n flowQuery.isLoading ||\n nodeTypesQuery.isLoading ||\n edgeTypesQuery.isLoading,\n error:\n (flowQuery.error as Error | null) ??\n (nodeTypesQuery.error as Error | null) ??\n (edgeTypesQuery.error as Error | null),\n }\n}\n","import type { PublicCollection, ApiQueryOptions } from '../client/types'\n\nexport function collectionKeys<T extends PublicCollection>(collection: T) {\n return {\n all: [collection] as const,\n lists: () => [collection, 'list'] as const,\n list: (options?: ApiQueryOptions) => [collection, 'list', options] as const,\n details: () => [collection, 'detail'] as const,\n detail: (id: string, options?: ApiQueryOptions) =>\n [collection, 'detail', id, options] as const,\n infinites: () => [collection, 'infinite'] as const,\n infinite: (options?: Omit<ApiQueryOptions, 'page'>) =>\n [collection, 'infinite', options] as const,\n }\n}\n\nexport const customerKeys = {\n all: ['customer'] as const,\n me: () => ['customer', 'me'] as const,\n}\n","import type { SDKClient } from './useFlow'\nimport { collectionKeys } from '../../core/query/query-keys'\n\nexport interface PrefetchFlowOptions {\n /** SDK client instance (Client or ServerClient) */\n client: SDKClient\n /** Flow slug (URL-friendly identifier) */\n slug?: string\n /** Flow document ID (UUID) */\n id?: string\n}\n\n/**\n * Prefetch flow data into the query cache.\n * Call in route loaders or server components to eliminate loading states on mount.\n *\n * ```ts\n * // React Router loader / Server Component\n * await prefetchFlow({ client, slug: 'Home' })\n * ```\n */\nexport async function prefetchFlow(\n options: PrefetchFlowOptions,\n): Promise<void> {\n const { client, slug, id } = options\n const identifier = id ?? slug ?? ''\n\n await Promise.all([\n client.queryClient.prefetchQuery({\n queryKey: collectionKeys('flows').detail(identifier),\n queryFn: async () => {\n if (id) return client.from('flows').findById(id)\n const result = await client.from('flows').find({\n where: { slug: { equals: slug } },\n limit: 1,\n })\n const doc = result.docs[0]\n if (!doc) throw new Error(`Flow not found: ${slug}`)\n return doc\n },\n }),\n client.queryClient.prefetchQuery({\n queryKey: collectionKeys('flow-node-types').lists(),\n queryFn: async () => {\n const result = await client\n .from('flow-node-types')\n .find({ limit: 100 })\n return result.docs\n },\n }),\n client.queryClient.prefetchQuery({\n queryKey: collectionKeys('flow-edge-types').lists(),\n queryFn: async () => {\n const result = await client\n .from('flow-edge-types')\n .find({ limit: 100 })\n return result.docs\n },\n }),\n ])\n}\n","import { useMemo } from 'react'\nimport type { CanvasData, FlowNode, NodeTypeDef, EdgeTypeDef } from './types'\nimport type { Edge } from '@xyflow/react'\nimport { BUILT_IN_NODE_TYPES } from './built-in-node-types'\nimport { BUILT_IN_EDGE_TYPES } from './built-in-edge-types'\n\n// ── Options & Result ──\n\nexport interface UseFlowDataOptions {\n /** Canvas data from Flow document's `canvas` field */\n data: CanvasData | undefined\n /** Node type definitions (defaults to built-in types) */\n nodeTypeDefs?: NodeTypeDef[]\n /** Edge type definitions (defaults to built-in types) */\n edgeTypeDefs?: EdgeTypeDef[]\n}\n\nexport interface UseFlowDataResult {\n /** Nodes from canvas data */\n nodes: FlowNode[]\n /** Edges from canvas data (typed for @xyflow/react) */\n edges: Edge[]\n /** Map of node type slug to definition */\n nodeTypeDefsMap: Map<string, NodeTypeDef>\n /** Map of edge type slug to definition */\n edgeTypeDefsMap: Map<string, EdgeTypeDef>\n}\n\n/**\n * Pure data transformation hook — extracts nodes, edges, and type definition\n * maps from canvas data without any rendering. Useful for headless usage\n * (custom layouts, analytics, server-side processing).\n */\nexport function useFlowData(options: UseFlowDataOptions): UseFlowDataResult {\n const { data, nodeTypeDefs: inputNodeDefs, edgeTypeDefs: inputEdgeDefs } =\n options\n\n const nodeTypeDefsMap = useMemo(() => {\n const allDefs = inputNodeDefs ?? BUILT_IN_NODE_TYPES\n return new Map(allDefs.map((d) => [d.slug, d]))\n }, [inputNodeDefs])\n\n const edgeTypeDefsMap = useMemo(() => {\n const allDefs = inputEdgeDefs ?? BUILT_IN_EDGE_TYPES\n return new Map(allDefs.map((d) => [d.slug, d]))\n }, [inputEdgeDefs])\n\n const nodes = useMemo(() => data?.nodes ?? [], [data?.nodes])\n const edges = useMemo(() => (data?.edges ?? []) as unknown as Edge[], [data?.edges])\n\n return {\n nodes,\n edges,\n nodeTypeDefsMap,\n edgeTypeDefsMap,\n }\n}\n","import type { FlowNode, FlowEdge, FlowBounds, CanvasData } from './types'\n\n// ── Shared helpers ──\n\nfunction getNodeSize(node: FlowNode): { width: number; height: number } {\n return {\n width:\n (node.style?.width as number) ??\n node.measured?.width ??\n node.width ??\n 200,\n height:\n (node.style?.height as number) ??\n node.measured?.height ??\n node.height ??\n 200,\n }\n}\n\nfunction getAbsolutePosition(\n node: FlowNode,\n nodeMap: Map<string, FlowNode>,\n): { x: number; y: number } {\n let x = node.position.x\n let y = node.position.y\n let current = node\n const visited = new Set<string>([node.id])\n while (current.parentId) {\n const parentId = current.parentId\n if (visited.has(parentId)) break\n const parent = nodeMap.get(parentId)\n if (!parent) break\n visited.add(parent.id)\n x += parent.position.x\n y += parent.position.y\n current = parent\n }\n return { x, y }\n}\n\n/** Collect a node and all its descendants (BFS with index pointer to avoid O(Q²) shift). */\nfunction collectDescendants(\n nodes: FlowNode[],\n rootId: string,\n): Set<string> {\n const result = new Set<string>([rootId])\n const queue = [rootId]\n let i = 0\n while (i < queue.length) {\n const current = queue[i++]\n for (const n of nodes) {\n if (n.parentId === current && !result.has(n.id)) {\n result.add(n.id)\n queue.push(n.id)\n }\n }\n }\n return result\n}\n\n// ── Public utilities ──\n\n/**\n * Calculate bounding box for given node IDs.\n * Pure function — usable in SSR, server components, or outside React.\n */\nexport function getNodeBounds(\n nodes: FlowNode[],\n nodeIds: string[],\n): FlowBounds | undefined {\n const idSet = new Set(nodeIds)\n const targetNodes = nodes.filter((n) => idSet.has(n.id))\n if (targetNodes.length === 0) return undefined\n\n const nodeMap = new Map(nodes.map((n) => [n.id, n]))\n\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n\n for (const node of targetNodes) {\n const abs = getAbsolutePosition(node, nodeMap)\n const { width: w, height: h } = getNodeSize(node)\n minX = Math.min(minX, abs.x)\n minY = Math.min(minY, abs.y)\n maxX = Math.max(maxX, abs.x + w)\n maxY = Math.max(maxY, abs.y + h)\n }\n\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY }\n}\n\n/**\n * Get all frame nodes with their bounds.\n * Sorted by position (top-left to bottom-right).\n */\nexport function getFrames(\n nodes: FlowNode[],\n): Array<{ id: string; label: string; bounds: FlowBounds }> {\n const frames = nodes.filter((n) => n.type === 'frame')\n if (frames.length === 0) return []\n\n const nodeMap = new Map(nodes.map((n) => [n.id, n]))\n\n return frames\n .map((f) => {\n const data = f.data as { label?: string }\n const abs = getAbsolutePosition(f, nodeMap)\n const { width: w, height: h } = getNodeSize(f)\n return {\n id: f.id,\n label: data.label ?? '',\n bounds: { x: abs.x, y: abs.y, width: w, height: h },\n }\n })\n .sort((a, b) => a.bounds.y - b.bounds.y || a.bounds.x - b.bounds.x)\n}\n\n/** Result of getFrameData — contains filtered canvas + dual bounds. */\nexport interface FrameData {\n /** Canvas data containing only the frame's descendants (nodes have draggable: false). */\n data: CanvasData\n /** Bounding box of child content nodes — use for initial viewport fit (centering). */\n fitBounds: FlowBounds\n /** Bounding box of the frame itself — use for panning/zoom restriction (clamp). */\n clampBounds: FlowBounds\n /** @deprecated Use fitBounds instead. Alias for clampBounds for backward compatibility. */\n bounds: FlowBounds\n}\n\n/**\n * Extract a frame's descendants and related edges from canvas data.\n * Recursively collects all nested children (supports nested frames).\n * Returns undefined if frameId is not found or is not a frame node.\n *\n * Child nodes are marked `draggable: false` to prevent interfering with canvas panning.\n * The frame node itself is included (use `frameRenderer={() => null}` to hide it).\n *\n * Returns dual bounds:\n * - `fitBounds`: child content bounding box (for centering the viewport)\n * - `clampBounds`: frame area bounding box (for panning restriction)\n */\nexport function getFrameData(\n data: CanvasData,\n frameId: string,\n): FrameData | undefined {\n const frame = data.nodes.find((n) => n.id === frameId)\n if (!frame || frame.type !== 'frame') return undefined\n\n // Recursively collect frame + all descendants\n const descendantIds = collectDescendants(data.nodes, frameId)\n const childNodes = data.nodes\n .filter((n) => descendantIds.has(n.id))\n .map((n) => ({ ...n, draggable: false }))\n\n // Keep only edges where both source and target are within the frame\n const childEdges = data.edges.filter(\n (e: FlowEdge) => descendantIds.has(e.source) && descendantIds.has(e.target),\n )\n\n // clampBounds: frame's own bounding box (for panning restriction)\n const frameBounds = getNodeBounds(data.nodes, [frameId])\n const { width: w, height: h } = getNodeSize(frame)\n const clampBounds: FlowBounds = frameBounds ?? {\n x: frame.position.x,\n y: frame.position.y,\n width: w,\n height: h,\n }\n\n // fitBounds: child content bounding box (for centering)\n const contentNodeIds = childNodes\n .filter((n) => n.id !== frameId)\n .map((n) => n.id)\n const contentBounds = contentNodeIds.length > 0\n ? getNodeBounds(data.nodes, contentNodeIds)\n : undefined\n const fitBounds = contentBounds ?? clampBounds\n\n return {\n data: {\n nodes: childNodes,\n edges: childEdges,\n viewport: data.viewport,\n },\n fitBounds,\n clampBounds,\n bounds: clampBounds,\n }\n}\n","'use client'\n\nimport React from 'react'\nimport { transform } from 'sucrase'\n\nexport interface CodeComponentProps {\n fields: Record<string, unknown>\n label: string\n color: string\n nodeTypeSlug: string\n width: number\n height: number\n}\n\nconst MAX_CACHE_SIZE = 100\nconst componentCache = new Map<string, React.FC<CodeComponentProps>>()\n\nfunction hashCode(str: string): string {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = ((hash << 5) - hash + char) | 0\n }\n return hash.toString(36)\n}\n\nconst BLOCKED_PATTERNS = [\n /\\bdocument\\s*\\./,\n /\\bwindow\\s*\\./,\n /\\bwindow\\s*\\[/,\n /\\bglobalThis\\s*\\./,\n /\\bfetch\\s*\\(/,\n /\\bXMLHttpRequest/,\n /\\beval\\s*\\(/,\n /\\bFunction\\s*\\(/,\n /\\bimport\\s*\\(/,\n /\\blocalStorage/,\n /\\bsessionStorage/,\n /\\bcookie/,\n /\\bpostMessage\\s*\\(/,\n /\\blocation\\s*[.=]/,\n /\\bnavigator\\s*\\./,\n /\\bsetTimeout\\s*\\(/,\n /\\bsetInterval\\s*\\(/,\n /\\bsetImmediate\\s*\\(/,\n /\\brequire\\s*\\(/,\n]\n\nfunction validateTemplateCode(code: string): boolean {\n return !BLOCKED_PATTERNS.some((pattern) => pattern.test(code))\n}\n\nexport function compileTemplate(\n code: string,\n slug: string,\n): React.FC<CodeComponentProps> | null {\n const cacheKey = `${slug}:${hashCode(code)}`\n\n if (componentCache.has(cacheKey)) {\n const cached = componentCache.get(cacheKey)!\n componentCache.delete(cacheKey)\n componentCache.set(cacheKey, cached)\n return cached\n }\n\n if (!validateTemplateCode(code)) {\n console.warn(`[flow] Template \"${slug}\" contains blocked patterns`)\n return null\n }\n\n try {\n const { code: jsCode } = transform(code, {\n transforms: ['typescript', 'jsx', 'imports'],\n jsxRuntime: 'classic',\n jsxPragma: 'React.createElement',\n jsxFragmentPragma: 'React.Fragment',\n })\n\n // Shadow dangerous globals to neutralize blocklist bypasses\n const factory = new Function(\n 'React',\n `\n var window = undefined;\n var document = undefined;\n var globalThis = undefined;\n var setTimeout = undefined;\n var setInterval = undefined;\n var setImmediate = undefined;\n var fetch = undefined;\n var XMLHttpRequest = undefined;\n var navigator = undefined;\n var location = undefined;\n var exports = {};\n var module = { exports: exports };\n ${jsCode}\n return module.exports.default || module.exports;\n `,\n )\n\n const Component = factory(React)\n if (typeof Component !== 'function') return null\n\n if (componentCache.size >= MAX_CACHE_SIZE) {\n const oldestKey = componentCache.keys().next().value\n if (oldestKey) componentCache.delete(oldestKey)\n }\n\n componentCache.set(cacheKey, Component)\n return Component\n } catch (e) {\n console.warn(`[flow] Failed to compile template for \"${slug}\":`, e)\n return null\n }\n}\n\nexport function clearTemplateCache(): void {\n componentCache.clear()\n}\n","'use client'\n\nimport React from 'react'\nimport {\n ReactFlow,\n ReactFlowProvider,\n Background,\n Controls,\n MiniMap,\n} from '@xyflow/react'\nimport type {\n CanvasData,\n DynamicNodeSlotProps,\n EdgeSlotProps,\n EdgeTypeDef,\n FlowBounds,\n FlowEdge,\n FlowNode,\n FlowViewport,\n FrameNodeSlotProps,\n NodeTypeDef,\n NodeWrapperSlotProps,\n} from './types'\nimport { createNodeTypes, createEdgeTypes } from './node-types-factory'\nimport { applyEdgeStyles } from './edge-styles'\nimport { FocusHandler } from './focus-handler'\n\n// ── FlowRenderer ──\n\n/**\n * Renders a Flow canvas in read-only mode.\n *\n * Requires `@xyflow/react` peer dependency and its CSS:\n * ```ts\n * import '@xyflow/react/dist/style.css'\n * ```\n */\nexport interface FlowRendererProps {\n /** Canvas data from Flow document's `canvas` field */\n data: CanvasData\n /** Container className */\n className?: string\n /** Container style */\n style?: React.CSSProperties\n /** Custom renderers by node type slug (e.g., `{ 'product-card': MyProductCard }`) */\n nodeRenderers?: Record<string, React.ComponentType<DynamicNodeSlotProps>>\n /** Node type definitions for enhanced rendering (field-type-aware display) */\n nodeTypeDefs?: NodeTypeDef[]\n /** Edge type definitions for styled edges (color, stroke, markers, animation) */\n edgeTypeDefs?: EdgeTypeDef[]\n /** Show background pattern (default: false) */\n background?: boolean\n /** Allow user interaction - pan, zoom (default: false for read-only display) */\n interactive?: boolean\n /** Fit view on mount (default: true) */\n fitView?: boolean\n /** Called when a node is clicked */\n onNodeClick?: (event: React.MouseEvent, node: FlowNode) => void\n /** Called when a node is double-clicked */\n onNodeDoubleClick?: (event: React.MouseEvent, node: FlowNode) => void\n /** Called on node right-click / context menu */\n onNodeContextMenu?: (event: React.MouseEvent, node: FlowNode) => void\n /** Called when mouse enters a node */\n onNodeMouseEnter?: (event: React.MouseEvent, node: FlowNode) => void\n /** Called when mouse leaves a node */\n onNodeMouseLeave?: (event: React.MouseEvent, node: FlowNode) => void\n /** Called when an edge is clicked */\n onEdgeClick?: (event: React.MouseEvent, edge: FlowEdge) => void\n /** S1: Custom frame node renderer. Should be a stable reference (memoize or define outside render). */\n frameRenderer?: React.ComponentType<FrameNodeSlotProps>\n /** S2: Custom edge renderers by edge type slug. Should be a stable reference (memoize or define outside render). */\n edgeRenderers?: Record<string, React.ComponentType<EdgeSlotProps>>\n /** S3: Wraps every dynamic node's rendered content. Should be a stable reference (memoize or define outside render). */\n nodeWrapper?: React.ComponentType<NodeWrapperSlotProps>\n /** S4: Show controls (default: false) */\n controls?: boolean\n /** S4: Show minimap (default: false) */\n minimap?: boolean\n /** S4: Custom minimap node color function */\n minimapNodeColor?: (node: FlowNode) => string\n /** S4: Additional children rendered inside ReactFlow */\n children?: React.ReactNode\n /** S5: Global override for all dynamic nodes. `content` is the resolved rendering (custom renderer output or default). `props.defaultRender` contains the original template/field-based rendering. */\n renderNode?: (\n props: DynamicNodeSlotProps,\n content: React.ReactElement,\n ) => React.ReactElement | null\n /** S6: Called when viewport changes (pan/zoom) */\n onViewportChange?: (viewport: FlowViewport) => void\n /** S6: Default viewport (used when fitView is false) */\n defaultViewport?: FlowViewport\n /** S8: Focus on specific bounds (used for initial viewport fit). */\n bounds?: FlowBounds\n /** S8: Separate bounds for panning/zoom restriction. When set, overrides bounds-based translateExtent. Useful when fitBounds (content) differs from clampBounds (frame area). */\n clampBounds?: FlowBounds\n /** S8: Padding for focus bounds (default: 0.1) */\n focusPadding?: number\n /** S8: Animate focus transition (true=300ms, number=custom ms, false=instant) */\n focusAnimation?: boolean | number\n /** S8: Focus mode — \"contain\" fits entire bounds (may have margins), \"cover\" fills viewport (may crop). Default: \"contain\" */\n focusMode?: 'contain' | 'cover'\n /** Re-fit viewport on container resize (default: true when bounds is set) */\n responsiveFit?: boolean\n /** Override translateExtent directly. When set, overrides the automatic bounds-based panning restriction. */\n translateExtent?: [[number, number], [number, number]]\n /** Minimum zoom level. When clampBounds is set, automatically enforced as cover zoom (user cannot zoom out beyond the frame). */\n minZoom?: number\n /** Maximum zoom level */\n maxZoom?: number\n}\n\nexport function FlowRenderer({\n data,\n className,\n style,\n nodeRenderers,\n nodeTypeDefs,\n edgeTypeDefs,\n background = false,\n interactive = false,\n fitView = true,\n onNodeClick,\n onNodeDoubleClick,\n onNodeContextMenu,\n onNodeMouseEnter,\n onNodeMouseLeave,\n onEdgeClick,\n frameRenderer,\n edgeRenderers,\n nodeWrapper,\n controls,\n minimap,\n minimapNodeColor,\n children,\n renderNode,\n onViewportChange,\n defaultViewport: defaultViewportProp,\n bounds,\n clampBounds,\n focusPadding,\n focusAnimation,\n focusMode = 'contain',\n responsiveFit,\n translateExtent: translateExtentProp,\n minZoom: minZoomProp,\n maxZoom: maxZoomProp,\n}: FlowRendererProps) {\n const nodeTypeDefsMap = React.useMemo(() => {\n if (!nodeTypeDefs?.length) return undefined\n return new Map(nodeTypeDefs.map((d) => [d.slug, d]))\n }, [nodeTypeDefs])\n\n const edgeTypeDefsMap = React.useMemo(() => {\n if (!edgeTypeDefs?.length) return undefined\n return new Map(edgeTypeDefs.map((d) => [d.slug, d]))\n }, [edgeTypeDefs])\n\n const nodeTypes = React.useMemo(\n () =>\n createNodeTypes(\n nodeRenderers,\n nodeTypeDefsMap,\n frameRenderer,\n nodeWrapper,\n renderNode,\n ),\n [nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrapper, renderNode],\n )\n\n // S2: Custom edge types\n const customEdgeTypes = React.useMemo(\n () => createEdgeTypes(edgeRenderers, edgeTypeDefsMap),\n [edgeRenderers, edgeTypeDefsMap],\n )\n\n // Merge all customCSS from node type definitions\n const mergedCSS = React.useMemo(() => {\n if (!nodeTypeDefs?.length) return ''\n return nodeTypeDefs\n .filter((d) => d.customCSS)\n .map((d) => d.customCSS)\n .join('\\n')\n }, [nodeTypeDefs])\n\n const styledEdges = React.useMemo(() => {\n let edges = applyEdgeStyles(data?.edges ?? [], edgeTypeDefsMap)\n // When custom edge renderers exist, set edge type to slug for matching\n if (edgeRenderers) {\n edges = edges.map((edge) => {\n const slug = (edge as unknown as FlowEdge).edgeTypeSlug\n if (slug && edgeRenderers[slug]) {\n return { ...edge, type: slug }\n }\n return edge\n })\n }\n return edges\n }, [data?.edges, edgeTypeDefsMap, edgeRenderers])\n\n // Panning restriction: explicit prop > clampBounds (no padding, hard boundary) > bounds (with padding)\n const translateExtent = React.useMemo(() => {\n if (translateExtentProp) return translateExtentProp\n const es = clampBounds ?? bounds\n if (!es) return undefined\n const ep = clampBounds ? 0 : (focusPadding ?? 0.1)\n return [\n [es.x - ep * es.width, es.y - ep * es.height],\n [es.x + es.width * (1 + ep), es.y + es.height * (1 + ep)],\n ] as [[number, number], [number, number]]\n }, [translateExtentProp, clampBounds, bounds, focusPadding])\n\n // Defer translateExtent until FocusHandler has set the initial viewport.\n // d3-zoom's transform() applies translateExtent clamping internally, which\n // causes asymmetric shift when content is offset within frame. By deferring,\n // the initial setViewport runs unclamped, then extent is applied for panning.\n const boundsKey = bounds\n ? `${bounds.x},${bounds.y},${bounds.width},${bounds.height}`\n : ''\n const extentReadyRef = React.useRef(false)\n const expandedExtentRef = React.useRef<\n [[number, number], [number, number]] | undefined\n >(undefined)\n const prevBoundsKeyRef = React.useRef(boundsKey)\n if (prevBoundsKeyRef.current !== boundsKey) {\n prevBoundsKeyRef.current = boundsKey\n extentReadyRef.current = false\n expandedExtentRef.current = undefined\n }\n const [, rerender] = React.useReducer((x: number) => x + 1, 0)\n const handleInitialFit = React.useCallback(\n (expandedExtent?: [[number, number], [number, number]]) => {\n extentReadyRef.current = true\n expandedExtentRef.current = expandedExtent\n rerender()\n },\n [],\n )\n // Use expanded extent (includes viewport visible area) to prevent\n // d3-zoom from clamping on first interaction\n const activeExtent =\n !bounds || extentReadyRef.current\n ? (expandedExtentRef.current ?? translateExtent)\n : undefined\n\n if (!data) return null\n\n const resolvedDefaultViewport =\n defaultViewportProp ??\n (!fitView && data.viewport ? data.viewport : undefined)\n\n return (\n <ReactFlowProvider>\n <div\n className={className}\n style={{\n width: '100%',\n height: '100%',\n background: 'transparent',\n ...style,\n }}\n >\n <ReactFlow\n nodes={\n (data.nodes ?? []) as unknown as Parameters<\n typeof ReactFlow\n >[0]['nodes']\n }\n edges={styledEdges}\n nodeTypes={nodeTypes}\n edgeTypes={\n customEdgeTypes as Parameters<typeof ReactFlow>[0]['edgeTypes']\n }\n defaultViewport={resolvedDefaultViewport}\n fitView={bounds ? false : fitView}\n translateExtent={activeExtent}\n onNodeClick={\n onNodeClick as Parameters<typeof ReactFlow>[0]['onNodeClick']\n }\n onNodeDoubleClick={\n onNodeDoubleClick as Parameters<\n typeof ReactFlow\n >[0]['onNodeDoubleClick']\n }\n onNodeContextMenu={\n onNodeContextMenu as Parameters<\n typeof ReactFlow\n >[0]['onNodeContextMenu']\n }\n onNodeMouseEnter={\n onNodeMouseEnter as Parameters<\n typeof ReactFlow\n >[0]['onNodeMouseEnter']\n }\n onNodeMouseLeave={\n onNodeMouseLeave as Parameters<\n typeof ReactFlow\n >[0]['onNodeMouseLeave']\n }\n onEdgeClick={\n onEdgeClick as Parameters<typeof ReactFlow>[0]['onEdgeClick']\n }\n onMoveEnd={\n onViewportChange\n ? (((_: unknown, vp: { x: number; y: number; zoom: number }) => {\n onViewportChange(vp)\n }) as Parameters<typeof ReactFlow>[0]['onMoveEnd'])\n : undefined\n }\n nodesDraggable={interactive}\n nodesConnectable={false}\n elementsSelectable={\n interactive ||\n !!onNodeClick ||\n !!onNodeDoubleClick ||\n !!onEdgeClick\n }\n panOnDrag={interactive}\n zoomOnScroll={interactive}\n zoomOnPinch={interactive}\n zoomOnDoubleClick={false}\n minZoom={minZoomProp}\n maxZoom={maxZoomProp}\n proOptions={{ hideAttribution: true }}\n >\n {mergedCSS && (\n <style dangerouslySetInnerHTML={{ __html: mergedCSS }} />\n )}\n {background && <Background />}\n {controls && <Controls />}\n {minimap && (\n <MiniMap\n nodeColor={\n minimapNodeColor as Parameters<typeof MiniMap>[0]['nodeColor']\n }\n />\n )}\n {bounds && (\n <FocusHandler\n bounds={bounds}\n padding={focusPadding ?? 0.1}\n animation={focusAnimation ?? true}\n mode={focusMode}\n responsive={responsiveFit ?? true}\n extent={translateExtent}\n clampBounds={clampBounds}\n minZoomProp={minZoomProp}\n onInitialFit={handleInitialFit}\n />\n )}\n {children}\n </ReactFlow>\n </div>\n </ReactFlowProvider>\n )\n}\n","import React from 'react'\nimport type { NodeTypes, NodeProps } from '@xyflow/react'\nimport type {\n DynamicNodeData,\n DynamicNodeSlotProps,\n EdgeSlotProps,\n EdgeTypeDef,\n FrameNodeData,\n FrameNodeSlotProps,\n NodeTypeDef,\n NodeWrapperSlotProps,\n} from './types'\nimport {\n DefaultDynamicNode,\n EnhancedDynamicNode,\n DefaultFrameNode,\n} from './node-renderers'\n\n// ── Node types builder ──\n\nexport function createNodeTypes(\n nodeRenderers?: Record<string, React.ComponentType<DynamicNodeSlotProps>>,\n nodeTypeDefsMap?: Map<string, NodeTypeDef>,\n frameRenderer?: React.ComponentType<FrameNodeSlotProps>,\n nodeWrapper?: React.ComponentType<NodeWrapperSlotProps>,\n renderNode?: (\n props: DynamicNodeSlotProps,\n content: React.ReactElement,\n ) => React.ReactElement | null,\n): NodeTypes {\n const types: NodeTypes = {} as NodeTypes\n\n // Dynamic node type\n types.dynamic = ((props: NodeProps) => {\n const d = props.data as unknown as DynamicNodeData\n const typeDef = nodeTypeDefsMap?.get(d.nodeTypeSlug)\n const CustomRenderer = nodeRenderers?.[d.nodeTypeSlug]\n\n // Compute default rendering (template or field-based)\n const defaultRender: React.ReactElement = typeDef ? (\n <EnhancedDynamicNode\n data={d}\n typeDef={typeDef}\n width={props.width}\n height={props.height}\n />\n ) : (\n <DefaultDynamicNode {...props} />\n )\n\n const slotProps: DynamicNodeSlotProps = {\n id: props.id,\n nodeTypeSlug: d.nodeTypeSlug,\n label: d.label,\n fields: d.fields,\n nodeTypeDef: typeDef,\n selected: props.selected,\n width: props.width,\n height: props.height,\n defaultRender,\n }\n\n let content: React.ReactElement = CustomRenderer ? (\n <CustomRenderer {...slotProps} />\n ) : (\n defaultRender\n )\n\n // S5: renderNode global callback\n if (renderNode) {\n const result = renderNode(slotProps, content)\n if (result !== null) content = result\n }\n\n // S3: nodeWrapper\n if (nodeWrapper) {\n const Wrapper = nodeWrapper\n content = (\n <Wrapper\n id={props.id}\n nodeTypeSlug={d.nodeTypeSlug}\n label={d.label}\n selected={props.selected}\n nodeTypeDef={typeDef}\n >\n {content}\n </Wrapper>\n )\n }\n\n return content\n }) as NodeTypes[string]\n\n // S1: Frame node type — custom or default\n types.frame = frameRenderer\n ? (((props: NodeProps) => {\n const d = props.data as unknown as FrameNodeData\n const Renderer = frameRenderer\n return (\n <Renderer\n id={props.id}\n label={d.label}\n color={d.color}\n padding={d.padding}\n borderStyle={d.borderStyle}\n opacity={d.opacity}\n width={props.width}\n height={props.height}\n />\n )\n }) as NodeTypes[string])\n : (DefaultFrameNode as NodeTypes[string])\n\n return types\n}\n\n// S2: Edge types builder\n\nexport function createEdgeTypes(\n edgeRenderers?: Record<string, React.ComponentType<EdgeSlotProps>>,\n edgeTypeDefsMap?: Map<string, EdgeTypeDef>,\n): Record<string, React.ComponentType<EdgeSlotProps>> | undefined {\n if (!edgeRenderers || Object.keys(edgeRenderers).length === 0)\n return undefined\n const types: Record<string, React.ComponentType<EdgeSlotProps>> = {}\n for (const [slug, Renderer] of Object.entries(edgeRenderers)) {\n types[slug] = ((props: Record<string, unknown>) => {\n const def = edgeTypeDefsMap?.get(slug)\n return (\n <Renderer\n id={props.id as string}\n edgeTypeSlug={slug}\n source={props.source as string}\n target={props.target as string}\n label={props.label as string | undefined}\n fields={\n (props.data as Record<string, unknown> | undefined)?.fields as\n | Record<string, unknown>\n | undefined\n }\n edgeTypeDef={def}\n style={props.style as React.CSSProperties | undefined}\n />\n )\n }) as unknown as React.ComponentType<EdgeSlotProps>\n }\n return types\n}\n","import React from 'react'\nimport type { NodeProps } from '@xyflow/react'\nimport type {\n DynamicNodeData,\n FrameNodeData,\n NodeTypeDef,\n NodeTypeFieldDef,\n} from './types'\nimport { compileTemplate } from './template-compiler'\n\n// ── Helpers ──\n\nfunction sanitizeUrl(url: string | undefined): string | undefined {\n if (!url) return url\n try {\n const parsed = new URL(url)\n if (parsed.protocol === 'http:' || parsed.protocol === 'https:') return url\n return undefined\n } catch {\n return undefined\n }\n}\n\n// ── Field renderer (type-aware, matching console style) ──\n\nexport function renderFieldValue(\n key: string,\n val: unknown,\n fieldDef?: NodeTypeFieldDef,\n): React.ReactNode {\n if (val == null || val === '') return null\n\n const fieldType = fieldDef?.fieldType\n\n // Image field — image only, no decoration\n if (\n fieldType === 'image' ||\n (typeof val === 'object' && val !== null && 'url' in val)\n ) {\n const imgUrl =\n typeof val === 'string' ? val : (val as { url?: string })?.url\n const safeUrl = sanitizeUrl(imgUrl)\n if (!safeUrl) return null\n return (\n <img\n key={key}\n src={safeUrl}\n alt=\"\"\n draggable={false}\n style={{ flex: 1, minHeight: 0, width: '100%', objectFit: 'contain' }}\n />\n )\n }\n\n // All other fields — text only\n return (\n <div\n key={key}\n style={{\n fontSize: 11,\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n overflow: 'hidden',\n flexShrink: 0,\n }}\n >\n {String(val)}\n </div>\n )\n}\n\n// ── Default dynamic node renderer (no typeDef) ──\n\nexport function DefaultDynamicNode({ data }: NodeProps) {\n const d = data as unknown as DynamicNodeData\n return (\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n {d.fields &&\n Object.entries(d.fields)\n .filter(([, v]) => v != null && v !== '')\n .map(([key, val]) => renderFieldValue(key, val))}\n </div>\n )\n}\n\n// ── Template error boundary ──\n\nclass TemplateErrorBoundary extends React.Component<\n { resetKey?: string; children: React.ReactNode },\n { error: Error | null }\n> {\n state: { error: Error | null } = { error: null }\n static getDerivedStateFromError(error: Error) {\n return { error }\n }\n componentDidUpdate(prevProps: { resetKey?: string }) {\n if (prevProps.resetKey !== this.props.resetKey && this.state.error) {\n this.setState({ error: null })\n }\n }\n render() {\n if (this.state.error) {\n return (\n <div style={{ padding: 8, fontSize: 11, color: '#ef4444' }}>\n <strong>Render error</strong>\n <pre style={{ fontSize: 10, whiteSpace: 'pre-wrap' }}>\n {this.state.error.message}\n </pre>\n </div>\n )\n }\n return this.props.children\n }\n}\n\n// ── Enhanced dynamic node renderer (with NodeTypeDef) ──\n\nexport function EnhancedDynamicNode({\n data,\n typeDef,\n width,\n height,\n}: {\n data: DynamicNodeData\n typeDef: NodeTypeDef\n width?: number\n height?: number\n}) {\n // Tier 2: Custom template rendering\n if (typeDef.template) {\n const Component = compileTemplate(typeDef.template, typeDef.slug)\n if (Component) {\n return (\n <div\n className={`flow-node flow-node--${typeDef.slug}${typeDef.transparentBackground ? ' flow-node--transparent-bg' : ''}`}\n style={{ width: '100%', height: '100%' }}\n >\n <TemplateErrorBoundary resetKey={typeDef.template}>\n <Component\n fields={data.fields}\n label={data.label}\n color={typeDef.color}\n nodeTypeSlug={typeDef.slug}\n width={width || typeDef.defaultSize.width}\n height={height || typeDef.defaultSize.height}\n />\n </TemplateErrorBoundary>\n </div>\n )\n }\n }\n\n // Tier 1: Default field rendering\n return (\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n {typeDef.fields.map((f) => {\n const val = data.fields[f.name]\n if (val == null || val === '') return null\n return renderFieldValue(f.name, val, f)\n })}\n </div>\n )\n}\n\n// ── Default frame node renderer ──\n\nexport function DefaultFrameNode({ data }: NodeProps) {\n const d = data as unknown as FrameNodeData\n const baseColor = d.color ?? 'rgb(128,128,128)'\n const padding = d.padding ?? 20\n const borderStyle = d.borderStyle ?? 'dashed'\n const opacity = d.opacity ?? 0.15\n\n // Apply opacity to color at render time\n const bgColor = (() => {\n const m = baseColor.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/)\n if (m) return `rgba(${m[1]},${m[2]},${m[3]},${opacity})`\n return baseColor\n })()\n\n return (\n <div\n style={{\n backgroundColor: bgColor,\n padding,\n width: '100%',\n height: '100%',\n border:\n borderStyle === 'none'\n ? 'none'\n : `2px ${borderStyle} rgba(128,128,128,0.3)`,\n }}\n >\n <div\n style={{\n fontSize: 11,\n fontWeight: 600,\n color: 'rgba(128,128,128,0.6)',\n userSelect: 'none',\n }}\n >\n {d.label}\n </div>\n </div>\n )\n}\n","import { MarkerType, type Edge } from '@xyflow/react'\nimport type { FlowEdge, EdgeTypeDef } from './types'\n\nfunction toMarkerType(value: string): MarkerType | undefined {\n if (value === 'arrow') return MarkerType.Arrow\n if (value === 'arrowclosed') return MarkerType.ArrowClosed\n return undefined\n}\n\nconst EDGE_TYPE_MAP: Record<string, string> = {\n step: 'step',\n smoothstep: 'smoothstep',\n bezier: 'default',\n default: 'default',\n}\n\nexport function applyEdgeStyles(\n edges: FlowEdge[],\n edgeTypeDefsMap?: Map<string, EdgeTypeDef>,\n): Edge[] {\n if (!edgeTypeDefsMap?.size) return edges as unknown as Edge[]\n\n return edges.map((edge) => {\n const slug = edge.edgeTypeSlug\n if (!slug) return edge as unknown as Edge\n\n const def = edgeTypeDefsMap.get(slug)\n if (!def) return edge as unknown as Edge\n\n const styled: Edge = { ...(edge as unknown as Edge) }\n\n // Edge type (line style) — canvas value takes precedence\n if (!styled.type && def.lineStyle) {\n styled.type = EDGE_TYPE_MAP[def.lineStyle] ?? 'default'\n }\n\n // Visual style — canvas style merged with def as fallback\n styled.style = {\n ...(def.color ? { stroke: def.color } : undefined),\n ...(def.strokeWidth ? { strokeWidth: def.strokeWidth } : undefined),\n ...edge.style,\n }\n\n // Animation — canvas value takes precedence\n if (styled.animated == null && def.animated) styled.animated = true\n\n // Markers — canvas value takes precedence over def\n if (!styled.markerStart) {\n const startType = toMarkerType(def.markerStart)\n if (startType) {\n styled.markerStart = {\n type: startType,\n ...(def.color ? { color: def.color } : undefined),\n }\n }\n }\n if (!styled.markerEnd) {\n const endType = toMarkerType(def.markerEnd)\n if (endType) {\n styled.markerEnd = {\n type: endType,\n ...(def.color ? { color: def.color } : undefined),\n }\n }\n }\n\n return styled\n })\n}\n","import React from 'react'\nimport { useReactFlow, useStoreApi } from '@xyflow/react'\nimport type { FlowBounds } from './types'\n\n// Match d3-zoom's translateExtent clamping so the viewport after resize\n// is identical to what the user sees after the first drag.\nfunction clampViewport(\n vp: { x: number; y: number; zoom: number },\n cw: number,\n ch: number,\n extent: [[number, number], [number, number]],\n): { x: number; y: number; zoom: number } {\n const left = -vp.x / vp.zoom\n const right = (cw - vp.x) / vp.zoom\n const top = -vp.y / vp.zoom\n const bottom = (ch - vp.y) / vp.zoom\n\n const dx0 = left - extent[0][0]\n const dx1 = right - extent[1][0]\n const dy0 = top - extent[0][1]\n const dy1 = bottom - extent[1][1]\n\n const cx =\n dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1)\n const cy =\n dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)\n\n if (cx === 0 && cy === 0) return vp\n return { x: vp.x + cx * vp.zoom, y: vp.y + cy * vp.zoom, zoom: vp.zoom }\n}\n\nexport function FocusHandler({\n bounds,\n padding,\n animation,\n mode,\n responsive,\n extent,\n clampBounds,\n minZoomProp,\n onInitialFit,\n}: {\n bounds: FlowBounds\n padding: number\n animation: boolean | number\n mode: 'contain' | 'cover'\n responsive: boolean\n extent?: [[number, number], [number, number]]\n /** When set, cover zoom of these bounds is enforced as minZoom via store API. */\n clampBounds?: FlowBounds\n /** User-specified minZoom prop, used with Math.max against coverZoom. */\n minZoomProp?: number\n /** Called after initial viewport is set with the expanded extent that fits the viewport. */\n onInitialFit?: (expandedExtent?: [[number, number], [number, number]]) => void\n}) {\n const { setViewport } = useReactFlow()\n const store = useStoreApi()\n const containerRef = React.useRef<HTMLDivElement>(null)\n const boundsKey = `${bounds.x},${bounds.y},${bounds.width},${bounds.height}`\n const boundsRef = React.useRef(bounds)\n boundsRef.current = bounds\n const [containerSize, setContainerSize] = React.useState({ w: 0, h: 0 })\n const prevBoundsKeyRef = React.useRef<string | null>(null)\n const prevSizeRef = React.useRef({ w: 0, h: 0 })\n\n // Track container size via ResizeObserver\n React.useEffect(() => {\n const el = containerRef.current\n if (!el) return\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (!entry) return\n const { width, height } = entry.contentRect\n setContainerSize({ w: width, h: height })\n })\n observer.observe(el)\n return () => observer.disconnect()\n }, [])\n\n React.useEffect(() => {\n if (containerSize.w === 0 || containerSize.h === 0) return\n\n const prevKey = prevBoundsKeyRef.current\n const prevSize = prevSizeRef.current\n prevBoundsKeyRef.current = boundsKey\n prevSizeRef.current = { w: containerSize.w, h: containerSize.h }\n\n // Determine trigger: bounds change vs resize-only\n const isBoundsChange = prevKey !== boundsKey\n const isResizeOnly =\n !isBoundsChange &&\n (prevSize.w !== containerSize.w || prevSize.h !== containerSize.h)\n const isInitial = prevKey === null\n\n // Skip resize-triggered re-fit if responsiveFit is disabled\n if (isResizeOnly && !responsive) return\n\n // Initial fit is always instant to prevent visual flash;\n // subsequent bounds changes and resizes respect the animation setting\n const duration =\n isInitial\n ? 0\n : isBoundsChange\n ? animation === true\n ? 300\n : typeof animation === 'number'\n ? animation\n : 0\n : 0\n\n const b = boundsRef.current\n const padX = padding * b.width\n const padY = padding * b.height\n const bw = b.width + padX * 2\n const bh = b.height + padY * 2\n\n if (bw === 0 || bh === 0) return\n\n // contain: fit inside viewport, cover: fill viewport (may crop)\n const zoomFn = mode === 'cover' ? Math.max : Math.min\n const zoom = zoomFn(containerSize.w / bw, containerSize.h / bh)\n // Center on clampBounds (frame) when available for symmetric frame margins;\n // fall back to bounds (content) center\n const centerTarget = clampBounds ?? b\n const cx = centerTarget.x + centerTarget.width / 2\n const cy = centerTarget.y + centerTarget.height / 2\n const x = containerSize.w / 2 - cx * zoom\n const y = containerSize.h / 2 - cy * zoom\n\n // Enforce minZoom: allow zooming back to the initial view level.\n // In contain mode, the initial zoom can be smaller than clampBounds cover zoom.\n if (clampBounds) {\n const coverZoom = Math.max(\n containerSize.w / clampBounds.width,\n containerSize.h / clampBounds.height,\n )\n store\n .getState()\n .setMinZoom(Math.max(Math.min(coverZoom, zoom), minZoomProp ?? 0))\n } else {\n store.getState().setMinZoom(minZoomProp ?? 0.5)\n }\n\n let vp = { x, y, zoom }\n\n if (isInitial || isBoundsChange) {\n // Initial fit or bounds change: no clampViewport.\n // translateExtent is deferred (not yet on ReactFlow) so d3-zoom\n // won't clamp this setViewport call.\n setViewport(vp, { duration: isInitial ? 0 : duration })\n\n // Compute expanded extent that includes the viewport's visible area.\n // Without this, d3-zoom would clamp on first interaction because\n // the visible area (in contain mode) can extend beyond clampBounds.\n if (extent) {\n const visW = containerSize.w / zoom\n const visH = containerSize.h / zoom\n onInitialFit?.([\n [Math.min(extent[0][0], cx - visW / 2), Math.min(extent[0][1], cy - visH / 2)],\n [Math.max(extent[1][0], cx + visW / 2), Math.max(extent[1][1], cy + visH / 2)],\n ])\n } else {\n onInitialFit?.()\n }\n } else {\n // Resize-only fits: apply clampViewport to match d3-zoom's behavior\n if (extent) {\n vp = clampViewport(vp, containerSize.w, containerSize.h, extent)\n }\n setViewport(vp, { duration })\n }\n }, [\n boundsKey,\n padding,\n animation,\n mode,\n responsive,\n containerSize.w,\n containerSize.h,\n extent,\n setViewport,\n clampBounds,\n minZoomProp,\n store,\n onInitialFit,\n ])\n\n // Measurement div — always rendered to track container size\n return (\n <div\n ref={containerRef}\n style={{\n position: 'absolute',\n inset: 0,\n pointerEvents: 'none',\n visibility: 'hidden',\n }}\n />\n )\n}\n"],"mappings":"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","names":["_a","useMemo","useMemo","React","React","React","React","React","React","React","_a"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ui/Flow/types.ts","../../src/ui/Flow/built-in-node-types.ts","../../src/ui/Flow/built-in-edge-types.ts","../../src/ui/Flow/useFlow.ts","../../src/core/query/query-keys.ts","../../src/ui/Flow/query-options.ts","../../src/ui/Flow/prefetchFlow.ts","../../src/ui/Flow/useFlowData.ts","../../src/ui/Flow/utils.ts","../../src/ui/Flow/template-compiler.ts","../../src/ui/Flow/quickjs-loader.ts","../../src/ui/Flow/node-renderers.tsx","../../src/ui/Flow/field-helpers.ts","../../src/ui/Flow/css-sanitizer.ts","../../src/ui/Flow/FlowRenderer.tsx","../../src/ui/Flow/node-types-factory.tsx","../../src/ui/Image/index.tsx","../../src/utils/image.ts","../../src/ui/Flow/edge-styles.ts","../../src/ui/Flow/focus-handler.tsx","../../src/ui/Flow/FlowFrame.tsx"],"sourcesContent":["import type React from 'react'\n\n// ── Dynamic node data ──\n\nexport interface DynamicNodeData {\n nodeTypeSlug: string\n label: string\n fields: Record<string, unknown>\n}\n\nexport type FlowNodeData = (DynamicNodeData | FrameNodeData) &\n Record<string, unknown>\n\n// ── Canvas types (mirrors @xyflow/react but standalone) ──\n\nexport interface FlowNodePosition {\n x: number\n y: number\n}\n\nexport interface FlowNode {\n id: string\n type?: string\n position: FlowNodePosition\n data: FlowNodeData\n parentId?: string\n style?: React.CSSProperties\n width?: number\n height?: number\n measured?: { width?: number; height?: number }\n draggable?: boolean\n selectable?: boolean\n [key: string]: unknown\n}\n\nexport interface FlowEdge {\n id: string\n source: string\n target: string\n sourceHandle?: string | null\n targetHandle?: string | null\n type?: string\n style?: React.CSSProperties\n animated?: boolean\n markerStart?: unknown\n markerEnd?: unknown\n edgeTypeSlug?: string\n fields?: Record<string, unknown>\n [key: string]: unknown\n}\n\nexport interface FlowViewport {\n x: number\n y: number\n zoom: number\n}\n\nexport interface CanvasData {\n nodes: FlowNode[]\n edges: FlowEdge[]\n viewport: FlowViewport\n}\n\n// ── Node type definitions (mirrors console's NodeTypeDef) ──\n\nexport interface NodeTypeFieldDef {\n name: string\n label: string\n fieldType:\n | 'text'\n | 'textarea'\n | 'number'\n | 'url'\n | 'color'\n | 'image'\n | 'select'\n | 'toggle'\n options?: { label: string; value: string }[]\n defaultValue?: string\n required?: boolean\n}\n\nexport interface NodeTypeDef {\n slug: string\n name: string\n color: string\n defaultSize: { width: number; height: number }\n fields: NodeTypeFieldDef[]\n transparentBackground?: boolean\n template?: string | null\n customCSS?: string | null\n}\n\n// ── Edge type definitions (mirrors console's EdgeTypeDef) ──\n\nexport interface EdgeTypeDef {\n slug: string\n name: string\n color: string\n strokeWidth: number\n animated: boolean\n lineStyle: string\n markerStart: string\n markerEnd: string\n fields: NodeTypeFieldDef[]\n}\n\n// ── Type guards ──\n\nexport function isDynamicNode(\n node: FlowNode,\n): node is FlowNode & { data: DynamicNodeData } {\n return node.type === 'dynamic'\n}\n\nexport function isFrameNode(\n node: FlowNode,\n): node is FlowNode & { data: FrameNodeData } {\n return node.type === 'frame'\n}\n\n// ── Component slot props ──\n\nexport interface DynamicNodeSlotProps {\n id: string\n nodeTypeSlug: string\n label: string\n fields: Record<string, unknown>\n nodeTypeDef?: NodeTypeDef\n /** Whether this node is currently selected */\n selected?: boolean\n /** Measured node width (undefined before first measurement) */\n width?: number\n /** Measured node height (undefined before first measurement) */\n height?: number\n /** The default rendering (template or field-based). Allows custom renderers to wrap/extend instead of replacing entirely. */\n defaultRender?: React.ReactElement\n}\n\n// ── Frame node data ──\n\nexport interface FrameNodeData {\n label: string\n color?: string\n padding?: number\n borderStyle?: 'dashed' | 'solid' | 'none'\n opacity?: number\n}\n\n// S1: Frame renderer slot\nexport interface FrameNodeSlotProps {\n id: string\n label: string\n color?: string\n padding?: number\n borderStyle?: 'dashed' | 'solid' | 'none'\n opacity?: number\n width?: number\n height?: number\n children?: React.ReactNode\n}\n\n// S2: Edge renderer slot\nexport interface EdgeSlotProps {\n id: string\n edgeTypeSlug?: string\n source: string\n target: string\n label?: string\n fields?: Record<string, unknown>\n edgeTypeDef?: EdgeTypeDef\n style?: React.CSSProperties\n}\n\n// S3: Node wrapper slot\nexport interface NodeWrapperSlotProps {\n id: string\n nodeTypeSlug: string\n label: string\n selected?: boolean\n nodeTypeDef?: NodeTypeDef\n children: React.ReactNode\n}\n\n// S8: Viewport focus\nexport interface FlowBounds {\n x: number\n y: number\n width: number\n height: number\n}\n","import type { NodeTypeDef } from './types'\n\nexport const BUILT_IN_NODE_TYPES: NodeTypeDef[] = [\n {\n slug: 'text',\n name: 'Text',\n color: '#e5e7eb',\n defaultSize: { width: 200, height: 200 },\n fields: [{ name: 'body', label: 'Body', fieldType: 'textarea' }],\n },\n {\n slug: 'image',\n name: 'Image',\n color: '#e5e7eb',\n transparentBackground: true,\n defaultSize: { width: 200, height: 200 },\n fields: [\n { name: 'image', label: 'Image', fieldType: 'image' },\n { name: 'alt', label: 'Alt Text', fieldType: 'text' },\n { name: 'caption', label: 'Caption', fieldType: 'text' },\n ],\n },\n]\n","import type { EdgeTypeDef } from './types'\n\nexport const BUILT_IN_EDGE_TYPES: EdgeTypeDef[] = [\n {\n slug: 'default',\n name: 'Default',\n color: '',\n strokeWidth: 2,\n animated: false,\n lineStyle: 'default',\n markerStart: 'none',\n markerEnd: 'arrow',\n fields: [],\n },\n]\n","'use client'\n\nimport { useQuery, type QueryClient } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport type { CanvasData, NodeTypeDef, EdgeTypeDef } from './types'\nimport { BUILT_IN_NODE_TYPES } from './built-in-node-types'\nimport { BUILT_IN_EDGE_TYPES } from './built-in-edge-types'\nimport { flowQueryOptions, nodeTypesQueryOptions, edgeTypesQueryOptions } from './query-options'\n\n// ── Client interface ──\n// Structurally compatible with both Client and ServerClient.\n// Lists only the collections useFlow actually queries so the generic\n// `from<T extends PublicCollection>` on the real clients satisfies this.\n\ntype FlowCollection = 'flows' | 'flow-node-types' | 'flow-edge-types'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyFn = (...args: any[]) => any\n\nexport interface SDKClient {\n from(collection: FlowCollection): {\n find: AnyFn\n findById: AnyFn\n }\n queryClient: QueryClient\n}\n\n// ── Options & Result ──\n\nexport interface UseFlowOptions {\n /** SDK client instance (Client or ServerClient) */\n client: SDKClient\n /** Flow slug (URL-friendly identifier) */\n slug?: string\n /** Flow document ID (UUID) */\n id?: string\n /** Enable/disable data fetching (default: true) */\n enabled?: boolean\n}\n\nexport interface UseFlowResult {\n data: CanvasData | undefined\n nodeTypeDefs: NodeTypeDef[]\n edgeTypeDefs: EdgeTypeDef[]\n flow: Record<string, unknown> | undefined\n isLoading: boolean\n error: Error | null\n}\n\n// ── Helpers ──\n\nfunction toNodeTypeDef(doc: Record<string, unknown>): NodeTypeDef {\n return {\n slug: String(doc.slug ?? ''),\n name: String(doc.title ?? ''),\n color: String(doc.color ?? '#e5e7eb'),\n defaultSize: (doc.defaultSize as NodeTypeDef['defaultSize']) ?? {\n width: 200,\n height: 200,\n },\n fields: Array.isArray(doc.fields)\n ? (doc.fields as NodeTypeDef['fields'])\n : [],\n transparentBackground: Boolean(doc.transparentBackground),\n template: (doc.template as string) ?? null,\n customCSS: (doc.customCSS as string) ?? null,\n }\n}\n\nfunction toEdgeTypeDef(doc: Record<string, unknown>): EdgeTypeDef {\n return {\n slug: String(doc.slug ?? ''),\n name: String(doc.title ?? ''),\n color: String(doc.color ?? ''),\n strokeWidth: (doc.strokeWidth as number) ?? 2,\n animated: (doc.animated as boolean) ?? false,\n lineStyle: String(doc.lineStyle ?? 'default'),\n markerStart: String(doc.markerStart ?? 'none'),\n markerEnd: String(doc.markerEnd ?? 'arrow'),\n fields: Array.isArray(doc.fields)\n ? (doc.fields as EdgeTypeDef['fields'])\n : [],\n }\n}\n\n// ── Hook ──\n\nexport function useFlow(options: UseFlowOptions): UseFlowResult {\n const { client, slug, id, enabled = true } = options\n const hasIdentifier = !!(slug || id)\n\n // Fetch flow document\n const flowQuery = useQuery<Record<string, unknown>>(\n {\n ...flowQueryOptions(client, slug, id),\n enabled: enabled && hasIdentifier,\n },\n client.queryClient,\n )\n\n // Fetch tenant's custom node types\n const nodeTypesQuery = useQuery<Record<string, unknown>[]>(\n {\n ...nodeTypesQueryOptions(client),\n enabled,\n },\n client.queryClient,\n )\n\n // Fetch tenant's custom edge types\n const edgeTypesQuery = useQuery<Record<string, unknown>[]>(\n {\n ...edgeTypesQueryOptions(client),\n enabled,\n },\n client.queryClient,\n )\n\n // Merge built-in + API node types\n const nodeTypeDefs = useMemo<NodeTypeDef[]>(() => {\n const apiDefs = (nodeTypesQuery.data ?? []).map(toNodeTypeDef)\n const builtInSlugs = new Set(BUILT_IN_NODE_TYPES.map((t) => t.slug))\n const customDefs = apiDefs.filter((d) => !builtInSlugs.has(d.slug))\n return [...BUILT_IN_NODE_TYPES, ...customDefs]\n }, [nodeTypesQuery.data])\n\n // Merge built-in + API edge types\n const edgeTypeDefs = useMemo<EdgeTypeDef[]>(() => {\n const apiDefs = (edgeTypesQuery.data ?? []).map(toEdgeTypeDef)\n const builtInSlugs = new Set(BUILT_IN_EDGE_TYPES.map((t) => t.slug))\n const customDefs = apiDefs.filter((d) => !builtInSlugs.has(d.slug))\n return [...BUILT_IN_EDGE_TYPES, ...customDefs]\n }, [edgeTypesQuery.data])\n\n const flow = flowQuery.data\n const canvas = flow?.canvas as CanvasData | undefined\n\n return {\n data: canvas,\n nodeTypeDefs,\n edgeTypeDefs,\n flow,\n isLoading:\n flowQuery.isLoading ||\n nodeTypesQuery.isLoading ||\n edgeTypesQuery.isLoading,\n error:\n (flowQuery.error as Error | null) ??\n (nodeTypesQuery.error as Error | null) ??\n (edgeTypesQuery.error as Error | null),\n }\n}\n","import type { PublicCollection, ApiQueryOptions } from '../client/types'\n\nexport function collectionKeys<T extends PublicCollection>(collection: T) {\n return {\n all: [collection] as const,\n lists: () => [collection, 'list'] as const,\n list: (options?: ApiQueryOptions) => [collection, 'list', options] as const,\n details: () => [collection, 'detail'] as const,\n detail: (id: string, options?: ApiQueryOptions) =>\n [collection, 'detail', id, options] as const,\n infinites: () => [collection, 'infinite'] as const,\n infinite: (options?: Omit<ApiQueryOptions, 'page'>) =>\n [collection, 'infinite', options] as const,\n }\n}\n\nexport const customerKeys = {\n all: ['customer'] as const,\n me: () => ['customer', 'me'] as const,\n}\n","import { collectionKeys } from '../../core/query/query-keys'\nimport type { SDKClient } from './useFlow'\n\nexport function flowQueryOptions(\n client: SDKClient,\n slug?: string,\n id?: string,\n) {\n const identifier = id ?? slug ?? ''\n return {\n queryKey: collectionKeys('flows').detail(identifier),\n queryFn: async () => {\n if (id) return client.from('flows').findById(id)\n const result = await client.from('flows').find({\n where: { slug: { equals: slug } },\n limit: 1,\n })\n const doc = result.docs[0]\n if (!doc) throw new Error(`Flow not found: ${slug}`)\n return doc\n },\n }\n}\n\nexport function nodeTypesQueryOptions(client: SDKClient) {\n return {\n queryKey: collectionKeys('flow-node-types').lists(),\n queryFn: async () => {\n // limit: 0 = fetch all documents (Payload CMS convention, disables pagination)\n const result = await client.from('flow-node-types').find({ limit: 0 })\n return result.docs\n },\n }\n}\n\nexport function edgeTypesQueryOptions(client: SDKClient) {\n return {\n queryKey: collectionKeys('flow-edge-types').lists(),\n queryFn: async () => {\n const result = await client.from('flow-edge-types').find({ limit: 0 })\n return result.docs\n },\n }\n}\n","import type { SDKClient } from './useFlow'\nimport {\n flowQueryOptions,\n nodeTypesQueryOptions,\n edgeTypesQueryOptions,\n} from './query-options'\n\nexport interface PrefetchFlowOptions {\n /** SDK client instance (Client or ServerClient) */\n client: SDKClient\n /** Flow slug (URL-friendly identifier) */\n slug?: string\n /** Flow document ID (UUID) */\n id?: string\n}\n\n/**\n * Prefetch flow data into the query cache.\n * Call in route loaders or server components to eliminate loading states on mount.\n *\n * ```ts\n * // React Router loader / Server Component\n * await prefetchFlow({ client, slug: 'Home' })\n * ```\n */\nexport async function prefetchFlow(\n options: PrefetchFlowOptions,\n): Promise<void> {\n const { client, slug, id } = options\n\n if (!slug && !id) {\n throw new Error('prefetchFlow requires either slug or id')\n }\n\n await Promise.all([\n client.queryClient.prefetchQuery(flowQueryOptions(client, slug, id)),\n client.queryClient.prefetchQuery(nodeTypesQueryOptions(client)),\n client.queryClient.prefetchQuery(edgeTypesQueryOptions(client)),\n ])\n}\n","import { useMemo } from 'react'\nimport type { CanvasData, FlowNode, NodeTypeDef, EdgeTypeDef } from './types'\nimport type { Edge } from '@xyflow/react'\nimport { BUILT_IN_NODE_TYPES } from './built-in-node-types'\nimport { BUILT_IN_EDGE_TYPES } from './built-in-edge-types'\n\n// ── Options & Result ──\n\nexport interface UseFlowDataOptions {\n /** Canvas data from Flow document's `canvas` field */\n data: CanvasData | undefined\n /** Node type definitions (defaults to built-in types) */\n nodeTypeDefs?: NodeTypeDef[]\n /** Edge type definitions (defaults to built-in types) */\n edgeTypeDefs?: EdgeTypeDef[]\n}\n\nexport interface UseFlowDataResult {\n /** Nodes from canvas data */\n nodes: FlowNode[]\n /** Edges from canvas data (typed for @xyflow/react) */\n edges: Edge[]\n /** Map of node type slug to definition */\n nodeTypeDefsMap: Map<string, NodeTypeDef>\n /** Map of edge type slug to definition */\n edgeTypeDefsMap: Map<string, EdgeTypeDef>\n}\n\n/**\n * Pure data transformation hook — extracts nodes, edges, and type definition\n * maps from canvas data without any rendering. Useful for headless usage\n * (custom layouts, analytics, server-side processing).\n */\nexport function useFlowData(options: UseFlowDataOptions): UseFlowDataResult {\n const { data, nodeTypeDefs: inputNodeDefs, edgeTypeDefs: inputEdgeDefs } =\n options\n\n const nodeTypeDefsMap = useMemo(() => {\n const allDefs = inputNodeDefs ?? BUILT_IN_NODE_TYPES\n return new Map(allDefs.map((d) => [d.slug, d]))\n }, [inputNodeDefs])\n\n const edgeTypeDefsMap = useMemo(() => {\n const allDefs = inputEdgeDefs ?? BUILT_IN_EDGE_TYPES\n return new Map(allDefs.map((d) => [d.slug, d]))\n }, [inputEdgeDefs])\n\n const nodes = useMemo(() => data?.nodes ?? [], [data?.nodes])\n // FlowEdge is a superset of @xyflow/react Edge; cast is safe while interfaces align.\n // TODO: Replace with explicit toXYFlowEdge() mapper if @xyflow/react Edge diverges.\n const edges = useMemo(() => (data?.edges ?? []) as unknown as Edge[], [data?.edges])\n\n return {\n nodes,\n edges,\n nodeTypeDefsMap,\n edgeTypeDefsMap,\n }\n}\n","import type { FlowNode, FlowEdge, FlowBounds, CanvasData } from './types'\n\n// ── Shared helpers ──\n\nfunction getNodeSize(node: FlowNode): { width: number; height: number } {\n return {\n width:\n (node.style?.width as number) ??\n node.measured?.width ??\n node.width ??\n 200,\n height:\n (node.style?.height as number) ??\n node.measured?.height ??\n node.height ??\n 200,\n }\n}\n\nfunction getAbsolutePosition(\n node: FlowNode,\n nodeMap: Map<string, FlowNode>,\n): { x: number; y: number } {\n let x = node.position.x\n let y = node.position.y\n let current = node\n const visited = new Set<string>([node.id])\n while (current.parentId) {\n const parentId = current.parentId\n if (visited.has(parentId)) break\n const parent = nodeMap.get(parentId)\n if (!parent) break\n visited.add(parent.id)\n x += parent.position.x\n y += parent.position.y\n current = parent\n }\n return { x, y }\n}\n\n/** Collect a node and all its descendants using a pre-built parent→children map (O(N)). */\nfunction collectDescendants(\n nodes: FlowNode[],\n rootId: string,\n): Set<string> {\n // Build parent → children lookup in O(N)\n const childrenMap = new Map<string, string[]>()\n for (const n of nodes) {\n if (n.parentId) {\n let siblings = childrenMap.get(n.parentId)\n if (!siblings) {\n siblings = []\n childrenMap.set(n.parentId, siblings)\n }\n siblings.push(n.id)\n }\n }\n\n // BFS over children map in O(descendants)\n const result = new Set<string>([rootId])\n const queue = [rootId]\n let i = 0\n while (i < queue.length) {\n const children = childrenMap.get(queue[i++]!)\n if (children) {\n for (const childId of children) {\n if (!result.has(childId)) {\n result.add(childId)\n queue.push(childId)\n }\n }\n }\n }\n return result\n}\n\n// ── Public utilities ──\n\n/**\n * Calculate bounding box for given node IDs.\n * Pure function — usable in SSR, server components, or outside React.\n */\nexport function getNodeBounds(\n nodes: FlowNode[],\n nodeIds: string[],\n): FlowBounds | undefined {\n const idSet = new Set(nodeIds)\n const targetNodes = nodes.filter((n) => idSet.has(n.id))\n if (targetNodes.length === 0) return undefined\n\n const nodeMap = new Map(nodes.map((n) => [n.id, n]))\n\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n\n for (const node of targetNodes) {\n const abs = getAbsolutePosition(node, nodeMap)\n const { width: w, height: h } = getNodeSize(node)\n minX = Math.min(minX, abs.x)\n minY = Math.min(minY, abs.y)\n maxX = Math.max(maxX, abs.x + w)\n maxY = Math.max(maxY, abs.y + h)\n }\n\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY }\n}\n\n/**\n * Get all frame nodes with their bounds.\n * Sorted by position (top-left to bottom-right).\n */\nexport function getFrames(\n nodes: FlowNode[],\n): Array<{ id: string; label: string; bounds: FlowBounds }> {\n const frames = nodes.filter((n) => n.type === 'frame')\n if (frames.length === 0) return []\n\n const nodeMap = new Map(nodes.map((n) => [n.id, n]))\n\n return frames\n .map((f) => {\n const data = f.data as { label?: string }\n const abs = getAbsolutePosition(f, nodeMap)\n const { width: w, height: h } = getNodeSize(f)\n return {\n id: f.id,\n label: data.label ?? '',\n bounds: { x: abs.x, y: abs.y, width: w, height: h },\n }\n })\n .sort((a, b) => a.bounds.y - b.bounds.y || a.bounds.x - b.bounds.x)\n}\n\n/** Result of getFrameData — contains filtered canvas + dual bounds. */\nexport interface FrameData {\n /** Canvas data containing only the frame's descendants (nodes have draggable: false). */\n data: CanvasData\n /** Bounding box of child content nodes — use for initial viewport fit (centering). */\n fitBounds: FlowBounds\n /** Bounding box of the frame itself — use for panning/zoom restriction (clamp). */\n clampBounds: FlowBounds\n /** @deprecated Use fitBounds instead. Alias for clampBounds for backward compatibility. */\n bounds: FlowBounds\n}\n\n/**\n * Extract a frame's descendants and related edges from canvas data.\n * Recursively collects all nested children (supports nested frames).\n * Returns undefined if frameId is not found or is not a frame node.\n *\n * Child nodes are marked `draggable: false` to prevent interfering with canvas panning.\n * The frame node itself is included (use `frameRenderer={() => null}` to hide it).\n *\n * Returns dual bounds:\n * - `fitBounds`: child content bounding box (for centering the viewport)\n * - `clampBounds`: frame area bounding box (for panning restriction)\n */\nexport function getFrameData(\n data: CanvasData,\n frameId: string,\n): FrameData | undefined {\n const frame = data.nodes.find((n) => n.id === frameId)\n if (!frame || frame.type !== 'frame') return undefined\n\n // Recursively collect frame + all descendants\n const descendantIds = collectDescendants(data.nodes, frameId)\n const childNodes = data.nodes\n .filter((n) => descendantIds.has(n.id))\n .map((n) => ({ ...n, draggable: false }))\n\n // Keep only edges where both source and target are within the frame\n const childEdges = data.edges.filter(\n (e: FlowEdge) => descendantIds.has(e.source) && descendantIds.has(e.target),\n )\n\n // clampBounds: frame's own bounding box (for panning restriction)\n const frameBounds = getNodeBounds(data.nodes, [frameId])\n const { width: w, height: h } = getNodeSize(frame)\n const clampBounds: FlowBounds = frameBounds ?? {\n x: frame.position.x,\n y: frame.position.y,\n width: w,\n height: h,\n }\n\n // fitBounds: child content bounding box (for centering)\n const contentNodeIds = childNodes\n .filter((n) => n.id !== frameId)\n .map((n) => n.id)\n const contentBounds = contentNodeIds.length > 0\n ? getNodeBounds(data.nodes, contentNodeIds)\n : undefined\n const fitBounds = contentBounds ?? clampBounds\n\n return {\n data: {\n nodes: childNodes,\n edges: childEdges,\n viewport: data.viewport,\n },\n fitBounds,\n clampBounds,\n bounds: clampBounds,\n }\n}\n","'use client'\n\nimport React from 'react'\nimport { transform } from 'sucrase'\nimport {\n ensureQuickJSLoaded,\n getQuickJSSnapshot,\n type QuickJSContext,\n type QuickJSHandle,\n type QuickJSModule,\n type QuickJSResult,\n} from './quickjs-loader'\n\nexport interface CodeComponentProps {\n fields: Record<string, unknown>\n label: string\n color: string\n nodeTypeSlug: string\n width: number\n height: number\n}\n\n// ── Element descriptor (QuickJS → host) ──\n\ninterface ElementDescriptor {\n $$t: 'el'\n type: string\n props: Record<string, unknown>\n ch: ChildDescriptor[]\n}\n\ninterface FragmentDescriptor {\n $$t: 'frag'\n ch: ChildDescriptor[]\n}\n\ntype ChildDescriptor =\n | ElementDescriptor\n | FragmentDescriptor\n | string\n | number\n | null\n | undefined\n\n// ── Security constants ──\n\nconst MAX_CACHE_SIZE = 100\nconst MAX_MATERIALIZE_DEPTH = 20\n\nconst ALLOWED_ELEMENTS = new Set([\n 'div', 'span', 'p',\n 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'ul', 'ol', 'li',\n 'strong', 'em', 'b', 'i', 'br',\n 'img', 'figure', 'section',\n 'table', 'thead', 'tbody', 'tr', 'th', 'td',\n 'pre', 'code',\n 'svg', 'path', 'g', 'circle', 'rect',\n])\n\nconst BLOCKED_PATTERNS = [\n /\\bdocument\\s*\\./,\n /\\bwindow\\s*\\./,\n /\\bwindow\\s*\\[/,\n /\\bglobalThis\\s*\\./,\n /\\bfetch\\s*\\(/,\n /\\bXMLHttpRequest/,\n /\\beval\\s*\\(/,\n /\\bFunction\\s*\\(/,\n /\\bimport\\s*\\(/,\n /\\blocalStorage/,\n /\\bsessionStorage/,\n /\\bcookie/,\n /\\bpostMessage\\s*\\(/,\n /\\blocation\\s*[.=]/,\n /\\bnavigator\\s*\\./,\n /\\bsetTimeout\\s*\\(/,\n /\\bsetInterval\\s*\\(/,\n /\\bsetImmediate\\s*\\(/,\n /\\brequire\\s*\\(/,\n /\\bself\\b/,\n /\\bconstructor\\s*\\.\\s*constructor/,\n /\\bReflect\\b/,\n /\\bProxy\\b/,\n /\\b__proto__\\b/,\n]\n\n// ── VM bootstrap code (injected once per render context) ──\n// Establishes a mock React.createElement that returns JSON-serializable descriptors,\n// and shadows all dangerous browser globals so they are unreachable from template code.\n\nconst VM_SETUP = `\nvar React = {\n createElement: function(type, props) {\n var args = Array.prototype.slice.call(arguments, 2);\n return { $$t: 'el', type: String(type), props: props || {}, ch: args };\n },\n Fragment: '__frag__'\n};\nvar exports = {};\nvar module = { exports: exports };\nvar window = undefined;\nvar document = undefined;\nvar globalThis = undefined;\nvar self = undefined;\nvar setTimeout = undefined;\nvar setInterval = undefined;\nvar setImmediate = undefined;\nvar fetch = undefined;\nvar XMLHttpRequest = undefined;\nvar navigator = undefined;\nvar location = undefined;\nvar localStorage = undefined;\nvar sessionStorage = undefined;\nvar cookie = undefined;\nvar postMessage = undefined;\n`\n// Note: `eval` is intentionally NOT shadowed here. Sucrase's 'imports' transform\n// prepends \"use strict\"; — and `var eval = ...` is a SyntaxError in strict mode.\n// QuickJS's built-in eval is sandboxed to the WASM realm and cannot access host\n// APIs; BLOCKED_PATTERNS already prevents template code from calling it.\n\n// ── LRU cache of compiled renderers ──\n\ntype CachedRenderer = (qjs: QuickJSModule, props: CodeComponentProps) => React.ReactNode\n\nconst rendererCache = new Map<string, CachedRenderer>()\n\n// ── Helpers ──\n\nfunction hashCode(str: string): string {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = ((hash << 5) - hash + char) | 0\n }\n return hash.toString(36)\n}\n\nfunction validateTemplateCode(code: string): boolean {\n return !BLOCKED_PATTERNS.some((pattern) => pattern.test(code))\n}\n\n// Restrict data URIs to safe raster formats — svg+xml is excluded because it can\n// embed scripts via <foreignObject> elements.\nconst SAFE_DATA_URI_PREFIXES = [\n 'data:image/png;',\n 'data:image/jpeg;',\n 'data:image/gif;',\n 'data:image/webp;',\n 'data:image/avif;',\n]\n\nfunction isSafeUrl(value: unknown): boolean {\n if (typeof value !== 'string') return false\n if (value.startsWith('/') || value.startsWith('./') || value.startsWith('../')) return true\n if (SAFE_DATA_URI_PREFIXES.some((p) => value.startsWith(p))) return true\n try {\n const url = new URL(value)\n return url.protocol === 'http:' || url.protocol === 'https:'\n } catch {\n return false\n }\n}\n\n// CSS properties that can load external resources or overlay host UI\nconst BLOCKED_STYLE_PROPS = new Set([\n 'backgroundImage', 'background', 'listStyleImage', 'content',\n 'borderImage', 'borderImageSource', 'maskImage', 'mask',\n 'filter', 'cursor',\n])\n\nfunction sanitizeStyle(style: unknown): Record<string, unknown> {\n if (!style || typeof style !== 'object' || Array.isArray(style)) return {}\n const safe: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(style as Record<string, unknown>)) {\n if (BLOCKED_STYLE_PROPS.has(k)) continue\n // block url() and position:fixed/absolute (UI redress)\n if (typeof v === 'string' && /url\\s*\\(/i.test(v)) continue\n if (k === 'position' && typeof v === 'string' && /fixed|absolute/i.test(v)) continue\n safe[k] = v\n }\n return safe\n}\n\n// ── materialize: QuickJS JSON descriptor → React element tree ──\n\nfunction materialize(node: unknown, depth = 0): React.ReactNode {\n if (depth > MAX_MATERIALIZE_DEPTH) return null\n if (node == null) return null\n if (typeof node === 'string' || typeof node === 'number') return node\n\n // JSX map expressions produce array children (e.g. {items.map(i => <li>{i}</li>)})\n if (Array.isArray(node)) {\n return React.createElement(\n React.Fragment,\n null,\n ...node.map((c) => materialize(c, depth + 1)),\n )\n }\n\n if (typeof node !== 'object') return null\n const d = node as Record<string, unknown>\n\n if (d.$$t === 'frag') {\n const ch = Array.isArray(d.ch) ? (d.ch as unknown[]) : []\n return React.createElement(\n React.Fragment,\n null,\n ...ch.map((c) => materialize(c, depth + 1)),\n )\n }\n\n if (d.$$t === 'el') {\n const type = String(d.type ?? '')\n const props = (d.props && typeof d.props === 'object' ? d.props : {}) as Record<string, unknown>\n const ch = Array.isArray(d.ch) ? (d.ch as unknown[]) : []\n\n // Allow only safelisted element types\n if (!ALLOWED_ELEMENTS.has(type.toLowerCase())) return null\n\n // Sanitize props: strip event handlers, dangerous attrs, unsafe URLs, unsafe styles\n const safeProps: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(props)) {\n if (k.startsWith('on')) continue\n if (k === 'dangerouslySetInnerHTML' || k === 'ref') continue\n if ((k === 'src' || k === 'href') && !isSafeUrl(v)) continue\n if (k === 'style') { safeProps[k] = sanitizeStyle(v); continue }\n safeProps[k] = v\n }\n\n const children = ch.map((c) => materialize(c, depth + 1))\n return React.createElement(type, safeProps, ...children)\n }\n\n return null\n}\n\n// ── Per-render QuickJS execution ──\n// Creates a fresh context per render call (~0.5–2ms overhead) to avoid\n// persistent VM state across renders. Contexts are disposed after each call.\n\nfunction evalInContext(\n vm: QuickJSContext,\n code: string,\n): { ok: true; handle: QuickJSHandle } | { ok: false } {\n const result: QuickJSResult = vm.evalCode(code)\n if (result.error) {\n result.error.dispose()\n return { ok: false }\n }\n return { ok: true, handle: result.value! }\n}\n\n// Max opcode cycles per template render — prevents infinite-loop DoS (client-side tab freeze).\n// QuickJS counts bytecode instructions; ~200K covers complex templates well within 10ms.\nconst MAX_VM_CYCLES = 200_000\n\nfunction makeRenderer(jsCode: string): CachedRenderer {\n return function runInQuickJS(qjs: QuickJSModule, props: CodeComponentProps): React.ReactNode {\n const vm = qjs.newContext()\n // Install cycle-budget interrupt to prevent infinite-loop DoS\n let cycles = 0\n vm.runtime.setInterruptHandler(() => {\n cycles++\n return cycles > MAX_VM_CYCLES\n })\n try {\n // Load bootstrap + module code\n const setupResult = evalInContext(vm, VM_SETUP + jsCode)\n if (!setupResult.ok) return null\n setupResult.handle.dispose()\n\n // Call the component, serializing props/result through JSON for cross-realm safety\n const propsJson = JSON.stringify(props)\n const callCode = `(function(){var __c=module.exports.default||module.exports;return JSON.stringify(__c(${propsJson}));})();`\n const callResult = evalInContext(vm, callCode)\n if (!callResult.ok) return null\n\n const raw = vm.dump(callResult.handle)\n callResult.handle.dispose()\n\n return materialize(JSON.parse(String(raw)))\n } catch {\n return null\n } finally {\n vm.dispose()\n }\n }\n}\n\nfunction makeReactFC(\n renderer: CachedRenderer,\n qjs: QuickJSModule,\n): React.FC<CodeComponentProps> {\n return function QuickJSTemplateComponent(props: CodeComponentProps) {\n return (renderer(qjs, props) as React.ReactElement) ?? null\n }\n}\n\n// ── Public API ──\n\nexport function compileTemplate(\n code: string,\n slug: string,\n): React.FC<CodeComponentProps> | null {\n // Trigger lazy load (no-op if already loading/ready/failed)\n ensureQuickJSLoaded()\n\n if (!validateTemplateCode(code)) return null\n\n const qjs = getQuickJSSnapshot()\n // QuickJS not ready yet — caller re-renders via useQuickJS() subscription when it loads\n if (!qjs) return null\n\n const cacheKey = `${slug}:${code.length}:${hashCode(code)}`\n\n // LRU hit — refresh recency\n if (rendererCache.has(cacheKey)) {\n const renderer = rendererCache.get(cacheKey)!\n rendererCache.delete(cacheKey)\n rendererCache.set(cacheKey, renderer)\n return makeReactFC(renderer, qjs)\n }\n\n // Transpile JSX/TS → plain JS\n let jsCode: string\n try {\n const result = transform(code, {\n transforms: ['typescript', 'jsx', 'imports'],\n jsxRuntime: 'classic',\n jsxPragma: 'React.createElement',\n jsxFragmentPragma: 'React.Fragment',\n })\n jsCode = result.code\n } catch {\n return null\n }\n\n const renderer = makeRenderer(jsCode)\n\n // LRU eviction\n if (rendererCache.size >= MAX_CACHE_SIZE) {\n const oldest = rendererCache.keys().next().value\n if (oldest) rendererCache.delete(oldest)\n }\n rendererCache.set(cacheKey, renderer)\n\n return makeReactFC(renderer, qjs)\n}\n\nexport function clearTemplateCache(): void {\n rendererCache.clear()\n}\n","'use client'\n\nimport { useSyncExternalStore } from 'react'\n\n// Duck-typed interfaces — avoid importing quickjs-emscripten at module level\n// so that the WASM binary is only fetched when a template actually needs to render.\nexport interface QuickJSHandle {\n dispose(): void\n}\n\nexport type QuickJSResult =\n | { value: QuickJSHandle; error?: never }\n | { error: QuickJSHandle; value?: never }\n\nexport interface QuickJSRuntime {\n setInterruptHandler(cb: () => boolean): void\n}\n\nexport interface QuickJSContext {\n runtime: QuickJSRuntime\n evalCode(code: string, filename?: string): QuickJSResult\n dump(handle: QuickJSHandle): unknown\n unwrapResult(result: QuickJSResult): QuickJSHandle\n dispose(): void\n}\n\nexport interface QuickJSModule {\n newContext(): QuickJSContext\n}\n\ntype LoadState =\n | { status: 'idle' | 'loading' | 'failed'; module: null }\n | { status: 'ready'; module: QuickJSModule }\n\nlet _state: LoadState = { status: 'idle', module: null }\nconst _listeners = new Set<() => void>()\n\nfunction _notify(): void {\n _listeners.forEach((fn) => fn())\n}\n\nexport function subscribeQuickJS(cb: () => void): () => void {\n _listeners.add(cb)\n return () => _listeners.delete(cb)\n}\n\nexport function getQuickJSSnapshot(): QuickJSModule | null {\n return _state.module\n}\n\nexport function ensureQuickJSLoaded(): void {\n if (_state.status !== 'idle') return\n _state = { status: 'loading', module: null }\n import('quickjs-emscripten')\n .then((mod) =>\n (mod as unknown as { getQuickJS(): Promise<QuickJSModule> }).getQuickJS(),\n )\n .then((module: QuickJSModule) => {\n _state = { status: 'ready', module }\n _notify()\n })\n .catch(() => {\n _state = { status: 'failed', module: null }\n })\n}\n\nexport function useQuickJS(): QuickJSModule | null {\n return useSyncExternalStore(subscribeQuickJS, getQuickJSSnapshot, () => null)\n}\n","import React from 'react'\nimport type { NodeProps } from '@xyflow/react'\nimport type {\n DynamicNodeData,\n FrameNodeData,\n NodeTypeDef,\n NodeTypeFieldDef,\n} from './types'\nimport { compileTemplate } from './template-compiler'\nimport { useQuickJS } from './quickjs-loader'\n\n// ── Helpers ──\n\nfunction sanitizeUrl(url: string | undefined): string | undefined {\n if (!url) return url\n try {\n const parsed = new URL(url)\n if (parsed.protocol === 'http:' || parsed.protocol === 'https:') return url\n return undefined\n } catch {\n return undefined\n }\n}\n\n// ── Field renderer (type-aware, matching console style) ──\n\nexport function renderFieldValue(\n key: string,\n val: unknown,\n fieldDef?: NodeTypeFieldDef,\n): React.ReactNode {\n if (val == null || val === '') return null\n\n const fieldType = fieldDef?.fieldType\n\n // Image field — image only, no decoration\n if (\n fieldType === 'image' ||\n (typeof val === 'object' && val !== null && 'url' in val)\n ) {\n const imgUrl =\n typeof val === 'string' ? val : (val as { url?: string })?.url\n const safeUrl = sanitizeUrl(imgUrl)\n if (!safeUrl) return null\n return (\n <img\n key={key}\n src={safeUrl}\n alt=\"\"\n draggable={false}\n style={{ flex: 1, minHeight: 0, width: '100%', objectFit: 'contain' }}\n />\n )\n }\n\n // All other fields — text only\n return (\n <div\n key={key}\n style={{\n fontSize: 11,\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n overflow: 'hidden',\n flexShrink: 0,\n }}\n >\n {String(val)}\n </div>\n )\n}\n\n// ── Default dynamic node renderer (no typeDef) ──\n\nexport function DefaultDynamicNode({ data }: NodeProps) {\n const d = data as unknown as DynamicNodeData\n return (\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n {d.fields &&\n Object.entries(d.fields)\n .filter(([, v]) => v != null && v !== '')\n .map(([key, val]) => renderFieldValue(key, val))}\n </div>\n )\n}\n\n// ── Template error boundary ──\n\nclass TemplateErrorBoundary extends React.Component<\n { resetKey?: string; children: React.ReactNode },\n { error: Error | null }\n> {\n state: { error: Error | null } = { error: null }\n static getDerivedStateFromError(error: Error) {\n return { error }\n }\n componentDidUpdate(prevProps: { resetKey?: string }) {\n if (prevProps.resetKey !== this.props.resetKey && this.state.error) {\n this.setState({ error: null })\n }\n }\n render() {\n if (this.state.error) {\n return (\n <div style={{ padding: 8, fontSize: 11, color: '#ef4444' }}>\n <strong>Render error</strong>\n <pre style={{ fontSize: 10, whiteSpace: 'pre-wrap' }}>\n {process.env.NODE_ENV === 'development'\n ? this.state.error.message\n : 'Template render failed'}\n </pre>\n </div>\n )\n }\n return this.props.children\n }\n}\n\n// ── Enhanced dynamic node renderer (with NodeTypeDef) ──\n\nexport function EnhancedDynamicNode({\n data,\n typeDef,\n width,\n height,\n}: {\n data: DynamicNodeData\n typeDef: NodeTypeDef\n width?: number\n height?: number\n}) {\n // Subscribe to QuickJS loading state — triggers re-render when QuickJS is ready.\n // compileTemplate returns null before QuickJS loads; this re-render picks it up.\n useQuickJS()\n\n // Tier 2: Custom template rendering\n if (typeDef.template) {\n const Component = compileTemplate(typeDef.template, typeDef.slug)\n if (Component) {\n return (\n <div\n className={`flow-node flow-node--${typeDef.slug}${typeDef.transparentBackground ? ' flow-node--transparent-bg' : ''}`}\n style={{ width: '100%', height: '100%' }}\n >\n <TemplateErrorBoundary resetKey={typeDef.template}>\n <Component\n fields={data.fields}\n label={data.label}\n color={typeDef.color}\n nodeTypeSlug={typeDef.slug}\n width={width || typeDef.defaultSize.width}\n height={height || typeDef.defaultSize.height}\n />\n </TemplateErrorBoundary>\n </div>\n )\n }\n }\n\n // Tier 1: Default field rendering\n return (\n <div\n className={`flow-node flow-node--${typeDef.slug}`}\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n {typeDef.fields.map((f) => {\n const val = data.fields[f.name]\n if (val == null || val === '') return null\n return renderFieldValue(f.name, val, f)\n })}\n </div>\n )\n}\n\n// ── Default frame node renderer ──\n\nexport function DefaultFrameNode({ data }: NodeProps) {\n const d = data as unknown as FrameNodeData\n const baseColor = d.color ?? 'rgb(128,128,128)'\n const padding = d.padding ?? 20\n const borderStyle = d.borderStyle ?? 'dashed'\n const opacity = d.opacity ?? 0.15\n\n // Apply opacity to color at render time\n const bgColor = (() => {\n const m = baseColor.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/)\n if (m) return `rgba(${m[1]},${m[2]},${m[3]},${opacity})`\n return baseColor\n })()\n\n return (\n <div\n style={{\n backgroundColor: bgColor,\n padding,\n width: '100%',\n height: '100%',\n border:\n borderStyle === 'none'\n ? 'none'\n : `2px ${borderStyle} rgba(128,128,128,0.3)`,\n }}\n >\n <div\n style={{\n fontSize: 11,\n fontWeight: 600,\n color: 'rgba(128,128,128,0.6)',\n userSelect: 'none',\n }}\n >\n {d.label}\n </div>\n </div>\n )\n}\n","import type { ImageData } from '../../utils/image'\n\n/** Extract an image field value with proper typing. */\nexport function getImageField(\n fields: Record<string, unknown>,\n name: string,\n): ImageData | undefined {\n const val = fields?.[name]\n if (val && typeof val === 'object' && val !== null && 'url' in val)\n return val as ImageData\n return undefined\n}\n\n/** Extract a text/textarea/url/color field value. */\nexport function getTextField(\n fields: Record<string, unknown>,\n name: string,\n): string | undefined {\n const val = fields?.[name]\n return typeof val === 'string' ? val : undefined\n}\n\n/** Extract a number field value. */\nexport function getNumberField(\n fields: Record<string, unknown>,\n name: string,\n): number | undefined {\n const val = fields?.[name]\n return typeof val === 'number' ? val : undefined\n}\n\n/** Extract a toggle/boolean field value. */\nexport function getBooleanField(\n fields: Record<string, unknown>,\n name: string,\n): boolean | undefined {\n const val = fields?.[name]\n return typeof val === 'boolean' ? val : undefined\n}\n","import postcss from 'postcss'\n\nconst ALLOWED_AT_RULES = new Set(['keyframes', 'media', 'supports', 'container', 'layer'])\nconst BLOCKED_VALUE_PATTERNS = [/url\\s*\\(/i, /expression\\s*\\(/i, /paint\\s*\\(/i, /-moz-binding/i]\nconst DANGEROUS_SELECTOR = /(?:^|[\\s,])(?::root|html|body)\\b/\n\n/**\n * Sanitize tenant-authored CSS using PostCSS AST parsing.\n *\n * - At-rules: allowlist only (@keyframes, @media, @supports, @container, @layer)\n * - Declarations: blocks url(), expression(), paint(), -moz-binding\n * - Selectors: removes :root/html/body targets; scopes remainder under scopeClass\n *\n * Returns empty string on parse failure (fail-closed).\n *\n * @param css - Raw CSS string from tenant\n * @param scopeClass - Container class to scope selectors (e.g. 'flow-node--my-type')\n */\nexport function sanitizeCSS(css: string, scopeClass?: string): string {\n let root: postcss.Root\n try {\n root = postcss.parse(css)\n } catch {\n return ''\n }\n\n // At-rules: remove anything not in the allowlist\n root.walkAtRules((node) => {\n if (!ALLOWED_AT_RULES.has(node.name.toLowerCase())) {\n node.remove()\n }\n })\n\n // Declarations: remove dangerous values\n root.walkDecls((node) => {\n if (BLOCKED_VALUE_PATTERNS.some((p) => p.test(node.value))) {\n node.remove()\n }\n })\n\n // Rules: strip dangerous selectors, then scope the rest\n root.walkRules((rule) => {\n rule.selectors = rule.selectors.filter((s) => !DANGEROUS_SELECTOR.test(s))\n if (!rule.selectors.length) {\n rule.remove()\n return\n }\n if (scopeClass) {\n // Strip CSS metacharacters from scopeClass (defense-in-depth against slug injection)\n const safeScopeClass = scopeClass.replace(/[{}()[\\];,'\"\\\\<>]/g, '')\n if (!safeScopeClass) { rule.remove(); return }\n // Skip scoping inside @keyframes — from/to/0% are not element selectors\n const parent = rule.parent\n if (\n parent?.type === 'atrule' &&\n (parent as postcss.AtRule).name.toLowerCase() === 'keyframes'\n ) {\n return\n }\n rule.selectors = rule.selectors.map((sel) => `.${safeScopeClass} ${sel}`)\n }\n })\n\n // Post-process: escape </style to prevent HTML parser closing the style tag in SSR contexts.\n // postcss parses this as valid CSS string content and reproduces it verbatim.\n return root.toString().replace(/<\\/style/gi, '<\\\\/style')\n}\n","'use client'\n\nimport React from 'react'\nimport {\n ReactFlow,\n ReactFlowProvider,\n Background,\n Controls,\n MiniMap,\n} from '@xyflow/react'\nimport type {\n CanvasData,\n DynamicNodeSlotProps,\n EdgeSlotProps,\n EdgeTypeDef,\n FlowBounds,\n FlowEdge,\n FlowNode,\n FlowViewport,\n FrameNodeSlotProps,\n NodeTypeDef,\n NodeWrapperSlotProps,\n} from './types'\nimport { createNodeTypes, createEdgeTypes } from './node-types-factory'\nimport { applyEdgeStyles } from './edge-styles'\nimport { FocusHandler } from './focus-handler'\nimport { sanitizeCSS } from './css-sanitizer'\n\n// ── FlowRenderer ──\n\n/**\n * Renders a Flow canvas in read-only mode.\n *\n * Requires `@xyflow/react` peer dependency and its CSS:\n * ```ts\n * import '@xyflow/react/dist/style.css'\n * ```\n */\nexport interface FlowRendererProps {\n /** Canvas data from Flow document's `canvas` field */\n data: CanvasData\n /** Container className */\n className?: string\n /** Container style */\n style?: React.CSSProperties\n /** Custom renderers by node type slug (e.g., `{ 'product-card': MyProductCard }`) */\n nodeRenderers?: Record<string, React.ComponentType<DynamicNodeSlotProps>>\n /** Node type definitions for enhanced rendering (field-type-aware display) */\n nodeTypeDefs?: NodeTypeDef[]\n /** Edge type definitions for styled edges (color, stroke, markers, animation) */\n edgeTypeDefs?: EdgeTypeDef[]\n /** Show background pattern (default: false) */\n background?: boolean\n /** Allow user interaction - pan, zoom (default: false for read-only display) */\n interactive?: boolean\n /** Fit view on mount (default: true) */\n fitView?: boolean\n /** Called when a node is clicked */\n onNodeClick?: (event: React.MouseEvent, node: FlowNode) => void\n /** Called when a node is double-clicked */\n onNodeDoubleClick?: (event: React.MouseEvent, node: FlowNode) => void\n /** Called on node right-click / context menu */\n onNodeContextMenu?: (event: React.MouseEvent, node: FlowNode) => void\n /** Called when mouse enters a node */\n onNodeMouseEnter?: (event: React.MouseEvent, node: FlowNode) => void\n /** Called when mouse leaves a node */\n onNodeMouseLeave?: (event: React.MouseEvent, node: FlowNode) => void\n /** Called when an edge is clicked */\n onEdgeClick?: (event: React.MouseEvent, edge: FlowEdge) => void\n /** S1: Custom frame node renderer */\n frameRenderer?: React.ComponentType<FrameNodeSlotProps>\n /** Hide frame nodes. Shorthand for `frameRenderer={() => null}`. Default: false */\n hideFrames?: boolean\n /** S2: Custom edge renderers by edge type slug */\n edgeRenderers?: Record<string, React.ComponentType<EdgeSlotProps>>\n /** S3: Wraps every dynamic node's rendered content */\n nodeWrapper?: React.ComponentType<NodeWrapperSlotProps>\n /** S4: Show controls (default: false) */\n controls?: boolean\n /** S4: Show minimap (default: false) */\n minimap?: boolean\n /** S4: Custom minimap node color function */\n minimapNodeColor?: (node: FlowNode) => string\n /** S4: Additional children rendered inside ReactFlow */\n children?: React.ReactNode\n /** S5: Global override for all dynamic nodes. `content` is the resolved rendering (custom renderer output or default). `props.defaultRender` contains the original template/field-based rendering. */\n renderNode?: (\n props: DynamicNodeSlotProps,\n content: React.ReactElement,\n ) => React.ReactElement | null\n /** S6: Called when viewport changes (pan/zoom) */\n onViewportChange?: (viewport: FlowViewport) => void\n /** S6: Default viewport (used when fitView is false) */\n defaultViewport?: FlowViewport\n /** S8: Focus on specific bounds (used for initial viewport fit). */\n bounds?: FlowBounds\n /** S8: Separate bounds for panning/zoom restriction. When set, overrides bounds-based translateExtent. Useful when fitBounds (content) differs from clampBounds (frame area). */\n clampBounds?: FlowBounds\n /** S8: Padding for focus bounds (default: 0.1) */\n focusPadding?: number\n /** S8: Animate focus transition (true=300ms, number=custom ms, false=instant) */\n focusAnimation?: boolean | number\n /** S8: Focus mode — \"contain\" fits entire bounds (may have margins), \"cover\" fills viewport (may crop). Default: \"contain\" */\n focusMode?: 'contain' | 'cover'\n /** Re-fit viewport on container resize (default: true when bounds is set) */\n responsiveFit?: boolean\n /** Override translateExtent directly. When set, overrides the automatic bounds-based panning restriction. */\n translateExtent?: [[number, number], [number, number]]\n /** Minimum zoom level. When clampBounds is set, automatically enforced as cover zoom (user cannot zoom out beyond the frame). */\n minZoom?: number\n /** Maximum zoom level */\n maxZoom?: number\n}\n\nconst NullFrameRenderer = () => null\n\nexport function FlowRenderer({\n data,\n className,\n style,\n nodeRenderers,\n nodeTypeDefs,\n edgeTypeDefs,\n background = false,\n interactive = false,\n fitView = true,\n onNodeClick,\n onNodeDoubleClick,\n onNodeContextMenu,\n onNodeMouseEnter,\n onNodeMouseLeave,\n onEdgeClick,\n frameRenderer,\n hideFrames = false,\n edgeRenderers,\n nodeWrapper,\n controls,\n minimap,\n minimapNodeColor,\n children,\n renderNode,\n onViewportChange,\n defaultViewport: defaultViewportProp,\n bounds,\n clampBounds,\n focusPadding,\n focusAnimation,\n focusMode = 'contain',\n responsiveFit,\n translateExtent: translateExtentProp,\n minZoom: minZoomProp,\n maxZoom: maxZoomProp,\n}: FlowRendererProps) {\n const resolvedFrameRenderer = hideFrames ? NullFrameRenderer : frameRenderer\n\n const nodeTypeDefsMap = React.useMemo(() => {\n if (!nodeTypeDefs?.length) return undefined\n return new Map(nodeTypeDefs.map((d) => [d.slug, d]))\n }, [nodeTypeDefs])\n\n const edgeTypeDefsMap = React.useMemo(() => {\n if (!edgeTypeDefs?.length) return undefined\n return new Map(edgeTypeDefs.map((d) => [d.slug, d]))\n }, [edgeTypeDefs])\n\n const nodeTypes = React.useMemo(\n () =>\n createNodeTypes(\n nodeRenderers,\n nodeTypeDefsMap,\n resolvedFrameRenderer,\n nodeWrapper,\n renderNode,\n ),\n [nodeRenderers, nodeTypeDefsMap, resolvedFrameRenderer, nodeWrapper, renderNode],\n )\n\n // S2: Custom edge types\n const customEdgeTypes = React.useMemo(\n () => createEdgeTypes(edgeRenderers, edgeTypeDefsMap),\n [edgeRenderers, edgeTypeDefsMap],\n )\n\n // Merge all customCSS from node type definitions, sanitized and scoped per slug\n const mergedCSS = React.useMemo(() => {\n if (!nodeTypeDefs?.length) return ''\n return nodeTypeDefs\n .filter((d) => d.customCSS)\n .map((d) => sanitizeCSS(d.customCSS!, `flow-node--${d.slug}`))\n .join('\\n')\n }, [nodeTypeDefs])\n\n const styledEdges = React.useMemo(() => {\n let edges = applyEdgeStyles(data?.edges ?? [], edgeTypeDefsMap)\n // When custom edge renderers exist, set edge type to slug for matching\n if (edgeRenderers) {\n edges = edges.map((edge) => {\n const slug = (edge as unknown as FlowEdge).edgeTypeSlug\n if (slug && edgeRenderers[slug]) {\n return { ...edge, type: slug }\n }\n return edge\n })\n }\n return edges\n }, [data?.edges, edgeTypeDefsMap, edgeRenderers])\n\n // Panning restriction: explicit prop > clampBounds (no padding, hard boundary) > bounds (with padding)\n const translateExtent = React.useMemo(() => {\n if (translateExtentProp) return translateExtentProp\n const es = clampBounds ?? bounds\n if (!es) return undefined\n const ep = clampBounds ? 0 : (focusPadding ?? 0.1)\n return [\n [es.x - ep * es.width, es.y - ep * es.height],\n [es.x + es.width * (1 + ep), es.y + es.height * (1 + ep)],\n ] as [[number, number], [number, number]]\n }, [translateExtentProp, clampBounds, bounds, focusPadding])\n\n // Defer translateExtent until FocusHandler has set the initial viewport.\n // d3-zoom's transform() applies translateExtent clamping internally, which\n // causes asymmetric shift when content is offset within frame. By deferring,\n // the initial setViewport runs unclamped, then extent is applied for panning.\n const boundsKey = bounds\n ? `${bounds.x},${bounds.y},${bounds.width},${bounds.height}`\n : ''\n const extentReadyRef = React.useRef(false)\n const expandedExtentRef = React.useRef<\n [[number, number], [number, number]] | undefined\n >(undefined)\n const prevBoundsKeyRef = React.useRef(boundsKey)\n if (prevBoundsKeyRef.current !== boundsKey) {\n prevBoundsKeyRef.current = boundsKey\n extentReadyRef.current = false\n expandedExtentRef.current = undefined\n }\n const [, rerender] = React.useReducer((x: number) => x + 1, 0)\n const handleInitialFit = React.useCallback(\n (expandedExtent?: [[number, number], [number, number]]) => {\n extentReadyRef.current = true\n expandedExtentRef.current = expandedExtent\n rerender()\n },\n [],\n )\n // Use expanded extent (includes viewport visible area) to prevent\n // d3-zoom from clamping on first interaction\n const activeExtent =\n !bounds || extentReadyRef.current\n ? (expandedExtentRef.current ?? translateExtent)\n : undefined\n\n if (!data) return null\n\n const resolvedDefaultViewport =\n defaultViewportProp ??\n (!fitView && data.viewport ? data.viewport : undefined)\n\n return (\n <ReactFlowProvider>\n <div\n className={className}\n style={{\n width: '100%',\n height: '100%',\n background: 'transparent',\n ...style,\n }}\n >\n <ReactFlow\n nodes={\n (data.nodes ?? []) as unknown as Parameters<\n typeof ReactFlow\n >[0]['nodes']\n }\n edges={styledEdges}\n nodeTypes={nodeTypes}\n edgeTypes={\n customEdgeTypes as Parameters<typeof ReactFlow>[0]['edgeTypes']\n }\n defaultViewport={resolvedDefaultViewport}\n fitView={bounds ? false : fitView}\n translateExtent={activeExtent}\n onNodeClick={\n onNodeClick as Parameters<typeof ReactFlow>[0]['onNodeClick']\n }\n onNodeDoubleClick={\n onNodeDoubleClick as Parameters<\n typeof ReactFlow\n >[0]['onNodeDoubleClick']\n }\n onNodeContextMenu={\n onNodeContextMenu as Parameters<\n typeof ReactFlow\n >[0]['onNodeContextMenu']\n }\n onNodeMouseEnter={\n onNodeMouseEnter as Parameters<\n typeof ReactFlow\n >[0]['onNodeMouseEnter']\n }\n onNodeMouseLeave={\n onNodeMouseLeave as Parameters<\n typeof ReactFlow\n >[0]['onNodeMouseLeave']\n }\n onEdgeClick={\n onEdgeClick as Parameters<typeof ReactFlow>[0]['onEdgeClick']\n }\n onMoveEnd={\n onViewportChange\n ? (((_: unknown, vp: { x: number; y: number; zoom: number }) => {\n onViewportChange(vp)\n }) as Parameters<typeof ReactFlow>[0]['onMoveEnd'])\n : undefined\n }\n nodesDraggable={interactive}\n nodesConnectable={false}\n elementsSelectable={\n interactive ||\n !!onNodeClick ||\n !!onNodeDoubleClick ||\n !!onEdgeClick\n }\n panOnDrag={interactive}\n zoomOnScroll={interactive}\n zoomOnPinch={interactive}\n zoomOnDoubleClick={false}\n minZoom={minZoomProp}\n maxZoom={maxZoomProp}\n proOptions={{ hideAttribution: true }}\n >\n {mergedCSS && (\n <style dangerouslySetInnerHTML={{ __html: mergedCSS }} />\n )}\n {background && <Background />}\n {controls && <Controls />}\n {minimap && (\n <MiniMap\n nodeColor={\n minimapNodeColor as Parameters<typeof MiniMap>[0]['nodeColor']\n }\n />\n )}\n {bounds && (\n <FocusHandler\n bounds={bounds}\n padding={focusPadding ?? 0.1}\n animation={focusAnimation ?? true}\n mode={focusMode}\n responsive={responsiveFit ?? true}\n extent={translateExtent}\n clampBounds={clampBounds}\n minZoomProp={minZoomProp}\n onInitialFit={handleInitialFit}\n />\n )}\n {children}\n </ReactFlow>\n </div>\n </ReactFlowProvider>\n )\n}\n","import React from 'react'\nimport type { NodeTypes, NodeProps } from '@xyflow/react'\nimport type {\n DynamicNodeData,\n DynamicNodeSlotProps,\n EdgeSlotProps,\n EdgeTypeDef,\n FrameNodeData,\n FrameNodeSlotProps,\n NodeTypeDef,\n NodeWrapperSlotProps,\n} from './types'\nimport {\n DefaultDynamicNode,\n EnhancedDynamicNode,\n DefaultFrameNode,\n} from './node-renderers'\nimport { Image } from '../Image'\nimport type { ImageData } from '../../utils/image'\n\n// ── Node types builder ──\n\nexport function createNodeTypes(\n nodeRenderers?: Record<string, React.ComponentType<DynamicNodeSlotProps>>,\n nodeTypeDefsMap?: Map<string, NodeTypeDef>,\n frameRenderer?: React.ComponentType<FrameNodeSlotProps>,\n nodeWrapper?: React.ComponentType<NodeWrapperSlotProps>,\n renderNode?: (\n props: DynamicNodeSlotProps,\n content: React.ReactElement,\n ) => React.ReactElement | null,\n): NodeTypes {\n const types: NodeTypes = {} as NodeTypes\n\n // Dynamic node type\n types.dynamic = ((props: NodeProps) => {\n const d = props.data as unknown as DynamicNodeData\n const typeDef = nodeTypeDefsMap?.get(d.nodeTypeSlug)\n const CustomRenderer = nodeRenderers?.[d.nodeTypeSlug]\n\n // Compute default rendering (template or field-based)\n const defaultRender: React.ReactElement = typeDef ? (\n <EnhancedDynamicNode\n data={d}\n typeDef={typeDef}\n width={props.width}\n height={props.height}\n />\n ) : (\n <DefaultDynamicNode {...props} />\n )\n\n const slotProps: DynamicNodeSlotProps = {\n id: props.id,\n nodeTypeSlug: d.nodeTypeSlug,\n label: d.label,\n fields: d.fields,\n nodeTypeDef: typeDef,\n selected: props.selected,\n width: props.width,\n height: props.height,\n defaultRender,\n }\n\n let content: React.ReactElement\n if (CustomRenderer) {\n content = <CustomRenderer {...slotProps} />\n } else if (d.nodeTypeSlug === 'image') { // matches BUILT_IN_NODE_TYPES slug\n // Built-in image renderer using SDK Image component (LQIP, srcSet, blur-up)\n const imageVal = d.fields?.image\n if (imageVal && typeof imageVal === 'object' && 'url' in imageVal) {\n content = (\n <Image\n image={imageVal as ImageData}\n width={props.width}\n fill\n priority\n objectFit=\"contain\"\n />\n )\n } else {\n content = defaultRender\n }\n } else {\n content = defaultRender\n }\n\n // S5: renderNode global callback\n if (renderNode) {\n const result = renderNode(slotProps, content)\n if (result !== null) content = result\n }\n\n // S3: nodeWrapper\n if (nodeWrapper) {\n const Wrapper = nodeWrapper\n content = (\n <Wrapper\n id={props.id}\n nodeTypeSlug={d.nodeTypeSlug}\n label={d.label}\n selected={props.selected}\n nodeTypeDef={typeDef}\n >\n {content}\n </Wrapper>\n )\n }\n\n return content\n }) as NodeTypes[string]\n\n // S1: Frame node type — custom or default\n types.frame = frameRenderer\n ? (((props: NodeProps) => {\n const d = props.data as unknown as FrameNodeData\n const Renderer = frameRenderer\n return (\n <Renderer\n id={props.id}\n label={d.label}\n color={d.color}\n padding={d.padding}\n borderStyle={d.borderStyle}\n opacity={d.opacity}\n width={props.width}\n height={props.height}\n />\n )\n }) as NodeTypes[string])\n : (DefaultFrameNode as NodeTypes[string])\n\n return types\n}\n\n// S2: Edge types builder\n\nexport function createEdgeTypes(\n edgeRenderers?: Record<string, React.ComponentType<EdgeSlotProps>>,\n edgeTypeDefsMap?: Map<string, EdgeTypeDef>,\n): Record<string, React.ComponentType<EdgeSlotProps>> | undefined {\n if (!edgeRenderers || Object.keys(edgeRenderers).length === 0)\n return undefined\n const types: Record<string, React.ComponentType<EdgeSlotProps>> = {}\n for (const [slug, Renderer] of Object.entries(edgeRenderers)) {\n types[slug] = ((props: Record<string, unknown>) => {\n const def = edgeTypeDefsMap?.get(slug)\n return (\n <Renderer\n id={props.id as string}\n edgeTypeSlug={slug}\n source={props.source as string}\n target={props.target as string}\n label={props.label as string | undefined}\n fields={\n (props.data as Record<string, unknown> | undefined)?.fields as\n | Record<string, unknown>\n | undefined\n }\n edgeTypeDef={def}\n style={props.style as React.CSSProperties | undefined}\n />\n )\n }) as unknown as React.ComponentType<EdgeSlotProps>\n }\n return types\n}\n","'use client'\n\nimport React, { useCallback, useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ImageData } from '../../utils/image'\nimport { getImageSrcSet, getImagePlaceholderStyle } from '../../utils/image'\n\nexport interface ImageProps {\n /** Payload image document */\n image: ImageData\n /** Display width in CSS pixels (for selecting optimal srcset size) */\n width?: number\n /** Device pixel ratio (default: 1) */\n dpr?: number\n /** Placeholder strategy (default: 'blur'; defaults to 'none' when imageRendering is 'pixelated' or 'crisp-edges') */\n placeholder?: 'blur' | 'color' | 'none'\n /** Container className */\n className?: string\n /** Container style */\n style?: CSSProperties\n /** Inner `<img>` className */\n imgClassName?: string\n /** Inner `<img>` style */\n imgStyle?: CSSProperties\n /** HTML sizes attribute */\n sizes?: string\n /** Loading strategy (default: 'lazy'; automatically 'eager' when priority is true) */\n loading?: 'lazy' | 'eager'\n /** Callback when image finishes loading */\n onLoad?: () => void\n /** Object-fit for the image (default: 'cover') */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** When true, loads eagerly with high fetch priority (for LCP images) */\n priority?: boolean\n /** When true, fills parent container (width/height: 100%, no aspect ratio) */\n fill?: boolean\n /** CSS image-rendering mode (e.g. 'pixelated' for pixel art) */\n imageRendering?: 'auto' | 'pixelated' | 'crisp-edges'\n}\n\n/**\n * Image component with blur-up / color placeholder support.\n *\n * Uses LQIP (Low Quality Image Placeholder) for a smooth blur-up effect,\n * falling back to palette color or no placeholder.\n */\nexport function Image({\n image,\n width,\n dpr = 1,\n placeholder: placeholderProp,\n className,\n style,\n imgClassName,\n imgStyle,\n sizes,\n loading: loadingProp,\n onLoad,\n objectFit = 'cover',\n priority = false,\n fill = false,\n imageRendering,\n}: ImageProps) {\n const [loaded, setLoaded] = useState(false)\n const firedRef = useRef(false)\n\n // Resolve defaults based on other props\n const isPixelRendering =\n imageRendering === 'pixelated' || imageRendering === 'crisp-edges'\n const placeholder = placeholderProp ?? (isPixelRendering ? 'none' : 'blur')\n const loading = priority ? 'eager' : (loadingProp ?? 'lazy')\n\n const aspectRatio =\n !fill && image.width && image.height\n ? `${image.width} / ${image.height}`\n : undefined\n\n const srcSet = getImageSrcSet(image)\n const src = image.url ?? undefined\n\n // Placeholder: LQIP overlay or color overlay (mutually exclusive)\n const hasLqip = placeholder === 'blur' && !!image.lqip\n const placeholderStyle = getImagePlaceholderStyle(image, {\n type: placeholder,\n })\n const placeholderColor =\n !hasLqip && 'backgroundColor' in placeholderStyle\n ? placeholderStyle.backgroundColor\n : undefined\n\n const fireLoad = useCallback(() => {\n if (firedRef.current) return\n firedRef.current = true\n setLoaded(true)\n onLoad?.()\n }, [onLoad])\n\n // Callback ref: detect SSR-cached images that are already loaded\n const imgRef = useCallback(\n (node: HTMLImageElement | null) => {\n if (node && node.complete && node.naturalWidth > 0) {\n fireLoad()\n }\n },\n [fireLoad],\n )\n\n // Container styles\n const containerStyle: CSSProperties = {\n position: 'relative',\n overflow: 'hidden',\n ...(fill ? { width: '100%', height: '100%' } : {}),\n ...(aspectRatio ? { aspectRatio } : {}),\n ...style,\n }\n\n // Shared overlay styles (LQIP and color)\n const overlayBase: CSSProperties = {\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n opacity: loaded ? 0 : 1,\n transition: 'opacity 0.3s ease',\n pointerEvents: 'none',\n }\n\n // Main image styles\n const mainImgStyle: CSSProperties = {\n display: 'block',\n width: '100%',\n height: '100%',\n objectFit,\n ...(imageRendering ? { imageRendering } : {}),\n opacity: loaded ? 1 : 0,\n transition: 'opacity 0.3s ease',\n ...imgStyle,\n }\n\n return (\n <div className={className} style={containerStyle}>\n {hasLqip && (\n <img\n aria-hidden\n alt=\"\"\n src={image.lqip!}\n style={{\n ...overlayBase,\n display: 'block',\n objectFit,\n filter: 'blur(20px)',\n transform: 'scale(1.1)',\n }}\n />\n )}\n {placeholderColor && (\n <div\n aria-hidden\n style={{\n ...overlayBase,\n backgroundColor: placeholderColor,\n }}\n />\n )}\n <img\n ref={imgRef}\n alt={image.alt ?? ''}\n src={src}\n srcSet={srcSet || undefined}\n sizes={sizes}\n width={width ? width * dpr : undefined}\n loading={loading}\n decoding=\"async\"\n fetchPriority={priority ? 'high' : undefined}\n onLoad={fireLoad}\n className={imgClassName}\n style={mainImgStyle}\n />\n </div>\n )\n}\n","/** Palette colors extracted from an image */\nexport interface ImagePalette {\n vibrant?: string | null\n muted?: string | null\n darkVibrant?: string | null\n darkMuted?: string | null\n lightVibrant?: string | null\n lightMuted?: string | null\n}\n\n/** Common image data shape from Payload CMS upload collections */\nexport interface ImageData {\n url?: string | null\n width?: number | null\n height?: number | null\n alt?: string | null\n lqip?: string | null\n palette?: ImagePalette | null\n sizes?: Record<\n string,\n | {\n url?: string | null\n width?: number | null\n height?: number | null\n }\n | undefined\n >\n}\n\n/** Pre-generated image size breakpoints (px) */\nexport const IMAGE_SIZES = [384, 768, 1536] as const\n\n/**\n * Returns the optimal image URL for a given display width.\n *\n * Picks the smallest pre-generated size whose width >= displayWidth × dpr.\n * Falls back to the original URL when no matching size exists.\n *\n * @param image - Payload image document\n * @param displayWidth - CSS pixel width the image will be displayed at\n * @param dpr - Device pixel ratio (default: 1)\n * @returns URL string, or empty string if no URL is available\n */\nexport function getImageUrl(\n image: ImageData,\n displayWidth: number,\n dpr: number = 1,\n): string {\n const target = displayWidth * dpr\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of IMAGE_SIZES) {\n if (size >= target) {\n const entry = sizes[String(size)]\n if (entry?.url) return entry.url\n }\n }\n }\n\n return image.url ?? ''\n}\n\n/**\n * Generates an HTML `srcset` attribute string from pre-generated sizes.\n *\n * Includes all available sizes plus the original image.\n * Example output: `\"url-384 384w, url-768 768w, url-1536 1536w, url-original 2000w\"`\n *\n * @param image - Payload image document\n * @returns srcset string, or empty string if no URLs are available\n */\nexport function getImageSrcSet(image: ImageData): string {\n const parts: string[] = []\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of IMAGE_SIZES) {\n const entry = sizes[String(size)]\n if (entry?.url && entry.width) {\n parts.push(`${entry.url} ${entry.width}w`)\n }\n }\n }\n\n if (image.url && image.width) {\n parts.push(`${image.url} ${image.width}w`)\n }\n\n return parts.join(', ')\n}\n\n/**\n * Returns the LQIP (Low Quality Image Placeholder) data URL for an image.\n *\n * @param image - Payload image document\n * @returns LQIP data URL string, or undefined if not available\n */\nexport function getImageLqip(image: ImageData): string | undefined {\n return image.lqip ?? undefined\n}\n\n/**\n * Returns the extracted color palette for an image.\n *\n * @param image - Payload image document\n * @returns ImagePalette object, or undefined if not available\n */\nexport function getImagePalette(image: ImageData): ImagePalette | undefined {\n return image.palette ?? undefined\n}\n\n/** Options for `getImagePlaceholderStyle` */\nexport interface ImagePlaceholderOptions {\n /** Placeholder strategy (default: 'blur') */\n type?: 'blur' | 'color' | 'none'\n /** Which palette color to use for 'color' strategy (default: 'muted') */\n paletteColor?: keyof ImagePalette\n}\n\n/**\n * Returns inline CSS styles for an image placeholder.\n *\n * - `blur`: uses LQIP as background, falls back to palette color, then empty\n * - `color`: uses palette color as background, falls back to empty\n * - `none`: always returns empty\n *\n * @param image - Payload image document\n * @param options - Placeholder options\n * @returns CSS style object compatible with React CSSProperties\n */\nexport function getImagePlaceholderStyle(\n image: ImageData,\n options?: ImagePlaceholderOptions,\n): Record<string, string> {\n const type = options?.type ?? 'blur'\n const paletteColor = options?.paletteColor ?? 'muted'\n\n if (type === 'none') return {}\n\n const color = image.palette?.[paletteColor]\n\n if (type === 'blur') {\n const lqip = image.lqip\n if (lqip) {\n return {\n backgroundImage: `url(${lqip})`,\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n }\n }\n // Cascade: fall back to color\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n }\n\n // type === 'color'\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n}\n","import { MarkerType, type Edge } from '@xyflow/react'\nimport type { FlowEdge, EdgeTypeDef } from './types'\n\nfunction toMarkerType(value: string): MarkerType | undefined {\n if (value === 'arrow') return MarkerType.Arrow\n if (value === 'arrowclosed') return MarkerType.ArrowClosed\n return undefined\n}\n\nconst EDGE_TYPE_MAP: Record<string, string> = {\n step: 'step',\n smoothstep: 'smoothstep',\n bezier: 'default',\n default: 'default',\n}\n\nexport function applyEdgeStyles(\n edges: FlowEdge[],\n edgeTypeDefsMap?: Map<string, EdgeTypeDef>,\n): Edge[] {\n // Note: FlowEdge ↔ Edge casts are safe while FlowEdge is a superset of @xyflow/react Edge.\n // If xyflow upgrades break this, replace with an explicit toXYFlowEdge() mapper.\n if (!edgeTypeDefsMap?.size) return edges as unknown as Edge[]\n\n return edges.map((edge) => {\n const slug = edge.edgeTypeSlug\n if (!slug) return edge as unknown as Edge\n\n const def = edgeTypeDefsMap.get(slug)\n if (!def) return edge as unknown as Edge\n\n const styled: Edge = { ...(edge as unknown as Edge) }\n\n // Edge type (line style) — canvas value takes precedence\n if (!styled.type && def.lineStyle) {\n styled.type = EDGE_TYPE_MAP[def.lineStyle] ?? 'default'\n }\n\n // Visual style — canvas style merged with def as fallback\n styled.style = {\n ...(def.color ? { stroke: def.color } : undefined),\n ...(def.strokeWidth ? { strokeWidth: def.strokeWidth } : undefined),\n ...edge.style,\n }\n\n // Animation — canvas value takes precedence\n if (styled.animated == null && def.animated) styled.animated = true\n\n // Markers — canvas value takes precedence over def\n if (!styled.markerStart) {\n const startType = toMarkerType(def.markerStart)\n if (startType) {\n styled.markerStart = {\n type: startType,\n ...(def.color ? { color: def.color } : undefined),\n }\n }\n }\n if (!styled.markerEnd) {\n const endType = toMarkerType(def.markerEnd)\n if (endType) {\n styled.markerEnd = {\n type: endType,\n ...(def.color ? { color: def.color } : undefined),\n }\n }\n }\n\n return styled\n })\n}\n","import React from 'react'\nimport { useReactFlow, useStoreApi } from '@xyflow/react'\nimport type { FlowBounds } from './types'\n\n// Match d3-zoom's translateExtent clamping so the viewport after resize\n// is identical to what the user sees after the first drag.\nfunction clampViewport(\n vp: { x: number; y: number; zoom: number },\n cw: number,\n ch: number,\n extent: [[number, number], [number, number]],\n): { x: number; y: number; zoom: number } {\n const left = -vp.x / vp.zoom\n const right = (cw - vp.x) / vp.zoom\n const top = -vp.y / vp.zoom\n const bottom = (ch - vp.y) / vp.zoom\n\n const dx0 = left - extent[0][0]\n const dx1 = right - extent[1][0]\n const dy0 = top - extent[0][1]\n const dy1 = bottom - extent[1][1]\n\n const cx =\n dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1)\n const cy =\n dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)\n\n if (cx === 0 && cy === 0) return vp\n return { x: vp.x + cx * vp.zoom, y: vp.y + cy * vp.zoom, zoom: vp.zoom }\n}\n\nexport function FocusHandler({\n bounds,\n padding,\n animation,\n mode,\n responsive,\n extent,\n clampBounds,\n minZoomProp,\n onInitialFit,\n}: {\n bounds: FlowBounds\n padding: number\n animation: boolean | number\n mode: 'contain' | 'cover'\n responsive: boolean\n extent?: [[number, number], [number, number]]\n /** When set, cover zoom of these bounds is enforced as minZoom via store API. */\n clampBounds?: FlowBounds\n /** User-specified minZoom prop, used with Math.max against coverZoom. */\n minZoomProp?: number\n /** Called after initial viewport is set with the expanded extent that fits the viewport. */\n onInitialFit?: (expandedExtent?: [[number, number], [number, number]]) => void\n}) {\n const { setViewport } = useReactFlow()\n const store = useStoreApi()\n const containerRef = React.useRef<HTMLDivElement>(null)\n const boundsKey = `${bounds.x},${bounds.y},${bounds.width},${bounds.height}`\n const boundsRef = React.useRef(bounds)\n boundsRef.current = bounds\n const [containerSize, setContainerSize] = React.useState({ w: 0, h: 0 })\n const prevBoundsKeyRef = React.useRef<string | null>(null)\n const prevSizeRef = React.useRef({ w: 0, h: 0 })\n\n // Track container size via ResizeObserver\n React.useEffect(() => {\n const el = containerRef.current\n if (!el) return\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (!entry) return\n const { width, height } = entry.contentRect\n setContainerSize({ w: width, h: height })\n })\n observer.observe(el)\n return () => observer.disconnect()\n }, [])\n\n React.useEffect(() => {\n if (containerSize.w === 0 || containerSize.h === 0) return\n\n const prevKey = prevBoundsKeyRef.current\n const prevSize = prevSizeRef.current\n prevBoundsKeyRef.current = boundsKey\n prevSizeRef.current = { w: containerSize.w, h: containerSize.h }\n\n // Determine trigger: bounds change vs resize-only\n const isBoundsChange = prevKey !== boundsKey\n const isResizeOnly =\n !isBoundsChange &&\n (prevSize.w !== containerSize.w || prevSize.h !== containerSize.h)\n const isInitial = prevKey === null\n\n // Skip resize-triggered re-fit if responsiveFit is disabled\n if (isResizeOnly && !responsive) return\n\n // Initial fit is always instant to prevent visual flash;\n // subsequent bounds changes and resizes respect the animation setting\n const duration =\n isInitial\n ? 0\n : isBoundsChange\n ? animation === true\n ? 300\n : typeof animation === 'number'\n ? animation\n : 0\n : 0\n\n const b = boundsRef.current\n const padX = padding * b.width\n const padY = padding * b.height\n const bw = b.width + padX * 2\n const bh = b.height + padY * 2\n\n if (bw === 0 || bh === 0) return\n\n // contain: fit inside viewport, cover: fill viewport (may crop)\n const zoomFn = mode === 'cover' ? Math.max : Math.min\n const zoom = zoomFn(containerSize.w / bw, containerSize.h / bh)\n // Center on clampBounds (frame) when available for symmetric frame margins;\n // fall back to bounds (content) center\n const centerTarget = clampBounds ?? b\n const cx = centerTarget.x + centerTarget.width / 2\n const cy = centerTarget.y + centerTarget.height / 2\n const x = containerSize.w / 2 - cx * zoom\n const y = containerSize.h / 2 - cy * zoom\n\n // Enforce minZoom: allow zooming back to the initial view level.\n // In contain mode, the initial zoom can be smaller than clampBounds cover zoom.\n if (clampBounds) {\n const coverZoom = Math.max(\n containerSize.w / clampBounds.width,\n containerSize.h / clampBounds.height,\n )\n store\n .getState()\n .setMinZoom(Math.max(Math.min(coverZoom, zoom), minZoomProp ?? 0))\n } else {\n store.getState().setMinZoom(minZoomProp ?? 0.5)\n }\n\n let vp = { x, y, zoom }\n\n if (isInitial || isBoundsChange) {\n // Initial fit or bounds change: no clampViewport.\n // translateExtent is deferred (not yet on ReactFlow) so d3-zoom\n // won't clamp this setViewport call.\n setViewport(vp, { duration: isInitial ? 0 : duration })\n\n // Compute expanded extent that includes the viewport's visible area.\n // Without this, d3-zoom would clamp on first interaction because\n // the visible area (in contain mode) can extend beyond clampBounds.\n if (extent) {\n const visW = containerSize.w / zoom\n const visH = containerSize.h / zoom\n onInitialFit?.([\n [Math.min(extent[0][0], cx - visW / 2), Math.min(extent[0][1], cy - visH / 2)],\n [Math.max(extent[1][0], cx + visW / 2), Math.max(extent[1][1], cy + visH / 2)],\n ])\n } else {\n onInitialFit?.()\n }\n } else {\n // Resize-only fits: apply clampViewport to match d3-zoom's behavior\n if (extent) {\n vp = clampViewport(vp, containerSize.w, containerSize.h, extent)\n }\n setViewport(vp, { duration })\n }\n }, [\n boundsKey,\n padding,\n animation,\n mode,\n responsive,\n containerSize.w,\n containerSize.h,\n extent,\n setViewport,\n clampBounds,\n minZoomProp,\n store,\n onInitialFit,\n ])\n\n // Measurement div — always rendered to track container size\n return (\n <div\n ref={containerRef}\n style={{\n position: 'absolute',\n inset: 0,\n pointerEvents: 'none',\n visibility: 'hidden',\n }}\n />\n )\n}\n","'use client'\n\nimport React, { useMemo, useEffect, useRef } from 'react'\nimport { useFlow, type SDKClient } from './useFlow'\nimport { getFrameData } from './utils'\nimport { FlowRenderer, type FlowRendererProps } from './FlowRenderer'\nimport type { FrameData } from './utils'\nimport { isFrameNode } from './types'\n\nexport interface FlowFrameProps\n extends Omit<\n FlowRendererProps,\n | 'data'\n | 'nodeTypeDefs'\n | 'edgeTypeDefs'\n | 'bounds'\n | 'clampBounds'\n | 'fitView'\n | 'hideFrames'\n | 'translateExtent'\n | 'defaultViewport'\n > {\n /** SDK client instance (Client or ServerClient) */\n client: SDKClient\n /** Flow slug (URL-friendly identifier) */\n slug?: string\n /** Flow document ID (UUID) */\n id?: string\n /** Frame node ID to render */\n frameId: string\n /** Content rendered while loading (default: null) */\n loading?: React.ReactNode\n /** Render function for error state (default: returns null) */\n error?: (err: Error) => React.ReactNode\n /**\n * Called when frame data is ready — escape hatch for raw data access.\n * Use `prefetchFlow({ client, slug })` for SSR.\n */\n onDataReady?: (frameData: FrameData, flow: Record<string, unknown>) => void\n}\n\n/**\n * Renders a single frame from a Flow document.\n *\n * Fetches the flow via `useFlow`, extracts the frame with `getFrameData`,\n * and passes the result to `FlowRenderer` with correct bounds wired.\n *\n * For SSR / prefetching use the existing `prefetchFlow({ client, slug })`.\n *\n * @example\n * ```tsx\n * import { FlowFrame } from '@01.software/sdk/ui/flow'\n *\n * export default function Home() {\n * return (\n * <div className=\"w-full h-screen\">\n * <FlowFrame client={client} slug=\"home\" frameId={FRAME_ID} interactive />\n * </div>\n * )\n * }\n * ```\n */\nexport function FlowFrame({\n client,\n slug,\n id,\n frameId,\n loading = null,\n error: renderError,\n onDataReady,\n ...rendererProps\n}: FlowFrameProps) {\n const { data, nodeTypeDefs, edgeTypeDefs, flow, isLoading, error } = useFlow({\n client,\n slug,\n id,\n })\n\n const frameData = useMemo(\n () => (data ? getFrameData(data, frameId) : undefined),\n [data, frameId],\n )\n\n // Stable ref so onDataReady doesn't need to be in effect deps.\n // Fires on every data update (including React Query background refetches).\n const onDataReadyRef = useRef<FlowFrameProps['onDataReady']>(onDataReady)\n onDataReadyRef.current = onDataReady\n\n useEffect(() => {\n if (frameData && flow) {\n onDataReadyRef.current?.(frameData, flow)\n }\n }, [frameData, flow])\n\n if (process.env.NODE_ENV !== 'production' && !slug && !id) {\n console.warn('[FlowFrame] Either \"slug\" or \"id\" must be provided.')\n }\n\n if (isLoading) return <>{loading}</>\n if (error) return renderError ? <>{renderError(error)}</> : null\n if (!frameData) {\n if (process.env.NODE_ENV !== 'production' && data) {\n const frames = data.nodes.filter(isFrameNode).map((n) => n.id)\n console.warn(\n `[FlowFrame] Frame \"${frameId}\" not found. Available frames: ${frames.join(', ') || '(none)'}`,\n )\n }\n return null\n }\n\n return (\n <FlowRenderer\n {...rendererProps}\n data={frameData.data}\n nodeTypeDefs={nodeTypeDefs}\n edgeTypeDefs={edgeTypeDefs}\n bounds={frameData.fitBounds}\n clampBounds={frameData.clampBounds}\n hideFrames\n />\n )\n}\n"],"mappings":"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","names":["_a","useMemo","useMemo","renderer","React","React","React","React","React","React","React","React","React","_a","React","useMemo","useRef","useMemo","useRef","_a","React"]}
|
package/dist/ui/form.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { F as Form } from '../payload-types-
|
|
2
|
+
import { F as Form } from '../payload-types-D8fN_vZR.cjs';
|
|
3
3
|
import { RichTextData } from './rich-text.cjs';
|
|
4
4
|
import '@payloadcms/richtext-lexical';
|
|
5
5
|
import '@payloadcms/richtext-lexical/lexical';
|
package/dist/ui/form.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { F as Form } from '../payload-types-
|
|
2
|
+
import { F as Form } from '../payload-types-D8fN_vZR.js';
|
|
3
3
|
import { RichTextData } from './rich-text.js';
|
|
4
4
|
import '@payloadcms/richtext-lexical';
|
|
5
5
|
import '@payloadcms/richtext-lexical/lexical';
|
package/dist/ui/video.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { CSSProperties } from 'react';
|
|
2
2
|
import { MuxPlayerProps, MuxPlayerRefAttributes } from '@mux/mux-player-react';
|
|
3
3
|
export { MuxPlayerRefAttributes as VideoPlayerRef } from '@mux/mux-player-react';
|
|
4
|
-
import { V as Video } from '../payload-types-
|
|
4
|
+
import { V as Video } from '../payload-types-D8fN_vZR.cjs';
|
|
5
5
|
export { e as VideoGifOptions, V as VideoThumbnailOptions, a as getVideoGif, c as getVideoMp4Url, d as getVideoStoryboard, b as getVideoStreamUrl, g as getVideoThumbnail } from '../video-DbLL8yuc.cjs';
|
|
6
6
|
|
|
7
7
|
interface VideoPlayerCSSProperties extends CSSProperties {
|
package/dist/ui/video.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { CSSProperties } from 'react';
|
|
2
2
|
import { MuxPlayerProps, MuxPlayerRefAttributes } from '@mux/mux-player-react';
|
|
3
3
|
export { MuxPlayerRefAttributes as VideoPlayerRef } from '@mux/mux-player-react';
|
|
4
|
-
import { V as Video } from '../payload-types-
|
|
4
|
+
import { V as Video } from '../payload-types-D8fN_vZR.js';
|
|
5
5
|
export { e as VideoGifOptions, V as VideoThumbnailOptions, a as getVideoGif, c as getVideoMp4Url, d as getVideoStoryboard, b as getVideoStreamUrl, g as getVideoThumbnail } from '../video-DbLL8yuc.js';
|
|
6
6
|
|
|
7
7
|
interface VideoPlayerCSSProperties extends CSSProperties {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as Collection } from './const-
|
|
2
|
-
import { C as Config } from './payload-types-
|
|
1
|
+
import { C as Collection } from './const-JbuUTzeh.js';
|
|
2
|
+
import { C as Config } from './payload-types-D8fN_vZR.js';
|
|
3
3
|
|
|
4
4
|
type CollectionType<T extends string> = T extends keyof Config['collections'] ? Config['collections'][T] : never;
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as Collection } from './const-
|
|
2
|
-
import { C as Config } from './payload-types-
|
|
1
|
+
import { C as Collection } from './const-C9I6r5Wa.cjs';
|
|
2
|
+
import { C as Config } from './payload-types-D8fN_vZR.cjs';
|
|
3
3
|
|
|
4
4
|
type CollectionType<T extends string> = T extends keyof Config['collections'] ? Config['collections'][T] : never;
|
|
5
5
|
|
package/dist/webhook.d.cts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { a as WebhookEvent, b as WebhookHandler, W as WebhookOperation, c as WebhookOptions, d as createTypedWebhookHandler, h as handleWebhook, i as isValidWebhookEvent } from './webhook-
|
|
2
|
-
import './const-
|
|
3
|
-
import './payload-types-
|
|
1
|
+
export { a as WebhookEvent, b as WebhookHandler, W as WebhookOperation, c as WebhookOptions, d as createTypedWebhookHandler, h as handleWebhook, i as isValidWebhookEvent } from './webhook-Dbx-pRib.cjs';
|
|
2
|
+
import './const-C9I6r5Wa.cjs';
|
|
3
|
+
import './payload-types-D8fN_vZR.cjs';
|
package/dist/webhook.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { a as WebhookEvent, b as WebhookHandler, W as WebhookOperation, c as WebhookOptions, d as createTypedWebhookHandler, h as handleWebhook, i as isValidWebhookEvent } from './webhook-
|
|
2
|
-
import './const-
|
|
3
|
-
import './payload-types-
|
|
1
|
+
export { a as WebhookEvent, b as WebhookHandler, W as WebhookOperation, c as WebhookOptions, d as createTypedWebhookHandler, h as handleWebhook, i as isValidWebhookEvent } from './webhook-BkwMrrL1.js';
|
|
2
|
+
import './const-JbuUTzeh.js';
|
|
3
|
+
import './payload-types-D8fN_vZR.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@01.software/sdk",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "01.software SDK",
|
|
5
5
|
"author": "<office@01.works>",
|
|
6
6
|
"keywords": [],
|
|
@@ -148,15 +148,17 @@
|
|
|
148
148
|
"shadcn": "^3.6.3",
|
|
149
149
|
"tsup": "^8.3.7",
|
|
150
150
|
"vitest": "^3.2.3",
|
|
151
|
-
"@repo/
|
|
152
|
-
"@repo/
|
|
151
|
+
"@repo/eslint-config": "0.0.0",
|
|
152
|
+
"@repo/typescript-config": "0.0.0"
|
|
153
153
|
},
|
|
154
154
|
"dependencies": {
|
|
155
155
|
"@payloadcms/richtext-lexical": ">=3.78.0",
|
|
156
156
|
"hast-util-to-jsx-runtime": "^2.3.6",
|
|
157
157
|
"jose": "^6.1.3",
|
|
158
158
|
"payload": ">=3.78.0",
|
|
159
|
+
"postcss": "^8.4.35",
|
|
159
160
|
"qs-esm": "^7.0.2",
|
|
161
|
+
"quickjs-emscripten": "0.29.2",
|
|
160
162
|
"shiki": "^4.0.1",
|
|
161
163
|
"sucrase": "^3.35.1"
|
|
162
164
|
},
|