Files
suaveplan/packages/api-stack/api/api-sandbox-wasm-host-bridge/src/route-discovery/route-discovery.md
2026-05-27 23:29:53 +01:00

2.5 KiB

Route discovery

(no submodules)

Purpose

discoverRoutes(exports, pluginName) calls the guest's __suaveplan_routes export exactly once at bridge-init time, unpacks the (pointer, length) pair the guest returns as a packed bigint, reads the JSON-encoded SerializedRoute[] from linear memory, frees the guest-allocated buffer, and returns the typed array. The bridge uses this list to build the PipelineRoute array installed on the host.

Features

  • Single bridge-init call — the result is cached by createSandboxedWasmPluginModule; the guest is never asked for its routes again.
  • Trap-protected: a fault inside __suaveplan_routes surfaces as SAND_WASM_BRIDGE.HANDLER_TRAPPED with context.phase: "routes" and a classified trapKind.
  • Malformed-payload aware: bytes that fail Zod validation surface as SAND_WASM_BRIDGE.UNMARSHAL_FAILED (re-thrown from unmarshalRoutes).
  • Empty-list tolerant: a guest returning (0, 0) is treated as "no routes" rather than as an error, so plugins with lifecycle-only hooks remain valid.
  • Frees the guest's buffer before returning — the bridge never leaves linear-memory pages owned by the guest's allocator dangling after init.

Usage: Basic

import { discoverRoutes } from "@suaveplan/api-sandbox-wasm-host-bridge/route-discovery";

const routes = discoverRoutes(exports, "example");

Usage: Advanced

import { discoverRoutes } from "@suaveplan/api-sandbox-wasm-host-bridge/route-discovery";
import type { SerializedRoute } from "@suaveplan/api-types/sandbox-bridge";

function buildRouteIndex(
    exports: import("@suaveplan/api-sandbox-wasm-host-bridge/wasm-abi").WasmAbiExports,
    plugin: string,
): ReadonlyMap<string, SerializedRoute> {
    const routes = discoverRoutes(exports, plugin);
    const index = new Map<string, SerializedRoute>();
    for (const route of routes) {
        index.set(`${route.method} ${route.path}`, route);
    }
    return index;
}

API Reference

  • discoverRoutes(exports: WasmAbiExports, pluginName: string): readonly SerializedRoute[].

Implementation Notes

The empty-list case (pointer === 0 || length === 0) is reached when the guest's __suaveplan_routes returns the literal bigint 0n. We still attempt to free the buffer when pointer !== 0 to be defensive — a guest that returns (ptr, 0) may have legitimately allocated a zero-length buffer that the host still owns the responsibility to release. The freeBuffer helper is a no-op when pointer === 0, so the double-guard is safe.