Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
# Route discovery
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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
```ts
import { discoverRoutes } from "@suaveplan/api-sandbox-wasm-host-bridge/route-discovery";
const routes = discoverRoutes(exports, "example");
```
## Usage: Advanced
```ts
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.