@modernrelay/orbit-react 0.2.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/LICENSE +21 -0
  2. package/dist/GraphProvider-B8ITDXS0.d.ts +11 -0
  3. package/dist/chunk-7XB47YST.js +69 -0
  4. package/dist/chunk-7XB47YST.js.map +1 -0
  5. package/dist/chunk-DGFLU2SN.js +108 -0
  6. package/dist/chunk-DGFLU2SN.js.map +1 -0
  7. package/dist/chunk-JN7QCMFW.js +93 -0
  8. package/dist/chunk-JN7QCMFW.js.map +1 -0
  9. package/dist/chunk-QJ7JXQVK.js +119 -0
  10. package/dist/chunk-QJ7JXQVK.js.map +1 -0
  11. package/dist/components/ContextMenu.d.ts +73 -0
  12. package/dist/components/ContextMenu.js +367 -0
  13. package/dist/components/ContextMenu.js.map +1 -0
  14. package/dist/components/Histogram.d.ts +33 -0
  15. package/dist/components/Histogram.js +216 -0
  16. package/dist/components/Histogram.js.map +1 -0
  17. package/dist/components/Inspector.d.ts +63 -0
  18. package/dist/components/Inspector.js +246 -0
  19. package/dist/components/Inspector.js.map +1 -0
  20. package/dist/components/Legend.d.ts +45 -0
  21. package/dist/components/Legend.js +185 -0
  22. package/dist/components/Legend.js.map +1 -0
  23. package/dist/components/Minimap.d.ts +63 -0
  24. package/dist/components/Minimap.js +222 -0
  25. package/dist/components/Minimap.js.map +1 -0
  26. package/dist/components/Navigator.d.ts +90 -0
  27. package/dist/components/Navigator.js +381 -0
  28. package/dist/components/Navigator.js.map +1 -0
  29. package/dist/components/Search.d.ts +70 -0
  30. package/dist/components/Search.js +203 -0
  31. package/dist/components/Search.js.map +1 -0
  32. package/dist/components/SelectionActions.d.ts +36 -0
  33. package/dist/components/SelectionActions.js +126 -0
  34. package/dist/components/SelectionActions.js.map +1 -0
  35. package/dist/components/SimControls.d.ts +124 -0
  36. package/dist/components/SimControls.js +221 -0
  37. package/dist/components/SimControls.js.map +1 -0
  38. package/dist/components/Table.d.ts +92 -0
  39. package/dist/components/Table.js +505 -0
  40. package/dist/components/Table.js.map +1 -0
  41. package/dist/components/Timeline.d.ts +34 -0
  42. package/dist/components/Timeline.js +182 -0
  43. package/dist/components/Timeline.js.map +1 -0
  44. package/dist/components/Toolbar.d.ts +60 -0
  45. package/dist/components/Toolbar.js +220 -0
  46. package/dist/components/Toolbar.js.map +1 -0
  47. package/dist/components/Tooltip.d.ts +65 -0
  48. package/dist/components/Tooltip.js +178 -0
  49. package/dist/components/Tooltip.js.map +1 -0
  50. package/dist/index.d.ts +488 -0
  51. package/dist/index.js +827 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/shared-Bj3Gk219.d.ts +43 -0
  54. package/package.json +99 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Lasso.tsx","../src/LabelLayer.tsx","../src/LiveRegion.tsx","../src/Graph.tsx"],"names":["useState","useRef","useEffect","jsx","useLayoutEffect","prevRef"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Lasso — the Shift+drag freeform selection overlay (§16.2, S6-T05 React half).\n *\n * A transparent div rendered above the engine canvas that captures pointer\n * events ONLY while Shift is held (or a lasso drag is already in progress);\n * otherwise `pointer-events: none` so it never intercepts canvas interaction.\n *\n * Gesture: pointerdown starts capture; pointermove appends polygon points\n * throttled to at most one per animation frame (leading edge + trailing\n * commit); an SVG path previews the polygon; pointerup with ≥3 points calls\n * `instance.selectWithinPolygon(polygon, { additive: metaKey })`. Abort paths\n * (pointercancel, Escape, unmount) always release capture and leave no state.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { CSSProperties, PointerEvent as ReactPointerEvent, ReactElement } from 'react';\nimport { useAmbientGraphInstance } from './GraphProvider';\n\ninterface DragState {\n pointerId: number;\n /** Committed polygon vertices (overlay-local screen coordinates). */\n points: [number, number][];\n /** Latest uncommitted pointer position (throttle window open). */\n pending: [number, number] | null;\n /** Scheduled animation frame id; null when no frame is pending. */\n frame: number | null;\n}\n\nconst OVERLAY_BASE: CSSProperties = {\n position: 'absolute',\n inset: 0,\n touchAction: 'none',\n userSelect: 'none',\n};\n\nconst OVERLAY_INACTIVE: CSSProperties = { ...OVERLAY_BASE, pointerEvents: 'none' };\nconst OVERLAY_ACTIVE: CSSProperties = {\n ...OVERLAY_BASE,\n pointerEvents: 'auto',\n cursor: 'crosshair',\n};\n\nconst SVG_STYLE: CSSProperties = {\n position: 'absolute',\n inset: 0,\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n overflow: 'visible',\n};\n\nfunction toPathData(points: readonly [number, number][]): string {\n let d = `M ${points[0]![0]} ${points[0]![1]}`;\n for (let i = 1; i < points.length; i++) d += ` L ${points[i]![0]} ${points[i]![1]}`;\n return points.length >= 3 ? `${d} Z` : d;\n}\n\n/** rAF when available; otherwise run synchronously (headless environments —\n * throttling degrades to per-event appends, which is still correct). */\nfunction scheduleFrame(cb: () => void): number | null {\n if (typeof requestAnimationFrame === 'function') return requestAnimationFrame(cb);\n cb();\n return null;\n}\n\nfunction cancelFrame(id: number | null): void {\n if (id !== null && typeof cancelAnimationFrame === 'function') cancelAnimationFrame(id);\n}\n\n/** Guarded pointer capture: jsdom (and older engines) may not implement it. */\nfunction capturePointer(el: HTMLElement, pointerId: number): void {\n if (typeof el.setPointerCapture === 'function') {\n try {\n el.setPointerCapture(pointerId);\n } catch {\n /* capture unavailable for this pointer — the gesture still works */\n }\n }\n}\n\nfunction releasePointer(el: HTMLElement, pointerId: number): void {\n if (typeof el.releasePointerCapture === 'function') {\n try {\n el.releasePointerCapture(pointerId);\n } catch {\n /* no active capture — already released */\n }\n }\n}\n\n/** Internal to <Graph> (gated by its `enableLasso` prop); reads the ambient\n * instance so advanced hosts composing GraphProvider directly can reuse it. */\nexport function Lasso(): ReactElement {\n const instance = useAmbientGraphInstance('Lasso');\n const overlayRef = useRef<HTMLDivElement | null>(null);\n const dragRef = useRef<DragState | null>(null);\n const [shiftHeld, setShiftHeld] = useState(false);\n /** Render mirror of the committed polygon; null = no drag in progress. */\n const [preview, setPreview] = useState<readonly [number, number][] | null>(null);\n\n /** Tear down the in-progress drag: cancel the pending frame, release\n * capture, clear all drag state. Safe to call when idle. */\n const releaseDrag = useCallback((): void => {\n const drag = dragRef.current;\n if (drag === null) return;\n dragRef.current = null;\n cancelFrame(drag.frame);\n const el = overlayRef.current;\n if (el !== null) releasePointer(el, drag.pointerId);\n setPreview(null);\n }, []);\n\n // Shift tracking + Escape abort. Window-level so the overlay activates\n // before it can receive any pointer event; blur releases a stuck Shift.\n useEffect(() => {\n const onKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Shift') setShiftHeld(true);\n else if (e.key === 'Escape') releaseDrag();\n };\n const onKeyUp = (e: KeyboardEvent): void => {\n if (e.key === 'Shift') setShiftHeld(false);\n };\n const onBlur = (): void => setShiftHeld(false);\n window.addEventListener('keydown', onKeyDown);\n window.addEventListener('keyup', onKeyUp);\n window.addEventListener('blur', onBlur);\n return () => {\n window.removeEventListener('keydown', onKeyDown);\n window.removeEventListener('keyup', onKeyUp);\n window.removeEventListener('blur', onBlur);\n releaseDrag(); // unmount mid-drag leaves no capture and no frame\n };\n }, [releaseDrag]);\n\n const localPoint = (e: ReactPointerEvent<HTMLDivElement>): [number, number] => {\n const el = overlayRef.current;\n if (el === null) return [e.clientX, e.clientY];\n const rect = el.getBoundingClientRect();\n return [e.clientX - rect.left, e.clientY - rect.top];\n };\n\n const commitPending = (drag: DragState): void => {\n if (drag.pending === null) return;\n drag.points.push(drag.pending);\n drag.pending = null;\n setPreview([...drag.points]);\n };\n\n const onPointerDown = (e: ReactPointerEvent<HTMLDivElement>): void => {\n if (dragRef.current !== null || e.button !== 0) return;\n // Lasso is a Shift gesture: the overlay only receives events while Shift\n // is held, but re-check for robustness (tests, synthetic dispatch).\n if (!e.shiftKey && !shiftHeld) return;\n const pointerId = e.pointerId ?? -1;\n const el = overlayRef.current;\n if (el !== null) capturePointer(el, pointerId);\n const p = localPoint(e);\n dragRef.current = { pointerId, points: [p], pending: null, frame: null };\n setPreview([p]);\n e.preventDefault();\n };\n\n const onPointerMove = (e: ReactPointerEvent<HTMLDivElement>): void => {\n const drag = dragRef.current;\n if (drag === null || (e.pointerId ?? -1) !== drag.pointerId) return;\n drag.pending = localPoint(e);\n if (drag.frame !== null) return; // throttle window open — coalesce\n // Leading edge: append immediately, then hold the window one frame at a\n // time while moves keep streaming in (trailing commit per frame).\n commitPending(drag);\n const tick = (): void => {\n drag.frame = null;\n if (dragRef.current !== drag) return; // drag ended while scheduled\n if (drag.pending !== null) {\n commitPending(drag);\n drag.frame = scheduleFrame(tick);\n }\n };\n drag.frame = scheduleFrame(tick);\n };\n\n const onPointerUp = (e: ReactPointerEvent<HTMLDivElement>): void => {\n const drag = dragRef.current;\n if (drag === null || (e.pointerId ?? -1) !== drag.pointerId) return;\n commitPending(drag); // the trailing point must land in the polygon\n const polygon = drag.points;\n const additive = e.metaKey;\n releaseDrag();\n if (polygon.length >= 3) instance.selectWithinPolygon(polygon, { additive });\n };\n\n const onPointerCancel = (e: ReactPointerEvent<HTMLDivElement>): void => {\n const drag = dragRef.current;\n if (drag === null || (e.pointerId ?? -1) !== drag.pointerId) return;\n releaseDrag();\n };\n\n const active = shiftHeld || preview !== null;\n return (\n <div\n ref={overlayRef}\n data-orbit-lasso=\"\"\n style={active ? OVERLAY_ACTIVE : OVERLAY_INACTIVE}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerCancel}\n >\n {preview !== null && preview.length > 0 ? (\n <svg data-orbit-lasso-preview=\"\" style={SVG_STYLE}>\n <path\n d={toPathData(preview)}\n fill=\"rgba(88, 134, 255, 0.12)\"\n stroke=\"rgba(88, 134, 255, 0.9)\"\n strokeWidth={1.5}\n strokeDasharray=\"4 3\"\n />\n </svg>\n ) : null}\n </div>\n );\n}\n","/**\n * LabelLayer — the §14 DOM label lane (S7-T05).\n *\n * Two-channel rendering against the pinned overlay interface:\n * - `labels.subscribeCandidates` fires only when the candidate SET changes →\n * React state → one absolutely-positioned <div> per candidate. Label text\n * is rendered as a TEXT NODE only (never markup), so hostile strings in\n * node attrs appear literally.\n * - `labels.subscribePositions` fires on scheduler ticks with fresh x/y for\n * the SAME set → imperative `style.transform` writes through refs keyed by\n * id. No React re-render per tick (M0: the label lane is pure CPU O(k)).\n *\n * The layer is pointer-inert; label divs opt back in and drive the S6\n * click-selection path through the same public mutators (replace on plain\n * click, toggle on meta/shift — S7-T17).\n */\n\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport type { CSSProperties, MouseEvent as ReactMouseEvent, ReactElement, ReactNode } from 'react';\nimport type { GraphNode, LabelPlacement, NodeId } from '@modernrelay/orbit-core';\nimport { useAmbientGraphInstance } from './GraphProvider';\nimport { overlaySurface, overlayLayerStyle } from './components/shared';\n\nexport interface LabelLayerProps {\n /** Class hook applied to every label div. */\n labelClassName?: string | undefined;\n /** Escape hatch rendered INSIDE the positioned div instead of the text node. */\n renderNodeLabel?: ((ctx: { node: GraphNode<any>; text: string }) => ReactNode) | undefined;\n /** Class hook applied to §16.3 CLUSTER label divs (in addition to\n * `labelClassName`), so the coarse layer can be styled apart. */\n clusterLabelClassName?: string | undefined;\n /** Escape hatch for cluster labels; `memberIds` are the ids a click\n * selects (R-16.3-18). */\n renderClusterLabel?:\n | ((ctx: { clusterKey: string; text: string; memberIds: readonly NodeId[] }) => ReactNode)\n | undefined;\n}\n\n/** Placements come from two id namespaces (node ids and cluster keys), so\n * element/position maps and React keys are keyed on `(kind, id)`. */\nfunction placementKey(p: LabelPlacement): string {\n return p.kind === 'cluster' ? `cluster\\u0000${p.id}` : `node\\u0000${p.id}`;\n}\n\nconst LAYER_STYLE: CSSProperties = { ...overlayLayerStyle, overflow: 'hidden' };\n\nconst LABEL_BASE_STYLE: CSSProperties = {\n position: 'absolute',\n top: 0,\n left: 0,\n pointerEvents: 'auto',\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n userSelect: 'none',\n willChange: 'transform',\n};\n\nfunction transformOf(x: number, y: number): string {\n return `translate3d(${x}px, ${y}px, 0)`;\n}\n\n/** Internal to <Graph> (gated by `labels.enabled`); reads the ambient\n * instance so hosts composing GraphProvider directly can reuse it. */\nexport function LabelLayer(props: LabelLayerProps): ReactElement {\n const instance = useAmbientGraphInstance('LabelLayer');\n const labels = overlaySurface(instance).labels;\n\n const [candidates, setCandidates] = useState<readonly LabelPlacement[]>([]);\n /** Live label elements, keyed by `(kind, id)` (populated via ref callbacks). */\n const elementsRef = useRef(new Map<string, HTMLDivElement>());\n /** Freshest known screen position per candidate — written by BOTH channels\n * so a candidate re-render never snaps back to a stale x/y. */\n const positionsRef = useRef(new Map<string, readonly [number, number]>());\n\n // Candidate SET changes: throttled re-rank → React re-render of the content.\n useEffect(() => {\n if (labels === undefined) return undefined;\n return labels.subscribeCandidates((list) => {\n const positions = positionsRef.current;\n const keep = new Set<string>();\n for (const p of list) {\n const key = placementKey(p);\n keep.add(key);\n positions.set(key, [p.x, p.y]);\n }\n for (const key of [...positions.keys()]) {\n if (!keep.has(key)) positions.delete(key);\n }\n // The core REUSES the emitted array/placement objects across ticks —\n // copy so React state gets a fresh identity (no Object.is bail-out).\n setCandidates(list.map((p) => ({ ...p })));\n });\n }, [labels]);\n\n // Scheduler position ticks: imperative transform writes, no re-render.\n useLayoutEffect(() => {\n if (labels === undefined) return undefined;\n return labels.subscribePositions((list) => {\n const elements = elementsRef.current;\n const positions = positionsRef.current;\n for (const p of list) {\n const key = placementKey(p);\n positions.set(key, [p.x, p.y]);\n const el = elements.get(key);\n if (el !== undefined) el.style.transform = transformOf(p.x, p.y);\n }\n });\n }, [labels]);\n\n // S6 click-selection semantics through the public mutators (S7-T17):\n // plain click replaces the node selection; meta/shift click toggles the id.\n const onLabelClick = (id: NodeId, e: ReactMouseEvent<HTMLDivElement>): void => {\n e.stopPropagation();\n if (e.metaKey || e.shiftKey) {\n const cur = instance.store.getState().selection.nodeIds;\n instance.setSelection(cur.includes(id) ? cur.filter((x) => x !== id) : [...cur, id]);\n return;\n }\n instance.setSelection([id]);\n };\n\n // R-16.3-18: a cluster label resolves to its MEMBER node ids through the\n // core mutator — clusters never enter the group selection namespace.\n const onClusterLabelClick = (key: string, e: ReactMouseEvent<HTMLDivElement>): void => {\n e.stopPropagation();\n instance.selectCluster(key, { additive: e.metaKey || e.shiftKey });\n };\n\n // Right-click routes into the SAME typed 'contextMenu' channel the canvas\n // gesture feeds. Label divs are pointerEvents:'auto' (click-to-focus), so\n // without this the gesture dies here and the browser's native menu opens\n // on exactly the nodes prominent enough to carry labels. Coordinates are\n // container-relative CSS px (the layer fills the container), matching the\n // §15 payload contract the canvas path uses.\n const layerRef = useRef<HTMLDivElement | null>(null);\n const onLabelContextMenu = (id: NodeId, e: ReactMouseEvent<HTMLDivElement>): void => {\n e.preventDefault();\n e.stopPropagation();\n const rect = layerRef.current?.getBoundingClientRect();\n if (rect === undefined) return;\n instance.requestNodeContextMenu(id, [e.clientX - rect.left, e.clientY - rect.top]);\n };\n\n const clusterMembers = (key: string): readonly NodeId[] =>\n instance.getClusters().find((c) => c.key === key)?.memberIds ?? [];\n\n return (\n <div data-orbit-label-layer=\"\" ref={layerRef} style={LAYER_STYLE}>\n {candidates.map((p) => {\n const key = placementKey(p);\n const [x, y] = positionsRef.current.get(key) ?? [p.x, p.y];\n const isCluster = p.kind === 'cluster';\n const className = isCluster\n ? [props.labelClassName, props.clusterLabelClassName].filter(Boolean).join(' ') ||\n undefined\n : props.labelClassName;\n return (\n <div\n key={key}\n {...(isCluster ? { 'data-orbit-cluster-label': p.id } : { 'data-orbit-label': p.id })}\n className={className}\n style={{ ...LABEL_BASE_STYLE, transform: transformOf(x, y) }}\n ref={(el) => {\n if (el === null) elementsRef.current.delete(key);\n else elementsRef.current.set(key, el);\n }}\n onClick={(e) => (isCluster ? onClusterLabelClick(p.id, e) : onLabelClick(p.id, e))}\n // Cluster labels keep the browser menu for now: their click\n // already selects members, and no cluster menu target exists.\n onContextMenu={isCluster ? undefined : (e) => onLabelContextMenu(p.id, e)}\n >\n {/* §14 text-node-only rendering holds for both kinds: a hostile\n key or label appears literally, never as markup. */}\n {isCluster\n ? props.renderClusterLabel !== undefined\n ? props.renderClusterLabel({\n clusterKey: p.id,\n text: p.text,\n memberIds: clusterMembers(p.id),\n })\n : p.text\n : props.renderNodeLabel !== undefined\n ? props.renderNodeLabel({\n node: instance.getNode(p.id) ?? { id: p.id },\n text: p.text,\n })\n : p.text}\n </div>\n );\n })}\n </div>\n );\n}\n","/**\n * LiveRegion — §15.1 screen-reader announcements (S7-T10).\n *\n * A visually-hidden `aria-live=\"polite\"` region adjacent to the canvas. It\n * subscribes to the STORE (never the frame clock, so simulation frames can\n * never announce) and speaks a coalesced summary — node/edge counts,\n * selection count, status — at most once every 800ms and only when the\n * summary STRING changes. Trailing-edge coalescing: a burst of store changes\n * lands as ONE announcement carrying the freshest state.\n *\n * Gated off entirely when `accessibility.announcements === false`.\n */\n\nimport { useEffect, useRef, useState } from 'react';\nimport type { ReactElement } from 'react';\nimport type { GraphStoreState } from '@modernrelay/orbit-core';\nimport { useAmbientGraphInstance } from './GraphProvider';\nimport { visuallyHiddenStyle } from './components/shared';\n\nexport const ANNOUNCE_INTERVAL_MS = 800;\n\nexport interface LiveRegionProps {\n /** `accessibility.announcements`; false gates all announcements. Default true. */\n announcements?: boolean | undefined;\n}\n\nfunction summarize(s: GraphStoreState): string {\n const selected = s.selection.nodeIds.length + s.selection.edgeIds.length;\n return `Graph ${s.status}. ${s.nodeCount} nodes, ${s.edgeCount} edges. ${selected} selected.`;\n}\n\n/** Internal to <Graph>; reads the ambient instance so hosts composing\n * GraphProvider directly can reuse it. */\nexport function LiveRegion(props: LiveRegionProps): ReactElement {\n const instance = useAmbientGraphInstance('LiveRegion');\n const enabled = props.announcements !== false;\n const [message, setMessage] = useState('');\n /** Last ANNOUNCED summary; seeded at subscribe time so the initial state\n * (already conveyed by the container's aria-label) is never announced. */\n const lastAnnouncedRef = useRef<string | null>(null);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (!enabled) return undefined;\n const store = instance.store;\n lastAnnouncedRef.current = summarize(store.getState());\n\n const fire = (): void => {\n timerRef.current = null;\n const next = summarize(store.getState());\n if (next === lastAnnouncedRef.current) return;\n lastAnnouncedRef.current = next;\n setMessage(next);\n };\n\n const unsubscribe = store.subscribe(() => {\n if (timerRef.current !== null) return; // window open — coalesce\n if (summarize(store.getState()) === lastAnnouncedRef.current) return;\n timerRef.current = setTimeout(fire, ANNOUNCE_INTERVAL_MS);\n });\n\n return () => {\n unsubscribe();\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n }, [instance, enabled]);\n\n return (\n <div\n data-orbit-live-region=\"\"\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n style={visuallyHiddenStyle}\n >\n {message}\n </div>\n );\n}\n","/**\n * <Graph> — the declarative React binding over a headless GraphInstance.\n *\n * Binding parity (§6): one committed render that changes multiple declarative\n * props issues AT MOST ONE applyHostUpdate carrying exactly the changed keys,\n * so a multi-prop commit produces exactly one store revision and at most one\n * engine commit.\n */\n\nimport {\n forwardRef,\n useEffect,\n useId,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { CSSProperties, ForwardedRef, ReactElement, ReactNode, RefAttributes } from 'react';\nimport {\n canonicalJson,\n canonicalScaleKey,\n createGraphInstance,\n sameGroupSpecArrays,\n} from '@modernrelay/orbit-core';\nimport type {\n Accessor,\n AcceptedEdge,\n AccessibilityConfig,\n BeginIngestOptions,\n ClusterSpec,\n CreateGraphInstanceOptions,\n CrossfilterSession,\n DimensionSpec,\n ExpandNodeResult,\n FilterExpr,\n FilterSpec,\n GraphDiagnostic,\n GraphHostUpdate,\n GraphInstance,\n GraphNode,\n GraphSnapshot,\n GraphTheme,\n GraphViewState,\n GroupBySpec,\n GroupSpec,\n IngestSession,\n JsonValue,\n LabelConfig,\n LayoutKind,\n MetaEdge,\n MetricColumn,\n PathOptions,\n PathResult,\n MetricName,\n NodeId,\n ResolvedCluster,\n ResolvedGroup,\n Revisions,\n Scale,\n ScaleChannelInfo,\n SearchResult,\n SearchUnavailableReason,\n SelectionState,\n SetViewStateResult,\n SimulationConfig,\n SubgraphSpec,\n ThemeInput,\n TimelinePlayback,\n ViewportState,\n} from '@modernrelay/orbit-core';\nimport type { EngineFactory, FitViewOptions } from '@modernrelay/orbit-core/engine';\nimport { GraphProvider } from './GraphProvider';\nimport { setSearchResultUnavailableCallback, useScaleInfoSubscription } from './hooks';\nimport { Lasso } from './Lasso';\nimport { LabelLayer } from './LabelLayer';\nimport { LiveRegion } from './LiveRegion';\nimport { overlaySurface, visuallyHiddenStyle } from './components/shared';\n\n/** Snapshot handed to `renderLegend` (§11): the active scale info per styling\n * channel (null when the channel is not scale-valued) plus the resolved\n * theme tokens. Recomputed on model/scope/render/theme store changes. */\nexport interface GraphLegendRenderInfo<N = Record<string, unknown>> {\n nodeColor: ScaleChannelInfo<N> | null;\n nodeSize: ScaleChannelInfo<N> | null;\n theme: GraphTheme;\n}\n\nexport interface GraphProps<N = Record<string, unknown>, E = Record<string, unknown>> {\n /** Engine factory; captured at first render — one factory per instance. */\n engine: EngineFactory;\n data?: GraphSnapshot<N, E>;\n /** Constant, accessor, or §11 Scale descriptor. Scale-valued props compare\n * by canonical structural value — equal inline literals never reproject. */\n nodeColor?: Accessor<GraphNode<N>, string> | Scale<string, N>;\n nodeSize?: Accessor<GraphNode<N>, number> | Scale<number, N>;\n linkColor?: Accessor<AcceptedEdge<E>, string>;\n linkWidth?: Accessor<AcceptedEdge<E>, number>;\n layout?: LayoutKind;\n simulation?: SimulationConfig;\n /** §8 theme tokens: full GraphTheme, Partial over a named base, or the\n * v0.1 `{background}` shorthand. Diffed structurally (JSON). */\n theme?: ThemeInput;\n /** §12 async metric columns, joined once with revision-gated admission.\n * Diffed by array reference. */\n metrics?: readonly MetricColumn[];\n /** §8 image sprites: synchronous string-ref accessor (URL/blob ref/cache\n * key — opaque to orbit). Diffed by reference. */\n nodeImage?: (node: GraphNode<N>) => string | null;\n /** §16.12 instanced arrowheads (capability-gated; inert when unsupported). */\n edgeArrows?: boolean;\n /** §16.13 runtime link-render toggle — a config-only commit. */\n showLinks?: boolean;\n /** §11 legend escape hatch: rendered inside the provider in a positioned\n * wrapper (bottom-left) whenever provided; re-invoked when scale info or\n * theme changes. Return custom JSX, or compose <GraphLegend> from\n * '@modernrelay/orbit-react/components/Legend' for the built-in rendering. */\n renderLegend?: (info: GraphLegendRenderInfo<N>) => ReactNode;\n /** §14 DOM label lane; forwarded through applyHostUpdate. `enabled: false`\n * also unmounts the <LabelLayer> overlay entirely. */\n labels?: LabelConfig<N>;\n /** §15.1 accessibility runtime options; forwarded through applyHostUpdate\n * and mirrored onto the container ARIA surface / live region. */\n accessibility?: AccessibilityConfig<N>;\n /** Class hook applied to every DOM label div (§14). */\n labelClassName?: string;\n /** Escape hatch: custom label content rendered INSIDE the positioned label\n * div (replaces the default text node; §14). */\n renderNodeLabel?: (ctx: { node: GraphNode<N>; text: string }) => ReactNode;\n /** Class hook applied to §16.3 cluster label divs, in addition to\n * `labelClassName` (S12-T07). */\n clusterLabelClassName?: string;\n /** Escape hatch: custom cluster-label content (replaces the default text\n * node; §14 text-node-only rendering otherwise). `memberIds` are the ids a\n * click selects (R-16.3-18). */\n renderClusterLabel?: (ctx: {\n clusterKey: string;\n text: string;\n memberIds: readonly NodeId[];\n }) => ReactNode;\n /** Controlled selection of the NODE namespace; providing it once flips\n * ownership permanently (§6.4). Edge/group namespaces stay instance-owned. */\n selection?: readonly NodeId[];\n /** §9.2 hard scope: feed ONLY the resolved subset through the reconciler;\n * `null` restores the full accepted model. Diffed STRUCTURALLY (specs are\n * small), so a new-but-equal object is a no-op. UNCONTROLLED-ONLY in v0.5:\n * this prop and isolateSelection()/resetIsolation() write the same\n * instance-owned state — last writer wins, and omitting the prop leaves\n * the last written scope in place. */\n subgraph?: SubgraphSpec | null;\n /** §9.1 soft filter: mask (hide/dim) with ZERO relayout; `null` clears.\n * Diffed by canonical structural compare — serializable exprs by JSON,\n * function predicates by reference — so a new-but-equal spec never\n * re-publishes (and the core no-ops canonical-equal specs regardless). */\n filter?: FilterSpec<N, E> | null;\n /** §16.6 crossfilter dimensions (declarative; brushes live on the session\n * — reach it via useGraphCrossfilter or handle.getCrossfilterSession()).\n * Forwarded on array-reference change; the core no-ops when every\n * DimensionSpec element is reference-equal. */\n crossfilter?: readonly DimensionSpec<N>[];\n /** §16.3 manual groups; `null` clears. Diffed STRUCTURALLY (equal inline\n * literals never re-forward). Providing it once flips the groups slice to\n * CONTROLLED (§6.4): handle ops then fire onGroupsChange with the next\n * array instead of writing — reflect it back here. Config error together\n * with `groupBy` (R-16.3-15: neither applies until one is removed). */\n groups?: readonly GroupSpec[] | null;\n /** §16.3 derived grouping; `null` clears. Reference-diffed (the spec\n * carries a function accessor); the core additionally no-ops structurally\n * equal respecs. Membership under groupBy is derived and READ-ONLY —\n * groupNodes/ungroup become config errors; setGroupCollapsed toggles the\n * instance-owned per-key collapsed residue (R-16.3-16). */\n groupBy?: GroupBySpec<N> | null;\n /** §16.3 stage-4 non-collapsing clusters (S12-T06); `null` clears (D2).\n * Reference-diffed (the spec carries a function accessor). Clusters PRESERVE\n * every node and edge — they never collapse anything — so they coexist with\n * `groups`/`groupBy`. Their labels ride the §14 overlay lane under\n * `labels.maxZoom` and select their member nodes on click. */\n clusters?: ClusterSpec<N> | null;\n /** §16.3 PERSISTENT pins (S12-T09) — independent of transient drag\n * pinning: the engine receives the UNION, so releasing a drag on a\n * persistently-pinned node leaves it pinned. Providing it once latches the\n * slice controlled (§6.4): handle ops then fire onPinnedChange with the\n * next array instead of writing. `null` clears (D2). */\n pinnedNodeIds?: readonly NodeId[] | null;\n /** §16.5 node attr fields the DEFAULT search service indexes (ids always).\n * Absent = id-only search — the service never guesses attr names.\n * CONSTRUCTION-ONLY (D7, spec host construction options): read once at\n * mount; changing it requires a keyed remount (a changed prop warns once\n * and is ignored). */\n searchIndex?: readonly string[];\n /** §16.5 result contract: the instance-wide DEFAULT for an activated\n * search result that cannot be focused ('not-loaded' | 'out-of-scope' |\n * 'filtered'). `<GraphSearch onResultUnavailable>` overrides it locally;\n * the host reacts explicitly (fetch/publish an overlay, reset isolation,\n * alter filters) — search never mutates scope/filters itself (S11). */\n onSearchResultUnavailable?: (result: SearchResult, reason: SearchUnavailableReason) => void;\n /** Captured at first render (instance construction option). Default true. */\n fitViewOnFirstData?: boolean;\n /** §9.2 service seam (instance construction option, D7): custom\n * revision-aware services — most usefully an async `expansion` service\n * backed by the host's own data source, so `expandNode`/the context menu's\n * Expand run against the network instead of the built-in local-adjacency\n * walk. CONSTRUCTION-ONLY: read once at mount; changing it requires a keyed\n * remount. */\n services?: CreateGraphInstanceOptions<N, E>['services'];\n /** Shift+drag freeform lasso selection overlay (§16.2). Default true. */\n enableLasso?: boolean;\n className?: string;\n style?: CSSProperties;\n /** Rendered inside the provider, above (after) the canvas container. */\n children?: ReactNode;\n onNodeClick?: (payload: { node: GraphNode<N>; metaKey?: boolean }) => void;\n onBackgroundClick?: () => void;\n onNodeHover?: (payload: { node: GraphNode<N> | null }) => void;\n onEdgeClick?: (payload: { edge: AcceptedEdge<E> }) => void;\n onEdgeHover?: (payload: { edge: AcceptedEdge<E> | null }) => void;\n onNodeDragStart?: (payload: { node: GraphNode<N> }) => void;\n onNodeDragEnd?: (payload: { node: GraphNode<N>; x: number; y: number }) => void;\n /** Fires with the full namespaced SelectionState (§16.2). */\n onSelectionChange?: (payload: SelectionState) => void;\n /** §16.3/§7.4: a super-node hit — the resolved GROUP payload, never a\n * GraphNode (R-16.3-12). */\n onGroupClick?: (payload: { group: ResolvedGroup; metaKey?: boolean }) => void;\n /** §16.3/§7.4: a meta-edge hit — the MetaEdge record (count badge datum). */\n onMetaEdgeClick?: (payload: { metaEdge: MetaEdge }) => void;\n /** §6.4 groups slice change callback: op results (uncontrolled), op\n * INTENTS (controlled — reflect the array back into `groups`), and groupBy\n * re-derivations (notification). Receives the resolved array. */\n onGroupsChange?: (groups: readonly ResolvedGroup[]) => void;\n /** §16.14 durable source coordinate — forwarded verbatim; serialized into\n * view states and canonically compared on restore. Diffed by canonical\n * JSON, so a new-but-equal object never re-forwards. */\n dataRef?: JsonValue;\n /** §16.14 aggregate restore intent (fires once per restore/history\n * transaction touching a controlled slice or serialized styling): reflect\n * every participating prop in ONE commit; matching values acknowledge. */\n onViewStateRestore?: (intent: {\n transactionId: string;\n source: 'setViewState' | 'undo' | 'redo';\n next: unknown;\n }) => void;\n /** §16.14: fired INSTEAD of applying a state whose dataRef mismatches. */\n onViewStateMismatch?: (stored: JsonValue | undefined, current: JsonValue | undefined) => void;\n /** §6.4 persistent-pin slice change (S12-T09): the applied set when\n * uncontrolled, the INTENT when controlled. */\n onPinnedChange?: (pinnedNodeIds: readonly NodeId[]) => void;\n onViewportChange?: (v: ViewportState) => void;\n onReady?: () => void;\n onError?: (payload: { error: Error }) => void;\n}\n\nexport interface GraphHandle<N = Record<string, unknown>, E = Record<string, unknown>> {\n /** `opts` is accepted for forward compatibility; core v0.1 ignores it. */\n fitView(opts?: FitViewOptions): void;\n zoomIn(): void;\n zoomOut(): void;\n /** `opts` is accepted for forward compatibility; core v0.1 ignores it. */\n setViewport(v: Partial<ViewportState>, opts?: { durationMs?: number }): void;\n focusNode(id: NodeId): void;\n /** Open the typed context menu for a node from host chrome (a list row, a\n * custom label) — the same 'contextMenu' event the canvas gesture emits.\n * `screen` is container-relative CSS px. */\n requestNodeContextMenu(id: NodeId, screen: readonly [number, number]): void;\n /** §16.14: serialize the exploration state (see core docs). */\n getViewState(opts?: { includePositions?: false }): GraphViewState;\n /** §16.14: atomic restore; typed results, never partial. */\n setViewState(\n raw: unknown,\n opts?: { ignoreMismatch?: boolean },\n ): Promise<SetViewStateResult>;\n /** §16.14 picture export: 'png' via the engine screenshot; 'svg' via the\n * engine-free exporter (typed export-too-large past the bound;\n * raster-hybrid fallback available). */\n exportImage(format: 'png'): Promise<Blob>;\n exportImage(\n format: 'svg',\n opts?: { maxSvgElements?: number; fallback?: 'raster-hybrid' },\n ): Promise<string>;\n /** §16.14 bounded object export; typed rejection past the limit. */\n exportData(\n scope?: 'visible' | 'accepted',\n opts?: { limit?: number },\n ): Promise<{ nodes: readonly GraphNode<N>[]; edges: readonly AcceptedEdge<E>[] }>;\n /** §16.14 memory-bounded JSONL stream over one pinned revision. */\n exportDataStream(scope?: 'visible' | 'accepted'): AsyncGenerator<string, void, undefined>;\n /** §16.14 bounded id → [x, y] map (one position readback). */\n exportLayout(opts?: { limit?: number }): Promise<ReadonlyMap<NodeId, readonly [number, number]>>;\n /** §16.14 layout JSONL stream over one pinned readback. */\n exportLayoutStream(): AsyncGenerator<string, void, undefined>;\n setSelection(ids: readonly NodeId[]): void;\n clearSelection(): void;\n // --- §16.3 persistent pins (S12-T09) ---\n /** Hold nodes at their CURRENT position (independent of drag pinning). */\n pinNodes(ids: readonly NodeId[]): void;\n unpinNodes(ids: readonly NodeId[]): void;\n // --- §16.2 paths (S12-T08) ---\n /** Resolve + atomically emphasize a path; null = unreachable (a result).\n * Emphasis is session-local — released by clearPath, any selection\n * mutation, undo/redo, or a scene rebuild; never in history/view state. */\n findPath(sourceId: NodeId, targetId: NodeId, options?: PathOptions): Promise<PathResult | null>;\n clearPath(): void;\n // --- §16.2 selection algebra ---\n /** Expand to the 1-hop neighborhood of `id` (or of the current selection). */\n selectNeighbors(id?: NodeId): void;\n selectAll(): void;\n invertSelection(): void;\n /** Resolve a SCREEN-coordinate polygon to node ids and replace (default) or\n * union (`additive`) the node selection; returns the resolved ids. */\n selectWithinPolygon(\n polygon: readonly [number, number][],\n opts?: { additive?: boolean },\n ): readonly NodeId[];\n // --- §16.3 pin / hide slices ---\n /** Pin at `xy` (space coords) or at the node's current position. */\n pinNode(id: NodeId, xy?: readonly [number, number]): void;\n unpinNode(id: NodeId): void;\n clearPins(): void;\n hideNodes(ids: readonly NodeId[]): void;\n showAll(): void;\n // --- §9.2 hard scope + expansion ---\n /** Hard-scope to the current node selection (no-op when empty; §9.2). */\n isolateSelection(): void;\n /** Clear the hard scope — the full accepted model returns (§9.2). */\n resetIsolation(): void;\n /** Ego-expand `id` through the configured ExpansionService (§9.2/§16.3). */\n expandNode(id: NodeId, opts?: { hops?: number }): Promise<ExpandNodeResult>;\n /** Abort `id`'s pending expansion and remove its committed expansion\n * overlays (§16.3). */\n retractExpansion(id: NodeId): void;\n // --- §16.3 group operations (§6.4 groups slice; S12-T02/T04) ---\n /** Add one group (same acyclic/singly-parented validation as the `groups` prop).\n * Controlled mode fires onGroupsChange with the next array instead. */\n groupNodes(spec: GroupSpec): void;\n /** Remove one group definition; its id prunes from selection.groupIds. */\n ungroup(groupId: string): void;\n /** Collapse/expand one group as a structural diff — the ONE op allowed on\n * groupBy-derived groups (toggles the per-key collapsed residue). */\n setGroupCollapsed(groupId: string, collapsed: boolean): void;\n // --- §16.3 node folds: an EXISTING node stands for its own neighbourhood.\n // Distinct from `expandNode`/`retractExpansion`, which navigate the data\n // source; a fold is pure containment over what is already loaded. ---\n /** Hide `id`'s neighbourhood behind `id`, rerouting the members' outside\n * edges onto it. Members default to unclaimed neighbours (first fold wins). */\n foldNode(id: NodeId, opts?: { memberIds?: readonly NodeId[] }): void;\n /** Return `id`'s folded members to the scene. No-op when not folded. */\n unfoldNode(id: NodeId): void;\n /** The members `id` stands for, or null when it is not folded. */\n getFold(id: NodeId): { memberIds: readonly NodeId[] } | null;\n // --- §16.3 stage-4 clusters (S12-T06/T07) ---\n /** Current clusters over the physical scene (keys, members, force center,\n * settled centroid). Empty when no `clusters` prop is active. */\n getClusters(): readonly ResolvedCluster[];\n /** Select a cluster's MEMBER node ids (R-16.3-18); `additive` unions. */\n selectCluster(key: string, opts?: { additive?: boolean }): void;\n // --- §7.5 revisioned ingestion ---\n /** Begin a bounded, cancellable ingest session (§7.5). */\n beginIngest(opts: BeginIngestOptions): IngestSession<N, E>;\n /** Atomically remove exactly one committed overlay; unknown ids are an\n * idempotent `{ removed: false }` (§7.5). */\n removeOverlay(overlayId: string): { removed: boolean };\n // --- §16.14 history ---\n /** Undo the most recent uncontrolled mutation entry (selection / hidden /\n * pins / scope / brushes). Returns false when there is nothing to undo. */\n undo(): boolean;\n /** Re-apply the most recently undone entry. False when nothing to redo. */\n redo(): boolean;\n // --- §16.6 timeline playback ---\n /** Play a brush window across a numeric/temporal dimension's domain\n * (crossfilter mask fast path; one playing dimension at a time). */\n playTimeline(key: string, playback?: Partial<TimelinePlayback>): void;\n pauseTimeline(): void;\n // --- §16.6 crossfilter ---\n /** The crossfilter session facade, or null until the `crossfilter` prop\n * has configured dimensions over an accepted base. */\n getCrossfilterSession(): CrossfilterSession | null;\n // --- §11/§12 styling reads (S10) ---\n /** §11 legend surface: the active Scale on a styling channel plus its\n * resolved domain or categorical rows; null when not scale-valued. */\n getScaleInfo(channel: 'nodeColor' | 'nodeSize'): ScaleChannelInfo<N> | null;\n /** §12 metric read for one node id (built-in degree family + admitted\n * columns); null for unknown ids/metrics and §8-null values. */\n getMetricValue(metric: MetricName, id: NodeId): number | null;\n getRevisions(): Revisions;\n getDiagnostics(): readonly GraphDiagnostic[];\n instance: GraphInstance<N, E>;\n}\n\n/** Last-committed declarative props. Fields are `| undefined` (not optional)\n * so the diff record is assignable under exactOptionalPropertyTypes. */\ninterface CommittedProps<N, E> {\n data: GraphSnapshot<N, E> | undefined;\n nodeColor: Accessor<GraphNode<N>, string> | Scale<string, N> | undefined;\n /** Canonical structural key when the committed nodeColor is a Scale (§11);\n * undefined for accessor/constant forms (those diff by reference). */\n nodeColorKey: string | undefined;\n nodeSize: Accessor<GraphNode<N>, number> | Scale<number, N> | undefined;\n nodeSizeKey: string | undefined;\n linkColor: Accessor<AcceptedEdge<E>, string> | undefined;\n linkWidth: Accessor<AcceptedEdge<E>, number> | undefined;\n layout: LayoutKind | undefined;\n simulation: SimulationConfig | undefined;\n /** JSON form of the last committed `theme` prop (small token set). */\n themeJson: string | undefined;\n metrics: readonly MetricColumn[] | undefined;\n nodeImage: ((node: GraphNode<N>) => string | null) | undefined;\n edgeArrows: boolean | undefined;\n showLinks: boolean | undefined;\n selection: readonly NodeId[] | undefined;\n labels: LabelConfig<N> | undefined;\n accessibility: AccessibilityConfig<N> | undefined;\n /** JSON form of the last committed `subgraph` prop — specs are small, so\n * the diff is a structural string compare ('null' when scope cleared). */\n subgraphJson: string | undefined;\n /** Last committed `filter` prop + its canonical key (§9.1): exprs compare\n * by JSON, function predicates by reference. */\n filter: FilterSpec<N, E> | null | undefined;\n filterKey: string | undefined;\n /** Last committed `crossfilter` prop (array reference; §16.6). */\n crossfilter: readonly DimensionSpec<N>[] | undefined;\n /** Last committed `groups` prop (structural diff via sameGroupSpecArrays;\n * §16.3 — equal inline literals never re-forward). */\n groups: readonly GroupSpec[] | null | undefined;\n dataRef: JsonValue | undefined;\n /** Last committed `groupBy` prop (reference diff — function-bearing). */\n groupBy: GroupBySpec<N> | null | undefined;\n /** Last committed `clusters` prop (reference diff — function-bearing). */\n clusters: ClusterSpec<N> | null | undefined;\n /** Last committed `pinnedNodeIds` prop (shallow element diff; S12-T09). */\n pinnedNodeIds: readonly NodeId[] | null | undefined;\n /** Last committed `searchIndex` prop (shallow element diff; §16.5/S11). */\n searchIndex: readonly string[] | undefined;\n}\n\n/**\n * Canonical key of a scale-valued styling channel (§11): `canonicalScaleKey`\n * when the value is a Scale descriptor, undefined for constant/accessor forms\n * (which diff by reference). Equal inline scale literals therefore never\n * re-forward; a function `by` keys by reference identity inside the core.\n */\nfunction scaleKeyOf(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const kind = (value as { kind?: unknown }).kind;\n if (kind !== 'sequential' && kind !== 'categorical' && kind !== 'diverging') return undefined;\n return canonicalScaleKey(value as Scale<unknown>);\n}\n\n/** Diff one nodeColor/nodeSize channel: scale forms compare by canonical key,\n * everything else by reference (a scale↔accessor flip always differs). */\nfunction styleChannelChanged(\n prevValue: unknown,\n prevKey: string | undefined,\n nextValue: unknown,\n nextKey: string | undefined,\n): boolean {\n if (nextKey !== undefined || prevKey !== undefined) return nextKey !== prevKey;\n return prevValue !== nextValue;\n}\n\n/** Canonical key of one filter side: 'u' absent, 'fn' a function predicate\n * (paired with a reference compare), else the expr JSON. */\nfunction filterSideKey(side: FilterExpr | ((item: never) => boolean) | undefined): string {\n if (side === undefined) return 'u';\n if (typeof side === 'function') return 'fn';\n return JSON.stringify(side);\n}\n\nfunction filterKeyOf<N, E>(spec: FilterSpec<N, E> | null): string {\n if (spec === null) return 'null';\n return `${spec.mode ?? 'hide'}|${filterSideKey(spec.nodes)}|${filterSideKey(spec.edges)}`;\n}\n\n/** Canonical-equal check: keys match AND any function sides are the SAME\n * references (a changed predicate function must re-evaluate). */\nfunction sameFilterSpec<N, E>(\n prev: FilterSpec<N, E> | null | undefined,\n prevKey: string | undefined,\n next: FilterSpec<N, E> | null,\n nextKey: string,\n): boolean {\n if (prevKey === undefined || prevKey !== nextKey) return false;\n if (next === null) return prev === null;\n if (prev === null || prev === undefined) return false;\n if (typeof next.nodes === 'function' && next.nodes !== prev.nodes) return false;\n if (typeof next.edges === 'function' && next.edges !== prev.edges) return false;\n return true;\n}\n\ninterface CallbackHolder<N, E> {\n onNodeClick: ((payload: { node: GraphNode<N>; metaKey?: boolean }) => void) | undefined;\n onBackgroundClick: (() => void) | undefined;\n onNodeHover: ((payload: { node: GraphNode<N> | null }) => void) | undefined;\n onEdgeClick: ((payload: { edge: AcceptedEdge<E> }) => void) | undefined;\n onEdgeHover: ((payload: { edge: AcceptedEdge<E> | null }) => void) | undefined;\n onNodeDragStart: ((payload: { node: GraphNode<N> }) => void) | undefined;\n onNodeDragEnd: ((payload: { node: GraphNode<N>; x: number; y: number }) => void) | undefined;\n onSelectionChange: ((payload: SelectionState) => void) | undefined;\n onGroupClick: ((payload: { group: ResolvedGroup; metaKey?: boolean }) => void) | undefined;\n onMetaEdgeClick: ((payload: { metaEdge: MetaEdge }) => void) | undefined;\n onGroupsChange: ((groups: readonly ResolvedGroup[]) => void) | undefined;\n onViewStateRestore:\n | ((intent: {\n transactionId: string;\n source: 'setViewState' | 'undo' | 'redo';\n next: unknown;\n }) => void)\n | undefined;\n onViewStateMismatch:\n | ((stored: JsonValue | undefined, current: JsonValue | undefined) => void)\n | undefined;\n onPinnedChange: ((pinnedNodeIds: readonly NodeId[]) => void) | undefined;\n onViewportChange: ((v: ViewportState) => void) | undefined;\n onReady: (() => void) | undefined;\n onError: ((payload: { error: Error }) => void) | undefined;\n}\n\nfunction sameIdArrays(a: readonly NodeId[], b: readonly NodeId[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\nconst CONTAINER_BASE_STYLE: CSSProperties = {\n position: 'relative',\n width: '100%',\n height: '100%',\n};\n\n// The canvas layer fills the outer div; children render after it in DOM order\n// so they naturally stack above the canvas.\nconst CANVAS_STYLE: CSSProperties = { position: 'absolute', inset: 0 };\n\n/** Positioned wrapper for the `renderLegend` slot (§11): bottom-left, above\n * the canvas, interactive (category rows are clickable). */\nconst LEGEND_SLOT_STYLE: CSSProperties = {\n position: 'absolute',\n left: 12,\n bottom: 12,\n};\n\n/** `renderLegend` slot host: re-reads getScaleInfo on every store publication\n * that can move scale info (model/scope/render revisions) or theme change,\n * and re-invokes the host's render function with the fresh snapshot. */\nfunction LegendSlot<N, E>(props: {\n instance: GraphInstance<N, E>;\n renderLegend: (info: GraphLegendRenderInfo<N>) => ReactNode;\n}): ReactElement {\n const { instance } = props;\n const { version, theme } = useScaleInfoSubscription(instance);\n const info = useMemo<GraphLegendRenderInfo<N>>(\n () => ({\n nodeColor: instance.getScaleInfo('nodeColor'),\n nodeSize: instance.getScaleInfo('nodeSize'),\n theme,\n }),\n // `version` is the invalidation token: a new store revision can change\n // what getScaleInfo returns without changing any other dependency.\n [instance, theme, version],\n );\n return (\n <div data-orbit-legend-slot=\"\" style={LEGEND_SLOT_STYLE}>\n {props.renderLegend(info)}\n </div>\n );\n}\n\nfunction GraphInner<N, E>(\n props: GraphProps<N, E>,\n ref: ForwardedRef<GraphHandle<N, E>>,\n): ReactElement {\n // Lazy, once per mounted component. `engine`/`fitViewOnFirstData`/\n // `searchIndex` are construction options (D7); later changes to them are\n // intentionally ignored (searchIndex additionally warns once below).\n const [instance] = useState<GraphInstance<N, E>>(() => {\n const options: CreateGraphInstanceOptions<N, E> = { engine: props.engine };\n if (props.fitViewOnFirstData !== undefined) {\n options.fitViewOnFirstData = props.fitViewOnFirstData;\n }\n if (props.searchIndex !== undefined) options.searchIndex = props.searchIndex;\n if (props.services !== undefined) options.services = props.services;\n return createGraphInstance<N, E>(options);\n });\n const searchIndexWarnedRef = useRef(false);\n\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n // --- latest-callback holder: event subscriptions read through this ref so\n // per-render callback identity churn never resubscribes ---\n const callbacksRef = useRef<CallbackHolder<N, E>>({\n onNodeClick: undefined,\n onBackgroundClick: undefined,\n onNodeHover: undefined,\n onEdgeClick: undefined,\n onEdgeHover: undefined,\n onNodeDragStart: undefined,\n onNodeDragEnd: undefined,\n onSelectionChange: undefined,\n onGroupClick: undefined,\n onMetaEdgeClick: undefined,\n onGroupsChange: undefined,\n onViewStateRestore: undefined,\n onViewStateMismatch: undefined,\n onPinnedChange: undefined,\n onViewportChange: undefined,\n onReady: undefined,\n onError: undefined,\n });\n useLayoutEffect(() => {\n callbacksRef.current = {\n onNodeClick: props.onNodeClick,\n onBackgroundClick: props.onBackgroundClick,\n onNodeHover: props.onNodeHover,\n onEdgeClick: props.onEdgeClick,\n onEdgeHover: props.onEdgeHover,\n onNodeDragStart: props.onNodeDragStart,\n onNodeDragEnd: props.onNodeDragEnd,\n onSelectionChange: props.onSelectionChange,\n onGroupClick: props.onGroupClick,\n onMetaEdgeClick: props.onMetaEdgeClick,\n onGroupsChange: props.onGroupsChange,\n onViewStateRestore: props.onViewStateRestore,\n onViewStateMismatch: props.onViewStateMismatch,\n onPinnedChange: props.onPinnedChange,\n onViewportChange: props.onViewportChange,\n onReady: props.onReady,\n onError: props.onError,\n };\n });\n\n // --- prop → host update: diff against the previous committed render and\n // issue at most one applyHostUpdate with exactly the changed keys ---\n const prevRef = useRef<CommittedProps<N, E> | null>(null);\n useLayoutEffect(() => {\n const prev = prevRef.current;\n const update: GraphHostUpdate<N, E> = {};\n let dirty = false;\n\n if (props.data !== undefined && (prev === null || prev.data !== props.data)) {\n update.data = props.data;\n dirty = true;\n }\n // §11 scale-aware channels: Scale descriptors diff by canonical\n // structural key (equal inline literals never re-forward); accessor and\n // constant forms keep the reference diff.\n const nodeColorKey = scaleKeyOf(props.nodeColor);\n if (\n props.nodeColor !== undefined &&\n (prev === null ||\n styleChannelChanged(prev.nodeColor, prev.nodeColorKey, props.nodeColor, nodeColorKey))\n ) {\n update.nodeColor = props.nodeColor;\n dirty = true;\n }\n const nodeSizeKey = scaleKeyOf(props.nodeSize);\n if (\n props.nodeSize !== undefined &&\n (prev === null ||\n styleChannelChanged(prev.nodeSize, prev.nodeSizeKey, props.nodeSize, nodeSizeKey))\n ) {\n update.nodeSize = props.nodeSize;\n dirty = true;\n }\n if (props.linkColor !== undefined && (prev === null || prev.linkColor !== props.linkColor)) {\n update.linkColor = props.linkColor;\n dirty = true;\n }\n if (props.linkWidth !== undefined && (prev === null || prev.linkWidth !== props.linkWidth)) {\n update.linkWidth = props.linkWidth;\n dirty = true;\n }\n if (props.layout !== undefined && (prev === null || prev.layout !== props.layout)) {\n update.layout = props.layout;\n dirty = true;\n }\n if (\n props.simulation !== undefined &&\n (prev === null || prev.simulation !== props.simulation)\n ) {\n update.simulation = props.simulation;\n dirty = true;\n }\n // §8 theme: a small token set — diffed structurally (JSON), so a\n // new-but-equal inline object never re-publishes.\n let themeJson: string | undefined;\n if (props.theme !== undefined) {\n themeJson = JSON.stringify(props.theme);\n if (prev === null || prev.themeJson !== themeJson) {\n update.theme = props.theme;\n dirty = true;\n }\n }\n // §12 metric columns: array-reference diff (columns are one-shot joins).\n if (props.metrics !== undefined && (prev === null || prev.metrics !== props.metrics)) {\n update.metrics = props.metrics;\n dirty = true;\n }\n // §8 image refs: function-prop contract — reference diff.\n if (props.nodeImage !== undefined && (prev === null || prev.nodeImage !== props.nodeImage)) {\n update.nodeImage = props.nodeImage;\n dirty = true;\n } else if (props.nodeImage === undefined && prev !== null && prev.nodeImage !== undefined) {\n // D2/F11-04: prop REMOVAL forwards the explicit clear — the natural\n // React idiom must not silently freeze the last accessor's images.\n update.nodeImage = null;\n dirty = true;\n }\n // §16.12/§16.13 toggles: plain value diff (config-only commits).\n if (props.edgeArrows !== undefined && (prev === null || prev.edgeArrows !== props.edgeArrows)) {\n update.edgeArrows = props.edgeArrows;\n dirty = true;\n }\n if (props.showLinks !== undefined && (prev === null || prev.showLinks !== props.showLinks)) {\n update.showLinks = props.showLinks;\n dirty = true;\n }\n if (\n props.selection !== undefined &&\n (prev === null ||\n prev.selection === undefined ||\n !sameIdArrays(prev.selection, props.selection))\n ) {\n update.selection = props.selection;\n dirty = true;\n }\n if (props.labels !== undefined && (prev === null || prev.labels !== props.labels)) {\n update.labels = props.labels;\n dirty = true;\n }\n if (\n props.accessibility !== undefined &&\n (prev === null || prev.accessibility !== props.accessibility)\n ) {\n update.accessibility = props.accessibility;\n dirty = true;\n }\n // §9.2 hard scope: structural (JSON) diff — a new-but-equal spec object\n // never re-publishes. An omitted prop is never forwarded (uncontrolled).\n let subgraphJson: string | undefined;\n if (props.subgraph !== undefined) {\n subgraphJson = JSON.stringify(props.subgraph);\n if (prev === null || prev.subgraphJson !== subgraphJson) {\n update.subgraph = props.subgraph;\n dirty = true;\n }\n }\n // §9.1 soft filter: canonical structural diff (exprs by JSON, function\n // predicates by reference). An omitted prop is never forwarded.\n let filterKey: string | undefined;\n if (props.filter !== undefined) {\n filterKey = filterKeyOf(props.filter);\n if (\n prev === null ||\n !sameFilterSpec(prev.filter, prev.filterKey, props.filter, filterKey)\n ) {\n update.filter = props.filter;\n dirty = true;\n }\n }\n // §16.6 crossfilter dimensions: forwarded on array-reference change; the\n // core no-ops when every DimensionSpec element is reference-equal.\n if (\n props.crossfilter !== undefined &&\n (prev === null || prev.crossfilter !== props.crossfilter)\n ) {\n update.crossfilter = props.crossfilter;\n dirty = true;\n }\n // §16.3 groups: structural diff (equal inline literals never\n // re-forward). An omitted prop is never forwarded — but ONCE provided\n // the core latches the slice controlled (§6.4).\n if (props.dataRef !== undefined) {\n const prevRef = prev === null ? undefined : prev.dataRef;\n if (prevRef === undefined || canonicalJson(props.dataRef) !== canonicalJson(prevRef)) {\n update.dataRef = props.dataRef;\n dirty = true;\n }\n }\n if (props.groups !== undefined) {\n const prevGroups = prev === null ? undefined : prev.groups;\n if (prevGroups === undefined || !sameGroupSpecArrays(prevGroups, props.groups)) {\n update.groups = props.groups;\n dirty = true;\n }\n }\n // §16.3 groupBy: reference diff (the spec carries a function accessor);\n // the core additionally no-ops structurally equal respecs.\n if (props.groupBy !== undefined && (prev === null || prev.groupBy !== props.groupBy)) {\n update.groupBy = props.groupBy;\n dirty = true;\n }\n // §16.3 clusters: reference diff (function-bearing spec); the core\n // re-derives membership only on a `by` identity change.\n if (props.clusters !== undefined && (prev === null || prev.clusters !== props.clusters)) {\n update.clusters = props.clusters;\n dirty = true;\n }\n // §16.3 pinnedNodeIds: shallow element diff (a small id list); ONCE\n // provided the core latches the slice controlled (§6.4).\n if (props.pinnedNodeIds !== undefined) {\n const prevPinned = prev === null ? undefined : prev.pinnedNodeIds;\n const changed =\n prevPinned === undefined ||\n prevPinned === null ||\n props.pinnedNodeIds === null ||\n !sameIdArrays(prevPinned, props.pinnedNodeIds);\n if (changed) {\n update.pinnedNodeIds = props.pinnedNodeIds;\n dirty = true;\n }\n }\n // §16.5/D7: searchIndex is CONSTRUCTION-ONLY (read once above). A\n // changed prop cannot take effect without a keyed remount — warn once\n // (shallow element diff, so a new-but-equal inline literal is fine).\n if (\n prev !== null &&\n !sameIdArrays(prev.searchIndex ?? [], props.searchIndex ?? []) &&\n !searchIndexWarnedRef.current\n ) {\n searchIndexWarnedRef.current = true;\n console.warn(\n '[orbit] searchIndex is construction-only (§16.5): the changed value was ignored — key-remount <Graph> to change it',\n );\n }\n\n prevRef.current = {\n data: props.data,\n nodeColor: props.nodeColor,\n nodeColorKey,\n nodeSize: props.nodeSize,\n nodeSizeKey,\n linkColor: props.linkColor,\n linkWidth: props.linkWidth,\n layout: props.layout,\n simulation: props.simulation,\n themeJson,\n metrics: props.metrics,\n nodeImage: props.nodeImage,\n edgeArrows: props.edgeArrows,\n showLinks: props.showLinks,\n selection: props.selection,\n labels: props.labels,\n accessibility: props.accessibility,\n subgraphJson,\n filter: props.filter,\n filterKey,\n crossfilter: props.crossfilter,\n groups: props.groups,\n dataRef: props.dataRef,\n groupBy: props.groupBy,\n clusters: props.clusters,\n pinnedNodeIds: props.pinnedNodeIds,\n searchIndex: props.searchIndex,\n };\n\n if (dirty) instance.applyHostUpdate(update);\n });\n\n // §16.5 (S11): register the instance-wide default unavailable-result\n // callback so <GraphSearch> (and bespoke activation UIs) resolve it without\n // <Graph> in their import graph. Identity churn is fine — registration is a\n // WeakMap write, never a re-render.\n useLayoutEffect(() => {\n setSearchResultUnavailableCallback(instance, props.onSearchResultUnavailable);\n });\n\n // --- event subscriptions: keyed on the instance only; identity churn of\n // the props is absorbed by callbacksRef ---\n useEffect(() => {\n const offs = [\n instance.on('nodeClick', (p) => callbacksRef.current.onNodeClick?.(p)),\n instance.on('backgroundClick', () => callbacksRef.current.onBackgroundClick?.()),\n instance.on('nodeHover', (p) => callbacksRef.current.onNodeHover?.(p)),\n instance.on('edgeClick', (p) => callbacksRef.current.onEdgeClick?.(p)),\n instance.on('edgeHover', (p) => callbacksRef.current.onEdgeHover?.(p)),\n instance.on('nodeDragStart', (p) => callbacksRef.current.onNodeDragStart?.(p)),\n instance.on('nodeDragEnd', (p) => callbacksRef.current.onNodeDragEnd?.(p)),\n instance.on('selectionChange', (p) => callbacksRef.current.onSelectionChange?.(p)),\n instance.on('groupClick', (p) => callbacksRef.current.onGroupClick?.(p)),\n instance.on('metaEdgeClick', (p) => callbacksRef.current.onMetaEdgeClick?.(p)),\n instance.on('groupsChange', (p) => callbacksRef.current.onGroupsChange?.(p.groups)),\n instance.on('viewStateRestore', (p) => callbacksRef.current.onViewStateRestore?.(p)),\n instance.on('viewStateMismatch', (p) =>\n callbacksRef.current.onViewStateMismatch?.(p.stored, p.current),\n ),\n instance.on('pinnedChange', (p) => callbacksRef.current.onPinnedChange?.(p.pinnedNodeIds)),\n instance.on('viewportChange', (v) => callbacksRef.current.onViewportChange?.(v)),\n instance.on('ready', () => callbacksRef.current.onReady?.()),\n instance.on('error', (p) => callbacksRef.current.onError?.(p)),\n ];\n return () => {\n for (const off of offs) off();\n };\n }, [instance]);\n\n // --- attach/detach: StrictMode's simulated remount detaches (destroying\n // the first engine) and re-attaches (fresh engine + full state replay) ---\n useEffect(() => {\n const container = containerRef.current;\n if (container === null) return undefined;\n // Each StrictMode setup (and each real mount) owns exactly one attach\n // result. Its promise may settle after cleanup because engine mounting is\n // asynchronous; a discarded generation must never inspect the newer\n // instance state or call the latest component callbacks.\n let active = true;\n void instance.attach(container).catch((err: unknown) => {\n if (!active) return;\n // A fatal mount fault already reached onError via the 'error' event.\n if (instance.store.getState().status === 'error') return;\n const error = err instanceof Error ? err : new Error(String(err));\n callbacksRef.current.onError?.({ error });\n });\n return () => {\n active = false;\n instance.detach();\n };\n }, [instance]);\n\n // --- destroy on true unmount only. destroy() is irreversible, so the\n // cleanup defers it one microtask; a StrictMode remount re-runs the setup\n // synchronously first and cancels it, leaving detach/attach replay to\n // restore the engine. A real unmount has no re-setup, so destroy fires. ---\n const destroyGateRef = useRef({ pendingDestroy: false });\n useEffect(() => {\n const gate = destroyGateRef.current;\n gate.pendingDestroy = false;\n return () => {\n gate.pendingDestroy = true;\n queueMicrotask(() => {\n if (gate.pendingDestroy) instance.destroy();\n });\n };\n }, [instance]);\n\n // --- reduced motion (§15.1): the binding detects the media preference and\n // reports it via instance.setReducedMotion; accessibility.reducedMotion\n // overrides inside the core. Subscribed for live preference changes. ---\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return undefined;\n }\n const mq = window.matchMedia('(prefers-reduced-motion: reduce)');\n const surface = overlaySurface(instance);\n surface.setReducedMotion?.(mq.matches);\n const onChange = (e: MediaQueryListEvent): void => {\n surface.setReducedMotion?.(e.matches);\n };\n if (typeof mq.addEventListener === 'function') {\n mq.addEventListener('change', onChange);\n return () => {\n mq.removeEventListener('change', onChange);\n };\n }\n // Legacy MediaQueryList (Safari < 14).\n if (typeof mq.addListener === 'function') {\n mq.addListener(onChange);\n return () => {\n mq.removeListener(onChange);\n };\n }\n return undefined;\n }, [instance]);\n\n useImperativeHandle(\n ref,\n (): GraphHandle<N, E> => ({\n fitView: (_opts?: FitViewOptions) => {\n instance.fitView();\n },\n zoomIn: () => {\n instance.zoomIn();\n },\n zoomOut: () => {\n instance.zoomOut();\n },\n setViewport: (v: Partial<ViewportState>, _opts?: { durationMs?: number }) => {\n instance.setViewport(v);\n },\n requestNodeContextMenu: (id: NodeId, screen: readonly [number, number]) => {\n instance.requestNodeContextMenu(id, screen);\n },\n getViewState: (opts?: { includePositions?: false }): GraphViewState =>\n instance.getViewState(opts),\n setViewState: (\n raw: unknown,\n opts?: { ignoreMismatch?: boolean },\n ): Promise<SetViewStateResult> => instance.setViewState(raw, opts),\n exportImage: ((format: 'png' | 'svg', opts?: { maxSvgElements?: number; fallback?: 'raster-hybrid' }) =>\n format === 'png' ? instance.exportImage('png') : instance.exportImage('svg', opts)) as GraphHandle<N, E>['exportImage'],\n exportData: (scope?: 'visible' | 'accepted', opts?: { limit?: number }) =>\n instance.exportData(scope, opts),\n exportDataStream: (scope?: 'visible' | 'accepted') => instance.exportDataStream(scope),\n exportLayout: (opts?: { limit?: number }) => instance.exportLayout(opts),\n exportLayoutStream: () => instance.exportLayoutStream(),\n focusNode: (id: NodeId) => {\n instance.focusNode(id);\n },\n setSelection: (ids: readonly NodeId[]) => {\n instance.setSelection(ids);\n },\n findPath: (sourceId: NodeId, targetId: NodeId, options?: PathOptions) =>\n instance.findPath(sourceId, targetId, options),\n clearPath: () => {\n instance.clearPath();\n },\n clearSelection: () => {\n instance.clearSelection();\n },\n selectNeighbors: (id?: NodeId) => {\n instance.selectNeighbors(id);\n },\n selectAll: () => {\n instance.selectAll();\n },\n invertSelection: () => {\n instance.invertSelection();\n },\n selectWithinPolygon: (\n polygon: readonly [number, number][],\n opts?: { additive?: boolean },\n ): readonly NodeId[] => instance.selectWithinPolygon(polygon, opts),\n pinNode: (id: NodeId, xy?: readonly [number, number]) => {\n instance.pinNode(id, xy);\n },\n unpinNode: (id: NodeId) => {\n instance.unpinNode(id);\n },\n clearPins: () => {\n instance.clearPins();\n },\n hideNodes: (ids: readonly NodeId[]) => {\n instance.hideNodes(ids);\n },\n showAll: () => {\n instance.showAll();\n },\n isolateSelection: () => {\n instance.isolateSelection();\n },\n resetIsolation: () => {\n instance.resetIsolation();\n },\n expandNode: (id: NodeId, opts?: { hops?: number }): Promise<ExpandNodeResult> =>\n instance.expandNode(id, opts),\n retractExpansion: (id: NodeId) => {\n instance.retractExpansion(id);\n },\n pinNodes: (ids: readonly NodeId[]) => {\n instance.pinNodes(ids);\n },\n unpinNodes: (ids: readonly NodeId[]) => {\n instance.unpinNodes(ids);\n },\n groupNodes: (spec: GroupSpec) => {\n instance.groupNodes(spec);\n },\n ungroup: (groupId: string) => {\n instance.ungroup(groupId);\n },\n setGroupCollapsed: (groupId: string, collapsed: boolean) => {\n instance.setGroupCollapsed(groupId, collapsed);\n },\n foldNode: (id: NodeId, opts?: { memberIds?: readonly NodeId[] }) => {\n instance.foldNode(id, opts);\n },\n unfoldNode: (id: NodeId) => {\n instance.unfoldNode(id);\n },\n getFold: (id: NodeId): { memberIds: readonly NodeId[] } | null => instance.getFold(id),\n getClusters: (): readonly ResolvedCluster[] => instance.getClusters(),\n selectCluster: (key: string, opts?: { additive?: boolean }) => {\n instance.selectCluster(key, opts);\n },\n beginIngest: (opts: BeginIngestOptions): IngestSession<N, E> => instance.beginIngest(opts),\n removeOverlay: (overlayId: string): { removed: boolean } =>\n instance.removeOverlay(overlayId),\n undo: (): boolean => instance.undo(),\n redo: (): boolean => instance.redo(),\n playTimeline: (key: string, playback?: Partial<TimelinePlayback>) => {\n instance.playTimeline(key, playback);\n },\n pauseTimeline: () => {\n instance.pauseTimeline();\n },\n getCrossfilterSession: (): CrossfilterSession | null => instance.getCrossfilterSession(),\n getScaleInfo: (channel: 'nodeColor' | 'nodeSize'): ScaleChannelInfo<N> | null =>\n instance.getScaleInfo(channel),\n getMetricValue: (metric: MetricName, id: NodeId): number | null =>\n instance.getMetricValue(metric, id),\n getRevisions: () => instance.getRevisions(),\n getDiagnostics: () => instance.getDiagnostics(),\n instance,\n }),\n [instance],\n );\n\n // --- §15.1 container ARIA surface ---\n const descriptionId = useId();\n const description = props.accessibility?.description;\n\n return (\n <div className={props.className} style={{ ...CONTAINER_BASE_STYLE, ...props.style }}>\n <GraphProvider instance={instance}>\n {/* Engine-owned canvas layer: must never contain React children. */}\n <div\n ref={containerRef}\n data-orbit-canvas=\"\"\n style={CANVAS_STYLE}\n role=\"application\"\n aria-label={props.accessibility?.label ?? 'Graph visualization'}\n aria-describedby={description !== undefined ? descriptionId : undefined}\n />\n {description !== undefined ? (\n <div id={descriptionId} style={visuallyHiddenStyle}>\n {description}\n </div>\n ) : null}\n {/* DOM label lane (§14): candidates via React, positions imperative. */}\n {props.labels?.enabled !== false ? (\n <LabelLayer\n labelClassName={props.labelClassName}\n renderNodeLabel={props.renderNodeLabel}\n clusterLabelClassName={props.clusterLabelClassName}\n renderClusterLabel={props.renderClusterLabel}\n />\n ) : null}\n {/* Lasso overlay: above the canvas, pointer-inert unless Shift-drag. */}\n {props.enableLasso !== false ? <Lasso /> : null}\n {/* §15.1 live region: store-driven, coalesced, visually hidden. */}\n <LiveRegion announcements={props.accessibility?.announcements} />\n {/* §11 legend slot: positioned wrapper re-rendered on scale/theme\n changes; the host returns custom JSX (or composes <GraphLegend>). */}\n {props.renderLegend !== undefined ? (\n <LegendSlot instance={instance} renderLegend={props.renderLegend} />\n ) : null}\n {props.children}\n </GraphProvider>\n </div>\n );\n}\n\n/** forwardRef erases generics; restore them with a typed call signature. */\ntype GraphComponent = <N = Record<string, unknown>, E = Record<string, unknown>>(\n props: GraphProps<N, E> & RefAttributes<GraphHandle<N, E>>,\n) => ReactElement;\n\nexport const Graph = forwardRef(GraphInner) as GraphComponent;\n"]}
