@jarenjs/mermaid 0.34.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.
Files changed (64) hide show
  1. package/README.md +282 -0
  2. package/dist/types/ast.d.ts +210 -0
  3. package/dist/types/component/index.d.ts +81 -0
  4. package/dist/types/errors.d.ts +27 -0
  5. package/dist/types/index.d.ts +97 -0
  6. package/dist/types/interactive.d.ts +36 -0
  7. package/dist/types/layout/flowchart.d.ts +12 -0
  8. package/dist/types/layout/sequence.d.ts +12 -0
  9. package/dist/types/layout/state.d.ts +19 -0
  10. package/dist/types/parser/class.d.ts +11 -0
  11. package/dist/types/parser/config.d.ts +61 -0
  12. package/dist/types/parser/er.d.ts +11 -0
  13. package/dist/types/parser/flowchart.d.ts +26 -0
  14. package/dist/types/parser/gantt.d.ts +11 -0
  15. package/dist/types/parser/index.d.ts +22 -0
  16. package/dist/types/parser/pie.d.ts +11 -0
  17. package/dist/types/parser/sequence.d.ts +16 -0
  18. package/dist/types/parser/state.d.ts +22 -0
  19. package/dist/types/plugin.d.ts +50 -0
  20. package/dist/types/render/error.d.ts +23 -0
  21. package/dist/types/render/flowchart.d.ts +18 -0
  22. package/dist/types/render/index.d.ts +23 -0
  23. package/dist/types/render/misc.d.ts +54 -0
  24. package/dist/types/render/sequence.d.ts +16 -0
  25. package/dist/types/styles.d.ts +81 -0
  26. package/dist/types/theme.d.ts +47 -0
  27. package/dist/types/to-mermaid.d.ts +20 -0
  28. package/dist/types/utils.d.ts +47 -0
  29. package/docs/MERMAID-FORMAT.md +242 -0
  30. package/package.json +84 -0
  31. package/schemas/jaren-mermaid-ast.schema.json +78 -0
  32. package/schemas/jaren-workflow.schema.json +28 -0
  33. package/src/ast.js +252 -0
  34. package/src/component/index.js +109 -0
  35. package/src/errors.js +35 -0
  36. package/src/index.js +155 -0
  37. package/src/interactive.js +244 -0
  38. package/src/layout/flowchart.js +352 -0
  39. package/src/layout/sequence.js +178 -0
  40. package/src/layout/state.js +65 -0
  41. package/src/parser/class.js +90 -0
  42. package/src/parser/config.js +215 -0
  43. package/src/parser/er.js +86 -0
  44. package/src/parser/flowchart.js +413 -0
  45. package/src/parser/gantt.js +49 -0
  46. package/src/parser/index.js +122 -0
  47. package/src/parser/pie.js +32 -0
  48. package/src/parser/sequence.js +156 -0
  49. package/src/parser/state.js +137 -0
  50. package/src/plugin.js +76 -0
  51. package/src/render/error.js +55 -0
  52. package/src/render/flowchart.js +249 -0
  53. package/src/render/index.js +93 -0
  54. package/src/render/misc.js +135 -0
  55. package/src/render/sequence.js +152 -0
  56. package/src/styles.js +181 -0
  57. package/src/theme.js +180 -0
  58. package/src/to-mermaid.js +317 -0
  59. package/src/utils.js +64 -0
  60. package/styles/mermaid.css +115 -0
  61. package/stylesheets/dag-to-flowchart.jslt.json +62 -0
  62. package/stylesheets/flowchart-to-dag.jslt.json +29 -0
  63. package/stylesheets/state-to-workflow.jslt.json +26 -0
  64. package/stylesheets/workflow-to-state.jslt.json +41 -0
package/README.md ADDED
@@ -0,0 +1,282 @@
1
+ # @jarenjs/mermaid
2
+
3
+ A native, **headless** Mermaid clone: diagrams-as-code parsed to a
4
+ geometry-free JSON AST and rendered as **pure-vnode SVG** through
5
+ [`@jarenjs/view`](../../packages/view) — no `innerHTML`, no browser, no
6
+ runtime dependency on mermaid.js. It is architecturally native to the
7
+ Jaren stack: parse-once/compile-to-closures, structurally shared,
8
+ content-hash-keyed, and **bidirectional** (`parseMermaid` ⇄
9
+ `toMermaid`).
10
+
11
+ Like [`@jarenjs/md`](../md), it ships in **two layers**: a pure engine
12
+ (text ⇄ AST ⇄ vnode) that knows only the vnode shape, and a visual
13
+ component that packages it for an `@jarenjs/app` host.
14
+
15
+ ## Format in one glance
16
+
17
+ ```js
18
+ import { parseMermaid, toMermaid, renderMermaid } from '@jarenjs/mermaid';
19
+
20
+ const doc = parseMermaid(`flowchart TD
21
+ A[Start] --> B{OK?}
22
+ B -->|yes| C((Done))`);
23
+
24
+ doc.diagram; // 'flowchart'
25
+ doc.ast.nodes[1]; // { id: 'B', label: 'OK?', shape: 'diamond' }
26
+ toMermaid(doc); // canonical text — parseMermaid(toMermaid(doc)) deep-equals doc.ast
27
+ renderMermaid(doc); // ['svg', { viewBox, … }, …] — a pure-vnode SVG, error-safe
28
+ ```
29
+
30
+ The AST is **geometry-free**: layout is a separate pass, so the AST is a
31
+ faithful semantic model — a directed graph, an ordered interaction, a
32
+ finite state machine — that other engines project. This is the two-layer
33
+ pipeline, drawn in Mermaid (and rendered by this engine on the website):
34
+
35
+ ```mermaid
36
+ flowchart LR
37
+ S[source text] --> P[parseMermaid]
38
+ P --> D[DiagramDocument<br/>geometry-free AST]
39
+ D --> L[layoutDiagram]
40
+ L --> R[diagramToVnode]
41
+ R --> V[SVG vnode]
42
+ D --> T[toMermaid]
43
+ T --> S
44
+ ```
45
+
46
+ ## Usage
47
+
48
+ **Parse / print / compile (pure):**
49
+
50
+ ```js
51
+ import { parseMermaid, toMermaid, compileMermaid } from '@jarenjs/mermaid';
52
+
53
+ const c = compileMermaid(source); // parse once; cached projections
54
+ c.doc; // the DiagramDocument
55
+ c.toVnode(); // pure-vnode SVG (reference-stable)
56
+ c.toSvgString(); // standalone SVG string — SSR, no browser
57
+ c.toText(); // canonical Mermaid (toMermaid)
58
+ c.toLayout(); // the PositionedDiagram — pure geometry
59
+ // (nodes x/y/w/h, routed edges); null for
60
+ // types without a layout. The rendered
61
+ // SVG also marks every node/edge with
62
+ // data-id / data-edge+data-from+data-to,
63
+ // so editors hit-test without re-layout.
64
+ ```
65
+
66
+ **Render pipeline:**
67
+
68
+ ```mermaid
69
+ sequenceDiagram
70
+ participant H as host
71
+ participant E as engine
72
+ participant V as @jarenjs/view
73
+ H->>E: renderMermaid(source)
74
+ E->>E: parse → layout → render
75
+ E-->>H: SVG vnode
76
+ H->>V: patch(vnode)
77
+ note over V: O(change) diff, keyed by content hash
78
+ ```
79
+
80
+ **Component (host):**
81
+
82
+ ```js
83
+ import { createMermaidComponent } from '@jarenjs/mermaid/component';
84
+ const mermaid = createMermaidComponent();
85
+ createApp(appDoc, {
86
+ effects: { ...mermaid.effects }, // mermaid-render, mermaid-load
87
+ viewModel: (state) => ({ ...state, diagram: mermaid.view(state.source) }),
88
+ });
89
+ ```
90
+
91
+ **Markdown plugin** — a `mermaid` fence renders inline, SSR-safe:
92
+
93
+ ```js
94
+ import { parseMarkdown, mdToVnode } from '@jarenjs/md';
95
+ import { mermaidPlugin } from '@jarenjs/mermaid/plugin';
96
+ const plugins = [mermaidPlugin()];
97
+ mdToVnode(parseMarkdown(md, { plugins }), { plugins }); // fence → inline <svg>
98
+ ```
99
+
100
+ ## The AST node types
101
+
102
+ ```mermaid
103
+ classDiagram
104
+ class DiagramDocument {
105
+ +String $mermaid
106
+ +String diagram
107
+ +Object config
108
+ +Object ast
109
+ +Object meta
110
+ }
111
+ class FlowNode {
112
+ +String id
113
+ +String label
114
+ +String shape
115
+ }
116
+ class FlowEdge {
117
+ +String from
118
+ +String to
119
+ +String stroke
120
+ }
121
+ DiagramDocument <|-- FlowNode
122
+ DiagramDocument <|-- FlowEdge
123
+ ```
124
+
125
+ ## Bidirectional semantic model
126
+
127
+ The geometry-free AST doubles as a reusable domain model, projected
128
+ both ways by plain JSLT stylesheets — no code, just documents. The
129
+ flagship: a `stateDiagram-v2` projects via
130
+ `stylesheets/state-to-workflow.jslt.json` into an executable machine
131
+ (the `@jarenjs/flow` jaren-fsm superset shape `{ initial, states,
132
+ transitions }`, validated by `schemas/jaren-workflow.schema.json`),
133
+ with a transition label's UML parts parsed for it: `event [guard] /
134
+ effect` become the machine's event, guard and `{ "run": effect }`
135
+ descriptor. The reverse stylesheet plus `toMermaid` turns a machine
136
+ back into editable diagram text — string guards round-trip exactly,
137
+ structured members print as documented `[…]` placeholders.
138
+
139
+ The same arrow exists for dataflow: `flowchart-to-dag.jslt.json`
140
+ projects a flowchart into a jaren-dag **skeleton** (task stubs named by
141
+ node id, edge labels becoming ports), and `dag-to-flowchart.jslt.json`
142
+ draws a real dag document as a flowchart — one shape per node kind,
143
+ ports and selects on the edge labels. Acyclicity stays `compileDag`'s
144
+ job; the projection just draws.
145
+
146
+ ```mermaid
147
+ flowchart LR
148
+ M[Mermaid text] --> A[state AST]
149
+ A -->|state-to-workflow.jslt| W[machine / FSM]
150
+ W -->|workflow-to-state.jslt| A2[state AST]
151
+ A2 -->|toMermaid| M
152
+ F[flowchart AST] -->|flowchart-to-dag.jslt| D[jaren-dag]
153
+ D -->|dag-to-flowchart.jslt| F
154
+ ```
155
+
156
+ ## Diagram coverage
157
+
158
+ Fully laid out: **flowchart**, **sequence**, **state** (through the
159
+ flowchart engine via an adapter — states as rounded nodes, `[*]` as a
160
+ filled start dot and an end ring, verbatim transition labels on the
161
+ edges; composite states stay flattened in v1). Structured panels /
162
+ chart: **class**, **ER**, **gantt**, **pie**. Parse-accepted with an
163
+ honest "not yet laid out" placeholder: mindmap, gitGraph, journey,
164
+ timeline, quadrantChart, requirement. The benchmark's coverage scorecard reports this
165
+ without hiding gaps.
166
+
167
+
168
+ ## Styling, notes and interaction
169
+
170
+ **`classDef` / `class` / `style` now paint.** The parser always recorded them;
171
+ nothing consumed them, so a styled node rendered exactly like an unstyled one.
172
+ They resolve per node in Mermaid's own precedence — classDef in application
173
+ order, then a per-node `style` — and reach the shape as SVG attributes:
174
+
175
+ ```mermaid
176
+ flowchart LR
177
+ A["input"] --> B["result"]
178
+ classDef good fill:#dcfce7,stroke:#16a34a
179
+ class B good
180
+ ```
181
+
182
+ **`note` is a built-in class.** Mermaid has no flowchart note, and a diagram
183
+ that cannot annotate a node loses exactly what an ASCII drawing used to carry
184
+ in a margin comment. Rather than invent syntax, apply the standard `class`
185
+ statement and the node is themed from the same `note*` tokens the sequence
186
+ renderer uses — dashed border, note fill, following light/dark:
187
+
188
+ ```mermaid
189
+ flowchart LR
190
+ K["@jarenjs/core"] --> E["engine"]
191
+ N["pure kernel: no I/O, deterministic"]
192
+ K -.- N
193
+ class N note
194
+ ```
195
+
196
+ A dotted link to a note-classed node reads as an annotation, and the document
197
+ stays valid Mermaid that any other tool can still parse — no dialect, no
198
+ compatibility cost.
199
+
200
+ **The label stays readable on whatever fill you pick.** A `fill` you name is a
201
+ constant — it does not follow light/dark — so the ink over it must not follow
202
+ the theme either, or a pale box under a dark theme gets pale text and the
203
+ label vanishes into it. The ink is derived from the fill's measured contrast
204
+ instead, and is guaranteed to clear WCAG AA for any colour. Name a `color`
205
+ yourself and that always wins.
206
+
207
+ **Pan, zoom and touch are opt-in.** `mermaidPlugin({ interactive: true })`
208
+ adds a `hydrate` that attaches to the finished SVG; the render is unchanged
209
+ and server output is byte-identical either way, so a page that does not ask
210
+ for it never loads the module.
211
+
212
+ ```javascript
213
+ createMdComponent({ plugins: [mermaidPlugin({ theme: 'host', interactive: true })] });
214
+ ```
215
+
216
+ The interaction rules are chosen so a figure never fights the page it sits in:
217
+
218
+ | gesture | behaviour |
219
+ |---|---|
220
+ | plain wheel | **scrolls the page** — hijacking it is how embedded viewers ruin a document |
221
+ | ctrl/⌘ + wheel | zooms toward the pointer |
222
+ | one-finger drag | pans **only once zoomed in**; at rest the swipe is the page's, and `touch-action` is switched to say so |
223
+ | two fingers | always pinch-zooms |
224
+ | double-click / tap | zooms in, or resets when already zoomed |
225
+ | keyboard | `+` `-` `0` and arrows, on a focusable figure with an aria-label |
226
+
227
+ Everything runs on the SVG's `viewBox` — four numbers changing. Nothing
228
+ re-renders, nothing re-parses, and the view is clamped so it can never be
229
+ panned off its own canvas.
230
+
231
+ Pie rendering delegates to [`@jarenjs/charts`](../charts) (the pie
232
+ engine's single home) — the emitted SVG is unchanged; mermaid passes
233
+ its class names, palette and theme through the render options.
234
+
235
+ ## Performance (measured)
236
+
237
+ Node v22.22.2, 2026-07-19, `npm run benchmark:mermaid` (run it
238
+ yourself). Mermaid has **two** parsers, so there are two honest
239
+ head-to-heads:
240
+
241
+ - **`@mermaid-js/parser`** is the standalone **Langium** parser — it
242
+ covers only the grammars migrated off Jison (pie, gitGraph, …) and
243
+ **cannot parse flowchart or sequence**. The overlapping type is
244
+ **pie**, where `@jarenjs/mermaid` is comparable (~0.003–0.006 ms/op
245
+ either way).
246
+ - **Flowchart and sequence** are still parsed by Mermaid's original
247
+ in-tree **Jison** grammars inside the full `mermaid` package (not by
248
+ `@mermaid-js/parser`). Against `mermaid.parse()` (DOM-coupled, run
249
+ under jsdom), `@jarenjs/mermaid` parses the same sources **roughly two
250
+ orders of magnitude faster**:
251
+
252
+ | flowchart/sequence parse (ms/op) | jaren-mermaid | mermaid.parse (Jison) |
253
+ |---|---|---|
254
+ | flowchart ~5 nodes | ~0.04 | ~10 |
255
+ | sequence ~5 nodes | ~0.02 | ~1.4 |
256
+ | flowchart ~25 nodes | ~0.09 | ~7 |
257
+ | sequence ~25 nodes | ~0.05 | ~4 |
258
+
259
+ (`mermaid.parse` is async and runs the whole parse front-end — type
260
+ detection + Jison + validation — so it is heavy and noisy; these are
261
+ representative, not a bare-grammar microbenchmark.)
262
+
263
+ The headless **parse → layout → SVG string** rows are jaren-only
264
+ (<!--bm:mermaid.svgMs-->~0.46 ms for a 25-node flowchart, ~1.4 ms at 100 nodes<!--/bm-->): mermaid.js
265
+ needs a browser DOM (`getBBox`) to render, so there is no fair
266
+ full-render head-to-head — producing a complete standalone SVG in pure
267
+ Node is a capability it lacks.
268
+
269
+ ## Design notes
270
+
271
+ - **Two layers, one-way arrow.** The engine imports only `@jarenjs/core`
272
+ and `@jarenjs/view` (shared SVG builders from `@jarenjs/view/helpers`,
273
+ `hashContent` from core); the component adds the app glue. The Markdown
274
+ plugin lives on the md→mermaid arrow with no cycle.
275
+ - **CSP-safe.** No `eval`, no `new Function`, no `innerHTML`. Text and
276
+ attributes are escaped by the view serializer.
277
+ - **Structural sharing.** Same source → reference-equal vnode; a small
278
+ source change re-emits only affected sub-scenes; block vnodes carry
279
+ content-hash keys.
280
+
281
+ See [ARCHITECTURE.md](ARCHITECTURE.md) and
282
+ [docs/MERMAID-FORMAT.md](docs/MERMAID-FORMAT.md).
@@ -0,0 +1,210 @@
1
+ /**
2
+ * @file The Mermaid AST vocabulary: node constructors and walkers.
3
+ *
4
+ * Every node is a plain JSON object born from a constructor so that all
5
+ * nodes of a type share one hidden class — property access stays
6
+ * monomorphic and the structural hash is deterministic (MERMAID-FORMAT
7
+ * §4). The AST is deliberately **geometry-free**:
8
+ * layout is a separate pass, so the AST is a faithful, lossless
9
+ * semantic model of the diagram's *meaning* — a directed graph
10
+ * (flowchart), an ordered interaction (sequence), a finite state machine
11
+ * (state) — that other engines project via JSLT without ever seeing a
12
+ * coordinate.
13
+ *
14
+ * Member order is fixed per constructor; keep it stable so the FNV-1a
15
+ * hash of `JSON.stringify` is reproducible and the round-trip printer
16
+ * (`to-mermaid.js`) is a fixed point.
17
+ */
18
+ /** The diagram-document format version this package produces. */
19
+ export declare const MERMAID_VERSION = "0.1";
20
+ export type DiagramDocument = {
21
+ /**
22
+ * format version
23
+ */
24
+ $mermaid: string;
25
+ /**
26
+ * diagram type (`flowchart`, `sequence`, …)
27
+ */
28
+ diagram: string;
29
+ /**
30
+ * plain-JSON config (theme, per-type options)
31
+ */
32
+ config: any;
33
+ /**
34
+ * the type-specific, geometry-free AST
35
+ */
36
+ ast: any;
37
+ meta: {
38
+ hash: string;
39
+ direction: string | null;
40
+ title: string | null;
41
+ };
42
+ };
43
+ /**
44
+ * @typedef {object} DiagramDocument
45
+ * @property {string} $mermaid format version
46
+ * @property {string} diagram diagram type (`flowchart`, `sequence`, …)
47
+ * @property {any} config plain-JSON config (theme, per-type options)
48
+ * @property {any} ast the type-specific, geometry-free AST
49
+ * @property {{ hash: string, direction: string|null, title: string|null }} meta
50
+ */
51
+ /**
52
+ * Assemble the shared DiagramDocument envelope. Fresh per parse,
53
+ * never mutated after return — share-friendly for JSLT/patch.
54
+ * @param {string} diagram
55
+ * @param {any} config
56
+ * @param {any} ast
57
+ * @param {{ hash: string, direction: string|null, title: string|null }} meta
58
+ * @returns {DiagramDocument}
59
+ */
60
+ export declare function diagramDocument(diagram: string, config: any, ast: any, meta: {
61
+ hash: string;
62
+ direction: string | null;
63
+ title: string | null;
64
+ }): DiagramDocument;
65
+ export type FlowShape = 'rect' | 'round' | 'stadium' | 'subroutine' | 'cylinder' | 'circle' | 'doublecircle' | 'diamond' | 'hexagon' | 'parallelogram' | 'parallelogram_alt' | 'trapezoid' | 'trapezoid_alt' | 'asymmetric';
66
+ /**
67
+ * @typedef {'rect'|'round'|'stadium'|'subroutine'|'cylinder'|'circle'
68
+ * |'doublecircle'|'diamond'|'hexagon'|'parallelogram'|'parallelogram_alt'
69
+ * |'trapezoid'|'trapezoid_alt'|'asymmetric'} FlowShape
70
+ */
71
+ /**
72
+ * A flowchart vertex.
73
+ * @param {string} id
74
+ * @param {string} label
75
+ * @param {FlowShape} shape
76
+ * @returns {{ id: string, label: string, shape: FlowShape }}
77
+ */
78
+ export declare function flowNode(id: string, label: string, shape: FlowShape): {
79
+ id: string;
80
+ label: string;
81
+ shape: FlowShape;
82
+ };
83
+ /**
84
+ * A flowchart edge (link). `stroke` is the line style, `head`/`tail`
85
+ * the endpoint markers, `length` the dash count (preserved so the
86
+ * canonical printer is a fixed point), `label` the optional edge text.
87
+ * @param {string} from
88
+ * @param {string} to
89
+ * @param {'solid'|'thick'|'dotted'} stroke
90
+ * @param {'none'|'arrow'|'circle'|'cross'} head
91
+ * @param {'none'|'arrow'|'circle'|'cross'} tail
92
+ * @param {number} length
93
+ * @param {string|null} label
94
+ * @returns {object}
95
+ */
96
+ export declare function flowEdge(from: string, to: string, stroke: 'solid' | 'thick' | 'dotted', head: 'none' | 'arrow' | 'circle' | 'cross', tail: 'none' | 'arrow' | 'circle' | 'cross', length: number, label: string | null): object;
97
+ /**
98
+ * A subgraph grouping.
99
+ * @param {string} id
100
+ * @param {string} label
101
+ * @param {string|null} direction
102
+ * @param {string[]} nodes ids of member nodes
103
+ * @returns {object}
104
+ */
105
+ export declare function flowSubgraph(id: string, label: string, direction: string | null, nodes: string[]): object;
106
+ /**
107
+ * A `classDef` style class.
108
+ * @param {string} name
109
+ * @param {string} styles semicolon-separated CSS declarations
110
+ * @returns {object}
111
+ */
112
+ export declare function flowClassDef(name: string, styles: string): object;
113
+ /**
114
+ * A `class`/`:::` assignment of a style class to a node.
115
+ * @param {string} node
116
+ * @param {string} name
117
+ * @returns {object}
118
+ */
119
+ export declare function flowClass(node: string, name: string): object;
120
+ /**
121
+ * A `style` inline-style assignment to a node.
122
+ * @param {string} node
123
+ * @param {string} styles
124
+ * @returns {object}
125
+ */
126
+ export declare function flowStyle(node: string, styles: string): object;
127
+ /**
128
+ * The flowchart AST root.
129
+ * @param {string} direction
130
+ * @param {object[]} nodes
131
+ * @param {object[]} edges
132
+ * @param {object[]} subgraphs
133
+ * @param {object[]} classDefs
134
+ * @param {object[]} classes
135
+ * @param {object[]} styles
136
+ * @returns {object}
137
+ */
138
+ export declare function flowchartAst(direction: string, nodes: object[], edges: object[], subgraphs: object[], classDefs: object[], classes: object[], styles: object[]): object;
139
+ /**
140
+ * A declared participant/actor.
141
+ * @param {string} id
142
+ * @param {string} label
143
+ * @param {'participant'|'actor'} kind
144
+ * @returns {object}
145
+ */
146
+ export declare function seqParticipant(id: string, label: string, kind: 'participant' | 'actor'): object;
147
+ /**
148
+ * A message statement.
149
+ * @param {string} from
150
+ * @param {string} to
151
+ * @param {string} text
152
+ * @param {'solid'|'dotted'} line
153
+ * @param {'arrow'|'open'|'cross'|'point'} head
154
+ * @param {'activate'|'deactivate'|null} activation `+`/`-` shorthand
155
+ * @returns {object}
156
+ */
157
+ export declare function seqMessage(from: string, to: string, text: string, line: 'solid' | 'dotted', head: 'arrow' | 'open' | 'cross' | 'point', activation: 'activate' | 'deactivate' | null): object;
158
+ /**
159
+ * A note statement.
160
+ * @param {'left of'|'right of'|'over'} placement
161
+ * @param {string[]} actors
162
+ * @param {string} text
163
+ * @returns {object}
164
+ */
165
+ export declare function seqNote(placement: 'left of' | 'right of' | 'over', actors: string[], text: string): object;
166
+ /**
167
+ * An explicit activate/deactivate statement.
168
+ * @param {'activate'|'deactivate'} kind
169
+ * @param {string} actor
170
+ * @returns {object}
171
+ */
172
+ export declare function seqActivation(kind: 'activate' | 'deactivate', actor: string): object;
173
+ /**
174
+ * A block statement (loop/opt/alt/par/critical/break). Single-branch
175
+ * blocks (loop/opt/critical/break) carry one branch; alt/par carry one
176
+ * per `else`/`and` section. `branches` is always present so the shape
177
+ * is monomorphic.
178
+ * @param {'loop'|'opt'|'alt'|'par'|'critical'|'break'} blockType
179
+ * @param {{ label: string, statements: object[] }[]} branches
180
+ * @returns {object}
181
+ */
182
+ export declare function seqBlock(blockType: 'loop' | 'opt' | 'alt' | 'par' | 'critical' | 'break', branches: {
183
+ label: string;
184
+ statements: object[];
185
+ }[]): object;
186
+ /**
187
+ * The sequence AST root.
188
+ * @param {object[]} participants explicitly declared participants
189
+ * @param {object[]} statements ordered interaction statements
190
+ * @param {boolean} autonumber
191
+ * @returns {object}
192
+ */
193
+ export declare function sequenceAst(participants: object[], statements: object[], autonumber: boolean): object;
194
+ /**
195
+ * A geometry-free "lines" AST for diagram types that parse-accept but
196
+ * are not yet laid out (the secondary types). Preserves the raw body
197
+ * lines so `toMermaid` round-trips and the coverage scorecard can be
198
+ * honest.
199
+ * @param {string} diagram
200
+ * @param {string[]} lines
201
+ * @returns {object}
202
+ */
203
+ export declare function rawAst(diagram: string, lines: string[]): object;
204
+ /**
205
+ * Walk the ordered statements of a sequence AST (descending into block
206
+ * branches), calling `visitor(stmt)` pre-order.
207
+ * @param {object[]} statements
208
+ * @param {(stmt: any) => void} visitor
209
+ */
210
+ export declare function walkSequence(statements: object[], visitor: (stmt: any) => void): void;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @file The Mermaid VISUAL COMPONENT — part two of the package.
3
+ *
4
+ * Everything below this line is presentation glue; the engine
5
+ * (`@jarenjs/mermaid`) neither knows nor needs any of it. Mirrors
6
+ * `@jarenjs/md`'s `createMdComponent` field-for-field:
7
+ *
8
+ * - `createMermaidComponent()` — a memoized `view()` projection for
9
+ * `@jarenjs/app` viewModels (reference-stable, so an unchanged source
10
+ * patches in O(1) — the O(change) contract), `effects` entries for
11
+ * the app effect registry (`mermaid-render`, `mermaid-load`), and a
12
+ * `hydrate()` pass kept for API symmetry (a no-op in v1: the render is
13
+ * already complete);
14
+ * - `styles/mermaid.css` — the component stylesheet.
15
+ *
16
+ * The boundary is one-way: the component imports the engine, never the
17
+ * reverse.
18
+ */
19
+ export type MermaidComponentOptions = {
20
+ /**
21
+ * theme name or override object
22
+ */
23
+ theme?: any;
24
+ /**
25
+ * LRU size for the source-string memo (default 32)
26
+ */
27
+ memoLimit?: number;
28
+ /**
29
+ * base URL for `mermaid-load`
30
+ */
31
+ base?: string | URL;
32
+ /**
33
+ * fetch implementation for `mermaid-load`
34
+ */
35
+ fetch?: typeof globalThis.fetch;
36
+ onHydrateError?: (err: any) => void;
37
+ };
38
+ export type MermaidComponent = {
39
+ /**
40
+ * memoized compile
41
+ */
42
+ compile: (source: string) => any;
43
+ /**
44
+ * memoized vnode projection
45
+ */
46
+ view: (sourceOrDoc: any) => any;
47
+ effects: Record<string, (props: any, dispatch: any) => any>;
48
+ /**
49
+ * no-op in v1
50
+ */
51
+ hydrate: (container: any) => void;
52
+ };
53
+ /**
54
+ * @typedef {object} MermaidComponentOptions
55
+ * @property {any} [theme] theme name or override object
56
+ * @property {number} [memoLimit] LRU size for the source-string memo (default 32)
57
+ * @property {string | URL} [base] base URL for `mermaid-load`
58
+ * @property {typeof globalThis.fetch} [fetch] fetch implementation for `mermaid-load`
59
+ * @property {(err: any) => void} [onHydrateError]
60
+ */
61
+ /**
62
+ * @typedef {object} MermaidComponent
63
+ * @property {(source: string) => any} compile memoized compile
64
+ * @property {(sourceOrDoc: any) => any} view memoized vnode projection
65
+ * @property {Record<string, (props: any, dispatch: any) => any>} effects
66
+ * @property {(container: any) => void} hydrate no-op in v1
67
+ */
68
+ /**
69
+ * Create the Mermaid component.
70
+ *
71
+ * @example
72
+ * const mermaid = createMermaidComponent();
73
+ * createApp(appDoc, {
74
+ * effects: { ...mermaid.effects },
75
+ * viewModel: (state) => ({ ...state, diagram: mermaid.view(state.source) }),
76
+ * });
77
+ *
78
+ * @param {MermaidComponentOptions} [options]
79
+ * @returns {MermaidComponent}
80
+ */
81
+ export declare function createMermaidComponent(options?: MermaidComponentOptions): MermaidComponent;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @file The engine's one error type. Parsers raise it with a 1-based
3
+ * `line`/`column`; the render path (`diagramToVnode`/`renderMermaid`)
4
+ * catches it and emits a clear error vnode instead of throwing, so
5
+ * rendering is always total.
6
+ */
7
+ export declare class MermaidParseError extends Error {
8
+ /** @type {number} */
9
+ line: number;
10
+ /** @type {number} */
11
+ column: number;
12
+ /**
13
+ * @param {string} message
14
+ * @param {number} [line] 1-based line number
15
+ * @param {number} [column] 1-based column number
16
+ */
17
+ constructor(message: string, line?: number, column?: number);
18
+ }
19
+ /**
20
+ * The `fail(message, position)` idiom from `packages/json/src/path.js`,
21
+ * adapted to line/column. Throws; never returns.
22
+ * @param {string} message
23
+ * @param {number} line
24
+ * @param {number} [column]
25
+ * @returns {never}
26
+ */
27
+ export declare function fail(message: string, line: number, column?: number): never;