@formicoidea/labre-framework-c4 0.33.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/dist/actions.d.ts +179 -0
- package/dist/actions.js +375 -0
- package/dist/background.d.ts +77 -0
- package/dist/background.js +223 -0
- package/dist/commands.d.ts +4 -0
- package/dist/commands.js +221 -0
- package/dist/component.d.ts +192 -0
- package/dist/component.js +188 -0
- package/dist/consts.d.ts +331 -0
- package/dist/consts.js +384 -0
- package/dist/descriptor.d.ts +12 -0
- package/dist/descriptor.js +10 -0
- package/dist/effects.d.ts +9 -0
- package/dist/effects.js +6 -0
- package/dist/element-renderer.d.ts +18 -0
- package/dist/element-renderer.js +14 -0
- package/dist/element-view.d.ts +51 -0
- package/dist/element-view.js +146 -0
- package/dist/export.d.ts +184 -0
- package/dist/export.js +454 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +52 -0
- package/dist/interchange.d.ts +74 -0
- package/dist/interchange.js +143 -0
- package/dist/legend.d.ts +37 -0
- package/dist/legend.js +123 -0
- package/dist/levels.d.ts +70 -0
- package/dist/levels.js +46 -0
- package/dist/morph.d.ts +89 -0
- package/dist/morph.js +229 -0
- package/dist/node/node-renderer.d.ts +6 -0
- package/dist/node/node-renderer.js +304 -0
- package/dist/node/node-view.d.ts +45 -0
- package/dist/node/node-view.js +80 -0
- package/dist/node/type-line-watcher.d.ts +70 -0
- package/dist/node/type-line-watcher.js +142 -0
- package/dist/presets.d.ts +84 -0
- package/dist/presets.js +149 -0
- package/dist/profiles.d.ts +2 -0
- package/dist/profiles.js +177 -0
- package/dist/roles.d.ts +116 -0
- package/dist/roles.js +303 -0
- package/dist/rules.d.ts +95 -0
- package/dist/rules.js +1261 -0
- package/dist/toolbar/c4-menu.d.ts +11 -0
- package/dist/toolbar/c4-menu.js +14 -0
- package/dist/toolbar/c4-senior-button.d.ts +19 -0
- package/dist/toolbar/c4-senior-button.js +23 -0
- package/dist/toolbar/config.d.ts +150 -0
- package/dist/toolbar/config.js +436 -0
- package/dist/toolbar/icons.d.ts +90 -0
- package/dist/toolbar/icons.js +157 -0
- package/dist/toolbar/senior-tool.d.ts +1 -0
- package/dist/toolbar/senior-tool.js +11 -0
- package/dist/translations.d.ts +18 -0
- package/dist/translations.js +42 -0
- package/dist/type-line.d.ts +175 -0
- package/dist/type-line.js +244 -0
- package/dist/view.d.ts +33 -0
- package/dist/view.js +148 -0
- package/package.json +34 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The C4 senior-button tile: a person, a dashed relationship, and the system
|
|
3
|
+
* they use — the smallest complete C4 sentence, in the stencil's own blues.
|
|
4
|
+
*
|
|
5
|
+
* The one COLOURED glyph of this file. Everything below it is a 24×24
|
|
6
|
+
* monochrome outline drawn in `currentColor`, because a command glyph sits in a
|
|
7
|
+
* menu row and takes the row's colour; the tile is the framework's face on the
|
|
8
|
+
* toolbar and is painted in the palette the pack draws with (`consts.ts`).
|
|
9
|
+
*/
|
|
10
|
+
export declare const c4ToolbarIcon: import("lit-html").TemplateResult<2>;
|
|
11
|
+
/** Person — a head over a rounded body, the stencil's own silhouette. */
|
|
12
|
+
export declare const c4PersonIcon: import("lit-html").TemplateResult<2>;
|
|
13
|
+
/**
|
|
14
|
+
* Person (external) — the same silhouette, DASHED. The stencil greys an
|
|
15
|
+
* external element out; a monochrome glyph has no grey to spend, so the dash is
|
|
16
|
+
* what carries "somebody else owns this" here.
|
|
17
|
+
*/
|
|
18
|
+
export declare const c4PersonExtIcon: import("lit-html").TemplateResult<2>;
|
|
19
|
+
/** Software system — a plain rounded rectangle, which is what C4 draws. */
|
|
20
|
+
export declare const c4SystemIcon: import("lit-html").TemplateResult<2>;
|
|
21
|
+
/** Software system (external) — the same rectangle, dashed. */
|
|
22
|
+
export declare const c4SystemExtIcon: import("lit-html").TemplateResult<2>;
|
|
23
|
+
/** Container — a box INSIDE a box: one level in from the system. */
|
|
24
|
+
export declare const c4ContainerIcon: import("lit-html").TemplateResult<2>;
|
|
25
|
+
/** Component — the UML component: a box with two tabs down its leading edge. */
|
|
26
|
+
export declare const c4ComponentIcon: import("lit-html").TemplateResult<2>;
|
|
27
|
+
/** Database — a cylinder. */
|
|
28
|
+
export declare const c4DatabaseIcon: import("lit-html").TemplateResult<2>;
|
|
29
|
+
/** Mobile app — a phone: a tall bezel with a speaker slot and a home bar. */
|
|
30
|
+
export declare const c4MobileIcon: import("lit-html").TemplateResult<2>;
|
|
31
|
+
/** Web browser — a window with a chrome band and its three dots. */
|
|
32
|
+
export declare const c4BrowserIcon: import("lit-html").TemplateResult<2>;
|
|
33
|
+
/** Relationship — a dashed arrow with a filled head, exactly as it is drawn. */
|
|
34
|
+
export declare const c4RelationshipIcon: import("lit-html").TemplateResult<2>;
|
|
35
|
+
/** C4 board — a titled card with two elements and the arrow between them. */
|
|
36
|
+
export declare const c4BoardIcon: import("lit-html").TemplateResult<2>;
|
|
37
|
+
/** System boundary — a dashed rectangle, and nothing inside it to see. */
|
|
38
|
+
export declare const c4SystemBoundaryIcon: import("lit-html").TemplateResult<2>;
|
|
39
|
+
/**
|
|
40
|
+
* Container boundary — the same dashed rectangle, one level IN: a second,
|
|
41
|
+
* smaller frame drawn inside it. The pair reads the way the two boundaries
|
|
42
|
+
* relate on the canvas, which is the only difference the notation makes between
|
|
43
|
+
* them.
|
|
44
|
+
*/
|
|
45
|
+
export declare const c4ContainerBoundaryIcon: import("lit-html").TemplateResult<2>;
|
|
46
|
+
/**
|
|
47
|
+
* Export as mermaid — a sheet with a page-corner fold and an arrow leaving it.
|
|
48
|
+
*
|
|
49
|
+
* Deliberately the SAME drawing as `bpmnExportXmlIcon`, down to the path data:
|
|
50
|
+
* it is the same gesture (take this board away as a file), and one gesture takes
|
|
51
|
+
* one glyph across the library. What it is not is a mermaid logo — the file
|
|
52
|
+
* format is what the menu LINE says, and a brand mark in a monochrome outline
|
|
53
|
+
* row would be the one icon nobody could recolour.
|
|
54
|
+
*
|
|
55
|
+
* Redrawn here rather than imported because BPMN's icons are that package's
|
|
56
|
+
* private module: a cross-framework import for one path would tie the C4 pack's
|
|
57
|
+
* build to BPMN's, and the two are meant to ship separately.
|
|
58
|
+
*/
|
|
59
|
+
export declare const c4ExportMermaidIcon: import("lit-html").TemplateResult<2>;
|
|
60
|
+
/**
|
|
61
|
+
* Every command glyph, keyed by its `iconKey`.
|
|
62
|
+
*
|
|
63
|
+
* Registered together with the commands themselves
|
|
64
|
+
* (`CommandExtension(c4Commands, c4CommandIcons)`), so a key a descriptor names
|
|
65
|
+
* and this record does not hold renders as nothing — which is what the icon
|
|
66
|
+
* coverage test in `__tests__/commands.unit.spec.ts` exists to catch.
|
|
67
|
+
*
|
|
68
|
+
* {@link c4ExportMermaidIcon} is deliberately NOT here and is added to
|
|
69
|
+
* `c4CommandIcons` in `commands.ts` instead: this record is the TOOLBOX — the
|
|
70
|
+
* thirteen glyphs of things C4 DRAWS — and an export draws nothing.
|
|
71
|
+
*
|
|
72
|
+
* The legend's glyph is in neither, because the legend is no longer a command at
|
|
73
|
+
* all: it is `dddLegendIcon`, referenced straight from `config.ts` by the button
|
|
74
|
+
* that is now the only way to reach it (PO arbitration, 27/08/2026).
|
|
75
|
+
*/
|
|
76
|
+
export declare const C4_TOOLBOX_ICONS: {
|
|
77
|
+
readonly 'c4.person': import("lit-html").TemplateResult<2>;
|
|
78
|
+
readonly 'c4.person.external': import("lit-html").TemplateResult<2>;
|
|
79
|
+
readonly 'c4.system': import("lit-html").TemplateResult<2>;
|
|
80
|
+
readonly 'c4.system.external': import("lit-html").TemplateResult<2>;
|
|
81
|
+
readonly 'c4.container': import("lit-html").TemplateResult<2>;
|
|
82
|
+
readonly 'c4.component': import("lit-html").TemplateResult<2>;
|
|
83
|
+
readonly 'c4.database': import("lit-html").TemplateResult<2>;
|
|
84
|
+
readonly 'c4.mobile': import("lit-html").TemplateResult<2>;
|
|
85
|
+
readonly 'c4.browser': import("lit-html").TemplateResult<2>;
|
|
86
|
+
readonly 'c4.relationship': import("lit-html").TemplateResult<2>;
|
|
87
|
+
readonly 'c4.board': import("lit-html").TemplateResult<2>;
|
|
88
|
+
readonly 'c4.boundary.system': import("lit-html").TemplateResult<2>;
|
|
89
|
+
readonly 'c4.boundary.container': import("lit-html").TemplateResult<2>;
|
|
90
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { svg } from 'lit';
|
|
2
|
+
/**
|
|
3
|
+
* The C4 senior-button tile: a person, a dashed relationship, and the system
|
|
4
|
+
* they use — the smallest complete C4 sentence, in the stencil's own blues.
|
|
5
|
+
*
|
|
6
|
+
* The one COLOURED glyph of this file. Everything below it is a 24×24
|
|
7
|
+
* monochrome outline drawn in `currentColor`, because a command glyph sits in a
|
|
8
|
+
* menu row and takes the row's colour; the tile is the framework's face on the
|
|
9
|
+
* toolbar and is painted in the palette the pack draws with (`consts.ts`).
|
|
10
|
+
*/
|
|
11
|
+
export const c4ToolbarIcon = svg `
|
|
12
|
+
<svg viewBox="0 0 56 56" width="100%" height="100%" fill="none"
|
|
13
|
+
xmlns="http://www.w3.org/2000/svg">
|
|
14
|
+
<circle cx="13" cy="10.5" r="5" fill="#08427b"/>
|
|
15
|
+
<rect x="5" y="16.5" width="16" height="11" rx="5.5" fill="#08427b"/>
|
|
16
|
+
<path d="M12.5 28.5 L19.4 33.8" stroke="#08427b" stroke-width="2"
|
|
17
|
+
stroke-dasharray="3 3" stroke-linecap="round"/>
|
|
18
|
+
<path d="M23 36.5 L18.1 35.6 L20.7 32 Z" fill="#08427b"/>
|
|
19
|
+
<rect x="24" y="22" width="27" height="28" rx="4" fill="#1168bd"/>
|
|
20
|
+
<rect x="28" y="27" width="12" height="8" rx="2" fill="#438dd5"/>
|
|
21
|
+
<rect x="42" y="27" width="5" height="8" rx="2" fill="#438dd5"/>
|
|
22
|
+
<rect x="28" y="39" width="19" height="7" rx="2" fill="#85bbf0"/>
|
|
23
|
+
</svg>
|
|
24
|
+
`;
|
|
25
|
+
/* ── The four levels ───────────────────────────────────────────────────── */
|
|
26
|
+
/** Person — a head over a rounded body, the stencil's own silhouette. */
|
|
27
|
+
export const c4PersonIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
28
|
+
<circle cx="12" cy="7" r="3.2" stroke="currentColor" stroke-width="1.6"/>
|
|
29
|
+
<rect x="5.5" y="12" width="13" height="8" rx="4" stroke="currentColor" stroke-width="1.6"/>
|
|
30
|
+
</svg>`;
|
|
31
|
+
/**
|
|
32
|
+
* Person (external) — the same silhouette, DASHED. The stencil greys an
|
|
33
|
+
* external element out; a monochrome glyph has no grey to spend, so the dash is
|
|
34
|
+
* what carries "somebody else owns this" here.
|
|
35
|
+
*/
|
|
36
|
+
export const c4PersonExtIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
37
|
+
<circle cx="12" cy="7" r="3.2" stroke="currentColor" stroke-width="1.6" stroke-dasharray="2.6 2"/>
|
|
38
|
+
<rect x="5.5" y="12" width="13" height="8" rx="4" stroke="currentColor" stroke-width="1.6" stroke-dasharray="2.6 2"/>
|
|
39
|
+
</svg>`;
|
|
40
|
+
/** Software system — a plain rounded rectangle, which is what C4 draws. */
|
|
41
|
+
export const c4SystemIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
42
|
+
<rect x="3.5" y="6" width="17" height="12" rx="2.5" stroke="currentColor" stroke-width="1.6"/>
|
|
43
|
+
</svg>`;
|
|
44
|
+
/** Software system (external) — the same rectangle, dashed. */
|
|
45
|
+
export const c4SystemExtIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
46
|
+
<rect x="3.5" y="6" width="17" height="12" rx="2.5" stroke="currentColor" stroke-width="1.6" stroke-dasharray="2.6 2"/>
|
|
47
|
+
</svg>`;
|
|
48
|
+
/** Container — a box INSIDE a box: one level in from the system. */
|
|
49
|
+
export const c4ContainerIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
50
|
+
<rect x="2.5" y="4.5" width="19" height="15" rx="2.5" stroke="currentColor" stroke-width="1.6"/>
|
|
51
|
+
<rect x="6.5" y="8.5" width="11" height="7" rx="1.8" stroke="currentColor" stroke-width="1.4"/>
|
|
52
|
+
</svg>`;
|
|
53
|
+
/** Component — the UML component: a box with two tabs down its leading edge. */
|
|
54
|
+
export const c4ComponentIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
55
|
+
<rect x="6" y="5.5" width="14.5" height="13" rx="1.8" stroke="currentColor" stroke-width="1.6"/>
|
|
56
|
+
<rect x="3.5" y="8" width="5" height="3" stroke="currentColor" stroke-width="1.3"/>
|
|
57
|
+
<rect x="3.5" y="13" width="5" height="3" stroke="currentColor" stroke-width="1.3"/>
|
|
58
|
+
</svg>`;
|
|
59
|
+
/* ── The container flavours the stencil gives a silhouette of their own ─── */
|
|
60
|
+
/** Database — a cylinder. */
|
|
61
|
+
export const c4DatabaseIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
62
|
+
<path d="M4.5 7 V17 C4.5 18.4 8 19.5 12 19.5 C16 19.5 19.5 18.4 19.5 17 V7" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/>
|
|
63
|
+
<ellipse cx="12" cy="7" rx="7.5" ry="2.5" stroke="currentColor" stroke-width="1.6"/>
|
|
64
|
+
</svg>`;
|
|
65
|
+
/** Mobile app — a phone: a tall bezel with a speaker slot and a home bar. */
|
|
66
|
+
export const c4MobileIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
67
|
+
<rect x="7" y="2.5" width="10" height="19" rx="2.2" stroke="currentColor" stroke-width="1.6"/>
|
|
68
|
+
<path d="M10.5 5.2 H13.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/>
|
|
69
|
+
<path d="M10 18.8 H14" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/>
|
|
70
|
+
</svg>`;
|
|
71
|
+
/** Web browser — a window with a chrome band and its three dots. */
|
|
72
|
+
export const c4BrowserIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
73
|
+
<rect x="2.5" y="4.5" width="19" height="15" rx="2.2" stroke="currentColor" stroke-width="1.6"/>
|
|
74
|
+
<path d="M2.5 9 H21.5" stroke="currentColor" stroke-width="1.4"/>
|
|
75
|
+
<circle cx="5.6" cy="6.8" r="0.85" fill="currentColor"/>
|
|
76
|
+
<circle cx="8.3" cy="6.8" r="0.85" fill="currentColor"/>
|
|
77
|
+
<circle cx="11" cy="6.8" r="0.85" fill="currentColor"/>
|
|
78
|
+
</svg>`;
|
|
79
|
+
/* ── The connecting object ─────────────────────────────────────────────── */
|
|
80
|
+
/** Relationship — a dashed arrow with a filled head, exactly as it is drawn. */
|
|
81
|
+
export const c4RelationshipIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
82
|
+
<path d="M3 12 H15.5" stroke="currentColor" stroke-width="1.8" stroke-dasharray="3 2.6" stroke-linecap="round"/>
|
|
83
|
+
<path d="M14.5 8.2 L21 12 L14.5 15.8 Z" fill="currentColor"/>
|
|
84
|
+
</svg>`;
|
|
85
|
+
/* ── The two frames ────────────────────────────────────────────────────── */
|
|
86
|
+
/** C4 board — a titled card with two elements and the arrow between them. */
|
|
87
|
+
export const c4BoardIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
88
|
+
<rect x="2.5" y="3.5" width="19" height="17" rx="2" stroke="currentColor" stroke-width="1.6"/>
|
|
89
|
+
<path d="M5.5 7 H12" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/>
|
|
90
|
+
<rect x="5.5" y="10" width="6" height="4" rx="1" stroke="currentColor" stroke-width="1.3"/>
|
|
91
|
+
<rect x="13" y="14" width="6" height="4" rx="1" stroke="currentColor" stroke-width="1.3"/>
|
|
92
|
+
<path d="M11.5 13 L13.5 14.6" stroke="currentColor" stroke-width="1.2" stroke-dasharray="2 1.6"/>
|
|
93
|
+
</svg>`;
|
|
94
|
+
/** System boundary — a dashed rectangle, and nothing inside it to see. */
|
|
95
|
+
export const c4SystemBoundaryIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
96
|
+
<rect x="2.5" y="4.5" width="19" height="15" rx="2" stroke="currentColor" stroke-width="1.6" stroke-dasharray="3.2 2.4"/>
|
|
97
|
+
</svg>`;
|
|
98
|
+
/**
|
|
99
|
+
* Container boundary — the same dashed rectangle, one level IN: a second,
|
|
100
|
+
* smaller frame drawn inside it. The pair reads the way the two boundaries
|
|
101
|
+
* relate on the canvas, which is the only difference the notation makes between
|
|
102
|
+
* them.
|
|
103
|
+
*/
|
|
104
|
+
export const c4ContainerBoundaryIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
105
|
+
<rect x="2.5" y="4.5" width="19" height="15" rx="2" stroke="currentColor" stroke-width="1.6" stroke-dasharray="3.2 2.4"/>
|
|
106
|
+
<rect x="6.5" y="8" width="11" height="8" rx="1.6" stroke="currentColor" stroke-width="1.3" stroke-dasharray="2.4 1.8"/>
|
|
107
|
+
</svg>`;
|
|
108
|
+
/* ── The gesture that takes a board away ───────────────────────────────── */
|
|
109
|
+
/**
|
|
110
|
+
* Export as mermaid — a sheet with a page-corner fold and an arrow leaving it.
|
|
111
|
+
*
|
|
112
|
+
* Deliberately the SAME drawing as `bpmnExportXmlIcon`, down to the path data:
|
|
113
|
+
* it is the same gesture (take this board away as a file), and one gesture takes
|
|
114
|
+
* one glyph across the library. What it is not is a mermaid logo — the file
|
|
115
|
+
* format is what the menu LINE says, and a brand mark in a monochrome outline
|
|
116
|
+
* row would be the one icon nobody could recolour.
|
|
117
|
+
*
|
|
118
|
+
* Redrawn here rather than imported because BPMN's icons are that package's
|
|
119
|
+
* private module: a cross-framework import for one path would tie the C4 pack's
|
|
120
|
+
* build to BPMN's, and the two are meant to ship separately.
|
|
121
|
+
*/
|
|
122
|
+
export const c4ExportMermaidIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
123
|
+
<path d="M13.5 3.5H7a1.5 1.5 0 0 0-1.5 1.5v14A1.5 1.5 0 0 0 7 20.5h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
124
|
+
<path d="M13.5 3.5 18.5 8.5V12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
125
|
+
<path d="M16 20.5v-6M13.5 18l2.5 2.5 2.5-2.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
126
|
+
</svg>`;
|
|
127
|
+
/**
|
|
128
|
+
* Every command glyph, keyed by its `iconKey`.
|
|
129
|
+
*
|
|
130
|
+
* Registered together with the commands themselves
|
|
131
|
+
* (`CommandExtension(c4Commands, c4CommandIcons)`), so a key a descriptor names
|
|
132
|
+
* and this record does not hold renders as nothing — which is what the icon
|
|
133
|
+
* coverage test in `__tests__/commands.unit.spec.ts` exists to catch.
|
|
134
|
+
*
|
|
135
|
+
* {@link c4ExportMermaidIcon} is deliberately NOT here and is added to
|
|
136
|
+
* `c4CommandIcons` in `commands.ts` instead: this record is the TOOLBOX — the
|
|
137
|
+
* thirteen glyphs of things C4 DRAWS — and an export draws nothing.
|
|
138
|
+
*
|
|
139
|
+
* The legend's glyph is in neither, because the legend is no longer a command at
|
|
140
|
+
* all: it is `dddLegendIcon`, referenced straight from `config.ts` by the button
|
|
141
|
+
* that is now the only way to reach it (PO arbitration, 27/08/2026).
|
|
142
|
+
*/
|
|
143
|
+
export const C4_TOOLBOX_ICONS = {
|
|
144
|
+
'c4.person': c4PersonIcon,
|
|
145
|
+
'c4.person.external': c4PersonExtIcon,
|
|
146
|
+
'c4.system': c4SystemIcon,
|
|
147
|
+
'c4.system.external': c4SystemExtIcon,
|
|
148
|
+
'c4.container': c4ContainerIcon,
|
|
149
|
+
'c4.component': c4ComponentIcon,
|
|
150
|
+
'c4.database': c4DatabaseIcon,
|
|
151
|
+
'c4.mobile': c4MobileIcon,
|
|
152
|
+
'c4.browser': c4BrowserIcon,
|
|
153
|
+
'c4.relationship': c4RelationshipIcon,
|
|
154
|
+
'c4.board': c4BoardIcon,
|
|
155
|
+
'c4.boundary.system': c4SystemBoundaryIcon,
|
|
156
|
+
'c4.boundary.container': c4ContainerBoundaryIcon,
|
|
157
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const c4SeniorTool: import("@formicoidea/labre-core/store").ExtensionType;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SeniorToolExtension } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
|
|
2
|
+
import { html } from 'lit';
|
|
3
|
+
export const c4SeniorTool = SeniorToolExtension('c4', ({ block }) => {
|
|
4
|
+
return {
|
|
5
|
+
name: 'C4 model',
|
|
6
|
+
labelKey: 'com.labre.framework.c4',
|
|
7
|
+
content: html `<edgeless-c4-senior-button
|
|
8
|
+
.edgeless=${block}
|
|
9
|
+
></edgeless-c4-senior-button>`,
|
|
10
|
+
};
|
|
11
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type TranslationKeyManifestEntry } from '@formicoidea/labre-core/std';
|
|
2
|
+
/**
|
|
3
|
+
* THIS framework's contribution to the translation-key manifest — every
|
|
4
|
+
* `com.labre.*` key C4 can hand to `TranslationProvider.t`, derived from the
|
|
5
|
+
* very declarations the editor registers (never restated).
|
|
6
|
+
*
|
|
7
|
+
* The contribution ships WITH the framework, exactly as BPMN's does: in the
|
|
8
|
+
* bundled distribution `@formicoidea/labre-framework-c4` carries it, and a host
|
|
9
|
+
* composes it into its catalogue the same way it already composes `c4Commands`
|
|
10
|
+
* into the command registry. See `packages/affine/all/src/translations.ts`.
|
|
11
|
+
*
|
|
12
|
+
* The two BACKGROUND declarations are walked even though neither carries a
|
|
13
|
+
* `labelKey` today: both frames write the user's own words and have no
|
|
14
|
+
* vocabulary to fall back to (`background.ts`). Walking them costs nothing and
|
|
15
|
+
* means the day one of them gains a declared label the manifest already names
|
|
16
|
+
* it — which is the whole reason these lists are derived rather than written.
|
|
17
|
+
*/
|
|
18
|
+
export declare const c4TranslationEntries: TranslationKeyManifestEntry[];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { collectTranslationKeys, commandTranslationEntries, mergeTranslationEntries, } from '@formicoidea/labre-core/std';
|
|
2
|
+
import { C4_BOARD_BACKGROUND, C4_BOUNDARY_BACKGROUND } from './background.js';
|
|
3
|
+
import { c4Commands } from './commands.js';
|
|
4
|
+
import { C4_BOARD_LEVEL_MENU } from './levels.js';
|
|
5
|
+
import { C4_PROFILES } from './profiles.js';
|
|
6
|
+
import { C4_ROLES } from './roles.js';
|
|
7
|
+
import { C4_RULES } from './rules.js';
|
|
8
|
+
/**
|
|
9
|
+
* THIS framework's contribution to the translation-key manifest — every
|
|
10
|
+
* `com.labre.*` key C4 can hand to `TranslationProvider.t`, derived from the
|
|
11
|
+
* very declarations the editor registers (never restated).
|
|
12
|
+
*
|
|
13
|
+
* The contribution ships WITH the framework, exactly as BPMN's does: in the
|
|
14
|
+
* bundled distribution `@formicoidea/labre-framework-c4` carries it, and a host
|
|
15
|
+
* composes it into its catalogue the same way it already composes `c4Commands`
|
|
16
|
+
* into the command registry. See `packages/affine/all/src/translations.ts`.
|
|
17
|
+
*
|
|
18
|
+
* The two BACKGROUND declarations are walked even though neither carries a
|
|
19
|
+
* `labelKey` today: both frames write the user's own words and have no
|
|
20
|
+
* vocabulary to fall back to (`background.ts`). Walking them costs nothing and
|
|
21
|
+
* means the day one of them gains a declared label the manifest already names
|
|
22
|
+
* it — which is the whole reason these lists are derived rather than written.
|
|
23
|
+
*/
|
|
24
|
+
export const c4TranslationEntries = mergeTranslationEntries(commandTranslationEntries(c4Commands), collectTranslationKeys('role', C4_ROLES), collectTranslationKeys('background', [
|
|
25
|
+
C4_BOARD_BACKGROUND,
|
|
26
|
+
C4_BOUNDARY_BACKGROUND,
|
|
27
|
+
// The LEVEL a board declares, and the words the picker offers it under.
|
|
28
|
+
//
|
|
29
|
+
// Filed under `background` with the two declarations above, and it is the
|
|
30
|
+
// honest bucket rather than a convenient one: `level` is a prop of the
|
|
31
|
+
// board BACKGROUND, these are the names of the values it can take, and
|
|
32
|
+
// the table is walked exactly as the two declarations beside it are —
|
|
33
|
+
// nothing is restated in `affine/all`, so a key added to the picker
|
|
34
|
+
// reaches a host's catalogue by construction.
|
|
35
|
+
C4_BOARD_LEVEL_MENU,
|
|
36
|
+
]),
|
|
37
|
+
// AFTER the two above, and the order is load-bearing: a rule carries its
|
|
38
|
+
// framework's `roles` and, for `c4.person-in-boundary`, the boundary's own
|
|
39
|
+
// declaration, so walking the rules reaches keys those two lists already
|
|
40
|
+
// named. `mergeTranslationEntries` keeps the FIRST occurrence, which is what
|
|
41
|
+
// makes each key report the source it actually comes from.
|
|
42
|
+
collectTranslationKeys('rule', C4_RULES), collectTranslationKeys('profile', C4_PROFILES));
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import type { C4NodeKind } from '@formicoidea/labre-core/model';
|
|
2
|
+
/**
|
|
3
|
+
* The middle tier of a C4 element's label — `[Person]`, `[Software System]`,
|
|
4
|
+
* `[Container: Java]` — SEMI-DERIVED: the word comes from the kind, the
|
|
5
|
+
* technology from the author.
|
|
6
|
+
*
|
|
7
|
+
* ## Semi-derived, and where the line actually lives
|
|
8
|
+
*
|
|
9
|
+
* The line is a real canvas TEXT element now (PO recette, 28/08/2026): a C4
|
|
10
|
+
* component is the shape and its own words, grouped, and every tier is edited in
|
|
11
|
+
* place like any other text on the canvas rather than typed into a form. So the
|
|
12
|
+
* string IS stored — but only half of it is the author's. The bracketed word is
|
|
13
|
+
* the notation's and comes from `kind`, which is what the renderer paints and
|
|
14
|
+
* what the exporter maps; letting an author retype it would be letting the words
|
|
15
|
+
* disagree with the picture.
|
|
16
|
+
*
|
|
17
|
+
* {@link normalizeC4TypeLine} is what keeps the halves apart. It runs when an
|
|
18
|
+
* edit COMMITS, reads whatever was typed for the one thing the notation leaves
|
|
19
|
+
* to the author — the technology — and writes the canonical line back. Type
|
|
20
|
+
* `Java` and the line becomes `[Container: Java]`; type `[Database: Java]` on a
|
|
21
|
+
* cylinder and it becomes `[Container: Java]`, because a database IS a container
|
|
22
|
+
* and the stencil says so.
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* The base word each kind is announced by, verbatim from the stencil's own
|
|
26
|
+
* `<desc>` strings (`C4Model_default.svg`, the PO's reference model).
|
|
27
|
+
*
|
|
28
|
+
* Two readings are worth spelling out, because both look like mistakes:
|
|
29
|
+
*
|
|
30
|
+
* - `database` says **Container**, not "Database". The stencil labels the
|
|
31
|
+
* cylinder `[Container: technology]` exactly as it labels the plain box: a
|
|
32
|
+
* database is a CONTAINER, and the cylinder is a picture of one, not a fourth
|
|
33
|
+
* level. (The mermaid export still emits `ContainerDb` — that is the one
|
|
34
|
+
* specialisation mermaid's own grammar draws, and it is a different question
|
|
35
|
+
* from what the box says on the canvas.)
|
|
36
|
+
* - an `-ext` variant says the same word as the kind it is external to. What
|
|
37
|
+
* "external" changes is the COLOUR — grey — and the stencil's gray sheet
|
|
38
|
+
* carries the identical `[Person]` / `[Software System]` wording.
|
|
39
|
+
*
|
|
40
|
+
* `Record<C4NodeKind, …>` and therefore compile-total: a kind added to the model
|
|
41
|
+
* without a word to announce it fails the build here.
|
|
42
|
+
*/
|
|
43
|
+
export declare const C4_TYPE_WORD: Record<C4NodeKind, string>;
|
|
44
|
+
/**
|
|
45
|
+
* The type line as it is drawn, brackets included.
|
|
46
|
+
*
|
|
47
|
+
* The technology is appended only when the author actually set one — an empty
|
|
48
|
+
* box, or one holding nothing but spaces, is not a technology and must not
|
|
49
|
+
* produce a dangling `[Container: ]`. Whitespace runs collapse for the same
|
|
50
|
+
* reason they do in the mermaid sanitizer: the line is one line.
|
|
51
|
+
*
|
|
52
|
+
* Pure, total and `std`-free, so the renderer, the exporter and a test can all
|
|
53
|
+
* ask the same question and get the same answer.
|
|
54
|
+
*/
|
|
55
|
+
export declare function c4TypeLine(kind: C4NodeKind, technology?: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* The technology an author stated in a type line, whatever shape they left it
|
|
58
|
+
* in — `''` when they stated none.
|
|
59
|
+
*
|
|
60
|
+
* Total over every string, which is what it has to be: this reads a canvas TEXT
|
|
61
|
+
* element somebody edited in place, so its input is not a field with a grammar,
|
|
62
|
+
* it is whatever was typed. Every one of these is a line this has met:
|
|
63
|
+
*
|
|
64
|
+
* ```
|
|
65
|
+
* [Container: Java] → Java the canonical form
|
|
66
|
+
* Container: Java → Java brackets deleted while editing
|
|
67
|
+
* Java → Java the whole line selected and retyped
|
|
68
|
+
* [Container] → '' the word alone: no technology stated
|
|
69
|
+
* [Container: ] → '' the technology deleted, brackets kept
|
|
70
|
+
* https://x/docs → https://x/docs a colon that is NOT a prefix
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* Pure and `std`-free, so the commit hook, the exporter and a test all read the
|
|
74
|
+
* same line the same way.
|
|
75
|
+
*
|
|
76
|
+
* It deliberately does NOT know about the creation placeholder: a node created
|
|
77
|
+
* and never touched carries `[Container: technology]`, and reading that as "no
|
|
78
|
+
* technology" here would make a focus-and-blur silently rewrite it to
|
|
79
|
+
* `[Container]` — the normalizer would eat the stencil's own prompt. The
|
|
80
|
+
* placeholder is a question for whoever asks what the element STATES, which is
|
|
81
|
+
* the exporter, and it is answered there.
|
|
82
|
+
*/
|
|
83
|
+
export declare function technologyOfTypeLine(text: string | null | undefined): string;
|
|
84
|
+
/**
|
|
85
|
+
* A type line as it must be STORED, whatever was typed into it.
|
|
86
|
+
*
|
|
87
|
+
* The semi-derived rule of the PO's recette, in one function: read the one half
|
|
88
|
+
* the author owns, write the whole line back from the kind. `[Person: Java]`
|
|
89
|
+
* typed on a container becomes `[Container: Java]`, a bare `Java` becomes
|
|
90
|
+
* `[Container: Java]`, and an emptied line becomes `[Container]`.
|
|
91
|
+
*
|
|
92
|
+
* Idempotent by construction — `normalize(normalize(x)) === normalize(x)` —
|
|
93
|
+
* which is what lets it run on every commit without a guard.
|
|
94
|
+
*/
|
|
95
|
+
export declare function normalizeC4TypeLine(kind: C4NodeKind, rawText: string | null | undefined): string;
|
|
96
|
+
/**
|
|
97
|
+
* The word a fresh type line prompts the author with, in the technology's slot.
|
|
98
|
+
*
|
|
99
|
+
* The stencil's own: its container reads `[Container: technology]` before
|
|
100
|
+
* anybody fills it in. A prompt rather than a value — see
|
|
101
|
+
* {@link C4_TYPE_PLACEHOLDER}.
|
|
102
|
+
*/
|
|
103
|
+
export declare const TYPE_TECHNOLOGY_PLACEHOLDER = "technology";
|
|
104
|
+
/**
|
|
105
|
+
* Which kinds announce a technology in their type line AT ALL.
|
|
106
|
+
*
|
|
107
|
+
* The notation's own division and not mermaid's, though the two agree: a person
|
|
108
|
+
* is not built with a technology and a software system's is a level down, so
|
|
109
|
+
* both are written `[Person]` / `[Software System]` full stop. Every container
|
|
110
|
+
* — the cylinder, the phone and the browser window included — and every
|
|
111
|
+
* component carries `[Word: technology]`, because at those two levels "what is
|
|
112
|
+
* it built with" is the question the diagram exists to answer.
|
|
113
|
+
*
|
|
114
|
+
* This decides the PLACEHOLDER only. An author who types a technology onto a
|
|
115
|
+
* person gets it drawn, exactly as `c4TypeLine` has always drawn it: the
|
|
116
|
+
* notation is a prompt here, not a validator.
|
|
117
|
+
*/
|
|
118
|
+
export declare const C4_TYPE_TAKES_TECHNOLOGY: Record<C4NodeKind, boolean>;
|
|
119
|
+
/**
|
|
120
|
+
* The type line a freshly created element is born carrying, per kind.
|
|
121
|
+
*
|
|
122
|
+
* Every tier of a C4 component exists from the moment it is drawn (PO
|
|
123
|
+
* arbitration, 28/08/2026), so the author meets three lines of stencil rather
|
|
124
|
+
* than a box and two invisible slots they have to be told about. What they meet
|
|
125
|
+
* is what the official stencil shows: `[Person]`, `[Software System]`,
|
|
126
|
+
* `[Container: technology]`, `[Component: technology]`.
|
|
127
|
+
*
|
|
128
|
+
* A PROMPT, not a value: {@link C4_TYPE_PLACEHOLDER} is what the exporter
|
|
129
|
+
* compares against to decide the author has stated nothing yet, so an untouched
|
|
130
|
+
* element exports as `Container(alias, "Container")` rather than as one built
|
|
131
|
+
* with a technology literally called "technology".
|
|
132
|
+
*/
|
|
133
|
+
export declare const C4_TYPE_PLACEHOLDER: Record<C4NodeKind, string>;
|
|
134
|
+
/**
|
|
135
|
+
* The type line a component should carry once its shape has morphed from `from`
|
|
136
|
+
* to `to` — or `null` when the line is the AUTHOR's and must not be touched.
|
|
137
|
+
*
|
|
138
|
+
* ## Why a morph has to ask this at all
|
|
139
|
+
*
|
|
140
|
+
* The bracketed word is derived from `kind` (see the head of this file), so a
|
|
141
|
+
* shape that becomes a component while its caption still reads `[Container]` is
|
|
142
|
+
* a picture contradicting its own words. But the caption is a canvas TEXT
|
|
143
|
+
* element an architect may have typed anything into, and rewriting that would
|
|
144
|
+
* be the morph taking away something nobody asked it to touch. So the rule is
|
|
145
|
+
* the narrowest one that fixes the contradiction:
|
|
146
|
+
*
|
|
147
|
+
* - the SOURCE kind's untouched prompt (`[Container: technology]`) becomes the
|
|
148
|
+
* TARGET's own prompt — `[Person]` on the way to a person, not `[Person:
|
|
149
|
+
* technology]`, because a person is not built with a technology
|
|
150
|
+
* ({@link C4_TYPE_TAKES_TECHNOLOGY});
|
|
151
|
+
* - a line that is exactly what the source kind DERIVES — `[Container: React]`,
|
|
152
|
+
* the form {@link normalizeC4TypeLine} leaves behind after every edit — is
|
|
153
|
+
* re-derived for the target, technology and all: `[Component: React]`;
|
|
154
|
+
* - anything else is the author's and comes back `null`. A line reading
|
|
155
|
+
* `see ADR 0042`, or one mid-edit, survives the morph verbatim.
|
|
156
|
+
*
|
|
157
|
+
* The placeholder is tested FIRST and not folded into the second branch, which
|
|
158
|
+
* would find it too: `technologyOfTypeLine('[Container: technology]')` is the
|
|
159
|
+
* literal word `technology`, and carrying it across would hand a person the
|
|
160
|
+
* `[Person: technology]` no stencil ever draws.
|
|
161
|
+
*
|
|
162
|
+
* ## Inert on today's families, and kept anyway
|
|
163
|
+
*
|
|
164
|
+
* Every family declared in `./morph.ts` shares one {@link C4_TYPE_WORD} — all
|
|
165
|
+
* four containers say `Container`, both people say `Person`, both systems say
|
|
166
|
+
* `Software System` — and shares its {@link C4_TYPE_TAKES_TECHNOLOGY} answer
|
|
167
|
+
* too, so on the shipped table this function returns the line it was given and
|
|
168
|
+
* nothing visibly happens. That is a property of the FAMILIES, which are data
|
|
169
|
+
* and grow by declaration, not of the notation: the moment a family gains a
|
|
170
|
+
* member that announces itself differently, the caption follows the shape
|
|
171
|
+
* without anyone being prompted to remember it should.
|
|
172
|
+
*
|
|
173
|
+
* Pure, total and `std`-free, like everything else in this file.
|
|
174
|
+
*/
|
|
175
|
+
export declare function c4MorphedTypeLine(from: C4NodeKind, to: C4NodeKind, rawText: string | null | undefined): string | null;
|