@@ -0,0 +1,43 @@
1
+ import { LabelPlacement } from '@modernrelay/orbit-core';
2
+ import { A as AnyGraphInstance } from './GraphProvider-B8ITDXS0.js';
3
+
4
+ /**
5
+ * Shared component foundation (S7-T03): instance resolution + tiny styling
6
+ * primitives every packaged component (`Toolbar`, `ContextMenu`,
7
+ * `SelectionActions`, `Navigator`) and the built-in overlays use.
8
+ */
9
+
10
+ /**
11
+ * Resolve the GraphInstance a component operates on: an explicit `instance`
12
+ * prop wins, else the ambient <Graph>/<GraphProvider> context. Throws a
13
+ * descriptive error naming the component when neither exists.
14
+ *
15
+ * Must be called unconditionally (it is itself a hook).
16
+ */
17
+ declare function useResolvedInstance(explicit?: AnyGraphInstance, componentName?: string): AnyGraphInstance;
18
+ /** Corner a floating component anchors to inside the graph container. */
19
+ type GraphCorner = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
20
+ /** Default distance from the two anchored edges, in CSS px. */
21
+ declare const DEFAULT_CORNER_OFFSET = 12;
22
+ /** `instance.labels` — the §14 DOM label lane subscription surface. */
23
+ interface GraphLabelsSurface {
24
+ /** Fires ONLY when the candidate SET changes (throttled re-rank; React
25
+ * re-renders label content). Replays current state on subscribe. */
26
+ subscribeCandidates(cb: (list: readonly LabelPlacement[]) => void): () => void;
27
+ /** Fires on scheduler ticks with fresh x/y for the SAME set (imperative
28
+ * transform writes — never a React re-render). Replays on subscribe. */
29
+ subscribePositions(cb: (list: readonly LabelPlacement[]) => void): () => void;
30
+ }
31
+ /** Instance members components rely on beyond the v0.3 GraphInstance type. */
32
+ interface GraphOverlaySurface {
33
+ labels?: GraphLabelsSurface;
34
+ /** Binding-detected reduced-motion media preference (§15.1). */
35
+ setReducedMotion?(v: boolean | undefined): void;
36
+ pauseSimulation?(): void;
37
+ resumeSimulation?(): void;
38
+ isSimulationRunning?(): boolean;
39
+ /** Delegates to the engine; resolves null when unsupported/not ready. */
40
+ captureScreenshot?(): Promise<Blob | null>;
41
+ }
42
+
43
+ export { DEFAULT_CORNER_OFFSET as D, type GraphCorner as G, type GraphLabelsSurface as a, type GraphOverlaySurface as b, useResolvedInstance as u };
package/package.json ADDED
@@ -0,0 +1,99 @@
1
+ {
2
+ "name": "@modernrelay/orbit-react",
3
+ "version": "0.2.0",
4
+ "description": "React binding for Orbit: <Graph> plus tree-shakeable components (toolbar, search, minimap, tooltip, inspector, table, navigator, and more).",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/ModernRelay/orbit.git",
9
+ "directory": "packages/react"
10
+ },
11
+ "type": "module",
12
+ "sideEffects": false,
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ },
21
+ "./components/Toolbar": {
22
+ "types": "./dist/components/Toolbar.d.ts",
23
+ "default": "./dist/components/Toolbar.js"
24
+ },
25
+ "./components/ContextMenu": {
26
+ "types": "./dist/components/ContextMenu.d.ts",
27
+ "default": "./dist/components/ContextMenu.js"
28
+ },
29
+ "./components/SelectionActions": {
30
+ "types": "./dist/components/SelectionActions.d.ts",
31
+ "default": "./dist/components/SelectionActions.js"
32
+ },
33
+ "./components/Navigator": {
34
+ "types": "./dist/components/Navigator.d.ts",
35
+ "default": "./dist/components/Navigator.js"
36
+ },
37
+ "./components/Histogram": {
38
+ "types": "./dist/components/Histogram.d.ts",
39
+ "default": "./dist/components/Histogram.js"
40
+ },
41
+ "./components/Timeline": {
42
+ "types": "./dist/components/Timeline.d.ts",
43
+ "default": "./dist/components/Timeline.js"
44
+ },
45
+ "./components/Legend": {
46
+ "types": "./dist/components/Legend.d.ts",
47
+ "default": "./dist/components/Legend.js"
48
+ },
49
+ "./components/Search": {
50
+ "types": "./dist/components/Search.d.ts",
51
+ "default": "./dist/components/Search.js"
52
+ },
53
+ "./components/Minimap": {
54
+ "types": "./dist/components/Minimap.d.ts",
55
+ "default": "./dist/components/Minimap.js"
56
+ },
57
+ "./components/Tooltip": {
58
+ "types": "./dist/components/Tooltip.d.ts",
59
+ "default": "./dist/components/Tooltip.js"
60
+ },
61
+ "./components/Inspector": {
62
+ "types": "./dist/components/Inspector.d.ts",
63
+ "default": "./dist/components/Inspector.js"
64
+ },
65
+ "./components/Table": {
66
+ "types": "./dist/components/Table.d.ts",
67
+ "default": "./dist/components/Table.js"
68
+ },
69
+ "./components/SimControls": {
70
+ "types": "./dist/components/SimControls.d.ts",
71
+ "default": "./dist/components/SimControls.js"
72
+ }
73
+ },
74
+ "publishConfig": {
75
+ "access": "public"
76
+ },
77
+ "dependencies": {
78
+ "@modernrelay/orbit-core": "0.2.0"
79
+ },
80
+ "peerDependencies": {
81
+ "react": ">=18",
82
+ "react-dom": ">=18"
83
+ },
84
+ "devDependencies": {
85
+ "@testing-library/react": "^16.0.0",
86
+ "@types/react": "^18.3.0",
87
+ "@types/react-dom": "^18.3.0",
88
+ "jsdom": "^26.0.0",
89
+ "react": "^18.3.1",
90
+ "react-dom": "^18.3.1",
91
+ "typescript": "^5.6.0",
92
+ "vitest": "^3.0.0"
93
+ },
94
+ "scripts": {
95
+ "build": "tsup",
96
+ "test": "vitest run",
97
+ "typecheck": "tsc --noEmit"
98
+ }
99
+ }