# @suaveplan/api-events-worker-proxy - Worker-tier proxy over a main-process @suaveplan/events EventBus. The main side calls createEventBusProxyServer(port, bus) to expose the bus over a MessagePort via @suaveplan/api-worker-rpc; worker-tier plugins call createEventBusProxyClient(port) to obtain an EventBus-shaped surface that marshals on/once/off/emit/emitAsync across the port. Subscriptions become long-lived stream-* frames that deliver one stream-chunk per main-side event. Zod-validated payload codec rejects non-structured-clone-safe payloads with EVENTS_PROXY.UNSERIALISABLE_PAYLOAD. Worker-tier proxy over a main-process `@suaveplan/events` `EventBus`. The host (main process) owns one `EventBus` instance. Worker-tier plugins want to publish to and subscribe from the same bus without running the bus in every worker. This package marshals every `on` / `once` / `off` / `emit` / `emitAsync` call across a `MessagePort` via `@suaveplan/api-worker-rpc`, so worker-tier plugin code compiles unchanged against an `EventBus`-shaped proxy surface. This is an adapter, not a new contract — the design doc (§5.2a) is explicit that no abstract `api-events` contract package exists. The host injects `@suaveplan/events` directly; this package is the worker-side surface over that existing bus. ## Documentation tree - [error-codes](./src/error-codes/error-codes.md) — Defines the stable string registry of `EVENTS_PROXY.*` error codes raised by every failure path in `@suaveplan/api-even… - [error-codes](./src/error-codes/error-codes.md) — Defines the stable string registry of `EVENTS_PROXY.*` error codes raised by every failure path in `@suaveplan/api-even… - [main-side](./src/main-side/main-side.md) — Mounts a main-process `@suaveplan/events` `EventBus` on a `MessagePort` via the `@suaveplan/api-worker-rpc` server so w… - [main-side](./src/main-side/main-side.md) — Mounts a main-process `@suaveplan/events` `EventBus` on a `MessagePort` via the `@suaveplan/api-worker-rpc` server so w… - [payload-codec](./src/payload-codec/payload-codec.md) — Encodes and decodes the wire envelope used to ship a single event from the main-process `EventBus` across a `MessagePor… - [payload-codec](./src/payload-codec/payload-codec.md) — Encodes and decodes the wire envelope used to ship a single event from the main-process `EventBus` across a `MessagePor… - [testing](./src/testing/testing.md) — Re-usable test fixtures for `@suaveplan/api-events-worker-proxy`. Builds a real `EventBus`, a real Node.js `MessageChan… - [testing](./src/testing/testing.md) — Re-usable test fixtures for `@suaveplan/api-events-worker-proxy`. Builds a real `EventBus`, a real Node.js `MessageChan… - [worker-side](./src/worker-side/worker-side.md) — Builds a worker-side proxy that exposes an `EventBus`-shaped surface backed by a `PortLike` connected to a main-process… - [worker-side](./src/worker-side/worker-side.md) — Builds a worker-side proxy that exposes an `EventBus`-shaped surface backed by a `PortLike` connected to a main-process… ## Install ```bash bun add @suaveplan/api-events-worker-proxy ``` ## Main-side (host) ```ts import { EventBus } from "@suaveplan/events"; import { createEventBusProxyServer } from "@suaveplan/api-events-worker-proxy/main-side"; import { createInProcessPortPair } from "@suaveplan/api-worker-rpc"; const bus = new EventBus<{ "billing.invoice.created": { id: string } }>(); const { clientPort, serverPort, close } = createInProcessPortPair(); const server = createEventBusProxyServer(serverPort, bus); // Hand `clientPort` to a worker; tear down with `server.dispose()` + close(). ``` ## Worker-side ```ts import { createEventBusProxyClient } from "@suaveplan/api-events-worker-proxy/worker-side"; type Map = { "billing.invoice.created": { id: string } }; const events = createEventBusProxyClient(port); events.on("billing.invoice.created", ({ id }) => console.log("got", id)); const result = await events.emitAsync("billing.invoice.created", { id: "i_1", }); console.log(result.delivered); ``` ## Exports - `./main-side` — `createEventBusProxyServer(port, bus)`. - `./worker-side` — `createEventBusProxyClient(port)`. - `./payload-codec` — Zod schema + structured-clone probe. - `./error-codes` — `EVENTS_PROXY.*` codes + `EventsProxyError`. - `./testing` — `createProxyPair` + `waitFor` for downstream tests. ## Error codes - `EVENTS_PROXY.UNSERIALISABLE_PAYLOAD` — payload failed the structured-clone safety probe (functions, class instances, cycles). - `EVENTS_PROXY.SUBSCRIPTION_DROPPED` — subscription terminated unexpectedly (server disposed, port closed mid-stream). - `EVENTS_PROXY.BACKPRESSURE_EXCEEDED` — worker-side queue exceeded the configured high-water mark. - `EVENTS_PROXY.PROXY_DISPOSED` — method called after `dispose()`. ## Docs - [`main-side`](./src/main-side/main-side.md) - [`worker-side`](./src/worker-side/worker-side.md) - [`payload-codec`](./src/payload-codec/payload-codec.md) - [`error-codes`](./src/error-codes/error-codes.md) - [`testing`](./src/testing/testing.md)