umlimator 0.19.0 → 0.21.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 CHANGED
@@ -22,11 +22,10 @@ drill-down, a data pipeline, an AI agent's skills, and host pages for embedding,
22
22
  straight; orthogonal lines that never run through a card, room for every label, containers kept apart, and cards with
23
23
  no lines in a row of their own, under the view or at the bottom of their box. The same model gives the same picture.
24
24
  - **Reading**: animated flow, neighbours lit on selection, numbered steps, tours, minimap, light and dark themes.
25
- - **Card shapes**: three notations. `box` (the default) draws every card as a rounded box, as before. `c4` draws people,
26
- browser apps, phones, databases, queues and files as the C4 model's tools do. `uml` draws UML 2.5's actors, nodes,
27
- artifacts, packages and data stores, with UML's component icon on a box. A card's own `shape` wins in any notation.
28
- The notation comes from the model, a view, `render()`, the page's toggle or the link; switching it draws the cards
29
- again and lays nothing out ([`examples/notations.html`](examples/notations.html)).
25
+ - **Card shapes**: one style, the union of what the C4 model's tools and UML 2.5 draw: people, robots, browser apps,
26
+ phones, terminals, queues, packages, hosts, data stores, files and hooks, each by its card's kind, and a rounded box
27
+ where no shape says more. A card's own `shape` wins. Each shape keeps to its card's box, so the layout is the same
28
+ ([`examples/notations.html`](examples/notations.html)).
30
29
  - **Exploring**: every path between two cards, or everything a card reaches, lit on the map; a view in plain sentences
31
30
  (`describe()`); a tour along any path the host names.
32
31
  - **Live data**: marks over the map without touching the model (`overlay()`): flow as fast as the traffic, errors that
@@ -58,6 +57,31 @@ drill-down, a data pipeline, an AI agent's skills, and host pages for embedding,
58
57
  ([`examples/bookshop-packages.json`](examples/bookshop-packages.json), [what it covers](docs/conformance/uml-package.md)).
59
58
  Ownership is edited by dropping an element into a box, or with the Owner field; both are checked by their types'
60
59
  rules, and the PDF's tables list slots and element kinds.
60
+ - **UML sequence and communication diagrams** (0.20.0): lifelines on a time axis with calls, async messages, replies,
61
+ creates and deletes, activation bars derived from the messages, `alt`, `opt`, `loop`, `par` and `break` frames with
62
+ their guards, and interaction uses ([`examples/checkout-sequence.json`](examples/checkout-sequence.json),
63
+ [what it covers](docs/conformance/uml-sequence.md)); the same interaction as lifelines joined by connectors, each
64
+ link's messages a stack of numbered rows (1, 1.1, 1.1.2) ([`examples/checkout-communication.json`](examples/checkout-communication.json),
65
+ [what it covers](docs/conformance/uml-communication.md)). Messages are inserted, moved in time, wrapped in a frame and
66
+ deleted on the canvas, by pointer and by key, each gesture an `edit` event; checked by the types' rules; a sequence
67
+ diagram is read from and written to Mermaid's `sequenceDiagram`, and an OpenTelemetry trace becomes one
68
+ (`umlimator.py trace --diagram uml.sequence`). The MCP server, the `map-repo` skill and the diff Action learn these
69
+ types in one package after 0.20.0; until then a reorder of a view's messages shows in a diff as changed, not moved.
70
+ - **UML use case, activity, state machine and interaction overview diagrams** (0.21.0): actors as stick figures, use
71
+ cases as ellipses with their extension points, a subject as a box holding its use cases, include, extend and
72
+ generalization ([`examples/shopping-use-cases.json`](examples/shopping-use-cases.json),
73
+ [what it covers](docs/conformance/uml-use-case.md)); actions, object nodes, data stores, send and accept actions, call
74
+ behaviour actions that open the activity they call, and the control nodes, in lanes (partitions, nested)
75
+ ([`examples/fulfil-activity.json`](examples/fulfil-activity.json), [what it covers](docs/conformance/uml-activity.md));
76
+ states with their entry, do and exit activities and internal transitions, composite states as boxes, orthogonal
77
+ regions with dashed dividers, every pseudostate, and transitions written `trigger [guard] / effect`
78
+ ([`examples/order-states.json`](examples/order-states.json), [what it covers](docs/conformance/uml-state-machine.md));
79
+ interaction uses and inline interactions, drawn with their sequence diagram inside, joined by the activity's control
80
+ nodes ([`examples/buy-book-overview.json`](examples/buy-book-overview.json),
81
+ [what it covers](docs/conformance/uml-interaction-overview.md)). Lines end on the outline of a circle, a diamond, a
82
+ bar or an ellipse. F2 edits a transition's or a flow's label through its parts; a drop changes a node's lane or a
83
+ state's region. A state machine is read from and written to Mermaid's `stateDiagram`. The MCP server's read tools and
84
+ the diff Action are tested on all four.
61
85
  - **Export**: any view as a stand-alone SVG or PNG, in the browser or from the CLI; the whole map as one PDF to hand in
