# `event-buffer` ## Purpose Provides the per-`(tenant, topic)` reconnect-event buffer used to replay events to a reconnecting client whose `lastEventId` precedes the current head. Two concrete implementations ship — `MemoryReconnectEventBuffer` for single-host deployments and `BrokerReconnectEventBuffer` for broker-backed multi-host fan-out — and `resolveReconnectEventBuffer` picks the right one according to the configured strategy and the broker wired into the host. This module is the operating-default pin for design doc §14 open question on buffer storage: the foundation ships `"auto"` which resolves to broker-backed when a Redis broker is wired, in-memory otherwise. ## Features - Strategy enum (`"auto" | "memory" | "broker"`) with three documented behaviours. - `MemoryReconnectEventBuffer` is a per-bucket ring buffer — FIFO eviction, `limit` events per `(tenant, topic)` pair. - `BrokerReconnectEventBuffer` maintains a local mirror so replay still works during transient broker downtime; pushes also flow to the broker on a fire-and-forget topic for peer-host mirrors. - `"broker"` strategy refuses boot with `WS_BUN.RECONNECT_BUFFER_MISS` when no buffer-capable broker is wired. ## Usage: Basic ```ts import { MemoryReconnectEventBuffer } from "@suaveplan/api-ws-bun"; const buf = new MemoryReconnectEventBuffer<{ value: number }>(64); buf.push({ id: "1", topic: "orders", tenant, payload: { value: 1 } }); buf.push({ id: "2", topic: "orders", tenant, payload: { value: 2 } }); const replay = buf.since(tenant, "orders", "1"); console.log(replay.length); // 1 ``` ## Usage: Advanced ```ts import { resolveReconnectEventBuffer, isBufferCapableBroker, } from "@suaveplan/api-ws-bun"; const buffer = resolveReconnectEventBuffer("auto", broker, 256); // If `broker.supportsReconnectBuffer === true`, returns a // BrokerReconnectEventBuffer wrapping `broker`. Otherwise returns // MemoryReconnectEventBuffer. console.log(isBufferCapableBroker(broker)); // true | false ``` ## API Reference - `BufferedEvent` — `{ id, topic, tenant, payload }`. - `ReconnectEventBuffer` — `{ push, since, dispose }`. - `BufferCapableBroker` — broker contract extension flagging buffer support. - `isBufferCapableBroker(broker): boolean` — discriminant. - `MemoryReconnectEventBuffer` — single-host implementation. - `BrokerReconnectEventBuffer` — broker-backed wrapper. - `resolveReconnectEventBuffer(strategy, broker, limit)` — factory. ## Implementation Notes The memory buffer uses `Array.prototype.shift()` for eviction because the typical `limit` is small (default 256 events per `(tenant, topic)` pair), so the O(n) shift is dwarfed by the network cost of a single broadcast. A linked-list ring would micro-optimise the eviction at the cost of opaqueness; the simple array form keeps the code one screenful tall. The broker wrapper performs `void this.broker.publish(...)` rather than awaiting because the buffer's contract guarantees `push` is synchronous — the caller is on the broadcast hot-path and cannot block on broker latency. Peer-host mirror sync is therefore best-effort; deployments that need strict mirror consistency configure `"broker"` against a stronger backend.