umlimator 0.19.0 → 0.20.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
@@ -58,6 +58,16 @@ drill-down, a data pipeline, an AI agent's skills, and host pages for embedding,
58
58
  ([`examples/bookshop-packages.json`](examples/bookshop-packages.json), [what it covers](docs/conformance/uml-package.md)).
59
59
  Ownership is edited by dropping an element into a box, or with the Owner field; both are checked by their types'
60
60
  rules, and the PDF's tables list slots and element kinds.
61
+ - **UML sequence and communication diagrams** (0.20.0): lifelines on a time axis with calls, async messages, replies,
62
+ creates and deletes, activation bars derived from the messages, `alt`, `opt`, `loop`, `par` and `break` frames with
63
+ their guards, and interaction uses ([`examples/checkout-sequence.json`](examples/checkout-sequence.json),
64
+ [what it covers](docs/conformance/uml-sequence.md)); the same interaction as lifelines joined by connectors, each
65
+ link's messages a stack of numbered rows (1, 1.1, 1.1.2) ([`examples/checkout-communication.json`](examples/checkout-communication.json),
66
+ [what it covers](docs/conformance/uml-communication.md)). Messages are inserted, moved in time, wrapped in a frame and
67
+ deleted on the canvas, by pointer and by key, each gesture an `edit` event; checked by the types' rules; a sequence
68
+ diagram is read from and written to Mermaid's `sequenceDiagram`, and an OpenTelemetry trace becomes one
69
+ (`umlimator.py trace --diagram uml.sequence`). The MCP server, the `map-repo` skill and the diff Action learn these
70
+ 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.
61
71
  - **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
72
  for a review: a cover with the contents, each view with its legend and tables of its cards, lines and boxes, then the
63
73
  rules (`umlimator.py pdf`).
@@ -80,7 +90,7 @@ drill-down, a data pipeline, an AI agent's skills, and host pages for embedding,
80
90
  npm install umlimator
81
91
  ```
82
92
 
83
- Or from GitHub, at a tag or any commit: `"umlimator": "github:zintaen/umlimator#v0.19.0"`. npm 12 refuses git
93
+ Or from GitHub, at a tag or any commit: `"umlimator": "github:zintaen/umlimator#v0.20.0"`. npm 12 refuses git
84
94
  dependencies unless the project opts in, so that also needs `allow-git=root` in the `.npmrc` next to `package.json`.
85
95
 
86
96
  ## Embed
@@ -129,7 +139,7 @@ function MapView({ model, onSelect }) {
129
139
  `map.shapes` reads the notation shown and sets another (`null`: each view's own again); the cards are drawn again from
130
140
  the geometry they have, with the camera, selection and marks kept, and nothing is laid out.
131
141
  - `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
142
+ - `import { render, apply, history } from 'umlimator/all'` draws diagram types too: a class, object, package, sequence or communication diagram, whose gestures emit
133
143
  `edit` transactions that `apply(model, e.commands)` turns into the next model (`examples/class-editor.html` is a
134
144
  working host). `umlimator` alone draws maps, and a typed view as plain cards with a warning.
135
145
  - `diff(before, after)` returns `after` with each card and line marked added, changed or removed, what changed in words,
@@ -208,8 +218,8 @@ path. The full schema is `engine/references/schema.md` (§ Map model); `examples
208
218
  A model file that starts with `"$schema": "<path to>/umlimator.schema.json"` (exported as `umlimator/schema.json`)
209
219
  gets completion and checks in editors, and `validate(model)` lists its errors and warnings, each with where it is.
210
220
  `"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
221
+ `diagram` is `"uml.class"`, `"uml.object"`, `"uml.package"`, `"uml.sequence"` or `"uml.communication"` is a UML class, object,
222
+ package, sequence or communication diagram, drawn by `umlimator/all` and the CLI; a type not drawn yet shows its
213
223
  nodes as plain cards, with a warning. A model with no `schemaVersion` is a map, as always, and a version newer than the
214
224
  module reads is an error.
215
225
 
