@milehimikey/em-portal 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -11
- package/dist/build.js +15 -1
- package/dist/build.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/pages/html.js +1 -0
- package/dist/pages/html.js.map +1 -1
- package/dist/pages/index.js +6 -1
- package/dist/pages/index.js.map +1 -1
- package/dist/pages/model.js +1 -0
- package/dist/pages/model.js.map +1 -1
- package/dist/pages/walkthrough.d.ts +11 -0
- package/dist/pages/walkthrough.js +325 -0
- package/dist/pages/walkthrough.js.map +1 -0
- package/dist/walkthroughSteps.d.ts +103 -0
- package/dist/walkthroughSteps.js +198 -0
- package/dist/walkthroughSteps.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,7 +14,9 @@ front and a way to navigate a system of several models, not a flat per-model sit
|
|
|
14
14
|
|
|
15
15
|
## Status
|
|
16
16
|
|
|
17
|
-
**0.
|
|
17
|
+
**0.2.0 — read-only multi-model browser + guided first read.** See
|
|
18
|
+
[What 0.1.0 includes](#what-01-includes) and [What 0.2.0 adds](#what-020-adds-the-guided-first-read)
|
|
19
|
+
below.
|
|
18
20
|
|
|
19
21
|
## Quickstart
|
|
20
22
|
|
|
@@ -25,9 +27,10 @@ npx em-portal build models/*/*.em -o site
|
|
|
25
27
|
|
|
26
28
|
```
|
|
27
29
|
site/
|
|
28
|
-
index.html # landing page: em status rollup (state up front)
|
|
30
|
+
index.html # landing page: em status rollup (state up front) + "First read" entry point
|
|
29
31
|
<model-key>/
|
|
30
32
|
index.html # model page: diagram + slice table
|
|
33
|
+
walkthrough.html # guided first read (0.2.0): teaches the notation on THIS model
|
|
31
34
|
diagram.svg
|
|
32
35
|
slices/
|
|
33
36
|
<slice-key>.html # slice page: diagram, doc, driftSignal, PR link
|
|
@@ -146,14 +149,9 @@ em-portal.
|
|
|
146
149
|
- Fully static, self-contained output; deterministic builds (same inputs -> byte-identical
|
|
147
150
|
site, verified in `test/build.test.ts`); no LLM anywhere.
|
|
148
151
|
|
|
149
|
-
**Deferred to 0.2.0** (MIL-174, "guided first read"): the onboarding/teaching layer — real
|
|
150
|
-
click-driven interaction that annotates a first-time reader's own model as they encounter each
|
|
151
|
-
element/pattern kind, rather than a glossary page. 0.1.0's pages are informative but not
|
|
152
|
-
teaching-aware.
|
|
153
|
-
|
|
154
152
|
**Deferred to 0.3.0** (MIL-175, "async review intake"): a "raise a question" affordance on a
|
|
155
|
-
slice page, triaged into an `issue "..."` marker through the normal ratified path.
|
|
156
|
-
read-only.
|
|
153
|
+
slice page, triaged into an `issue "..."` marker through the normal ratified path. The portal is
|
|
154
|
+
still read-only otherwise.
|
|
157
155
|
|
|
158
156
|
**Also deferred / open, not yet built**:
|
|
159
157
|
- A real GitHub Pages/bucket deploy workflow wired to a specific target repo — see
|
|
@@ -161,8 +159,55 @@ read-only.
|
|
|
161
159
|
and tests, since it has no real event models of its own to publish.
|
|
162
160
|
- Parallelizing the per-model `em export`/`em render` calls (they run sequentially today — see
|
|
163
161
|
[Open questions](#open-questions)).
|
|
164
|
-
- Any client-side JS (search, filtering, sort
|
|
165
|
-
`em catalog`.
|
|
162
|
+
- Any client-side JS beyond the walkthrough's own stepper (search, filtering, sort across the
|
|
163
|
+
slice table) — every other page is still plain static HTML, same posture as `em catalog`.
|
|
164
|
+
|
|
165
|
+
## What 0.2.0 adds: the guided first read
|
|
166
|
+
|
|
167
|
+
**MIL-174.** A first-time, non-technical reader clicks "First read" — prominent on the landing
|
|
168
|
+
page (pointed at the first model given to `em-portal build`) and on every model page (pointed at
|
|
169
|
+
that model) — and gets a self-paced, Next/Prev walkthrough that teaches the notation using **the
|
|
170
|
+
team's own model as every example**, never a generic glossary:
|
|
171
|
+
|
|
172
|
+
1. Time runs left to right — anchored to the model's own first slice.
|
|
173
|
+
2. A real **event**, **command**, and **view/read model** from this model, each with its
|
|
174
|
+
definition and a color-keyed callout naming the actual element.
|
|
175
|
+
3. **Personas & swimlanes** — this model's own declared personas and contexts.
|
|
176
|
+
4. The **four slice patterns** (State Change, State View, Automation, Translation), each taught
|
|
177
|
+
on the first real slice of that pattern this model has — a pattern the model doesn't use yet
|
|
178
|
+
is still explained, but says so plainly ("this model has no Translation slice yet") instead of
|
|
179
|
+
pointing at nothing.
|
|
180
|
+
5. The three **markers** (amber note = linked design doc, red issue = open question, teal
|
|
181
|
+
divergence = accepted deviation), each on a real marked-up element when this model has one.
|
|
182
|
+
6. **Status & ratification** — the draft → reviewed → ready-to-implement → implemented lifecycle,
|
|
183
|
+
a real example of this model's own slice status, that a named human ratifies (`ratifiedBy`),
|
|
184
|
+
and a link to the landing page's status rollup as the "is this healthy" view.
|
|
185
|
+
7. Where to go next: the slice table, a real slice page, the status rollup.
|
|
186
|
+
|
|
187
|
+
Every step is picked **deterministically at build time** from the model's own `em export` JSON
|
|
188
|
+
(first occurrence in model order — see `src/walkthroughSteps.ts`, unit-tested independently of any
|
|
189
|
+
HTML) and embedded in the generated page as a small JSON blob; a vanilla-JS stepper (no
|
|
190
|
+
dependency, inlined, no fetch of any other page) drives Next/Prev, the left/right arrow keys, a
|
|
191
|
+
numbered step nav, and a visible "Exit walkthrough" link/Escape key at every step. The step count
|
|
192
|
+
is always the same 14 regardless of what the model contains, so the progress indicator ("Step 4
|
|
193
|
+
of 14") never depends on how much of the model's own vocabulary happens to show up.
|
|
194
|
+
|
|
195
|
+
**Highlight mechanism** (verified against a real `em render` SVG, not assumed): `em`'s renderer
|
|
196
|
+
already tags every element's node group with `data-slice="<index>"` and embeds an
|
|
197
|
+
`<metadata id="em-slices">` block — the same mechanism `em watch --serve`'s own Review mode
|
|
198
|
+
storyboard uses to spotlight one slice at a time. The walkthrough inlines the model's own
|
|
199
|
+
`diagram.svg` directly into the page (not `<object>`-embedded, which isn't reliably
|
|
200
|
+
script-reachable from `file://`) and reuses that same `data-slice` attribute to dim every other
|
|
201
|
+
slice while a step is active — a real, intentional, already-load-bearing integration point, not a
|
|
202
|
+
new one invented for this feature.
|
|
203
|
+
|
|
204
|
+
There is deliberately **no per-element spotlight** inside the diagram: `em`'s SVG node ids come
|
|
205
|
+
from a model-wide, name-only slug (`makeId()` in the em repo), independent of `em export`'s own
|
|
206
|
+
stable `<sliceKey>/<kind>.<slug>` ref scheme and never published as a stable contract — relying on
|
|
207
|
+
it would mean treating an internal Graphviz `<title>` as an API. Single-element steps degrade
|
|
208
|
+
honestly instead: a color-keyed callout card (kind + name + a same-page link to the real element),
|
|
209
|
+
styled to match the diagram's own kind/marker colors, so it reads as the same visual language
|
|
210
|
+
rather than a second one.
|
|
166
211
|
|
|
167
212
|
## CI publish recipe
|
|
168
213
|
|
package/dist/build.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
// index.html landing page: em status rollup + model index
|
|
8
8
|
// <model-key>/
|
|
9
9
|
// index.html model page: diagram + slice table
|
|
10
|
+
// walkthrough.html guided first read (MIL-174) over this model
|
|
10
11
|
// diagram.svg
|
|
11
12
|
// slices/
|
|
12
13
|
// <slice-key>.html slice page: diagram, doc, driftSignal, PR link
|
|
@@ -15,7 +16,7 @@
|
|
|
15
16
|
// Every model gets its own output directory (mirroring `em catalog`'s
|
|
16
17
|
// convention) so slice keys from different models can never collide, even
|
|
17
18
|
// without a cross-file dedupe pass.
|
|
18
|
-
import { mkdir, writeFile } from "node:fs/promises";
|
|
19
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
19
20
|
import { basename, extname, join } from "node:path";
|
|
20
21
|
import { emExportJson, emRenderModel, emRenderSlice, emStatusJson } from "./em/run.js";
|
|
21
22
|
import { checkExportSchemaCompatible } from "./em/exportDoc.js";
|
|
@@ -26,6 +27,8 @@ import { dedupe, kebabSlug } from "./slug.js";
|
|
|
26
27
|
import { renderIndexPage } from "./pages/index.js";
|
|
27
28
|
import { renderModelPage } from "./pages/model.js";
|
|
28
29
|
import { renderSlicePage } from "./pages/slice.js";
|
|
30
|
+
import { renderWalkthroughPage } from "./pages/walkthrough.js";
|
|
31
|
+
import { buildWalkthroughSteps } from "./walkthroughSteps.js";
|
|
29
32
|
export async function buildPortal(files, opts) {
|
|
30
33
|
const t0 = performance.now();
|
|
31
34
|
if (files.length === 0)
|
|
@@ -90,6 +93,17 @@ export async function buildPortal(files, opts) {
|
|
|
90
93
|
slices: sliceSummaries,
|
|
91
94
|
});
|
|
92
95
|
await writeFile(join(modelDir, "index.html"), modelPage, "utf8");
|
|
96
|
+
// MIL-174: the guided first read — built from the SAME diagram.svg just
|
|
97
|
+
// written to disk (read back rather than re-rendered, so this never
|
|
98
|
+
// shells out to `em` a second time for a file already sitting there).
|
|
99
|
+
const diagramSvgSource = await readFile(join(modelDir, diagramFile), "utf8");
|
|
100
|
+
const walkthroughPage = renderWalkthroughPage({
|
|
101
|
+
modelKey,
|
|
102
|
+
modelName: doc.model.name ?? modelKey,
|
|
103
|
+
steps: buildWalkthroughSteps(doc),
|
|
104
|
+
diagramSvgSource,
|
|
105
|
+
});
|
|
106
|
+
await writeFile(join(modelDir, "walkthrough.html"), walkthroughPage, "utf8");
|
|
93
107
|
modelSummaries.push({
|
|
94
108
|
key: modelKey,
|
|
95
109
|
name: doc.model.name ?? modelKey,
|
package/dist/build.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,wEAAwE;AACxE,8EAA8E;AAC9E,yEAAyE;AACzE,EAAE;AACF,cAAc;AACd,8EAA8E;AAC9E,mBAAmB;AACnB,oEAAoE;AACpE,oBAAoB;AACpB,gBAAgB;AAChB,iFAAiF;AACjF,0BAA0B;AAC1B,EAAE;AACF,sEAAsE;AACtE,0EAA0E;AAC1E,oCAAoC;AAEpC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ const program = new Command();
|
|
|
7
7
|
program
|
|
8
8
|
.name("em-portal")
|
|
9
9
|
.description("Stakeholder-facing static portal for em event models")
|
|
10
|
-
.version("0.
|
|
10
|
+
.version("0.2.0");
|
|
11
11
|
program
|
|
12
12
|
.command("build")
|
|
13
13
|
.description("Build a static, read-only multi-model portal site from one or more .em model files")
|
package/dist/pages/html.js
CHANGED
|
@@ -53,6 +53,7 @@ const STYLE = `
|
|
|
53
53
|
.permalink a { color: inherit; }
|
|
54
54
|
code { background: #eee; padding: .05rem .3rem; border-radius: 3px; }
|
|
55
55
|
footer { max-width: 1000px; margin: 0 auto; padding: 0 1.25rem 2rem; font-size: 12px; color: #7b8794; }
|
|
56
|
+
.first-read-cta { display: inline-block; margin: .5rem 0 1rem; padding: .5rem 1rem; border-radius: 6px; background: #1f2933; color: #fff; text-decoration: none; font-weight: 600; }
|
|
56
57
|
`;
|
|
57
58
|
/** `homeHref` is always relative to the page being built so the whole site
|
|
58
59
|
* works opened straight off disk via `file://` or served from any subpath —
|
package/dist/pages/html.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/pages/html.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,2EAA2E;AAC3E,2EAA2E;AAC3E,qEAAqE;AACrE,wEAAwE;AACxE,+DAA+D;AAE/D,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,OAAO,CAAC;SACL,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,KAAK,GAAG
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/pages/html.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,2EAA2E;AAC3E,2EAA2E;AAC3E,qEAAqE;AACrE,wEAAwE;AACxE,+DAA+D;AAE/D,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,OAAO,CAAC;SACL,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Cb,CAAC;AAOF;;;;iDAIiD;AACjD,MAAM,UAAU,MAAM,CAAC,KAAa,EAAE,QAAgB,EAAE,QAAgB,EAAE,SAAkB,EAAE;IAC5F,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM;QAC7B,CAAC,CAAC,wBAAwB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS;QACrI,CAAC,CAAC,EAAE,CAAC;IACP,OAAO;;;;;WAKE,UAAU,CAAC,KAAK,CAAC;WACjB,KAAK;;;qBAGK,UAAU,CAAC,QAAQ,CAAC,kBAAkB,SAAS;;EAElE,QAAQ;;;;;CAKT,CAAC;AACF,CAAC"}
|
package/dist/pages/index.js
CHANGED
|
@@ -114,7 +114,12 @@ ${linkRows}
|
|
|
114
114
|
</tbody>
|
|
115
115
|
</table>`
|
|
116
116
|
: "";
|
|
117
|
-
const
|
|
117
|
+
const firstReadHref = summary.models[0] ? `${escapeHtml(summary.models[0].key)}/walkthrough.html` : null;
|
|
118
|
+
const firstReadBanner = firstReadHref
|
|
119
|
+
? ` <p><a class="first-read-cta" href="${firstReadHref}">First read: new here? Learn the notation on ${escapeHtml(summary.models[0].name)} →</a></p>`
|
|
120
|
+
: "";
|
|
121
|
+
const body = `${firstReadBanner}
|
|
122
|
+
${renderStatusSection(status)}
|
|
118
123
|
<h2>Models</h2>
|
|
119
124
|
<table>
|
|
120
125
|
<thead><tr><th>Model</th><th>Slices</th><th>Source</th></tr></thead>
|
package/dist/pages/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pages/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pages/index.ts"],"names":[],"mappings":"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"}
|
package/dist/pages/model.js
CHANGED
|
@@ -41,6 +41,7 @@ export function renderModelPage(args) {
|
|
|
41
41
|
.join("\n");
|
|
42
42
|
const body = ` <p><code>${escapeHtml(file)}</code></p>
|
|
43
43
|
<h1>${escapeHtml(modelName)}</h1>
|
|
44
|
+
<p><a class="first-read-cta" href="walkthrough.html">First read: learn the notation on this model →</a></p>
|
|
44
45
|
<div class="diagram-frame"><object class="diagram" type="image/svg+xml" data="${escapeHtml(diagramFile)}"></object></div>
|
|
45
46
|
<p class="full-diagram-link"><a href="${escapeHtml(diagramFile)}">Open full diagram →</a></p>
|
|
46
47
|
<table>
|
package/dist/pages/model.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/pages/model.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,sEAAsE;AACtE,0EAA0E;AAC1E,6EAA6E;AAE7E,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAE/C,2EAA2E;AAC3E,uEAAuE;AACvE,sEAAsE;AACtE,sEAAsE;AACtE,mCAAmC;AAEnC,MAAM,aAAa,GAAiC;IAClD,cAAc,EAAE,cAAc;IAC9B,YAAY,EAAE,YAAY;IAC1B,UAAU,EAAE,YAAY;IACxB,WAAW,EAAE,aAAa;IAC1B,YAAY,EAAE,cAAc;CAC7B,CAAC;AAEF,SAAS,WAAW,CAAC,MAAe,EAAE,MAAqB;IACzD,IAAI,CAAC,MAAM;QAAE,OAAO,mCAAmC,CAAC;IACxD,IAAI,CAAC,MAAM;QAAE,OAAO,oCAAoC,CAAC;IACzD,MAAM,GAAG,GAAG,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,OAAO,sBAAsB,GAAG,KAAK,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC;AACnE,CAAC;AAED,SAAS,UAAU,CAAC,KAAoB;IACtC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,MAAM,GAAG,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IACxF,OAAO,sBAAsB,GAAG,KAAK,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC;AAClE,CAAC;AAmBD,MAAM,UAAU,eAAe,CAAC,IAAmB;IACjD,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACtD,MAAM,IAAI,GAAG,MAAM;SAChB,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;8BACjB,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;8BAC7C,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;cACpD,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;cAC/B,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;YAC3B,CACP;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,IAAI,GAAG,gBAAgB,UAAU,CAAC,IAAI,CAAC;UACrC,UAAU,CAAC,SAAS,CAAC
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/pages/model.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,sEAAsE;AACtE,0EAA0E;AAC1E,6EAA6E;AAE7E,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAE/C,2EAA2E;AAC3E,uEAAuE;AACvE,sEAAsE;AACtE,sEAAsE;AACtE,mCAAmC;AAEnC,MAAM,aAAa,GAAiC;IAClD,cAAc,EAAE,cAAc;IAC9B,YAAY,EAAE,YAAY;IAC1B,UAAU,EAAE,YAAY;IACxB,WAAW,EAAE,aAAa;IAC1B,YAAY,EAAE,cAAc;CAC7B,CAAC;AAEF,SAAS,WAAW,CAAC,MAAe,EAAE,MAAqB;IACzD,IAAI,CAAC,MAAM;QAAE,OAAO,mCAAmC,CAAC;IACxD,IAAI,CAAC,MAAM;QAAE,OAAO,oCAAoC,CAAC;IACzD,MAAM,GAAG,GAAG,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,OAAO,sBAAsB,GAAG,KAAK,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC;AACnE,CAAC;AAED,SAAS,UAAU,CAAC,KAAoB;IACtC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,MAAM,GAAG,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IACxF,OAAO,sBAAsB,GAAG,KAAK,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC;AAClE,CAAC;AAmBD,MAAM,UAAU,eAAe,CAAC,IAAmB;IACjD,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACtD,MAAM,IAAI,GAAG,MAAM;SAChB,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;8BACjB,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;8BAC7C,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;cACpD,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;cAC/B,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;YAC3B,CACP;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,IAAI,GAAG,gBAAgB,UAAU,CAAC,IAAI,CAAC;UACrC,UAAU,CAAC,SAAS,CAAC;;oFAEqD,UAAU,CAAC,WAAW,CAAC;4CAC/D,UAAU,CAAC,WAAW,CAAC;;;;EAIjE,IAAI;;aAEO,CAAC;IAEZ,OAAO,MAAM,CAAC,GAAG,SAAS,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AACtG,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { WalkthroughStep } from "../walkthroughSteps.js";
|
|
2
|
+
export interface WalkthroughPageArgs {
|
|
3
|
+
modelKey: string;
|
|
4
|
+
modelName: string;
|
|
5
|
+
steps: WalkthroughStep[];
|
|
6
|
+
/** The model's own full `em render` diagram.svg, as raw file content —
|
|
7
|
+
* inlined into the page (not <object>-embedded) so the client-side
|
|
8
|
+
* spotlight script can reach its `data-slice` nodes. */
|
|
9
|
+
diagramSvgSource: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function renderWalkthroughPage(args: WalkthroughPageArgs): string;
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// MIL-174: the "guided first read" page — a self-paced Next/Prev walkthrough
|
|
3
|
+
// that teaches the notation using the team's own model as every example (see
|
|
4
|
+
// docs/decisions/mil-162-teachable-navigator.md's "guided first read"
|
|
5
|
+
// property). Every step's copy is built here from the structured picks
|
|
6
|
+
// src/walkthroughSteps.ts already made; this file only turns that into
|
|
7
|
+
// escaped HTML + the small inline JS stepper — no element/slice selection
|
|
8
|
+
// logic lives here.
|
|
9
|
+
//
|
|
10
|
+
// Highlight mechanism (verified against a real `em render` SVG, not
|
|
11
|
+
// assumed): `em`'s own renderer tags every element's node group with
|
|
12
|
+
// `data-slice="<sliceIndex>"` and embeds an `<metadata id="em-slices">`
|
|
13
|
+
// block (src/render/sliceOverlay.ts in the em repo) — the exact mechanism
|
|
14
|
+
// `em watch --serve`'s own Review mode storyboard uses to spotlight one
|
|
15
|
+
// slice at a time. That's a real, intentional, documented integration
|
|
16
|
+
// point, so this page reuses it at SLICE granularity: the model's own
|
|
17
|
+
// diagram.svg is inlined (not <object>-embedded — a cross-document
|
|
18
|
+
// <object> isn't reliably script-reachable from file://, and em's own
|
|
19
|
+
// viewer inlines for the same reason) and a `.wt-dim` class dims every
|
|
20
|
+
// `[data-slice]` node not matching the active step's slice.
|
|
21
|
+
//
|
|
22
|
+
// There is no equivalent per-ELEMENT hook: `em`'s SVG node ids come from
|
|
23
|
+
// `makeId(name)` (model/model.ts in the em repo) — a model-wide, name-only
|
|
24
|
+
// slug, deduped independently of `em export`'s own `<sliceKey>/<kind>.<slug>`
|
|
25
|
+
// ref scheme, and never surfaced as a stable public contract. Depending on
|
|
26
|
+
// it would mean parsing an internal Graphviz-emitted <title> as if it were
|
|
27
|
+
// an API. So single-element steps (a specific event/command/view, a single
|
|
28
|
+
// marked-up element) degrade honestly, per this ticket's own guidance: a
|
|
29
|
+
// color-keyed callout card (kind + name + a same-page link to the real
|
|
30
|
+
// element), not a fragile in-SVG spotlight — built from the same
|
|
31
|
+
// ElementExport-shaped data every other page already renders, just styled
|
|
32
|
+
// to match the diagram's own kind colors (src/emit/theme.ts /
|
|
33
|
+
// src/render/drawNotes.ts in the em repo) so it reads as "the same
|
|
34
|
+
// notation," not a second visual language.
|
|
35
|
+
import { escapeHtml, layout } from "./html.js";
|
|
36
|
+
const KIND_COLOR = {
|
|
37
|
+
ui: { fill: "#FFFFFF", stroke: "#9AA0A6" },
|
|
38
|
+
command: { fill: "#B8D0F5", stroke: "#2B6CB0" },
|
|
39
|
+
view: { fill: "#C6E7C6", stroke: "#2F855A" },
|
|
40
|
+
event: { fill: "#F6B26B", stroke: "#B7791F" },
|
|
41
|
+
automation: { fill: "#DBDBDB", stroke: "#5F6368" },
|
|
42
|
+
processor: { fill: "#DBDBDB", stroke: "#5F6368" },
|
|
43
|
+
saga: { fill: "#DBDBDB", stroke: "#5F6368" },
|
|
44
|
+
translation: { fill: "#DBDBDB", stroke: "#5F6368" },
|
|
45
|
+
};
|
|
46
|
+
const DEFAULT_KIND_COLOR = { fill: "#EEEEEE", stroke: "#9AA0A6" };
|
|
47
|
+
function kindColor(kind) {
|
|
48
|
+
return KIND_COLOR[kind] ?? DEFAULT_KIND_COLOR;
|
|
49
|
+
}
|
|
50
|
+
const MARKER_COLOR = {
|
|
51
|
+
note: { fill: "#F4C430", stroke: "#7A5200" },
|
|
52
|
+
issue: { fill: "#E53935", stroke: "#8B0000" },
|
|
53
|
+
divergence: { fill: "#26A69A", stroke: "#00695C" },
|
|
54
|
+
};
|
|
55
|
+
const MARKER_LABEL = {
|
|
56
|
+
note: "note",
|
|
57
|
+
issue: "issue",
|
|
58
|
+
divergence: "accepted divergence",
|
|
59
|
+
};
|
|
60
|
+
const MARKER_DEFINITION = {
|
|
61
|
+
note: "An amber folded corner marks a <strong>note</strong> — a linked design doc with more detail than fits on the diagram itself.",
|
|
62
|
+
issue: "A red folded corner marks an <strong>issue</strong> — an open question awaiting a ruling before this element's design is settled.",
|
|
63
|
+
divergence: "A teal folded corner marks a <strong>divergence</strong> — a reasoned, ratified deviation between the model and its implementation: already decided, not still open.",
|
|
64
|
+
};
|
|
65
|
+
const PATTERN_DEFINITION = {
|
|
66
|
+
"state-change": "A <strong>State Change</strong> slice is the classic write path: a UI issues a command, the system validates it, and — if accepted — records one or more events. <code>ui → command → event</code>.",
|
|
67
|
+
"state-view": "A <strong>State View</strong> slice is the classic read path: one or more events are replayed into a read model, which a UI then displays. <code>event → view → ui</code>.",
|
|
68
|
+
automation: "An <strong>Automation</strong> slice is the system reacting to its own events with no person in the loop — a processor watches a view (or events) and issues a command by itself.",
|
|
69
|
+
translation: "A <strong>Translation</strong> slice crosses a system or context boundary — adapting something external into a command, or pushing internal state out to another system.",
|
|
70
|
+
};
|
|
71
|
+
/** Every dynamic string this page inserts goes through escapeHtml; ref/slug
|
|
72
|
+
* values used inside an href are also escaped (they're safe URL characters
|
|
73
|
+
* by construction, but this file makes no exception for that). */
|
|
74
|
+
function elementCallout(pick, extra = "") {
|
|
75
|
+
const c = kindColor(pick.kind);
|
|
76
|
+
return `<div class="wt-callout" style="background:${c.fill};border-color:${c.stroke}">
|
|
77
|
+
<div class="wt-callout-head"><span class="wt-callout-kind">${escapeHtml(pick.kind)}</span><span class="wt-callout-name">${escapeHtml(pick.name)}</span></div>
|
|
78
|
+
<div class="wt-callout-slice">in <a href="slices/${escapeHtml(pick.sliceKey)}.html#${escapeHtml(pick.ref)}">${escapeHtml(pick.sliceName)}</a></div>
|
|
79
|
+
${extra}
|
|
80
|
+
</div>`;
|
|
81
|
+
}
|
|
82
|
+
function flowChip(pick) {
|
|
83
|
+
const c = kindColor(pick.kind);
|
|
84
|
+
return `<span class="wt-chip" style="background:${c.fill};border-color:${c.stroke}"><span class="wt-chip-kind">${escapeHtml(pick.kind)}</span> ${escapeHtml(pick.name)}</span>`;
|
|
85
|
+
}
|
|
86
|
+
function renderIntro(step) {
|
|
87
|
+
const anchor = step.firstSlice
|
|
88
|
+
? `<p>Your model's story starts with the <strong>${escapeHtml(step.firstSlice.name)}</strong> slice, spotlighted below — everything to its right happened later.</p>`
|
|
89
|
+
: `<p>This model doesn't have any slices yet — once it does, its story will read left to right here.</p>`;
|
|
90
|
+
return `<p>Time runs left to right. This whole picture is <strong>${escapeHtml(step.modelName)}</strong>'s business process, told as a timeline: earlier things happened on the left, later things on the right.</p>
|
|
91
|
+
${anchor}`;
|
|
92
|
+
}
|
|
93
|
+
const ELEMENT_DEFINITION = {
|
|
94
|
+
event: "An <strong>event</strong> is a fact that already happened — always named in the past tense (“Order Placed,” not “Place Order”). Once recorded, an event is never deleted or edited; if something changes, a later event records that.",
|
|
95
|
+
command: "A <strong>command</strong> is an intention — someone or something asking for a change. Unlike an event, a command can be <strong>rejected</strong>: the system might refuse it (bad data, a broken rule, no permission).",
|
|
96
|
+
view: "A <strong>view</strong> (also called a read model) is what someone reads — a screen, a report, a dashboard. A view is always built by replaying events; it never stores a new fact of its own.",
|
|
97
|
+
};
|
|
98
|
+
function renderElement(step) {
|
|
99
|
+
const def = `<p>${ELEMENT_DEFINITION[step.kind]}</p>`;
|
|
100
|
+
if (!step.element) {
|
|
101
|
+
return `${def}<p>This model doesn't have a${step.kind === "event" ? "n" : ""} ${escapeHtml(step.kind)} yet.</p>`;
|
|
102
|
+
}
|
|
103
|
+
const fromLine = step.kind === "view" && step.fromNames && step.fromNames.length > 0
|
|
104
|
+
? `<div class="wt-callout-slice">Built from: ${step.fromNames.map((n) => `<code>${escapeHtml(n)}</code>`).join(", ")}</div>`
|
|
105
|
+
: "";
|
|
106
|
+
return `${def}${elementCallout(step.element, fromLine)}`;
|
|
107
|
+
}
|
|
108
|
+
function renderSwimlanes(step) {
|
|
109
|
+
return `<p>Across the top of the diagram are <strong>persona</strong> rows — who acts: ${step.personas.map((p) => `<code>${escapeHtml(p)}</code>`).join(", ")}.</p>
|
|
110
|
+
<p>Below those are rows for each part of the system that records something — ${step.contexts.map((c) => `<code>${escapeHtml(c)}</code>`).join(", ")}.</p>
|
|
111
|
+
<p>Reading a diagram is reading down a column — what happened, all at once, across every row — as much as it's reading left to right.</p>`;
|
|
112
|
+
}
|
|
113
|
+
function renderPattern(step) {
|
|
114
|
+
const def = `<p>${PATTERN_DEFINITION[step.pattern]}</p>`;
|
|
115
|
+
if (!step.found || !step.slice) {
|
|
116
|
+
return `${def}<p>This model has no ${escapeHtml(step.patternLabel)} slice yet — you'll recognize the shape once one exists.</p>`;
|
|
117
|
+
}
|
|
118
|
+
const flow = step.elements.map(flowChip).join(' <span class="wt-arrow">→</span> ');
|
|
119
|
+
return `${def}<p>A real example from your model: the <strong>${escapeHtml(step.slice.name)}</strong> slice.</p>
|
|
120
|
+
<div class="wt-flow">${flow}</div>
|
|
121
|
+
<p><a href="slices/${escapeHtml(step.slice.key)}.html">Open this slice →</a></p>`;
|
|
122
|
+
}
|
|
123
|
+
function renderMarker(step) {
|
|
124
|
+
const def = `<p>${MARKER_DEFINITION[step.marker]}</p>`;
|
|
125
|
+
if (!step.found || !step.element) {
|
|
126
|
+
return `${def}<p>This model has no ${escapeHtml(MARKER_LABEL[step.marker])} yet.</p>`;
|
|
127
|
+
}
|
|
128
|
+
const c = MARKER_COLOR[step.marker];
|
|
129
|
+
const textHtml = step.text
|
|
130
|
+
? `<div class="wt-callout-slice">${escapeHtml(step.text)}</div>`
|
|
131
|
+
: "";
|
|
132
|
+
const callout = `<div class="wt-callout" style="background:${c.fill};border-color:${c.stroke}">
|
|
133
|
+
<div class="wt-callout-head"><span class="wt-callout-kind">${escapeHtml(step.element.kind)}</span><span class="wt-callout-name">${escapeHtml(step.element.name)}</span></div>
|
|
134
|
+
<div class="wt-callout-slice">in <a href="slices/${escapeHtml(step.element.sliceKey)}.html#${escapeHtml(step.element.ref)}">${escapeHtml(step.element.sliceName)}</a></div>
|
|
135
|
+
${textHtml}
|
|
136
|
+
</div>`;
|
|
137
|
+
return `${def}${callout}`;
|
|
138
|
+
}
|
|
139
|
+
function statusBadgeClass(status) {
|
|
140
|
+
return status === "implemented" ? "ok" : "";
|
|
141
|
+
}
|
|
142
|
+
function renderStatus(step) {
|
|
143
|
+
const lifecycle = `<p>Every slice doc moves through a lifecycle: <strong>draft</strong> → <strong>reviewed</strong> → <strong>ready-to-implement</strong> → <strong>implemented</strong>.</p>`;
|
|
144
|
+
const example = step.exampleStatus
|
|
145
|
+
? `<p>For example, your <strong>${escapeHtml(step.exampleStatus.sliceName)}</strong> slice is currently <span class="badge ${statusBadgeClass(step.exampleStatus.status)}">${escapeHtml(step.exampleStatus.status)}</span>.</p>`
|
|
146
|
+
: `<p>This model's slices don't have a recorded status yet — routine for an early model, not a defect.</p>`;
|
|
147
|
+
const ratify = `<p>A named human <strong>ratifies</strong> a slice doc — signs off that its current status is correct.</p>`;
|
|
148
|
+
const ratifyExample = step.exampleRatified
|
|
149
|
+
? `<p><strong>${escapeHtml(step.exampleRatified.sliceName)}</strong> was ratified by <strong>${escapeHtml(step.exampleRatified.ratifiedBy)}</strong>${step.exampleRatified.ratifiedOn ? ` on ${escapeHtml(step.exampleRatified.ratifiedOn)}` : ""}.</p>`
|
|
150
|
+
: `<p>None of this model's slices have been ratified yet — also routine early on.</p>`;
|
|
151
|
+
const rollup = `<p>The landing page's status rollup is the “is this healthy” view across every model — <a href="../index.html">see it</a>.</p>`;
|
|
152
|
+
return `${lifecycle}${example}${ratify}${ratifyExample}${rollup}`;
|
|
153
|
+
}
|
|
154
|
+
function renderNext(step, modelName) {
|
|
155
|
+
const links = [`<a class="wt-cta" href="index.html">Browse the slice table →</a>`];
|
|
156
|
+
if (step.firstSlice) {
|
|
157
|
+
links.push(`<a class="wt-cta" href="slices/${escapeHtml(step.firstSlice.key)}.html">Read a real slice: ${escapeHtml(step.firstSlice.name)} →</a>`);
|
|
158
|
+
}
|
|
159
|
+
links.push(`<a class="wt-cta" href="../index.html">Check system health →</a>`);
|
|
160
|
+
return `<p>That's the whole notation — four kinds of box, three kinds of marker. Everything else on this site is the same vocabulary, applied to the rest of <strong>${escapeHtml(modelName)}</strong>'s real slices.</p>
|
|
161
|
+
<div class="wt-next-links">${links.join("\n ")}</div>`;
|
|
162
|
+
}
|
|
163
|
+
function renderStepBody(step, modelName) {
|
|
164
|
+
switch (step.kind) {
|
|
165
|
+
case "intro":
|
|
166
|
+
return renderIntro(step);
|
|
167
|
+
case "event":
|
|
168
|
+
case "command":
|
|
169
|
+
case "view":
|
|
170
|
+
return renderElement(step);
|
|
171
|
+
case "swimlanes":
|
|
172
|
+
return renderSwimlanes(step);
|
|
173
|
+
case "pattern":
|
|
174
|
+
return renderPattern(step);
|
|
175
|
+
case "marker":
|
|
176
|
+
return renderMarker(step);
|
|
177
|
+
case "status":
|
|
178
|
+
return renderStatus(step);
|
|
179
|
+
case "next":
|
|
180
|
+
return renderNext(step, modelName);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/** Strips the XML/DOCTYPE preamble and any comments graphviz puts before its
|
|
184
|
+
* `<svg ...>` root (verified against a real `em render` output: `<?xml ...?>`
|
|
185
|
+
* + a `<!DOCTYPE svg ...>` block, neither of which is legal inside an HTML
|
|
186
|
+
* document body), keeping the `<svg>...</svg>` element itself — the part
|
|
187
|
+
* that carries the `data-slice` attributes and `em-slices` metadata this
|
|
188
|
+
* page's spotlight needs. Falls back to the raw source if the expected
|
|
189
|
+
* `<svg`/`</svg>` markers aren't found, rather than throwing — a
|
|
190
|
+
* malformed-looking diagram beats a failed build. */
|
|
191
|
+
function extractInlineSvg(svgSource) {
|
|
192
|
+
const start = svgSource.indexOf("<svg");
|
|
193
|
+
const end = svgSource.lastIndexOf("</svg>");
|
|
194
|
+
if (start === -1 || end === -1)
|
|
195
|
+
return svgSource;
|
|
196
|
+
return svgSource.slice(start, end + "</svg>".length).replace("<svg", '<svg id="wt-diagram"');
|
|
197
|
+
}
|
|
198
|
+
const WALKTHROUGH_STYLE = `
|
|
199
|
+
.wt-nav { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; margin: 1rem 0; }
|
|
200
|
+
.wt-nav button { font: inherit; padding: .5rem 1rem; border-radius: 6px; border: 1px solid #ccc; background: #fff; cursor: pointer; }
|
|
201
|
+
.wt-nav button:disabled { opacity: .4; cursor: default; }
|
|
202
|
+
.wt-nav button.wt-primary { background: #1f2933; color: #fff; border-color: #1f2933; }
|
|
203
|
+
.wt-nav a.wt-exit { margin-left: auto; font-size: 13px; }
|
|
204
|
+
.wt-dots { display: flex; flex-wrap: wrap; gap: .35rem; margin: 0 0 1rem; padding: 0; }
|
|
205
|
+
.wt-dots button { width: 1.6rem; height: 1.6rem; border-radius: 50%; border: 1px solid #ccc; background: #fff; font-size: 11px; cursor: pointer; padding: 0; }
|
|
206
|
+
.wt-dots button[aria-current="step"] { background: #1f2933; color: #fff; border-color: #1f2933; }
|
|
207
|
+
.wt-diagram-frame { position: relative; overflow: auto; }
|
|
208
|
+
.wt-diagram-frame svg [data-slice] { transition: opacity .15s ease; }
|
|
209
|
+
.wt-diagram-frame svg [data-slice].wt-dim { opacity: .15; }
|
|
210
|
+
@media (prefers-reduced-motion: reduce) {
|
|
211
|
+
.wt-diagram-frame svg [data-slice] { transition: none; }
|
|
212
|
+
}
|
|
213
|
+
.wt-panels { margin-top: 1rem; }
|
|
214
|
+
.wt-step h2 { margin-top: 0; }
|
|
215
|
+
.wt-callout { border: 2px solid; border-radius: 8px; padding: .6rem .8rem; margin: .75rem 0; max-width: 28rem; }
|
|
216
|
+
.wt-callout-head { display: flex; gap: .5rem; align-items: baseline; }
|
|
217
|
+
.wt-callout-kind { text-transform: uppercase; font-size: 11px; letter-spacing: .03em; font-weight: 700; color: #3f3f3f; }
|
|
218
|
+
.wt-callout-name { font-weight: 600; }
|
|
219
|
+
.wt-callout-slice { font-size: 13px; margin-top: .25rem; }
|
|
220
|
+
.wt-flow { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: .75rem 0; }
|
|
221
|
+
.wt-chip { border: 1px solid; border-radius: 999px; padding: .15rem .6rem; font-size: 13px; }
|
|
222
|
+
.wt-chip-kind { font-size: 10px; text-transform: uppercase; color: #3f3f3f; }
|
|
223
|
+
.wt-arrow { color: #7b8794; }
|
|
224
|
+
.wt-next-links { display: flex; flex-direction: column; gap: .5rem; margin-top: 1rem; }
|
|
225
|
+
.wt-cta { display: inline-block; padding: .6rem .9rem; border-radius: 6px; background: #1f2933; color: #fff; text-decoration: none; width: fit-content; }
|
|
226
|
+
`;
|
|
227
|
+
function stepperScript(exitHref) {
|
|
228
|
+
// Vanilla JS, inlined, no external assets — the whole page must work
|
|
229
|
+
// opened straight off disk via file:// (no fetch of any other page). Reads
|
|
230
|
+
// the JSON blob (#wt-data) for navigation-only metadata (id/title/
|
|
231
|
+
// sliceIndex per step); every step's actual copy is already server-rendered
|
|
232
|
+
// markup in .wt-step panels, so the JSON is deliberately small.
|
|
233
|
+
return `(function () {
|
|
234
|
+
var data = JSON.parse(document.getElementById('wt-data').textContent);
|
|
235
|
+
var panels = Array.prototype.slice.call(document.querySelectorAll('.wt-step'));
|
|
236
|
+
var svg = document.getElementById('wt-diagram');
|
|
237
|
+
var progressEl = document.getElementById('wt-progress');
|
|
238
|
+
var prevBtn = document.getElementById('wt-prev');
|
|
239
|
+
var nextBtn = document.getElementById('wt-next');
|
|
240
|
+
var dots = Array.prototype.slice.call(document.querySelectorAll('#wt-dots button'));
|
|
241
|
+
var reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
242
|
+
var idx = 0;
|
|
243
|
+
|
|
244
|
+
function applySpotlight(sliceIndex) {
|
|
245
|
+
if (!svg) return;
|
|
246
|
+
var nodes = svg.querySelectorAll('[data-slice]');
|
|
247
|
+
for (var i = 0; i < nodes.length; i++) {
|
|
248
|
+
var dim = sliceIndex !== null && nodes[i].getAttribute('data-slice') !== String(sliceIndex);
|
|
249
|
+
nodes[i].classList.toggle('wt-dim', dim);
|
|
250
|
+
}
|
|
251
|
+
if (sliceIndex !== null) {
|
|
252
|
+
var target = svg.querySelector('[data-slice="' + sliceIndex + '"]');
|
|
253
|
+
if (target && target.scrollIntoView) {
|
|
254
|
+
target.scrollIntoView({ behavior: reduceMotion ? 'auto' : 'smooth', block: 'nearest', inline: 'center' });
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function render() {
|
|
260
|
+
for (var i = 0; i < panels.length; i++) panels[i].hidden = i !== idx;
|
|
261
|
+
if (progressEl) progressEl.textContent = 'Step ' + (idx + 1) + ' of ' + data.length + ': ' + data[idx].title;
|
|
262
|
+
if (prevBtn) prevBtn.disabled = idx === 0;
|
|
263
|
+
if (nextBtn) nextBtn.textContent = idx === data.length - 1 ? 'Finish' : 'Next \\u2192';
|
|
264
|
+
for (var d = 0; d < dots.length; d++) dots[d].setAttribute('aria-current', d === idx ? 'step' : 'false');
|
|
265
|
+
applySpotlight(data[idx].sliceIndex);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function go(n) {
|
|
269
|
+
idx = Math.max(0, Math.min(data.length - 1, n));
|
|
270
|
+
render();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (prevBtn) prevBtn.addEventListener('click', function () { go(idx - 1); });
|
|
274
|
+
if (nextBtn) nextBtn.addEventListener('click', function () {
|
|
275
|
+
if (idx === data.length - 1) { window.location.href = ${JSON.stringify(exitHref)}; }
|
|
276
|
+
else { go(idx + 1); }
|
|
277
|
+
});
|
|
278
|
+
dots.forEach(function (btn, i) { btn.addEventListener('click', function () { go(i); }); });
|
|
279
|
+
document.addEventListener('keydown', function (e) {
|
|
280
|
+
if (e.target && (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA')) return;
|
|
281
|
+
if (e.key === 'ArrowRight') go(idx + 1);
|
|
282
|
+
else if (e.key === 'ArrowLeft') go(idx - 1);
|
|
283
|
+
else if (e.key === 'Escape') window.location.href = ${JSON.stringify(exitHref)};
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
render();
|
|
287
|
+
})();`;
|
|
288
|
+
}
|
|
289
|
+
export function renderWalkthroughPage(args) {
|
|
290
|
+
const { modelName, steps } = args;
|
|
291
|
+
const inlineSvg = extractInlineSvg(args.diagramSvgSource);
|
|
292
|
+
const dotsHtml = steps
|
|
293
|
+
.map((_, i) => `<button type="button" data-step-index="${i}" aria-current="${i === 0 ? "step" : "false"}">${i + 1}</button>`)
|
|
294
|
+
.join("");
|
|
295
|
+
const panelsHtml = steps
|
|
296
|
+
.map((s, i) => ` <section class="wt-step" id="wt-step-${escapeHtml(s.id)}" ${i === 0 ? "" : "hidden"}>
|
|
297
|
+
<h2>${escapeHtml(s.title)}</h2>
|
|
298
|
+
${renderStepBody(s, modelName)}
|
|
299
|
+
</section>`)
|
|
300
|
+
.join("\n");
|
|
301
|
+
// Navigation-only metadata for the client script — title/sliceIndex per
|
|
302
|
+
// step, nothing that duplicates the panel markup above.
|
|
303
|
+
const navData = steps.map((s) => ({ id: s.id, title: s.title, sliceIndex: s.sliceIndex }));
|
|
304
|
+
const body = ` <style>${WALKTHROUGH_STYLE}</style>
|
|
305
|
+
<p class="pattern">Guided first read · ${escapeHtml(modelName)}</p>
|
|
306
|
+
<h1>First read: ${escapeHtml(modelName)}</h1>
|
|
307
|
+
<p id="wt-progress" class="pattern" aria-live="polite">Step 1 of ${steps.length}: ${escapeHtml(steps[0]?.title ?? "")}</p>
|
|
308
|
+
<div class="wt-nav">
|
|
309
|
+
<button id="wt-prev" type="button" disabled>← Prev</button>
|
|
310
|
+
<button id="wt-next" type="button" class="wt-primary">Next →</button>
|
|
311
|
+
<a class="wt-exit" href="index.html">Exit walkthrough</a>
|
|
312
|
+
</div>
|
|
313
|
+
<nav class="wt-dots" id="wt-dots" aria-label="Steps">${dotsHtml}</nav>
|
|
314
|
+
<div class="diagram-frame wt-diagram-frame">${inlineSvg}</div>
|
|
315
|
+
<div class="wt-panels">
|
|
316
|
+
${panelsHtml}
|
|
317
|
+
</div>
|
|
318
|
+
<script type="application/json" id="wt-data">${JSON.stringify(navData)}</script>
|
|
319
|
+
<script>${stepperScript("index.html")}</script>`;
|
|
320
|
+
return layout(`First read: ${modelName} — em portal`, body, "../index.html", [
|
|
321
|
+
{ label: modelName, href: "index.html" },
|
|
322
|
+
{ label: "First read", href: "." },
|
|
323
|
+
]);
|
|
324
|
+
}
|
|
325
|
+
//# sourceMappingURL=walkthrough.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walkthrough.js","sourceRoot":"","sources":["../../src/pages/walkthrough.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { ExportDoc, SlicePattern } from "./em/exportDoc.js";
|
|
2
|
+
/** The four canonical patterns taught by the walkthrough, in the order
|
|
3
|
+
* they're introduced — "unclassified" (a slice em couldn't classify) is
|
|
4
|
+
* never one of them; it isn't a pattern a reader should learn as normal
|
|
5
|
+
* vocabulary. */
|
|
6
|
+
export declare const TAUGHT_PATTERNS: readonly SlicePattern[];
|
|
7
|
+
export declare const PATTERN_LABEL: Record<SlicePattern, string>;
|
|
8
|
+
export interface WalkthroughElementPick {
|
|
9
|
+
ref: string;
|
|
10
|
+
kind: string;
|
|
11
|
+
name: string;
|
|
12
|
+
sliceKey: string;
|
|
13
|
+
sliceName: string;
|
|
14
|
+
sliceIndex: number;
|
|
15
|
+
}
|
|
16
|
+
interface BaseStep {
|
|
17
|
+
id: string;
|
|
18
|
+
title: string;
|
|
19
|
+
/** Which slice (by `EmSlice.index`) the inline diagram should spotlight
|
|
20
|
+
* while this step is active, or `null` to show the whole diagram at full
|
|
21
|
+
* opacity — used for steps that aren't anchored to one slice (swimlanes,
|
|
22
|
+
* status, where-to-go-next). */
|
|
23
|
+
sliceIndex: number | null;
|
|
24
|
+
}
|
|
25
|
+
export interface IntroStep extends BaseStep {
|
|
26
|
+
kind: "intro";
|
|
27
|
+
modelName: string;
|
|
28
|
+
firstSlice: {
|
|
29
|
+
key: string;
|
|
30
|
+
name: string;
|
|
31
|
+
index: number;
|
|
32
|
+
} | null;
|
|
33
|
+
}
|
|
34
|
+
export interface ElementStep extends BaseStep {
|
|
35
|
+
kind: "event" | "command" | "view";
|
|
36
|
+
element: WalkthroughElementPick | null;
|
|
37
|
+
/** `view` only: the names this view's `from` clause cites, when present —
|
|
38
|
+
* "always built from events" is easier to believe pointing at the actual
|
|
39
|
+
* source name(s). */
|
|
40
|
+
fromNames: string[] | null;
|
|
41
|
+
}
|
|
42
|
+
export interface SwimlanesStep extends BaseStep {
|
|
43
|
+
kind: "swimlanes";
|
|
44
|
+
personas: string[];
|
|
45
|
+
contexts: string[];
|
|
46
|
+
}
|
|
47
|
+
export interface PatternStep extends BaseStep {
|
|
48
|
+
kind: "pattern";
|
|
49
|
+
pattern: SlicePattern;
|
|
50
|
+
patternLabel: string;
|
|
51
|
+
found: boolean;
|
|
52
|
+
slice: {
|
|
53
|
+
key: string;
|
|
54
|
+
name: string;
|
|
55
|
+
index: number;
|
|
56
|
+
} | null;
|
|
57
|
+
/** The matched slice's own elements, in declaration order, so the
|
|
58
|
+
* renderer can narrate its actual flow (e.g. ui -> command -> event) —
|
|
59
|
+
* empty when `found` is false. */
|
|
60
|
+
elements: WalkthroughElementPick[];
|
|
61
|
+
}
|
|
62
|
+
export type MarkerKind = "note" | "issue" | "divergence";
|
|
63
|
+
export interface MarkerStep extends BaseStep {
|
|
64
|
+
kind: "marker";
|
|
65
|
+
marker: MarkerKind;
|
|
66
|
+
found: boolean;
|
|
67
|
+
element: WalkthroughElementPick | null;
|
|
68
|
+
/** The marker's own text: the note's doc path, the issue's question, or
|
|
69
|
+
* the divergence's rationale. */
|
|
70
|
+
text: string | null;
|
|
71
|
+
}
|
|
72
|
+
export interface StatusStep extends BaseStep {
|
|
73
|
+
kind: "status";
|
|
74
|
+
exampleStatus: {
|
|
75
|
+
sliceKey: string;
|
|
76
|
+
sliceName: string;
|
|
77
|
+
status: string;
|
|
78
|
+
} | null;
|
|
79
|
+
exampleRatified: {
|
|
80
|
+
sliceKey: string;
|
|
81
|
+
sliceName: string;
|
|
82
|
+
ratifiedBy: string;
|
|
83
|
+
ratifiedOn: string | null;
|
|
84
|
+
} | null;
|
|
85
|
+
}
|
|
86
|
+
export interface NextStep extends BaseStep {
|
|
87
|
+
kind: "next";
|
|
88
|
+
firstSlice: {
|
|
89
|
+
key: string;
|
|
90
|
+
name: string;
|
|
91
|
+
} | null;
|
|
92
|
+
}
|
|
93
|
+
export type WalkthroughStep = IntroStep | ElementStep | SwimlanesStep | PatternStep | MarkerStep | StatusStep | NextStep;
|
|
94
|
+
/** Derives the full, ordered "guided first read" step sequence for one
|
|
95
|
+
* model — always the same 14 steps in the same order (intro, event,
|
|
96
|
+
* command, view, swimlanes, the 4 patterns, the 3 markers, status, next),
|
|
97
|
+
* regardless of what the model contains, so the progress indicator ("Step
|
|
98
|
+
* N of 14") never has to depend on how much of the model's own vocabulary
|
|
99
|
+
* actually shows up. What differs per model is only each step's content —
|
|
100
|
+
* which real element/slice it points at, or, honestly, that it has none
|
|
101
|
+
* yet. */
|
|
102
|
+
export declare function buildWalkthroughSteps(doc: ExportDoc): WalkthroughStep[];
|
|
103
|
+
export {};
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// MIL-174: build-time derivation of the "guided first read" walkthrough's
|
|
3
|
+
// steps — a pure, deterministic function of one model's own `em export`
|
|
4
|
+
// document. This is deliberately separate from src/pages/walkthrough.ts
|
|
5
|
+
// (which turns these into HTML + the client-side stepper's JSON blob), the
|
|
6
|
+
// same split crossModel.ts (pure join) / pages/index.ts (HTML) already uses:
|
|
7
|
+
// keeps "which element did we pick, and why" unit-testable without a DOM or
|
|
8
|
+
// an HTML string to grep.
|
|
9
|
+
//
|
|
10
|
+
// Per docs/decisions/mil-162-teachable-navigator.md's "guided first read"
|
|
11
|
+
// property, every example the walkthrough teaches with is a REAL element
|
|
12
|
+
// from the team's own model, picked deterministically — first occurrence in
|
|
13
|
+
// model order (slice order, then element-declaration order within a slice),
|
|
14
|
+
// never randomly and never hardcoded copy. A model with no matching element
|
|
15
|
+
// (a pattern this model doesn't use, a marker kind it never sets, or a model
|
|
16
|
+
// with zero slices at all) degrades honestly: the step still appears (so the
|
|
17
|
+
// reader learns the full vocabulary and the progress count stays stable),
|
|
18
|
+
// but its body says so instead of pointing at nothing — never a broken
|
|
19
|
+
// reference, never a silently-vanished step.
|
|
20
|
+
/** The four canonical patterns taught by the walkthrough, in the order
|
|
21
|
+
* they're introduced — "unclassified" (a slice em couldn't classify) is
|
|
22
|
+
* never one of them; it isn't a pattern a reader should learn as normal
|
|
23
|
+
* vocabulary. */
|
|
24
|
+
export const TAUGHT_PATTERNS = ["state-change", "state-view", "automation", "translation"];
|
|
25
|
+
export const PATTERN_LABEL = {
|
|
26
|
+
"state-change": "State Change",
|
|
27
|
+
"state-view": "State View",
|
|
28
|
+
automation: "Automation",
|
|
29
|
+
translation: "Translation",
|
|
30
|
+
unclassified: "Unclassified",
|
|
31
|
+
};
|
|
32
|
+
function toPick(el, slice) {
|
|
33
|
+
return {
|
|
34
|
+
ref: el.ref,
|
|
35
|
+
kind: el.kind,
|
|
36
|
+
name: el.name,
|
|
37
|
+
sliceKey: slice.key,
|
|
38
|
+
sliceName: slice.name,
|
|
39
|
+
sliceIndex: slice.index,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** First element of `kind` in model order (slice order, then declaration
|
|
43
|
+
* order within the slice) — the deterministic "pick a real example" rule
|
|
44
|
+
* every step in this module follows. `null` for a model with no element of
|
|
45
|
+
* that kind at all (including a model with zero slices). */
|
|
46
|
+
function firstElementOfKind(model, kind) {
|
|
47
|
+
for (const slice of model.slices) {
|
|
48
|
+
for (const el of slice.elements) {
|
|
49
|
+
if (el.kind === kind)
|
|
50
|
+
return { el, slice };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
/** First slice (in model order) classified as `pattern`, or `null` if this
|
|
56
|
+
* model has none — the "skip patterns the model doesn't contain, saying
|
|
57
|
+
* so" case. */
|
|
58
|
+
function firstSliceOfPattern(model, pattern) {
|
|
59
|
+
return model.slices.find((s) => s.pattern === pattern) ?? null;
|
|
60
|
+
}
|
|
61
|
+
/** First element (model order) carrying a non-null value for `field`, or
|
|
62
|
+
* `null` if no element in this model sets that marker at all. */
|
|
63
|
+
function firstElementWithMarker(model, field) {
|
|
64
|
+
for (const slice of model.slices) {
|
|
65
|
+
for (const el of slice.elements) {
|
|
66
|
+
if (el[field])
|
|
67
|
+
return { el, slice };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
function buildIntroStep(model) {
|
|
73
|
+
const first = model.slices[0] ?? null;
|
|
74
|
+
return {
|
|
75
|
+
id: "intro",
|
|
76
|
+
kind: "intro",
|
|
77
|
+
title: "Reading the picture",
|
|
78
|
+
sliceIndex: first?.index ?? null,
|
|
79
|
+
modelName: model.name ?? "this model",
|
|
80
|
+
firstSlice: first ? { key: first.key, name: first.name, index: first.index } : null,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function buildElementStep(model, kind) {
|
|
84
|
+
const found = firstElementOfKind(model, kind);
|
|
85
|
+
const titleByKind = {
|
|
86
|
+
event: "Event",
|
|
87
|
+
command: "Command",
|
|
88
|
+
view: "View / read model",
|
|
89
|
+
};
|
|
90
|
+
return {
|
|
91
|
+
id: kind,
|
|
92
|
+
kind,
|
|
93
|
+
title: titleByKind[kind],
|
|
94
|
+
sliceIndex: found?.slice.index ?? null,
|
|
95
|
+
element: found ? toPick(found.el, found.slice) : null,
|
|
96
|
+
fromNames: kind === "view" && found?.el.from ? found.el.from.map((f) => f.name) : null,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function buildSwimlanesStep(model) {
|
|
100
|
+
return {
|
|
101
|
+
id: "swimlanes",
|
|
102
|
+
kind: "swimlanes",
|
|
103
|
+
title: "Personas & swimlanes",
|
|
104
|
+
sliceIndex: null,
|
|
105
|
+
personas: model.personas,
|
|
106
|
+
contexts: model.contexts,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function buildPatternSteps(model) {
|
|
110
|
+
return TAUGHT_PATTERNS.map((pattern) => {
|
|
111
|
+
const slice = firstSliceOfPattern(model, pattern);
|
|
112
|
+
return {
|
|
113
|
+
id: `pattern-${pattern}`,
|
|
114
|
+
kind: "pattern",
|
|
115
|
+
title: `Pattern: ${PATTERN_LABEL[pattern]}`,
|
|
116
|
+
sliceIndex: slice?.index ?? null,
|
|
117
|
+
pattern,
|
|
118
|
+
patternLabel: PATTERN_LABEL[pattern],
|
|
119
|
+
found: slice !== null,
|
|
120
|
+
slice: slice ? { key: slice.key, name: slice.name, index: slice.index } : null,
|
|
121
|
+
elements: slice ? slice.elements.map((el) => toPick(el, slice)) : [],
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function buildMarkerSteps(model) {
|
|
126
|
+
const markers = [
|
|
127
|
+
{ marker: "note", field: "note", title: "Marker: linked design doc" },
|
|
128
|
+
{ marker: "issue", field: "issue", title: "Marker: open question" },
|
|
129
|
+
{ marker: "divergence", field: "divergence", title: "Marker: accepted divergence" },
|
|
130
|
+
];
|
|
131
|
+
return markers.map(({ marker, field, title }) => {
|
|
132
|
+
const found = firstElementWithMarker(model, field);
|
|
133
|
+
return {
|
|
134
|
+
id: `marker-${marker}`,
|
|
135
|
+
kind: "marker",
|
|
136
|
+
title,
|
|
137
|
+
sliceIndex: found?.slice.index ?? null,
|
|
138
|
+
marker,
|
|
139
|
+
found: found !== null,
|
|
140
|
+
element: found ? toPick(found.el, found.slice) : null,
|
|
141
|
+
text: found ? found.el[field] : null,
|
|
142
|
+
};
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function buildStatusStep(model) {
|
|
146
|
+
const withStatus = model.slices.find((s) => s.doc.found && s.doc.status);
|
|
147
|
+
const withRatification = model.slices.find((s) => s.doc.found && s.doc.ratifiedBy);
|
|
148
|
+
return {
|
|
149
|
+
id: "status",
|
|
150
|
+
kind: "status",
|
|
151
|
+
title: "Status & ratification",
|
|
152
|
+
sliceIndex: null,
|
|
153
|
+
exampleStatus: withStatus
|
|
154
|
+
? { sliceKey: withStatus.key, sliceName: withStatus.name, status: withStatus.doc.status }
|
|
155
|
+
: null,
|
|
156
|
+
exampleRatified: withRatification
|
|
157
|
+
? {
|
|
158
|
+
sliceKey: withRatification.key,
|
|
159
|
+
sliceName: withRatification.name,
|
|
160
|
+
ratifiedBy: withRatification.doc.ratifiedBy,
|
|
161
|
+
ratifiedOn: withRatification.doc.ratifiedOn,
|
|
162
|
+
}
|
|
163
|
+
: null,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function buildNextStep(model) {
|
|
167
|
+
const first = model.slices[0] ?? null;
|
|
168
|
+
return {
|
|
169
|
+
id: "next",
|
|
170
|
+
kind: "next",
|
|
171
|
+
title: "Where to go next",
|
|
172
|
+
sliceIndex: null,
|
|
173
|
+
firstSlice: first ? { key: first.key, name: first.name } : null,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/** Derives the full, ordered "guided first read" step sequence for one
|
|
177
|
+
* model — always the same 14 steps in the same order (intro, event,
|
|
178
|
+
* command, view, swimlanes, the 4 patterns, the 3 markers, status, next),
|
|
179
|
+
* regardless of what the model contains, so the progress indicator ("Step
|
|
180
|
+
* N of 14") never has to depend on how much of the model's own vocabulary
|
|
181
|
+
* actually shows up. What differs per model is only each step's content —
|
|
182
|
+
* which real element/slice it points at, or, honestly, that it has none
|
|
183
|
+
* yet. */
|
|
184
|
+
export function buildWalkthroughSteps(doc) {
|
|
185
|
+
const model = doc.model;
|
|
186
|
+
return [
|
|
187
|
+
buildIntroStep(model),
|
|
188
|
+
buildElementStep(model, "event"),
|
|
189
|
+
buildElementStep(model, "command"),
|
|
190
|
+
buildElementStep(model, "view"),
|
|
191
|
+
buildSwimlanesStep(model),
|
|
192
|
+
...buildPatternSteps(model),
|
|
193
|
+
...buildMarkerSteps(model),
|
|
194
|
+
buildStatusStep(model),
|
|
195
|
+
buildNextStep(model),
|
|
196
|
+
];
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=walkthroughSteps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walkthroughSteps.js","sourceRoot":"","sources":["../src/walkthroughSteps.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED