@hedwigjs/broker 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/utils/matchPattern.ts","../src/core/bridge/Bridge.ts","../src/core/routing/RoutingResult.ts","../src/core/routing/Router.ts","../src/core/hooks/HooksRegistry.ts","../src/core/client/ClientRegistry.ts","../src/core/routing/Subscriptions.ts","../src/core/backpressure/strategies/ThrottleStrategy.ts","../src/core/backpressure/strategies/DebounceStrategy.ts","../src/core/backpressure/strategies/RateLimitStrategy.ts","../src/core/backpressure/BackpressureHandler.ts","../src/core/utils/deepFreeze.ts","../src/core/history/MessageHistory.ts","../src/core/history/SubscriptionReplay.ts","../src/core/events/SystemEvents.ts","../src/core/observability/inspect/Inspector.ts","../src/core/logger/BrokerLogger.types.ts","../src/core/BrokerCore.ts","../src/core/client/BrokerClient.ts","../src/facade.ts","../src/transports/PostMessageTransport.ts","../src/transports/BroadcastChannelTransport.ts","../src/transports/WebSocketTransport.ts","../src/transports/SSETransport.ts"],"names":["direct","result","core"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Pattern matching utility for topics\n *\n * Supports patterns:\n * - '*' — matches everything\n * - 'user.*' — prefix: matches 'user.login', 'user.logout.confirmed'\n * - '*.created.v1' — suffix: matches 'user.created.v1', 'order.created.v1'\n * - 'user.*.v1' — middle: matches 'user.login.v1', 'user.logout.v1'\n * - 'user.login' — exact match\n */\n\n/**\n * Check if topic matches a single pattern\n *\n * @param topic - Topic to check (e.g. 'user.login')\n * @param pattern - Pattern to match against (e.g. 'user.*')\n * @returns true if matches\n */\nexport function matchPattern(topic: string, pattern: string): boolean {\n if (pattern === '*') return true;\n if (topic === pattern) return true;\n if (!pattern.includes('*')) return false;\n\n // Convert glob pattern to regex: escape special chars, replace * with .*\n const regexPattern = pattern\n .replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*/g, '.*');\n\n return new RegExp(`^${regexPattern}$`).test(topic);\n}\n\n/**\n * Check if topic matches any of the patterns\n *\n * @param topic - Topic to check\n * @param patterns - Array of patterns\n * @returns true if matches at least one pattern\n */\nexport function matchesAnyPattern(topic: string, patterns: string[]): boolean {\n return patterns.some((pattern) => matchPattern(topic, pattern));\n}\n","import type { Message } from '../types';\nimport type {\n Bridge as IBridge,\n BridgeConfig,\n BridgeTransport,\n ExternalMessageInjector,\n} from './Bridge.types';\nimport type { BrokerLogger } from '../logger/BrokerLogger.types';\nimport { matchesAnyPattern } from '../utils/matchPattern';\n\n/**\n * Bridge - Transport layer for cross-context communication\n *\n * Bridge is NOT a client in the message system.\n * It's infrastructure that forwards messages between broker and external contexts.\n *\n * Responsibilities:\n * - OUTBOUND: When broker calls send(), forward message to transport\n * - INBOUND: Listen to transport and inject messages into broker\n *\n * Use cases:\n * - iframe communication (PostMessageTransport)\n * - cross-tab sync (BroadcastChannelTransport)\n * - server messages (WebSocketTransport)\n */\nexport class Bridge<T extends string = string, P extends Record<T, any> = any>\n implements IBridge\n{\n #inject: ExternalMessageInjector<T, P>;\n #transport: BridgeTransport;\n #patterns: string[];\n #unsubscribe: (() => void) | null = null;\n #logger: BrokerLogger;\n\n constructor(\n inject: ExternalMessageInjector<T, P>,\n config: BridgeConfig,\n logger: BrokerLogger,\n ) {\n this.#inject = inject;\n this.#transport = config.transport;\n this.#patterns = config.forward;\n this.#logger = logger;\n\n // Start listening for incoming messages from transport\n this.#unsubscribe = this.#transport.onMessage((data) => {\n this.#handleIncoming(data);\n });\n }\n\n get forwardPatterns(): ReadonlyArray<string> {\n return this.#patterns;\n }\n\n /**\n * Human-friendly transport class name, derived from the constructor —\n * `WebSocket` for `WebSocketTransport`, etc. Used by DevTools to label\n * bridges. `undefined` for anonymous-class transports.\n */\n get transportKind(): string | undefined {\n const raw = this.#transport.constructor?.name;\n if (!raw) return undefined;\n return raw.endsWith(\"Transport\") ? raw.slice(0, -\"Transport\".length) : raw;\n }\n\n /**\n * Check if topic matches forward patterns\n */\n shouldForward(topic: string): boolean {\n return matchesAnyPattern(topic, this.#patterns);\n }\n\n /**\n * Send message to transport (OUTBOUND)\n * Called by BrokerCore when message matches forward patterns\n */\n send(message: Message): void {\n this.#transport.send(message);\n }\n\n /**\n * Handle incoming message from transport (INBOUND)\n * Parse and inject into broker\n */\n #handleIncoming(data: unknown): void {\n const message = this.#parseMessage(data);\n if (!message) return;\n\n // Only process messages that match our patterns\n if (!this.shouldForward(message.topic)) return;\n\n // Internal injection path — does NOT forward back to bridges and does NOT\n // record into history (the other side already did). The `fromExternal`\n // flag is set inside the inject callback wired by BrokerCore.\n this.#inject(\n message.topic as T,\n message.source,\n message.target,\n message.data,\n );\n }\n\n /**\n * Parse raw data into Message object\n */\n #parseMessage(data: unknown): Message | null {\n try {\n // Handle both string (JSON) and object data\n const message = typeof data === 'string' ? JSON.parse(data) : data;\n\n // Validate required fields\n if (!message || typeof message !== 'object') return null;\n if (!message.topic || typeof message.topic !== 'string') return null;\n\n return message as Message;\n } catch (error) {\n this.#logger.error('bridge.message.parse_failed', { error });\n return null;\n }\n }\n\n /**\n * Cleanup: stop listening and destroy transport\n */\n destroy(): void {\n this.#unsubscribe?.();\n this.#unsubscribe = null;\n this.#transport.destroy();\n }\n}\n","import type { ClientID } from '../types';\n\nexport const RoutingReason = {\n DELIVERED: 'DELIVERED',\n DISPATCHED: 'DISPATCHED',\n REPLAY_DELIVERED: 'REPLAY_DELIVERED',\n HOOK_REJECTED: 'HOOK_REJECTED',\n NO_SUBSCRIBERS: 'NO_SUBSCRIBERS',\n NOT_SUBSCRIBED: 'NOT_SUBSCRIBED',\n HANDLER_FAILED: 'HANDLER_FAILED',\n BROKER_DESTROYED: 'BROKER_DESTROYED',\n} as const;\n\nexport type RoutingReasonType = (typeof RoutingReason)[keyof typeof RoutingReason];\n\n/**\n * RoutingResult - Message delivery result (Value Object)\n *\n * Immutable object representing the result of a message dispatch operation.\n * Can only be created through the static factory method create().\n */\nexport class RoutingResult<TResponse = unknown> {\n readonly status: 'ACK' | 'NACK';\n readonly reason: RoutingReasonType;\n readonly message: string;\n readonly timestamp: number;\n /** Recipient client ID — set for unicast, undefined for multicast. */\n readonly recipientId?: ClientID;\n /** All recipient client IDs — set for multicast, undefined for unicast. */\n readonly recipientIds?: ClientID[];\n readonly data?: TResponse;\n\n private constructor(\n status: 'ACK' | 'NACK',\n reason: RoutingReasonType,\n message: string,\n recipientId?: ClientID,\n data?: TResponse,\n recipientIds?: ClientID[],\n ) {\n this.status = status;\n this.reason = reason;\n this.message = message;\n this.timestamp = Date.now();\n this.recipientId = recipientId;\n this.recipientIds = recipientIds;\n this.data = data;\n\n Object.freeze(this);\n }\n\n /**\n * @param status - ACK for success, NACK for failure\n * @param reason - Machine-readable reason code (use RoutingReason constants)\n * @param message - Human-readable result description\n * @param recipientId - Recipient client ID (unicast only)\n * @param data - Response data from handler (Request-Reply pattern only)\n * @param recipientIds - All recipient client IDs (multicast only)\n */\n static create<T = unknown>(\n status: 'ACK' | 'NACK',\n reason: RoutingReasonType,\n message: string,\n recipientId?: ClientID,\n data?: T,\n recipientIds?: ClientID[],\n ): RoutingResult<T> {\n return new RoutingResult(status, reason, message, recipientId, data, recipientIds);\n }\n}\n","import type { Message, ClientID, MessageHandler } from '../types';\nimport type { Subscriptions } from './Subscriptions';\nimport type { BrokerLogger } from '../logger/BrokerLogger.types';\nimport { RoutingResult, RoutingReason } from './RoutingResult';\n\n/**\n * Router - Pure message routing logic\n *\n * Responsibilities:\n * - Route messages to correct subscribers (unicast/multicast)\n * - Execute handlers\n * - Return delivery results\n *\n * Does NOT handle:\n * - Subscription management (delegated to Subscriptions)\n * - Hooks (delegated to HooksRegistry)\n * - Bridge forwarding (delegated to BrokerCore)\n * - Message creation (delegated to BrokerCore)\n *\n * Design: Uses Dependency Injection to receive Subscriptions (read-only access)\n */\nexport class Router<T extends string, P extends Record<T, any>> {\n #subscriptions: Subscriptions<T>;\n #logger: BrokerLogger;\n\n constructor(subscriptions: Subscriptions<T>, logger: BrokerLogger) {\n this.#subscriptions = subscriptions;\n this.#logger = logger;\n }\n\n /**\n * Route unicast message to specific recipient.\n *\n * If the recipient registered multiple handlers on the topic, the FIRST\n * one (in registration order) receives the message and its return value\n * is captured. Multi-handler unicast is not a supported responder pattern\n * — callers that expect a single response should keep unicast slots to\n * one handler.\n */\n async unicast<K extends T, R = unknown>(\n message: Message<K, P[K]>,\n recipient: ClientID,\n ): Promise<RoutingResult<R>> {\n if (!this.#subscriptions.isSubscribed(recipient, message.topic)) {\n return RoutingResult.create<R>(\n 'NACK',\n RoutingReason.NOT_SUBSCRIBED,\n `Client '${recipient}' not subscribed to '${message.topic}'`,\n recipient,\n );\n }\n\n const entries = this.#subscriptions.getEntries(recipient, message.topic);\n const first = entries[0]?.handler;\n const { success, data: responseData } = await this.#executeHandler<R>(message, first);\n\n return RoutingResult.create<R>(\n success ? 'ACK' : 'NACK',\n success ? RoutingReason.DELIVERED : RoutingReason.HANDLER_FAILED,\n success\n ? `Message delivered and handled by '${recipient}'`\n : `Message not handled by '${recipient}'`,\n recipient,\n responseData,\n );\n }\n\n /**\n * Route multicast message to all subscribers except sender.\n *\n * A subscriber may have registered multiple handlers on the topic — every\n * one of them fires. The `dispatched` count reflects unique recipients\n * (not handler invocations) to keep the ACK payload consistent with the\n * subscriber-centric mental model.\n *\n * Handlers run fire-and-forget — ACK means dispatch completed, not that\n * every subscriber finished processing the message.\n */\n async multicast<K extends T>(message: Message<K, P[K]>, sender: ClientID): Promise<RoutingResult> {\n const subscribers = this.#subscriptions.getSubscribers(message.topic);\n\n const dispatched: ClientID[] = [];\n for (const clientId of subscribers) {\n if (clientId === sender) continue;\n const entries = this.#subscriptions.getEntries(clientId, message.topic);\n if (entries.length === 0) continue;\n\n for (const entry of entries) {\n this.#executeHandlerFireAndForget(message, entry.handler, clientId);\n }\n dispatched.push(clientId);\n }\n\n if (dispatched.length === 0) {\n return RoutingResult.create('NACK', RoutingReason.NO_SUBSCRIBERS, `No subscribers for message '${message.topic}'`);\n }\n\n return RoutingResult.create(\n 'ACK',\n RoutingReason.DISPATCHED,\n `Multicast dispatched to ${dispatched.length} subscriber${dispatched.length === 1 ? '' : 's'}`,\n undefined,\n undefined,\n dispatched,\n );\n }\n\n // ========================================\n // PRIVATE HELPER METHODS\n // ========================================\n\n /**\n * Execute a handler with error handling and response capture\n * @private\n */\n async #executeHandler<R = unknown>(\n message: Message<T, P[T]>,\n handler: MessageHandler | undefined,\n ): Promise<{ success: boolean; data?: R }> {\n if (!handler) return { success: false };\n\n try {\n const result = await handler(message);\n return { success: true, data: result as R };\n } catch (handlerError) {\n this.#logger.error('handler.failed', { error: handlerError });\n return { success: false };\n }\n }\n\n /**\n * Execute handler in fire-and-forget mode (for multicast)\n * @private\n */\n #executeHandlerFireAndForget(message: Message<T, P[T]>, handler: MessageHandler, clientId: ClientID): void {\n try {\n Promise.resolve(handler(message)).catch((handlerError: unknown) => {\n this.#logger.error('handler.failed', { clientId, error: handlerError });\n });\n } catch (handlerError: unknown) {\n this.#logger.error('handler.failed', { clientId, error: handlerError });\n }\n }\n}\n","import type { Message, ClientID } from '../types';\nimport type { RoutingResult } from '../routing/RoutingResult';\nimport type { HookResult, OnSubscribeHook, BeforeSendHook, AfterSendHook } from './HooksRegistry.types';\nimport type { BrokerLogger } from '../logger/BrokerLogger.types';\n\n/**\n * HooksRegistry — central registry for broker extension hooks.\n *\n * Hook types:\n * - onSubscribe: guard hook, called on client subscription; can block\n * - beforeSend: guard hook, called before routing; can block\n * - afterSend: observer hook, called after routing with delivery result\n *\n * All hooks are executed for ALL messages including those from bridges.\n * Use `message.fromExternal` to distinguish local vs external messages.\n */\nexport class HooksRegistry<T extends string, P extends Record<T, any>> {\n #onSubscribeHooks: Array<OnSubscribeHook<T>> = [];\n #beforeSendHooks: Array<BeforeSendHook<T, P>> = [];\n #afterSendHooks: Array<AfterSendHook<T, P>> = [];\n #logger: BrokerLogger;\n\n constructor(logger: BrokerLogger) {\n this.#logger = logger;\n }\n\n // ========================================\n // REGISTRATION\n // ========================================\n\n /**\n * Register onSubscribe hook(s).\n * Called whenever a client subscribes to a topic. Return `{ allowed: false }` to block.\n *\n * @returns Cleanup function to remove the hook(s).\n */\n addOnSubscribeHook(hook: OnSubscribeHook<T> | OnSubscribeHook<T>[]): () => void {\n return this.#addHook(this.#onSubscribeHooks, hook);\n }\n\n /**\n * Register beforeSend hook(s).\n *\n * Called before routing for EVERY message, including those received from bridges.\n * Return `{ allowed: false }` to block delivery.\n *\n * @returns Cleanup function to remove the hook(s).\n */\n addBeforeSendHook(hook: BeforeSendHook<T, P> | BeforeSendHook<T, P>[]): () => void {\n return this.#addHook(this.#beforeSendHooks, hook);\n }\n\n /**\n * Register afterSend hook(s).\n *\n * Called after each message is processed. Receives the routing result.\n * Called for ALL messages — both local and forwarded from bridges.\n *\n * @returns Cleanup function to remove the hook(s).\n */\n addAfterSendHook(hook: AfterSendHook<T, P> | AfterSendHook<T, P>[]): () => void {\n return this.#addHook(this.#afterSendHooks, hook);\n }\n\n // ========================================\n // EXECUTION (called by BrokerCore)\n // ========================================\n\n /**\n * Execute onSubscribe hooks. Stops at the first hook that denies.\n */\n onSubscribe(topic: T, clientId: ClientID): HookResult {\n return this.#runGuard(this.#onSubscribeHooks, 'onSubscribe', (hook) =>\n hook(topic, clientId),\n );\n }\n\n /**\n * Execute beforeSend hooks. Stops at the first hook that denies.\n * Executed for ALL messages, including those from bridges.\n */\n beforeSend(message: Readonly<Message<T, P[T]>>): HookResult {\n return this.#runGuard(this.#beforeSendHooks, 'beforeSend', (hook) => hook(message));\n }\n\n /**\n * Execute afterSend hooks. All hooks run; errors are isolated per-hook.\n * Executed for ALL messages (local and external).\n */\n afterSend(message: Readonly<Message<T, P[T]>>, messageResult: RoutingResult): void {\n for (const hook of this.#afterSendHooks) {\n try {\n hook(message, messageResult);\n } catch (error) {\n this.#logger.error('hook.after_send.failed', { error });\n }\n }\n }\n\n // ========================================\n // LIFECYCLE\n // ========================================\n\n /**\n * Remove all registered hooks.\n */\n clear(): void {\n this.#onSubscribeHooks = [];\n this.#beforeSendHooks = [];\n this.#afterSendHooks = [];\n }\n\n // ========================================\n // PRIVATE HELPERS\n // ========================================\n\n /**\n * Add one or more hooks to a list and return an unsubscribe function.\n * Preserves insertion order for deterministic hook execution.\n */\n #addHook<H>(list: H[], hookOrHooks: H | H[]): () => void {\n const added = Array.isArray(hookOrHooks) ? [...hookOrHooks] : [hookOrHooks];\n list.push(...added);\n\n return () => {\n for (const hook of added) {\n const index = list.indexOf(hook);\n if (index !== -1) list.splice(index, 1);\n }\n };\n }\n\n /**\n * Run a list of guard-style hooks: each returns HookResult, execution stops\n * at the first `{ allowed: false }`. Errors are caught and logged (fail-open):\n * a throwing hook does not block the pipeline.\n */\n #runGuard<H extends (...args: any[]) => HookResult>(\n hooks: H[],\n kind: string,\n invoke: (hook: H) => HookResult,\n ): HookResult {\n for (const hook of hooks) {\n try {\n const result = invoke(hook);\n if (!result.allowed) return result;\n } catch (error) {\n this.#logger.error('hook.failed', { kind, error });\n }\n }\n return { allowed: true };\n }\n}\n","import type { ClientID } from '../types';\nimport type { BrokerClient } from './BrokerClient';\n\n/**\n * ClientRegistry - Manages registered clients\n *\n * Responsibilities:\n * - Register/unregister clients\n * - Track active clients\n * - Provide client lookup\n *\n * Used for observability and DevTools integration\n */\nexport class ClientRegistry<T extends string, P extends Record<T, any>> {\n #clients = new Map<ClientID, BrokerClient<T, P>>();\n #connectedAt = new Map<ClientID, number>();\n\n /**\n * Register a client\n */\n register(client: BrokerClient<T, P>): void {\n this.#clients.set(client.id, client);\n this.#connectedAt.set(client.id, Date.now());\n }\n\n /**\n * Unregister a client\n */\n unregister(clientId: ClientID): void {\n this.#clients.delete(clientId);\n this.#connectedAt.delete(clientId);\n }\n\n /**\n * Get the timestamp when a client registered (Unix ms)\n */\n getConnectedAt(clientId: ClientID): number | undefined {\n return this.#connectedAt.get(clientId);\n }\n\n /**\n * Get client by ID\n */\n get(clientId: ClientID): BrokerClient<T, P> | undefined {\n return this.#clients.get(clientId);\n }\n\n /**\n * Check if client is registered\n */\n has(clientId: ClientID): boolean {\n return this.#clients.has(clientId);\n }\n\n /**\n * Get all registered clients\n */\n getAll(): BrokerClient<T, P>[] {\n return Array.from(this.#clients.values());\n }\n\n /**\n * Get all client IDs\n */\n getAllIds(): ClientID[] {\n return Array.from(this.#clients.keys());\n }\n\n /**\n * Clear all clients\n */\n clear(): void {\n this.#clients.clear();\n this.#connectedAt.clear();\n }\n\n /**\n * Get number of registered clients\n */\n get size(): number {\n return this.#clients.size;\n }\n}\n","import type { ClientID, MessageHandler, SubscriptionOptions } from '../types';\n\n/**\n * Subscriptions - Efficient subscription and handler management\n *\n * A single `(clientId, topic)` pair may hold MANY handlers. Each individual\n * subscription is identified by a monotonic numeric id returned from\n * {@link subscribe}, so callers can remove one handler without touching the\n * others. Bulk operations (`unsubscribe(clientId, topic)`,\n * `unsubscribeAll(clientId)`) still nuke every handler in scope.\n *\n * Bidirectional indexes for O(1) lookups:\n * - Topic → Clients mapping (multicast recipient lookup — a client appears\n * once no matter how many handlers it registered)\n * - Client → Topics mapping (unsubscribe fan-out)\n * - Composite key → ordered handler entries\n * - Subscription id → location (for O(1) per-handler removal)\n *\n * @internal This class is used internally by BrokerCore and Router\n */\n\n/** Opaque handle returned by {@link Subscriptions.subscribe}. */\nexport type SubscriptionId = number;\n\nexport type SubscriptionEntry = {\n readonly id: SubscriptionId;\n readonly handler: MessageHandler;\n readonly options?: SubscriptionOptions;\n};\n\nexport class Subscriptions<T extends string> {\n // ========================================\n // BIDIRECTIONAL INDEXES FOR O(1) OPERATIONS\n // ========================================\n\n /** Topic → Clients mapping for fast multicast recipient lookup */\n #subscriptions = new Map<T, Set<ClientID>>();\n\n /** Client → Topics mapping for fast unsubscribe operations */\n #clientSubscriptions = new Map<ClientID, Set<T>>();\n\n /** Composite key → ordered handler entries (many per pair). */\n #entries = new Map<string, SubscriptionEntry[]>();\n\n /** Subscription id → its location, for O(1) single-handler removal. */\n #entryLocations = new Map<SubscriptionId, { clientId: ClientID; topic: T }>();\n\n /** Monotonic subscription id counter. */\n #nextId: SubscriptionId = 1;\n\n /** Shared empty set to avoid allocations */\n readonly #emptySet: ReadonlySet<ClientID> = Object.freeze(new Set<ClientID>());\n readonly #emptyEntries: readonly SubscriptionEntry[] = Object.freeze([]);\n\n // ========================================\n // SUBSCRIPTION OPERATIONS\n // ========================================\n\n /**\n * Reserve a subscription id ahead of {@link subscribe}.\n *\n * Callers that need the id BEFORE the handler is finalized (e.g. to key\n * a backpressure strategy by that id) can pre-allocate here and then\n * pass the reserved id to {@link subscribe}.\n */\n reserveId(): SubscriptionId {\n return this.#nextId++;\n }\n\n /**\n * Subscribe a handler to a (client, topic) pair.\n *\n * Appends a new entry — previously registered handlers on the same pair\n * are preserved. Returns the subscription id so the caller can remove\n * this specific handler later via {@link unsubscribeOne}.\n *\n * If `preReservedId` is provided (from {@link reserveId}), that id is\n * used instead of generating a new one.\n */\n subscribe(\n clientId: ClientID,\n topic: T,\n handler: MessageHandler,\n options?: SubscriptionOptions,\n preReservedId?: SubscriptionId,\n ): SubscriptionId {\n if (!this.#subscriptions.has(topic)) {\n this.#subscriptions.set(topic, new Set());\n }\n this.#subscriptions.get(topic)!.add(clientId);\n\n if (!this.#clientSubscriptions.has(clientId)) {\n this.#clientSubscriptions.set(clientId, new Set());\n }\n this.#clientSubscriptions.get(clientId)!.add(topic);\n\n const id: SubscriptionId = preReservedId ?? this.#nextId++;\n const entry: SubscriptionEntry = { id, handler, options };\n\n const key = this.#getKey(clientId, topic);\n let list = this.#entries.get(key);\n if (!list) {\n list = [];\n this.#entries.set(key, list);\n }\n list.push(entry);\n\n this.#entryLocations.set(id, { clientId, topic });\n\n return id;\n }\n\n /**\n * Remove a single handler by its subscription id.\n *\n * If this was the last handler for the pair, the pair is fully removed\n * from the bidirectional indexes (mirroring `unsubscribe` semantics).\n *\n * @returns Removal outcome: the removed entry, the pair it belonged to,\n * and whether it was the last handler on that pair. `undefined`\n * when no such id existed.\n */\n unsubscribeOne(id: SubscriptionId):\n | {\n entry: SubscriptionEntry;\n clientId: ClientID;\n topic: T;\n wasLast: boolean;\n }\n | undefined {\n const location = this.#entryLocations.get(id);\n if (!location) return undefined;\n\n const { clientId, topic } = location;\n const key = this.#getKey(clientId, topic);\n const list = this.#entries.get(key);\n if (!list) {\n this.#entryLocations.delete(id);\n return undefined;\n }\n\n const idx = list.findIndex((e) => e.id === id);\n if (idx === -1) {\n this.#entryLocations.delete(id);\n return undefined;\n }\n\n const [removed] = list.splice(idx, 1);\n this.#entryLocations.delete(id);\n\n const wasLast = list.length === 0;\n if (wasLast) {\n this.#entries.delete(key);\n this.#subscriptions.get(topic)?.delete(clientId);\n this.#clientSubscriptions.get(clientId)?.delete(topic);\n\n if (this.#subscriptions.get(topic)?.size === 0) {\n this.#subscriptions.delete(topic);\n }\n }\n\n return { entry: removed, clientId, topic, wasLast };\n }\n\n /**\n * Unsubscribe every handler a client holds on a topic.\n *\n * @returns Entries that were actually removed. Empty when the client had\n * no handlers on the topic. Callers use this to release\n * per-handler resources (e.g. backpressure strategies).\n */\n unsubscribe(clientId: ClientID, topic: T): readonly SubscriptionEntry[] {\n const key = this.#getKey(clientId, topic);\n const list = this.#entries.get(key);\n if (!list || list.length === 0) return this.#emptyEntries;\n\n for (const entry of list) {\n this.#entryLocations.delete(entry.id);\n }\n this.#entries.delete(key);\n\n this.#subscriptions.get(topic)?.delete(clientId);\n this.#clientSubscriptions.get(clientId)?.delete(topic);\n\n if (this.#subscriptions.get(topic)?.size === 0) {\n this.#subscriptions.delete(topic);\n }\n\n return list;\n }\n\n /**\n * Remove every subscription held by a given client.\n *\n * @returns Per-topic entry buckets that were removed, in iteration order.\n * Empty when the client had no active subscriptions. Callers use\n * this to release per-handler resources and emit per-topic\n * `subscription.removed` events.\n */\n unsubscribeAll(\n clientId: ClientID,\n ): ReadonlyArray<{ topic: T; entries: readonly SubscriptionEntry[] }> {\n const clientTopics = this.#clientSubscriptions.get(clientId);\n if (!clientTopics || clientTopics.size === 0) {\n this.#clientSubscriptions.delete(clientId);\n return [];\n }\n\n const removed: Array<{ topic: T; entries: readonly SubscriptionEntry[] }> = [];\n for (const topic of clientTopics) {\n const key = this.#getKey(clientId, topic);\n const list = this.#entries.get(key);\n if (list) {\n for (const entry of list) {\n this.#entryLocations.delete(entry.id);\n }\n this.#entries.delete(key);\n removed.push({ topic, entries: list });\n }\n\n this.#subscriptions.get(topic)?.delete(clientId);\n if (this.#subscriptions.get(topic)?.size === 0) {\n this.#subscriptions.delete(topic);\n }\n }\n\n this.#clientSubscriptions.delete(clientId);\n return removed;\n }\n\n // ========================================\n // QUERY OPERATIONS\n // ========================================\n\n /**\n * Get all topics a client is subscribed to\n */\n getClientTopics(clientId: ClientID): ReadonlySet<T> | undefined {\n return this.#clientSubscriptions.get(clientId);\n }\n\n /**\n * Check if a client has at least one handler on a topic.\n */\n isSubscribed(clientId: ClientID, topic: T): boolean {\n return this.#clientSubscriptions.get(clientId)?.has(topic) ?? false;\n }\n\n /**\n * All handler entries a client has on a topic, in registration order.\n */\n getEntries(clientId: ClientID, topic: T): readonly SubscriptionEntry[] {\n return this.#entries.get(this.#getKey(clientId, topic)) ?? this.#emptyEntries;\n }\n\n /**\n * Options of the first handler registered on `(clientId, topic)`.\n *\n * Convenience for read-only observers (e.g. Inspector) that predate the\n * multi-handler model and expect a single options blob per pair.\n */\n getFirstOptions(clientId: ClientID, topic: T): SubscriptionOptions | undefined {\n return this.#entries.get(this.#getKey(clientId, topic))?.[0]?.options;\n }\n\n /**\n * Number of handlers a client holds on a topic (0 = not subscribed).\n */\n getHandlerCount(clientId: ClientID, topic: T): number {\n return this.#entries.get(this.#getKey(clientId, topic))?.length ?? 0;\n }\n\n /**\n * Get all subscribers for a topic (read-only)\n */\n getSubscribers(topic: T): ReadonlySet<ClientID> {\n return this.#subscriptions.get(topic) ?? this.#emptySet;\n }\n\n /**\n * Get list of all clients that have active subscriptions\n */\n getAllSubscribedClients(): ClientID[] {\n return Array.from(this.#clientSubscriptions.keys());\n }\n\n /**\n * Get detailed subscription map for all clients\n */\n getAllSubscriptions(): Record<string, string[]> {\n const result: Record<string, string[]> = {};\n for (const [clientId, topics] of this.#clientSubscriptions) {\n result[clientId] = Array.from(topics);\n }\n return result;\n }\n\n // ========================================\n // LIFECYCLE\n // ========================================\n\n /**\n * Clear all subscriptions and handlers.\n *\n * @returns All entries that were held, so the caller can release\n * per-handler resources (e.g. backpressure strategies).\n */\n clear(): readonly SubscriptionEntry[] {\n const all: SubscriptionEntry[] = [];\n for (const list of this.#entries.values()) {\n for (const entry of list) {\n all.push(entry);\n }\n }\n this.#subscriptions.clear();\n this.#clientSubscriptions.clear();\n this.#entries.clear();\n this.#entryLocations.clear();\n return all;\n }\n\n // ========================================\n // PRIVATE HELPERS\n // ========================================\n\n #getKey(clientId: ClientID, topic: T): string {\n return `${clientId}:${topic}`;\n }\n}\n","import type { Message, MessageHandler } from '../../types';\nimport type { BackpressureStrategy } from '../BackpressureHandler.types';\nimport type { BrokerLogger } from '../../logger/BrokerLogger.types';\n\n/**\n * ThrottleStrategy - Limits handler calls to once per throttle period\n *\n * Algorithm:\n * 1. First call executes immediately\n * 2. Subsequent calls within throttle period are delayed\n * 3. Only the last pending message is executed after throttle period\n *\n * Guarantees:\n * - Maximum call rate (1 per throttleMs)\n * - Last message is always processed (not lost)\n *\n * Use cases:\n * - Real-time charts (limit chart updates)\n * - High-frequency WebSocket streams\n * - Scroll/resize message handlers\n */\nexport class ThrottleStrategy implements BackpressureStrategy {\n #throttleMs: number;\n #lastExecutionTime = 0;\n #timeoutId?: NodeJS.Timeout;\n #pendingMessage?: Message;\n #pendingHandler?: MessageHandler;\n #logger: BrokerLogger;\n\n constructor(throttleMs: number, logger: BrokerLogger) {\n if (typeof throttleMs !== 'number' || !Number.isFinite(throttleMs)) {\n throw new Error('Throttle period must be a finite number');\n }\n if (throttleMs <= 0) {\n throw new Error('Throttle period must be positive');\n }\n this.#throttleMs = throttleMs;\n this.#logger = logger;\n }\n\n /**\n * Process message through throttle\n *\n * @param message - Incoming message\n * @param handler - Handler to call\n * @returns true if executed immediately, false if delayed\n */\n process(message: Message, handler: MessageHandler): boolean {\n const now = Date.now();\n const timeSinceLastExecution = now - this.#lastExecutionTime;\n\n // Can execute immediately\n if (timeSinceLastExecution >= this.#throttleMs) {\n this.#execute(message, handler);\n return true;\n }\n\n // Delay execution - save message and handler\n this.#pendingMessage = message;\n this.#pendingHandler = handler;\n\n // Schedule execution if not already scheduled\n if (!this.#timeoutId) {\n const delay = this.#throttleMs - timeSinceLastExecution;\n this.#timeoutId = setTimeout(() => {\n this.#flush();\n }, delay);\n }\n\n return false; // Delayed\n }\n\n /**\n * Execute handler and update last execution time\n */\n #execute(message: Message, handler: MessageHandler): void {\n this.#lastExecutionTime = Date.now();\n try {\n handler(message);\n } catch (error) {\n this.#logger.error('backpressure.handler.failed', { strategy: 'throttle', error });\n }\n }\n\n /**\n * Flush pending message\n */\n #flush(): void {\n if (this.#pendingMessage && this.#pendingHandler) {\n this.#execute(this.#pendingMessage, this.#pendingHandler);\n }\n\n // Clear state\n this.#pendingMessage = undefined;\n this.#pendingHandler = undefined;\n this.#timeoutId = undefined;\n }\n\n /**\n * Force flush pending messages\n * Called on unsubscribe to ensure no messages are lost\n */\n flush(): void {\n if (this.#timeoutId) {\n clearTimeout(this.#timeoutId);\n this.#flush();\n }\n }\n\n /**\n * Cleanup resources\n */\n destroy(): void {\n if (this.#timeoutId) {\n clearTimeout(this.#timeoutId);\n }\n this.#pendingMessage = undefined;\n this.#pendingHandler = undefined;\n }\n}\n","import type { Message, MessageHandler } from '../../types';\nimport type { BackpressureStrategy } from '../BackpressureHandler.types';\nimport type { BrokerLogger } from '../../logger/BrokerLogger.types';\n\n/**\n * DebounceStrategy - Delays handler execution until silence period\n *\n * Algorithm:\n * 1. On each message, reset the timer\n * 2. Save the last message\n * 3. Execute only after debounce period of silence\n *\n * Guarantees:\n * - Handler called only after user stops\n * - Only last message is processed\n * - Earlier messages are ignored (not lost, just not needed)\n *\n * Use cases:\n * - Search autocomplete (wait for user to stop typing)\n * - Form validation (validate after pause in input)\n * - Window resize handlers\n */\nexport class DebounceStrategy implements BackpressureStrategy {\n #debounceMs: number;\n #timeoutId?: NodeJS.Timeout;\n #pendingMessage?: Message;\n #pendingHandler?: MessageHandler;\n #logger: BrokerLogger;\n\n constructor(debounceMs: number, logger: BrokerLogger) {\n if (typeof debounceMs !== 'number' || !Number.isFinite(debounceMs)) {\n throw new Error('Debounce period must be a finite number');\n }\n if (debounceMs <= 0) {\n throw new Error('Debounce period must be positive');\n }\n this.#debounceMs = debounceMs;\n this.#logger = logger;\n }\n\n /**\n * Process message through debounce\n *\n * Resets timer on each call. Only executes after silence period.\n *\n * @param message - Incoming message\n * @param handler - Handler to call\n * @returns false (always delayed)\n */\n process(message: Message, handler: MessageHandler): boolean {\n // Clear previous timer\n if (this.#timeoutId) {\n clearTimeout(this.#timeoutId);\n }\n\n // Save message and handler\n this.#pendingMessage = message;\n this.#pendingHandler = handler;\n\n // Start new timer\n this.#timeoutId = setTimeout(() => {\n this.#flush();\n }, this.#debounceMs);\n\n return false; // Always delayed\n }\n\n /**\n * Execute pending message\n */\n #flush(): void {\n if (this.#pendingMessage && this.#pendingHandler) {\n try {\n this.#pendingHandler(this.#pendingMessage);\n } catch (error) {\n this.#logger.error('backpressure.handler.failed', { strategy: 'debounce', error });\n }\n }\n\n // Clear state\n this.#pendingMessage = undefined;\n this.#pendingHandler = undefined;\n this.#timeoutId = undefined;\n }\n\n /**\n * Force flush pending message\n * Called on unsubscribe to ensure no messages are lost\n */\n flush(): void {\n if (this.#timeoutId) {\n clearTimeout(this.#timeoutId);\n this.#flush();\n }\n }\n\n /**\n * Cleanup resources\n */\n destroy(): void {\n if (this.#timeoutId) {\n clearTimeout(this.#timeoutId);\n }\n this.#pendingMessage = undefined;\n this.#pendingHandler = undefined;\n }\n}\n","import type { Message, MessageHandler } from '../../types';\nimport type { BackpressureStrategy } from '../BackpressureHandler.types';\nimport type { BrokerLogger } from '../../logger/BrokerLogger.types';\n\n/**\n * RateLimitStrategy - Limits message processing rate with hard cap\n *\n * Algorithm (Sliding Window with Circular Buffer):\n * 1. Pre-allocate a fixed-size buffer of `max` timestamps\n * 2. On new message:\n * - Evict expired timestamps by advancing head pointer\n * - If count < max: record timestamp and allow message\n * - If count >= max: drop message + call onDrop()\n *\n * Key difference from throttle:\n * - Messages are DROPPED (lost forever), not delayed\n * - Hard limit enforcement\n * - No guarantees about which messages are kept\n *\n * Use cases:\n * - Spam protection\n * - Flood prevention\n * - Offline recovery (limit burst)\n * - API rate limiting\n */\nexport class RateLimitStrategy implements BackpressureStrategy {\n #max: number;\n #windowMs: number;\n #onDrop?: (droppedCount: number) => void;\n #timestamps: number[];\n #head = 0;\n #count = 0;\n #droppedCount = 0;\n\n #logger: BrokerLogger;\n\n constructor(options: { max: number; window: number }, onDrop: ((droppedCount: number) => void) | undefined, logger: BrokerLogger) {\n if (typeof options.max !== 'number' || !Number.isFinite(options.max)) {\n throw new Error('Rate limit max must be a finite number');\n }\n if (options.max <= 0) {\n throw new Error('Rate limit max must be positive');\n }\n\n if (typeof options.window !== 'number' || !Number.isFinite(options.window)) {\n throw new Error('Rate limit window must be a finite number');\n }\n if (options.window <= 0) {\n throw new Error('Rate limit window must be positive');\n }\n\n this.#max = options.max;\n this.#windowMs = options.window;\n this.#onDrop = onDrop;\n this.#timestamps = new Array(options.max).fill(0);\n this.#logger = logger;\n }\n\n /**\n * Process message through rate limit\n *\n * Uses sliding window with circular buffer for O(1) amortized eviction.\n *\n * @param message - Incoming message\n * @param handler - Handler to call\n * @returns true if processed, false if dropped\n */\n process(message: Message, handler: MessageHandler): boolean {\n const now = Date.now();\n\n this.#evict(now);\n\n if (this.#count < this.#max) {\n const tail = (this.#head + this.#count) % this.#max;\n this.#timestamps[tail] = now;\n this.#count++;\n\n try {\n handler(message);\n } catch (error) {\n this.#logger.error('backpressure.handler.failed', { strategy: 'rateLimit', error });\n }\n\n return true;\n }\n\n this.#droppedCount++;\n\n if (this.#onDrop) {\n try {\n this.#onDrop(this.#droppedCount);\n } catch (error) {\n this.#logger.error('backpressure.on_drop.failed', { error });\n }\n }\n\n return false;\n }\n\n /**\n * Flush is no-op for rate limiting\n * Rate limit doesn't accumulate messages, so nothing to flush\n */\n flush(): void {\n // No-op: rate limit doesn't buffer messages\n }\n\n /**\n * Cleanup resources\n */\n destroy(): void {\n this.#head = 0;\n this.#count = 0;\n this.#timestamps.fill(0);\n }\n\n /**\n * Get number of dropped messages (for debugging/metrics)\n */\n get droppedCount(): number {\n return this.#droppedCount;\n }\n\n /**\n * Get current count in window (for debugging/metrics)\n */\n get currentCount(): number {\n this.#evict(Date.now());\n return this.#count;\n }\n\n /** Advance head past expired timestamps */\n #evict(now: number): void {\n while (this.#count > 0 && now - this.#timestamps[this.#head] >= this.#windowMs) {\n this.#head = (this.#head + 1) % this.#max;\n this.#count--;\n }\n }\n}\n","import type { ClientID, MessageHandler, SubscriptionOptions } from '../types';\nimport type { BackpressureStrategy, BackpressureOptions } from './BackpressureHandler.types';\nimport type { BrokerLogger } from '../logger/BrokerLogger.types';\nimport { ThrottleStrategy } from './strategies/ThrottleStrategy';\nimport { DebounceStrategy } from './strategies/DebounceStrategy';\nimport { RateLimitStrategy } from './strategies/RateLimitStrategy';\n\n/**\n * BackpressureHandler - Coordinates backpressure strategies\n *\n * Responsibilities:\n * - Create appropriate strategy based on options\n * - Wrap handlers with strategy logic\n * - Manage strategy lifecycle (cleanup on unsubscribe)\n *\n * Available strategies:\n * - Throttle: Limit handler calls to once per period\n * - Debounce: Delay execution until silence\n * - Rate Limit: Drop messages exceeding rate limit\n *\n * Multi-handler model: each subscription on a `(clientId, topic)` pair\n * gets its own strategy instance, keyed by the subscription id.\n *\n * Note: Only ONE strategy can be specified per subscription. Specifying\n * multiple strategies will throw an error.\n */\nexport class BackpressureHandler {\n /** subscriptionId → strategy. One entry per handler that opted into BP. */\n #strategies = new Map<number, BackpressureStrategy>();\n #logger: BrokerLogger;\n\n constructor(logger: BrokerLogger) {\n this.#logger = logger;\n }\n\n /**\n * Wrap handler in backpressure strategy\n *\n * If options.backpressure is undefined/null, returns original handler (no backpressure).\n * Otherwise creates appropriate strategy and returns wrapped handler.\n *\n * @param subscriptionId - Unique id of this handler subscription.\n * The id is emitted by {@link Subscriptions.subscribe} — the caller is\n * responsible for reserving it and passing the same value to both\n * `wrap()` and `subscribe()` so the strategy can be released via\n * {@link removeOne} when that specific handler unsubscribes.\n * @param clientId - Unique client identifier (for logging context)\n * @param topic - Topic being subscribed to (for logging context)\n * @param handler - Original handler function\n * @param options - Subscription options (optional)\n * @returns Wrapped handler or original handler if no backpressure options\n */\n wrap(\n subscriptionId: number,\n clientId: ClientID,\n topic: string,\n handler: MessageHandler,\n options?: SubscriptionOptions,\n ): MessageHandler {\n void clientId;\n void topic;\n\n const bpOptions = options?.backpressure;\n if (!bpOptions) {\n return handler;\n }\n\n const strategy = this.#createStrategy(bpOptions);\n this.#strategies.set(subscriptionId, strategy);\n\n return (message) => {\n strategy.process(message, handler);\n };\n }\n\n /**\n * Create strategy instance based on backpressure options\n *\n * Only ONE strategy can be specified per subscription.\n * Multiple strategies will throw an error.\n *\n * @throws Error if no strategy specified\n * @throws Error if multiple strategies specified\n */\n #createStrategy(options: BackpressureOptions): BackpressureStrategy {\n // Validate: only one strategy allowed\n const specifiedStrategies = [\n options.throttle !== undefined && 'throttle',\n options.debounce !== undefined && 'debounce',\n options.rateLimit !== undefined && 'rateLimit',\n ].filter(Boolean) as string[];\n\n if (specifiedStrategies.length === 0) {\n throw new Error(\n 'No backpressure strategy specified. ' +\n 'Provide one of: throttle, debounce, or rateLimit.',\n );\n }\n\n if (specifiedStrategies.length > 1) {\n throw new Error(\n `Multiple backpressure strategies specified: ${specifiedStrategies.join(', ')}. ` +\n 'Only one strategy is allowed per subscription.',\n );\n }\n\n // Create strategy (only one will match)\n if (options.throttle !== undefined) {\n return new ThrottleStrategy(options.throttle, this.#logger);\n }\n\n if (options.debounce !== undefined) {\n return new DebounceStrategy(options.debounce, this.#logger);\n }\n\n if (options.rateLimit) {\n return new RateLimitStrategy(options.rateLimit, options.onDrop, this.#logger);\n }\n\n // Unreachable (covered by validation above)\n throw new Error('No backpressure strategy specified in BackpressureOptions');\n }\n\n /**\n * Release the strategy attached to a single subscription id.\n *\n * Called when the corresponding handler unsubscribes. Flushes pending\n * messages and destroys the strategy. No-op when the subscription had\n * no backpressure.\n */\n removeOne(subscriptionId: number): void {\n const strategy = this.#strategies.get(subscriptionId);\n if (!strategy) return;\n strategy.flush();\n strategy.destroy();\n this.#strategies.delete(subscriptionId);\n }\n\n /**\n * Bulk release for a set of subscription ids.\n *\n * Used when a client unsubscribes from a whole topic (or resets), which\n * removes N handlers at once.\n */\n removeMany(subscriptionIds: Iterable<number>): void {\n for (const id of subscriptionIds) {\n this.removeOne(id);\n }\n }\n\n /**\n * Cleanup all strategies\n *\n * Called when broker is destroyed.\n */\n destroy(): void {\n for (const strategy of this.#strategies.values()) {\n strategy.flush();\n strategy.destroy();\n }\n this.#strategies.clear();\n }\n\n /**\n * Get number of active strategies (for debugging/metrics)\n */\n get activeStrategies(): number {\n return this.#strategies.size;\n }\n}\n","/**\n * Deep freeze an object and all its nested properties\n *\n * Used to make events immutable before passing to hooks and handlers.\n * This prevents accidental mutations that could cause bugs.\n *\n * @param obj - Object to freeze\n * @returns Frozen object (same reference)\n */\nexport function deepFreeze<T>(obj: T): T {\n Object.freeze(obj);\n\n Object.getOwnPropertyNames(obj).forEach((prop) => {\n const value = (obj as any)[prop];\n if (\n value !== null &&\n (typeof value === 'object' || typeof value === 'function') &&\n !Object.isFrozen(value)\n ) {\n deepFreeze(value);\n }\n });\n\n return obj;\n}\n","import type { Message } from '../types';\nimport type {\n HistoryEntry,\n HistoryFilter,\n HistoryConfig,\n HistoryStats,\n} from './MessageHistory.types';\nimport { deepFreeze } from '../utils/deepFreeze';\nimport { matchPattern } from '../utils/matchPattern';\n\n/**\n * MessageHistory - In-memory message history\n *\n * Features:\n * - FIFO eviction when maxSize is reached\n * - TTL-based automatic cleanup\n * - Glob pattern matching for topics\n * - Immutable messages (deepFreeze)\n * - Efficient filtering\n */\nexport class MessageHistory<T extends string, P extends Record<T, any>> {\n #entries: HistoryEntry<T, P[T]>[] = [];\n #sequence = 0;\n #config: Required<HistoryConfig>;\n #cleanupTimer?: ReturnType<typeof setInterval>;\n\n constructor(config: HistoryConfig) {\n // Apply defaults for optional fields\n this.#config = {\n enabled: config.enabled,\n maxSize: config.maxSize ?? 1000,\n ttl: config.ttl,\n } as Required<HistoryConfig>;\n\n // Start TTL cleanup if configured\n if (this.#config.ttl !== undefined) {\n this.#startCleanup();\n }\n }\n\n /**\n * Record a message to history\n */\n record(message: Message<T, P[T]>): void {\n const entry: HistoryEntry<T, P[T]> = {\n message: deepFreeze(message),\n timestamp: message.timestamp,\n sequence: this.#sequence++,\n };\n\n this.#entries.push(entry);\n\n // FIFO eviction if maxSize exceeded\n if (this.#entries.length > this.#config.maxSize) {\n this.#entries.shift();\n }\n }\n\n /**\n * Query messages from history\n */\n async query(filter?: HistoryFilter<T>): Promise<HistoryEntry<T, P[T]>[]> {\n let results = [...this.#entries];\n\n // Filter by time range (since, until)\n if (filter?.since !== undefined) {\n results = results.filter((entry) => entry.timestamp >= filter.since!);\n }\n if (filter?.until !== undefined) {\n results = results.filter((entry) => entry.timestamp <= filter.until!);\n }\n\n // Filter by topics (supports glob patterns)\n if (filter?.topics && filter.topics.length > 0) {\n results = results.filter((entry) =>\n filter.topics!.some((pattern) => matchPattern(entry.message.topic, pattern)),\n );\n }\n\n // Filter by sources\n if (filter?.sources && filter.sources.length > 0) {\n results = results.filter((entry) => filter.sources!.includes(entry.message.source));\n }\n\n // Apply limit (last N messages)\n if (filter?.limit !== undefined && filter.limit > 0) {\n results = results.slice(-filter.limit);\n }\n\n return results;\n }\n\n /**\n * Clear messages from history\n */\n async clear(filter?: HistoryFilter<T>): Promise<void> {\n if (!filter) {\n // Clear all\n this.#entries = [];\n return;\n }\n\n // Clear filtered entries\n const toKeep = await this.#getInverseFilter(filter);\n this.#entries = toKeep;\n }\n\n /**\n * Return a point-in-time snapshot of all entries (oldest → newest).\n */\n getSnapshot(): ReadonlyArray<HistoryEntry<T, P[T]>> {\n return [...this.#entries];\n }\n\n /**\n * Get history statistics\n */\n getStats(): HistoryStats {\n const count = this.#entries.length;\n\n if (count === 0) {\n return { count: 0 };\n }\n\n const oldestTimestamp = this.#entries[0]?.timestamp;\n const newestTimestamp = this.#entries[count - 1]?.timestamp;\n const memoryUsage = this.#estimateMemoryUsage();\n\n return {\n count,\n oldestTimestamp,\n newestTimestamp,\n memoryUsage,\n };\n }\n\n /**\n * Cleanup and destroy\n */\n destroy(): void {\n if (this.#cleanupTimer) {\n clearInterval(this.#cleanupTimer);\n this.#cleanupTimer = undefined;\n }\n this.#entries = [];\n }\n\n // ========================================\n // PRIVATE METHODS\n // ========================================\n\n /**\n * Get entries that should be kept (inverse of filter)\n */\n async #getInverseFilter(filter: HistoryFilter<T>): Promise<HistoryEntry<T, P[T]>[]> {\n return this.#entries.filter((entry) => {\n // Keep if outside time range\n if (filter.since !== undefined && entry.timestamp < filter.since) {\n return true;\n }\n if (filter.until !== undefined && entry.timestamp > filter.until) {\n return true;\n }\n\n // Keep if topic doesn't match\n if (filter.topics && filter.topics.length > 0) {\n const matches = filter.topics.some((pattern) =>\n matchPattern(entry.message.topic, pattern),\n );\n if (!matches) {\n return true;\n }\n }\n\n // Keep if source doesn't match\n if (filter.sources && filter.sources.length > 0) {\n if (!filter.sources.includes(entry.message.source)) {\n return true;\n }\n }\n\n // Don't keep (should be cleared)\n return false;\n });\n }\n\n /**\n * Start periodic TTL-based cleanup\n */\n #startCleanup(): void {\n const ttl = this.#config.ttl;\n if (!ttl) return;\n\n // Run cleanup every TTL/2 (or every minute, whichever is smaller)\n const interval = Math.min(ttl / 2, 60000);\n\n this.#cleanupTimer = setInterval(() => {\n const now = Date.now();\n const cutoff = now - ttl;\n\n // Remove messages older than TTL\n this.#entries = this.#entries.filter((entry) => entry.timestamp > cutoff);\n }, interval);\n }\n\n /**\n * Estimate memory usage (rough approximation)\n */\n #estimateMemoryUsage(): number {\n return this.#entries.length * 100;\n }\n}\n","import { RoutingResult, RoutingReason } from '../routing/RoutingResult';\n\nimport type { ClientID, MessageHandler, SubscriptionOptions } from '../types';\nimport type { MessageHistory } from './MessageHistory';\nimport type { HooksRegistry } from '../hooks/HooksRegistry';\nimport type { BrokerLogger } from '../logger/BrokerLogger.types';\n\n/**\n * SubscriptionReplay - delivers historical messages to a newly created subscription.\n *\n * This is a standalone subsystem on top of {@link MessageHistory}. It encapsulates\n * everything BrokerCore would otherwise need to inline at the subscription site:\n *\n * - querying the history by topic / time window / limit;\n * - routing-level security: a unicast message is replayed ONLY to its original\n * recipient; multicast messages are replayed to every new subscriber;\n * - shaping the message (shallow copy + `replayed: true` flag);\n * - invoking the subscriber's handler;\n * - emitting an `afterSend` hook so observers (DevTools, logging) see replayed\n * messages in the feed — note that replayed messages do NOT pass through\n * `beforeSend`, they have already been validated at original emit time;\n * - async scheduling via `queueMicrotask` so that `subscribe()` returns\n * immediately and replay never blocks the subscription establishment;\n * - per-message and per-query error isolation — a failing handler for one\n * historical entry does not abort the rest of the replay.\n *\n * The class is instantiated by BrokerCore only when history is enabled, so its\n * `history` dependency is always present (no null-checks inside). This removes\n * the `this.#history!` non-null assertion from the broker.\n */\nexport class SubscriptionReplay<T extends string, P extends Record<T, any>> {\n #history: MessageHistory<T, P>;\n #hooks: HooksRegistry<T, P>;\n #logger: BrokerLogger;\n\n constructor(history: MessageHistory<T, P>, hooks: HooksRegistry<T, P>, logger: BrokerLogger) {\n this.#history = history;\n this.#hooks = hooks;\n this.#logger = logger;\n }\n\n /**\n * Asynchronously replay matching history entries to the given subscription.\n *\n * Does NOT await completion — returns immediately while the replay runs on\n * the microtask queue. Callers should not assume replay is finished when\n * this method returns.\n *\n * @param clientId - Target subscriber identifier.\n * @param topic - Subscribed topic (supports glob; forwarded to history.query).\n * @param handler - Handler to receive each replayed message.\n * @param options - Replay window (`limit`, `since`, `until`).\n */\n start(\n clientId: ClientID,\n topic: T,\n handler: MessageHandler,\n options: NonNullable<SubscriptionOptions['replay']>,\n ): void {\n queueMicrotask(async () => {\n try {\n const entries = await this.#history.query({\n topics: [topic],\n limit: options.limit,\n since: options.since,\n until: options.until,\n });\n\n for (const entry of entries) {\n try {\n const recipient = entry.message.target;\n\n // Security: unicast messages are only replayed to their original\n // recipient. Multicast (`*`) is replayed to every new subscriber.\n if (recipient !== '*' && recipient !== clientId) continue;\n\n const replayedMessage = {\n ...entry.message,\n replayed: true,\n };\n\n await handler(replayedMessage);\n\n // Feed replayed messages into afterSend so observers (DevTools)\n // see them in the feed. beforeSend is intentionally skipped —\n // the message was already validated when it was originally sent.\n this.#hooks.afterSend(\n replayedMessage as any,\n RoutingResult.create(\n 'ACK',\n RoutingReason.REPLAY_DELIVERED,\n `Replayed to '${clientId}'`,\n clientId,\n ),\n );\n } catch (error) {\n this.#logger.error('replay.handler.failed', {\n messageId: entry.message.id,\n clientId,\n error,\n });\n }\n }\n } catch (error) {\n this.#logger.error('replay.query.failed', { clientId, error });\n }\n });\n }\n}\n","import type {\n SystemEventsEmitter,\n SystemEventName,\n SystemEventPayload,\n SystemEventListener,\n SystemAnyEventListener,\n} from './SystemEvents.types';\nimport type { BrokerLogger } from '../logger/BrokerLogger.types';\n\n/**\n * System events channel - pub/sub dispatcher for broker-internal events.\n *\n * Not to be confused with the user message bus (`broker.emit` / `client.on`).\n * This channel carries infrastructure-level signals (client/subscription/bridge\n * lifecycle) and is exposed on the broker as `$systemEvents`. The `$` prefix\n * marks it as a broker-internal API — consumers should be tooling only.\n *\n * Keeps per-event listener sets and an \"any\" listener set.\n * Emission is synchronous, error-isolated, and O(n) in the number of\n * listeners for the given event.\n *\n * `emit()` and `clear()` are only on this class (not on the `SystemEventsEmitter`\n * interface), so only code that holds the concrete instance — i.e. `BrokerCore` —\n * can publish events or tear down listeners.\n */\nexport class SystemEvents<T extends string, P extends Record<T, any>>\n implements SystemEventsEmitter<T, P>\n{\n #listeners = new Map<SystemEventName<T, P>, Set<(payload: any) => void>>();\n #anyListeners = new Set<SystemAnyEventListener<T, P>>();\n #logger: BrokerLogger;\n\n constructor(logger: BrokerLogger) {\n this.#logger = logger;\n }\n\n on<K extends SystemEventName<T, P>>(\n event: K,\n listener: SystemEventListener<T, P, K>,\n ): () => void {\n let set = this.#listeners.get(event);\n if (!set) {\n set = new Set();\n this.#listeners.set(event, set);\n }\n set.add(listener as (payload: any) => void);\n\n return () => {\n const s = this.#listeners.get(event);\n if (!s) return;\n s.delete(listener as (payload: any) => void);\n if (s.size === 0) this.#listeners.delete(event);\n };\n }\n\n once<K extends SystemEventName<T, P>>(\n event: K,\n listener: SystemEventListener<T, P, K>,\n ): () => void {\n const wrapped: SystemEventListener<T, P, K> = (payload) => {\n unsubscribe();\n listener(payload);\n };\n const unsubscribe = this.on(event, wrapped);\n return unsubscribe;\n }\n\n off<K extends SystemEventName<T, P>>(event?: K): void {\n if (event === undefined) {\n this.#listeners.clear();\n return;\n }\n this.#listeners.delete(event);\n }\n\n onAny(listener: SystemAnyEventListener<T, P>): () => void {\n this.#anyListeners.add(listener);\n return () => this.#anyListeners.delete(listener);\n }\n\n listenerCount<K extends SystemEventName<T, P>>(event?: K): number {\n if (event === undefined) {\n let total = this.#anyListeners.size;\n for (const set of this.#listeners.values()) total += set.size;\n return total;\n }\n return (this.#listeners.get(event)?.size ?? 0) + this.#anyListeners.size;\n }\n\n /**\n * Emit a system event to all subscribed listeners.\n *\n * Safe to call on the hot path: returns immediately when no listeners are\n * registered (zero allocation). Listener errors are caught and logged;\n * they never propagate back to the broker pipeline.\n */\n emit<K extends SystemEventName<T, P>>(event: K, payload: SystemEventPayload<T, P, K>): void {\n if (this.#anyListeners.size === 0) {\n const direct = this.#listeners.get(event);\n if (!direct || direct.size === 0) return;\n this.#dispatch(direct, payload, event);\n return;\n }\n\n const direct = this.#listeners.get(event);\n if (direct && direct.size > 0) this.#dispatch(direct, payload, event);\n\n for (const listener of this.#anyListeners) {\n try {\n listener(event, payload);\n } catch (err) {\n this.#logger.error('system_events.listener.failed', { event: String(event), error: err });\n }\n }\n }\n\n /**\n * Remove all listeners. Called by `BrokerCore.destroy()`.\n */\n clear(): void {\n this.#listeners.clear();\n this.#anyListeners.clear();\n }\n\n #dispatch<K extends SystemEventName<T, P>>(\n listeners: Set<(payload: any) => void>,\n payload: SystemEventPayload<T, P, K>,\n event: K,\n ): void {\n for (const listener of listeners) {\n try {\n listener(payload);\n } catch (err) {\n this.#logger.error('system_events.listener.failed', { event: String(event), error: err });\n }\n }\n }\n}\n","import type { ClientID, ClientInfo } from '../../types';\nimport type { ClientRegistry } from '../../client/ClientRegistry';\nimport type { Subscriptions } from '../../routing/Subscriptions';\nimport type { Bridge } from '../../bridge/Bridge.types';\nimport type { MessageHistory } from '../../history/MessageHistory';\nimport type { HistoryEntry, HistoryStats } from '../../history/MessageHistory.types';\nimport type { BridgeInfo } from './Inspector.types';\n\n/**\n * Inspector - read-only view over broker state.\n *\n * Exposed via `broker.inspect`. Intended for DevTools, debugging tools, and\n * diagnostic integrations that need point-in-time state snapshots (pull model).\n * Pair with `broker.$systemEvents` (push model) for incremental updates.\n *\n * This class is a pure facade over internal registries — it does NOT own data,\n * it only aggregates and projects it. Dependencies are injected as references,\n * so adding new snapshot methods does not require changing the constructor\n * shape or threading callbacks through `BrokerCore`.\n *\n * All collection-returning methods return `ReadonlyArray<T>` to prevent\n * accidental mutation of broker state by external callers.\n */\nexport class Inspector<T extends string, P extends Record<T, any>> {\n #clients: ClientRegistry<T, P>;\n #subscriptions: Subscriptions<T>;\n #bridges: ReadonlyMap<string, Bridge>;\n #getHistory: () => MessageHistory<T, P> | undefined;\n\n constructor(\n clients: ClientRegistry<T, P>,\n subscriptions: Subscriptions<T>,\n bridges: ReadonlyMap<string, Bridge>,\n getHistory: () => MessageHistory<T, P> | undefined,\n ) {\n this.#clients = clients;\n this.#subscriptions = subscriptions;\n this.#bridges = bridges;\n this.#getHistory = getHistory;\n }\n\n /**\n * Snapshot of every registered client together with its active subscriptions.\n *\n * Use together with `$systemEvents.on('client.*' | 'subscription.*')` to\n * build an accurate initial state without race conditions: read the snapshot\n * first, then subscribe to events for incremental updates.\n */\n getClients(): ReadonlyArray<ClientInfo> {\n return this.#clients.getAllIds().map((id) => ({\n id,\n connectedAt: this.#clients.getConnectedAt(id) ?? Date.now(),\n subscriptions: Array.from(this.#subscriptions.getClientTopics(id) ?? []).map((topic) => ({\n topic,\n // A pair may hold N handlers with different options — the Inspector\n // surface predates the multi-handler model and exposes a single\n // options blob. First handler wins; drill into `getEntries()` for\n // full detail.\n options: this.#subscriptions.getFirstOptions(id, topic as T),\n handlerCount: this.#subscriptions.getHandlerCount(id, topic as T),\n })),\n }));\n }\n\n /**\n * IDs of clients that have at least one active subscription.\n */\n getSubscribedClientIds(): ReadonlyArray<ClientID> {\n return this.#subscriptions.getAllSubscribedClients();\n }\n\n /**\n * Lifecycle info for every registered bridge. Does NOT expose internal\n * `Bridge` instances (see `BridgeInfo`).\n */\n getBridges(): ReadonlyArray<BridgeInfo> {\n const result: BridgeInfo[] = [];\n for (const [id, bridge] of this.#bridges) {\n result.push({\n id,\n forwardPatterns: bridge.forwardPatterns,\n transportKind: bridge.transportKind,\n });\n }\n return result;\n }\n\n /**\n * All messages currently stored in the replay buffer (oldest → newest).\n * Returns an empty array when history is not enabled.\n */\n getHistory(): ReadonlyArray<HistoryEntry> {\n const history = this.#getHistory();\n if (!history) return [];\n return history.getSnapshot();\n }\n\n /**\n * Replay buffer statistics. Always returns `{ enabled: false, count: 0 }`\n * when history is not enabled.\n */\n getHistoryStats(): HistoryStats & { enabled: boolean } {\n const history = this.#getHistory();\n if (!history) return { count: 0, enabled: false };\n return { ...history.getStats(), enabled: true };\n }\n}\n","/**\n * All structured log events emitted by the broker infrastructure.\n *\n * These are machine-readable codes — stable across versions.\n * Use them as filter keys in Sentry / Datadog / Grafana.\n */\nexport type BrokerLogEvent =\n // Broker lifecycle\n | 'broker.subscribe.after_destroy'\n | 'broker.bridge.add.after_destroy'\n | 'broker.bridge.replaced'\n | 'broker.client.register.after_destroy'\n | 'broker.replay.history_disabled'\n | 'facade.createClient.reset'\n // Message routing\n | 'handler.failed'\n // Hooks\n | 'hook.after_send.failed'\n | 'hook.failed'\n // Bridge\n | 'bridge.message.parse_failed'\n // Backpressure\n | 'backpressure.handler.failed'\n | 'backpressure.on_drop.failed'\n // Replay\n | 'replay.handler.failed'\n | 'replay.query.failed'\n // System events\n | 'system_events.listener.failed';\n\n/**\n * Pluggable logger interface for broker infrastructure events.\n *\n * Implement this to redirect broker warnings and errors to your\n * observability stack (Sentry, Datadog, pino, etc.).\n *\n * @example\n * initBroker({\n * logger: {\n * warn: (event, meta) => myLogger.warn(event, meta),\n * error: (event, meta) => Sentry.captureMessage(event, { extra: meta }),\n * }\n * });\n */\nexport interface BrokerLogger {\n warn(event: BrokerLogEvent, meta?: Record<string, unknown>): void;\n error(event: BrokerLogEvent, meta?: Record<string, unknown>): void;\n}\n\n/**\n * Default logger — forwards to console.\n * Used when no logger is provided in BrokerConfig.\n */\nexport const defaultLogger: BrokerLogger = {\n warn(event, meta) {\n meta !== undefined\n ? console.warn(`[broker] ${event}`, meta)\n : console.warn(`[broker] ${event}`);\n },\n error(event, meta) {\n meta !== undefined\n ? console.error(`[broker] ${event}`, meta)\n : console.error(`[broker] ${event}`);\n },\n};\n","import { Bridge as BridgeImpl } from './bridge/Bridge';\nimport { RoutingResult, RoutingReason } from './routing/RoutingResult';\nimport { Router } from './routing/Router';\nimport { HooksRegistry } from './hooks/HooksRegistry';\nimport { ClientRegistry } from './client/ClientRegistry';\nimport { Subscriptions } from './routing/Subscriptions';\nimport { BackpressureHandler } from './backpressure/BackpressureHandler';\nimport { MessageHistory } from './history/MessageHistory';\nimport { SubscriptionReplay } from './history/SubscriptionReplay';\nimport { SystemEvents } from './events/SystemEvents';\nimport { Inspector } from './observability/inspect/Inspector';\nimport { deepFreeze } from './utils/deepFreeze';\nimport { defaultLogger } from './logger/BrokerLogger.types';\n\nimport type {\n Message,\n ClientID,\n MessageHandler,\n SubscriptionOptions,\n BrokerConfig,\n MessageOptions,\n} from './types';\nimport type { BrokerLogger } from './logger/BrokerLogger.types';\nimport type { BrokerClient } from './client/BrokerClient';\nimport type { OnSubscribeHook, BeforeSendHook, AfterSendHook } from './hooks/HooksRegistry.types';\nimport type { Bridge, BridgeConfig, ExternalMessageInjector } from './bridge/Bridge.types';\nimport type { SystemEventsEmitter } from './events/SystemEvents.types';\nimport type { MessageBroker } from './MessageBroker';\n\n/**\n * BrokerCore — low-level message broker engine, internal implementation\n * of the public {@link MessageBroker} interface.\n *\n * Responsibilities:\n * - Message routing and delivery pipeline (hooks → routing → history → bridges)\n * - Subscription management (delegates to Subscriptions)\n * - Coordinate Router, HooksRegistry, ClientRegistry\n * - Bridge management for cross-context communication\n * - Message history & replay\n * - Emit system events on the internal system events channel\n * - Expose state snapshots via the inspect facade\n * - Lifecycle management\n *\n * The class is exported within the package for unit tests. Consumers\n * receive only the `MessageBroker<T, P>` contract from `initBroker()` /\n * `getBroker()`. Methods tagged `@internal` (subscribe, unsubscribe,\n * processMessage, registerClient, unregisterClient, resetClient,\n * getClient) form the internal protocol between\n * BrokerClient, Bridge and the facade — they are stable only inside the\n * package and may change without notice.\n */\nexport class BrokerCore<T extends string, P extends Record<T, any>>\n implements MessageBroker<T, P>\n{\n #isDestroyed = false;\n #sessionId = crypto.randomUUID();\n #eventCounter = 0;\n #subscriptions = new Subscriptions<T>();\n #router: Router<T, P>;\n #hooks: HooksRegistry<T, P>;\n #clientRegistry = new ClientRegistry<T, P>();\n #systemEvents: SystemEvents<T, P>;\n #backpressure: BackpressureHandler;\n #history?: MessageHistory<T, P>;\n #replay?: SubscriptionReplay<T, P>;\n #bridges = new Map<string, Bridge>();\n #inspect: Inspector<T, P>;\n\n /**\n * Infrastructure logger configured via {@link BrokerConfig.logger}.\n *\n * @internal Used by the facade layer.\n */\n readonly logger: BrokerLogger;\n\n constructor(config?: BrokerConfig) {\n this.logger = config?.logger ?? defaultLogger;\n\n this.#hooks = new HooksRegistry(this.logger);\n this.#systemEvents = new SystemEvents(this.logger);\n this.#backpressure = new BackpressureHandler(this.logger);\n this.#router = new Router(this.#subscriptions, this.logger);\n\n if (config?.history?.enabled) {\n this.#history = new MessageHistory(config.history);\n this.#replay = new SubscriptionReplay(this.#history, this.#hooks, this.logger);\n }\n\n // Inspector is a read-only facade over internal state: it receives references,\n // not callbacks, so future snapshot methods can be added without changing wiring.\n this.#inspect = new Inspector(\n this.#clientRegistry,\n this.#subscriptions,\n this.#bridges,\n () => this.#history,\n );\n }\n\n // ========================================\n // SYSTEM EVENTS & INSPECT\n // ========================================\n\n /**\n * Broker-internal system event channel (push model).\n *\n * The `$` prefix marks this as a broker-internal API. Intended for tooling:\n * DevTools, tracing collectors, metrics integrations.\n *\n * This is NOT for extending broker behaviour — extension hooks are exposed\n * via `useBeforeSendHook`, `useAfterSendHook`, `useOnSubscribeHook`.\n *\n * @example\n * broker.$systemEvents.on('client.registered', ({ clientId }) => { ... });\n * broker.$systemEvents.on('subscription.added', ({ clientId, topic }) => { ... });\n */\n get $systemEvents(): SystemEventsEmitter<T, P> {\n return this.#systemEvents;\n }\n\n /**\n * Point-in-time state snapshots (pull model).\n *\n * Read-only view over broker state for DevTools and debugging tools.\n *\n * @example\n * const clients = broker.inspect.getClients();\n * const history = broker.inspect.getHistory();\n */\n get inspect(): Inspector<T, P> {\n return this.#inspect;\n }\n\n // ========================================\n // SUBSCRIPTION MANAGEMENT\n // ========================================\n\n /**\n * Subscribe a client to a topic.\n *\n * Multiple handlers may be attached to the same `(clientId, topic)` pair —\n * each call returns a distinct subscription id that identifies THIS\n * handler for later removal via {@link unsubscribeOne}.\n *\n * @returns Subscription id, or `0` when the call was a no-op (broker\n * destroyed). Zero is never a valid id.\n *\n * @throws Error if subscription is blocked on onSubscribe hook\n *\n * @internal Called by {@link BrokerClient.on}. Not part of the public\n * `MessageBroker` contract.\n */\n subscribe(\n clientId: ClientID,\n topic: T,\n handler: MessageHandler,\n options?: SubscriptionOptions,\n ): number {\n if (this.#isDestroyed) {\n this.logger.warn('broker.subscribe.after_destroy', { clientId, topic });\n return 0;\n }\n\n const hookResult = this.#hooks.onSubscribe(topic, clientId);\n if (!hookResult.allowed) {\n // Surface the denial on the system-events channel so observability\n // tools (DevTools, audit loggers) see it. Then throw — throwing keeps\n // the failure locally observable at the call site as well.\n this.#systemEvents.emit('subscription.rejected', {\n clientId,\n topic,\n reason: hookResult.message,\n });\n throw new Error(hookResult.message);\n }\n\n // Reserve id first so backpressure keys its strategy by the same value\n // we hand back to the caller.\n const subscriptionId = this.#subscriptions.reserveId();\n const wrappedHandler = this.#backpressure.wrap(\n subscriptionId,\n clientId,\n topic,\n handler,\n options,\n );\n\n this.#subscriptions.subscribe(clientId, topic, wrappedHandler, options, subscriptionId);\n this.#systemEvents.emit('subscription.added', { clientId, topic, options });\n\n if (options?.replay) {\n if (!this.#replay) {\n this.logger.warn('broker.replay.history_disabled', { clientId, topic });\n } else {\n this.#replay.start(clientId, topic, wrappedHandler, options.replay);\n }\n }\n return subscriptionId;\n }\n\n /**\n * Unsubscribe a client from a topic — removes every handler this client\n * has attached to the topic.\n *\n * @internal Called by {@link BrokerClient.off}. Not part of the public\n * `MessageBroker` contract.\n */\n unsubscribe(clientId: ClientID, topic: T): void {\n const removed = this.#subscriptions.unsubscribe(clientId, topic);\n if (removed.length === 0) return;\n\n for (const entry of removed) {\n this.#backpressure.removeOne(entry.id);\n }\n this.#systemEvents.emit('subscription.removed', { clientId, topic });\n }\n\n /**\n * Unsubscribe a single handler by its subscription id.\n *\n * Fires `subscription.removed` only if this was the last handler that\n * client had on the topic — otherwise the client is still subscribed.\n *\n * @internal Called by the unsubscribe closure returned from {@link BrokerClient.on}.\n */\n unsubscribeOne(subscriptionId: number): void {\n if (subscriptionId === 0) return;\n const outcome = this.#subscriptions.unsubscribeOne(subscriptionId);\n if (!outcome) return;\n\n this.#backpressure.removeOne(outcome.entry.id);\n\n // Only surface subscription.removed when the pair is fully drained —\n // otherwise the client is still subscribed via other handlers.\n if (outcome.wasLast) {\n this.#systemEvents.emit('subscription.removed', {\n clientId: outcome.clientId,\n topic: outcome.topic,\n });\n }\n }\n\n // ========================================\n // MESSAGE DELIVERY\n // ========================================\n\n /**\n * Process a message originating from a local client.\n *\n * Runs the full lifecycle pipeline: beforeSend → history → routing →\n * afterSend → forward to bridges.\n *\n * @param topic - Type of message\n * @param sender - Client ID of sender\n * @param recipient - Target recipient: specific ClientID (unicast) or '*' (multicast)\n * @param data - Message payload\n * @param options - Message options (history)\n * @returns Promise resolving to RoutingResult with delivery status\n *\n * @internal Called by {@link BrokerClient.emit} / {@link BrokerClient.request}.\n * Not part of the public `MessageBroker` contract.\n */\n async processMessage<K extends T, R = unknown>(\n topic: K,\n sender: ClientID,\n recipient: ClientID | '*',\n data: P[K],\n options?: MessageOptions,\n ): Promise<RoutingResult<R>> {\n return this.#runPipeline<K, R>(topic, sender, recipient, data, options, false, false);\n }\n\n /**\n * Broker-internal debug channel.\n *\n * `send()` runs the full message pipeline exactly like a normal\n * `Client.emit()` / `Client.request()` — routing, hooks, history and\n * bridge forwarding all apply — but with two differences:\n *\n * 1. `source` is an arbitrary string, not tied to a registered client.\n * Nothing gets reset in the client registry: safe to «impersonate»\n * any client id for testing subscribers without breaking that\n * client's own subscriptions.\n * 2. `message.synthetic === true` on the resulting Message, so\n * DevTools and integration tests can distinguish spoofed traffic\n * from production events (e.g. render a `SYNTHETIC` badge).\n *\n * Multicast vs unicast is picked by `target`: `'*'` fans out to all\n * subscribers, a specific `ClientID` targets one recipient and captures\n * that handler's return value in `RoutingResult.data`.\n *\n * The `$` prefix marks this as a broker-internal API — for DevTools\n * and integration tests, not for business code.\n */\n get $debug(): {\n send<K extends T, R = unknown>(\n source: ClientID,\n topic: K,\n target: ClientID | '*',\n data: P[K],\n options?: MessageOptions,\n ): Promise<RoutingResult<R>>;\n } {\n return {\n send: <K extends T, R = unknown>(\n source: ClientID,\n topic: K,\n target: ClientID | '*',\n data: P[K],\n options?: MessageOptions,\n ): Promise<RoutingResult<R>> => {\n return this.#runPipeline<K, R>(topic, source, target, data, options, false, true);\n },\n };\n }\n\n /**\n * Shared pipeline body for local {@link processMessage} and external\n * inject wired in {@link addBridge}.\n *\n * Pipeline stages:\n * 1. Create Message (assign id, timestamp) and deep-freeze it.\n * 2. Run `beforeSend` hooks. If any hook denies, short-circuit with\n * NACK(HOOK_REJECTED) — still fire `afterSend` so observers see the\n * rejection.\n * 3. Record to history — ONLY for local-origin messages that explicitly\n * opt in via `options.history`. External (injected) messages are\n * skipped: the sender-side broker has already recorded them; recording\n * again here would duplicate on every bridge hop.\n * 4. Route: unicast → one recipient, multicast (`*`) → all subscribers.\n * 5. Run `afterSend` hooks with the delivery result.\n * 6. Forward to bridges — ONLY for local-origin messages. External\n * messages are never bounced back to bridges; otherwise a bridge would\n * send what it just received right back to its transport.\n *\n * `fromExternal` gates stages 3 and 6 — the two places where local and\n * external paths diverge. `synthetic` is metadata-only: routing, hooks,\n * history and bridge forwarding all treat the message as real. Both\n * flags are internal — never on the public API.\n */\n async #runPipeline<K extends T, R = unknown>(\n topic: K,\n sender: ClientID,\n recipient: ClientID | '*',\n data: P[K],\n options: MessageOptions | undefined,\n fromExternal: boolean,\n synthetic: boolean,\n ): Promise<RoutingResult<R>> {\n if (this.#isDestroyed) {\n return RoutingResult.create<R>('NACK', RoutingReason.BROKER_DESTROYED, 'Broker is destroyed');\n }\n\n // Stage 1: Create Message and freeze once\n const message = this.#createMessage(topic, sender, recipient, data);\n\n if (fromExternal) {\n message.fromExternal = true;\n }\n if (synthetic) {\n message.synthetic = true;\n }\n\n const frozenMessage = deepFreeze(message);\n\n // Stage 2: beforeSend hooks (guard)\n const hookResult = this.#hooks.beforeSend(frozenMessage);\n if (!hookResult.allowed) {\n const result = RoutingResult.create<R>(\n 'NACK',\n RoutingReason.HOOK_REJECTED,\n hookResult.message,\n recipient !== '*' ? recipient : undefined,\n );\n // Publish the denial to system events too — same rationale as\n // `subscription.rejected`: give observers a dedicated stream of\n // security signals independent from the delivery-result channel.\n this.#systemEvents.emit('message.rejected', {\n source: sender,\n target: recipient,\n topic,\n reason: hookResult.message,\n });\n this.#hooks.afterSend(frozenMessage, result);\n return result;\n }\n\n // Stage 3: Record to history (only if explicitly requested and not from external)\n if (this.#history && !fromExternal && options?.history === true) {\n this.#history.record(frozenMessage);\n }\n\n // Multicast never carries response data; the cast widens its phantom R\n // so both branches share the Promise<RoutingResult<R>> return type.\n const result: RoutingResult<R> =\n recipient === '*'\n ? ((await this.#router.multicast(frozenMessage, sender)) as RoutingResult<R>)\n : await this.#router.unicast<K, R>(frozenMessage, recipient);\n\n // Stage 5: afterSend hooks\n this.#hooks.afterSend(frozenMessage, result);\n\n // Stage 6: Forward to bridges (only if not from external source)\n if (!fromExternal) {\n this.#forwardToBridges(frozenMessage);\n }\n\n return result;\n }\n\n // ========================================\n // BRIDGE MANAGEMENT\n // ========================================\n\n /**\n * Add a bridge for cross-context communication (idempotent)\n *\n * If a bridge with the given ID already exists, the old bridge is destroyed\n * and replaced with the new one. This prevents duplicate bridges during HMR.\n *\n * @param id - Unique identifier for the bridge (e.g. 'cross-tab', 'iframe-checkout')\n * @param config - Bridge configuration (transport + forward patterns)\n * @returns Function to remove the bridge\n */\n addBridge(id: string, config: BridgeConfig): () => void {\n if (this.#isDestroyed) {\n this.logger.warn('broker.bridge.add.after_destroy', { bridgeId: id });\n return () => {};\n }\n\n const existing = this.#bridges.get(id);\n\n if (existing) {\n this.logger.warn('broker.bridge.replaced', { bridgeId: id });\n existing.destroy();\n this.#systemEvents.emit('bridge.removed', { bridgeId: id });\n }\n\n const inject: ExternalMessageInjector<T, P> = (topic, sender, recipient, data) =>\n this.#runPipeline(topic, sender, recipient, data, undefined, true, false);\n\n const bridge = new BridgeImpl<T, P>(inject, config, this.logger);\n this.#bridges.set(id, bridge);\n this.#systemEvents.emit('bridge.added', { bridgeId: id });\n\n return () => {\n if (this.#bridges.get(id) === bridge) {\n this.#bridges.delete(id);\n bridge.destroy();\n this.#systemEvents.emit('bridge.removed', { bridgeId: id });\n }\n };\n }\n\n // ========================================\n // CLIENT REGISTRY\n // ========================================\n\n /**\n * Register a client instance.\n *\n * @internal Called by the `BrokerClient` constructor.\n */\n registerClient(client: BrokerClient<T, P>): void {\n if (this.#isDestroyed) {\n this.logger.warn('broker.client.register.after_destroy', { clientId: client.id });\n return;\n }\n this.#clientRegistry.register(client);\n this.#systemEvents.emit('client.registered', {\n clientId: client.id,\n at: this.#clientRegistry.getConnectedAt(client.id) ?? Date.now(),\n });\n }\n\n /**\n * Unregister a client and remove all its subscriptions.\n *\n * @internal Called by {@link BrokerClient.destroy}.\n */\n unregisterClient(clientId: ClientID): void {\n const removed = this.#subscriptions.unsubscribeAll(clientId);\n this.#clientRegistry.unregister(clientId);\n\n for (const bucket of removed) {\n for (const entry of bucket.entries) {\n this.#backpressure.removeOne(entry.id);\n }\n this.#systemEvents.emit('subscription.removed', { clientId, topic: bucket.topic });\n }\n this.#systemEvents.emit('client.unregistered', { clientId, at: Date.now() });\n }\n\n /**\n * Get a registered client by ID.\n *\n * @param clientId - Unique client identifier\n * @returns Client instance or undefined if not found\n *\n * @internal Used by the `createClient` facade for idempotency checks.\n */\n getClient(clientId: ClientID): BrokerClient<T, P> | undefined {\n return this.#clientRegistry.get(clientId);\n }\n\n /**\n * Reset a client: clear all its subscriptions and backpressure strategies\n * while keeping the client registered.\n *\n * Used for idempotent client creation (HMR, re-mounting).\n * Iterates the client's subscriptions and calls unsubscribe() for each,\n * which correctly flushes/destroys backpressure strategies.\n *\n * @param clientId - Unique client identifier\n *\n * @internal Called by {@link BrokerClient.reset} and by the\n * `createClient` facade on idempotent re-creation.\n */\n resetClient(clientId: ClientID): void {\n const topics = this.#subscriptions.getClientTopics(clientId);\n if (topics) {\n for (const topic of [...topics]) {\n this.unsubscribe(clientId, topic);\n }\n }\n }\n\n // ========================================\n // HOOKS & EXTENSIBILITY\n // ========================================\n\n /**\n * Register a beforeSend hook\n *\n * Called before routing for ALL messages, including those from bridges.\n * Use message.fromExternal to distinguish local vs external if needed.\n */\n useBeforeSendHook(hook: BeforeSendHook<T, P>): () => void {\n return this.#hooks.addBeforeSendHook(hook);\n }\n\n /**\n * Register an afterSend hook\n * Note: afterSend hooks are called for ALL messages (check message.fromExternal if needed)\n */\n useAfterSendHook(hook: AfterSendHook<T, P>): () => void {\n return this.#hooks.addAfterSendHook(hook);\n }\n\n /**\n * Register an onSubscribe hook\n */\n useOnSubscribeHook(hook: OnSubscribeHook<T>): () => void {\n return this.#hooks.addOnSubscribeHook(hook);\n }\n\n // ========================================\n // PRIVATE METHODS\n // ========================================\n\n /**\n * Forward message to all bridges that match the topic\n * @private\n */\n #forwardToBridges(message: Message<T, P[T]>): void {\n for (const bridge of this.#bridges.values()) {\n if (bridge.shouldForward(message.topic)) {\n bridge.send(message);\n }\n }\n }\n\n /**\n * Create a message with all required fields\n *\n * @private\n */\n #createMessage<K extends T>(\n topic: K,\n sender: ClientID,\n recipient: ClientID | '*',\n data: P[K],\n ): Message<K, P[K]> {\n return {\n id: `${this.#sessionId}-${++this.#eventCounter}`,\n topic: topic,\n source: sender,\n target: recipient,\n data,\n timestamp: Date.now(),\n };\n }\n\n // ========================================\n // LIFECYCLE & CLEANUP\n // ========================================\n\n /**\n * Destroy the broker and clean up all resources\n */\n destroy(): void {\n if (this.#isDestroyed) {\n return;\n }\n this.#isDestroyed = true;\n\n for (const bridge of this.#bridges.values()) {\n bridge.destroy();\n }\n this.#bridges.clear();\n\n this.#hooks.clear();\n this.#history?.destroy();\n // Release per-handler backpressure strategies via the cleared entries,\n // then run destroy() as a belt-and-suspenders sweep for anything that\n // somehow escaped bookkeeping.\n const cleared = this.#subscriptions.clear();\n for (const entry of cleared) {\n this.#backpressure.removeOne(entry.id);\n }\n this.#backpressure.destroy();\n this.#clientRegistry.clear();\n this.#systemEvents.clear();\n }\n}\n","import type { BrokerCore } from '../BrokerCore';\nimport type { ClientID, HandlerFn, MessageHandler, SubscriptionOptions, MessageOptions } from '../types';\nimport type { RoutingResult } from '../routing/RoutingResult';\nimport type { Client } from './Client.types';\n\n/**\n * BrokerClient — concrete implementation of the {@link Client} contract.\n *\n * Created by the facade function `createClient(id)`. Use cases:\n * - Communication between microfrontends in the same browser context\n * - Fastest possible message delivery (no serialization)\n * - Default choice for most applications\n *\n * Consumers should treat `Client<T, P>` as the stable surface — this\n * class is an internal implementation detail. It is exported within the\n * package so unit tests can construct instances directly with a\n * `BrokerCore` stub, but it is NOT part of the public API: transport of\n * `BrokerClient` through the package exports map is disabled.\n */\nexport class BrokerClient<T extends string, P extends Record<T, any>>\n implements Client<T, P>\n{\n readonly id: ClientID;\n #core: BrokerCore<T, P>;\n\n constructor(id: ClientID, core: BrokerCore<T, P>) {\n this.id = id;\n this.#core = core;\n this.#core.registerClient(this);\n }\n\n /**\n * Subscribe to a topic with handler\n *\n * @param topic - Topic to subscribe to (e.g. 'user.login.v1')\n * @param handler - Message handler function\n * @param options - Subscription options (backpressure, replay)\n * @returns Unsubscribe function\n */\n on<K extends T>(\n topic: K,\n handler: HandlerFn<K, P[K]>,\n options?: SubscriptionOptions,\n ): () => void {\n if (!handler) {\n throw new Error('BrokerClient requires explicit handler function');\n }\n\n const subscriptionId = this.#core.subscribe(\n this.id,\n topic,\n handler as MessageHandler,\n options,\n );\n\n return () => {\n this.#core.unsubscribeOne(subscriptionId);\n };\n }\n\n /**\n * Emit message to all subscribers (multicast)\n */\n async emit<K extends T>(topic: K, data: P[K], options?: MessageOptions): Promise<RoutingResult> {\n return this.#core.processMessage(topic, this.id, '*', data, options);\n }\n\n /**\n * Send request to specific client (unicast).\n *\n * The recipient's handler return value (if any) is captured in\n * `RoutingResult.data`. Caller specifies `R` to type that payload.\n * The broker does not enforce that the handler actually returns `R` —\n * the cast happens at the boundary, same trust level as `as R`.\n */\n async request<K extends T, R = unknown>(\n recipient: ClientID,\n topic: K,\n data: P[K],\n options?: MessageOptions,\n ): Promise<RoutingResult<R>> {\n return this.#core.processMessage<K, R>(topic, this.id, recipient, data, options);\n }\n\n /**\n * Unsubscribe from a topic\n */\n off<K extends T>(topic: K): void {\n this.#core.unsubscribe(this.id, topic);\n }\n\n /**\n * Reset client: clear all subscriptions and backpressure strategies\n * while keeping the client registered in the broker.\n *\n * After reset, the client can subscribe to messages again with fresh handlers.\n * Existing backpressure strategies are flushed and destroyed.\n */\n reset(): void {\n this.#core.resetClient(this.id);\n }\n\n /**\n * Destroy client and cleanup resources\n */\n destroy(): void {\n this.#core.unregisterClient(this.id);\n }\n}\n","import { BrokerCore } from './core/BrokerCore';\nimport { BrokerClient } from './core/client/BrokerClient';\nimport type { BrokerConfig } from './core/types';\nimport type { MessageBroker } from './core/MessageBroker';\nimport type { Client } from './core/client/Client.types';\n\nlet core: BrokerCore<any, any> | null = null;\n\n/**\n * Initialize the message broker (idempotent).\n *\n * Called once by the host application (e.g. the shell / app bootstrap).\n * If the broker is already initialized, the existing instance is returned\n * without changes. To reinitialize, call {@link destroyBroker} first.\n *\n * @param config - Broker configuration (history, etc.).\n * @returns The broker instance typed against the caller's Topics/Payloads.\n */\nexport function initBroker<\n T extends string = string,\n P extends Record<T, any> = any,\n>(config?: BrokerConfig): MessageBroker<T, P> {\n if (core) {\n return core as MessageBroker<T, P>;\n }\n\n core = new BrokerCore<T, P>(config);\n return core as MessageBroker<T, P>;\n}\n\n/**\n * Create or retrieve a client for message communication (idempotent).\n *\n * If a client with the given ID already exists, its subscriptions and\n * backpressure strategies are reset and the existing instance is returned.\n * Safe for HMR and component re-mounting scenarios.\n *\n * Pass explicit type parameters to get a fully typed client without a cast:\n *\n * @example\n * import type { Topic, TopicPayloads } from '@hedwigjs/registry';\n * const client = createClient<Topic, TopicPayloads>('cart');\n *\n * @param id - Unique identifier for the client.\n * @throws Error if the broker has not been initialized.\n */\nexport function createClient<\n T extends string = string,\n P extends Record<T, any> = any,\n>(id: string): Client<T, P> {\n if (!core) {\n throw new Error(\n 'MessageBroker not initialized. Call initBroker(config) first.',\n );\n }\n\n const existing = core.getClient(id);\n\n if (existing) {\n core.logger.warn('facade.createClient.reset', { clientId: id });\n core.resetClient(id);\n return existing as Client<T, P>;\n }\n return new BrokerClient<T, P>(id, core as BrokerCore<T, P>);\n}\n\n/**\n * Get the current broker instance.\n *\n * Use when you need access to broker methods (hooks, `$systemEvents`,\n * `inspect`, `addBridge`) without holding the reference returned by\n * {@link initBroker}.\n *\n * Types can be passed explicitly: `getBroker<MyTopics, MyPayloads>()`.\n *\n * @throws Error if the broker has not been initialized.\n */\nexport function getBroker<\n T extends string = string,\n P extends Record<T, any> = any,\n>(): MessageBroker<T, P> {\n if (!core) {\n throw new Error(\n 'MessageBroker not initialized. Call initBroker(config) first.',\n );\n }\n return core as MessageBroker<T, P>;\n}\n\n/**\n * Destroy the broker and release all resources.\n *\n * Destroys bridges, clears subscriptions, history, and the client registry.\n */\nexport function destroyBroker(): void {\n core?.destroy();\n core = null;\n}\n","import type { BridgeTransport } from '../core/bridge/Bridge.types';\n\n/**\n * Configuration for PostMessageTransport\n */\nexport interface PostMessageTransportConfig {\n /** Target window to communicate with (iframe.contentWindow, window.parent, etc.) */\n target: Window;\n\n /**\n * Target origin for outbound `postMessage` calls.\n * Use `'*'` only for trusted contexts — the browser will otherwise refuse\n * to deliver the message if the target's origin doesn't match.\n * @default '*'\n */\n origin?: string;\n\n /**\n * Explicit allowlist for **inbound** message origins.\n *\n * When set, only messages whose `e.origin` is included in this list are\n * forwarded to the broker; others are dropped with a `console.warn`. This\n * is the trust boundary between the broker and cross-origin iframes.\n *\n * When omitted, inbound validation falls back to `origin`:\n * - If `origin` is an explicit URL, it acts as a single-item allowlist.\n * - If `origin` is `'*'`, all origins are accepted (a `console.warn` is\n * emitted at construction time — this mode is intended only for\n * trusted contexts and should not be used in production against\n * untrusted iframes).\n *\n * Prefer setting `allowedOrigins` explicitly for cross-origin scenarios.\n */\n allowedOrigins?: string[];\n}\n\n/**\n * PostMessageTransport - Transport for cross-window communication\n *\n * Uses `window.postMessage` for iframe/popup communication.\n *\n * Security:\n * - Validates message source window (must match configured `target`).\n * - Validates message origin against `allowedOrigins` (explicit allowlist)\n * or `origin` (fallback single-item allowlist).\n */\nexport class PostMessageTransport implements BridgeTransport {\n #target: Window;\n #origin: string;\n #allowedOrigins: readonly string[] | null;\n #wildcardWarned = false;\n #messageHandler: ((e: MessageEvent) => void) | null = null;\n #messageCallback: ((data: unknown) => void) | null = null;\n\n constructor(config: PostMessageTransportConfig) {\n this.#target = config.target;\n this.#origin = config.origin ?? '*';\n\n if (config.allowedOrigins !== undefined) {\n this.#allowedOrigins = [...config.allowedOrigins];\n } else if (this.#origin !== '*') {\n // Backward compatible: use `origin` as an implicit single-item allowlist.\n this.#allowedOrigins = [this.#origin];\n } else {\n // Wildcard mode: accept any origin (source-window check still applies).\n // Warning is deferred until the first `onMessage` call — send-only usage\n // is not an inbound vector and does not need a security warning.\n this.#allowedOrigins = null;\n }\n }\n\n /**\n * Send data to target window via postMessage\n */\n send(data: unknown): void {\n try {\n this.#target.postMessage(data, this.#origin);\n } catch (error) {\n console.error('[PostMessageTransport] Failed to send:', error);\n }\n }\n\n /**\n * Subscribe to incoming messages from target window\n */\n onMessage(callback: (data: unknown) => void): () => void {\n this.#messageCallback = callback;\n\n if (this.#allowedOrigins === null && !this.#wildcardWarned) {\n this.#wildcardWarned = true;\n console.warn(\n \"[PostMessageTransport] Listening with wildcard origin ('*') and \" +\n 'no allowedOrigins — inbound messages from ANY origin will be ' +\n 'accepted (source-window check still applies). Set `allowedOrigins` ' +\n 'explicitly for cross-origin scenarios.',\n );\n }\n\n this.#messageHandler = (e: MessageEvent) => {\n // Only process messages from our target window\n if (e.source !== this.#target) {\n return;\n }\n\n // Validate origin against the allowlist (if any).\n if (this.#allowedOrigins !== null && !this.#allowedOrigins.includes(e.origin)) {\n console.warn(\n `[PostMessageTransport] Message from unauthorized origin: ${e.origin} ` +\n `(allowed: ${this.#allowedOrigins.join(', ')})`,\n );\n return;\n }\n\n this.#messageCallback?.(e.data);\n };\n\n window.addEventListener('message', this.#messageHandler);\n\n return () => this.destroy();\n }\n\n /**\n * Cleanup: remove event listener\n */\n destroy(): void {\n if (this.#messageHandler) {\n window.removeEventListener('message', this.#messageHandler);\n this.#messageHandler = null;\n }\n this.#messageCallback = null;\n }\n}\n","import type { BridgeTransport } from '../core/bridge/Bridge.types';\n\n/**\n * BroadcastChannelTransport - Transport for cross-tab communication\n *\n * Uses BroadcastChannel API for communication between browser tabs\n * of the same origin.\n *\n * Use cases:\n * - Sync user session across tabs\n * - Sync theme/locale preferences\n * - Broadcast notifications to all tabs\n */\nexport class BroadcastChannelTransport implements BridgeTransport {\n #channel: BroadcastChannel;\n #messageCallback: ((data: unknown) => void) | null = null;\n\n /**\n * @param channelName - Unique channel name for this application\n */\n constructor(channelName: string) {\n this.#channel = new BroadcastChannel(channelName);\n }\n\n /**\n * Broadcast data to all other tabs\n */\n send(data: unknown): void {\n try {\n this.#channel.postMessage(data);\n } catch (error) {\n console.error('[BroadcastChannelTransport] Failed to send:', error);\n }\n }\n\n /**\n * Subscribe to messages from other tabs\n */\n onMessage(callback: (data: unknown) => void): () => void {\n this.#messageCallback = callback;\n\n this.#channel.onmessage = (e: MessageEvent) => {\n this.#messageCallback?.(e.data);\n };\n\n return () => this.destroy();\n }\n\n /**\n * Cleanup: close the channel\n */\n destroy(): void {\n this.#channel.onmessage = null;\n this.#messageCallback = null;\n this.#channel.close();\n }\n}\n","import type { BridgeTransport } from '../core/bridge/Bridge.types';\n\n/**\n * WebSocketTransport - Transport wrapper for WebSocket\n *\n * Simple wrapper that forwards messages to/from an existing WebSocket.\n * All connection management (connect, reconnect, etc.) is handled externally.\n */\nexport class WebSocketTransport implements BridgeTransport {\n #socket: WebSocket;\n #messageCallback: ((data: unknown) => void) | null = null;\n #messageHandler: ((e: MessageEvent) => void) | null = null;\n\n /**\n * @param socket - WebSocket instance (managed externally)\n */\n constructor(socket: WebSocket) {\n this.#socket = socket;\n }\n\n /**\n * Send data to server via WebSocket\n */\n send(data: unknown): void {\n if (this.#socket.readyState !== WebSocket.OPEN) {\n console.warn('[WebSocketTransport] Cannot send: socket not open');\n return;\n }\n\n try {\n this.#socket.send(JSON.stringify(data));\n } catch (error) {\n console.error('[WebSocketTransport] Failed to send:', error);\n }\n }\n\n /**\n * Subscribe to messages from server\n */\n onMessage(callback: (data: unknown) => void): () => void {\n this.#messageCallback = callback;\n\n this.#messageHandler = (e: MessageEvent) => {\n try {\n const data = typeof e.data === 'string' ? JSON.parse(e.data) : e.data;\n this.#messageCallback?.(data);\n } catch (error) {\n console.error('[WebSocketTransport] Failed to parse message:', error);\n }\n };\n\n this.#socket.addEventListener('message', this.#messageHandler);\n\n return () => this.destroy();\n }\n\n /**\n * Cleanup: remove listener (does NOT close socket)\n */\n destroy(): void {\n if (this.#messageHandler) {\n this.#socket.removeEventListener('message', this.#messageHandler);\n this.#messageHandler = null;\n }\n this.#messageCallback = null;\n }\n}\n","import type { BridgeTransport } from '../core/bridge/Bridge.types';\n\n/**\n * Configuration for {@link SSETransport}.\n */\nexport interface SSETransportConfig {\n /**\n * URL of the Server-Sent Events endpoint. `EventSource` is created\n * internally and the browser handles reconnection.\n */\n url: string;\n\n /**\n * If set, subscribes to a named SSE event (`event: <name>`) instead of\n * the default unnamed `message` stream. Broker Messages already carry\n * their own `topic` field, so most integrations leave this unset and\n * multiplex on the topic.\n */\n eventName?: string;\n\n /**\n * Passed to `new EventSource(url, { withCredentials })`. Enables sending\n * cookies for same-origin auth on cross-origin SSE endpoints.\n */\n withCredentials?: boolean;\n}\n\n/**\n * SSETransport — inbound-only transport backed by `EventSource`.\n *\n * SSE is server → client by design. `send()` is a no-op with a warning;\n * bridges built on top of this transport are effectively receive-only.\n * If your integration needs client → server frames, use\n * {@link WebSocketTransport} or pair SSE with a separate POST endpoint.\n *\n * Reconnect handling is delegated to the browser's built-in EventSource\n * behavior — no external backoff required, unlike WebSocket where the\n * transport wraps an already-connected socket.\n *\n * Expects incoming payloads to be JSON-encoded broker Messages\n * (`{id, topic, source, target, data, timestamp}`) — the same wire\n * format all the other bridges use.\n */\nexport class SSETransport implements BridgeTransport {\n #eventSource: EventSource;\n #eventName: string;\n #messageHandler: ((e: MessageEvent) => void) | null = null;\n #messageCallback: ((data: unknown) => void) | null = null;\n\n constructor(config: SSETransportConfig) {\n this.#eventName = config.eventName ?? 'message';\n this.#eventSource = new EventSource(config.url, {\n withCredentials: config.withCredentials ?? false,\n });\n }\n\n /**\n * SSE has no upstream channel from the browser. This method exists to\n * satisfy the {@link BridgeTransport} contract but never actually\n * transmits — it logs a warning so misconfigurations surface early.\n *\n * Practical guidance: keep the bridge's `forward` list to topics that\n * are ONLY emitted by the server (never by local clients), so this\n * warning never fires in normal operation.\n */\n send(_data: unknown): void {\n console.warn(\n '[SSETransport] send() is a no-op — SSE is inbound-only. ' +\n 'Ensure the bridge forward list contains topics emitted only by ' +\n 'the server, or use WebSocketTransport for duplex traffic.',\n );\n }\n\n /**\n * Subscribe to incoming SSE messages. Parses JSON payloads before\n * forwarding to the bridge.\n */\n onMessage(callback: (data: unknown) => void): () => void {\n this.#messageCallback = callback;\n\n this.#messageHandler = (e: MessageEvent) => {\n try {\n const data = typeof e.data === 'string' ? JSON.parse(e.data) : e.data;\n this.#messageCallback?.(data);\n } catch (error) {\n console.error('[SSETransport] Failed to parse message:', error);\n }\n };\n\n this.#eventSource.addEventListener(this.#eventName, this.#messageHandler);\n\n return () => this.destroy();\n }\n\n /**\n * Cleanup: remove listener and close the underlying EventSource.\n */\n destroy(): void {\n if (this.#messageHandler) {\n this.#eventSource.removeEventListener(this.#eventName, this.#messageHandler);\n this.#messageHandler = null;\n }\n this.#messageCallback = null;\n this.#eventSource.close();\n }\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@hedwigjs/broker",
3
+ "version": "0.1.0",
4
+ "description": "Runtime broker for the Hedwig messaging toolkit. One API over any transport.",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "main": "./dist/index.cjs",
9
+ "module": "./dist/index.mjs",
10
+ "types": "./dist/index.d.ts",
11
+ "sideEffects": false,
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.mjs",
16
+ "require": "./dist/index.cjs",
17
+ "default": "./dist/index.mjs"
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/hedwigjs/hedwig.git",
25
+ "directory": "packages/broker"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/hedwigjs/hedwig/issues"
29
+ },
30
+ "homepage": "https://github.com/hedwigjs/hedwig/tree/main/packages/broker#readme",
31
+ "scripts": {
32
+ "build": "rm -rf dist && tsup",
33
+ "watch": "tsup --watch",
34
+ "test": "jest",
35
+ "test:watch": "jest --watch",
36
+ "test:coverage": "jest --coverage",
37
+ "format": "prettier --write \"src/**/*.{ts,tsx,json,md}\"",
38
+ "typecheck": "tsc --noEmit",
39
+ "bench": "node benchmarks/run-all.mjs",
40
+ "bench:one": "node benchmarks/run-one.mjs"
41
+ },
42
+ "devDependencies": {
43
+ "@types/jest": "^29.5.0",
44
+ "jest": "^29.5.0",
45
+ "jest-environment-jsdom": "^29.7.0",
46
+ "prettier": "^3.0.0",
47
+ "tinybench": "^6.1.4",
48
+ "ts-jest": "^29.1.0",
49
+ "ts-node": "^10.9.2",
50
+ "tsup": "^8.5.1",
51
+ "typescript": "^5.8.3"
52
+ },
53
+ "keywords": [
54
+ "hedwig",
55
+ "message-broker",
56
+ "event-bus",
57
+ "pubsub",
58
+ "microfrontend",
59
+ "type-safe",
60
+ "typescript"
61
+ ],
62
+ "files": [
63
+ "dist",
64
+ "README.md",
65
+ "LICENSE"
66
+ ],
67
+ "engines": {
68
+ "node": ">=18.17.0"
69
+ },
70
+ "jest": {
71
+ "preset": "ts-jest",
72
+ "testEnvironment": "node",
73
+ "testMatch": [
74
+ "**/src/**/*.test.ts"
75
+ ],
76
+ "testTimeout": 60000
77
+ }
78
+ }