91 lines
5.1 KiB
Markdown
91 lines
5.1 KiB
Markdown
# @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<TMap>` 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.
|
|
|
|
<!-- begin:auto-docs -->
|
|
## 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…
|
|
<!-- end:auto-docs -->
|
|
|
|
## 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<Map>(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)
|
|
|