@particle-academy/fancy-flow 0.35.0 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/FlowViewer-C4QAVgWv.d.ts +62 -0
  2. package/dist/FlowViewer-nLqo7s2E.d.cts +62 -0
  3. package/dist/{chunk-N5ICD2WZ.js → chunk-3BKU4SQZ.js} +3 -3
  4. package/dist/{chunk-N5ICD2WZ.js.map → chunk-3BKU4SQZ.js.map} +1 -1
  5. package/dist/chunk-5UCWY7G3.js +593 -0
  6. package/dist/chunk-5UCWY7G3.js.map +1 -0
  7. package/dist/{chunk-EBE3FEAJ.js → chunk-A6RFLGWV.js} +4 -4
  8. package/dist/{chunk-EBE3FEAJ.js.map → chunk-A6RFLGWV.js.map} +1 -1
  9. package/dist/{chunk-Q6IPK64P.js → chunk-PVROYW7C.js} +32 -5
  10. package/dist/chunk-PVROYW7C.js.map +1 -0
  11. package/dist/{chunk-FKOXQP76.js → chunk-QZTGV3ZL.js} +3 -3
  12. package/dist/{chunk-FKOXQP76.js.map → chunk-QZTGV3ZL.js.map} +1 -1
  13. package/dist/{chunk-THU5LW22.js → chunk-UX65ML3J.js} +4 -4
  14. package/dist/{chunk-THU5LW22.js.map → chunk-UX65ML3J.js.map} +1 -1
  15. package/dist/{chunk-RE7T5GKQ.js → chunk-VLATLVGH.js} +3 -3
  16. package/dist/{chunk-RE7T5GKQ.js.map → chunk-VLATLVGH.js.map} +1 -1
  17. package/dist/engine.cjs +10 -2
  18. package/dist/engine.cjs.map +1 -1
  19. package/dist/engine.d.cts +1 -1
  20. package/dist/engine.d.ts +1 -1
  21. package/dist/engine.js +5 -5
  22. package/dist/index.cjs +163 -4
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +2 -1
  25. package/dist/index.d.ts +2 -1
  26. package/dist/index.js +21 -473
  27. package/dist/index.js.map +1 -1
  28. package/dist/registry/index.d.cts +1 -1
  29. package/dist/registry/index.d.ts +1 -1
  30. package/dist/{registry-Ru5jIS5H.d.cts → registry-BADFn97n.d.cts} +41 -1
  31. package/dist/{registry-Df2-bTXZ.d.ts → registry-DYbFLEcW.d.ts} +41 -1
  32. package/dist/registry.cjs +31 -2
  33. package/dist/registry.cjs.map +1 -1
  34. package/dist/registry.js +3 -3
  35. package/dist/runtime.cjs +7 -1
  36. package/dist/runtime.cjs.map +1 -1
  37. package/dist/runtime.js +4 -4
  38. package/dist/schema.cjs +7 -1
  39. package/dist/schema.cjs.map +1 -1
  40. package/dist/schema.js +2 -2
  41. package/dist/screens.cjs +9834 -0
  42. package/dist/screens.cjs.map +1 -0
  43. package/dist/screens.css +563 -0
  44. package/dist/screens.css.map +1 -0
  45. package/dist/screens.d.cts +25 -0
  46. package/dist/screens.d.ts +25 -0
  47. package/dist/screens.js +21 -0
  48. package/dist/screens.js.map +1 -0
  49. package/dist/styles.css +103 -0
  50. package/dist/styles.css.map +1 -1
  51. package/dist/ux.cjs.map +1 -1
  52. package/dist/ux.js +1 -1
  53. package/package.json +196 -181
  54. package/dist/chunk-Q6IPK64P.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/nodes/NodeShell.tsx","../src/components/nodes/TriggerNode.tsx","../src/components/nodes/ActionNode.tsx","../src/components/nodes/DecisionNode.tsx","../src/components/nodes/OutputNode.tsx","../src/components/nodes/SubgraphNode.tsx","../src/components/nodes/index.ts","../src/components/FlowEditor/graph-ops.ts","../src/components/canvas/helper-lines.ts","../src/components/canvas/HelperLines.tsx","../src/components/canvas/FlowCanvas.tsx","../src/components/FlowViewer/FlowViewer.tsx"],"names":["jsx","memo","jsxs","reconnectEdge","cx","useMemo","index"],"mappings":"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","file":"chunk-5UCWY7G3.js","sourcesContent":["import { type ReactNode, memo } from \"react\";\nimport { Handle, Position, type NodeProps } from \"@xyflow/react\";\nimport type { FlowNode, NodeRunStatus, PortDescriptor } from \"../../types\";\n\nexport type NodeShellProps = {\n /** Required: the xyflow node this is rendering. */\n node: NodeProps<FlowNode>;\n /** Accent color for the title bar / status ring. */\n accent: string;\n /** Tag/label shown to the left of the title (e.g. \"TRIGGER\", \"ACTION\"). */\n tag: string;\n /** Optional icon glyph (single-character string is fine). */\n icon?: ReactNode;\n /** Whether to show input handles on the left. Defaults true. */\n showInputs?: boolean;\n /** Whether to show output handles on the right. Defaults true. */\n showOutputs?: boolean;\n /** Body content under the title bar. */\n children?: ReactNode;\n};\n\n/**\n * Shared chrome for every kit node — title bar, accent border, status ring,\n * port handles. Specific node kinds compose this with their body content.\n */\nfunction NodeShellInner({\n node,\n accent,\n tag,\n icon,\n showInputs = true,\n showOutputs = true,\n children,\n}: NodeShellProps) {\n const data = node.data;\n const status: NodeRunStatus = data.status ?? \"idle\";\n const inputs = data.inputs ?? defaultInputs(showInputs);\n const outputs = data.outputs ?? defaultOutputs(showOutputs);\n\n return (\n <div\n className={[\"ff-node\", `ff-node--status-${status}`, node.selected ? \"ff-node--selected\" : \"\"].filter(Boolean).join(\" \")}\n style={{ borderColor: node.selected ? accent : undefined }}\n >\n <header className=\"ff-node__header\" style={{ background: accent }}>\n <span className=\"ff-node__icon\" aria-hidden>{icon ?? null}</span>\n <span className=\"ff-node__tag\">{tag}</span>\n <span className=\"ff-node__label\">{data.label}</span>\n {status !== \"idle\" && <StatusDot status={status} />}\n </header>\n\n {data.description && <p className=\"ff-node__desc\">{data.description}</p>}\n {children && <div className=\"ff-node__body\">{children}</div>}\n {data.statusText && <p className=\"ff-node__status-text\">{data.statusText}</p>}\n\n {inputs.map((p, i) => (\n <Handle\n key={p.id}\n type=\"target\"\n position={Position.Left}\n id={p.id}\n style={portStyle(i, inputs.length)}\n title={p.label ?? p.id}\n />\n ))}\n {outputs.map((p, i) => (\n <Handle\n key={p.id}\n type=\"source\"\n position={Position.Right}\n id={p.id}\n style={portStyle(i, outputs.length)}\n title={p.label ?? p.id}\n />\n ))}\n </div>\n );\n}\n\nexport const NodeShell = memo(NodeShellInner);\n\nfunction defaultInputs(show: boolean): PortDescriptor[] {\n return show ? [{ id: \"in\" }] : [];\n}\nfunction defaultOutputs(show: boolean): PortDescriptor[] {\n return show ? [{ id: \"out\" }] : [];\n}\n\nfunction portStyle(i: number, total: number): React.CSSProperties {\n if (total <= 1) return {};\n const slot = (100 / (total + 1)) * (i + 1);\n return { top: `${slot}%` };\n}\n\nfunction StatusDot({ status }: { status: NodeRunStatus }) {\n return <span className={`ff-node__dot ff-node__dot--${status}`} aria-label={`status ${status}`} />;\n}\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\n/** Entry-point node — outputs only, no inputs. */\nfunction TriggerNodeInner(props: NodeProps<FlowNode>) {\n return <NodeShell node={props} accent=\"#10b981\" tag=\"TRIGGER\" icon=\"⚡\" showInputs={false} />;\n}\nexport const TriggerNode = memo(TriggerNodeInner);\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\n/** General-purpose work node — inputs and outputs. */\nfunction ActionNodeInner(props: NodeProps<FlowNode>) {\n return <NodeShell node={props} accent=\"#3b82f6\" tag=\"ACTION\" icon=\"▸\" />;\n}\nexport const ActionNode = memo(ActionNodeInner);\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode, PortDescriptor } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\nconst DEFAULT_BRANCHES: PortDescriptor[] = [\n { id: \"true\", label: \"true\" },\n { id: \"false\", label: \"false\" },\n];\n\n/** Branching node — multiple typed outputs, one input. */\nfunction DecisionNodeInner(props: NodeProps<FlowNode>) {\n // If the host hasn't customised outputs, default to a true/false split.\n if (!props.data.outputs) {\n props = { ...props, data: { ...props.data, outputs: DEFAULT_BRANCHES } };\n }\n return <NodeShell node={props} accent=\"#f59e0b\" tag=\"DECISION\" icon=\"◇\" />;\n}\nexport const DecisionNode = memo(DecisionNodeInner);\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\n/** Terminal node — receives the workflow's final result; no outputs. */\nfunction OutputNodeInner(props: NodeProps<FlowNode>) {\n return <NodeShell node={props} accent=\"#a855f7\" tag=\"OUTPUT\" icon=\"●\" showOutputs={false} />;\n}\nexport const OutputNode = memo(OutputNodeInner);\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode, SubgraphNodeData } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\n/**\n * SubgraphNode — collapses a group of nodes behind a single facade with\n * inputs and outputs that map to the inner graph's boundary ports. The\n * runtime treats it like an action node: when running, it dispatches to\n * the registered \"subgraph\" executor (host decides expand vs inline).\n *\n * v0.1 just renders the facade. Expand/collapse interactions and inner-\n * graph editing are deferred — host apps can implement those by toggling\n * `data.collapsed` and rendering a nested <FlowCanvas> when expanded.\n */\nfunction SubgraphNodeInner(props: NodeProps<FlowNode>) {\n const data = props.data as SubgraphNodeData;\n const childCount = data.childIds?.length ?? 0;\n return (\n <NodeShell node={props} accent=\"#0ea5e9\" tag=\"SUBGRAPH\" icon=\"❐\">\n <div className=\"ff-subgraph__meta\">\n <span>{childCount} node{childCount === 1 ? \"\" : \"s\"}</span>\n <span>{data.collapsed === false ? \"expanded\" : \"collapsed\"}</span>\n </div>\n </NodeShell>\n );\n}\nexport const SubgraphNode = memo(SubgraphNodeInner);\n","import type { NodeTypes } from \"@xyflow/react\";\nimport { TriggerNode } from \"./TriggerNode\";\nimport { ActionNode } from \"./ActionNode\";\nimport { DecisionNode } from \"./DecisionNode\";\nimport { OutputNode } from \"./OutputNode\";\nimport { NoteNode } from \"./NoteNode\";\nimport { SubgraphNode } from \"./SubgraphNode\";\n\nexport { TriggerNode, ActionNode, DecisionNode, OutputNode, NoteNode, SubgraphNode };\nexport { LaneNode } from \"./LaneNode\";\nexport { NodeShell, type NodeShellProps } from \"./NodeShell\";\n\n/**\n * Default xyflow `nodeTypes` map covering the kit. Spread into your own:\n *\n * <FlowCanvas nodeTypes={{ ...defaultNodeTypes, custom: MyNode }} ... />\n */\nexport const defaultNodeTypes: NodeTypes = {\n trigger: TriggerNode,\n action: ActionNode,\n decision: DecisionNode,\n output: OutputNode,\n note: NoteNode,\n subgraph: SubgraphNode,\n};\n","import { reconnectEdge as xyReconnectEdge, type Connection, type Edge } from \"@xyflow/react\";\nimport type { FlowGraph, FlowNode } from \"../../types\";\n\n/**\n * Remove nodes AND every edge attached to them.\n *\n * Deleting a node without pruning its edges leaves danglers that point at\n * nothing — they survive a round-trip through the schema and blow up the\n * runner, so the two always move together.\n */\nexport function removeNodes(graph: FlowGraph, ids: string[]): FlowGraph {\n if (ids.length === 0) return graph;\n const doomed = new Set(ids);\n\n return {\n nodes: graph.nodes.filter((n) => !doomed.has(n.id)),\n edges: graph.edges.filter((e) => !doomed.has(e.source) && !doomed.has(e.target)),\n };\n}\n\n/** Remove edges by id, leaving nodes untouched. */\nexport function removeEdges(edges: Edge[], ids: string[]): Edge[] {\n if (ids.length === 0) return edges;\n const doomed = new Set(ids);\n\n return edges.filter((e) => !doomed.has(e.id));\n}\n\n/**\n * Set (or clear) an edge's label.\n *\n * An empty/whitespace label is removed rather than stored as `\"\"` — xyflow\n * renders an empty label as an empty chip on the wire, and a blank key would\n * survive export into the workflow schema.\n */\nexport function setEdgeLabel(edges: Edge[], id: string, label: string | undefined): Edge[] {\n const next = label?.trim();\n return edges.map((e) => {\n if (e.id !== id) return e;\n if (!next) {\n const { label: _drop, ...rest } = e;\n return rest as Edge;\n }\n return { ...e, label: next };\n });\n}\n\n/** Copy a node with a fresh id, offset so it doesn't sit exactly on top. */\nexport function duplicateNode(node: FlowNode, id: string, offset = 40): FlowNode {\n return {\n ...node,\n id,\n position: { x: node.position.x + offset, y: node.position.y + offset },\n // Deep copy so the clone's config edits don't mutate the original.\n data: JSON.parse(JSON.stringify(node.data ?? {})),\n } as FlowNode;\n}\n\n/**\n * Clone a set of nodes AND the edges internal to that set, remapping every id.\n * This is the piece `duplicateNode` lacks: a copy/paste (or duplicate-selection)\n * that preserves the wiring *between* the copied nodes. Edges with an endpoint\n * outside the set are dropped (they'd dangle). A `parentId` pointing inside the\n * set is remapped; one pointing outside is detached.\n */\nexport function cloneSubgraph(\n nodes: FlowNode[],\n edges: Edge[],\n opts: { makeId: () => string; offset?: number },\n): { nodes: FlowNode[]; edges: Edge[]; idMap: Map<string, string> } {\n const offset = opts.offset ?? 40;\n const idMap = new Map<string, string>();\n for (const n of nodes) idMap.set(n.id, opts.makeId());\n\n const clonedNodes = nodes.map((n) => {\n const cloned = duplicateNode(n, idMap.get(n.id)!, offset) as any;\n const parentId = (n as any).parentId;\n if (parentId && idMap.has(parentId)) cloned.parentId = idMap.get(parentId);\n else if (parentId) delete cloned.parentId;\n return cloned as FlowNode;\n });\n\n const clonedEdges = edges\n .filter((e) => idMap.has(e.source) && idMap.has(e.target))\n .map((e) => ({ ...e, id: opts.makeId(), source: idMap.get(e.source)!, target: idMap.get(e.target)! }));\n\n return { nodes: clonedNodes, edges: clonedEdges, idMap };\n}\n\n/**\n * Rewire one edge's endpoint(s) — wraps xyflow's `reconnectEdge`. Keeps the\n * edge's id (`shouldReplaceId: false`) so its label and identity survive the\n * rewire instead of being regenerated from the new endpoints.\n */\nexport function reconnectEdge(edges: Edge[], oldEdge: Edge, newConnection: Connection): Edge[] {\n return xyReconnectEdge(oldEdge, newConnection, edges, { shouldReplaceId: false });\n}\n\nexport type AlignEdge = \"left\" | \"hcenter\" | \"right\" | \"top\" | \"vcenter\" | \"bottom\";\n\nconst nodeW = (n: FlowNode): number => (n as any).width ?? (n as any).measured?.width ?? 0;\nconst nodeH = (n: FlowNode): number => (n as any).height ?? (n as any).measured?.height ?? 0;\n\n/** Align a selection to a shared edge/center of its bounding box. */\nexport function alignNodes(nodes: FlowNode[], edge: AlignEdge): FlowNode[] {\n if (nodes.length < 2) return nodes;\n const minL = Math.min(...nodes.map((n) => n.position.x));\n const maxR = Math.max(...nodes.map((n) => n.position.x + nodeW(n)));\n const minT = Math.min(...nodes.map((n) => n.position.y));\n const maxB = Math.max(...nodes.map((n) => n.position.y + nodeH(n)));\n const cx = (minL + maxR) / 2;\n const cy = (minT + maxB) / 2;\n return nodes.map((n) => {\n let { x, y } = n.position;\n if (edge === \"left\") x = minL;\n else if (edge === \"right\") x = maxR - nodeW(n);\n else if (edge === \"hcenter\") x = cx - nodeW(n) / 2;\n else if (edge === \"top\") y = minT;\n else if (edge === \"bottom\") y = maxB - nodeH(n);\n else if (edge === \"vcenter\") y = cy - nodeH(n) / 2;\n return { ...n, position: { x, y } };\n });\n}\n\n/**\n * Order nodes so every parent precedes its children — xyflow misrenders (and\n * warns) when a child appears before its `parentId` in the array. Stable\n * otherwise. Apply at the render boundary once grouping is in play.\n */\nexport function sortNodesParentFirst<T extends { id: string; parentId?: string }>(nodes: T[]): T[] {\n const byId = new Map(nodes.map((n) => [n.id, n] as const));\n const seen = new Set<string>();\n const out: T[] = [];\n const visit = (n: T) => {\n if (seen.has(n.id)) return;\n const pid = (n as any).parentId as string | undefined;\n if (pid && byId.has(pid) && !seen.has(pid)) visit(byId.get(pid)!);\n seen.add(n.id);\n out.push(n);\n };\n for (const n of nodes) visit(n);\n return out;\n}\n\n/** Absolute position of a node, accounting for one level of parent nesting. */\nfunction absolutePosition(node: FlowNode, nodes: FlowNode[]): { x: number; y: number } {\n const pid = (node as any).parentId as string | undefined;\n if (!pid) return node.position;\n const parent = nodes.find((n) => n.id === pid);\n return parent ? { x: node.position.x + parent.position.x, y: node.position.y + parent.position.y } : node.position;\n}\n\n/**\n * Put a node inside a lane/container: set `parentId` + `extent:'parent'` and\n * convert its position to be relative to the lane. Idempotent-safe; a no-op if\n * either id is missing or they're the same node.\n */\nexport function assignToLane(nodes: FlowNode[], nodeId: string, laneId: string): FlowNode[] {\n if (nodeId === laneId) return nodes;\n const node = nodes.find((n) => n.id === nodeId);\n const lane = nodes.find((n) => n.id === laneId);\n if (!node || !lane) return nodes;\n const abs = absolutePosition(node, nodes);\n const laneAbs = absolutePosition(lane, nodes);\n const rel = { x: abs.x - laneAbs.x, y: abs.y - laneAbs.y };\n return nodes.map((n) => (n.id === nodeId ? ({ ...n, parentId: laneId, extent: \"parent\", position: rel } as FlowNode) : n));\n}\n\n/** Take a node out of its lane: drop `parentId`/`extent`, restore absolute position. */\nexport function removeFromLane(nodes: FlowNode[], nodeId: string): FlowNode[] {\n const node = nodes.find((n) => n.id === nodeId);\n if (!node || !(node as any).parentId) return nodes;\n const abs = absolutePosition(node, nodes);\n return nodes.map((n) => {\n if (n.id !== nodeId) return n;\n const { parentId: _p, extent: _e, ...rest } = n as any;\n return { ...rest, position: abs } as FlowNode;\n });\n}\n\n/**\n * Stack lanes into contiguous rows (horizontal) or columns (vertical) — the\n * \"fixed rows/columns\" behavior. `isLane` picks which nodes are lanes; they're\n * ordered by their current cross-axis position and repacked from the first\n * lane's origin. Each lane keeps its own size (independently resizable).\n */\nexport function stackLanes(\n nodes: FlowNode[],\n isLane: (n: FlowNode) => boolean,\n opts: { orientation?: \"horizontal\" | \"vertical\"; gap?: number } = {},\n): FlowNode[] {\n const orientation = opts.orientation ?? \"horizontal\";\n const gap = opts.gap ?? 12;\n const vertical = orientation === \"vertical\";\n const lanes = nodes.filter(isLane).sort((a, b) => (vertical ? a.position.x - b.position.x : a.position.y - b.position.y));\n if (lanes.length === 0) return nodes;\n const originX = lanes[0].position.x;\n const originY = lanes[0].position.y;\n const moves = new Map<string, { x: number; y: number }>();\n let cursor = vertical ? originX : originY;\n for (const lane of lanes) {\n moves.set(lane.id, vertical ? { x: cursor, y: originY } : { x: originX, y: cursor });\n cursor += (vertical ? ((lane as any).width ?? 320) : ((lane as any).height ?? 160)) + gap;\n }\n return nodes.map((n) => (moves.has(n.id) ? { ...n, position: moves.get(n.id)! } : n));\n}\n\n/** Evenly distribute a selection's gaps along an axis (needs 3+ nodes). */\nexport function distributeNodes(nodes: FlowNode[], axis: \"h\" | \"v\"): FlowNode[] {\n if (nodes.length < 3) return nodes;\n const size = (n: FlowNode) => (axis === \"h\" ? nodeW(n) : nodeH(n));\n const coord = (n: FlowNode) => (axis === \"h\" ? n.position.x : n.position.y);\n const sorted = [...nodes].sort((a, b) => coord(a) - coord(b));\n const start = coord(sorted[0]);\n const last = sorted[sorted.length - 1];\n const end = coord(last) + size(last);\n const totalSize = sorted.reduce((s, n) => s + size(n), 0);\n const gap = (end - start - totalSize) / (sorted.length - 1);\n const posById = new Map<string, number>();\n let cursor = start;\n for (const n of sorted) {\n posById.set(n.id, cursor);\n cursor += size(n) + gap;\n }\n return nodes.map((n) => {\n const p = posById.get(n.id)!;\n return { ...n, position: axis === \"h\" ? { ...n.position, x: p } : { ...n.position, y: p } };\n });\n}\n","import type { FlowNode } from \"../../types\";\n\nexport type HelperLineChange = { id: string; position?: { x: number; y: number } };\n\nexport type HelperLinesResult = {\n /** Y of a horizontal guide line (flow coords), if the drag aligns on Y. */\n horizontal?: number;\n /** X of a vertical guide line (flow coords), if the drag aligns on X. */\n vertical?: number;\n /** The snapped position to apply to the dragged node. */\n snapPosition: { x?: number; y?: number };\n};\n\nconst w = (n: FlowNode): number => (n as any).width ?? (n as any).measured?.width ?? 0;\nconst h = (n: FlowNode): number => (n as any).height ?? (n as any).measured?.height ?? 0;\n\n/**\n * Compute alignment guide lines (and a snapped position) for a node being\n * dragged to `change.position`, against the other nodes. Standard \"helper\n * lines\" algorithm: match the dragged node's left/right/top/bottom edges to any\n * other node's edges within `distance`, snapping to the nearest. Pure + testable.\n */\nexport function getHelperLines(change: HelperLineChange, nodes: FlowNode[], distance = 6): HelperLinesResult {\n const result: HelperLinesResult = { snapPosition: { x: undefined, y: undefined } };\n const a = nodes.find((n) => n.id === change.id);\n if (!a || !change.position) return result;\n\n const A = {\n left: change.position.x,\n right: change.position.x + w(a),\n top: change.position.y,\n bottom: change.position.y + h(a),\n width: w(a),\n height: h(a),\n };\n let vDist = distance;\n let hDist = distance;\n\n for (const b of nodes) {\n if (b.id === a.id) continue;\n const B = { left: b.position.x, right: b.position.x + w(b), top: b.position.y, bottom: b.position.y + h(b) };\n\n // Vertical guides (X alignment).\n const ll = Math.abs(A.left - B.left);\n if (ll < vDist) { result.snapPosition.x = B.left; result.vertical = B.left; vDist = ll; }\n const rr = Math.abs(A.right - B.right);\n if (rr < vDist) { result.snapPosition.x = B.right - A.width; result.vertical = B.right; vDist = rr; }\n const lr = Math.abs(A.left - B.right);\n if (lr < vDist) { result.snapPosition.x = B.right; result.vertical = B.right; vDist = lr; }\n const rl = Math.abs(A.right - B.left);\n if (rl < vDist) { result.snapPosition.x = B.left - A.width; result.vertical = B.left; vDist = rl; }\n\n // Horizontal guides (Y alignment).\n const tt = Math.abs(A.top - B.top);\n if (tt < hDist) { result.snapPosition.y = B.top; result.horizontal = B.top; hDist = tt; }\n const bb = Math.abs(A.bottom - B.bottom);\n if (bb < hDist) { result.snapPosition.y = B.bottom - A.height; result.horizontal = B.bottom; hDist = bb; }\n const tb = Math.abs(A.top - B.bottom);\n if (tb < hDist) { result.snapPosition.y = B.bottom; result.horizontal = B.bottom; hDist = tb; }\n const bt = Math.abs(A.bottom - B.top);\n if (bt < hDist) { result.snapPosition.y = B.top - A.height; result.horizontal = B.top; hDist = bt; }\n }\n\n return result;\n}\n","import { ViewportPortal } from \"@xyflow/react\";\n\n/**\n * HelperLines — alignment guides drawn during a drag. Rendered in flow\n * coordinate space (ViewportPortal), so the lines track pan/zoom. Positions come\n * from `getHelperLines`.\n */\nexport function HelperLines({ horizontal, vertical }: { horizontal?: number; vertical?: number }) {\n if (horizontal === undefined && vertical === undefined) return null;\n return (\n <ViewportPortal>\n {vertical !== undefined && (\n <div\n className=\"ff-helper-line\"\n style={{ position: \"absolute\", transform: `translateX(${vertical}px)`, top: -5000, height: 10000, width: 1, pointerEvents: \"none\" }}\n />\n )}\n {horizontal !== undefined && (\n <div\n className=\"ff-helper-line\"\n style={{ position: \"absolute\", transform: `translateY(${horizontal}px)`, left: -5000, width: 10000, height: 1, pointerEvents: \"none\" }}\n />\n )}\n </ViewportPortal>\n );\n}\n","import {\n type CSSProperties,\n type ReactNode,\n type WheelEvent as ReactWheelEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n ReactFlow,\n Background,\n BackgroundVariant,\n Controls,\n MiniMap,\n type DefaultEdgeOptions,\n type Edge,\n type EdgeTypes,\n type FitViewOptions,\n type NodeTypes,\n type ReactFlowProps,\n} from \"@xyflow/react\";\nimport \"@xyflow/react/dist/style.css\";\nimport { defaultNodeTypes } from \"../nodes\";\nimport { createConnectionValidator, type ConnectionValidatorOptions } from \"../../registry/connection\";\nimport { sortNodesParentFirst } from \"../FlowEditor/graph-ops\";\nimport { getHelperLines } from \"./helper-lines\";\nimport { HelperLines } from \"./HelperLines\";\nimport type { FlowNode } from \"../../types\";\n\n/**\n * With wheel-zoom off, Shift+wheel still zooms — and must not ALSO scroll the\n * page while it does. React Flow's own `preventScrolling` is all-or-nothing, so\n * the modifier case is handled here: swallow the gesture that zooms, leave the\n * one that doesn't alone.\n *\n * Capture phase, so it lands before React Flow's own wheel handling.\n */\nfunction preventScrollWhileZooming(event: ReactWheelEvent<HTMLDivElement>): void {\n if (event.shiftKey) event.preventDefault();\n}\n\n/**\n * The three React Flow props that together decide what the wheel does.\n *\n * Extracted because they only make sense as a set, and getting the set wrong is\n * invisible in a screenshot: the canvas looks fine and feels broken. This is\n * the unit worth testing — mounting a canvas to assert it would be testing\n * d3-zoom through jsdom.\n *\n * - **on** (default): no modifier needed, and the page never scrolls under a\n * wheel that is zooming.\n * - **off**: zoom moves to Shift+wheel and the bare wheel goes back to the\n * page. `preventScrolling` alone cannot express that — left true it swallows\n * the bare wheel (page frozen, nothing zooms), left false it lets Shift+wheel\n * zoom *and* scroll at once — so the handler covers the modifier case.\n */\nexport function wheelZoomProps(zoomOnWheel: boolean): {\n zoomActivationKeyCode: string | null;\n preventScrolling: boolean;\n onWheelCapture?: (event: ReactWheelEvent<HTMLDivElement>) => void;\n} {\n return zoomOnWheel\n ? { zoomActivationKeyCode: null, preventScrolling: true }\n : {\n zoomActivationKeyCode: \"Shift\",\n preventScrolling: false,\n onWheelCapture: preventScrollWhileZooming,\n };\n}\n\nexport type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, \"nodes\" | \"edges\" | \"height\"> & {\n nodes: FlowNode[];\n edges: Edge[];\n /** Background variant. Default: \"dots\". */\n background?: BackgroundVariant | \"none\";\n /** Show pan/zoom/fit controls. Default true. */\n showControls?: boolean;\n /** Show minimap. Default false (turn on for big graphs). */\n showMinimap?: boolean;\n /** Pixel height; FlowCanvas expects a sized container. Default 600. */\n height?: number | string;\n /**\n * Enforce port-type compatibility on new connections. `true` (default) uses\n * the built-in validator: a connection is refused only when both ports\n * declare a concrete, differing `type` (so untyped graphs are unaffected),\n * and self-loops are blocked. Pass options to tune the rule, or `false` to\n * disable. An `isValidConnection` you pass yourself always takes precedence.\n */\n validateConnections?: boolean | ConnectionValidatorOptions;\n /** Show alignment guide lines while dragging, and snap to them. Default off. */\n showHelperLines?: boolean;\n /**\n * A bare mouse wheel over the canvas zooms it. Default **true**.\n *\n * Turn it off for a canvas embedded mid-page, where a reader scrolling past\n * would otherwise get trapped zooming. With it off the wheel scrolls the page\n * and **Shift+wheel** zooms instead.\n *\n * Either way, a wheel gesture that zooms never also scrolls the page — the\n * two happening at once is the thing that makes an embedded canvas feel\n * broken.\n */\n zoomOnWheel?: boolean;\n /** Optional toolbar / palette etc. rendered above the canvas. */\n toolbar?: ReactNode;\n className?: string;\n style?: CSSProperties;\n};\n\nconst DEFAULT_FIT_VIEW: FitViewOptions = { padding: 0.2 };\nconst DEFAULT_EDGE_OPTIONS: DefaultEdgeOptions = {\n type: \"smoothstep\",\n animated: false,\n};\n\n/**\n * FlowCanvas — themed React Flow surface with the kit's nodes registered\n * by default. Pass your own `nodeTypes` to extend; the kit's defaults are\n * merged behind yours.\n *\n * Hosts wire `onNodesChange` / `onEdgesChange` / `onConnect` themselves\n * (xyflow's standard pattern). The surrounding `useFlowState` hook in\n * `runtime/use-flow-state.ts` is a convenience that wires those for you.\n */\nexport function FlowCanvas({\n nodes,\n edges,\n background = BackgroundVariant.Dots,\n showControls = true,\n showMinimap = false,\n height = 600,\n validateConnections = true,\n isValidConnection,\n colorMode,\n showHelperLines = false,\n zoomOnWheel = true,\n onNodesChange,\n toolbar,\n nodeTypes,\n edgeTypes,\n className,\n style,\n ...rest\n}: FlowCanvasProps) {\n const mergedNodeTypes = useMemo<NodeTypes>(\n () => ({ ...defaultNodeTypes, ...(nodeTypes ?? {}) }),\n [nodeTypes],\n );\n\n // Read nodes live through a ref so the validator (built once) always sees the\n // current graph without being rebuilt on every node change.\n const nodesRef = useRef(nodes);\n nodesRef.current = nodes;\n const builtinValidator = useMemo(\n () =>\n validateConnections === false\n ? undefined\n : createConnectionValidator(\n () => nodesRef.current,\n validateConnections === true ? undefined : validateConnections,\n ),\n [validateConnections],\n );\n // A caller-supplied predicate wins; otherwise fall back to port-type validation.\n const resolvedIsValidConnection = isValidConnection ?? builtinValidator;\n\n const mergedEdgeTypes = useMemo<EdgeTypes | undefined>(\n () => (edgeTypes ? { ...edgeTypes } : undefined),\n [edgeTypes],\n );\n\n // xyflow requires a parent node to precede its children in the array; grouping\n // (swimlanes) can produce any order, so normalize it here at the boundary.\n const orderedNodes = useMemo(() => sortNodesParentFirst(nodes), [nodes]);\n\n // Helper lines: on a single-node drag, snap to aligned edges + show guides.\n const [helperLines, setHelperLines] = useState<{ horizontal?: number; vertical?: number }>({});\n const handleNodesChange = useCallback(\n (changes: any[]) => {\n if (showHelperLines) {\n const pos = changes.filter((c) => c.type === \"position\" && c.position);\n if (pos.length === 1 && pos[0].dragging) {\n const lines = getHelperLines(pos[0], nodesRef.current);\n if (lines.snapPosition.x !== undefined) pos[0].position.x = lines.snapPosition.x;\n if (lines.snapPosition.y !== undefined) pos[0].position.y = lines.snapPosition.y;\n setHelperLines({ horizontal: lines.horizontal, vertical: lines.vertical });\n } else {\n setHelperLines({});\n }\n }\n onNodesChange?.(changes as any);\n },\n [showHelperLines, onNodesChange],\n );\n\n return (\n <div\n className={[\n \"ff-canvas\",\n // colorMode drives BOTH react-flow's chrome (below) and our `ff-` styles\n // via the shared `.dark` class / light opt-out — one theme signal.\n colorMode === \"dark\" ? \"dark\" : \"\",\n colorMode === \"light\" ? \"ff-canvas--light\" : \"\",\n className ?? \"\",\n ]\n .filter(Boolean)\n .join(\" \")}\n style={{ height, ...style }}\n >\n {toolbar && <div className=\"ff-canvas__toolbar\">{toolbar}</div>}\n <div className=\"ff-canvas__surface\">\n <ReactFlow\n nodes={orderedNodes}\n edges={edges}\n onNodesChange={handleNodesChange}\n colorMode={colorMode}\n nodeTypes={mergedNodeTypes}\n edgeTypes={mergedEdgeTypes}\n fitView\n fitViewOptions={DEFAULT_FIT_VIEW}\n defaultEdgeOptions={DEFAULT_EDGE_OPTIONS}\n proOptions={{ hideAttribution: true }}\n // Wheel zooms by default; `zoomOnWheel={false}` moves that onto\n // Shift+wheel and gives the bare wheel back to the page. The three\n // props only make sense as a set — see wheelZoomProps.\n {...wheelZoomProps(zoomOnWheel)}\n isValidConnection={resolvedIsValidConnection}\n {...rest}\n >\n {background !== \"none\" && (\n <Background variant={background as BackgroundVariant} gap={20} size={1} color=\"rgba(0,0,0,0.18)\" />\n )}\n {showControls && <Controls className=\"ff-controls\" position=\"bottom-right\" />}\n {showMinimap && <MiniMap className=\"ff-minimap\" pannable zoomable />}\n {showHelperLines && <HelperLines horizontal={helperLines.horizontal} vertical={helperLines.vertical} />}\n </ReactFlow>\n </div>\n </div>\n );\n}\n","import { useMemo, type CSSProperties, type ReactNode } from \"react\";\nimport { FlowCanvas } from \"../canvas\";\nimport { buildNodeTypes } from \"../../registry\";\nimport { categoryAccent, getNodeKind } from \"../../registry/registry\";\nimport type { FlowGraph, FlowNode } from \"../../types\";\n\n/** Outcome of one node in a run, for annotating the graph after the fact. */\nexport type FlowNodeStatus = \"ok\" | \"running\" | \"failed\" | \"skipped\" | \"pending\";\n\nexport interface FlowViewerClassNames {\n root?: string;\n list?: string;\n row?: string;\n rowIndex?: string;\n rowTitle?: string;\n rowDescription?: string;\n rowStatus?: string;\n}\n\nexport interface FlowViewerProps {\n /** The graph to show. */\n graph: FlowGraph;\n /**\n * `canvas` draws the graph. `list` renders the nodes as rows — for a docs\n * page, a narrow column, print, or an audit view, where a pan-zoom surface is\n * the wrong shape and often not usable at all.\n */\n variant?: \"canvas\" | \"list\";\n /** Canvas height. Ignored by `list`. Default 480. */\n height?: number | string;\n /** Canvas minimap. Default false. */\n showMinimap?: boolean;\n /** Canvas pan/zoom/fit controls. Default true. */\n showControls?: boolean;\n /**\n * Per-node run outcome, keyed by node id. Lets the same component serve\n * \"here is the workflow\" and \"here is what happened on Tuesday\".\n */\n statuses?: Record<string, FlowNodeStatus>;\n /** Controlled selection. */\n selectedNodeId?: string | null;\n /** Omit and nothing is clickable — a viewer with no handler is inert. */\n onSelectNode?: (node: FlowNode) => void;\n className?: string;\n classNames?: FlowViewerClassNames;\n style?: CSSProperties;\n /** Rendered when the graph has no nodes. */\n empty?: ReactNode;\n}\n\nconst STATUS_LABEL: Record<FlowNodeStatus, string> = {\n ok: \"ok\",\n running: \"running\",\n failed: \"failed\",\n skipped: \"skipped\",\n pending: \"pending\",\n};\n\n/**\n * FlowViewer — a workflow, read-only.\n *\n * **Read-only by construction, not by configuration.** There is no prop that\n * makes this editable, because a viewer that can be switched into an editor is\n * a viewer somebody eventually switches into an editor by accident. Before this\n * existed the only way to show a flow was `FlowEditor` (the whole editor) or\n * `FlowCanvas` plus four React Flow flags a consumer had to know to pass —\n * assembly, not an affordance, and nothing stopped the next person shipping a\n * fully editable canvas where they wanted a picture.\n *\n * Node titles come from the registry, so `overrideNodeKind()` renames apply\n * here too.\n */\nexport function FlowViewer({\n graph,\n variant = \"canvas\",\n height = 480,\n showMinimap = false,\n showControls = true,\n statuses,\n selectedNodeId = null,\n onSelectNode,\n className,\n classNames = {},\n style,\n empty,\n}: FlowViewerProps) {\n const nodeTypes = useMemo(() => buildNodeTypes(), []);\n\n const rows = useMemo(\n () =>\n graph.nodes.map((node, index) => {\n const kind = getNodeKind(node.data?.kind ?? node.type ?? \"\");\n return {\n node,\n index,\n title: kind?.label ?? node.data?.label ?? node.data?.kind ?? node.id,\n description: kind?.description ?? null,\n accent: kind?.accent ?? categoryAccent(kind?.category ?? \"custom\"),\n status: statuses?.[node.id] ?? null,\n };\n }),\n [graph.nodes, statuses],\n );\n\n if (graph.nodes.length === 0) {\n return (\n <div className={cx(\"ff-viewer ff-viewer--empty\", className, classNames.root)} style={style}>\n {empty ?? <span className=\"ff-viewer__empty\">This flow has no nodes.</span>}\n </div>\n );\n }\n\n if (variant === \"list\") {\n return (\n <div\n className={cx(\"ff-viewer ff-viewer--list\", className, classNames.root)}\n style={style}\n data-flow-viewer=\"list\"\n >\n <ol className={cx(\"ff-viewer__list\", classNames.list)}>\n {rows.map(({ node, index, title, description, accent, status }) => {\n const selected = node.id === selectedNodeId;\n const Row = onSelectNode ? \"button\" : \"div\";\n\n return (\n <li key={node.id}>\n <Row\n {...(onSelectNode\n ? { type: \"button\" as const, onClick: () => onSelectNode(node) }\n : {})}\n className={cx(\n \"ff-viewer__row\",\n selected && \"ff-viewer__row--selected\",\n onSelectNode && \"ff-viewer__row--interactive\",\n classNames.row,\n )}\n data-flow-viewer-node={node.id}\n data-flow-viewer-status={status ?? undefined}\n aria-current={selected || undefined}\n >\n <span\n className={cx(\"ff-viewer__index\", classNames.rowIndex)}\n style={{ backgroundColor: accent }}\n aria-hidden\n >\n {index + 1}\n </span>\n\n <span className=\"ff-viewer__body\">\n <span className={cx(\"ff-viewer__title\", classNames.rowTitle)}>{title}</span>\n {description && (\n <span className={cx(\"ff-viewer__desc\", classNames.rowDescription)}>\n {description}\n </span>\n )}\n </span>\n\n {status && (\n <span\n className={cx(\n \"ff-viewer__status\",\n `ff-viewer__status--${status}`,\n classNames.rowStatus,\n )}\n >\n {STATUS_LABEL[status]}\n </span>\n )}\n </Row>\n </li>\n );\n })}\n </ol>\n </div>\n );\n }\n\n return (\n <div\n className={cx(\"ff-viewer ff-viewer--canvas\", className, classNames.root)}\n style={style}\n data-flow-viewer=\"canvas\"\n >\n <FlowCanvas\n nodes={graph.nodes}\n edges={graph.edges}\n nodeTypes={nodeTypes}\n height={height}\n showControls={showControls}\n showMinimap={showMinimap}\n // The read-only contract. Every mutation path React Flow offers is\n // closed here rather than left to the caller to remember.\n nodesDraggable={false}\n nodesConnectable={false}\n nodesFocusable={Boolean(onSelectNode)}\n edgesFocusable={false}\n elementsSelectable={Boolean(onSelectNode)}\n deleteKeyCode={null}\n selectionKeyCode={null}\n multiSelectionKeyCode={null}\n connectOnClick={false}\n // A canvas embedded mid-page must not trap a reader's scroll.\n zoomOnScroll={false}\n onNodeClick={onSelectNode ? (_, node) => onSelectNode(node as FlowNode) : undefined}\n fitView\n />\n </div>\n );\n}\n\nfunction cx(...parts: Array<string | false | null | undefined>): string {\n return parts.filter(Boolean).join(\" \");\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { applyNodeChanges, applyEdgeChanges, addEdge } from './chunk-OWENS2H5.js';
