59 lines
2.2 KiB
JavaScript
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 };
|
|
}
|