Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer, web workflow engine and protocol, tooling, docs and task records. Large generated evidence, user-testing archives, build snapshots and imported test assets remain untracked. Co-Authored-By: Claude Code <noreply@anthropic.com>
49 lines
2.3 KiB
JavaScript
49 lines
2.3 KiB
JavaScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import crypto from "node:crypto";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const hash = (bytes) => crypto.createHash("sha256").update(bytes).digest("hex");
|
|
|
|
export function syncWebEngineRuntime(root) {
|
|
const build = path.join(root, "build_web_blender6/bin");
|
|
const wasm = fs.readFileSync(path.join(build, "web_engine.wasm"));
|
|
const loader = fs.readFileSync(path.join(build, "web_engine.js"));
|
|
if (!WebAssembly.validate(wasm) || !loader.length) throw new Error("compiled WebEngine artifacts are invalid");
|
|
const manifestPath = path.join(root, "web/app/public/wasm-module-manifest.json");
|
|
const original = fs.readFileSync(manifestPath, "utf8");
|
|
const manifest = JSON.parse(original);
|
|
const artifactHashes = { "web_engine.wasm": hash(wasm), "web_engine.js": hash(loader) };
|
|
let bindings = 0;
|
|
for (const module of manifest.modules ?? []) {
|
|
for (const resource of Object.values(module.resources ?? {})) {
|
|
for (const [name, digest] of Object.entries(artifactHashes)) {
|
|
if (resource.url === `/vendor/blender/${name}`) {
|
|
resource.sha256 = digest;
|
|
bindings += 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!bindings) throw new Error("runtime manifest has no compiled WebEngine binding");
|
|
const changed = [];
|
|
const write = (destination, data) => {
|
|
if (fs.existsSync(destination) && fs.readFileSync(destination).equals(Buffer.from(data))) return;
|
|
fs.mkdirSync(path.dirname(destination), { recursive: true });
|
|
const temporary = `${destination}.tmp-${process.pid}`;
|
|
fs.writeFileSync(temporary, data);
|
|
fs.renameSync(temporary, destination);
|
|
changed.push(path.relative(root, destination));
|
|
};
|
|
for (const directory of ["web/app/src/vendor/blender", "web/app/public/vendor/blender"]) {
|
|
write(path.join(root, directory, "web_engine.js"), loader);
|
|
write(path.join(root, directory, "web_engine.wasm"), wasm);
|
|
}
|
|
write(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
return { operation: "sync_compiled_runtime", status: "PASS", changed, bindings, artifactHashes };
|
|
}
|
|
|
|
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
console.log(JSON.stringify(syncWebEngineRuntime(path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."))));
|
|
}
|