likec4 1.59.4 → 1.61.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/README.md +2 -0
- package/__app__/codegen/react.mjs +4 -10
- package/__app__/codegen/webcomponent.mjs +6 -131
- package/__app__/index.html +15 -15
- package/__app__/src/aichat/index.mjs +11 -7
- package/__app__/src/chunks/AIChat.mjs +1355 -739
- package/__app__/src/chunks/ErrorComponent.mjs +444 -0
- package/__app__/src/chunks/Header.mjs +269 -0
- package/__app__/src/chunks/ViewReact.mjs +438 -0
- package/__app__/src/chunks/find.mjs +38 -0
- package/__app__/src/chunks/hooks.mjs +158 -472
- package/__app__/src/chunks/libs/@tabler/icons-react.mjs +340 -0
- package/__app__/src/chunks/libs/@tanstack-ai.mjs +11841 -1417
- package/__app__/src/chunks/libs/@tanstack.mjs +5110 -2404
- package/__app__/src/chunks/libs/fast-equals.mjs +507 -214
- package/__app__/src/chunks/libs/html-to-image.mjs +613 -0
- package/__app__/src/chunks/libs/nanostores.mjs +170 -0
- package/__app__/src/chunks/libs/react-resizable-panels.mjs +2792 -0
- package/__app__/src/chunks/react.mjs +22 -0
- package/__app__/src/chunks/rolldown-runtime.mjs +16 -29
- package/__app__/src/chunks/router.mjs +106 -0
- package/__app__/src/chunks/scope.mjs +106 -0
- package/__app__/src/chunks/searchParams.mjs +29 -0
- package/__app__/src/chunks/single-index.mjs +465 -0
- package/__app__/src/chunks/styled-system.mjs +1826 -2528
- package/__app__/src/chunks/useAsync.mjs +69 -0
- package/__app__/src/chunks/useSyncedRef.mjs +16 -0
- package/__app__/src/components/ColorSchemeToggle.mjs +124 -0
- package/__app__/src/components/CopyToClipboard.mjs +53 -0
- package/__app__/src/components/ErrorComponent.mjs +1 -0
- package/__app__/src/components/NavigationPanel.mjs +63 -0
- package/__app__/src/components/NotFound.mjs +155 -0
- package/__app__/src/components/ViewOutlet.mjs +9 -0
- package/__app__/src/components/model-diff/CompareModelProvider.mjs +44 -0
- package/__app__/src/components/model-diff/ModelDiffPanel.mjs +179 -0
- package/__app__/src/components/model-diff/compare-model.mjs +76 -0
- package/__app__/src/components/model-diff/state.mjs +45 -0
- package/__app__/src/components/search/OverviewSearch.mjs +92 -0
- package/__app__/src/components/search/OverviewSearchAdapter.mjs +94 -0
- package/__app__/src/components/sidebar/DiagramTree.css.mjs +48 -0
- package/__app__/src/components/sidebar/DiagramsTree.mjs +304 -0
- package/__app__/src/components/sidebar/Drawer.mjs +178 -0
- package/__app__/src/components/sidebar/SidebarBurger.mjs +28 -0
- package/__app__/src/components/sidebar/data.mjs +94 -0
- package/__app__/src/components/sidebar/state.mjs +16 -0
- package/__app__/src/components/view-page/Header.mjs +1 -0
- package/__app__/src/components/view-page/SelectProject.mjs +258 -0
- package/__app__/src/components/view-page/ShareModal.mjs +111 -0
- package/__app__/src/components/view-page/share-modal/AlertLocalhost.mjs +31 -0
- package/__app__/src/components/view-page/share-modal/CopyButtonChild.mjs +36 -0
- package/__app__/src/components/view-page/share-modal/EmbedPanel.mjs +100 -0
- package/__app__/src/components/view-page/share-modal/WebcomponentsPanel.mjs +264 -0
- package/__app__/src/components/view-page/state.mjs +17 -0
- package/__app__/src/context/LikeC4CustomizationContext.mjs +26 -0
- package/__app__/src/context/LikeC4IconRendererContext.mjs +29 -0
- package/__app__/src/context/LikeC4ModelContext.mjs +34 -0
- package/__app__/src/context/LikeC4ProjectsContext.mjs +40 -0
- package/__app__/src/context/ModelDiffsContext.mjs +33 -0
- package/__app__/src/context/safeCtx.mjs +14 -0
- package/__app__/src/fonts.css +112 -1
- package/__app__/src/hooks.mjs +1 -0
- package/__app__/src/main.mjs +6 -29151
- package/__app__/src/pages/EmbedPage.mjs +93 -0
- package/__app__/src/pages/ExportPage.mjs +691 -0
- package/__app__/src/pages/ProjectsOverview.mjs +23 -0
- package/__app__/src/pages/ViewAsD2.mjs +105 -0
- package/__app__/src/pages/ViewAsDot.mjs +65 -0
- package/__app__/src/pages/ViewAsMmd.mjs +109 -0
- package/__app__/src/pages/ViewAsPuml.mjs +105 -0
- package/__app__/src/pages/ViewEditor.mjs +220 -0
- package/__app__/src/pages/ViewReact.mjs +1 -0
- package/__app__/src/pages/export-layout.mjs +95 -0
- package/__app__/src/pages/export-page-params.mjs +9 -0
- package/__app__/src/pages/styles.css.mjs +23 -0
- package/__app__/src/routeTree.gen.mjs +105 -0
- package/__app__/src/router.mjs +1 -0
- package/__app__/src/routes/__root.mjs +65 -0
- package/__app__/src/routes/index.css.mjs +29 -0
- package/__app__/src/routes/index.mjs +32 -0
- package/__app__/src/routes/project._projectId/-components.mjs +100 -0
- package/__app__/src/routes/project._projectId/embed._viewId.mjs +5 -0
- package/__app__/src/routes/project._projectId/export._viewId.mjs +24 -0
- package/__app__/src/routes/project._projectId/index.mjs +14 -0
- package/__app__/src/routes/project._projectId/route.mjs +93 -0
- package/__app__/src/routes/project._projectId/view._viewId.d2.mjs +34 -0
- package/__app__/src/routes/project._projectId/view._viewId.dot.mjs +41 -0
- package/__app__/src/routes/project._projectId/view._viewId.index.mjs +7 -0
- package/__app__/src/routes/project._projectId/view._viewId.mjs +23 -0
- package/__app__/src/routes/project._projectId/view._viewId.mmd.mjs +39 -0
- package/__app__/src/routes/project._projectId/view._viewId.puml.mjs +34 -0
- package/__app__/src/routes/projects.mjs +36 -0
- package/__app__/src/routes/single-index.mjs +1 -0
- package/__app__/src/routes/webcomponent._.mjs +94 -0
- package/__app__/src/style.css +18497 -1
- package/config/schema.json +146 -97
- package/dist/app/render-view-client.css +1 -1
- package/dist/app/render-view-client.js +394 -238
- package/dist/chunks/enableServer.mjs +1 -1
- package/dist/chunks/filenames.mjs +25 -17
- package/dist/chunks/generate-likec4.mjs +5 -0
- package/dist/chunks/index.d.mts +255 -194
- package/dist/chunks/index2.d.mts +8246 -3610
- package/dist/chunks/libs/@chenglou/pretext.mjs +9 -0
- package/dist/chunks/libs/@chevrotain/gast.mjs +27 -1
- package/dist/chunks/libs/@chevrotain/regexp-to-ast.mjs +81 -9
- package/dist/chunks/libs/@logtape/logtape.mjs +5 -4
- package/dist/chunks/libs/@lume/kiwi.mjs +1 -1
- package/dist/chunks/libs/@ts-graphviz/common.d.mts +2 -4
- package/dist/chunks/libs/@ts-graphviz/core.mjs +1 -1
- package/dist/chunks/libs/birpc.mjs +1 -1
- package/dist/chunks/libs/chevrotain-allstar.mjs +2 -2
- package/dist/chunks/libs/chevrotain.mjs +88 -36
- package/dist/chunks/libs/clone.mjs +1 -0
- package/dist/chunks/libs/eventemitter3.mjs +1 -1
- package/dist/chunks/libs/fast-equals.mjs +1 -0
- package/dist/chunks/libs/fontkit.mjs +1 -0
- package/dist/chunks/libs/json5.mjs +4 -4
- package/dist/chunks/libs/langium.d.mts +6707 -6715
- package/dist/chunks/libs/langium.mjs +16 -24
- package/dist/chunks/libs/merge-error-cause.mjs +1 -1
- package/dist/chunks/libs/p-limit.mjs +1 -0
- package/dist/chunks/libs/p-queue.mjs +1 -1
- package/dist/chunks/libs/package-manager-detector.mjs +1 -1
- package/dist/chunks/libs/pako.mjs +1 -1
- package/dist/chunks/libs/pathe.mjs +1 -1
- package/dist/chunks/libs/pretty-ms.mjs +1 -1
- package/dist/chunks/libs/remeda.mjs +1 -1
- package/dist/chunks/libs/ufo.mjs +1 -1
- package/dist/chunks/libs/unstorage.mjs +1 -1
- package/dist/chunks/libs/which.mjs +1 -1
- package/dist/chunks/node.mjs +111 -77
- package/dist/chunks/rolldown-runtime.mjs +1 -1
- package/dist/chunks/sequence-view.mjs +1 -1
- package/dist/chunks/vite-plugin.mjs +185 -166
- package/dist/cli/index.mjs +254 -1306
- package/dist/config/index.d.mts +66 -5
- package/dist/config/index.mjs +1 -1
- package/dist/generators/likec4.d.mts +6530 -0
- package/dist/generators/likec4.mjs +1 -0
- package/dist/index.d.mts +2 -4
- package/dist/model/index.d.mts +0 -7
- package/dist/vite-plugin/index.d.mts +83 -58
- package/dist/vite-plugin/index.mjs +1 -1
- package/dist/vite-plugin/internal/chunks/rolldown-runtime.mjs +8 -0
- package/dist/vite-plugin/internal/index.d.mts +92 -17
- package/dist/vite-plugin/internal/index.mjs +225 -126
- package/generators/likec4/package.json +4 -0
- package/package.json +134 -122
- package/react/index.d.mts +7496 -26659
- package/react/index.mjs +533 -63936
- package/react/rolldown-runtime-CfRud99p.js +1 -0
- package/skills/likec4-dsl/SKILL.md +474 -0
- package/skills/likec4-dsl/evals/evals-public.json +207 -0
- package/skills/likec4-dsl/evals/grading-spec.json +603 -0
- package/skills/likec4-dsl/references/bridge-leanix-drawio.md +42 -0
- package/skills/likec4-dsl/references/cli.md +168 -0
- package/skills/likec4-dsl/references/configuration.md +266 -0
- package/skills/likec4-dsl/references/deployment.md +160 -0
- package/skills/likec4-dsl/references/diffs.md +52 -0
- package/skills/likec4-dsl/references/dynamic-views.md +455 -0
- package/skills/likec4-dsl/references/examples.md +370 -0
- package/skills/likec4-dsl/references/identifier-validity.md +90 -0
- package/skills/likec4-dsl/references/include-predicates-wildcards.md +180 -0
- package/skills/likec4-dsl/references/model.md +182 -0
- package/skills/likec4-dsl/references/predicates.md +123 -0
- package/skills/likec4-dsl/references/relationships-bidirectional.md +176 -0
- package/skills/likec4-dsl/references/specification.md +79 -0
- package/skills/likec4-dsl/references/style-tokens-colors.md +150 -0
- package/skills/likec4-dsl/references/troubleshooting.md +101 -0
- package/skills/likec4-dsl/references/views.md +329 -0
- package/vite-plugin-modules.d.ts +126 -51
- package/__app__/src/chunks/LikeC4Styles.mjs +0 -2306
- package/__app__/src/chunks/ProjectsOverview.mjs +0 -537
- package/__app__/src/chunks/es.mjs +0 -439
- package/__app__/src/chunks/libs/@floating-ui.mjs +0 -2532
- package/__app__/src/chunks/libs/@mantine.mjs +0 -13868
- package/__app__/src/chunks/libs/@xstate/react.mjs +0 -2015
- package/__app__/src/chunks/libs/@xyflow/react.mjs +0 -5367
- package/__app__/src/chunks/libs/bezier-js.mjs +0 -1007
- package/__app__/src/chunks/libs/d3.mjs +0 -2817
- package/__app__/src/chunks/libs/framer.mjs +0 -5926
- package/__app__/src/chunks/libs/zod.mjs +0 -3176
- package/dist/chunks/libs/@chevrotain/types.d.mts +0 -108
- package/dist/chunks/libs/picomatch.mjs +0 -1
- package/dist/chunks/libs/zod.d.mts +0 -3840
- package/dist/chunks/libs/zod.mjs +0 -65
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
Compact, real-world patterns. Each example demonstrates multiple features.
|
|
4
|
+
|
|
5
|
+
## Extend Element & Metadata Merge
|
|
6
|
+
|
|
7
|
+
```likec4
|
|
8
|
+
// base.c4
|
|
9
|
+
model {
|
|
10
|
+
cloud = system "Cloud" {
|
|
11
|
+
api = service "API" {
|
|
12
|
+
metadata { owner "team-a"; port "8080" }
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ops.c4 — extend adds nested elements, merges metadata (duplicate keys become arrays)
|
|
18
|
+
model {
|
|
19
|
+
extend cloud.api {
|
|
20
|
+
#monitored
|
|
21
|
+
metadata { port "9090"; region "us-east-1" }
|
|
22
|
+
// Result: port becomes ["8080", "9090"]
|
|
23
|
+
|
|
24
|
+
health = component "Health Check" { technology "HTTP" }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Extend Relationship
|
|
30
|
+
|
|
31
|
+
```likec4
|
|
32
|
+
specification {
|
|
33
|
+
relationship async { color amber; line dotted }
|
|
34
|
+
}
|
|
35
|
+
model {
|
|
36
|
+
frontend -> api "requests"
|
|
37
|
+
frontend -[async]-> api "streams" // different relation (kind distinguishes)
|
|
38
|
+
|
|
39
|
+
// Extend adds metadata/tags to existing relation (must match source, target, title, kind)
|
|
40
|
+
extend frontend -> api "requests" {
|
|
41
|
+
metadata { latency_p95 "150ms" }
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## View Extends (Inheritance)
|
|
47
|
+
|
|
48
|
+
```likec4
|
|
49
|
+
views {
|
|
50
|
+
view overview {
|
|
51
|
+
include *
|
|
52
|
+
style * { color muted }
|
|
53
|
+
}
|
|
54
|
+
view detail extends overview {
|
|
55
|
+
title "More detail"
|
|
56
|
+
include cloud.backend.* // adds to parent's includes
|
|
57
|
+
style cloud.backend.* { color primary }
|
|
58
|
+
}
|
|
59
|
+
view deep extends detail { // cascade inheritance
|
|
60
|
+
include cloud.backend.api.*
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Scoped View
|
|
66
|
+
|
|
67
|
+
```likec4
|
|
68
|
+
views {
|
|
69
|
+
// "of" scopes the view — `*` means the scoped element + direct children
|
|
70
|
+
view backend of cloud.backend {
|
|
71
|
+
include *
|
|
72
|
+
include -> cloud.backend -> // incoming/outgoing relations
|
|
73
|
+
|
|
74
|
+
style cloud.backend { color primary }
|
|
75
|
+
style cloud.backend.* { color secondary }
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Groups in Views
|
|
81
|
+
|
|
82
|
+
```likec4
|
|
83
|
+
views {
|
|
84
|
+
view grouped {
|
|
85
|
+
group "Internal" {
|
|
86
|
+
color primary
|
|
87
|
+
opacity 20%
|
|
88
|
+
include cloud.*
|
|
89
|
+
}
|
|
90
|
+
group "External" {
|
|
91
|
+
color amber
|
|
92
|
+
include customer, partner
|
|
93
|
+
}
|
|
94
|
+
// Unnamed group
|
|
95
|
+
group {
|
|
96
|
+
include monitoring.*
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Global Style & Predicate Groups
|
|
103
|
+
|
|
104
|
+
```likec4
|
|
105
|
+
global {
|
|
106
|
+
styleGroup theme {
|
|
107
|
+
style element.tag = #deprecated { color muted; opacity 20% }
|
|
108
|
+
style element.tag = #critical { color red }
|
|
109
|
+
}
|
|
110
|
+
predicateGroup core_services {
|
|
111
|
+
include cloud.* where kind is service
|
|
112
|
+
exclude * where tag is #deprecated
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
views {
|
|
116
|
+
global style theme // apply to all views in block
|
|
117
|
+
|
|
118
|
+
view services {
|
|
119
|
+
global predicate core_services
|
|
120
|
+
include * -> cloud.* // add relations to included elements
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Dynamic View — Parallel, Notes, NavigateTo
|
|
126
|
+
|
|
127
|
+
```likec4
|
|
128
|
+
dynamic view checkout {
|
|
129
|
+
title "Checkout Flow"
|
|
130
|
+
|
|
131
|
+
customer -> frontend "places order" {
|
|
132
|
+
notes '''
|
|
133
|
+
**Entry point**: customer submits cart
|
|
134
|
+
'''
|
|
135
|
+
}
|
|
136
|
+
frontend
|
|
137
|
+
-> api "POST /checkout"
|
|
138
|
+
-> validator "validate cart" // chained syntax
|
|
139
|
+
|
|
140
|
+
parallel {
|
|
141
|
+
api -> payments "charge card"
|
|
142
|
+
api -> inventory "reserve items"
|
|
143
|
+
api -> notifications "send confirmation"
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
api <- payments "payment result" {
|
|
147
|
+
navigateTo payment-detail // link to another view
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
include cloud with { opacity 10%; color gray }
|
|
151
|
+
style customer { color green }
|
|
152
|
+
autoLayout TopBottom
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Dynamic View — Flow Control (alt / try / loop)
|
|
157
|
+
|
|
158
|
+
```likec4
|
|
159
|
+
dynamic view resilient-checkout {
|
|
160
|
+
variant sequence
|
|
161
|
+
|
|
162
|
+
customer -> app "checkout"
|
|
163
|
+
alt {
|
|
164
|
+
when "authorized" {
|
|
165
|
+
loop "until confirmed" {
|
|
166
|
+
try {
|
|
167
|
+
app -> payments "charge card"
|
|
168
|
+
} catch "declined" {
|
|
169
|
+
app -> customer "ask for another card"
|
|
170
|
+
} finally {
|
|
171
|
+
app -> audit "record attempt"
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else "not authorized" {
|
|
176
|
+
app -> customer "show login"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
- Each block takes an optional title. Blocks nest to any depth — the only exception is `parallel`/`par`, which cannot nest.
|
|
183
|
+
- `when`/`if`/`else` are valid only directly inside `alt`; other blocks (`loop`/`opt`/`parallel`/`try`) must sit inside a branch, not directly under `alt`.
|
|
184
|
+
- try/catch/finally order is fixed: `try` → `catch?` → `finally?`.
|
|
185
|
+
|
|
186
|
+
## Deployment — Multi-Environment, InstanceOf
|
|
187
|
+
|
|
188
|
+
```likec4
|
|
189
|
+
specification {
|
|
190
|
+
deploymentNode environment { style { color gray } }
|
|
191
|
+
deploymentNode region
|
|
192
|
+
deploymentNode vm
|
|
193
|
+
}
|
|
194
|
+
deployment {
|
|
195
|
+
environment prod "Production" {
|
|
196
|
+
technology "OpenTofu"
|
|
197
|
+
|
|
198
|
+
region eu {
|
|
199
|
+
vm server1 {
|
|
200
|
+
app = instanceOf cloud.api // named instance
|
|
201
|
+
instanceOf cloud.ui // anonymous instance
|
|
202
|
+
}
|
|
203
|
+
vm server2 {
|
|
204
|
+
db = instanceOf cloud.db {
|
|
205
|
+
title "Primary DB"
|
|
206
|
+
technology "PostgreSQL 16"
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
region us {
|
|
211
|
+
vm server3 {
|
|
212
|
+
db = instanceOf cloud.db "Replica DB"
|
|
213
|
+
}
|
|
214
|
+
// Deployment-specific relation (replication)
|
|
215
|
+
server3.db -> eu.server2.db "replicates" {
|
|
216
|
+
metadata { lag "100ms"; mode "async" }
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
views {
|
|
222
|
+
deployment view prod_deploy {
|
|
223
|
+
title "Production"
|
|
224
|
+
include prod.**
|
|
225
|
+
style eu._ { color primary }
|
|
226
|
+
style us._ { color secondary }
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Rank — Layout Control
|
|
232
|
+
|
|
233
|
+
```likec4
|
|
234
|
+
views {
|
|
235
|
+
view ranked {
|
|
236
|
+
include A, B, C, D, E, F
|
|
237
|
+
|
|
238
|
+
rank same { A, B } // same vertical level
|
|
239
|
+
rank source { C, D } // force to top
|
|
240
|
+
rank max { F } // force to bottom
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Where Predicates — Filtering
|
|
246
|
+
|
|
247
|
+
```likec4
|
|
248
|
+
views {
|
|
249
|
+
view filtered {
|
|
250
|
+
// By tag
|
|
251
|
+
include cloud.* where tag is #production
|
|
252
|
+
|
|
253
|
+
// By kind + negated tag
|
|
254
|
+
include cloud.* where kind is service and tag is not #deprecated
|
|
255
|
+
|
|
256
|
+
// By metadata
|
|
257
|
+
include cloud.* where metadata.region is "eu"
|
|
258
|
+
|
|
259
|
+
// Relationship filtering, including own vs endpoint metadata
|
|
260
|
+
include cloud.* -> amazon.* where source.tag is #critical
|
|
261
|
+
exclude * -> * where metadata.protocol is "http"
|
|
262
|
+
exclude * -> * where target.metadata.zone is "restricted"
|
|
263
|
+
|
|
264
|
+
// Wildcard with expansion
|
|
265
|
+
include cloud._ // direct children that have relationships with the accumulated result
|
|
266
|
+
include cloud.** // all descendants
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Relationship Kinds & Styling
|
|
272
|
+
|
|
273
|
+
```likec4
|
|
274
|
+
specification {
|
|
275
|
+
relationship async { color amber; line dotted; head diamond; tail vee }
|
|
276
|
+
relationship sync { color primary; line solid }
|
|
277
|
+
}
|
|
278
|
+
model {
|
|
279
|
+
api -[async]-> queue "publishes" {
|
|
280
|
+
technology "Kafka"
|
|
281
|
+
metadata { format "CloudEvents" }
|
|
282
|
+
}
|
|
283
|
+
api .sync cache "reads" // alternative syntax: .KIND (no arrow)
|
|
284
|
+
|
|
285
|
+
// Inline style override
|
|
286
|
+
api -> db "writes" {
|
|
287
|
+
style { color red; line dashed; head odiamond }
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Complete Mini-Project
|
|
293
|
+
|
|
294
|
+
```likec4
|
|
295
|
+
specification {
|
|
296
|
+
element actor { style { shape person } }
|
|
297
|
+
element system { style { shape rectangle } }
|
|
298
|
+
element service { style { shape component } }
|
|
299
|
+
element webapp { style { shape browser } }
|
|
300
|
+
element db { style { shape storage } }
|
|
301
|
+
|
|
302
|
+
tag deprecated
|
|
303
|
+
tag critical
|
|
304
|
+
|
|
305
|
+
relationship async { color amber; line dotted }
|
|
306
|
+
deploymentNode env
|
|
307
|
+
deploymentNode vm
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
model {
|
|
311
|
+
customer = actor "Customer"
|
|
312
|
+
|
|
313
|
+
cloud = system "Cloud" {
|
|
314
|
+
ui = webapp "Frontend" { icon tech:react }
|
|
315
|
+
api = service "API" {
|
|
316
|
+
#critical
|
|
317
|
+
technology "Node.js"
|
|
318
|
+
icon tech:nodejs
|
|
319
|
+
}
|
|
320
|
+
db = db "Database" {
|
|
321
|
+
icon tech:postgresql
|
|
322
|
+
description '''
|
|
323
|
+
Primary PostgreSQL database.
|
|
324
|
+
Handles all transactional data.
|
|
325
|
+
'''
|
|
326
|
+
}
|
|
327
|
+
api -> db "reads/writes"
|
|
328
|
+
ui -> api "calls" { technology "HTTPS" }
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
customer -> cloud.ui "browses" {
|
|
332
|
+
navigateTo user-flow
|
|
333
|
+
metadata { protocol "HTTPS" }
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
deployment {
|
|
338
|
+
env prod {
|
|
339
|
+
vm web { instanceOf cloud.ui; instanceOf cloud.api }
|
|
340
|
+
vm data { instanceOf cloud.db }
|
|
341
|
+
web -> data "internal network"
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
views {
|
|
346
|
+
view index {
|
|
347
|
+
include *
|
|
348
|
+
style cloud { color primary }
|
|
349
|
+
style customer { color green }
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
view backend of cloud {
|
|
353
|
+
include *
|
|
354
|
+
autoLayout LeftRight
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
dynamic view user-flow {
|
|
358
|
+
customer -> cloud.ui "opens app"
|
|
359
|
+
cloud.ui -> cloud.api "fetches data"
|
|
360
|
+
cloud.api -> cloud.db "queries"
|
|
361
|
+
cloud.api -> cloud.ui "returns"
|
|
362
|
+
|
|
363
|
+
style cloud { opacity 20% }
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
deployment view prod-deploy {
|
|
367
|
+
include prod.**
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
```
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Identifier Validity (LikeC4 DSL)
|
|
2
|
+
|
|
3
|
+
## Valid identifier form
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
identifier = /^[a-zA-Z_][a-zA-Z0-9_-]*$/
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
- **Starts with** letter or underscore
|
|
10
|
+
- **Contains** letters, digits, hyphens, or underscores only
|
|
11
|
+
- **No dots**, no spaces, no special characters
|
|
12
|
+
|
|
13
|
+
## Valid examples
|
|
14
|
+
|
|
15
|
+
| Valid | Why |
|
|
16
|
+
| ----------------- | ----------------------------- |
|
|
17
|
+
| `payment-api` | hyphens allowed |
|
|
18
|
+
| `paymentAPI` | camelCase allowed |
|
|
19
|
+
| `payment_service` | underscores allowed |
|
|
20
|
+
| `service1` | digits allowed (not at start) |
|
|
21
|
+
| `_internal` | underscore at start allowed |
|
|
22
|
+
| `PaymentService` | PascalCase allowed |
|
|
23
|
+
|
|
24
|
+
## Invalid examples
|
|
25
|
+
|
|
26
|
+
| Invalid | Why | Correct form |
|
|
27
|
+
| ------------- | ------------------------------------------------- | ----------------------------- |
|
|
28
|
+
| `payment.api` | **dots are FQN separators**, not identifier chars | `payment-api` or `paymentApi` |
|
|
29
|
+
| `payment api` | spaces not allowed | `payment-api` |
|
|
30
|
+
| `1payment` | cannot start with digit | `payment1` |
|
|
31
|
+
| `payment-` | cannot end with hyphen | `payment` |
|
|
32
|
+
| `payment@api` | special chars not allowed | `payment-api` |
|
|
33
|
+
|
|
34
|
+
## Critical: dots vs. hyphens
|
|
35
|
+
|
|
36
|
+
**Dots are reserved for fully qualified names (FQN):**
|
|
37
|
+
|
|
38
|
+
```likec4
|
|
39
|
+
model {
|
|
40
|
+
cloud.backend.payment-api // FQN: cloud (parent) -> backend (child) -> payment-api (child identifier)
|
|
41
|
+
// ^ ^ Dots separate hierarchy levels
|
|
42
|
+
// |---- hyphen used in identifier name itself
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Correct identifier:** `payment-api` (with hyphen)\
|
|
47
|
+
**Incorrect identifier:** `payment.api` (dots are FQN syntax, not part of the name)
|
|
48
|
+
|
|
49
|
+
## Use in different contexts
|
|
50
|
+
|
|
51
|
+
| Context | Rule | Example |
|
|
52
|
+
| --------------------- | --------------------------------- | ---------------------------------------- |
|
|
53
|
+
| **Element name** | Must be valid identifier | `service name = api "payment api"` ✓ |
|
|
54
|
+
| **Tag name** | Must be valid identifier | `tag critical` ✓, `tag #critical` ✗ |
|
|
55
|
+
| **Relationship kind** | Must be valid identifier | `-[async]->` ✓, `-[async-queue]->` ✓ |
|
|
56
|
+
| **Kind name** | Must be valid identifier | `element service`, `deploymentNode vm` ✓ |
|
|
57
|
+
| **Metadata key** | Must be valid identifier | `metadata { api_version "1.0" }` ✓ |
|
|
58
|
+
| **Color name** | Must be valid identifier (or hex) | `color primary`, `color custom-blue` ✓ |
|
|
59
|
+
|
|
60
|
+
## When referencing by FQN
|
|
61
|
+
|
|
62
|
+
Once defined, elements are referenced using their fully qualified names (FQNs), which _do_ use dots:
|
|
63
|
+
|
|
64
|
+
```likec4
|
|
65
|
+
model {
|
|
66
|
+
// Definition (identifier = payment-api, no dots)
|
|
67
|
+
cloud = system {
|
|
68
|
+
backend = container {
|
|
69
|
+
payment-api = service "Payment API"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
deployment {
|
|
75
|
+
vm1 {
|
|
76
|
+
// Reference (FQN = cloud.backend.payment-api, dots for hierarchy)
|
|
77
|
+
instanceOf cloud.backend.payment-api
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Summary
|
|
83
|
+
|
|
84
|
+
| Check | Valid | Invalid |
|
|
85
|
+
| ---------------- | --------------------------------------------------------------------------------- | --------------------------------------- |
|
|
86
|
+
| Identifier rule | `[a-zA-Z_][a-zA-Z0-9_-]*` | Contains dots, spaces, or special chars |
|
|
87
|
+
| Hyphens allowed? | **Yes** in identifiers | Not dots |
|
|
88
|
+
| Dots allowed? | **Only in FQNs** (for scope separation) | Never in a single identifier name |
|
|
89
|
+
| `payment-api` | ✓ identifier | — |
|
|
90
|
+
| `payment.api` | ✗ identifier, but valid as FQN if `payment` and `api` are nested parents/children | — |
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Include Predicates and Wildcards in Views
|
|
2
|
+
|
|
3
|
+
## Wildcard semantics
|
|
4
|
+
|
|
5
|
+
LikeC4 view predicates use the wildcard `*` and the selector suffixes `parent.*`, `parent._` and `parent.**`.
|
|
6
|
+
`_` and `**` exist **only** as suffixes on an element reference: bare `include **` and `exclude _` are parse errors.
|
|
7
|
+
|
|
8
|
+
### `*` — immediate children and direct contains-relationships
|
|
9
|
+
|
|
10
|
+
```likec4
|
|
11
|
+
views {
|
|
12
|
+
view container-overview {
|
|
13
|
+
include *
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- Includes **direct children** of the scoped element (one level down).
|
|
19
|
+
- Includes **direct relationships** defined at the same scope.
|
|
20
|
+
- Does **not** include grandchildren or descendant chains.
|
|
21
|
+
|
|
22
|
+
### `parent._` — expand (children that have relationships)
|
|
23
|
+
|
|
24
|
+
```likec4
|
|
25
|
+
views {
|
|
26
|
+
view connected-children {
|
|
27
|
+
include customer
|
|
28
|
+
include cloud._
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- Includes `cloud` and only those direct children of `cloud` that have relationships with visible elements; other children are omitted.
|
|
34
|
+
- Same as `include cloud` + `include -> cloud.* ->`.
|
|
35
|
+
- `_` is **not** a "match anything" wildcard. To exclude every visible element with a tag, use `exclude * where tag is #deprecated`.
|
|
36
|
+
|
|
37
|
+
### `parent.**` — recursive descent (descendants)
|
|
38
|
+
|
|
39
|
+
```likec4
|
|
40
|
+
views {
|
|
41
|
+
view full-tree {
|
|
42
|
+
include cloud.**
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- Includes **all descendants** recursively (grandchildren, great-grandchildren, etc.).
|
|
48
|
+
- **Not** the same as `include cloud.*` (which is immediate children only).
|
|
49
|
+
- Use when you want nested hierarchies visible in a single view.
|
|
50
|
+
|
|
51
|
+
## Scoped view base semantics
|
|
52
|
+
|
|
53
|
+
In a **scoped view** (`view name of parent { ... }`), the `include` base set has special meaning:
|
|
54
|
+
|
|
55
|
+
```likec4
|
|
56
|
+
views {
|
|
57
|
+
view backend-overview of cloud.backend {
|
|
58
|
+
include * // Base set: cloud.backend + its immediate children
|
|
59
|
+
include -> cloud.backend // Add: inbound relationships to the scope
|
|
60
|
+
include -> * // Add: outbound relationships from children
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Key facts:**
|
|
66
|
+
|
|
67
|
+
- `include *` in a scoped view = the scoped parent + **direct children only**
|
|
68
|
+
- Grandchildren inside `*` context are **not** included (you'd need `include cloud.backend.**` or explicit FQN inclusion)
|
|
69
|
+
- Relationship predicates like `->` and `<->` can further expand what neighbors appear
|
|
70
|
+
|
|
71
|
+
## Common filter patterns
|
|
72
|
+
|
|
73
|
+
### Show a container and its components
|
|
74
|
+
|
|
75
|
+
```likec4
|
|
76
|
+
views {
|
|
77
|
+
view container-details of cloud.backend.api {
|
|
78
|
+
include * // api (parent) + all components
|
|
79
|
+
include -> api // Add external callers
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Show descendants recursively
|
|
85
|
+
|
|
86
|
+
```likec4
|
|
87
|
+
views {
|
|
88
|
+
view system-tree of cloud {
|
|
89
|
+
include cloud.** // All descendants of cloud (full tree)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Filter by kind
|
|
95
|
+
|
|
96
|
+
```likec4
|
|
97
|
+
views {
|
|
98
|
+
view services-only {
|
|
99
|
+
include * where kind is service
|
|
100
|
+
include cloud.** where kind is service // All services at any depth inside cloud
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Filter by tag
|
|
106
|
+
|
|
107
|
+
```likec4
|
|
108
|
+
views {
|
|
109
|
+
view critical-view {
|
|
110
|
+
include * where tag is #critical
|
|
111
|
+
exclude * where tag is #deprecated // Removes deprecated elements at any depth
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Relationship predicate expansion
|
|
117
|
+
|
|
118
|
+
In scoped views, you can expand what neighboring elements appear via relationship predicates:
|
|
119
|
+
|
|
120
|
+
```likec4
|
|
121
|
+
views {
|
|
122
|
+
view backend-with-neighbors of cloud.backend {
|
|
123
|
+
include * // Base: backend scope + direct children
|
|
124
|
+
include -> cloud.backend // Add: inbound edges from outside scope
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
This **does not change the base set of elements**; it only **includes relationships** that end in the visible elements. Neighbors of the scope that have incoming edges _do_ appear because they are needed to render those edges visually.
|
|
130
|
+
|
|
131
|
+
## Wildcard `**` vs. explicit include
|
|
132
|
+
|
|
133
|
+
### Using `**` (recursive)
|
|
134
|
+
|
|
135
|
+
```likec4
|
|
136
|
+
views {
|
|
137
|
+
view all-elements {
|
|
138
|
+
include cloud.**
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
- Automatically includes all descendants.
|
|
144
|
+
- Used when hierarchy depth is unknown or variable.
|
|
145
|
+
|
|
146
|
+
### Using `*` + explicit FQNs
|
|
147
|
+
|
|
148
|
+
```likec4
|
|
149
|
+
views {
|
|
150
|
+
view two-levels {
|
|
151
|
+
include * // Level 1
|
|
152
|
+
include cloud.* // Level 2 under cloud
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- More explicit; requires knowing the hierarchy.
|
|
158
|
+
- Useful when you want fine-grained control.
|
|
159
|
+
|
|
160
|
+
## Common mistakes
|
|
161
|
+
|
|
162
|
+
| Wrong | Right | Why |
|
|
163
|
+
| ----------------------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------------------------- |
|
|
164
|
+
| Bare `include **` or `exclude _` | `include cloud.**`, `exclude * where tag is #deprecated` | `**` and `_` are suffixes on an element reference, not standalone wildcards |
|
|
165
|
+
| `include cloud.**` expecting only immediate children | `include cloud.*` | `**` is recursive; use `*` for one level |
|
|
166
|
+
| Forgetting to add relationship filters in scoped view | `include *` + `include -> parent` | Relationships may not auto-render without explicit inclusion |
|
|
167
|
+
| Assuming `include *` includes grandchildren | Use `include cloud.**` instead | `*` is immediate children only |
|
|
168
|
+
|
|
169
|
+
## Summary table
|
|
170
|
+
|
|
171
|
+
| Form | Matches | Scope context |
|
|
172
|
+
| -------------------- | ------------------------------------------------------------------------ | ---------------------------- |
|
|
173
|
+
| `*` | Direct children + sibling relationships | One level down |
|
|
174
|
+
| `parent._` | `parent` + direct children that have relationships with visible elements | One level down |
|
|
175
|
+
| `parent.**` | All descendants recursively | Any depth |
|
|
176
|
+
| `include -> element` | Inbound relationships to element | Shows external sources |
|
|
177
|
+
| `include element ->` | Outbound relationships from element | Shows targets |
|
|
178
|
+
| `include a <-> b` | Relationships between `a` and `b` in either direction | Shows symmetric dependencies |
|
|
179
|
+
|
|
180
|
+
**In scoped views:** `include *` establishes a base set of the scope parent + immediate children. Relationship predicates like `->` and `<->` can bring in neighboring elements needed to render those relationships.
|