{"version":3,"file":"use-on-graph-events.cjs","sources":["../../../src/hooks/use-on-graph-events.ts"],"sourcesContent":["import { mvc, type dia } from '@joint/core';\nimport { useContext } from 'react';\nimport { GraphStoreContext } from '../context';\nimport { isRecord } from '../utils/is';\nimport { useOnEvents } from './use-on-events';\n\nconst EMPTY_HANDLERS: GraphEventMap = {};\n\n/**\n * Checks if a value is a JointJS graph instance.\n * @param value - Candidate value.\n * @returns True when value behaves like `dia.Graph`.\n */\nfunction isGraphInstance(value: unknown): value is dia.Graph {\n  return isRecord(value) && 'addCell' in value;\n}\n\n/**\n * Subscribes all handlers to a graph using mvc.Listener.\n * @param graph - Graph instance to subscribe on.\n * @param handlers - Event handlers keyed by JointJS graph event names.\n * @returns Cleanup callback that stops all listeners.\n */\nfunction subscribeToGraphEvents(graph: dia.Graph, handlers: GraphEventMap): () => void {\n  const controller = new mvc.Listener();\n\n  for (const eventName in handlers) {\n    const handler = handlers[eventName];\n    if (!handler) continue;\n\n    controller.listenTo(graph, eventName, (...args: Parameters<mvc.EventHandler>) => {\n      handler(...args);\n    });\n  }\n\n  return () => controller.stopListening();\n}\n\n/**\n * Maps JointJS graph event names to their handler callbacks, the shape\n * {@link useOnGraphEvents} accepts. Every entry is optional, list only the\n * events you want to react to. Keys and handler arguments mirror\n * [`dia.Graph` events](https://docs.jointjs.com/api/dia/Graph#events) one to one\n * (`'add'`, `'remove'`, `'change:position'`, …).\n * @group Types\n */\nexport type GraphEventMap = Partial<dia.Graph.EventMap>;\n\n/**\n * Subscribes to graph events by their native JointJS names, so you can react to\n * cells being added, removed, moved, or otherwise changed without wiring up\n * listeners by hand. This form reads the graph from the surrounding\n * `<GraphProvider>` and throws when used outside one.\n *\n * Handlers are **always-latest**: the subscription is established once and each\n * event reads the current handler, so inline maps and closures need no\n * `useCallback`. Re-subscription happens only when the graph or the set of event\n * names changes.\n *\n * See {@link GraphEventMap} for the available event names and their arguments.\n * @title On the current graph\n * @param handlers - Map of JointJS graph event names to callbacks.\n * @group Hooks\n * @example\n * ```tsx\n * import { GraphProvider, useOnGraphEvents } from '@joint/react';\n *\n * function CellLogger() {\n *   useOnGraphEvents({\n *     add: (cell) => console.log('added', cell.id),\n *     remove: (cell) => console.log('removed', cell.id),\n *     'change:position': (cell) => console.log('moved', cell.id),\n *   });\n *   return null;\n * }\n *\n * // Mount inside a <GraphProvider> so the hook can find the graph.\n * <GraphProvider>\n *   <CellLogger />\n * </GraphProvider>\n * ```\n */\nexport function useOnGraphEvents(handlers: GraphEventMap): void;\n/**\n * Subscribes to graph events on a graph instance you pass in explicitly. Reach\n * for this when you hold a `dia.Graph` outside of any `<GraphProvider>` (e.g. a\n * graph you created yourself). Same always-latest handler semantics as the\n * context form.\n * @title On a specific graph\n * @param graph - The graph instance to listen on.\n * @param handlers - Map of JointJS graph event names to callbacks.\n * @group Hooks\n * @example\n * ```tsx\n * import { dia } from '@joint/core';\n * import { useOnGraphEvents } from '@joint/react';\n *\n * function useGraphLogger(graph: dia.Graph) {\n *   useOnGraphEvents(graph, {\n *     add: (cell) => console.log('added', cell.id),\n *   });\n * }\n * ```\n */\nexport function useOnGraphEvents(graph: dia.Graph, handlers: GraphEventMap): void;\nexport function useOnGraphEvents(\n  graphOrHandlers: dia.Graph | GraphEventMap,\n  handlersArgument?: GraphEventMap\n): void {\n  const graphStore = useContext(GraphStoreContext);\n  const isTargetForm = isGraphInstance(graphOrHandlers);\n\n  if (!isTargetForm && !graphStore) {\n    throw new Error('useOnGraphEvents without a graph target must be used within a GraphProvider.');\n  }\n\n  const graph = isTargetForm ? graphOrHandlers : graphStore?.graph ?? null;\n  const handlers = isTargetForm ? handlersArgument ?? EMPTY_HANDLERS : graphOrHandlers;\n\n  useOnEvents(graph, handlers, subscribeToGraphEvents);\n}\n"],"names":["isRecord","mvc","useContext","GraphStoreContext","useOnEvents"],"mappings":"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"}