// Bundles the 2026 explorer's standalone build (eqtylab/explorer `dist/standalone`, built // from the `preview` branch with `pnpm build:standalone`) into one self-contained // explorer/explorer.js: lazy chunks, highlighter grammars and wasm all inline. // // Why: same reason as legacy/bundle.mjs. In a private Space only a request carrying the // `__sign` token is authorized inside the huggingface.co embed, and the standalone build // fetches its chunks and wasm relative to itself, without the token. One file = one // request, which index.html makes with the token. // // Usage: node explorer/bundle.mjs [path/to/explorer/dist/standalone] import { build } from "esbuild"; import { readFileSync, writeFileSync, readdirSync, mkdtempSync, cpSync } from "node:fs"; import { join, dirname } from "node:path"; import { tmpdir } from "node:os"; import { fileURLToPath } from "node:url"; const here = dirname(fileURLToPath(import.meta.url)); const src = process.argv[2] || join(here, "../../../EQTY/explorer/dist/standalone"); const work = mkdtempSync(join(tmpdir(), "explorer-")); cpSync(src, work, { recursive: true }); // new URL("x.wasm", import.meta.url) -> a data: URI (the wasm loaders accept those) const wasmUri = (f) => `data:application/wasm;base64,${readFileSync(join(work, f)).toString("base64")}`; let inlined = 0; for (const f of readdirSync(work).filter((f) => f.endsWith(".js"))) { const path = join(work, f); const text = readFileSync(path, "utf8").replace(/new URL\("([\w.-]+\.wasm)",import\.meta\.url\)/g, (m, w) => { inlined++; return `new URL("${wasmUri(w)}")`; }); writeFileSync(path, text); } const wasmCount = readdirSync(work).filter((f) => f.endsWith(".wasm")).length; if (inlined < wasmCount) throw new Error(`inlined ${inlined} wasm references, expected at least ${wasmCount}`); // esbuild folds the dynamic imports (verifier chunk, ./grammars/${lang}.js) into the bundle. const out = await build({ entryPoints: [join(work, "explorer.js")], bundle: true, format: "esm", write: false, minify: true, target: "es2022", logLevel: "warning", legalComments: "none", }); const js = out.outputFiles[0].text; const banner = `// 2026 explorer (@eqtylab/explorer standalone, preview branch). Generated by explorer/bundle.mjs; don't edit.\n`; writeFileSync(join(here, "explorer.js"), banner + js); console.log(`explorer/explorer.js: ${(js.length / 1e6).toFixed(2)} MB (${inlined} wasm inlined)`);