@@ -264,6 +274,19 @@ In a version-2 model, a class diagram (`examples/sales-classes.json`; every fiel
264
274
  | view | `direction` | `"down"` lays it out top to bottom, the general class above (default `"right"`) |
265
275
  | view | `present` | per element: `collapsed` compartments, and at most `rows` rows each, then "+k more" |
266
276
 
277
+ A sequence diagram (`examples/checkout-sequence.json`, [`docs/conformance/uml-sequence.md`](docs/conformance/uml-sequence.md))
278
+ and a communication diagram (`examples/checkout-communication.json`,
279
+ [`docs/conformance/uml-communication.md`](docs/conformance/uml-communication.md)), from 0.20.0:
280
+
281
+ | On | Field | What it does |
282
+ |---|---|---|
283
+ | node | `type` | `uml.Lifeline`; its `props.represents` is what it is an instance of, drawn `name : Type` |
284
+ | edge | `type` | `uml.Message`; on a communication view also `uml.Connector`, the link messages are sent along |
285
+ | edge | `props` | a message's `sort` (`call`, `async`, `reply`, `create`, `delete`) and a reply's `replyTo`, the call it answers |
286
+ | view | `diagram` | `"uml.sequence"` or `"uml.communication"` |
287
+ | 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 |
288
+ | 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 |
289
+
267
290
  ## Command line
268
291
 
269
292
  ```bash
@@ -279,11 +302,13 @@ python3 umlimator.py check page.html --expand # also ea
279
302
  python3 umlimator.py record bike-share.html --story ride --out ride.png # bike-share's story as an animated PNG, its tours riding
280
303
  python3 umlimator.py import workspace.dsl --out model.json # a diagram you have already, as a model
281
304
  python3 umlimator.py import classes.mmd --out classes.json # a Mermaid classDiagram, as a UML class diagram (needs Node)
305
+ python3 umlimator.py import checkout.mmd --out checkout.json # a Mermaid sequenceDiagram, as a UML sequence diagram (needs Node)
282
306
  python3 umlimator.py render examples/sales-classes.json --out classes.html # a class diagram's page; stills, check and pdf take it too
283
307
  docker compose config --format json > compose.json && python3 umlimator.py import compose.json --out model.json
284
308
  kubectl get deploy,sts,svc,ing -A -o json > cluster.json && python3 umlimator.py import cluster.json --out model.json
285
309
  python3 umlimator.py pdf page.html --out map.pdf # every view in one PDF: a cover, each view with its tables, the rules
286
310
  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
311
+ 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
312
  python3 umlimator.py mcp model.json # an MCP server over stdio, for an AI assistant (below)
288
313
  ```
289
314
 
@@ -291,7 +316,8 @@ python3 umlimator.py mcp model.json # an MCP
291
316
 
292
317
  `import` reads Structurizr DSL (people, systems, containers and components, their relationships, and the workspace's
293
318
  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
319
+ `C4Container` or `C4Component`; a `classDiagram` becomes a UML class diagram and a `sequenceDiagram` a UML sequence
320
+ diagram, each read through Node), and the JSON of `docker compose config` (services, `depends_on`, networks) and of
295
321
  `kubectl get` (workloads, Services, Ingresses). It tells the format from the content, then the extension; `--format`
296
322
  decides. Groups, boundaries, subgraphs, networks and namespaces become boxes; Structurizr's views stay views, a card
297
323
  opening the view below it; `examples/clinic.json` is `examples/clinic.dsl`, imported. What each element becomes, and
@@ -342,7 +368,7 @@ jobs:
342
368
  runs-on: ubuntu-latest
343
369
  steps:
344
370
  - uses: actions/checkout@v4
345
- - uses: zintaen/umlimator@v0.19.0
371
+ - uses: zintaen/umlimator@v0.20.0
346
372
  with:
347
373
  models: "docs/*.json" # optional: where the models are (default: every .json that is a map model)
348
374
  ```
@@ -1701,7 +1701,9 @@ function routeAudit(geo, where, only, refs) { // only: a set of edges; counts ju
1701
1701
  const box = n => ({ x: n.x, y: n.y, w: n.w, h: n.h });
1702
1702
  function overlapIssues(geo, where, refs) {
1703
1703
  const issues = [], nodes = geo.nodes, say = teller(issues, refs);
1704
- for (let i = 0; i < nodes.length; i++) for (let j = i + 1; j < nodes.length; j++) if (hit(box(nodes[i]), box(nodes[j]), -1)) say(`${where}: nodes "${nodes[i].label}" and "${nodes[j].label}" overlap`, nodes[i], nodes[j]);
1704
+ const inside = (a, b) => a.x >= b.x - 1 && a.y >= b.y - 1 && a.x + a.w <= b.x + b.w + 1 && a.y + a.h <= b.y + b.h + 1;
1705
+ const holds = (a, b) => (a.holder && inside(b, a)) || (b.holder && inside(a, b)); // a holder (a sequence's frame) may hold what it meets, not cross it
1706
+ for (let i = 0; i < nodes.length; i++) for (let j = i + 1; j < nodes.length; j++) if (hit(box(nodes[i]), box(nodes[j]), -1) && !holds(nodes[i], nodes[j])) say(`${where}: nodes "${nodes[i].label}" and "${nodes[j].label}" overlap`, nodes[i], nodes[j]);
1705
1707
  return issues;
1706
1708
  }
1707
1709
  function leaveIssues(geo, where, refs) {
@@ -1724,7 +1726,7 @@ function leaveIssues(geo, where, refs) {
1724
1726
  function auditSvg(svg, geo, where) {
1725
1727
  const issues = overlapIssues(geo, where), R = box;
1726
1728
  const T = [...svg.querySelectorAll('text[data-t]')].map(t => { let b; try { b = t.getBBox(); } catch (_) { return null; } return { t: t.dataset.t, o: t.dataset.o, txt: t.textContent, b: { x: b.x, y: b.y, w: b.width, h: b.height } }; }).filter(x => x && x.b.w);
1727
- const nodes = geo.nodes, faces = Object.fromEntries([...svg.querySelectorAll('.node[data-face]')].map(g => [g.dataset.id, g.dataset.face.split(' ').map(Number)])); // a shape's face (0.15.0)
1729
+ const nodes = geo.nodes.filter(n => !n.holder), faces = Object.fromEntries([...svg.querySelectorAll('.node[data-face]')].map(g => [g.dataset.id, g.dataset.face.split(' ').map(Number)])); // a shape's face (0.15.0)
1728
1730
  T.forEach(a => {
1729
1731
  if (a.t === 'lt' || a.t === 'ft') {
1730
1732
  nodes.forEach(n => { if (hit(a.b, R(n), -1)) issues.push(`${where}: lane "${a.txt}": header covers node "${n.label}"`); });
@@ -7955,11 +7957,11 @@ function sqRun(model, view) {
7955
7957
  ...o.heads.map((h, j) => { const n = H.get(h.id), st = sqStereo(n);
7956
7958
  return { ...h, shape: 'lifeline', type: 'uml.Lifeline', label: sqHeadText(n), stereotypes: st, k: 'file', stem: o.stems[j], aria: `Lifeline ${sqHeadText(n)}${st.length ? ` (${st.join(', ')})` : ''}` }; }),
7957
7959
  ...o.frames.flatMap(fr => { const f = X.F.get(fr.id), op = sqOperator(f), ms = SQ_ARR(f.members).filter(SQ_OBJ);
7958
- return [{ id: fr.id, shape: 'frame', type: 'uml.CombinedFragment', label: op, k: 'file', x: fr.x, y: fr.y, w: fr.w, h: fr.h, aria: `Combined fragment ${op}, ${ms.length} ${ms.length === 1 ? 'operand' : 'operands'}` },
7960
+ return [{ id: fr.id, shape: 'frame', type: 'uml.CombinedFragment', label: op, k: 'file', holder: true, x: fr.x, y: fr.y, w: fr.w, h: fr.h, aria: `Combined fragment ${op}, ${ms.length} ${ms.length === 1 ? 'operand' : 'operands'}` },
7959
7961
  ...fr.parts.map(p => { const m = ms.find(x => x.id === p.id) || {}, k = direct(p.id);
7960
- return { ...p, shape: 'operand', type: 'uml.InteractionOperand', label: m.label, k: 'file', aria: `Operand ${SQ_HAS(m.label) ? m.label + ' ' : ''}of ${op}, ${k} ${k === 1 ? 'occurrence' : 'occurrences'}` }; })]; }),
7962
+ return { ...p, shape: 'operand', type: 'uml.InteractionOperand', label: m.label, k: 'file', holder: true, aria: `Operand ${SQ_HAS(m.label) ? m.label + ' ' : ''}of ${op}, ${k} ${k === 1 ? 'occurrence' : 'occurrences'}` }; })]; }),
7961
7963
  ...o.spans.map(s => { const u = X.byId.get(s.id), cs = SQ_ARR(sqProps(u.el).covers).filter(id => H.has(id)), all = heads.map(n => n.id), ids = cs.length ? all.filter(id => cs.includes(id)) : all;
7962
- return { ...s, shape: 'use', type: 'uml.InteractionUse', label: String(u.el.label ?? ''), k: 'file',
7964
+ return { ...s, shape: 'use', type: 'uml.InteractionUse', label: String(u.el.label ?? ''), k: 'file', holder: true,
7963
7965
  aria: `Interaction use ${u.el.label ?? ''}${ids.length ? `, over ${sqName(H.get(ids[0]))}${ids.length > 1 ? ' to ' + sqName(H.get(ids[ids.length - 1])) : ''}` : ''}` }; }),
7964
7966
  ];
7965
7967
  const byId = Object.fromEntries(nodes.map(n => [n.id, n]));
@@ -48,8 +48,8 @@ export interface MapNode {
48
48
  /** A typed element in schema version 2's envelope (docs/diagrams/model.md §1): a node, a member, a typed edge, a
49
49
  * fragment. Nodes, edges, members and fragments share one id space; an id never contains "->". A typed edge is an
50
50
  * Element with `from` and `to`, which may name a member. A typed view is a MapView with `diagram` (uml.class), and may
51
- * have `subject`, `direction` ('right' | 'down'), `notation`, `present`, `fragments` and `timeline`. umlimator/all draws `uml.class` (0.18.0), `uml.object` and `uml.package` (0.19.0); other types draw as plain cards.
52
- * From 0.19.0 those three draw a shown package that owns something the view shows as a box holding it (`parent`), and
51
+ * have `subject`, `direction` ('right' | 'down'), `notation`, `present`, `fragments` and `timeline`. umlimator/all draws `uml.class` (0.18.0), `uml.object` and `uml.package` (0.19.0), `uml.sequence` and `uml.communication` (0.20.0); other types draw as plain cards.
52
+ * From 0.19.0 the class, object and package types draw a shown package that owns something the view shows as a box holding it (`parent`), and
53
53
  * qualify names (`sales::Order`) from the nearest shown owner, the view's `subject`, or the top. */
54
54
  export interface Element {
55
55
  id: string; type: string; label?: string; parent?: string; props?: Record<string, unknown>; members?: Element[];
@@ -99,6 +99,33 @@ export interface UmlPackageImportProps { visibility?: 'public' | 'private'; ster
99
99
  /** What a typed view shows of one element, in its `present` by the element's id: compartments not drawn, divider and
100
100
  * all, and at most `rows` rows in each, then "+k more". */
101
101
  export interface UmlPresent { collapsed?: ('attributes' | 'operations' | 'literals')[]; rows?: number }
102
+ /** The sequence diagram's vocabulary (a view with `diagram: 'uml.sequence'`, umlimator/all from 0.20.0;
103
+ * docs/conformance/uml-sequence.md). Lifelines are model nodes the view lists in `nodeIds`, left to right. Messages and
104
+ * interaction uses are inline in the view's `edges`, in time order; a fragment's content is one run there, operand by
105
+ * operand. Combined fragments are in the view's `fragments`, each with its operands as `members`; an occurrence's or a
106
+ * fragment's `parent` is the operand that holds it. Activations and message numbers are derived, never stored. */
107
+ export type UmlSequenceElementType = 'uml.Lifeline' | 'uml.InteractionUse' | 'uml.CombinedFragment';
108
+ export type UmlSequenceMemberType = 'uml.InteractionOperand';
109
+ export type UmlSequenceLineType = 'uml.Message';
110
+ /** A lifeline's props: what it represents, by name, as text (drawn `name : Type`); stereotype `actor` draws «actor». */
111
+ export interface UmlLifelineProps { represents?: string; stereotypes?: string[]; [key: string]: unknown }
112
+ /** A message's kind: a call (filled arrow, the default), async (open arrow), reply (dashed, open), create (dashed, open;
113
+ * the receiver's head is lowered to it) or delete (the receiver's stem ends in a cross). */
114
+ export type UmlMessageSort = 'call' | 'async' | 'reply' | 'create' | 'delete';
115
+ /** A message's props: its sort; a reply's `replyTo`, the id of the earlier call it answers. */
116
+ export interface UmlMessageProps { sort?: UmlMessageSort; replyTo?: string; stereotypes?: string[]; [key: string]: unknown }
117
+ /** An interaction use's props: the lifelines it covers (next to each other in `nodeIds`), and the view it refers to. */
118
+ export interface UmlInteractionUseProps { covers?: string[]; refersTo?: string; [key: string]: unknown }
119
+ /** A combined fragment's operator; any other is drawn by its name, with a warning. opt, loop and break have one operand,
120
+ * whose `label` is its guard. */
121
+ export type UmlInteractionOperator = 'alt' | 'opt' | 'loop' | 'par' | 'break';
122
+ export interface UmlCombinedFragmentProps { operator?: UmlInteractionOperator; [key: string]: unknown }
123
+ /** The communication diagram's vocabulary (a view with `diagram: 'uml.communication'`, umlimator/all from 0.20.0;
124
+ * docs/conformance/uml-communication.md): lifelines; connectors and messages are model edges the view's `edges` lists,
125
+ * connectors first. Only the messages' order means anything; their numbers (1, 1.1, 1.1.2) are derived. A message's
126
+ * props are UmlMessageProps; a message needs a connector between its two lifelines. */
127
+ export type UmlCommunicationElementType = 'uml.Lifeline';
128
+ export type UmlCommunicationLineType = 'uml.Connector' | 'uml.Message';
102
129
  /** What a line means, drawn as its colour: calls (the default), feeds (hands work on), triggers (suggests, offers, fires),
103
130
  * state (reads or writes a file, board or config: a thinner line, a muted label, no flow) and guard (a hook steps in).
104
131
  * Colours are --um-w-<kind>. An edge's `style` (emphasis, dashed, security) wins over its kind's colour. */
@@ -139,7 +166,8 @@ export interface MapEdge {
139
166
  }
140
167
  export interface MapView {
141
168
  id: string; parent?: string | null; title?: string; nodeIds: string[];
142
- edges?: (string | MapEdge)[]; layout?: Record<string, [number, number]>; repair?: boolean;
169
+ /** Model line ids or lines of its own; in a sequence view (0.20.0) its messages and interaction uses (Elements), in time order. */
170
+ edges?: (string | MapEdge | Element)[]; layout?: Record<string, [number, number]>; repair?: boolean;
143
171
  /** Cards 80 px tall that show their sub-line and then their chips (`verbs`) on a third line. Default: 64 px, and a card's
144
172
  * chips take its sub-line's place. A script card (no kind) shows no sub-line either way. */
145
173
  subAndChips?: boolean;
package/lib/umlimator.js CHANGED
@@ -1700,7 +1700,9 @@ function routeAudit(geo, where, only, refs) { // only: a set of edges; counts ju
1700
1700
  const box = n => ({ x: n.x, y: n.y, w: n.w, h: n.h });
1701
1701
  function overlapIssues(geo, where, refs) {
1702
1702
  const issues = [], nodes = geo.nodes, say = teller(issues, refs);
1703
- for (let i = 0; i < nodes.length; i++) for (let j = i + 1; j < nodes.length; j++) if (hit(box(nodes[i]), box(nodes[j]), -1)) say(`${where}: nodes "${nodes[i].label}" and "${nodes[j].label}" overlap`, nodes[i], nodes[j]);
1703
+ const inside = (a, b) => a.x >= b.x - 1 && a.y >= b.y - 1 && a.x + a.w <= b.x + b.w + 1 && a.y + a.h <= b.y + b.h + 1;
1704
+ const holds = (a, b) => (a.holder && inside(b, a)) || (b.holder && inside(a, b)); // a holder (a sequence's frame) may hold what it meets, not cross it
1705
+ for (let i = 0; i < nodes.length; i++) for (let j = i + 1; j < nodes.length; j++) if (hit(box(nodes[i]), box(nodes[j]), -1) && !holds(nodes[i], nodes[j])) say(`${where}: nodes "${nodes[i].label}" and "${nodes[j].label}" overlap`, nodes[i], nodes[j]);
1704
1706
  return issues;
1705
1707
  }
1706
1708
  function leaveIssues(geo, where, refs) {
@@ -1723,7 +1725,7 @@ function leaveIssues(geo, where, refs) {
1723
1725
  function auditSvg(svg, geo, where) {
1724
1726
  const issues = overlapIssues(geo, where), R = box;
1725
1727
  const T = [...svg.querySelectorAll('text[data-t]')].map(t => { let b; try { b = t.getBBox(); } catch (_) { return null; } return { t: t.dataset.t, o: t.dataset.o, txt: t.textContent, b: { x: b.x, y: b.y, w: b.width, h: b.height } }; }).filter(x => x && x.b.w);
1726
- const nodes = geo.nodes, faces = Object.fromEntries([...svg.querySelectorAll('.node[data-face]')].map(g => [g.dataset.id, g.dataset.face.split(' ').map(Number)])); // a shape's face (0.15.0)
1728
+ const nodes = geo.nodes.filter(n => !n.holder), faces = Object.fromEntries([...svg.querySelectorAll('.node[data-face]')].map(g => [g.dataset.id, g.dataset.face.split(' ').map(Number)])); // a shape's face (0.15.0)
1727
1729
  T.forEach(a => {
1728
1730
  if (a.t === 'lt' || a.t === 'ft') {
1729
1731
  nodes.forEach(n => { if (hit(a.b, R(n), -1)) issues.push(`${where}: lane "${a.txt}": header covers node "${n.label}"`); });
@@ -419,7 +419,7 @@
419
419
  }
420
420
  },
421
421
  "type": {
422
- "description": "Schema version 2: the element's type, <notation>.<Name> (uml.Class). validate() checks typed fields only in a model with schemaVersion 2. The class diagram (uml.class, 0.18.0): uml.Class, uml.Interface, uml.Enumeration, uml.DataType, uml.PrimitiveType, uml.Package and uml.Comment; their members uml.Property, uml.Operation and uml.EnumerationLiteral. The object diagram (uml.object, 0.19.0): uml.InstanceSpecification and uml.Comment; an instance's members uml.Slot. The package diagram (uml.package, 0.19.0): uml.Package and the class diagram's classifiers, and uml.Comment.",
422
+ "description": "Schema version 2: the element's type, <notation>.<Name> (uml.Class). validate() checks typed fields only in a model with schemaVersion 2. The class diagram (uml.class, 0.18.0): uml.Class, uml.Interface, uml.Enumeration, uml.DataType, uml.PrimitiveType, uml.Package and uml.Comment; their members uml.Property, uml.Operation and uml.EnumerationLiteral. The object diagram (uml.object, 0.19.0): uml.InstanceSpecification and uml.Comment; an instance's members uml.Slot. The package diagram (uml.package, 0.19.0): uml.Package and the class diagram's classifiers, and uml.Comment. The sequence and communication diagrams (uml.sequence, uml.communication, 0.20.0): uml.Lifeline.",
423
423
  "examples": [
424
424
  "uml.Class",
425
425
  "uml.Interface",
@@ -428,14 +428,15 @@
428
428
  "uml.PrimitiveType",
429
429
  "uml.Package",
430
430
  "uml.Comment",
431
- "uml.InstanceSpecification"
431
+ "uml.InstanceSpecification",
432
+ "uml.Lifeline"
432
433
  ]
433
434
  },
434
435
  "parent": {
435
436
  "description": "Schema version 2: the element that owns it (a package, a composite state, a lane). From 0.19.0 a class, object or package view draws a shown package that owns something it shows as a box holding it."
436
437
  },
437
438
  "props": {
438
- "description": "Schema version 2: the type's own properties. The class diagram (uml.class, 0.18.0): isAbstract and stereotypes on a classifier; on a member, the fields of its UML text (docs/conformance/uml-class.md). The object diagram (uml.object, 0.19.0): an instance's classifier and stereotypes; a slot's value (docs/conformance/uml-object.md).",
439
+ "description": "Schema version 2: the type's own properties. The class diagram (uml.class, 0.18.0): isAbstract and stereotypes on a classifier; on a member, the fields of its UML text (docs/conformance/uml-class.md). The object diagram (uml.object, 0.19.0): an instance's classifier and stereotypes; a slot's value (docs/conformance/uml-object.md). The sequence and communication diagrams (uml.sequence, uml.communication, 0.20.0): a lifeline's represents, and stereotypes (actor draws «actor» over its name).",
439
440
  "anyOf": [
440
441
  {
441
442
  "type": "object",
@@ -448,6 +449,9 @@
448
449
  },
449
450
  "classifier": {
450
451
  "description": "uml.InstanceSpecification: the name (or qualified name, sales::Order) of the classifier it is an instance of, as text; drawn name : Classifier, underlined."
452
+ },
453
+ "represents": {
454
+ "description": "uml.Lifeline: what it is an instance of, by name, as text; drawn name : Type (docs/diagrams/risks.md M8)."
451
455
  }
452
456
  }
453
457
  },
@@ -814,7 +818,7 @@
814
818
  "description": "When the line is used."
815
819
  },
816
820
  "type": {
817
- "description": "Schema version 2: the element's type, <notation>.<Name> (uml.Class). The class diagram (uml.class, 0.18.0): uml.Association, uml.Generalization (from the specific to the general), uml.InterfaceRealization (to the interface), uml.Dependency (from the client) and uml.CommentLink (from the comment). The object diagram (uml.object, 0.19.0): uml.Link and uml.CommentLink. The package diagram (uml.package, 0.19.0): uml.PackageImport and uml.PackageMerge (from the importing or merging package), uml.Dependency and uml.CommentLink.",
821
+ "description": "Schema version 2: the element's type, <notation>.<Name> (uml.Class). The class diagram (uml.class, 0.18.0): uml.Association, uml.Generalization (from the specific to the general), uml.InterfaceRealization (to the interface), uml.Dependency (from the client) and uml.CommentLink (from the comment). The object diagram (uml.object, 0.19.0): uml.Link and uml.CommentLink. The package diagram (uml.package, 0.19.0): uml.PackageImport and uml.PackageMerge (from the importing or merging package), uml.Dependency and uml.CommentLink. The sequence diagram (uml.sequence, 0.20.0): uml.Message, inline in its view's edges, in time order. The communication diagram (uml.communication, 0.20.0): uml.Connector and uml.Message, model lines its view lists, connectors first; only the messages' order means anything.",
818
822
  "examples": [
819
823
  "uml.Association",
820
824
  "uml.Generalization",
@@ -823,14 +827,16 @@
823
827
  "uml.CommentLink",
824
828
  "uml.Link",
825
829
  "uml.PackageImport",
826
- "uml.PackageMerge"
830
+ "uml.PackageMerge",
831
+ "uml.Message",
832
+ "uml.Connector"
827
833
  ]
828
834
  },
829
835
  "parent": {
830
- "description": "Schema version 2: the element that owns it (a package, a composite state, a lane)."
836
+ "description": "Schema version 2: the element that owns it (a package, a composite state, a lane). In a sequence view: the operand (uml.InteractionOperand) of one of its fragments that holds the message; none at the top level."
831
837
  },
832
838
  "props": {
833
- "description": "Schema version 2: the type's own properties. The class diagram (uml.class, 0.18.0): an association's ends, and stereotypes on any line («use» on a dependency). The object diagram (uml.object, 0.19.0): a link's association and the roles at its ends. The package diagram (uml.package, 0.19.0): a package import's visibility.",
839
+ "description": "Schema version 2: the type's own properties. The class diagram (uml.class, 0.18.0): an association's ends, and stereotypes on any line («use» on a dependency). The object diagram (uml.object, 0.19.0): a link's association and the roles at its ends. The package diagram (uml.package, 0.19.0): a package import's visibility. The sequence and communication diagrams (0.20.0): a message's sort and replyTo.",
834
840
  "anyOf": [
835
841
  {
836
842
  "type": "object",
@@ -900,6 +906,19 @@
900
906
  },
901
907
  "visibility": {
902
908
  "description": "uml.PackageImport: public (the default, drawn «import») or private (drawn «access»)."
909
+ },
910
+ "sort": {
911
+ "description": "uml.Message: call (the default), async, reply, create or delete; any other is drawn as a call, with a warning.",
912
+ "examples": [
913
+ "call",
914
+ "async",
915
+ "reply",
916
+ "create",
917
+ "delete"
918
+ ]
919
+ },
920
+ "replyTo": {
921
+ "description": "uml.Message, a reply: the id of the earlier call it answers, which it goes back along."
903
922
  }
904
923
  }
905
924
  },
@@ -985,7 +1004,7 @@
985
1004
  },
986
1005
  "edges": {
987
1006
  "type": "array",
988
- "description": "The lines this view draws: model line ids or lines of its own. Default: every model line between its cards; [] draws none.",
1007
+ "description": "The lines this view draws: model line ids or lines of its own. Default: every model line between its cards; [] draws none. In a sequence view (uml.sequence, 0.20.0): its occurrences in time order, each message and interaction use inline, a fragment's operand by operand.",
989
1008
  "items": {
990
1009
  "anyOf": [
991
1010
  {
@@ -993,6 +1012,49 @@
993
1012
  },
994
1013
  {
995
1014
  "$ref": "#/$defs/edge"
1015
+ },
1016
+ {
1017
+ "type": "object",
1018
+ "required": [
1019
+ "id",
1020
+ "type"
1021
+ ],
1022
+ "properties": {
1023
+ "type": {
1024
+ "const": "uml.InteractionUse"
1025
+ },
1026
+ "label": {
1027
+ "description": "The interaction it refers to, by name."
1028
+ },
1029
+ "parent": {
1030
+ "description": "The operand (uml.InteractionOperand) that holds it; none at the top level."
1031
+ },
1032
+ "props": {
1033
+ "properties": {
1034
+ "covers": {
1035
+ "description": "The ids of the lifelines it spans, next to each other in the view's nodeIds."
1036
+ },
1037
+ "refersTo": {
1038
+ "description": "The id of the view it refers to."
1039
+ }
1040
+ }
1041
+ }
1042
+ },
1043
+ "not": {
1044
+ "anyOf": [
1045
+ {
1046
+ "required": [
1047
+ "from"
1048
+ ]
1049
+ },
1050
+ {
1051
+ "required": [
1052
+ "to"
1053
+ ]
1054
+ }
1055
+ ]
1056
+ },
1057
+ "description": "Schema version 2: an occurrence of a sequence view that is not a line: an interaction use (uml.InteractionUse), its label the interaction it refers to, props.covers the lifelines it spans (next to each other in nodeIds), props.refersTo a view's id, parent its operand."
996
1058
  }
997
1059
  ]
998
1060
  }
@@ -1146,18 +1208,20 @@
1146
1208
  "description": "Guess a line's kind from its label's words when its edges name none (render() and layout(); the standalone page always does)."
1147
1209
  },
1148
1210
  "diagram": {
1149
- "description": "Schema version 2: the view's diagram type; without it the view is a map. uml.class draws a class diagram (0.18.0, lib/umlimator-all.js), uml.object an object diagram and uml.package a package diagram (0.19.0); a type this release does not draw is drawn as plain cards, with a warning.",
1211
+ "description": "Schema version 2: the view's diagram type; without it the view is a map. uml.class draws a class diagram (0.18.0, lib/umlimator-all.js), uml.object an object diagram and uml.package a package diagram (0.19.0), uml.sequence a sequence diagram and uml.communication a communication diagram (0.20.0); a type this release does not draw is drawn as plain cards, with a warning.",
1150
1212
  "examples": [
1151
1213
  "uml.class",
1152
1214
  "uml.object",
1153
- "uml.package"
1215
+ "uml.package",
1216
+ "uml.sequence",
1217
+ "uml.communication"
1154
1218
  ]
1155
1219
  },
1156
1220
  "subject": {
1157
1221
  "description": "Schema version 2: the element this diagram is the inside of. In a class, object or package view, the package names are qualified from (sales::Order without sales:: in a view of sales); not drawn unless the view lists it."
1158
1222
  },
1159
1223
  "direction": {
1160
- "description": "Schema version 2: a typed view's layout direction (default right). A map stays left to right."
1224
+ "description": "Schema version 2: a typed view's layout direction (default right). A map stays left to right. A sequence view is always down; another direction is a warning."
1161
1225
  },
1162
1226
  "notation": {
1163
1227
  "description": "Schema version 2: a skin of the diagram type (crowsfoot for er)."
@@ -1189,7 +1253,48 @@
1189
1253
  ]
1190
1254
  },
1191
1255
  "fragments": {
1192
- "description": "Schema version 2: a sequence view's combined fragments and interaction uses."
1256
+ "description": "Schema version 2: a sequence view's combined fragments (uml.CombinedFragment, props.operator alt, opt, loop, par or break), outermost first; each one's members are its operands (uml.InteractionOperand, label the guard) in order, and its parent is the operand that holds it (uml.sequence, 0.20.0).",
1257
+ "items": {
1258
+ "properties": {
1259
+ "type": {
1260
+ "examples": [
1261
+ "uml.CombinedFragment"
1262
+ ]
1263
+ },
1264
+ "parent": {
1265
+ "description": "The operand (uml.InteractionOperand) that holds it; none at the top level."
1266
+ },
1267
+ "props": {
1268
+ "properties": {
1269
+ "operator": {
1270
+ "description": "The fragment's operator; any other is a warning.",
1271
+ "examples": [
1272
+ "alt",
1273
+ "opt",
1274
+ "loop",
1275
+ "par",
1276
+ "break"
1277
+ ]
1278
+ }
1279
+ }
1280
+ },
1281
+ "members": {
1282
+ "description": "Its operands, in order.",
1283
+ "items": {
1284
+ "properties": {
1285
+ "type": {
1286
+ "examples": [
1287
+ "uml.InteractionOperand"
1288
+ ]
1289
+ },
1290
+ "label": {
1291
+ "description": "The operand's guard."
1292
+ }
1293
+ }
1294
+ }
1295
+ }
1296
+ }
1297
+ }
1193
1298
  },
1194
1299
  "timeline": {
1195
1300
  "description": "Schema version 2: a timing view's unit, changes and constraints."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "umlimator",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "description": "Embeddable, layered architecture maps: layout, orthogonal routing and an interactive canvas in one ES module.",
5
5
  "keywords": ["architecture", "diagram", "c4", "map", "svg", "layout", "orthogonal-routing", "drill-down"],
6
6
  "homepage": "https://zintaen.github.io/umlimator/",