import { join, dirname, resolve } from "node:path";
import { fileURLToPath } from 'node:url';
import { readFile } from "node:fs/promises";
import { spawn } from "node:child_process";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const WASM_FILE = join(__dirname, "bin/ssclient.wasm");
if (process && process.emitWarning) {
const emitWarning = process.emitWarning;
process.emitWarning = (warning, type) => {
if (type === "ExperimentalWarning") {
if (warning.toString().includes("WASI")) {
return false;
}
}
return emitWarning(arguments);
};
}
let WASI;
try {
const wasiModule = await import("node:wasi");
WASI = wasiModule.WASI;
} catch (e) {
const scriptPath = fileURLToPath(import.meta.url);
if (process.argv.find(arg => arg === "--experimental-wasi-unstable-preview1")) {
console.error(`Unable to load WASI module: ${e}`);
process.exit(1);
}
const child = spawn(
process.execPath,
["--experimental-wasi-unstable-preview1", scriptPath, ...process.argv.slice(2)],
{ stdio: "inherit" }
);
child.on("exit", (code) => process.exit(code ?? 0));
await new Promise(() => {});
}
async function runWasm(payload) {
const args = process.argv.slice(2);
const cwd = process.cwd();
const env = process.env;
const wasi = new WASI({
version: "preview1",
args: ["ssclient", ...args],
env: env,
preopens: {
[cwd]: cwd,
".": ".",
},
});
const wasiImportObject = wasi.getImportObject ? wasi.getImportObject()
: { wasi_snapshot_preview1: wasi.wasiImport };
try {
const wasmPath = resolve(payload);
const wasmBuffer = await readFile(wasmPath);
const wasmModule = await WebAssembly.compile(wasmBuffer);
const instance = await WebAssembly.instantiate(
wasmModule,
wasiImportObject,
);
wasi.start(instance);
} catch (err) {
const msg = err instanceof Error ? err.message : err?.toString();
console.error(`Error executing ${payload}: `, msg);
process.exit(1);
}
}
await runWasm(WASM_FILE);