@principal-ai/principal-view-react 0.16.22 → 0.16.24
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/dist/components/GraphRenderer.js.map +1 -1
- package/dist/graphify/consolidated.d.ts +170 -0
- package/dist/graphify/consolidated.d.ts.map +1 -0
- package/dist/graphify/consolidated.js +11 -0
- package/dist/graphify/consolidated.js.map +1 -0
- package/dist/graphify/index.d.ts +9 -0
- package/dist/graphify/index.d.ts.map +1 -0
- package/dist/graphify/index.js +8 -0
- package/dist/graphify/index.js.map +1 -0
- package/dist/graphify/types.d.ts +141 -0
- package/dist/graphify/types.d.ts.map +1 -0
- package/dist/graphify/types.js +8 -0
- package/dist/graphify/types.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.d.ts +28 -0
- package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -0
- package/dist/subsystem/SubsystemComponentGraph.js +365 -0
- package/dist/subsystem/SubsystemComponentGraph.js.map +1 -0
- package/dist/subsystem/model.d.ts +131 -0
- package/dist/subsystem/model.d.ts.map +1 -0
- package/dist/subsystem/model.js +296 -0
- package/dist/subsystem/model.js.map +1 -0
- package/dist/subsystem/nodes.d.ts +28 -0
- package/dist/subsystem/nodes.d.ts.map +1 -0
- package/dist/subsystem/nodes.js +230 -0
- package/dist/subsystem/nodes.js.map +1 -0
- package/dist/utils/elkLayout.d.ts +19 -0
- package/dist/utils/elkLayout.d.ts.map +1 -1
- package/dist/utils/elkLayout.js +72 -9
- package/dist/utils/elkLayout.js.map +1 -1
- package/package.json +3 -3
- package/src/components/GraphRenderer.tsx +2 -2
- package/src/graphify/consolidated.ts +202 -0
- package/src/graphify/index.ts +36 -0
- package/src/graphify/types.ts +164 -0
- package/src/index.ts +42 -0
- package/src/stories/SubsystemComponentGraph.stories.tsx +761 -0
- package/src/subsystem/SubsystemComponentGraph.tsx +585 -0
- package/src/subsystem/model.test.ts +81 -0
- package/src/subsystem/model.ts +434 -0
- package/src/subsystem/nodes.tsx +353 -0
- package/src/utils/elkLayout.ts +98 -9
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graphify graph.json schema types.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the graphify data model (graphify/validate.py, graphify/export.py)
|
|
5
|
+
* so graphify output can be consumed by this library in a type-compatible way.
|
|
6
|
+
*/
|
|
7
|
+
/** Any JSON-serializable value carried in node/edge metadata. */
|
|
8
|
+
export type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
9
|
+
[key: string]: JsonValue;
|
|
10
|
+
};
|
|
11
|
+
/** Node classification (graphify/validate.py VALID_FILE_TYPES). */
|
|
12
|
+
export type GraphifyFileType = 'code' | 'document' | 'paper' | 'image' | 'rationale' | 'concept';
|
|
13
|
+
/** Edge provenance tag (graphify/validate.py VALID_CONFIDENCES). */
|
|
14
|
+
export type GraphifyConfidence = 'EXTRACTED' | 'INFERRED' | 'AMBIGUOUS';
|
|
15
|
+
/** Optional semantic kind carried on nodes (e.g. `module`, `namespace`). */
|
|
16
|
+
export type GraphifyNodeType = 'module' | 'namespace' | string;
|
|
17
|
+
/** Canonical relation verbs emitted by graphify extractors and resolvers. */
|
|
18
|
+
export type GraphifyRelation = 'calls' | 'imports' | 'imports_from' | 're_exports' | 'references' | 'inherits' | 'implements' | 'mixes_in' | 'uses' | 'contains' | 'defines' | 'method' | 'decorator' | 'rationale_for' | 'semantically_similar_to' | string;
|
|
19
|
+
/**
|
|
20
|
+
* A graphify node.
|
|
21
|
+
*
|
|
22
|
+
* Required fields are enforced by graphify/validate.py:
|
|
23
|
+
* `id`, `label`, `file_type`, `source_file`. The rest are populated by the
|
|
24
|
+
* extractors (`source_location`, optional `type`/`metadata`) and by the build
|
|
25
|
+
* writer (`community`, `community_name`, `norm_label`).
|
|
26
|
+
*/
|
|
27
|
+
export interface GraphifyNode {
|
|
28
|
+
/** Stable identifier: repo-relative path + symbol names (make_id slug). */
|
|
29
|
+
id: string;
|
|
30
|
+
/** Human-readable name. */
|
|
31
|
+
label: string;
|
|
32
|
+
/** Classification used as the primary node kind. */
|
|
33
|
+
file_type: GraphifyFileType;
|
|
34
|
+
/** Repo-relative path of the source file this node came from. */
|
|
35
|
+
source_file: string;
|
|
36
|
+
/** `L<line>` location, or `''` for sourceless stub nodes. */
|
|
37
|
+
source_location?: string | null;
|
|
38
|
+
/** Optional semantic kind (e.g. `module`, `namespace`). */
|
|
39
|
+
type?: GraphifyNodeType;
|
|
40
|
+
/** Node state / extra node definitions. */
|
|
41
|
+
state?: string;
|
|
42
|
+
/** Arbitrary per-extractor metadata (e.g. `{ kind: "csharp_namespace" }`). */
|
|
43
|
+
metadata?: Record<string, JsonValue>;
|
|
44
|
+
/** Leiden community id, stamped at build time. */
|
|
45
|
+
community?: number | null;
|
|
46
|
+
/** Human-readable community label, stamped at build time. */
|
|
47
|
+
community_name?: string;
|
|
48
|
+
/** Diacritic-stripped lowercased label, stamped at build time. */
|
|
49
|
+
norm_label?: string;
|
|
50
|
+
/** Extra fields tolerated for forward compatibility. */
|
|
51
|
+
[key: string]: unknown;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A graphify edge.
|
|
55
|
+
*
|
|
56
|
+
* Required fields: `source`, `target`, `relation`, `confidence`, `source_file`.
|
|
57
|
+
* `context` is populated for `references` edges (e.g. `type`, `return_type`,
|
|
58
|
+
* `field`, `generic_arg`).
|
|
59
|
+
*/
|
|
60
|
+
export interface GraphifyEdge {
|
|
61
|
+
/** Source node id. */
|
|
62
|
+
source: string;
|
|
63
|
+
/** Target node id. */
|
|
64
|
+
target: string;
|
|
65
|
+
/** Canonical relation verb. */
|
|
66
|
+
relation: GraphifyRelation;
|
|
67
|
+
/** Provenance: read directly from source vs. resolved by graphify. */
|
|
68
|
+
confidence: GraphifyConfidence;
|
|
69
|
+
/** Float 0.0-1.0; 1.0 for EXTRACTED, discrete rubric for INFERRED. */
|
|
70
|
+
confidence_score?: number;
|
|
71
|
+
/** Repo-relative path where the relationship was found. */
|
|
72
|
+
source_file: string;
|
|
73
|
+
/** `L<line>` location of the relationship. */
|
|
74
|
+
source_location?: string | null;
|
|
75
|
+
/** Edge weight. */
|
|
76
|
+
weight?: number;
|
|
77
|
+
/** Reference context for `references` edges. */
|
|
78
|
+
context?: string;
|
|
79
|
+
/** Arbitrary per-extractor metadata. */
|
|
80
|
+
metadata?: Record<string, JsonValue>;
|
|
81
|
+
/** Extra fields tolerated for forward compatibility. */
|
|
82
|
+
[key: string]: unknown;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* A graphify hyperedge — a group relationship connecting 3+ nodes.
|
|
86
|
+
*
|
|
87
|
+
* Member list is canonical on `nodes` (aliases `members`/`node_ids` are folded
|
|
88
|
+
* by graphify/export.py build normalization).
|
|
89
|
+
*/
|
|
90
|
+
export interface GraphifyHyperedge {
|
|
91
|
+
/** Stable identifier. */
|
|
92
|
+
id: string;
|
|
93
|
+
/** Human-readable label. */
|
|
94
|
+
label?: string;
|
|
95
|
+
/** Member node ids (canonical key). */
|
|
96
|
+
nodes: string[];
|
|
97
|
+
/** Group relation verb (e.g. `participate_in`, `implement`, `form`). */
|
|
98
|
+
relation?: GraphifyRelation;
|
|
99
|
+
/** Provenance tag. */
|
|
100
|
+
confidence?: GraphifyConfidence;
|
|
101
|
+
/** Float 0.0-1.0. */
|
|
102
|
+
confidence_score?: number;
|
|
103
|
+
/** Repo-relative path where the relationship was found. */
|
|
104
|
+
source_file?: string;
|
|
105
|
+
/** Extra fields tolerated for forward compatibility. */
|
|
106
|
+
[key: string]: unknown;
|
|
107
|
+
}
|
|
108
|
+
/** Graph-level metadata stored on the graph (`graph` key). */
|
|
109
|
+
export interface GraphifyGraphMetadata {
|
|
110
|
+
directed?: boolean;
|
|
111
|
+
multigraph?: boolean;
|
|
112
|
+
/** Edges may be serialized under `links` (NetworkX node-link) or `edges`. */
|
|
113
|
+
hyperedges?: GraphifyHyperedge[];
|
|
114
|
+
[key: string]: unknown;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The full graph.json document.
|
|
118
|
+
*
|
|
119
|
+
* graphify writes NetworkX node-link format: nodes under `nodes`, edges under
|
|
120
|
+
* `links`. Older/legacy payloads may use `edges` instead of `links`.
|
|
121
|
+
*/
|
|
122
|
+
export interface GraphifyGraph {
|
|
123
|
+
/** Graph nodes. */
|
|
124
|
+
nodes: GraphifyNode[];
|
|
125
|
+
/** Graph edges (NetworkX node-link key). */
|
|
126
|
+
links?: GraphifyEdge[];
|
|
127
|
+
/** Legacy alias for `links`. */
|
|
128
|
+
edges?: GraphifyEdge[];
|
|
129
|
+
/** Group relationships connecting 3+ nodes. */
|
|
130
|
+
hyperedges?: GraphifyHyperedge[];
|
|
131
|
+
/** Graph-level metadata (directed, multigraph, hyperedges). */
|
|
132
|
+
graph?: GraphifyGraphMetadata;
|
|
133
|
+
/** Top-level directed flag (NetworkX). */
|
|
134
|
+
directed?: boolean;
|
|
135
|
+
/** Top-level multigraph flag (NetworkX). */
|
|
136
|
+
multigraph?: boolean;
|
|
137
|
+
/** Git HEAD the graph was built against, when available. */
|
|
138
|
+
built_at_commit?: string;
|
|
139
|
+
[key: string]: unknown;
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/graphify/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/graphify/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
package/dist/index.d.ts
CHANGED
|
@@ -47,4 +47,9 @@ export { PipelineView, useStateView } from './components/state-view';
|
|
|
47
47
|
export type { StateEvent, EventSource, StateReducer, StateDiff, TransitionDefinition, ActiveAnimation, AnimationType, ReplayControls, StateViewDefinition, PipelineState, PipelineStage, PipelineRepoState, PipelineEvent, PipelineEventType, ActivityState, RoomState, ActivityEvent, ActivityEventType, QuotaDistributionState, UserQuotaState, QuotaEvent, QuotaEventType, UseStateViewOptions, UseStateViewResult, PipelineViewProps, } from './components/state-view';
|
|
48
48
|
export { SessionEventFeed, SessionEventFeedGrouped, } from './components/session-events';
|
|
49
49
|
export type { SessionEventFeedProps, SessionEventFeedGroupedProps, SessionEventFeedRow, } from './components/session-events';
|
|
50
|
+
export type { JsonValue, GraphifyFileType, GraphifyConfidence, GraphifyNodeType, GraphifyRelation, GraphifyNode, GraphifyEdge, GraphifyHyperedge, GraphifyGraphMetadata, GraphifyGraph, } from './graphify';
|
|
51
|
+
export type { GraphifyAnchorResolution, SubsystemGraphifyAnchor, GraphifyMethodInfo, GraphifyPropertyInfo, GraphifyParamInfo, GraphifyCallInfo, GraphifyReferenceInfo, GraphifyImportInfo, GraphifyClassDetail, GraphifyFunctionDetail, GraphifyTypeDetail, GraphifyModuleDetail, GraphifyExternalDetail, GraphifyComponentDetail, GraphifyEdgeRef, } from './graphify';
|
|
52
|
+
export { SubsystemComponentGraph } from './subsystem/SubsystemComponentGraph';
|
|
53
|
+
export type { SubsystemComponentGraphProps } from './subsystem/SubsystemComponentGraph';
|
|
54
|
+
export type { SubsystemComponent, SubsystemComponentEdge, SubsystemGraphDocument, SubsystemComponentKind, SubsystemEdgeMechanism, } from './subsystem/model';
|
|
50
55
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -35,4 +35,6 @@ export { DashboardRenderer, MetricPanel, MetricCard, LineChart, BarChart, Source
|
|
|
35
35
|
export { PipelineView, useStateView } from './components/state-view';
|
|
36
36
|
// Session event diagnostic feed (raw → repo-normalized → accumulated)
|
|
37
37
|
export { SessionEventFeed, SessionEventFeedGrouped, } from './components/session-events';
|
|
38
|
+
// Subsystem component graph
|
|
39
|
+
export { SubsystemComponentGraph } from './subsystem/SubsystemComponentGraph';
|
|
38
40
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,oBAAoB;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAQ3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAG/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAG/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAS9D,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAOnG,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAG3E,6BAA6B;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,8BAA8B;AAC9B,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAUtB,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,2BAA2B;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,mBAAmB;AACnB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAGvG,4DAA4D;AAC5D,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG1E,6EAA6E;AAC7E,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,SAAS,EACT,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAsChC,6DAA6D;AAC7D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAmCrE,sEAAsE;AACtE,OAAO,EACL,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,oBAAoB;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAQ3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAG/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAG/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAS9D,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAOnG,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAG3E,6BAA6B;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,8BAA8B;AAC9B,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAUtB,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,2BAA2B;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,mBAAmB;AACnB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAGvG,4DAA4D;AAC5D,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG1E,6EAA6E;AAC7E,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,SAAS,EACT,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAsChC,6DAA6D;AAC7D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAmCrE,sEAAsE;AACtE,OAAO,EACL,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AAsCrC,4BAA4B;AAC5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SubsystemComponentGraph — a clickable, read-only React Flow component graph
|
|
3
|
+
* for a subsystem snapshot.
|
|
4
|
+
*
|
|
5
|
+
* Nodes are positioned with ELK auto-layout (layered, minimized crossings) and
|
|
6
|
+
* colored by package. Only cross-package edges leave a package region. Clicking
|
|
7
|
+
* a component invokes `onSelect`. (Package frames are deferred — nodes are
|
|
8
|
+
* color-coded by package for now.)
|
|
9
|
+
*
|
|
10
|
+
* This is a focused fork of the package's `GraphRenderer` pipeline (same ELK
|
|
11
|
+
* edge routing, delayed fitView, Background/Controls/MiniMap, node/edge type
|
|
12
|
+
* injection, onNodeClick) adapted to the subsystem model — read-only.
|
|
13
|
+
*/
|
|
14
|
+
import { type SubsystemComponentEdge, type SubsystemComponent } from './model';
|
|
15
|
+
export interface SubsystemComponentGraphProps {
|
|
16
|
+
components: SubsystemComponent[];
|
|
17
|
+
edges: SubsystemComponentEdge[];
|
|
18
|
+
onSelect?: (componentId: string) => void;
|
|
19
|
+
/** Called when an edge is clicked (relationship / mechanism + refs seam). */
|
|
20
|
+
onEdgeSelect?: (edge: SubsystemComponentEdge) => void;
|
|
21
|
+
/** Upper bound for node width in px; nodes grow with content up to this,
|
|
22
|
+
* then the name wraps. Defaults to 300 for components (320 for packages). */
|
|
23
|
+
maxNodeWidth?: number;
|
|
24
|
+
/** Show edge labels (mechanism names) on the graph. @default true */
|
|
25
|
+
showEdgeLabels?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare function SubsystemComponentGraph(props: SubsystemComponentGraphProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
//# sourceMappingURL=SubsystemComponentGraph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubsystemComponentGraph.d.ts","sourceRoot":"","sources":["../../src/subsystem/SubsystemComponentGraph.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAsBH,OAAO,EAKL,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EAExB,MAAM,SAAS,CAAC;AAIjB,MAAM,WAAW,4BAA4B;IAC3C,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,6EAA6E;IAC7E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACtD;kFAC8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAyeD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,2CAsC1E"}
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* SubsystemComponentGraph — a clickable, read-only React Flow component graph
|
|
4
|
+
* for a subsystem snapshot.
|
|
5
|
+
*
|
|
6
|
+
* Nodes are positioned with ELK auto-layout (layered, minimized crossings) and
|
|
7
|
+
* colored by package. Only cross-package edges leave a package region. Clicking
|
|
8
|
+
* a component invokes `onSelect`. (Package frames are deferred — nodes are
|
|
9
|
+
* color-coded by package for now.)
|
|
10
|
+
*
|
|
11
|
+
* This is a focused fork of the package's `GraphRenderer` pipeline (same ELK
|
|
12
|
+
* edge routing, delayed fitView, Background/Controls/MiniMap, node/edge type
|
|
13
|
+
* injection, onNodeClick) adapted to the subsystem model — read-only.
|
|
14
|
+
*/
|
|
15
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
16
|
+
import { ReactFlow, ReactFlowProvider, Background, BackgroundVariant, Controls, useReactFlow, useViewport, applyNodeChanges, } from '@xyflow/react';
|
|
17
|
+
import { useTheme } from '@principal-ade/industry-theme';
|
|
18
|
+
import { buildSubsystemGraph, KIND_COLOR, MECHANISM_COLOR, deriveNameFromSymbol, } from './model';
|
|
19
|
+
import { SubsystemComponentNode, SubsystemEdge, SUBSYSTEM_CALLBACKS } from './nodes';
|
|
20
|
+
const nodeTypes = {
|
|
21
|
+
'subsystem-component': SubsystemComponentNode,
|
|
22
|
+
};
|
|
23
|
+
const edgeTypes = {
|
|
24
|
+
'subsystem-edge': SubsystemEdge,
|
|
25
|
+
};
|
|
26
|
+
function Inner({ components, edges, onSelect, onEdgeSelect, measured, maxNodeWidth, showEdgeLabels }) {
|
|
27
|
+
const { theme } = useTheme();
|
|
28
|
+
const { fitView } = useReactFlow();
|
|
29
|
+
const viewport = useViewport();
|
|
30
|
+
const [built, setBuilt] = useState({
|
|
31
|
+
nodes: [],
|
|
32
|
+
edges: [],
|
|
33
|
+
});
|
|
34
|
+
const [layoutReady, setLayoutReady] = useState(false);
|
|
35
|
+
const [selected, setSelected] = useState(null);
|
|
36
|
+
// Ref mirror of `selected` so the SUBSYSTEM_CALLBACKS click handler (a
|
|
37
|
+
// closure over the effect deps) can toggle without a stale value.
|
|
38
|
+
const selectedRef = useRef(null);
|
|
39
|
+
selectedRef.current = selected;
|
|
40
|
+
// Pass 1: build with estimated widths so React Flow can measure the DOM.
|
|
41
|
+
// The pane stays hidden until Pass 2 completes.
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
let alive = true;
|
|
44
|
+
pass2DoneRef.current = false;
|
|
45
|
+
measuredDimsRef.current = new Map();
|
|
46
|
+
prevMeasuredSigRef.current = '';
|
|
47
|
+
void buildSubsystemGraph({ components, edges }, { maxNodeWidth, showEdgeLabels }).then(({ nodes, edges: e }) => {
|
|
48
|
+
if (!alive)
|
|
49
|
+
return;
|
|
50
|
+
setBuilt({ nodes, edges: e });
|
|
51
|
+
setLayoutReady(false);
|
|
52
|
+
});
|
|
53
|
+
return () => { alive = false; };
|
|
54
|
+
}, [components, edges]);
|
|
55
|
+
// Track measured dimensions from React Flow's dimension changes.
|
|
56
|
+
// These arrive as { type: 'dimensions', id, dimensions } in onNodesChange.
|
|
57
|
+
const measuredDimsRef = useRef(new Map());
|
|
58
|
+
const pendingMeasuredRef = useRef(false);
|
|
59
|
+
// Pass 2: once every node has a measured dimension, re-run ELK.
|
|
60
|
+
const prevMeasuredSigRef = useRef('');
|
|
61
|
+
const pass2DoneRef = useRef(false);
|
|
62
|
+
const triggerPass2 = useCallback(() => {
|
|
63
|
+
if (pass2DoneRef.current)
|
|
64
|
+
return;
|
|
65
|
+
const dims = measuredDimsRef.current;
|
|
66
|
+
if (dims.size < built.nodes.length)
|
|
67
|
+
return;
|
|
68
|
+
const sig = built.nodes.map((n) => `${n.id}:${dims.get(n.id)?.width ?? '?'}`).join(',');
|
|
69
|
+
if (sig.includes('?:'))
|
|
70
|
+
return;
|
|
71
|
+
if (sig === prevMeasuredSigRef.current)
|
|
72
|
+
return;
|
|
73
|
+
prevMeasuredSigRef.current = sig;
|
|
74
|
+
pendingMeasuredRef.current = false;
|
|
75
|
+
pass2DoneRef.current = true;
|
|
76
|
+
const measuredWidths = new Map(built.nodes.map((n) => [n.id, dims.get(n.id).width]));
|
|
77
|
+
const measuredHeights = new Map(built.nodes.map((n) => [n.id, dims.get(n.id).height]));
|
|
78
|
+
let alive = true;
|
|
79
|
+
void buildSubsystemGraph({ components, edges }, { maxNodeWidth, showEdgeLabels, measuredWidths, measuredHeights }).then(({ nodes, edges: e }) => {
|
|
80
|
+
if (!alive)
|
|
81
|
+
return;
|
|
82
|
+
setBuilt({ nodes, edges: e });
|
|
83
|
+
setLayoutReady(true);
|
|
84
|
+
});
|
|
85
|
+
return () => { alive = false; };
|
|
86
|
+
}, [built.nodes, components, edges, maxNodeWidth, showEdgeLabels]);
|
|
87
|
+
// Node components call SUBSYSTEM_CALLBACKS.onSelect on click (their inner
|
|
88
|
+
// onClick stops React Flow propagation), so wire selection + width through it.
|
|
89
|
+
// Lookup from edge id → the authored SubsystemComponentEdge (for onEdgeSelect).
|
|
90
|
+
const edgeById = useMemo(() => new Map(edges.map((e) => [e.id, e])), [edges]);
|
|
91
|
+
// Shared edge-selection logic used by both React Flow's onEdgeClick and the
|
|
92
|
+
// clickable edge label (SUBSYSTEM_CALLBACKS.onEdgeSelect).
|
|
93
|
+
const selectEdge = useCallback((edgeId) => {
|
|
94
|
+
if (selectedEdgeIdRef.current === edgeId) {
|
|
95
|
+
setSelectedEdgeId(null);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const src = edgeById.get(edgeId);
|
|
99
|
+
setSelectedEdgeId(edgeId);
|
|
100
|
+
if (src)
|
|
101
|
+
onEdgeSelect?.(src);
|
|
102
|
+
}, [edgeById, onEdgeSelect]);
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
SUBSYSTEM_CALLBACKS.onSelect = (id) => {
|
|
105
|
+
const comp = components.find((c) => c.id === id);
|
|
106
|
+
if (comp) {
|
|
107
|
+
// Clicking the already-selected node unselects it (toggle off).
|
|
108
|
+
if (selectedRef.current?.id === comp.id) {
|
|
109
|
+
setSelected(null);
|
|
110
|
+
setSelectedEdgeId(null);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
setSelected(comp);
|
|
114
|
+
setSelectedEdgeId(null);
|
|
115
|
+
onSelect?.(id);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
SUBSYSTEM_CALLBACKS.onEdgeSelect = selectEdge;
|
|
119
|
+
SUBSYSTEM_CALLBACKS.maxNodeWidth = maxNodeWidth;
|
|
120
|
+
return () => {
|
|
121
|
+
SUBSYSTEM_CALLBACKS.onSelect = undefined;
|
|
122
|
+
SUBSYSTEM_CALLBACKS.onEdgeSelect = undefined;
|
|
123
|
+
SUBSYSTEM_CALLBACKS.maxNodeWidth = undefined;
|
|
124
|
+
};
|
|
125
|
+
}, [components, onSelect, maxNodeWidth, selectEdge]);
|
|
126
|
+
const { nodes, edges: convertedEdges } = built;
|
|
127
|
+
const xyflowNodesBase = nodes;
|
|
128
|
+
const baseEdges = convertedEdges;
|
|
129
|
+
const baseNodesKey = useMemo(() => nodes.map((n) => n.id).sort().join(','), [nodes]);
|
|
130
|
+
const baseEdgesKey = useMemo(() => convertedEdges.map((e) => e.id).sort().join(','), [convertedEdges]);
|
|
131
|
+
// When an edge is selected, dim every other edge + its label to focus it.
|
|
132
|
+
const [selectedEdgeId, setSelectedEdgeId] = useState(null);
|
|
133
|
+
// Ref mirror so `selectEdge` (a useCallback over early deps) can toggle
|
|
134
|
+
// without a stale closure value.
|
|
135
|
+
const selectedEdgeIdRef = useRef(null);
|
|
136
|
+
selectedEdgeIdRef.current = selectedEdgeId;
|
|
137
|
+
const dispEdges = useMemo(() => {
|
|
138
|
+
if (!selectedEdgeId)
|
|
139
|
+
return baseEdges;
|
|
140
|
+
return baseEdges.map((e) => ({
|
|
141
|
+
...e,
|
|
142
|
+
data: {
|
|
143
|
+
...e.data,
|
|
144
|
+
dimmed: e.id !== selectedEdgeId,
|
|
145
|
+
},
|
|
146
|
+
}));
|
|
147
|
+
}, [baseEdges, selectedEdgeId]);
|
|
148
|
+
const onNodesChange = useCallback((changes) => {
|
|
149
|
+
// Capture dimension changes (React Flow's measurement callback).
|
|
150
|
+
for (const ch of changes) {
|
|
151
|
+
if (ch.type === 'dimensions' && ch.dimensions) {
|
|
152
|
+
measuredDimsRef.current.set(ch.id, ch.dimensions);
|
|
153
|
+
pendingMeasuredRef.current = true;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const result = applyNodeChanges(changes, xyflowNodesBase);
|
|
157
|
+
// After applying changes, check if we should trigger pass 2.
|
|
158
|
+
if (pendingMeasuredRef.current) {
|
|
159
|
+
// Use microtask so the state update from applyNodeChanges commits first.
|
|
160
|
+
queueMicrotask(() => triggerPass2());
|
|
161
|
+
}
|
|
162
|
+
return result;
|
|
163
|
+
}, [xyflowNodesBase, triggerPass2]);
|
|
164
|
+
const onEdgesChange = useCallback((_changes) => dispEdges, [dispEdges]);
|
|
165
|
+
useEffect(() => {
|
|
166
|
+
const t = setTimeout(() => {
|
|
167
|
+
fitView({ padding: 0.1, includeHiddenNodes: false, minZoom: 0.05, maxZoom: 2, duration: 200 });
|
|
168
|
+
}, 200);
|
|
169
|
+
return () => clearTimeout(t);
|
|
170
|
+
}, [baseNodesKey, baseEdgesKey, fitView]);
|
|
171
|
+
const onNodeClick = useCallback((_e, node) => {
|
|
172
|
+
const comp = node.data?.component;
|
|
173
|
+
setSelectedEdgeId(null);
|
|
174
|
+
if (node.type === 'subsystem-component' && comp) {
|
|
175
|
+
// Clicking the already-selected node unselects it (toggle off).
|
|
176
|
+
if (selected?.id === comp.id) {
|
|
177
|
+
setSelected(null);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
setSelected(comp);
|
|
181
|
+
if (comp.id)
|
|
182
|
+
onSelect?.(comp.id);
|
|
183
|
+
}
|
|
184
|
+
}, [onSelect, selected]);
|
|
185
|
+
// React Flow's edge click → the same shared selection logic as the label.
|
|
186
|
+
const onEdgeClick = useCallback((_e, edge) => {
|
|
187
|
+
selectEdge(edge.id);
|
|
188
|
+
}, [selectEdge]);
|
|
189
|
+
const onPaneClick = useCallback(() => {
|
|
190
|
+
setSelected(null);
|
|
191
|
+
setSelectedEdgeId(null);
|
|
192
|
+
}, []);
|
|
193
|
+
// Edge label data for the overlay (rendered OUTSIDE ReactFlow so the pane
|
|
194
|
+
// doesn't intercept pointer events). Uses ELK-computed label midpoints from
|
|
195
|
+
// the actual edge path (not node-center approximations).
|
|
196
|
+
const edgeLabels = useMemo(() => {
|
|
197
|
+
return dispEdges.map((e) => {
|
|
198
|
+
const d = e.data;
|
|
199
|
+
return {
|
|
200
|
+
id: e.id,
|
|
201
|
+
mechanism: d?.mechanism ?? 'imports',
|
|
202
|
+
dimmed: d?.dimmed === true,
|
|
203
|
+
midX: d?.labelX ?? 0,
|
|
204
|
+
midY: d?.labelY ?? 0,
|
|
205
|
+
};
|
|
206
|
+
});
|
|
207
|
+
}, [dispEdges]);
|
|
208
|
+
return (_jsxs("div", { style: { visibility: layoutReady ? 'visible' : 'hidden', width: '100%', height: '100%' }, children: [showEdgeLabels !== false && (_jsx("div", { style: {
|
|
209
|
+
position: 'absolute',
|
|
210
|
+
inset: 0,
|
|
211
|
+
overflow: 'hidden',
|
|
212
|
+
pointerEvents: 'none',
|
|
213
|
+
zIndex: 5,
|
|
214
|
+
}, children: edgeLabels.map((lbl) => {
|
|
215
|
+
const color = MECHANISM_COLOR[lbl.mechanism] ?? '#888';
|
|
216
|
+
const screenX = lbl.midX * viewport.zoom + viewport.x;
|
|
217
|
+
const screenY = lbl.midY * viewport.zoom + viewport.y;
|
|
218
|
+
return (_jsx("div", { "data-edge-label": lbl.id, onClick: (e) => {
|
|
219
|
+
e.stopPropagation();
|
|
220
|
+
selectEdge(lbl.id);
|
|
221
|
+
}, style: {
|
|
222
|
+
position: 'absolute',
|
|
223
|
+
left: screenX,
|
|
224
|
+
top: screenY,
|
|
225
|
+
fontSize: 10,
|
|
226
|
+
fontFamily: theme.fonts.monospace,
|
|
227
|
+
fontWeight: 500,
|
|
228
|
+
color,
|
|
229
|
+
background: 'rgba(21,21,21,0.9)',
|
|
230
|
+
border: `0.5px solid ${color}`,
|
|
231
|
+
borderRadius: 4,
|
|
232
|
+
padding: '1px 5px',
|
|
233
|
+
cursor: 'pointer',
|
|
234
|
+
pointerEvents: 'auto',
|
|
235
|
+
opacity: lbl.dimmed ? 0.15 : 1,
|
|
236
|
+
whiteSpace: 'nowrap',
|
|
237
|
+
}, children: lbl.mechanism }, lbl.id));
|
|
238
|
+
}) })), _jsxs(ReactFlow, { nodes: xyflowNodesBase, edges: dispEdges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, minZoom: 0.05, maxZoom: 4, onNodeClick: onNodeClick, onEdgeClick: onEdgeClick, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange, proOptions: { hideAttribution: true }, nodesDraggable: false, elementsSelectable: true, selectNodesOnDrag: false, nodesConnectable: false, edgesReconnectable: false, onPaneClick: onPaneClick, panOnDrag: true, panOnScroll: true, zoomOnScroll: false, zoomOnPinch: true, zoomOnDoubleClick: false, style: {
|
|
239
|
+
width: measured ? measured.w : '100%',
|
|
240
|
+
height: measured ? measured.h : '100%',
|
|
241
|
+
flex: 1,
|
|
242
|
+
minHeight: 0,
|
|
243
|
+
background: theme.colors.background,
|
|
244
|
+
}, children: [_jsx(Background, { variant: BackgroundVariant.Dots, gap: 16, size: 1 }), _jsx(Controls, { showZoom: true, showFitView: true, showInteractive: true })] }, `${baseNodesKey}-${baseEdgesKey}`), selected && _jsx(ComponentDetail, { component: selected })] }));
|
|
245
|
+
}
|
|
246
|
+
/** Detail panel for the selected component — the verifiable identity + sources
|
|
247
|
+
* moved off the canvas so nodes stay minimal. */
|
|
248
|
+
function ComponentDetail({ component }) {
|
|
249
|
+
const { theme } = useTheme();
|
|
250
|
+
const muted = theme.colors.textMuted ?? theme.colors.textSecondary;
|
|
251
|
+
const color = KIND_COLOR[component.kind] ?? '#888';
|
|
252
|
+
const displayName = deriveNameFromSymbol(component.symbol, component.kind, component.name, component.file);
|
|
253
|
+
const rows = [];
|
|
254
|
+
if (component.symbol)
|
|
255
|
+
rows.push(['Symbol', component.symbol]);
|
|
256
|
+
if (component.file)
|
|
257
|
+
rows.push(['File', component.file]);
|
|
258
|
+
if (component.purpose)
|
|
259
|
+
rows.push(['Purpose', component.purpose]);
|
|
260
|
+
rows.push(['PURL', component.purl]);
|
|
261
|
+
return (_jsxs("div", { style: {
|
|
262
|
+
borderTop: `1px solid ${theme.colors.border}`,
|
|
263
|
+
background: theme.colors.background,
|
|
264
|
+
padding: '10px 12px',
|
|
265
|
+
fontFamily: theme.fonts.body,
|
|
266
|
+
}, children: [_jsxs("div", { style: {
|
|
267
|
+
display: 'flex',
|
|
268
|
+
alignItems: 'center',
|
|
269
|
+
gap: 8,
|
|
270
|
+
fontSize: theme.fontSizes[1],
|
|
271
|
+
fontWeight: 600,
|
|
272
|
+
marginBottom: 6,
|
|
273
|
+
}, children: [_jsx("span", { style: { color }, children: displayName }), _jsx("span", { style: {
|
|
274
|
+
fontSize: theme.fontSizes[0] * 0.8,
|
|
275
|
+
fontFamily: theme.fonts.monospace,
|
|
276
|
+
textTransform: 'uppercase',
|
|
277
|
+
color,
|
|
278
|
+
}, children: component.kind })] }), rows.map(([k, v]) => (_jsxs("div", { style: { display: 'flex', gap: 8, fontSize: theme.fontSizes[0], lineHeight: 1.5 }, children: [_jsx("span", { style: {
|
|
279
|
+
width: 64,
|
|
280
|
+
flexShrink: 0,
|
|
281
|
+
color: muted,
|
|
282
|
+
fontFamily: theme.fonts.monospace,
|
|
283
|
+
textTransform: 'uppercase',
|
|
284
|
+
fontSize: theme.fontSizes[0] * 0.8,
|
|
285
|
+
}, children: k }), _jsx("span", { style: { color: theme.colors.text, fontFamily: theme.fonts.monospace }, children: v })] }, k))), component.detail && _jsx(GraphifyDetailSections, { detail: component.detail })] }));
|
|
286
|
+
}
|
|
287
|
+
/** Renders the graphify drill-down payload for a component. */
|
|
288
|
+
function GraphifyDetailSections({ detail }) {
|
|
289
|
+
const { theme } = useTheme();
|
|
290
|
+
const muted = theme.colors.textMuted ?? theme.colors.textSecondary;
|
|
291
|
+
const label = (k) => (_jsx("span", { style: {
|
|
292
|
+
width: 64,
|
|
293
|
+
flexShrink: 0,
|
|
294
|
+
color: muted,
|
|
295
|
+
fontFamily: theme.fonts.monospace,
|
|
296
|
+
textTransform: 'uppercase',
|
|
297
|
+
fontSize: theme.fontSizes[0] * 0.8,
|
|
298
|
+
}, children: k }));
|
|
299
|
+
const chip = (name, meta, key) => (_jsxs("span", { style: {
|
|
300
|
+
fontFamily: theme.fonts.monospace,
|
|
301
|
+
fontSize: theme.fontSizes[0],
|
|
302
|
+
color: theme.colors.text,
|
|
303
|
+
border: `1px solid ${theme.colors.border}`,
|
|
304
|
+
borderRadius: 4,
|
|
305
|
+
padding: '1px 6px',
|
|
306
|
+
marginRight: 6,
|
|
307
|
+
marginBottom: 4,
|
|
308
|
+
display: 'inline-block',
|
|
309
|
+
}, children: [name, meta ? _jsxs("span", { style: { color: muted }, children: [" ", meta] }) : ''] }, key));
|
|
310
|
+
const row = (k, children) => (_jsxs("div", { style: { display: 'flex', gap: 8, fontSize: theme.fontSizes[0], lineHeight: 1.5, marginBottom: 4 }, children: [label(k), _jsx("div", { style: { minWidth: 0 }, children: children })] }));
|
|
311
|
+
switch (detail.kind) {
|
|
312
|
+
case 'class':
|
|
313
|
+
return (_jsxs(_Fragment, { children: [detail.methods.length > 0 &&
|
|
314
|
+
row('methods', detail.methods.map((m, i) => chip(m.name, m.returnType, i))), detail.properties.length > 0 &&
|
|
315
|
+
row('props', detail.properties.map((p, i) => chip(p.name, p.type, i))), detail.extends.length > 0 && row('extends', detail.extends.map((e, i) => chip(e, undefined, i))), detail.implements.length > 0 && row('impl', detail.implements.map((e, i) => chip(e, undefined, i))), detail.instantiations.length > 0 &&
|
|
316
|
+
row('insts', detail.instantiations.map((i, idx) => chip(i.name, undefined, idx))), detail.references.length > 0 &&
|
|
317
|
+
row('refs', detail.references.map((r, idx) => chip(r.name, undefined, idx)))] }));
|
|
318
|
+
case 'function':
|
|
319
|
+
return (_jsxs(_Fragment, { children: [detail.parameters.length > 0 &&
|
|
320
|
+
row('params', detail.parameters.map((p, i) => chip(p.type, undefined, i))), detail.returnType && row('return', _jsx("span", { children: detail.returnType })), detail.callers.length > 0 &&
|
|
321
|
+
row('callers', detail.callers.map((c, i) => chip(c.name, undefined, i))), detail.callees.length > 0 &&
|
|
322
|
+
row('callees', detail.callees.map((c, i) => chip(c.name, undefined, i)))] }));
|
|
323
|
+
case 'type':
|
|
324
|
+
return (_jsxs(_Fragment, { children: [detail.properties.length > 0 &&
|
|
325
|
+
row('props', detail.properties.map((p, i) => chip(p.name, p.type, i))), detail.usedBy.length > 0 &&
|
|
326
|
+
row('used by', detail.usedBy.map((u, i) => chip(u.name, undefined, i))), detail.implementors.length > 0 &&
|
|
327
|
+
row('impl', detail.implementors.map((e, i) => chip(e, undefined, i)))] }));
|
|
328
|
+
case 'module':
|
|
329
|
+
return (_jsxs(_Fragment, { children: [detail.exports.length > 0 &&
|
|
330
|
+
row('exports', detail.exports.map((e, i) => chip(e, undefined, i))), detail.imports.length > 0 &&
|
|
331
|
+
row('imports', detail.imports.map((i, idx) => chip(i.name, undefined, idx))), detail.symbols.length > 0 &&
|
|
332
|
+
row('symbols', detail.symbols.map((s, i) => chip(s, undefined, i)))] }));
|
|
333
|
+
case 'external':
|
|
334
|
+
return row('source', _jsx("span", { children: detail.label }));
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
export function SubsystemComponentGraph(props) {
|
|
338
|
+
const wrapRef = useRef(null);
|
|
339
|
+
const [size, setSize] = useState(null);
|
|
340
|
+
// Measure the container so React Flow always has a real, non-zero pixel size
|
|
341
|
+
// (responsive to the parent; avoids the %→0 blank canvas).
|
|
342
|
+
useEffect(() => {
|
|
343
|
+
const el = wrapRef.current;
|
|
344
|
+
if (!el)
|
|
345
|
+
return;
|
|
346
|
+
const update = () => {
|
|
347
|
+
const rect = el.getBoundingClientRect();
|
|
348
|
+
if (rect.width > 0 && rect.height > 0)
|
|
349
|
+
setSize({ w: rect.width, h: rect.height });
|
|
350
|
+
};
|
|
351
|
+
update();
|
|
352
|
+
const ro = new ResizeObserver(update);
|
|
353
|
+
ro.observe(el);
|
|
354
|
+
return () => ro.disconnect();
|
|
355
|
+
}, []);
|
|
356
|
+
return (_jsx("div", { ref: wrapRef, style: {
|
|
357
|
+
position: 'relative',
|
|
358
|
+
width: '100%',
|
|
359
|
+
height: '100%',
|
|
360
|
+
minHeight: 0,
|
|
361
|
+
display: 'flex',
|
|
362
|
+
flexDirection: 'column',
|
|
363
|
+
}, children: _jsx("div", { style: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }, children: _jsx(ReactFlowProvider, { children: _jsx(Inner, { ...props, measured: size }) }) }) }));
|
|
364
|
+
}
|
|
365
|
+
//# sourceMappingURL=SubsystemComponentGraph.js.map
|