mcard-js
Version:
MCard - Content-addressable storage with cryptographic hashing, handle resolution, and vector search for Node.js and browsers
55 lines • 2.17 kB
JavaScript
/**
* WASM runtime executor.
*
* Executes WebAssembly modules via wasmtime CLI.
*/
import * as path from 'path';
import * as child_process from 'child_process';
export class WasmRuntime {
async execute(wasmPath, context, config, chapterDir) {
const fullPath = path.resolve(chapterDir, wasmPath);
const contextStr = typeof context === 'string' ? context : JSON.stringify(context ?? {});
return new Promise((resolve, reject) => {
const proc = child_process.spawn('wasmtime', [fullPath, contextStr]);
// Close stdin immediately - WASM programs don't read from stdin
proc.stdin.end();
let stdout = '';
let stderr = '';
proc.stdout.on('data', (data) => {
stdout += data.toString('utf-8');
});
proc.stderr.on('data', (data) => {
stderr += data.toString('utf-8');
});
proc.on('error', (err) => {
reject(err);
});
proc.on('close', (code) => {
if (code !== 0) {
if (stderr.includes('command not found') || stderr.includes('wasmtime: not found')) {
return reject(new Error('WASM runtime requires wasmtime CLI. Install it, e.g. with: brew install wasmtime'));
}
return reject(new Error(`wasmtime exited with code ${code}: ${stderr || stdout}`));
}
const out = stdout.trim();
if (!out) {
return resolve(undefined);
}
// Try numeric first (for arithmetic chapters)
const numeric = out.trim();
if (numeric && !Number.isNaN(Number(numeric))) {
return resolve(Number(numeric));
}
// Try JSON
try {
return resolve(JSON.parse(out));
}
catch {
// Fallback: raw string
return resolve(out);
}
});
});
}
}
//# sourceMappingURL=wasm.js.map