likec4 1.59.3 → 1.60.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/__app__/codegen/react.mjs +6 -6
- package/__app__/codegen/webcomponent.mjs +147 -69
- package/__app__/src/aichat/index.mjs +10 -5
- package/__app__/src/chunks/AIChat.mjs +1134 -693
- package/__app__/src/chunks/LikeC4Styles.mjs +4101 -1737
- package/__app__/src/chunks/ProjectsOverview.mjs +624 -334
- package/__app__/src/chunks/es.mjs +515 -335
- package/__app__/src/chunks/hooks.mjs +578 -366
- package/__app__/src/chunks/libs/@floating-ui.mjs +2720 -1966
- package/__app__/src/chunks/libs/@mantine.mjs +14067 -9487
- package/__app__/src/chunks/libs/@tanstack-ai.mjs +2266 -1146
- package/__app__/src/chunks/libs/@tanstack.mjs +3152 -1932
- package/__app__/src/chunks/libs/@xstate/react.mjs +2924 -1468
- package/__app__/src/chunks/libs/@xyflow/react.mjs +6627 -4067
- package/__app__/src/chunks/libs/bezier-js.mjs +1312 -726
- package/__app__/src/chunks/libs/d3.mjs +3218 -1509
- package/__app__/src/chunks/libs/fast-equals.mjs +437 -201
- package/__app__/src/chunks/libs/framer.mjs +9251 -3846
- package/__app__/src/chunks/libs/nanostores.mjs +174 -0
- package/__app__/src/chunks/libs/zod.mjs +4591 -2363
- package/__app__/src/chunks/rolldown-runtime.mjs +39 -23
- package/__app__/src/chunks/styled-system.mjs +3538 -756
- package/__app__/src/fonts.css +112 -1
- package/__app__/src/main.mjs +44398 -24039
- package/__app__/src/style.css +18488 -1
- package/config/schema.json +136 -97
- package/dist/app/render-view-client.css +1 -1
- package/dist/app/render-view-client.js +506 -338
- package/dist/chunks/enableServer.mjs +1 -1
- package/dist/chunks/filenames.mjs +16 -14
- package/dist/chunks/generate-likec4.mjs +5 -0
- package/dist/chunks/index.d.mts +246 -180
- package/dist/chunks/index2.d.mts +2882 -1977
- package/dist/chunks/libs/@chevrotain/gast.mjs +27 -1
- package/dist/chunks/libs/@chevrotain/regexp-to-ast.mjs +81 -9
- package/dist/chunks/libs/@chevrotain/types.d.mts +111 -0
- package/dist/chunks/libs/@logtape/logtape.mjs +5 -4
- package/dist/chunks/libs/@lume/kiwi.mjs +1 -1
- 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 +87 -35
- package/dist/chunks/libs/eventemitter3.mjs +1 -1
- package/dist/chunks/libs/json5.mjs +4 -4
- package/dist/chunks/libs/langium.d.mts +9903 -5297
- 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 +2 -2
- 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 +60 -60
- package/dist/chunks/rolldown-runtime.mjs +1 -1
- package/dist/chunks/sequence-view.mjs +1 -1
- package/dist/chunks/vite-plugin.mjs +55 -52
- package/dist/cli/index.d.mts +1 -1
- package/dist/cli/index.mjs +208 -1300
- package/dist/config/index.d.mts +2 -2
- package/dist/generators/likec4.d.mts +6578 -0
- package/dist/generators/likec4.mjs +1 -0
- package/dist/index.d.mts +3 -3
- package/dist/model/index.d.mts +8 -5
- package/dist/vite-plugin/index.d.mts +6 -3
- package/dist/vite-plugin/index.mjs +1 -1
- package/dist/vite-plugin/internal/chunks/rolldown-runtime.mjs +9 -0
- package/dist/vite-plugin/internal/index.d.mts +16 -15
- package/dist/vite-plugin/internal/index.mjs +144 -46
- package/generators/likec4/package.json +4 -0
- package/package.json +117 -110
- package/react/index.d.mts +8500 -5399
- package/react/index.mjs +534 -58617
- package/react/rolldown-runtime-DnkiqaRY.js +1 -0
- package/skills/likec4-dsl/SKILL.md +428 -0
- package/skills/likec4-dsl/evals/evals-public.json +202 -0
- package/skills/likec4-dsl/evals/grading-spec.json +589 -0
- package/skills/likec4-dsl/references/bridge-leanix-drawio.md +42 -0
- package/skills/likec4-dsl/references/cli.md +139 -0
- package/skills/likec4-dsl/references/configuration.md +266 -0
- package/skills/likec4-dsl/references/deployment.md +160 -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 +179 -0
- package/skills/likec4-dsl/references/model.md +151 -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 +75 -0
- package/skills/likec4-dsl/references/style-tokens-colors.md +150 -0
- package/skills/likec4-dsl/references/troubleshooting.md +96 -0
- package/skills/likec4-dsl/references/views.md +329 -0
- package/vite-plugin-modules.d.ts +4 -2
- package/dist/chunks/libs/picomatch.mjs +0 -1
- package/dist/chunks/libs/zod.d.mts +0 -2140
- package/dist/chunks/libs/zod.mjs +0 -65
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
# Dynamic Views — Flow & Sequence Diagrams
|
|
2
|
+
|
|
3
|
+
Dynamic views model temporal interactions and flows between elements. They render as animated flow diagrams or (optionally) UML sequence diagrams.
|
|
4
|
+
|
|
5
|
+
## Syntax Overview
|
|
6
|
+
|
|
7
|
+
```likec4
|
|
8
|
+
views {
|
|
9
|
+
dynamic view name {
|
|
10
|
+
variant sequence // optional: render as UML sequence diagram
|
|
11
|
+
|
|
12
|
+
title "Flow title"
|
|
13
|
+
description "Flow description"
|
|
14
|
+
|
|
15
|
+
SOURCE -> TARGET "step title"
|
|
16
|
+
SOURCE <- TARGET "return flow"
|
|
17
|
+
|
|
18
|
+
// flow-control blocks (each takes an optional title, can nest)
|
|
19
|
+
parallel 'optional' { // also: par, opt, loop, break
|
|
20
|
+
SOURCE_1 -> TARGET_1 "parallel action 1"
|
|
21
|
+
SOURCE_2 -> TARGET_2 "parallel action 2"
|
|
22
|
+
}
|
|
23
|
+
alt 'optional' { // mutually exclusive branches
|
|
24
|
+
when 'condition' { SOURCE -> TARGET }
|
|
25
|
+
else { SOURCE -> TARGET }
|
|
26
|
+
}
|
|
27
|
+
try 'optional' { SOURCE -> TARGET }
|
|
28
|
+
catch 'optional' { SOURCE -> TARGET }
|
|
29
|
+
finally 'optional' { SOURCE -> TARGET }
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Basic Steps
|
|
35
|
+
|
|
36
|
+
### Forward step
|
|
37
|
+
|
|
38
|
+
```likec4
|
|
39
|
+
dynamic view checkout-flow {
|
|
40
|
+
customer -> frontend "opens cart"
|
|
41
|
+
frontend -> backend "requests checkout"
|
|
42
|
+
backend -> payment-service "initiates payment"
|
|
43
|
+
payment-service -> bank "authorizes card"
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- Renders as directed arrow from source to target.
|
|
48
|
+
- Title appears on the arrow/step.
|
|
49
|
+
|
|
50
|
+
### Return step (response arrow)
|
|
51
|
+
|
|
52
|
+
```likec4
|
|
53
|
+
dynamic view checkout-flow {
|
|
54
|
+
customer -> frontend "opens cart"
|
|
55
|
+
frontend -> backend "requests checkout"
|
|
56
|
+
frontend <- backend "payment result" // Return flow
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- `<-` denotes response/return flow.
|
|
61
|
+
- Renders as dotted or dashed arrow depending on theme.
|
|
62
|
+
- Semantically indicates flow **back** to the source.
|
|
63
|
+
|
|
64
|
+
### Chained steps
|
|
65
|
+
|
|
66
|
+
```likec4
|
|
67
|
+
dynamic view multi-hop {
|
|
68
|
+
customer
|
|
69
|
+
-> frontend "request"
|
|
70
|
+
-> backend "forwards"
|
|
71
|
+
-> db "query"
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Keep the chain as one compound expression when the prompt explicitly asks for chained syntax.
|
|
76
|
+
|
|
77
|
+
### Hop-local body (exactness for evals)
|
|
78
|
+
|
|
79
|
+
```likec4
|
|
80
|
+
dynamic view checkout-flow {
|
|
81
|
+
customer -> frontend
|
|
82
|
+
-> api {
|
|
83
|
+
technology 'HTTPS'
|
|
84
|
+
navigateTo payment-detail
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Attach the body only to the requested hop. Do not move the block onto the whole chain unless the prompt allows it.
|
|
90
|
+
|
|
91
|
+
## Flow Control Blocks
|
|
92
|
+
|
|
93
|
+
Steps can be grouped into **flow-control blocks**. `parallel` is one of these blocks — not a special case. Every block:
|
|
94
|
+
|
|
95
|
+
- takes an **optional title** (a `String`) right after the keyword, then wraps a `{ ... }` body of steps;
|
|
96
|
+
- may be **nested to any depth** — the only exception is `parallel`/`par`, which cannot nest inside another `parallel`/`par`.
|
|
97
|
+
|
|
98
|
+
Block keyword map:
|
|
99
|
+
|
|
100
|
+
| Block | Keyword(s) | Meaning |
|
|
101
|
+
| --------------------- | --------------------------- | ----------------------------------------------- |
|
|
102
|
+
| Parallel | `parallel` / `par` | Steps inside run concurrently |
|
|
103
|
+
| Optional | `opt` | Steps that may be skipped |
|
|
104
|
+
| Loop | `loop` | Steps that repeat |
|
|
105
|
+
| Break | `break` | Interrupts the enclosing flow (e.g. exits loop) |
|
|
106
|
+
| Alternatives | `alt` | Container of mutually exclusive branches |
|
|
107
|
+
| Branch (inside `alt`) | `when` / `if` / `else` | One branch of an `alt` (`if` is a `when` alias) |
|
|
108
|
+
| Error handling | `try` / `catch` / `finally` | Happy path plus optional error handling |
|
|
109
|
+
|
|
110
|
+
### Parallel — `parallel` / `par`
|
|
111
|
+
|
|
112
|
+
Steps inside run concurrently. Use for fan-outs (one source to multiple targets):
|
|
113
|
+
|
|
114
|
+
```likec4
|
|
115
|
+
dynamic view fan-out {
|
|
116
|
+
backend -> cache "write to cache"
|
|
117
|
+
parallel {
|
|
118
|
+
backend -> db "save record"
|
|
119
|
+
backend -> audit-log "log event"
|
|
120
|
+
backend -> notification-service "send notification"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
- `par { ... }` is an exact alias for `parallel { ... }`.
|
|
126
|
+
- Renders with time-aligned horizontal layout.
|
|
127
|
+
- **Cannot nest**: `parallel { parallel { ... } }` (or with `par`) is a validation error — `Nested parallel blocks are not allowed`. A `parallel` block may still live inside `opt` / `loop` / `try` / an `alt` branch.
|
|
128
|
+
- When the prompt asks for one fan-out, keep sibling actions in **one** `parallel { ... }` block; do not split them into multiple one-step blocks.
|
|
129
|
+
|
|
130
|
+
### Optional — `opt`
|
|
131
|
+
|
|
132
|
+
A block of steps that may be skipped:
|
|
133
|
+
|
|
134
|
+
```likec4
|
|
135
|
+
opt 'if not cached' {
|
|
136
|
+
api -> db 'load and cache'
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Loop — `loop`
|
|
141
|
+
|
|
142
|
+
A block of steps that repeats:
|
|
143
|
+
|
|
144
|
+
```likec4
|
|
145
|
+
loop 'until success' {
|
|
146
|
+
api -> auth 'retry authentication'
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Break — `break`
|
|
151
|
+
|
|
152
|
+
Interrupts the enclosing flow (typically exits a `loop`):
|
|
153
|
+
|
|
154
|
+
```likec4
|
|
155
|
+
loop 'poll for result' {
|
|
156
|
+
api -> db 'check status'
|
|
157
|
+
break 'when ready' {
|
|
158
|
+
api -> web 'return result'
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Alternatives — `alt` with `when` / `if` / `else`
|
|
164
|
+
|
|
165
|
+
`alt` groups mutually exclusive branches. Its **direct children must be branches** — `when`, `if`, or `else` (with an optional title each):
|
|
166
|
+
|
|
167
|
+
```likec4
|
|
168
|
+
alt {
|
|
169
|
+
when 'authorized' {
|
|
170
|
+
app -> api 'requests data'
|
|
171
|
+
}
|
|
172
|
+
else 'not authorized' {
|
|
173
|
+
app -> customer 'shows login'
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
- `if` is an alias for `when`; both are branch keywords.
|
|
179
|
+
- `when` / `if` / `else` are only valid **inside** `alt`. Using them at the top level or inside `loop` / `parallel` / `opt` is a validation error (`"when" alternative branch must be inside "alt"`).
|
|
180
|
+
- Putting a non-branch block (`loop`, `opt`, `parallel`, `try`) as a **direct** child of `alt` is a validation error (`"loop" can not be used as an alternative branch`). Nest those blocks **inside** a branch instead.
|
|
181
|
+
|
|
182
|
+
### Try / catch / finally — `try`
|
|
183
|
+
|
|
184
|
+
Models the happy path with optional error handling. `catch` and `finally` are both optional, but order is fixed: `try` → `catch?` → `finally?`.
|
|
185
|
+
|
|
186
|
+
```likec4
|
|
187
|
+
try {
|
|
188
|
+
api -> db 'query'
|
|
189
|
+
} catch 'on failure' {
|
|
190
|
+
api -> web 'shows error'
|
|
191
|
+
} finally {
|
|
192
|
+
api -> api 'release resources'
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
- `try` alone, `try { } catch { }`, `try { } finally { }`, and `try { } catch { } finally { }` are all valid.
|
|
197
|
+
- A `catch` with no preceding `try`, or a `catch` after `finally`, is a validation error.
|
|
198
|
+
- `try` cannot be a direct child of `alt` (only branches can) — put it inside a `when` / `else` branch.
|
|
199
|
+
|
|
200
|
+
### Nesting
|
|
201
|
+
|
|
202
|
+
Blocks combine and nest to any depth (except `parallel` inside `parallel`):
|
|
203
|
+
|
|
204
|
+
```likec4
|
|
205
|
+
dynamic view resilient-sync {
|
|
206
|
+
variant sequence
|
|
207
|
+
loop 'until synced' {
|
|
208
|
+
try {
|
|
209
|
+
alt {
|
|
210
|
+
when 'online' {
|
|
211
|
+
web -> api 'sync changes'
|
|
212
|
+
}
|
|
213
|
+
else 'offline' {
|
|
214
|
+
opt {
|
|
215
|
+
web -> web 'queue locally'
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
} finally {
|
|
220
|
+
web <- api 'ack'
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Step Properties (Body)
|
|
227
|
+
|
|
228
|
+
Attach a body block `{ ... }` to a step for additional properties:
|
|
229
|
+
|
|
230
|
+
```likec4
|
|
231
|
+
dynamic view with-notes {
|
|
232
|
+
customer -> frontend "view product" {
|
|
233
|
+
title "View Product Detail"
|
|
234
|
+
technology "HTTPS"
|
|
235
|
+
description "Customer opens product page"
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
frontend -> backend "fetch product data" {
|
|
239
|
+
notes """
|
|
240
|
+
Includes:
|
|
241
|
+
- Product info
|
|
242
|
+
- Pricing
|
|
243
|
+
- Available inventory
|
|
244
|
+
"""
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Available properties inside step body:**
|
|
250
|
+
|
|
251
|
+
- `title` — alternative or longer title
|
|
252
|
+
- `technology` — technology/protocol used
|
|
253
|
+
- `description` — detailed description
|
|
254
|
+
- `notes` — markdown-formatted notes/commentary
|
|
255
|
+
- `navigateTo` — drill-down link to another dynamic view (see below)
|
|
256
|
+
|
|
257
|
+
A step body does **not** accept `metadata` (parse error). Put metadata on the model relationship instead.
|
|
258
|
+
|
|
259
|
+
## Navigation & Drill-down
|
|
260
|
+
|
|
261
|
+
Link to another view from a step:
|
|
262
|
+
|
|
263
|
+
```likec4
|
|
264
|
+
dynamic view high-level {
|
|
265
|
+
customer -> frontend "browse"
|
|
266
|
+
frontend -> backend "request data" {
|
|
267
|
+
navigateTo data-fetch-details // Link to another view
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
dynamic view data-fetch-details {
|
|
272
|
+
// Detailed flow of the "data-fetch" step
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
- `navigateTo <view-name>` — renders as a clickable link to drill down.
|
|
277
|
+
- On a dynamic step, `navigateTo` resolves **only** to another `dynamic view`. Pointing it at an element view fails with `Could not resolve reference to DynamicView`.
|
|
278
|
+
- Use for progressive disclosure: high-level flows → detailed sub-flows.
|
|
279
|
+
|
|
280
|
+
## Variant: Sequence Diagram
|
|
281
|
+
|
|
282
|
+
Render the dynamic view as a UML-style sequence diagram:
|
|
283
|
+
|
|
284
|
+
```likec4
|
|
285
|
+
dynamic view checkout-sequence {
|
|
286
|
+
variant sequence // Switch to sequence diagram rendering
|
|
287
|
+
|
|
288
|
+
customer -> frontend "click checkout"
|
|
289
|
+
frontend -> backend "POST /checkout"
|
|
290
|
+
backend -> payment-service "charge card"
|
|
291
|
+
payment-service <- bank "authorization"
|
|
292
|
+
backend <- payment-service "charge approved"
|
|
293
|
+
frontend <- backend "200 OK"
|
|
294
|
+
customer <- frontend "show confirmation"
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
- `variant sequence` — tells LikeC4 to render as sequence diagram.
|
|
299
|
+
- Timeline flows top-to-bottom (instead of left-to-right flow diagram).
|
|
300
|
+
- Actors (lifelines) are participants; return arrows are dashed.
|
|
301
|
+
|
|
302
|
+
### Comparing flow vs. sequence rendering
|
|
303
|
+
|
|
304
|
+
| Aspect | Flow Diagram | Sequence Diagram (variant sequence) |
|
|
305
|
+
| ------------- | ------------------------------ | ----------------------------------- |
|
|
306
|
+
| Layout | Left-to-right or top-down flow | Top-to-bottom lifelines |
|
|
307
|
+
| Return arrows | Style varies | Dashed lines standard |
|
|
308
|
+
| Parallel feel | Horizontal alignment | Time-based with spacing |
|
|
309
|
+
| Best for | System interactions | Message exchange protocols |
|
|
310
|
+
|
|
311
|
+
## Response Arrow Patterns (exactness)
|
|
312
|
+
|
|
313
|
+
If the prompt asks for response arrows back out, prefer `<-` steps over inventing extra forward steps:
|
|
314
|
+
|
|
315
|
+
```likec4
|
|
316
|
+
dynamic view checkout-flow {
|
|
317
|
+
customer -> frontend -> api
|
|
318
|
+
frontend <- api // One <- step per response hop
|
|
319
|
+
customer <- frontend // <- cannot be chained (`a <- b <- c` is a parse error)
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
NOT:
|
|
324
|
+
|
|
325
|
+
```likec4
|
|
326
|
+
dynamic view checkout-flow {
|
|
327
|
+
customer -> frontend -> api
|
|
328
|
+
api -> frontend "returns" // Wrong: not a response arrow (missing symmetry)
|
|
329
|
+
frontend -> customer "returns"
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Common Patterns
|
|
334
|
+
|
|
335
|
+
### Fan-out with return
|
|
336
|
+
|
|
337
|
+
```likec4
|
|
338
|
+
dynamic view fan-out-return {
|
|
339
|
+
backend -> cache "check"
|
|
340
|
+
backend -> db "if miss"
|
|
341
|
+
backend <- db "result"
|
|
342
|
+
backend -> client "send"
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Order: send to multiple targets, then collect responses separately when they differ.
|
|
347
|
+
|
|
348
|
+
### Pipeline / staged flow
|
|
349
|
+
|
|
350
|
+
```likec4
|
|
351
|
+
dynamic view data-pipeline {
|
|
352
|
+
source -> ingester "submit"
|
|
353
|
+
ingester -> parser "parse"
|
|
354
|
+
parser -> validator "validate"
|
|
355
|
+
validator -> storage "store"
|
|
356
|
+
validator <- storage "ack"
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
- Linear chain: each stage outputs to the next.
|
|
361
|
+
- Use for ETL/processing workflows.
|
|
362
|
+
|
|
363
|
+
### Conditional/branching
|
|
364
|
+
|
|
365
|
+
Prefer an `alt` block with `if` / `when` / `else` branches — this renders as an explicit alternative frame in the `sequence` variant:
|
|
366
|
+
|
|
367
|
+
```likec4
|
|
368
|
+
dynamic view payment-decision {
|
|
369
|
+
customer -> frontend "enter amount"
|
|
370
|
+
frontend -> backend "validate"
|
|
371
|
+
alt {
|
|
372
|
+
when 'within limit' {
|
|
373
|
+
backend -> payment-service "charge"
|
|
374
|
+
backend <- payment-service "result"
|
|
375
|
+
}
|
|
376
|
+
else 'over limit' {
|
|
377
|
+
backend -> frontend "rejected"
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
- Reach for `opt` for an "if without else" (a step group that may be skipped), and `try` / `catch` for success-vs-failure paths.
|
|
384
|
+
- `notes` on a step remains a lightweight way to document decision logic when a full branch block is not warranted.
|
|
385
|
+
|
|
386
|
+
## Anti-Patterns to Avoid
|
|
387
|
+
|
|
388
|
+
| Anti-pattern | Problem | Solution |
|
|
389
|
+
| ------------------------------------------------- | ------------------------------------------- | --------------------------------------------------- |
|
|
390
|
+
| Nested `parallel { parallel { ... } }` | `Nested parallel blocks are not allowed` | Put all concurrent steps in one `parallel {}` |
|
|
391
|
+
| `when` / `if` / `else` outside `alt` | `alternative branch must be inside "alt"` | Wrap branches in an `alt { ... }` block |
|
|
392
|
+
| `loop`/`opt`/`parallel`/`try` direct in `alt` | `can not be used as an alternative branch` | Nest them inside a `when` / `else` branch |
|
|
393
|
+
| `catch` without `try`, or `catch` after `finally` | Invalid try/catch/finally order | Keep order `try` → `catch?` → `finally?` |
|
|
394
|
+
| Too many steps in one view | Diagram becomes unreadable | Split into sub-views with `navigateTo` |
|
|
395
|
+
| Using `<-` for side-by-side actions | Implies return; violates sequence semantics | Use forward `->` or group with `parallel` |
|
|
396
|
+
| Forgetting `variant sequence` when UML needed | Wrong rendering | Add `variant sequence` if sequence diagram required |
|
|
397
|
+
|
|
398
|
+
## Predicate Filters in Dynamic Views
|
|
399
|
+
|
|
400
|
+
Dynamic views do not use predicates to generate or filter interaction steps. Steps must be listed explicitly.
|
|
401
|
+
|
|
402
|
+
You may still use normal include predicates to add context elements that do not participate in steps:
|
|
403
|
+
|
|
404
|
+
```likec4
|
|
405
|
+
dynamic view critical-flow {
|
|
406
|
+
frontend -> api "request"
|
|
407
|
+
api -> db "query"
|
|
408
|
+
|
|
409
|
+
include cloud.* where tag is #critical
|
|
410
|
+
include cloud.* where metadata.region is "eu"
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
dynamic view with-cache {
|
|
414
|
+
// Alternative flow with cache layer
|
|
415
|
+
frontend -> cache "check"
|
|
416
|
+
cache -> backend "if miss"
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## Reference and Examples
|
|
421
|
+
|
|
422
|
+
Full LikeC4 dynamic view docs: https://likec4.dev/dsl/views/dynamic/
|
|
423
|
+
|
|
424
|
+
Common scenarios:
|
|
425
|
+
|
|
426
|
+
- **Authentication flow** — customer → login → auth-service → database
|
|
427
|
+
- **CQRS pattern** — command → service → write-db (parallel: query-handler → read-db)
|
|
428
|
+
- **Webhook callback** — external-system → api (parallel within with navigateTo service-webhook-handler)
|
|
429
|
+
- **Pub/Sub flow** — publisher → message-bus → consumer (with parallel for multiple subscribers)
|
|
430
|
+
|
|
431
|
+
When the prompt asks for one parallel fan-out, keep sibling actions inside one `parallel { ... }` block. Do not split the three steps into separate one-step blocks.
|
|
432
|
+
|
|
433
|
+
### Sequence variant
|
|
434
|
+
|
|
435
|
+
```likec4
|
|
436
|
+
dynamic view checkout-flow {
|
|
437
|
+
variant sequence
|
|
438
|
+
customer -> frontend -> api
|
|
439
|
+
frontend <- api
|
|
440
|
+
customer <- frontend
|
|
441
|
+
}
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Use `variant sequence` when the prompt explicitly asks for UML-style sequence rendering.
|
|
445
|
+
|
|
446
|
+
## Quick anti-patterns
|
|
447
|
+
|
|
448
|
+
- Rewriting a requested chain as separate top-level steps
|
|
449
|
+
- Using forward arrows where the prompt explicitly asks for response arrows back out
|
|
450
|
+
- Spreading one requested parallel fan-out across multiple `parallel` blocks
|
|
451
|
+
- Omitting required hop-local tokens such as `technology` or `navigateTo`
|
|
452
|
+
- Placing `when` / `if` / `else` anywhere but directly inside `alt`
|
|
453
|
+
- Putting `loop` / `opt` / `parallel` / `try` as a direct child of `alt` instead of inside a branch
|
|
454
|
+
- Nesting `parallel` inside `parallel` (only block that cannot nest)
|
|
455
|
+
- Breaking try/catch/finally order (`try` → `catch?` → `finally?`)
|