Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
# `control-channel`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Bidirectional control plane: the main process tells a worker-isolated
plugin to stop or resume emitting log records. The host calls `disable`
during plugin shutdown so a worker that is still draining its work
queue does not keep producing records after the main-side sink has been
torn down (design doc §5.5 — components dispose in reverse dependency
order). Without this channel the main-side sink would either log to a
zombie sink (silent loss with no diagnostic) or panic on a closed port.
Frames are simple: `{ kind: "control", action: "disable" | "enable" }`.
There is no acknowledgement frame; the channel is fire-and-forget. The
worker maintains a shared `ControlState` object the proxy client checks
synchronously on every log call, so a `disable` received between two
calls correctly suppresses the second.
## Features
- `createControlChannelSender(port)` — returns `{ disable, enable }`
thunks usable from the main process.
- `mountControlChannelReceiver(port, options?)` — installs a listener
on the worker-side port; returns the shared `ControlState` plus a
`dispose` thunk. Tolerates malformed frames (silent drop) so a
hostile or buggy host cannot crash the worker.
- `onChange` callback fires only on real transitions, not on repeated
same-value frames.
## Usage: Basic
```ts
// Main side
import { createControlChannelSender } from "@suaveplan/api-logger-worker-proxy/control-channel";
const ctl = createControlChannelSender(mainPort);
ctl.disable();
// ... main-side sink torn down ...
worker.terminate();
```
```ts
// Worker side
import { mountControlChannelReceiver } from "@suaveplan/api-logger-worker-proxy/control-channel";
const ctl = mountControlChannelReceiver(workerPort);
// log.info() etc. read ctl.state.enabled synchronously
```
## Usage: Advanced
Observe transitions to flush in-flight batches and surface a counter:
```ts
import { mountControlChannelReceiver } from "@suaveplan/api-logger-worker-proxy/control-channel";
const ctl = mountControlChannelReceiver(port, {
onChange: (enabled) => {
if (!enabled) batcher.flush();
meter.add(`logger_proxy.control_state.${enabled ? "on" : "off"}`, 1);
},
});
```
## API Reference
- `createControlChannelSender(port: PortLike): ControlChannelSender`
— emits `{ v, kind: "control", action }` frames.
- `mountControlChannelReceiver(port, options?)` —
returns `{ state: Readonly<ControlState>, dispose }`.
- `ControlState` — `{ enabled: boolean }`. Defaults to `true` so
workers emit normally until told otherwise.
## Implementation Notes
The receiver shares the port with `goodbye` and (incidentally) with the
worker-side log emit path — frames whose `kind` is not `"control"` are
ignored so the receiver composes cleanly with other listeners on the
same port. The state object is mutated in place (not replaced) so the
proxy client can capture a stable reference at construction time and
not need to re-resolve a getter on the per-call hot path.