# Worker host conformance harness _(no submodules)_ ## Purpose `runWorkerHostConformance` spins up an in-process worker-shaped peer using paired `MessageChannel` ports. It exists so this package's own test suite — and the lifecycle-driver tests inside `api-host` — can exercise the full bootstrap → lifecycle → capability-proxy chain without spawning a real `node:worker_threads` `Worker`. Two paired ports are wired up (one for control, one for capability), the bootstrap is run on the worker-side ports, a stub capability server is mounted on the main-side of the capability port, and a main-side RPC client is wired to the control port — giving callers everything they need to drive lifecycle commands and observe capability call dispatch deterministically. ## Features - Optional overrides for `manifest`, `capabilityHandles`, plugin `hooks` and the main-side `capabilityHandlers`. - Reasonable defaults (`{ name: "test-plugin", version: "0.1.0", tier: "isolated", capabilities: [] }`) so trivial tests need zero setup. - Returns the live `WorkerHost`, the main-side `WorkerRpcClient`, the stub capability server, both port pairs and a single `dispose()` that tears everything down in reverse order. - No real `Worker` thread spawned — pure structured-clone routing via `MessageChannel`. ## Usage: Basic ```ts import { runWorkerHostConformance, } from "@suaveplan/api-worker-host/testing"; const h = runWorkerHostConformance({ hooks: { install: () => {} }, }); const ack = await h.mainClient.call("lifecycle.dispatch", [ { command: "install" }, ]); h.dispose(); ``` ## Usage: Advanced Provide capability handles + main-side handlers to round-trip a capability call: ```ts import { runWorkerHostConformance, } from "@suaveplan/api-worker-host/testing"; const h = runWorkerHostConformance({ capabilityHandles: { db: { methods: ["query"] } }, capabilityHandlers: { "db.query": (params) => ({ rows: [params[0]] }), }, }); const query = h.host.capabilities.db?.query; const result = await query?.("SELECT 1"); h.dispose(); ``` ## API Reference - `runWorkerHostConformance(opts?): WorkerHostConformanceHarness` - `WorkerHostConformanceOptions`: - `manifest?: ManifestEnvelope` - `capabilityHandles?: CapabilityHandles` - `hooks?: PluginLifecycleHooks` - `capabilityHandlers?: WorkerRpcHandlers` - `WorkerHostConformanceHarness`: - `host: WorkerHost` - `mainClient: WorkerRpcClient` - `capabilityServer: WorkerRpcServer` - `controlPorts / capabilityPorts: InProcessPortPair` - `dispose(): void` ## Implementation Notes `dispose()` closes the main-side client first so it stops sending, then the worker host (which closes its own server + capability client), then the main-side capability server, then both port pairs. Closing in reverse-construction order avoids `port already closed` log noise in vitest while still flushing the inflight RPC budget.