@principal-ai/subsystems-react 0.50.0 → 0.51.1
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/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/pierre/PierreTrailCodeView.d.ts +1 -1
- package/dist/pierre/PierreTrailCodeView.d.ts.map +1 -1
- package/dist/pierre/PierreTrailCodeView.js +44 -21
- package/dist/pierre/PierreTrailCodeView.js.map +1 -1
- package/dist/stories/Subsystem/C4Graph/c4ProposedElements.fixture.d.ts +493 -0
- package/dist/stories/Subsystem/C4Graph/c4ProposedElements.fixture.d.ts.map +1 -0
- package/dist/stories/Subsystem/C4Graph/c4ProposedElements.fixture.js +329 -0
- package/dist/stories/Subsystem/C4Graph/c4ProposedElements.fixture.js.map +1 -0
- package/dist/subsystem/C4Graph.d.ts +2 -2
- package/dist/subsystem/C4Graph.d.ts.map +1 -1
- package/dist/subsystem/C4Graph.js +38 -73
- package/dist/subsystem/C4Graph.js.map +1 -1
- package/dist/subsystem/C4NodeCard.d.ts +119 -0
- package/dist/subsystem/C4NodeCard.d.ts.map +1 -0
- package/dist/subsystem/C4NodeCard.js +223 -0
- package/dist/subsystem/C4NodeCard.js.map +1 -0
- package/dist/subsystem/DiagnosticToggle.d.ts +8 -1
- package/dist/subsystem/DiagnosticToggle.d.ts.map +1 -1
- package/dist/subsystem/DiagnosticToggle.js +40 -6
- package/dist/subsystem/DiagnosticToggle.js.map +1 -1
- package/dist/subsystem/FileDrawer.d.ts.map +1 -1
- package/dist/subsystem/FileDrawer.js +20 -21
- package/dist/subsystem/FileDrawer.js.map +1 -1
- package/dist/subsystem/IssueList.js +1 -1
- package/dist/subsystem/IssueList.js.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.js +13 -4
- package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
- package/dist/subsystem/c4.d.ts +272 -0
- package/dist/subsystem/c4.d.ts.map +1 -0
- package/dist/subsystem/c4.js +322 -0
- package/dist/subsystem/c4.js.map +1 -0
- package/dist/subsystem/c4Evidence.d.ts +143 -0
- package/dist/subsystem/c4Evidence.d.ts.map +1 -0
- package/dist/subsystem/c4Evidence.js +240 -0
- package/dist/subsystem/c4Evidence.js.map +1 -0
- package/dist/subsystem/model.d.ts +27 -7
- package/dist/subsystem/model.d.ts.map +1 -1
- package/dist/subsystem/model.js +15 -0
- package/dist/subsystem/model.js.map +1 -1
- package/dist/subsystem/nodes.d.ts.map +1 -1
- package/dist/subsystem/nodes.js +78 -7
- package/dist/subsystem/nodes.js.map +1 -1
- package/package.json +3 -2
- package/src/index.ts +37 -0
- package/src/pierre/PierreTrailCodeView.tsx +49 -21
- package/src/stories/Subsystem/C4Graph/C4NodeGallery.stories.tsx +413 -0
- package/src/stories/Subsystem/C4Graph/ProposedElements.stories.tsx +293 -0
- package/src/stories/Subsystem/C4Graph/c4ProposedElements.fixture.ts +366 -0
- package/src/stories/Subsystem/ComponentGraph/Deprecated.stories.tsx +358 -0
- package/src/stories/Subsystem/ComponentGraph/Diagnostics.stories.tsx +27 -2
- package/src/stories/Subsystem/ComponentGraph/IssueOverlay.stories.tsx +1 -1
- package/src/stories/Subsystem/ComponentGraph/Issues.stories.tsx +1 -1
- package/src/stories/Subsystem/ComponentGraph/{Flows.stories.tsx → Trails.stories.tsx} +4 -4
- package/src/subsystem/C4Graph.tsx +81 -107
- package/src/subsystem/C4NodeCard.test.ts +301 -0
- package/src/subsystem/C4NodeCard.tsx +301 -0
- package/src/subsystem/DiagnosticToggle.tsx +58 -4
- package/src/subsystem/FileDrawer.tsx +32 -34
- package/src/subsystem/IssueList.tsx +1 -1
- package/src/subsystem/SubsystemComponentGraph.tsx +13 -5
- package/src/subsystem/c4.test.ts +573 -0
- package/src/subsystem/c4.ts +558 -0
- package/src/subsystem/c4Evidence.test.ts +386 -0
- package/src/subsystem/c4Evidence.ts +329 -0
- package/src/subsystem/model.ts +36 -7
- package/src/subsystem/nodes.tsx +124 -5
- package/dist/stories/Subsystem/C4Graph/c4Fixture.d.ts +0 -3
- package/dist/stories/Subsystem/C4Graph/c4Fixture.d.ts.map +0 -1
- package/dist/stories/Subsystem/C4Graph/c4Fixture.js +0 -2
- package/dist/stories/Subsystem/C4Graph/c4Fixture.js.map +0 -1
- package/dist/subsystem/toC4.d.ts +0 -95
- package/dist/subsystem/toC4.d.ts.map +0 -1
- package/dist/subsystem/toC4.js +0 -192
- package/dist/subsystem/toC4.js.map +0 -1
- package/src/stories/Subsystem/C4Graph/C4Container.stories.tsx +0 -101
- package/src/stories/Subsystem/C4Graph/c4Fixture.ts +0 -6
- package/src/subsystem/toC4.test.ts +0 -114
- package/src/subsystem/toC4.ts +0 -273
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C4 elements — the authored boxes on a diagram.
|
|
3
|
+
*
|
|
4
|
+
* A C4 diagram says something a code model cannot: *these* runs of code are
|
|
5
|
+
* one deployable unit, *this* component has no home, *this* external system is
|
|
6
|
+
* outside our boundary. That is an architectural judgement, and no amount of
|
|
7
|
+
* reading `process` strings will produce it — `process` answers "where does
|
|
8
|
+
* this run", which is a different question.
|
|
9
|
+
*
|
|
10
|
+
* So the element list is authored. An agent proposes it, a person confirms it,
|
|
11
|
+
* and `buildC4Model` does the only mechanical job left: draw the boxes the
|
|
12
|
+
* author named, and use the trails to draw the lines between them.
|
|
13
|
+
*
|
|
14
|
+
* ## Why a union and not one type with two axes
|
|
15
|
+
*
|
|
16
|
+
* C4's vocabulary is closed: software system, container, component, code —
|
|
17
|
+
* plus person outside the boundary. An earlier shape here carried a `level`
|
|
18
|
+
* (where it sits) and a `type` (what it is) as independent fields, which let
|
|
19
|
+
* combinations that mean nothing (`external` + `data-store`) and invented one
|
|
20
|
+
* that contradicts C4 (`library`, which is "typically not" an element at all).
|
|
21
|
+
*
|
|
22
|
+
* Four types carry only the fields the [C4 notation] requires for them:
|
|
23
|
+
*
|
|
24
|
+
* - technology is required on containers and components, optional on an
|
|
25
|
+
* external system, absent on a person
|
|
26
|
+
* - a component names its container, because a C4 component belongs to
|
|
27
|
+
* exactly one container
|
|
28
|
+
* - there is no `library` type; a package that is not a deployable unit is
|
|
29
|
+
* recorded as a review comment, not a new element kind
|
|
30
|
+
*
|
|
31
|
+
* [C4 notation]: https://c4model.com/diagrams/notation
|
|
32
|
+
*/
|
|
33
|
+
import type { SubsystemComponent, SubsystemModelDocument } from './model';
|
|
34
|
+
/**
|
|
35
|
+
* Has anyone signed off on this element yet?
|
|
36
|
+
*
|
|
37
|
+
* `proposed` is what an agent writes and a human has not looked at. `accepted`
|
|
38
|
+
* is a human decision. `rejected` means the proposal was wrong and the box
|
|
39
|
+
* should not be drawn at all.
|
|
40
|
+
*/
|
|
41
|
+
export type C4ElementState = 'proposed' | 'accepted' | 'rejected';
|
|
42
|
+
/** Fields every element carries, whatever its kind. */
|
|
43
|
+
interface C4ElementBase {
|
|
44
|
+
/**
|
|
45
|
+
* Stable identity: `container:studio-host`. Survives member churn, so a
|
|
46
|
+
* reviewer's accept/reject keeps pointing at the same box next week.
|
|
47
|
+
*/
|
|
48
|
+
id: string;
|
|
49
|
+
/** Display name. */
|
|
50
|
+
label: string;
|
|
51
|
+
/**
|
|
52
|
+
* The component aliases that live directly inside this element.
|
|
53
|
+
*
|
|
54
|
+
* Named explicitly rather than derived from a `process` value, because two
|
|
55
|
+
* runs of code being one container is a judgement, not a lookup. This is also
|
|
56
|
+
* the dedup mechanism: two elements that should be one simply end up as one
|
|
57
|
+
* element holding both member sets.
|
|
58
|
+
*
|
|
59
|
+
* Each alias belongs to exactly one element. A container does *not* repeat
|
|
60
|
+
* the aliases its components already claim — `buildC4Model` rolls those up.
|
|
61
|
+
*/
|
|
62
|
+
members: string[];
|
|
63
|
+
/**
|
|
64
|
+
* The `process` values this element consolidated, when it came from more than
|
|
65
|
+
* one. Purely provenance — it lets the confirm UI show "this box absorbed
|
|
66
|
+
* principal-studio/host". Never used to infer membership.
|
|
67
|
+
*/
|
|
68
|
+
derivedFrom?: string[];
|
|
69
|
+
/** C4 asks every element to carry a one-line responsibility. */
|
|
70
|
+
description?: string;
|
|
71
|
+
state: C4ElementState;
|
|
72
|
+
/** Why this element is proposed as it is — shown in the confirm UI. */
|
|
73
|
+
rationale?: string;
|
|
74
|
+
/** Who or what authored it. */
|
|
75
|
+
author?: string;
|
|
76
|
+
/** When the state last changed (ISO). */
|
|
77
|
+
decidedAt?: string;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* What kind of thing a container is.
|
|
81
|
+
*
|
|
82
|
+
* `application` is a deployable program; the other two are storage that the
|
|
83
|
+
* system reads or writes. Note c4model is explicit that an individual *queue*
|
|
84
|
+
* is a data store, not the bus: "model the message bus as a container" is
|
|
85
|
+
* listed as incorrect.
|
|
86
|
+
*/
|
|
87
|
+
export type C4ContainerKind = 'application' | 'data-store' | 'queue';
|
|
88
|
+
/** A deployable unit or a store — the C4 level 2 box. */
|
|
89
|
+
export interface C4Container extends C4ElementBase {
|
|
90
|
+
kind: 'container';
|
|
91
|
+
/** What sort of container this is. */
|
|
92
|
+
containerKind: C4ContainerKind;
|
|
93
|
+
/** C4 requires a technology on every container. */
|
|
94
|
+
technology: string;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* A functional grouping inside a container — the C4 level 3 box.
|
|
98
|
+
*
|
|
99
|
+
* `container` is required, not inferred. C4 says all components inside a
|
|
100
|
+
* container share one process space, so a component has exactly one parent;
|
|
101
|
+
* inferring it from member overlap gets that wrong whenever one concept is
|
|
102
|
+
* split across containers (an RPC bridge with a renderer half and a host half),
|
|
103
|
+
* which is precisely the case worth being able to state.
|
|
104
|
+
*/
|
|
105
|
+
export interface C4Component extends C4ElementBase {
|
|
106
|
+
kind: 'component';
|
|
107
|
+
/** The id of the container this component sits inside. */
|
|
108
|
+
container: string;
|
|
109
|
+
/** C4 requires a technology on every component. */
|
|
110
|
+
technology: string;
|
|
111
|
+
}
|
|
112
|
+
/** A software system outside the boundary we are drawing. */
|
|
113
|
+
export interface C4ExternalSystem extends C4ElementBase {
|
|
114
|
+
kind: 'external-system';
|
|
115
|
+
/** Often unknown for a third-party system, so optional here. */
|
|
116
|
+
technology?: string;
|
|
117
|
+
}
|
|
118
|
+
/** A person. Outside the boundary, and never has technology. */
|
|
119
|
+
export interface C4Person extends C4ElementBase {
|
|
120
|
+
kind: 'person';
|
|
121
|
+
}
|
|
122
|
+
/** One element. Four kinds, no fifth. */
|
|
123
|
+
export type C4Element = C4Container | C4Component | C4ExternalSystem | C4Person;
|
|
124
|
+
/** A whole authored element list, for one repo or composed graph. */
|
|
125
|
+
export interface C4ElementSet {
|
|
126
|
+
/** Repo key this set describes, e.g. `pkg:github/owner/name`. */
|
|
127
|
+
repoKey: string;
|
|
128
|
+
/** ISO timestamp of the last change. */
|
|
129
|
+
updatedAt?: string;
|
|
130
|
+
elements: C4Element[];
|
|
131
|
+
}
|
|
132
|
+
/** Which level to draw. Determines which frames are drawn. */
|
|
133
|
+
export type C4View = 'container' | 'component';
|
|
134
|
+
/**
|
|
135
|
+
* A flattened element, as the renderer reads it.
|
|
136
|
+
*
|
|
137
|
+
* The union above is what an author writes; this is the one shape every box
|
|
138
|
+
* draws with, so the card does not branch on kind to find a label.
|
|
139
|
+
*/
|
|
140
|
+
export interface C4Node {
|
|
141
|
+
id: string;
|
|
142
|
+
kind: C4Element['kind'];
|
|
143
|
+
/**
|
|
144
|
+
* Nesting parent: a component's container, a container or external system's
|
|
145
|
+
* frame, and nothing for a person — C4 puts people outside every system.
|
|
146
|
+
*/
|
|
147
|
+
parentId?: string;
|
|
148
|
+
label: string;
|
|
149
|
+
technology?: string;
|
|
150
|
+
description?: string;
|
|
151
|
+
state: C4ElementState;
|
|
152
|
+
/** `application` / `data-store` / `queue`. Set on containers only. */
|
|
153
|
+
containerKind?: C4ContainerKind;
|
|
154
|
+
/** Provenance, when the element consolidated several derived keys. */
|
|
155
|
+
derivedFrom?: string[];
|
|
156
|
+
/** Resolved members, when a document was supplied. A container's list includes its components'. */
|
|
157
|
+
members: string[];
|
|
158
|
+
/** Distinct constructs among resolved members. */
|
|
159
|
+
constructs: string[];
|
|
160
|
+
/** Present at component level when the document resolved it. */
|
|
161
|
+
component?: SubsystemComponent;
|
|
162
|
+
/** Source model ids that contributed members, when attribution is supplied. */
|
|
163
|
+
models?: string[];
|
|
164
|
+
}
|
|
165
|
+
/** A compound frame: the system, or a container holding its components. */
|
|
166
|
+
export interface C4Group {
|
|
167
|
+
id: string;
|
|
168
|
+
kind: 'system' | 'container';
|
|
169
|
+
label: string;
|
|
170
|
+
parentId?: string;
|
|
171
|
+
memberIds: string[];
|
|
172
|
+
}
|
|
173
|
+
/** A line between two elements, rolled up from a trail step. */
|
|
174
|
+
export interface C4Edge {
|
|
175
|
+
id: string;
|
|
176
|
+
source: string;
|
|
177
|
+
target: string;
|
|
178
|
+
label: string;
|
|
179
|
+
mechanisms: string[];
|
|
180
|
+
/** Trail steps that produced this line. */
|
|
181
|
+
count: number;
|
|
182
|
+
}
|
|
183
|
+
/** A drawable C4 projection. */
|
|
184
|
+
export interface C4Model {
|
|
185
|
+
view: C4View;
|
|
186
|
+
system: {
|
|
187
|
+
id: string;
|
|
188
|
+
label: string;
|
|
189
|
+
repoKey?: string;
|
|
190
|
+
};
|
|
191
|
+
nodes: C4Node[];
|
|
192
|
+
groups: C4Group[];
|
|
193
|
+
edges: C4Edge[];
|
|
194
|
+
}
|
|
195
|
+
/** Something an author should fix before this set is trusted. */
|
|
196
|
+
export type C4ProblemKind =
|
|
197
|
+
/** a member is claimed by two elements */
|
|
198
|
+
'conflicting_member'
|
|
199
|
+
/** a member is not in the supplied document */
|
|
200
|
+
| 'unknown_member'
|
|
201
|
+
/** two elements share an id */
|
|
202
|
+
| 'duplicate_id'
|
|
203
|
+
/** an element that should have contents has none */
|
|
204
|
+
| 'empty_element'
|
|
205
|
+
/** a component names a container that is missing, or is not a container */
|
|
206
|
+
| 'unknown_container';
|
|
207
|
+
export interface C4Problem {
|
|
208
|
+
kind: C4ProblemKind;
|
|
209
|
+
message: string;
|
|
210
|
+
/** Alias for member problems, element id for the rest. */
|
|
211
|
+
subject: string;
|
|
212
|
+
}
|
|
213
|
+
export interface C4BuildResult {
|
|
214
|
+
model: C4Model;
|
|
215
|
+
/** Authoring mistakes. An empty array means the set is self-consistent. */
|
|
216
|
+
problems: C4Problem[];
|
|
217
|
+
/** Component aliases in the document that no element claims. */
|
|
218
|
+
unmapped: string[];
|
|
219
|
+
}
|
|
220
|
+
export interface C4BuildOptions {
|
|
221
|
+
/** The elements. The source of truth — nothing is invented. */
|
|
222
|
+
elements: readonly C4Element[];
|
|
223
|
+
/** Supply to resolve members and draw lines from trails. */
|
|
224
|
+
document?: SubsystemModelDocument;
|
|
225
|
+
view?: C4View;
|
|
226
|
+
/** Name of the system the elements sit in. */
|
|
227
|
+
systemLabel?: string;
|
|
228
|
+
/** Override the repo key (defaults to the first member's purl). */
|
|
229
|
+
repoKey?: string;
|
|
230
|
+
/** Model-id attribution per component alias. */
|
|
231
|
+
modelsByAlias?: Record<string, string[]>;
|
|
232
|
+
}
|
|
233
|
+
/** True when this element kind is drawn inside the system frame. */
|
|
234
|
+
export declare function isInBoundary(e: C4Element): boolean;
|
|
235
|
+
/** `owner/name` from a purl, trimmed of scheme and fragment. */
|
|
236
|
+
export declare function labelFromPurl(purl: string): string;
|
|
237
|
+
/**
|
|
238
|
+
* Build the drawable projection from authored elements.
|
|
239
|
+
*
|
|
240
|
+
* A plain join with no architectural judgement:
|
|
241
|
+
*
|
|
242
|
+
* boxes ← one per element, named and placed by the author
|
|
243
|
+
* lines ← trail steps, with each endpoint mapped to its owning element
|
|
244
|
+
*
|
|
245
|
+
* Trail steps whose endpoints are not claimed by any element are skipped:
|
|
246
|
+
* drawing them would assert a relationship the author did not describe.
|
|
247
|
+
*/
|
|
248
|
+
export declare function buildC4Model(options: C4BuildOptions): C4BuildResult;
|
|
249
|
+
/**
|
|
250
|
+
* Tally for the confirm UI: how much is proposed vs accepted, and how much is
|
|
251
|
+
* still missing what the C4 notation requires.
|
|
252
|
+
*
|
|
253
|
+
* Counts the authored set, not the projection — a rejected element is still a
|
|
254
|
+
* decision that was made, so it is reported rather than forgotten.
|
|
255
|
+
*/
|
|
256
|
+
export declare function summarizeElements(elements: readonly C4Element[]): {
|
|
257
|
+
containers: number;
|
|
258
|
+
components: number;
|
|
259
|
+
externals: number;
|
|
260
|
+
people: number;
|
|
261
|
+
accepted: number;
|
|
262
|
+
proposed: number;
|
|
263
|
+
rejected: number;
|
|
264
|
+
/** Containers missing the technology C4 requires. */
|
|
265
|
+
missingTechnology: number;
|
|
266
|
+
/** Elements missing a description. */
|
|
267
|
+
missingDescription: number;
|
|
268
|
+
/** Elements whose state is not yet `accepted`. */
|
|
269
|
+
needsDecision: number;
|
|
270
|
+
};
|
|
271
|
+
export {};
|
|
272
|
+
//# sourceMappingURL=c4.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c4.d.ts","sourceRoot":"","sources":["../../src/subsystem/c4.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C4 elements — the authored boxes on a diagram.
|
|
3
|
+
*
|
|
4
|
+
* A C4 diagram says something a code model cannot: *these* runs of code are
|
|
5
|
+
* one deployable unit, *this* component has no home, *this* external system is
|
|
6
|
+
* outside our boundary. That is an architectural judgement, and no amount of
|
|
7
|
+
* reading `process` strings will produce it — `process` answers "where does
|
|
8
|
+
* this run", which is a different question.
|
|
9
|
+
*
|
|
10
|
+
* So the element list is authored. An agent proposes it, a person confirms it,
|
|
11
|
+
* and `buildC4Model` does the only mechanical job left: draw the boxes the
|
|
12
|
+
* author named, and use the trails to draw the lines between them.
|
|
13
|
+
*
|
|
14
|
+
* ## Why a union and not one type with two axes
|
|
15
|
+
*
|
|
16
|
+
* C4's vocabulary is closed: software system, container, component, code —
|
|
17
|
+
* plus person outside the boundary. An earlier shape here carried a `level`
|
|
18
|
+
* (where it sits) and a `type` (what it is) as independent fields, which let
|
|
19
|
+
* combinations that mean nothing (`external` + `data-store`) and invented one
|
|
20
|
+
* that contradicts C4 (`library`, which is "typically not" an element at all).
|
|
21
|
+
*
|
|
22
|
+
* Four types carry only the fields the [C4 notation] requires for them:
|
|
23
|
+
*
|
|
24
|
+
* - technology is required on containers and components, optional on an
|
|
25
|
+
* external system, absent on a person
|
|
26
|
+
* - a component names its container, because a C4 component belongs to
|
|
27
|
+
* exactly one container
|
|
28
|
+
* - there is no `library` type; a package that is not a deployable unit is
|
|
29
|
+
* recorded as a review comment, not a new element kind
|
|
30
|
+
*
|
|
31
|
+
* [C4 notation]: https://c4model.com/diagrams/notation
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Element kinds drawn inside the system boundary.
|
|
35
|
+
*
|
|
36
|
+
* A C4 container diagram puts external systems *inside* the boundary: they are
|
|
37
|
+
* things this system depends on, drawn as containers we do not own. People go
|
|
38
|
+
* outside it, because a person is never part of any system.
|
|
39
|
+
*/
|
|
40
|
+
const IN_BOUNDARY = new Set(['container', 'external-system']);
|
|
41
|
+
/** True when this element kind is drawn inside the system frame. */
|
|
42
|
+
export function isInBoundary(e) {
|
|
43
|
+
return IN_BOUNDARY.has(e.kind);
|
|
44
|
+
}
|
|
45
|
+
function purlRepoKey(purl) {
|
|
46
|
+
const p = (purl ?? '').split('#')[0]?.trim();
|
|
47
|
+
if (!p || p === 'external' || p.startsWith('external:'))
|
|
48
|
+
return undefined;
|
|
49
|
+
return p;
|
|
50
|
+
}
|
|
51
|
+
/** `owner/name` from a purl, trimmed of scheme and fragment. */
|
|
52
|
+
export function labelFromPurl(purl) {
|
|
53
|
+
const base = purl.replace(/^external:/, '').split('#')[0]?.trim() ?? '';
|
|
54
|
+
const parts = base.split('/').filter(Boolean);
|
|
55
|
+
return parts.slice(-2).join('/') || base || purl;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build the drawable projection from authored elements.
|
|
59
|
+
*
|
|
60
|
+
* A plain join with no architectural judgement:
|
|
61
|
+
*
|
|
62
|
+
* boxes ← one per element, named and placed by the author
|
|
63
|
+
* lines ← trail steps, with each endpoint mapped to its owning element
|
|
64
|
+
*
|
|
65
|
+
* Trail steps whose endpoints are not claimed by any element are skipped:
|
|
66
|
+
* drawing them would assert a relationship the author did not describe.
|
|
67
|
+
*/
|
|
68
|
+
export function buildC4Model(options) {
|
|
69
|
+
const view = options.view ?? 'container';
|
|
70
|
+
const doc = options.document;
|
|
71
|
+
const problems = [];
|
|
72
|
+
const byAlias = new Map(doc?.components.map((c) => [c.alias, c]) ?? []);
|
|
73
|
+
/**
|
|
74
|
+
* Alias → owning element, innermost home wins. One owner per alias: this is
|
|
75
|
+
* what makes `conflicting_member` mean "two boxes disagree" rather than
|
|
76
|
+
* "a container and its components both mention the same code".
|
|
77
|
+
*/
|
|
78
|
+
const membersOf = new Map();
|
|
79
|
+
// --- accept each element once, and resolve membership --------------------
|
|
80
|
+
const seenIds = new Set();
|
|
81
|
+
/** alias → element id. One owner per alias; conflicts are reported. */
|
|
82
|
+
const ownerOf = new Map();
|
|
83
|
+
/** Ids in authored order, duplicates dropped. */
|
|
84
|
+
const accepted = [];
|
|
85
|
+
const elementById = new Map();
|
|
86
|
+
for (const e of options.elements) {
|
|
87
|
+
if (seenIds.has(e.id)) {
|
|
88
|
+
problems.push({
|
|
89
|
+
kind: 'duplicate_id',
|
|
90
|
+
subject: e.id,
|
|
91
|
+
message: `two elements share the id ${e.id}`,
|
|
92
|
+
});
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
seenIds.add(e.id);
|
|
96
|
+
accepted.push(e.id);
|
|
97
|
+
elementById.set(e.id, e);
|
|
98
|
+
// A rejected element is not drawn, so its members are inside nothing.
|
|
99
|
+
// Leaving them claimed would hide them from `unmapped` and quietly hide
|
|
100
|
+
// the fact that rejecting an element orphans whatever was in it.
|
|
101
|
+
if (e.state === 'rejected')
|
|
102
|
+
continue;
|
|
103
|
+
for (const alias of e.members) {
|
|
104
|
+
if (doc && !byAlias.has(alias)) {
|
|
105
|
+
problems.push({
|
|
106
|
+
kind: 'unknown_member',
|
|
107
|
+
subject: alias,
|
|
108
|
+
message: `element "${e.id}" claims "${alias}", which is not in the supplied document`,
|
|
109
|
+
});
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const existing = ownerOf.get(alias);
|
|
113
|
+
if (existing && existing !== e.id) {
|
|
114
|
+
problems.push({
|
|
115
|
+
kind: 'conflicting_member',
|
|
116
|
+
subject: alias,
|
|
117
|
+
message: `"${alias}" is claimed by both ${existing} and ${e.id}; it is drawn inside ${existing}`,
|
|
118
|
+
});
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
ownerOf.set(alias, e.id);
|
|
122
|
+
const list = membersOf.get(e.id) ?? [];
|
|
123
|
+
list.push(alias);
|
|
124
|
+
membersOf.set(e.id, list);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// --- the system boundary -------------------------------------------------
|
|
128
|
+
const repoKey = options.repoKey ??
|
|
129
|
+
options.elements
|
|
130
|
+
.flatMap((e) => e.members)
|
|
131
|
+
.map((alias) => purlRepoKey(byAlias.get(alias)?.purl))
|
|
132
|
+
.find(Boolean);
|
|
133
|
+
const systemId = `system:${repoKey ?? 'unspecified'}`;
|
|
134
|
+
const systemLabel = options.systemLabel ?? (repoKey ? labelFromPurl(repoKey) : 'Software System');
|
|
135
|
+
// --- draw the boxes ------------------------------------------------------
|
|
136
|
+
const nodes = [];
|
|
137
|
+
/**
|
|
138
|
+
* The aliases an element claimed itself, before any rollup. A component's
|
|
139
|
+
* own members and its container's own members are disjoint by construction,
|
|
140
|
+
* which is what lets the two be added together below.
|
|
141
|
+
*/
|
|
142
|
+
const ownMembers = new Map();
|
|
143
|
+
for (const id of accepted) {
|
|
144
|
+
const e = elementById.get(id);
|
|
145
|
+
if (e.state === 'rejected')
|
|
146
|
+
continue;
|
|
147
|
+
const own = membersOf.get(id) ?? [];
|
|
148
|
+
// A component's parent is stated, not inferred. Check it resolves: a
|
|
149
|
+
// dangling parent would silently drop the component out of every frame.
|
|
150
|
+
let parentId;
|
|
151
|
+
if (e.kind === 'component') {
|
|
152
|
+
const parent = elementById.get(e.container);
|
|
153
|
+
if (!parent || parent.state === 'rejected') {
|
|
154
|
+
problems.push({
|
|
155
|
+
kind: 'unknown_container',
|
|
156
|
+
subject: id,
|
|
157
|
+
message: `component "${id}" names container "${e.container}", which is not in this set`,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
else if (parent.kind !== 'container') {
|
|
161
|
+
problems.push({
|
|
162
|
+
kind: 'unknown_container',
|
|
163
|
+
subject: id,
|
|
164
|
+
message: `component "${id}" names container "${e.container}", which is a ${parent.kind}, not a container`,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
parentId = parent.id;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (isInBoundary(e)) {
|
|
172
|
+
parentId = systemId;
|
|
173
|
+
}
|
|
174
|
+
ownMembers.set(id, own);
|
|
175
|
+
nodes.push({
|
|
176
|
+
id: e.id,
|
|
177
|
+
kind: e.kind,
|
|
178
|
+
label: e.label,
|
|
179
|
+
...(parentId ? { parentId } : {}),
|
|
180
|
+
technology: 'technology' in e ? e.technology : undefined,
|
|
181
|
+
description: e.description,
|
|
182
|
+
state: e.state,
|
|
183
|
+
...(e.kind === 'container' ? { containerKind: e.containerKind } : {}),
|
|
184
|
+
...(e.derivedFrom && e.derivedFrom.length > 1 ? { derivedFrom: e.derivedFrom } : {}),
|
|
185
|
+
members: own,
|
|
186
|
+
constructs: [],
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
// --- roll components up into their container ------------------------------
|
|
190
|
+
//
|
|
191
|
+
// A C4 container diagram draws the container as a whole, so a container
|
|
192
|
+
// holds everything inside its components. Membership is still authored
|
|
193
|
+
// exactly once: an alias belongs to one element, so a container must not
|
|
194
|
+
// repeat what its components already claim — that repetition would read as
|
|
195
|
+
// a `conflicting_member` and hide the real question, which is how many
|
|
196
|
+
// components a container has.
|
|
197
|
+
for (const n of nodes) {
|
|
198
|
+
if (n.kind !== 'component' || !n.parentId)
|
|
199
|
+
continue;
|
|
200
|
+
const list = membersOf.get(n.parentId) ?? [];
|
|
201
|
+
list.push(...(ownMembers.get(n.id) ?? []));
|
|
202
|
+
membersOf.set(n.parentId, list);
|
|
203
|
+
}
|
|
204
|
+
for (const n of nodes) {
|
|
205
|
+
n.members = membersOf.get(n.id) ?? [];
|
|
206
|
+
if (n.members.length === 0) {
|
|
207
|
+
problems.push({
|
|
208
|
+
kind: 'empty_element',
|
|
209
|
+
subject: n.id,
|
|
210
|
+
message: `element "${n.id}" (${n.kind}) claims no members, and nothing is inside it either, so there is nothing to draw`,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
const resolved = n.members.map((m) => byAlias.get(m)).filter((c) => !!c);
|
|
214
|
+
const constructs = [];
|
|
215
|
+
for (const c of resolved)
|
|
216
|
+
if (!constructs.includes(c.construct))
|
|
217
|
+
constructs.push(c.construct);
|
|
218
|
+
n.constructs = constructs;
|
|
219
|
+
if (n.kind === 'component' && resolved[0])
|
|
220
|
+
n.component = resolved[0];
|
|
221
|
+
const models = [...new Set(n.members.flatMap((m) => options.modelsByAlias?.[m] ?? []))];
|
|
222
|
+
if (models.length > 0)
|
|
223
|
+
n.models = models;
|
|
224
|
+
}
|
|
225
|
+
// --- compound frames -----------------------------------------------------
|
|
226
|
+
const groups = [];
|
|
227
|
+
if (view === 'container') {
|
|
228
|
+
const containerIds = nodes.filter((n) => n.kind === 'container').map((n) => n.id);
|
|
229
|
+
if (containerIds.length > 0) {
|
|
230
|
+
groups.push({ id: systemId, kind: 'system', label: systemLabel, memberIds: containerIds });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
const byContainer = new Map();
|
|
235
|
+
for (const n of nodes) {
|
|
236
|
+
if (n.kind !== 'component' || !n.parentId)
|
|
237
|
+
continue;
|
|
238
|
+
const list = byContainer.get(n.parentId) ?? [];
|
|
239
|
+
list.push(n.id);
|
|
240
|
+
byContainer.set(n.parentId, list);
|
|
241
|
+
}
|
|
242
|
+
const framed = [];
|
|
243
|
+
for (const [id, memberIds] of byContainer) {
|
|
244
|
+
const label = nodes.find((n) => n.id === id)?.label ?? id;
|
|
245
|
+
groups.push({ id, kind: 'container', label, parentId: systemId, memberIds });
|
|
246
|
+
framed.push(id);
|
|
247
|
+
}
|
|
248
|
+
if (framed.length > 0) {
|
|
249
|
+
groups.push({ id: systemId, kind: 'system', label: systemLabel, memberIds: framed });
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
// --- lines, from the trails ---------------------------------------------
|
|
253
|
+
const drawn = new Set(nodes.map((n) => n.id));
|
|
254
|
+
const edges = new Map();
|
|
255
|
+
for (const trail of doc?.trails ?? []) {
|
|
256
|
+
for (const step of trail.steps ?? []) {
|
|
257
|
+
const source = ownerOf.get(step.from);
|
|
258
|
+
const target = ownerOf.get(step.to);
|
|
259
|
+
// An endpoint no element claims has no box, so there is no line to draw.
|
|
260
|
+
if (!source || !target || source === target)
|
|
261
|
+
continue;
|
|
262
|
+
if (!drawn.has(source) || !drawn.has(target))
|
|
263
|
+
continue;
|
|
264
|
+
const key = `${source}\0${target}`;
|
|
265
|
+
const edge = edges.get(key);
|
|
266
|
+
if (edge) {
|
|
267
|
+
edge.count += 1;
|
|
268
|
+
if (!edge.mechanisms.includes(step.mechanism))
|
|
269
|
+
edge.mechanisms.push(step.mechanism);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
edges.set(key, {
|
|
273
|
+
id: `flow:${key}`,
|
|
274
|
+
source,
|
|
275
|
+
target,
|
|
276
|
+
label: step.mechanism,
|
|
277
|
+
mechanisms: [step.mechanism],
|
|
278
|
+
count: 1,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
for (const e of edges.values())
|
|
284
|
+
e.label = [...e.mechanisms].sort().join(' + ');
|
|
285
|
+
const unmapped = (doc?.components ?? []).filter((c) => !ownerOf.has(c.alias)).map((c) => c.alias);
|
|
286
|
+
return {
|
|
287
|
+
model: {
|
|
288
|
+
view,
|
|
289
|
+
system: { id: systemId, label: systemLabel, repoKey },
|
|
290
|
+
nodes,
|
|
291
|
+
groups,
|
|
292
|
+
edges: [...edges.values()],
|
|
293
|
+
},
|
|
294
|
+
problems,
|
|
295
|
+
unmapped,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Tally for the confirm UI: how much is proposed vs accepted, and how much is
|
|
300
|
+
* still missing what the C4 notation requires.
|
|
301
|
+
*
|
|
302
|
+
* Counts the authored set, not the projection — a rejected element is still a
|
|
303
|
+
* decision that was made, so it is reported rather than forgotten.
|
|
304
|
+
*/
|
|
305
|
+
export function summarizeElements(elements) {
|
|
306
|
+
const live = elements.filter((e) => e.state !== 'rejected');
|
|
307
|
+
return {
|
|
308
|
+
containers: live.filter((e) => e.kind === 'container').length,
|
|
309
|
+
components: live.filter((e) => e.kind === 'component').length,
|
|
310
|
+
externals: live.filter((e) => e.kind === 'external-system').length,
|
|
311
|
+
people: live.filter((e) => e.kind === 'person').length,
|
|
312
|
+
accepted: live.filter((e) => e.state === 'accepted').length,
|
|
313
|
+
proposed: live.filter((e) => e.state === 'proposed').length,
|
|
314
|
+
rejected: elements.filter((e) => e.state === 'rejected').length,
|
|
315
|
+
// `technology` is required by the type on containers and components, so a
|
|
316
|
+
// missing one can only mean an empty string — still worth reporting.
|
|
317
|
+
missingTechnology: live.filter((e) => 'technology' in e && !e.technology).length,
|
|
318
|
+
missingDescription: live.filter((e) => !e.description).length,
|
|
319
|
+
needsDecision: live.filter((e) => e.state !== 'accepted').length,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
//# sourceMappingURL=c4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c4.js","sourceRoot":"","sources":["../../src/subsystem/c4.ts"],"names":[],"mappings":"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"}
|