{"$schema":"https:\/\/ui.particle.academy\/schema\/registry-item.json","name":"use-flow-state","type":"registry:ui","title":"useFlowState","description":"Controlled state hook.","package":"fancy-flow","dependencies":["@xyflow\/react"],"registryDependencies":["types"],"files":[{"path":"components\/fancy\/use-flow-state\/use-flow-state.ts","content":"import { useCallback, useState } from \"react\";\r\nimport {\r\n  addEdge,\r\n  applyEdgeChanges,\r\n  applyNodeChanges,\r\n  type Connection,\r\n  type Edge,\r\n  type EdgeChange,\r\n  type NodeChange,\r\n} from \"@xyflow\/react\";\r\nimport type { FlowEdge, FlowGraph, FlowNode } from \"..\/types\";\r\n\r\nexport type UseFlowStateReturn = {\r\n  nodes: FlowNode[];\r\n  edges: FlowEdge[];\r\n  setNodes: React.Dispatch<React.SetStateAction<FlowNode[]>>;\r\n  setEdges: React.Dispatch<React.SetStateAction<FlowEdge[]>>;\r\n  \/**\r\n   * Replace nodes AND edges atomically in a single commit. Use this for any op\r\n   * that touches both (delete-with-edge-prune, undo\/redo restore, setGraph):\r\n   * calling `setNodes` then `setEdges` is NOT atomic in controlled mode (each\r\n   * closes over a stale `value`), so the second write clobbers the first.\r\n   *\/\r\n  setGraph: (graph: FlowGraph) => void;\r\n  onNodesChange: (changes: NodeChange[]) => void;\r\n  onEdgesChange: (changes: EdgeChange[]) => void;\r\n  onConnect: (connection: Connection) => void;\r\n  \/** Snapshot the current graph (suitable for serialization). *\/\r\n  toGraph: () => FlowGraph;\r\n};\r\n\r\n\/**\r\n * useFlowState \u2014 React Flow's standard controlled-state plumbing in one hook.\r\n * Spread into <FlowCanvas>.\r\n *\/\r\nexport function useFlowState(initial: FlowGraph): UseFlowStateReturn {\r\n  const [nodes, setNodes] = useState<FlowNode[]>(initial.nodes);\r\n  const [edges, setEdges] = useState<FlowEdge[]>(initial.edges);\r\n\r\n  const onNodesChange = useCallback((changes: NodeChange[]) => {\r\n    setNodes((ns) => applyNodeChanges(changes, ns) as FlowNode[]);\r\n  }, []);\r\n  const onEdgesChange = useCallback((changes: EdgeChange[]) => {\r\n    setEdges((es) => applyEdgeChanges(changes, es));\r\n  }, []);\r\n  const onConnect = useCallback((connection: Connection) => {\r\n    setEdges((es) => addEdge(connection, es) as Edge[]);\r\n  }, []);\r\n\r\n  const setGraph = useCallback((graph: FlowGraph) => {\r\n    \/\/ Two useState writes in one event are batched, so this IS atomic here.\r\n    setNodes(graph.nodes);\r\n    setEdges(graph.edges);\r\n  }, []);\r\n\r\n  const toGraph = useCallback(() => ({ nodes, edges }), [nodes, edges]);\r\n\r\n  return { nodes, edges, setNodes, setEdges, setGraph, onNodesChange, onEdgesChange, onConnect, toGraph };\r\n}\r\n","type":"registry:ui","target":"components\/fancy\/use-flow-state\/use-flow-state.ts"}]}