@miragon/event-storming-dsl 0.3.0 → 0.3.2

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
@@ -1,10 +1,10 @@
1
1
  # @miragon/event-storming-dsl
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/@miragon/event-storming-dsl)](https://www.npmjs.com/package/@miragon/event-storming-dsl)
4
- [![License: MIT](https://img.shields.io/github/license/Miragon/event-storming-modeler)](https://github.com/Miragon/event-storming-modeler/blob/main/LICENSE)
4
+ [![License: MIT](https://img.shields.io/github/license/Miragon/modeler-suite)](https://github.com/Miragon/modeler-suite/blob/main/modelers/event-storming/LICENSE)
5
5
 
6
6
  DOM-free bridge between the Event Storming `.storm` text DSL and the `EventStormingBoard`
7
- model — a lossless round-trip.
7
+ model, as a lossless round-trip.
8
8
 
9
9
  ## Install
10
10
 
@@ -15,7 +15,7 @@ npm install @miragon/event-storming-dsl
15
15
  ## Usage
16
16
 
17
17
  ```ts
18
- import { parseDSL, serializeDSL } from '@miragon/event-storming-dsl';
18
+ import { parseDSL, serializeDSL } from "@miragon/event-storming-dsl";
19
19
 
20
20
  const board = parseDSL(`title Order Checkout
21
21
  actor Customer [80, 300]
@@ -29,7 +29,7 @@ const text = serializeDSL(board); // back to .storm text, losslessly
29
29
  ## The `.storm` format
30
30
 
31
31
  One statement per line. Coordinates are `[x, y]` in board pixels (x first), optional
32
- (default `[0, 0]`), unbounded — the canvas is free.
32
+ (default `[0, 0]`) and unbounded: the canvas is free.
33
33
 
34
34
  ```
35
35
  title Order Checkout // config; also: style classic|dark
@@ -53,7 +53,7 @@ Unknown lines and comments are kept losslessly in `rawPassthrough`;
53
53
  `parseDSLWithDiagnostics` reports uninterpretable lines with 1-based line numbers instead of
54
54
  throwing.
55
55
 
56
- Part of the [Event Storming Modeler](https://github.com/Miragon/event-storming-modeler) monorepo.
56
+ Part of the [Event Storming Modeler](https://github.com/Miragon/modeler-suite/tree/main/modelers/event-storming) in the [Miragon modeler suite](https://github.com/Miragon/modeler-suite).
57
57
 
58
58
  ## License
59
59
 
package/dist/index.cjs CHANGED
@@ -3,12 +3,9 @@
3
3
  var eventStormingSchemaModel = require('@miragon/event-storming-schema-model');
4
4
 
5
5
  // src/parser.ts
6
-
7
- // src/lexer.ts
8
6
  var COORDS_RE = /\[\s*([-\d.]+)\s*,\s*([-\d.]+)\s*\]/;
9
- var LARGEST_DRAWABLE_NUMBER = 1e38;
10
7
  function isDrawable(value) {
11
- return Math.abs(value) <= LARGEST_DRAWABLE_NUMBER;
8
+ return Math.abs(value) <= eventStormingSchemaModel.LARGEST_DRAWABLE_NUMBER;
12
9
  }
13
10
  function drawablePair(a, b) {
14
11
  return isDrawable(a) && isDrawable(b);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lexer.ts","../src/ids.ts","../src/parser.ts","../src/serializer.ts"],"names":["ATTACHABLE_STICKY_KINDS","HOST_STICKY_KINDS","id","CURRENT_SCHEMA_VERSION","validateBoard","on","idp","al","sz","col"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Small, line-oriented helpers for the Event Storming `.storm` DSL.\n * The DSL is line-based; a full tokenizer/generator is not needed.\n */\n\nexport interface ParsedCoords {\n readonly a: number;\n readonly b: number;\n}\n\nconst COORDS_RE = /\\[\\s*([-\\d.]+)\\s*,\\s*([-\\d.]+)\\s*\\]/;\n\n/**\n * The canvas places shapes with 32-bit SVG transforms, which overflow near 3.4e38 and would make\n * an import throw half-way; 1e38 leaves room for a corner half a note's size beyond its centre.\n * A larger number (a digit run of 309 or more even overflows to Infinity) is unreadable like\n * `1.2.3`, so its line stays in rawPassthrough.\n */\nconst LARGEST_DRAWABLE_NUMBER = 1e38;\n\nfunction isDrawable(value: number): boolean {\n return Math.abs(value) <= LARGEST_DRAWABLE_NUMBER;\n}\n\nfunction drawablePair(a: number, b: number): boolean {\n return isDrawable(a) && isDrawable(b);\n}\n\n/** Order stays raw (a, b). */\nexport function parseCoords(line: string): ParsedCoords | null {\n const m = COORDS_RE.exec(line);\n if (!m) return null;\n const a = Number(m[1]);\n const b = Number(m[2]);\n if (!drawablePair(a, b)) return null;\n return { a, b };\n}\n\n/**\n * Splits a line at the first `[a, b]` tuple: name before, suffix after.\n * Extras like `(color …)` may then only be looked up in the suffix — parentheses\n * inside the name stay untouched.\n */\nexport function splitAtCoords(\n line: string,\n): { name: string; coords: ParsedCoords; suffix: string } | null {\n const m = COORDS_RE.exec(line);\n if (!m) return null;\n const a = Number(m[1]);\n const b = Number(m[2]);\n if (!drawablePair(a, b)) return null;\n return {\n name: line.slice(0, m.index).trim(),\n coords: { a, b },\n suffix: line.slice(m.index + m[0].length),\n };\n}\n\n// `[^[\\]]` (tuples cannot contain '[') + bounded whitespace keep the scan linear (ReDoS-safe).\nconst MULTI_COORDS_RE = /\\[\\s{0,8}(\\[[^[\\]]*\\](?:\\s{0,8},\\s{0,8}\\[[^[\\]]*\\])+)\\s{0,8}\\]/;\n\n/** Extracts a tuple list `[[a,b],[c,d],…]` (freeform `line` drawing) — or null. */\nexport function parseMultiCoords(line: string): { tuples: ParsedCoords[]; rest: string } | null {\n const m = MULTI_COORDS_RE.exec(line);\n if (!m) return null;\n const tuples: ParsedCoords[] = [];\n const inner = /\\[\\s{0,8}([-\\d.]+)\\s{0,8},\\s{0,8}([-\\d.]+)\\s{0,8}\\]/g;\n let t: RegExpExecArray | null;\n while ((t = inner.exec(m[1]!))) {\n const a = Number(t[1]);\n const b = Number(t[2]);\n if (!drawablePair(a, b)) return null;\n tuples.push({ a, b });\n }\n if (!tuples.length) return null;\n return { tuples, rest: line.replace(MULTI_COORDS_RE, ' ') };\n}\n\n/**\n * Splits off a `//` line comment. Quote-aware (`'//weird'` inside quotes stays untouched) and\n * URL-aware: `//` directly after `:` is a scheme separator (`https://…`), not a comment.\n */\nexport function splitLineComment(line: string): { code: string; comment: string | null } {\n let inQuote = false;\n for (let i = 0; i < line.length - 1; i++) {\n const ch = line[i];\n if (ch === \"'\") inQuote = !inQuote;\n else if (!inQuote && ch === '/' && line[i + 1] === '/' && line[i - 1] !== ':') {\n return { code: line.slice(0, i), comment: line.slice(i) };\n }\n }\n return { code: line, comment: null };\n}\n\n/** First occurrence of `needle` outside `'…'` quotes — or -1. */\nexport function indexOfOutsideQuotes(line: string, needle: string): number {\n let inQuote = false;\n for (let i = 0; i + needle.length <= line.length; i++) {\n const ch = line[i];\n if (ch === \"'\") {\n inQuote = !inQuote;\n continue;\n }\n if (!inQuote && line.startsWith(needle, i)) return i;\n }\n return -1;\n}\n\n// Color override extension: `(color #rrggbb)` OR `(color green)`. Deliberately placed after\n// the coordinates so parentheses inside sticky names are never mistaken for it.\n// Accepts hex or CSS color names.\nconst COLOR_RE = /\\(\\s*color\\s+(#[0-9a-fA-F]{3,8}|[a-zA-Z][\\w-]*)\\s*\\)/i;\n\nexport function parseColor(line: string): { color?: string; rest: string } {\n const m = COLOR_RE.exec(line);\n if (!m || !m[1]) return { rest: line };\n return { color: m[1], rest: line.replace(COLOR_RE, ' ') };\n}\n\n// Attachment extension: `(on <Host Name>)` — canonically the LAST suffix. The host name runs\n// up to the line's FINAL ')', so names may themselves contain parentheses (`Payment (retry)`).\n// Extracted BEFORE the other suffixes so a `(color …)` or `(size …)` inside a host name is\n// never mistaken for one.\nconst ON_RE = /\\(\\s*on\\s+/i;\n\nexport function parseOn(line: string): { host?: string; rest: string } {\n const m = ON_RE.exec(line);\n if (!m) return { rest: line };\n const start = m.index + m[0].length;\n const close = line.lastIndexOf(')');\n if (close < start) return { rest: line };\n const host = line.slice(start, close).trim();\n if (!host) return { rest: line };\n return { host, rest: `${line.slice(0, m.index)} ${line.slice(close + 1)}` };\n}\n\n// Internal-id extension: `(id <id>)` — emitted on sticky lines only when the name alone would\n// be ambiguous. The charset is deliberately tight (letters/digits/underscore/hyphen) so an id\n// can never collide with the line grammar (`)`/whitespace/`#` are all illegal).\nexport const ID_CHARSET_RE = /^[A-Za-z0-9_-]+$/;\n\nconst ID_RE = /\\(\\s*id\\s+([A-Za-z0-9_-]+)\\s*\\)/i;\n\n// Any `(id …)` group — catches malformed variants so the caller can report a diagnostic.\nconst ID_PRESENT_RE = /\\(\\s*id\\b[^)]*\\)/i;\n\nexport function parseId(line: string): {\n id?: string;\n /** The matched `(id …)` text when present but unreadable (illegal charset). */\n invalid?: string;\n rest: string;\n} {\n const m = ID_RE.exec(line);\n if (m?.[1]) return { id: m[1], rest: line.replace(ID_RE, ' ') };\n const p = ID_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(ID_PRESENT_RE, ' ') };\n}\n\n// Resize extension: `(size <w>x<h>)` — canonically the last suffix before `(on …)` on note\n// lines. The serializer emits no spaces around the `x`; the parser tolerates optional whitespace.\n// Deliberately looked up only after the coordinates so `(size 1x1)` inside note text survives.\nconst SIZE_RE = /\\(\\s*size\\s+([\\d.]+)\\s*x\\s*([\\d.]+)\\s*\\)/i;\n\n// Any `(size …)` group — catches malformed variants so the caller can report a diagnostic.\nconst SIZE_PRESENT_RE = /\\(\\s*size\\b[^)]*\\)/i;\n\nexport function parseSize(line: string): {\n size?: { width: number; height: number };\n /** The matched `(size …)` text when present but unreadable (malformed or non-positive). */\n invalid?: string;\n rest: string;\n} {\n const m = SIZE_RE.exec(line);\n if (m) {\n const width = Number(m[1]);\n const height = Number(m[2]);\n // Non-positive, NaN (`1.2.3`) or beyond the canvas falls through to the malformed branch.\n if (width > 0 && height > 0 && isDrawable(width) && isDrawable(height)) {\n return { size: { width, height }, rest: line.replace(SIZE_RE, ' ') };\n }\n }\n const p = SIZE_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(SIZE_PRESENT_RE, ' ') };\n}\n\n// Alignment extension: `(align <horizontal> <vertical>)` — canonically between `(size …)` and\n// `(on …)` on note lines, both words always present. Values are matched case-insensitively and\n// canonicalized to lowercase. Deliberately looked up only after the coordinates so an\n// `(align center middle)` inside note text survives.\nconst ALIGN_RE = /\\(\\s*align\\s+(left|center|right)\\s+(top|middle|bottom)\\s*\\)/i;\n\n// Any `(align …)` group — catches malformed variants so the caller can report a diagnostic.\nconst ALIGN_PRESENT_RE = /\\(\\s*align\\b[^)]*\\)/i;\n\nexport function parseAlign(line: string): {\n align?: {\n horizontal: 'left' | 'center' | 'right';\n vertical: 'top' | 'middle' | 'bottom';\n };\n /** The matched `(align …)` text when present but unreadable (unknown/missing axis words). */\n invalid?: string;\n rest: string;\n} {\n const m = ALIGN_RE.exec(line);\n if (m) {\n return {\n align: {\n horizontal: m[1]!.toLowerCase() as 'left' | 'center' | 'right',\n vertical: m[2]!.toLowerCase() as 'top' | 'middle' | 'bottom',\n },\n rest: line.replace(ALIGN_RE, ' '),\n };\n }\n const p = ALIGN_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(ALIGN_PRESENT_RE, ' ') };\n}\n\n/** Undoes the serializer's `\\n` name escaping (line-based DSL, multi-line labels). */\nexport function decodeName(name: string): string {\n return name.replace(/\\\\n/g, '\\n');\n}\n\n/** First word (keyword) of a line, lowercased. */\nexport function keywordOf(line: string): string {\n const m = /^\\s*([A-Za-z][\\w-]*)/.exec(line);\n return m ? m[1]!.toLowerCase() : '';\n}\n\nexport function slug(label: string): string {\n return (\n label\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_/, '')\n .replace(/_$/, '') || 'x'\n );\n}\n","import type { ElementType } from '@miragon/event-storming-schema-model';\nimport { slug } from './lexer.js';\n\n/** Sticky keywords double as `elementType` values; the value is the ID prefix. */\nexport const STICKY_ID_PREFIXES: Readonly<Partial<Record<ElementType, string>>> = {\n event: 'event',\n command: 'cmd',\n actor: 'actor',\n aggregate: 'agg',\n policy: 'policy',\n readmodel: 'read',\n external: 'ext',\n hotspot: 'hot',\n};\n\n// Board ids become diagram-js element ids, and the renderer's root elements live in the same\n// registry: an element claiming one of these would make the import throw halfway through.\nconst ENGINE_ID_RE = /^(?:event-storming-root$|__implicitroot)/;\n\nexport function isEngineId(id: string): boolean {\n return ENGINE_ID_RE.test(id);\n}\n\n/**\n * The parser's id allocation, shared with the serializer: the serializer replays it in emit order\n * to decide which ids the text has to carry so that every sticky gets its id back on re-import.\n */\nexport class IdAllocator {\n private readonly used = new Set<string>();\n\n /** Explicit `(id …)` — false when the id is taken or reserved (caller reports + allocates). */\n claim(id: string): boolean {\n if (this.used.has(id) || isEngineId(id)) return false;\n this.used.add(id);\n return true;\n }\n\n /** The id `alloc(prefix, label)` would return, without taking it. */\n peek(prefix: string, label: string): string {\n const base = `${prefix}_${slug(label)}`;\n let id = base;\n let i = 2;\n while (this.used.has(id)) id = `${base}_${i++}`;\n return id;\n }\n\n alloc(prefix: string, label: string): string {\n const id = this.peek(prefix, label);\n this.used.add(id);\n return id;\n }\n}\n","import {\n ATTACHABLE_STICKY_KINDS,\n CURRENT_SCHEMA_VERSION,\n HOST_STICKY_KINDS,\n validateBoard,\n type BoardConfig,\n type BoardEdge,\n type BoardLevel,\n type BoardElement,\n type Coordinate,\n type DrawingElement,\n type DrawingStrokeStyle,\n type ElementType,\n type EventStormingBoard,\n type NoteAlign,\n type NoteAlignHorizontal,\n type NoteAlignVertical,\n type NoteElement,\n} from '@miragon/event-storming-schema-model';\nimport {\n indexOfOutsideQuotes,\n keywordOf,\n parseAlign,\n parseColor,\n parseCoords,\n parseId,\n parseMultiCoords,\n parseOn,\n parseSize,\n splitAtCoords,\n splitLineComment,\n decodeName,\n} from './lexer.js';\nimport { IdAllocator, STICKY_ID_PREFIXES, isEngineId } from './ids.js';\n\n/** Splits `A -> B` at the FIRST arrow — plain indexOf, immune to regex backtracking. */\nfunction splitArrow(core: string): { left: string; right: string } | null {\n const arrow = core.indexOf('->');\n if (arrow <= 0) return null;\n const left = core.slice(0, arrow).trim();\n const right = core.slice(arrow + 2).trim();\n return left && right ? { left, right } : null;\n}\n\nconst KNOWN_STYLES: ReadonlySet<string> = new Set(['classic', 'dark']);\n\nconst ATTACHABLE_KINDS: ReadonlySet<string> = new Set(ATTACHABLE_STICKY_KINDS);\n\nconst HOST_KINDS: ReadonlySet<string> = new Set(HOST_STICKY_KINDS);\n\nconst KNOWN_LEVELS: ReadonlySet<string> = new Set(['big-picture', 'process', 'design']);\n\n// The 8 sticky kinds — the only legal arrow endpoints (mirrors validateBoard's contract).\nconst STICKY_KINDS: ReadonlySet<string> = new Set(Object.keys(STICKY_ID_PREFIXES));\n\ninterface PendingArrow {\n readonly left: string;\n readonly right: string;\n /** Annotation text after `;`. */\n readonly label?: string;\n readonly raw: string;\n readonly lineNo: number;\n}\n\n/** `(on …)` attachment — host referenced BY NAME, resolution deferred like arrow endpoints. */\ninterface PendingAttachment {\n /** Index into `elements` of the attachable sticky. */\n readonly index: number;\n readonly host: string;\n readonly raw: string;\n readonly lineNo: number;\n}\n\nfunction compact<T extends Record<string, unknown>>(obj: T): T {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) if (v !== undefined) out[k] = v;\n return out as T;\n}\n\n/**\n * Text `(align <h> <v>)` pair -> model value: default axes (left/top) are dropped, both-default\n * collapses to absent — `(align left top)` and no suffix are the same board (the serializer\n * emits the suffix only when an axis differs from the default).\n */\nfunction modelAlign(\n align: { horizontal: NoteAlignHorizontal; vertical: NoteAlignVertical } | undefined,\n): NoteAlign | undefined {\n if (!align) return undefined;\n const out = compact({\n horizontal: align.horizontal === 'left' ? undefined : align.horizontal,\n vertical: align.vertical === 'top' ? undefined : align.vertical,\n }) as NoteAlign;\n return Object.keys(out).length ? out : undefined;\n}\n\n/** Finding produced while parsing — line is 1-based; `text` is the (comment-stripped) line. */\nexport interface ParseDiagnostic {\n readonly line: number;\n readonly message: string;\n readonly text: string;\n}\n\nexport interface ParseResult {\n readonly board: EventStormingBoard;\n readonly diagnostics: readonly ParseDiagnostic[];\n}\n\n/**\n * Line-based keyword parsing; coordinates are `[x, y]` in board pixels (x FIRST), unbounded,\n * optional (default `[0, 0]`). Unknown lines land in `rawPassthrough`.\n */\nexport function parseDSL(text: string): EventStormingBoard {\n return parseDSLWithDiagnostics(text).board;\n}\n\n/**\n * Like `parseDSL`, but additionally returns findings with line numbers (uninterpretable lines,\n * unresolved references) — for editor feedback instead of silent loss.\n */\nexport function parseDSLWithDiagnostics(text: string): ParseResult {\n const diagnostics: ParseDiagnostic[] = [];\n const ids = new IdAllocator();\n const nameToId = new Map<string, string>();\n const elements: BoardElement[] = [];\n const rawPassthrough: string[] = [];\n const pendingArrows: PendingArrow[] = [];\n const pendingAttachments: PendingAttachment[] = [];\n\n let config: BoardConfig = { title: 'Untitled Board' };\n let inBlockComment = false;\n\n const register = (name: string, id: string) => {\n if (!nameToId.has(name)) nameToId.set(name, id);\n };\n\n // Diagnostics helpers: read the current line/number from the loop state.\n let lineNo = 0;\n let currentLine = '';\n\n /** Tries to capture a line as an arrow. Returns true when consumed. */\n const pushArrow = (line: string): boolean => {\n // Split off an optional arrow annotation after ';' (e.g. `A -> B; async`).\n const semi = line.indexOf(';');\n const core = semi >= 0 ? line.slice(0, semi).trim() : line;\n const arrowLabel = semi >= 0 ? line.slice(semi + 1).trim() : '';\n const arrow = splitArrow(core);\n if (!arrow) return false;\n pendingArrows.push({\n left: arrow.left,\n right: arrow.right,\n ...(arrowLabel ? { label: arrowLabel } : {}),\n raw: line,\n lineNo,\n });\n return true;\n };\n const diag = (message: string, atLine = lineNo, text_ = currentLine) =>\n diagnostics.push({ line: atLine, message, text: text_ });\n /** Passthrough for a line that looks like a known construct but cannot be parsed. */\n const failed = (l: string) => {\n rawPassthrough.push(l);\n diag(\"Couldn't read this line. It stays in the file unchanged.\");\n };\n /** Board pixels, unbounded — no clamping on the free canvas. */\n const pos = (x: number, y: number): Coordinate => ({ x, y });\n\n const sourceLines = text.split(/\\r?\\n/);\n for (let i = 0; i < sourceLines.length; i++) {\n const raw = sourceLines[i]!;\n // The empty piece after a final newline is no line: inside an open block comment it would be\n // kept as one, and every save would append another blank line.\n if (raw === '' && i === sourceLines.length - 1) continue;\n lineNo = i + 1;\n currentLine = raw.trim();\n let working = raw;\n\n // --- Comments (`//`, `/* */`): strip, but keep losslessly in rawPassthrough. ---\n if (inBlockComment) {\n const close = working.indexOf('*/');\n if (close < 0) {\n rawPassthrough.push(raw);\n continue;\n }\n rawPassthrough.push(working.slice(0, close + 2));\n working = working.slice(close + 2);\n inBlockComment = false;\n }\n let open = indexOfOutsideQuotes(working, '/*');\n while (open >= 0) {\n const close = working.indexOf('*/', open + 2);\n if (close < 0) {\n rawPassthrough.push(working.slice(open));\n working = working.slice(0, open);\n inBlockComment = true;\n break;\n }\n rawPassthrough.push(working.slice(open, close + 2));\n working = `${working.slice(0, open)} ${working.slice(close + 2)}`;\n open = indexOfOutsideQuotes(working, '/*');\n }\n const { code, comment } = splitLineComment(working);\n if (comment !== null) rawPassthrough.push(comment);\n working = code;\n\n const line = working.trim();\n if (!line) continue;\n\n const kw = keywordOf(line);\n const after = line.slice(kw.length).trim();\n\n // Arrows FIRST: sticky NAMES may begin with a keyword word (the default command is\n // named \"Command\" -> arrow `Command -> X`). Declarations carry coordinates `[...]`,\n // arrows never do — but only the part BEFORE the `;` annotation counts, the annotation\n // is free text and may contain a tuple. Without this pre-detection `Command -> X` would\n // be misread as a (broken) `command` declaration and vanish on re-import. `title` is\n // exempt (its content may itself use `->`) UNLESS the left side is an already-declared\n // sticky name (e.g. one named \"Title Page\" — declarations always precede arrows in\n // serialized DSL). `style`/`level`/`line` need no exemption: style and level values are\n // single words and drawings always carry coordinate tuples.\n const semi = line.indexOf(';');\n const beforeAnnotation = semi >= 0 ? line.slice(0, semi) : line;\n const titleAsArrow = (): boolean => {\n const arrow = splitArrow(beforeAnnotation.trim());\n return arrow !== null && nameToId.has(decodeName(arrow.left));\n };\n if ((kw !== 'title' || titleAsArrow()) && !parseCoords(beforeAnnotation) && pushArrow(line)) {\n continue;\n }\n\n switch (kw) {\n case 'title':\n config = { ...config, title: after };\n break;\n\n case 'style': {\n const s = after.toLowerCase();\n if (KNOWN_STYLES.has(s)) config = { ...config, style: s as 'classic' | 'dark' };\n else failed(line);\n break;\n }\n\n case 'level': {\n const l = after.toLowerCase();\n if (KNOWN_LEVELS.has(l)) config = { ...config, level: l as BoardLevel };\n else failed(line);\n break;\n }\n\n case 'event':\n case 'command':\n case 'actor':\n case 'aggregate':\n case 'policy':\n case 'readmodel':\n case 'external':\n case 'hotspot': {\n const node = parseSticky(after);\n if (!node) {\n failed(line);\n break;\n }\n if (node.idInvalid) {\n diag(\n `Couldn't read the id “${node.idInvalid.trim()}”. An id has letters, digits, “_” or “-”, as in (id order_1).`,\n );\n }\n const explicit = node.id !== undefined && ids.claim(node.id) ? node.id : undefined;\n if (node.id !== undefined && explicit === undefined) {\n diag(\n isEngineId(node.id)\n ? `The id “${node.id}” belongs to the board itself, so this sticky got a new id.`\n : `The id “${node.id}” is already taken, so this sticky got a new id.`,\n );\n }\n const id = explicit ?? ids.alloc(STICKY_ID_PREFIXES[kw as ElementType]!, node.name);\n elements.push(\n compact({\n id,\n elementType: kw as ElementType,\n label: node.name,\n position: pos(node.coords.x, node.coords.y),\n color: node.color,\n }) as BoardElement,\n );\n register(node.name, id);\n if (node.host !== undefined) {\n if (ATTACHABLE_KINDS.has(kw)) {\n pendingAttachments.push({\n index: elements.length - 1,\n host: node.host,\n raw: line,\n lineNo,\n });\n } else {\n diag(`A ${kw} can't be pinned. Only an actor, a hotspot or a note takes (on …).`);\n }\n }\n if (node.sizeSuffix) {\n diag(`A ${kw} can't be resized. Only a note takes (size …).`);\n }\n if (node.alignSuffix) {\n diag(`A ${kw} can't be aligned. Only a note takes (align …).`);\n }\n break;\n }\n\n case 'note': {\n const split = splitAtCoords(after);\n if (!split && after.includes('[')) {\n failed(line);\n break;\n }\n // Suffixes ONLY after the coordinates (mirrors parseSticky) — notes are free text, so\n // `(on …)`, `(color …)` or `(size 1x1)` may legitimately appear inside it. `(on …)` is\n // stripped FIRST: it is always the last suffix and its host name runs to the final `)`,\n // so it may itself contain a `(color …)`, `(size …)` or `(align …)`.\n const on = parseOn(split ? split.suffix : after);\n const al = parseAlign(on.rest);\n const sz = parseSize(al.rest);\n const idp = parseId(sz.rest);\n const col = parseColor(idp.rest);\n if (al.invalid) {\n diag(\n `Couldn't read the alignment “${al.invalid.trim()}”. Write (align left|center|right top|middle|bottom).`,\n );\n }\n if (sz.invalid) {\n diag(\n `Couldn't read the size “${sz.invalid.trim()}”. Write (size <w>x<h>) with positive numbers.`,\n );\n }\n if (idp.id !== undefined || idp.invalid) {\n diag(\"A note can't have an id. Only a sticky takes (id …).\");\n }\n // Literal `\\n` back into real line breaks (multi-line notes).\n const textPart = decodeName((split ? split.name : col.rest).trim());\n const id = ids.alloc('note', textPart || 'note');\n const note: NoteElement = compact({\n id,\n elementType: 'note',\n label: textPart,\n position: split ? pos(split.coords.a, split.coords.b) : pos(0, 0),\n color: col.color,\n size: sz.size,\n align: modelAlign(al.align),\n }) as NoteElement;\n elements.push(note);\n if (on.host !== undefined) {\n pendingAttachments.push({ index: elements.length - 1, host: on.host, raw: line, lineNo });\n }\n break;\n }\n\n case 'line': {\n // Project extension (freeform drawing): `line [[x,y], [x,y], …] (closed) (dashed) (color x)`.\n const col = parseColor(after);\n const multi = parseMultiCoords(col.rest);\n if (!multi || multi.tuples.length < 2) {\n failed(line);\n break;\n }\n const onDrawing = parseOn(multi.rest);\n if (onDrawing.host !== undefined) {\n diag(\"A drawing can't be pinned. Only an actor, a hotspot or a note takes (on …).\");\n }\n const szDrawing = parseSize(onDrawing.rest);\n if (szDrawing.size || szDrawing.invalid) {\n diag(\"A drawing can't be resized. Only a note takes (size …).\");\n }\n const alDrawing = parseAlign(onDrawing.rest);\n if (alDrawing.align || alDrawing.invalid) {\n diag(\"A drawing can't be aligned. Only a note takes (align …).\");\n }\n const idDrawing = parseId(onDrawing.rest);\n if (idDrawing.id !== undefined || idDrawing.invalid) {\n diag(\"A drawing can't have an id. Only a sticky takes (id …).\");\n }\n const flags = onDrawing.rest.toLowerCase();\n const strokeStyle: DrawingStrokeStyle | undefined = flags.includes('(dashed)')\n ? 'dashed'\n : flags.includes('(dotted)')\n ? 'dotted'\n : undefined;\n const points = multi.tuples.map((t) => pos(t.a, t.b));\n const drawing: DrawingElement = {\n id: ids.alloc('draw', 'line'),\n elementType: 'drawing',\n label: '',\n position: points[0]!,\n points,\n ...(flags.includes('(closed)') ? { closed: true } : {}),\n ...(strokeStyle ? { strokeStyle } : {}),\n ...(col.color ? { color: col.color } : {}),\n };\n elements.push(drawing);\n break;\n }\n\n default: {\n // Unknown keyword: try as an arrow (e.g. `A -> B; async`), otherwise keep raw.\n if (!pushArrow(line)) rawPassthrough.push(line);\n }\n }\n }\n\n // Reference resolution for arrow endpoints and `(on …)` hosts: a `#`-prefixed token is an id\n // reference (ids exist for EVERY element, not only those declared with `(id …)`); anything\n // else stays a label lookup. No fallback across the two — `#` always means id.\n const resolve = (token: string): BoardElement | undefined => {\n if (token.startsWith('#')) {\n const id = token.slice(1);\n return elements.find((e) => e.id === id);\n }\n const id = nameToId.get(decodeName(token));\n return id !== undefined ? elements.find((e) => e.id === id) : undefined;\n };\n\n // Deferred like arrows so a host may be declared after its attacher. On failure the sticky\n // stays WITHOUT attachedTo (it was already created above) — no rawPassthrough, the line is\n // otherwise fully represented.\n for (const att of pendingAttachments) {\n const host = resolve(att.host);\n if (!host) {\n diag(`There's no “${att.host}” on the board to pin this to.`, att.lineNo, att.raw);\n continue;\n }\n if (!HOST_KINDS.has(host.elementType)) {\n diag(\n `“${att.host}” is a ${host.elementType}. An actor, a hotspot or a note is pinned to an event, a command, an aggregate, a policy, a read model or an external system.`,\n att.lineNo,\n att.raw,\n );\n continue;\n }\n elements[att.index] = { ...elements[att.index]!, attachedTo: host.id } as BoardElement;\n }\n\n let arrowN = 0;\n // An explicit `(id arrow_N)` on a sticky may occupy an arrow-id slot — skip it (diagram-js\n // has ONE id namespace for shapes and connections; validateBoard rejects the collision).\n const elementIds = new Set(elements.map((e) => e.id));\n const nextArrowId = (): string => {\n let id = `arrow_${++arrowN}`;\n while (elementIds.has(id)) id = `arrow_${++arrowN}`;\n return id;\n };\n const edges: BoardEdge[] = [];\n for (const arrow of pendingArrows) {\n const from = resolve(arrow.left);\n const to = resolve(arrow.right);\n if (!from || !to) {\n rawPassthrough.push(arrow.raw);\n diag(\n !from\n ? `This arrow starts at “${arrow.left}”, which isn't on the board.`\n : `This arrow points to “${arrow.right}”, which isn't on the board.`,\n arrow.lineNo,\n arrow.raw,\n );\n continue;\n }\n // Only reachable via `#id` refs (labels are registered for sticky kinds only) — an edge to\n // a note/drawing would make validateBoard throw, so it is dropped losslessly instead.\n const nonSticky = !STICKY_KINDS.has(from.elementType)\n ? ([arrow.left, from] as const)\n : !STICKY_KINDS.has(to.elementType)\n ? ([arrow.right, to] as const)\n : undefined;\n if (nonSticky) {\n rawPassthrough.push(arrow.raw);\n diag(\n `“${nonSticky[0]}” is a ${nonSticky[1].elementType}, and an arrow only connects stickies.`,\n arrow.lineNo,\n arrow.raw,\n );\n continue;\n }\n edges.push(\n compact({\n id: nextArrowId(),\n edgeType: 'arrow',\n from: from.id,\n to: to.id,\n label: arrow.label,\n }) as BoardEdge,\n );\n }\n\n const board = compact({\n schemaVersion: CURRENT_SCHEMA_VERSION,\n config,\n elements,\n edges,\n rawPassthrough: rawPassthrough.length ? rawPassthrough : undefined,\n }) as EventStormingBoard;\n\n return { board: validateBoard(board), diagnostics };\n}\n\ninterface ParsedSticky {\n readonly name: string;\n readonly coords: { x: number; y: number };\n /** Color override `(color …)` — supported on every element line. */\n readonly color?: string;\n /** Attachment `(on <Host Name>)` — host name still undecoded, resolved by the caller. */\n readonly host?: string;\n /** Explicit `(id …)` — the caller claims it (duplicate ⇒ diagnostic + fresh id). */\n readonly id?: string;\n /** The matched `(id …)` text when present but unreadable (illegal charset). */\n readonly idInvalid?: string;\n /** A `(size …)` suffix appeared — only notes support it, the caller reports a diagnostic. */\n readonly sizeSuffix?: boolean;\n /** An `(align …)` suffix appeared — only notes support it, the caller reports a diagnostic. */\n readonly alignSuffix?: boolean;\n}\n\n/**\n * Parses `<name> [x, y] [(color …)] [(id …)] [(on …)]`. The suffixes are looked up ONLY AFTER\n * the coordinates — parentheses inside the name stay untouched. `(on …)` is extracted first\n * (its host name runs to the final `)` and may itself contain a `(color …)`, `(id …)` or\n * `(size …)`). Coordinates are optional and default to `[0, 0]`; a malformed tuple (bracket\n * present but unreadable) is rejected so the caller can report a diagnostic instead of\n * swallowing it into the name.\n */\nfunction parseSticky(after: string): ParsedSticky | null {\n const split = splitAtCoords(after);\n if (split) {\n if (!split.name) return null;\n const on = parseOn(split.suffix);\n const idp = parseId(on.rest);\n const al = parseAlign(idp.rest);\n const sz = parseSize(al.rest);\n const col = parseColor(sz.rest);\n return compact({\n name: decodeName(split.name),\n coords: { x: split.coords.a, y: split.coords.b },\n color: col.color ?? undefined,\n host: on.host,\n id: idp.id,\n idInvalid: idp.invalid,\n sizeSuffix: sz.size || sz.invalid ? true : undefined,\n alignSuffix: al.align || al.invalid ? true : undefined,\n }) as ParsedSticky;\n }\n if (after.includes('[')) return null;\n const on = parseOn(after);\n const idp = parseId(on.rest);\n const al = parseAlign(idp.rest);\n const sz = parseSize(al.rest);\n const col = parseColor(sz.rest);\n const name = col.rest.trim();\n if (!name) return null;\n return compact({\n name: decodeName(name),\n coords: { x: 0, y: 0 },\n color: col.color ?? undefined,\n host: on.host,\n id: idp.id,\n idInvalid: idp.invalid,\n sizeSuffix: sz.size || sz.invalid ? true : undefined,\n alignSuffix: al.align || al.invalid ? true : undefined,\n }) as ParsedSticky;\n}\n","import type {\n BoardElement,\n EventStormingBoard,\n NoteElement,\n} from '@miragon/event-storming-schema-model';\nimport { IdAllocator, STICKY_ID_PREFIXES } from './ids.js';\nimport { ID_CHARSET_RE, decodeName, slug } from './lexer.js';\n\n/**\n * Coordinate formatter: 3-decimal rounding, NEVER exponent notation — `String(1e21)` yields\n * `\"1e+21\"`, which the coordinate regex cannot read back. Magnitudes >= 1e21 are always\n * integer-valued doubles, so BigInt expands them losslessly (the rounding step is skipped\n * there; it would be a no-op and could overflow to Infinity for huge values).\n */\nfunction r(n: number): string {\n const v = Math.abs(n) < 1e21 ? Math.round(n * 1000) / 1000 : n;\n return Math.abs(v) < 1e21 ? String(v) : BigInt(v).toString();\n}\n\n/**\n * Free text emitted into the line-based grammar: real line breaks become the literal `\\n`\n * escape (decoded on parse) and comment starters are defused with the Unicode division slash\n * — otherwise the parser would split the line or strip the rest as a comment. `//` directly\n * after `:` stays untouched (URL scheme separator, the comment splitter is URL-aware).\n */\nfunction escapeText(label: string): string {\n return label\n .trim()\n .replace(/\\n/g, '\\\\n')\n .replace(/(?<!:)\\/\\//g, '∕∕')\n .replace(/\\/\\*/g, '∕*');\n}\n\n/** Names are additionally arrow-safe: a literal `->` inside a name would break `A -> B` lines. */\nfunction escapeName(label: string): string {\n return escapeText(label).replace(/->/g, '→');\n}\n\n/** Types referenced BY THEIR NAME in the DSL (arrow endpoints + namespace) — all sticky kinds. */\nconst NAMED_TYPES: ReadonlySet<string> = new Set([\n 'event',\n 'command',\n 'actor',\n 'aggregate',\n 'policy',\n 'readmodel',\n 'external',\n 'hotspot',\n]);\n\nconst DEFAULT_NAMES: Readonly<Record<string, string>> = {\n event: 'Domain Event',\n command: 'Command',\n actor: 'Actor',\n aggregate: 'Aggregate',\n policy: 'Policy',\n readmodel: 'Read Model',\n external: 'External System',\n hotspot: 'Hotspot',\n};\n\nfunction defaultName(type: string): string {\n return DEFAULT_NAMES[type] ?? 'Sticky';\n}\n\n/**\n * Returns the DSL name per element ID for the referenceable types (the sticky kinds): the\n * escaped label, or the per-kind default for an empty one. Duplicate labels are legal — an\n * ambiguous name is disambiguated via an `(id …)` suffix plus `#id` references instead of\n * being silently renamed.\n */\nfunction serializedNames(board: EventStormingBoard): Map<string, string> {\n const byId = new Map<string, string>();\n for (const el of board.elements) {\n if (!NAMED_TYPES.has(el.elementType)) continue;\n byId.set(el.id, escapeName(el.label) || defaultName(el.elementType));\n }\n return byId;\n}\n\n/** Color override extension: `(color …)` after the coordinates. */\nfunction colorSuffix(el: { color?: string }): string {\n return el.color ? ` (color ${el.color})` : '';\n}\n\n/**\n * Alignment extension: `(align <horizontal> <vertical>)` — both words always emitted together\n * using the EFFECTIVE values, and only when at least one axis differs from the default\n * left/top, so existing boards serialize byte-identically.\n */\nfunction alignSuffix(el: NoteElement): string {\n const horizontal = el.align?.horizontal ?? 'left';\n const vertical = el.align?.vertical ?? 'top';\n return horizontal === 'left' && vertical === 'top' ? '' : ` (align ${horizontal} ${vertical})`;\n}\n\n/**\n * Serializes an EventStormingBoard into `.storm` text. Deterministic; writes only syntax the\n * parser reads back. `rawPassthrough` is appended unchanged. Coordinates are `[x, y]` in board\n * pixels (x FIRST), rounded to 3 decimals.\n */\nexport function serializeDSL(board: EventStormingBoard): string {\n const lines: string[] = [];\n const names = serializedNames(board);\n const nameOf = (el: BoardElement): string => names.get(el.id) ?? el.label;\n\n // A `#…` token in a reference position always reads as an id — so a sticky whose serialized\n // name is AMBIGUOUS (shared by >= 2 stickies) or literally starts with `#` is referenced as\n // `#id`. Everything else stays purely name-based, so unambiguous boards serialize without any\n // ids, byte-identical to before.\n const nameCount = new Map<string, number>();\n for (const name of names.values()) nameCount.set(name, (nameCount.get(name) ?? 0) + 1);\n const referencedById = (id: string): boolean => {\n const name = names.get(id);\n return name !== undefined && (nameCount.get(name)! > 1 || name.startsWith('#'));\n };\n\n // Ids surface in the text only via the `(id …)` suffix. An id outside the DSL id charset\n // (possible in JSON-authored boards) would emit unparsable syntax and lose the arrows on\n // re-import — a slug-based, collision-checked stand-in is substituted for the suffix AND every\n // reference.\n const emitIds = new Map<string, string>();\n const taken = new Set(board.elements.map((e) => e.id));\n for (const el of board.elements) {\n if (!referencedById(el.id) || ID_CHARSET_RE.test(el.id)) continue;\n let candidate = slug(el.id);\n for (let i = 2; taken.has(candidate); i++) candidate = `${slug(el.id)}_${i}`;\n taken.add(candidate);\n emitIds.set(el.id, candidate);\n }\n const idOf = (id: string): string => emitIds.get(id) ?? id;\n const declaredIds = idsToDeclare(board, nameOf, referencedById, idOf);\n const ref = (id: string): string => (referencedById(id) ? `#${idOf(id)}` : (names.get(id) ?? id));\n\n lines.push(`title ${board.config.title}`);\n if (board.config.style) lines.push(`style ${board.config.style}`);\n if (board.config.level) lines.push(`level ${board.config.level}`);\n\n // Pinning `(on …)` is ALWAYS the last suffix — the parser reads the host name up to the\n // line's final `)`, so host names containing parentheses survive. validateBoard guarantees\n // the host is a named sticky kind; `ref` falls back to the raw id purely defensively.\n const onSuffix = (el: BoardElement): string => {\n const hostId =\n el.elementType === 'actor' || el.elementType === 'hotspot' || el.elementType === 'note'\n ? el.attachedTo\n : undefined;\n return hostId ? ` (on ${ref(hostId)})` : '';\n };\n\n for (const el of board.elements) {\n const idSuffix = declaredIds.has(el.id) ? ` (id ${idOf(el.id)})` : '';\n lines.push(elementLine(el, nameOf(el), idSuffix, onSuffix(el)));\n }\n\n // validateBoard guarantees arrow endpoints are sticky kinds, so the name map always covers\n // them — `ref`'s raw-id fallback is purely defensive for unvalidated input.\n for (const edge of board.edges) {\n const annotation = edge.label ? `; ${edge.label}` : '';\n lines.push(`${ref(edge.from)} -> ${ref(edge.to)}${annotation}`);\n }\n\n // Config keywords were already emitted from the board above. A rawPassthrough entry with the\n // same keyword (e.g. an unparsable `style` line from externally-authored DSL) would otherwise\n // produce a contradictory duplicate line — drop it (config is the truth).\n if (board.rawPassthrough) {\n const emitted = new Set<string>(['title']);\n if (board.config.style) emitted.add('style');\n if (board.config.level) emitted.add('level');\n for (const raw of board.rawPassthrough) {\n if (emitted.has(raw.trim().split(/\\s+/)[0]!)) continue;\n lines.push(raw);\n }\n }\n\n return lines.join('\\n') + '\\n';\n}\n\n/**\n * The stickies whose line carries `(id …)`: those referenced as `#id`, plus every sticky whose id\n * the parser would not allocate again at its line — one created on the canvas (`event_3`),\n * renamed after its id was derived from the old label, or declared with an explicit id. Hosts\n * anchor todos, presence and deep links to these ids, so they must survive a save and re-open.\n * Replays the parser's allocation in emit order; an id equal to the allocated one stays implicit,\n * which keeps boards authored without ids byte-identical.\n */\nfunction idsToDeclare(\n board: EventStormingBoard,\n nameOf: (el: BoardElement) => string,\n referencedById: (id: string) => boolean,\n emittedId: (id: string) => string,\n): Set<string> {\n const allocator = new IdAllocator();\n const declared = new Set<string>();\n for (const el of board.elements) {\n const prefix = STICKY_ID_PREFIXES[el.elementType];\n if (prefix === undefined) {\n allocator.alloc(el.elementType === 'note' ? 'note' : 'draw', noteOrDrawingName(el));\n continue;\n }\n const parsedName = decodeName(nameOf(el));\n const declare =\n referencedById(el.id) ||\n (ID_CHARSET_RE.test(el.id) && allocator.peek(prefix, parsedName) !== el.id);\n if (declare) {\n declared.add(el.id);\n allocator.claim(emittedId(el.id));\n } else {\n allocator.alloc(prefix, parsedName);\n }\n }\n return declared;\n}\n\n/** The label the parser allocates a note's or a drawing's id from. */\nfunction noteOrDrawingName(el: BoardElement): string {\n if (el.elementType === 'drawing') return 'line';\n return decodeName(escapeText(el.label)) || 'note';\n}\n\nfunction elementLine(el: BoardElement, name: string, idSuffix: string, attach: string): string {\n const p = el.position;\n switch (el.elementType) {\n case 'event':\n case 'command':\n case 'actor':\n case 'aggregate':\n case 'policy':\n case 'readmodel':\n case 'external':\n case 'hotspot':\n // Canonical suffix order: `(color …) (id …) (on …)` — `(on …)` stays last (see above).\n return `${el.elementType} ${name} [${r(p.x)}, ${r(p.y)}]${colorSuffix(el)}${idSuffix}${attach}`;\n case 'note': {\n // Escape line breaks/comment starters -> the line-based DSL stays single-line. `->` is\n // fine in note text (notes are never arrow endpoints), so no `→` replacement here.\n // Canonical note suffix order: `(color …) (size WxH) (align h v) (on …)` — `(on …)`\n // stays last (final-paren rule, see above); size/align/attachment are only present when\n // set, so plain boards stay byte-identical.\n const size = el.size ? ` (size ${r(el.size.width)}x${r(el.size.height)})` : '';\n return `note ${escapeText(name)} [${r(p.x)}, ${r(p.y)}]${colorSuffix(el)}${size}${alignSuffix(el)}${attach}`;\n }\n case 'drawing': {\n // Project extension (freeform drawing): tuple list + style flags.\n const pts = el.points.map((q) => `[${r(q.x)}, ${r(q.y)}]`).join(', ');\n const closed = el.closed ? ' (closed)' : '';\n const stroke = el.strokeStyle && el.strokeStyle !== 'solid' ? ` (${el.strokeStyle})` : '';\n return `line [${pts}]${closed}${stroke}${colorSuffix(el)}`;\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/lexer.ts","../src/ids.ts","../src/parser.ts","../src/serializer.ts"],"names":["LARGEST_DRAWABLE_NUMBER","ATTACHABLE_STICKY_KINDS","HOST_STICKY_KINDS","id","CURRENT_SCHEMA_VERSION","validateBoard","on","idp","al","sz","col"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Small, line-oriented helpers for the Event Storming `.storm` DSL.\n * The DSL is line-based; a full tokenizer/generator is not needed.\n */\n\nimport { LARGEST_DRAWABLE_NUMBER } from \"@miragon/event-storming-schema-model\";\n\nexport interface ParsedCoords {\n readonly a: number;\n readonly b: number;\n}\n\nconst COORDS_RE = /\\[\\s*([-\\d.]+)\\s*,\\s*([-\\d.]+)\\s*\\]/;\n\n/**\n * A number beyond the canvas's range (a digit run of 309 or more even overflows to Infinity) is\n * unreadable like `1.2.3`, so its line stays in rawPassthrough; JSON boards share the bound.\n */\nfunction isDrawable(value: number): boolean {\n return Math.abs(value) <= LARGEST_DRAWABLE_NUMBER;\n}\n\nfunction drawablePair(a: number, b: number): boolean {\n return isDrawable(a) && isDrawable(b);\n}\n\n/** Order stays raw (a, b). */\nexport function parseCoords(line: string): ParsedCoords | null {\n const m = COORDS_RE.exec(line);\n if (!m) return null;\n const a = Number(m[1]);\n const b = Number(m[2]);\n if (!drawablePair(a, b)) return null;\n return { a, b };\n}\n\n/**\n * Splits a line at the first `[a, b]` tuple: name before, suffix after.\n * Extras like `(color …)` may then only be looked up in the suffix — parentheses\n * inside the name stay untouched.\n */\nexport function splitAtCoords(\n line: string,\n): { name: string; coords: ParsedCoords; suffix: string } | null {\n const m = COORDS_RE.exec(line);\n if (!m) return null;\n const a = Number(m[1]);\n const b = Number(m[2]);\n if (!drawablePair(a, b)) return null;\n return {\n name: line.slice(0, m.index).trim(),\n coords: { a, b },\n suffix: line.slice(m.index + m[0].length),\n };\n}\n\n// `[^[\\]]` (tuples cannot contain '[') + bounded whitespace keep the scan linear (ReDoS-safe).\nconst MULTI_COORDS_RE = /\\[\\s{0,8}(\\[[^[\\]]*\\](?:\\s{0,8},\\s{0,8}\\[[^[\\]]*\\])+)\\s{0,8}\\]/;\n\n/** Extracts a tuple list `[[a,b],[c,d],…]` (freeform `line` drawing) — or null. */\nexport function parseMultiCoords(line: string): { tuples: ParsedCoords[]; rest: string } | null {\n const m = MULTI_COORDS_RE.exec(line);\n if (!m) return null;\n const tuples: ParsedCoords[] = [];\n const inner = /\\[\\s{0,8}([-\\d.]+)\\s{0,8},\\s{0,8}([-\\d.]+)\\s{0,8}\\]/g;\n let t: RegExpExecArray | null;\n while ((t = inner.exec(m[1]!))) {\n const a = Number(t[1]);\n const b = Number(t[2]);\n if (!drawablePair(a, b)) return null;\n tuples.push({ a, b });\n }\n if (!tuples.length) return null;\n return { tuples, rest: line.replace(MULTI_COORDS_RE, \" \") };\n}\n\n/**\n * Splits off a `//` line comment. Quote-aware (`'//weird'` inside quotes stays untouched) and\n * URL-aware: `//` directly after `:` is a scheme separator (`https://…`), not a comment.\n */\nexport function splitLineComment(line: string): { code: string; comment: string | null } {\n let inQuote = false;\n for (let i = 0; i < line.length - 1; i++) {\n const ch = line[i];\n if (ch === \"'\") inQuote = !inQuote;\n else if (!inQuote && ch === \"/\" && line[i + 1] === \"/\" && line[i - 1] !== \":\") {\n return { code: line.slice(0, i), comment: line.slice(i) };\n }\n }\n return { code: line, comment: null };\n}\n\n/** First occurrence of `needle` outside `'…'` quotes — or -1. */\nexport function indexOfOutsideQuotes(line: string, needle: string): number {\n let inQuote = false;\n for (let i = 0; i + needle.length <= line.length; i++) {\n const ch = line[i];\n if (ch === \"'\") {\n inQuote = !inQuote;\n continue;\n }\n if (!inQuote && line.startsWith(needle, i)) return i;\n }\n return -1;\n}\n\n// Color override extension: `(color #rrggbb)` OR `(color green)`. Deliberately placed after\n// the coordinates so parentheses inside sticky names are never mistaken for it.\n// Accepts hex or CSS color names.\nconst COLOR_RE = /\\(\\s*color\\s+(#[0-9a-fA-F]{3,8}|[a-zA-Z][\\w-]*)\\s*\\)/i;\n\nexport function parseColor(line: string): { color?: string; rest: string } {\n const m = COLOR_RE.exec(line);\n if (!m || !m[1]) return { rest: line };\n return { color: m[1], rest: line.replace(COLOR_RE, \" \") };\n}\n\n// Attachment extension: `(on <Host Name>)` — canonically the LAST suffix. The host name runs\n// up to the line's FINAL ')', so names may themselves contain parentheses (`Payment (retry)`).\n// Extracted BEFORE the other suffixes so a `(color …)` or `(size …)` inside a host name is\n// never mistaken for one.\nconst ON_RE = /\\(\\s*on\\s+/i;\n\nexport function parseOn(line: string): { host?: string; rest: string } {\n const m = ON_RE.exec(line);\n if (!m) return { rest: line };\n const start = m.index + m[0].length;\n const close = line.lastIndexOf(\")\");\n if (close < start) return { rest: line };\n const host = line.slice(start, close).trim();\n if (!host) return { rest: line };\n return { host, rest: `${line.slice(0, m.index)} ${line.slice(close + 1)}` };\n}\n\n// Internal-id extension: `(id <id>)` — emitted on sticky lines only when the name alone would\n// be ambiguous. The charset is deliberately tight (letters/digits/underscore/hyphen) so an id\n// can never collide with the line grammar (`)`/whitespace/`#` are all illegal).\nexport const ID_CHARSET_RE = /^[A-Za-z0-9_-]+$/;\n\nconst ID_RE = /\\(\\s*id\\s+([A-Za-z0-9_-]+)\\s*\\)/i;\n\n// Any `(id …)` group — catches malformed variants so the caller can report a diagnostic.\nconst ID_PRESENT_RE = /\\(\\s*id\\b[^)]*\\)/i;\n\nexport function parseId(line: string): {\n id?: string;\n /** The matched `(id …)` text when present but unreadable (illegal charset). */\n invalid?: string;\n rest: string;\n} {\n const m = ID_RE.exec(line);\n if (m?.[1]) return { id: m[1], rest: line.replace(ID_RE, \" \") };\n const p = ID_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(ID_PRESENT_RE, \" \") };\n}\n\n// Resize extension: `(size <w>x<h>)` — canonically the last suffix before `(on …)` on note\n// lines. The serializer emits no spaces around the `x`; the parser tolerates optional whitespace.\n// Deliberately looked up only after the coordinates so `(size 1x1)` inside note text survives.\nconst SIZE_RE = /\\(\\s*size\\s+([\\d.]+)\\s*x\\s*([\\d.]+)\\s*\\)/i;\n\n// Any `(size …)` group — catches malformed variants so the caller can report a diagnostic.\nconst SIZE_PRESENT_RE = /\\(\\s*size\\b[^)]*\\)/i;\n\nexport function parseSize(line: string): {\n size?: { width: number; height: number };\n /** The matched `(size …)` text when present but unreadable (malformed or non-positive). */\n invalid?: string;\n rest: string;\n} {\n const m = SIZE_RE.exec(line);\n if (m) {\n const width = Number(m[1]);\n const height = Number(m[2]);\n // Non-positive, NaN (`1.2.3`) or beyond the canvas falls through to the malformed branch.\n if (width > 0 && height > 0 && isDrawable(width) && isDrawable(height)) {\n return { size: { width, height }, rest: line.replace(SIZE_RE, \" \") };\n }\n }\n const p = SIZE_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(SIZE_PRESENT_RE, \" \") };\n}\n\n// Alignment extension: `(align <horizontal> <vertical>)` — canonically between `(size …)` and\n// `(on …)` on note lines, both words always present. Values are matched case-insensitively and\n// canonicalized to lowercase. Deliberately looked up only after the coordinates so an\n// `(align center middle)` inside note text survives.\nconst ALIGN_RE = /\\(\\s*align\\s+(left|center|right)\\s+(top|middle|bottom)\\s*\\)/i;\n\n// Any `(align …)` group — catches malformed variants so the caller can report a diagnostic.\nconst ALIGN_PRESENT_RE = /\\(\\s*align\\b[^)]*\\)/i;\n\nexport function parseAlign(line: string): {\n align?: {\n horizontal: \"left\" | \"center\" | \"right\";\n vertical: \"top\" | \"middle\" | \"bottom\";\n };\n /** The matched `(align …)` text when present but unreadable (unknown/missing axis words). */\n invalid?: string;\n rest: string;\n} {\n const m = ALIGN_RE.exec(line);\n if (m) {\n return {\n align: {\n horizontal: m[1]!.toLowerCase() as \"left\" | \"center\" | \"right\",\n vertical: m[2]!.toLowerCase() as \"top\" | \"middle\" | \"bottom\",\n },\n rest: line.replace(ALIGN_RE, \" \"),\n };\n }\n const p = ALIGN_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(ALIGN_PRESENT_RE, \" \") };\n}\n\n/** Undoes the serializer's `\\n` name escaping (line-based DSL, multi-line labels). */\nexport function decodeName(name: string): string {\n return name.replace(/\\\\n/g, \"\\n\");\n}\n\n/** First word (keyword) of a line, lowercased. */\nexport function keywordOf(line: string): string {\n const m = /^\\s*([A-Za-z][\\w-]*)/.exec(line);\n return m ? m[1]!.toLowerCase() : \"\";\n}\n\nexport function slug(label: string): string {\n return (\n label\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_/, \"\")\n .replace(/_$/, \"\") || \"x\"\n );\n}\n","import type { ElementType } from \"@miragon/event-storming-schema-model\";\nimport { slug } from \"./lexer.js\";\n\n/** Sticky keywords double as `elementType` values; the value is the ID prefix. */\nexport const STICKY_ID_PREFIXES: Readonly<Partial<Record<ElementType, string>>> = {\n event: \"event\",\n command: \"cmd\",\n actor: \"actor\",\n aggregate: \"agg\",\n policy: \"policy\",\n readmodel: \"read\",\n external: \"ext\",\n hotspot: \"hot\",\n};\n\n// Board ids become diagram-js element ids, and the renderer's root elements live in the same\n// registry: an element claiming one of these would make the import throw halfway through.\nconst ENGINE_ID_RE = /^(?:event-storming-root$|__implicitroot)/;\n\nexport function isEngineId(id: string): boolean {\n return ENGINE_ID_RE.test(id);\n}\n\n/**\n * The parser's id allocation, shared with the serializer: the serializer replays it in emit order\n * to decide which ids the text has to carry so that every sticky gets its id back on re-import.\n */\nexport class IdAllocator {\n private readonly used = new Set<string>();\n\n /** Explicit `(id …)` — false when the id is taken or reserved (caller reports + allocates). */\n claim(id: string): boolean {\n if (this.used.has(id) || isEngineId(id)) return false;\n this.used.add(id);\n return true;\n }\n\n /** The id `alloc(prefix, label)` would return, without taking it. */\n peek(prefix: string, label: string): string {\n const base = `${prefix}_${slug(label)}`;\n let id = base;\n let i = 2;\n while (this.used.has(id)) id = `${base}_${i++}`;\n return id;\n }\n\n alloc(prefix: string, label: string): string {\n const id = this.peek(prefix, label);\n this.used.add(id);\n return id;\n }\n}\n","import {\n ATTACHABLE_STICKY_KINDS,\n CURRENT_SCHEMA_VERSION,\n HOST_STICKY_KINDS,\n validateBoard,\n type BoardConfig,\n type BoardEdge,\n type BoardLevel,\n type BoardElement,\n type Coordinate,\n type DrawingElement,\n type DrawingStrokeStyle,\n type ElementType,\n type EventStormingBoard,\n type NoteAlign,\n type NoteAlignHorizontal,\n type NoteAlignVertical,\n type NoteElement,\n} from \"@miragon/event-storming-schema-model\";\nimport {\n indexOfOutsideQuotes,\n keywordOf,\n parseAlign,\n parseColor,\n parseCoords,\n parseId,\n parseMultiCoords,\n parseOn,\n parseSize,\n splitAtCoords,\n splitLineComment,\n decodeName,\n} from \"./lexer.js\";\nimport { IdAllocator, STICKY_ID_PREFIXES, isEngineId } from \"./ids.js\";\n\n/** Splits `A -> B` at the FIRST arrow — plain indexOf, immune to regex backtracking. */\nfunction splitArrow(core: string): { left: string; right: string } | null {\n const arrow = core.indexOf(\"->\");\n if (arrow <= 0) return null;\n const left = core.slice(0, arrow).trim();\n const right = core.slice(arrow + 2).trim();\n return left && right ? { left, right } : null;\n}\n\nconst KNOWN_STYLES: ReadonlySet<string> = new Set([\"classic\", \"dark\"]);\n\nconst ATTACHABLE_KINDS: ReadonlySet<string> = new Set(ATTACHABLE_STICKY_KINDS);\n\nconst HOST_KINDS: ReadonlySet<string> = new Set(HOST_STICKY_KINDS);\n\nconst KNOWN_LEVELS: ReadonlySet<string> = new Set([\"big-picture\", \"process\", \"design\"]);\n\n// The 8 sticky kinds — the only legal arrow endpoints (mirrors validateBoard's contract).\nconst STICKY_KINDS: ReadonlySet<string> = new Set(Object.keys(STICKY_ID_PREFIXES));\n\ninterface PendingArrow {\n readonly left: string;\n readonly right: string;\n /** Annotation text after `;`. */\n readonly label?: string;\n readonly raw: string;\n readonly lineNo: number;\n}\n\n/** `(on …)` attachment — host referenced BY NAME, resolution deferred like arrow endpoints. */\ninterface PendingAttachment {\n /** Index into `elements` of the attachable sticky. */\n readonly index: number;\n readonly host: string;\n readonly raw: string;\n readonly lineNo: number;\n}\n\nfunction compact<T extends Record<string, unknown>>(obj: T): T {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) if (v !== undefined) out[k] = v;\n return out as T;\n}\n\n/**\n * Text `(align <h> <v>)` pair -> model value: default axes (left/top) are dropped, both-default\n * collapses to absent — `(align left top)` and no suffix are the same board (the serializer\n * emits the suffix only when an axis differs from the default).\n */\nfunction modelAlign(\n align: { horizontal: NoteAlignHorizontal; vertical: NoteAlignVertical } | undefined,\n): NoteAlign | undefined {\n if (!align) return undefined;\n const out = compact({\n horizontal: align.horizontal === \"left\" ? undefined : align.horizontal,\n vertical: align.vertical === \"top\" ? undefined : align.vertical,\n }) as NoteAlign;\n return Object.keys(out).length ? out : undefined;\n}\n\n/** Finding produced while parsing — line is 1-based; `text` is the (comment-stripped) line. */\nexport interface ParseDiagnostic {\n readonly line: number;\n readonly message: string;\n readonly text: string;\n}\n\nexport interface ParseResult {\n readonly board: EventStormingBoard;\n readonly diagnostics: readonly ParseDiagnostic[];\n}\n\n/**\n * Line-based keyword parsing; coordinates are `[x, y]` in board pixels (x FIRST), unbounded,\n * optional (default `[0, 0]`). Unknown lines land in `rawPassthrough`.\n */\nexport function parseDSL(text: string): EventStormingBoard {\n return parseDSLWithDiagnostics(text).board;\n}\n\n/**\n * Like `parseDSL`, but additionally returns findings with line numbers (uninterpretable lines,\n * unresolved references) — for editor feedback instead of silent loss.\n */\nexport function parseDSLWithDiagnostics(text: string): ParseResult {\n const diagnostics: ParseDiagnostic[] = [];\n const ids = new IdAllocator();\n const nameToId = new Map<string, string>();\n const elements: BoardElement[] = [];\n const rawPassthrough: string[] = [];\n const pendingArrows: PendingArrow[] = [];\n const pendingAttachments: PendingAttachment[] = [];\n\n let config: BoardConfig = { title: \"Untitled Board\" };\n let inBlockComment = false;\n\n const register = (name: string, id: string) => {\n if (!nameToId.has(name)) nameToId.set(name, id);\n };\n\n // Diagnostics helpers: read the current line/number from the loop state.\n let lineNo = 0;\n let currentLine = \"\";\n\n /** Tries to capture a line as an arrow. Returns true when consumed. */\n const pushArrow = (line: string): boolean => {\n // Split off an optional arrow annotation after ';' (e.g. `A -> B; async`).\n const semi = line.indexOf(\";\");\n const core = semi >= 0 ? line.slice(0, semi).trim() : line;\n const arrowLabel = semi >= 0 ? line.slice(semi + 1).trim() : \"\";\n const arrow = splitArrow(core);\n if (!arrow) return false;\n pendingArrows.push({\n left: arrow.left,\n right: arrow.right,\n ...(arrowLabel ? { label: arrowLabel } : {}),\n raw: line,\n lineNo,\n });\n return true;\n };\n const diag = (message: string, atLine = lineNo, text_ = currentLine) =>\n diagnostics.push({ line: atLine, message, text: text_ });\n /** Passthrough for a line that looks like a known construct but cannot be parsed. */\n const failed = (l: string) => {\n rawPassthrough.push(l);\n diag(\"Couldn't read this line. It stays in the file unchanged.\");\n };\n /** Board pixels, unbounded — no clamping on the free canvas. */\n const pos = (x: number, y: number): Coordinate => ({ x, y });\n\n const sourceLines = text.split(/\\r?\\n/);\n for (let i = 0; i < sourceLines.length; i++) {\n const raw = sourceLines[i]!;\n // The empty piece after a final newline is no line: inside an open block comment it would be\n // kept as one, and every save would append another blank line.\n if (raw === \"\" && i === sourceLines.length - 1) continue;\n lineNo = i + 1;\n currentLine = raw.trim();\n let working = raw;\n\n // --- Comments (`//`, `/* */`): strip, but keep losslessly in rawPassthrough. ---\n if (inBlockComment) {\n const close = working.indexOf(\"*/\");\n if (close < 0) {\n rawPassthrough.push(raw);\n continue;\n }\n rawPassthrough.push(working.slice(0, close + 2));\n working = working.slice(close + 2);\n inBlockComment = false;\n }\n let open = indexOfOutsideQuotes(working, \"/*\");\n while (open >= 0) {\n const close = working.indexOf(\"*/\", open + 2);\n if (close < 0) {\n rawPassthrough.push(working.slice(open));\n working = working.slice(0, open);\n inBlockComment = true;\n break;\n }\n rawPassthrough.push(working.slice(open, close + 2));\n working = `${working.slice(0, open)} ${working.slice(close + 2)}`;\n open = indexOfOutsideQuotes(working, \"/*\");\n }\n const { code, comment } = splitLineComment(working);\n if (comment !== null) rawPassthrough.push(comment);\n working = code;\n\n const line = working.trim();\n if (!line) continue;\n\n const kw = keywordOf(line);\n const after = line.slice(kw.length).trim();\n\n // Arrows FIRST: sticky NAMES may begin with a keyword word (the default command is\n // named \"Command\" -> arrow `Command -> X`). Declarations carry coordinates `[...]`,\n // arrows never do — but only the part BEFORE the `;` annotation counts, the annotation\n // is free text and may contain a tuple. Without this pre-detection `Command -> X` would\n // be misread as a (broken) `command` declaration and vanish on re-import. `title` is\n // exempt (its content may itself use `->`) UNLESS the left side is an already-declared\n // sticky name (e.g. one named \"Title Page\" — declarations always precede arrows in\n // serialized DSL). `style`/`level`/`line` need no exemption: style and level values are\n // single words and drawings always carry coordinate tuples.\n const semi = line.indexOf(\";\");\n const beforeAnnotation = semi >= 0 ? line.slice(0, semi) : line;\n const titleAsArrow = (): boolean => {\n const arrow = splitArrow(beforeAnnotation.trim());\n return arrow !== null && nameToId.has(decodeName(arrow.left));\n };\n if ((kw !== \"title\" || titleAsArrow()) && !parseCoords(beforeAnnotation) && pushArrow(line)) {\n continue;\n }\n\n switch (kw) {\n case \"title\":\n config = { ...config, title: after };\n break;\n\n case \"style\": {\n const s = after.toLowerCase();\n if (KNOWN_STYLES.has(s)) config = { ...config, style: s as \"classic\" | \"dark\" };\n else failed(line);\n break;\n }\n\n case \"level\": {\n const l = after.toLowerCase();\n if (KNOWN_LEVELS.has(l)) config = { ...config, level: l as BoardLevel };\n else failed(line);\n break;\n }\n\n case \"event\":\n case \"command\":\n case \"actor\":\n case \"aggregate\":\n case \"policy\":\n case \"readmodel\":\n case \"external\":\n case \"hotspot\": {\n const node = parseSticky(after);\n if (!node) {\n failed(line);\n break;\n }\n if (node.idInvalid) {\n diag(\n `Couldn't read the id “${node.idInvalid.trim()}”. An id has letters, digits, “_” or “-”, as in (id order_1).`,\n );\n }\n const explicit = node.id !== undefined && ids.claim(node.id) ? node.id : undefined;\n if (node.id !== undefined && explicit === undefined) {\n diag(\n isEngineId(node.id)\n ? `The id “${node.id}” belongs to the board itself, so this sticky got a new id.`\n : `The id “${node.id}” is already taken, so this sticky got a new id.`,\n );\n }\n const id = explicit ?? ids.alloc(STICKY_ID_PREFIXES[kw as ElementType]!, node.name);\n elements.push(\n compact({\n id,\n elementType: kw as ElementType,\n label: node.name,\n position: pos(node.coords.x, node.coords.y),\n color: node.color,\n }) as BoardElement,\n );\n register(node.name, id);\n if (node.host !== undefined) {\n if (ATTACHABLE_KINDS.has(kw)) {\n pendingAttachments.push({\n index: elements.length - 1,\n host: node.host,\n raw: line,\n lineNo,\n });\n } else {\n diag(`A ${kw} can't be pinned. Only an actor, a hotspot or a note takes (on …).`);\n }\n }\n if (node.sizeSuffix) {\n diag(`A ${kw} can't be resized. Only a note takes (size …).`);\n }\n if (node.alignSuffix) {\n diag(`A ${kw} can't be aligned. Only a note takes (align …).`);\n }\n break;\n }\n\n case \"note\": {\n const split = splitAtCoords(after);\n if (!split && after.includes(\"[\")) {\n failed(line);\n break;\n }\n // Suffixes ONLY after the coordinates (mirrors parseSticky) — notes are free text, so\n // `(on …)`, `(color …)` or `(size 1x1)` may legitimately appear inside it. `(on …)` is\n // stripped FIRST: it is always the last suffix and its host name runs to the final `)`,\n // so it may itself contain a `(color …)`, `(size …)` or `(align …)`.\n const on = parseOn(split ? split.suffix : after);\n const al = parseAlign(on.rest);\n const sz = parseSize(al.rest);\n const idp = parseId(sz.rest);\n const col = parseColor(idp.rest);\n if (al.invalid) {\n diag(\n `Couldn't read the alignment “${al.invalid.trim()}”. Write (align left|center|right top|middle|bottom).`,\n );\n }\n if (sz.invalid) {\n diag(\n `Couldn't read the size “${sz.invalid.trim()}”. Write (size <w>x<h>) with positive numbers.`,\n );\n }\n if (idp.id !== undefined || idp.invalid) {\n diag(\"A note can't have an id. Only a sticky takes (id …).\");\n }\n // Literal `\\n` back into real line breaks (multi-line notes).\n const textPart = decodeName((split ? split.name : col.rest).trim());\n const id = ids.alloc(\"note\", textPart || \"note\");\n const note: NoteElement = compact({\n id,\n elementType: \"note\",\n label: textPart,\n position: split ? pos(split.coords.a, split.coords.b) : pos(0, 0),\n color: col.color,\n size: sz.size,\n align: modelAlign(al.align),\n }) as NoteElement;\n elements.push(note);\n if (on.host !== undefined) {\n pendingAttachments.push({ index: elements.length - 1, host: on.host, raw: line, lineNo });\n }\n break;\n }\n\n case \"line\": {\n // Project extension (freeform drawing): `line [[x,y], [x,y], …] (closed) (dashed) (color x)`.\n const col = parseColor(after);\n const multi = parseMultiCoords(col.rest);\n if (!multi || multi.tuples.length < 2) {\n failed(line);\n break;\n }\n const onDrawing = parseOn(multi.rest);\n if (onDrawing.host !== undefined) {\n diag(\"A drawing can't be pinned. Only an actor, a hotspot or a note takes (on …).\");\n }\n const szDrawing = parseSize(onDrawing.rest);\n if (szDrawing.size || szDrawing.invalid) {\n diag(\"A drawing can't be resized. Only a note takes (size …).\");\n }\n const alDrawing = parseAlign(onDrawing.rest);\n if (alDrawing.align || alDrawing.invalid) {\n diag(\"A drawing can't be aligned. Only a note takes (align …).\");\n }\n const idDrawing = parseId(onDrawing.rest);\n if (idDrawing.id !== undefined || idDrawing.invalid) {\n diag(\"A drawing can't have an id. Only a sticky takes (id …).\");\n }\n const flags = onDrawing.rest.toLowerCase();\n const strokeStyle: DrawingStrokeStyle | undefined = flags.includes(\"(dashed)\")\n ? \"dashed\"\n : flags.includes(\"(dotted)\")\n ? \"dotted\"\n : undefined;\n const points = multi.tuples.map((t) => pos(t.a, t.b));\n const drawing: DrawingElement = {\n id: ids.alloc(\"draw\", \"line\"),\n elementType: \"drawing\",\n label: \"\",\n position: points[0]!,\n points,\n ...(flags.includes(\"(closed)\") ? { closed: true } : {}),\n ...(strokeStyle ? { strokeStyle } : {}),\n ...(col.color ? { color: col.color } : {}),\n };\n elements.push(drawing);\n break;\n }\n\n default: {\n // Unknown keyword: try as an arrow (e.g. `A -> B; async`), otherwise keep raw.\n if (!pushArrow(line)) rawPassthrough.push(line);\n }\n }\n }\n\n // Reference resolution for arrow endpoints and `(on …)` hosts: a `#`-prefixed token is an id\n // reference (ids exist for EVERY element, not only those declared with `(id …)`); anything\n // else stays a label lookup. No fallback across the two — `#` always means id.\n const resolve = (token: string): BoardElement | undefined => {\n if (token.startsWith(\"#\")) {\n const id = token.slice(1);\n return elements.find((e) => e.id === id);\n }\n const id = nameToId.get(decodeName(token));\n return id !== undefined ? elements.find((e) => e.id === id) : undefined;\n };\n\n // Deferred like arrows so a host may be declared after its attacher. On failure the sticky\n // stays WITHOUT attachedTo (it was already created above) — no rawPassthrough, the line is\n // otherwise fully represented.\n for (const att of pendingAttachments) {\n const host = resolve(att.host);\n if (!host) {\n diag(`There's no “${att.host}” on the board to pin this to.`, att.lineNo, att.raw);\n continue;\n }\n if (!HOST_KINDS.has(host.elementType)) {\n diag(\n `“${att.host}” is a ${host.elementType}. An actor, a hotspot or a note is pinned to an event, a command, an aggregate, a policy, a read model or an external system.`,\n att.lineNo,\n att.raw,\n );\n continue;\n }\n elements[att.index] = { ...elements[att.index]!, attachedTo: host.id } as BoardElement;\n }\n\n let arrowN = 0;\n // An explicit `(id arrow_N)` on a sticky may occupy an arrow-id slot — skip it (diagram-js\n // has ONE id namespace for shapes and connections; validateBoard rejects the collision).\n const elementIds = new Set(elements.map((e) => e.id));\n const nextArrowId = (): string => {\n let id = `arrow_${++arrowN}`;\n while (elementIds.has(id)) id = `arrow_${++arrowN}`;\n return id;\n };\n const edges: BoardEdge[] = [];\n for (const arrow of pendingArrows) {\n const from = resolve(arrow.left);\n const to = resolve(arrow.right);\n if (!from || !to) {\n rawPassthrough.push(arrow.raw);\n diag(\n !from\n ? `This arrow starts at “${arrow.left}”, which isn't on the board.`\n : `This arrow points to “${arrow.right}”, which isn't on the board.`,\n arrow.lineNo,\n arrow.raw,\n );\n continue;\n }\n // Only reachable via `#id` refs (labels are registered for sticky kinds only) — an edge to\n // a note/drawing would make validateBoard throw, so it is dropped losslessly instead.\n const nonSticky = !STICKY_KINDS.has(from.elementType)\n ? ([arrow.left, from] as const)\n : !STICKY_KINDS.has(to.elementType)\n ? ([arrow.right, to] as const)\n : undefined;\n if (nonSticky) {\n rawPassthrough.push(arrow.raw);\n diag(\n `“${nonSticky[0]}” is a ${nonSticky[1].elementType}, and an arrow only connects stickies.`,\n arrow.lineNo,\n arrow.raw,\n );\n continue;\n }\n edges.push(\n compact({\n id: nextArrowId(),\n edgeType: \"arrow\",\n from: from.id,\n to: to.id,\n label: arrow.label,\n }) as BoardEdge,\n );\n }\n\n const board = compact({\n schemaVersion: CURRENT_SCHEMA_VERSION,\n config,\n elements,\n edges,\n rawPassthrough: rawPassthrough.length ? rawPassthrough : undefined,\n }) as EventStormingBoard;\n\n return { board: validateBoard(board), diagnostics };\n}\n\ninterface ParsedSticky {\n readonly name: string;\n readonly coords: { x: number; y: number };\n /** Color override `(color …)` — supported on every element line. */\n readonly color?: string;\n /** Attachment `(on <Host Name>)` — host name still undecoded, resolved by the caller. */\n readonly host?: string;\n /** Explicit `(id …)` — the caller claims it (duplicate ⇒ diagnostic + fresh id). */\n readonly id?: string;\n /** The matched `(id …)` text when present but unreadable (illegal charset). */\n readonly idInvalid?: string;\n /** A `(size …)` suffix appeared — only notes support it, the caller reports a diagnostic. */\n readonly sizeSuffix?: boolean;\n /** An `(align …)` suffix appeared — only notes support it, the caller reports a diagnostic. */\n readonly alignSuffix?: boolean;\n}\n\n/**\n * Parses `<name> [x, y] [(color …)] [(id …)] [(on …)]`. The suffixes are looked up ONLY AFTER\n * the coordinates — parentheses inside the name stay untouched. `(on …)` is extracted first\n * (its host name runs to the final `)` and may itself contain a `(color …)`, `(id …)` or\n * `(size …)`). Coordinates are optional and default to `[0, 0]`; a malformed tuple (bracket\n * present but unreadable) is rejected so the caller can report a diagnostic instead of\n * swallowing it into the name.\n */\nfunction parseSticky(after: string): ParsedSticky | null {\n const split = splitAtCoords(after);\n if (split) {\n if (!split.name) return null;\n const on = parseOn(split.suffix);\n const idp = parseId(on.rest);\n const al = parseAlign(idp.rest);\n const sz = parseSize(al.rest);\n const col = parseColor(sz.rest);\n return compact({\n name: decodeName(split.name),\n coords: { x: split.coords.a, y: split.coords.b },\n color: col.color ?? undefined,\n host: on.host,\n id: idp.id,\n idInvalid: idp.invalid,\n sizeSuffix: sz.size || sz.invalid ? true : undefined,\n alignSuffix: al.align || al.invalid ? true : undefined,\n }) as ParsedSticky;\n }\n if (after.includes(\"[\")) return null;\n const on = parseOn(after);\n const idp = parseId(on.rest);\n const al = parseAlign(idp.rest);\n const sz = parseSize(al.rest);\n const col = parseColor(sz.rest);\n const name = col.rest.trim();\n if (!name) return null;\n return compact({\n name: decodeName(name),\n coords: { x: 0, y: 0 },\n color: col.color ?? undefined,\n host: on.host,\n id: idp.id,\n idInvalid: idp.invalid,\n sizeSuffix: sz.size || sz.invalid ? true : undefined,\n alignSuffix: al.align || al.invalid ? true : undefined,\n }) as ParsedSticky;\n}\n","import type {\n BoardElement,\n EventStormingBoard,\n NoteElement,\n} from \"@miragon/event-storming-schema-model\";\nimport { IdAllocator, STICKY_ID_PREFIXES } from \"./ids.js\";\nimport { ID_CHARSET_RE, decodeName, slug } from \"./lexer.js\";\n\n/**\n * Coordinate formatter: 3-decimal rounding, NEVER exponent notation — `String(1e21)` yields\n * `\"1e+21\"`, which the coordinate regex cannot read back. Magnitudes >= 1e21 are always\n * integer-valued doubles, so BigInt expands them losslessly (the rounding step is skipped\n * there; it would be a no-op and could overflow to Infinity for huge values).\n */\nfunction r(n: number): string {\n const v = Math.abs(n) < 1e21 ? Math.round(n * 1000) / 1000 : n;\n return Math.abs(v) < 1e21 ? String(v) : BigInt(v).toString();\n}\n\n/**\n * Free text emitted into the line-based grammar: real line breaks become the literal `\\n`\n * escape (decoded on parse) and comment starters are defused with the Unicode division slash\n * — otherwise the parser would split the line or strip the rest as a comment. `//` directly\n * after `:` stays untouched (URL scheme separator, the comment splitter is URL-aware).\n */\nfunction escapeText(label: string): string {\n return label\n .trim()\n .replace(/\\n/g, \"\\\\n\")\n .replace(/(?<!:)\\/\\//g, \"∕∕\")\n .replace(/\\/\\*/g, \"∕*\");\n}\n\n/** Names are additionally arrow-safe: a literal `->` inside a name would break `A -> B` lines. */\nfunction escapeName(label: string): string {\n return escapeText(label).replace(/->/g, \"→\");\n}\n\n/** Types referenced BY THEIR NAME in the DSL (arrow endpoints + namespace) — all sticky kinds. */\nconst NAMED_TYPES: ReadonlySet<string> = new Set([\n \"event\",\n \"command\",\n \"actor\",\n \"aggregate\",\n \"policy\",\n \"readmodel\",\n \"external\",\n \"hotspot\",\n]);\n\nconst DEFAULT_NAMES: Readonly<Record<string, string>> = {\n event: \"Domain Event\",\n command: \"Command\",\n actor: \"Actor\",\n aggregate: \"Aggregate\",\n policy: \"Policy\",\n readmodel: \"Read Model\",\n external: \"External System\",\n hotspot: \"Hotspot\",\n};\n\nfunction defaultName(type: string): string {\n return DEFAULT_NAMES[type] ?? \"Sticky\";\n}\n\n/**\n * Returns the DSL name per element ID for the referenceable types (the sticky kinds): the\n * escaped label, or the per-kind default for an empty one. Duplicate labels are legal — an\n * ambiguous name is disambiguated via an `(id …)` suffix plus `#id` references instead of\n * being silently renamed.\n */\nfunction serializedNames(board: EventStormingBoard): Map<string, string> {\n const byId = new Map<string, string>();\n for (const el of board.elements) {\n if (!NAMED_TYPES.has(el.elementType)) continue;\n byId.set(el.id, escapeName(el.label) || defaultName(el.elementType));\n }\n return byId;\n}\n\n/** Color override extension: `(color …)` after the coordinates. */\nfunction colorSuffix(el: { color?: string }): string {\n return el.color ? ` (color ${el.color})` : \"\";\n}\n\n/**\n * Alignment extension: `(align <horizontal> <vertical>)` — both words always emitted together\n * using the EFFECTIVE values, and only when at least one axis differs from the default\n * left/top, so existing boards serialize byte-identically.\n */\nfunction alignSuffix(el: NoteElement): string {\n const horizontal = el.align?.horizontal ?? \"left\";\n const vertical = el.align?.vertical ?? \"top\";\n return horizontal === \"left\" && vertical === \"top\" ? \"\" : ` (align ${horizontal} ${vertical})`;\n}\n\n/**\n * Serializes an EventStormingBoard into `.storm` text. Deterministic; writes only syntax the\n * parser reads back. `rawPassthrough` is appended unchanged. Coordinates are `[x, y]` in board\n * pixels (x FIRST), rounded to 3 decimals.\n */\nexport function serializeDSL(board: EventStormingBoard): string {\n const lines: string[] = [];\n const names = serializedNames(board);\n const nameOf = (el: BoardElement): string => names.get(el.id) ?? el.label;\n\n // A `#…` token in a reference position always reads as an id — so a sticky whose serialized\n // name is AMBIGUOUS (shared by >= 2 stickies) or literally starts with `#` is referenced as\n // `#id`. Everything else stays purely name-based, so unambiguous boards serialize without any\n // ids, byte-identical to before.\n const nameCount = new Map<string, number>();\n for (const name of names.values()) nameCount.set(name, (nameCount.get(name) ?? 0) + 1);\n const referencedById = (id: string): boolean => {\n const name = names.get(id);\n return name !== undefined && (nameCount.get(name)! > 1 || name.startsWith(\"#\"));\n };\n\n // Ids surface in the text only via the `(id …)` suffix. An id outside the DSL id charset\n // (possible in JSON-authored boards) would emit unparsable syntax and lose the arrows on\n // re-import — a slug-based, collision-checked stand-in is substituted for the suffix AND every\n // reference.\n const emitIds = new Map<string, string>();\n const taken = new Set(board.elements.map((e) => e.id));\n for (const el of board.elements) {\n if (!referencedById(el.id) || ID_CHARSET_RE.test(el.id)) continue;\n let candidate = slug(el.id);\n for (let i = 2; taken.has(candidate); i++) candidate = `${slug(el.id)}_${i}`;\n taken.add(candidate);\n emitIds.set(el.id, candidate);\n }\n const idOf = (id: string): string => emitIds.get(id) ?? id;\n const declaredIds = idsToDeclare(board, nameOf, referencedById, idOf);\n const ref = (id: string): string => (referencedById(id) ? `#${idOf(id)}` : (names.get(id) ?? id));\n\n lines.push(`title ${board.config.title}`);\n if (board.config.style) lines.push(`style ${board.config.style}`);\n if (board.config.level) lines.push(`level ${board.config.level}`);\n\n // Pinning `(on …)` is ALWAYS the last suffix — the parser reads the host name up to the\n // line's final `)`, so host names containing parentheses survive. validateBoard guarantees\n // the host is a named sticky kind; `ref` falls back to the raw id purely defensively.\n const onSuffix = (el: BoardElement): string => {\n const hostId =\n el.elementType === \"actor\" || el.elementType === \"hotspot\" || el.elementType === \"note\"\n ? el.attachedTo\n : undefined;\n return hostId ? ` (on ${ref(hostId)})` : \"\";\n };\n\n for (const el of board.elements) {\n const idSuffix = declaredIds.has(el.id) ? ` (id ${idOf(el.id)})` : \"\";\n lines.push(elementLine(el, nameOf(el), idSuffix, onSuffix(el)));\n }\n\n // validateBoard guarantees arrow endpoints are sticky kinds, so the name map always covers\n // them — `ref`'s raw-id fallback is purely defensive for unvalidated input.\n for (const edge of board.edges) {\n const annotation = edge.label ? `; ${edge.label}` : \"\";\n lines.push(`${ref(edge.from)} -> ${ref(edge.to)}${annotation}`);\n }\n\n // Config keywords were already emitted from the board above. A rawPassthrough entry with the\n // same keyword (e.g. an unparsable `style` line from externally-authored DSL) would otherwise\n // produce a contradictory duplicate line — drop it (config is the truth).\n if (board.rawPassthrough) {\n const emitted = new Set<string>([\"title\"]);\n if (board.config.style) emitted.add(\"style\");\n if (board.config.level) emitted.add(\"level\");\n for (const raw of board.rawPassthrough) {\n if (emitted.has(raw.trim().split(/\\s+/)[0]!)) continue;\n lines.push(raw);\n }\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/**\n * The stickies whose line carries `(id …)`: those referenced as `#id`, plus every sticky whose id\n * the parser would not allocate again at its line — one created on the canvas (`event_3`),\n * renamed after its id was derived from the old label, or declared with an explicit id. Hosts\n * anchor todos, presence and deep links to these ids, so they must survive a save and re-open.\n * Replays the parser's allocation in emit order; an id equal to the allocated one stays implicit,\n * which keeps boards authored without ids byte-identical.\n */\nfunction idsToDeclare(\n board: EventStormingBoard,\n nameOf: (el: BoardElement) => string,\n referencedById: (id: string) => boolean,\n emittedId: (id: string) => string,\n): Set<string> {\n const allocator = new IdAllocator();\n const declared = new Set<string>();\n for (const el of board.elements) {\n const prefix = STICKY_ID_PREFIXES[el.elementType];\n if (prefix === undefined) {\n allocator.alloc(el.elementType === \"note\" ? \"note\" : \"draw\", noteOrDrawingName(el));\n continue;\n }\n const parsedName = decodeName(nameOf(el));\n const declare =\n referencedById(el.id) ||\n (ID_CHARSET_RE.test(el.id) && allocator.peek(prefix, parsedName) !== el.id);\n if (declare) {\n declared.add(el.id);\n allocator.claim(emittedId(el.id));\n } else {\n allocator.alloc(prefix, parsedName);\n }\n }\n return declared;\n}\n\n/** The label the parser allocates a note's or a drawing's id from. */\nfunction noteOrDrawingName(el: BoardElement): string {\n if (el.elementType === \"drawing\") return \"line\";\n return decodeName(escapeText(el.label)) || \"note\";\n}\n\nfunction elementLine(el: BoardElement, name: string, idSuffix: string, attach: string): string {\n const p = el.position;\n switch (el.elementType) {\n case \"event\":\n case \"command\":\n case \"actor\":\n case \"aggregate\":\n case \"policy\":\n case \"readmodel\":\n case \"external\":\n case \"hotspot\":\n // Canonical suffix order: `(color …) (id …) (on …)` — `(on …)` stays last (see above).\n return `${el.elementType} ${name} [${r(p.x)}, ${r(p.y)}]${colorSuffix(el)}${idSuffix}${attach}`;\n case \"note\": {\n // Escape line breaks/comment starters -> the line-based DSL stays single-line. `->` is\n // fine in note text (notes are never arrow endpoints), so no `→` replacement here.\n // Canonical note suffix order: `(color …) (size WxH) (align h v) (on …)` — `(on …)`\n // stays last (final-paren rule, see above); size/align/attachment are only present when\n // set, so plain boards stay byte-identical.\n const size = el.size ? ` (size ${r(el.size.width)}x${r(el.size.height)})` : \"\";\n return `note ${escapeText(name)} [${r(p.x)}, ${r(p.y)}]${colorSuffix(el)}${size}${alignSuffix(el)}${attach}`;\n }\n case \"drawing\": {\n // Project extension (freeform drawing): tuple list + style flags.\n const pts = el.points.map((q) => `[${r(q.x)}, ${r(q.y)}]`).join(\", \");\n const closed = el.closed ? \" (closed)\" : \"\";\n const stroke = el.strokeStyle && el.strokeStyle !== \"solid\" ? ` (${el.strokeStyle})` : \"\";\n return `line [${pts}]${closed}${stroke}${colorSuffix(el)}`;\n }\n }\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -43,4 +43,5 @@ declare function parseCoords(line: string): ParsedCoords | null;
43
43
  declare function keywordOf(line: string): string;
44
44
  declare function slug(label: string): string;
45
45
 
46
- export { type ParseDiagnostic, type ParseResult, type ParsedCoords, keywordOf, parseCoords, parseDSL, parseDSLWithDiagnostics, serializeDSL, slug };
46
+ export { keywordOf, parseCoords, parseDSL, parseDSLWithDiagnostics, serializeDSL, slug };
47
+ export type { ParseDiagnostic, ParseResult, ParsedCoords };
package/dist/index.d.ts CHANGED
@@ -43,4 +43,5 @@ declare function parseCoords(line: string): ParsedCoords | null;
43
43
  declare function keywordOf(line: string): string;
44
44
  declare function slug(label: string): string;
45
45
 
46
- export { type ParseDiagnostic, type ParseResult, type ParsedCoords, keywordOf, parseCoords, parseDSL, parseDSLWithDiagnostics, serializeDSL, slug };
46
+ export { keywordOf, parseCoords, parseDSL, parseDSLWithDiagnostics, serializeDSL, slug };
47
+ export type { ParseDiagnostic, ParseResult, ParsedCoords };
package/dist/index.js CHANGED
@@ -1,11 +1,8 @@
1
- import { ATTACHABLE_STICKY_KINDS, HOST_STICKY_KINDS, validateBoard, CURRENT_SCHEMA_VERSION } from '@miragon/event-storming-schema-model';
1
+ import { ATTACHABLE_STICKY_KINDS, HOST_STICKY_KINDS, validateBoard, CURRENT_SCHEMA_VERSION, LARGEST_DRAWABLE_NUMBER } from '@miragon/event-storming-schema-model';
2
2
  export { parseBoardJSON as boardFromJSON, serializeBoard as boardToJSON, loadBoard } from '@miragon/event-storming-schema-model';
3
3
 
4
4
  // src/parser.ts
5
-
6
- // src/lexer.ts
7
5
  var COORDS_RE = /\[\s*([-\d.]+)\s*,\s*([-\d.]+)\s*\]/;
8
- var LARGEST_DRAWABLE_NUMBER = 1e38;
9
6
  function isDrawable(value) {
10
7
  return Math.abs(value) <= LARGEST_DRAWABLE_NUMBER;
11
8
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lexer.ts","../src/ids.ts","../src/parser.ts","../src/serializer.ts"],"names":["id","on","idp","al","sz","col"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Small, line-oriented helpers for the Event Storming `.storm` DSL.\n * The DSL is line-based; a full tokenizer/generator is not needed.\n */\n\nexport interface ParsedCoords {\n readonly a: number;\n readonly b: number;\n}\n\nconst COORDS_RE = /\\[\\s*([-\\d.]+)\\s*,\\s*([-\\d.]+)\\s*\\]/;\n\n/**\n * The canvas places shapes with 32-bit SVG transforms, which overflow near 3.4e38 and would make\n * an import throw half-way; 1e38 leaves room for a corner half a note's size beyond its centre.\n * A larger number (a digit run of 309 or more even overflows to Infinity) is unreadable like\n * `1.2.3`, so its line stays in rawPassthrough.\n */\nconst LARGEST_DRAWABLE_NUMBER = 1e38;\n\nfunction isDrawable(value: number): boolean {\n return Math.abs(value) <= LARGEST_DRAWABLE_NUMBER;\n}\n\nfunction drawablePair(a: number, b: number): boolean {\n return isDrawable(a) && isDrawable(b);\n}\n\n/** Order stays raw (a, b). */\nexport function parseCoords(line: string): ParsedCoords | null {\n const m = COORDS_RE.exec(line);\n if (!m) return null;\n const a = Number(m[1]);\n const b = Number(m[2]);\n if (!drawablePair(a, b)) return null;\n return { a, b };\n}\n\n/**\n * Splits a line at the first `[a, b]` tuple: name before, suffix after.\n * Extras like `(color …)` may then only be looked up in the suffix — parentheses\n * inside the name stay untouched.\n */\nexport function splitAtCoords(\n line: string,\n): { name: string; coords: ParsedCoords; suffix: string } | null {\n const m = COORDS_RE.exec(line);\n if (!m) return null;\n const a = Number(m[1]);\n const b = Number(m[2]);\n if (!drawablePair(a, b)) return null;\n return {\n name: line.slice(0, m.index).trim(),\n coords: { a, b },\n suffix: line.slice(m.index + m[0].length),\n };\n}\n\n// `[^[\\]]` (tuples cannot contain '[') + bounded whitespace keep the scan linear (ReDoS-safe).\nconst MULTI_COORDS_RE = /\\[\\s{0,8}(\\[[^[\\]]*\\](?:\\s{0,8},\\s{0,8}\\[[^[\\]]*\\])+)\\s{0,8}\\]/;\n\n/** Extracts a tuple list `[[a,b],[c,d],…]` (freeform `line` drawing) — or null. */\nexport function parseMultiCoords(line: string): { tuples: ParsedCoords[]; rest: string } | null {\n const m = MULTI_COORDS_RE.exec(line);\n if (!m) return null;\n const tuples: ParsedCoords[] = [];\n const inner = /\\[\\s{0,8}([-\\d.]+)\\s{0,8},\\s{0,8}([-\\d.]+)\\s{0,8}\\]/g;\n let t: RegExpExecArray | null;\n while ((t = inner.exec(m[1]!))) {\n const a = Number(t[1]);\n const b = Number(t[2]);\n if (!drawablePair(a, b)) return null;\n tuples.push({ a, b });\n }\n if (!tuples.length) return null;\n return { tuples, rest: line.replace(MULTI_COORDS_RE, ' ') };\n}\n\n/**\n * Splits off a `//` line comment. Quote-aware (`'//weird'` inside quotes stays untouched) and\n * URL-aware: `//` directly after `:` is a scheme separator (`https://…`), not a comment.\n */\nexport function splitLineComment(line: string): { code: string; comment: string | null } {\n let inQuote = false;\n for (let i = 0; i < line.length - 1; i++) {\n const ch = line[i];\n if (ch === \"'\") inQuote = !inQuote;\n else if (!inQuote && ch === '/' && line[i + 1] === '/' && line[i - 1] !== ':') {\n return { code: line.slice(0, i), comment: line.slice(i) };\n }\n }\n return { code: line, comment: null };\n}\n\n/** First occurrence of `needle` outside `'…'` quotes — or -1. */\nexport function indexOfOutsideQuotes(line: string, needle: string): number {\n let inQuote = false;\n for (let i = 0; i + needle.length <= line.length; i++) {\n const ch = line[i];\n if (ch === \"'\") {\n inQuote = !inQuote;\n continue;\n }\n if (!inQuote && line.startsWith(needle, i)) return i;\n }\n return -1;\n}\n\n// Color override extension: `(color #rrggbb)` OR `(color green)`. Deliberately placed after\n// the coordinates so parentheses inside sticky names are never mistaken for it.\n// Accepts hex or CSS color names.\nconst COLOR_RE = /\\(\\s*color\\s+(#[0-9a-fA-F]{3,8}|[a-zA-Z][\\w-]*)\\s*\\)/i;\n\nexport function parseColor(line: string): { color?: string; rest: string } {\n const m = COLOR_RE.exec(line);\n if (!m || !m[1]) return { rest: line };\n return { color: m[1], rest: line.replace(COLOR_RE, ' ') };\n}\n\n// Attachment extension: `(on <Host Name>)` — canonically the LAST suffix. The host name runs\n// up to the line's FINAL ')', so names may themselves contain parentheses (`Payment (retry)`).\n// Extracted BEFORE the other suffixes so a `(color …)` or `(size …)` inside a host name is\n// never mistaken for one.\nconst ON_RE = /\\(\\s*on\\s+/i;\n\nexport function parseOn(line: string): { host?: string; rest: string } {\n const m = ON_RE.exec(line);\n if (!m) return { rest: line };\n const start = m.index + m[0].length;\n const close = line.lastIndexOf(')');\n if (close < start) return { rest: line };\n const host = line.slice(start, close).trim();\n if (!host) return { rest: line };\n return { host, rest: `${line.slice(0, m.index)} ${line.slice(close + 1)}` };\n}\n\n// Internal-id extension: `(id <id>)` — emitted on sticky lines only when the name alone would\n// be ambiguous. The charset is deliberately tight (letters/digits/underscore/hyphen) so an id\n// can never collide with the line grammar (`)`/whitespace/`#` are all illegal).\nexport const ID_CHARSET_RE = /^[A-Za-z0-9_-]+$/;\n\nconst ID_RE = /\\(\\s*id\\s+([A-Za-z0-9_-]+)\\s*\\)/i;\n\n// Any `(id …)` group — catches malformed variants so the caller can report a diagnostic.\nconst ID_PRESENT_RE = /\\(\\s*id\\b[^)]*\\)/i;\n\nexport function parseId(line: string): {\n id?: string;\n /** The matched `(id …)` text when present but unreadable (illegal charset). */\n invalid?: string;\n rest: string;\n} {\n const m = ID_RE.exec(line);\n if (m?.[1]) return { id: m[1], rest: line.replace(ID_RE, ' ') };\n const p = ID_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(ID_PRESENT_RE, ' ') };\n}\n\n// Resize extension: `(size <w>x<h>)` — canonically the last suffix before `(on …)` on note\n// lines. The serializer emits no spaces around the `x`; the parser tolerates optional whitespace.\n// Deliberately looked up only after the coordinates so `(size 1x1)` inside note text survives.\nconst SIZE_RE = /\\(\\s*size\\s+([\\d.]+)\\s*x\\s*([\\d.]+)\\s*\\)/i;\n\n// Any `(size …)` group — catches malformed variants so the caller can report a diagnostic.\nconst SIZE_PRESENT_RE = /\\(\\s*size\\b[^)]*\\)/i;\n\nexport function parseSize(line: string): {\n size?: { width: number; height: number };\n /** The matched `(size …)` text when present but unreadable (malformed or non-positive). */\n invalid?: string;\n rest: string;\n} {\n const m = SIZE_RE.exec(line);\n if (m) {\n const width = Number(m[1]);\n const height = Number(m[2]);\n // Non-positive, NaN (`1.2.3`) or beyond the canvas falls through to the malformed branch.\n if (width > 0 && height > 0 && isDrawable(width) && isDrawable(height)) {\n return { size: { width, height }, rest: line.replace(SIZE_RE, ' ') };\n }\n }\n const p = SIZE_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(SIZE_PRESENT_RE, ' ') };\n}\n\n// Alignment extension: `(align <horizontal> <vertical>)` — canonically between `(size …)` and\n// `(on …)` on note lines, both words always present. Values are matched case-insensitively and\n// canonicalized to lowercase. Deliberately looked up only after the coordinates so an\n// `(align center middle)` inside note text survives.\nconst ALIGN_RE = /\\(\\s*align\\s+(left|center|right)\\s+(top|middle|bottom)\\s*\\)/i;\n\n// Any `(align …)` group — catches malformed variants so the caller can report a diagnostic.\nconst ALIGN_PRESENT_RE = /\\(\\s*align\\b[^)]*\\)/i;\n\nexport function parseAlign(line: string): {\n align?: {\n horizontal: 'left' | 'center' | 'right';\n vertical: 'top' | 'middle' | 'bottom';\n };\n /** The matched `(align …)` text when present but unreadable (unknown/missing axis words). */\n invalid?: string;\n rest: string;\n} {\n const m = ALIGN_RE.exec(line);\n if (m) {\n return {\n align: {\n horizontal: m[1]!.toLowerCase() as 'left' | 'center' | 'right',\n vertical: m[2]!.toLowerCase() as 'top' | 'middle' | 'bottom',\n },\n rest: line.replace(ALIGN_RE, ' '),\n };\n }\n const p = ALIGN_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(ALIGN_PRESENT_RE, ' ') };\n}\n\n/** Undoes the serializer's `\\n` name escaping (line-based DSL, multi-line labels). */\nexport function decodeName(name: string): string {\n return name.replace(/\\\\n/g, '\\n');\n}\n\n/** First word (keyword) of a line, lowercased. */\nexport function keywordOf(line: string): string {\n const m = /^\\s*([A-Za-z][\\w-]*)/.exec(line);\n return m ? m[1]!.toLowerCase() : '';\n}\n\nexport function slug(label: string): string {\n return (\n label\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_/, '')\n .replace(/_$/, '') || 'x'\n );\n}\n","import type { ElementType } from '@miragon/event-storming-schema-model';\nimport { slug } from './lexer.js';\n\n/** Sticky keywords double as `elementType` values; the value is the ID prefix. */\nexport const STICKY_ID_PREFIXES: Readonly<Partial<Record<ElementType, string>>> = {\n event: 'event',\n command: 'cmd',\n actor: 'actor',\n aggregate: 'agg',\n policy: 'policy',\n readmodel: 'read',\n external: 'ext',\n hotspot: 'hot',\n};\n\n// Board ids become diagram-js element ids, and the renderer's root elements live in the same\n// registry: an element claiming one of these would make the import throw halfway through.\nconst ENGINE_ID_RE = /^(?:event-storming-root$|__implicitroot)/;\n\nexport function isEngineId(id: string): boolean {\n return ENGINE_ID_RE.test(id);\n}\n\n/**\n * The parser's id allocation, shared with the serializer: the serializer replays it in emit order\n * to decide which ids the text has to carry so that every sticky gets its id back on re-import.\n */\nexport class IdAllocator {\n private readonly used = new Set<string>();\n\n /** Explicit `(id …)` — false when the id is taken or reserved (caller reports + allocates). */\n claim(id: string): boolean {\n if (this.used.has(id) || isEngineId(id)) return false;\n this.used.add(id);\n return true;\n }\n\n /** The id `alloc(prefix, label)` would return, without taking it. */\n peek(prefix: string, label: string): string {\n const base = `${prefix}_${slug(label)}`;\n let id = base;\n let i = 2;\n while (this.used.has(id)) id = `${base}_${i++}`;\n return id;\n }\n\n alloc(prefix: string, label: string): string {\n const id = this.peek(prefix, label);\n this.used.add(id);\n return id;\n }\n}\n","import {\n ATTACHABLE_STICKY_KINDS,\n CURRENT_SCHEMA_VERSION,\n HOST_STICKY_KINDS,\n validateBoard,\n type BoardConfig,\n type BoardEdge,\n type BoardLevel,\n type BoardElement,\n type Coordinate,\n type DrawingElement,\n type DrawingStrokeStyle,\n type ElementType,\n type EventStormingBoard,\n type NoteAlign,\n type NoteAlignHorizontal,\n type NoteAlignVertical,\n type NoteElement,\n} from '@miragon/event-storming-schema-model';\nimport {\n indexOfOutsideQuotes,\n keywordOf,\n parseAlign,\n parseColor,\n parseCoords,\n parseId,\n parseMultiCoords,\n parseOn,\n parseSize,\n splitAtCoords,\n splitLineComment,\n decodeName,\n} from './lexer.js';\nimport { IdAllocator, STICKY_ID_PREFIXES, isEngineId } from './ids.js';\n\n/** Splits `A -> B` at the FIRST arrow — plain indexOf, immune to regex backtracking. */\nfunction splitArrow(core: string): { left: string; right: string } | null {\n const arrow = core.indexOf('->');\n if (arrow <= 0) return null;\n const left = core.slice(0, arrow).trim();\n const right = core.slice(arrow + 2).trim();\n return left && right ? { left, right } : null;\n}\n\nconst KNOWN_STYLES: ReadonlySet<string> = new Set(['classic', 'dark']);\n\nconst ATTACHABLE_KINDS: ReadonlySet<string> = new Set(ATTACHABLE_STICKY_KINDS);\n\nconst HOST_KINDS: ReadonlySet<string> = new Set(HOST_STICKY_KINDS);\n\nconst KNOWN_LEVELS: ReadonlySet<string> = new Set(['big-picture', 'process', 'design']);\n\n// The 8 sticky kinds — the only legal arrow endpoints (mirrors validateBoard's contract).\nconst STICKY_KINDS: ReadonlySet<string> = new Set(Object.keys(STICKY_ID_PREFIXES));\n\ninterface PendingArrow {\n readonly left: string;\n readonly right: string;\n /** Annotation text after `;`. */\n readonly label?: string;\n readonly raw: string;\n readonly lineNo: number;\n}\n\n/** `(on …)` attachment — host referenced BY NAME, resolution deferred like arrow endpoints. */\ninterface PendingAttachment {\n /** Index into `elements` of the attachable sticky. */\n readonly index: number;\n readonly host: string;\n readonly raw: string;\n readonly lineNo: number;\n}\n\nfunction compact<T extends Record<string, unknown>>(obj: T): T {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) if (v !== undefined) out[k] = v;\n return out as T;\n}\n\n/**\n * Text `(align <h> <v>)` pair -> model value: default axes (left/top) are dropped, both-default\n * collapses to absent — `(align left top)` and no suffix are the same board (the serializer\n * emits the suffix only when an axis differs from the default).\n */\nfunction modelAlign(\n align: { horizontal: NoteAlignHorizontal; vertical: NoteAlignVertical } | undefined,\n): NoteAlign | undefined {\n if (!align) return undefined;\n const out = compact({\n horizontal: align.horizontal === 'left' ? undefined : align.horizontal,\n vertical: align.vertical === 'top' ? undefined : align.vertical,\n }) as NoteAlign;\n return Object.keys(out).length ? out : undefined;\n}\n\n/** Finding produced while parsing — line is 1-based; `text` is the (comment-stripped) line. */\nexport interface ParseDiagnostic {\n readonly line: number;\n readonly message: string;\n readonly text: string;\n}\n\nexport interface ParseResult {\n readonly board: EventStormingBoard;\n readonly diagnostics: readonly ParseDiagnostic[];\n}\n\n/**\n * Line-based keyword parsing; coordinates are `[x, y]` in board pixels (x FIRST), unbounded,\n * optional (default `[0, 0]`). Unknown lines land in `rawPassthrough`.\n */\nexport function parseDSL(text: string): EventStormingBoard {\n return parseDSLWithDiagnostics(text).board;\n}\n\n/**\n * Like `parseDSL`, but additionally returns findings with line numbers (uninterpretable lines,\n * unresolved references) — for editor feedback instead of silent loss.\n */\nexport function parseDSLWithDiagnostics(text: string): ParseResult {\n const diagnostics: ParseDiagnostic[] = [];\n const ids = new IdAllocator();\n const nameToId = new Map<string, string>();\n const elements: BoardElement[] = [];\n const rawPassthrough: string[] = [];\n const pendingArrows: PendingArrow[] = [];\n const pendingAttachments: PendingAttachment[] = [];\n\n let config: BoardConfig = { title: 'Untitled Board' };\n let inBlockComment = false;\n\n const register = (name: string, id: string) => {\n if (!nameToId.has(name)) nameToId.set(name, id);\n };\n\n // Diagnostics helpers: read the current line/number from the loop state.\n let lineNo = 0;\n let currentLine = '';\n\n /** Tries to capture a line as an arrow. Returns true when consumed. */\n const pushArrow = (line: string): boolean => {\n // Split off an optional arrow annotation after ';' (e.g. `A -> B; async`).\n const semi = line.indexOf(';');\n const core = semi >= 0 ? line.slice(0, semi).trim() : line;\n const arrowLabel = semi >= 0 ? line.slice(semi + 1).trim() : '';\n const arrow = splitArrow(core);\n if (!arrow) return false;\n pendingArrows.push({\n left: arrow.left,\n right: arrow.right,\n ...(arrowLabel ? { label: arrowLabel } : {}),\n raw: line,\n lineNo,\n });\n return true;\n };\n const diag = (message: string, atLine = lineNo, text_ = currentLine) =>\n diagnostics.push({ line: atLine, message, text: text_ });\n /** Passthrough for a line that looks like a known construct but cannot be parsed. */\n const failed = (l: string) => {\n rawPassthrough.push(l);\n diag(\"Couldn't read this line. It stays in the file unchanged.\");\n };\n /** Board pixels, unbounded — no clamping on the free canvas. */\n const pos = (x: number, y: number): Coordinate => ({ x, y });\n\n const sourceLines = text.split(/\\r?\\n/);\n for (let i = 0; i < sourceLines.length; i++) {\n const raw = sourceLines[i]!;\n // The empty piece after a final newline is no line: inside an open block comment it would be\n // kept as one, and every save would append another blank line.\n if (raw === '' && i === sourceLines.length - 1) continue;\n lineNo = i + 1;\n currentLine = raw.trim();\n let working = raw;\n\n // --- Comments (`//`, `/* */`): strip, but keep losslessly in rawPassthrough. ---\n if (inBlockComment) {\n const close = working.indexOf('*/');\n if (close < 0) {\n rawPassthrough.push(raw);\n continue;\n }\n rawPassthrough.push(working.slice(0, close + 2));\n working = working.slice(close + 2);\n inBlockComment = false;\n }\n let open = indexOfOutsideQuotes(working, '/*');\n while (open >= 0) {\n const close = working.indexOf('*/', open + 2);\n if (close < 0) {\n rawPassthrough.push(working.slice(open));\n working = working.slice(0, open);\n inBlockComment = true;\n break;\n }\n rawPassthrough.push(working.slice(open, close + 2));\n working = `${working.slice(0, open)} ${working.slice(close + 2)}`;\n open = indexOfOutsideQuotes(working, '/*');\n }\n const { code, comment } = splitLineComment(working);\n if (comment !== null) rawPassthrough.push(comment);\n working = code;\n\n const line = working.trim();\n if (!line) continue;\n\n const kw = keywordOf(line);\n const after = line.slice(kw.length).trim();\n\n // Arrows FIRST: sticky NAMES may begin with a keyword word (the default command is\n // named \"Command\" -> arrow `Command -> X`). Declarations carry coordinates `[...]`,\n // arrows never do — but only the part BEFORE the `;` annotation counts, the annotation\n // is free text and may contain a tuple. Without this pre-detection `Command -> X` would\n // be misread as a (broken) `command` declaration and vanish on re-import. `title` is\n // exempt (its content may itself use `->`) UNLESS the left side is an already-declared\n // sticky name (e.g. one named \"Title Page\" — declarations always precede arrows in\n // serialized DSL). `style`/`level`/`line` need no exemption: style and level values are\n // single words and drawings always carry coordinate tuples.\n const semi = line.indexOf(';');\n const beforeAnnotation = semi >= 0 ? line.slice(0, semi) : line;\n const titleAsArrow = (): boolean => {\n const arrow = splitArrow(beforeAnnotation.trim());\n return arrow !== null && nameToId.has(decodeName(arrow.left));\n };\n if ((kw !== 'title' || titleAsArrow()) && !parseCoords(beforeAnnotation) && pushArrow(line)) {\n continue;\n }\n\n switch (kw) {\n case 'title':\n config = { ...config, title: after };\n break;\n\n case 'style': {\n const s = after.toLowerCase();\n if (KNOWN_STYLES.has(s)) config = { ...config, style: s as 'classic' | 'dark' };\n else failed(line);\n break;\n }\n\n case 'level': {\n const l = after.toLowerCase();\n if (KNOWN_LEVELS.has(l)) config = { ...config, level: l as BoardLevel };\n else failed(line);\n break;\n }\n\n case 'event':\n case 'command':\n case 'actor':\n case 'aggregate':\n case 'policy':\n case 'readmodel':\n case 'external':\n case 'hotspot': {\n const node = parseSticky(after);\n if (!node) {\n failed(line);\n break;\n }\n if (node.idInvalid) {\n diag(\n `Couldn't read the id “${node.idInvalid.trim()}”. An id has letters, digits, “_” or “-”, as in (id order_1).`,\n );\n }\n const explicit = node.id !== undefined && ids.claim(node.id) ? node.id : undefined;\n if (node.id !== undefined && explicit === undefined) {\n diag(\n isEngineId(node.id)\n ? `The id “${node.id}” belongs to the board itself, so this sticky got a new id.`\n : `The id “${node.id}” is already taken, so this sticky got a new id.`,\n );\n }\n const id = explicit ?? ids.alloc(STICKY_ID_PREFIXES[kw as ElementType]!, node.name);\n elements.push(\n compact({\n id,\n elementType: kw as ElementType,\n label: node.name,\n position: pos(node.coords.x, node.coords.y),\n color: node.color,\n }) as BoardElement,\n );\n register(node.name, id);\n if (node.host !== undefined) {\n if (ATTACHABLE_KINDS.has(kw)) {\n pendingAttachments.push({\n index: elements.length - 1,\n host: node.host,\n raw: line,\n lineNo,\n });\n } else {\n diag(`A ${kw} can't be pinned. Only an actor, a hotspot or a note takes (on …).`);\n }\n }\n if (node.sizeSuffix) {\n diag(`A ${kw} can't be resized. Only a note takes (size …).`);\n }\n if (node.alignSuffix) {\n diag(`A ${kw} can't be aligned. Only a note takes (align …).`);\n }\n break;\n }\n\n case 'note': {\n const split = splitAtCoords(after);\n if (!split && after.includes('[')) {\n failed(line);\n break;\n }\n // Suffixes ONLY after the coordinates (mirrors parseSticky) — notes are free text, so\n // `(on …)`, `(color …)` or `(size 1x1)` may legitimately appear inside it. `(on …)` is\n // stripped FIRST: it is always the last suffix and its host name runs to the final `)`,\n // so it may itself contain a `(color …)`, `(size …)` or `(align …)`.\n const on = parseOn(split ? split.suffix : after);\n const al = parseAlign(on.rest);\n const sz = parseSize(al.rest);\n const idp = parseId(sz.rest);\n const col = parseColor(idp.rest);\n if (al.invalid) {\n diag(\n `Couldn't read the alignment “${al.invalid.trim()}”. Write (align left|center|right top|middle|bottom).`,\n );\n }\n if (sz.invalid) {\n diag(\n `Couldn't read the size “${sz.invalid.trim()}”. Write (size <w>x<h>) with positive numbers.`,\n );\n }\n if (idp.id !== undefined || idp.invalid) {\n diag(\"A note can't have an id. Only a sticky takes (id …).\");\n }\n // Literal `\\n` back into real line breaks (multi-line notes).\n const textPart = decodeName((split ? split.name : col.rest).trim());\n const id = ids.alloc('note', textPart || 'note');\n const note: NoteElement = compact({\n id,\n elementType: 'note',\n label: textPart,\n position: split ? pos(split.coords.a, split.coords.b) : pos(0, 0),\n color: col.color,\n size: sz.size,\n align: modelAlign(al.align),\n }) as NoteElement;\n elements.push(note);\n if (on.host !== undefined) {\n pendingAttachments.push({ index: elements.length - 1, host: on.host, raw: line, lineNo });\n }\n break;\n }\n\n case 'line': {\n // Project extension (freeform drawing): `line [[x,y], [x,y], …] (closed) (dashed) (color x)`.\n const col = parseColor(after);\n const multi = parseMultiCoords(col.rest);\n if (!multi || multi.tuples.length < 2) {\n failed(line);\n break;\n }\n const onDrawing = parseOn(multi.rest);\n if (onDrawing.host !== undefined) {\n diag(\"A drawing can't be pinned. Only an actor, a hotspot or a note takes (on …).\");\n }\n const szDrawing = parseSize(onDrawing.rest);\n if (szDrawing.size || szDrawing.invalid) {\n diag(\"A drawing can't be resized. Only a note takes (size …).\");\n }\n const alDrawing = parseAlign(onDrawing.rest);\n if (alDrawing.align || alDrawing.invalid) {\n diag(\"A drawing can't be aligned. Only a note takes (align …).\");\n }\n const idDrawing = parseId(onDrawing.rest);\n if (idDrawing.id !== undefined || idDrawing.invalid) {\n diag(\"A drawing can't have an id. Only a sticky takes (id …).\");\n }\n const flags = onDrawing.rest.toLowerCase();\n const strokeStyle: DrawingStrokeStyle | undefined = flags.includes('(dashed)')\n ? 'dashed'\n : flags.includes('(dotted)')\n ? 'dotted'\n : undefined;\n const points = multi.tuples.map((t) => pos(t.a, t.b));\n const drawing: DrawingElement = {\n id: ids.alloc('draw', 'line'),\n elementType: 'drawing',\n label: '',\n position: points[0]!,\n points,\n ...(flags.includes('(closed)') ? { closed: true } : {}),\n ...(strokeStyle ? { strokeStyle } : {}),\n ...(col.color ? { color: col.color } : {}),\n };\n elements.push(drawing);\n break;\n }\n\n default: {\n // Unknown keyword: try as an arrow (e.g. `A -> B; async`), otherwise keep raw.\n if (!pushArrow(line)) rawPassthrough.push(line);\n }\n }\n }\n\n // Reference resolution for arrow endpoints and `(on …)` hosts: a `#`-prefixed token is an id\n // reference (ids exist for EVERY element, not only those declared with `(id …)`); anything\n // else stays a label lookup. No fallback across the two — `#` always means id.\n const resolve = (token: string): BoardElement | undefined => {\n if (token.startsWith('#')) {\n const id = token.slice(1);\n return elements.find((e) => e.id === id);\n }\n const id = nameToId.get(decodeName(token));\n return id !== undefined ? elements.find((e) => e.id === id) : undefined;\n };\n\n // Deferred like arrows so a host may be declared after its attacher. On failure the sticky\n // stays WITHOUT attachedTo (it was already created above) — no rawPassthrough, the line is\n // otherwise fully represented.\n for (const att of pendingAttachments) {\n const host = resolve(att.host);\n if (!host) {\n diag(`There's no “${att.host}” on the board to pin this to.`, att.lineNo, att.raw);\n continue;\n }\n if (!HOST_KINDS.has(host.elementType)) {\n diag(\n `“${att.host}” is a ${host.elementType}. An actor, a hotspot or a note is pinned to an event, a command, an aggregate, a policy, a read model or an external system.`,\n att.lineNo,\n att.raw,\n );\n continue;\n }\n elements[att.index] = { ...elements[att.index]!, attachedTo: host.id } as BoardElement;\n }\n\n let arrowN = 0;\n // An explicit `(id arrow_N)` on a sticky may occupy an arrow-id slot — skip it (diagram-js\n // has ONE id namespace for shapes and connections; validateBoard rejects the collision).\n const elementIds = new Set(elements.map((e) => e.id));\n const nextArrowId = (): string => {\n let id = `arrow_${++arrowN}`;\n while (elementIds.has(id)) id = `arrow_${++arrowN}`;\n return id;\n };\n const edges: BoardEdge[] = [];\n for (const arrow of pendingArrows) {\n const from = resolve(arrow.left);\n const to = resolve(arrow.right);\n if (!from || !to) {\n rawPassthrough.push(arrow.raw);\n diag(\n !from\n ? `This arrow starts at “${arrow.left}”, which isn't on the board.`\n : `This arrow points to “${arrow.right}”, which isn't on the board.`,\n arrow.lineNo,\n arrow.raw,\n );\n continue;\n }\n // Only reachable via `#id` refs (labels are registered for sticky kinds only) — an edge to\n // a note/drawing would make validateBoard throw, so it is dropped losslessly instead.\n const nonSticky = !STICKY_KINDS.has(from.elementType)\n ? ([arrow.left, from] as const)\n : !STICKY_KINDS.has(to.elementType)\n ? ([arrow.right, to] as const)\n : undefined;\n if (nonSticky) {\n rawPassthrough.push(arrow.raw);\n diag(\n `“${nonSticky[0]}” is a ${nonSticky[1].elementType}, and an arrow only connects stickies.`,\n arrow.lineNo,\n arrow.raw,\n );\n continue;\n }\n edges.push(\n compact({\n id: nextArrowId(),\n edgeType: 'arrow',\n from: from.id,\n to: to.id,\n label: arrow.label,\n }) as BoardEdge,\n );\n }\n\n const board = compact({\n schemaVersion: CURRENT_SCHEMA_VERSION,\n config,\n elements,\n edges,\n rawPassthrough: rawPassthrough.length ? rawPassthrough : undefined,\n }) as EventStormingBoard;\n\n return { board: validateBoard(board), diagnostics };\n}\n\ninterface ParsedSticky {\n readonly name: string;\n readonly coords: { x: number; y: number };\n /** Color override `(color …)` — supported on every element line. */\n readonly color?: string;\n /** Attachment `(on <Host Name>)` — host name still undecoded, resolved by the caller. */\n readonly host?: string;\n /** Explicit `(id …)` — the caller claims it (duplicate ⇒ diagnostic + fresh id). */\n readonly id?: string;\n /** The matched `(id …)` text when present but unreadable (illegal charset). */\n readonly idInvalid?: string;\n /** A `(size …)` suffix appeared — only notes support it, the caller reports a diagnostic. */\n readonly sizeSuffix?: boolean;\n /** An `(align …)` suffix appeared — only notes support it, the caller reports a diagnostic. */\n readonly alignSuffix?: boolean;\n}\n\n/**\n * Parses `<name> [x, y] [(color …)] [(id …)] [(on …)]`. The suffixes are looked up ONLY AFTER\n * the coordinates — parentheses inside the name stay untouched. `(on …)` is extracted first\n * (its host name runs to the final `)` and may itself contain a `(color …)`, `(id …)` or\n * `(size …)`). Coordinates are optional and default to `[0, 0]`; a malformed tuple (bracket\n * present but unreadable) is rejected so the caller can report a diagnostic instead of\n * swallowing it into the name.\n */\nfunction parseSticky(after: string): ParsedSticky | null {\n const split = splitAtCoords(after);\n if (split) {\n if (!split.name) return null;\n const on = parseOn(split.suffix);\n const idp = parseId(on.rest);\n const al = parseAlign(idp.rest);\n const sz = parseSize(al.rest);\n const col = parseColor(sz.rest);\n return compact({\n name: decodeName(split.name),\n coords: { x: split.coords.a, y: split.coords.b },\n color: col.color ?? undefined,\n host: on.host,\n id: idp.id,\n idInvalid: idp.invalid,\n sizeSuffix: sz.size || sz.invalid ? true : undefined,\n alignSuffix: al.align || al.invalid ? true : undefined,\n }) as ParsedSticky;\n }\n if (after.includes('[')) return null;\n const on = parseOn(after);\n const idp = parseId(on.rest);\n const al = parseAlign(idp.rest);\n const sz = parseSize(al.rest);\n const col = parseColor(sz.rest);\n const name = col.rest.trim();\n if (!name) return null;\n return compact({\n name: decodeName(name),\n coords: { x: 0, y: 0 },\n color: col.color ?? undefined,\n host: on.host,\n id: idp.id,\n idInvalid: idp.invalid,\n sizeSuffix: sz.size || sz.invalid ? true : undefined,\n alignSuffix: al.align || al.invalid ? true : undefined,\n }) as ParsedSticky;\n}\n","import type {\n BoardElement,\n EventStormingBoard,\n NoteElement,\n} from '@miragon/event-storming-schema-model';\nimport { IdAllocator, STICKY_ID_PREFIXES } from './ids.js';\nimport { ID_CHARSET_RE, decodeName, slug } from './lexer.js';\n\n/**\n * Coordinate formatter: 3-decimal rounding, NEVER exponent notation — `String(1e21)` yields\n * `\"1e+21\"`, which the coordinate regex cannot read back. Magnitudes >= 1e21 are always\n * integer-valued doubles, so BigInt expands them losslessly (the rounding step is skipped\n * there; it would be a no-op and could overflow to Infinity for huge values).\n */\nfunction r(n: number): string {\n const v = Math.abs(n) < 1e21 ? Math.round(n * 1000) / 1000 : n;\n return Math.abs(v) < 1e21 ? String(v) : BigInt(v).toString();\n}\n\n/**\n * Free text emitted into the line-based grammar: real line breaks become the literal `\\n`\n * escape (decoded on parse) and comment starters are defused with the Unicode division slash\n * — otherwise the parser would split the line or strip the rest as a comment. `//` directly\n * after `:` stays untouched (URL scheme separator, the comment splitter is URL-aware).\n */\nfunction escapeText(label: string): string {\n return label\n .trim()\n .replace(/\\n/g, '\\\\n')\n .replace(/(?<!:)\\/\\//g, '∕∕')\n .replace(/\\/\\*/g, '∕*');\n}\n\n/** Names are additionally arrow-safe: a literal `->` inside a name would break `A -> B` lines. */\nfunction escapeName(label: string): string {\n return escapeText(label).replace(/->/g, '→');\n}\n\n/** Types referenced BY THEIR NAME in the DSL (arrow endpoints + namespace) — all sticky kinds. */\nconst NAMED_TYPES: ReadonlySet<string> = new Set([\n 'event',\n 'command',\n 'actor',\n 'aggregate',\n 'policy',\n 'readmodel',\n 'external',\n 'hotspot',\n]);\n\nconst DEFAULT_NAMES: Readonly<Record<string, string>> = {\n event: 'Domain Event',\n command: 'Command',\n actor: 'Actor',\n aggregate: 'Aggregate',\n policy: 'Policy',\n readmodel: 'Read Model',\n external: 'External System',\n hotspot: 'Hotspot',\n};\n\nfunction defaultName(type: string): string {\n return DEFAULT_NAMES[type] ?? 'Sticky';\n}\n\n/**\n * Returns the DSL name per element ID for the referenceable types (the sticky kinds): the\n * escaped label, or the per-kind default for an empty one. Duplicate labels are legal — an\n * ambiguous name is disambiguated via an `(id …)` suffix plus `#id` references instead of\n * being silently renamed.\n */\nfunction serializedNames(board: EventStormingBoard): Map<string, string> {\n const byId = new Map<string, string>();\n for (const el of board.elements) {\n if (!NAMED_TYPES.has(el.elementType)) continue;\n byId.set(el.id, escapeName(el.label) || defaultName(el.elementType));\n }\n return byId;\n}\n\n/** Color override extension: `(color …)` after the coordinates. */\nfunction colorSuffix(el: { color?: string }): string {\n return el.color ? ` (color ${el.color})` : '';\n}\n\n/**\n * Alignment extension: `(align <horizontal> <vertical>)` — both words always emitted together\n * using the EFFECTIVE values, and only when at least one axis differs from the default\n * left/top, so existing boards serialize byte-identically.\n */\nfunction alignSuffix(el: NoteElement): string {\n const horizontal = el.align?.horizontal ?? 'left';\n const vertical = el.align?.vertical ?? 'top';\n return horizontal === 'left' && vertical === 'top' ? '' : ` (align ${horizontal} ${vertical})`;\n}\n\n/**\n * Serializes an EventStormingBoard into `.storm` text. Deterministic; writes only syntax the\n * parser reads back. `rawPassthrough` is appended unchanged. Coordinates are `[x, y]` in board\n * pixels (x FIRST), rounded to 3 decimals.\n */\nexport function serializeDSL(board: EventStormingBoard): string {\n const lines: string[] = [];\n const names = serializedNames(board);\n const nameOf = (el: BoardElement): string => names.get(el.id) ?? el.label;\n\n // A `#…` token in a reference position always reads as an id — so a sticky whose serialized\n // name is AMBIGUOUS (shared by >= 2 stickies) or literally starts with `#` is referenced as\n // `#id`. Everything else stays purely name-based, so unambiguous boards serialize without any\n // ids, byte-identical to before.\n const nameCount = new Map<string, number>();\n for (const name of names.values()) nameCount.set(name, (nameCount.get(name) ?? 0) + 1);\n const referencedById = (id: string): boolean => {\n const name = names.get(id);\n return name !== undefined && (nameCount.get(name)! > 1 || name.startsWith('#'));\n };\n\n // Ids surface in the text only via the `(id …)` suffix. An id outside the DSL id charset\n // (possible in JSON-authored boards) would emit unparsable syntax and lose the arrows on\n // re-import — a slug-based, collision-checked stand-in is substituted for the suffix AND every\n // reference.\n const emitIds = new Map<string, string>();\n const taken = new Set(board.elements.map((e) => e.id));\n for (const el of board.elements) {\n if (!referencedById(el.id) || ID_CHARSET_RE.test(el.id)) continue;\n let candidate = slug(el.id);\n for (let i = 2; taken.has(candidate); i++) candidate = `${slug(el.id)}_${i}`;\n taken.add(candidate);\n emitIds.set(el.id, candidate);\n }\n const idOf = (id: string): string => emitIds.get(id) ?? id;\n const declaredIds = idsToDeclare(board, nameOf, referencedById, idOf);\n const ref = (id: string): string => (referencedById(id) ? `#${idOf(id)}` : (names.get(id) ?? id));\n\n lines.push(`title ${board.config.title}`);\n if (board.config.style) lines.push(`style ${board.config.style}`);\n if (board.config.level) lines.push(`level ${board.config.level}`);\n\n // Pinning `(on …)` is ALWAYS the last suffix — the parser reads the host name up to the\n // line's final `)`, so host names containing parentheses survive. validateBoard guarantees\n // the host is a named sticky kind; `ref` falls back to the raw id purely defensively.\n const onSuffix = (el: BoardElement): string => {\n const hostId =\n el.elementType === 'actor' || el.elementType === 'hotspot' || el.elementType === 'note'\n ? el.attachedTo\n : undefined;\n return hostId ? ` (on ${ref(hostId)})` : '';\n };\n\n for (const el of board.elements) {\n const idSuffix = declaredIds.has(el.id) ? ` (id ${idOf(el.id)})` : '';\n lines.push(elementLine(el, nameOf(el), idSuffix, onSuffix(el)));\n }\n\n // validateBoard guarantees arrow endpoints are sticky kinds, so the name map always covers\n // them — `ref`'s raw-id fallback is purely defensive for unvalidated input.\n for (const edge of board.edges) {\n const annotation = edge.label ? `; ${edge.label}` : '';\n lines.push(`${ref(edge.from)} -> ${ref(edge.to)}${annotation}`);\n }\n\n // Config keywords were already emitted from the board above. A rawPassthrough entry with the\n // same keyword (e.g. an unparsable `style` line from externally-authored DSL) would otherwise\n // produce a contradictory duplicate line — drop it (config is the truth).\n if (board.rawPassthrough) {\n const emitted = new Set<string>(['title']);\n if (board.config.style) emitted.add('style');\n if (board.config.level) emitted.add('level');\n for (const raw of board.rawPassthrough) {\n if (emitted.has(raw.trim().split(/\\s+/)[0]!)) continue;\n lines.push(raw);\n }\n }\n\n return lines.join('\\n') + '\\n';\n}\n\n/**\n * The stickies whose line carries `(id …)`: those referenced as `#id`, plus every sticky whose id\n * the parser would not allocate again at its line — one created on the canvas (`event_3`),\n * renamed after its id was derived from the old label, or declared with an explicit id. Hosts\n * anchor todos, presence and deep links to these ids, so they must survive a save and re-open.\n * Replays the parser's allocation in emit order; an id equal to the allocated one stays implicit,\n * which keeps boards authored without ids byte-identical.\n */\nfunction idsToDeclare(\n board: EventStormingBoard,\n nameOf: (el: BoardElement) => string,\n referencedById: (id: string) => boolean,\n emittedId: (id: string) => string,\n): Set<string> {\n const allocator = new IdAllocator();\n const declared = new Set<string>();\n for (const el of board.elements) {\n const prefix = STICKY_ID_PREFIXES[el.elementType];\n if (prefix === undefined) {\n allocator.alloc(el.elementType === 'note' ? 'note' : 'draw', noteOrDrawingName(el));\n continue;\n }\n const parsedName = decodeName(nameOf(el));\n const declare =\n referencedById(el.id) ||\n (ID_CHARSET_RE.test(el.id) && allocator.peek(prefix, parsedName) !== el.id);\n if (declare) {\n declared.add(el.id);\n allocator.claim(emittedId(el.id));\n } else {\n allocator.alloc(prefix, parsedName);\n }\n }\n return declared;\n}\n\n/** The label the parser allocates a note's or a drawing's id from. */\nfunction noteOrDrawingName(el: BoardElement): string {\n if (el.elementType === 'drawing') return 'line';\n return decodeName(escapeText(el.label)) || 'note';\n}\n\nfunction elementLine(el: BoardElement, name: string, idSuffix: string, attach: string): string {\n const p = el.position;\n switch (el.elementType) {\n case 'event':\n case 'command':\n case 'actor':\n case 'aggregate':\n case 'policy':\n case 'readmodel':\n case 'external':\n case 'hotspot':\n // Canonical suffix order: `(color …) (id …) (on …)` — `(on …)` stays last (see above).\n return `${el.elementType} ${name} [${r(p.x)}, ${r(p.y)}]${colorSuffix(el)}${idSuffix}${attach}`;\n case 'note': {\n // Escape line breaks/comment starters -> the line-based DSL stays single-line. `->` is\n // fine in note text (notes are never arrow endpoints), so no `→` replacement here.\n // Canonical note suffix order: `(color …) (size WxH) (align h v) (on …)` — `(on …)`\n // stays last (final-paren rule, see above); size/align/attachment are only present when\n // set, so plain boards stay byte-identical.\n const size = el.size ? ` (size ${r(el.size.width)}x${r(el.size.height)})` : '';\n return `note ${escapeText(name)} [${r(p.x)}, ${r(p.y)}]${colorSuffix(el)}${size}${alignSuffix(el)}${attach}`;\n }\n case 'drawing': {\n // Project extension (freeform drawing): tuple list + style flags.\n const pts = el.points.map((q) => `[${r(q.x)}, ${r(q.y)}]`).join(', ');\n const closed = el.closed ? ' (closed)' : '';\n const stroke = el.strokeStyle && el.strokeStyle !== 'solid' ? ` (${el.strokeStyle})` : '';\n return `line [${pts}]${closed}${stroke}${colorSuffix(el)}`;\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/lexer.ts","../src/ids.ts","../src/parser.ts","../src/serializer.ts"],"names":["id","on","idp","al","sz","col"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Small, line-oriented helpers for the Event Storming `.storm` DSL.\n * The DSL is line-based; a full tokenizer/generator is not needed.\n */\n\nimport { LARGEST_DRAWABLE_NUMBER } from \"@miragon/event-storming-schema-model\";\n\nexport interface ParsedCoords {\n readonly a: number;\n readonly b: number;\n}\n\nconst COORDS_RE = /\\[\\s*([-\\d.]+)\\s*,\\s*([-\\d.]+)\\s*\\]/;\n\n/**\n * A number beyond the canvas's range (a digit run of 309 or more even overflows to Infinity) is\n * unreadable like `1.2.3`, so its line stays in rawPassthrough; JSON boards share the bound.\n */\nfunction isDrawable(value: number): boolean {\n return Math.abs(value) <= LARGEST_DRAWABLE_NUMBER;\n}\n\nfunction drawablePair(a: number, b: number): boolean {\n return isDrawable(a) && isDrawable(b);\n}\n\n/** Order stays raw (a, b). */\nexport function parseCoords(line: string): ParsedCoords | null {\n const m = COORDS_RE.exec(line);\n if (!m) return null;\n const a = Number(m[1]);\n const b = Number(m[2]);\n if (!drawablePair(a, b)) return null;\n return { a, b };\n}\n\n/**\n * Splits a line at the first `[a, b]` tuple: name before, suffix after.\n * Extras like `(color …)` may then only be looked up in the suffix — parentheses\n * inside the name stay untouched.\n */\nexport function splitAtCoords(\n line: string,\n): { name: string; coords: ParsedCoords; suffix: string } | null {\n const m = COORDS_RE.exec(line);\n if (!m) return null;\n const a = Number(m[1]);\n const b = Number(m[2]);\n if (!drawablePair(a, b)) return null;\n return {\n name: line.slice(0, m.index).trim(),\n coords: { a, b },\n suffix: line.slice(m.index + m[0].length),\n };\n}\n\n// `[^[\\]]` (tuples cannot contain '[') + bounded whitespace keep the scan linear (ReDoS-safe).\nconst MULTI_COORDS_RE = /\\[\\s{0,8}(\\[[^[\\]]*\\](?:\\s{0,8},\\s{0,8}\\[[^[\\]]*\\])+)\\s{0,8}\\]/;\n\n/** Extracts a tuple list `[[a,b],[c,d],…]` (freeform `line` drawing) — or null. */\nexport function parseMultiCoords(line: string): { tuples: ParsedCoords[]; rest: string } | null {\n const m = MULTI_COORDS_RE.exec(line);\n if (!m) return null;\n const tuples: ParsedCoords[] = [];\n const inner = /\\[\\s{0,8}([-\\d.]+)\\s{0,8},\\s{0,8}([-\\d.]+)\\s{0,8}\\]/g;\n let t: RegExpExecArray | null;\n while ((t = inner.exec(m[1]!))) {\n const a = Number(t[1]);\n const b = Number(t[2]);\n if (!drawablePair(a, b)) return null;\n tuples.push({ a, b });\n }\n if (!tuples.length) return null;\n return { tuples, rest: line.replace(MULTI_COORDS_RE, \" \") };\n}\n\n/**\n * Splits off a `//` line comment. Quote-aware (`'//weird'` inside quotes stays untouched) and\n * URL-aware: `//` directly after `:` is a scheme separator (`https://…`), not a comment.\n */\nexport function splitLineComment(line: string): { code: string; comment: string | null } {\n let inQuote = false;\n for (let i = 0; i < line.length - 1; i++) {\n const ch = line[i];\n if (ch === \"'\") inQuote = !inQuote;\n else if (!inQuote && ch === \"/\" && line[i + 1] === \"/\" && line[i - 1] !== \":\") {\n return { code: line.slice(0, i), comment: line.slice(i) };\n }\n }\n return { code: line, comment: null };\n}\n\n/** First occurrence of `needle` outside `'…'` quotes — or -1. */\nexport function indexOfOutsideQuotes(line: string, needle: string): number {\n let inQuote = false;\n for (let i = 0; i + needle.length <= line.length; i++) {\n const ch = line[i];\n if (ch === \"'\") {\n inQuote = !inQuote;\n continue;\n }\n if (!inQuote && line.startsWith(needle, i)) return i;\n }\n return -1;\n}\n\n// Color override extension: `(color #rrggbb)` OR `(color green)`. Deliberately placed after\n// the coordinates so parentheses inside sticky names are never mistaken for it.\n// Accepts hex or CSS color names.\nconst COLOR_RE = /\\(\\s*color\\s+(#[0-9a-fA-F]{3,8}|[a-zA-Z][\\w-]*)\\s*\\)/i;\n\nexport function parseColor(line: string): { color?: string; rest: string } {\n const m = COLOR_RE.exec(line);\n if (!m || !m[1]) return { rest: line };\n return { color: m[1], rest: line.replace(COLOR_RE, \" \") };\n}\n\n// Attachment extension: `(on <Host Name>)` — canonically the LAST suffix. The host name runs\n// up to the line's FINAL ')', so names may themselves contain parentheses (`Payment (retry)`).\n// Extracted BEFORE the other suffixes so a `(color …)` or `(size …)` inside a host name is\n// never mistaken for one.\nconst ON_RE = /\\(\\s*on\\s+/i;\n\nexport function parseOn(line: string): { host?: string; rest: string } {\n const m = ON_RE.exec(line);\n if (!m) return { rest: line };\n const start = m.index + m[0].length;\n const close = line.lastIndexOf(\")\");\n if (close < start) return { rest: line };\n const host = line.slice(start, close).trim();\n if (!host) return { rest: line };\n return { host, rest: `${line.slice(0, m.index)} ${line.slice(close + 1)}` };\n}\n\n// Internal-id extension: `(id <id>)` — emitted on sticky lines only when the name alone would\n// be ambiguous. The charset is deliberately tight (letters/digits/underscore/hyphen) so an id\n// can never collide with the line grammar (`)`/whitespace/`#` are all illegal).\nexport const ID_CHARSET_RE = /^[A-Za-z0-9_-]+$/;\n\nconst ID_RE = /\\(\\s*id\\s+([A-Za-z0-9_-]+)\\s*\\)/i;\n\n// Any `(id …)` group — catches malformed variants so the caller can report a diagnostic.\nconst ID_PRESENT_RE = /\\(\\s*id\\b[^)]*\\)/i;\n\nexport function parseId(line: string): {\n id?: string;\n /** The matched `(id …)` text when present but unreadable (illegal charset). */\n invalid?: string;\n rest: string;\n} {\n const m = ID_RE.exec(line);\n if (m?.[1]) return { id: m[1], rest: line.replace(ID_RE, \" \") };\n const p = ID_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(ID_PRESENT_RE, \" \") };\n}\n\n// Resize extension: `(size <w>x<h>)` — canonically the last suffix before `(on …)` on note\n// lines. The serializer emits no spaces around the `x`; the parser tolerates optional whitespace.\n// Deliberately looked up only after the coordinates so `(size 1x1)` inside note text survives.\nconst SIZE_RE = /\\(\\s*size\\s+([\\d.]+)\\s*x\\s*([\\d.]+)\\s*\\)/i;\n\n// Any `(size …)` group — catches malformed variants so the caller can report a diagnostic.\nconst SIZE_PRESENT_RE = /\\(\\s*size\\b[^)]*\\)/i;\n\nexport function parseSize(line: string): {\n size?: { width: number; height: number };\n /** The matched `(size …)` text when present but unreadable (malformed or non-positive). */\n invalid?: string;\n rest: string;\n} {\n const m = SIZE_RE.exec(line);\n if (m) {\n const width = Number(m[1]);\n const height = Number(m[2]);\n // Non-positive, NaN (`1.2.3`) or beyond the canvas falls through to the malformed branch.\n if (width > 0 && height > 0 && isDrawable(width) && isDrawable(height)) {\n return { size: { width, height }, rest: line.replace(SIZE_RE, \" \") };\n }\n }\n const p = SIZE_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(SIZE_PRESENT_RE, \" \") };\n}\n\n// Alignment extension: `(align <horizontal> <vertical>)` — canonically between `(size …)` and\n// `(on …)` on note lines, both words always present. Values are matched case-insensitively and\n// canonicalized to lowercase. Deliberately looked up only after the coordinates so an\n// `(align center middle)` inside note text survives.\nconst ALIGN_RE = /\\(\\s*align\\s+(left|center|right)\\s+(top|middle|bottom)\\s*\\)/i;\n\n// Any `(align …)` group — catches malformed variants so the caller can report a diagnostic.\nconst ALIGN_PRESENT_RE = /\\(\\s*align\\b[^)]*\\)/i;\n\nexport function parseAlign(line: string): {\n align?: {\n horizontal: \"left\" | \"center\" | \"right\";\n vertical: \"top\" | \"middle\" | \"bottom\";\n };\n /** The matched `(align …)` text when present but unreadable (unknown/missing axis words). */\n invalid?: string;\n rest: string;\n} {\n const m = ALIGN_RE.exec(line);\n if (m) {\n return {\n align: {\n horizontal: m[1]!.toLowerCase() as \"left\" | \"center\" | \"right\",\n vertical: m[2]!.toLowerCase() as \"top\" | \"middle\" | \"bottom\",\n },\n rest: line.replace(ALIGN_RE, \" \"),\n };\n }\n const p = ALIGN_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(ALIGN_PRESENT_RE, \" \") };\n}\n\n/** Undoes the serializer's `\\n` name escaping (line-based DSL, multi-line labels). */\nexport function decodeName(name: string): string {\n return name.replace(/\\\\n/g, \"\\n\");\n}\n\n/** First word (keyword) of a line, lowercased. */\nexport function keywordOf(line: string): string {\n const m = /^\\s*([A-Za-z][\\w-]*)/.exec(line);\n return m ? m[1]!.toLowerCase() : \"\";\n}\n\nexport function slug(label: string): string {\n return (\n label\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_/, \"\")\n .replace(/_$/, \"\") || \"x\"\n );\n}\n","import type { ElementType } from \"@miragon/event-storming-schema-model\";\nimport { slug } from \"./lexer.js\";\n\n/** Sticky keywords double as `elementType` values; the value is the ID prefix. */\nexport const STICKY_ID_PREFIXES: Readonly<Partial<Record<ElementType, string>>> = {\n event: \"event\",\n command: \"cmd\",\n actor: \"actor\",\n aggregate: \"agg\",\n policy: \"policy\",\n readmodel: \"read\",\n external: \"ext\",\n hotspot: \"hot\",\n};\n\n// Board ids become diagram-js element ids, and the renderer's root elements live in the same\n// registry: an element claiming one of these would make the import throw halfway through.\nconst ENGINE_ID_RE = /^(?:event-storming-root$|__implicitroot)/;\n\nexport function isEngineId(id: string): boolean {\n return ENGINE_ID_RE.test(id);\n}\n\n/**\n * The parser's id allocation, shared with the serializer: the serializer replays it in emit order\n * to decide which ids the text has to carry so that every sticky gets its id back on re-import.\n */\nexport class IdAllocator {\n private readonly used = new Set<string>();\n\n /** Explicit `(id …)` — false when the id is taken or reserved (caller reports + allocates). */\n claim(id: string): boolean {\n if (this.used.has(id) || isEngineId(id)) return false;\n this.used.add(id);\n return true;\n }\n\n /** The id `alloc(prefix, label)` would return, without taking it. */\n peek(prefix: string, label: string): string {\n const base = `${prefix}_${slug(label)}`;\n let id = base;\n let i = 2;\n while (this.used.has(id)) id = `${base}_${i++}`;\n return id;\n }\n\n alloc(prefix: string, label: string): string {\n const id = this.peek(prefix, label);\n this.used.add(id);\n return id;\n }\n}\n","import {\n ATTACHABLE_STICKY_KINDS,\n CURRENT_SCHEMA_VERSION,\n HOST_STICKY_KINDS,\n validateBoard,\n type BoardConfig,\n type BoardEdge,\n type BoardLevel,\n type BoardElement,\n type Coordinate,\n type DrawingElement,\n type DrawingStrokeStyle,\n type ElementType,\n type EventStormingBoard,\n type NoteAlign,\n type NoteAlignHorizontal,\n type NoteAlignVertical,\n type NoteElement,\n} from \"@miragon/event-storming-schema-model\";\nimport {\n indexOfOutsideQuotes,\n keywordOf,\n parseAlign,\n parseColor,\n parseCoords,\n parseId,\n parseMultiCoords,\n parseOn,\n parseSize,\n splitAtCoords,\n splitLineComment,\n decodeName,\n} from \"./lexer.js\";\nimport { IdAllocator, STICKY_ID_PREFIXES, isEngineId } from \"./ids.js\";\n\n/** Splits `A -> B` at the FIRST arrow — plain indexOf, immune to regex backtracking. */\nfunction splitArrow(core: string): { left: string; right: string } | null {\n const arrow = core.indexOf(\"->\");\n if (arrow <= 0) return null;\n const left = core.slice(0, arrow).trim();\n const right = core.slice(arrow + 2).trim();\n return left && right ? { left, right } : null;\n}\n\nconst KNOWN_STYLES: ReadonlySet<string> = new Set([\"classic\", \"dark\"]);\n\nconst ATTACHABLE_KINDS: ReadonlySet<string> = new Set(ATTACHABLE_STICKY_KINDS);\n\nconst HOST_KINDS: ReadonlySet<string> = new Set(HOST_STICKY_KINDS);\n\nconst KNOWN_LEVELS: ReadonlySet<string> = new Set([\"big-picture\", \"process\", \"design\"]);\n\n// The 8 sticky kinds — the only legal arrow endpoints (mirrors validateBoard's contract).\nconst STICKY_KINDS: ReadonlySet<string> = new Set(Object.keys(STICKY_ID_PREFIXES));\n\ninterface PendingArrow {\n readonly left: string;\n readonly right: string;\n /** Annotation text after `;`. */\n readonly label?: string;\n readonly raw: string;\n readonly lineNo: number;\n}\n\n/** `(on …)` attachment — host referenced BY NAME, resolution deferred like arrow endpoints. */\ninterface PendingAttachment {\n /** Index into `elements` of the attachable sticky. */\n readonly index: number;\n readonly host: string;\n readonly raw: string;\n readonly lineNo: number;\n}\n\nfunction compact<T extends Record<string, unknown>>(obj: T): T {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) if (v !== undefined) out[k] = v;\n return out as T;\n}\n\n/**\n * Text `(align <h> <v>)` pair -> model value: default axes (left/top) are dropped, both-default\n * collapses to absent — `(align left top)` and no suffix are the same board (the serializer\n * emits the suffix only when an axis differs from the default).\n */\nfunction modelAlign(\n align: { horizontal: NoteAlignHorizontal; vertical: NoteAlignVertical } | undefined,\n): NoteAlign | undefined {\n if (!align) return undefined;\n const out = compact({\n horizontal: align.horizontal === \"left\" ? undefined : align.horizontal,\n vertical: align.vertical === \"top\" ? undefined : align.vertical,\n }) as NoteAlign;\n return Object.keys(out).length ? out : undefined;\n}\n\n/** Finding produced while parsing — line is 1-based; `text` is the (comment-stripped) line. */\nexport interface ParseDiagnostic {\n readonly line: number;\n readonly message: string;\n readonly text: string;\n}\n\nexport interface ParseResult {\n readonly board: EventStormingBoard;\n readonly diagnostics: readonly ParseDiagnostic[];\n}\n\n/**\n * Line-based keyword parsing; coordinates are `[x, y]` in board pixels (x FIRST), unbounded,\n * optional (default `[0, 0]`). Unknown lines land in `rawPassthrough`.\n */\nexport function parseDSL(text: string): EventStormingBoard {\n return parseDSLWithDiagnostics(text).board;\n}\n\n/**\n * Like `parseDSL`, but additionally returns findings with line numbers (uninterpretable lines,\n * unresolved references) — for editor feedback instead of silent loss.\n */\nexport function parseDSLWithDiagnostics(text: string): ParseResult {\n const diagnostics: ParseDiagnostic[] = [];\n const ids = new IdAllocator();\n const nameToId = new Map<string, string>();\n const elements: BoardElement[] = [];\n const rawPassthrough: string[] = [];\n const pendingArrows: PendingArrow[] = [];\n const pendingAttachments: PendingAttachment[] = [];\n\n let config: BoardConfig = { title: \"Untitled Board\" };\n let inBlockComment = false;\n\n const register = (name: string, id: string) => {\n if (!nameToId.has(name)) nameToId.set(name, id);\n };\n\n // Diagnostics helpers: read the current line/number from the loop state.\n let lineNo = 0;\n let currentLine = \"\";\n\n /** Tries to capture a line as an arrow. Returns true when consumed. */\n const pushArrow = (line: string): boolean => {\n // Split off an optional arrow annotation after ';' (e.g. `A -> B; async`).\n const semi = line.indexOf(\";\");\n const core = semi >= 0 ? line.slice(0, semi).trim() : line;\n const arrowLabel = semi >= 0 ? line.slice(semi + 1).trim() : \"\";\n const arrow = splitArrow(core);\n if (!arrow) return false;\n pendingArrows.push({\n left: arrow.left,\n right: arrow.right,\n ...(arrowLabel ? { label: arrowLabel } : {}),\n raw: line,\n lineNo,\n });\n return true;\n };\n const diag = (message: string, atLine = lineNo, text_ = currentLine) =>\n diagnostics.push({ line: atLine, message, text: text_ });\n /** Passthrough for a line that looks like a known construct but cannot be parsed. */\n const failed = (l: string) => {\n rawPassthrough.push(l);\n diag(\"Couldn't read this line. It stays in the file unchanged.\");\n };\n /** Board pixels, unbounded — no clamping on the free canvas. */\n const pos = (x: number, y: number): Coordinate => ({ x, y });\n\n const sourceLines = text.split(/\\r?\\n/);\n for (let i = 0; i < sourceLines.length; i++) {\n const raw = sourceLines[i]!;\n // The empty piece after a final newline is no line: inside an open block comment it would be\n // kept as one, and every save would append another blank line.\n if (raw === \"\" && i === sourceLines.length - 1) continue;\n lineNo = i + 1;\n currentLine = raw.trim();\n let working = raw;\n\n // --- Comments (`//`, `/* */`): strip, but keep losslessly in rawPassthrough. ---\n if (inBlockComment) {\n const close = working.indexOf(\"*/\");\n if (close < 0) {\n rawPassthrough.push(raw);\n continue;\n }\n rawPassthrough.push(working.slice(0, close + 2));\n working = working.slice(close + 2);\n inBlockComment = false;\n }\n let open = indexOfOutsideQuotes(working, \"/*\");\n while (open >= 0) {\n const close = working.indexOf(\"*/\", open + 2);\n if (close < 0) {\n rawPassthrough.push(working.slice(open));\n working = working.slice(0, open);\n inBlockComment = true;\n break;\n }\n rawPassthrough.push(working.slice(open, close + 2));\n working = `${working.slice(0, open)} ${working.slice(close + 2)}`;\n open = indexOfOutsideQuotes(working, \"/*\");\n }\n const { code, comment } = splitLineComment(working);\n if (comment !== null) rawPassthrough.push(comment);\n working = code;\n\n const line = working.trim();\n if (!line) continue;\n\n const kw = keywordOf(line);\n const after = line.slice(kw.length).trim();\n\n // Arrows FIRST: sticky NAMES may begin with a keyword word (the default command is\n // named \"Command\" -> arrow `Command -> X`). Declarations carry coordinates `[...]`,\n // arrows never do — but only the part BEFORE the `;` annotation counts, the annotation\n // is free text and may contain a tuple. Without this pre-detection `Command -> X` would\n // be misread as a (broken) `command` declaration and vanish on re-import. `title` is\n // exempt (its content may itself use `->`) UNLESS the left side is an already-declared\n // sticky name (e.g. one named \"Title Page\" — declarations always precede arrows in\n // serialized DSL). `style`/`level`/`line` need no exemption: style and level values are\n // single words and drawings always carry coordinate tuples.\n const semi = line.indexOf(\";\");\n const beforeAnnotation = semi >= 0 ? line.slice(0, semi) : line;\n const titleAsArrow = (): boolean => {\n const arrow = splitArrow(beforeAnnotation.trim());\n return arrow !== null && nameToId.has(decodeName(arrow.left));\n };\n if ((kw !== \"title\" || titleAsArrow()) && !parseCoords(beforeAnnotation) && pushArrow(line)) {\n continue;\n }\n\n switch (kw) {\n case \"title\":\n config = { ...config, title: after };\n break;\n\n case \"style\": {\n const s = after.toLowerCase();\n if (KNOWN_STYLES.has(s)) config = { ...config, style: s as \"classic\" | \"dark\" };\n else failed(line);\n break;\n }\n\n case \"level\": {\n const l = after.toLowerCase();\n if (KNOWN_LEVELS.has(l)) config = { ...config, level: l as BoardLevel };\n else failed(line);\n break;\n }\n\n case \"event\":\n case \"command\":\n case \"actor\":\n case \"aggregate\":\n case \"policy\":\n case \"readmodel\":\n case \"external\":\n case \"hotspot\": {\n const node = parseSticky(after);\n if (!node) {\n failed(line);\n break;\n }\n if (node.idInvalid) {\n diag(\n `Couldn't read the id “${node.idInvalid.trim()}”. An id has letters, digits, “_” or “-”, as in (id order_1).`,\n );\n }\n const explicit = node.id !== undefined && ids.claim(node.id) ? node.id : undefined;\n if (node.id !== undefined && explicit === undefined) {\n diag(\n isEngineId(node.id)\n ? `The id “${node.id}” belongs to the board itself, so this sticky got a new id.`\n : `The id “${node.id}” is already taken, so this sticky got a new id.`,\n );\n }\n const id = explicit ?? ids.alloc(STICKY_ID_PREFIXES[kw as ElementType]!, node.name);\n elements.push(\n compact({\n id,\n elementType: kw as ElementType,\n label: node.name,\n position: pos(node.coords.x, node.coords.y),\n color: node.color,\n }) as BoardElement,\n );\n register(node.name, id);\n if (node.host !== undefined) {\n if (ATTACHABLE_KINDS.has(kw)) {\n pendingAttachments.push({\n index: elements.length - 1,\n host: node.host,\n raw: line,\n lineNo,\n });\n } else {\n diag(`A ${kw} can't be pinned. Only an actor, a hotspot or a note takes (on …).`);\n }\n }\n if (node.sizeSuffix) {\n diag(`A ${kw} can't be resized. Only a note takes (size …).`);\n }\n if (node.alignSuffix) {\n diag(`A ${kw} can't be aligned. Only a note takes (align …).`);\n }\n break;\n }\n\n case \"note\": {\n const split = splitAtCoords(after);\n if (!split && after.includes(\"[\")) {\n failed(line);\n break;\n }\n // Suffixes ONLY after the coordinates (mirrors parseSticky) — notes are free text, so\n // `(on …)`, `(color …)` or `(size 1x1)` may legitimately appear inside it. `(on …)` is\n // stripped FIRST: it is always the last suffix and its host name runs to the final `)`,\n // so it may itself contain a `(color …)`, `(size …)` or `(align …)`.\n const on = parseOn(split ? split.suffix : after);\n const al = parseAlign(on.rest);\n const sz = parseSize(al.rest);\n const idp = parseId(sz.rest);\n const col = parseColor(idp.rest);\n if (al.invalid) {\n diag(\n `Couldn't read the alignment “${al.invalid.trim()}”. Write (align left|center|right top|middle|bottom).`,\n );\n }\n if (sz.invalid) {\n diag(\n `Couldn't read the size “${sz.invalid.trim()}”. Write (size <w>x<h>) with positive numbers.`,\n );\n }\n if (idp.id !== undefined || idp.invalid) {\n diag(\"A note can't have an id. Only a sticky takes (id …).\");\n }\n // Literal `\\n` back into real line breaks (multi-line notes).\n const textPart = decodeName((split ? split.name : col.rest).trim());\n const id = ids.alloc(\"note\", textPart || \"note\");\n const note: NoteElement = compact({\n id,\n elementType: \"note\",\n label: textPart,\n position: split ? pos(split.coords.a, split.coords.b) : pos(0, 0),\n color: col.color,\n size: sz.size,\n align: modelAlign(al.align),\n }) as NoteElement;\n elements.push(note);\n if (on.host !== undefined) {\n pendingAttachments.push({ index: elements.length - 1, host: on.host, raw: line, lineNo });\n }\n break;\n }\n\n case \"line\": {\n // Project extension (freeform drawing): `line [[x,y], [x,y], …] (closed) (dashed) (color x)`.\n const col = parseColor(after);\n const multi = parseMultiCoords(col.rest);\n if (!multi || multi.tuples.length < 2) {\n failed(line);\n break;\n }\n const onDrawing = parseOn(multi.rest);\n if (onDrawing.host !== undefined) {\n diag(\"A drawing can't be pinned. Only an actor, a hotspot or a note takes (on …).\");\n }\n const szDrawing = parseSize(onDrawing.rest);\n if (szDrawing.size || szDrawing.invalid) {\n diag(\"A drawing can't be resized. Only a note takes (size …).\");\n }\n const alDrawing = parseAlign(onDrawing.rest);\n if (alDrawing.align || alDrawing.invalid) {\n diag(\"A drawing can't be aligned. Only a note takes (align …).\");\n }\n const idDrawing = parseId(onDrawing.rest);\n if (idDrawing.id !== undefined || idDrawing.invalid) {\n diag(\"A drawing can't have an id. Only a sticky takes (id …).\");\n }\n const flags = onDrawing.rest.toLowerCase();\n const strokeStyle: DrawingStrokeStyle | undefined = flags.includes(\"(dashed)\")\n ? \"dashed\"\n : flags.includes(\"(dotted)\")\n ? \"dotted\"\n : undefined;\n const points = multi.tuples.map((t) => pos(t.a, t.b));\n const drawing: DrawingElement = {\n id: ids.alloc(\"draw\", \"line\"),\n elementType: \"drawing\",\n label: \"\",\n position: points[0]!,\n points,\n ...(flags.includes(\"(closed)\") ? { closed: true } : {}),\n ...(strokeStyle ? { strokeStyle } : {}),\n ...(col.color ? { color: col.color } : {}),\n };\n elements.push(drawing);\n break;\n }\n\n default: {\n // Unknown keyword: try as an arrow (e.g. `A -> B; async`), otherwise keep raw.\n if (!pushArrow(line)) rawPassthrough.push(line);\n }\n }\n }\n\n // Reference resolution for arrow endpoints and `(on …)` hosts: a `#`-prefixed token is an id\n // reference (ids exist for EVERY element, not only those declared with `(id …)`); anything\n // else stays a label lookup. No fallback across the two — `#` always means id.\n const resolve = (token: string): BoardElement | undefined => {\n if (token.startsWith(\"#\")) {\n const id = token.slice(1);\n return elements.find((e) => e.id === id);\n }\n const id = nameToId.get(decodeName(token));\n return id !== undefined ? elements.find((e) => e.id === id) : undefined;\n };\n\n // Deferred like arrows so a host may be declared after its attacher. On failure the sticky\n // stays WITHOUT attachedTo (it was already created above) — no rawPassthrough, the line is\n // otherwise fully represented.\n for (const att of pendingAttachments) {\n const host = resolve(att.host);\n if (!host) {\n diag(`There's no “${att.host}” on the board to pin this to.`, att.lineNo, att.raw);\n continue;\n }\n if (!HOST_KINDS.has(host.elementType)) {\n diag(\n `“${att.host}” is a ${host.elementType}. An actor, a hotspot or a note is pinned to an event, a command, an aggregate, a policy, a read model or an external system.`,\n att.lineNo,\n att.raw,\n );\n continue;\n }\n elements[att.index] = { ...elements[att.index]!, attachedTo: host.id } as BoardElement;\n }\n\n let arrowN = 0;\n // An explicit `(id arrow_N)` on a sticky may occupy an arrow-id slot — skip it (diagram-js\n // has ONE id namespace for shapes and connections; validateBoard rejects the collision).\n const elementIds = new Set(elements.map((e) => e.id));\n const nextArrowId = (): string => {\n let id = `arrow_${++arrowN}`;\n while (elementIds.has(id)) id = `arrow_${++arrowN}`;\n return id;\n };\n const edges: BoardEdge[] = [];\n for (const arrow of pendingArrows) {\n const from = resolve(arrow.left);\n const to = resolve(arrow.right);\n if (!from || !to) {\n rawPassthrough.push(arrow.raw);\n diag(\n !from\n ? `This arrow starts at “${arrow.left}”, which isn't on the board.`\n : `This arrow points to “${arrow.right}”, which isn't on the board.`,\n arrow.lineNo,\n arrow.raw,\n );\n continue;\n }\n // Only reachable via `#id` refs (labels are registered for sticky kinds only) — an edge to\n // a note/drawing would make validateBoard throw, so it is dropped losslessly instead.\n const nonSticky = !STICKY_KINDS.has(from.elementType)\n ? ([arrow.left, from] as const)\n : !STICKY_KINDS.has(to.elementType)\n ? ([arrow.right, to] as const)\n : undefined;\n if (nonSticky) {\n rawPassthrough.push(arrow.raw);\n diag(\n `“${nonSticky[0]}” is a ${nonSticky[1].elementType}, and an arrow only connects stickies.`,\n arrow.lineNo,\n arrow.raw,\n );\n continue;\n }\n edges.push(\n compact({\n id: nextArrowId(),\n edgeType: \"arrow\",\n from: from.id,\n to: to.id,\n label: arrow.label,\n }) as BoardEdge,\n );\n }\n\n const board = compact({\n schemaVersion: CURRENT_SCHEMA_VERSION,\n config,\n elements,\n edges,\n rawPassthrough: rawPassthrough.length ? rawPassthrough : undefined,\n }) as EventStormingBoard;\n\n return { board: validateBoard(board), diagnostics };\n}\n\ninterface ParsedSticky {\n readonly name: string;\n readonly coords: { x: number; y: number };\n /** Color override `(color …)` — supported on every element line. */\n readonly color?: string;\n /** Attachment `(on <Host Name>)` — host name still undecoded, resolved by the caller. */\n readonly host?: string;\n /** Explicit `(id …)` — the caller claims it (duplicate ⇒ diagnostic + fresh id). */\n readonly id?: string;\n /** The matched `(id …)` text when present but unreadable (illegal charset). */\n readonly idInvalid?: string;\n /** A `(size …)` suffix appeared — only notes support it, the caller reports a diagnostic. */\n readonly sizeSuffix?: boolean;\n /** An `(align …)` suffix appeared — only notes support it, the caller reports a diagnostic. */\n readonly alignSuffix?: boolean;\n}\n\n/**\n * Parses `<name> [x, y] [(color …)] [(id …)] [(on …)]`. The suffixes are looked up ONLY AFTER\n * the coordinates — parentheses inside the name stay untouched. `(on …)` is extracted first\n * (its host name runs to the final `)` and may itself contain a `(color …)`, `(id …)` or\n * `(size …)`). Coordinates are optional and default to `[0, 0]`; a malformed tuple (bracket\n * present but unreadable) is rejected so the caller can report a diagnostic instead of\n * swallowing it into the name.\n */\nfunction parseSticky(after: string): ParsedSticky | null {\n const split = splitAtCoords(after);\n if (split) {\n if (!split.name) return null;\n const on = parseOn(split.suffix);\n const idp = parseId(on.rest);\n const al = parseAlign(idp.rest);\n const sz = parseSize(al.rest);\n const col = parseColor(sz.rest);\n return compact({\n name: decodeName(split.name),\n coords: { x: split.coords.a, y: split.coords.b },\n color: col.color ?? undefined,\n host: on.host,\n id: idp.id,\n idInvalid: idp.invalid,\n sizeSuffix: sz.size || sz.invalid ? true : undefined,\n alignSuffix: al.align || al.invalid ? true : undefined,\n }) as ParsedSticky;\n }\n if (after.includes(\"[\")) return null;\n const on = parseOn(after);\n const idp = parseId(on.rest);\n const al = parseAlign(idp.rest);\n const sz = parseSize(al.rest);\n const col = parseColor(sz.rest);\n const name = col.rest.trim();\n if (!name) return null;\n return compact({\n name: decodeName(name),\n coords: { x: 0, y: 0 },\n color: col.color ?? undefined,\n host: on.host,\n id: idp.id,\n idInvalid: idp.invalid,\n sizeSuffix: sz.size || sz.invalid ? true : undefined,\n alignSuffix: al.align || al.invalid ? true : undefined,\n }) as ParsedSticky;\n}\n","import type {\n BoardElement,\n EventStormingBoard,\n NoteElement,\n} from \"@miragon/event-storming-schema-model\";\nimport { IdAllocator, STICKY_ID_PREFIXES } from \"./ids.js\";\nimport { ID_CHARSET_RE, decodeName, slug } from \"./lexer.js\";\n\n/**\n * Coordinate formatter: 3-decimal rounding, NEVER exponent notation — `String(1e21)` yields\n * `\"1e+21\"`, which the coordinate regex cannot read back. Magnitudes >= 1e21 are always\n * integer-valued doubles, so BigInt expands them losslessly (the rounding step is skipped\n * there; it would be a no-op and could overflow to Infinity for huge values).\n */\nfunction r(n: number): string {\n const v = Math.abs(n) < 1e21 ? Math.round(n * 1000) / 1000 : n;\n return Math.abs(v) < 1e21 ? String(v) : BigInt(v).toString();\n}\n\n/**\n * Free text emitted into the line-based grammar: real line breaks become the literal `\\n`\n * escape (decoded on parse) and comment starters are defused with the Unicode division slash\n * — otherwise the parser would split the line or strip the rest as a comment. `//` directly\n * after `:` stays untouched (URL scheme separator, the comment splitter is URL-aware).\n */\nfunction escapeText(label: string): string {\n return label\n .trim()\n .replace(/\\n/g, \"\\\\n\")\n .replace(/(?<!:)\\/\\//g, \"∕∕\")\n .replace(/\\/\\*/g, \"∕*\");\n}\n\n/** Names are additionally arrow-safe: a literal `->` inside a name would break `A -> B` lines. */\nfunction escapeName(label: string): string {\n return escapeText(label).replace(/->/g, \"→\");\n}\n\n/** Types referenced BY THEIR NAME in the DSL (arrow endpoints + namespace) — all sticky kinds. */\nconst NAMED_TYPES: ReadonlySet<string> = new Set([\n \"event\",\n \"command\",\n \"actor\",\n \"aggregate\",\n \"policy\",\n \"readmodel\",\n \"external\",\n \"hotspot\",\n]);\n\nconst DEFAULT_NAMES: Readonly<Record<string, string>> = {\n event: \"Domain Event\",\n command: \"Command\",\n actor: \"Actor\",\n aggregate: \"Aggregate\",\n policy: \"Policy\",\n readmodel: \"Read Model\",\n external: \"External System\",\n hotspot: \"Hotspot\",\n};\n\nfunction defaultName(type: string): string {\n return DEFAULT_NAMES[type] ?? \"Sticky\";\n}\n\n/**\n * Returns the DSL name per element ID for the referenceable types (the sticky kinds): the\n * escaped label, or the per-kind default for an empty one. Duplicate labels are legal — an\n * ambiguous name is disambiguated via an `(id …)` suffix plus `#id` references instead of\n * being silently renamed.\n */\nfunction serializedNames(board: EventStormingBoard): Map<string, string> {\n const byId = new Map<string, string>();\n for (const el of board.elements) {\n if (!NAMED_TYPES.has(el.elementType)) continue;\n byId.set(el.id, escapeName(el.label) || defaultName(el.elementType));\n }\n return byId;\n}\n\n/** Color override extension: `(color …)` after the coordinates. */\nfunction colorSuffix(el: { color?: string }): string {\n return el.color ? ` (color ${el.color})` : \"\";\n}\n\n/**\n * Alignment extension: `(align <horizontal> <vertical>)` — both words always emitted together\n * using the EFFECTIVE values, and only when at least one axis differs from the default\n * left/top, so existing boards serialize byte-identically.\n */\nfunction alignSuffix(el: NoteElement): string {\n const horizontal = el.align?.horizontal ?? \"left\";\n const vertical = el.align?.vertical ?? \"top\";\n return horizontal === \"left\" && vertical === \"top\" ? \"\" : ` (align ${horizontal} ${vertical})`;\n}\n\n/**\n * Serializes an EventStormingBoard into `.storm` text. Deterministic; writes only syntax the\n * parser reads back. `rawPassthrough` is appended unchanged. Coordinates are `[x, y]` in board\n * pixels (x FIRST), rounded to 3 decimals.\n */\nexport function serializeDSL(board: EventStormingBoard): string {\n const lines: string[] = [];\n const names = serializedNames(board);\n const nameOf = (el: BoardElement): string => names.get(el.id) ?? el.label;\n\n // A `#…` token in a reference position always reads as an id — so a sticky whose serialized\n // name is AMBIGUOUS (shared by >= 2 stickies) or literally starts with `#` is referenced as\n // `#id`. Everything else stays purely name-based, so unambiguous boards serialize without any\n // ids, byte-identical to before.\n const nameCount = new Map<string, number>();\n for (const name of names.values()) nameCount.set(name, (nameCount.get(name) ?? 0) + 1);\n const referencedById = (id: string): boolean => {\n const name = names.get(id);\n return name !== undefined && (nameCount.get(name)! > 1 || name.startsWith(\"#\"));\n };\n\n // Ids surface in the text only via the `(id …)` suffix. An id outside the DSL id charset\n // (possible in JSON-authored boards) would emit unparsable syntax and lose the arrows on\n // re-import — a slug-based, collision-checked stand-in is substituted for the suffix AND every\n // reference.\n const emitIds = new Map<string, string>();\n const taken = new Set(board.elements.map((e) => e.id));\n for (const el of board.elements) {\n if (!referencedById(el.id) || ID_CHARSET_RE.test(el.id)) continue;\n let candidate = slug(el.id);\n for (let i = 2; taken.has(candidate); i++) candidate = `${slug(el.id)}_${i}`;\n taken.add(candidate);\n emitIds.set(el.id, candidate);\n }\n const idOf = (id: string): string => emitIds.get(id) ?? id;\n const declaredIds = idsToDeclare(board, nameOf, referencedById, idOf);\n const ref = (id: string): string => (referencedById(id) ? `#${idOf(id)}` : (names.get(id) ?? id));\n\n lines.push(`title ${board.config.title}`);\n if (board.config.style) lines.push(`style ${board.config.style}`);\n if (board.config.level) lines.push(`level ${board.config.level}`);\n\n // Pinning `(on …)` is ALWAYS the last suffix — the parser reads the host name up to the\n // line's final `)`, so host names containing parentheses survive. validateBoard guarantees\n // the host is a named sticky kind; `ref` falls back to the raw id purely defensively.\n const onSuffix = (el: BoardElement): string => {\n const hostId =\n el.elementType === \"actor\" || el.elementType === \"hotspot\" || el.elementType === \"note\"\n ? el.attachedTo\n : undefined;\n return hostId ? ` (on ${ref(hostId)})` : \"\";\n };\n\n for (const el of board.elements) {\n const idSuffix = declaredIds.has(el.id) ? ` (id ${idOf(el.id)})` : \"\";\n lines.push(elementLine(el, nameOf(el), idSuffix, onSuffix(el)));\n }\n\n // validateBoard guarantees arrow endpoints are sticky kinds, so the name map always covers\n // them — `ref`'s raw-id fallback is purely defensive for unvalidated input.\n for (const edge of board.edges) {\n const annotation = edge.label ? `; ${edge.label}` : \"\";\n lines.push(`${ref(edge.from)} -> ${ref(edge.to)}${annotation}`);\n }\n\n // Config keywords were already emitted from the board above. A rawPassthrough entry with the\n // same keyword (e.g. an unparsable `style` line from externally-authored DSL) would otherwise\n // produce a contradictory duplicate line — drop it (config is the truth).\n if (board.rawPassthrough) {\n const emitted = new Set<string>([\"title\"]);\n if (board.config.style) emitted.add(\"style\");\n if (board.config.level) emitted.add(\"level\");\n for (const raw of board.rawPassthrough) {\n if (emitted.has(raw.trim().split(/\\s+/)[0]!)) continue;\n lines.push(raw);\n }\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/**\n * The stickies whose line carries `(id …)`: those referenced as `#id`, plus every sticky whose id\n * the parser would not allocate again at its line — one created on the canvas (`event_3`),\n * renamed after its id was derived from the old label, or declared with an explicit id. Hosts\n * anchor todos, presence and deep links to these ids, so they must survive a save and re-open.\n * Replays the parser's allocation in emit order; an id equal to the allocated one stays implicit,\n * which keeps boards authored without ids byte-identical.\n */\nfunction idsToDeclare(\n board: EventStormingBoard,\n nameOf: (el: BoardElement) => string,\n referencedById: (id: string) => boolean,\n emittedId: (id: string) => string,\n): Set<string> {\n const allocator = new IdAllocator();\n const declared = new Set<string>();\n for (const el of board.elements) {\n const prefix = STICKY_ID_PREFIXES[el.elementType];\n if (prefix === undefined) {\n allocator.alloc(el.elementType === \"note\" ? \"note\" : \"draw\", noteOrDrawingName(el));\n continue;\n }\n const parsedName = decodeName(nameOf(el));\n const declare =\n referencedById(el.id) ||\n (ID_CHARSET_RE.test(el.id) && allocator.peek(prefix, parsedName) !== el.id);\n if (declare) {\n declared.add(el.id);\n allocator.claim(emittedId(el.id));\n } else {\n allocator.alloc(prefix, parsedName);\n }\n }\n return declared;\n}\n\n/** The label the parser allocates a note's or a drawing's id from. */\nfunction noteOrDrawingName(el: BoardElement): string {\n if (el.elementType === \"drawing\") return \"line\";\n return decodeName(escapeText(el.label)) || \"note\";\n}\n\nfunction elementLine(el: BoardElement, name: string, idSuffix: string, attach: string): string {\n const p = el.position;\n switch (el.elementType) {\n case \"event\":\n case \"command\":\n case \"actor\":\n case \"aggregate\":\n case \"policy\":\n case \"readmodel\":\n case \"external\":\n case \"hotspot\":\n // Canonical suffix order: `(color …) (id …) (on …)` — `(on …)` stays last (see above).\n return `${el.elementType} ${name} [${r(p.x)}, ${r(p.y)}]${colorSuffix(el)}${idSuffix}${attach}`;\n case \"note\": {\n // Escape line breaks/comment starters -> the line-based DSL stays single-line. `->` is\n // fine in note text (notes are never arrow endpoints), so no `→` replacement here.\n // Canonical note suffix order: `(color …) (size WxH) (align h v) (on …)` — `(on …)`\n // stays last (final-paren rule, see above); size/align/attachment are only present when\n // set, so plain boards stay byte-identical.\n const size = el.size ? ` (size ${r(el.size.width)}x${r(el.size.height)})` : \"\";\n return `note ${escapeText(name)} [${r(p.x)}, ${r(p.y)}]${colorSuffix(el)}${size}${alignSuffix(el)}${attach}`;\n }\n case \"drawing\": {\n // Project extension (freeform drawing): tuple list + style flags.\n const pts = el.points.map((q) => `[${r(q.x)}, ${r(q.y)}]`).join(\", \");\n const closed = el.closed ? \" (closed)\" : \"\";\n const stroke = el.strokeStyle && el.strokeStyle !== \"solid\" ? ` (${el.strokeStyle})` : \"\";\n return `line [${pts}]${closed}${stroke}${colorSuffix(el)}`;\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@miragon/event-storming-dsl",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Convert between the Event Storming .storm text format and the Event Storming board model, with lossless round-trips.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/Miragon/event-storming-modeler.git",
9
- "directory": "packages/dsl"
8
+ "url": "git+https://github.com/Miragon/modeler-suite.git",
9
+ "directory": "modelers/event-storming/packages/dsl"
10
10
  },
11
- "homepage": "https://github.com/Miragon/event-storming-modeler/tree/main/packages/dsl#readme",
12
- "bugs": "https://github.com/Miragon/event-storming-modeler/issues",
11
+ "homepage": "https://github.com/Miragon/modeler-suite/tree/main/modelers/event-storming/packages/dsl#readme",
12
+ "bugs": "https://github.com/Miragon/modeler-suite/issues",
13
13
  "type": "module",
14
14
  "sideEffects": false,
15
15
  "exports": {
@@ -33,11 +33,11 @@
33
33
  "test": "vitest run"
34
34
  },
35
35
  "dependencies": {
36
- "@miragon/event-storming-schema-model": "0.2.1"
36
+ "@miragon/event-storming-schema-model": "0.2.3"
37
37
  },
38
38
  "devDependencies": {
39
- "tsup": "8.5.1",
39
+ "tsup": "9.0.0",
40
40
  "typescript": "6.0.3",
41
- "vitest": "5.0.3"
41
+ "vitest": "5.0.5"
42
42
  }
43
43
  }