Files
suaveplan/packages/api-stack/api/wasm-compiler-javy/src/route-extract/route-extract.md
2026-05-27 23:29:53 +01:00

2.9 KiB

extractRoutes — host-side WASI route probe

Purpose

extractRoutes is step 6 of the TS->WASM compilation pipeline: it boots the produced .wasm artifact under a host-side WASI runner (the same createWasiStdioRunner @suaveplan/api-sandbox-wasm-host-bridge uses at deploy time), sends a single {kind:"routes"} envelope, and captures the {kind:"routes", routes} reply. The captured routes: readonly SerializedRoute[] array feeds the manifest step.

Reusing the bridge's runner is deliberate. If the compiler probed routes via a bespoke WASI snapshot, a guest that booted under the probe but tripped on the bridge's snapshot (or vice-versa) would slip through. By going through the exact code path the host will run, the compile-time probe exercises the same instantiation, memory binding, stdio framing, and decode logic — eliminating "compiles but won't deploy" failure modes at the source.

Features

  • Single-envelope round-trip — runner.exchange({kind:"routes"}, "routes") returns synchronously.
  • pluginName threads through into bridge error context so a malformed routes reply surfaces with the plugin's name attached.
  • stdioTimeoutMs knob bumps the per-step deadline for plugins that need to do heavy module-scope init before the routes reply.
  • Guaranteed cleanup: runner.dispose() runs in a finally block whether the exchange succeeded or threw.

Usage: Basic

import { extractRoutes, validateAbi } from "@suaveplan/wasm-compiler-javy";

const { module } = await validateAbi({ wasmBytes });
const { routes } = extractRoutes({ module, pluginName: "my-plugin" });
console.log(routes); // [{ method:"GET", path:"/hello" }, ...]

Usage: Advanced

import { extractRoutes } from "@suaveplan/wasm-compiler-javy";

const { routes } = extractRoutes({
    module,
    pluginName: "my-plugin",
    stdioTimeoutMs: 30_000, // give a slow plugin 30s of init headroom
});
if (routes.length === 0) {
    throw new Error("plugin declares no routes — refusing to ship");
}

API Reference

  • extractRoutes(options: ExtractRoutesOptions): ExtractRoutesResult — entrypoint.
  • ExtractRoutesOptions: { module: WebAssembly.Module; pluginName: string; stdioTimeoutMs?: number }.
  • ExtractRoutesResult: { routes: readonly SerializedRoute[] }.

Implementation Notes

The runner expects a WasmSandboxHandle for dispose chaining but accepts an undefined sandbox — the compile-time probe has no sandbox to chain against, so the field is omitted. Should the reply envelope come back with an unexpected kind (e.g. an {kind:"error"} from the plugin choking on its own routes getter), the function raises ABI_VALIDATION_FAILED with context.reason="routes_reply_kind" and the received kind. Empty routes arrays are deliberately NOT raised here — the manifest step owns that check via WASM_COMPILER.MANIFEST_MISSING_ROUTES so this function remains a pure probe.