@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,488 @@
1
+ import { ReactNode, CSSProperties, RefAttributes, ReactElement } from 'react';
2
+ import { GraphSnapshot, Accessor, GraphNode, Scale, AcceptedEdge, LayoutKind, SimulationConfig, ThemeInput, MetricColumn, ScaleChannelInfo, GraphTheme, LabelConfig, AccessibilityConfig, NodeId, SubgraphSpec, FilterSpec, DimensionSpec, GroupSpec, GroupBySpec, ClusterSpec, SearchResult, SearchUnavailableReason, CreateGraphInstanceOptions, SelectionState, ResolvedGroup, MetaEdge, JsonValue, ViewportState, GraphViewState, SetViewStateResult, PathOptions, PathResult, ExpandNodeResult, ResolvedCluster, BeginIngestOptions, IngestSession, TimelinePlayback, CrossfilterSession, MetricName, Revisions, GraphDiagnostic, GraphInstance, DimensionSummary, BrushState, EdgeId, InstanceStatus } from '@modernrelay/orbit-core';
3
+ import { EngineFactory, FitViewOptions } from '@modernrelay/orbit-core/engine';
4
+ export { G as GraphProvider, a as GraphProviderProps } from './GraphProvider-B8ITDXS0.js';
5
+ export { D as DEFAULT_CORNER_OFFSET, G as GraphCorner, a as GraphLabelsSurface, b as GraphOverlaySurface, u as useResolvedInstance } from './shared-Bj3Gk219.js';
6
+
7
+ /**
8
+ * <Graph> — the declarative React binding over a headless GraphInstance.
9
+ *
10
+ * Binding parity (§6): one committed render that changes multiple declarative
11
+ * props issues AT MOST ONE applyHostUpdate carrying exactly the changed keys,
12
+ * so a multi-prop commit produces exactly one store revision and at most one
13
+ * engine commit.
14
+ */
15
+
16
+ /** Snapshot handed to `renderLegend` (§11): the active scale info per styling
17
+ * channel (null when the channel is not scale-valued) plus the resolved
18
+ * theme tokens. Recomputed on model/scope/render/theme store changes. */
19
+ interface GraphLegendRenderInfo<N = Record<string, unknown>> {
20
+ nodeColor: ScaleChannelInfo<N> | null;
21
+ nodeSize: ScaleChannelInfo<N> | null;
22
+ theme: GraphTheme;
23
+ }
24
+ interface GraphProps<N = Record<string, unknown>, E = Record<string, unknown>> {
25
+ /** Engine factory; captured at first render — one factory per instance. */
26
+ engine: EngineFactory;
27
+ data?: GraphSnapshot<N, E>;
28
+ /** Constant, accessor, or §11 Scale descriptor. Scale-valued props compare
29
+ * by canonical structural value — equal inline literals never reproject. */
30
+ nodeColor?: Accessor<GraphNode<N>, string> | Scale<string, N>;
31
+ nodeSize?: Accessor<GraphNode<N>, number> | Scale<number, N>;
32
+ linkColor?: Accessor<AcceptedEdge<E>, string>;
33
+ linkWidth?: Accessor<AcceptedEdge<E>, number>;
34
+ layout?: LayoutKind;
35
+ simulation?: SimulationConfig;
36
+ /** §8 theme tokens: full GraphTheme, Partial over a named base, or the
37
+ * v0.1 `{background}` shorthand. Diffed structurally (JSON). */
38
+ theme?: ThemeInput;
39
+ /** §12 async metric columns, joined once with revision-gated admission.
40
+ * Diffed by array reference. */
41
+ metrics?: readonly MetricColumn[];
42
+ /** §8 image sprites: synchronous string-ref accessor (URL/blob ref/cache
43
+ * key — opaque to orbit). Diffed by reference. */
44
+ nodeImage?: (node: GraphNode<N>) => string | null;
45
+ /** §16.12 instanced arrowheads (capability-gated; inert when unsupported). */
46
+ edgeArrows?: boolean;
47
+ /** §16.13 runtime link-render toggle — a config-only commit. */
48
+ showLinks?: boolean;
49
+ /** §11 legend escape hatch: rendered inside the provider in a positioned
50
+ * wrapper (bottom-left) whenever provided; re-invoked when scale info or
51
+ * theme changes. Return custom JSX, or compose <GraphLegend> from
52
+ * '@modernrelay/orbit-react/components/Legend' for the built-in rendering. */
53
+ renderLegend?: (info: GraphLegendRenderInfo<N>) => ReactNode;
54
+ /** §14 DOM label lane; forwarded through applyHostUpdate. `enabled: false`
55
+ * also unmounts the <LabelLayer> overlay entirely. */
56
+ labels?: LabelConfig<N>;
57
+ /** §15.1 accessibility runtime options; forwarded through applyHostUpdate
58
+ * and mirrored onto the container ARIA surface / live region. */
59
+ accessibility?: AccessibilityConfig<N>;
60
+ /** Class hook applied to every DOM label div (§14). */
61
+ labelClassName?: string;
62
+ /** Escape hatch: custom label content rendered INSIDE the positioned label
63
+ * div (replaces the default text node; §14). */
64
+ renderNodeLabel?: (ctx: {
65
+ node: GraphNode<N>;
66
+ text: string;
67
+ }) => ReactNode;
68
+ /** Class hook applied to §16.3 cluster label divs, in addition to
69
+ * `labelClassName` (S12-T07). */
70
+ clusterLabelClassName?: string;
71
+ /** Escape hatch: custom cluster-label content (replaces the default text
72
+ * node; §14 text-node-only rendering otherwise). `memberIds` are the ids a
73
+ * click selects (R-16.3-18). */
74
+ renderClusterLabel?: (ctx: {
75
+ clusterKey: string;
76
+ text: string;
77
+ memberIds: readonly NodeId[];
78
+ }) => ReactNode;
79
+ /** Controlled selection of the NODE namespace; providing it once flips
80
+ * ownership permanently (§6.4). Edge/group namespaces stay instance-owned. */
81
+ selection?: readonly NodeId[];
82
+ /** §9.2 hard scope: feed ONLY the resolved subset through the reconciler;
83
+ * `null` restores the full accepted model. Diffed STRUCTURALLY (specs are
84
+ * small), so a new-but-equal object is a no-op. UNCONTROLLED-ONLY in v0.5:
85
+ * this prop and isolateSelection()/resetIsolation() write the same
86
+ * instance-owned state — last writer wins, and omitting the prop leaves
87
+ * the last written scope in place. */
88
+ subgraph?: SubgraphSpec | null;
89
+ /** §9.1 soft filter: mask (hide/dim) with ZERO relayout; `null` clears.
90
+ * Diffed by canonical structural compare — serializable exprs by JSON,
91
+ * function predicates by reference — so a new-but-equal spec never
92
+ * re-publishes (and the core no-ops canonical-equal specs regardless). */
93
+ filter?: FilterSpec<N, E> | null;
94
+ /** §16.6 crossfilter dimensions (declarative; brushes live on the session
95
+ * — reach it via useGraphCrossfilter or handle.getCrossfilterSession()).
96
+ * Forwarded on array-reference change; the core no-ops when every
97
+ * DimensionSpec element is reference-equal. */
98
+ crossfilter?: readonly DimensionSpec<N>[];
99
+ /** §16.3 manual groups; `null` clears. Diffed STRUCTURALLY (equal inline
100
+ * literals never re-forward). Providing it once flips the groups slice to
101
+ * CONTROLLED (§6.4): handle ops then fire onGroupsChange with the next
102
+ * array instead of writing — reflect it back here. Config error together
103
+ * with `groupBy` (R-16.3-15: neither applies until one is removed). */
104
+ groups?: readonly GroupSpec[] | null;
105
+ /** §16.3 derived grouping; `null` clears. Reference-diffed (the spec
106
+ * carries a function accessor); the core additionally no-ops structurally
107
+ * equal respecs. Membership under groupBy is derived and READ-ONLY —
108
+ * groupNodes/ungroup become config errors; setGroupCollapsed toggles the
109
+ * instance-owned per-key collapsed residue (R-16.3-16). */
110
+ groupBy?: GroupBySpec<N> | null;
111
+ /** §16.3 stage-4 non-collapsing clusters (S12-T06); `null` clears (D2).
112
+ * Reference-diffed (the spec carries a function accessor). Clusters PRESERVE
113
+ * every node and edge — they never collapse anything — so they coexist with
114
+ * `groups`/`groupBy`. Their labels ride the §14 overlay lane under
115
+ * `labels.maxZoom` and select their member nodes on click. */
116
+ clusters?: ClusterSpec<N> | null;
117
+ /** §16.3 PERSISTENT pins (S12-T09) — independent of transient drag
118
+ * pinning: the engine receives the UNION, so releasing a drag on a
119
+ * persistently-pinned node leaves it pinned. Providing it once latches the
120
+ * slice controlled (§6.4): handle ops then fire onPinnedChange with the
121
+ * next array instead of writing. `null` clears (D2). */
122
+ pinnedNodeIds?: readonly NodeId[] | null;
123
+ /** §16.5 node attr fields the DEFAULT search service indexes (ids always).
124
+ * Absent = id-only search — the service never guesses attr names.
125
+ * CONSTRUCTION-ONLY (D7, spec host construction options): read once at
126
+ * mount; changing it requires a keyed remount (a changed prop warns once
127
+ * and is ignored). */
128
+ searchIndex?: readonly string[];
129
+ /** §16.5 result contract: the instance-wide DEFAULT for an activated
130
+ * search result that cannot be focused ('not-loaded' | 'out-of-scope' |
131
+ * 'filtered'). `<GraphSearch onResultUnavailable>` overrides it locally;
132
+ * the host reacts explicitly (fetch/publish an overlay, reset isolation,
133
+ * alter filters) — search never mutates scope/filters itself (S11). */
134
+ onSearchResultUnavailable?: (result: SearchResult, reason: SearchUnavailableReason) => void;
135
+ /** Captured at first render (instance construction option). Default true. */
136
+ fitViewOnFirstData?: boolean;
137
+ /** §9.2 service seam (instance construction option, D7): custom
138
+ * revision-aware services — most usefully an async `expansion` service
139
+ * backed by the host's own data source, so `expandNode`/the context menu's
140
+ * Expand run against the network instead of the built-in local-adjacency
141
+ * walk. CONSTRUCTION-ONLY: read once at mount; changing it requires a keyed
142
+ * remount. */
143
+ services?: CreateGraphInstanceOptions<N, E>['services'];
144
+ /** Shift+drag freeform lasso selection overlay (§16.2). Default true. */
145
+ enableLasso?: boolean;
146
+ className?: string;
147
+ style?: CSSProperties;
148
+ /** Rendered inside the provider, above (after) the canvas container. */
149
+ children?: ReactNode;
150
+ onNodeClick?: (payload: {
151
+ node: GraphNode<N>;
152
+ metaKey?: boolean;
153
+ }) => void;
154
+ onBackgroundClick?: () => void;
155
+ onNodeHover?: (payload: {
156
+ node: GraphNode<N> | null;
157
+ }) => void;
158
+ onEdgeClick?: (payload: {
159
+ edge: AcceptedEdge<E>;
160
+ }) => void;
161
+ onEdgeHover?: (payload: {
162
+ edge: AcceptedEdge<E> | null;
163
+ }) => void;
164
+ onNodeDragStart?: (payload: {
165
+ node: GraphNode<N>;
166
+ }) => void;
167
+ onNodeDragEnd?: (payload: {
168
+ node: GraphNode<N>;
169
+ x: number;
170
+ y: number;
171
+ }) => void;
172
+ /** Fires with the full namespaced SelectionState (§16.2). */
173
+ onSelectionChange?: (payload: SelectionState) => void;
174
+ /** §16.3/§7.4: a super-node hit — the resolved GROUP payload, never a
175
+ * GraphNode (R-16.3-12). */
176
+ onGroupClick?: (payload: {
177
+ group: ResolvedGroup;
178
+ metaKey?: boolean;
179
+ }) => void;
180
+ /** §16.3/§7.4: a meta-edge hit — the MetaEdge record (count badge datum). */
181
+ onMetaEdgeClick?: (payload: {
182
+ metaEdge: MetaEdge;
183
+ }) => void;
184
+ /** §6.4 groups slice change callback: op results (uncontrolled), op
185
+ * INTENTS (controlled — reflect the array back into `groups`), and groupBy
186
+ * re-derivations (notification). Receives the resolved array. */
187
+ onGroupsChange?: (groups: readonly ResolvedGroup[]) => void;
188
+ /** §16.14 durable source coordinate — forwarded verbatim; serialized into
189
+ * view states and canonically compared on restore. Diffed by canonical
190
+ * JSON, so a new-but-equal object never re-forwards. */
191
+ dataRef?: JsonValue;
192
+ /** §16.14 aggregate restore intent (fires once per restore/history
193
+ * transaction touching a controlled slice or serialized styling): reflect
194
+ * every participating prop in ONE commit; matching values acknowledge. */
195
+ onViewStateRestore?: (intent: {
196
+ transactionId: string;
197
+ source: 'setViewState' | 'undo' | 'redo';
198
+ next: unknown;
199
+ }) => void;
200
+ /** §16.14: fired INSTEAD of applying a state whose dataRef mismatches. */
201
+ onViewStateMismatch?: (stored: JsonValue | undefined, current: JsonValue | undefined) => void;
202
+ /** §6.4 persistent-pin slice change (S12-T09): the applied set when
203
+ * uncontrolled, the INTENT when controlled. */
204
+ onPinnedChange?: (pinnedNodeIds: readonly NodeId[]) => void;
205
+ onViewportChange?: (v: ViewportState) => void;
206
+ onReady?: () => void;
207
+ onError?: (payload: {
208
+ error: Error;
209
+ }) => void;
210
+ }
211
+ interface GraphHandle<N = Record<string, unknown>, E = Record<string, unknown>> {
212
+ /** `opts` is accepted for forward compatibility; core v0.1 ignores it. */
213
+ fitView(opts?: FitViewOptions): void;
214
+ zoomIn(): void;
215
+ zoomOut(): void;
216
+ /** `opts` is accepted for forward compatibility; core v0.1 ignores it. */
217
+ setViewport(v: Partial<ViewportState>, opts?: {
218
+ durationMs?: number;
219
+ }): void;
220
+ focusNode(id: NodeId): void;
221
+ /** Open the typed context menu for a node from host chrome (a list row, a
222
+ * custom label) — the same 'contextMenu' event the canvas gesture emits.
223
+ * `screen` is container-relative CSS px. */
224
+ requestNodeContextMenu(id: NodeId, screen: readonly [number, number]): void;
225
+ /** §16.14: serialize the exploration state (see core docs). */
226
+ getViewState(opts?: {
227
+ includePositions?: false;
228
+ }): GraphViewState;
229
+ /** §16.14: atomic restore; typed results, never partial. */
230
+ setViewState(raw: unknown, opts?: {
231
+ ignoreMismatch?: boolean;
232
+ }): Promise<SetViewStateResult>;
233
+ /** §16.14 picture export: 'png' via the engine screenshot; 'svg' via the
234
+ * engine-free exporter (typed export-too-large past the bound;
235
+ * raster-hybrid fallback available). */
236
+ exportImage(format: 'png'): Promise<Blob>;
237
+ exportImage(format: 'svg', opts?: {
238
+ maxSvgElements?: number;
239
+ fallback?: 'raster-hybrid';
240
+ }): Promise<string>;
241
+ /** §16.14 bounded object export; typed rejection past the limit. */
242
+ exportData(scope?: 'visible' | 'accepted', opts?: {
243
+ limit?: number;
244
+ }): Promise<{
245
+ nodes: readonly GraphNode<N>[];
246
+ edges: readonly AcceptedEdge<E>[];
247
+ }>;
248
+ /** §16.14 memory-bounded JSONL stream over one pinned revision. */
249
+ exportDataStream(scope?: 'visible' | 'accepted'): AsyncGenerator<string, void, undefined>;
250
+ /** §16.14 bounded id → [x, y] map (one position readback). */
251
+ exportLayout(opts?: {
252
+ limit?: number;
253
+ }): Promise<ReadonlyMap<NodeId, readonly [number, number]>>;
254
+ /** §16.14 layout JSONL stream over one pinned readback. */
255
+ exportLayoutStream(): AsyncGenerator<string, void, undefined>;
256
+ setSelection(ids: readonly NodeId[]): void;
257
+ clearSelection(): void;
258
+ /** Hold nodes at their CURRENT position (independent of drag pinning). */
259
+ pinNodes(ids: readonly NodeId[]): void;
260
+ unpinNodes(ids: readonly NodeId[]): void;
261
+ /** Resolve + atomically emphasize a path; null = unreachable (a result).
262
+ * Emphasis is session-local — released by clearPath, any selection
263
+ * mutation, undo/redo, or a scene rebuild; never in history/view state. */
264
+ findPath(sourceId: NodeId, targetId: NodeId, options?: PathOptions): Promise<PathResult | null>;
265
+ clearPath(): void;
266
+ /** Expand to the 1-hop neighborhood of `id` (or of the current selection). */
267
+ selectNeighbors(id?: NodeId): void;
268
+ selectAll(): void;
269
+ invertSelection(): void;
270
+ /** Resolve a SCREEN-coordinate polygon to node ids and replace (default) or
271
+ * union (`additive`) the node selection; returns the resolved ids. */
272
+ selectWithinPolygon(polygon: readonly [number, number][], opts?: {
273
+ additive?: boolean;
274
+ }): readonly NodeId[];
275
+ /** Pin at `xy` (space coords) or at the node's current position. */
276
+ pinNode(id: NodeId, xy?: readonly [number, number]): void;
277
+ unpinNode(id: NodeId): void;
278
+ clearPins(): void;
279
+ hideNodes(ids: readonly NodeId[]): void;
280
+ showAll(): void;
281
+ /** Hard-scope to the current node selection (no-op when empty; §9.2). */
282
+ isolateSelection(): void;
283
+ /** Clear the hard scope — the full accepted model returns (§9.2). */
284
+ resetIsolation(): void;
285
+ /** Ego-expand `id` through the configured ExpansionService (§9.2/§16.3). */
286
+ expandNode(id: NodeId, opts?: {
287
+ hops?: number;
288
+ }): Promise<ExpandNodeResult>;
289
+ /** Abort `id`'s pending expansion and remove its committed expansion
290
+ * overlays (§16.3). */
291
+ retractExpansion(id: NodeId): void;
292
+ /** Add one group (same acyclic/singly-parented validation as the `groups` prop).
293
+ * Controlled mode fires onGroupsChange with the next array instead. */
294
+ groupNodes(spec: GroupSpec): void;
295
+ /** Remove one group definition; its id prunes from selection.groupIds. */
296
+ ungroup(groupId: string): void;
297
+ /** Collapse/expand one group as a structural diff — the ONE op allowed on
298
+ * groupBy-derived groups (toggles the per-key collapsed residue). */
299
+ setGroupCollapsed(groupId: string, collapsed: boolean): void;
300
+ /** Hide `id`'s neighbourhood behind `id`, rerouting the members' outside
301
+ * edges onto it. Members default to unclaimed neighbours (first fold wins). */
302
+ foldNode(id: NodeId, opts?: {
303
+ memberIds?: readonly NodeId[];
304
+ }): void;
305
+ /** Return `id`'s folded members to the scene. No-op when not folded. */
306
+ unfoldNode(id: NodeId): void;
307
+ /** The members `id` stands for, or null when it is not folded. */
308
+ getFold(id: NodeId): {
309
+ memberIds: readonly NodeId[];
310
+ } | null;
311
+ /** Current clusters over the physical scene (keys, members, force center,
312
+ * settled centroid). Empty when no `clusters` prop is active. */
313
+ getClusters(): readonly ResolvedCluster[];
314
+ /** Select a cluster's MEMBER node ids (R-16.3-18); `additive` unions. */
315
+ selectCluster(key: string, opts?: {
316
+ additive?: boolean;
317
+ }): void;
318
+ /** Begin a bounded, cancellable ingest session (§7.5). */
319
+ beginIngest(opts: BeginIngestOptions): IngestSession<N, E>;
320
+ /** Atomically remove exactly one committed overlay; unknown ids are an
321
+ * idempotent `{ removed: false }` (§7.5). */
322
+ removeOverlay(overlayId: string): {
323
+ removed: boolean;
324
+ };
325
+ /** Undo the most recent uncontrolled mutation entry (selection / hidden /
326
+ * pins / scope / brushes). Returns false when there is nothing to undo. */
327
+ undo(): boolean;
328
+ /** Re-apply the most recently undone entry. False when nothing to redo. */
329
+ redo(): boolean;
330
+ /** Play a brush window across a numeric/temporal dimension's domain
331
+ * (crossfilter mask fast path; one playing dimension at a time). */
332
+ playTimeline(key: string, playback?: Partial<TimelinePlayback>): void;
333
+ pauseTimeline(): void;
334
+ /** The crossfilter session facade, or null until the `crossfilter` prop
335
+ * has configured dimensions over an accepted base. */
336
+ getCrossfilterSession(): CrossfilterSession | null;
337
+ /** §11 legend surface: the active Scale on a styling channel plus its
338
+ * resolved domain or categorical rows; null when not scale-valued. */
339
+ getScaleInfo(channel: 'nodeColor' | 'nodeSize'): ScaleChannelInfo<N> | null;
340
+ /** §12 metric read for one node id (built-in degree family + admitted
341
+ * columns); null for unknown ids/metrics and §8-null values. */
342
+ getMetricValue(metric: MetricName, id: NodeId): number | null;
343
+ getRevisions(): Revisions;
344
+ getDiagnostics(): readonly GraphDiagnostic[];
345
+ instance: GraphInstance<N, E>;
346
+ }
347
+ /** forwardRef erases generics; restore them with a typed call signature. */
348
+ type GraphComponent = <N = Record<string, unknown>, E = Record<string, unknown>>(props: GraphProps<N, E> & RefAttributes<GraphHandle<N, E>>) => ReactElement;
349
+ declare const Graph: GraphComponent;
350
+
351
+ /**
352
+ * LabelLayer — the §14 DOM label lane (S7-T05).
353
+ *
354
+ * Two-channel rendering against the pinned overlay interface:
355
+ * - `labels.subscribeCandidates` fires only when the candidate SET changes →
356
+ * React state → one absolutely-positioned <div> per candidate. Label text
357
+ * is rendered as a TEXT NODE only (never markup), so hostile strings in
358
+ * node attrs appear literally.
359
+ * - `labels.subscribePositions` fires on scheduler ticks with fresh x/y for
360
+ * the SAME set → imperative `style.transform` writes through refs keyed by
361
+ * id. No React re-render per tick (M0: the label lane is pure CPU O(k)).
362
+ *
363
+ * The layer is pointer-inert; label divs opt back in and drive the S6
364
+ * click-selection path through the same public mutators (replace on plain
365
+ * click, toggle on meta/shift — S7-T17).
366
+ */
367
+
368
+ interface LabelLayerProps {
369
+ /** Class hook applied to every label div. */
370
+ labelClassName?: string | undefined;
371
+ /** Escape hatch rendered INSIDE the positioned div instead of the text node. */
372
+ renderNodeLabel?: ((ctx: {
373
+ node: GraphNode<any>;
374
+ text: string;
375
+ }) => ReactNode) | undefined;
376
+ /** Class hook applied to §16.3 CLUSTER label divs (in addition to
377
+ * `labelClassName`), so the coarse layer can be styled apart. */
378
+ clusterLabelClassName?: string | undefined;
379
+ /** Escape hatch for cluster labels; `memberIds` are the ids a click
380
+ * selects (R-16.3-18). */
381
+ renderClusterLabel?: ((ctx: {
382
+ clusterKey: string;
383
+ text: string;
384
+ memberIds: readonly NodeId[];
385
+ }) => ReactNode) | undefined;
386
+ }
387
+ /** Internal to <Graph> (gated by `labels.enabled`); reads the ambient
388
+ * instance so hosts composing GraphProvider directly can reuse it. */
389
+ declare function LabelLayer(props: LabelLayerProps): ReactElement;
390
+
391
+ /**
392
+ * LiveRegion — §15.1 screen-reader announcements (S7-T10).
393
+ *
394
+ * A visually-hidden `aria-live="polite"` region adjacent to the canvas. It
395
+ * subscribes to the STORE (never the frame clock, so simulation frames can
396
+ * never announce) and speaks a coalesced summary — node/edge counts,
397
+ * selection count, status — at most once every 800ms and only when the
398
+ * summary STRING changes. Trailing-edge coalescing: a burst of store changes
399
+ * lands as ONE announcement carrying the freshest state.
400
+ *
401
+ * Gated off entirely when `accessibility.announcements === false`.
402
+ */
403
+
404
+ interface LiveRegionProps {
405
+ /** `accessibility.announcements`; false gates all announcements. Default true. */
406
+ announcements?: boolean | undefined;
407
+ }
408
+ /** Internal to <Graph>; reads the ambient instance so hosts composing
409
+ * GraphProvider directly can reuse it. */
410
+ declare function LiveRegion(props: LiveRegionProps): ReactElement;
411
+
412
+ /**
413
+ * Public hooks — thin useSyncExternalStore selectors over the ambient
414
+ * GraphInstance's vanilla zustand store. All throw a descriptive error when
415
+ * used outside a <Graph>/<GraphProvider> subtree.
416
+ */
417
+
418
+ declare function useGraphInstance<N = Record<string, unknown>, E = Record<string, unknown>>(): GraphInstance<N, E>;
419
+ /** The full namespaced SelectionState (§16.2); was `readonly NodeId[]` before
420
+ * v0.3 — read `.nodeIds` for the node namespace. */
421
+ declare function useGraphSelection(): SelectionState;
422
+ declare function useGraphHover(): NodeId | null;
423
+ declare function useGraphEdgeHover(): EdgeId | null;
424
+ /** The §16.3 pin slice: node id → pinned space position. */
425
+ declare function useGraphPins(): ReadonlyMap<NodeId, readonly [number, number]>;
426
+ declare function useGraphViewport(): ViewportState | null;
427
+ declare function useGraphStatus(): InstanceStatus;
428
+ declare function useGraphDiagnostics(): readonly GraphDiagnostic[];
429
+ /** Whether the engine force simulation is currently running (S7; drives the
430
+ * toolbar pause/resume affordance). */
431
+ declare function useGraphSimulationRunning(): boolean;
432
+ /** The active §9.2 hard scope (`subgraph`); null while the full accepted
433
+ * model is in view. Uncontrolled-only in v0.5: the `subgraph` prop and
434
+ * isolateSelection()/resetIsolation() write this same instance-owned state. */
435
+ declare function useGraphScope(): SubgraphSpec | null;
436
+ /** Node ids with an expansion in flight (§9.2 loading affordance — drive
437
+ * spinners/ghost skeletons from this set). */
438
+ declare function useGraphPendingExpansions(): ReadonlySet<NodeId>;
439
+ /** Committed §7.5 overlay ids for the current dataset. */
440
+ declare function useGraphOverlays(): readonly string[];
441
+ /** §9.1 soft-mask visibility counts: scene entities with zero hide-failures
442
+ * (equals the accepted counts when nothing masks). */
443
+ declare function useGraphVisible(): {
444
+ nodes: number;
445
+ edges: number;
446
+ };
447
+ /** §16.6 timeline playback state — at most one playing dimension key. */
448
+ declare function useGraphTimeline(): {
449
+ playingKey: string | null;
450
+ };
451
+ /** §16.14 history kernel depths (S9 wiring; full walk semantics in S15). */
452
+ declare function useGraphHistory(): {
453
+ undoDepth: number;
454
+ redoDepth: number;
455
+ };
456
+ /** §8 resolved theme tokens (S10): the merged GraphTheme currently driving
457
+ * engine config, projection fallbacks, and mask dim alpha (`store.theme`).
458
+ * Style legend chrome, tooltips, and other host overlays from these tokens. */
459
+ declare function useGraphTheme(): GraphTheme;
460
+ /** The last completed §16.5 search (`store.search`): `{query, results}` after
461
+ * a successful `instance.search`, null after `clearSearch()` / a dataset
462
+ * swap. Drives `<GraphSearch>`'s result list and the §15.1 navigator's
463
+ * search-results section. */
464
+ declare function useGraphSearch(): {
465
+ query: string;
466
+ results: readonly SearchResult[];
467
+ } | null;
468
+ /** §16.5 `onSearchResultUnavailable` callback type (spec §16.5 result
469
+ * contract): fired when an activated result cannot be focused; `reason` is
470
+ * 'not-loaded' | 'out-of-scope' | 'filtered'. The host reacts explicitly —
471
+ * orbit never changes scope/filters behind the user's back. */
472
+ type SearchResultUnavailableCallback = (result: SearchResult, reason: SearchUnavailableReason) => void;
473
+ /** One §16.6 crossfilter dimension: live summary + brush + a setter. */
474
+ interface GraphCrossfilterDimension {
475
+ /** Null until the `crossfilter` prop builds the dimension over data. */
476
+ summary: DimensionSummary | null;
477
+ brush: BrushState;
478
+ setBrush: (brush: BrushState) => void;
479
+ }
480
+ /**
481
+ * Subscribe to one crossfilter dimension by key (§16.6). Re-reads
482
+ * summarize/getBrush on session notify; resolves the session lazily (null
483
+ * summary until the `crossfilter` prop builds dimensions over an accepted
484
+ * base — the store publishes when they do).
485
+ */
486
+ declare function useGraphCrossfilter(key: string): GraphCrossfilterDimension;
487
+
488
+ export { Graph, type GraphCrossfilterDimension, type GraphHandle, type GraphLegendRenderInfo, type GraphProps, LabelLayer, type LabelLayerProps, LiveRegion, type LiveRegionProps, type SearchResultUnavailableCallback, useGraphCrossfilter, useGraphDiagnostics, useGraphEdgeHover, useGraphHistory, useGraphHover, useGraphInstance, useGraphOverlays, useGraphPendingExpansions, useGraphPins, useGraphScope, useGraphSearch, useGraphSelection, useGraphSimulationRunning, useGraphStatus, useGraphTheme, useGraphTimeline, useGraphViewport, useGraphVisible };