import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises"; import { fileURLToPath } from "node:url"; import { build } from "esbuild"; import { writeWebLicenseNotices } from "./package-licenses.mjs"; import { createElement } from "react"; import { renderToStaticMarkup } from "react-dom/server"; import { tsImport } from "tsx/esm/api"; import { buildDocumentation } from "../site/docs/build.mjs"; const source = new URL("../site/", import.meta.url); const output = new URL("../build/site/", import.meta.url); await rm(output, { recursive: true, force: true }); await mkdir(output, { recursive: true }); await cp(source, output, { recursive: true, filter: (path) => path !== fileURLToPath(new URL("docs", source)) && !path.endsWith(".ts") && !path.endsWith(".tsx") && !path.endsWith("tsconfig.json") && !path.endsWith("README.md"), }); await cp(new URL("../LICENSE", import.meta.url), new URL("LICENSE", output)); const [{ locales }, { Glyph }] = await Promise.all([ "../src/client/locales/index.ts", "../src/client/ui/icons.tsx", ].map(path => tsImport(path, { parentURL: import.meta.url, tsconfig: fileURLToPath(new URL("../src/tsconfig.json", import.meta.url)), }))); // Independent locale pools stay inert HTML; the first entry is also the no-JS fallback. const welcomePools = [locales.en, locales.zh].map(locale => locale.playful.welcome.map(({ text }) => renderToStaticMarkup(createElement("span", { lang: locale.tag }, `“${text}”`)))); const homepage = (await readFile(new URL("index.html", source), "utf8")) .replace(/
.*?<\/p>/, `
${welcomePools.map(pool => pool[0] ?? "").join("")}
`); await writeFile(new URL("index.html", output), homepage.replace( '', `${welcomePools.flat().join('')}`, )); // The page shares only the small, DOM-based rotation owner with the product UI. await build({ entryPoints: [fileURLToPath(new URL("main.js", source))], outfile: fileURLToPath(new URL("main.js", output)), bundle: true, format: "esm", minify: true, }); // The opening shot uses the current homepage, with only its film clock adapter // substituted for the ordinary page script. Keep its layout and copy in one place. await writeFile(new URL("film/ui/website.html", output), homepage .replace('
', '
') .replace('', '') .replace('', (await readFile(new URL("film/ui/index.html", source), "utf8")).match(/