62
86
  for a review: a cover with the contents, each view with its legend and tables of its cards, lines and boxes, then the
63
87
  rules (`umlimator.py pdf`).
@@ -80,7 +104,7 @@ drill-down, a data pipeline, an AI agent's skills, and host pages for embedding,
80
104
  npm install umlimator
81
105
  ```
82
106
 
83
- Or from GitHub, at a tag or any commit: `"umlimator": "github:zintaen/umlimator#v0.19.0"`. npm 12 refuses git
107
+ Or from GitHub, at a tag or any commit: `"umlimator": "github:zintaen/umlimator#v0.21.0"`. npm 12 refuses git
84
108
  dependencies unless the project opts in, so that also needs `allow-git=root` in the `.npmrc` next to `package.json`.
85
109
 
86
110
  ## Embed
@@ -125,11 +149,8 @@ function MapView({ model, onSelect }) {
125
149
  - `map.lens(id)` puts one of the model's lenses on the map. `critical(model, view, { from, to, by })` finds the slowest
126
150
  or costliest path, `whatIf(model, view, { remove })` what loses its way when cards go down, and
127
151
  `sequenceFromTrace(model, spans, { view, match })` keeps a trace as a numbered view; all three in Node too.
128
- - `shapes: 'box' | 'c4' | 'uml'` draws every view in that notation, over each view's own (and the model's).
129
- `map.shapes` reads the notation shown and sets another (`null`: each view's own again); the cards are drawn again from
130
- the geometry they have, with the camera, selection and marks kept, and nothing is laid out.
131
152
  - `editable: true` turns on editing gestures ([docs/editing.md](docs/editing.md); `examples/edit.html` is a working host).
132
- - `import { render, apply, history } from 'umlimator/all'` draws diagram types too: a class, object or package diagram, whose gestures emit
153
+ - `import { render, apply, history } from 'umlimator/all'` draws diagram types too: a class, object, package, sequence, communication, use case, activity, state machine or interaction overview diagram, whose gestures emit
133
154
  `edit` transactions that `apply(model, e.commands)` turns into the next model (`examples/class-editor.html` is a
134
155
  working host). `umlimator` alone draws maps, and a typed view as plain cards with a warning.
135
156
  - `diff(before, after)` returns `after` with each card and line marked added, changed or removed, what changed in words,
@@ -172,8 +193,7 @@ the map is drawn, and stay where scripts don't run ([`examples/element.html`](ex
172
193
  - **Attributes**: `view`, `minimap`, `controls="false"`, `wheel="ctrl"` (the wheel zooms only with Ctrl or ⌘, and scrolls
173
194
  the page otherwise, as a map in a document should), `height` (a number is pixels; 480 by default, or size it in CSS)
174
195
  and `theme` (`light` or `dark`: theme.css's palette for that map, whatever the page's). Changing one draws the map
175
- again, and removing the element destroys it. `shapes` (`box`, `c4` or `uml`) is the notation; changing it draws the
176
- cards again in the map drawn, with nothing loaded or laid out again.
196
+ again, and removing the element destroys it.
177
197
  - **Events**: `umlimator:select`, `umlimator:open` (cancel it to stay) and `umlimator:viewchange`, the map's event as
178
198
  `detail`; `load` once it is drawn, `error` when it can't be. `el.map` is the `render()` handle.
179
199
  - **Colours**: theme.css, as above, or your own `--um-*` variables. The element fetches nothing but its model.
@@ -208,8 +228,9 @@ path. The full schema is `engine/references/schema.md` (§ Map model); `examples
208
228
  A model file that starts with `"$schema": "<path to>/umlimator.schema.json"` (exported as `umlimator/schema.json`)
209
229
  gets completion and checks in editors, and `validate(model)` lists its errors and warnings, each with where it is.
210
230
  `"schemaVersion": 2` marks a model that may hold typed elements and typed views (`docs/diagrams/model.md`). A view whose
