96 lines
5.3 KiB
Markdown
96 lines
5.3 KiB
Markdown
# @suaveplan/api-sandbox-vm-host-bridge - Host-integration bridge that wraps a @suaveplan/api-sandbox-vm VmSandboxHandle as a PluginModule + PipelineRoute[] bundle for @suaveplan/api-host.installPlugin. Marshals host Request → SerializedRequest into the vm.Context, unmarshals SerializedResponse → host Response, delegates start/dispose lifecycle to the sandbox handle, and surfaces sandbox faults via the SAND_VM_BRIDGE.* code registry.
|
|
|
|
Host-integration bridge that lets a `VmSandboxHandle` from
|
|
`@suaveplan/api-sandbox-vm` install into `@suaveplan/api-host` as a
|
|
first-class plugin.
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [bridge](./src/bridge/bridge.md) — This module is the package's flagship factory: `createSandboxedVmPluginModule({ sandbox, manifest, registry })` → `Brid…
|
|
- [bridge](./src/bridge/bridge.md) — This module is the package's flagship factory: `createSandboxedVmPluginModule({ sandbox, manifest, registry })` → `Brid…
|
|
- [error-codes](./src/error-codes/error-codes.md) — This module owns the stable `SAND_VM_BRIDGE.*` error-code registry used by every public failure path inside the host br…
|
|
- [error-codes](./src/error-codes/error-codes.md) — This module owns the stable `SAND_VM_BRIDGE.*` error-code registry used by every public failure path inside the host br…
|
|
- [instruments](./src/instruments/instruments.md) — This module owns the OTel instrument bundle the bridge emits. Splitting the bundle off the bridge module makes the metr…
|
|
- [instruments](./src/instruments/instruments.md) — This module owns the OTel instrument bundle the bridge emits. Splitting the bundle off the bridge module makes the metr…
|
|
- [lifecycle](./src/lifecycle/lifecycle.md) — This module owns the idempotency wrapper around a `VmSandboxHandle`'s `start` / `dispose` lifecycle. The host's lifecyc…
|
|
- [lifecycle](./src/lifecycle/lifecycle.md) — This module owns the idempotency wrapper around a `VmSandboxHandle`'s `start` / `dispose` lifecycle. The host's lifecyc…
|
|
- [marshal-request](./src/marshal/marshal-request.md) — This module turns the host's per-request `RequestContext` into a plain-data `SerializedRequest` value that the sandbox…
|
|
- [marshal-response](./src/marshal/marshal-response.md) — This module turns the value returned by a sandboxed handler into a host `Response`. The sandbox-side handler returns a…
|
|
- [route-discovery](./src/route-discovery/route-discovery.md) — This module owns the route-discovery protocol that lets a sandboxed plugin tell the host which HTTP routes it wants to…
|
|
- [route-discovery](./src/route-discovery/route-discovery.md) — This module owns the route-discovery protocol that lets a sandboxed plugin tell the host which HTTP routes it wants to…
|
|
- [vm-host-bridge-conformance](./src/testing/vm-host-bridge-conformance/vm-host-bridge-conformance.md) — This module ships `runVmHostBridgeConformance({ buildBridge })` — a five-invariant conformance suite that every concret…
|
|
- [vm-host-bridge-conformance](./src/testing/vm-host-bridge-conformance/vm-host-bridge-conformance.md) — This module ships `runVmHostBridgeConformance({ buildBridge })` — a five-invariant conformance suite that every concret…
|
|
<!-- end:auto-docs -->
|
|
|
|
## What it does
|
|
|
|
A `VmSandboxHandle` is a frozen `vm.Context` running a `SourceTextModule`
|
|
with permission-gated `__suaveplan` capabilities — but it is NOT a
|
|
`PluginModule`. The host's `installPlugin({ module, manifest, routes })`
|
|
takes a plain TS object with `start/stop/dispose/health` hooks plus a
|
|
`PipelineRoute[]` registration list. This package builds that
|
|
`PluginModule + routes` bundle by:
|
|
|
|
1. Asking the sandbox (via a host-installed `bridge.registerRoute`
|
|
capability) for the plugin's route registrations.
|
|
2. Wrapping every registered handler in a marshal closure that turns the
|
|
host `Request` into a `SerializedRequest`, calls the sandbox-side
|
|
handler, and turns the returned `SerializedResponse` into a host
|
|
`Response`.
|
|
3. Delegating `start()` / `dispose()` to the underlying sandbox handle,
|
|
idempotently.
|
|
|
|
## Quickstart
|
|
|
|
```ts
|
|
import {
|
|
createSandboxedVmPluginModule,
|
|
createBridgeRouteRegistry,
|
|
} from "@suaveplan/api-sandbox-vm-host-bridge";
|
|
import { createVmSandbox } from "@suaveplan/api-sandbox-vm";
|
|
|
|
const registry = createBridgeRouteRegistry();
|
|
const sandbox = createVmSandbox({
|
|
pluginId: "demo",
|
|
pluginModule: { kind: "source", identifier: "demo.mjs", source },
|
|
checker, // PermissionChecker
|
|
proxies: {
|
|
fs,
|
|
fetch,
|
|
capabilities: { bridge: registry.capability },
|
|
},
|
|
logger,
|
|
});
|
|
|
|
const bridged = await createSandboxedVmPluginModule({
|
|
sandbox,
|
|
manifest,
|
|
registry,
|
|
});
|
|
|
|
await host.installPlugin({
|
|
module: bridged.module,
|
|
manifest,
|
|
manifestHash,
|
|
specifier,
|
|
routes: bridged.routes,
|
|
});
|
|
```
|
|
|
|
## Error codes
|
|
|
|
`SAND_VM_BRIDGE.*` — five stable codes covering plugin-surface
|
|
discovery (`INVALID_PLUGIN_SURFACE`), wire marshalling (`MARSHAL_FAILED`
|
|
/ `UNMARSHAL_FAILED`), handler throws (`HANDLER_REJECTED`), and
|
|
lifecycle delegation (`LIFECYCLE_FAILED`).
|
|
|
|
## Conformance
|
|
|
|
`@suaveplan/api-sandbox-vm-host-bridge/testing` ships
|
|
`runVmHostBridgeConformance({ buildBridge })` with the five invariants
|
|
the spec mandates: route registration, request round-trip, idempotent
|
|
lifecycle, error propagation with `cause` chain, and capability
|
|
passthrough including denied capability surfacing `SAND_PERM.DENIED`.
|
|
|