Files
FreeCADWasmDev/tools/wasm-probe-runtime.mjs
wangdequan 9a7c4f0335 Save FreeCAD Web workspace sources and user validation evidence
IFC native binding remains incomplete; preserve accurate test results.
2026-09-15 22:01:58 +08:00

59 lines
2.2 KiB
JavaScript

import fs from "node:fs";
import path from "node:path";
import { createRequire } from "node:module";
import { pathToFileURL } from "node:url";
function hasArtifacts(directory, stem) {
return fs.existsSync(path.join(directory, `${stem}.js`))
&& fs.existsSync(path.join(directory, `${stem}.wasm`));
}
export function resolveProbeBuildDirectory(input, stem) {
const requested = path.resolve(input);
const candidates = [requested];
if (path.basename(requested) === "bin") candidates.push(path.dirname(requested));
else candidates.push(path.join(requested, "bin"));
for (const candidate of candidates) {
if (hasArtifacts(candidate, stem)) return candidate;
const bin = path.join(candidate, "bin");
if (hasArtifacts(bin, stem)) return bin;
}
throw new Error(`missing ${stem}.{js,wasm} under ${requested}`);
}
export function stagePthreadWorker(buildDirectory, stem) {
const workerJs = path.join(buildDirectory, `${stem}.worker.js`);
if (!fs.existsSync(workerJs)) return null;
const workerCjs = path.join(buildDirectory, `${stem}.worker.cjs`);
const source = fs.statSync(workerJs);
let current = null;
try {
current = fs.statSync(workerCjs);
} catch {
// The CommonJS staging artifact will be created below.
}
if (!current || current.size !== source.size || current.mtimeMs < source.mtimeMs) {
fs.copyFileSync(workerJs, workerCjs);
}
return workerCjs;
}
export async function loadWasmProbe(input, stem, options = {}) {
const buildDirectory = resolveProbeBuildDirectory(input, stem);
const workerCjs = stagePthreadWorker(buildDirectory, stem);
globalThis.__dirname = `${buildDirectory}${path.sep}`;
globalThis.require = createRequire(import.meta.url);
const loader = await import(pathToFileURL(path.join(buildDirectory, `${stem}.js`)));
const locateFile = (file) => {
if (workerCjs && file.endsWith(".worker.js")) return workerCjs;
return path.join(buildDirectory, file);
};
const kernel = await loader.default({
wasmBinary: fs.readFileSync(path.join(buildDirectory, `${stem}.wasm`)),
locateFile,
print: options.print ?? (() => {}),
printErr: options.printErr ?? (() => {}),
});
return { kernel, buildDirectory, workerCjs };
}