import { createHash } from "node:crypto"; import { copyFileSync, readFileSync, writeFileSync } from "node:fs"; import { dirname, resolve } from "node:path"; import { fileURLToPath } from "node:url"; const root = resolve(dirname(fileURLToPath(import.meta.url)), ".."); const packageRoot = resolve(root, "node_modules/@rerun-io/web-viewer"); const manifest = JSON.parse(readFileSync(resolve(packageRoot, "package.json"), "utf8")); const vendorRoot = resolve(root, "vendor/rerun-web-viewer-0.34.1"); const sha256File = (path) => createHash("sha256").update(readFileSync(path)).digest("hex"); if (manifest.version !== "0.34.1") { throw new Error( `Refusing to patch @rerun-io/web-viewer ${manifest.version}; audit the new vendor lifecycle first.`, ); } const vendorRuntime = [ { label: "wasm runtime", packagePath: resolve(packageRoot, "re_viewer_bg.wasm"), vendorPath: resolve(vendorRoot, "re_viewer_bg.nodedc.wasm"), publishedSha256: "3fe7aab8ea6bb0fd03c3ef694932943411ee174029e398c539c390beb0824d35", previousNodedcSha256: "e85dbad1569431620d4fabb18c1dbddd3a26d071eec1bb88a036fa755bc921da", nodedcSha256: "6aca9da47ad561d2046ad0c7c0b8a7f653f023a77132c5c6304789320db512c2", }, { label: "wasm JavaScript glue", packagePath: resolve(packageRoot, "re_viewer.js"), vendorPath: resolve(vendorRoot, "re_viewer.nodedc.js"), publishedSha256: "7c4ba900820137a6ba23e0f7f57d56e3b007db0de3825d5c8bf0d7684b3cc6a6", nodedcSha256: "0f7b76c9f24cbd8437021b5d37499894aeadc586183e422ebc82ef556d7b8339", }, ]; for (const runtime of vendorRuntime) { const vendorSha256 = sha256File(runtime.vendorPath); if (vendorSha256 !== runtime.nodedcSha256) { throw new Error( `Refusing corrupt NODE.DC Rerun ${runtime.label}: ${vendorSha256} != ${runtime.nodedcSha256}`, ); } const installedSha256 = sha256File(runtime.packagePath); if ( ![ runtime.publishedSha256, runtime.previousNodedcSha256, runtime.nodedcSha256, ].includes(installedSha256) ) { throw new Error( `Refusing to replace unexpected Rerun ${runtime.label}: ${installedSha256}`, ); } copyFileSync(runtime.vendorPath, runtime.packagePath); if (sha256File(runtime.packagePath) !== runtime.nodedcSha256) { throw new Error(`NODE.DC Rerun ${runtime.label} verification failed after copy`); } } const patches = [ { label: "compiled watchdog", path: resolve(packageRoot, "index.js"), before: ` function check_for_panic() {\n if (self.#handle?.has_panicked()) {`, after: ` function check_for_panic() {\n if (self.#state !== "ready" || !self.#handle) {\n return;\n }\n if (self.#handle.has_panicked()) {`, }, { label: "source watchdog", path: resolve(packageRoot, "index.ts"), before: ` function check_for_panic() {\n if (self.#handle?.has_panicked()) {`, after: ` function check_for_panic() {\n if (self.#state !== "ready" || !self.#handle) {\n return;\n }\n if (self.#handle.has_panicked()) {`, }, { label: "compiled singleton global listener", path: resolve(packageRoot, "index.js"), before: `function setupGlobalEventListeners() {\n window.addEventListener("keyup", (e) => {`, after: `let globalEventListenersInstalled = false;\nfunction setupGlobalEventListeners() {\n if (globalEventListenersInstalled) {\n return;\n }\n globalEventListenersInstalled = true;\n window.addEventListener("keyup", (e) => {`, }, { label: "source singleton global listener", path: resolve(packageRoot, "index.ts"), before: `function setupGlobalEventListeners() {\n window.addEventListener("keyup", (e) => {`, after: `let globalEventListenersInstalled = false;\nfunction setupGlobalEventListeners() {\n if (globalEventListenersInstalled) {\n return;\n }\n globalEventListenersInstalled = true;\n window.addEventListener("keyup", (e) => {`, }, ]; for (const patch of patches) { const source = readFileSync(patch.path, "utf8"); if (source.includes(patch.after)) continue; if (!source.includes(patch.before)) { throw new Error(`Vendor ${patch.label} patch no longer matches ${patch.path}.`); } writeFileSync(patch.path, source.replace(patch.before, patch.after)); } for (const path of [resolve(packageRoot, "index.js"), resolve(packageRoot, "index.ts")]) { const source = readFileSync(path, "utf8"); const keyupListenerCount = source.split('window.addEventListener("keyup"').length - 1; if (!source.includes("let globalEventListenersInstalled = false;") || keyupListenerCount !== 1) { throw new Error(`Vendor singleton global listener verification failed for ${path}.`); } } console.log( "Patched @rerun-io/web-viewer 0.34.1 pointer navigation, camera continuity, watchdog teardown, and singleton global keyup listener.", );