@mantaq/viz 0.0.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.
@@ -0,0 +1,55 @@
1
+ // src/html.ts
2
+ /** Element id the standalone page carries its document in (read by `mountEmbedded`). */
3
+ const DOCUMENT_ELEMENT_ID = "mantaq-viz-document";
4
+ function escapeText(text) {
5
+ return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;");
6
+ }
7
+ /** Inline script or style text may not close its own element early. */
8
+ function inline(text, tag) {
9
+ return text.replaceAll(`</${tag}`, `<\\/${tag}`);
10
+ }
11
+ /**
12
+ * One HTML file that shows `document` with no server and no network: the
13
+ * viewer bundle, its CSS and the document are all inlined.
14
+ */
15
+ function standaloneHtml(parts) {
16
+ return [
17
+ "<!doctype html>",
18
+ "<html lang=\"en\">",
19
+ "<head>",
20
+ "<meta charset=\"utf-8\" />",
21
+ "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />",
22
+ `<title>${escapeText(parts.title)}</title>`,
23
+ `<style>${inline(parts.css, "style")}</style>`,
24
+ "</head>",
25
+ "<body class=\"viz\">",
26
+ "<main id=\"app\"></main>",
27
+ `<script type="application/json" id="${DOCUMENT_ELEMENT_ID}">${parts.document.replaceAll("<", "\\u003c")}<\/script>`,
28
+ `<script>${inline(parts.script, "script")}<\/script>`,
29
+ "</body>",
30
+ "</html>",
31
+ ""
32
+ ].join("\n");
33
+ }
34
+ /** Custom HMR event `@mantaq/inspect/vite` sends after a machine file changes. */
35
+ const UPDATE_EVENT = "mantaq:viz-update";
36
+ /** The live page: the viewer as a module, fetching the document from `source`. */
37
+ function livePageHtml(parts) {
38
+ return [
39
+ "<!doctype html>",
40
+ "<html lang=\"en\">",
41
+ "<head>",
42
+ "<meta charset=\"utf-8\" />",
43
+ "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />",
44
+ `<title>${escapeText(parts.title)}</title>`,
45
+ `<style>${inline(parts.css, "style")}</style>`,
46
+ "</head>",
47
+ "<body class=\"viz\">",
48
+ `<main id="app" data-src="${escapeText(parts.source)}"></main>`,
49
+ `<script type="module" src="${escapeText(parts.entry)}"><\/script>`,
50
+ "</body>",
51
+ "</html>",
52
+ ""
53
+ ].join("\n");
54
+ }
55
+ export { standaloneHtml as i, UPDATE_EVENT as n, livePageHtml as r, DOCUMENT_ELEMENT_ID as t };
@@ -0,0 +1,82 @@
1
+ import { A as coveredByAny, C as VizLiveState, D as VizMachine, E as VizLocation, M as scopeOf, O as VizState, S as VizLiveOutcome, T as VizLiveTimer, _ as VizExplanation, a as VIZ_SCHEMA_VERSION, b as VizFuzzSequence, c as VizComparison, d as VizDriver, f as VizEdge, g as VizEvent, h as VizEffect, i as ANY_STATE, j as isAnyState, k as VizStep, l as VizCoverage, m as VizEdgeOrigin, n as validateViz, o as VizBranch, p as VizEdgeKind, r as VizIssue, s as VizBranchTarget, t as parseViz, u as VizDocument, v as VizFuzz, w as VizLiveStep, x as VizJson, y as VizFuzzError } from "./validate-C_EXBtem.mjs";
2
+ /** Byte-stable JSON: sorted object keys, two-space indent, trailing newline. */
3
+ export declare function serializeViz(document: VizDocument): string;
4
+ /**
5
+ * Walking the drawn graph by hand: no actor runs. A path is the edges taken
6
+ * from the initial state, each with the state it led to. Guards are not
7
+ * evaluated, so a path shows what the declarations allow, not what a run does.
8
+ */
9
+ interface ExploreStep {
10
+ edge: string;
11
+ to: string;
12
+ }
13
+ /**
14
+ * `input`: sent from outside. `effect`: sent by an effect of the current
15
+ * state (its `sends` list). `internal`: any other internal event (another
16
+ * actor, a timer the effect did not declare, a test injecting it).
17
+ */
18
+ type MoveGroup = "input" | "effect" | "internal";
19
+ interface Move {
20
+ edge: VizEdge;
21
+ /** States this edge can lead to; several for an undetermined edge, none when unknown. */
22
+ targets: string[];
23
+ group: MoveGroup;
24
+ /** Effects of the current state whose `sends` list this event. */
25
+ sentBy: string[];
26
+ }
27
+ /**
28
+ * Every edge an event can take out of `state`: its own registrations and the
29
+ * `onAny` ones. A final state has none: the actor has stopped.
30
+ */
31
+ export declare function movesFrom(machine: VizMachine, state: string): Move[];
32
+ /** Where a path ends: the last step's target, or the initial state. */
33
+ export declare function stateAfter(machine: VizMachine, path: ReadonlyArray<ExploreStep>): string | null;
34
+ /** Events an effect of `state` declares in `sends` that no handler in `state` takes. */
35
+ export declare function unhandledSends(machine: VizMachine, state: string): Array<{
36
+ effect: string;
37
+ event: string;
38
+ }>;
39
+ /** One step as text for a URL: the edge id, plus `~target` when the edge has no single target. */
40
+ export declare function encodeStep(machine: VizMachine, step: ExploreStep): string;
41
+ /**
42
+ * Rebuild a path from encoded steps (e.g. `?step=` in a shared link). Stops at
43
+ * the first step the graph does not allow from where the path has got to, so
44
+ * a link from an older document still opens at its last valid point.
45
+ */
46
+ export declare function decodePath(machine: VizMachine, encoded: ReadonlyArray<string>): ExploreStep[];
47
+ interface RoutingWarning {
48
+ machine: string;
49
+ event: string;
50
+ message: string;
51
+ }
52
+ /**
53
+ * `onAny` handlers that pick their target from the current state. Drawn from
54
+ * `*`, they claim every declared target from every state; per-state `m.on`
55
+ * registrations would draw the exact source/target pairs.
56
+ */
57
+ export declare function routingWarnings(machine: VizMachine): RoutingWarning[];
58
+ /** Element id the standalone page carries its document in (read by `mountEmbedded`). */
59
+ export declare const DOCUMENT_ELEMENT_ID = "mantaq-viz-document";
60
+ /**
61
+ * One HTML file that shows `document` with no server and no network: the
62
+ * viewer bundle, its CSS and the document are all inlined.
63
+ */
64
+ export declare function standaloneHtml(parts: {
65
+ title: string;
66
+ /** Built viewer bundle (classic script) whose entry is `viewer/standalone.ts`. */
67
+ script: string;
68
+ css: string;
69
+ /** Serialized viz document. */
70
+ document: string;
71
+ }): string;
72
+ /** Custom HMR event `@mantaq/inspect/vite` sends after a machine file changes. */
73
+ export declare const UPDATE_EVENT = "mantaq:viz-update";
74
+ /** The live page: the viewer as a module, fetching the document from `source`. */
75
+ export declare function livePageHtml(parts: {
76
+ title: string;
77
+ source: string;
78
+ entry: string;
79
+ /** Stylesheet text, inlined: the built entry carries no CSS of its own. */
80
+ css: string;
81
+ }): string;
82
+ export { ANY_STATE, type ExploreStep, type Move, type MoveGroup, type RoutingWarning, VIZ_SCHEMA_VERSION, VizBranch, VizBranchTarget, VizComparison, VizCoverage, VizDocument, VizDriver, VizEdge, VizEdgeKind, VizEdgeOrigin, VizEffect, VizEvent, VizExplanation, VizFuzz, VizFuzzError, VizFuzzSequence, type VizIssue, VizJson, VizLiveOutcome, VizLiveState, VizLiveStep, VizLiveTimer, VizLocation, VizMachine, VizState, VizStep, coveredByAny, isAnyState, parseViz, scopeOf, validateViz };
package/dist/index.mjs ADDED
@@ -0,0 +1,13 @@
1
+ import { a as encodeStep, c as stateAfter, d as validateViz, f as ANY_STATE, g as scopeOf, h as isAnyState, l as unhandledSends, m as coveredByAny, o as movesFrom, p as VIZ_SCHEMA_VERSION, r as decodePath, t as routingWarnings, u as parseViz } from "./routing-xXYo05xv.mjs";
2
+ import { i as standaloneHtml, n as UPDATE_EVENT, r as livePageHtml, t as DOCUMENT_ELEMENT_ID } from "./html-BfvuzJs6.mjs";
3
+ // src/serialize.ts
4
+ function sortKeys(value) {
5
+ if (Array.isArray(value)) return value.map(sortKeys);
6
+ if (typeof value !== "object" || value === null) return value;
7
+ return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, child]) => [key, sortKeys(child)]));
8
+ }
9
+ /** Byte-stable JSON: sorted object keys, two-space indent, trailing newline. */
10
+ function serializeViz(document) {
11
+ return `${JSON.stringify(sortKeys(document), null, 2)}\n`;
12
+ }
13
+ export { ANY_STATE, DOCUMENT_ELEMENT_ID, UPDATE_EVENT, VIZ_SCHEMA_VERSION, coveredByAny, decodePath, encodeStep, isAnyState, livePageHtml, movesFrom, parseViz, routingWarnings, scopeOf, serializeViz, standaloneHtml, stateAfter, unhandledSends, validateViz };
@@ -0,0 +1 @@
1
+ export {}
package/dist/live.mjs ADDED
@@ -0,0 +1,16 @@
1
+ import { n as UPDATE_EVENT } from "./html-BfvuzJs6.mjs";
2
+ import { mountLive } from "./page.mjs";
3
+ // src/viewer/live.ts
4
+ /**
5
+ * Entry of the live page the `@mantaq/inspect/vite` plugin serves. Reads the
6
+ * document URL from `#app[data-src]` and redraws, keeping the walk, whenever
7
+ * the dev server reports that a machine file changed.
8
+ */
9
+ const root = document.querySelector("#app");
10
+ const source = root?.dataset["src"];
11
+ if (root && source !== void 0) {
12
+ const draw = () => void mountLive(root, source);
13
+ draw();
14
+ import.meta.hot?.on(UPDATE_EVENT, draw);
15
+ }
16
+ export {};
@@ -0,0 +1,7 @@
1
+ import { a as ViewerOptions } from "./embed-CISoaFIK.mjs";
2
+ /** Options that open the walk named in the address bar and keep it there. */
3
+ export declare function linkOptions(): ViewerOptions;
4
+ /** Mount the document embedded in the page itself. */
5
+ export declare function mountEmbedded(root: HTMLElement): void;
6
+ /** Fetch the document from `source` and mount it; call again to redraw, keeping the walk. */
7
+ export declare function mountLive(root: HTMLElement, source: string): Promise<void>;
package/dist/page.mjs ADDED
@@ -0,0 +1,53 @@
1
+ import "./html-BfvuzJs6.mjs";
2
+ import { n as showIssues, t as mountVizText } from "./embed-QX7vRXoL.mjs";
3
+ // src/viewer/page.ts
4
+ /**
5
+ * Whole-page entries: a self-contained HTML file (`mountEmbedded`) and a live
6
+ * page served by a dev server (`mountLive`). Both keep `?machine=&step=` in
7
+ * the address bar so a walk can be shared.
8
+ */
9
+ function rememberWalk(where) {
10
+ const next = new URLSearchParams(location.search);
11
+ next.set("machine", where.machine);
12
+ next.delete("step");
13
+ for (const step of where.steps) next.append("step", step);
14
+ history.replaceState(null, "", `?${next.toString()}`);
15
+ }
16
+ /** Options that open the walk named in the address bar and keep it there. */
17
+ function linkOptions() {
18
+ const params = new URLSearchParams(location.search);
19
+ const machine = params.get("machine");
20
+ return {
21
+ ...machine === null ? {} : { machine },
22
+ steps: params.getAll("step"),
23
+ onNavigate: rememberWalk
24
+ };
25
+ }
26
+ /** Mount the document embedded in the page itself. */
27
+ function mountEmbedded(root) {
28
+ const text = document.getElementById("mantaq-viz-document")?.textContent ?? "";
29
+ mountVizText(root, {
30
+ source: document.title,
31
+ text
32
+ }, linkOptions());
33
+ }
34
+ /** Fetch the document from `source` and mount it; call again to redraw, keeping the walk. */
35
+ async function mountLive(root, source) {
36
+ const response = await fetch(source).catch(() => null);
37
+ if (response === null || !response.ok) {
38
+ const status = response === null ? "network error" : `HTTP ${response.status}`;
39
+ showIssues(root, {
40
+ source,
41
+ issues: [{
42
+ path: "$",
43
+ message: status
44
+ }]
45
+ });
46
+ return;
47
+ }
48
+ mountVizText(root, {
49
+ source,
50
+ text: await response.text()
51
+ }, linkOptions());
52
+ }
53
+ export { linkOptions, mountEmbedded, mountLive };