@kekonic/diagrams-core 1.0.0-rc.4

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.
@@ -0,0 +1,967 @@
1
+ //#region src/types/geometry.d.ts
2
+ /** Core geometry and shared primitives — no AST types here. */
3
+ type Point = {
4
+ x: number;
5
+ y: number;
6
+ };
7
+ type Vec2 = {
8
+ x: number;
9
+ y: number;
10
+ };
11
+ type Rect = {
12
+ x: number;
13
+ y: number;
14
+ width: number;
15
+ height: number;
16
+ };
17
+ type BoxPadding = {
18
+ top: number;
19
+ right: number;
20
+ bottom: number;
21
+ left: number;
22
+ };
23
+ type SourceRange = {
24
+ start: {
25
+ line: number;
26
+ column: number;
27
+ offset: number;
28
+ };
29
+ end: {
30
+ line: number;
31
+ column: number;
32
+ offset: number;
33
+ };
34
+ };
35
+ type Diagnostic = {
36
+ severity: "error" | "warning" | "info";
37
+ code: string;
38
+ message: string;
39
+ range: SourceRange;
40
+ hint?: string;
41
+ };
42
+ declare function rectCenter(r: Rect): Point;
43
+ declare function rectRight(r: Rect): number;
44
+ declare function rectBottom(r: Rect): number;
45
+ declare function rectsOverlap(a: Rect, b: Rect, gap?: number): boolean;
46
+ declare function expandRect(r: Rect, pad: number): Rect;
47
+ declare function manhattan(a: Point, b: Point): number;
48
+ //#endregion
49
+ //#region src/types/shapes.d.ts
50
+ /**
51
+ * Shared shape id vocabulary — leaf types used by kinds, compile, and geometry.
52
+ * Geometry implementations live in @kekonic/diagrams-geometry; this module
53
+ * only names the ids so core can validate without depending on renderers.
54
+ */
55
+ declare const BUILTIN_SHAPE_IDS: readonly ["rectangle", "rounded", "pill", "circle", "ellipse", "diamond", "hexagon", "triangle", "parallelogram", "trapezoid", "document", "folded-document", "cylinder", "cloud", "person", "queue", "stream", "table", "boundary"];
56
+ type BuiltinShapeId = (typeof BUILTIN_SHAPE_IDS)[number];
57
+ /**
58
+ * Open shape id — built-ins plus custom registry ids.
59
+ * Prefer this over a closed union so `registerShape()` can extend the set.
60
+ */
61
+ type ShapeId = BuiltinShapeId | (string & {});
62
+ declare function normalizeShapeId(shape: string | undefined | null): string;
63
+ declare function isKnownShapeId(shape: string | undefined | null): boolean;
64
+ declare function listBuiltinShapeIds(): readonly string[];
65
+ //#endregion
66
+ //#region src/types/branch.d.ts
67
+ /** Compiled / derived branch outcome for edges (layout + theme share this). */
68
+ type BranchKind = "yes" | "no" | "neutral";
69
+ /**
70
+ * Classify an edge label into a yes/no/neutral branch cue.
71
+ * Only clear affirmative/negative tokens — use `branch: yes|no` for outcome wording.
72
+ */
73
+ declare function classifyBranch(label?: string): BranchKind;
74
+ declare function normalizeBranch(value: unknown): BranchKind | undefined;
75
+ //#endregion
76
+ //#region src/types/cardinality.d.ts
77
+ /**
78
+ * Relationship endpoint multiplicity for ERD edges.
79
+ * Drawn as crow's-foot / IE-style markers instead of plain arrowheads.
80
+ */
81
+ type Cardinality = "one" | "zeroOrOne" | "oneOrMany" | "zeroOrMany";
82
+ type EdgeCardinality = {
83
+ /** Multiplicity at the source (from) end. */from: Cardinality; /** Multiplicity at the target (to) end. */
84
+ to: Cardinality;
85
+ };
86
+ /**
87
+ * Parse cardinality from a property or label.
88
+ *
89
+ * Forms:
90
+ * - `"1:N"` / `"1:0..N"` / `"0..1:N"` (from:to)
91
+ * - Mermaid-ish `"||--o{"` / `"}o--||"`
92
+ * - Single side `"N"` (applied to target; source defaults to `one`)
93
+ */
94
+ declare function parseCardinality(raw: unknown): EdgeCardinality | undefined;
95
+ /**
96
+ * True when a label only encodes cardinality (crow's-foot already conveys it).
97
+ * Shared by finalize (label placement) and SVG (hide duplicate text).
98
+ */
99
+ declare function isPureCardinalityLabel(label: string | undefined): boolean;
100
+ declare function cardinalityLabel(c: EdgeCardinality): string;
101
+ /** Default IE cardinality for a FK from parent → child. */
102
+ declare function fkCardinality(fkNotNull: boolean | undefined): EdgeCardinality;
103
+ //#endregion
104
+ //#region src/types/table.d.ts
105
+ /** Column key roles for ERD-style table nodes. */
106
+ type TableColumnKey = "pk" | "fk" | "uk";
107
+ type TableColumnRef = {
108
+ /** Referenced table / entity node id. */table: string; /** Referenced column name (usually a PK). */
109
+ column: string;
110
+ };
111
+ type TableColumn = {
112
+ /** Column / attribute name. */name: string; /** SQL-ish or conceptual type (e.g. uuid, text, timestamptz). */
113
+ type?: string; /** Primary / foreign / unique key markers (order preserved). */
114
+ keys: TableColumnKey[]; /** NOT NULL */
115
+ notNull?: boolean; /** FK target — e.g. from `"customer_id FK uuid -> customers.id"`. */
116
+ references?: TableColumnRef; /** Optional short note shown muted after the type. */
117
+ note?: string;
118
+ };
119
+ /**
120
+ * Parse a compact column spec string into a structured column.
121
+ *
122
+ * Accepted forms (whitespace-separated):
123
+ * - `"id PK uuid"`
124
+ * - `"email text UK NN"`
125
+ * - `"customer_id : uuid FK"`
126
+ * - `"customer_id FK uuid -> customers.id"`
127
+ * - `"status text NN // order lifecycle"` (note after //)
128
+ *
129
+ * Flags: PK, FK, UK/UNIQUE, NN/NOT NULL/NOTNULL (case-insensitive).
130
+ */
131
+ declare function parseTableColumnSpec(raw: string): TableColumn | null;
132
+ declare function parseTableColumns(raw: unknown): TableColumn[];
133
+ declare function findColumnIndex(columns: TableColumn[] | undefined, name: string): number;
134
+ /**
135
+ * Format a structured column as a highlightable line:
136
+ * `customer_id: uuid FK NN -> customers.id // buyer`
137
+ */
138
+ declare function formatTableColumnLine(col: TableColumn): string;
139
+ //#endregion
140
+ //#region src/types/sequence.d.ts
141
+ /** Diagram surface — flow/state use ELK; sequence uses the time-axis layout engine. */
142
+ type DiagramKind = "flow" | "state" | "sequence";
143
+ type SequenceMessageKind = "sync" | "async" | "return" | "create" | "destroy" | "failure" | "found" | "lost";
144
+ /**
145
+ * Combined-fragment operators (canonical long names).
146
+ * Parser also accepts Mermaid-style aliases: alt, opt, par, group.
147
+ */
148
+ type SequenceFragmentOperator = "alternate" | "optional" | "loop" | "parallel" | "critical" | "break" | "section";
149
+ /** Map authored keyword (including aliases) → canonical operator. */
150
+ declare const SEQUENCE_FRAGMENT_ALIASES: Record<string, SequenceFragmentOperator>;
151
+ /** Title-case label painted on the fragment frame (newcomer-friendly). */
152
+ declare function sequenceFragmentDisplayName(operator: SequenceFragmentOperator): string;
153
+ declare function normalizeSequenceFragmentOperator(word: string): SequenceFragmentOperator | undefined;
154
+ type SequenceNotePlacement = "over" | "left" | "right";
155
+ type SequenceMessage = {
156
+ id: string;
157
+ order: number;
158
+ from: string | null;
159
+ to: string | null;
160
+ kind: SequenceMessageKind;
161
+ label?: string;
162
+ labelAuthored?: boolean; /** Pair return messages back to the call that opened them (when known). */
163
+ replyTo?: string;
164
+ sourceRange?: SourceRange;
165
+ };
166
+ type SequenceActivation = {
167
+ id: string;
168
+ participantId: string;
169
+ startOrder: number;
170
+ endOrder: number;
171
+ sourceRange?: SourceRange;
172
+ };
173
+ type SequenceFragmentOperand = {
174
+ label?: string;
175
+ styleRefs: string[]; /** Inclusive message-order span covered by this operand. */
176
+ startOrder: number;
177
+ endOrder: number;
178
+ children: SequenceFragment[];
179
+ };
180
+ type SequenceFragment = {
181
+ id: string;
182
+ operator: SequenceFragmentOperator;
183
+ label?: string; /** `is danger` / authored fragment styles. */
184
+ styleRefs: string[]; /** Inline CSS vars from `style … for fragment` resolution inputs (compile-time bag). */
185
+ unresolvedVars: Record<string, string>;
186
+ startOrder: number;
187
+ endOrder: number;
188
+ operands: SequenceFragmentOperand[];
189
+ sourceRange?: SourceRange;
190
+ };
191
+ type SequenceNote = {
192
+ id: string;
193
+ order: number;
194
+ placement: SequenceNotePlacement;
195
+ participantIds: string[];
196
+ text: string;
197
+ sourceRange?: SourceRange;
198
+ };
199
+ type SequenceDivider = {
200
+ id: string;
201
+ order: number;
202
+ label?: string;
203
+ sourceRange?: SourceRange;
204
+ };
205
+ /**
206
+ * Sequence-specific IR compiled beside GraphModel.
207
+ * Ordering, activations, and fragments live here — not on unordered GraphEdge alone.
208
+ */
209
+ type SequenceIR = {
210
+ autonumber: boolean;
211
+ messages: SequenceMessage[];
212
+ activations: SequenceActivation[];
213
+ fragments: SequenceFragment[];
214
+ notes: SequenceNote[];
215
+ dividers: SequenceDivider[]; /** Participant ids in declaration order (X axis). */
216
+ participantOrder: string[];
217
+ };
218
+ //#endregion
219
+ //#region src/parser/edge-ops.d.ts
220
+ /** Edge operators — longest first so `<->` / `<..` / `<~` / `-->` win over shorter prefixes. */
221
+ declare const EDGE_OPS: readonly ["<->", "<..", "<~", "<=", "<-", "x-", "=>", "~>", "..>", "-->", "-x", "->", "--"];
222
+ type EdgeOperator = (typeof EDGE_OPS)[number];
223
+ /** Escape for TextMate / Shiki character classes (e.g. `.` in `..>`). */
224
+ declare function edgeOpsPattern(): string;
225
+ //#endregion
226
+ //#region src/parser/ast.d.ts
227
+ type PropertyValue = string | number | boolean | string[];
228
+ type PropertyMap = Record<string, PropertyValue>;
229
+ type KDiagramAst = {
230
+ type: "Document";
231
+ version?: number;
232
+ body: TopLevelNode[];
233
+ diagnostics: Diagnostic[];
234
+ };
235
+ type TopLevelNode = DiagramAst | SequenceAst;
236
+ type DiagramAst = {
237
+ type: "Diagram";
238
+ diagramKind: "flow" | "state"; /** Optional quoted title after `diagram` — used for SVG/a11y and presentation chrome. */
239
+ name?: string;
240
+ statements: StatementAst[];
241
+ range: SourceRange;
242
+ };
243
+ /** Classical UML sequence diagram — time-axis layout, not ELK layered flow. */
244
+ type SequenceAst = {
245
+ type: "Sequence";
246
+ name?: string;
247
+ statements: SequenceStatementAst[];
248
+ range: SourceRange;
249
+ };
250
+ type StatementAst = NodeAst | EdgeAst | GroupAst | StyleAst | StyleRefAst | GroupMemberAst | DirectiveAst | LayoutBlockAst | EdgePolicyBlockAst | RenderBlockAst | PresentationBlockAst | AnimationBlockAst;
251
+ type SequenceStatementAst = NodeAst | EdgeAst | StyleAst | StyleRefAst | DirectiveAst | LayoutBlockAst | EdgePolicyBlockAst | RenderBlockAst | PresentationBlockAst | AnimationBlockAst | SequenceActivateAst | SequenceDeactivateAst | SequenceCreateAst | SequenceDestroyAst | SequenceNoteAst | SequenceDividerAst | SequenceAutonumberAst | SequenceFragmentAst;
252
+ type SequenceActivateAst = {
253
+ type: "SequenceActivate";
254
+ participantId: string;
255
+ range: SourceRange;
256
+ };
257
+ type SequenceDeactivateAst = {
258
+ type: "SequenceDeactivate";
259
+ participantId: string;
260
+ range: SourceRange;
261
+ };
262
+ type SequenceCreateAst = {
263
+ type: "SequenceCreate";
264
+ node: NodeAst;
265
+ range: SourceRange;
266
+ };
267
+ type SequenceDestroyAst = {
268
+ type: "SequenceDestroy";
269
+ participantId: string;
270
+ range: SourceRange;
271
+ };
272
+ type SequenceNoteAst = {
273
+ type: "SequenceNote";
274
+ placement: "over" | "left" | "right";
275
+ participantIds: string[];
276
+ text: string;
277
+ range: SourceRange;
278
+ };
279
+ type SequenceDividerAst = {
280
+ type: "SequenceDivider";
281
+ label?: string;
282
+ range: SourceRange;
283
+ };
284
+ type SequenceAutonumberAst = {
285
+ type: "SequenceAutonumber";
286
+ range: SourceRange;
287
+ };
288
+ type SequenceFragmentAst = {
289
+ type: "SequenceFragment";
290
+ operator: SequenceFragmentOperator;
291
+ label?: string; /** Semantic / authored styles (`is danger`, `is timeoutBand`). */
292
+ styleRefs: string[];
293
+ operands: SequenceFragmentOperandAst[];
294
+ range: SourceRange;
295
+ };
296
+ type SequenceFragmentOperandAst = {
297
+ /** `else` / `and` label, or primary fragment label. */label?: string; /** Per-operand styles (`else "timeout" is danger`). */
298
+ styleRefs: string[];
299
+ statements: SequenceStatementAst[];
300
+ range: SourceRange;
301
+ };
302
+ type AnimationTargetAst = {
303
+ type: "all";
304
+ } | {
305
+ type: "node";
306
+ id: string;
307
+ } | {
308
+ type: "edge";
309
+ from: string;
310
+ to: string;
311
+ };
312
+ type AnimationCueAst = {
313
+ type: "dim";
314
+ targets: AnimationTargetAst[];
315
+ range: SourceRange;
316
+ } | {
317
+ type: "activate";
318
+ targets: AnimationTargetAst[];
319
+ range: SourceRange;
320
+ } | {
321
+ type: "pulse";
322
+ targets: AnimationTargetAst[];
323
+ durationMs?: number;
324
+ range: SourceRange;
325
+ } | {
326
+ type: "flow";
327
+ path: string[];
328
+ durationMs?: number;
329
+ range: SourceRange;
330
+ } | {
331
+ type: "wait";
332
+ durationMs: number;
333
+ range: SourceRange;
334
+ } | {
335
+ type: "loop";
336
+ range: SourceRange;
337
+ } | {
338
+ type: "parallel";
339
+ cues: AnimationCueAst[];
340
+ range: SourceRange;
341
+ };
342
+ type AnimationBlockAst = {
343
+ type: "AnimationBlock";
344
+ name: string;
345
+ cues: AnimationCueAst[];
346
+ range: SourceRange;
347
+ };
348
+ type NodeAst = {
349
+ type: "Node";
350
+ id: string;
351
+ kind: string;
352
+ label?: string;
353
+ properties: PropertyMap; /** From inline `is styleName` on the declaration (before or after `{ … }`). */
354
+ styleRefs: string[];
355
+ range: SourceRange;
356
+ };
357
+ type EdgeAst = {
358
+ type: "Edge";
359
+ from: string;
360
+ to: string; /** Optional column on the source table (ERD: `customers.id -> …`). */
361
+ fromColumn?: string; /** Optional column on the target table (ERD: `… -> orders.customer_id`). */
362
+ toColumn?: string;
363
+ op: EdgeOperator;
364
+ label?: string;
365
+ properties: PropertyMap;
366
+ styleRefs: string[];
367
+ range: SourceRange;
368
+ };
369
+ type GroupAst = {
370
+ type: "Group";
371
+ id?: string;
372
+ label?: string;
373
+ groupKind: "group" | "boundary" | "zone" | "swimlane";
374
+ statements: StatementAst[];
375
+ properties: PropertyMap;
376
+ range: SourceRange;
377
+ };
378
+ type StyleAst = {
379
+ type: "Style";
380
+ name: string;
381
+ target: "node" | "edge" | "fragment";
382
+ properties: PropertyMap;
383
+ range: SourceRange;
384
+ };
385
+ type StyleRefAst = {
386
+ type: "StyleRef";
387
+ targetIds: string[];
388
+ styleName: string;
389
+ range: SourceRange;
390
+ };
391
+ type GroupMemberAst = {
392
+ type: "GroupMember";
393
+ nodeIds: string[];
394
+ range: SourceRange;
395
+ };
396
+ type DirectiveAst = {
397
+ type: "Directive";
398
+ name: string; /** Scalar or identifier list (e.g. `columns: [edge, core, data]`). */
399
+ value?: string | number | boolean | string[];
400
+ range: SourceRange;
401
+ };
402
+ type LayoutBlockAst = {
403
+ type: "LayoutBlock";
404
+ properties: PropertyMap;
405
+ range: SourceRange;
406
+ };
407
+ type EdgePolicyBlockAst = {
408
+ type: "EdgePolicyBlock";
409
+ properties: PropertyMap;
410
+ range: SourceRange;
411
+ };
412
+ type RenderBlockAst = {
413
+ type: "RenderBlock";
414
+ properties: PropertyMap;
415
+ range: SourceRange;
416
+ };
417
+ type PresentationBlockAst = {
418
+ type: "PresentationBlock";
419
+ properties: PropertyMap;
420
+ range: SourceRange;
421
+ };
422
+ //#endregion
423
+ //#region src/animation/types.d.ts
424
+ /** Compiled animation targeting graph nodes/edges by id. */
425
+ type AnimationTarget = {
426
+ type: "all";
427
+ } | {
428
+ type: "node";
429
+ id: string;
430
+ } | {
431
+ type: "edge";
432
+ from: string;
433
+ to: string;
434
+ };
435
+ type AnimationCue = {
436
+ op: "dim";
437
+ targets: AnimationTarget[];
438
+ } | {
439
+ op: "activate";
440
+ targets: AnimationTarget[];
441
+ } | {
442
+ op: "pulse";
443
+ targets: AnimationTarget[];
444
+ durationMs: number;
445
+ } | {
446
+ op: "flow";
447
+ path: string[];
448
+ durationMs: number; /** Prefer this edge when from→to is ambiguous (sequence, single hop). */
449
+ edgeId?: string;
450
+ /**
451
+ * Per-hop edge ids aligned with `path` (`path.length - 1` entries).
452
+ * When present, index `i` is the edge for hop `path[i] → path[i+1]`.
453
+ */
454
+ edgeIds?: string[];
455
+ } | {
456
+ op: "wait";
457
+ durationMs: number;
458
+ } /** Sibling cues that share one clock — duration is max(child durations). */ | {
459
+ op: "parallel";
460
+ cues: AnimationCue[];
461
+ };
462
+ type AnimationDefinition = {
463
+ /** Stable slug (from authored name, or `"auto"` for inferred). */id: string; /** Display name for the picker. */
464
+ name: string;
465
+ loop: boolean;
466
+ cues: AnimationCue[];
467
+ /**
468
+ * `authored` — explicit cues.
469
+ * `auto` — empty opt-in block; player fills cues via `inferAutoAnimation`.
470
+ */
471
+ source: "auto" | "authored";
472
+ };
473
+ //#endregion
474
+ //#region src/types/presentation.d.ts
475
+ /** Padding — uniform number or per-side box. */
476
+ type PaddingSpec = number | {
477
+ top?: number;
478
+ right?: number;
479
+ bottom?: number;
480
+ left?: number;
481
+ };
482
+ /** Only as-authored — no silent case transforms. */
483
+ type LabelCasePolicy = "as-authored";
484
+ type TitleSpec = false | true | "auto" | {
485
+ text?: string;
486
+ subtitle?: string;
487
+ align?: "start" | "center";
488
+ };
489
+ /**
490
+ * Opt-in presentation chrome. Omitted options yield embeddable, transparent SVG.
491
+ * There are no presets — set fields explicitly when you want title, accents, etc.
492
+ */
493
+ type PresentationOptions = {
494
+ title?: TitleSpec; /** Outer inset around the full rendered canvas (including chrome). */
495
+ padding?: PaddingSpec; /** Gap between chrome elements (title block) and diagram content. */
496
+ contentPadding?: PaddingSpec;
497
+ labelCase?: LabelCasePolicy;
498
+ /**
499
+ * When true, stamp built-in kind eyebrows (Service, Gateway, …) under every node.
500
+ * Prefer per-node `subtitle: "…"` for authored captions. Default false.
501
+ */
502
+ showKindSubtitles?: boolean;
503
+ /**
504
+ * When true, paint small dots where edges meet node silhouettes.
505
+ * Dot fill matches the edge stroke. Default false.
506
+ */
507
+ showEndpoints?: boolean; /** Tint group bands for review readability. */
508
+ groupAccent?: boolean; /** Keep edge labels inside the diagram bounds (default true). */
509
+ clampLabels?: boolean;
510
+ };
511
+ type ResolvedPadding = {
512
+ top: number;
513
+ right: number;
514
+ bottom: number;
515
+ left: number;
516
+ };
517
+ type ResolvedTitle = false | {
518
+ text: string;
519
+ subtitle?: string;
520
+ align: "start" | "center";
521
+ };
522
+ /** Fully resolved presentation — no undefined fields. */
523
+ type ResolvedPresentation = {
524
+ title: ResolvedTitle;
525
+ padding: ResolvedPadding;
526
+ contentPadding: ResolvedPadding;
527
+ labelCase: LabelCasePolicy;
528
+ showKindSubtitles: boolean;
529
+ showEndpoints: boolean;
530
+ groupAccent: boolean;
531
+ clampLabels: boolean;
532
+ };
533
+ /** Props removed from the presentation DSL — emit a diagnostic instead of ignoring. */
534
+ declare const REMOVED_PRESENTATION_PROPS: readonly ["preset", "background", "grid", "frame", "legend", "nodeGradient", "groupHeaders"];
535
+ type RemovedPresentationProp = (typeof REMOVED_PRESENTATION_PROPS)[number];
536
+ declare function normalizePadding(spec: PaddingSpec | undefined, fallback?: number): ResolvedPadding;
537
+ /** Merge explicit options onto chromeless defaults. */
538
+ declare function resolvePresentation(options: PresentationOptions | undefined, graphTitle?: string): ResolvedPresentation;
539
+ /** Parse a DSL property map into PresentationOptions. */
540
+ declare function presentationFromProperties(props: Record<string, unknown>): PresentationOptions;
541
+ /**
542
+ * Pick the case policy for a concrete label.
543
+ * Quoted / authored labels are never rewritten.
544
+ */
545
+ declare function displayLabelCase(_labelAuthored: boolean | undefined, _policy: LabelCasePolicy): LabelCasePolicy;
546
+ declare function formatLabelText(text: string, _policy: LabelCasePolicy): string;
547
+ /** Shallow-merge presentation layers (later wins). */
548
+ declare function mergePresentationOptions(...layers: (PresentationOptions | undefined)[]): PresentationOptions | undefined;
549
+ //#endregion
550
+ //#region src/types/graph.d.ts
551
+ type EdgeKind = "sync" | "async" | "eventual" | "dependency" | "failure" | "association";
552
+ /** Where arrowheads attach after layout (path always runs from → to). */
553
+ type EdgeArrows = "end" | "start" | "both" | "none";
554
+ type GroupKind = "group" | "boundary" | "zone" | "swimlane";
555
+ type Direction = "LR" | "RL" | "TD" | "BT";
556
+ /** Whole-diagram spacing preset. Local `gap` / `padding` prefer px numbers. */
557
+ type Density = "compact" | "normal" | "spacious";
558
+ type RouteMode = "straight" | "bezier" | "orthogonal" | "rounded" | "metro";
559
+ type CrossingMode = "none" | "gaps" | "jumps" | "smart";
560
+ type BuiltinThemeMode = "dark" | "light";
561
+ /** Built-in themes or names passed to `registerTheme()`. */
562
+ type ThemeMode = BuiltinThemeMode | (string & {});
563
+ type StyleDefinition = {
564
+ name: string; /** Defaults to node when omitted (authored `style name { }` / builtins). */
565
+ target?: "node" | "edge" | "fragment";
566
+ properties: Record<string, string>;
567
+ };
568
+ type GraphNode = {
569
+ id: string;
570
+ label: string;
571
+ /**
572
+ * True when `label` came from a quoted string literal in source.
573
+ * False when the label was derived from the bare id.
574
+ * Authored labels must render verbatim (aside from XML/SVG escaping).
575
+ */
576
+ labelAuthored?: boolean;
577
+ kind: string; /** Geometry id from the shared shape library (normalized at compile). */
578
+ shape?: ShapeId;
579
+ icon?: string; /** Paint policy for icons: brand (embedded fills, default) or theme (currentColor). */
580
+ iconPaint?: "theme" | "brand";
581
+ /**
582
+ * Icon-only ink (CSS color). Compiles to `--icon-color` and themes the glyph
583
+ * without changing the node shell stroke/fill.
584
+ */
585
+ iconColor?: string;
586
+ depth?: number;
587
+ minWidth?: number;
588
+ maxWidth?: number; /** Presentation scale for measure + label size (1 = default). */
589
+ scale?: number;
590
+ groupId?: string;
591
+ styleRefs: string[];
592
+ unresolvedVars?: Record<string, string>;
593
+ note?: string;
594
+ /**
595
+ * When true, show the built-in kind eyebrow (e.g. "Service") for this node.
596
+ * Prefer authored `subtitle` text when you want a custom line.
597
+ */
598
+ showSubtitle?: boolean; /** Optional author-provided subtitle under the title (not the kind name). */
599
+ subtitle?: string; /** C4 / architecture technology tag (e.g. "Spring Boot", "[Java]"). */
600
+ technology?: string; /** Longer body text under the title (C4 description). */
601
+ description?: string; /** ERD columns — when present on a `table` kind, shape becomes an entity card. */
602
+ columns?: TableColumn[];
603
+ sourceRange?: SourceRange;
604
+ };
605
+ type GraphEdge = {
606
+ id: string;
607
+ from: string;
608
+ to: string;
609
+ label?: string;
610
+ /**
611
+ * True when `label` came from a quoted string literal in source.
612
+ * Edge labels are only present when authored; keep the flag for render policy.
613
+ */
614
+ labelAuthored?: boolean;
615
+ kind: EdgeKind;
616
+ /**
617
+ * Arrowhead placement on the routed path (`from` → `to`).
618
+ * Reverse DSL ops (`<-`, …) swap endpoints at compile so arrows stay `"end"`.
619
+ * Bidirectional `<->` compiles to `"both"`.
620
+ */
621
+ arrows?: EdgeArrows;
622
+ styleRefs: string[]; /** Optional icon shown beside the edge label (same id vocabulary as nodes). */
623
+ icon?: string; /** Paint policy for edge icons: brand (embedded fills) or theme (currentColor). */
624
+ iconPaint?: "theme" | "brand"; /** Icon-only ink (CSS color) for the edge label glyph. */
625
+ iconColor?: string;
626
+ priority?: "low" | "normal" | "high";
627
+ /**
628
+ * Prefer the label near the start, middle, or end of the routed path.
629
+ * Auto placement still avoids nodes/crossings; this biases the scorer.
630
+ */
631
+ labelPosition?: "start" | "middle" | "end"; /** Yes/no/neutral branch cue — explicit DSL or compiled from label. */
632
+ branch?: BranchKind; /** ERD relationship multiplicity (crow's-foot markers). */
633
+ cardinality?: EdgeCardinality; /** Source column name for ERD column-anchored edges. */
634
+ fromColumn?: string; /** Target column name for ERD column-anchored edges. */
635
+ toColumn?: string;
636
+ /**
637
+ * Identifying relationship (solid) vs non-identifying (dashed).
638
+ * Column-anchored FK edges default to `false` (non-identifying).
639
+ * Plain table edges without column anchors stay solid unless set explicitly.
640
+ */
641
+ identifying?: boolean; /** Sequence message order (0-based) when diagramKind is sequence. */
642
+ sequenceOrder?: number; /** Sequence message kind when diagramKind is sequence. */
643
+ sequenceKind?: SequenceMessageKind;
644
+ sourceRange?: SourceRange;
645
+ };
646
+ type RegionArrange = "stack" | "row" | "grid";
647
+ type RegionAlign = "stretch" | "start" | "center" | "end";
648
+ type CellArrange = "flow" | "pack" | "stack";
649
+ /** Track spec: count, or named tracks for column/row assignment. */
650
+ type TrackSpec = number | string[];
651
+ /** Declaration-order member of a group (node or nested group/zone). */
652
+ type GroupMemberRef = {
653
+ kind: "node";
654
+ id: string;
655
+ } | {
656
+ kind: "group";
657
+ id: string;
658
+ };
659
+ type GraphGroup = {
660
+ id: string;
661
+ label: string;
662
+ /**
663
+ * True when `label` came from a quoted string literal in source.
664
+ * False when the label was derived from the bare group id.
665
+ */
666
+ labelAuthored?: boolean;
667
+ kind: GroupKind;
668
+ parentId?: string;
669
+ nodeIds: string[];
670
+ childGroupIds: string[];
671
+ /**
672
+ * Source order of direct members (nodes + child groups).
673
+ * Used by region arrange so interleaved nodes stay on the track.
674
+ */
675
+ members?: GroupMemberRef[];
676
+ styleRefs: string[];
677
+ paddingHint?: string;
678
+ /**
679
+ * When false, skip border/fill/label (layout-only plane).
680
+ * Default true — dashed group chrome.
681
+ */
682
+ chrome?: boolean; /** Optional glyph beside the group label (same id vocabulary as nodes). */
683
+ icon?: string; /** Paint policy for group icons: brand (default for logos) or theme. */
684
+ iconPaint?: "theme" | "brand"; /** Tint the group glyph without changing the group rim. */
685
+ iconColor?: string;
686
+ /**
687
+ * How this group places its child groups/zones.
688
+ * `stack` / `row` / `grid` = region tracks; omit = ELK ownership.
689
+ */
690
+ arrange?: RegionArrange; /** Cross-axis alignment of child regions (default stretch). */
691
+ align?: RegionAlign; /** Gap between child regions (`compact` | `normal` | `spacious` or px). */
692
+ gap?: string | number; /** Grid column tracks (count or names). */
693
+ columns?: TrackSpec; /** Grid row tracks (count or names). */
694
+ rows?: TrackSpec; /** This region's column (1-based index or track name). */
695
+ column?: number | string; /** This region's row (1-based index or track name). */
696
+ row?: number | string; /** Span along the main axis (stack/row) or shorthand for colSpan. */
697
+ span?: number;
698
+ colSpan?: number;
699
+ rowSpan?: number; /** How nodes inside this region are laid out (default flow = ELK). */
700
+ cellArrange?: CellArrange;
701
+ };
702
+ type GraphModel = {
703
+ id: string;
704
+ title?: string; /** Flow (ELK) vs sequence (time-axis). Default `"flow"` when omitted. */
705
+ diagramKind?: DiagramKind; /** Present when `diagramKind === "sequence"`. */
706
+ sequence?: SequenceIR;
707
+ nodes: GraphNode[];
708
+ edges: GraphEdge[];
709
+ groups: GraphGroup[];
710
+ styles: StyleDefinition[]; /** Authored `animation` blocks compiled onto the graph (auto is inferred separately). */
711
+ animations?: AnimationDefinition[];
712
+ diagnostics: Diagnostic[];
713
+ };
714
+ type LayoutOptions = {
715
+ direction?: Direction;
716
+ density?: Density;
717
+ spacingScale?: number;
718
+ algorithmVersion?: "elk-layered-v1";
719
+ groupGap?: number;
720
+ /**
721
+ * Nested group handling for ELK.
722
+ * - `compound` / `auto` → INCLUDE_CHILDREN (default)
723
+ * - `flat` → SEPARATE_CHILDREN
724
+ * - `swimlane` → INCLUDE_CHILDREN (DSL group kind still distinct)
725
+ */
726
+ groupLayout?: "auto" | "flat" | "compound" | "swimlane";
727
+ /**
728
+ * How layered layout places nodes along each rank.
729
+ * - `straight` — prefer aligned/straight edges (ELK Brandes–Köpf)
730
+ * - `balanced` — more even packing (ELK network simplex; default)
731
+ * - `basic` — fastest / simplest placement (often cleaner for ERDs)
732
+ *
733
+ * The compiler also accepts common short aliases (`brandes`, `network`, `simple`)
734
+ * and ELK strategy spellings (`BRANDES_KOEPF`, …) and maps them to these values.
735
+ */
736
+ nodePlacement?: "straight" | "balanced" | "basic"; /** Prefer source order when ranking/ordering. */
737
+ considerModelOrder?: boolean; /** Edge–node clearance override (defaults from density). */
738
+ edgeNodeSpacing?: number; /** Parallel-edge clearance override. */
739
+ edgeEdgeSpacing?: number; /** Clearance between edge labels and other edges/nodes. */
740
+ edgeLabelSpacing?: number;
741
+ /**
742
+ * Arrange ungrouped nodes and top-level groups/zones into tracks (stack / row / grid).
743
+ * Per-group `arrange` wins when set on a parent.
744
+ */
745
+ arrange?: RegionArrange; /** Cross-axis alignment for diagram-level arrange (default stretch). */
746
+ align?: RegionAlign; /** Gap between top-level regions when `arrange` is set. */
747
+ gap?: string | number; /** Grid columns when diagram `arrange: grid`. */
748
+ columns?: TrackSpec; /** Grid rows when diagram `arrange: grid`. */
749
+ rows?: TrackSpec;
750
+ };
751
+ type RoutingOptions = {
752
+ /** Paint style for edge polylines (geometry always comes from ELK orthogonal). */route?: RouteMode;
753
+ crossings?: CrossingMode;
754
+ cornerRadius?: number; /** DSL-accepted; ignored by ELK (orthogonal routes are independent). */
755
+ parallel?: "separate" | "shared";
756
+ arrowheads?: boolean;
757
+ algorithmVersion?: string;
758
+ };
759
+ type RenderOptions = {
760
+ theme?: ThemeMode;
761
+ snapshotTheme?: boolean; /** Additive presentation chrome — default chromeless transparent SVG. */
762
+ presentation?: PresentationOptions;
763
+ debug?: DebugOptions; /** Opt-in drop shadows / glow. Default off. */
764
+ shadows?: boolean;
765
+ /**
766
+ * Opt-in corner radius on rectangular node shells (rounded/rectangle/pill,
767
+ * ERD tables, groups, edge labels). Default off — sharp corners.
768
+ */
769
+ roundedCorners?: boolean;
770
+ };
771
+ type DebugOptions = {
772
+ /** Draw circles at ELK edge attachment points (source + target). */showPorts?: boolean;
773
+ showBounds?: boolean;
774
+ showKindLabels?: boolean;
775
+ };
776
+ type CompileOptions = Record<string, never>;
777
+ type InteractiveRenderOptions = RenderOptions & {
778
+ layout?: LayoutOptions;
779
+ edges?: RoutingOptions;
780
+ };
781
+ type RenderStats = {
782
+ parseMs: number;
783
+ compileMs: number;
784
+ measureMs: number;
785
+ layoutMs: number;
786
+ routeMs: number;
787
+ renderMs: number;
788
+ totalMs: number;
789
+ nodeCount: number;
790
+ edgeCount: number;
791
+ layoutAlgorithm: string;
792
+ routerAlgorithm: string;
793
+ };
794
+ type CompileResult = {
795
+ graph: GraphModel;
796
+ layoutHints: LayoutOptions;
797
+ routingHints: RoutingOptions;
798
+ renderHints: RenderOptions;
799
+ diagnostics: Diagnostic[];
800
+ };
801
+ type ParseResult = {
802
+ ast: KDiagramAst;
803
+ diagnostics: Diagnostic[];
804
+ };
805
+ type RenderResult = {
806
+ ok: boolean;
807
+ svg?: string;
808
+ ast?: KDiagramAst;
809
+ graph?: GraphModel;
810
+ layout?: unknown;
811
+ routing?: unknown;
812
+ diagnostics: Diagnostic[];
813
+ stats: RenderStats;
814
+ };
815
+ type AnimationListItem = {
816
+ id: string;
817
+ name: string;
818
+ source: "auto" | "authored";
819
+ };
820
+ type AnimationPlayerState = {
821
+ id: string | null;
822
+ playing: boolean;
823
+ timeMs: number;
824
+ durationMs: number;
825
+ loop: boolean; /** Playback rate in [0.5, 2]. */
826
+ speed: number;
827
+ };
828
+ type AnimationController = {
829
+ list(): AnimationListItem[];
830
+ play(id?: string): void;
831
+ pause(): void;
832
+ stop(): void;
833
+ seek(ms: number): void;
834
+ step(delta: -1 | 1): void;
835
+ setLoop(on: boolean): void; /** Clamp playback rate to [0.5, 2]. */
836
+ setSpeed(rate: number): void;
837
+ subscribe(listener: (state: AnimationPlayerState) => void): () => void;
838
+ getState(): AnimationPlayerState;
839
+ };
840
+ type RenderController = {
841
+ update(source: string, options?: Partial<InteractiveRenderOptions>): Promise<RenderResult>;
842
+ setTheme(theme: ThemeMode): Promise<RenderResult>; /** Resolves after the initial paint (and first fit). */
843
+ ready(): Promise<RenderResult>;
844
+ fit(): void;
845
+ zoomIn(): void;
846
+ zoomOut(): void; /** Reset pan/zoom to the fitted natural view (not a model/view switch). */
847
+ resetView(): void; /** Diagram animation player (auto path or authored `animation` blocks). */
848
+ animations: AnimationController;
849
+ destroy(): void;
850
+ };
851
+ declare function mergeOptions<T extends Record<string, unknown>>(defaults: T, ...layers: (Partial<T> | undefined)[]): T;
852
+ //#endregion
853
+ //#region src/animation/infer-auto-animation.d.ts
854
+ type AutoWalkStep = {
855
+ kind: "chapter";
856
+ } | {
857
+ kind: "enter";
858
+ nodeId: string;
859
+ } | {
860
+ kind: "enter-many";
861
+ nodeIds: string[];
862
+ } | {
863
+ kind: "edge";
864
+ from: string;
865
+ to: string;
866
+ } | {
867
+ kind: "parallel-edges";
868
+ edges: Array<{
869
+ from: string;
870
+ to: string;
871
+ }>;
872
+ };
873
+ /**
874
+ * Infer Automatic animation.
875
+ *
876
+ * - **Exclusive** fan-out (choice nodes / yes·no branches) → one chapter per alternative.
877
+ * - **Parallel** fan-out (everything else) → `parallel` flow cues in a single story.
878
+ */
879
+ declare function inferAutoAnimation(graph: GraphModel): AnimationDefinition | null;
880
+ /**
881
+ * Chaptered walk: exclusive alternatives restart as chapters; concurrent
882
+ * fan-out becomes parallel edge steps within a chapter.
883
+ */
884
+ declare function planAutoWalk(graph: GraphModel): AutoWalkStep[];
885
+ /**
886
+ * Exclusive alternatives as node sequences (parallel siblings linearized in
887
+ * wavefront order). Prefer {@link planAutoWalk} for playback structure.
888
+ */
889
+ declare function enumerateAutoPaths(graph: GraphModel): string[][];
890
+ /** First-visit node order across Automatic chapters. */
891
+ declare function traceDeclarationPath(graph: GraphModel): string[];
892
+ //#endregion
893
+ //#region src/animation/bind-sequence-flow-edge-ids.d.ts
894
+ type FlowEdgeRefs = {
895
+ edgeId?: string;
896
+ edgeIds?: string[];
897
+ };
898
+ /**
899
+ * Resolve the concrete edge/message id for hop `i` of a flow cue.
900
+ * `edgeIds` is authoritative and index-aligned with hops; lone `edgeId` only
901
+ * covers hop 0 (single-hop convenience / auto-anim).
902
+ */
903
+ declare function flowHopEdgeId(hopIndex: number, refs: FlowEdgeRefs): string | undefined;
904
+ /** Attach concrete sequence message ids to authored `flow` cues (in place-safe copy). */
905
+ declare function bindSequenceFlowEdgeIds(graph: GraphModel, cues: AnimationCue[]): AnimationCue[];
906
+ //#endregion
907
+ //#region src/animation/index.d.ts
908
+ /** Slugify an authored animation name into a stable id. */
909
+ declare function animationIdFromName(name: string): string;
910
+ //#endregion
911
+ //#region src/parser/parser.d.ts
912
+ declare function parse(source: string): KDiagramAst;
913
+ //#endregion
914
+ //#region src/parser/lexer.d.ts
915
+ /** Soft keywords — statement intros; lexer emits them as identifiers. */
916
+ declare const STATEMENT_KEYWORDS: Set<string>;
917
+ //#endregion
918
+ //#region src/compiler/compile.d.ts
919
+ declare function compile(ast: KDiagramAst, diagramIndex?: number): CompileResult;
920
+ //#endregion
921
+ //#region src/compiler/kinds.d.ts
922
+ /**
923
+ * Capabilities communicate layout/render behavior beyond the visible shape.
924
+ * Example: ERD column cards need row anchors even when themed like a cylinder.
925
+ */
926
+ type NodeCapability = "erd-table" | "symbolic" | "icon-only" | "card" | "annotation" | "boundary" | "messaging" | "datastore" | "sequence-lifeline";
927
+ type NodeKindCategory = "general" | "flowchart" | "architecture" | "infrastructure" | "messaging" | "modeling" | "state" | "git" /** Bare geometry ids usable as kinds: `n: diamond "X"`. */ | "shape";
928
+ type NodeKindDefaults = {
929
+ shape: ShapeId; /** Default icon when the author omits `icon:` (suppressed with `icon: none`). */
930
+ icon?: string; /** Presentation subtitle (C4 / architecture eyebrow). */
931
+ subtitle: string;
932
+ classNames: string[];
933
+ cssVars: Record<string, string>;
934
+ defaultMinWidth: number;
935
+ defaultMaxWidth: number;
936
+ defaultDepth: number;
937
+ category: NodeKindCategory;
938
+ capabilities: NodeCapability[];
939
+ };
940
+ declare function getKindDefaults(kind: string): {
941
+ defaults: NodeKindDefaults;
942
+ isBuiltin: boolean;
943
+ };
944
+ declare function isBuiltinKind(kind: string): boolean;
945
+ /**
946
+ * True when `kind` names a built-in shape (or alias): `diamond`, `hex`, `cloud`, …
947
+ * Semantic kinds that share a shape id (`cloud`, `document`, `person`, `queue`) count —
948
+ * they are usable as both meaning and geometry. ERD `table` is excluded.
949
+ */
950
+ declare function isGeometryKind(kind: string): boolean;
951
+ declare function kindHasCapability(kind: string, capability: NodeCapability): boolean;
952
+ /** Human-readable kind subtitle for presentation chrome. */
953
+ declare function kindSubtitle(kind: string): string;
954
+ declare function listKindsByCategory(category: NodeKindCategory): string[];
955
+ /**
956
+ * Shape ids usable directly as kinds (excludes ERD `table`, which stays semantic-only).
957
+ * Includes semantic synonyms that share a shape id (`cloud`, `document`, `person`, `queue`).
958
+ */
959
+ declare function listGeometryKinds(): string[];
960
+ declare const BUILTIN_KIND_LIST: string[];
961
+ declare const BUILTIN_KIND_CATALOG: Readonly<Record<string, NodeKindDefaults>>;
962
+ //#endregion
963
+ //#region src/format/print.d.ts
964
+ declare function formatSource(source: string): string;
965
+ //#endregion
966
+ export { type AnimationBlockAst, type AnimationController, type AnimationCue, type AnimationCueAst, type AnimationDefinition, type AnimationListItem, type AnimationPlayerState, type AnimationTarget, type AnimationTargetAst, type AutoWalkStep, BUILTIN_KIND_CATALOG, BUILTIN_KIND_LIST, BUILTIN_SHAPE_IDS, type BoxPadding, type BranchKind, type BuiltinShapeId, type BuiltinThemeMode, type Cardinality, type CellArrange, type CompileOptions, type CompileResult, type CrossingMode, type DebugOptions, type Density, type Diagnostic, type DiagramAst, type DiagramKind, type Direction, type DirectiveAst, EDGE_OPS, type EdgeArrows, type EdgeAst, type EdgeCardinality, type EdgeKind, type EdgeOperator, type EdgePolicyBlockAst, type FlowEdgeRefs, type GraphEdge, type GraphGroup, type GraphModel, type GraphNode, type GroupAst, type GroupKind, type GroupMemberAst, type GroupMemberRef, type InteractiveRenderOptions, type KDiagramAst, type LabelCasePolicy, type LayoutBlockAst, type LayoutOptions, type NodeAst, type NodeCapability, type NodeKindCategory, type NodeKindDefaults, type PaddingSpec, type ParseResult, type Point, type PresentationBlockAst, type PresentationOptions, type PropertyMap, type PropertyValue, REMOVED_PRESENTATION_PROPS, type Rect, type RegionAlign, type RegionArrange, type RemovedPresentationProp, type RenderBlockAst, type RenderController, type RenderOptions, type RenderResult, type RenderStats, type ResolvedPadding, type ResolvedPresentation, type ResolvedTitle, type RouteMode, type RoutingOptions, SEQUENCE_FRAGMENT_ALIASES, STATEMENT_KEYWORDS, type SequenceActivateAst, type SequenceActivation, type SequenceAst, type SequenceAutonumberAst, type SequenceCreateAst, type SequenceDeactivateAst, type SequenceDestroyAst, type SequenceDivider, type SequenceDividerAst, type SequenceFragment, type SequenceFragmentAst, type SequenceFragmentOperand, type SequenceFragmentOperandAst, type SequenceFragmentOperator, type SequenceIR, type SequenceMessage, type SequenceMessageKind, type SequenceNote, type SequenceNoteAst, type SequenceNotePlacement, type SequenceStatementAst, type ShapeId, type SourceRange, type StatementAst, type StyleAst, type StyleDefinition, type StyleRefAst, type TableColumn, type TableColumnKey, type TableColumnRef, type ThemeMode, type TitleSpec, type TopLevelNode, type TrackSpec, type Vec2, animationIdFromName, bindSequenceFlowEdgeIds, cardinalityLabel, classifyBranch, compile, displayLabelCase, edgeOpsPattern, enumerateAutoPaths, expandRect, findColumnIndex, fkCardinality, flowHopEdgeId, formatLabelText, formatSource, formatTableColumnLine, getKindDefaults, inferAutoAnimation, isBuiltinKind, isGeometryKind, isKnownShapeId, isPureCardinalityLabel, kindHasCapability, kindSubtitle, listBuiltinShapeIds, listGeometryKinds, listKindsByCategory, manhattan, mergeOptions, mergePresentationOptions, normalizeBranch, type normalizePadding, normalizeSequenceFragmentOperator, normalizeShapeId, parse, parseCardinality, parseTableColumnSpec, parseTableColumns, planAutoWalk, presentationFromProperties, rectBottom, rectCenter, rectRight, rectsOverlap, resolvePresentation, sequenceFragmentDisplayName, traceDeclarationPath };
967
+ //# sourceMappingURL=index.d.mts.map