@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.
- package/LICENSE +21 -0
- package/README.md +46 -0
- package/dist/embed-CISoaFIK.d.mts +37 -0
- package/dist/embed-QX7vRXoL.mjs +1332 -0
- package/dist/html-BfvuzJs6.mjs +55 -0
- package/dist/index.d.mts +82 -0
- package/dist/index.mjs +13 -0
- package/dist/live.d.mts +1 -0
- package/dist/live.mjs +16 -0
- package/dist/page.d.mts +7 -0
- package/dist/page.mjs +53 -0
- package/dist/routing-xXYo05xv.mjs +833 -0
- package/dist/standalone.d.mts +1 -0
- package/dist/standalone.mjs +6 -0
- package/dist/style.css +404 -0
- package/dist/validate-C_EXBtem.d.mts +230 -0
- package/dist/viewer.d.mts +2 -0
- package/dist/viewer.mjs +1 -0
- package/package.json +44 -5
- package/src/viewer/page.css +12 -0
- package/src/viewer/viewer.css +406 -0
|
@@ -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("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """);
|
|
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 };
|
package/dist/index.d.mts
ADDED
|
@@ -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 };
|
package/dist/live.d.mts
ADDED
|
@@ -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 {};
|
package/dist/page.d.mts
ADDED
|
@@ -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 };
|