@r0kshan/cairn 1.0.0-RC11 → 1.0.0-RC13
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 +113 -19
- package/THIRD-PARTY-NOTICES.md +11 -5
- package/bin/cairn.mjs +4756 -3889
- package/dist/cairn.mjs +4826 -3795
- package/licenses/elkjs-EPL-2.0.md +263 -0
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -31,7 +31,8 @@ Furthermore, complexe software architecture with many flows and component genera
|
|
|
31
31
|
| **Configurable dispositions** | `slide` and `page` dispositions available to suit different presentation requirements |
|
|
32
32
|
| **Spacial optimization** | Cairn aims to optimize space as much as possible (Still working on improving this functionnality) |
|
|
33
33
|
| **Typed diagrams with validation.** | Each view defines its element kinds and rules; `cairn validate` reports syntax, schema, and completeness issues as source-located, coded diagnostics, with a JSON mode for CI. |
|
|
34
|
-
| **
|
|
34
|
+
| **Flow matrix.** | `cairn matrix` exports the flow matrix as CSV, Markdown, or SVG — from any view, with the columns that view can fill. In infrastructure it splits protocol from port and annotates endpoints that sit in a network zone; headers localise via `style { lang: fr }`. The same table is available to embedders through `compile(source, { matrix: true })`. |
|
|
35
|
+
| **Author-controlled positioning.** | Layout is automatic, with three opt-in overrides for when it gets a diagram wrong: `order: 2` sequences a top-level element along the disposition's own reading direction (left to right in `wide`, top to bottom in `tall`) and sorts siblings inside a container, `A.right -> B.left` pins which side of an element a flow leaves and arrives on, and the arrow glyph carries the line style (`->` solid, `-->` dashed, `..>` dotted). |
|
|
35
36
|
| **Enterprise-view extras.** | Business objects on flows, an auto-generated legend, and a numbered-flow table via `flow-text: numbered`. |
|
|
36
37
|
| **French or English output.** | `style { lang: fr }` localizes band titles, legend, and matrix headers while keeping keywords English for portable sources (open to adding other languages if you find this usefull) |
|
|
37
38
|
| **In-built themes and customizable colours** | Whether using the default or a chosen in-built theme, element colours can be overriden for all elements of a given kind in the `style` block |
|
|
@@ -56,15 +57,10 @@ As a result here's a comparaison of the same diagram done with D2 (ELK Layout) v
|
|
|
56
57
|
</tr>
|
|
57
58
|
<tr>
|
|
58
59
|
<td>I encountered overlapping issues for which I couldn't find a workaround</td>
|
|
59
|
-
<td>The overlapping
|
|
60
|
+
<td>The overlapping labels have been addressed.</td>
|
|
60
61
|
</tr>
|
|
61
62
|
</table>
|
|
62
63
|
|
|
63
|
-
## Known limitations I'm working on
|
|
64
|
-
|
|
65
|
-
* While Cairn ensures 0 label overlap, flows on large diagrams still take a longer than neccessary route to the target element - issue [#26](https://github.com/R0kshan/cairn/issues/26) created to adress this
|
|
66
|
-
* At the moment Cairn doesn't give the user the possibility to control positioning - issue [#8](https://github.com/R0kshan/cairn/issues/8) created to adress this
|
|
67
|
-
|
|
68
64
|
## Usage
|
|
69
65
|
|
|
70
66
|
Either use the cli or the [ playground](https://cairn-psi-five.vercel.app/).
|
|
@@ -87,6 +83,27 @@ Every image below is rendered by cairn CLI from a `.cairn` source in [`examples/
|
|
|
87
83
|
<p align="center"><img src="examples/application-medium.svg" alt="Medium application view" width="760"></p>
|
|
88
84
|
<p align="center"><img src="examples/application-large.svg" alt="Large application view" width="760"></p>
|
|
89
85
|
|
|
86
|
+
#### System boundaries
|
|
87
|
+
|
|
88
|
+
`system` is a C4 system boundary: it groups the applications, queues and
|
|
89
|
+
datastores that belong to one system — the small example above uses one. The
|
|
90
|
+
flow matrix names an endpoint's nearest container, so a module reads
|
|
91
|
+
`Name (App)` and a queue sitting directly in the system reads `Name (System)`.
|
|
92
|
+
From [`examples/application-system.cairn`](examples/application-system.cairn):
|
|
93
|
+
|
|
94
|
+
```cairn
|
|
95
|
+
system ORDERS "Order platform" {
|
|
96
|
+
application ORDER_APP "Order management" {
|
|
97
|
+
module CAPTURE "Order\ncapture"
|
|
98
|
+
module VALIDATE "Order\nvalidation"
|
|
99
|
+
}
|
|
100
|
+
queue EVENTS "Order event\nbus"
|
|
101
|
+
datastore ORDER_DB "Order\nrepository"
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
<p align="center"><img src="examples/application-system.svg" alt="Application view with a system boundary" width="760"></p>
|
|
106
|
+
|
|
90
107
|
### Infrastructure view diagram examples from small to large
|
|
91
108
|
|
|
92
109
|
<p align="center"><img src="examples/infrastructure-small.svg" alt="Small infrastructure view" width="760"></p>
|
|
@@ -103,7 +120,7 @@ Colours are resolved at three levels — most specific wins. From lowest to high
|
|
|
103
120
|
|
|
104
121
|
1. **Theme defaults** — per-kind colours defined by the selected theme (fill, stroke, text for each element kind).
|
|
105
122
|
2. **Diagram-level per-kind overrides** — override colours for all elements of a given kind in the `style` block:
|
|
106
|
-
```
|
|
123
|
+
```cairn
|
|
107
124
|
style {
|
|
108
125
|
fill actor-group: #eef4fb
|
|
109
126
|
stroke actor-group: #7a9cc4 dashed
|
|
@@ -112,12 +129,12 @@ Colours are resolved at three levels — most specific wins. From lowest to high
|
|
|
112
129
|
}
|
|
113
130
|
```
|
|
114
131
|
3. **Inline per-element styles** — override colour for a single element:
|
|
115
|
-
```
|
|
132
|
+
```cairn
|
|
116
133
|
block API "API gateway" { style { fill: #e8f5e9 stroke: #2e7d32 text: #1b5e20 } }
|
|
117
134
|
```
|
|
118
135
|
|
|
119
136
|
Flows can also be coloured inline:
|
|
120
|
-
```
|
|
137
|
+
```cairn
|
|
121
138
|
COM_CTR -> OBS : "Alerts…" { label: above stroke: dashed #a33 text: #a33 }
|
|
122
139
|
```
|
|
123
140
|
|
|
@@ -125,11 +142,93 @@ See [`examples/colors-custom.cairn`](examples/colors-custom.cairn) for a full ex
|
|
|
125
142
|
|
|
126
143
|
<p align="center"><img src="examples/colors-custom.svg" alt="Custom colours" width="620"></p>
|
|
127
144
|
|
|
145
|
+
### Positioning and flow line styles
|
|
146
|
+
|
|
147
|
+
**Line style** — carried by the arrow glyph:
|
|
148
|
+
|
|
149
|
+
```cairn
|
|
150
|
+
TRIAGE -> TASKS (MQ, JSON) # solid — the default
|
|
151
|
+
SCORING --> REINSURER (SFTP, CSV) # dashed
|
|
152
|
+
TRIAGE ..> REINSURER (API_REST, JSON) # dotted
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Attachment sides** — pin either endpoint, or both, with `left`, `right`,
|
|
156
|
+
`top` or `bottom`:
|
|
157
|
+
|
|
158
|
+
```cairn
|
|
159
|
+
FORM.right -> TRIAGE.left (API_REST, JSON) # both ends pinned
|
|
160
|
+
SCORING -> TASKS.right (MQ, JSON) # only the arrival pinned
|
|
161
|
+
SCORING.top -> TRIAGE.top (API_REST, JSON) # a backward flow, pinned both ends
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
<p align="center"><img src="examples/positioning-sides.svg" alt="Flow attachment sides" width="760"></p>
|
|
165
|
+
|
|
166
|
+
**Element ordering** — `order:` is a statement in the element's own body, not a
|
|
167
|
+
`style` entry. Lower comes first along the disposition's reading direction: left
|
|
168
|
+
to right in `wide`/`slide`, top to bottom in `tall`/`page`. From
|
|
169
|
+
[`examples/placement/reading-order.cairn`](examples/placement/reading-order.cairn):
|
|
170
|
+
|
|
171
|
+
```cairn
|
|
172
|
+
application BACKEND_L1 "Line 1 backend" {
|
|
173
|
+
order: 1
|
|
174
|
+
module MSG_L1 "Messaging\nhandler"
|
|
175
|
+
}
|
|
176
|
+
application BACKEND_L2 "Line 2 backend" {
|
|
177
|
+
order: 2
|
|
178
|
+
module MSG_L2 "Messaging\nhandler"
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
<p align="center"><img src="examples/placement/reading-order.svg" alt="Top-level elements sequenced by order:" width="620"></p>
|
|
183
|
+
|
|
184
|
+
Inside a container the axis flips: `order:` sorts the siblings sharing a layer —
|
|
185
|
+
top to bottom in `wide`, left to right in `tall`. From
|
|
186
|
+
[`examples/positioning.cairn`](examples/positioning.cairn):
|
|
187
|
+
|
|
188
|
+
```cairn
|
|
189
|
+
actor-group STAFF "Payment actors" {
|
|
190
|
+
actor OPERATOR "Payment operator" { order: 1 }
|
|
191
|
+
actor AUDITOR "Compliance auditor" { order: 2 }
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Values need not be contiguous, and the hint never moves an element into another
|
|
196
|
+
band. Where a declared order contradicts a flow, the order wins and the flow is
|
|
197
|
+
drawn running backwards.
|
|
198
|
+
|
|
199
|
+
<p align="center"><img src="examples/positioning.svg" alt="Element ordering, pinned sides and arrow glyphs" width="760"></p>
|
|
200
|
+
|
|
201
|
+
More examples: [`examples/placement/`](examples/placement/) shows one shape four
|
|
202
|
+
ways (`baseline.cairn`, `sides.cairn`, `reading-order.cairn`,
|
|
203
|
+
`flow-label.cairn`), and [`examples/dispositions/`](examples/dispositions/) ships
|
|
204
|
+
the attachment-sides file as `wide`, `tall`, `slide` and `page` variants.
|
|
205
|
+
|
|
206
|
+
**Label position** — this one *is* style, so it lives in the `style` block and
|
|
207
|
+
resolves at the usual three levels (view default, diagram, inline per flow). From
|
|
208
|
+
[`examples/placement/flow-label.cairn`](examples/placement/flow-label.cairn):
|
|
209
|
+
|
|
210
|
+
```cairn
|
|
211
|
+
style {
|
|
212
|
+
flow-label: above # on-line (default) | above | below
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
AGENT -> RECEIVE : "File a claim" # above, from the style block
|
|
216
|
+
ASSIGN -> SETTLE : "Request settlement" { label: below } # overridden per flow
|
|
217
|
+
TRACE -> STORE : "Archive the trace" { label: on-line } # back to the default
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
<p align="center"><img src="examples/placement/flow-label.svg" alt="Flow label positions" width="760"></p>
|
|
221
|
+
|
|
222
|
+
`on-line` centres the text on the run behind a halo; `above`/`below` lift it clear
|
|
223
|
+
by a fixed offset first. Either way the label is settled afterwards, so the
|
|
224
|
+
zero-overlap gate holds. Every other diagram in this README shows the `on-line`
|
|
225
|
+
default.
|
|
226
|
+
|
|
128
227
|
### Dispositions
|
|
129
228
|
|
|
130
229
|
Same diagram different disposition :
|
|
131
|
-
- [Slide disposition](https://cairn-psi-five.vercel.app/#src=
|
|
132
|
-
- [Page disposition](https://cairn-psi-five.vercel.app/#src=
|
|
230
|
+
- [Slide disposition](https://cairn-psi-five.vercel.app/#src=ZGlhZ3JhbSBsb2dpY2FsICJPbmxpbmUgYXBwb2ludG1lbnQgYm9va2luZyDigJQgbG9naWNhbCB2aWV3IgpzdHlsZSB7IGRpc3Bvc2l0aW9uOiBzbGlkZSB9CgphY3Rvci1ncm91cCBVU0VSUyAiVXNlcnMiIHsKICBhY3RvciBQQVRJRU5UICJQYXRpZW50Igp9CgphY3Rvci1ncm91cCBTVEFGRiAiU3RhZmYiIHsKICBhY3RvciBTRUNSRVRBUlkgIk1lZGljYWwgc2VjcmV0YXJ5Igp9CgpzeXN0ZW0gQk9PS0lORyAiQXBwb2ludG1lbnQgYm9va2luZyBzeXN0ZW0iIHsKICBsYXllciBGUk9OVCAiQm9va2luZyBjaGFubmVscyIgewogICAgYmxvY2sgUE9SVEFMICJCb29raW5nXG5wb3J0YWwiCiAgfQogIGxheWVyIEJVU0lORVNTICJBcHBvaW50bWVudCBtYW5hZ2VtZW50IiB7CiAgICBibG9jayBTQ0hFRFVMRVIgIlNsb3Rcbm1hbmFnZW1lbnQiCiAgICBibG9jayBOT1RJRiAiTm90aWZpY2F0aW9ucyIKICB9Cn0KCmV4dGVybmFsIEVYVCAiRXh0ZXJuYWwgc3lzdGVtcyIgewogIGJsb2NrIFNNUyAiU01TIGdhdGV3YXkiCn0KCiMgLS0tLSBidXNpbmVzcyBvYmplY3RzIC0tLS0KYnVzaW5lc3Mtb2JqZWN0IEJPX0FQUFQgIkFwcG9pbnRtZW50IiAic2xvdCBib29rZWQgYnkgYSBwYXRpZW50IHdpdGggYSBwcmFjdGl0aW9uZXIiCmJ1c2luZXNzLW9iamVjdCBCT19TTE9UICJTbG90IiAidGltZSB3aW5kb3cgb3BlbiBmb3IgYm9va2luZyIKClBBVElFTlQgLT4gUE9SVEFMIDogIlNlYXJjaCBhIHNsb3RcbmFuZCBib29rIiBbQk9fU0xPVF0KUE9SVEFMIC0+IFNDSEVEVUxFUiA6ICJCb29raW5nIHJlcXVlc3QiIFtCT19BUFBUXQpTQ0hFRFVMRVIgLT4gTk9USUYgOiAiQXBwb2ludG1lbnQgY29uZmlybWVkIiBbQk9fQVBQVF0KTk9USUYgLT4gU01TIDogIlNlbmQgU01TIHJlbWluZGVyIgpTRUNSRVRBUlkgLT4gU0NIRURVTEVSIDogIk9wZW4gLyBibG9ja1xuc2xvdHMiIFtCT19TTE9UXQpTQ0hFRFVMRVIgLT4gUEFUSUVOVCA6ICJBcHBvaW50bWVudFxuY29uZmlybWF0aW9uIiBbQk9fQVBQVF0KCmxlZ2VuZCB7CiAgbm90ZSAiSGVhbHRoIGRhdGEgaXMgc3RvcmVkIG9uIGNlcnRpZmllZCBoZWFsdGgtZGF0YS1ob3N0aW5nIGluZnJhc3RydWN0dXJlIgp9Cg==)
|
|
231
|
+
- [Page disposition](https://cairn-psi-five.vercel.app/#src=ZGlhZ3JhbSBsb2dpY2FsICJPbmxpbmUgYXBwb2ludG1lbnQgYm9va2luZyDigJQgbG9naWNhbCB2aWV3IgpzdHlsZSB7IGRpc3Bvc2l0aW9uOiBwYWdlIH0KCmFjdG9yLWdyb3VwIFVTRVJTICJVc2VycyIgewogIGFjdG9yIFBBVElFTlQgIlBhdGllbnQiCn0KCmFjdG9yLWdyb3VwIFNUQUZGICJTdGFmZiIgewogIGFjdG9yIFNFQ1JFVEFSWSAiTWVkaWNhbCBzZWNyZXRhcnkiCn0KCnN5c3RlbSBCT09LSU5HICJBcHBvaW50bWVudCBib29raW5nIHN5c3RlbSIgewogIGxheWVyIEZST05UICJCb29raW5nIGNoYW5uZWxzIiB7CiAgICBibG9jayBQT1JUQUwgIkJvb2tpbmdcbnBvcnRhbCIKICB9CiAgbGF5ZXIgQlVTSU5FU1MgIkFwcG9pbnRtZW50IG1hbmFnZW1lbnQiIHsKICAgIGJsb2NrIFNDSEVEVUxFUiAiU2xvdFxubWFuYWdlbWVudCIKICAgIGJsb2NrIE5PVElGICJOb3RpZmljYXRpb25zIgogIH0KfQoKZXh0ZXJuYWwgRVhUICJFeHRlcm5hbCBzeXN0ZW1zIiB7CiAgYmxvY2sgU01TICJTTVMgZ2F0ZXdheSIKfQoKIyAtLS0tIGJ1c2luZXNzIG9iamVjdHMgLS0tLQpidXNpbmVzcy1vYmplY3QgQk9fQVBQVCAiQXBwb2ludG1lbnQiICJzbG90IGJvb2tlZCBieSBhIHBhdGllbnQgd2l0aCBhIHByYWN0aXRpb25lciIKYnVzaW5lc3Mtb2JqZWN0IEJPX1NMT1QgIlNsb3QiICJ0aW1lIHdpbmRvdyBvcGVuIGZvciBib29raW5nIgoKUEFUSUVOVCAtPiBQT1JUQUwgOiAiU2VhcmNoIGEgc2xvdFxuYW5kIGJvb2siIFtCT19TTE9UXQpQT1JUQUwgLT4gU0NIRURVTEVSIDogIkJvb2tpbmcgcmVxdWVzdCIgW0JPX0FQUFRdClNDSEVEVUxFUiAtPiBOT1RJRiA6ICJBcHBvaW50bWVudCBjb25maXJtZWQiIFtCT19BUFBUXQpOT1RJRiAtPiBTTVMgOiAiU2VuZCBTTVMgcmVtaW5kZXIiClNFQ1JFVEFSWSAtPiBTQ0hFRFVMRVIgOiAiT3BlbiAvIGJsb2NrXG5zbG90cyIgW0JPX1NMT1RdClNDSEVEVUxFUiAtPiBQQVRJRU5UIDogIkFwcG9pbnRtZW50XG5jb25maXJtYXRpb24iIFtCT19BUFBUXQoKbGVnZW5kIHsKICBub3RlICJIZWFsdGggZGF0YSBpcyBzdG9yZWQgb24gY2VydGlmaWVkIGhlYWx0aC1kYXRhLWhvc3RpbmcgaW5mcmFzdHJ1Y3R1cmUiCn0K)
|
|
133
232
|
|
|
134
233
|
|
|
135
234
|
### Numbered flows
|
|
@@ -174,15 +273,8 @@ brew install R0kshan/tap/cairn
|
|
|
174
273
|
# Windows — Scoop
|
|
175
274
|
scoop bucket add cairn https://github.com/R0kshan/scoop-bucket
|
|
176
275
|
scoop install cairn
|
|
177
|
-
|
|
178
|
-
# npm (requires Node ≥ 22.6)
|
|
179
|
-
npm i -g @r0kshan/cairn@unstable
|
|
180
276
|
```
|
|
181
277
|
|
|
182
|
-
> `@unstable` is not optional: cairn is pre-stable, so tagged versions publish to
|
|
183
|
-
> that dist-tag and there is no `latest` yet — a bare `npm i -g @r0kshan/cairn`
|
|
184
|
-
> fails with `No matching version found` until the first stable release.
|
|
185
|
-
|
|
186
278
|
From source (no release needed — requires Node ≥ 22.6):
|
|
187
279
|
|
|
188
280
|
```sh
|
|
@@ -234,6 +326,8 @@ On validation errors nothing is written and the exit code is 1; warnings are pri
|
|
|
234
326
|
cairn matrix my-infra.cairn --format csv # csv (default) | md | svg · -o to set the path
|
|
235
327
|
```
|
|
236
328
|
|
|
329
|
+
Every view exports one; the columns follow the view (infrastructure keeps protocol and port, application keeps the protocol alone, logical keeps just the exchange).
|
|
330
|
+
|
|
237
331
|
### Rebuild on every save
|
|
238
332
|
|
|
239
333
|
```sh
|
package/THIRD-PARTY-NOTICES.md
CHANGED
|
@@ -12,8 +12,13 @@ theirs is distributed.
|
|
|
12
12
|
Version 0.12.0, inlined unmodified. Upstream: https://github.com/kieler/elkjs
|
|
13
13
|
|
|
14
14
|
Declared license: `EPL-2.0 OR GPL-3.0-or-later`. cairn elects **EPL-2.0** — full
|
|
15
|
-
text
|
|
16
|
-
elkjs
|
|
15
|
+
text in [`licenses/elkjs-EPL-2.0.md`](./licenses/elkjs-EPL-2.0.md), a verbatim
|
|
16
|
+
copy of elkjs' own `LICENSE.md`, upstream at https://www.eclipse.org/legal/epl-2.0/.
|
|
17
|
+
|
|
18
|
+
That copy is vendored rather than referenced because elkjs is a *devDependency*:
|
|
19
|
+
the published package installs zero dependencies, so `node_modules/elkjs/` never
|
|
20
|
+
reaches a consumer while the inlined code does. EPL-2.0 §3.1(b) requires the
|
|
21
|
+
license to travel with the distributed form, so `files` ships it in the tarball.
|
|
17
22
|
|
|
18
23
|
Per EPL-2.0 §3.1(a): the source code for elkjs is available under the EPL-2.0,
|
|
19
24
|
and can be obtained from https://github.com/kieler/elkjs or from the published
|
|
@@ -26,6 +31,7 @@ covers cairn's own code only.
|
|
|
26
31
|
|
|
27
32
|
---
|
|
28
33
|
|
|
29
|
-
If the set of inlined dependencies changes, update this file
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
If the set of inlined dependencies changes, update this file **and** `licenses/`
|
|
35
|
+
in the same commit — a notice that names a license text the tarball doesn't carry
|
|
36
|
+
is the failure mode this section exists to prevent. `files` in `package.json`
|
|
37
|
+
ships both with the npm package.
|