/** * RedisEventBus — Redis Pub/Sub implementation of the EventBus contract. * * Publishes the runtime's emitted-event envelope to a single Redis channel and * fans it back out to every subscriber process. Redis requires a *dedicated* * connection in subscriber mode, so each `subscribe` call opens its own * connection via `client.duplicate()` — this is exactly what the old * RedisStore pub/sub stub admitted it was missing. * * 'ioredis' is an optional peer dependency. It is loaded via dynamic import at * construction time (only when the bus creates its own connection). If the * package is not installed, a clear error is thrown. When a `client` is * injected, no import happens — tests drive the bus with an in-memory fake. * * Connection ownership: * - A client the bus creates itself (from `url`/defaults) is owned by the bus: * `close()` quits it. * - An injected `client` belongs to the caller: `close()` does NOT quit it. * - Subscriber connections are always created by the bus via `duplicate()`, so * the bus owns them regardless of where the base client came from — `close()` * (and each subscription's own unsubscribe) quits them. * * The bus is deterministic: no timers, no ret/backoff. Delivery is whatever * Redis Pub/Sub provides. Self-delivery is included — the bus is dumb; the * runtime engine is responsible for filtering messages by `originId`. */ import type { EventBus, EventBusHandler, EventBusMessage } from './event-bus'; /** * Minimal structural view of the Redis client the bus needs. Both the real * ioredis client and the in-test fake satisfy this shape. Subscriber-mode * connections come from `duplicate()`. */ export interface RedisEventBusClient { publish(channel: string, message: string): Promise | unknown; duplicate(): RedisEventBusClient; subscribe(channel: string): Promise | unknown; on(event: 'message', listener: (channel: string, message: string) => void): unknown; quit(): Promise | unknown; } export interface RedisEventBusConfig { /** Redis connection URL (redis://... or rediss:// for TLS). Ignored when `client` is set. */ url?: string; /** Pre-initialized Redis client. When provided, the bus does not load ioredis and does not own the connection. */ client?: RedisEventBusClient; /** Channel to publish/subscribe on (default: 'manifest:events'). */ channel?: string; } export declare class RedisEventBus implements EventBus { private channel; private publisher; private ownsPublisher; private ready; private readonly url; private subscribers; private closed; constructor(config?: RedisEventBusConfig); private ensureReady; private initPublisher; publish(message: EventBusMessage): Promise; subscribe(handler: EventBusHandler): Promise<() => Promise>; close(): Promise; } //# sourceMappingURL=redis.d.ts.map