@@ -250,8 +250,14 @@ as the entry point at the top.
250250runtime. It is a text → visual transformation, like a
251251Mermaid renderer.
252252
253- ** Mermaid as the rendering engine** : The parsed flow
254- model maps directly to Mermaid flowchart syntax:
253+ ** @xyflow/react as the rendering engine** : The parsed
254+ flow model maps to React Flow nodes and edges. Each
255+ step becomes a custom node; each transition becomes an
256+ edge. The same parser also generates Mermaid markup as
257+ a portable export format.
258+
259+ Example flow (the same saga renders interactively in
260+ the browser and as copyable Mermaid markup):
255261
256262``` mermaid
257263flowchart TD
@@ -269,20 +275,23 @@ flowchart TD
269275 S8[book_wholesale_position\n position_keeping.initiate_log] --> END([VALUED])
270276```
271277
272- Mermaid is the right tool here because:
278+ @ xyflow/react is the right tool here because:
273279
274- - The Starlark flow is inherently linear with branches
275- — exactly what Mermaid flowcharts express
276- - mermaid.js is a standard rendering library with
277- automatic layout (dagre) built in
278- - GitHub, GitLab, and Markdown tools render it natively,
279- making the generated diagrams portable
280+ - It is already in the bundle for the composition graph
281+ (Phase 5) — zero incremental cost for saga flows
282+ - Custom React nodes enable the linked experience:
283+ click a step node to highlight code in the editor,
284+ hover to show handler signatures from handlers.yaml
280285- Starlark's bounded nature (no while loops, no
281- recursion) means every saga maps to a finite flowchart
286+ recursion) means every saga maps to a finite graph
287+ with straightforward automatic layout (dagre-d3 or
288+ elkjs)
282289
283- The parser generates Mermaid markup as a string; the
284- component renders it with mermaid.js. This keeps the
285- rendering stateless and cacheable.
290+ ** Mermaid as the export format** : The parser also
291+ generates Mermaid markup as a string. This serves as
292+ the "Source" tab content in the preview/source toggle,
293+ giving readers a portable diagram they can paste into
294+ GitHub issues, ADRs, or Confluence.
286295
287296### Service Module Reference (Live from handlers.yaml)
288297
@@ -356,7 +365,7 @@ reference — are interconnected:
356365
357366``` text
358367+---------------------------+---------------------------+
359- | Starlark Editor | Flow Diagram (Mermaid) |
368+ | Starlark Editor | Flow Diagram (React Flow) |
360369| | |
361370| step("create_lien") <---|--- [create_lien] |
362371| lien = payment_order. | payment_order |
@@ -373,15 +382,17 @@ reference — are interconnected:
373382+-------------------------------------------------------+
374383```
375384
376- ** Interactions: **
385+ ** Interactions** (native with @ xyflow/react nodes):
377386
378- - Click a node in the Mermaid diagram → scroll to and
387+ - Click a node in the flow diagram → scroll to and
379388 highlight the corresponding ` step() ` block in the
380389 editor
381390- Click a ` service.method() ` call in the editor →
382- expand the API reference panel for that handler
391+ highlight the corresponding node and expand the API
392+ reference panel for that handler
383393- Hover a service badge in the flow diagram → tooltip
384394 showing handler signature and compensation chain
395+ - Zoom and pan the flow diagram for complex sagas
385396
386397This linked experience is what makes the cookbook
387398browser more than a static catalogue: it's an
@@ -402,7 +413,7 @@ reuse what they see.
402413
403414| Context | Preview tab | Source tab |
404415| ---------| ------------| -----------|
405- | Saga flow diagram | Rendered Mermaid flowchart | Generated Mermaid markup |
416+ | Saga flow diagram | Interactive @ xyflow/react graph | Generated Mermaid markup |
406417| Starlark editor | Syntax-highlighted code | Raw ` .star ` file content |
407418| Service module reference | Formatted API docs | Raw ` handlers.yaml ` block |
408419| UI component preview | Live rendered component | Component JSX + props |
@@ -574,48 +585,55 @@ page) is an open question — see OQ5.
574585
575586### Saga Flow Rendering
576587
577- ** Decision: Mermaid** — Parse ` .star ` → generate Mermaid
578- flowchart syntax → render with mermaid.js.
588+ ** Decision: @xyflow/react + Mermaid export** — Parse
589+ ` .star ` → build flow model → render interactively with
590+ @xyflow/react (preview tab) and generate Mermaid markup
591+ (source tab).
579592
580593Rationale:
581594
595+ - @xyflow/react is already in the bundle for the
596+ composition graph — zero incremental cost
597+ - Custom React nodes enable the linked experience
598+ natively: click to highlight code, hover for handler
599+ tooltips, zoom/pan for complex sagas
582600- Starlark's bounded structure (no while, no recursion)
583- maps perfectly to finite Mermaid flowcharts
584- - mermaid.js is well-maintained and renders natively
585- in GitHub/GitLab/Markdown tools
586- - The generated Mermaid markup is portable — it can be
587- embedded in ADRs, PRDs, or issue descriptions
588- - Mermaid handles layout automatically (no manual
589- positioning or force-directed physics)
590- - The parser output is a string (Mermaid markup), not
591- a component tree — trivially cacheable and testable
601+ maps perfectly to a finite directed graph
602+ - Layout via dagre-d3 or elkjs (same libraries Mermaid
603+ uses internally, exposed directly)
604+ - Mermaid markup is generated alongside for the source
605+ tab — portable to GitHub, ADRs, and issue descriptions
592606
593607Alternatives considered:
594608
595- - ** @xyflow/react ** : More interactive (drag, zoom) but
596- requires manual layout logic, produces non-portable
597- output, and the interactivity isn't needed for a
598- read-only flow view
609+ - ** Mermaid only** : Portable and auto-layout, but
610+ interactivity requires DOM manipulation on generated
611+ SVG. Click-to-highlight and hover tooltips are
612+ awkward to wire up. No incremental cost advantage
613+ since @xyflow/react is already bundled.
599614- ** Custom SVG** : Full design control but high
600615 implementation cost for layout algorithms
601616
602617### Composition Graph
603618
604- ** Decision: @xyflow/react (React Flow)** — For the
605- pattern relationship graph only (not saga flows).
619+ ** Decision: @xyflow/react (React Flow)** — Shared with
620+ saga flow rendering. The composition graph uses the
621+ same library with different node types and a
622+ force-directed layout instead of dagre.
606623
607624The composition graph benefits from interactivity
608625(click to navigate, hover to highlight neighbours,
609- filter by category) in a way that saga flows do not .
626+ filter by category).
610627Force-directed layout with ** elkjs** running in a web
611628worker for automatic positioning.
612629
613- This means two rendering approaches:
630+ Both views share @xyflow/react with different
631+ configurations:
614632
615- | View | Library | Why |
616- | ------| --------- | -----|
617- | Saga flow | mermaid.js | Linear flow, read-only, portable |
618- | Composition graph | @ xyflow/react | Interactive exploration, force layout |
633+ | View | Layout | Node type |
634+ | ------| --------| ------ -----|
635+ | Saga flow | dagre (top-down) | Step nodes with service badges |
636+ | Composition graph | Force-directed | Pattern nodes sized by complexity |
619637
620638## Open Questions
621639
@@ -628,10 +646,11 @@ This means two rendering approaches:
628646 handle all patterns without manual annotation; this
629647 question is about how far ahead to build.
630648
631- 2 . ** Graph library weight** : @xyflow/react adds ~ 150KB
632- gzipped. Is this acceptable for a staff-only page?
633- Alternative: render to SVG server-side and serve as
634- static images (loses interactivity).
649+ 2 . ** Layout engine** : @xyflow/react handles rendering
650+ but needs a layout engine. dagre-d3 is the standard
651+ choice (same as Mermaid uses). elkjs is an
652+ alternative with better compound node support.
653+ Decision deferred to implementation.
635654
6366553 . ** Component preview mocking** : UI component previews
637656 need sample data. Where does this come from?
0 commit comments