// Boots the TinyGo `core.wasm` module under Vitest/JSDOM by reading // the artefact and the matching wasm_exec.js shim from disk, evaluating // the shim into the test's global scope, then instantiating WebAssembly // against `(new Go()).importObject`. Returns a `Core` ready to use in // tests; subsequent calls return the cached instance so each Vitest // file pays the boot cost once. import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import { runInThisContext } from "node:vm"; import { adaptBridge, requireBridge } from "../src/platform/core/wasm"; import type { Core } from "../src/platform/core/index"; // Vitest is launched from ui/frontend, so the static artefacts produced // by `make wasm` sit at /static/. Resolving via process.cwd avoids // the JSDOM-specific "URL must be of scheme file" error that // import.meta.url triggers under the jsdom test environment. const STATIC_DIR = resolve(process.cwd(), "static") + "/"; let cached: Promise | undefined; export function loadWasmCoreForTest(): Promise { if (!cached) { cached = boot(); } return cached; } async function boot(): Promise { if (typeof globalThis.Go === "undefined") { const shim = readFileSync(`${STATIC_DIR}wasm_exec.js`, "utf8"); runInThisContext(shim); } const Go = globalThis.Go; if (!Go) { throw new Error("setup-wasm: Go runtime missing after wasm_exec.js eval"); } const go = new Go(); const wasm = readFileSync(`${STATIC_DIR}core.wasm`); const { instance } = await WebAssembly.instantiate( wasm, go.importObject, ); void go.run(instance); // `go.run` is async but the Go side registers `globalThis.galaxyCore` // and then blocks on `select {}`; the registration happens // synchronously before the first await, so by the time the next // microtask runs the bridge is already available. await new Promise((resolve) => setTimeout(resolve, 0)); return adaptBridge(requireBridge()); }