first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
# Worker host conformance harness
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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.