211
- `diagram` is `"uml.class"`, `"uml.object"` or `"uml.package"` is a UML class, object or package diagram, drawn by
212
- `umlimator/all` and the CLI; a type not drawn yet shows its
231
+ `diagram` is `"uml.class"`, `"uml.object"`, `"uml.package"`, `"uml.sequence"`, `"uml.communication"`, `"uml.use-case"`,
232
+ `"uml.activity"`, `"uml.state-machine"` or `"uml.interaction-overview"` is a UML class, object, package, sequence,
233
+ communication, use case, activity, state machine or interaction overview diagram, drawn by `umlimator/all` and the CLI; a type not drawn yet shows its
213
234
  nodes as plain cards, with a warning. A model with no `schemaVersion` is a map, as always, and a version newer than the
214
235
  module reads is an error.
215
236
 
@@ -223,7 +244,7 @@ kinds such as `public`, `lane`, `script`, `hook` and `board` work too). Fields b
223
244
  | node | `noSub` | the name only; the description stays in the details panel |
224
245
  | node | `opensView`, `opensCount` | the view the card opens, which may not be loaded yet, and the ⤢ number for it |
225
246
  | node | `owner` | who owns the card (a team): rules and lenses pick by it, and a lens can ring cards by owner |
226
- | node | `shape` | the card's own shape in every notation: `box`, `person`, `browser`, `mobile`, `cylinder`, `pipe`, `document`, `hexagon`, `robot`, `terminal`, `window`, `folder` or `node` |
247
+ | node | `shape` | the card's own shape, over the one its kind draws: `box`, `person`, `browser`, `mobile`, `cylinder`, `pipe`, `document`, `hexagon`, `robot`, `terminal`, `window`, `folder` or `node` |
227
248
  | node, edge | `edited` | a marker on the card or line |
228
249
  | edge | `kind` | what the line means, drawn as its colour: `calls` (default), `feeds`, `triggers`, `state`, `guard` |
229
250
  | edge | `weight` | 1, 2 or 3: how much the line stands for, drawn as its width |
@@ -239,9 +260,8 @@ kinds such as `public`, `lane`, `script`, `hook` and `board` work too). Fields b
239
260
  | view | `repair: false` | no port repair |
240
261
  | view | `subAndChips` | cards 80 px tall that show their sub-line, then their chips |
241
262
  | view | `kindsFromLabels` | a line whose edges name no `kind` takes one guessed from its label |
