#!/usr/bin/env node
import { existsSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import {
buildWebPackage,
collectBundleSize,
cleanOutputDir,
collectAssetFiles,
copyDirectory,
writeCompressedSiblings,
rewriteIndexForPackage,
rewriteRuntimeForPackage,
} from "./web-bundle-tools.mjs";
const assert = (condition, message) => {
if (!condition) {
console.error(message);
process.exit(1);
}
};
buildWebPackage("examples/counter/web_wasm");
const manifest = collectBundleSize("examples/counter/web_wasm");
assert(manifest.schemaVersion === 1, "bundle manifest schema version mismatch");
assert(manifest.package === "examples/counter/web_wasm", "bundle package mismatch");
assert(manifest.assets.some(asset => asset.name === "web_wasm.wasm" && asset.group === "app"), "missing wasm asset");
assert(manifest.assets.some(asset => asset.name === "runtime.js" && asset.group === "runtime"), "missing runtime.js asset");
assert(manifest.assets.some(asset => asset.name === "browser_runtime.js" && asset.group === "runtime"), "missing browser_runtime.js asset");
assert(manifest.assets.some(asset => asset.name === "canvas2d_runtime.js" && asset.group === "runtime"), "missing canvas2d_runtime.js asset");
assert(manifest.assets.some(asset => asset.name === "assets/readme.txt" && asset.group === "assets"), "missing copied asset fixture in size manifest");
assert(manifest.groupTotals.assets.rawBytes > 0, "asset group total should include fixture bytes");
assert(manifest.totals.rawBytes >= manifest.groupTotals.app.rawBytes + manifest.groupTotals.runtime.rawBytes, "bundle total should include app and runtime groups");
const html = `import { bootMouiWasmGcApp } from "../../../moui_web_renderer/runtime.js";
bootMouiWasmGcApp({
wasmUrl: new URL(
"../../../_build/wasm-gc/debug/build/examples/counter/web_wasm/web_wasm.wasm",
import.meta.url,
),
});`;
const rewritten = rewriteIndexForPackage(html, "web_wasm.wasm");
assert(rewritten.includes('from "./runtime.js"'), "packaged index should import local runtime.js");
assert(rewritten.includes('"./web_wasm.wasm"'), "packaged index should reference local wasm");
assert(!rewritten.includes("_build/wasm-gc"), "packaged index should not reference build tree");
const runtimeSource = readFileSync("moui_web_renderer/runtime.js", "utf8");
assert(!runtimeSource.includes('from "./canvas2d_runtime.js"'), "runtime.js should not statically import Canvas2D fallback");
assert(runtimeSource.includes('await import("./canvas2d_runtime.js")'), "runtime.js should dynamically import Canvas2D fallback");
const packagedRuntime = rewriteRuntimeForPackage(runtimeSource);
assert(packagedRuntime.includes('from "./browser_runtime.js"'), "packaged runtime should import local browser_runtime.js");
assert(!packagedRuntime.includes("../moui/backend/web/browser_runtime.js"), "packaged runtime should not reference the source tree");
const tmp = mkdtempSync(join(tmpdir(), "moui-web-bundle-tools-"));
writeFileSync(join(tmp, "manifest.json"), JSON.stringify(manifest, null, 2));
const assetOutput = cleanOutputDir(join(tmp, "assets-out"));
copyDirectory("examples/counter/web_wasm/assets", join(assetOutput, "assets"));
for (const asset of collectAssetFiles(join(assetOutput, "assets"))) {
writeCompressedSiblings(asset.fullPath);
}
assert(existsSync(join(assetOutput, "assets", "readme.txt.gz")), "packaged asset gzip sibling missing");
assert(existsSync(join(assetOutput, "assets", "readme.txt.br")), "packaged asset brotli sibling missing");
console.log("web bundle tool tests: ok");