@velumo/theme-show-engine 0.1.0-beta.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,81 @@
1
+ // Embeds the show-engine theme's woff2 fonts into `src/fonts.generated.ts` as
2
+ // base64 data-URIs, so the theme is self-contained and the DOM renderer can
3
+ // inject `@font-face` rules that reach every surface (deck, presenter, overview,
4
+ // CLI-default) without any font-serving plumbing.
5
+ //
6
+ // Usage:
7
+ // node scripts/embed-fonts.mjs # (re)generate src/fonts.generated.ts
8
+ // node scripts/embed-fonts.mjs --check # fail if the committed file is stale
9
+ //
10
+ // The fonts are read from the show-engine example's public/fonts directory,
11
+ // which remains the source of truth for the binary woff2 files.
12
+
13
+ import { readFile, writeFile } from "node:fs/promises";
14
+ import { dirname, join } from "node:path";
15
+ import { fileURLToPath } from "node:url";
16
+
17
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
18
+ const packageDir = join(scriptDir, "..");
19
+ const repoRoot = join(packageDir, "..", "..");
20
+ const fontsDir = join(repoRoot, "examples", "show-engine", "public", "fonts");
21
+ const outFile = join(packageDir, "src", "fonts.generated.ts");
22
+
23
+ // file (in fontsDir) -> face metadata. The typography tokens name these
24
+ // families/weights; font-display: swap matches the example's prior fonts.css.
25
+ const FACES = [
26
+ { file: "bebas-neue-latin-400-normal.woff2", family: "Bebas Neue", weight: 400 },
27
+ { file: "inter-latin-400-normal.woff2", family: "Inter", weight: 400 },
28
+ { file: "inter-latin-500-normal.woff2", family: "Inter", weight: 500 },
29
+ { file: "inter-latin-600-normal.woff2", family: "Inter", weight: 600 },
30
+ { file: "inter-latin-700-normal.woff2", family: "Inter", weight: 700 },
31
+ { file: "jetbrains-mono-latin-400-normal.woff2", family: "JetBrains Mono", weight: 400 },
32
+ { file: "jetbrains-mono-latin-500-normal.woff2", family: "JetBrains Mono", weight: 500 },
33
+ { file: "jetbrains-mono-latin-700-normal.woff2", family: "JetBrains Mono", weight: 700 },
34
+ ];
35
+
36
+ async function render() {
37
+ const entries = [];
38
+ for (const face of FACES) {
39
+ const bytes = await readFile(join(fontsDir, face.file));
40
+ if (bytes.subarray(0, 4).toString("latin1") !== "wOF2") {
41
+ throw new Error(`${face.file} is not a woff2 file (missing wOF2 signature)`);
42
+ }
43
+ const source = `data:font/woff2;base64,${bytes.toString("base64")}`;
44
+ entries.push(
45
+ ` {\n` +
46
+ ` family: ${JSON.stringify(face.family)},\n` +
47
+ ` weight: ${face.weight},\n` +
48
+ ` style: "normal",\n` +
49
+ ` display: "swap",\n` +
50
+ ` source: ${JSON.stringify(source)},\n` +
51
+ ` },`,
52
+ );
53
+ }
54
+
55
+ return (
56
+ `// AUTO-GENERATED by scripts/embed-fonts.mjs — do not edit by hand.\n` +
57
+ `// Regenerate with: node scripts/embed-fonts.mjs\n` +
58
+ `// The woff2 bytes are OFL-licensed; see OFL.txt and README.md.\n` +
59
+ `import type { ThemeFontFace } from "@velumo/core";\n\n` +
60
+ `export const showEngineFonts: readonly ThemeFontFace[] = [\n` +
61
+ `${entries.join("\n")}\n` +
62
+ `];\n`
63
+ );
64
+ }
65
+
66
+ const check = process.argv.includes("--check");
67
+ const rendered = await render();
68
+
69
+ if (check) {
70
+ const existing = await readFile(outFile, "utf8").catch(() => "");
71
+ if (existing !== rendered) {
72
+ console.error(
73
+ "fonts.generated.ts is stale — run `node scripts/embed-fonts.mjs`.",
74
+ );
75
+ process.exit(1);
76
+ }
77
+ console.log("fonts.generated.ts is up to date.");
78
+ } else {
79
+ await writeFile(outFile, rendered);
80
+ console.log(`Wrote ${outFile} (${FACES.length} faces).`);
81
+ }