2
- import { runFlow } from './chunk-RE7T5GKQ.js';
3
- import { getNodeKind } from './chunk-Q6IPK64P.js';
2
+ import { runFlow } from './chunk-VLATLVGH.js';
3
+ import { getNodeKind } from './chunk-PVROYW7C.js';
4
4
  import { useState, useRef, useCallback, useMemo } from 'react';
5
5
 
6
6
  function useFlowRun({ maxFeed = 200 } = {}) {
@@ -231,5 +231,5 @@ function useFlowHistory(flow) {
231
231
  }
232
232
 
233
233
  export { applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState };
234
- //# sourceMappingURL=chunk-EBE3FEAJ.js.map
235
- //# sourceMappingURL=chunk-EBE3FEAJ.js.map
234
+ //# sourceMappingURL=chunk-A6RFLGWV.js.map
235
+ //# sourceMappingURL=chunk-A6RFLGWV.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime/use-flow-run.ts","../src/runtime/use-flow-state.ts","../src/runtime/history.ts","../src/runtime/use-flow-history.ts"],"names":["useState","useCallback","useRef"],"mappings":"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","file":"chunk-EBE3FEAJ.js","sourcesContent":["import { useCallback, useRef, useState } from \"react\";\nimport { runFlow, type RunOptions, type RunResult } from \"./run-flow\";\nimport { getNodeKind } from \"../registry/registry\";\nimport type {\n ExecutorRegistry,\n FlowGraph,\n NodeRunStatus,\n RunEvent,\n} from \"../types\";\n\nexport type FlowRunFeedEntry = {\n id: string;\n at: number;\n level: \"info\" | \"warn\" | \"error\" | \"status\";\n text: string;\n nodeId?: string;\n detail?: unknown;\n};\n\nexport type UseFlowRunReturn = {\n /** Status keyed by nodeId — drive the UI overlay from this. */\n statuses: Record<string, NodeRunStatus>;\n /** Per-node status text (e.g. error message). */\n statusText: Record<string, string | undefined>;\n /** Latest computed output value per node (for reactive kinds). */\n outputs: Record<string, unknown>;\n /** Live event log (capped to last N). */\n feed: FlowRunFeedEntry[];\n /** Whether a run is currently in progress. */\n running: boolean;\n /** Last run result, or null. */\n lastResult: RunResult | null;\n /** Kick off a run with the provided graph + executors. */\n run: (graph: FlowGraph, executors: ExecutorRegistry, options?: RunOptions) => Promise<RunResult>;\n /** Cancel the current run (if any). */\n cancel: () => void;\n /** Reset all runtime state (statuses, feed, lastResult). */\n reset: () => void;\n};\n\nexport type UseFlowRunOptions = {\n /** Cap the in-memory feed to this many entries. Default 200. */\n maxFeed?: number;\n};\n\n/**\n * useFlowRun — drives `runFlow` + maintains observability state. Pair with\n * `applyStatusesToNodes` (below) before passing nodes to `<FlowCanvas>` so\n * the per-node status badge renders.\n */\nexport function useFlowRun({ maxFeed = 200 }: UseFlowRunOptions = {}): UseFlowRunReturn {\n const [statuses, setStatuses] = useState<Record<string, NodeRunStatus>>({});\n const [statusText, setStatusText] = useState<Record<string, string | undefined>>({});\n const [outputs, setOutputs] = useState<Record<string, unknown>>({});\n const [feed, setFeed] = useState<FlowRunFeedEntry[]>([]);\n const [running, setRunning] = useState(false);\n const [lastResult, setLastResult] = useState<RunResult | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n\n const handleEvent = useCallback(\n (e: RunEvent) => {\n switch (e.type) {\n case \"node-status\":\n setStatuses((s) => ({ ...s, [e.nodeId]: e.status }));\n setStatusText((t) => ({ ...t, [e.nodeId]: e.text }));\n appendFeed({ level: \"status\", text: `${e.nodeId} → ${e.status}${e.text ? ` (${e.text})` : \"\"}`, nodeId: e.nodeId });\n break;\n case \"node-output\":\n setOutputs((o) => ({ ...o, [e.nodeId]: e.value }));\n appendFeed({ level: \"info\", text: `${e.nodeId}.${e.portId} = ${preview(e.value)}`, nodeId: e.nodeId, detail: e.value });\n break;\n case \"log\":\n appendFeed({ level: e.level, text: e.message, nodeId: e.nodeId, detail: e.detail });\n break;\n case \"run-start\":\n appendFeed({ level: \"info\", text: \"▶ run started\" });\n break;\n case \"run-end\":\n appendFeed({ level: e.ok ? \"info\" : \"error\", text: e.ok ? \"✓ run complete\" : \"✗ run failed\" });\n break;\n case \"run-error\":\n appendFeed({ level: \"error\", text: e.error });\n break;\n }\n function appendFeed(partial: Omit<FlowRunFeedEntry, \"id\" | \"at\">) {\n setFeed((f) => {\n const entry: FlowRunFeedEntry = { id: `${Date.now()}_${f.length}`, at: Date.now(), ...partial };\n const next = [...f, entry];\n return next.length > maxFeed ? next.slice(next.length - maxFeed) : next;\n });\n }\n },\n [maxFeed],\n );\n\n const run = useCallback(\n async (graph: FlowGraph, executors: ExecutorRegistry, options: RunOptions = {}) => {\n if (running) {\n return { ok: false, outputs: {}, error: \"another run is already in progress\" } satisfies RunResult;\n }\n const controller = new AbortController();\n abortRef.current = controller;\n // Reset previous statuses for the nodes we're about to run.\n const idleStatuses: Record<string, NodeRunStatus> = {};\n for (const n of graph.nodes) idleStatuses[n.id] = \"idle\";\n setStatuses(idleStatuses);\n setStatusText({});\n setOutputs({});\n setRunning(true);\n try {\n const result = await runFlow(graph, executors, handleEvent, { ...options, signal: controller.signal });\n setLastResult(result);\n return result;\n } finally {\n setRunning(false);\n abortRef.current = null;\n }\n },\n [handleEvent, running],\n );\n\n const cancel = useCallback(() => abortRef.current?.abort(), []);\n\n const reset = useCallback(() => {\n setStatuses({});\n setStatusText({});\n setOutputs({});\n setFeed([]);\n setLastResult(null);\n }, []);\n\n return { statuses, statusText, outputs, feed, running, lastResult, run, cancel, reset };\n}\n\n/**\n * Write each reactive kind's latest run output into its `data.output`, so its\n * card can render the computed value live. Non-reactive kinds are returned\n * untouched. Pair with `applyStatusesToNodes` before rendering.\n */\nexport function applyOutputsToNodes<TNode extends { id: string; type?: string; data: any }>(\n nodes: TNode[],\n outputs: Record<string, unknown>,\n): TNode[] {\n return nodes.map((n) => {\n const kind = getNodeKind((n.data as any)?.kind ?? n.type ?? \"\");\n if (!kind?.reactive || !(n.id in outputs)) return n;\n return { ...n, data: { ...n.data, output: outputs[n.id] } };\n });\n}\n\n/** Merge runtime statuses into nodes for rendering. */\nexport function applyStatusesToNodes<TNode extends { id: string; data: any }>(\n nodes: TNode[],\n statuses: Record<string, NodeRunStatus>,\n statusText: Record<string, string | undefined>,\n): TNode[] {\n return nodes.map((n) => ({\n ...n,\n data: {\n ...n.data,\n status: statuses[n.id] ?? n.data?.status ?? \"idle\",\n statusText: statusText[n.id] ?? n.data?.statusText,\n },\n }));\n}\n\nfunction preview(v: unknown): string {\n try {\n const s = JSON.stringify(v);\n return s && s.length > 60 ? s.slice(0, 57) + \"…\" : (s ?? String(v));\n } catch {\n return String(v);\n }\n}\n","import { useCallback, useState } from \"react\";\nimport {\n addEdge,\n applyEdgeChanges,\n applyNodeChanges,\n type Connection,\n type Edge,\n type EdgeChange,\n type NodeChange,\n} from \"@xyflow/react\";\nimport type { FlowEdge, FlowGraph, FlowNode } from \"../types\";\n\nexport type UseFlowStateReturn = {\n nodes: FlowNode[];\n edges: FlowEdge[];\n setNodes: React.Dispatch<React.SetStateAction<FlowNode[]>>;\n setEdges: React.Dispatch<React.SetStateAction<FlowEdge[]>>;\n /**\n * Replace nodes AND edges atomically in a single commit. Use this for any op\n * that touches both (delete-with-edge-prune, undo/redo restore, setGraph):\n * calling `setNodes` then `setEdges` is NOT atomic in controlled mode (each\n * closes over a stale `value`), so the second write clobbers the first.\n */\n setGraph: (graph: FlowGraph) => void;\n onNodesChange: (changes: NodeChange[]) => void;\n onEdgesChange: (changes: EdgeChange[]) => void;\n onConnect: (connection: Connection) => void;\n /** Snapshot the current graph (suitable for serialization). */\n toGraph: () => FlowGraph;\n};\n\n/**\n * useFlowState — React Flow's standard controlled-state plumbing in one hook.\n * Spread into <FlowCanvas>.\n */\nexport function useFlowState(initial: FlowGraph): UseFlowStateReturn {\n const [nodes, setNodes] = useState<FlowNode[]>(initial.nodes);\n const [edges, setEdges] = useState<FlowEdge[]>(initial.edges);\n\n const onNodesChange = useCallback((changes: NodeChange[]) => {\n setNodes((ns) => applyNodeChanges(changes, ns) as FlowNode[]);\n }, []);\n const onEdgesChange = useCallback((changes: EdgeChange[]) => {\n setEdges((es) => applyEdgeChanges(changes, es));\n }, []);\n const onConnect = useCallback((connection: Connection) => {\n setEdges((es) => addEdge(connection, es) as Edge[]);\n }, []);\n\n const setGraph = useCallback((graph: FlowGraph) => {\n // Two useState writes in one event are batched, so this IS atomic here.\n setNodes(graph.nodes);\n setEdges(graph.edges);\n }, []);\n\n const toGraph = useCallback(() => ({ nodes, edges }), [nodes, edges]);\n\n return { nodes, edges, setNodes, setEdges, setGraph, onNodesChange, onEdgesChange, onConnect, toGraph };\n}\n","import type { FlowGraph } from \"../types\";\n\n/**\n * Undo/redo history — a pure, React-free snapshot controller. The editor pushes\n * a graph snapshot BEFORE each committing mutation; `undo`/`redo` swap snapshots\n * between the past/future stacks. Kept free of React so it can be unit-tested\n * and reused by any host (or a headless driver).\n *\n * Coalescing (collapsing a burst of setState calls from one logical op into a\n * single undo step) is the caller's job — see `useFlowHistory`.\n */\nexport type HistoryController = {\n /** Record `graph` as an undo point. Clears the redo stack (new branch). */\n push: (graph: FlowGraph) => void;\n /** Pop the last undo point; `current` is pushed onto the redo stack. */\n undo: (current: FlowGraph) => FlowGraph | null;\n /** Pop the last redo point; `current` is pushed back onto the undo stack. */\n redo: (current: FlowGraph) => FlowGraph | null;\n canUndo: () => boolean;\n canRedo: () => boolean;\n clear: () => void;\n /** Test/inspection helper — sizes of the two stacks. */\n size: () => { past: number; future: number };\n};\n\nexport function createHistory(limit = 100): HistoryController {\n let past: FlowGraph[] = [];\n let future: FlowGraph[] = [];\n\n return {\n push(graph) {\n past.push(graph);\n if (past.length > limit) past.shift();\n future = [];\n },\n undo(current) {\n const prev = past.pop();\n if (prev === undefined) return null;\n future.push(current);\n return prev;\n },\n redo(current) {\n const next = future.pop();\n if (next === undefined) return null;\n past.push(current);\n return next;\n },\n canUndo: () => past.length > 0,\n canRedo: () => future.length > 0,\n clear() {\n past = [];\n future = [];\n },\n size: () => ({ past: past.length, future: future.length }),\n };\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { EdgeChange, NodeChange } from \"@xyflow/react\";\nimport type { FlowGraph } from \"../types\";\nimport { createHistory } from \"./history\";\nimport type { UseFlowStateReturn } from \"./use-flow-state\";\n\nexport type UseFlowHistoryReturn = {\n /** The flow sink wrapped so committing mutations snapshot for undo first. */\n flow: UseFlowStateReturn;\n undo: () => void;\n redo: () => void;\n canUndo: boolean;\n canRedo: boolean;\n /** Snapshot the current graph as an undo point (before a programmatic edit). */\n capture: () => void;\n /** Wire to `<FlowCanvas onNodeDragStart>` — snapshots the pre-drag graph. */\n onNodeDragStart: () => void;\n};\n\n/**\n * useFlowHistory — the commit/undo pipeline. Wraps a flow sink (the uncontrolled\n * `useFlowState` hook OR the controlled adapter) so every *committing* mutation\n * records a snapshot first, giving undo/redo without the editor threading\n * history through each call site. This is the single interception point the\n * two-sink architecture otherwise lacks.\n *\n * Granularity: a burst of setState calls from one logical op (e.g. a\n * delete = setNodes+setEdges) is coalesced into ONE undo step; transient\n * interactive changes (drag-move, dimension-measure, selection) are NOT captured\n * — a drag is captured once at `onNodeDragStart` instead.\n */\nexport function useFlowHistory(flow: UseFlowStateReturn): UseFlowHistoryReturn {\n const history = useRef(createHistory()).current;\n const restoring = useRef(false);\n const coalesced = useRef(false);\n const [, bump] = useState(0);\n const rerender = useCallback(() => bump((n) => n + 1), []);\n\n // Latest graph via a ref, so capture never reads a stale snapshot.\n const graphRef = useRef<FlowGraph>({ nodes: flow.nodes, edges: flow.edges });\n graphRef.current = { nodes: flow.nodes, edges: flow.edges };\n\n const capture = useCallback(() => {\n if (restoring.current || coalesced.current) return;\n coalesced.current = true;\n queueMicrotask(() => {\n coalesced.current = false;\n });\n history.push(graphRef.current);\n rerender();\n }, [history, rerender]);\n\n const restore = useCallback(\n (g: FlowGraph | null) => {\n if (!g) return;\n restoring.current = true;\n flow.setGraph(g);\n queueMicrotask(() => {\n restoring.current = false;\n });\n rerender();\n },\n [flow, rerender],\n );\n\n const undo = useCallback(() => restore(history.undo(graphRef.current)), [history, restore]);\n const redo = useCallback(() => restore(history.redo(graphRef.current)), [history, restore]);\n\n const wrapped = useMemo<UseFlowStateReturn>(\n () => ({\n ...flow,\n setNodes: (next) => {\n capture();\n flow.setNodes(next);\n },\n setEdges: (next) => {\n capture();\n flow.setEdges(next);\n },\n setGraph: (g) => {\n capture();\n flow.setGraph(g);\n },\n onNodesChange: (changes: NodeChange[]) => {\n // Only structural removes commit; position/dimensions/select are transient.\n if (!restoring.current && changes.some((c) => c.type === \"remove\")) capture();\n flow.onNodesChange(changes);\n },\n onEdgesChange: (changes: EdgeChange[]) => {\n if (!restoring.current && changes.some((c) => c.type === \"remove\")) capture();\n flow.onEdgesChange(changes);\n },\n onConnect: (conn) => {\n capture();\n flow.onConnect(conn);\n },\n }),\n [flow, capture],\n );\n\n return {\n flow: wrapped,\n undo,\n redo,\n canUndo: history.canUndo(),\n canRedo: history.canRedo(),\n capture,\n onNodeDragStart: capture,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/runtime/use-flow-run.ts","../src/runtime/use-flow-state.ts","../src/runtime/history.ts","../src/runtime/use-flow-history.ts"],"names":["useState","useCallback","useRef"],"mappings":"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","file":"chunk-A6RFLGWV.js","sourcesContent":["import { useCallback, useRef, useState } from \"react\";\nimport { runFlow, type RunOptions, type RunResult } from \"./run-flow\";\nimport { getNodeKind } from \"../registry/registry\";\nimport type {\n ExecutorRegistry,\n FlowGraph,\n NodeRunStatus,\n RunEvent,\n} from \"../types\";\n\nexport type FlowRunFeedEntry = {\n id: string;\n at: number;\n level: \"info\" | \"warn\" | \"error\" | \"status\";\n text: string;\n nodeId?: string;\n detail?: unknown;\n};\n\nexport type UseFlowRunReturn = {\n /** Status keyed by nodeId — drive the UI overlay from this. */\n statuses: Record<string, NodeRunStatus>;\n /** Per-node status text (e.g. error message). */\n statusText: Record<string, string | undefined>;\n /** Latest computed output value per node (for reactive kinds). */\n outputs: Record<string, unknown>;\n /** Live event log (capped to last N). */\n feed: FlowRunFeedEntry[];\n /** Whether a run is currently in progress. */\n running: boolean;\n /** Last run result, or null. */\n lastResult: RunResult | null;\n /** Kick off a run with the provided graph + executors. */\n run: (graph: FlowGraph, executors: ExecutorRegistry, options?: RunOptions) => Promise<RunResult>;\n /** Cancel the current run (if any). */\n cancel: () => void;\n /** Reset all runtime state (statuses, feed, lastResult). */\n reset: () => void;\n};\n\nexport type UseFlowRunOptions = {\n /** Cap the in-memory feed to this many entries. Default 200. */\n maxFeed?: number;\n};\n\n/**\n * useFlowRun — drives `runFlow` + maintains observability state. Pair with\n * `applyStatusesToNodes` (below) before passing nodes to `<FlowCanvas>` so\n * the per-node status badge renders.\n */\nexport function useFlowRun({ maxFeed = 200 }: UseFlowRunOptions = {}): UseFlowRunReturn {\n const [statuses, setStatuses] = useState<Record<string, NodeRunStatus>>({});\n const [statusText, setStatusText] = useState<Record<string, string | undefined>>({});\n const [outputs, setOutputs] = useState<Record<string, unknown>>({});\n const [feed, setFeed] = useState<FlowRunFeedEntry[]>([]);\n const [running, setRunning] = useState(false);\n const [lastResult, setLastResult] = useState<RunResult | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n\n const handleEvent = useCallback(\n (e: RunEvent) => {\n switch (e.type) {\n case \"node-status\":\n setStatuses((s) => ({ ...s, [e.nodeId]: e.status }));\n setStatusText((t) => ({ ...t, [e.nodeId]: e.text }));\n appendFeed({ level: \"status\", text: `${e.nodeId} → ${e.status}${e.text ? ` (${e.text})` : \"\"}`, nodeId: e.nodeId });\n break;\n case \"node-output\":\n setOutputs((o) => ({ ...o, [e.nodeId]: e.value }));\n appendFeed({ level: \"info\", text: `${e.nodeId}.${e.portId} = ${preview(e.value)}`, nodeId: e.nodeId, detail: e.value });\n break;\n case \"log\":\n appendFeed({ level: e.level, text: e.message, nodeId: e.nodeId, detail: e.detail });\n break;\n case \"run-start\":\n appendFeed({ level: \"info\", text: \"▶ run started\" });\n break;\n case \"run-end\":\n appendFeed({ level: e.ok ? \"info\" : \"error\", text: e.ok ? \"✓ run complete\" : \"✗ run failed\" });\n break;\n case \"run-error\":\n appendFeed({ level: \"error\", text: e.error });\n break;\n }\n function appendFeed(partial: Omit<FlowRunFeedEntry, \"id\" | \"at\">) {\n setFeed((f) => {\n const entry: FlowRunFeedEntry = { id: `${Date.now()}_${f.length}`, at: Date.now(), ...partial };\n const next = [...f, entry];\n return next.length > maxFeed ? next.slice(next.length - maxFeed) : next;\n });\n }\n },\n [maxFeed],\n );\n\n const run = useCallback(\n async (graph: FlowGraph, executors: ExecutorRegistry, options: RunOptions = {}) => {\n if (running) {\n return { ok: false, outputs: {}, error: \"another run is already in progress\" } satisfies RunResult;\n }\n const controller = new AbortController();\n abortRef.current = controller;\n // Reset previous statuses for the nodes we're about to run.\n const idleStatuses: Record<string, NodeRunStatus> = {};\n for (const n of graph.nodes) idleStatuses[n.id] = \"idle\";\n setStatuses(idleStatuses);\n setStatusText({});\n setOutputs({});\n setRunning(true);\n try {\n const result = await runFlow(graph, executors, handleEvent, { ...options, signal: controller.signal });\n setLastResult(result);\n return result;\n } finally {\n setRunning(false);\n abortRef.current = null;\n }\n },\n [handleEvent, running],\n );\n\n const cancel = useCallback(() => abortRef.current?.abort(), []);\n\n const reset = useCallback(() => {\n setStatuses({});\n setStatusText({});\n setOutputs({});\n setFeed([]);\n setLastResult(null);\n }, []);\n\n return { statuses, statusText, outputs, feed, running, lastResult, run, cancel, reset };\n}\n\n/**\n * Write each reactive kind's latest run output into its `data.output`, so its\n * card can render the computed value live. Non-reactive kinds are returned\n * untouched. Pair with `applyStatusesToNodes` before rendering.\n */\nexport function applyOutputsToNodes<TNode extends { id: string; type?: string; data: any }>(\n nodes: TNode[],\n outputs: Record<string, unknown>,\n): TNode[] {\n return nodes.map((n) => {\n const kind = getNodeKind((n.data as any)?.kind ?? n.type ?? \"\");\n if (!kind?.reactive || !(n.id in outputs)) return n;\n return { ...n, data: { ...n.data, output: outputs[n.id] } };\n });\n}\n\n/** Merge runtime statuses into nodes for rendering. */\nexport function applyStatusesToNodes<TNode extends { id: string; data: any }>(\n nodes: TNode[],\n statuses: Record<string, NodeRunStatus>,\n statusText: Record<string, string | undefined>,\n): TNode[] {\n return nodes.map((n) => ({\n ...n,\n data: {\n ...n.data,\n status: statuses[n.id] ?? n.data?.status ?? \"idle\",\n statusText: statusText[n.id] ?? n.data?.statusText,\n },\n }));\n}\n\nfunction preview(v: unknown): string {\n try {\n const s = JSON.stringify(v);\n return s && s.length > 60 ? s.slice(0, 57) + \"…\" : (s ?? String(v));\n } catch {\n return String(v);\n }\n}\n","import { useCallback, useState } from \"react\";\nimport {\n addEdge,\n applyEdgeChanges,\n applyNodeChanges,\n type Connection,\n type Edge,\n type EdgeChange,\n type NodeChange,\n} from \"@xyflow/react\";\nimport type { FlowEdge, FlowGraph, FlowNode } from \"../types\";\n\nexport type UseFlowStateReturn = {\n nodes: FlowNode[];\n edges: FlowEdge[];\n setNodes: React.Dispatch<React.SetStateAction<FlowNode[]>>;\n setEdges: React.Dispatch<React.SetStateAction<FlowEdge[]>>;\n /**\n * Replace nodes AND edges atomically in a single commit. Use this for any op\n * that touches both (delete-with-edge-prune, undo/redo restore, setGraph):\n * calling `setNodes` then `setEdges` is NOT atomic in controlled mode (each\n * closes over a stale `value`), so the second write clobbers the first.\n */\n setGraph: (graph: FlowGraph) => void;\n onNodesChange: (changes: NodeChange[]) => void;\n onEdgesChange: (changes: EdgeChange[]) => void;\n onConnect: (connection: Connection) => void;\n /** Snapshot the current graph (suitable for serialization). */\n toGraph: () => FlowGraph;\n};\n\n/**\n * useFlowState — React Flow's standard controlled-state plumbing in one hook.\n * Spread into <FlowCanvas>.\n */\nexport function useFlowState(initial: FlowGraph): UseFlowStateReturn {\n const [nodes, setNodes] = useState<FlowNode[]>(initial.nodes);\n const [edges, setEdges] = useState<FlowEdge[]>(initial.edges);\n\n const onNodesChange = useCallback((changes: NodeChange[]) => {\n setNodes((ns) => applyNodeChanges(changes, ns) as FlowNode[]);\n }, []);\n const onEdgesChange = useCallback((changes: EdgeChange[]) => {\n setEdges((es) => applyEdgeChanges(changes, es));\n }, []);\n const onConnect = useCallback((connection: Connection) => {\n setEdges((es) => addEdge(connection, es) as Edge[]);\n }, []);\n\n const setGraph = useCallback((graph: FlowGraph) => {\n // Two useState writes in one event are batched, so this IS atomic here.\n setNodes(graph.nodes);\n setEdges(graph.edges);\n }, []);\n\n const toGraph = useCallback(() => ({ nodes, edges }), [nodes, edges]);\n\n return { nodes, edges, setNodes, setEdges, setGraph, onNodesChange, onEdgesChange, onConnect, toGraph };\n}\n","import type { FlowGraph } from \"../types\";\n\n/**\n * Undo/redo history — a pure, React-free snapshot controller. The editor pushes\n * a graph snapshot BEFORE each committing mutation; `undo`/`redo` swap snapshots\n * between the past/future stacks. Kept free of React so it can be unit-tested\n * and reused by any host (or a headless driver).\n *\n * Coalescing (collapsing a burst of setState calls from one logical op into a\n * single undo step) is the caller's job — see `useFlowHistory`.\n */\nexport type HistoryController = {\n /** Record `graph` as an undo point. Clears the redo stack (new branch). */\n push: (graph: FlowGraph) => void;\n /** Pop the last undo point; `current` is pushed onto the redo stack. */\n undo: (current: FlowGraph) => FlowGraph | null;\n /** Pop the last redo point; `current` is pushed back onto the undo stack. */\n redo: (current: FlowGraph) => FlowGraph | null;\n canUndo: () => boolean;\n canRedo: () => boolean;\n clear: () => void;\n /** Test/inspection helper — sizes of the two stacks. */\n size: () => { past: number; future: number };\n};\n\nexport function createHistory(limit = 100): HistoryController {\n let past: FlowGraph[] = [];\n let future: FlowGraph[] = [];\n\n return {\n push(graph) {\n past.push(graph);\n if (past.length > limit) past.shift();\n future = [];\n },\n undo(current) {\n const prev = past.pop();\n if (prev === undefined) return null;\n future.push(current);\n return prev;\n },\n redo(current) {\n const next = future.pop();\n if (next === undefined) return null;\n past.push(current);\n return next;\n },\n canUndo: () => past.length > 0,\n canRedo: () => future.length > 0,\n clear() {\n past = [];\n future = [];\n },\n size: () => ({ past: past.length, future: future.length }),\n };\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { EdgeChange, NodeChange } from \"@xyflow/react\";\nimport type { FlowGraph } from \"../types\";\nimport { createHistory } from \"./history\";\nimport type { UseFlowStateReturn } from \"./use-flow-state\";\n\nexport type UseFlowHistoryReturn = {\n /** The flow sink wrapped so committing mutations snapshot for undo first. */\n flow: UseFlowStateReturn;\n undo: () => void;\n redo: () => void;\n canUndo: boolean;\n canRedo: boolean;\n /** Snapshot the current graph as an undo point (before a programmatic edit). */\n capture: () => void;\n /** Wire to `<FlowCanvas onNodeDragStart>` — snapshots the pre-drag graph. */\n onNodeDragStart: () => void;\n};\n\n/**\n * useFlowHistory — the commit/undo pipeline. Wraps a flow sink (the uncontrolled\n * `useFlowState` hook OR the controlled adapter) so every *committing* mutation\n * records a snapshot first, giving undo/redo without the editor threading\n * history through each call site. This is the single interception point the\n * two-sink architecture otherwise lacks.\n *\n * Granularity: a burst of setState calls from one logical op (e.g. a\n * delete = setNodes+setEdges) is coalesced into ONE undo step; transient\n * interactive changes (drag-move, dimension-measure, selection) are NOT captured\n * — a drag is captured once at `onNodeDragStart` instead.\n */\nexport function useFlowHistory(flow: UseFlowStateReturn): UseFlowHistoryReturn {\n const history = useRef(createHistory()).current;\n const restoring = useRef(false);\n const coalesced = useRef(false);\n const [, bump] = useState(0);\n const rerender = useCallback(() => bump((n) => n + 1), []);\n\n // Latest graph via a ref, so capture never reads a stale snapshot.\n const graphRef = useRef<FlowGraph>({ nodes: flow.nodes, edges: flow.edges });\n graphRef.current = { nodes: flow.nodes, edges: flow.edges };\n\n const capture = useCallback(() => {\n if (restoring.current || coalesced.current) return;\n coalesced.current = true;\n queueMicrotask(() => {\n coalesced.current = false;\n });\n history.push(graphRef.current);\n rerender();\n }, [history, rerender]);\n\n const restore = useCallback(\n (g: FlowGraph | null) => {\n if (!g) return;\n restoring.current = true;\n flow.setGraph(g);\n queueMicrotask(() => {\n restoring.current = false;\n });\n rerender();\n },\n [flow, rerender],\n );\n\n const undo = useCallback(() => restore(history.undo(graphRef.current)), [history, restore]);\n const redo = useCallback(() => restore(history.redo(graphRef.current)), [history, restore]);\n\n const wrapped = useMemo<UseFlowStateReturn>(\n () => ({\n ...flow,\n setNodes: (next) => {\n capture();\n flow.setNodes(next);\n },\n setEdges: (next) => {\n capture();\n flow.setEdges(next);\n },\n setGraph: (g) => {\n capture();\n flow.setGraph(g);\n },\n onNodesChange: (changes: NodeChange[]) => {\n // Only structural removes commit; position/dimensions/select are transient.\n if (!restoring.current && changes.some((c) => c.type === \"remove\")) capture();\n flow.onNodesChange(changes);\n },\n onEdgesChange: (changes: EdgeChange[]) => {\n if (!restoring.current && changes.some((c) => c.type === \"remove\")) capture();\n flow.onEdgesChange(changes);\n },\n onConnect: (conn) => {\n capture();\n flow.onConnect(conn);\n },\n }),\n [flow, capture],\n );\n\n return {\n flow: wrapped,\n undo,\n redo,\n canUndo: history.canUndo(),\n canRedo: history.canRedo(),\n capture,\n onNodeDragStart: capture,\n };\n}\n"]}
@@ -2,6 +2,7 @@
2
2
  var kinds = /* @__PURE__ */ new Map();
3
3
  var aliases = /* @__PURE__ */ new Map();
4
4
  var listeners = /* @__PURE__ */ new Set();
5
+ var overrides = /* @__PURE__ */ new Map();
5
6
  function registerNodeKind(definition) {
6
7
  kinds.set(definition.name, definition);
7
8
  for (const alias of definition.aliases ?? []) aliases.set(alias, definition.name);
@@ -21,15 +22,41 @@ function resolveKindId(id) {
21
22
  const canonical = aliases.get(id);
22
23
  return canonical && kinds.has(canonical) ? canonical : null;
23
24
  }
25
+ function overrideNodeKind(name, patch) {
26
+ const canonical = resolveKindId(name) ?? name;
27
+ const previous = overrides.get(canonical);
28
+ overrides.set(canonical, { ...previous, ...patch });
29
+ notify();
30
+ return () => {
31
+ if (previous) {
32
+ overrides.set(canonical, previous);
33
+ } else {
34
+ overrides.delete(canonical);
35
+ }
36
+ notify();
37
+ };
38
+ }
39
+ function clearNodeKindOverrides() {
40
+ if (overrides.size === 0) return;
41
+ overrides.clear();
42
+ notify();
43
+ }
44
+ function withOverride(kind) {
45
+ if (!kind) return null;
46
+ const patch = overrides.get(kind.name);
47
+ return patch ? { ...kind, ...patch } : kind;
48
+ }
24
49
  function getNodeKind(name) {
25
50
  const canonical = resolveKindId(name);
26
- return canonical ? kinds.get(canonical) ?? null : null;
51
+ return canonical ? withOverride(kinds.get(canonical)) : null;
27
52
  }
28
53
  function kindIds(kind) {
29
54
  return [kind.name, ...kind.aliases ?? []];
30
55
  }
31
56
  function listNodeKinds(category) {
32
- const all = Array.from(kinds.values());
57
+ const all = Array.from(kinds.values()).map(
58
+ (k) => withOverride(k)
59
+ );
33
60
  return category ? all.filter((k) => k.category === category) : all;
34
61
  }
35
62
  function onNodeKindsChanged(listener) {
@@ -155,6 +182,6 @@ function categoryAccent(category) {
155
182
  }
156
183
  }
157
184
 
158
- export { categoryAccent, defaultConfigFor, getNodeKind, kindIds, listNodeKinds, onNodeKindsChanged, registerNodeKind, resolveKindId, validateConfig };
159
- //# sourceMappingURL=chunk-Q6IPK64P.js.map
160
- //# sourceMappingURL=chunk-Q6IPK64P.js.map
185
+ export { categoryAccent, clearNodeKindOverrides, defaultConfigFor, getNodeKind, kindIds, listNodeKinds, onNodeKindsChanged, overrideNodeKind, registerNodeKind, resolveKindId, validateConfig };
186
+ //# sourceMappingURL=chunk-PVROYW7C.js.map
187
+ //# sourceMappingURL=chunk-PVROYW7C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/registry/registry.ts"],"names":[],"mappings":"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","file":"chunk-PVROYW7C.js","sourcesContent":["import type { ConfigField, NodeKindDefinition } from \"./types\";\n\nconst kinds = new Map<string, NodeKindDefinition<any, any, any>>();\n/** alias → canonical name. See `resolveKindId`. */\nconst aliases = new Map<string, string>();\nconst listeners = new Set<() => void>();\n/**\n * canonical name → presentation patch. See `overrideNodeKind`.\n *\n * Kept SEPARATE from `kinds` on purpose: an override has to survive its base\n * kind being re-registered (HMR, a later `registerBuiltinKinds()`, a package\n * upgrade). Merging into the definition would mean the next registration\n * silently reverts the consumer's naming.\n */\nconst overrides = new Map<string, NodeKindPresentation>();\n\n/**\n * The presentation fields a consumer may override on someone else's node kind.\n *\n * Deliberately excludes everything behavioural — `executor`, `inputs`,\n * `outputs`, `configSchema`, `sideEffects`. An \"override\" that could change\n * those is not an override, it is a fork wearing a friendly name, and it would\n * desync the graph from the runtime that executes it.\n *\n * `category` IS included: which drawer a node appears in is presentation, and a\n * consumer regrouping their palette is the same kind of act as renaming.\n */\nexport type NodeKindPresentation = Partial<\n Pick<NodeKindDefinition, \"label\" | \"description\" | \"icon\" | \"accent\" | \"category\">\n>;\n\n/**\n * registerNodeKind — install a node kind in the global registry. Returns\n * an `unregister` function. Calling with the same name replaces the prior\n * registration (handy for HMR).\n *\n * A kind's `name` is its CANONICAL id and is what gets written into saved\n * documents. Publish namespaced (`@fancy/llm_branch`, `@acme/salesforce_upsert`)\n * and list any previous bare names in `aliases`, so graphs saved before the\n * rename keep resolving.\n */\nexport function registerNodeKind<TC = any, TI = any, TO = any>(\n definition: NodeKindDefinition<TC, TI, TO>,\n): () => void {\n kinds.set(definition.name, definition as NodeKindDefinition<any, any, any>);\n for (const alias of definition.aliases ?? []) aliases.set(alias, definition.name);\n notify();\n return () => {\n if (kinds.get(definition.name) === (definition as any)) {\n kinds.delete(definition.name);\n for (const alias of definition.aliases ?? []) {\n if (aliases.get(alias) === definition.name) aliases.delete(alias);\n }\n notify();\n }\n };\n}\n\n/**\n * Resolve any id — canonical or alias — to the canonical one, or null.\n *\n * `kind` is persisted inside every saved graph, so a bare name that two\n * packages could both claim is unfixable after the fact: the ambiguous string\n * is already in the document. Canonical ids are namespaced; aliases exist so\n * documents written before namespacing keep opening.\n */\nexport function resolveKindId(id: string): string | null {\n if (kinds.has(id)) return id;\n const canonical = aliases.get(id);\n return canonical && kinds.has(canonical) ? canonical : null;\n}\n\n/**\n * Rename or re-describe a kind you did not author.\n *\n * Before this existed the only way to relabel a builtin was `registerNodeKind`\n * with a full definition — which REPLACES the kind, so a consumer wanting\n * \"Call an API\" instead of \"HTTP Request\" had to re-declare that node's\n * configSchema, ports, executor and renderer, and silently forfeited whatever\n * the builtin gained in the next release. In practice nobody renamed a node,\n * and the palette could not be localised at all.\n *\n * ```ts\n * const undo = overrideNodeKind(\"@particle-academy/http_request\", {\n * label: \"Call an API\",\n * description: \"Fetch or post JSON to a URL\",\n * });\n * ```\n *\n * Applies at `getNodeKind()` and `listNodeKinds()`, so one call reaches the\n * palette, the node cards on the canvas, `FlowViewer`, and anything else that\n * reads the registry. Returns an unsubscribe, matching `registerNodeKind`.\n *\n * Patching an unregistered id is allowed and takes effect if that kind is\n * registered later — order of module side effects is not something a consumer\n * should have to reason about.\n */\nexport function overrideNodeKind(name: string, patch: NodeKindPresentation): () => void {\n const canonical = resolveKindId(name) ?? name;\n const previous = overrides.get(canonical);\n\n overrides.set(canonical, { ...previous, ...patch });\n notify();\n\n return () => {\n if (previous) {\n overrides.set(canonical, previous);\n } else {\n overrides.delete(canonical);\n }\n notify();\n };\n}\n\n/** Remove every presentation override. Mostly for tests. */\nexport function clearNodeKindOverrides(): void {\n if (overrides.size === 0) return;\n overrides.clear();\n notify();\n}\n\nfunction withOverride(kind: NodeKindDefinition | undefined): NodeKindDefinition | null {\n if (!kind) return null;\n const patch = overrides.get(kind.name);\n return patch ? ({ ...kind, ...patch } as NodeKindDefinition) : kind;\n}\n\n/** Get a single kind by canonical id or alias, or null. */\nexport function getNodeKind(name: string): NodeKindDefinition | null {\n const canonical = resolveKindId(name);\n return canonical ? withOverride(kinds.get(canonical) as NodeKindDefinition) : null;\n}\n\n/** Every id a kind answers to — canonical first. Used to key node-type maps. */\nexport function kindIds(kind: NodeKindDefinition): string[] {\n return [kind.name, ...(kind.aliases ?? [])];\n}\n\n/** List every registered kind, optionally filtered by category. */\nexport function listNodeKinds(category?: string): NodeKindDefinition[] {\n const all = Array.from(kinds.values()).map((k) =>\n withOverride(k as NodeKindDefinition),\n ) as NodeKindDefinition[];\n // Filter AFTER applying overrides, so an override that moves a node to a\n // different category actually moves it in the palette rather than leaving it\n // filed under the old one with a new name.\n return category ? all.filter((k) => k.category === category) : all;\n}\n\n/** Subscribe to registry changes. Returns an unsubscribe function. */\nexport function onNodeKindsChanged(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nfunction notify(): void {\n for (const l of listeners) l();\n}\n\n/** Fill in defaults from a kind's configSchema for newly-created nodes. */\nexport function defaultConfigFor(kind: NodeKindDefinition): Record<string, unknown> {\n const fromKind = kind.defaultConfig ? { ...(kind.defaultConfig as Record<string, unknown>) } : {};\n for (const field of kind.configSchema ?? []) {\n if (fromKind[field.key] !== undefined) continue;\n if (\"default\" in field && (field as any).default !== undefined) {\n fromKind[field.key] = (field as any).default;\n }\n }\n return fromKind;\n}\n\n/**\n * Validate a config object against a kind's schema. Returns an array of\n * issues (empty = valid). Validation is intentionally light — type\n * coercion + required-field checks. Hosts can layer Zod / Ajv on top.\n */\nexport function validateConfig(\n kind: NodeKindDefinition,\n config: Record<string, unknown>,\n): Array<{ key: string; message: string }> {\n const issues: Array<{ key: string; message: string }> = [];\n for (const field of kind.configSchema ?? []) {\n const value = config[field.key];\n if (field.required && (value === undefined || value === null || value === \"\")) {\n issues.push({ key: field.key, message: `${field.label} is required` });\n continue;\n }\n if (value === undefined || value === null) continue;\n const issue = validateField(field, value);\n if (issue) issues.push({ key: field.key, message: issue });\n }\n return issues;\n}\n\nfunction validateField(field: ConfigField, value: unknown): string | null {\n switch (field.type) {\n case \"text\":\n case \"textarea\":\n case \"expression\":\n case \"credential\":\n return typeof value === \"string\" ? null : `${field.label} must be a string`;\n case \"number\": {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return `${field.label} must be a number`;\n if (field.min !== undefined && value < field.min) return `${field.label} must be >= ${field.min}`;\n if (field.max !== undefined && value > field.max) return `${field.label} must be <= ${field.max}`;\n return null;\n }\n case \"switch\":\n return typeof value === \"boolean\" ? null : `${field.label} must be a boolean`;\n case \"select\": {\n const allowed = field.options.map((o) => o.value);\n return allowed.includes(String(value)) ? null : `${field.label} must be one of ${allowed.join(\", \")}`;\n }\n case \"json\":\n return null; // permissive — just JSON-shaped\n case \"repeater\": {\n if (!Array.isArray(value)) return `${field.label} must be a list`;\n if (field.minItems !== undefined && value.length < field.minItems) {\n return `${field.label} needs at least ${field.minItems}`;\n }\n if (field.maxItems !== undefined && value.length > field.maxItems) {\n return `${field.label} allows at most ${field.maxItems}`;\n }\n // Surface the first offending row so the author knows WHICH one.\n for (let i = 0; i < value.length; i++) {\n const row = value[i];\n if (!row || typeof row !== \"object\" || Array.isArray(row)) {\n return `${field.label} item ${i + 1} must be an object`;\n }\n for (const sub of field.fields) {\n const cell = (row as Record<string, unknown>)[sub.key];\n if (sub.required && (cell === undefined || cell === null || cell === \"\")) {\n return `${field.label} item ${i + 1}: ${sub.label} is required`;\n }\n if (cell === undefined || cell === null) continue;\n const issue = validateField(sub, cell);\n if (issue) return `${field.label} item ${i + 1}: ${issue}`;\n }\n }\n return null;\n }\n case \"keyvalue\": {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return `${field.label} must be a key/value map`;\n }\n const allowed = field.valueOptions?.map((o) => o.value);\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (typeof v !== \"string\") return `${field.label}: \"${k}\" must be a string`;\n if (allowed && !allowed.includes(v)) {\n return `${field.label}: \"${k}\" must be one of ${allowed.join(\", \")}`;\n }\n }\n return null;\n }\n case \"document\":\n return null; // opaque to fancy-flow — the host's editor owns its shape\n default:\n return null;\n }\n}\n\n/** Default accents per category. */\nexport function categoryAccent(category: string): string {\n switch (category) {\n case \"trigger\": return \"#10b981\";\n case \"logic\": return \"#f59e0b\";\n case \"data\": return \"#0ea5e9\";\n case \"ai\": return \"#8b5cf6\";\n case \"io\": return \"#3b82f6\";\n case \"human\": return \"#ec4899\";\n case \"output\": return \"#a855f7\";\n case \"layout\": return \"#64748b\";\n case \"annotation\": return \"#eab308\";\n default: return \"#71717a\";\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { runFlow } from './chunk-RE7T5GKQ.js';
1
+ import { runFlow } from './chunk-VLATLVGH.js';
2
2
 
3
3
  // src/runtime/run-cohort.ts
4
4
  async function runCohort(flows, executors, onEvent = () => {
@@ -46,5 +46,5 @@ function errorText(error) {
46
46
  }
47
47
 
48
48
  export { runCohort };
49
- //# sourceMappingURL=chunk-FKOXQP76.js.map
50
- //# sourceMappingURL=chunk-FKOXQP76.js.map
49
+ //# sourceMappingURL=chunk-QZTGV3ZL.js.map
50
+ //# sourceMappingURL=chunk-QZTGV3ZL.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime/run-cohort.ts"],"names":[],"mappings":";;;AAoFA,eAAsB,SAAA,CACpB,KAAA,EACA,SAAA,EACA,OAAA,GAAoD,MAAM;AAAC,CAAA,EAC3D,OAAA,GAAyB,EAAC,EACD;AACzB,EAAA,MAAM,EAAE,MAAA,GAAS,gBAAA,EAAkB,OAAO,MAAA,EAAQ,GAAG,YAAW,GAAI,OAAA;AAEpE,EAAA,IAAI,WAAW,UAAA,EAAY;AACzB,IAAA,OAAO,OAAA,CAAQ,GAAA;AAAA,MACb,KAAA,CAAM,GAAA,CAAI,OAAO,IAAA,EAAM,KAAA,MAAW;AAAA,QAChC,GAAI,MAAM,OAAA,CAAQ,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA,KAAM,OAAA,CAAQ,CAAA,EAAG,KAAK,CAAA,EAAG,UAAU,CAAA;AAAA,QACvE;AAAA,OACF,CAAE;AAAA,KACJ;AAAA,EACF;AAEA,EAAA,MAAM,UAA0B,EAAC;AAEjC,EAAA,KAAA,MAAW,CAAC,KAAA,EAAO,IAAI,CAAA,IAAK,KAAA,CAAM,SAAQ,EAAG;AAC3C,IAAA,IAAI,MAAA,KAAW,oBAAoB,KAAA,EAAO;AACxC,MAAA,MAAM,GAAA,GAAM,MAAM,MAAA,GAAS,IAAA,EAAM,KAAK,CAAA,IAAK,sCAAA;AAC3C,MAAA,IAAI,MAAA;AAEJ,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,MAAM,KAAA,CAAM,IAAA,EAAM,KAAK,CAAA;AAAA,MAClC,SAAS,KAAA,EAAO;AAGd,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,EAAA,EAAI,KAAA;AAAA,UACJ,SAAS,EAAC;AAAA,UACV,KAAA;AAAA,UACA,OAAA,EAAS,IAAA;AAAA,UACT,aAAA,EAAe,CAAA,8BAAA,EAAiC,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,SACjE,CAAA;AACD,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,EAAC,EAAG,KAAA,EAAO,OAAA,EAAS,IAAA,EAAM,aAAA,EAAe,GAAA,IAAO,CAAA;AACnF,QAAA;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,GAAI,MAAM,OAAA,CAAQ,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA,KAAM,OAAA,CAAQ,CAAA,EAAG,KAAK,CAAA,EAAG,UAAU,CAAA;AAAA,MACvE;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,UAAU,KAAA,EAAwB;AACzC,EAAA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAC9D","file":"chunk-FKOXQP76.js","sourcesContent":["import type { ExecutorRegistry, FlowGraph, RunEvent } from \"../types\";\nimport { runFlow, type RunOptions, type RunResult } from \"./run-flow\";\n\n/**\n * How the flows one trigger fired should treat each other.\n *\n * - `serial-guarded` (default) — run in the declared order, one at a time,\n * re-checking `guard` immediately before each. This is the safe default\n * because it is the only one that notices when an earlier flow invalidated\n * the state a later one was fired for.\n * - `serial` — ordered, one at a time, unguarded.\n * - `parallel` — all at once. Ordering is incidental and collisions are yours to\n * handle; correct for fan-outs that share no state, and only those.\n */\nexport type CohortPolicy = \"serial-guarded\" | \"serial\" | \"parallel\";\n\n/**\n * The precondition re-checked just before each flow starts.\n *\n * Return `false` (or throw) to skip that flow. The engine cannot know what\n * \"still valid\" means for your data, so it asks you — right before the run,\n * not at dispatch, because the whole hazard is what changed in between.\n */\nexport type CohortGuard = (\n flow: FlowGraph,\n index: number,\n) => boolean | Promise<boolean>;\n\nexport type CohortOptions = RunOptions & {\n policy?: CohortPolicy;\n guard?: CohortGuard;\n /** Why the guard said no — recorded on the skipped result. */\n reason?: (flow: FlowGraph, index: number) => string;\n};\n\nexport type CohortResult = RunResult & {\n index: number;\n /** True when the flow never ran because its guard did not pass. */\n skipped?: boolean;\n skippedReason?: string;\n};\n\n/**\n * runCohort — run every flow that one trigger event fired, as a group.\n *\n * ## Why this exists\n *\n * `runFlow` runs one graph. A host that fans a single webhook, schedule, or\n * record change out to several flows usually loops it — and a loop, or worse a\n * `Promise.all`, has no answer for the case that actually bites: one of those\n * flows deletes or mutates the record they were ALL fired for. The others then\n * run against state that is no longer there and resolve `ok: true`, having done\n * nothing. Nothing throws. Nothing is logged. That silent success is the failure\n * mode this function exists to remove.\n *\n * ## What it does\n *\n * Runs the flows in the order you declared, one at a time, and calls `guard`\n * immediately before each. A flow whose guard does not pass is returned with\n * `skipped: true` and a reason instead of being run — and the cohort carries on\n * to the next one.\n *\n * ```ts\n * const results = await runCohort([enrich, archive, notify], executors, undefined, {\n * initialInputs: { t: { deal } }, // snapshotted once, shared by all\n * guard: async () => Boolean(await findDeal(deal.id)),\n * reason: () => `deal ${deal.id} no longer exists`,\n * });\n * ```\n *\n * If `archive` deletes the deal, `notify` comes back skipped with that reason\n * rather than notifying about nothing.\n *\n * ## Failure does not cancel the cohort\n *\n * A flow that fails is reported and the next one still runs. \"The flow before me\n * threw\" is not an answer to \"is my input still there\" — the guard is, and it\n * gets asked either way.\n *\n * The Laravel twin (`FancyFlow::dispatchCohort()` in `fancy-flow-php`) is the\n * same contract across a queue, where each run is durable and hands on to its\n * successor when it settles. Same policies, same guard semantics, same\n * fail-closed rule.\n */\nexport async function runCohort(\n flows: FlowGraph[],\n executors: ExecutorRegistry,\n onEvent: (event: RunEvent, index: number) => void = () => {},\n options: CohortOptions = {},\n): Promise<CohortResult[]> {\n const { policy = \"serial-guarded\", guard, reason, ...runOptions } = options;\n\n if (policy === \"parallel\") {\n return Promise.all(\n flows.map(async (flow, index) => ({\n ...(await runFlow(flow, executors, (e) => onEvent(e, index), runOptions)),\n index,\n })),\n );\n }\n\n const results: CohortResult[] = [];\n\n for (const [index, flow] of flows.entries()) {\n if (policy === \"serial-guarded\" && guard) {\n const why = () => reason?.(flow, index) ?? \"trigger precondition no longer holds\";\n let passes: boolean;\n\n try {\n passes = await guard(flow, index);\n } catch (error) {\n // Fail CLOSED. A guard that cannot answer is not permission to proceed:\n // a skip is visible and re-runnable, a run over missing state is neither.\n results.push({\n ok: false,\n outputs: {},\n index,\n skipped: true,\n skippedReason: `guard could not be evaluated: ${errorText(error)}`,\n });\n continue;\n }\n\n if (!passes) {\n results.push({ ok: false, outputs: {}, index, skipped: true, skippedReason: why() });\n continue;\n }\n }\n\n results.push({\n ...(await runFlow(flow, executors, (e) => onEvent(e, index), runOptions)),\n index,\n });\n }\n\n return results;\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
1
+ {"version":3,"sources":["../src/runtime/run-cohort.ts"],"names":[],"mappings":";;;AAoFA,eAAsB,SAAA,CACpB,KAAA,EACA,SAAA,EACA,OAAA,GAAoD,MAAM;AAAC,CAAA,EAC3D,OAAA,GAAyB,EAAC,EACD;AACzB,EAAA,MAAM,EAAE,MAAA,GAAS,gBAAA,EAAkB,OAAO,MAAA,EAAQ,GAAG,YAAW,GAAI,OAAA;AAEpE,EAAA,IAAI,WAAW,UAAA,EAAY;AACzB,IAAA,OAAO,OAAA,CAAQ,GAAA;AAAA,MACb,KAAA,CAAM,GAAA,CAAI,OAAO,IAAA,EAAM,KAAA,MAAW;AAAA,QAChC,GAAI,MAAM,OAAA,CAAQ,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA,KAAM,OAAA,CAAQ,CAAA,EAAG,KAAK,CAAA,EAAG,UAAU,CAAA;AAAA,QACvE;AAAA,OACF,CAAE;AAAA,KACJ;AAAA,EACF;AAEA,EAAA,MAAM,UAA0B,EAAC;AAEjC,EAAA,KAAA,MAAW,CAAC,KAAA,EAAO,IAAI,CAAA,IAAK,KAAA,CAAM,SAAQ,EAAG;AAC3C,IAAA,IAAI,MAAA,KAAW,oBAAoB,KAAA,EAAO;AACxC,MAAA,MAAM,GAAA,GAAM,MAAM,MAAA,GAAS,IAAA,EAAM,KAAK,CAAA,IAAK,sCAAA;AAC3C,MAAA,IAAI,MAAA;AAEJ,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,MAAM,KAAA,CAAM,IAAA,EAAM,KAAK,CAAA;AAAA,MAClC,SAAS,KAAA,EAAO;AAGd,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,EAAA,EAAI,KAAA;AAAA,UACJ,SAAS,EAAC;AAAA,UACV,KAAA;AAAA,UACA,OAAA,EAAS,IAAA;AAAA,UACT,aAAA,EAAe,CAAA,8BAAA,EAAiC,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,SACjE,CAAA;AACD,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,EAAC,EAAG,KAAA,EAAO,OAAA,EAAS,IAAA,EAAM,aAAA,EAAe,GAAA,IAAO,CAAA;AACnF,QAAA;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,GAAI,MAAM,OAAA,CAAQ,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA,KAAM,OAAA,CAAQ,CAAA,EAAG,KAAK,CAAA,EAAG,UAAU,CAAA;AAAA,MACvE;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,UAAU,KAAA,EAAwB;AACzC,EAAA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAC9D","file":"chunk-QZTGV3ZL.js","sourcesContent":["import type { ExecutorRegistry, FlowGraph, RunEvent } from \"../types\";\nimport { runFlow, type RunOptions, type RunResult } from \"./run-flow\";\n\n/**\n * How the flows one trigger fired should treat each other.\n *\n * - `serial-guarded` (default) — run in the declared order, one at a time,\n * re-checking `guard` immediately before each. This is the safe default\n * because it is the only one that notices when an earlier flow invalidated\n * the state a later one was fired for.\n * - `serial` — ordered, one at a time, unguarded.\n * - `parallel` — all at once. Ordering is incidental and collisions are yours to\n * handle; correct for fan-outs that share no state, and only those.\n */\nexport type CohortPolicy = \"serial-guarded\" | \"serial\" | \"parallel\";\n\n/**\n * The precondition re-checked just before each flow starts.\n *\n * Return `false` (or throw) to skip that flow. The engine cannot know what\n * \"still valid\" means for your data, so it asks you — right before the run,\n * not at dispatch, because the whole hazard is what changed in between.\n */\nexport type CohortGuard = (\n flow: FlowGraph,\n index: number,\n) => boolean | Promise<boolean>;\n\nexport type CohortOptions = RunOptions & {\n policy?: CohortPolicy;\n guard?: CohortGuard;\n /** Why the guard said no — recorded on the skipped result. */\n reason?: (flow: FlowGraph, index: number) => string;\n};\n\nexport type CohortResult = RunResult & {\n index: number;\n /** True when the flow never ran because its guard did not pass. */\n skipped?: boolean;\n skippedReason?: string;\n};\n\n/**\n * runCohort — run every flow that one trigger event fired, as a group.\n *\n * ## Why this exists\n *\n * `runFlow` runs one graph. A host that fans a single webhook, schedule, or\n * record change out to several flows usually loops it — and a loop, or worse a\n * `Promise.all`, has no answer for the case that actually bites: one of those\n * flows deletes or mutates the record they were ALL fired for. The others then\n * run against state that is no longer there and resolve `ok: true`, having done\n * nothing. Nothing throws. Nothing is logged. That silent success is the failure\n * mode this function exists to remove.\n *\n * ## What it does\n *\n * Runs the flows in the order you declared, one at a time, and calls `guard`\n * immediately before each. A flow whose guard does not pass is returned with\n * `skipped: true` and a reason instead of being run — and the cohort carries on\n * to the next one.\n *\n * ```ts\n * const results = await runCohort([enrich, archive, notify], executors, undefined, {\n * initialInputs: { t: { deal } }, // snapshotted once, shared by all\n * guard: async () => Boolean(await findDeal(deal.id)),\n * reason: () => `deal ${deal.id} no longer exists`,\n * });\n * ```\n *\n * If `archive` deletes the deal, `notify` comes back skipped with that reason\n * rather than notifying about nothing.\n *\n * ## Failure does not cancel the cohort\n *\n * A flow that fails is reported and the next one still runs. \"The flow before me\n * threw\" is not an answer to \"is my input still there\" — the guard is, and it\n * gets asked either way.\n *\n * The Laravel twin (`FancyFlow::dispatchCohort()` in `fancy-flow-php`) is the\n * same contract across a queue, where each run is durable and hands on to its\n * successor when it settles. Same policies, same guard semantics, same\n * fail-closed rule.\n */\nexport async function runCohort(\n flows: FlowGraph[],\n executors: ExecutorRegistry,\n onEvent: (event: RunEvent, index: number) => void = () => {},\n options: CohortOptions = {},\n): Promise<CohortResult[]> {\n const { policy = \"serial-guarded\", guard, reason, ...runOptions } = options;\n\n if (policy === \"parallel\") {\n return Promise.all(\n flows.map(async (flow, index) => ({\n ...(await runFlow(flow, executors, (e) => onEvent(e, index), runOptions)),\n index,\n })),\n );\n }\n\n const results: CohortResult[] = [];\n\n for (const [index, flow] of flows.entries()) {\n if (policy === \"serial-guarded\" && guard) {\n const why = () => reason?.(flow, index) ?? \"trigger precondition no longer holds\";\n let passes: boolean;\n\n try {\n passes = await guard(flow, index);\n } catch (error) {\n // Fail CLOSED. A guard that cannot answer is not permission to proceed:\n // a skip is visible and re-runnable, a run over missing state is neither.\n results.push({\n ok: false,\n outputs: {},\n index,\n skipped: true,\n skippedReason: `guard could not be evaluated: ${errorText(error)}`,\n });\n continue;\n }\n\n if (!passes) {\n results.push({ ok: false, outputs: {}, index, skipped: true, skippedReason: why() });\n continue;\n }\n }\n\n results.push({\n ...(await runFlow(flow, executors, (e) => onEvent(e, index), runOptions)),\n index,\n });\n }\n\n return results;\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  import { NodeResizer, NodeToolbar, Handle, Position } from './chunk-OWENS2H5.js';
2
2
  import { getWorkflowResolver, isResolutionFailure, getLlmClient } from './chunk-USL4FMFU.js';
3
- import { runFlow } from './chunk-RE7T5GKQ.js';
3
+ import { runFlow } from './chunk-VLATLVGH.js';
4
4
  import { resolveNodePorts, nodeConfig } from './chunk-TITD5W4Y.js';
5
- import { getNodeKind, categoryAccent, registerNodeKind, listNodeKinds, kindIds } from './chunk-Q6IPK64P.js';
5
+ import { getNodeKind, categoryAccent, registerNodeKind, listNodeKinds, kindIds } from './chunk-PVROYW7C.js';
6
6
  import { RichInputPreview } from './chunk-F5RPRB7A.js';
7
7
  import { memo, createContext, useMemo, useState, useRef, useEffect, useContext, createElement } from 'react';
8
8
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -1225,5 +1225,5 @@ function buildNodeTypes() {
1225
1225
  }
1226
1226
 
1227
1227
  export { ANY_PORT_TYPE, BUILTIN_KINDS, DEFAULT_MAX_DEPTH, FlowEditorProvider, LaneNode, NoteNode, RegistryNode, buildNodeTypes, createConnectionValidator, declaredRoutes, defaultPortCompatibility, llmRouterExecutor, registerBuiltinKinds, resolveFallbackPort, subflowExecutor, subflowMode, subflowPorts, useFlowEditor, useFlowEditorOptional };
1228
- //# sourceMappingURL=chunk-THU5LW22.js.map
1229
- //# sourceMappingURL=chunk-THU5LW22.js.map
1228
+ //# sourceMappingURL=chunk-UX65ML3J.js.map
1229
+ //# sourceMappingURL=chunk-UX65ML3J.js.map