diff --git a/rerun_js/web-viewer/build-wasm.mjs b/rerun_js/web-viewer/build-wasm.mjs index 8921bf378bb9..81ca9d67c5ea 100644 --- a/rerun_js/web-viewer/build-wasm.mjs +++ b/rerun_js/web-viewer/build-wasm.mjs @@ -14,7 +14,7 @@ const exec = (cmd) => { child_process.execSync(cmd, { cwd: __dirname, stdio: "inherit" }); }; -function wasm(mode) { +function buildWebViewer(mode) { switch (mode) { case "debug": { return exec( @@ -31,13 +31,9 @@ function wasm(mode) { } } -child_process.execSync( - "cargo run -p re_dev_tools -- build-web-viewer --debug --target no-modules-base -o rerun_js/web-viewer", - { cwd: __dirname, stdio: "inherit" }, -); - -function script() { +async function re_viewer_js(mode) { let code = fs.readFileSync(path.join(__dirname, "re_viewer.js"), "utf-8"); + await checkHash(mode, "re_viewer.js", code); // this transforms the module, wrapping it in a default-exported function. // calling the function produces a new "instance" of the module, because @@ -64,11 +60,10 @@ ${code} function deinit() { __wbg_init.__wbindgen_wasm_module = null; wasm = null; - cachedFloat32Memory0 = null; - cachedFloat64Memory0 = null; - cachedInt32Memory0 = null; - cachedUint32Memory0 = null; - cachedUint8Memory0 = null; + cachedFloat32ArrayMemory0 = null; + cachedInt32ArrayMemory0 = null; + cachedUint32ArrayMemory0 = null; + cachedUint8ArrayMemory0 = null; } return Object.assign(__wbg_init, { initSync, deinit }, __exports); @@ -94,8 +89,9 @@ return Object.assign(__wbg_init, { initSync, deinit }, __exports); fs.writeFileSync(path.join(__dirname, "re_viewer.js"), code); } -function types() { +async function re_viewer_d_ts(mode) { let code = fs.readFileSync(path.join(__dirname, "re_viewer.d.ts"), "utf-8"); + await checkHash(mode, "re_viewer.d.ts", code); // this transformation just re-exports WebHandle and adds a default export inside the `.d.ts` file @@ -108,18 +104,77 @@ export default function(): wasm_bindgen; fs.writeFileSync(path.join(__dirname, "re_viewer.d.ts"), code); } +async function hash(data) { + const buffer = await crypto.subtle.digest("sha-256", data); + return Array.from(new Uint8Array(buffer)) + .map((b) => b.toString(16).padStart(2, "0")) + .join(""); +} + +async function checkHash(mode, id, data) { + const storedHash = hashes?.[mode]?.[id]; + const computedHash = await hash(new TextEncoder().encode(data)); + + if (updateHashes) { + hashes[mode] ??= {}; + hashes[mode][id] = computedHash; + return; + } + + if (storedHash !== computedHash) { + console.error(` +============================================================== +Output of "${id}" changed. +Update the \`build-wasm.mjs\` script to handle the new output, +then run \`pixi run node build-wasm.mjs --update-hashes\`. +============================================================== +`); + process.exit(1); + } +} + +async function run(mode) { + buildWebViewer(mode); + await re_viewer_js(mode); + await re_viewer_d_ts(mode); +} + const args = util.parseArgs({ options: { mode: { type: "string", }, + "update-hashes": { + type: "boolean", + }, }, }); -if (!args.values.mode) { - throw new Error("Missing required argument: mode"); +let updateHashes = !!args.values["update-hashes"]; +let hashes; +try { + hashes = JSON.parse( + fs.readFileSync(path.join(__dirname, "hashes.json"), "utf-8"), + ); +} catch (e) { + hashes = {}; } -wasm(args.values.mode); -script(); -types(); +try { + if (updateHashes) { + await run("release"); + await run("debug"); + fs.writeFileSync( + path.join(__dirname, "hashes.json"), + JSON.stringify(hashes), + ); + } else { + if (!args.values.mode) { + throw new Error("Missing required argument: mode"); + } + + await run(args.values.mode); + } +} catch (e) { + console.error(e.message); +} diff --git a/rerun_js/web-viewer/hashes.json b/rerun_js/web-viewer/hashes.json new file mode 100644 index 000000000000..6dd33989c499 --- /dev/null +++ b/rerun_js/web-viewer/hashes.json @@ -0,0 +1 @@ +{"release":{"re_viewer.js":"9548c50002f6c6844e50ceb154641a4ca547413a54eb3214b18909848776492f","re_viewer.d.ts":"d533906cbd59ac7b2f4a962a24daad55c5df854343414b8b6db08e2d956fdee3"},"debug":{"re_viewer.js":"74ec126e7deeb831c72c7a2ccffb98c3c63fb7268f27feffdfb2da286db65816","re_viewer.d.ts":"c642a7f1990d414d9953f0b215d8114418502b3b9f0240ca81b039766d5236b0"}} \ No newline at end of file diff --git a/rerun_js/web-viewer/package.json b/rerun_js/web-viewer/package.json index 6ec096d30663..166571453f92 100644 --- a/rerun_js/web-viewer/package.json +++ b/rerun_js/web-viewer/package.json @@ -61,4 +61,4 @@ "dts-buddy": "^0.3.0", "typescript": "^5.2.2" } -} \ No newline at end of file +}