242
- | view, model | `shapes` | the notation the cards are drawn in: `box` (default), `c4` or `uml`; a view's wins over the model's ([what each draws](docs/module-api.md#card-shapes-box-c4-and-uml)) |
243
263
  | container | `badges` | tabs on the box's border |
244
- | container | `tone` | a palette name, as a badge's: the region behind the box tinted in it, its border dashed and its title in the tone (in `c4`, every box is dashed) |
264
+ | container | `tone` | a palette name, as a badge's: the region behind the box tinted in it, its border dashed and its title in the tone |
245
265
  | model | `rules` | what must hold: no line `from` some cards `to` others (picked by id, kind, box or owner), or `noCycles` between boxes |
246
266
  | model | `stories` | walk-throughs: steps that each set the view, camera, selection, highlight, tour and caption |
247
267
  | model | `lenses` | ways to look at the map: what `pick` picks (by id, kind, box, owner or `line` kind) lit, the rest dimmed; `color: "owner"` rings cards by owner |
@@ -264,6 +284,35 @@ In a version-2 model, a class diagram (`examples/sales-classes.json`; every fiel
264
284
  | view | `direction` | `"down"` lays it out top to bottom, the general class above (default `"right"`) |
265
285
  | view | `present` | per element: `collapsed` compartments, and at most `rows` rows each, then "+k more" |
266
286
 
287
+ A sequence diagram (`examples/checkout-sequence.json`, [`docs/conformance/uml-sequence.md`](docs/conformance/uml-sequence.md))
288
+ and a communication diagram (`examples/checkout-communication.json`,
289
+ [`docs/conformance/uml-communication.md`](docs/conformance/uml-communication.md)), from 0.20.0:
290
+
291
+ | On | Field | What it does |
292
+ |---|---|---|
293
+ | node | `type` | `uml.Lifeline`; its `props.represents` is what it is an instance of, drawn `name : Type` |
294
+ | edge | `type` | `uml.Message`; on a communication view also `uml.Connector`, the link messages are sent along |
295
+ | edge | `props` | a message's `sort` (`call`, `async`, `reply`, `create`, `delete`) and a reply's `replyTo`, the call it answers |
296
+ | view | `diagram` | `"uml.sequence"` or `"uml.communication"` |
297
+ | view | `edges` | a sequence view's messages and interaction uses (`uml.InteractionUse`, `props.covers`), inline and in time order; a communication view's connectors, then its messages, by id, in order. Bars and numbers are derived |
298
+ | view | `fragments` | a sequence view's combined fragments (`uml.CombinedFragment`, `props.operator`), each with its operands as `members` (`label` the guard); a message's or fragment's `parent` is its operand |
299
+
300
+ A use case diagram, an activity diagram, a state machine diagram and an interaction overview diagram
301
+ (`examples/shopping-use-cases.json`, `fulfil-activity.json`, `order-states.json` and `buy-book-overview.json`; each
302
+ type's note in [`docs/conformance/`](docs/conformance/)), from 0.21.0:
303
+
304
+ | On | Field | What it does |
305
+ |---|---|---|
306
+ | node, member, edge | `type` | use case: `uml.Actor`, `uml.UseCase` (members `uml.ExtensionPoint`), `uml.Subject`; lines `uml.Association`, `uml.Include`, `uml.Extend`, `uml.Generalization` |
307
+ | node, edge | `type` | activity: `uml.Action`, `uml.CallBehaviorAction`, `uml.SendSignalAction`, `uml.AcceptEventAction`, `uml.ObjectNode`, `uml.DataStoreNode`, `uml.InitialNode`, `uml.ActivityFinalNode`, `uml.FlowFinalNode`, `uml.DecisionNode`, `uml.MergeNode`, `uml.ForkNode`, `uml.JoinNode`, `uml.ActivityPartition`; lines `uml.ControlFlow`, `uml.ObjectFlow` |
308
+ | node, member, edge | `type` | state machine: `uml.State` (members `uml.Region`, `uml.InternalTransition`), `uml.Pseudostate`, `uml.FinalState`; lines `uml.Transition` |
309
+ | node, edge | `type` | interaction overview: the activity's control nodes, `uml.InteractionUse`, `uml.Interaction` (an inline interaction); lines `uml.ControlFlow` |
310
+ | node | `parent` | a use case's subject; an activity node's partition (its lane), a partition's enclosing partition; a substate's state or region |
311
+ | node | `opensView` | the activity a call behaviour action calls; the sequence view an interaction use or inline interaction shows |
312
+ | node | `props` | a state's `entry`, `do`, `exit`; a pseudostate's `kind` (`initial`, `choice`, `junction`, `fork`, `join`, `shallowHistory`, `deepHistory`, `terminate`) |
313
+ | edge, member | `props` | an extend's `extensionPoints` (ids) and `condition`; a flow's `guard` (its `label` is its name); a transition's or internal transition's `trigger`, `guard` and `effect`, drawn `trigger [guard] / effect` |
314
+ | view | `diagram` | `"uml.use-case"`, `"uml.activity"`, `"uml.state-machine"` or `"uml.interaction-overview"` |
315
+
267
316
  ## Command line
268
317
 
269
318
  ```bash
@@ -279,11 +328,14 @@ python3 umlimator.py check page.html --expand # also ea
279
328
  python3 umlimator.py record bike-share.html --story ride --out ride.png # bike-share's story as an animated PNG, its tours riding
280
329
  python3 umlimator.py import workspace.dsl --out model.json # a diagram you have already, as a model
281
330
  python3 umlimator.py import classes.mmd --out classes.json # a Mermaid classDiagram, as a UML class diagram (needs Node)
331
+ python3 umlimator.py import checkout.mmd --out checkout.json # a Mermaid sequenceDiagram, as a UML sequence diagram (needs Node)
332
+ python3 umlimator.py import order.mmd --out order.json # a Mermaid stateDiagram, as a UML state machine diagram (needs Node)
282
333
  python3 umlimator.py render examples/sales-classes.json --out classes.html # a class diagram's page; stills, check and pdf take it too
283
334
  docker compose config --format json > compose.json && python3 umlimator.py import compose.json --out model.json
284
335
  kubectl get deploy,sts,svc,ing -A -o json > cluster.json && python3 umlimator.py import cluster.json --out model.json
285
336
  python3 umlimator.py pdf page.html --out map.pdf # every view in one PDF: a cover, each view with its tables, the rules
286
337
  python3 umlimator.py trace model.json trace.json --view ride-end --match match.json --out model.json # an OTLP trace kept as a numbered view
338
+ python3 umlimator.py trace model.json trace.json --view ride-end --match match.json --diagram uml.sequence --out traced.json # ... as a UML sequence diagram, in a version-2 model
287
339
  python3 umlimator.py mcp model.json # an MCP server over stdio, for an AI assistant (below)
288
340
  ```
289
341
 
@@ -291,13 +343,14 @@ python3 umlimator.py mcp model.json # an MCP
291
343
 
292
344
  `import` reads Structurizr DSL (people, systems, containers and components, their relationships, and the workspace's
293
345
  views), C4-PlantUML (its element, relationship and boundary macros), Mermaid (`flowchart` or `graph`, and `C4Context`,
294
- `C4Container` or `C4Component`; a `classDiagram` becomes a UML class diagram, read through Node), and the JSON of `docker compose config` (services, `depends_on`, networks) and of
346
+ `C4Container` or `C4Component`; a `classDiagram` becomes a UML class diagram, a `sequenceDiagram` a UML sequence
347
+ diagram and a `stateDiagram` a UML state machine diagram, each read through Node), and the JSON of `docker compose config` (services, `depends_on`, networks) and of
295
348
  `kubectl get` (workloads, Services, Ingresses). It tells the format from the content, then the extension; `--format`
296
349
  decides. Groups, boundaries, subgraphs, networks and namespaces become boxes; Structurizr's views stay views, a card
297
350
  opening the view below it; `examples/clinic.json` is `examples/clinic.dsl`, imported. What each element becomes, and
298
351
  what is left out: [docs/module-api.md § Import](docs/module-api.md#import-90). Whatever the file holds that `import`
299
- doesn't read is listed on stderr with its line (in JSON, its path). A Structurizr, C4-PlantUML or Mermaid C4 source is
300
- drawn in the `c4` notation: its people as people (`person`, or `user` outside the system), its phone apps as phones. A
352
+ doesn't read is listed on stderr with its line (in JSON, its path). A Structurizr, C4-PlantUML or Mermaid C4 source's
353
+ people are people (`person`, or `user` outside the system), and its phone apps phones. A
301
354
  Structurizr workspace's `styles` give its elements their shapes (`shape Person`, `Cylinder`, `WebBrowser`, ...), in
302
355
  Structurizr's own order; a shape the map has no counterpart for is listed in `notImported`.
303
356
 
@@ -311,8 +364,8 @@ the title and "page N of M". It takes `--views` and `--theme`, as `stills` does,
311
364
  default; both across).
312
365
 
313
366
  The page has breadcrumbs, a details panel per card (with the slowest path from it and what-if), ⌘K search, deep links
314
- (`#view=<id>&node=<id>`, `#story=<id>&step=<n>` for a story's step, `#lens=<id>` and `#shapes=c4`), stories, lenses, a
315
- card shapes toggle next to ◐ (box, c4, uml; the page keeps the reader's choice), and export. For
367
+ (`#view=<id>&node=<id>`, `#story=<id>&step=<n>` for a story's step, `#lens=<id>`), stories, lenses, a
368
+ light and dark toggle (◐), and export. For
316
369
  scripts and tests, it keeps its map's handle on `window.umlimatorMap`: the `Handle` that `render()` returns (`setView()`,
317
370
  `highlight()`, `tour()`, `play()` ...).
318
371
  `stills` skips a view whose inputs have not changed since its last export (`--all` exports every view), and exits 1,
@@ -342,7 +395,7 @@ jobs:
342
395
  runs-on: ubuntu-latest
343
396
  steps:
344
397
  - uses: actions/checkout@v4
345
- - uses: zintaen/umlimator@v0.19.0
398
+ - uses: zintaen/umlimator@v0.21.0
346
399
  with:
347
400
  models: "docs/*.json" # optional: where the models are (default: every .json that is a map model)
348
401
  ```
@@ -415,7 +468,7 @@ With `UMLIMATOR_OFFLINE=1` the CLI fetches nothing: a logo not in the cache keep
415
468
 
416
469
  ```bash
417
470
  npm run build # src/ into lib/umlimator.js and lib/umlimator-all.js: edit the sources, commit all three
418
- node --test # layout() in Node: the bench views' geometry and the layout rules
471
+ node --test # layout() in Node: the bench views' geometry and the layout rules; npm test runs the "(timed)" tests apart, one file at a time
419
472
  python3 tests/embed.py # render() in headless Chrome: events, keyboard, colours, contrast, editing, the element
420
473
  python3 bench/bench.py --check-determinism --expect bench/expected.json --max-ms m50=2000
421
474
  ```