Skip to content
HomePlayground

Build with it

Architecture

A short map of the code, for people changing it.

.dsl text -> parser -> Model -> commands (inspect, validate, deps, triggers, scenarios)
-> diagram builders -> svg | mermaid | dot
Piece File Job
Parser lib/parser.js A recursive-descent parser. Reads statements in any order and reports the line and what it expected.
Model lib/model.js Holds the statements and, after finalize(), an event index: who emits each event, who reads it, which facts nobody emits.
Commands lib/commands/*.js One file per CLI command. They read the model and print.
Board lib/diagram/board.js Builds the Event Modeling board: lanes, columns, slices, boundary brackets.
System diagrams lib/diagram/system.js Builds context, containers, data flow, deployment and the context map as one generic graph.
Layout lib/diagram/layout.js Layering shared by the diagrams. Edges that close a loop are set aside, so loops never break placement.
Renderers lib/diagram/svg.js, export.js SVG with no dependencies. Mermaid and DOT from the same graph.
Folder models lib/folder.js Reads a folder of .dsl files as one model and maps a line back to its file. Node only.
Rules lib/rules/ The validation rules. core.js is the language, profile.js the Event Modeling and stricter rules, catalogue.js says what each rule means.
Library entry lib/index.js, lib/diagram/index.js The public API: parse, check, render. Nothing in this path touches the file system.

A diagram draws only what the model states.

  • Facts nobody emits show as a note under the command, not as nodes.
  • A command that a policy calls but nobody declared is drawn dashed and marked “not modeled”.
  • The model does not say which container calls an outside service, so no arrow is drawn into one.
  • The deployment view stops with a message when the system has no region:, instead of guessing.

If a diagram needs something the model cannot say, change the language, not the diagram. That is how in Boundary(key) came to exist.

Every rule is listed once in lib/rules/catalogue.js, with its profile, severity, category, why and how to fix it. check(model, { profile }) runs the core rules, then the profile’s, and gives each finding its category, the statement it is about and where that statement ends. docs/RULES.md is generated from the catalogue: run node scripts/build-rules-doc.js after changing it. Tests fail if a rule reports an id that is not in the catalogue, if a catalogue example does not behave as it says, or if the page is stale. The playground shows the findings as marks beside the lines, badges on the boxes and a list; the profile is part of the shared address as &p=.

Links between diagrams are in lib/diagram/links.js: one place that knows how the six diagrams name the same box, with @link annotations overriding what it derives. render(..., { links: true }) hands the result to the SVG, Mermaid and DOT writers.

site/ is the GitHub Pages site and is published by .github/workflows/pages.yml. Its example file, its board image and the playground’s bundle come from the model, so run this after changing an example, the diagram code or anything in lib/:

Terminal window
node scripts/build-site.js

The playground on the landing page runs site/eventline.js, which is lib/index.js bundled for the browser, so it uses the same parser, checks and board renderer as the CLI. The board SVG tags every node and edge with data-id, data-from and data-to, which the page uses to light a box’s lineage. Command, view and policy nodes also carry data-lines, the source lines the parser recorded (line to endLine), so a click on a box finds its text in the playground editor and the caret finds its box. test/site.test.js fails when the page’s counts, DSL listing, board, bundle or example copies drift from examples/. A model can be shared as /eventline/#play=<base64url of the text>; the docs use the same link. The link can also name a diagram and a box, &d=containers&n=view%3AOrders, and turn on links between diagrams, &links=1. The playground’s diagram tabs and Links button read and write those parts, and the back button walks the links you followed.

docs-site/ builds the documentation site at /eventline/docs/ with Astro Starlight. The Markdown in docs/, EVENTLINE-AXI.md and CONTRIBUTING.md stays the source. docs-site/scripts/sync-docs.mjs turns it into Starlight pages when the site builds: it takes the title from the first heading, turns links between docs into site routes, tags code blocks that hold eventline source so they are highlighted, and renders the diagrams derived from examples/billing.dsl. A block that parses as a model with a command, view or policy also gets an Open in playground link. Nothing it writes is committed. The build fails on a broken link between pages. .github/workflows/pages.yml builds the docs next to the landing page and deploys both as one Pages artifact.

To preview locally, run npm ci && npm run build in docs-site/ and serve dist/ under /eventline/docs/. A new file in docs/ needs an entry in PAGES in the sync script and in the sidebar in docs-site/astro.config.mjs. test/docs-site.test.js fails if either is missing.

npm test runs the parser, diagram, CLI and site tests with Node’s built-in runner.