/** * Build dist/diagram-render.html — the single-file offline render page. * * One command updates everything: `bun run build` (in this directory) or * `bun run build:diagram-render` (repo root). To bump a dependency: edit the * exact pin in package.json, `bun install`, rebuild, commit src + dist + * BUILD_INFO.json together. The drift test (test/diagram-render-drift.test.ts) * fails CI when dist and BUILD_INFO disagree. * * Page assembly notes (learned in the spike, do not "simplify" away): * - The script MUST be `type="module"` — mermaid's bundle contains * import.meta, which throws in a classic script. * - ` terminates early ("Unexpected end of input"). * - A with an absolute URL is required: the page lives at * about:blank (page.setContent), where relative URL construction throws. */ import { createHash } from "node:crypto"; import path from "node:path"; const ROOT = path.resolve(import.meta.dir, ".."); const ENTRY = path.join(ROOT, "src", "entry.ts"); const DIST_DIR = path.join(ROOT, "dist"); const DIST_HTML = path.join(DIST_DIR, "diagram-render.html"); const BUILD_INFO = path.join(DIST_DIR, "BUILD_INFO.json"); const pkg = await Bun.file(path.join(ROOT, "package.json")).json(); const deps: Record = pkg.dependencies; const result = await Bun.build({ entrypoints: [ENTRY], target: "browser", minify: true, define: { __BUNDLE_INFO_DEPS__: JSON.stringify(deps), "process.env.NODE_ENV": '"production"', }, }); if (!result.success) { for (const log of result.logs) console.error(log); process.exit(1); } const js = await result.outputs[0].text(); // Escape inline-script terminators (see header note). const inlineJs = js.replaceAll(" gstack diagram-render
loading
`; const html = head + inlineJs + tail; await Bun.write(DIST_HTML, html); const sha256 = createHash("sha256").update(html).digest("hex"); // Source fingerprint: lets the drift test catch "edited src, forgot to // rebuild dist" WITHOUT needing node_modules for a full rebuild (the deep // rebuild check only runs where deps are installed). const srcSha256 = createHash("sha256") .update(await Bun.file(ENTRY).text()) .update(await Bun.file(import.meta.path).text()) .digest("hex"); const info = { name: "gstack-diagram-render", sha256, srcSha256, bytes: Buffer.byteLength(html), bunVersion: Bun.version, deps, }; await Bun.write(BUILD_INFO, JSON.stringify(info, null, 2) + "\n"); console.log(`built ${path.relative(process.cwd(), DIST_HTML)} (${(info.bytes / 1024 / 1024).toFixed(2)} MB)`); console.log(`sha256 ${sha256}`);