@ankhorage/zora 25.10.9 → 25.11.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.
- package/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.d.ts +10 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.js +18 -8
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.d.ts +9 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.js +36 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.js.map +1 -0
- package/dist/features/graph-view/constants/events.d.ts +11 -0
- package/dist/features/graph-view/constants/events.d.ts.map +1 -0
- package/dist/features/graph-view/constants/events.js +10 -0
- package/dist/features/graph-view/constants/events.js.map +1 -0
- package/dist/features/graph-view/public.d.ts +2 -1
- package/dist/features/graph-view/public.d.ts.map +1 -1
- package/dist/features/graph-view/public.js +1 -0
- package/dist/features/graph-view/public.js.map +1 -1
- package/dist/types/graph-view.d.ts +4 -0
- package/dist/types/graph-view.d.ts.map +1 -1
- package/dist/types/graph-view.js.map +1 -1
- package/package.json +1 -1
- package/src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx +36 -13
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.test.ts +77 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.ts +55 -0
- package/src/features/graph-view/constants/events.ts +12 -0
- package/src/features/graph-view/public.ts +2 -0
- package/src/types/graph-view.ts +5 -0
- package/web-dist/components/graph-view/GraphView.d.ts +12 -1
- package/web-dist/components/graph-view/GraphView.js +45 -8
- package/web-dist/components/graph-view/GraphView.types-0.d.ts +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 25.11.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9f6a15f: Expose public bubbling GraphView browser lifecycle events carrying the existing controller, so integrations can measure and target actual rendered graph nodes without private renderer access.
|
|
8
|
+
|
|
3
9
|
## 25.10.9
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# @ankhorage/zora
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.
|
|
9
9
|
|
|
@@ -8,10 +8,20 @@ import type { GraphViewProps } from '../../../../../types/graph-view';
|
|
|
8
8
|
* text. Keep padding in styleRules. Compound and rich-node dimensions retain their existing owners.
|
|
9
9
|
* minReadableLabelSize Expand the manual zoom ceiling until plain labels reach this CSS-pixel size.
|
|
10
10
|
* maxFitLabelSize Cap automatic fitting at this plain-label CSS-pixel size, leaving whitespace for tiny graphs.
|
|
11
|
+
* Browser lifecycle events named by public GRAPH_VIEW_EVENTS bubble from the root
|
|
12
|
+
* with `detail.controller`: the same public GraphViewController delivered to React.
|
|
13
|
+
* Browser integrations can call `measureNodes` without accessing the Cytoscape runtime.
|
|
14
|
+
* The standalone browser artifact exposes the same names as `GraphView.events`.
|
|
11
15
|
* onSpacingFactorChange Receive the spacing accepted by explicit fit({ optimizeSpacing: true }).
|
|
12
16
|
* Ordinary zoom never adjusts spacing or relayouts. Explicit optimization preserves layout ordering,
|
|
13
17
|
* stops once effective fit reaches maxFitLabelSize, keeps labels and unrelated compound boundaries
|
|
14
18
|
* collision-safe, and permits only a small rendered background-overlap fallback for dense graphs.
|
|
15
19
|
*/
|
|
16
20
|
export declare function GraphView(props: GraphViewProps): React.JSX.Element;
|
|
21
|
+
export declare namespace GraphView {
|
|
22
|
+
var events: {
|
|
23
|
+
readonly ready: "zora-graph-view-ready";
|
|
24
|
+
readonly layoutComplete: "zora-graph-view-layout-complete";
|
|
25
|
+
};
|
|
26
|
+
}
|
|
17
27
|
//# sourceMappingURL=GraphView.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphView.d.ts","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAGV,cAAc,EAEf,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"GraphView.d.ts","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAGV,cAAc,EAEf,MAAM,iCAAiC,CAAC;AAQzC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,qBAiC9C;yBAjCe,SAAS"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { GRAPH_VIEW_EVENTS } from '../../../constants/events';
|
|
2
3
|
import { createGraphRuntime } from './createGraphRuntime';
|
|
4
|
+
import { createGraphViewDomCallbacks } from './createGraphViewDomCallbacks';
|
|
3
5
|
import { GraphNodeOverlay } from './GraphNodeOverlay';
|
|
4
6
|
/***
|
|
5
7
|
* Render a browser graph while one runtime owns Cytoscape layout, viewport, and disposal.
|
|
@@ -9,14 +11,19 @@ import { GraphNodeOverlay } from './GraphNodeOverlay';
|
|
|
9
11
|
* text. Keep padding in styleRules. Compound and rich-node dimensions retain their existing owners.
|
|
10
12
|
* minReadableLabelSize Expand the manual zoom ceiling until plain labels reach this CSS-pixel size.
|
|
11
13
|
* maxFitLabelSize Cap automatic fitting at this plain-label CSS-pixel size, leaving whitespace for tiny graphs.
|
|
14
|
+
* Browser lifecycle events named by public GRAPH_VIEW_EVENTS bubble from the root
|
|
15
|
+
* with `detail.controller`: the same public GraphViewController delivered to React.
|
|
16
|
+
* Browser integrations can call `measureNodes` without accessing the Cytoscape runtime.
|
|
17
|
+
* The standalone browser artifact exposes the same names as `GraphView.events`.
|
|
12
18
|
* onSpacingFactorChange Receive the spacing accepted by explicit fit({ optimizeSpacing: true }).
|
|
13
19
|
* Ordinary zoom never adjusts spacing or relayouts. Explicit optimization preserves layout ordering,
|
|
14
20
|
* stops once effective fit reaches maxFitLabelSize, keeps labels and unrelated compound boundaries
|
|
15
21
|
* collision-safe, and permits only a small rendered background-overlap fallback for dense graphs.
|
|
16
22
|
*/
|
|
17
23
|
export function GraphView(props) {
|
|
18
|
-
const
|
|
19
|
-
|
|
24
|
+
const hostRef = React.useRef(null);
|
|
25
|
+
const { containerRef, renderedNodes, runtimeRef } = useGraphViewRuntime(props, hostRef);
|
|
26
|
+
return (<div ref={hostRef} aria-label={props.ariaLabel ?? 'Graph'} className={props.className} role="application" style={{
|
|
20
27
|
height: '100%',
|
|
21
28
|
minHeight: 0,
|
|
22
29
|
minWidth: 0,
|
|
@@ -28,11 +35,13 @@ export function GraphView(props) {
|
|
|
28
35
|
{props.renderNode ? (<GraphNodeOverlay nodes={props.nodes} renderedNodes={renderedNodes} renderNode={props.renderNode} onNodeEvent={(id, type, selectionIntent) => runtimeRef.current?.handleOverlayNodeEvent(id, type, selectionIntent)} onNodeSize={(id, size) => runtimeRef.current?.setNodeSize(id, size)}/>) : null}
|
|
29
36
|
</div>);
|
|
30
37
|
}
|
|
38
|
+
/*** Publish the same canonical event registry on the standalone GraphView artifact. */
|
|
39
|
+
GraphView.events = GRAPH_VIEW_EVENTS;
|
|
31
40
|
/*** Compose React synchronization around the single imperative graph runtime. */
|
|
32
|
-
function useGraphViewRuntime(props) {
|
|
41
|
+
function useGraphViewRuntime(props, hostRef) {
|
|
33
42
|
const containerRef = React.useRef(null);
|
|
34
43
|
const runtimeRef = React.useRef(null);
|
|
35
|
-
const callbacksRef = useGraphCallbacksRef(props);
|
|
44
|
+
const callbacksRef = useGraphCallbacksRef(props, hostRef);
|
|
36
45
|
const [renderedNodes, setRenderedNodes] = React.useState([]);
|
|
37
46
|
useRuntimeLifecycle(containerRef, runtimeRef, callbacksRef);
|
|
38
47
|
useRuntimeGraphUpdate(runtimeRef, props);
|
|
@@ -42,18 +51,18 @@ function useGraphViewRuntime(props) {
|
|
|
42
51
|
return { containerRef, renderedNodes, runtimeRef };
|
|
43
52
|
}
|
|
44
53
|
/*** Keep the callback ref current without mutating refs during render. */
|
|
45
|
-
function useGraphCallbacksRef(props) {
|
|
46
|
-
const callbacksRef = React.useRef(readCallbacks(props));
|
|
54
|
+
function useGraphCallbacksRef(props, hostRef) {
|
|
55
|
+
const callbacksRef = React.useRef(createGraphViewDomCallbacks(readCallbacks(props), hostRef));
|
|
47
56
|
const { onEdgeEvent, onLayoutComplete, onNodeEvent, onReady, onViewportChange, onSpacingFactorChange, } = props;
|
|
48
57
|
React.useEffect(() => {
|
|
49
|
-
callbacksRef.current = {
|
|
58
|
+
callbacksRef.current = createGraphViewDomCallbacks({
|
|
50
59
|
onEdgeEvent,
|
|
51
60
|
onLayoutComplete,
|
|
52
61
|
onNodeEvent,
|
|
53
62
|
onReady,
|
|
54
63
|
onViewportChange,
|
|
55
64
|
onSpacingFactorChange,
|
|
56
|
-
};
|
|
65
|
+
}, hostRef);
|
|
57
66
|
}, [
|
|
58
67
|
onEdgeEvent,
|
|
59
68
|
onLayoutComplete,
|
|
@@ -61,6 +70,7 @@ function useGraphCallbacksRef(props) {
|
|
|
61
70
|
onReady,
|
|
62
71
|
onViewportChange,
|
|
63
72
|
onSpacingFactorChange,
|
|
73
|
+
hostRef,
|
|
64
74
|
]);
|
|
65
75
|
return callbacksRef;
|
|
66
76
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphView.js","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { CytoscapeOptions } from 'cytoscape';\nimport React from 'react';\n\nimport type {\n GraphViewCallbacks,\n GraphViewNode,\n GraphViewProps,\n GraphViewRenderedNode,\n} from '../../../../../types/graph-view';\nimport { createGraphRuntime, type GraphRuntime } from './createGraphRuntime';\nimport { GraphNodeOverlay } from './GraphNodeOverlay';\n\ntype GraphContainer = NonNullable<CytoscapeOptions['container']>;\n\n/***\n * Render a browser graph while one runtime owns Cytoscape layout, viewport, and disposal.\n * zoomMode Use `fit-relative` to make controller zoom, events and min/max limits relative\n * to the visible-node fit (1 = fit). The default `absolute` keeps engine-space zoom units.\n * sizeNodesToLabels Opt in to renderer-measured plain labels, including bold and Unicode\n * text. Keep padding in styleRules. Compound and rich-node dimensions retain their existing owners.\n * minReadableLabelSize Expand the manual zoom ceiling until plain labels reach this CSS-pixel size.\n * maxFitLabelSize Cap automatic fitting at this plain-label CSS-pixel size, leaving whitespace for tiny graphs.\n * onSpacingFactorChange Receive the spacing accepted by explicit fit({ optimizeSpacing: true }).\n * Ordinary zoom never adjusts spacing or relayouts. Explicit optimization preserves layout ordering,\n * stops once effective fit reaches maxFitLabelSize, keeps labels and unrelated compound boundaries\n * collision-safe, and permits only a small rendered background-overlap fallback for dense graphs.\n */\nexport function GraphView(props: GraphViewProps) {\n const { containerRef, renderedNodes, runtimeRef } = useGraphViewRuntime(props);\n\n return (\n <div\n aria-label={props.ariaLabel ?? 'Graph'}\n className={props.className}\n role=\"application\"\n style={{\n height: '100%',\n minHeight: 0,\n minWidth: 0,\n position: 'relative',\n width: '100%',\n ...props.style,\n }}\n >\n <div ref={containerRef} style={{ height: '100%', width: '100%' }} />\n {props.renderNode ? (\n <GraphNodeOverlay\n nodes={props.nodes}\n renderedNodes={renderedNodes}\n renderNode={props.renderNode}\n onNodeEvent={(id, type, selectionIntent) =>\n runtimeRef.current?.handleOverlayNodeEvent(id, type, selectionIntent)\n }\n onNodeSize={(id, size) => runtimeRef.current?.setNodeSize(id, size)}\n />\n ) : null}\n </div>\n );\n}\n\n/*** Compose React synchronization around the single imperative graph runtime. */\nfunction useGraphViewRuntime(props: GraphViewProps) {\n const containerRef = React.useRef<GraphContainer | null>(null);\n const runtimeRef = React.useRef<GraphRuntime | null>(null);\n const callbacksRef = useGraphCallbacksRef(props);\n const [renderedNodes, setRenderedNodes] = React.useState<readonly GraphViewRenderedNode[]>([]);\n\n useRuntimeLifecycle(containerRef, runtimeRef, callbacksRef);\n useRuntimeGraphUpdate(runtimeRef, props);\n useRuntimeSelection(runtimeRef, props.selectedNodeIds);\n useRenderedNodeSubscription(runtimeRef, props.renderNode, setRenderedNodes);\n useKnownNodeSizes(runtimeRef, props.nodes, props.getNodeSize);\n\n return { containerRef, renderedNodes, runtimeRef };\n}\n\n/*** Keep the callback ref current without mutating refs during render. */\nfunction useGraphCallbacksRef(props: GraphViewProps) {\n const callbacksRef = React.useRef<GraphViewCallbacks>(readCallbacks(props));\n const {\n onEdgeEvent,\n onLayoutComplete,\n onNodeEvent,\n onReady,\n onViewportChange,\n onSpacingFactorChange,\n } = props;\n\n React.useEffect(() => {\n callbacksRef.current = {\n onEdgeEvent,\n onLayoutComplete,\n onNodeEvent,\n onReady,\n onViewportChange,\n onSpacingFactorChange,\n };\n }, [\n onEdgeEvent,\n onLayoutComplete,\n onNodeEvent,\n onReady,\n onViewportChange,\n onSpacingFactorChange,\n ]);\n\n return callbacksRef;\n}\n\n/*** Create and dispose the runtime only with the underlying browser container lifetime. */\nfunction useRuntimeLifecycle(\n containerRef: { current: GraphContainer | null },\n runtimeRef: { current: GraphRuntime | null },\n callbacksRef: { current: GraphViewCallbacks },\n) {\n React.useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n const runtime = createGraphRuntime(container, callbacksRef);\n runtimeRef.current = runtime;\n return () => {\n runtime.destroy();\n runtimeRef.current = null;\n };\n }, [callbacksRef, containerRef, runtimeRef]);\n}\n\n/*** Synchronize graph data and layout policy without exposing Cytoscape to React. */\nfunction useRuntimeGraphUpdate(\n runtimeRef: { current: GraphRuntime | null },\n props: GraphViewProps,\n) {\n const {\n edges,\n fitPadding,\n layout,\n layoutOptions,\n maxZoom,\n minReadableLabelSize,\n maxFitLabelSize,\n minZoom,\n zoomMode,\n sizeNodesToLabels,\n nodes,\n renderNode,\n spacingFactor,\n styleRules,\n } = props;\n\n React.useEffect(() => {\n runtimeRef.current?.update({\n edges,\n fitPadding,\n layout,\n layoutOptions,\n maxZoom,\n minReadableLabelSize,\n maxFitLabelSize,\n minZoom,\n zoomMode,\n sizeNodesToLabels,\n nodes,\n richNodeRendering: renderNode !== undefined,\n spacingFactor,\n styleRules,\n });\n }, [\n edges,\n fitPadding,\n layout,\n layoutOptions,\n maxZoom,\n minReadableLabelSize,\n maxFitLabelSize,\n minZoom,\n zoomMode,\n sizeNodesToLabels,\n nodes,\n renderNode,\n runtimeRef,\n spacingFactor,\n styleRules,\n ]);\n}\n\n/*** Synchronize optional controlled selection independently from graph layout. */\nfunction useRuntimeSelection(\n runtimeRef: { current: GraphRuntime | null },\n selectedNodeIds: readonly string[] | undefined,\n) {\n React.useEffect(() => {\n runtimeRef.current?.setSelectedNodeIds(selectedNodeIds);\n }, [runtimeRef, selectedNodeIds]);\n}\n\n/*** Subscribe the optional rich-node overlay to rendered runtime positions. */\nfunction useRenderedNodeSubscription(\n runtimeRef: { current: GraphRuntime | null },\n renderNode: GraphViewProps['renderNode'],\n setRenderedNodes: (nodes: readonly GraphViewRenderedNode[]) => void,\n) {\n React.useEffect(() => {\n const runtime = runtimeRef.current;\n if (runtime === null || renderNode === undefined) {\n setRenderedNodes([]);\n return;\n }\n return runtime.subscribeRenderedNodes(setRenderedNodes);\n }, [renderNode, runtimeRef, setRenderedNodes]);\n}\n\n/*** Seed known rich-node dimensions without requiring DOM measurement. */\nfunction useKnownNodeSizes(\n runtimeRef: { current: GraphRuntime | null },\n nodes: readonly GraphViewNode[],\n getNodeSize: GraphViewProps['getNodeSize'],\n) {\n React.useEffect(() => {\n const runtime = runtimeRef.current;\n if (runtime === null || getNodeSize === undefined) return;\n for (const node of nodes) {\n const size = getNodeSize(node);\n if (size) runtime.setNodeSize(node.id, size);\n }\n }, [getNodeSize, nodes, runtimeRef]);\n}\n\n/*** Read callback props for the initial runtime callback-ref value. */\nfunction readCallbacks(props: GraphViewProps): GraphViewCallbacks {\n return {\n onEdgeEvent: props.onEdgeEvent,\n onLayoutComplete: props.onLayoutComplete,\n onNodeEvent: props.onNodeEvent,\n onReady: props.onReady,\n onViewportChange: props.onViewportChange,\n onSpacingFactorChange: props.onSpacingFactorChange,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"GraphView.js","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { CytoscapeOptions } from 'cytoscape';\nimport React from 'react';\n\nimport type {\n GraphViewCallbacks,\n GraphViewNode,\n GraphViewProps,\n GraphViewRenderedNode,\n} from '../../../../../types/graph-view';\nimport { GRAPH_VIEW_EVENTS } from '../../../constants/events';\nimport { createGraphRuntime, type GraphRuntime } from './createGraphRuntime';\nimport { createGraphViewDomCallbacks } from './createGraphViewDomCallbacks';\nimport { GraphNodeOverlay } from './GraphNodeOverlay';\n\ntype GraphContainer = NonNullable<CytoscapeOptions['container']>;\n\n/***\n * Render a browser graph while one runtime owns Cytoscape layout, viewport, and disposal.\n * zoomMode Use `fit-relative` to make controller zoom, events and min/max limits relative\n * to the visible-node fit (1 = fit). The default `absolute` keeps engine-space zoom units.\n * sizeNodesToLabels Opt in to renderer-measured plain labels, including bold and Unicode\n * text. Keep padding in styleRules. Compound and rich-node dimensions retain their existing owners.\n * minReadableLabelSize Expand the manual zoom ceiling until plain labels reach this CSS-pixel size.\n * maxFitLabelSize Cap automatic fitting at this plain-label CSS-pixel size, leaving whitespace for tiny graphs.\n * Browser lifecycle events named by public GRAPH_VIEW_EVENTS bubble from the root\n * with `detail.controller`: the same public GraphViewController delivered to React.\n * Browser integrations can call `measureNodes` without accessing the Cytoscape runtime.\n * The standalone browser artifact exposes the same names as `GraphView.events`.\n * onSpacingFactorChange Receive the spacing accepted by explicit fit({ optimizeSpacing: true }).\n * Ordinary zoom never adjusts spacing or relayouts. Explicit optimization preserves layout ordering,\n * stops once effective fit reaches maxFitLabelSize, keeps labels and unrelated compound boundaries\n * collision-safe, and permits only a small rendered background-overlap fallback for dense graphs.\n */\nexport function GraphView(props: GraphViewProps) {\n const hostRef = React.useRef<HTMLDivElement | null>(null);\n const { containerRef, renderedNodes, runtimeRef } = useGraphViewRuntime(props, hostRef);\n\n return (\n <div\n ref={hostRef}\n aria-label={props.ariaLabel ?? 'Graph'}\n className={props.className}\n role=\"application\"\n style={{\n height: '100%',\n minHeight: 0,\n minWidth: 0,\n position: 'relative',\n width: '100%',\n ...props.style,\n }}\n >\n <div ref={containerRef} style={{ height: '100%', width: '100%' }} />\n {props.renderNode ? (\n <GraphNodeOverlay\n nodes={props.nodes}\n renderedNodes={renderedNodes}\n renderNode={props.renderNode}\n onNodeEvent={(id, type, selectionIntent) =>\n runtimeRef.current?.handleOverlayNodeEvent(id, type, selectionIntent)\n }\n onNodeSize={(id, size) => runtimeRef.current?.setNodeSize(id, size)}\n />\n ) : null}\n </div>\n );\n}\n\n/*** Publish the same canonical event registry on the standalone GraphView artifact. */\nGraphView.events = GRAPH_VIEW_EVENTS;\n\n/*** Compose React synchronization around the single imperative graph runtime. */\nfunction useGraphViewRuntime(\n props: GraphViewProps,\n hostRef: React.RefObject<HTMLDivElement | null>,\n) {\n const containerRef = React.useRef<GraphContainer | null>(null);\n const runtimeRef = React.useRef<GraphRuntime | null>(null);\n const callbacksRef = useGraphCallbacksRef(props, hostRef);\n const [renderedNodes, setRenderedNodes] = React.useState<readonly GraphViewRenderedNode[]>([]);\n\n useRuntimeLifecycle(containerRef, runtimeRef, callbacksRef);\n useRuntimeGraphUpdate(runtimeRef, props);\n useRuntimeSelection(runtimeRef, props.selectedNodeIds);\n useRenderedNodeSubscription(runtimeRef, props.renderNode, setRenderedNodes);\n useKnownNodeSizes(runtimeRef, props.nodes, props.getNodeSize);\n\n return { containerRef, renderedNodes, runtimeRef };\n}\n\n/*** Keep the callback ref current without mutating refs during render. */\nfunction useGraphCallbacksRef(\n props: GraphViewProps,\n hostRef: React.RefObject<HTMLDivElement | null>,\n) {\n const callbacksRef = React.useRef<GraphViewCallbacks>(\n createGraphViewDomCallbacks(readCallbacks(props), hostRef),\n );\n const {\n onEdgeEvent,\n onLayoutComplete,\n onNodeEvent,\n onReady,\n onViewportChange,\n onSpacingFactorChange,\n } = props;\n\n React.useEffect(() => {\n callbacksRef.current = createGraphViewDomCallbacks(\n {\n onEdgeEvent,\n onLayoutComplete,\n onNodeEvent,\n onReady,\n onViewportChange,\n onSpacingFactorChange,\n },\n hostRef,\n );\n }, [\n onEdgeEvent,\n onLayoutComplete,\n onNodeEvent,\n onReady,\n onViewportChange,\n onSpacingFactorChange,\n hostRef,\n ]);\n\n return callbacksRef;\n}\n\n/*** Create and dispose the runtime only with the underlying browser container lifetime. */\nfunction useRuntimeLifecycle(\n containerRef: { current: GraphContainer | null },\n runtimeRef: { current: GraphRuntime | null },\n callbacksRef: { current: GraphViewCallbacks },\n) {\n React.useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n const runtime = createGraphRuntime(container, callbacksRef);\n runtimeRef.current = runtime;\n return () => {\n runtime.destroy();\n runtimeRef.current = null;\n };\n }, [callbacksRef, containerRef, runtimeRef]);\n}\n\n/*** Synchronize graph data and layout policy without exposing Cytoscape to React. */\nfunction useRuntimeGraphUpdate(\n runtimeRef: { current: GraphRuntime | null },\n props: GraphViewProps,\n) {\n const {\n edges,\n fitPadding,\n layout,\n layoutOptions,\n maxZoom,\n minReadableLabelSize,\n maxFitLabelSize,\n minZoom,\n zoomMode,\n sizeNodesToLabels,\n nodes,\n renderNode,\n spacingFactor,\n styleRules,\n } = props;\n\n React.useEffect(() => {\n runtimeRef.current?.update({\n edges,\n fitPadding,\n layout,\n layoutOptions,\n maxZoom,\n minReadableLabelSize,\n maxFitLabelSize,\n minZoom,\n zoomMode,\n sizeNodesToLabels,\n nodes,\n richNodeRendering: renderNode !== undefined,\n spacingFactor,\n styleRules,\n });\n }, [\n edges,\n fitPadding,\n layout,\n layoutOptions,\n maxZoom,\n minReadableLabelSize,\n maxFitLabelSize,\n minZoom,\n zoomMode,\n sizeNodesToLabels,\n nodes,\n renderNode,\n runtimeRef,\n spacingFactor,\n styleRules,\n ]);\n}\n\n/*** Synchronize optional controlled selection independently from graph layout. */\nfunction useRuntimeSelection(\n runtimeRef: { current: GraphRuntime | null },\n selectedNodeIds: readonly string[] | undefined,\n) {\n React.useEffect(() => {\n runtimeRef.current?.setSelectedNodeIds(selectedNodeIds);\n }, [runtimeRef, selectedNodeIds]);\n}\n\n/*** Subscribe the optional rich-node overlay to rendered runtime positions. */\nfunction useRenderedNodeSubscription(\n runtimeRef: { current: GraphRuntime | null },\n renderNode: GraphViewProps['renderNode'],\n setRenderedNodes: (nodes: readonly GraphViewRenderedNode[]) => void,\n) {\n React.useEffect(() => {\n const runtime = runtimeRef.current;\n if (runtime === null || renderNode === undefined) {\n setRenderedNodes([]);\n return;\n }\n return runtime.subscribeRenderedNodes(setRenderedNodes);\n }, [renderNode, runtimeRef, setRenderedNodes]);\n}\n\n/*** Seed known rich-node dimensions without requiring DOM measurement. */\nfunction useKnownNodeSizes(\n runtimeRef: { current: GraphRuntime | null },\n nodes: readonly GraphViewNode[],\n getNodeSize: GraphViewProps['getNodeSize'],\n) {\n React.useEffect(() => {\n const runtime = runtimeRef.current;\n if (runtime === null || getNodeSize === undefined) return;\n for (const node of nodes) {\n const size = getNodeSize(node);\n if (size) runtime.setNodeSize(node.id, size);\n }\n }, [getNodeSize, nodes, runtimeRef]);\n}\n\n/*** Read callback props for the initial runtime callback-ref value. */\nfunction readCallbacks(props: GraphViewProps): GraphViewCallbacks {\n return {\n onEdgeEvent: props.onEdgeEvent,\n onLayoutComplete: props.onLayoutComplete,\n onNodeEvent: props.onNodeEvent,\n onReady: props.onReady,\n onViewportChange: props.onViewportChange,\n onSpacingFactorChange: props.onSpacingFactorChange,\n };\n}\n"]}
|
package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { GraphViewCallbacks } from '../../../../../types/graph-view';
|
|
2
|
+
/***
|
|
3
|
+
* Mirror public GraphView controller callbacks as bubbling browser lifecycle events.
|
|
4
|
+
* Browser hosts can measure actual rendered nodes without reaching into the graph engine.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createGraphViewDomCallbacks(callbacks: GraphViewCallbacks, hostRef: {
|
|
7
|
+
readonly current: unknown;
|
|
8
|
+
}): GraphViewCallbacks;
|
|
9
|
+
//# sourceMappingURL=createGraphViewDomCallbacks.d.ts.map
|
package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createGraphViewDomCallbacks.d.ts","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAGnB,MAAM,iCAAiC,CAAC;AAGzC;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,kBAAkB,EAC7B,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACrC,kBAAkB,CAYpB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { GRAPH_VIEW_EVENTS } from '../../../constants/events';
|
|
2
|
+
/***
|
|
3
|
+
* Mirror public GraphView controller callbacks as bubbling browser lifecycle events.
|
|
4
|
+
* Browser hosts can measure actual rendered nodes without reaching into the graph engine.
|
|
5
|
+
*/
|
|
6
|
+
export function createGraphViewDomCallbacks(callbacks, hostRef) {
|
|
7
|
+
return {
|
|
8
|
+
...callbacks,
|
|
9
|
+
onReady(controller) {
|
|
10
|
+
callbacks.onReady?.(controller);
|
|
11
|
+
dispatchGraphViewControllerEvent(hostRef, GRAPH_VIEW_EVENTS.ready, controller);
|
|
12
|
+
},
|
|
13
|
+
onLayoutComplete(controller) {
|
|
14
|
+
callbacks.onLayoutComplete?.(controller);
|
|
15
|
+
dispatchGraphViewControllerEvent(hostRef, GRAPH_VIEW_EVENTS.layoutComplete, controller);
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/*** Deliver the existing public controller reference on the GraphView root event channel. */
|
|
20
|
+
function dispatchGraphViewControllerEvent(hostRef, name, controller) {
|
|
21
|
+
const host = hostRef.current;
|
|
22
|
+
if (!canDispatchBrowserEvent(host))
|
|
23
|
+
return;
|
|
24
|
+
host.dispatchEvent(new CustomEvent(name, {
|
|
25
|
+
bubbles: true,
|
|
26
|
+
detail: { controller },
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
/*** Narrow an untrusted browser host to the standard event-dispatch method. */
|
|
30
|
+
function canDispatchBrowserEvent(value) {
|
|
31
|
+
return (typeof value === 'object' &&
|
|
32
|
+
value !== null &&
|
|
33
|
+
'dispatchEvent' in value &&
|
|
34
|
+
typeof value.dispatchEvent === 'function');
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=createGraphViewDomCallbacks.js.map
|
package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createGraphViewDomCallbacks.js","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAwC,MAAM,2BAA2B,CAAC;AAEpG;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CACzC,SAA6B,EAC7B,OAAsC;IAEtC,OAAO;QACL,GAAG,SAAS;QACZ,OAAO,CAAC,UAAU;YAChB,SAAS,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC;YAChC,gCAAgC,CAAC,OAAO,EAAE,iBAAiB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QACjF,CAAC;QACD,gBAAgB,CAAC,UAAU;YACzB,SAAS,CAAC,gBAAgB,EAAE,CAAC,UAAU,CAAC,CAAC;YACzC,gCAAgC,CAAC,OAAO,EAAE,iBAAiB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QAC1F,CAAC;KACF,CAAC;AACJ,CAAC;AAED,6FAA6F;AAC7F,SAAS,gCAAgC,CACvC,OAAsC,EACtC,IAAqC,EACrC,UAA+B;IAE/B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;IAC7B,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC;QAAE,OAAO;IAC3C,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAoC,IAAI,EAAE;QACvD,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,EAAE,UAAU,EAAE;KACvB,CAAC,CACH,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,SAAS,uBAAuB,CAC9B,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,eAAe,IAAI,KAAK;QACxB,OAAO,KAAK,CAAC,aAAa,KAAK,UAAU,CAC1C,CAAC;AACJ,CAAC","sourcesContent":["import type {\n GraphViewCallbacks,\n GraphViewController,\n GraphViewDomControllerEventDetail,\n} from '../../../../../types/graph-view';\nimport { GRAPH_VIEW_EVENTS, type GraphViewDomControllerEventName } from '../../../constants/events';\n\n/***\n * Mirror public GraphView controller callbacks as bubbling browser lifecycle events.\n * Browser hosts can measure actual rendered nodes without reaching into the graph engine.\n */\nexport function createGraphViewDomCallbacks(\n callbacks: GraphViewCallbacks,\n hostRef: { readonly current: unknown },\n): GraphViewCallbacks {\n return {\n ...callbacks,\n onReady(controller) {\n callbacks.onReady?.(controller);\n dispatchGraphViewControllerEvent(hostRef, GRAPH_VIEW_EVENTS.ready, controller);\n },\n onLayoutComplete(controller) {\n callbacks.onLayoutComplete?.(controller);\n dispatchGraphViewControllerEvent(hostRef, GRAPH_VIEW_EVENTS.layoutComplete, controller);\n },\n };\n}\n\n/*** Deliver the existing public controller reference on the GraphView root event channel. */\nfunction dispatchGraphViewControllerEvent(\n hostRef: { readonly current: unknown },\n name: GraphViewDomControllerEventName,\n controller: GraphViewController,\n): void {\n const host = hostRef.current;\n if (!canDispatchBrowserEvent(host)) return;\n host.dispatchEvent(\n new CustomEvent<GraphViewDomControllerEventDetail>(name, {\n bubbles: true,\n detail: { controller },\n }),\n );\n}\n\n/*** Narrow an untrusted browser host to the standard event-dispatch method. */\nfunction canDispatchBrowserEvent(\n value: unknown,\n): value is { dispatchEvent(event: Event): boolean } {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'dispatchEvent' in value &&\n typeof value.dispatchEvent === 'function'\n );\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/***
|
|
2
|
+
* Canonical public GraphView browser lifecycle event names.
|
|
3
|
+
* Candidate for a shared Ankhorage event strategy: define common naming, typed
|
|
4
|
+
* payloads and dispatch conventions before extracting a cross-component contract.
|
|
5
|
+
*/
|
|
6
|
+
export declare const GRAPH_VIEW_EVENTS: {
|
|
7
|
+
readonly ready: "zora-graph-view-ready";
|
|
8
|
+
readonly layoutComplete: "zora-graph-view-layout-complete";
|
|
9
|
+
};
|
|
10
|
+
export type GraphViewDomControllerEventName = (typeof GRAPH_VIEW_EVENTS)[keyof typeof GRAPH_VIEW_EVENTS];
|
|
11
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../../src/features/graph-view/constants/events.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;CAGpB,CAAC;AAEX,MAAM,MAAM,+BAA+B,GACzC,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/***
|
|
2
|
+
* Canonical public GraphView browser lifecycle event names.
|
|
3
|
+
* Candidate for a shared Ankhorage event strategy: define common naming, typed
|
|
4
|
+
* payloads and dispatch conventions before extracting a cross-component contract.
|
|
5
|
+
*/
|
|
6
|
+
export const GRAPH_VIEW_EVENTS = {
|
|
7
|
+
ready: 'zora-graph-view-ready',
|
|
8
|
+
layoutComplete: 'zora-graph-view-layout-complete',
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../src/features/graph-view/constants/events.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,KAAK,EAAE,uBAAuB;IAC9B,cAAc,EAAE,iCAAiC;CACzC,CAAC","sourcesContent":["/***\n * Canonical public GraphView browser lifecycle event names.\n * Candidate for a shared Ankhorage event strategy: define common naming, typed\n * payloads and dispatch conventions before extracting a cross-component contract.\n */\nexport const GRAPH_VIEW_EVENTS = {\n ready: 'zora-graph-view-ready',\n layoutComplete: 'zora-graph-view-layout-complete',\n} as const;\n\nexport type GraphViewDomControllerEventName =\n (typeof GRAPH_VIEW_EVENTS)[keyof typeof GRAPH_VIEW_EVENTS];\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export type { GraphViewCallbacks, GraphViewController, GraphViewEdge, GraphViewElementEvent, GraphViewElementEventType, GraphViewFitOptions, GraphViewLayoutName, GraphViewMeasurement, GraphViewNode, GraphViewNodeMeasurement, GraphViewNodeRenderContext, GraphViewPoint, GraphViewProps, GraphViewRenderedNode, GraphViewSize, GraphViewStyleRule, GraphViewViewport, } from '../../types/graph-view';
|
|
1
|
+
export type { GraphViewCallbacks, GraphViewController, GraphViewDomControllerEventDetail, GraphViewEdge, GraphViewElementEvent, GraphViewElementEventType, GraphViewFitOptions, GraphViewLayoutName, GraphViewMeasurement, GraphViewNode, GraphViewNodeMeasurement, GraphViewNodeRenderContext, GraphViewPoint, GraphViewProps, GraphViewRenderedNode, GraphViewSize, GraphViewStyleRule, GraphViewViewport, } from '../../types/graph-view';
|
|
2
2
|
export { GraphView } from './adapters/inbound/web-artifact/GraphView';
|
|
3
|
+
export { GRAPH_VIEW_EVENTS } from './constants/events';
|
|
3
4
|
//# sourceMappingURL=public.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/graph-view/public.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACb,qBAAqB,EACrB,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,wBAAwB,EACxB,0BAA0B,EAC1B,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC"}
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/graph-view/public.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,kBAAkB,EAClB,mBAAmB,EACnB,iCAAiC,EACjC,aAAa,EACb,qBAAqB,EACrB,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,wBAAwB,EACxB,0BAA0B,EAC1B,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/graph-view/public.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/graph-view/public.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export type {\n GraphViewCallbacks,\n GraphViewController,\n GraphViewDomControllerEventDetail,\n GraphViewEdge,\n GraphViewElementEvent,\n GraphViewElementEventType,\n GraphViewFitOptions,\n GraphViewLayoutName,\n GraphViewMeasurement,\n GraphViewNode,\n GraphViewNodeMeasurement,\n GraphViewNodeRenderContext,\n GraphViewPoint,\n GraphViewProps,\n GraphViewRenderedNode,\n GraphViewSize,\n GraphViewStyleRule,\n GraphViewViewport,\n} from '../../types/graph-view';\nexport { GraphView } from './adapters/inbound/web-artifact/GraphView';\nexport { GRAPH_VIEW_EVENTS } from './constants/events';\n"]}
|
|
@@ -81,6 +81,10 @@ export interface GraphViewController {
|
|
|
81
81
|
setZoom(zoom: number): void;
|
|
82
82
|
zoomBy(factor: number): void;
|
|
83
83
|
}
|
|
84
|
+
/*** The browser lifecycle events carry only the existing public graph controller. */
|
|
85
|
+
export interface GraphViewDomControllerEventDetail {
|
|
86
|
+
readonly controller: GraphViewController;
|
|
87
|
+
}
|
|
84
88
|
export interface GraphViewProps {
|
|
85
89
|
readonly nodes: readonly GraphViewNode[];
|
|
86
90
|
readonly edges: readonly GraphViewEdge[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-view.d.ts","sourceRoot":"","sources":["../../src/types/graph-view.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"graph-view.d.ts","sourceRoot":"","sources":["../../src/types/graph-view.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-view.js","sourceRoot":"","sources":["../../src/types/graph-view.ts"],"names":[],"mappings":"","sourcesContent":["import type { SelectionIntent } from '@ankhorage/utility/selection';\nimport type React from 'react';\n\nexport type GraphViewLayoutName = 'breadthfirst' | 'circle' | 'concentric' | 'elk' | 'grid';\nexport type GraphViewElementEventType =\n 'press' | 'double-press' | 'select' | 'unselect' | 'pointer-enter' | 'pointer-leave';\n\nexport interface GraphViewNode {\n readonly id: string;\n readonly label?: string;\n readonly parentId?: string;\n readonly classes?: string;\n readonly data?: Readonly<Record<string, unknown>>;\n}\n\nexport interface GraphViewEdge {\n readonly id?: string;\n readonly source: string;\n readonly target: string;\n readonly classes?: string;\n readonly data?: Readonly<Record<string, unknown>>;\n}\n\nexport interface GraphViewStyleRule {\n readonly selector: string;\n readonly style: Readonly<Record<string, unknown>>;\n}\n\nexport interface GraphViewPoint {\n readonly x: number;\n readonly y: number;\n}\n\nexport interface GraphViewSize {\n readonly width: number;\n readonly height: number;\n}\n\nexport interface GraphViewNodeRenderContext {\n readonly hovered: boolean;\n readonly node: GraphViewNode;\n readonly selected: boolean;\n readonly zoom: number;\n}\n\nexport interface GraphViewRenderedNode {\n readonly hovered: boolean;\n readonly id: string;\n readonly position: GraphViewPoint;\n readonly selected: boolean;\n readonly zoom: number;\n}\n\nexport interface GraphViewNodeMeasurement {\n readonly id: string;\n readonly position: GraphViewPoint;\n readonly size: GraphViewSize;\n}\n\nexport interface GraphViewMeasurement {\n readonly nodes: readonly GraphViewNodeMeasurement[];\n readonly viewport: GraphViewSize;\n}\n\nexport interface GraphViewViewport {\n readonly zoom: number;\n readonly pan: GraphViewPoint;\n}\n\nexport interface GraphViewFitOptions {\n /**\n * Optimize effective rendered fit without rerunning the layout algorithm; whole-graph fits only.\n * Stops at the configured fit-size target and keeps semantic labels collision-safe.\n */\n readonly optimizeSpacing?: boolean;\n readonly nodeIds?: readonly string[];\n readonly padding?: number;\n}\n\nexport interface GraphViewElementEvent {\n readonly id: string;\n readonly type: GraphViewElementEventType;\n readonly selectionIntent?: SelectionIntent;\n}\n\nexport interface GraphViewController {\n fit(options?: GraphViewFitOptions): void;\n /** Measure rendered node geometry without exposing the backing graph engine. */\n measureNodes?(nodeIds: readonly string[]): GraphViewMeasurement | null;\n getViewport(): GraphViewViewport;\n getZoomRange(): { readonly min: number; readonly max: number };\n setPan(pan: GraphViewPoint): void;\n setZoom(zoom: number): void;\n zoomBy(factor: number): void;\n}\n\nexport interface GraphViewProps {\n readonly nodes: readonly GraphViewNode[];\n readonly edges: readonly GraphViewEdge[];\n readonly layout?: GraphViewLayoutName;\n readonly layoutOptions?: Readonly<Record<string, unknown>>;\n readonly spacingFactor?: number;\n readonly styleRules?: readonly GraphViewStyleRule[];\n readonly selectedNodeIds?: readonly string[];\n readonly renderNode?: (context: GraphViewNodeRenderContext) => React.ReactNode;\n readonly getNodeSize?: (node: GraphViewNode) => GraphViewSize | undefined;\n readonly fitPadding?: number;\n readonly minZoom?: number;\n readonly maxZoom?: number;\n readonly minReadableLabelSize?: number;\n readonly maxFitLabelSize?: number;\n /** Zoom values and bounds use the full-node fit as 1 when fit-relative is selected. */\n readonly zoomMode?: 'absolute' | 'fit-relative';\n /** Measure plain labels before layout instead of estimating width from character count. */\n readonly sizeNodesToLabels?: boolean;\n readonly className?: string;\n readonly style?: React.CSSProperties;\n readonly ariaLabel?: string;\n readonly onReady?: (controller: GraphViewController) => void;\n readonly onLayoutComplete?: (controller: GraphViewController) => void;\n readonly onNodeEvent?: (event: GraphViewElementEvent) => void;\n readonly onEdgeEvent?: (event: GraphViewElementEvent) => void;\n readonly onViewportChange?: (viewport: GraphViewViewport) => void;\n readonly onSpacingFactorChange?: (spacingFactor: number) => void;\n}\n\nexport type GraphViewCallbacks = Pick<\n GraphViewProps,\n | 'onEdgeEvent'\n | 'onLayoutComplete'\n | 'onNodeEvent'\n | 'onReady'\n | 'onViewportChange'\n | 'onSpacingFactorChange'\n>;\n"]}
|
|
1
|
+
{"version":3,"file":"graph-view.js","sourceRoot":"","sources":["../../src/types/graph-view.ts"],"names":[],"mappings":"","sourcesContent":["import type { SelectionIntent } from '@ankhorage/utility/selection';\nimport type React from 'react';\n\nexport type GraphViewLayoutName = 'breadthfirst' | 'circle' | 'concentric' | 'elk' | 'grid';\nexport type GraphViewElementEventType =\n 'press' | 'double-press' | 'select' | 'unselect' | 'pointer-enter' | 'pointer-leave';\n\nexport interface GraphViewNode {\n readonly id: string;\n readonly label?: string;\n readonly parentId?: string;\n readonly classes?: string;\n readonly data?: Readonly<Record<string, unknown>>;\n}\n\nexport interface GraphViewEdge {\n readonly id?: string;\n readonly source: string;\n readonly target: string;\n readonly classes?: string;\n readonly data?: Readonly<Record<string, unknown>>;\n}\n\nexport interface GraphViewStyleRule {\n readonly selector: string;\n readonly style: Readonly<Record<string, unknown>>;\n}\n\nexport interface GraphViewPoint {\n readonly x: number;\n readonly y: number;\n}\n\nexport interface GraphViewSize {\n readonly width: number;\n readonly height: number;\n}\n\nexport interface GraphViewNodeRenderContext {\n readonly hovered: boolean;\n readonly node: GraphViewNode;\n readonly selected: boolean;\n readonly zoom: number;\n}\n\nexport interface GraphViewRenderedNode {\n readonly hovered: boolean;\n readonly id: string;\n readonly position: GraphViewPoint;\n readonly selected: boolean;\n readonly zoom: number;\n}\n\nexport interface GraphViewNodeMeasurement {\n readonly id: string;\n readonly position: GraphViewPoint;\n readonly size: GraphViewSize;\n}\n\nexport interface GraphViewMeasurement {\n readonly nodes: readonly GraphViewNodeMeasurement[];\n readonly viewport: GraphViewSize;\n}\n\nexport interface GraphViewViewport {\n readonly zoom: number;\n readonly pan: GraphViewPoint;\n}\n\nexport interface GraphViewFitOptions {\n /**\n * Optimize effective rendered fit without rerunning the layout algorithm; whole-graph fits only.\n * Stops at the configured fit-size target and keeps semantic labels collision-safe.\n */\n readonly optimizeSpacing?: boolean;\n readonly nodeIds?: readonly string[];\n readonly padding?: number;\n}\n\nexport interface GraphViewElementEvent {\n readonly id: string;\n readonly type: GraphViewElementEventType;\n readonly selectionIntent?: SelectionIntent;\n}\n\nexport interface GraphViewController {\n fit(options?: GraphViewFitOptions): void;\n /** Measure rendered node geometry without exposing the backing graph engine. */\n measureNodes?(nodeIds: readonly string[]): GraphViewMeasurement | null;\n getViewport(): GraphViewViewport;\n getZoomRange(): { readonly min: number; readonly max: number };\n setPan(pan: GraphViewPoint): void;\n setZoom(zoom: number): void;\n zoomBy(factor: number): void;\n}\n\n/*** The browser lifecycle events carry only the existing public graph controller. */\nexport interface GraphViewDomControllerEventDetail {\n readonly controller: GraphViewController;\n}\n\nexport interface GraphViewProps {\n readonly nodes: readonly GraphViewNode[];\n readonly edges: readonly GraphViewEdge[];\n readonly layout?: GraphViewLayoutName;\n readonly layoutOptions?: Readonly<Record<string, unknown>>;\n readonly spacingFactor?: number;\n readonly styleRules?: readonly GraphViewStyleRule[];\n readonly selectedNodeIds?: readonly string[];\n readonly renderNode?: (context: GraphViewNodeRenderContext) => React.ReactNode;\n readonly getNodeSize?: (node: GraphViewNode) => GraphViewSize | undefined;\n readonly fitPadding?: number;\n readonly minZoom?: number;\n readonly maxZoom?: number;\n readonly minReadableLabelSize?: number;\n readonly maxFitLabelSize?: number;\n /** Zoom values and bounds use the full-node fit as 1 when fit-relative is selected. */\n readonly zoomMode?: 'absolute' | 'fit-relative';\n /** Measure plain labels before layout instead of estimating width from character count. */\n readonly sizeNodesToLabels?: boolean;\n readonly className?: string;\n readonly style?: React.CSSProperties;\n readonly ariaLabel?: string;\n readonly onReady?: (controller: GraphViewController) => void;\n readonly onLayoutComplete?: (controller: GraphViewController) => void;\n readonly onNodeEvent?: (event: GraphViewElementEvent) => void;\n readonly onEdgeEvent?: (event: GraphViewElementEvent) => void;\n readonly onViewportChange?: (viewport: GraphViewViewport) => void;\n readonly onSpacingFactorChange?: (spacingFactor: number) => void;\n}\n\nexport type GraphViewCallbacks = Pick<\n GraphViewProps,\n | 'onEdgeEvent'\n | 'onLayoutComplete'\n | 'onNodeEvent'\n | 'onReady'\n | 'onViewportChange'\n | 'onSpacingFactorChange'\n>;\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "25.
|
|
4
|
+
"version": "25.11.0",
|
|
5
5
|
"description": "Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/zora#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -7,7 +7,9 @@ import type {
|
|
|
7
7
|
GraphViewProps,
|
|
8
8
|
GraphViewRenderedNode,
|
|
9
9
|
} from '../../../../../types/graph-view';
|
|
10
|
+
import { GRAPH_VIEW_EVENTS } from '../../../constants/events';
|
|
10
11
|
import { createGraphRuntime, type GraphRuntime } from './createGraphRuntime';
|
|
12
|
+
import { createGraphViewDomCallbacks } from './createGraphViewDomCallbacks';
|
|
11
13
|
import { GraphNodeOverlay } from './GraphNodeOverlay';
|
|
12
14
|
|
|
13
15
|
type GraphContainer = NonNullable<CytoscapeOptions['container']>;
|
|
@@ -20,16 +22,22 @@ type GraphContainer = NonNullable<CytoscapeOptions['container']>;
|
|
|
20
22
|
* text. Keep padding in styleRules. Compound and rich-node dimensions retain their existing owners.
|
|
21
23
|
* minReadableLabelSize Expand the manual zoom ceiling until plain labels reach this CSS-pixel size.
|
|
22
24
|
* maxFitLabelSize Cap automatic fitting at this plain-label CSS-pixel size, leaving whitespace for tiny graphs.
|
|
25
|
+
* Browser lifecycle events named by public GRAPH_VIEW_EVENTS bubble from the root
|
|
26
|
+
* with `detail.controller`: the same public GraphViewController delivered to React.
|
|
27
|
+
* Browser integrations can call `measureNodes` without accessing the Cytoscape runtime.
|
|
28
|
+
* The standalone browser artifact exposes the same names as `GraphView.events`.
|
|
23
29
|
* onSpacingFactorChange Receive the spacing accepted by explicit fit({ optimizeSpacing: true }).
|
|
24
30
|
* Ordinary zoom never adjusts spacing or relayouts. Explicit optimization preserves layout ordering,
|
|
25
31
|
* stops once effective fit reaches maxFitLabelSize, keeps labels and unrelated compound boundaries
|
|
26
32
|
* collision-safe, and permits only a small rendered background-overlap fallback for dense graphs.
|
|
27
33
|
*/
|
|
28
34
|
export function GraphView(props: GraphViewProps) {
|
|
29
|
-
const
|
|
35
|
+
const hostRef = React.useRef<HTMLDivElement | null>(null);
|
|
36
|
+
const { containerRef, renderedNodes, runtimeRef } = useGraphViewRuntime(props, hostRef);
|
|
30
37
|
|
|
31
38
|
return (
|
|
32
39
|
<div
|
|
40
|
+
ref={hostRef}
|
|
33
41
|
aria-label={props.ariaLabel ?? 'Graph'}
|
|
34
42
|
className={props.className}
|
|
35
43
|
role="application"
|
|
@@ -58,11 +66,17 @@ export function GraphView(props: GraphViewProps) {
|
|
|
58
66
|
);
|
|
59
67
|
}
|
|
60
68
|
|
|
69
|
+
/*** Publish the same canonical event registry on the standalone GraphView artifact. */
|
|
70
|
+
GraphView.events = GRAPH_VIEW_EVENTS;
|
|
71
|
+
|
|
61
72
|
/*** Compose React synchronization around the single imperative graph runtime. */
|
|
62
|
-
function useGraphViewRuntime(
|
|
73
|
+
function useGraphViewRuntime(
|
|
74
|
+
props: GraphViewProps,
|
|
75
|
+
hostRef: React.RefObject<HTMLDivElement | null>,
|
|
76
|
+
) {
|
|
63
77
|
const containerRef = React.useRef<GraphContainer | null>(null);
|
|
64
78
|
const runtimeRef = React.useRef<GraphRuntime | null>(null);
|
|
65
|
-
const callbacksRef = useGraphCallbacksRef(props);
|
|
79
|
+
const callbacksRef = useGraphCallbacksRef(props, hostRef);
|
|
66
80
|
const [renderedNodes, setRenderedNodes] = React.useState<readonly GraphViewRenderedNode[]>([]);
|
|
67
81
|
|
|
68
82
|
useRuntimeLifecycle(containerRef, runtimeRef, callbacksRef);
|
|
@@ -75,8 +89,13 @@ function useGraphViewRuntime(props: GraphViewProps) {
|
|
|
75
89
|
}
|
|
76
90
|
|
|
77
91
|
/*** Keep the callback ref current without mutating refs during render. */
|
|
78
|
-
function useGraphCallbacksRef(
|
|
79
|
-
|
|
92
|
+
function useGraphCallbacksRef(
|
|
93
|
+
props: GraphViewProps,
|
|
94
|
+
hostRef: React.RefObject<HTMLDivElement | null>,
|
|
95
|
+
) {
|
|
96
|
+
const callbacksRef = React.useRef<GraphViewCallbacks>(
|
|
97
|
+
createGraphViewDomCallbacks(readCallbacks(props), hostRef),
|
|
98
|
+
);
|
|
80
99
|
const {
|
|
81
100
|
onEdgeEvent,
|
|
82
101
|
onLayoutComplete,
|
|
@@ -87,14 +106,17 @@ function useGraphCallbacksRef(props: GraphViewProps) {
|
|
|
87
106
|
} = props;
|
|
88
107
|
|
|
89
108
|
React.useEffect(() => {
|
|
90
|
-
callbacksRef.current =
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
109
|
+
callbacksRef.current = createGraphViewDomCallbacks(
|
|
110
|
+
{
|
|
111
|
+
onEdgeEvent,
|
|
112
|
+
onLayoutComplete,
|
|
113
|
+
onNodeEvent,
|
|
114
|
+
onReady,
|
|
115
|
+
onViewportChange,
|
|
116
|
+
onSpacingFactorChange,
|
|
117
|
+
},
|
|
118
|
+
hostRef,
|
|
119
|
+
);
|
|
98
120
|
}, [
|
|
99
121
|
onEdgeEvent,
|
|
100
122
|
onLayoutComplete,
|
|
@@ -102,6 +124,7 @@ function useGraphCallbacksRef(props: GraphViewProps) {
|
|
|
102
124
|
onReady,
|
|
103
125
|
onViewportChange,
|
|
104
126
|
onSpacingFactorChange,
|
|
127
|
+
hostRef,
|
|
105
128
|
]);
|
|
106
129
|
|
|
107
130
|
return callbacksRef;
|
package/src/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.test.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { expect, test } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import { GRAPH_VIEW_EVENTS } from '../../../constants/events';
|
|
4
|
+
import { createGraphViewDomCallbacks } from './createGraphViewDomCallbacks';
|
|
5
|
+
|
|
6
|
+
test('exposes public controller on bubbling ready and layout events without changing React callbacks', () => {
|
|
7
|
+
const host = new EventTarget();
|
|
8
|
+
const controller = createController();
|
|
9
|
+
const observed: string[] = [];
|
|
10
|
+
const browserEvents: string[] = [];
|
|
11
|
+
for (const name of [GRAPH_VIEW_EVENTS.ready, GRAPH_VIEW_EVENTS.layoutComplete]) {
|
|
12
|
+
host.addEventListener(name, (event) => {
|
|
13
|
+
if (!(event instanceof CustomEvent)) throw new Error('Expected a CustomEvent.');
|
|
14
|
+
const detail: unknown = event.detail;
|
|
15
|
+
if (typeof detail !== 'object' || detail === null || !('controller' in detail))
|
|
16
|
+
throw new Error('Expected a public controller in the browser event.');
|
|
17
|
+
expect(detail.controller).toBe(controller);
|
|
18
|
+
expect(event.bubbles).toBe(true);
|
|
19
|
+
browserEvents.push(name);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const callbacks = createGraphViewDomCallbacks(
|
|
24
|
+
{
|
|
25
|
+
onReady: (received) => {
|
|
26
|
+
expect(received).toBe(controller);
|
|
27
|
+
observed.push('ready');
|
|
28
|
+
},
|
|
29
|
+
onLayoutComplete: (received) => {
|
|
30
|
+
expect(received).toBe(controller);
|
|
31
|
+
observed.push('layout');
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{ current: host },
|
|
35
|
+
);
|
|
36
|
+
callbacks.onReady?.(controller);
|
|
37
|
+
callbacks.onLayoutComplete?.(controller);
|
|
38
|
+
|
|
39
|
+
expect(observed).toEqual(['ready', 'layout']);
|
|
40
|
+
expect(browserEvents).toEqual([GRAPH_VIEW_EVENTS.ready, GRAPH_VIEW_EVENTS.layoutComplete]);
|
|
41
|
+
expect(controller.measureNodes(['src']).nodes[0]?.id).toBe('src');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('preserves React callbacks when the browser host is unmounted', () => {
|
|
45
|
+
const controller = createController();
|
|
46
|
+
const observed: string[] = [];
|
|
47
|
+
const callbacks = createGraphViewDomCallbacks(
|
|
48
|
+
{
|
|
49
|
+
onReady: () => observed.push('ready'),
|
|
50
|
+
onLayoutComplete: () => observed.push('layout'),
|
|
51
|
+
},
|
|
52
|
+
{ current: null },
|
|
53
|
+
);
|
|
54
|
+
callbacks.onReady?.(controller);
|
|
55
|
+
callbacks.onLayoutComplete?.(controller);
|
|
56
|
+
expect(observed).toEqual(['ready', 'layout']);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
/*** Supplies public viewport and rendered geometry without a Cytoscape instance. */
|
|
60
|
+
function createController() {
|
|
61
|
+
return {
|
|
62
|
+
fit: () => undefined,
|
|
63
|
+
measureNodes: (ids: readonly string[]) => ({
|
|
64
|
+
nodes: ids.map((id) => ({
|
|
65
|
+
id,
|
|
66
|
+
position: { x: 120, y: 80 },
|
|
67
|
+
size: { width: 100, height: 48 },
|
|
68
|
+
})),
|
|
69
|
+
viewport: { width: 800, height: 600 },
|
|
70
|
+
}),
|
|
71
|
+
getViewport: () => ({ pan: { x: 0, y: 0 }, zoom: 1 }),
|
|
72
|
+
getZoomRange: () => ({ min: 0.5, max: 2 }),
|
|
73
|
+
setPan: () => undefined,
|
|
74
|
+
setZoom: () => undefined,
|
|
75
|
+
zoomBy: () => undefined,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
GraphViewCallbacks,
|
|
3
|
+
GraphViewController,
|
|
4
|
+
GraphViewDomControllerEventDetail,
|
|
5
|
+
} from '../../../../../types/graph-view';
|
|
6
|
+
import { GRAPH_VIEW_EVENTS, type GraphViewDomControllerEventName } from '../../../constants/events';
|
|
7
|
+
|
|
8
|
+
/***
|
|
9
|
+
* Mirror public GraphView controller callbacks as bubbling browser lifecycle events.
|
|
10
|
+
* Browser hosts can measure actual rendered nodes without reaching into the graph engine.
|
|
11
|
+
*/
|
|
12
|
+
export function createGraphViewDomCallbacks(
|
|
13
|
+
callbacks: GraphViewCallbacks,
|
|
14
|
+
hostRef: { readonly current: unknown },
|
|
15
|
+
): GraphViewCallbacks {
|
|
16
|
+
return {
|
|
17
|
+
...callbacks,
|
|
18
|
+
onReady(controller) {
|
|
19
|
+
callbacks.onReady?.(controller);
|
|
20
|
+
dispatchGraphViewControllerEvent(hostRef, GRAPH_VIEW_EVENTS.ready, controller);
|
|
21
|
+
},
|
|
22
|
+
onLayoutComplete(controller) {
|
|
23
|
+
callbacks.onLayoutComplete?.(controller);
|
|
24
|
+
dispatchGraphViewControllerEvent(hostRef, GRAPH_VIEW_EVENTS.layoutComplete, controller);
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/*** Deliver the existing public controller reference on the GraphView root event channel. */
|
|
30
|
+
function dispatchGraphViewControllerEvent(
|
|
31
|
+
hostRef: { readonly current: unknown },
|
|
32
|
+
name: GraphViewDomControllerEventName,
|
|
33
|
+
controller: GraphViewController,
|
|
34
|
+
): void {
|
|
35
|
+
const host = hostRef.current;
|
|
36
|
+
if (!canDispatchBrowserEvent(host)) return;
|
|
37
|
+
host.dispatchEvent(
|
|
38
|
+
new CustomEvent<GraphViewDomControllerEventDetail>(name, {
|
|
39
|
+
bubbles: true,
|
|
40
|
+
detail: { controller },
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/*** Narrow an untrusted browser host to the standard event-dispatch method. */
|
|
46
|
+
function canDispatchBrowserEvent(
|
|
47
|
+
value: unknown,
|
|
48
|
+
): value is { dispatchEvent(event: Event): boolean } {
|
|
49
|
+
return (
|
|
50
|
+
typeof value === 'object' &&
|
|
51
|
+
value !== null &&
|
|
52
|
+
'dispatchEvent' in value &&
|
|
53
|
+
typeof value.dispatchEvent === 'function'
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/***
|
|
2
|
+
* Canonical public GraphView browser lifecycle event names.
|
|
3
|
+
* Candidate for a shared Ankhorage event strategy: define common naming, typed
|
|
4
|
+
* payloads and dispatch conventions before extracting a cross-component contract.
|
|
5
|
+
*/
|
|
6
|
+
export const GRAPH_VIEW_EVENTS = {
|
|
7
|
+
ready: 'zora-graph-view-ready',
|
|
8
|
+
layoutComplete: 'zora-graph-view-layout-complete',
|
|
9
|
+
} as const;
|
|
10
|
+
|
|
11
|
+
export type GraphViewDomControllerEventName =
|
|
12
|
+
(typeof GRAPH_VIEW_EVENTS)[keyof typeof GRAPH_VIEW_EVENTS];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type {
|
|
2
2
|
GraphViewCallbacks,
|
|
3
3
|
GraphViewController,
|
|
4
|
+
GraphViewDomControllerEventDetail,
|
|
4
5
|
GraphViewEdge,
|
|
5
6
|
GraphViewElementEvent,
|
|
6
7
|
GraphViewElementEventType,
|
|
@@ -18,3 +19,4 @@ export type {
|
|
|
18
19
|
GraphViewViewport,
|
|
19
20
|
} from '../../types/graph-view';
|
|
20
21
|
export { GraphView } from './adapters/inbound/web-artifact/GraphView';
|
|
22
|
+
export { GRAPH_VIEW_EVENTS } from './constants/events';
|
package/src/types/graph-view.ts
CHANGED
|
@@ -94,6 +94,11 @@ export interface GraphViewController {
|
|
|
94
94
|
zoomBy(factor: number): void;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
/*** The browser lifecycle events carry only the existing public graph controller. */
|
|
98
|
+
export interface GraphViewDomControllerEventDetail {
|
|
99
|
+
readonly controller: GraphViewController;
|
|
100
|
+
}
|
|
101
|
+
|
|
97
102
|
export interface GraphViewProps {
|
|
98
103
|
readonly nodes: readonly GraphViewNode[];
|
|
99
104
|
readonly edges: readonly GraphViewEdge[];
|
|
@@ -10,10 +10,21 @@ import type { GraphViewProps } from './GraphView.types-0';
|
|
|
10
10
|
* text. Keep padding in styleRules. Compound and rich-node dimensions retain their existing owners.
|
|
11
11
|
* minReadableLabelSize Expand the manual zoom ceiling until plain labels reach this CSS-pixel size.
|
|
12
12
|
* maxFitLabelSize Cap automatic fitting at this plain-label CSS-pixel size, leaving whitespace for tiny graphs.
|
|
13
|
+
* Browser lifecycle events named by public GRAPH_VIEW_EVENTS bubble from the root
|
|
14
|
+
* with `detail.controller`: the same public GraphViewController delivered to React.
|
|
15
|
+
* Browser integrations can call `measureNodes` without accessing the Cytoscape runtime.
|
|
16
|
+
* The standalone browser artifact exposes the same names as `GraphView.events`.
|
|
13
17
|
* onSpacingFactorChange Receive the spacing accepted by explicit fit({ optimizeSpacing: true }).
|
|
14
18
|
* Ordinary zoom never adjusts spacing or relayouts. Explicit optimization preserves layout ordering,
|
|
15
19
|
* stops once effective fit reaches maxFitLabelSize, keeps labels and unrelated compound boundaries
|
|
16
20
|
* collision-safe, and permits only a small rendered background-overlap fallback for dense graphs.
|
|
17
21
|
*/
|
|
18
22
|
export declare function GraphView(props: GraphViewProps): React.JSX.Element;
|
|
19
|
-
|
|
23
|
+
|
|
24
|
+
export declare namespace GraphView {
|
|
25
|
+
var events: {
|
|
26
|
+
readonly ready: "zora-graph-view-ready";
|
|
27
|
+
readonly layoutComplete: "zora-graph-view-layout-complete";
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export type { GraphViewCallbacks, GraphViewController, GraphViewDomControllerEventDetail, GraphViewEdge, GraphViewElementEvent, GraphViewElementEventType, GraphViewFitOptions, GraphViewLayoutName, GraphViewMeasurement, GraphViewNode, GraphViewNodeMeasurement, GraphViewNodeRenderContext, GraphViewPoint, GraphViewProps, GraphViewRenderedNode, GraphViewSize, GraphViewStyleRule, GraphViewViewport } from './GraphView.types-0';
|
|
@@ -91964,6 +91964,12 @@ Consider installing the package or pass your own 'workerFactory' to ELK's constr
|
|
|
91964
91964
|
// src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx
|
|
91965
91965
|
import React2 from "react";
|
|
91966
91966
|
|
|
91967
|
+
// src/features/graph-view/constants/events.ts
|
|
91968
|
+
var GRAPH_VIEW_EVENTS = {
|
|
91969
|
+
ready: "zora-graph-view-ready",
|
|
91970
|
+
layoutComplete: "zora-graph-view-layout-complete"
|
|
91971
|
+
};
|
|
91972
|
+
|
|
91967
91973
|
// node_modules/cytoscape/dist/cytoscape.esm.mjs
|
|
91968
91974
|
function _arrayLikeToArray(r, a) {
|
|
91969
91975
|
(a == null || a > r.length) && (a = r.length);
|
|
@@ -123615,6 +123621,33 @@ function destroyRuntime(state) {
|
|
|
123615
123621
|
}
|
|
123616
123622
|
registerGraphLayouts();
|
|
123617
123623
|
|
|
123624
|
+
// src/features/graph-view/adapters/inbound/web-artifact/createGraphViewDomCallbacks.ts
|
|
123625
|
+
function createGraphViewDomCallbacks(callbacks, hostRef) {
|
|
123626
|
+
return {
|
|
123627
|
+
...callbacks,
|
|
123628
|
+
onReady(controller) {
|
|
123629
|
+
callbacks.onReady?.(controller);
|
|
123630
|
+
dispatchGraphViewControllerEvent(hostRef, GRAPH_VIEW_EVENTS.ready, controller);
|
|
123631
|
+
},
|
|
123632
|
+
onLayoutComplete(controller) {
|
|
123633
|
+
callbacks.onLayoutComplete?.(controller);
|
|
123634
|
+
dispatchGraphViewControllerEvent(hostRef, GRAPH_VIEW_EVENTS.layoutComplete, controller);
|
|
123635
|
+
}
|
|
123636
|
+
};
|
|
123637
|
+
}
|
|
123638
|
+
function dispatchGraphViewControllerEvent(hostRef, name, controller) {
|
|
123639
|
+
const host = hostRef.current;
|
|
123640
|
+
if (!canDispatchBrowserEvent(host))
|
|
123641
|
+
return;
|
|
123642
|
+
host.dispatchEvent(new CustomEvent(name, {
|
|
123643
|
+
bubbles: true,
|
|
123644
|
+
detail: { controller }
|
|
123645
|
+
}));
|
|
123646
|
+
}
|
|
123647
|
+
function canDispatchBrowserEvent(value) {
|
|
123648
|
+
return typeof value === "object" && value !== null && "dispatchEvent" in value && typeof value.dispatchEvent === "function";
|
|
123649
|
+
}
|
|
123650
|
+
|
|
123618
123651
|
// src/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.tsx
|
|
123619
123652
|
import React from "react";
|
|
123620
123653
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -123700,8 +123733,10 @@ function readResizeObserverConstructor2() {
|
|
|
123700
123733
|
// src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx
|
|
123701
123734
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
123702
123735
|
function GraphView(props) {
|
|
123703
|
-
const
|
|
123736
|
+
const hostRef = React2.useRef(null);
|
|
123737
|
+
const { containerRef, renderedNodes, runtimeRef } = useGraphViewRuntime(props, hostRef);
|
|
123704
123738
|
return /* @__PURE__ */ jsxs("div", {
|
|
123739
|
+
ref: hostRef,
|
|
123705
123740
|
"aria-label": props.ariaLabel ?? "Graph",
|
|
123706
123741
|
className: props.className,
|
|
123707
123742
|
role: "application",
|
|
@@ -123728,10 +123763,11 @@ function GraphView(props) {
|
|
|
123728
123763
|
]
|
|
123729
123764
|
});
|
|
123730
123765
|
}
|
|
123731
|
-
|
|
123766
|
+
GraphView.events = GRAPH_VIEW_EVENTS;
|
|
123767
|
+
function useGraphViewRuntime(props, hostRef) {
|
|
123732
123768
|
const containerRef = React2.useRef(null);
|
|
123733
123769
|
const runtimeRef = React2.useRef(null);
|
|
123734
|
-
const callbacksRef = useGraphCallbacksRef(props);
|
|
123770
|
+
const callbacksRef = useGraphCallbacksRef(props, hostRef);
|
|
123735
123771
|
const [renderedNodes, setRenderedNodes] = React2.useState([]);
|
|
123736
123772
|
useRuntimeLifecycle(containerRef, runtimeRef, callbacksRef);
|
|
123737
123773
|
useRuntimeGraphUpdate(runtimeRef, props);
|
|
@@ -123740,8 +123776,8 @@ function useGraphViewRuntime(props) {
|
|
|
123740
123776
|
useKnownNodeSizes(runtimeRef, props.nodes, props.getNodeSize);
|
|
123741
123777
|
return { containerRef, renderedNodes, runtimeRef };
|
|
123742
123778
|
}
|
|
123743
|
-
function useGraphCallbacksRef(props) {
|
|
123744
|
-
const callbacksRef = React2.useRef(readCallbacks(props));
|
|
123779
|
+
function useGraphCallbacksRef(props, hostRef) {
|
|
123780
|
+
const callbacksRef = React2.useRef(createGraphViewDomCallbacks(readCallbacks(props), hostRef));
|
|
123745
123781
|
const {
|
|
123746
123782
|
onEdgeEvent,
|
|
123747
123783
|
onLayoutComplete,
|
|
@@ -123751,21 +123787,22 @@ function useGraphCallbacksRef(props) {
|
|
|
123751
123787
|
onSpacingFactorChange
|
|
123752
123788
|
} = props;
|
|
123753
123789
|
React2.useEffect(() => {
|
|
123754
|
-
callbacksRef.current = {
|
|
123790
|
+
callbacksRef.current = createGraphViewDomCallbacks({
|
|
123755
123791
|
onEdgeEvent,
|
|
123756
123792
|
onLayoutComplete,
|
|
123757
123793
|
onNodeEvent,
|
|
123758
123794
|
onReady,
|
|
123759
123795
|
onViewportChange,
|
|
123760
123796
|
onSpacingFactorChange
|
|
123761
|
-
};
|
|
123797
|
+
}, hostRef);
|
|
123762
123798
|
}, [
|
|
123763
123799
|
onEdgeEvent,
|
|
123764
123800
|
onLayoutComplete,
|
|
123765
123801
|
onNodeEvent,
|
|
123766
123802
|
onReady,
|
|
123767
123803
|
onViewportChange,
|
|
123768
|
-
onSpacingFactorChange
|
|
123804
|
+
onSpacingFactorChange,
|
|
123805
|
+
hostRef
|
|
123769
123806
|
]);
|
|
123770
123807
|
return callbacksRef;
|
|
123771
123808
|
}
|
|
@@ -81,6 +81,10 @@ export interface GraphViewController {
|
|
|
81
81
|
setZoom(zoom: number): void;
|
|
82
82
|
zoomBy(factor: number): void;
|
|
83
83
|
}
|
|
84
|
+
/*** The browser lifecycle events carry only the existing public graph controller. */
|
|
85
|
+
export interface GraphViewDomControllerEventDetail {
|
|
86
|
+
readonly controller: GraphViewController;
|
|
87
|
+
}
|
|
84
88
|
export interface GraphViewProps {
|
|
85
89
|
readonly nodes: readonly GraphViewNode[];
|
|
86
90
|
readonly edges: readonly GraphViewEdge[];
|