@polyxd/ds-kit 0.2.2 → 0.3.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/NOTICE +13 -0
- package/README.md +37 -0
- package/dist/dev-pack.d.ts +9 -0
- package/dist/dev-pack.js +100 -0
- package/dist/dev-pack.js.map +1 -0
- package/dist/dev-page.d.ts +17 -0
- package/dist/dev-page.js +359 -0
- package/dist/dev-page.js.map +1 -0
- package/dist/dev.d.ts +74 -0
- package/dist/dev.js +373 -0
- package/dist/dev.js.map +1 -0
- package/dist/polyxd.js +14 -1
- package/dist/polyxd.js.map +1 -1
- package/package.json +5 -4
package/NOTICE
CHANGED
|
@@ -135,6 +135,19 @@ Upstream: https://github.com/adobe/spectrum-tokens
|
|
|
135
135
|
|
|
136
136
|
Vendored under `packages/ds-spectrum/scripts/sources/`, with the upstream licence file beside it.
|
|
137
137
|
|
|
138
|
+
## Template packs
|
|
139
|
+
|
|
140
|
+
Twelve packs are original Polyxd templates, not readings of any design system:
|
|
141
|
+
`@polyxd/ds-sketch`, `@polyxd/ds-wireframe`, `@polyxd/ds-editorial`,
|
|
142
|
+
`@polyxd/ds-brutalist`, `@polyxd/ds-glass`, `@polyxd/ds-terminal`,
|
|
143
|
+
`@polyxd/ds-pastel`, `@polyxd/ds-civic`, `@polyxd/ds-finance`,
|
|
144
|
+
`@polyxd/ds-health`, `@polyxd/ds-neon` and `@polyxd/ds-mono`. Every value in
|
|
145
|
+
them was chosen for the template, they vendor nothing, and they are Apache-2.0
|
|
146
|
+
like the rest of Polyxd. The typefaces some of them name (Caveat, Patrick Hand,
|
|
147
|
+
Fraunces, Nunito, JetBrains Mono, Space Grotesk) are under the SIL Open Font
|
|
148
|
+
License and are loaded from Google Fonts by the page that uses them, never
|
|
149
|
+
distributed here.
|
|
150
|
+
|
|
138
151
|
## Specification
|
|
139
152
|
|
|
140
153
|
### A2UI
|
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @polyxd/ds-kit
|
|
2
|
+
|
|
3
|
+
The `polyxd` command, and the shared parts of building a Polyxd design-system pack: reading CSS custom properties, converting values to DTCG, writing the tiers and the manifest.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npx polyxd pack ./src/tokens.css # a pack from your tokens, plus a mapping to correct
|
|
7
|
+
npx polyxd check ./ds-acme/manifest.json # the pack against the semantic token contract
|
|
8
|
+
npx polyxd studio push ./ --to https://studio.polyxd.com/api/w/acme
|
|
9
|
+
npx polyxd dev ./screens # preview the documents in a folder as you edit them
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## polyxd dev
|
|
13
|
+
|
|
14
|
+
A local preview for people who write Polyxd documents in their editor.
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
npx polyxd dev [dir] [--port 4310] [--theme material3] [--data <file.json>] [--pack <manifest.json|theme.css>] [--verify] [--open]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
It watches `dir` (default: the current folder) for documents: a JSON file with `specVersion` and `components`, or an intent-shaped file with a `document` inside (the document and its `data` are used). A document without embedded data takes `<name>.data.json` beside it, else the file given with `--data`. Packs, registries, reports and other JSON are ignored.
|
|
21
|
+
|
|
22
|
+
The page at `http://localhost:4310/` lists the documents with a dot for the static check (green clean, amber warnings, red errors), renders the selected one with the real renderer, and lets you switch between all built-in packs (plus one of yours with `--pack`), light and dark, phone, tablet and desktop widths with a draggable edge, and density. Beside the surface: the static check's issues, run in the page with `@polyxd/spec/browser` against the data (a binding that reads nothing is a warning); the document JSON with a copy button; the data, and the data as edited in the surface; and a log of the actions the surface dispatches, with their context resolved. Save any file and the surface reloads in place, keeping your selection and controls.
|
|
23
|
+
|
|
24
|
+
`--verify` adds a button that runs the full verifier for the selected document (13 packs × light/dark × 390/1100 with axe and the layout check) and streams its output into the panel. It needs `@polyxd/verifier` installed (`npm install -D @polyxd/verifier && npx playwright install chromium`).
|
|
25
|
+
|
|
26
|
+
The renderer comes from `@polyxd/react/preview`, a single script and stylesheet with React, the renderer, the validator and every theme, so nothing is built on your side. Everything else is Node: `http`, `fs.watch`, and server-sent events.
|
|
27
|
+
|
|
28
|
+
## Library
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { cssVars, resolveVars, length, duration, bezier, shadowLayers, writePack } from "@polyxd/ds-kit";
|
|
32
|
+
import { inferMapping } from "@polyxd/ds-kit/infer";
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`cssVars` reads every custom property under the selectors you choose, `resolveVars` follows `var()` references, the converters turn CSS values into DTCG dimensions, durations, easings and shadows, and `writePack` writes the tiers, the manifest and a package.json. `inferMapping` guesses which of your variables fill which contract tokens, from their names and, failing that, by measuring them; `polyxd pack` is built on it.
|
|
36
|
+
|
|
37
|
+
[Docs](https://polyxd.com/docs/your-design-system/) · [Polyxd](https://polyxd.com) · [Source](https://github.com/visualfart/polyxd)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface PackCss {
|
|
2
|
+
/** The value the surface's data-pxd-theme attribute takes. */
|
|
3
|
+
name: string;
|
|
4
|
+
css: string;
|
|
5
|
+
}
|
|
6
|
+
/** CSS declarations for one resolved token; composite typography expands into its parts. */
|
|
7
|
+
export declare function declarations(name: string, type: string, value: unknown): [string, string][];
|
|
8
|
+
/** A pack as theme CSS: from its manifest (compiled here) or from a stylesheet (served as is). */
|
|
9
|
+
export declare function packCss(path: string): Promise<PackCss>;
|
package/dist/dev-pack.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `polyxd dev --pack`: a pack of your own in the preview's pack switcher, next to the built-in ones.
|
|
3
|
+
*
|
|
4
|
+
* Takes a manifest (what `polyxd pack` writes) and compiles its semantic tier to the CSS variables
|
|
5
|
+
* the renderer reads, the way @polyxd/react's theme build does; or an already compiled theme
|
|
6
|
+
* stylesheet, served as it is.
|
|
7
|
+
*/
|
|
8
|
+
import { readFile } from "node:fs/promises";
|
|
9
|
+
import { basename } from "node:path";
|
|
10
|
+
import { loadContract, loadDesignSystem } from "@polyxd/spec";
|
|
11
|
+
const cssVar = (token) => `--pxd-${token.replace(/\./g, "-")}`;
|
|
12
|
+
const dim = (v) => (typeof v === "object" && v && "unit" in v ? `${v.value}${v.unit}` : String(v));
|
|
13
|
+
function color(v) {
|
|
14
|
+
if (typeof v === "string")
|
|
15
|
+
return v;
|
|
16
|
+
const c = v;
|
|
17
|
+
if (c.alpha !== undefined && c.alpha < 1 && c.colorSpace === "srgb") {
|
|
18
|
+
const [r, g, b] = c.components.map((x) => Math.round(x * 255));
|
|
19
|
+
return `rgb(${r} ${g} ${b} / ${c.alpha})`;
|
|
20
|
+
}
|
|
21
|
+
return c.hex ?? `color(${c.colorSpace} ${c.components.join(" ")})`;
|
|
22
|
+
}
|
|
23
|
+
const GENERIC = /^(serif|sans-serif|monospace|cursive|fantasy|system-ui|ui-sans-serif|ui-serif|ui-monospace|ui-rounded|math|emoji|fangsong|-apple-system|BlinkMacSystemFont)$/;
|
|
24
|
+
function family(v) {
|
|
25
|
+
const names = (Array.isArray(v) ? v : String(v).split(",")).map((f) => String(f).trim().replace(/^["']|["']$/g, ""));
|
|
26
|
+
const css = names.map((f) => (GENERIC.test(f) || /^[A-Za-z_][\w-]*$/.test(f) ? f : `"${f}"`));
|
|
27
|
+
if (!names.some((f) => /^(serif|sans-serif|monospace|system-ui|ui-sans-serif|ui-serif|ui-monospace)$/.test(f)))
|
|
28
|
+
css.push("system-ui", "sans-serif");
|
|
29
|
+
return css.join(", ");
|
|
30
|
+
}
|
|
31
|
+
/** CSS declarations for one resolved token; composite typography expands into its parts. */
|
|
32
|
+
export function declarations(name, type, value) {
|
|
33
|
+
const v = cssVar(name);
|
|
34
|
+
switch (type) {
|
|
35
|
+
case "color":
|
|
36
|
+
return [[v, color(value)]];
|
|
37
|
+
case "dimension":
|
|
38
|
+
case "duration":
|
|
39
|
+
return [[v, dim(value)]];
|
|
40
|
+
case "number":
|
|
41
|
+
return [[v, String(value)]];
|
|
42
|
+
case "cubicBezier":
|
|
43
|
+
return [[v, `cubic-bezier(${value.join(", ")})`]];
|
|
44
|
+
case "shadow": {
|
|
45
|
+
const one = (s) => `${s.inset ? "inset " : ""}${dim(s.offsetX)} ${dim(s.offsetY)} ${dim(s.blur)} ${dim(s.spread)} ${color(s.color)}`;
|
|
46
|
+
return [[v, Array.isArray(value) ? value.map(one).join(", ") : one(value)]];
|
|
47
|
+
}
|
|
48
|
+
case "fontFamily":
|
|
49
|
+
return [[v, family(value)]];
|
|
50
|
+
case "typography": {
|
|
51
|
+
const t = value;
|
|
52
|
+
return [
|
|
53
|
+
[`${v}-family`, family(t.fontFamily)],
|
|
54
|
+
[`${v}-size`, dim(t.fontSize)],
|
|
55
|
+
[`${v}-weight`, String(t.fontWeight)],
|
|
56
|
+
[`${v}-line-height`, dim(t.lineHeight)],
|
|
57
|
+
[`${v}-letter-spacing`, t.letterSpacing === undefined ? "normal" : dim(t.letterSpacing)],
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
default:
|
|
61
|
+
return [[v, String(value)]];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** A pack as theme CSS: from its manifest (compiled here) or from a stylesheet (served as is). */
|
|
65
|
+
export async function packCss(path) {
|
|
66
|
+
if (path.endsWith(".css")) {
|
|
67
|
+
const css = await readFile(path, "utf8");
|
|
68
|
+
const named = /data-pxd-theme=["']?([a-z0-9-]+)/i.exec(css);
|
|
69
|
+
return { name: named?.[1] ?? basename(path, ".css"), css };
|
|
70
|
+
}
|
|
71
|
+
const [{ manifest, modes }, contract] = await Promise.all([loadDesignSystem(path), loadContract()]);
|
|
72
|
+
const blocks = [`/* ${manifest.name}, compiled by polyxd dev from ${basename(path)} */`];
|
|
73
|
+
const missing = [];
|
|
74
|
+
for (const [mode, tokens] of modes) {
|
|
75
|
+
const lines = [];
|
|
76
|
+
for (const name of Object.keys(contract.tokens)) {
|
|
77
|
+
const t = tokens.get(name);
|
|
78
|
+
if (!t) {
|
|
79
|
+
missing.push(`${mode}: ${name}`);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
for (const [k, val] of declarations(name, t.type, t.value))
|
|
83
|
+
lines.push(` ${k}: ${val};`);
|
|
84
|
+
}
|
|
85
|
+
for (const [k, v] of Object.entries(manifest.layout ?? {}))
|
|
86
|
+
lines.push(` --pxd-layout-${k}: ${v};`);
|
|
87
|
+
lines.push(` color-scheme: ${mode === "dark" ? "dark" : "light"};`);
|
|
88
|
+
const selector = modes.size === 1
|
|
89
|
+
? `[data-pxd-theme="${manifest.name}"]`
|
|
90
|
+
: mode === manifest.defaultMode
|
|
91
|
+
? `[data-pxd-theme="${manifest.name}"]:not([data-pxd-mode]),\n[data-pxd-theme="${manifest.name}"][data-pxd-mode="${mode}"]`
|
|
92
|
+
: `[data-pxd-theme="${manifest.name}"][data-pxd-mode="${mode}"]`;
|
|
93
|
+
blocks.push(`${selector} {\n${lines.join("\n")}\n}`);
|
|
94
|
+
}
|
|
95
|
+
// A pack still being drafted renders with what it has; the contract check is `polyxd check`'s job.
|
|
96
|
+
if (missing.length)
|
|
97
|
+
blocks.push(`/* ${missing.length} contract token(s) not in this pack: ${missing.slice(0, 8).join(", ")}${missing.length > 8 ? ", …" : ""} */`);
|
|
98
|
+
return { name: manifest.name, css: blocks.join("\n\n") + "\n" };
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=dev-pack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-pack.js","sourceRoot":"","sources":["../src/dev-pack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `polyxd dev` page: plain HTML, CSS and JS shipped with the package, so a preview needs no
|
|
3
|
+
* build step on the author's side. Its chrome is in the system font; only the surface is in the
|
|
4
|
+
* pack's. Everything it knows about the folder comes from /api/documents and the event stream.
|
|
5
|
+
*/
|
|
6
|
+
export interface PageOptions {
|
|
7
|
+
dir: string;
|
|
8
|
+
/** The pack selected on first open. */
|
|
9
|
+
theme: string;
|
|
10
|
+
/** A pack added with --pack, by name. */
|
|
11
|
+
pack?: string;
|
|
12
|
+
verify: boolean;
|
|
13
|
+
/** Whether the renderer bundle is installed. */
|
|
14
|
+
bundle: boolean;
|
|
15
|
+
themes: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare function devPage(options: PageOptions): string;
|
package/dist/dev-page.js
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
export function devPage(options) {
|
|
2
|
+
return PAGE.replace("__OPTIONS__", JSON.stringify(options).replace(/</g, "\\u003c"));
|
|
3
|
+
}
|
|
4
|
+
const PAGE = `<!doctype html>
|
|
5
|
+
<html lang="en">
|
|
6
|
+
<head>
|
|
7
|
+
<meta charset="utf-8">
|
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
9
|
+
<title>polyxd dev</title>
|
|
10
|
+
<link rel="stylesheet" href="/preview/polyxd.css">
|
|
11
|
+
<link rel="stylesheet" href="/pack.css" id="packcss">
|
|
12
|
+
<style>
|
|
13
|
+
:root { color-scheme: light; --bg: #f4f4f6; --panel: #ffffff; --line: #dcdce2; --ink: #1c1c22; --muted: #6a6a75; --accent: #3554d1; --ok: #2e9e5b; --warn: #d99a1b; --err: #d0392b; }
|
|
14
|
+
* { box-sizing: border-box; }
|
|
15
|
+
html, body { height: 100%; margin: 0; }
|
|
16
|
+
body { font: 13px/1.45 system-ui, -apple-system, "Segoe UI", sans-serif; color: var(--ink); background: var(--bg); display: flex; flex-direction: column; }
|
|
17
|
+
button, select { font: inherit; color: inherit; }
|
|
18
|
+
code, pre { font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
|
19
|
+
.bar { display: flex; align-items: center; gap: 16px; padding: 8px 14px; background: var(--panel); border-bottom: 1px solid var(--line); flex-wrap: wrap; }
|
|
20
|
+
.bar h1 { font-size: 14px; margin: 0; font-weight: 600; }
|
|
21
|
+
.bar .dir { color: var(--muted); font-family: ui-monospace, Menlo, monospace; font-size: 12px; }
|
|
22
|
+
.controls { display: flex; align-items: center; gap: 12px; margin-left: auto; flex-wrap: wrap; }
|
|
23
|
+
.controls label { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); }
|
|
24
|
+
select { padding: 4px 6px; border: 1px solid var(--line); border-radius: 6px; background: #fff; }
|
|
25
|
+
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; }
|
|
26
|
+
.seg button { border: 0; background: #fff; padding: 4px 10px; cursor: pointer; border-right: 1px solid var(--line); }
|
|
27
|
+
.seg button:last-child { border-right: 0; }
|
|
28
|
+
.seg button[aria-pressed="true"] { background: var(--ink); color: #fff; }
|
|
29
|
+
.status { color: var(--muted); min-width: 120px; }
|
|
30
|
+
.status.live::before { content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--ok); margin-right: 6px; }
|
|
31
|
+
.status.off::before { content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--err); margin-right: 6px; }
|
|
32
|
+
.layout { flex: 1; display: grid; grid-template-columns: 260px 1fr 400px; min-height: 0; }
|
|
33
|
+
.list { border-right: 1px solid var(--line); background: var(--panel); overflow: auto; padding: 8px 0; }
|
|
34
|
+
.list h2 { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin: 8px 14px 4px; font-weight: 600; }
|
|
35
|
+
.doc { display: grid; grid-template-columns: 12px 1fr; gap: 0 8px; width: 100%; text-align: left; border: 0; background: none; padding: 7px 14px; cursor: pointer; }
|
|
36
|
+
.doc:hover { background: #f0f0f4; }
|
|
37
|
+
.doc[aria-current="true"] { background: #e8ecfb; }
|
|
38
|
+
.doc .dot { width: 9px; height: 9px; border-radius: 50%; margin-top: 5px; background: var(--ok); }
|
|
39
|
+
.doc .dot.warn { background: var(--warn); }
|
|
40
|
+
.doc .dot.err { background: var(--err); }
|
|
41
|
+
.doc .t { font-weight: 500; }
|
|
42
|
+
.doc .m { color: var(--muted); font-size: 12px; font-family: ui-monospace, Menlo, monospace; }
|
|
43
|
+
.doc .k { color: var(--muted); font-size: 11px; }
|
|
44
|
+
.stage { overflow: auto; padding: 20px; display: flex; justify-content: center; align-items: flex-start; }
|
|
45
|
+
.frame { position: relative; flex: none; min-height: 60%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.08), 0 0 0 1px var(--line); border-radius: 6px; overflow: visible; }
|
|
46
|
+
.frame .grip { position: absolute; top: 0; right: -14px; width: 10px; height: 100%; cursor: ew-resize; border-radius: 4px; background: transparent; }
|
|
47
|
+
.frame .grip::after { content: ""; position: absolute; top: 50%; left: 3px; width: 4px; height: 36px; margin-top: -18px; border-radius: 2px; background: #c2c2cc; }
|
|
48
|
+
.frame .grip:hover::after, .frame .grip.on::after { background: var(--accent); }
|
|
49
|
+
#surface { min-height: 200px; }
|
|
50
|
+
.empty { padding: 40px; color: var(--muted); text-align: center; }
|
|
51
|
+
.panel { border-left: 1px solid var(--line); background: var(--panel); display: flex; flex-direction: column; min-height: 0; }
|
|
52
|
+
.tabs { display: flex; border-bottom: 1px solid var(--line); }
|
|
53
|
+
.tabs button { flex: 1; border: 0; background: none; padding: 9px 4px; cursor: pointer; color: var(--muted); border-bottom: 2px solid transparent; font-size: 12px; }
|
|
54
|
+
.tabs button[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--accent); }
|
|
55
|
+
.tabs button b { font-weight: 600; }
|
|
56
|
+
.pane { display: none; overflow: auto; flex: 1; padding: 12px 14px; }
|
|
57
|
+
.pane.on { display: block; }
|
|
58
|
+
.pane pre { margin: 0; white-space: pre-wrap; word-break: break-word; background: #f6f6f8; border: 1px solid var(--line); border-radius: 6px; padding: 10px; }
|
|
59
|
+
.pane h3 { font-size: 12px; margin: 14px 0 6px; color: var(--muted); font-weight: 600; }
|
|
60
|
+
.pane h3:first-child { margin-top: 0; }
|
|
61
|
+
.note { color: var(--muted); margin: 0 0 10px; }
|
|
62
|
+
.toolrow { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
|
|
63
|
+
.btn { border: 1px solid var(--line); background: #fff; border-radius: 6px; padding: 4px 10px; cursor: pointer; }
|
|
64
|
+
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
|
|
65
|
+
.btn[disabled] { opacity: .5; cursor: default; }
|
|
66
|
+
.issue { display: grid; grid-template-columns: 52px 1fr; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--line); }
|
|
67
|
+
.issue .sev { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; padding-top: 2px; }
|
|
68
|
+
.issue .sev.error { color: var(--err); }
|
|
69
|
+
.issue .sev.warning { color: var(--warn); }
|
|
70
|
+
.issue .at { font-family: ui-monospace, Menlo, monospace; font-size: 11px; color: var(--muted); }
|
|
71
|
+
.action { padding: 8px 0; border-bottom: 1px solid var(--line); }
|
|
72
|
+
.action .n { font-weight: 600; }
|
|
73
|
+
.action .s { color: var(--muted); font-size: 12px; }
|
|
74
|
+
.action pre { margin-top: 4px; }
|
|
75
|
+
.verify-out { font-size: 11px; max-height: none; }
|
|
76
|
+
.verify-out .err { color: var(--err); }
|
|
77
|
+
.warning-box { background: #fff7e6; border: 1px solid #f0d9a0; padding: 10px; border-radius: 6px; margin-bottom: 10px; }
|
|
78
|
+
@media (max-width: 1100px) { .layout { grid-template-columns: 220px 1fr; } .panel { grid-column: 1 / -1; border-left: 0; border-top: 1px solid var(--line); max-height: 40vh; } }
|
|
79
|
+
</style>
|
|
80
|
+
</head>
|
|
81
|
+
<body>
|
|
82
|
+
<header class="bar">
|
|
83
|
+
<h1>polyxd dev</h1>
|
|
84
|
+
<span class="dir" id="dir"></span>
|
|
85
|
+
<div class="controls">
|
|
86
|
+
<label>Pack <select id="theme" aria-label="Design-system pack"></select></label>
|
|
87
|
+
<div class="seg" id="mode" role="group" aria-label="Mode"><button data-v="light">Light</button><button data-v="dark">Dark</button></div>
|
|
88
|
+
<div class="seg" id="width" role="group" aria-label="Width"><button data-v="390">Phone</button><button data-v="820">Tablet</button><button data-v="1100">Desktop</button></div>
|
|
89
|
+
<span id="widthpx" class="dir">390px</span>
|
|
90
|
+
<label>Density <select id="density" aria-label="Density"><option value="comfortable">comfortable</option><option value="compact">compact</option><option value="spacious">spacious</option></select></label>
|
|
91
|
+
<span class="status" id="status" aria-live="polite"></span>
|
|
92
|
+
</div>
|
|
93
|
+
</header>
|
|
94
|
+
<main class="layout">
|
|
95
|
+
<nav class="list" id="list" aria-label="Documents"></nav>
|
|
96
|
+
<section class="stage" id="stage">
|
|
97
|
+
<div class="frame" id="frame" style="width:390px">
|
|
98
|
+
<div id="surface"></div>
|
|
99
|
+
<div class="grip" id="grip" title="Drag to resize" role="separator" aria-orientation="vertical" aria-label="Resize the surface"></div>
|
|
100
|
+
</div>
|
|
101
|
+
</section>
|
|
102
|
+
<aside class="panel">
|
|
103
|
+
<div class="tabs" role="tablist" aria-label="Panel">
|
|
104
|
+
<button role="tab" data-tab="issues" id="tab-issues">Issues</button>
|
|
105
|
+
<button role="tab" data-tab="document">Document</button>
|
|
106
|
+
<button role="tab" data-tab="data">Data</button>
|
|
107
|
+
<button role="tab" data-tab="actions" id="tab-actions">Actions</button>
|
|
108
|
+
<button role="tab" data-tab="verify">Verify</button>
|
|
109
|
+
</div>
|
|
110
|
+
<div class="pane" id="pane-issues" role="tabpanel"></div>
|
|
111
|
+
<div class="pane" id="pane-document" role="tabpanel">
|
|
112
|
+
<div class="toolrow"><button class="btn" id="copy-doc">Copy JSON</button><span class="note" id="doc-note"></span></div>
|
|
113
|
+
<pre id="doc-json"></pre>
|
|
114
|
+
</div>
|
|
115
|
+
<div class="pane" id="pane-data" role="tabpanel"></div>
|
|
116
|
+
<div class="pane" id="pane-actions" role="tabpanel"></div>
|
|
117
|
+
<div class="pane" id="pane-verify" role="tabpanel"></div>
|
|
118
|
+
</aside>
|
|
119
|
+
</main>
|
|
120
|
+
<script src="/preview/polyxd.js"></script>
|
|
121
|
+
<script>
|
|
122
|
+
(function () {
|
|
123
|
+
var O = __OPTIONS__;
|
|
124
|
+
var P = window.Polyxd;
|
|
125
|
+
var $ = function (id) { return document.getElementById(id); };
|
|
126
|
+
var esc = function (s) { return String(s).replace(/[&<>"]/g, function (c) { return { "&": "&", "<": "<", ">": ">", '"': """ }[c]; }); };
|
|
127
|
+
var pretty = function (v) { return JSON.stringify(v, null, 2); };
|
|
128
|
+
var time = function () { return new Date().toLocaleTimeString("en-GB"); };
|
|
129
|
+
|
|
130
|
+
// ---- state, kept across reloads of this page; the event stream never reloads it ----
|
|
131
|
+
var KEY = "polyxd-dev:" + O.dir;
|
|
132
|
+
var state = { selected: null, theme: O.theme, mode: "light", width: 390, density: "comfortable", tab: "issues" };
|
|
133
|
+
try { Object.assign(state, JSON.parse(localStorage.getItem(KEY) || "{}")); } catch (e) {}
|
|
134
|
+
var save = function () { try { localStorage.setItem(KEY, JSON.stringify(state)); } catch (e) {} };
|
|
135
|
+
|
|
136
|
+
var docs = [], broken = [], current = null, handle = null, versions = {}, actions = [], liveData = null, verifyStream = null;
|
|
137
|
+
var themes = (P && P.themes) || O.themes;
|
|
138
|
+
if (O.pack && themes.indexOf(O.pack) < 0) themes = [O.pack].concat(themes);
|
|
139
|
+
if (themes.indexOf(state.theme) < 0) state.theme = O.theme;
|
|
140
|
+
if (!O.pack) $("packcss").remove();
|
|
141
|
+
|
|
142
|
+
// ---- controls ----
|
|
143
|
+
$("dir").textContent = O.dir;
|
|
144
|
+
var themeSel = $("theme");
|
|
145
|
+
themes.forEach(function (t) { var o = document.createElement("option"); o.value = t; o.textContent = t === O.pack ? t + " (--pack)" : t; themeSel.appendChild(o); });
|
|
146
|
+
themeSel.value = state.theme;
|
|
147
|
+
themeSel.onchange = function () { state.theme = themeSel.value; save(); render(); };
|
|
148
|
+
var dens = $("density");
|
|
149
|
+
dens.value = state.density;
|
|
150
|
+
dens.onchange = function () { state.density = dens.value; save(); render(); };
|
|
151
|
+
var seg = function (id, get, set) {
|
|
152
|
+
var el = $(id);
|
|
153
|
+
var paint = function () { Array.prototype.forEach.call(el.querySelectorAll("button"), function (b) { b.setAttribute("aria-pressed", String(b.dataset.v === String(get()))); }); };
|
|
154
|
+
el.onclick = function (e) { var b = e.target.closest("button"); if (!b) return; set(b.dataset.v); paint(); };
|
|
155
|
+
paint();
|
|
156
|
+
return paint;
|
|
157
|
+
};
|
|
158
|
+
var paintMode = seg("mode", function () { return state.mode; }, function (v) { state.mode = v; save(); render(); });
|
|
159
|
+
var paintWidth = seg("width", function () { return state.width; }, function (v) { setWidth(Number(v)); });
|
|
160
|
+
function setWidth(w) {
|
|
161
|
+
var max = Math.max(320, $("stage").clientWidth - 60);
|
|
162
|
+
state.width = Math.round(Math.min(max, Math.max(320, w)));
|
|
163
|
+
$("frame").style.width = state.width + "px";
|
|
164
|
+
$("widthpx").textContent = state.width + "px";
|
|
165
|
+
paintWidth();
|
|
166
|
+
save();
|
|
167
|
+
}
|
|
168
|
+
setWidth(state.width);
|
|
169
|
+
// The grip: drag the surface's edge to any width between phone and the stage.
|
|
170
|
+
(function () {
|
|
171
|
+
var grip = $("grip"), startX = 0, startW = 0;
|
|
172
|
+
var move = function (e) { setWidth(startW + (e.clientX - startX)); };
|
|
173
|
+
var up = function () { grip.classList.remove("on"); window.removeEventListener("pointermove", move); window.removeEventListener("pointerup", up); };
|
|
174
|
+
grip.addEventListener("pointerdown", function (e) { startX = e.clientX; startW = state.width; grip.classList.add("on"); window.addEventListener("pointermove", move); window.addEventListener("pointerup", up); e.preventDefault(); });
|
|
175
|
+
grip.addEventListener("keydown", function (e) { if (e.key === "ArrowLeft") setWidth(state.width - 20); if (e.key === "ArrowRight") setWidth(state.width + 20); });
|
|
176
|
+
grip.tabIndex = 0;
|
|
177
|
+
})();
|
|
178
|
+
|
|
179
|
+
// ---- tabs ----
|
|
180
|
+
var tabs = document.querySelectorAll(".tabs button");
|
|
181
|
+
var showTab = function (name) {
|
|
182
|
+
state.tab = name; save();
|
|
183
|
+
Array.prototype.forEach.call(tabs, function (b) { b.setAttribute("aria-selected", String(b.dataset.tab === name)); });
|
|
184
|
+
Array.prototype.forEach.call(document.querySelectorAll(".pane"), function (p) { p.classList.toggle("on", p.id === "pane-" + name); });
|
|
185
|
+
};
|
|
186
|
+
Array.prototype.forEach.call(tabs, function (b) { b.onclick = function () { showTab(b.dataset.tab); }; });
|
|
187
|
+
showTab(state.tab);
|
|
188
|
+
|
|
189
|
+
// ---- the document list ----
|
|
190
|
+
var dot = function (check) { return check.errors ? "err" : check.warnings ? "warn" : "ok"; };
|
|
191
|
+
function paintList() {
|
|
192
|
+
var list = $("list");
|
|
193
|
+
var html = "<h2>" + docs.length + " document" + (docs.length === 1 ? "" : "s") + "</h2>";
|
|
194
|
+
if (!docs.length) html += '<p class="note" style="padding:0 14px">No documents here yet. A document is a JSON file with <code>specVersion</code> and <code>components</code>, or an intent file with a <code>document</code> inside.</p>';
|
|
195
|
+
docs.forEach(function (d) {
|
|
196
|
+
var kind = [d.kind, d.origin, d.dataFrom === "none" ? "no data" : d.dataFrom === "embedded" ? null : "data: " + d.dataFrom].filter(Boolean).join(" · ");
|
|
197
|
+
var title = d.check.errors + " error(s), " + d.check.warnings + " warning(s)";
|
|
198
|
+
html += '<button class="doc" data-file="' + esc(d.file) + '" aria-current="' + (d.file === state.selected) + '" title="' + esc(title) + '">' +
|
|
199
|
+
'<span class="dot ' + dot(d.check) + '" aria-label="' + esc(title) + '"></span>' +
|
|
200
|
+
'<span><span class="t">' + esc(d.title) + '</span><br><span class="m">' + esc(d.id || d.file) + '</span><br><span class="k">' + esc(kind) + '</span></span></button>';
|
|
201
|
+
});
|
|
202
|
+
if (broken.length) {
|
|
203
|
+
html += "<h2>Did not parse</h2>";
|
|
204
|
+
broken.forEach(function (b) { html += '<div class="doc" title="' + esc(b.message) + '"><span class="dot err"></span><span><span class="m">' + esc(b.file) + '</span><br><span class="k">' + esc(b.message) + '</span></span></div>'; });
|
|
205
|
+
}
|
|
206
|
+
list.innerHTML = html;
|
|
207
|
+
Array.prototype.forEach.call(list.querySelectorAll("button.doc"), function (b) { b.onclick = function () { select(b.dataset.file); }; });
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// ---- the selected document ----
|
|
211
|
+
function select(file) {
|
|
212
|
+
if (!docs.some(function (d) { return d.file === file; })) file = docs.length ? docs[0].file : null;
|
|
213
|
+
var changed = file !== state.selected;
|
|
214
|
+
state.selected = file; save();
|
|
215
|
+
paintList();
|
|
216
|
+
if (!file) { current = null; unmount(); $("surface").innerHTML = '<p class="empty">Nothing to render.</p>'; paintPanels(); return; }
|
|
217
|
+
if (changed) { actions = []; liveData = null; stopVerify(); }
|
|
218
|
+
fetch("/api/documents/" + encodeURIComponent(file).replace(/%2F/g, "/")).then(function (r) { return r.json(); }).then(function (d) {
|
|
219
|
+
if (d.error) return;
|
|
220
|
+
current = d;
|
|
221
|
+
versions[file] = (versions[file] || 0) + 1;
|
|
222
|
+
render();
|
|
223
|
+
paintPanels();
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
function unmount() { if (handle) { handle.unmount(); handle = null; } }
|
|
227
|
+
function render() {
|
|
228
|
+
if (!current) return;
|
|
229
|
+
if (!P) { $("surface").innerHTML = '<p class="empty">The renderer bundle isn\\u2019t installed, so nothing renders here: <code>npm install @polyxd/react</code>, then start again.</p>'; return; }
|
|
230
|
+
var file = current.file;
|
|
231
|
+
var props = {
|
|
232
|
+
key: file + ":" + versions[file],
|
|
233
|
+
document: current.document,
|
|
234
|
+
data: current.data,
|
|
235
|
+
theme: state.theme,
|
|
236
|
+
mode: state.mode,
|
|
237
|
+
density: state.density,
|
|
238
|
+
onAction: function (e) { actions.unshift({ at: time(), name: e.name, source: e.source, context: e.context }); paintActions(); },
|
|
239
|
+
onDismiss: function () { actions.unshift({ at: time(), name: "ui.dismiss", source: "(surface)", context: {} }); paintActions(); },
|
|
240
|
+
onDataChange: function (d) { liveData = d; if (state.tab === "data") paintData(); }
|
|
241
|
+
};
|
|
242
|
+
if (handle) handle.update(props);
|
|
243
|
+
else { $("surface").innerHTML = ""; handle = P.mount($("surface"), props); }
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// ---- panels ----
|
|
247
|
+
function paintPanels() { paintIssues(); paintDocument(); paintData(); paintActions(); paintVerify(); }
|
|
248
|
+
function issuesOf(d) {
|
|
249
|
+
if (P && P.validateDocument) {
|
|
250
|
+
try {
|
|
251
|
+
var doc = d.data !== undefined ? Object.assign({}, d.document, { data: d.data }) : d.document;
|
|
252
|
+
return P.validateDocument(doc, { missingData: "warning" }).issues;
|
|
253
|
+
} catch (e) { return [{ severity: "error", at: "/", message: "validator failed: " + e.message }]; }
|
|
254
|
+
}
|
|
255
|
+
return d.issues || [];
|
|
256
|
+
}
|
|
257
|
+
function paintIssues() {
|
|
258
|
+
var pane = $("pane-issues"), tab = $("tab-issues");
|
|
259
|
+
if (!current) { pane.innerHTML = '<p class="note">Select a document.</p>'; tab.innerHTML = "Issues"; return; }
|
|
260
|
+
var issues = issuesOf(current);
|
|
261
|
+
var errors = issues.filter(function (i) { return i.severity === "error"; }).length;
|
|
262
|
+
var warnings = issues.length - errors;
|
|
263
|
+
tab.innerHTML = "Issues" + (issues.length ? " <b>" + issues.length + "</b>" : "");
|
|
264
|
+
var html = '<p class="note">Static check' + (P ? " (run in this page with @polyxd/spec/browser)" : "") + ": schema, structure and every binding against the data the surface shows. " +
|
|
265
|
+
(issues.length ? errors + " error" + (errors === 1 ? "" : "s") + ", " + warnings + " warning" + (warnings === 1 ? "" : "s") + "." : "Nothing to report.") + "</p>";
|
|
266
|
+
issues.forEach(function (i) {
|
|
267
|
+
html += '<div class="issue"><span class="sev ' + i.severity + '">' + i.severity + "</span><span>" + esc(i.message) + '<br><span class="at">' + esc(i.at) + (i.code ? " · " + esc(i.code) : "") + "</span></span></div>";
|
|
268
|
+
});
|
|
269
|
+
pane.innerHTML = html;
|
|
270
|
+
}
|
|
271
|
+
function paintDocument() {
|
|
272
|
+
if (!current) { $("doc-json").textContent = ""; $("doc-note").textContent = ""; return; }
|
|
273
|
+
$("doc-json").textContent = pretty(current.document);
|
|
274
|
+
$("doc-note").textContent = current.file + " · " + current.document.components.length + " components" + (current.kind === "intent" ? " · from the intent file's document" : "");
|
|
275
|
+
}
|
|
276
|
+
$("copy-doc").onclick = function () {
|
|
277
|
+
if (!current) return;
|
|
278
|
+
var b = $("copy-doc");
|
|
279
|
+
navigator.clipboard.writeText(pretty(current.document)).then(function () { b.textContent = "Copied"; setTimeout(function () { b.textContent = "Copy JSON"; }, 1200); }, function () { b.textContent = "Couldn\\u2019t copy"; });
|
|
280
|
+
};
|
|
281
|
+
function paintData() {
|
|
282
|
+
var pane = $("pane-data");
|
|
283
|
+
if (!current) { pane.innerHTML = '<p class="note">Select a document.</p>'; return; }
|
|
284
|
+
var from = { embedded: "the document\\u2019s own data", sibling: "the sibling .data.json file", "default": "--data", none: "nowhere: this document has no data" }[current.dataFrom];
|
|
285
|
+
var html = "<h3>Data from " + esc(from) + "</h3>";
|
|
286
|
+
html += current.data === undefined ? '<p class="note">Bindings will render blank. Put a <code>data</code> snapshot in the document, a <code>' + esc(current.file.replace(/\\.json$/, ".data.json")) + "</code> beside it, or pass <code>--data</code>.</p>" : "<pre>" + esc(pretty(current.data)) + "</pre>";
|
|
287
|
+
if (liveData) html += "<h3>As edited in the surface</h3><pre>" + esc(pretty(liveData)) + "</pre>";
|
|
288
|
+
pane.innerHTML = html;
|
|
289
|
+
}
|
|
290
|
+
function paintActions() {
|
|
291
|
+
var pane = $("pane-actions"), tab = $("tab-actions");
|
|
292
|
+
tab.innerHTML = "Actions" + (actions.length ? " <b>" + actions.length + "</b>" : "");
|
|
293
|
+
if (!actions.length) { pane.innerHTML = '<p class="note">Actions the surface dispatches show here with their context resolved against the data: press a button, choose a row, submit a form.</p>'; return; }
|
|
294
|
+
pane.innerHTML = '<div class="toolrow"><button class="btn" id="clear-actions">Clear</button></div>' + actions.map(function (a) {
|
|
295
|
+
return '<div class="action"><span class="n">' + esc(a.name) + '</span> <span class="s">from ' + esc(a.source) + " · " + a.at + "</span><pre>" + esc(pretty(a.context)) + "</pre></div>";
|
|
296
|
+
}).join("");
|
|
297
|
+
$("clear-actions").onclick = function () { actions = []; paintActions(); };
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// ---- verify: the full verifier, streamed ----
|
|
301
|
+
function stopVerify() { if (verifyStream) { verifyStream.close(); verifyStream = null; } }
|
|
302
|
+
function paintVerify() {
|
|
303
|
+
var pane = $("pane-verify");
|
|
304
|
+
if (!O.verify) { pane.innerHTML = '<p class="note">Start with <code>--verify</code> to run the full verifier from here: every built-in pack, light and dark, phone and desktop, with axe and the layout check. It needs <code>@polyxd/verifier</code> installed.</p>'; return; }
|
|
305
|
+
pane.innerHTML = '<div class="toolrow"><button class="btn primary" id="run-verify"' + (current ? "" : " disabled") + ">Verify in " + O.themes.length + ' packs</button><span class="note" id="verify-note"></span></div><pre class="verify-out" id="verify-out"></pre>';
|
|
306
|
+
$("run-verify").onclick = runVerify;
|
|
307
|
+
}
|
|
308
|
+
function runVerify() {
|
|
309
|
+
if (!current) return;
|
|
310
|
+
stopVerify();
|
|
311
|
+
var out = $("verify-out"), btn = $("run-verify"), note = $("verify-note");
|
|
312
|
+
out.textContent = ""; btn.disabled = true; note.textContent = "Running\\u2026 (26 renders; a minute or so)";
|
|
313
|
+
verifyStream = new EventSource("/api/verify/" + encodeURIComponent(current.file).replace(/%2F/g, "/"));
|
|
314
|
+
verifyStream.addEventListener("line", function (e) {
|
|
315
|
+
var d = JSON.parse(e.data);
|
|
316
|
+
var span = document.createElement("span");
|
|
317
|
+
span.className = d.stream === "err" ? "err" : "";
|
|
318
|
+
span.textContent = d.text + "\\n";
|
|
319
|
+
out.appendChild(span);
|
|
320
|
+
out.scrollTop = out.scrollHeight;
|
|
321
|
+
});
|
|
322
|
+
verifyStream.addEventListener("done", function (e) {
|
|
323
|
+
var d = JSON.parse(e.data);
|
|
324
|
+
note.textContent = d.code === 0 ? "Done: no errors." : d.code === 1 ? "Done: errors found." : "Did not run.";
|
|
325
|
+
btn.disabled = false;
|
|
326
|
+
stopVerify();
|
|
327
|
+
});
|
|
328
|
+
verifyStream.onerror = function () { note.textContent = "Stream ended."; btn.disabled = false; stopVerify(); };
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// ---- the folder, live ----
|
|
332
|
+
function apply(listing) {
|
|
333
|
+
docs = listing.documents; broken = listing.broken || [];
|
|
334
|
+
paintList();
|
|
335
|
+
}
|
|
336
|
+
function setStatus(text, cls) { var s = $("status"); s.textContent = text; s.className = "status " + (cls || ""); }
|
|
337
|
+
var events = new EventSource("/api/events");
|
|
338
|
+
events.addEventListener("hello", function (e) {
|
|
339
|
+
apply(JSON.parse(e.data));
|
|
340
|
+
setStatus("watching", "live");
|
|
341
|
+
if (!current || !docs.some(function (d) { return d.file === state.selected; })) select(state.selected);
|
|
342
|
+
});
|
|
343
|
+
events.addEventListener("change", function (e) {
|
|
344
|
+
var d = JSON.parse(e.data);
|
|
345
|
+
apply(d);
|
|
346
|
+
if (state.selected && d.removed.indexOf(state.selected) >= 0) { select(null); setStatus("removed " + time(), "live"); return; }
|
|
347
|
+
if (state.selected && d.changed.indexOf(state.selected) >= 0) { select(state.selected); setStatus("reloaded " + time(), "live"); }
|
|
348
|
+
else if (!state.selected && docs.length) select(docs[0].file);
|
|
349
|
+
else setStatus("watching", "live");
|
|
350
|
+
});
|
|
351
|
+
events.addEventListener("bye", function () { setStatus("server stopped", "off"); });
|
|
352
|
+
events.onerror = function () { setStatus("reconnecting\\u2026", "off"); };
|
|
353
|
+
window.addEventListener("resize", function () { setWidth(state.width); });
|
|
354
|
+
})();
|
|
355
|
+
</script>
|
|
356
|
+
</body>
|
|
357
|
+
</html>
|
|
358
|
+
`;
|
|
359
|
+
//# sourceMappingURL=dev-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-page.js","sourceRoot":"","sources":["../src/dev-page.ts"],"names":[],"mappings":"AAiBA,MAAM,UAAU,OAAO,CAAC,OAAoB;IAC1C,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;AACvF,CAAC;AAED,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkWZ,CAAC"}
|
package/dist/dev.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type Issue } from "@polyxd/spec";
|
|
2
|
+
import { type PackCss } from "./dev-pack.ts";
|
|
3
|
+
export type Json = any;
|
|
4
|
+
export interface DevDocument {
|
|
5
|
+
/** Path relative to the watched folder, with `/` separators: the stable key. */
|
|
6
|
+
file: string;
|
|
7
|
+
/** surface.id */
|
|
8
|
+
id: string;
|
|
9
|
+
title: string;
|
|
10
|
+
/** A bare document, or an intent-shaped file whose `document` is used. */
|
|
11
|
+
kind: "document" | "intent";
|
|
12
|
+
/** surface.origin when the document states one. */
|
|
13
|
+
origin?: string;
|
|
14
|
+
pattern?: string;
|
|
15
|
+
/** Where the data came from. */
|
|
16
|
+
dataFrom: "embedded" | "sibling" | "default" | "none";
|
|
17
|
+
document: Json;
|
|
18
|
+
data?: Json;
|
|
19
|
+
check: StaticCheck;
|
|
20
|
+
}
|
|
21
|
+
export interface StaticCheck {
|
|
22
|
+
errors: number;
|
|
23
|
+
warnings: number;
|
|
24
|
+
issues: Issue[];
|
|
25
|
+
}
|
|
26
|
+
export interface Discovery {
|
|
27
|
+
documents: DevDocument[];
|
|
28
|
+
/** JSON files that didn't parse: while someone is mid-edit, usually. */
|
|
29
|
+
broken: {
|
|
30
|
+
file: string;
|
|
31
|
+
message: string;
|
|
32
|
+
}[];
|
|
33
|
+
}
|
|
34
|
+
/** The static check: schema and structure, and every binding against the data the surface will show. */
|
|
35
|
+
export declare function checkDocument(document: Json, data?: Json): StaticCheck;
|
|
36
|
+
/**
|
|
37
|
+
* Every document under `dir`: a JSON file with `specVersion` and `components`, or an intent-shaped
|
|
38
|
+
* file whose `document` has them. Data is the document's own, else `<name>.data.json` beside it,
|
|
39
|
+
* else `defaultData`. Everything else (packs, reports, registries, tsconfigs) is ignored.
|
|
40
|
+
*/
|
|
41
|
+
export declare function discoverDocuments(dir: string, options?: {
|
|
42
|
+
defaultData?: Json;
|
|
43
|
+
}): Promise<Discovery>;
|
|
44
|
+
/** One line per document, the way the pack command reports. */
|
|
45
|
+
export declare function describe(d: DevDocument): string;
|
|
46
|
+
/** Where the renderer's browser bundle lives, if @polyxd/react is installed with one. */
|
|
47
|
+
export declare function findBundle(): string | undefined;
|
|
48
|
+
/** The verifier's command line, if @polyxd/verifier is installed. */
|
|
49
|
+
export declare function findVerifier(): string | undefined;
|
|
50
|
+
export interface DevServerOptions {
|
|
51
|
+
dir: string;
|
|
52
|
+
port?: number;
|
|
53
|
+
theme?: string;
|
|
54
|
+
/** A JSON file used as data for documents that have none. */
|
|
55
|
+
data?: string;
|
|
56
|
+
/** A manifest.json or theme .css to add to the pack switcher. */
|
|
57
|
+
pack?: string;
|
|
58
|
+
/** Show the Verify button; runs @polyxd/verifier when it is installed. */
|
|
59
|
+
verify?: boolean;
|
|
60
|
+
/** Directory holding polyxd.js and polyxd.css. Default: @polyxd/react/preview. */
|
|
61
|
+
bundle?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface DevServer {
|
|
64
|
+
url: string;
|
|
65
|
+
port: number;
|
|
66
|
+
documents: () => DevDocument[];
|
|
67
|
+
broken: () => Discovery["broken"];
|
|
68
|
+
pack?: PackCss;
|
|
69
|
+
/** Re-reads the folder and tells open pages what changed. Called by the watcher; tests call it directly. */
|
|
70
|
+
rescan: () => Promise<void>;
|
|
71
|
+
close: () => Promise<void>;
|
|
72
|
+
}
|
|
73
|
+
export declare function createDevServer(options: DevServerOptions): Promise<DevServer>;
|
|
74
|
+
export declare function main(argv: string[]): Promise<number>;
|
package/dist/dev.js
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `polyxd dev`: a local preview for people who author Polyxd documents in their editor.
|
|
3
|
+
*
|
|
4
|
+
* npx polyxd dev the documents in this folder
|
|
5
|
+
* npx polyxd dev ./screens --port 4310 --theme material3 --data ./sample.json --open
|
|
6
|
+
* npx polyxd dev ./screens --pack ./ds-acme/manifest.json --verify
|
|
7
|
+
*
|
|
8
|
+
* It watches a folder for documents, renders the selected one with the real renderer in any
|
|
9
|
+
* built-in pack (or one of yours), light or dark, at phone, tablet and desktop widths, and shows
|
|
10
|
+
* beside it what the static check finds, the document, its data, and the actions it dispatches.
|
|
11
|
+
* Save a file and the surface reloads in place, keeping your selection and controls.
|
|
12
|
+
*
|
|
13
|
+
* Nothing but Node here: http, fs.watch, server-sent events, and the renderer's browser bundle
|
|
14
|
+
* from @polyxd/react/preview.
|
|
15
|
+
*/
|
|
16
|
+
import { spawn } from "node:child_process";
|
|
17
|
+
import { existsSync, watch } from "node:fs";
|
|
18
|
+
import { mkdtemp, readdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
19
|
+
import { createServer } from "node:http";
|
|
20
|
+
import { tmpdir } from "node:os";
|
|
21
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
22
|
+
import { parseArgs } from "node:util";
|
|
23
|
+
import { fileURLToPath } from "node:url";
|
|
24
|
+
import { validateDocument } from "@polyxd/spec";
|
|
25
|
+
import { packCss } from "./dev-pack.js";
|
|
26
|
+
import { devPage } from "./dev-page.js";
|
|
27
|
+
const SKIP_DIRS = new Set(["node_modules", "dist", "build", "coverage"]);
|
|
28
|
+
const THEMES = ["material3", "carbon", "antd", "fluent", "shadcn", "bootstrap", "mantine", "radix", "polaris", "primer", "spectrum", "govuk", "chakra"];
|
|
29
|
+
const isDocument = (v) => !!v && typeof v === "object" && typeof v.specVersion === "string" && Array.isArray(v.components);
|
|
30
|
+
const posix = (p) => p.split(sep).join("/");
|
|
31
|
+
/** The static check: schema and structure, and every binding against the data the surface will show. */
|
|
32
|
+
export function checkDocument(document, data) {
|
|
33
|
+
const doc = data !== undefined ? { ...document, data } : document;
|
|
34
|
+
let issues;
|
|
35
|
+
try {
|
|
36
|
+
issues = validateDocument(doc, { missingData: "warning" }).issues;
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
issues = [{ severity: "error", at: "/", message: `validator failed: ${e.message}` }];
|
|
40
|
+
}
|
|
41
|
+
return { errors: issues.filter((i) => i.severity === "error").length, warnings: issues.filter((i) => i.severity === "warning").length, issues };
|
|
42
|
+
}
|
|
43
|
+
async function* jsonFiles(dir, depth = 0) {
|
|
44
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
45
|
+
for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
46
|
+
if (e.name.startsWith("."))
|
|
47
|
+
continue;
|
|
48
|
+
if (e.isDirectory()) {
|
|
49
|
+
if (!SKIP_DIRS.has(e.name) && depth < 4)
|
|
50
|
+
yield* jsonFiles(join(dir, e.name), depth + 1);
|
|
51
|
+
}
|
|
52
|
+
else if (e.name.endsWith(".json"))
|
|
53
|
+
yield join(dir, e.name);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Every document under `dir`: a JSON file with `specVersion` and `components`, or an intent-shaped
|
|
58
|
+
* file whose `document` has them. Data is the document's own, else `<name>.data.json` beside it,
|
|
59
|
+
* else `defaultData`. Everything else (packs, reports, registries, tsconfigs) is ignored.
|
|
60
|
+
*/
|
|
61
|
+
export async function discoverDocuments(dir, options = {}) {
|
|
62
|
+
const documents = [];
|
|
63
|
+
const broken = [];
|
|
64
|
+
for await (const path of jsonFiles(dir)) {
|
|
65
|
+
if (path.endsWith(".data.json"))
|
|
66
|
+
continue;
|
|
67
|
+
const file = posix(relative(dir, path));
|
|
68
|
+
let raw;
|
|
69
|
+
try {
|
|
70
|
+
raw = JSON.parse(await readFile(path, "utf8"));
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
broken.push({ file, message: e.message });
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const kind = isDocument(raw) ? "document" : isDocument(raw?.document) ? "intent" : undefined;
|
|
77
|
+
if (!kind)
|
|
78
|
+
continue;
|
|
79
|
+
const document = kind === "intent" ? raw.document : raw;
|
|
80
|
+
let data = document.data;
|
|
81
|
+
let dataFrom = data !== undefined ? "embedded" : "none";
|
|
82
|
+
if (data === undefined) {
|
|
83
|
+
const sibling = path.replace(/\.json$/, ".data.json");
|
|
84
|
+
if (existsSync(sibling)) {
|
|
85
|
+
try {
|
|
86
|
+
data = JSON.parse(await readFile(sibling, "utf8"));
|
|
87
|
+
dataFrom = "sibling";
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
broken.push({ file: posix(relative(dir, sibling)), message: e.message });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (data === undefined && options.defaultData !== undefined) {
|
|
95
|
+
data = options.defaultData;
|
|
96
|
+
dataFrom = "default";
|
|
97
|
+
}
|
|
98
|
+
const surface = document.surface ?? {};
|
|
99
|
+
documents.push({
|
|
100
|
+
file,
|
|
101
|
+
id: String(surface.id ?? (kind === "intent" ? raw.id : "") ?? ""),
|
|
102
|
+
title: String(surface.title ?? raw.title ?? basename(file, ".json")),
|
|
103
|
+
kind,
|
|
104
|
+
origin: surface.origin,
|
|
105
|
+
pattern: surface.pattern,
|
|
106
|
+
dataFrom,
|
|
107
|
+
document,
|
|
108
|
+
data,
|
|
109
|
+
check: checkDocument(document, data),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return { documents, broken };
|
|
113
|
+
}
|
|
114
|
+
/** One line per document, the way the pack command reports. */
|
|
115
|
+
export function describe(d) {
|
|
116
|
+
const status = d.check.errors ? "error" : d.check.warnings ? "warn " : "ok ";
|
|
117
|
+
const counts = [d.check.errors ? `${d.check.errors} error${d.check.errors === 1 ? "" : "s"}` : "", d.check.warnings ? `${d.check.warnings} warning${d.check.warnings === 1 ? "" : "s"}` : ""].filter(Boolean).join(", ");
|
|
118
|
+
const what = [d.kind === "intent" ? "intent" : "document", d.origin, d.dataFrom === "none" ? "no data" : d.dataFrom === "embedded" ? "" : `data: ${d.dataFrom}`].filter(Boolean).join(" · ");
|
|
119
|
+
return ` ${status} ${d.file.padEnd(32)} ${d.title.slice(0, 28).padEnd(28)} ${what}${counts ? ` (${counts})` : ""}`;
|
|
120
|
+
}
|
|
121
|
+
/** Where the renderer's browser bundle lives, if @polyxd/react is installed with one. */
|
|
122
|
+
export function findBundle() {
|
|
123
|
+
try {
|
|
124
|
+
const js = fileURLToPath(import.meta.resolve("@polyxd/react/preview/polyxd.js"));
|
|
125
|
+
return existsSync(js) && existsSync(js.replace(/\.js$/, ".css")) ? dirname(js) : undefined;
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/** The verifier's command line, if @polyxd/verifier is installed. */
|
|
132
|
+
export function findVerifier() {
|
|
133
|
+
try {
|
|
134
|
+
const cli = fileURLToPath(import.meta.resolve("@polyxd/verifier/dist/cli.js"));
|
|
135
|
+
return existsSync(cli) ? cli : undefined;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const meta = (d) => ({ file: d.file, id: d.id, title: d.title, kind: d.kind, origin: d.origin, pattern: d.pattern, dataFrom: d.dataFrom, check: { errors: d.check.errors, warnings: d.check.warnings } });
|
|
142
|
+
const json = (res, status, body) => {
|
|
143
|
+
res.writeHead(status, { "content-type": "application/json; charset=utf-8", "cache-control": "no-store" });
|
|
144
|
+
res.end(JSON.stringify(body));
|
|
145
|
+
};
|
|
146
|
+
const text = (res, status, body, type = "text/plain") => {
|
|
147
|
+
res.writeHead(status, { "content-type": `${type}; charset=utf-8`, "cache-control": "no-store" });
|
|
148
|
+
res.end(body);
|
|
149
|
+
};
|
|
150
|
+
const sse = (res) => {
|
|
151
|
+
res.writeHead(200, { "content-type": "text/event-stream", "cache-control": "no-store", connection: "keep-alive" });
|
|
152
|
+
res.write(": polyxd dev\n\n");
|
|
153
|
+
return (event, data) => res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
|
154
|
+
};
|
|
155
|
+
export async function createDevServer(options) {
|
|
156
|
+
const dir = resolve(options.dir);
|
|
157
|
+
const info = await stat(dir).catch(() => null);
|
|
158
|
+
if (!info?.isDirectory())
|
|
159
|
+
throw new Error(`${options.dir} is not a folder`);
|
|
160
|
+
const dataFile = options.data ? resolve(options.data) : undefined;
|
|
161
|
+
const readDefaultData = async () => (dataFile ? JSON.parse(await readFile(dataFile, "utf8")) : undefined);
|
|
162
|
+
const pack = options.pack ? await packCss(resolve(options.pack)) : undefined;
|
|
163
|
+
const bundle = options.bundle ?? findBundle();
|
|
164
|
+
const theme = options.theme ?? (pack?.name ?? "material3");
|
|
165
|
+
let defaultData = await readDefaultData();
|
|
166
|
+
let found = await discoverDocuments(dir, { defaultData });
|
|
167
|
+
const clients = new Set();
|
|
168
|
+
const broadcast = (event, data) => {
|
|
169
|
+
for (const send of clients)
|
|
170
|
+
send(event, data);
|
|
171
|
+
};
|
|
172
|
+
const listing = () => ({ dir, theme, pack: pack?.name, verify: !!options.verify, bundle: !!bundle, documents: found.documents.map(meta), broken: found.broken });
|
|
173
|
+
const rescan = async () => {
|
|
174
|
+
try {
|
|
175
|
+
defaultData = await readDefaultData();
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// A half-saved default data file: keep the last good one until the next save.
|
|
179
|
+
}
|
|
180
|
+
const before = new Map(found.documents.map((d) => [d.file, JSON.stringify({ d: d.document, x: d.data })]));
|
|
181
|
+
found = await discoverDocuments(dir, { defaultData });
|
|
182
|
+
const changed = found.documents.filter((d) => before.get(d.file) !== JSON.stringify({ d: d.document, x: d.data })).map((d) => d.file);
|
|
183
|
+
const removed = [...before.keys()].filter((f) => !found.documents.some((d) => d.file === f));
|
|
184
|
+
broadcast("change", { changed, removed, ...listing() });
|
|
185
|
+
};
|
|
186
|
+
let timer;
|
|
187
|
+
const schedule = () => {
|
|
188
|
+
clearTimeout(timer);
|
|
189
|
+
timer = setTimeout(() => void rescan(), 80);
|
|
190
|
+
};
|
|
191
|
+
const watchers = [];
|
|
192
|
+
try {
|
|
193
|
+
watchers.push(watch(dir, { recursive: true }, schedule));
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
watchers.push(watch(dir, schedule));
|
|
197
|
+
}
|
|
198
|
+
if (dataFile && !dataFile.startsWith(dir + sep))
|
|
199
|
+
watchers.push(watch(dataFile, schedule));
|
|
200
|
+
let verifying = false;
|
|
201
|
+
const verify = async (doc, send, done) => {
|
|
202
|
+
const cli = findVerifier();
|
|
203
|
+
if (!cli) {
|
|
204
|
+
send("line", { text: "The verifier isn't installed here. It renders in a real browser, so it's a separate package:" });
|
|
205
|
+
send("line", { text: " npm install -D @polyxd/verifier && npx playwright install chromium" });
|
|
206
|
+
send("done", { code: 2 });
|
|
207
|
+
return done();
|
|
208
|
+
}
|
|
209
|
+
if (verifying) {
|
|
210
|
+
send("line", { text: "A verification is already running; wait for it to finish." });
|
|
211
|
+
send("done", { code: 3 });
|
|
212
|
+
return done();
|
|
213
|
+
}
|
|
214
|
+
verifying = true;
|
|
215
|
+
const tmp = await mkdtemp(join(tmpdir(), "polyxd-dev-verify-"));
|
|
216
|
+
const file = join(tmp, `${basename(doc.file, ".json")}.json`);
|
|
217
|
+
await writeFile(file, JSON.stringify(doc.data !== undefined ? { ...doc.document, data: doc.data } : doc.document));
|
|
218
|
+
send("line", { text: `polyxd-verify ${basename(file)} --themes ${THEMES.join(",")} --modes light,dark --widths 390,1100` });
|
|
219
|
+
const child = spawn(process.execPath, [cli, file, "--themes", THEMES.join(","), "--modes", "light,dark", "--widths", "390,1100"], { stdio: ["ignore", "pipe", "pipe"] });
|
|
220
|
+
let rest = "";
|
|
221
|
+
const lines = (chunk, stream) => {
|
|
222
|
+
rest += chunk.toString();
|
|
223
|
+
const parts = rest.split("\n");
|
|
224
|
+
rest = parts.pop() ?? "";
|
|
225
|
+
for (const line of parts)
|
|
226
|
+
send("line", { text: line, stream });
|
|
227
|
+
};
|
|
228
|
+
child.stdout.on("data", (c) => lines(c, "out"));
|
|
229
|
+
child.stderr.on("data", (c) => lines(c, "err"));
|
|
230
|
+
child.on("close", async (code) => {
|
|
231
|
+
if (rest)
|
|
232
|
+
send("line", { text: rest });
|
|
233
|
+
send("done", { code: code ?? 1 });
|
|
234
|
+
verifying = false;
|
|
235
|
+
await rm(tmp, { recursive: true, force: true });
|
|
236
|
+
done();
|
|
237
|
+
});
|
|
238
|
+
};
|
|
239
|
+
const handle = async (req, res) => {
|
|
240
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
241
|
+
const path = decodeURIComponent(url.pathname);
|
|
242
|
+
if (path === "/")
|
|
243
|
+
return text(res, 200, devPage({ dir, theme, pack: pack?.name, verify: !!options.verify, bundle: !!bundle, themes: THEMES }), "text/html");
|
|
244
|
+
if (path === "/preview/polyxd.js" || path === "/preview/polyxd.css") {
|
|
245
|
+
if (!bundle)
|
|
246
|
+
return text(res, 404, "The renderer bundle isn't installed: npm install @polyxd/react");
|
|
247
|
+
const body = await readFile(join(bundle, basename(path))).catch(() => null);
|
|
248
|
+
if (!body)
|
|
249
|
+
return text(res, 404, "not found");
|
|
250
|
+
res.writeHead(200, { "content-type": path.endsWith(".js") ? "text/javascript; charset=utf-8" : "text/css; charset=utf-8", "cache-control": "no-store" });
|
|
251
|
+
return res.end(body);
|
|
252
|
+
}
|
|
253
|
+
if (path === "/pack.css")
|
|
254
|
+
return pack ? text(res, 200, pack.css, "text/css") : text(res, 404, "no --pack");
|
|
255
|
+
if (path === "/api/documents")
|
|
256
|
+
return json(res, 200, listing());
|
|
257
|
+
if (path === "/api/events") {
|
|
258
|
+
const send = sse(res);
|
|
259
|
+
clients.add(send);
|
|
260
|
+
send("hello", listing());
|
|
261
|
+
req.on("close", () => clients.delete(send));
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const doc = (prefix) => (path.startsWith(prefix) ? found.documents.find((d) => d.file === path.slice(prefix.length)) : undefined);
|
|
265
|
+
if (path.startsWith("/api/documents/")) {
|
|
266
|
+
const d = doc("/api/documents/");
|
|
267
|
+
return d ? json(res, 200, { ...meta(d), document: d.document, data: d.data, issues: d.check.issues }) : json(res, 404, { error: "no such document" });
|
|
268
|
+
}
|
|
269
|
+
if (path.startsWith("/api/verify/")) {
|
|
270
|
+
const d = doc("/api/verify/");
|
|
271
|
+
if (!d)
|
|
272
|
+
return json(res, 404, { error: "no such document" });
|
|
273
|
+
const send = sse(res);
|
|
274
|
+
return verify(d, send, () => res.end());
|
|
275
|
+
}
|
|
276
|
+
text(res, 404, "not found");
|
|
277
|
+
};
|
|
278
|
+
const server = createServer((req, res) => {
|
|
279
|
+
handle(req, res).catch((e) => {
|
|
280
|
+
if (!res.headersSent)
|
|
281
|
+
json(res, 500, { error: e.message });
|
|
282
|
+
else
|
|
283
|
+
res.end();
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
const port = await new Promise((ok, fail) => {
|
|
287
|
+
server.once("error", fail);
|
|
288
|
+
server.listen(options.port ?? 4310, "127.0.0.1", () => ok(server.address().port));
|
|
289
|
+
});
|
|
290
|
+
return {
|
|
291
|
+
url: `http://localhost:${port}/`,
|
|
292
|
+
port,
|
|
293
|
+
documents: () => found.documents,
|
|
294
|
+
broken: () => found.broken,
|
|
295
|
+
pack,
|
|
296
|
+
rescan,
|
|
297
|
+
close: async () => {
|
|
298
|
+
clearTimeout(timer);
|
|
299
|
+
for (const w of watchers)
|
|
300
|
+
w.close();
|
|
301
|
+
for (const send of clients)
|
|
302
|
+
send("bye", {});
|
|
303
|
+
// Event streams never end on their own; close them so the server can.
|
|
304
|
+
const closed = new Promise((ok) => server.close(() => ok()));
|
|
305
|
+
server.closeAllConnections();
|
|
306
|
+
await closed;
|
|
307
|
+
},
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
const USAGE = `polyxd dev [dir] [--port 4310] [--theme material3] [--data <file.json>] [--pack <manifest.json|theme.css>] [--verify] [--open]
|
|
311
|
+
|
|
312
|
+
Previews the Polyxd documents in a folder (default: this one) in the browser, rendered with the
|
|
313
|
+
real renderer in any built-in design system, light or dark, at phone, tablet and desktop widths,
|
|
314
|
+
with the static check, the document, its data and the actions it dispatches beside it. Save a
|
|
315
|
+
file and the surface reloads in place.`;
|
|
316
|
+
export async function main(argv) {
|
|
317
|
+
let values;
|
|
318
|
+
let positionals;
|
|
319
|
+
try {
|
|
320
|
+
({ values, positionals } = parseArgs({
|
|
321
|
+
args: argv,
|
|
322
|
+
allowPositionals: true,
|
|
323
|
+
options: { port: { type: "string" }, theme: { type: "string" }, data: { type: "string" }, pack: { type: "string" }, verify: { type: "boolean" }, open: { type: "boolean" }, help: { type: "boolean", short: "h" } },
|
|
324
|
+
}));
|
|
325
|
+
}
|
|
326
|
+
catch (e) {
|
|
327
|
+
console.error(e.message);
|
|
328
|
+
console.log(USAGE);
|
|
329
|
+
return 2;
|
|
330
|
+
}
|
|
331
|
+
if (values.help) {
|
|
332
|
+
console.log(USAGE);
|
|
333
|
+
return 0;
|
|
334
|
+
}
|
|
335
|
+
const port = values.port === undefined ? 4310 : Number(values.port);
|
|
336
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
337
|
+
console.error(`--port should be a number, not ${values.port}`);
|
|
338
|
+
return 2;
|
|
339
|
+
}
|
|
340
|
+
if (values.theme && !THEMES.includes(String(values.theme)) && !values.pack) {
|
|
341
|
+
console.error(`--theme should be one of ${THEMES.join(", ")}, or the pack given with --pack`);
|
|
342
|
+
return 2;
|
|
343
|
+
}
|
|
344
|
+
let server;
|
|
345
|
+
try {
|
|
346
|
+
server = await createDevServer({ dir: positionals[0] ?? ".", port, theme: values.theme, data: values.data, pack: values.pack, verify: !!values.verify });
|
|
347
|
+
}
|
|
348
|
+
catch (e) {
|
|
349
|
+
const err = e;
|
|
350
|
+
console.error(err.code === "EADDRINUSE" ? `Port ${port} is taken; pass --port with another.` : err.message);
|
|
351
|
+
return 1;
|
|
352
|
+
}
|
|
353
|
+
const docs = server.documents();
|
|
354
|
+
const absolute = resolve(positionals[0] ?? ".");
|
|
355
|
+
const rel = relative(process.cwd(), absolute);
|
|
356
|
+
const dir = rel === "" ? "." : rel.startsWith("..") ? absolute : rel;
|
|
357
|
+
console.log(`polyxd dev ${server.url}`);
|
|
358
|
+
console.log(`${docs.length} document${docs.length === 1 ? "" : "s"} in ${dir}, watching for changes${server.pack ? ` · pack ${server.pack.name} from --pack` : ""}${values.verify ? findVerifier() ? " · verifier ready" : " · verifier not installed (npm install -D @polyxd/verifier)" : ""}`);
|
|
359
|
+
if (!findBundle())
|
|
360
|
+
console.log("The renderer bundle isn't installed, so the page can list and check documents but not render them: npm install @polyxd/react");
|
|
361
|
+
for (const d of docs)
|
|
362
|
+
console.log(describe(d));
|
|
363
|
+
for (const b of server.broken())
|
|
364
|
+
console.log(` error ${b.file.padEnd(32)} did not parse: ${b.message}`);
|
|
365
|
+
if (!docs.length)
|
|
366
|
+
console.log(" (no documents yet: a document is a JSON file with specVersion and components, or an intent file with a document inside)");
|
|
367
|
+
if (values.open) {
|
|
368
|
+
const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
369
|
+
spawn(opener, [server.url], { stdio: "ignore", detached: true, shell: process.platform === "win32" }).on("error", () => undefined).unref();
|
|
370
|
+
}
|
|
371
|
+
return 0;
|
|
372
|
+
}
|
|
373
|
+
//# sourceMappingURL=dev.js.map
|
package/dist/dev.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"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"}
|
package/dist/polyxd.js
CHANGED
|
@@ -34,6 +34,14 @@ switch (command) {
|
|
|
34
34
|
const { main } = await import("./studio.js");
|
|
35
35
|
process.exit(await main(rest));
|
|
36
36
|
}
|
|
37
|
+
case "dev": {
|
|
38
|
+
// Stays up once it has started: the server and the watcher keep the process alive.
|
|
39
|
+
const { main } = await import("./dev.js");
|
|
40
|
+
const code = await main(rest);
|
|
41
|
+
if (code || rest.includes("--help") || rest.includes("-h"))
|
|
42
|
+
process.exit(code);
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
37
45
|
default:
|
|
38
46
|
console.log(`polyxd <command>
|
|
39
47
|
|
|
@@ -47,7 +55,12 @@ switch (command) {
|
|
|
47
55
|
|
|
48
56
|
studio push <package dir | tarball | token file> --to <studio>/api/w/<workspace>
|
|
49
57
|
Sends your tokens to Polyxd Studio as a new version of your design system, using an
|
|
50
|
-
API key from POLYXD_STUDIO_KEY. Made for a CI step on every release
|
|
58
|
+
API key from POLYXD_STUDIO_KEY. Made for a CI step on every release.
|
|
59
|
+
|
|
60
|
+
dev [dir] [--port 4310] [--theme material3] [--data <file.json>] [--pack <manifest.json|theme.css>] [--verify] [--open]
|
|
61
|
+
Previews the documents in a folder as you edit them: rendered with the real renderer in
|
|
62
|
+
any built-in pack or one of yours, light or dark, phone to desktop, with the static check,
|
|
63
|
+
the document, its data and the actions it dispatches beside it. Reloads on save.`);
|
|
51
64
|
process.exit(command ? 1 : 0);
|
|
52
65
|
}
|
|
53
66
|
export {};
|
package/dist/polyxd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polyxd.js","sourceRoot":"","sources":["../src/polyxd.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjD,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;AAE3D,QAAQ,OAAO,EAAE,CAAC;IAChB,KAAK,MAAM;QACT,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QACzB,MAAM;IACR,KAAK,OAAO,EAAE,CAAC;QACb,sFAAsF;QACtF,6BAA6B;QAC7B,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACjD,KAAK,MAAM,CAAC,IAAI,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/F,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,sDAAsD,CAAC,CAAC;QACpH,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,KAAK,QAAQ,EAAE,CAAC;QACd,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACjC,CAAC;IACD;QACE,OAAO,CAAC,GAAG,CAAC
|
|
1
|
+
{"version":3,"file":"polyxd.js","sourceRoot":"","sources":["../src/polyxd.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjD,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;AAE3D,QAAQ,OAAO,EAAE,CAAC;IAChB,KAAK,MAAM;QACT,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QACzB,MAAM;IACR,KAAK,OAAO,EAAE,CAAC;QACb,sFAAsF;QACtF,6BAA6B;QAC7B,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACjD,KAAK,MAAM,CAAC,IAAI,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/F,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,sDAAsD,CAAC,CAAC;QACpH,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,KAAK,QAAQ,EAAE,CAAC;QACd,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,KAAK,KAAK,EAAE,CAAC;QACX,mFAAmF;QACnF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/E,MAAM;IACR,CAAC;IACD;QACE,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;uFAiBuE,CAAC,CAAC;QACrF,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polyxd/ds-kit",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Shared parts of building a Polyxd design-system pack
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Shared parts of building a Polyxd design-system pack, and the polyxd command: pack, check, studio push, dev",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@polyxd/spec": "^0.
|
|
27
|
+
"@polyxd/spec": "^0.3.0"
|
|
28
28
|
},
|
|
29
29
|
"bin": {
|
|
30
30
|
"polyxd": "dist/polyxd.js"
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
"NOTICE"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@polyxd/spec": "^0.
|
|
44
|
+
"@polyxd/spec": "^0.3.0",
|
|
45
|
+
"@polyxd/react": "^0.3.0"
|
|
45
46
|
},
|
|
46
47
|
"repository": {
|
|
47
48
|
"type": "git",
|