Files
skills/docs/api-stack/api/api-sse-bun/src/event-buffer/event-buffer.md
2026-05-29 08:20:56 +01:00

2.9 KiB

event-buffer

(no submodules)

Purpose

The event-buffer module owns the per-(tenant, topic) replay storage the engine consults on Last-Event-Id reconnects. Two implementations are exported: an in-memory ring buffer for single-host deployments and a broker-backed adapter for clusters that share replay state with the WS engine. Both expose the same EventBuffer surface so the engine code path is identical regardless of deployment topology.

Features

  • Multi-key buffer (tenantId, topic) on top of the abstract ReplayBuffer exported by @suaveplan/api-sse.
  • In-memory mode: lazy slot allocation, size + ttl bounded ring buffer, one ReplayBuffer per (tenantId, topic).
  • Broker mode: delegates publish to the wired SseBroker, keeps a shadow in-memory mirror so reads stay synchronous.
  • evictExpired(now) sweeps every per-key buffer in one call.
  • Synchronous size(key) probe used by the BUFFER_MISS decision.

Usage: Basic

import { createInMemoryEventBuffer } from "@suaveplan/api-sse-bun";

const buffer = createInMemoryEventBuffer({
    eventBufferSize: 256,
    eventBufferMs: 300_000,
});

const key = { tenantId: "acme" as never, topic: "audit" };
buffer.append(key, { id: "1", data: "first" });
const replay = await buffer.since(key, "non-existent");
console.log(replay); // []

Usage: Advanced

import {
    createBrokerBackedEventBuffer,
    type EventBuffer,
} from "@suaveplan/api-sse-bun";
import type { SseBroker } from "@suaveplan/api-sse";

declare const broker: SseBroker;

const buffer: EventBuffer = createBrokerBackedEventBuffer({
    eventBufferSize: 1024,
    eventBufferMs: 600_000,
    broker,
});
await buffer.append(
    { tenantId: "acme" as never, topic: "audit" },
    { id: "1", data: "first" }
);

API Reference

  • interface EventBuffer — append(key, event), since(key, lastId), size(key), evictExpired(now), mode: "memory" | "broker".
  • interface InMemoryEventBufferOptions — eventBufferSize, eventBufferMs, optional clock.
  • function createInMemoryEventBuffer(options): EventBuffer.
  • interface BrokerBackedEventBufferOptions extends InMemoryEventBufferOptions — adds required broker: SseBroker.
  • function createBrokerBackedEventBuffer(options): EventBuffer.

Implementation Notes

The broker-backed adapter keeps a shadow in-memory mirror because the SseBroker contract does not yet expose a synchronous read path — real implementations (Redis sorted-set) require an async query and the engine resolves since synchronously during the handshake. The shadow mirror is consistent on the local host; cross-host replay (a client reconnects to a different host than the one that emitted the event) delegates to the broker's since surface, which lives in the broker package, not here. Eviction in broker mode operates only on the local shadow — the broker manages its own TTL via Redis' native expiration.