{"version":3,"sources":["../../../src/events/streaming/StreamConnectionManager.ts","../../../src/events/streaming/StreamBroadcaster.ts","../../../src/events/streaming/auth/BaseAuthAdapter.ts","../../../src/events/streaming/auth/adapters/AnonymousAuthAdapter.ts","../../../src/events/streaming/transports/BaseTransportAdapter.ts","../../../src/events/streaming/transports/adapters/SSETransportAdapter.ts","../../../src/events/streaming/frameworks/BaseFrameworkAdapter.ts","../../../src/events/streaming/frameworks/NextJSFrameworkAdapter.ts","../../../src/events/streaming/frameworks/ExpressFrameworkAdapter.ts","../../../src/events/streaming/frameworks/NestJSFrameworkAdapter.ts","../../../src/events/streaming/StreamServer.ts","../../../src/events/streaming/auth/adapters/TokenAuthAdapter.ts","../../../src/events/streaming/transports/adapters/WebSocketTransportAdapter.ts","../../../src/events/streaming/StreamRegistry.ts","../../../src/events/streaming/base/BaseStreamEndpoint.ts","../../../src/events/streaming/channels/BaseChannelController.ts","../../../src/utils/common/id.ts","../../../src/events/CoreEventManager.ts","../../../src/domain/files/streaming/FilesChannelController.ts","../../../src/domain/files/streaming/FilesStreamEndpoint.ts","../../../src/domain/notifications/streaming/NotificationsChannelController.ts","../../../src/domain/notifications/streaming/NotificationsStreamEndpoint.ts","../../../src/events/streaming/endpoints/system/SystemChannelController.ts","../../../src/events/streaming/endpoints/system/SystemStreamEndpoint.ts","../../../src/events/streaming/middleware/MiddlewareChain.ts","../../../src/events/streaming/middleware/RateLimitMiddleware.ts"],"names":["TIME_CONSTANTS","DEFAULT_STALE_MINUTES","DEFAULT_MAX_STALE_AGE","HTTP_STATUS","StreamPackageError","STREAM_ERROR_CODES","CoreLogger"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Stream Connection Manager\n *\n * Manages active streaming connections and channel subscriptions.\n * Provides connection lifecycle and subscription management.\n */\n\nimport type {\n  StreamChannel,\n  StreamConnection,\n  StreamConnectionInfo,\n  StreamManagerStats,\n  StreamTransportType,\n} from '@plyaz/types/core';\nimport { TIME_CONSTANTS } from '@plyaz/config';\n\n/**\n * Default configuration\n */\nconst DEFAULT_STALE_MINUTES = 5;\nconst DEFAULT_MAX_STALE_AGE = DEFAULT_STALE_MINUTES * TIME_CONSTANTS.MINUTE; // 5 minutes\n\n/**\n * StreamConnectionManager - Manages streaming connections\n *\n * Features:\n * - Connection lifecycle management\n * - Channel-based subscriptions\n * - Activity tracking for stale connection cleanup\n * - Statistics and debugging info\n *\n * @example\n * ```ts\n * const manager = new StreamConnectionManager();\n *\n * // Add connection\n * manager.addConnection({\n *   id: 'conn-1',\n *   transport: 'sse',\n *   channels: new Set(),\n *   createdAt: new Date(),\n *   lastActivity: new Date(),\n * });\n *\n * // Subscribe to channel\n * manager.subscribe('conn-1', 'upload:abc123');\n *\n * // Get connections for broadcasting\n * const connections = manager.getConnectionsByChannel('upload:abc123');\n * ```\n */\nexport class StreamConnectionManager {\n  /** Active connections by ID */\n  private connections = new Map<string, StreamConnection>();\n\n  /** Channel → connection IDs mapping for efficient broadcasting */\n  private channelSubscriptions = new Map<string, Set<string>>();\n\n  /**\n   * Add a new connection\n   *\n   * @param connection - Connection to add\n   */\n  addConnection(connection: StreamConnection): void {\n    this.connections.set(connection.id, connection);\n  }\n\n  /**\n   * Remove a connection and its subscriptions\n   *\n   * @param connectionId - Connection to remove\n   */\n  removeConnection(connectionId: string): void {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return;\n\n    // Remove from all channel subscriptions\n    for (const channel of connection.channels) {\n      this.channelSubscriptions.get(channel)?.delete(connectionId);\n\n      // Clean up empty channel sets\n      if (this.channelSubscriptions.get(channel)?.size === 0) {\n        this.channelSubscriptions.delete(channel);\n      }\n    }\n\n    // Remove connection\n    this.connections.delete(connectionId);\n  }\n\n  /**\n   * Get a connection by ID\n   *\n   * @param connectionId - Connection ID\n   */\n  getConnection(connectionId: string): StreamConnection | undefined {\n    return this.connections.get(connectionId);\n  }\n\n  /**\n   * Check if connection exists\n   *\n   * @param connectionId - Connection ID\n   */\n  hasConnection(connectionId: string): boolean {\n    return this.connections.has(connectionId);\n  }\n\n  /**\n   * Subscribe connection to a channel\n   *\n   * @param connectionId - Connection to subscribe\n   * @param channel - Channel to subscribe to\n   */\n  subscribe(connectionId: string, channel: StreamChannel): void {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return;\n\n    // Add to connection's channels\n    connection.channels.add(channel);\n\n    // Add to channel subscriptions index\n    if (!this.channelSubscriptions.has(channel)) {\n      this.channelSubscriptions.set(channel, new Set());\n    }\n    this.channelSubscriptions.get(channel)!.add(connectionId);\n\n    // Update activity\n    connection.lastActivity = new Date();\n  }\n\n  /**\n   * Unsubscribe connection from a channel\n   *\n   * @param connectionId - Connection to unsubscribe\n   * @param channel - Channel to unsubscribe from\n   */\n  unsubscribe(connectionId: string, channel: StreamChannel): void {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return;\n\n    // Remove from connection's channels\n    connection.channels.delete(channel);\n\n    // Remove from channel subscriptions index\n    this.channelSubscriptions.get(channel)?.delete(connectionId);\n\n    // Clean up empty channel sets\n    if (this.channelSubscriptions.get(channel)?.size === 0) {\n      this.channelSubscriptions.delete(channel);\n    }\n\n    // Update activity\n    connection.lastActivity = new Date();\n  }\n\n  /**\n   * Get all connections subscribed to a channel\n   *\n   * @param channel - Channel to query\n   */\n  getConnectionsByChannel(channel: StreamChannel): StreamConnection[] {\n    const connectionIds = this.channelSubscriptions.get(channel);\n    if (!connectionIds) return [];\n\n    return Array.from(connectionIds)\n      .map(id => this.connections.get(id))\n      .filter((conn): conn is StreamConnection => conn !== undefined);\n  }\n\n  /**\n   * Get all channels a connection is subscribed to\n   *\n   * @param connectionId - Connection ID\n   */\n  getChannelsByConnection(connectionId: string): StreamChannel[] {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return [];\n\n    return Array.from(connection.channels) as StreamChannel[];\n  }\n\n  /**\n   * Update connection's last activity timestamp\n   *\n   * @param connectionId - Connection ID\n   */\n  updateActivity(connectionId: string): void {\n    const connection = this.connections.get(connectionId);\n    if (connection) {\n      connection.lastActivity = new Date();\n    }\n  }\n\n  /**\n   * Clean up stale connections\n   *\n   * @param maxAge - Maximum age in milliseconds (default: 5 minutes)\n   * @returns Removed connection IDs\n   */\n  cleanupStale(maxAge: number = DEFAULT_MAX_STALE_AGE): string[] {\n    const now = Date.now();\n    const removed: string[] = [];\n\n    for (const [id, connection] of this.connections) {\n      const age = now - connection.lastActivity.getTime();\n      if (age > maxAge) {\n        this.removeConnection(id);\n        removed.push(id);\n      }\n    }\n\n    return removed;\n  }\n\n  /**\n   * Get all connection IDs\n   */\n  getConnectionIds(): string[] {\n    return Array.from(this.connections.keys());\n  }\n\n  /**\n   * Get all connections\n   */\n  getAllConnections(): StreamConnection[] {\n    return Array.from(this.connections.values());\n  }\n\n  /**\n   * Get all active channels\n   */\n  getActiveChannels(): StreamChannel[] {\n    return Array.from(this.channelSubscriptions.keys()) as StreamChannel[];\n  }\n\n  /**\n   * Get connection info (serializable)\n   *\n   * @param connectionId - Connection ID\n   */\n  getConnectionInfo(connectionId: string): StreamConnectionInfo | undefined {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return undefined;\n\n    return {\n      id: connection.id,\n      userId: connection.userId,\n      transport: connection.transport,\n      channels: Array.from(connection.channels),\n      createdAt: connection.createdAt.toISOString(),\n      lastActivity: connection.lastActivity.toISOString(),\n      metadata: connection.metadata,\n    };\n  }\n\n  /**\n   * Get manager statistics\n   */\n  getStats(): StreamManagerStats {\n    const connectionsByTransport: Record<StreamTransportType, number> = {\n      sse: 0,\n      websocket: 0,\n    };\n\n    for (const connection of this.connections.values()) {\n      connectionsByTransport[connection.transport]++;\n    }\n\n    return {\n      totalConnections: this.connections.size,\n      connectionsByTransport,\n      totalSubscriptions: Array.from(this.channelSubscriptions.values()).reduce(\n        (sum, set) => sum + set.size,\n        0\n      ),\n      activeChannels: this.channelSubscriptions.size,\n    };\n  }\n\n  /**\n   * Clear all connections (for shutdown)\n   */\n  clear(): void {\n    this.connections.clear();\n    this.channelSubscriptions.clear();\n  }\n}\n","/**\n * Stream Broadcaster\n *\n * Core infrastructure for streaming to clients.\n * Orchestrates auth, transport, and connection management.\n *\n * Note: Event subscriptions are handled by ChannelControllers,\n * not directly by StreamBroadcaster.\n */\nimport type { BaseAuthAdapter } from './auth/BaseAuthAdapter';\nimport type { BaseTransportAdapter } from './transports/BaseTransportAdapter';\nimport { StreamConnectionManager } from './StreamConnectionManager';\nimport type {\n  StreamAuthResult,\n  StreamBroadcasterConfig,\n  StreamChannel,\n  StreamConnection,\n  StreamManagerStats,\n  StreamMessage,\n  StreamTransportType,\n} from '@plyaz/types/core';\nimport { STREAM_ERROR_CODES } from '@plyaz/types';\nimport { TIME_CONSTANTS } from '@plyaz/config';\nimport { StreamPackageError } from '@plyaz/errors';\n\n/**\n * Default configuration\n */\nconst DEFAULT_CLEANUP_INTERVAL = TIME_CONSTANTS.MINUTE; // 1 minute\nconst DEFAULT_STALE_MINUTES = 5;\nconst DEFAULT_MAX_STALE_AGE = DEFAULT_STALE_MINUTES * TIME_CONSTANTS.MINUTE; // 5 minutes\n\n/**\n * StreamBroadcaster - Core streaming infrastructure\n *\n * Features:\n * - Manages connections via StreamConnectionManager\n * - Routes messages through transport adapters (SSE, WebSocket)\n * - Handles auth via adapter\n * - Automatic stale connection cleanup\n * - Channel-based message broadcasting\n *\n * Note: Event subscriptions are handled by endpoint controllers\n * registered via StreamRegistry (e.g., FilesChannelController).\n *\n * @example\n * ```ts\n * const broadcaster = new StreamBroadcaster(\n *   new AnonymousAuthAdapter(),\n *   [new SSETransportAdapter()]\n * );\n *\n * broadcaster.initialize();\n *\n * // Register with StreamRegistry\n * await StreamRegistry.initialize({\n *   broadcaster,\n *   endpoints: [\n *     { endpoint: FilesStreamEndpoint, config: { enabled: true } },\n *   ],\n * });\n *\n * // In API route\n * const authResult = await broadcaster.authenticate(request);\n * const response = await broadcaster.createConnection('conn-1', 'sse', request);\n * broadcaster.subscribe('conn-1', 'upload:abc123', authResult);\n * return response;\n * ```\n */\nexport class StreamBroadcaster {\n  private readonly connectionManager: StreamConnectionManager;\n  private readonly authAdapter: BaseAuthAdapter;\n  private readonly transports: Map<StreamTransportType, BaseTransportAdapter>;\n  private readonly maxStaleAge: number;\n\n  private unsubscribers: (() => void)[] = [];\n  private cleanupTimer?: ReturnType<typeof setInterval>;\n  private initialized = false;\n\n  constructor(\n    authAdapter: BaseAuthAdapter,\n    transports: BaseTransportAdapter[],\n    config?: StreamBroadcasterConfig\n  ) {\n    this.connectionManager = new StreamConnectionManager();\n    this.authAdapter = authAdapter;\n    this.transports = new Map(transports.map(t => [t.type, t]));\n    this.maxStaleAge = config?.maxStaleAge ?? DEFAULT_MAX_STALE_AGE;\n  }\n\n  /**\n   * Initialize cleanup timer\n   * Call once on startup\n   *\n   * Note: Event subscriptions are now handled by endpoint controllers\n   * registered via StreamRegistry (e.g., FilesChannelController, SystemChannelController).\n   */\n  initialize(): void {\n    if (this.initialized) return;\n\n    // Start cleanup timer for stale connections\n    this.cleanupTimer = setInterval(() => {\n      this.cleanupStaleConnections();\n    }, DEFAULT_CLEANUP_INTERVAL);\n\n    this.initialized = true;\n  }\n\n  /**\n   * Authenticate a connection request\n   *\n   * @param request - HTTP request\n   * @returns Authentication result\n   */\n  async authenticate(request: Request): Promise<StreamAuthResult> {\n    return this.authAdapter.authenticate(request);\n  }\n\n  /**\n   * Check if user can subscribe to a channel\n   *\n   * @param authResult - Authentication result\n   * @param channel - Channel to subscribe\n   */\n  canSubscribe(authResult: StreamAuthResult, channel: StreamChannel): boolean {\n    return this.authAdapter.canSubscribe(authResult.userId, channel, authResult.scopes);\n  }\n\n  /**\n   * Create a new streaming connection\n   *\n   * @param connectionId - Unique connection ID\n   * @param transportType - Transport to use (sse or websocket)\n   * @param request - HTTP request\n   * @param authResult - Optional auth result (if already authenticated)\n   * @returns Response (for SSE) or void (for WebSocket)\n   */\n  async createConnection(\n    connectionId: string,\n    transportType: StreamTransportType,\n    request: Request,\n    authResult?: StreamAuthResult\n  ): Promise<Response | void> {\n    const transport = this.transports.get(transportType);\n    if (!transport) {\n      throw new StreamPackageError(\n        `Transport not available: ${transportType}`,\n        STREAM_ERROR_CODES.TRANSPORT_NOT_SUPPORTED,\n        { context: { transport: transportType } }\n      );\n    }\n\n    // Create connection in transport\n    const response = await transport.createConnection(connectionId, request);\n\n    // Track connection\n    const connection: StreamConnection = {\n      id: connectionId,\n      userId: authResult?.userId,\n      transport: transportType,\n      channels: new Set(),\n      createdAt: new Date(),\n      lastActivity: new Date(),\n      metadata: authResult?.metadata,\n    };\n    this.connectionManager.addConnection(connection);\n\n    return response;\n  }\n\n  /**\n   * Subscribe connection to a channel\n   *\n   * @param connectionId - Connection ID\n   * @param channel - Channel to subscribe\n   * @param authResult - Auth result for permission check\n   * @returns Whether subscription succeeded\n   */\n  subscribe(connectionId: string, channel: StreamChannel, authResult?: StreamAuthResult): boolean {\n    // Check permission if auth result provided\n    if (authResult && !this.canSubscribe(authResult, channel)) {\n      return false;\n    }\n\n    this.connectionManager.subscribe(connectionId, channel);\n    return true;\n  }\n\n  /**\n   * Unsubscribe connection from a channel\n   *\n   * @param connectionId - Connection ID\n   * @param channel - Channel to unsubscribe\n   */\n  unsubscribe(connectionId: string, channel: StreamChannel): void {\n    this.connectionManager.unsubscribe(connectionId, channel);\n  }\n\n  /**\n   * Close a connection\n   *\n   * @param connectionId - Connection to close\n   */\n  async closeConnection(connectionId: string): Promise<void> {\n    const connection = this.connectionManager.getConnection(connectionId);\n    if (!connection) return;\n\n    // Close in transport\n    const transport = this.transports.get(connection.transport);\n    if (transport) {\n      await transport.close(connectionId);\n    }\n\n    // Remove from manager\n    this.connectionManager.removeConnection(connectionId);\n  }\n\n  /**\n   * Broadcast message to all connections on a channel\n   *\n   * @param channel - Channel to broadcast to\n   * @param message - Message to send\n   */\n  broadcastToChannel(channel: StreamChannel, message: StreamMessage): void {\n    const connections = this.connectionManager.getConnectionsByChannel(channel);\n\n    for (const conn of connections) {\n      const transport = this.transports.get(conn.transport);\n      if (transport) {\n        transport.send(conn.id, { ...message, channel }).catch(() => {\n          // Connection likely dead, will be cleaned up\n        });\n      }\n    }\n  }\n\n  /**\n   * Send message to a specific connection\n   *\n   * @param connectionId - Connection ID\n   * @param message - Message to send\n   */\n  async sendToConnection(connectionId: string, message: StreamMessage): Promise<void> {\n    const connection = this.connectionManager.getConnection(connectionId);\n    if (!connection) return;\n\n    const transport = this.transports.get(connection.transport);\n    if (transport) {\n      await transport.send(connectionId, message);\n    }\n  }\n\n  /**\n   * Broadcast to all connections (system-wide)\n   *\n   * @param message - Message to send\n   */\n  broadcastToAll(message: StreamMessage): void {\n    for (const connection of this.connectionManager.getAllConnections()) {\n      const transport = this.transports.get(connection.transport);\n      if (transport) {\n        transport.send(connection.id, message).catch(() => {\n          // Connection likely dead\n        });\n      }\n    }\n  }\n\n  /**\n   * Get manager statistics\n   */\n  getStats(): StreamManagerStats {\n    return this.connectionManager.getStats();\n  }\n\n  /**\n   * Dispose broadcaster (for shutdown)\n   */\n  dispose(): void {\n    // Stop event subscriptions\n    this.unsubscribers.forEach(unsub => unsub());\n    this.unsubscribers = [];\n\n    // Stop cleanup timer\n    if (this.cleanupTimer) {\n      clearInterval(this.cleanupTimer);\n      this.cleanupTimer = undefined;\n    }\n\n    // Close all connections\n    for (const [, transport] of this.transports) {\n      if ('closeAll' in transport && typeof transport.closeAll === 'function') {\n        void (transport as { closeAll: () => Promise<void> }).closeAll();\n      }\n    }\n\n    // Clear connection manager\n    this.connectionManager.clear();\n\n    this.initialized = false;\n  }\n\n  /**\n   * Clean up stale connections\n   */\n  private cleanupStaleConnections(): void {\n    const removed = this.connectionManager.cleanupStale(this.maxStaleAge);\n\n    // Also close in transports\n    for (const connectionId of removed) {\n      for (const [, transport] of this.transports) {\n        if (transport.isAlive(connectionId)) {\n          transport.close(connectionId).catch(() => {\n            // Already closed\n          });\n        }\n      }\n    }\n  }\n}\n","/**\n * Base Auth Adapter\n *\n * Abstract base class for stream authentication adapters.\n * Follows the adapter pattern used in @plyaz/storage.\n */\n\nimport type { StreamAuthAdapterConfig, StreamAuthResult, StreamChannel } from '@plyaz/types/core';\n\n/**\n * BaseAuthAdapter - Abstract base class for all stream auth adapters\n *\n * Provides:\n * - Common configuration handling\n * - Interface for authentication and authorization\n *\n * Subclasses must implement:\n * - authenticate() - Validate connection request\n * - canSubscribe() - Check channel subscription permissions\n *\n * @example\n * ```ts\n * class MyAuthAdapter extends BaseAuthAdapter {\n *   async authenticate(request: Request): Promise<StreamAuthResult> {\n *     // Custom authentication logic\n *   }\n *\n *   canSubscribe(userId, channel, scopes): boolean {\n *     // Custom authorization logic\n *   }\n * }\n * ```\n */\nexport abstract class BaseAuthAdapter {\n  /** Adapter name for logging/debugging */\n  readonly name: string;\n\n  /** Whether this adapter is enabled */\n  readonly enabled: boolean;\n\n  constructor(config: StreamAuthAdapterConfig) {\n    this.name = config.name;\n    this.enabled = config.enabled ?? true;\n  }\n\n  /**\n   * Authenticate a connection request\n   *\n   * @param request - HTTP request or WebSocket upgrade request\n   * @returns Authentication result with user info if authenticated\n   */\n  abstract authenticate(request: Request): Promise<StreamAuthResult>;\n\n  /**\n   * Check if user can subscribe to a channel\n   *\n   * @param userId - User ID (undefined for anonymous connections)\n   * @param channel - Channel to subscribe to\n   * @param scopes - User's allowed scopes from authentication\n   * @returns Whether subscription is allowed\n   */\n  abstract canSubscribe(\n    userId: string | undefined,\n    channel: StreamChannel,\n    scopes?: string[]\n  ): boolean;\n\n  /**\n   * Get adapter info for debugging\n   */\n  getAdapterInfo(): { name: string; enabled: boolean } {\n    return {\n      name: this.name,\n      enabled: this.enabled,\n    };\n  }\n}\n","/**\n * Anonymous Auth Adapter\n *\n * No-op authentication adapter for local/development use.\n * Allows all connections and channel subscriptions.\n */\n\nimport type { StreamAuthResult, StreamChannel } from '@plyaz/types/core';\nimport { BaseAuthAdapter } from '../BaseAuthAdapter';\n\n/**\n * AnonymousAuthAdapter - Allows all connections without authentication\n *\n * Use cases:\n * - Local development\n * - Internal services without auth requirements\n * - Testing environments\n *\n * @example\n * ```ts\n * const authAdapter = new AnonymousAuthAdapter();\n *\n * // Always returns authenticated: true\n * const result = await authAdapter.authenticate(request);\n * console.log(result.authenticated); // true\n *\n * // Always allows subscription\n * const canSub = authAdapter.canSubscribe(undefined, 'uploads');\n * console.log(canSub); // true\n * ```\n */\nexport class AnonymousAuthAdapter extends BaseAuthAdapter {\n  constructor() {\n    super({ name: 'anonymous' });\n  }\n\n  /**\n   * Authenticate request (always succeeds)\n   *\n   * @returns Always returns { authenticated: true }\n   */\n  async authenticate(): Promise<StreamAuthResult> {\n    return { authenticated: true };\n  }\n\n  /**\n   * Check subscription permission (always allowed)\n   *\n   * @returns Always returns true\n   */\n  // eslint-disable-next-line  no-unused-vars\n  canSubscribe(_userId: string | undefined, _channel: StreamChannel, _scopes?: string[]): boolean {\n    return true;\n  }\n}\n","/**\n * Base Transport Adapter\n *\n * Abstract base class for stream transport adapters.\n * Follows the adapter pattern used in @plyaz/storage.\n */\n\nimport type {\n  StreamMessage,\n  StreamTransportAdapterConfig,\n  StreamTransportType,\n} from '@plyaz/types/core';\nimport { STREAMING_DEFAULTS } from '@plyaz/config/streaming';\n\n/**\n * BaseTransportAdapter - Abstract base class for all transport adapters\n *\n * Provides:\n * - Common configuration handling\n * - Interface for connection management\n * - Message sending abstraction\n *\n * Subclasses must implement:\n * - createConnection() - Create new connection\n * - send() - Send message to connection\n * - close() - Close connection\n * - isAlive() - Check connection status\n *\n * @example\n * ```ts\n * class MyTransportAdapter extends BaseTransportAdapter {\n *   async createConnection(connectionId: string, request: Request): Promise<Response> {\n *     // Implementation\n *   }\n *   // ... other methods\n * }\n * ```\n */\nexport abstract class BaseTransportAdapter {\n  /** Adapter name for logging/debugging */\n  readonly name: string;\n\n  /** Transport type identifier */\n  readonly type: StreamTransportType;\n\n  /** Heartbeat interval in milliseconds */\n  protected readonly heartbeatInterval: number;\n\n  /** Maximum concurrent connections */\n  protected readonly maxConnections: number;\n\n  constructor(config: StreamTransportAdapterConfig & { type: StreamTransportType }) {\n    this.name = config.name;\n    this.type = config.type;\n    this.heartbeatInterval = config.heartbeatInterval ?? STREAMING_DEFAULTS.HEARTBEAT_INTERVAL_MS;\n    this.maxConnections = config.maxConnections ?? STREAMING_DEFAULTS.MAX_CONNECTIONS;\n  }\n\n  /**\n   * Create a new streaming connection\n   *\n   * For SSE: Returns a Response with streaming body\n   * For WebSocket: Modifies socket directly, returns void\n   *\n   * @param connectionId - Unique connection identifier\n   * @param request - HTTP request or WebSocket upgrade request\n   * @returns Response for SSE, void for WebSocket\n   */\n  abstract createConnection(connectionId: string, request: Request): Promise<Response | void>;\n\n  /**\n   * Send a message to a specific connection\n   *\n   * @param connectionId - Connection to send to\n   * @param message - Message to send\n   */\n  abstract send(connectionId: string, message: StreamMessage): Promise<void>;\n\n  /**\n   * Close a connection\n   *\n   * @param connectionId - Connection to close\n   */\n  abstract close(connectionId: string): Promise<void>;\n\n  /**\n   * Check if a connection is still alive\n   *\n   * @param connectionId - Connection to check\n   * @returns Whether connection is alive\n   */\n  abstract isAlive(connectionId: string): boolean;\n\n  /**\n   * Get current connection count\n   *\n   * @returns Number of active connections\n   */\n  abstract getConnectionCount(): number;\n\n  /**\n   * Get adapter info for debugging\n   */\n  getAdapterInfo(): {\n    name: string;\n    type: StreamTransportType;\n    heartbeatInterval: number;\n    maxConnections: number;\n    connectionCount: number;\n  } {\n    return {\n      name: this.name,\n      type: this.type,\n      heartbeatInterval: this.heartbeatInterval,\n      maxConnections: this.maxConnections,\n      connectionCount: this.getConnectionCount(),\n    };\n  }\n\n  /**\n   * Check if adapter can accept more connections\n   */\n  canAcceptConnection(): boolean {\n    return this.getConnectionCount() < this.maxConnections;\n  }\n}\n","/**\n * SSE Transport Adapter\n *\n * Server-Sent Events transport for real-time streaming.\n * Uses Web Streams API for compatibility with Next.js/Edge runtime.\n */\n\n/* eslint-disable n/no-unsupported-features/node-builtins */\n// ReadableStream and ReadableStreamDefaultController are stable Web APIs,\n// supported in all modern browsers and Edge runtime\n\nimport type { StreamMessage, StreamTransportAdapterConfig } from '@plyaz/types/core';\nimport { BaseTransportAdapter } from '../BaseTransportAdapter';\n\n/**\n * Internal connection state\n */\ninterface SSEConnection {\n  controller: ReadableStreamDefaultController;\n  heartbeatTimer?: ReturnType<typeof setInterval>;\n  createdAt: Date;\n}\n\n/**\n * SSETransportAdapter - Server-Sent Events transport\n *\n * Features:\n * - Web Streams API for Edge runtime compatibility\n * - Automatic heartbeat to keep connections alive\n * - Proper SSE formatting with event, id, retry, data fields\n * - Connection cleanup on disconnect\n *\n * @example\n * ```ts\n * const sseAdapter = new SSETransportAdapter({ heartbeatInterval: 15000 });\n *\n * // In API route\n * const response = await sseAdapter.createConnection(connectionId, request);\n * return response; // Returns SSE stream\n *\n * // Send message\n * await sseAdapter.send(connectionId, {\n *   event: 'progress',\n *   data: { percentage: 50 },\n * });\n * ```\n */\nexport class SSETransportAdapter extends BaseTransportAdapter {\n  private connections = new Map<string, SSEConnection>();\n\n  constructor(config?: Partial<StreamTransportAdapterConfig>) {\n    super({\n      name: config?.name ?? 'sse',\n      type: 'sse',\n      heartbeatInterval: config?.heartbeatInterval,\n      maxConnections: config?.maxConnections,\n    });\n  }\n\n  /**\n   * Create a new SSE connection\n   *\n   * @param connectionId - Unique connection identifier\n   * @returns Response with SSE stream\n   */\n  async createConnection(connectionId: string): Promise<Response> {\n    // Check if we can accept more connections\n    if (!this.canAcceptConnection()) {\n      return new Response('Too many connections', { status: 503 });\n    }\n\n    // Create the SSE stream\n    const stream = new ReadableStream({\n      start: controller => {\n        // Store connection\n        const connection: SSEConnection = {\n          controller,\n          createdAt: new Date(),\n        };\n        this.connections.set(connectionId, connection);\n\n        // Send initial connection message\n        this.sendImmediate(controller, {\n          event: 'connected',\n          data: { connectionId, timestamp: Date.now() },\n        });\n\n        // Start heartbeat\n        connection.heartbeatTimer = setInterval(() => {\n          if (!this.isAlive(connectionId)) {\n            this.cleanup(connectionId);\n            return;\n          }\n          this.sendImmediate(controller, {\n            event: 'heartbeat',\n            data: { timestamp: Date.now() },\n          });\n        }, this.heartbeatInterval);\n      },\n      cancel: () => {\n        this.cleanup(connectionId);\n      },\n    });\n\n    return new Response(stream, {\n      headers: {\n        'Content-Type': 'text/event-stream',\n        'Cache-Control': 'no-cache, no-transform',\n        Connection: 'keep-alive',\n        'X-Accel-Buffering': 'no', // Disable nginx buffering\n      },\n    });\n  }\n\n  /**\n   * Send a message to a connection\n   *\n   * @param connectionId - Connection to send to\n   * @param message - Message to send\n   */\n  async send(connectionId: string, message: StreamMessage): Promise<void> {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return;\n\n    try {\n      this.sendImmediate(connection.controller, message);\n    } catch {\n      // Connection likely closed, cleanup\n      this.cleanup(connectionId);\n    }\n  }\n\n  /**\n   * Close a connection\n   *\n   * @param connectionId - Connection to close\n   */\n  async close(connectionId: string): Promise<void> {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return;\n\n    try {\n      // Send close event before closing\n      this.sendImmediate(connection.controller, {\n        event: 'close',\n        data: { reason: 'server_close' },\n      });\n      connection.controller.close();\n    } catch {\n      // Already closed\n    }\n\n    this.cleanup(connectionId);\n  }\n\n  /**\n   * Check if a connection is alive\n   *\n   * @param connectionId - Connection to check\n   */\n  isAlive(connectionId: string): boolean {\n    return this.connections.has(connectionId);\n  }\n\n  /**\n   * Get current connection count\n   */\n  getConnectionCount(): number {\n    return this.connections.size;\n  }\n\n  /**\n   * Get all connection IDs\n   */\n  getConnectionIds(): string[] {\n    return Array.from(this.connections.keys());\n  }\n\n  /**\n   * Send message immediately to controller\n   */\n  private sendImmediate(controller: ReadableStreamDefaultController, message: StreamMessage): void {\n    const formatted = this.formatSSE(message);\n    controller.enqueue(new TextEncoder().encode(formatted));\n  }\n\n  /**\n   * Format message as SSE\n   *\n   * SSE format:\n   * ```\n   * id: messageId\n   * retry: retryMs\n   * data: {\"event\":\"eventName\",\"channel\":\"channelName\",\"data\":{...}}\n   *\n   * ```\n   *\n   * Note: We intentionally DON'T use SSE named events (event: line) because:\n   * 1. EventSource silently drops events without registered listeners\n   * 2. Hardcoding all possible event names is not scalable\n   * 3. Including event in JSON payload is more flexible\n   *\n   * The client extracts event/channel from the JSON payload in onmessage.\n   */\n  private formatSSE(message: StreamMessage): string {\n    let output = '';\n\n    if (message.id) {\n      output += `id: ${message.id}\\n`;\n    }\n\n    if (message.retry !== undefined) {\n      output += `retry: ${message.retry}\\n`;\n    }\n\n    // Include event and channel in the data payload for the client to extract\n    const payload = {\n      event: message.event,\n      channel: message.channel,\n      data: message.data,\n      timestamp: message.timestamp ?? Date.now(),\n    };\n\n    output += `data: ${JSON.stringify(payload)}\\n`;\n\n    // Double newline to end message\n    output += '\\n';\n\n    return output;\n  }\n\n  /**\n   * Cleanup connection resources\n   */\n  private cleanup(connectionId: string): void {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return;\n\n    // Clear heartbeat timer\n    if (connection.heartbeatTimer) {\n      clearInterval(connection.heartbeatTimer);\n    }\n\n    // Remove from map\n    this.connections.delete(connectionId);\n  }\n\n  /**\n   * Close all connections (for shutdown)\n   */\n  async closeAll(): Promise<void> {\n    const connectionIds = this.getConnectionIds();\n    await Promise.all(connectionIds.map(id => this.close(id)));\n  }\n}\n","/**\n * Base Framework Adapter\n *\n * Abstract base class for framework-specific streaming adapters.\n * Converts framework-specific request/response to Web Request/Response.\n *\n * Follows the adapter pattern used in BaseTransportAdapter and BaseAuthAdapter.\n *\n * @example\n * ```typescript\n * class MyFrameworkAdapter extends BaseFrameworkAdapter {\n *   readonly framework = 'myframework' as const;\n *\n *   createHandler(handleRequest, options) {\n *     return (req, res) => {\n *       const webRequest = this.convertRequest(req);\n *       const response = await handleRequest(webRequest, options?.transport);\n *       await this.handleResponse(response, req, res);\n *     };\n *   }\n *   // ... other methods\n * }\n * ```\n */\n\nimport type {\n  FrameworkType,\n  FrameworkAdapterConfig,\n  FrameworkHandlerOptions,\n  CoreRequestHandler,\n} from '@plyaz/types/core';\n\n/**\n * BaseFrameworkAdapter - Abstract base class for framework adapters\n *\n * Provides:\n * - Common configuration handling\n * - Interface for request/response conversion\n * - Handler creation abstraction\n *\n * Subclasses must implement:\n * - framework - Framework identifier\n * - createHandler() - Create framework-specific handler\n * - convertRequest() - Convert framework request to Web Request\n * - handleResponse() - Handle Web Response for framework\n */\nexport abstract class BaseFrameworkAdapter {\n  /** Adapter name for logging/debugging */\n  readonly name: string;\n\n  /** Framework type identifier */\n  abstract readonly framework: FrameworkType;\n\n  /** Whether adapter is enabled */\n  readonly enabled: boolean;\n\n  constructor(config: FrameworkAdapterConfig = {} as FrameworkAdapterConfig) {\n    this.name = config.name ?? this.constructor.name;\n    this.enabled = config.enabled ?? true;\n  }\n\n  /**\n   * Create a handler function for the framework.\n   *\n   * The returned handler type varies by framework:\n   * - Next.js: `(request: Request) => Promise<Response>`\n   * - Express: `(req: Request, res: Response) => Promise<void>`\n   * - NestJS: `(req: Request, res: Response) => Promise<void>`\n   *\n   * @param handleRequest - Core request handler from StreamServer\n   * @param options - Handler options (transport type, etc.)\n   * @returns Framework-specific handler function\n   *\n   * @example\n   * ```typescript\n   * // Next.js\n   * export const GET = adapter.createHandler(streamServer.handleRequest);\n   *\n   * // Express\n   * app.get('/stream', adapter.createHandler(streamServer.handleRequest));\n   * ```\n   */\n  abstract createHandler(\n    handleRequest: CoreRequestHandler,\n    options?: FrameworkHandlerOptions\n  ): unknown;\n\n  /**\n   * Convert framework-specific request to Web Request.\n   *\n   * @param frameworkRequest - Framework-specific request object\n   * @returns Web Request object\n   */\n  abstract convertRequest(frameworkRequest: unknown): Request;\n\n  /**\n   * Handle Web Response and send to framework response.\n   *\n   * For Next.js/Edge: Returns Response directly\n   * For Express/NestJS: Streams to res object\n   *\n   * @param response - Web Response from core handler\n   * @param frameworkRequest - Original framework request\n   * @param frameworkResponse - Framework response object (for Express-like frameworks)\n   * @returns Response for return-based frameworks, void for stream-based\n   */\n  abstract handleResponse(\n    response: Response,\n    frameworkRequest: unknown,\n    frameworkResponse?: unknown\n  ): Promise<Response | void>;\n\n  /**\n   * Get adapter info for debugging\n   */\n  getAdapterInfo(): {\n    name: string;\n    framework: FrameworkType;\n    enabled: boolean;\n  } {\n    return {\n      name: this.name,\n      framework: this.framework,\n      enabled: this.enabled,\n    };\n  }\n}\n","/**\n * Next.js Framework Adapter\n *\n * Framework adapter for Next.js App Router (Route Handlers).\n * Next.js uses Web Request/Response natively, so this is mostly a passthrough.\n *\n * @example\n * ```typescript\n * // app/api/events/stream/route.ts\n * import { streamServer } from '@/lib/stream';\n *\n * export const GET = streamServer.getHandler('nextjs');\n * ```\n */\n\nimport type {\n  FrameworkAdapterConfig,\n  FrameworkHandlerOptions,\n  CoreRequestHandler,\n  NextJSHandler,\n} from '@plyaz/types/core';\nimport { BaseFrameworkAdapter } from './BaseFrameworkAdapter';\n\n/**\n * NextJSFrameworkAdapter - Next.js App Router adapter\n *\n * Features:\n * - Native Web Request/Response support (zero conversion overhead)\n * - Works with Next.js App Router route handlers\n * - Edge Runtime compatible\n *\n * @example\n * ```typescript\n * const adapter = new NextJSFrameworkAdapter();\n * const handler = adapter.createHandler(streamServer.handleRequest);\n * export const GET = handler;\n * ```\n */\nexport class NextJSFrameworkAdapter extends BaseFrameworkAdapter {\n  readonly framework = 'nextjs' as const;\n\n  constructor(config?: FrameworkAdapterConfig) {\n    super({\n      name: config?.name ?? 'nextjs',\n      enabled: config?.enabled,\n    });\n  }\n\n  /**\n   * Create Next.js route handler.\n   *\n   * @param handleRequest - Core request handler from StreamServer\n   * @param options - Handler options\n   * @returns Next.js route handler function\n   */\n  createHandler(\n    handleRequest: CoreRequestHandler,\n    options?: FrameworkHandlerOptions\n  ): NextJSHandler {\n    const transport = options?.transport ?? 'sse';\n\n    return (request: Request): Promise<Response> => {\n      return handleRequest(request, transport);\n    };\n  }\n\n  /**\n   * Convert Next.js request to Web Request.\n   * Next.js already uses Web Request, so this is a passthrough.\n   *\n   * @param request - Next.js Request (which is a Web Request)\n   * @returns The same Request object\n   */\n  convertRequest(request: Request): Request {\n    return request;\n  }\n\n  /**\n   * Handle Web Response for Next.js.\n   * Next.js returns Response directly, so this is a passthrough.\n   *\n   * @param response - Web Response from core handler\n   * @returns The same Response object\n   */\n  async handleResponse(response: Response): Promise<Response> {\n    return response;\n  }\n}\n","/**\n * Express Framework Adapter\n *\n * Framework adapter for Express.js and compatible frameworks (Fastify, Koa, etc.).\n * Converts Express req/res to Web Request/Response and handles SSE streaming.\n *\n * @example\n * ```typescript\n * import express from 'express';\n * import { streamServer } from './stream';\n *\n * const app = express();\n * app.get('/events/stream', streamServer.getHandler('express'));\n * ```\n */\n\nimport { HTTP_STATUS } from '@plyaz/types';\nimport type {\n  FrameworkAdapterConfig,\n  FrameworkHandlerOptions,\n  CoreRequestHandler,\n  ExpressRequest,\n  ExpressResponse,\n  ExpressHandler,\n} from '@plyaz/types/core';\nimport { BaseFrameworkAdapter } from './BaseFrameworkAdapter';\n\n/**\n * ExpressFrameworkAdapter - Express/Fastify adapter\n *\n * Features:\n * - Converts Express req/res to Web Request/Response\n * - Handles SSE streaming to Express response\n * - Manages connection cleanup on client disconnect\n * - Compatible with Express, Fastify, Koa (with adapters)\n *\n * @example\n * ```typescript\n * const adapter = new ExpressFrameworkAdapter();\n * const handler = adapter.createHandler(streamServer.handleRequest);\n * app.get('/stream', handler);\n * ```\n */\nexport class ExpressFrameworkAdapter extends BaseFrameworkAdapter {\n  readonly framework = 'express' as const;\n\n  constructor(config?: FrameworkAdapterConfig) {\n    super({\n      name: config?.name ?? 'express',\n      enabled: config?.enabled,\n    });\n  }\n\n  /**\n   * Create Express route handler.\n   *\n   * @param handleRequest - Core request handler from StreamServer\n   * @param options - Handler options\n   * @returns Express route handler function\n   */\n  createHandler(\n    handleRequest: CoreRequestHandler,\n    options?: FrameworkHandlerOptions\n  ): ExpressHandler {\n    const transport = options?.transport ?? 'sse';\n\n    return async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n      const webRequest = this.convertRequest(req);\n      const response = await handleRequest(webRequest, transport);\n      await this.handleResponse(response, req, res);\n    };\n  }\n\n  /**\n   * Convert Express request to Web Request.\n   *\n   * @param req - Express request object\n   * @returns Web Request object\n   */\n  convertRequest(req: ExpressRequest): Request {\n    const url = new URL(req.url, 'http://localhost');\n\n    // Convert headers, handling array values\n    const headers = new Headers();\n    for (const [key, value] of Object.entries(req.headers)) {\n      if (value !== undefined && value !== null) {\n        if (Array.isArray(value)) {\n          value.forEach(v => headers.append(key, v));\n        } else {\n          headers.set(key, value as string);\n        }\n      }\n    }\n\n    return new Request(url, {\n      headers,\n      method: req.method ?? 'GET',\n    });\n  }\n\n  /**\n   * Handle Web Response and stream to Express response.\n   *\n   * @param response - Web Response from core handler\n   * @param _req - Original Express request (unused)\n   * @param res - Express response object\n   */\n  async handleResponse(response: Response, _req: unknown, res: unknown): Promise<void> {\n    const expressRes = res as ExpressResponse;\n\n    // Write SSE headers\n    expressRes.writeHead(HTTP_STATUS.OK, {\n      'Content-Type': 'text/event-stream',\n      'Cache-Control': 'no-cache',\n      Connection: 'keep-alive',\n    });\n\n    // Stream response body\n    const reader = response.body?.getReader();\n    if (reader) {\n      const pump = async (): Promise<void> => {\n        const { done, value } = await reader.read();\n        if (done) return;\n        expressRes.write(new TextDecoder().decode(value));\n        return pump();\n      };\n      void pump();\n\n      // Handle client disconnect\n      expressRes.on('close', () => {\n        void reader.cancel();\n      });\n    }\n  }\n}\n","/**\n * NestJS Framework Adapter\n *\n * Framework adapter for NestJS controllers.\n * NestJS typically uses Express under the hood, so this adapter handles\n * the Express-style req/res pattern used in NestJS controllers.\n *\n * @example\n * ```typescript\n * // In a NestJS controller\n * @Controller('events')\n * export class StreamingController {\n *   constructor(@Inject(STREAM_SERVER) private streamServer: StreamServer) {}\n *\n *   @Get('stream')\n *   async stream(@Req() req: Request, @Res() res: Response) {\n *     const handler = this.streamServer.getHandler('nestjs');\n *     await handler(req, res);\n *   }\n * }\n * ```\n */\n\nimport { HTTP_STATUS } from '@plyaz/types';\nimport type {\n  FrameworkAdapterConfig,\n  FrameworkHandlerOptions,\n  CoreRequestHandler,\n  NestJSRequest,\n  NestJSResponse,\n  NestJSHandler,\n} from '@plyaz/types/core';\nimport { BaseFrameworkAdapter } from './BaseFrameworkAdapter';\n\n/**\n * NestJSFrameworkAdapter - NestJS adapter\n *\n * Features:\n * - Works with NestJS Express-based controllers\n * - Handles @Req() and @Res() decorated parameters\n * - Supports both writeHead and setHeader patterns\n * - Manages SSE streaming to response\n *\n * @example\n * ```typescript\n * const adapter = new NestJSFrameworkAdapter();\n * const handler = adapter.createHandler(streamServer.handleRequest);\n *\n * // In controller method:\n * await handler(req, res);\n * ```\n */\nexport class NestJSFrameworkAdapter extends BaseFrameworkAdapter {\n  readonly framework = 'nestjs' as const;\n\n  constructor(config?: FrameworkAdapterConfig) {\n    super({\n      name: config?.name ?? 'nestjs',\n      enabled: config?.enabled,\n    });\n  }\n\n  /**\n   * Create NestJS controller handler.\n   *\n   * @param handleRequest - Core request handler from StreamServer\n   * @param options - Handler options\n   * @returns NestJS controller handler function\n   */\n  createHandler(\n    handleRequest: CoreRequestHandler,\n    options?: FrameworkHandlerOptions\n  ): NestJSHandler {\n    const transport = options?.transport ?? 'sse';\n\n    return async (req: NestJSRequest, res: NestJSResponse): Promise<void> => {\n      const webRequest = this.convertRequest(req);\n      const response = await handleRequest(webRequest, transport);\n      await this.handleResponse(response, req, res);\n    };\n  }\n\n  /**\n   * Convert NestJS request to Web Request.\n   *\n   * @param req - NestJS request object\n   * @returns Web Request object\n   */\n  convertRequest(req: NestJSRequest): Request {\n    const url = new URL(req.url, 'http://localhost');\n\n    // Convert headers, handling array values\n    const headers = new Headers();\n    for (const [key, value] of Object.entries(req.headers)) {\n      if (value !== undefined && value !== null) {\n        if (Array.isArray(value)) {\n          value.forEach(v => headers.append(key, v));\n        } else {\n          headers.set(key, value as string);\n        }\n      }\n    }\n\n    return new Request(url, {\n      headers,\n      method: req.method ?? 'GET',\n    });\n  }\n\n  /**\n   * Handle Web Response and stream to NestJS response.\n   *\n   * @param response - Web Response from core handler\n   * @param _req - Original NestJS request (unused)\n   * @param res - NestJS response object\n   */\n  async handleResponse(response: Response, _req: unknown, res: unknown): Promise<void> {\n    const nestRes = res as NestJSResponse;\n\n    // Set SSE headers using available method\n    if (nestRes.writeHead) {\n      nestRes.writeHead(HTTP_STATUS.OK, {\n        'Content-Type': 'text/event-stream',\n        'Cache-Control': 'no-cache',\n        Connection: 'keep-alive',\n      });\n    } else {\n      // Fallback to setHeader for NestJS\n      nestRes.status(HTTP_STATUS.OK);\n      nestRes.setHeader('Content-Type', 'text/event-stream');\n      nestRes.setHeader('Cache-Control', 'no-cache');\n      nestRes.setHeader('Connection', 'keep-alive');\n      // Flush headers to start streaming\n      if (nestRes.flushHeaders) {\n        nestRes.flushHeaders();\n      }\n    }\n\n    // Stream response body\n    const reader = response.body?.getReader();\n    if (reader) {\n      const pump = async (): Promise<void> => {\n        const { done, value } = await reader.read();\n        if (done) return;\n        nestRes.write(new TextDecoder().decode(value));\n        return pump();\n      };\n      void pump();\n\n      // Handle client disconnect\n      nestRes.on('close', () => {\n        void reader.cancel();\n      });\n    }\n  }\n}\n","/**\n * Stream Server\n *\n * Framework-agnostic streaming server factory.\n * Provides easy configuration and integration with Next.js, NestJS, Express, etc.\n *\n * Uses framework adapters for handling different runtimes:\n * - NextJSFrameworkAdapter - Next.js App Router (Web Request/Response)\n * - ExpressFrameworkAdapter - Express/Fastify (req/res pattern)\n * - NestJSFrameworkAdapter - NestJS controllers\n *\n * @example\n * ```ts\n * // Create server with builder pattern\n * const streamServer = StreamServer.create()\n *   .withAuth(new AnonymousAuthAdapter())\n *   .withSSE({ heartbeatInterval: 15000 })\n *   .build();\n *\n * // Use in Next.js\n * export const GET = streamServer.getHandler('nextjs');\n *\n * // Use in Express\n * app.get('/stream', streamServer.getHandler('express'));\n *\n * // Use in NestJS\n * const handler = streamServer.getHandler('nestjs');\n * await handler(req, res);\n * ```\n */\n\nimport { StreamBroadcaster } from './StreamBroadcaster';\nimport type { BaseAuthAdapter } from './auth/BaseAuthAdapter';\nimport { AnonymousAuthAdapter } from './auth/adapters/AnonymousAuthAdapter';\nimport type { BaseTransportAdapter } from './transports/BaseTransportAdapter';\nimport { SSETransportAdapter } from './transports/adapters/SSETransportAdapter';\nimport type { BaseFrameworkAdapter } from './frameworks';\nimport {\n  NextJSFrameworkAdapter,\n  ExpressFrameworkAdapter,\n  NestJSFrameworkAdapter,\n  type FrameworkType,\n  type FrameworkHandlerOptions,\n} from './frameworks';\nimport type {\n  StreamAuthResult,\n  StreamBroadcasterConfig,\n  StreamChannel,\n  StreamManagerStats,\n  StreamTransportType,\n  SSEConfig,\n  WebSocketConfig,\n} from '@plyaz/types/core';\nimport { STREAM_ERROR_CODES } from '@plyaz/types';\nimport { StreamPackageError } from '@plyaz/errors';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Configuration Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Stream server configuration\n */\nexport interface StreamServerConfig {\n  /** Auth adapter to use */\n  auth?: BaseAuthAdapter;\n  /** Transport adapters to use */\n  transports?: BaseTransportAdapter[];\n  /** Broadcaster configuration */\n  broadcaster?: StreamBroadcasterConfig;\n  /** Default channels for new connections */\n  defaultChannels?: StreamChannel[];\n  /** Parse channels from request (default: query param 'channels') */\n  parseChannels?: (request: Request) => StreamChannel[];\n  /** Custom framework adapters (NextJS, Express, NestJS registered by default) */\n  frameworkAdapters?: BaseFrameworkAdapter[];\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Stream Server Builder\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Builder for StreamServer\n */\nexport class StreamServerBuilder {\n  private authAdapter?: BaseAuthAdapter;\n  private transports: BaseTransportAdapter[] = [];\n  private broadcasterConfig?: StreamBroadcasterConfig;\n  private defaultChannels: StreamChannel[] = ['uploads'];\n  private channelParser?: (request: Request) => StreamChannel[];\n\n  /**\n   * Configure authentication\n   */\n  withAuth(adapter: BaseAuthAdapter): this {\n    this.authAdapter = adapter;\n    return this;\n  }\n\n  /**\n   * Enable SSE transport\n   */\n  withSSE(config?: SSEConfig): this {\n    if (config?.enabled === false) return this;\n    this.transports.push(new SSETransportAdapter(config));\n    return this;\n  }\n\n  /**\n   * Enable WebSocket transport (future)\n   */\n  // eslint-disable-next-line no-unused-vars\n  withWebSocket(_config?: WebSocketConfig): this {\n    // Future: this.transports.push(new WebSocketTransportAdapter(config));\n    console.warn('WebSocket transport not yet implemented');\n    return this;\n  }\n\n  /**\n   * Add custom transport\n   */\n  withTransport(adapter: BaseTransportAdapter): this {\n    this.transports.push(adapter);\n    return this;\n  }\n\n  /**\n   * Configure broadcaster\n   */\n  withBroadcaster(config: StreamBroadcasterConfig): this {\n    this.broadcasterConfig = config;\n    return this;\n  }\n\n  /**\n   * Set default channels for new connections\n   */\n  withDefaultChannels(channels: StreamChannel[]): this {\n    this.defaultChannels = channels;\n    return this;\n  }\n\n  /**\n   * Custom channel parser\n   */\n  withChannelParser(parser: (request: Request) => StreamChannel[]): this {\n    this.channelParser = parser;\n    return this;\n  }\n\n  /**\n   * Build the stream server\n   */\n  build(): StreamServer {\n    // Default to anonymous auth if not specified\n    const auth = this.authAdapter ?? new AnonymousAuthAdapter();\n\n    // Default to SSE if no transports specified\n    const transports = this.transports.length > 0 ? this.transports : [new SSETransportAdapter()];\n\n    return new StreamServer({\n      auth,\n      transports,\n      broadcaster: this.broadcasterConfig,\n      defaultChannels: this.defaultChannels,\n      parseChannels: this.channelParser,\n    });\n  }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Stream Server\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * StreamServer - Framework-agnostic streaming server\n *\n * Features:\n * - Builder pattern for easy configuration\n * - Framework adapter pattern for easy integration\n * - Automatic connection lifecycle management\n * - Channel-based subscriptions\n *\n * @example\n * ```ts\n * const server = StreamServer.create()\n *   .withAuth(new TokenAuthAdapter({ verifyToken: myVerifier }))\n *   .withSSE({ heartbeatInterval: 30000 })\n *   .build();\n *\n * // Initialize on startup\n * server.initialize();\n *\n * // Get handler for your framework\n * export const GET = server.getHandler('nextjs');\n * // or\n * app.get('/stream', server.getHandler('express'));\n *\n * // Register endpoints via StreamRegistry\n * await StreamRegistry.initialize({\n *   broadcaster: server.getBroadcaster(),\n *   endpoints: [\n *     { endpoint: FilesStreamEndpoint, config: { enabled: true } },\n *     { endpoint: SystemStreamEndpoint, config: { enabled: true } },\n *   ],\n * });\n * ```\n */\nexport class StreamServer {\n  private readonly broadcaster: StreamBroadcaster;\n  private readonly config: StreamServerConfig;\n  private readonly frameworkAdapters = new Map<FrameworkType, BaseFrameworkAdapter>();\n  private initialized = false;\n\n  constructor(config: StreamServerConfig) {\n    this.config = config;\n\n    // Create broadcaster\n    this.broadcaster = new StreamBroadcaster(\n      config.auth ?? new AnonymousAuthAdapter(),\n      config.transports ?? [new SSETransportAdapter()],\n      config.broadcaster\n    );\n\n    // Register default framework adapters\n    this.registerFrameworkAdapter(new NextJSFrameworkAdapter());\n    this.registerFrameworkAdapter(new ExpressFrameworkAdapter());\n    this.registerFrameworkAdapter(new NestJSFrameworkAdapter());\n\n    // Register custom framework adapters if provided\n    if (config.frameworkAdapters) {\n      for (const adapter of config.frameworkAdapters) {\n        this.registerFrameworkAdapter(adapter);\n      }\n    }\n  }\n\n  /**\n   * Create a new builder\n   */\n  static create(): StreamServerBuilder {\n    return new StreamServerBuilder();\n  }\n\n  /**\n   * Initialize the stream server\n   * Call once on application startup\n   */\n  initialize(): void {\n    if (this.initialized) return;\n    this.broadcaster.initialize();\n    this.initialized = true;\n  }\n\n  /**\n   * Dispose the stream server\n   * Call on application shutdown\n   */\n  dispose(): void {\n    this.broadcaster.dispose();\n    this.initialized = false;\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────\n  // Request Handling\n  // ─────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Handle a streaming request (framework-agnostic)\n   *\n   * @param request - HTTP request\n   * @param transportType - Transport to use (default: 'sse')\n   */\n  async handleRequest(\n    request: Request,\n    transportType: StreamTransportType = 'sse'\n  ): Promise<Response> {\n    // Ensure initialized\n    if (!this.initialized) {\n      this.initialize();\n    }\n\n    // Parse channels from request\n    const channels = this.parseChannels(request);\n\n    // Authenticate\n    const authResult = await this.broadcaster.authenticate(request);\n\n    // Generate connection ID\n    const connectionId = crypto.randomUUID();\n\n    // Create connection\n    const response = await this.broadcaster.createConnection(\n      connectionId,\n      transportType,\n      request,\n      authResult\n    );\n\n    if (!response) {\n      return new Response('Failed to create connection', { status: 500 });\n    }\n\n    // Subscribe to channels\n    for (const channel of channels) {\n      if (this.broadcaster.canSubscribe(authResult, channel)) {\n        this.broadcaster.subscribe(connectionId, channel, authResult);\n      }\n    }\n\n    return response;\n  }\n\n  /**\n   * Parse channels from request\n   */\n  private parseChannels(request: Request): StreamChannel[] {\n    // Use custom parser if provided\n    if (this.config.parseChannels) {\n      return this.config.parseChannels(request);\n    }\n\n    // Default: parse from query param\n    const { searchParams } = new URL(request.url);\n    const channelsParam = searchParams.get('channels');\n\n    if (!channelsParam) {\n      return this.config.defaultChannels ?? ['uploads'];\n    }\n\n    return channelsParam.split(',').filter(Boolean) as StreamChannel[];\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────\n  // Framework Adapters\n  // ─────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Register a framework adapter.\n   *\n   * Default adapters (NextJS, Express, NestJS) are registered automatically.\n   * Use this to add custom adapters or override existing ones.\n   *\n   * @param adapter - Framework adapter to register\n   *\n   * @example\n   * ```ts\n   * // Register custom adapter\n   * streamServer.registerFrameworkAdapter(new MyCustomAdapter());\n   *\n   * // Override default adapter\n   * streamServer.registerFrameworkAdapter(new NextJSFrameworkAdapter({ name: 'custom-nextjs' }));\n   * ```\n   */\n  registerFrameworkAdapter(adapter: BaseFrameworkAdapter): void {\n    this.frameworkAdapters.set(adapter.framework, adapter);\n  }\n\n  /**\n   * Get a framework adapter by type.\n   *\n   * @param framework - Framework type to get\n   * @returns Framework adapter or undefined if not registered\n   */\n  getFrameworkAdapter<T extends BaseFrameworkAdapter>(framework: FrameworkType): T | undefined {\n    return this.frameworkAdapters.get(framework) as T | undefined;\n  }\n\n  /**\n   * Get handler for a specific framework.\n   *\n   * This is the primary API for integrating with frameworks.\n   *\n   * @param framework - Framework type ('nextjs', 'express', 'nestjs')\n   * @param options - Handler options (transport type, etc.)\n   * @returns Framework-specific handler function\n   *\n   * @example\n   * ```ts\n   * // Next.js App Router\n   * export const GET = streamServer.getHandler('nextjs');\n   *\n   * // Express\n   * app.get('/stream', streamServer.getHandler('express'));\n   *\n   * // NestJS controller\n   * const handler = streamServer.getHandler('nestjs');\n   * await handler(req, res);\n   *\n   * // With options\n   * export const GET = streamServer.getHandler('nextjs', { transport: 'sse' });\n   * ```\n   */\n  getHandler<T = unknown>(framework: FrameworkType, options?: FrameworkHandlerOptions): T {\n    const adapter = this.frameworkAdapters.get(framework);\n\n    if (!adapter) {\n      throw new StreamPackageError(\n        `Framework adapter '${framework}' not registered. Available adapters: ${Array.from(this.frameworkAdapters.keys()).join(', ')}`,\n        STREAM_ERROR_CODES.ENDPOINT_NOT_FOUND,\n        { context: { framework, availableAdapters: Array.from(this.frameworkAdapters.keys()) } }\n      );\n    }\n\n    if (!adapter.enabled) {\n      throw new StreamPackageError(\n        `Framework adapter '${framework}' is disabled`,\n        STREAM_ERROR_CODES.ENDPOINT_DISABLED,\n        { context: { framework } }\n      );\n    }\n\n    return adapter.createHandler(\n      (request, transport) => this.handleRequest(request, transport),\n      options\n    ) as T;\n  }\n\n  /**\n   * Get list of registered framework adapters.\n   */\n  getRegisteredFrameworks(): FrameworkType[] {\n    return Array.from(this.frameworkAdapters.keys());\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────\n  // Direct Access\n  // ─────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Get the underlying broadcaster for advanced usage\n   */\n  getBroadcaster(): StreamBroadcaster {\n    return this.broadcaster;\n  }\n\n  /**\n   * Authenticate a request\n   */\n  async authenticate(request: Request): Promise<StreamAuthResult> {\n    return this.broadcaster.authenticate(request);\n  }\n\n  /**\n   * Check if user can subscribe to a channel\n   */\n  canSubscribe(authResult: StreamAuthResult, channel: StreamChannel): boolean {\n    return this.broadcaster.canSubscribe(authResult, channel);\n  }\n\n  /**\n   * Get server statistics\n   */\n  getStats(): StreamManagerStats {\n    return this.broadcaster.getStats();\n  }\n\n  /**\n   * Check if server is initialized\n   */\n  isInitialized(): boolean {\n    return this.initialized;\n  }\n}\n","/**\n * Token Auth Adapter\n *\n * JWT/Bearer token authentication adapter.\n * Validates tokens via a configurable verifier function,\n * allowing integration with any auth provider.\n */\n\nimport type { StreamAuthResult, StreamChannel, TokenAuthAdapterConfig } from '@plyaz/types/core';\nimport { BaseAuthAdapter } from '../BaseAuthAdapter';\n\n/**\n * TokenAuthAdapter - Bearer token authentication\n *\n * Features:\n * - Configurable token verification function\n * - Scope-based channel authorization\n * - Support for custom header names\n *\n * @example\n * ```ts\n * const authAdapter = new TokenAuthAdapter({\n *   name: 'jwt',\n *   verifyToken: async (token) => {\n *     const decoded = await verifyJWT(token);\n *     return {\n *       valid: !!decoded,\n *       userId: decoded?.sub,\n *       scopes: decoded?.scopes,\n *     };\n *   },\n * });\n *\n * // Authenticate request\n * const result = await authAdapter.authenticate(request);\n * if (result.authenticated) {\n *   console.log('User:', result.userId);\n * }\n * ```\n */\nexport class TokenAuthAdapter extends BaseAuthAdapter {\n  private readonly verifyToken: TokenAuthAdapterConfig['verifyToken'];\n  private readonly headerName: string;\n\n  constructor(config: TokenAuthAdapterConfig) {\n    super(config);\n    this.verifyToken = config.verifyToken;\n    this.headerName = config.headerName ?? 'Authorization';\n  }\n\n  /**\n   * Authenticate request using bearer token\n   *\n   * @param request - HTTP request with Authorization header\n   * @returns Authentication result with user info if valid\n   */\n  async authenticate(request: Request): Promise<StreamAuthResult> {\n    const header = request.headers.get(this.headerName);\n\n    if (!header) {\n      return { authenticated: false };\n    }\n\n    // Extract token from \"Bearer <token>\" format\n    const BEARER_PREFIX_LENGTH = 7;\n    const token = header.startsWith('Bearer ') ? header.slice(BEARER_PREFIX_LENGTH) : header;\n\n    try {\n      const result = await this.verifyToken(token);\n\n      return {\n        authenticated: result.valid,\n        userId: result.userId,\n        scopes: result.scopes,\n      };\n    } catch {\n      // Token verification failed\n      return { authenticated: false };\n    }\n  }\n\n  /**\n   * Check if user can subscribe to a channel\n   *\n   * Rules:\n   * - 'system' channel requires authentication\n   * - If scopes provided, channel must match a scope prefix\n   * - Otherwise, allow subscription\n   *\n   * @param userId - User ID (undefined for anonymous)\n   * @param channel - Channel to subscribe\n   * @param scopes - User's allowed scopes\n   */\n  canSubscribe(userId: string | undefined, channel: StreamChannel, scopes?: string[]): boolean {\n    // System channel requires authentication\n    if (channel === 'system' && !userId) {\n      return false;\n    }\n\n    // If no scopes defined, allow all (for backwards compatibility)\n    if (!scopes || scopes.length === 0) {\n      return true;\n    }\n\n    // Check if channel matches any scope prefix\n    // e.g., scope 'upload:' allows 'upload:abc123'\n    return scopes.some(scope => channel.startsWith(scope) || channel === scope);\n  }\n}\n","/**\n * WebSocket Transport Adapter\n *\n * WebSocket transport for real-time bidirectional streaming.\n * Provides an alternative to SSE with support for client-to-server messages.\n *\n * NOTE: This is a placeholder implementation. Full WebSocket support requires\n * runtime-specific handling (Node.js 'ws' package, Bun/Deno native WebSocket, etc.)\n *\n * For production use:\n * - Node.js: Use 'ws' package with HTTP upgrade\n * - Bun: Use Bun.serve with websocket option\n * - Deno: Use Deno.upgradeWebSocket\n * - Next.js: WebSocket requires custom server, not supported in serverless\n */\n\nimport type { StreamMessage, StreamTransportAdapterConfig } from '@plyaz/types/core';\nimport type { ErrorResponse } from '@plyaz/types/errors';\nimport { STREAM_ERROR_CODES } from '@plyaz/types/errors';\nimport { HTTP_STATUS } from '@plyaz/types';\nimport { BaseTransportAdapter } from '../BaseTransportAdapter';\n\n/**\n * WebSocket close codes\n */\nconst WS_CLOSE_NORMAL = 1000;\nconst WS_CLOSE_TRY_AGAIN = 1013;\n\n/**\n * Internal WebSocket connection state\n */\ninterface WebSocketConnection {\n  socket: WebSocket;\n  heartbeatTimer?: ReturnType<typeof setInterval>;\n  createdAt: Date;\n}\n\n/**\n * WebSocketTransportAdapter - WebSocket transport\n *\n * Features:\n * - Bidirectional communication\n * - Automatic heartbeat (ping/pong)\n * - JSON message formatting\n * - Connection cleanup on disconnect\n *\n * @example\n * ```ts\n * // With Bun\n * const wsAdapter = new WebSocketTransportAdapter();\n *\n * Bun.serve({\n *   fetch(req, server) {\n *     const success = server.upgrade(req, { data: { connectionId } });\n *     if (success) return undefined;\n *     return new Response('WebSocket upgrade failed', { status: 400 });\n *   },\n *   websocket: {\n *     open(ws) { wsAdapter.registerConnection(connectionId, ws); },\n *     message(ws, message) { wsAdapter.handleMessage(connectionId, message); },\n *     close(ws) { wsAdapter.close(connectionId); },\n *   },\n * });\n * ```\n */\nexport class WebSocketTransportAdapter extends BaseTransportAdapter {\n  private connections = new Map<string, WebSocketConnection>();\n\n  constructor(config?: Partial<StreamTransportAdapterConfig>) {\n    super({\n      name: config?.name ?? 'websocket',\n      type: 'websocket',\n      heartbeatInterval: config?.heartbeatInterval,\n      maxConnections: config?.maxConnections,\n    });\n  }\n\n  /**\n   * Create a new WebSocket connection.\n   *\n   * NOTE: In most runtimes, WebSocket connections are created via HTTP upgrade,\n   * not through this method directly. Use registerConnection() instead.\n   *\n   * @param _connectionId - Unique connection identifier\n   * @returns Response indicating WebSocket upgrade is needed\n   */\n  // eslint-disable-next-line no-unused-vars\n  async createConnection(_connectionId: string): Promise<Response> {\n    // WebSocket connections are established through HTTP upgrade, not here\n    // This returns an error response; use runtime-specific upgrade instead\n    const errorResponse: ErrorResponse = [\n      {\n        errorCode: STREAM_ERROR_CODES.TRANSPORT_NOT_SUPPORTED,\n        message:\n          'WebSocket connections require HTTP upgrade. Use runtime-specific WebSocket upgrade mechanism.',\n      },\n    ];\n\n    return new Response(JSON.stringify(errorResponse), {\n      status: HTTP_STATUS.UPGRADE_REQUIRED,\n      headers: {\n        'Content-Type': 'application/json',\n        Upgrade: 'websocket',\n      },\n    });\n  }\n\n  /**\n   * Register an already-upgraded WebSocket connection.\n   * Call this from your runtime's WebSocket open handler.\n   *\n   * @param connectionId - Unique connection identifier\n   * @param socket - The WebSocket instance\n   */\n  registerConnection(connectionId: string, socket: WebSocket): void {\n    if (!this.canAcceptConnection()) {\n      socket.close(WS_CLOSE_TRY_AGAIN, 'Too many connections');\n      return;\n    }\n\n    const connection: WebSocketConnection = {\n      socket,\n      createdAt: new Date(),\n    };\n\n    this.connections.set(connectionId, connection);\n\n    // Send initial connection message\n    this.sendImmediate(socket, {\n      event: 'connected',\n      data: { connectionId, timestamp: Date.now() },\n    });\n\n    // Start heartbeat (using WebSocket ping/pong)\n    connection.heartbeatTimer = setInterval(() => {\n      if (!this.isAlive(connectionId)) {\n        this.cleanup(connectionId);\n        return;\n      }\n      // Send ping - most WebSocket implementations handle pong automatically\n      this.sendImmediate(socket, {\n        event: 'heartbeat',\n        data: { timestamp: Date.now() },\n      });\n    }, this.heartbeatInterval);\n  }\n\n  /**\n   * Handle incoming message from WebSocket.\n   * Call this from your runtime's WebSocket message handler.\n   *\n   * @param _connectionId - Connection that sent the message\n   * @param message - Raw message data\n   * @returns Parsed message or null if invalid\n   */\n  handleMessage(_connectionId: string, message: string | ArrayBuffer): StreamMessage | null {\n    try {\n      const data = typeof message === 'string' ? message : new TextDecoder().decode(message);\n      return JSON.parse(data) as StreamMessage;\n    } catch {\n      return null;\n    }\n  }\n\n  /**\n   * Send a message to a connection.\n   *\n   * @param connectionId - Connection to send to\n   * @param message - Message to send\n   */\n  async send(connectionId: string, message: StreamMessage): Promise<void> {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return;\n\n    try {\n      this.sendImmediate(connection.socket, message);\n    } catch {\n      // Connection likely closed, cleanup\n      this.cleanup(connectionId);\n    }\n  }\n\n  /**\n   * Close a connection.\n   *\n   * @param connectionId - Connection to close\n   */\n  async close(connectionId: string): Promise<void> {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return;\n\n    try {\n      // Send close event before closing\n      this.sendImmediate(connection.socket, {\n        event: 'close',\n        data: { reason: 'server_close' },\n      });\n      connection.socket.close(WS_CLOSE_NORMAL, 'Server closing');\n    } catch {\n      // Already closed\n    }\n\n    this.cleanup(connectionId);\n  }\n\n  /**\n   * Check if a connection is alive.\n   *\n   * @param connectionId - Connection to check\n   */\n  isAlive(connectionId: string): boolean {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return false;\n    return connection.socket.readyState === WebSocket.OPEN;\n  }\n\n  /**\n   * Get current connection count.\n   */\n  getConnectionCount(): number {\n    return this.connections.size;\n  }\n\n  /**\n   * Get all connection IDs.\n   */\n  getConnectionIds(): string[] {\n    return Array.from(this.connections.keys());\n  }\n\n  /**\n   * Send message immediately to socket.\n   */\n  private sendImmediate(socket: WebSocket, message: StreamMessage): void {\n    if (socket.readyState !== WebSocket.OPEN) return;\n    socket.send(JSON.stringify(message));\n  }\n\n  /**\n   * Cleanup connection resources.\n   */\n  private cleanup(connectionId: string): void {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return;\n\n    // Clear heartbeat timer\n    if (connection.heartbeatTimer) {\n      clearInterval(connection.heartbeatTimer);\n    }\n\n    // Remove from map\n    this.connections.delete(connectionId);\n  }\n\n  /**\n   * Close all connections (for shutdown).\n   */\n  async closeAll(): Promise<void> {\n    const connectionIds = this.getConnectionIds();\n    await Promise.all(connectionIds.map(id => this.close(id)));\n  }\n}\n","/**\n * Stream Registry\n *\n * Auto-discovery and initialization for stream endpoints.\n * Similar to ServiceRegistry but for real-time streaming.\n *\n * @example\n * ```typescript\n * import { StreamServer, StreamRegistry } from '@plyaz/core/events/streaming';\n * import { FilesStreamEndpoint } from '@plyaz/core/domain/files/streaming';\n * import { SystemStreamEndpoint } from '@plyaz/core/events/streaming/endpoints';\n *\n * // Create stream server\n * const streamServer = StreamServer.create()\n *   .withAuth(new TokenAuthAdapter({ verifyToken: myVerifier }))\n *   .withSSE({ heartbeatInterval: 15000 })\n *   .build();\n *\n * // Initialize stream registry (like ServiceRegistry)\n * await StreamRegistry.initialize({\n *   broadcaster: streamServer.getBroadcaster(),\n *   endpoints: [\n *     { endpoint: FilesStreamEndpoint, config: { enabled: true } },\n *     { endpoint: SystemStreamEndpoint, config: { enabled: true } },\n *   ],\n * });\n * ```\n */\n\nimport { CoreLogger } from '@plyaz/logger';\nimport { StreamPackageError } from '@plyaz/errors';\nimport { STREAM_ERROR_CODES } from '@plyaz/types/errors';\nimport type {\n  StreamEndpointConfig,\n  StreamRegistryConfig,\n  StreamBroadcasterInterface,\n} from '@plyaz/types/core';\nimport type { BaseStreamEndpoint } from './base/BaseStreamEndpoint';\nimport type { BaseChannelController } from './channels/BaseChannelController';\n\n/**\n * Global Singleton Pattern using globalThis for static class state\n *\n * @see CoreEventManager.ts for detailed explanation of why this pattern is needed.\n *\n * TL;DR: In Next.js and similar frameworks, module isolation can create multiple\n * instances of static class state. Using globalThis + Symbol.for() ensures ONE\n * shared state per process, preventing issues like stream endpoints being registered\n * in one module context but not accessible from another (e.g., API routes).\n */\ninterface StreamRegistryState {\n  endpoints: Map<string, BaseStreamEndpoint>;\n  controllers: Map<string, BaseChannelController>;\n  broadcaster: StreamBroadcasterInterface | null;\n  initialized: boolean;\n}\n\nconst STREAM_REGISTRY_KEY = Symbol.for('plyaz.StreamRegistry');\n\nfunction getStreamRegistryState(): StreamRegistryState {\n  const globalAny = globalThis as unknown as { [key: symbol]: StreamRegistryState };\n  if (!globalAny[STREAM_REGISTRY_KEY]) {\n    globalAny[STREAM_REGISTRY_KEY] = {\n      endpoints: new Map(),\n      controllers: new Map(),\n      broadcaster: null,\n      initialized: false,\n    };\n  }\n  return globalAny[STREAM_REGISTRY_KEY];\n}\n\n/**\n * StreamRegistry - Auto-discovery and initialization for stream endpoints\n *\n * Features:\n * - Auto-initialization of stream endpoints\n * - get() and getAsync() access patterns (like ServiceRegistry)\n * - Lifecycle management\n * - Controller registration with broadcaster\n */\nexport class StreamRegistry {\n  private static readonly logger = new CoreLogger({\n    service: 'StreamRegistry',\n  });\n\n  // State accessors using globalThis\n  private static get _endpoints(): Map<string, BaseStreamEndpoint> {\n    return getStreamRegistryState().endpoints;\n  }\n  private static get _controllers(): Map<string, BaseChannelController> {\n    return getStreamRegistryState().controllers;\n  }\n  private static get _broadcaster(): StreamBroadcasterInterface | null {\n    return getStreamRegistryState().broadcaster;\n  }\n  private static set _broadcaster(value: StreamBroadcasterInterface | null) {\n    getStreamRegistryState().broadcaster = value;\n  }\n  private static get _initialized(): boolean {\n    return getStreamRegistryState().initialized;\n  }\n  private static set _initialized(value: boolean) {\n    getStreamRegistryState().initialized = value;\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Initialization\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Initialize the stream registry with endpoints.\n   *\n   * @param config - Registry configuration\n   * @throws StreamPackageError if already initialized or endpoint fails\n   *\n   * @example\n   * ```typescript\n   * await StreamRegistry.initialize({\n   *   broadcaster: streamServer.getBroadcaster(),\n   *   endpoints: [\n   *     { endpoint: FilesStreamEndpoint, config: { enabled: true } },\n   *     { endpoint: SystemStreamEndpoint, config: { enabled: true } },\n   *   ],\n   * });\n   * ```\n   */\n  static async initialize(config: StreamRegistryConfig): Promise<void> {\n    if (StreamRegistry._initialized) {\n      StreamRegistry.logger.warn('StreamRegistry already initialized');\n      return;\n    }\n\n    StreamRegistry._broadcaster = config.broadcaster;\n\n    for (const entry of config.endpoints) {\n      const endpointKey = entry.endpoint.endpointKey;\n      const enabled = entry.config.enabled !== false;\n\n      if (!enabled) {\n        StreamRegistry.logger.debug(`Endpoint ${endpointKey} is disabled, skipping`);\n        continue;\n      }\n\n      try {\n        // Create endpoint configuration\n        const endpointConfig: StreamEndpointConfig = {\n          endpointKey,\n          name: entry.config.name ?? endpointKey,\n          channels: entry.config.channels ?? [],\n          enabled: entry.config.enabled,\n          supportedRuntimes: entry.config.supportedRuntimes,\n        };\n\n        // Create endpoint instance via static create()\n        const instance = (await entry.endpoint.create(endpointConfig, {\n          broadcaster: config.broadcaster,\n        })) as BaseStreamEndpoint;\n\n        // Initialize the endpoint\n        instance.initialize();\n\n        // Get the channel controller\n        const controller = instance.getChannelController();\n\n        // Register controller with broadcaster (if it supports this)\n        if ('registerController' in config.broadcaster) {\n          (\n            config.broadcaster as { registerController: (c: BaseChannelController) => void }\n          ).registerController(controller);\n        }\n\n        // Store endpoint and controller\n        StreamRegistry._endpoints.set(endpointKey, instance);\n        StreamRegistry._controllers.set(controller.scope, controller);\n\n        StreamRegistry.logger.info(`Endpoint initialized: ${endpointKey}`, {\n          scope: controller.scope,\n          patterns: controller.getPatterns(),\n        });\n      } catch (error) {\n        StreamRegistry.logger.error(`Failed to initialize endpoint: ${endpointKey}`, { error });\n        throw error;\n      }\n    }\n\n    StreamRegistry._initialized = true;\n    StreamRegistry.logger.info('StreamRegistry initialized', {\n      endpoints: [...StreamRegistry._endpoints.keys()],\n      controllers: [...StreamRegistry._controllers.keys()],\n    });\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Endpoint Access\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Get an endpoint by key (synchronous).\n   *\n   * @param key - Endpoint key\n   * @returns Endpoint instance\n   * @throws StreamPackageError if endpoint not found\n   *\n   * @example\n   * ```typescript\n   * const filesEndpoint = StreamRegistry.get<FilesStreamEndpoint>('files');\n   * ```\n   */\n  static get<T extends BaseStreamEndpoint>(key: string): T {\n    const endpoint = StreamRegistry._endpoints.get(key);\n    if (!endpoint) {\n      throw new StreamPackageError(\n        `Stream endpoint '${key}' not found. Register it in StreamRegistry.initialize()`,\n        STREAM_ERROR_CODES.ENDPOINT_NOT_FOUND\n      );\n    }\n    return endpoint as T;\n  }\n\n  /**\n   * Get an endpoint by key (async for lazy initialization if needed).\n   *\n   * @param key - Endpoint key\n   * @returns Promise resolving to endpoint instance\n   */\n  static async getAsync<T extends BaseStreamEndpoint>(key: string): Promise<T> {\n    return StreamRegistry.get<T>(key);\n  }\n\n  /**\n   * Check if an endpoint is registered.\n   *\n   * @param key - Endpoint key\n   * @returns true if endpoint is registered\n   */\n  static has(key: string): boolean {\n    return StreamRegistry._endpoints.has(key);\n  }\n\n  /**\n   * Get all registered endpoint keys.\n   *\n   * @returns Array of endpoint keys\n   */\n  static getRegisteredKeys(): string[] {\n    return [...StreamRegistry._endpoints.keys()];\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Controller Access\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Get a controller by scope.\n   *\n   * @param scope - Controller scope\n   * @returns Controller instance or undefined\n   */\n  static getController(scope: string): BaseChannelController | undefined {\n    return StreamRegistry._controllers.get(scope);\n  }\n\n  /**\n   * Get controller for a channel.\n   *\n   * @param channel - Channel name\n   * @returns Controller that handles the channel, or undefined\n   */\n  static getControllerForChannel(channel: string): BaseChannelController | undefined {\n    for (const controller of StreamRegistry._controllers.values()) {\n      if (controller.handlesChannel(channel)) {\n        return controller;\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * Get all registered controller scopes.\n   *\n   * @returns Array of controller scopes\n   */\n  static getRegisteredScopes(): string[] {\n    return [...StreamRegistry._controllers.keys()];\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Broadcaster Access\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Get the broadcaster instance.\n   *\n   * @returns Broadcaster instance\n   * @throws StreamPackageError if not initialized\n   */\n  static getBroadcaster(): StreamBroadcasterInterface {\n    if (!StreamRegistry._broadcaster) {\n      throw new StreamPackageError(\n        'StreamRegistry not initialized. Call StreamRegistry.initialize() first.',\n        STREAM_ERROR_CODES.INITIALIZATION_FAILED\n      );\n    }\n    return StreamRegistry._broadcaster;\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Status\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Check if registry is initialized.\n   *\n   * @returns true if initialized\n   */\n  static isInitialized(): boolean {\n    return StreamRegistry._initialized;\n  }\n\n  /**\n   * Get registry statistics.\n   *\n   * @returns Statistics object\n   */\n  static getStats(): {\n    initialized: boolean;\n    endpointCount: number;\n    controllerCount: number;\n    endpoints: string[];\n    controllers: string[];\n  } {\n    return {\n      initialized: StreamRegistry._initialized,\n      endpointCount: StreamRegistry._endpoints.size,\n      controllerCount: StreamRegistry._controllers.size,\n      endpoints: StreamRegistry.getRegisteredKeys(),\n      controllers: StreamRegistry.getRegisteredScopes(),\n    };\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Lifecycle\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Dispose all endpoints and reset registry.\n   */\n  static dispose(): void {\n    StreamRegistry.logger.info('Disposing StreamRegistry');\n\n    // Dispose all endpoints\n    StreamRegistry._endpoints.forEach((endpoint, key) => {\n      try {\n        endpoint.dispose();\n        StreamRegistry.logger.debug(`Disposed endpoint: ${key}`);\n      } catch (error) {\n        StreamRegistry.logger.error(`Error disposing endpoint: ${key}`, { error });\n      }\n    });\n\n    // Clear all maps\n    StreamRegistry._endpoints.clear();\n    StreamRegistry._controllers.clear();\n    StreamRegistry._broadcaster = null;\n    StreamRegistry._initialized = false;\n\n    StreamRegistry.logger.info('StreamRegistry disposed');\n  }\n\n  /**\n   * Reset registry (for testing).\n   */\n  static reset(): void {\n    StreamRegistry.dispose();\n  }\n}\n","/**\n * Base Stream Endpoint\n *\n * Abstract base class for stream endpoints, following patterns from BaseBackendDomainService.\n * Each endpoint manages a set of channels and their event handlers.\n *\n * @example\n * ```typescript\n * class FilesStreamEndpoint extends BaseStreamEndpoint {\n *   static readonly endpointKey = 'files';\n *\n *   protected createChannelController(): BaseChannelController {\n *     return new FilesChannelController();\n *   }\n *\n *   initialize(): void {\n *     this.channelController.initialize(this.broadcaster);\n *     this.logger.info('FilesStreamEndpoint initialized');\n *   }\n *\n *   static async create(\n *     config: StreamEndpointConfig,\n *     options: StreamEndpointCreateOptions\n *   ): Promise<FilesStreamEndpoint> {\n *     return new FilesStreamEndpoint(config, options);\n *   }\n * }\n * ```\n */\n\nimport { CoreLogger } from '@plyaz/logger';\nimport type {\n  StreamEndpointConfig,\n  StreamEndpointCreateOptions,\n  StreamBroadcasterInterface,\n  StreamResponse,\n  StreamErrorEvent,\n  StreamChannel,\n  StreamConnection,\n  StreamAuthResult,\n} from '@plyaz/types/core';\nimport type { ErrorResponse } from '@plyaz/types/errors';\nimport { STREAM_ERROR_CODES } from '@plyaz/types/errors';\nimport { StreamPackageError } from '@plyaz/errors';\nimport type { BaseChannelController } from '../channels/BaseChannelController';\n\n/**\n * BaseStreamEndpoint - Abstract base for stream endpoints\n *\n * Similar to BaseBackendDomainService but for real-time streaming.\n * Provides:\n * - Static create() for initialization (like domain services)\n * - Lifecycle hooks (beforeSubscribe, afterSubscribe, etc.)\n * - Channel controller management\n * - Error handling with standard ErrorResponse format\n * - Response formatting consistent with API patterns\n */\nexport abstract class BaseStreamEndpoint {\n  /**\n   * Static endpoint key (like serviceKey in domain services).\n   * Override in subclass.\n   */\n  static readonly endpointKey: string;\n\n  /** Logger instance */\n  protected readonly logger: CoreLogger;\n\n  /** Endpoint configuration */\n  protected readonly config: StreamEndpointConfig;\n\n  /** Broadcaster interface */\n  protected readonly broadcaster: StreamBroadcasterInterface;\n\n  /** Channel controller for this endpoint */\n  protected readonly channelController: BaseChannelController;\n\n  /** Unsubscribe functions for cleanup */\n  protected readonly unsubscribers: Array<() => void> = [];\n\n  constructor(config: StreamEndpointConfig, options: StreamEndpointCreateOptions) {\n    this.config = config;\n    this.broadcaster = options.broadcaster;\n\n    this.logger = new CoreLogger({\n      service: `StreamEndpoint:${config.endpointKey}`,\n    });\n\n    // Create channel controller for this endpoint\n    this.channelController = this.createChannelController();\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Abstract Methods (must implement)\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Create the channel controller for this endpoint.\n   * Called during construction.\n   */\n  protected abstract createChannelController(): BaseChannelController;\n\n  /**\n   * Initialize event subscriptions.\n   * Called by StreamRegistry during initialization.\n   */\n  abstract initialize(): void;\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Static Factory (like domain services)\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Create endpoint instance.\n   * Override in subclass with proper typing.\n   *\n   * @param config - Endpoint configuration\n   * @param options - Create options (broadcaster, auth, etc.)\n   * @returns Promise resolving to endpoint instance\n   */\n\n  static async create(\n    // eslint-disable-next-line no-unused-vars\n    _config: StreamEndpointConfig,\n    // eslint-disable-next-line no-unused-vars\n    _options: StreamEndpointCreateOptions\n  ): Promise<BaseStreamEndpoint> {\n    throw new StreamPackageError(\n      'Subclass must implement static create()',\n      STREAM_ERROR_CODES.TRANSPORT_NOT_SUPPORTED,\n      { context: { endpoint: this.endpointKey ?? 'unknown' } }\n    );\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Lifecycle Hooks (optional - override in subclass)\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Called before a connection subscribes to a channel.\n   * Return false to prevent subscription.\n   *\n   * @param channel - Channel being subscribed to\n   * @param connection - Connection subscribing\n   * @param authResult - Authentication result for the connection\n   * @returns true to allow subscription, false to deny\n   */\n  protected async beforeSubscribe?(\n    channel: StreamChannel,\n    connection: StreamConnection,\n    authResult: StreamAuthResult\n  ): Promise<boolean>;\n\n  /**\n   * Called after a connection subscribes to a channel.\n   *\n   * @param channel - Channel subscribed to\n   * @param connection - Connection that subscribed\n   */\n  protected async afterSubscribe?(\n    channel: StreamChannel,\n    connection: StreamConnection\n  ): Promise<void>;\n\n  /**\n   * Called before a connection unsubscribes from a channel.\n   *\n   * @param channel - Channel being unsubscribed from\n   * @param connectionId - Connection ID unsubscribing\n   */\n  protected async beforeUnsubscribe?(channel: StreamChannel, connectionId: string): Promise<void>;\n\n  /**\n   * Called when a new connection is established.\n   *\n   * @param connection - The new connection\n   */\n  protected async onConnect?(connection: StreamConnection): Promise<void>;\n\n  /**\n   * Called when a connection is closed.\n   *\n   * @param connectionId - ID of the closed connection\n   */\n  protected async onDisconnect?(connectionId: string): Promise<void>;\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Response Helpers (consistent with API patterns)\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Create a success response.\n   *\n   * @param data - Response data payload\n   * @param channel - Channel this response is for\n   * @param message - Human-readable message (default: 'Success')\n   * @returns Formatted StreamResponse\n   */\n  protected createResponse<T>(data: T, channel: string, message = 'Success'): StreamResponse<T> {\n    return {\n      success: true,\n      message,\n      data,\n      channel,\n      timestamp: Date.now(),\n      correlationId: crypto.randomUUID(),\n    };\n  }\n\n  /**\n   * Create an error response using standard ErrorResponse format.\n   *\n   * @param errors - Array of error details\n   * @param channel - Channel this error occurred on\n   * @returns Formatted StreamErrorEvent\n   */\n  protected createErrorResponse(\n    errors: Array<{ errorCode: string; message: string; field?: string }>,\n    channel: string\n  ): StreamErrorEvent {\n    // Convert to standard ErrorResponse format\n    const errorResponse: ErrorResponse = errors.map(e => ({\n      errorCode: e.errorCode,\n      message: e.message,\n      field: e.field,\n    }));\n\n    return {\n      success: false,\n      errors: errorResponse,\n      channel,\n      timestamp: Date.now(),\n      correlationId: crypto.randomUUID(),\n    };\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Public API\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Get endpoint configuration.\n   */\n  getConfig(): StreamEndpointConfig {\n    return this.config;\n  }\n\n  /**\n   * Get the endpoint key.\n   */\n  getEndpointKey(): string {\n    return this.config.endpointKey;\n  }\n\n  /**\n   * Get channel controller.\n   */\n  getChannelController(): BaseChannelController {\n    return this.channelController;\n  }\n\n  /**\n   * Check if endpoint handles a channel.\n   *\n   * @param channel - Channel to check\n   * @returns true if this endpoint handles the channel\n   */\n  handlesChannel(channel: StreamChannel): boolean {\n    return this.channelController.handlesChannel(channel);\n  }\n\n  /**\n   * Check if endpoint is enabled.\n   */\n  isEnabled(): boolean {\n    return this.config.enabled !== false;\n  }\n\n  /**\n   * Check if endpoint supports the current runtime.\n   *\n   * @param runtime - Runtime to check\n   * @returns true if supported\n   */\n  supportsRuntime(runtime: 'node' | 'bun' | 'deno' | 'edge'): boolean {\n    if (!this.config.supportedRuntimes) return true;\n    return this.config.supportedRuntimes.includes(runtime);\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Lifecycle\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Dispose endpoint and cleanup.\n   */\n  dispose(): void {\n    this.logger.debug('Disposing endpoint', { key: this.config.endpointKey });\n\n    // Call all unsubscribe functions\n    this.unsubscribers.forEach(unsub => {\n      try {\n        unsub();\n      } catch (error) {\n        this.logger.error('Error during unsubscribe', { error });\n      }\n    });\n\n    // Clear unsubscribers\n    this.unsubscribers.length = 0;\n\n    // Dispose channel controller\n    this.channelController.dispose();\n\n    this.logger.debug('Endpoint disposed', { key: this.config.endpointKey });\n  }\n\n  /**\n   * Add an unsubscribe function to be called on dispose.\n   *\n   * @param unsub - Unsubscribe function\n   */\n  protected addUnsubscriber(unsub: () => void): void {\n    this.unsubscribers.push(unsub);\n  }\n}\n","/**\n * Base Channel Controller\n *\n * Abstract base class for channel event handlers.\n * Each controller manages a specific scope of channels (e.g., 'upload:', 'generate:', 'system').\n *\n * @example\n * ```typescript\n * class FilesChannelController extends BaseChannelController {\n *   constructor() {\n *     super({\n *       scope: 'files',\n *       patterns: ['upload:', 'uploads', 'generate:'],\n *     });\n *   }\n *\n *   initialize(broadcaster: StreamBroadcasterInterface): void {\n *     this.unsubscribers.push(\n *       CoreEventManager.on('files:upload:progress', event => {\n *         broadcaster.broadcastToChannel(`upload:${event.data.fileId}`, {\n *           event: 'progress',\n *           data: this.createResponse(event.data, `upload:${event.data.fileId}`),\n *         });\n *       })\n *     );\n *   }\n * }\n * ```\n */\n\nimport { CoreLogger } from '@plyaz/logger';\nimport type {\n  ChannelControllerConfig,\n  StreamBroadcasterInterface,\n  StreamResponse,\n  StreamErrorEvent,\n} from '@plyaz/types/core';\nimport type { ErrorResponse } from '@plyaz/types/errors';\n\n/**\n * BaseChannelController - Abstract base for channel event handlers\n *\n * Features:\n * - Pattern matching for channels\n * - Response formatting helpers (consistent with API patterns)\n * - Subscription management with automatic cleanup\n * - Error response using standard ErrorResponse format\n */\nexport abstract class BaseChannelController {\n  /** Channel scope (e.g., 'upload', 'generate', 'system') */\n  readonly scope: string;\n\n  /** Channel patterns this controller handles */\n  readonly patterns: string[];\n\n  /** Whether controller is enabled */\n  readonly enabled: boolean;\n\n  /** Logger instance */\n  protected readonly logger: CoreLogger;\n\n  /** Unsubscribe functions for cleanup */\n  protected unsubscribers: Array<() => void> = [];\n\n  constructor(config: ChannelControllerConfig) {\n    this.scope = config.scope;\n    this.patterns = config.patterns;\n    this.enabled = config.enabled ?? true;\n\n    this.logger = new CoreLogger({\n      service: `ChannelController:${config.scope}`,\n    });\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Abstract Methods\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Initialize event subscriptions.\n   * Called when the controller is registered with the broadcaster.\n   *\n   * @param broadcaster - The broadcaster to send messages through\n   */\n  abstract initialize(broadcaster: StreamBroadcasterInterface): void;\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Channel Matching\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Check if this controller handles a given channel.\n   *\n   * @param channel - Channel name to check\n   * @returns true if this controller handles the channel\n   */\n  handlesChannel(channel: string): boolean {\n    // Check exact match or scope prefix\n    return this.patterns.some(\n      pattern => channel === pattern || channel.startsWith(`${this.scope}:`)\n    );\n  }\n\n  /**\n   * Get all patterns this controller handles.\n   */\n  getPatterns(): string[] {\n    return [...this.patterns];\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Response Helpers (consistent with API ReturnResponseType)\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Create a success response.\n   *\n   * @param data - Response data payload\n   * @param channel - Channel this response is for\n   * @param message - Human-readable message (default: 'Success')\n   * @returns Formatted StreamResponse\n   */\n  protected createResponse<T>(data: T, channel: string, message = 'Success'): StreamResponse<T> {\n    return {\n      success: true,\n      message,\n      data,\n      channel,\n      timestamp: Date.now(),\n      correlationId: crypto.randomUUID(),\n    };\n  }\n\n  /**\n   * Create an error response using standard ErrorResponse format.\n   *\n   * @param errors - Array of error details\n   * @param channel - Channel this error occurred on\n   * @returns Formatted StreamErrorEvent\n   */\n  protected createErrorResponse(\n    errors: Array<{ errorCode: string; message: string; field?: string }>,\n    channel: string\n  ): StreamErrorEvent {\n    // Convert to standard ErrorResponse format\n    const errorResponse: ErrorResponse = errors.map(e => ({\n      errorCode: e.errorCode,\n      message: e.message,\n      field: e.field,\n    }));\n\n    return {\n      success: false,\n      errors: errorResponse,\n      channel,\n      timestamp: Date.now(),\n      correlationId: crypto.randomUUID(),\n    };\n  }\n\n  /**\n   * Create a single error response.\n   *\n   * @param errorCode - Error code\n   * @param message - Error message\n   * @param channel - Channel this error occurred on\n   * @param field - Optional field that caused the error\n   * @returns Formatted StreamErrorEvent\n   */\n  protected createSingleError(\n    errorCode: string,\n    message: string,\n    channel: string,\n    field?: string\n  ): StreamErrorEvent {\n    return this.createErrorResponse([{ errorCode, message, field }], channel);\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Lifecycle\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /**\n   * Dispose controller and cleanup subscriptions.\n   */\n  dispose(): void {\n    this.logger.debug('Disposing controller', { scope: this.scope });\n\n    // Call all unsubscribe functions\n    this.unsubscribers.forEach(unsub => {\n      try {\n        unsub();\n      } catch (error) {\n        this.logger.error('Error during unsubscribe', { error });\n      }\n    });\n\n    this.unsubscribers = [];\n    this.logger.debug('Controller disposed', { scope: this.scope });\n  }\n\n  /**\n   * Add an unsubscribe function to be called on dispose.\n   *\n   * @param unsub - Unsubscribe function\n   */\n  protected addUnsubscriber(unsub: () => void): void {\n    this.unsubscribers.push(unsub);\n  }\n}\n","/**\n * ID Generation Utilities\n *\n * Provides consistent ID generation across the application.\n * Uses globalThis.crypto when available, with a fallback for environments without it.\n *\n * @fileoverview ID generation utility functions\n */\n\n// Constants for ID generation\nconst RANDOM_ID_RADIX = 36;\nconst RANDOM_ID_SLICE_START = 2;\nconst SHORT_ID_LENGTH = 8;\nconst HEX_RADIX = 16;\nconst HEX_SLICE_START = 2;\nconst HEX_SLICE_END = 18;\nconst SPAN_ID_LENGTH = 16;\n\n/**\n * Generate a UUID v4 string.\n * Uses crypto.randomUUID when available, otherwise falls back to a timestamp-based ID.\n *\n * @returns A UUID v4 string or fallback ID\n *\n * @example\n * ```typescript\n * const id = generateId();\n * // => 'a1b2c3d4-e5f6-7890-abcd-ef1234567890' (crypto available)\n * // => '1701475200000-x7k9m2' (fallback)\n * ```\n */\nexport function generateId(): string {\n  const cryptoApi = globalThis.crypto as { randomUUID?: () => string } | undefined;\n  if (cryptoApi?.randomUUID) {\n    return cryptoApi.randomUUID();\n  }\n  return `${Date.now()}-${Math.random().toString(RANDOM_ID_RADIX).slice(RANDOM_ID_SLICE_START)}`;\n}\n\n/**\n * Generate a short random ID (8 characters).\n * Useful for correlation IDs, short references, etc.\n *\n * @returns A short random string\n *\n * @example\n * ```typescript\n * const shortId = generateShortId();\n * // => 'x7k9m2ab'\n * ```\n */\nexport function generateShortId(): string {\n  const cryptoApi = globalThis.crypto as { randomUUID?: () => string } | undefined;\n  if (cryptoApi?.randomUUID) {\n    return cryptoApi.randomUUID().replace(/-/g, '').slice(0, SHORT_ID_LENGTH);\n  }\n  return Math.random()\n    .toString(RANDOM_ID_RADIX)\n    .slice(RANDOM_ID_SLICE_START, RANDOM_ID_SLICE_START + SHORT_ID_LENGTH);\n}\n\n/**\n * Generate a correlation ID for tracing.\n * Format: timestamp-randomString\n *\n * @returns A correlation ID string\n *\n * @example\n * ```typescript\n * const correlationId = generateCorrelationId();\n * // => '1701475200000-x7k9m2'\n * ```\n */\nexport function generateCorrelationId(): string {\n  return `${Date.now()}-${generateShortId()}`;\n}\n\n/**\n * Generate a trace ID for distributed tracing (32 hex characters / 128 bits).\n *\n * @returns A 32-character hex string\n *\n * @example\n * ```typescript\n * const traceId = generateTraceId();\n * // => 'a1b2c3d4e5f67890abcdef1234567890'\n * ```\n */\nexport function generateTraceId(): string {\n  const cryptoApi = globalThis.crypto as { randomUUID?: () => string } | undefined;\n  if (cryptoApi?.randomUUID) {\n    // Use two UUIDs without dashes to get 64 hex chars, take first 32\n    return cryptoApi.randomUUID().replace(/-/g, '');\n  }\n  // Fallback: concatenate two random hex strings\n  return (\n    Math.random().toString(HEX_RADIX).substring(HEX_SLICE_START, HEX_SLICE_END) +\n    Math.random().toString(HEX_RADIX).substring(HEX_SLICE_START, HEX_SLICE_END)\n  );\n}\n\n/**\n * Generate a span ID for distributed tracing (16 hex characters / 64 bits).\n *\n * @returns A 16-character hex string\n *\n * @example\n * ```typescript\n * const spanId = generateSpanId();\n * // => 'a1b2c3d4e5f67890'\n * ```\n */\nexport function generateSpanId(): string {\n  const cryptoApi = globalThis.crypto as { randomUUID?: () => string } | undefined;\n  if (cryptoApi?.randomUUID) {\n    // Use UUID without dashes, take first 16 chars\n    return cryptoApi.randomUUID().replace(/-/g, '').substring(0, SPAN_ID_LENGTH);\n  }\n  // Fallback: random hex string\n  return Math.random().toString(HEX_RADIX).substring(HEX_SLICE_START, HEX_SLICE_END);\n}\n\n/**\n * UUID v4 regex pattern.\n * Matches standard UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n */\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/**\n * Check if a string is a valid UUID v4.\n *\n * @param value - The string to check\n * @returns true if the string is a valid UUID\n *\n * @example\n * ```typescript\n * isValidUUID('a1b2c3d4-e5f6-4890-abcd-ef1234567890'); // true\n * isValidUUID('not-a-uuid'); // false\n * isValidUUID('bulk-upload-123456'); // false\n * ```\n */\nexport function isValidUUID(value: string | null | undefined): boolean {\n  if (!value) return false;\n  return UUID_REGEX.test(value);\n}\n\n/**\n * ID generation utilities object for convenient access.\n */\nexport const IdUtils = {\n  generate: generateId,\n  generateShort: generateShortId,\n  generateCorrelation: generateCorrelationId,\n  generateTraceId,\n  generateSpanId,\n  isValidUUID,\n} as const;\n","/**\n * Core Event Manager\n *\n * Type-safe event system for the Plyaz ecosystem.\n * Services emit events → Store, API cache, and UI subscribe independently.\n *\n * @example\n * ```typescript\n * import { CoreEventManager, CORE_EVENTS } from '@plyaz/core/events';\n *\n * // Type-safe emission (using CORE_EVENTS constants)\n * CoreEventManager.emit(CORE_EVENTS.API.REQUEST_ERROR, {\n *   method: 'GET',\n *   url: '/api/users',\n *   requestId: '123',\n *   error: new Error('Failed'),\n *   duration: 500,\n * });\n *\n * // Type-safe subscription\n * CoreEventManager.on(CORE_EVENTS.AUTH.LOGIN, (event) => {\n *   console.log(event.data.userId); // Typed!\n * });\n *\n * // Custom events (with generic type)\n * CoreEventManager.emit<MyPayload>('custom:event', { custom: 'data' });\n * ```\n */\n\nimport { EventEmitter } from 'events';\nimport type { CoreEventPayloadMap, CoreEventScopeType, CoreEvent } from '@plyaz/types/core';\nimport { generateCorrelationId } from '../utils/common';\n\n/**\n * Core Event Manager\n *\n * Features:\n * - Type-safe event emission and subscription via CORE_EVENTS constants\n * - Scope-based event filtering\n * - Wildcard subscriptions\n * - Auto cleanup on dispose\n * - Correlation IDs for tracing\n *\n * @example\n * ```typescript\n * import { CoreEventManager, CORE_EVENTS } from '@plyaz/core/events';\n *\n * // Type-safe with CORE_EVENTS\n * CoreEventManager.emit(CORE_EVENTS.AUTH.LOGIN, {\n *   userId: '123',\n *   method: 'email',\n * });\n *\n * CoreEventManager.on(CORE_EVENTS.AUTH.LOGIN, (event) => {\n *   console.log(event.data.userId); // Typed as string!\n * });\n *\n * // Custom events with explicit type\n * interface MyPayload { custom: string }\n * CoreEventManager.emit<MyPayload>('custom:event', { custom: 'data' });\n * ```\n */\n\n// Constants\nconst MAX_EVENT_LISTENERS = 100;\n\nclass CoreEventManagerClass {\n  private emitter = new EventEmitter();\n  private subscriptions = new Map<string, Set<(event: CoreEvent<unknown, string>) => void>>();\n\n  constructor() {\n    // Increase max listeners for large apps\n    this.emitter.setMaxListeners(MAX_EVENT_LISTENERS);\n  }\n\n  /**\n   * Emit an event\n   *\n   * @param eventType - Event type from CORE_EVENTS or custom string\n   * @param data - Event payload (type-safe when using CORE_EVENTS)\n   *\n   * @example\n   * ```typescript\n   * // Type-safe with CORE_EVENTS\n   * CoreEventManager.emit(CORE_EVENTS.AUTH.LOGIN, { userId: '123', method: 'email' });\n   *\n   * // Custom event\n   * CoreEventManager.emit<MyPayload>('custom:event', { custom: 'data' });\n   * ```\n   */\n  emit<T extends keyof CoreEventPayloadMap>(eventType: T, data: CoreEventPayloadMap[T]): boolean;\n  emit<TData = unknown>(eventType: string, data?: TData): boolean;\n  emit<TData = unknown>(eventType: string, data?: TData): boolean {\n    const [scope] = eventType.split(':');\n    const event: CoreEvent<TData, string> = {\n      type: eventType,\n      scope: scope ?? 'system',\n      timestamp: Date.now(),\n      correlationId: this.getCorrelationId(),\n      data: data as TData,\n    };\n\n    // Emit to specific listeners\n    this.emitter.emit(eventType, event);\n\n    // Emit to wildcard listeners\n    this.emitter.emit('*', event);\n\n    return true;\n  }\n\n  /**\n   * Subscribe to an event\n   *\n   * @param eventType - Event type from CORE_EVENTS or custom string\n   * @param handler - Event handler (type-safe when using CORE_EVENTS)\n   * @returns Unsubscribe function\n   *\n   * @example\n   * ```typescript\n   * // Type-safe with CORE_EVENTS\n   * const unsub = CoreEventManager.on(CORE_EVENTS.AUTH.LOGIN, (event) => {\n   *   console.log(event.data.userId); // Typed!\n   * });\n   *\n   * // Custom event\n   * CoreEventManager.on<MyPayload>('custom:event', (event) => {\n   *   console.log(event.data.custom);\n   * });\n   * ```\n   */\n  on<T extends keyof CoreEventPayloadMap>(\n    eventType: T,\n    handler: (event: CoreEvent<CoreEventPayloadMap[T], CoreEventScopeType>) => void\n  ): () => void;\n  on<TData = unknown, TScope extends string = string>(\n    eventType: string,\n    handler: (event: CoreEvent<TData, TScope>) => void\n  ): () => void;\n  on<TData = unknown, TScope extends string = string>(\n    eventType: string,\n    handler: (event: CoreEvent<TData, TScope>) => void\n  ): () => void {\n    this.emitter.on(eventType, handler as (event: CoreEvent<unknown, string>) => void);\n\n    // Track for cleanup\n    if (!this.subscriptions.has(eventType)) {\n      this.subscriptions.set(eventType, new Set());\n    }\n    this.subscriptions.get(eventType)!.add(handler as (event: CoreEvent<unknown, string>) => void);\n\n    // Return unsubscribe function\n    return () => {\n      this.emitter.off(eventType, handler as (event: CoreEvent<unknown, string>) => void);\n      this.subscriptions\n        .get(eventType)\n        ?.delete(handler as (event: CoreEvent<unknown, string>) => void);\n    };\n  }\n\n  /**\n   * Subscribe once to an event\n   *\n   * @param eventType - Event type from CORE_EVENTS or custom string\n   * @param handler - Event handler\n   * @returns Unsubscribe function\n   */\n  once<T extends keyof CoreEventPayloadMap>(\n    eventType: T,\n    handler: (event: CoreEvent<CoreEventPayloadMap[T], CoreEventScopeType>) => void\n  ): () => void;\n  once<TData = unknown, TScope extends string = string>(\n    eventType: string,\n    handler: (event: CoreEvent<TData, TScope>) => void\n  ): () => void;\n  once<TData = unknown, TScope extends string = string>(\n    eventType: string,\n    handler: (event: CoreEvent<TData, TScope>) => void\n  ): () => void {\n    const wrappedHandler = (event: CoreEvent<TData, TScope>): void => {\n      handler(event);\n      this.emitter.off(eventType, wrappedHandler as (event: CoreEvent<unknown, string>) => void);\n      this.subscriptions\n        .get(eventType)\n        ?.delete(wrappedHandler as (event: CoreEvent<unknown, string>) => void);\n    };\n\n    this.emitter.on(eventType, wrappedHandler as (event: CoreEvent<unknown, string>) => void);\n\n    // Track for cleanup\n    if (!this.subscriptions.has(eventType)) {\n      this.subscriptions.set(eventType, new Set());\n    }\n    this.subscriptions\n      .get(eventType)!\n      .add(wrappedHandler as (event: CoreEvent<unknown, string>) => void);\n\n    // Return unsubscribe function\n    return () => {\n      this.emitter.off(eventType, wrappedHandler as (event: CoreEvent<unknown, string>) => void);\n      this.subscriptions\n        .get(eventType)\n        ?.delete(wrappedHandler as (event: CoreEvent<unknown, string>) => void);\n    };\n  }\n\n  /**\n   * Subscribe to all events in a scope\n   *\n   * @param scope - Event scope to listen to (e.g., CoreEventScope.AUTH)\n   * @param handler - Event handler\n   * @returns Unsubscribe function\n   *\n   * @example\n   * ```typescript\n   * CoreEventManager.onScope(CoreEventScope.AUTH, (event) => {\n   *   // Handles auth:login, auth:logout, auth:tokenRefresh, etc.\n   *   console.log(`Auth event: ${event.type}`, event.data);\n   * });\n   * ```\n   */\n  onScope<TScope extends string = string, TData = unknown>(\n    scope: TScope,\n    handler: (event: CoreEvent<TData, TScope>) => void\n  ): () => void {\n    const wrappedHandler = (event: CoreEvent<TData, TScope>): void => {\n      if (event.scope === scope) {\n        handler(event);\n      }\n    };\n    return this.on('*', wrappedHandler as (event: CoreEvent<unknown, string>) => void);\n  }\n\n  /**\n   * Remove a specific handler from an event\n   *\n   * @param eventType - Event type\n   * @param handler - Handler to remove\n   */\n  off<TData = unknown, TScope extends string = string>(\n    eventType: string,\n    handler: (event: CoreEvent<TData, TScope>) => void\n  ): void {\n    this.emitter.off(eventType, handler as (event: CoreEvent<unknown, string>) => void);\n    this.subscriptions\n      .get(eventType)\n      ?.delete(handler as (event: CoreEvent<unknown, string>) => void);\n  }\n\n  /**\n   * Dispose all subscriptions\n   */\n  dispose(): void {\n    this.subscriptions.forEach((handlers, eventType) => {\n      handlers.forEach(handler => this.emitter.off(eventType, handler));\n    });\n    this.subscriptions.clear();\n    this.emitter.removeAllListeners();\n  }\n\n  /**\n   * Generate correlation ID for event tracing\n   */\n  private getCorrelationId(): string {\n    return generateCorrelationId();\n  }\n}\n\n/**\n * Global Singleton Pattern using globalThis\n *\n * WHY THIS IS NEEDED:\n * In Next.js (and similar frameworks with module isolation), different parts of the application\n * can have separate module instances. For example:\n * - API routes may run in isolated module contexts\n * - Hot Module Replacement (HMR) during development creates new module instances\n * - Server Components vs API routes may have different module caches\n *\n * This causes a critical issue: if CoreEventManager is instantiated as a simple module-level\n * singleton (`export const X = new XClass()`), each isolated context gets its OWN instance.\n * Events emitted in one context (e.g., API route) won't reach listeners in another context\n * (e.g., streaming endpoints).\n *\n * THE SOLUTION:\n * Using `globalThis` with `Symbol.for()` ensures a TRUE singleton across all module boundaries:\n * - `globalThis` is the global object in any JavaScript environment (Node.js, browsers, workers)\n * - `Symbol.for('key')` returns the SAME symbol from the global symbol registry, even across\n *   different module instances\n * - This combination guarantees ONE instance per process, regardless of how many times the\n *   module is loaded\n *\n * WORKS WITH:\n * - Next.js (API routes, server components, middleware)\n * - Express/NestJS/Fastify (single process, but safe for hot reload)\n * - Bun/Deno (same globalThis semantics)\n *\n * DOES NOT HELP WITH:\n * - Truly isolated serverless functions (each invocation = new process)\n * - Multi-process clusters (need Redis pub/sub or similar for cross-process events)\n */\nconst GLOBAL_KEY = Symbol.for('plyaz.CoreEventManager');\n\nfunction getCoreEventManager(): CoreEventManagerClass {\n  const globalAny = globalThis as unknown as { [key: symbol]: CoreEventManagerClass };\n\n  if (!globalAny[GLOBAL_KEY]) {\n    globalAny[GLOBAL_KEY] = new CoreEventManagerClass();\n  }\n\n  return globalAny[GLOBAL_KEY];\n}\n\nexport const CoreEventManager = getCoreEventManager();\n","/**\n * Files Channel Controller\n *\n * Handles file-related streaming channels: upload, download, generate.\n * Listens to CoreEventManager events and broadcasts to connected clients.\n */\n\nimport { CoreEventManager } from '../../../events/CoreEventManager';\nimport { BaseChannelController } from '../../../events/streaming/channels/BaseChannelController';\nimport type {\n  StreamBroadcasterInterface,\n  FilesUploadStreamProgress,\n  FilesDownloadStreamProgress,\n  FilesGenerateStreamProgress,\n  CoreEvent,\n} from '@plyaz/types/core';\nimport { FILES_STREAM_CHANNEL_PREFIX, FILES_STREAM_BROADCAST_CHANNEL } from '@plyaz/types/core';\nimport { STORAGE_ERROR_CODES } from '@plyaz/types/errors';\n\n/**\n * FilesChannelController - Handles file streaming channels\n *\n * Channels:\n * - `upload:{fileId}` - Per-file upload progress\n * - `uploads` - Broadcast channel for all uploads\n * - `download:{fileId}` - Per-file download progress\n * - `downloads` - Broadcast channel for all downloads\n * - `generate:{templateId}` - Per-template generation progress\n * - `generations` - Broadcast channel for all generations\n */\nexport class FilesChannelController extends BaseChannelController {\n  constructor() {\n    super({\n      scope: 'files',\n      patterns: [\n        // Upload channels\n        FILES_STREAM_CHANNEL_PREFIX.UPLOAD,\n        FILES_STREAM_BROADCAST_CHANNEL.UPLOADS,\n        // Download channels\n        FILES_STREAM_CHANNEL_PREFIX.DOWNLOAD,\n        FILES_STREAM_BROADCAST_CHANNEL.DOWNLOADS,\n        // Generate channels\n        FILES_STREAM_CHANNEL_PREFIX.GENERATE,\n        FILES_STREAM_BROADCAST_CHANNEL.GENERATIONS,\n      ],\n    });\n  }\n\n  /**\n   * Initialize event subscriptions.\n   * Listens to CoreEventManager events and broadcasts to appropriate channels.\n   */\n  // eslint-disable-next-line max-lines-per-function\n  initialize(broadcaster: StreamBroadcasterInterface): void {\n    this.logger.debug('[FilesChannelController] initialize() called');\n\n    // Listen for upload progress events\n    this.addUnsubscriber(\n      CoreEventManager.on<FilesUploadStreamProgress>(\n        'upload:progress',\n        (event: CoreEvent<FilesUploadStreamProgress>) => {\n          const progress = event.data;\n          const channel = `${FILES_STREAM_CHANNEL_PREFIX.UPLOAD}${progress.fileId}`;\n\n          this.logger.debug('[FilesChannelController] Received upload:progress event', {\n            fileId: progress.fileId,\n            percentage: progress.percentage,\n            channel,\n            broadcastChannel: FILES_STREAM_BROADCAST_CHANNEL.UPLOADS,\n          });\n\n          // Broadcast to file-specific channel with prefixed event name\n          broadcaster.broadcastToChannel(channel, {\n            event: 'upload:progress',\n            data: this.createResponse(progress, channel, 'Upload progress'),\n          });\n\n          // Also broadcast to general uploads channel\n          broadcaster.broadcastToChannel(FILES_STREAM_BROADCAST_CHANNEL.UPLOADS, {\n            event: 'upload:progress',\n            data: this.createResponse(progress, FILES_STREAM_BROADCAST_CHANNEL.UPLOADS),\n          });\n        }\n      )\n    );\n\n    // Listen for upload completed events\n    this.addUnsubscriber(\n      CoreEventManager.on<FilesUploadStreamProgress>(\n        'upload:completed',\n        (event: CoreEvent<FilesUploadStreamProgress>) => {\n          const progress = event.data;\n          const channel = `${FILES_STREAM_CHANNEL_PREFIX.UPLOAD}${progress.fileId}`;\n\n          broadcaster.broadcastToChannel(channel, {\n            event: 'upload:completed',\n            data: this.createResponse(progress, channel, 'Upload completed'),\n          });\n\n          broadcaster.broadcastToChannel(FILES_STREAM_BROADCAST_CHANNEL.UPLOADS, {\n            event: 'upload:completed',\n            data: this.createResponse(progress, FILES_STREAM_BROADCAST_CHANNEL.UPLOADS),\n          });\n        }\n      )\n    );\n\n    // Listen for upload error events\n    this.addUnsubscriber(\n      CoreEventManager.on<FilesUploadStreamProgress>(\n        'upload:error',\n        (event: CoreEvent<FilesUploadStreamProgress>) => {\n          const progress = event.data;\n          const channel = `${FILES_STREAM_CHANNEL_PREFIX.UPLOAD}${progress.fileId}`;\n\n          broadcaster.broadcastToChannel(channel, {\n            event: 'upload:failed',\n            data: this.createSingleError(\n              STORAGE_ERROR_CODES.FILE_UPLOAD_FAILED,\n              progress.error ?? 'Upload failed',\n              channel\n            ),\n          });\n\n          broadcaster.broadcastToChannel(FILES_STREAM_BROADCAST_CHANNEL.UPLOADS, {\n            event: 'upload:failed',\n            data: this.createSingleError(\n              STORAGE_ERROR_CODES.FILE_UPLOAD_FAILED,\n              progress.error ?? 'Upload failed',\n              FILES_STREAM_BROADCAST_CHANNEL.UPLOADS\n            ),\n          });\n        }\n      )\n    );\n\n    // Listen for download progress events\n    this.addUnsubscriber(\n      CoreEventManager.on<FilesDownloadStreamProgress>(\n        'download:progress',\n        (event: CoreEvent<FilesDownloadStreamProgress>) => {\n          const progress = event.data;\n          const channel = `${FILES_STREAM_CHANNEL_PREFIX.DOWNLOAD}${progress.fileId}`;\n\n          this.logger.debug('[FilesChannelController] Received download:progress event', {\n            fileId: progress.fileId,\n            percentage: progress.percentage,\n            channel,\n            broadcastChannel: FILES_STREAM_BROADCAST_CHANNEL.DOWNLOADS,\n          });\n\n          // Broadcast to file-specific channel with prefixed event name\n          broadcaster.broadcastToChannel(channel, {\n            event: 'download:progress',\n            data: this.createResponse(progress, channel, 'Download progress'),\n          });\n\n          // Also broadcast to general downloads channel\n          broadcaster.broadcastToChannel(FILES_STREAM_BROADCAST_CHANNEL.DOWNLOADS, {\n            event: 'download:progress',\n            data: this.createResponse(progress, FILES_STREAM_BROADCAST_CHANNEL.DOWNLOADS),\n          });\n        }\n      )\n    );\n\n    // Listen for download completed events\n    this.addUnsubscriber(\n      CoreEventManager.on<FilesDownloadStreamProgress>(\n        'download:completed',\n        (event: CoreEvent<FilesDownloadStreamProgress>) => {\n          const progress = event.data;\n          const channel = `${FILES_STREAM_CHANNEL_PREFIX.DOWNLOAD}${progress.fileId}`;\n\n          broadcaster.broadcastToChannel(channel, {\n            event: 'download:completed',\n            data: this.createResponse(progress, channel, 'Download completed'),\n          });\n\n          broadcaster.broadcastToChannel(FILES_STREAM_BROADCAST_CHANNEL.DOWNLOADS, {\n            event: 'download:completed',\n            data: this.createResponse(progress, FILES_STREAM_BROADCAST_CHANNEL.DOWNLOADS),\n          });\n        }\n      )\n    );\n\n    // Listen for download error events\n    this.addUnsubscriber(\n      CoreEventManager.on<FilesDownloadStreamProgress>(\n        'download:error',\n        (event: CoreEvent<FilesDownloadStreamProgress>) => {\n          const progress = event.data;\n          const channel = `${FILES_STREAM_CHANNEL_PREFIX.DOWNLOAD}${progress.fileId}`;\n\n          broadcaster.broadcastToChannel(channel, {\n            event: 'download:failed',\n            data: this.createSingleError(\n              STORAGE_ERROR_CODES.FILE_DOWNLOAD_FAILED,\n              progress.error ?? 'Download failed',\n              channel\n            ),\n          });\n\n          broadcaster.broadcastToChannel(FILES_STREAM_BROADCAST_CHANNEL.DOWNLOADS, {\n            event: 'download:failed',\n            data: this.createSingleError(\n              STORAGE_ERROR_CODES.FILE_DOWNLOAD_FAILED,\n              progress.error ?? 'Download failed',\n              FILES_STREAM_BROADCAST_CHANNEL.DOWNLOADS\n            ),\n          });\n        }\n      )\n    );\n\n    // Listen for generate progress events\n    this.addUnsubscriber(\n      CoreEventManager.on<FilesGenerateStreamProgress>(\n        'generate:progress',\n        (event: CoreEvent<FilesGenerateStreamProgress>) => {\n          const data = event.data;\n          const channel = `${FILES_STREAM_CHANNEL_PREFIX.GENERATE}${data.templateId}`;\n\n          broadcaster.broadcastToChannel(channel, {\n            event: 'generate:progress',\n            data: this.createResponse(data, channel, 'Generation progress'),\n          });\n\n          broadcaster.broadcastToChannel(FILES_STREAM_BROADCAST_CHANNEL.GENERATIONS, {\n            event: 'generate:progress',\n            data: this.createResponse(data, FILES_STREAM_BROADCAST_CHANNEL.GENERATIONS),\n          });\n        }\n      )\n    );\n\n    this.logger.info('FilesChannelController initialized');\n  }\n\n  /**\n   * Override handlesChannel to match file patterns.\n   */\n  override handlesChannel(channel: string): boolean {\n    // Check if channel starts with any of the prefixes\n    return (\n      channel.startsWith(FILES_STREAM_CHANNEL_PREFIX.UPLOAD) ||\n      channel.startsWith(FILES_STREAM_CHANNEL_PREFIX.DOWNLOAD) ||\n      channel.startsWith(FILES_STREAM_CHANNEL_PREFIX.GENERATE) ||\n      channel === FILES_STREAM_BROADCAST_CHANNEL.UPLOADS ||\n      channel === FILES_STREAM_BROADCAST_CHANNEL.DOWNLOADS ||\n      channel === FILES_STREAM_BROADCAST_CHANNEL.GENERATIONS\n    );\n  }\n}\n","/**\n * Files Stream Endpoint\n *\n * Stream endpoint for file-related real-time events.\n * Handles upload, download, and document generation progress.\n *\n * @example\n * ```typescript\n * // Register in StreamRegistry\n * await StreamRegistry.initialize({\n *   broadcaster: streamServer.getBroadcaster(),\n *   endpoints: [\n *     { endpoint: FilesStreamEndpoint, config: { enabled: true } },\n *   ],\n * });\n * ```\n */\n\nimport { BaseStreamEndpoint } from '../../../events/streaming/base/BaseStreamEndpoint';\nimport { FilesChannelController } from './FilesChannelController';\nimport type { BaseChannelController } from '../../../events/streaming/channels/BaseChannelController';\nimport type { StreamEndpointConfig, StreamEndpointCreateOptions } from '@plyaz/types/core';\n\n/**\n * FilesStreamEndpoint - Handles file streaming events\n *\n * Channels managed:\n * - `upload:{fileId}` - Per-file upload progress\n * - `uploads` - All uploads broadcast\n * - `download:{fileId}` - Per-file download progress\n * - `downloads` - All downloads broadcast\n * - `generate:{templateId}` - Per-template generation progress\n * - `generations` - All generations broadcast\n */\nexport class FilesStreamEndpoint extends BaseStreamEndpoint {\n  /** Static endpoint key for registry lookup */\n  static readonly endpointKey = 'files';\n\n  /**\n   * Create channel controller for this endpoint.\n   */\n  protected createChannelController(): BaseChannelController {\n    return new FilesChannelController();\n  }\n\n  /**\n   * Initialize event subscriptions.\n   * Called by StreamRegistry during initialization.\n   */\n  initialize(): void {\n    this.logger.debug('[FilesStreamEndpoint] initialize() called');\n\n    // Initialize the channel controller with broadcaster\n    this.channelController.initialize(this.broadcaster);\n\n    this.logger.debug('[FilesStreamEndpoint] initialized', {\n      patterns: this.channelController.getPatterns(),\n    });\n  }\n\n  /**\n   * Static factory method for creating endpoint instances.\n   *\n   * @param config - Endpoint configuration\n   * @param options - Create options (broadcaster, auth, etc.)\n   * @returns Promise resolving to endpoint instance\n   */\n  static async create(\n    config: StreamEndpointConfig,\n    options: StreamEndpointCreateOptions\n  ): Promise<FilesStreamEndpoint> {\n    return new FilesStreamEndpoint(config, options);\n  }\n}\n","/**\n * Notifications Channel Controller\n *\n * Handles IN_APP notification streaming - broadcasts new notifications to users.\n * Only supports notification:created event - when a new notification is created,\n * it's broadcasted to the user's channel based on userId.\n *\n * NOTE: This controller handles IN_APP notifications only.\n * Email, SMS, and Push are handled by @plyaz/notifications package.\n *\n * Flow:\n * 1. Backend creates notification with user_id\n * 2. Backend emits notification:created via CoreEventManager\n * 3. This controller broadcasts to user:notifications:{userId}\n * 4. User's connected clients receive and display the notification\n */\n\nimport { CoreEventManager } from '../../../events/CoreEventManager';\nimport { BaseChannelController } from '../../../events/streaming/channels/BaseChannelController';\nimport type { StreamBroadcasterInterface, CoreEvent } from '@plyaz/types/core';\nimport {\n  NOTIFICATIONS_STREAM_CHANNEL_PREFIX,\n  NOTIFICATIONS_STREAM_BROADCAST_CHANNEL,\n} from '@plyaz/types/core';\nimport type { NotificationCreatedStreamData } from '@plyaz/types/core';\n\n/**\n * NotificationsChannelController - Broadcasts new notifications to users\n *\n * Channel:\n * - `user:notifications:{userId}` - User subscribes to receive their notifications\n */\nexport class NotificationsChannelController extends BaseChannelController {\n  constructor() {\n    super({\n      scope: 'notifications',\n      patterns: [\n        NOTIFICATIONS_STREAM_CHANNEL_PREFIX.USER,\n        NOTIFICATIONS_STREAM_BROADCAST_CHANNEL.ALL_NOTIFICATIONS,\n      ],\n    });\n  }\n\n  /**\n   * Initialize event subscriptions.\n   * Listens to notification:created and broadcasts to user's channel.\n   */\n  initialize(broadcaster: StreamBroadcasterInterface): void {\n    this.logger.debug('[NotificationsChannelController] initialize() called');\n\n    // Listen for notification:created events\n    this.addUnsubscriber(\n      CoreEventManager.on<NotificationCreatedStreamData>(\n        'notification:created',\n        (event: CoreEvent<NotificationCreatedStreamData>) => {\n          const data = event.data;\n\n          // userId is REQUIRED for routing\n          if (!data.userId) {\n            this.logger.warn(\n              '[NotificationsChannelController] notification:created missing userId',\n              {\n                notificationId: data.notificationId,\n              }\n            );\n            return;\n          }\n\n          const userChannel = `${NOTIFICATIONS_STREAM_CHANNEL_PREFIX.USER}${data.userId}`;\n\n          this.logger.debug('[NotificationsChannelController] notification:created', {\n            notificationId: data.notificationId,\n            userId: data.userId,\n            userChannel,\n          });\n\n          // Broadcast to user's notifications channel\n          broadcaster.broadcastToChannel(userChannel, {\n            event: 'notification:created',\n            data: this.createResponse(data, userChannel, 'New notification'),\n          });\n\n          // Also broadcast to general channel (for admin/debug)\n          broadcaster.broadcastToChannel(NOTIFICATIONS_STREAM_BROADCAST_CHANNEL.ALL_NOTIFICATIONS, {\n            event: 'notification:created',\n            data: this.createResponse(\n              data,\n              NOTIFICATIONS_STREAM_BROADCAST_CHANNEL.ALL_NOTIFICATIONS\n            ),\n          });\n        }\n      )\n    );\n\n    this.logger.info('NotificationsChannelController initialized (notification:created only)');\n  }\n\n  /**\n   * Override handlesChannel to match notification patterns.\n   */\n  override handlesChannel(channel: string): boolean {\n    return (\n      channel.startsWith(NOTIFICATIONS_STREAM_CHANNEL_PREFIX.USER) ||\n      channel === NOTIFICATIONS_STREAM_BROADCAST_CHANNEL.ALL_NOTIFICATIONS\n    );\n  }\n}\n","/**\n * Notifications Stream Endpoint\n *\n * Stream endpoint for IN_APP notification real-time events.\n * Handles notification lifecycle events (created, read, unread, deleted).\n *\n * NOTE: This endpoint handles IN_APP notifications only (bell icon notifications).\n * Email, SMS, and Push notification delivery is handled by @plyaz/notifications package.\n *\n * @example\n * ```typescript\n * // Register in StreamRegistry\n * await StreamRegistry.initialize({\n *   broadcaster: streamServer.getBroadcaster(),\n *   endpoints: [\n *     { endpoint: NotificationsStreamEndpoint, config: { enabled: true } },\n *   ],\n * });\n * ```\n */\n\nimport { BaseStreamEndpoint } from '../../../events/streaming/base/BaseStreamEndpoint';\nimport { NotificationsChannelController } from './NotificationsChannelController';\nimport type { BaseChannelController } from '../../../events/streaming/channels/BaseChannelController';\nimport type { StreamEndpointConfig, StreamEndpointCreateOptions } from '@plyaz/types/core';\n\n/**\n * NotificationsStreamEndpoint - Handles IN_APP notification streaming events\n *\n * Channels managed:\n * - `notification:{notificationId}` - Per-notification updates\n * - `user:notifications:{userId}` - All notifications for a specific user\n * - `notifications` - Broadcast channel for all notifications (current user)\n * - `notifications:unread` - Broadcast channel for unread notifications\n *\n * Events:\n * - `notification:created` - New in-app notification created\n * - `notification:read` - Notification marked as read\n * - `notification:unread` - Notification marked as unread\n * - `notification:deleted` - Notification deleted\n * - `notifications:batch` - Batch operations (e.g., mark all as read)\n */\nexport class NotificationsStreamEndpoint extends BaseStreamEndpoint {\n  /** Static endpoint key for registry lookup */\n  static readonly endpointKey = 'notifications';\n\n  /**\n   * Create channel controller for this endpoint.\n   */\n  protected createChannelController(): BaseChannelController {\n    return new NotificationsChannelController();\n  }\n\n  /**\n   * Initialize event subscriptions.\n   * Called by StreamRegistry during initialization.\n   */\n  initialize(): void {\n    this.logger.debug('[NotificationsStreamEndpoint] initialize() called');\n\n    // Initialize the channel controller with broadcaster\n    this.channelController.initialize(this.broadcaster);\n\n    this.logger.debug('[NotificationsStreamEndpoint] initialized (IN_APP notifications)', {\n      patterns: this.channelController.getPatterns(),\n    });\n  }\n\n  /**\n   * Static factory method for creating endpoint instances.\n   *\n   * @param config - Endpoint configuration\n   * @param options - Create options (broadcaster, auth, etc.)\n   * @returns Promise resolving to endpoint instance\n   */\n  static async create(\n    config: StreamEndpointConfig,\n    options: StreamEndpointCreateOptions\n  ): Promise<NotificationsStreamEndpoint> {\n    return new NotificationsStreamEndpoint(config, options);\n  }\n}\n","/**\n * System Channel Controller\n *\n * Handles system-level streaming channels: heartbeat, connection lifecycle.\n */\n\nimport { BaseChannelController } from '../../channels/BaseChannelController';\nimport type { StreamBroadcasterInterface } from '@plyaz/types/core';\nimport { SYSTEM_STREAM_CHANNEL } from '@plyaz/types/core';\n\n/**\n * SystemChannelController - Handles system streaming channels\n *\n * Channels:\n * - `system` - System-level events (heartbeat, connected, disconnected)\n */\nexport class SystemChannelController extends BaseChannelController {\n  /** Heartbeat interval timer */\n  private heartbeatTimer?: ReturnType<typeof setInterval>;\n\n  /** Heartbeat interval in milliseconds */\n  private readonly heartbeatInterval: number;\n\n  constructor(heartbeatInterval = 30000) {\n    super({\n      scope: 'system',\n      patterns: [SYSTEM_STREAM_CHANNEL.SYSTEM],\n    });\n    this.heartbeatInterval = heartbeatInterval;\n  }\n\n  /**\n   * Initialize event subscriptions.\n   * Sets up heartbeat broadcasting.\n   */\n  initialize(broadcaster: StreamBroadcasterInterface): void {\n    this.logger.debug('Initializing SystemChannelController');\n\n    // Start heartbeat timer\n    this.heartbeatTimer = setInterval(() => {\n      broadcaster.broadcastToChannel(SYSTEM_STREAM_CHANNEL.SYSTEM, {\n        event: 'heartbeat',\n        data: this.createResponse(\n          { timestamp: Date.now() },\n          SYSTEM_STREAM_CHANNEL.SYSTEM,\n          'Heartbeat'\n        ),\n      });\n    }, this.heartbeatInterval);\n\n    this.logger.info('SystemChannelController initialized', {\n      heartbeatInterval: this.heartbeatInterval,\n    });\n  }\n\n  /**\n   * Override handlesChannel to match system patterns.\n   */\n  override handlesChannel(channel: string): boolean {\n    return channel === SYSTEM_STREAM_CHANNEL.SYSTEM || channel.startsWith('system:');\n  }\n\n  /**\n   * Override dispose to clean up heartbeat timer.\n   */\n  override dispose(): void {\n    if (this.heartbeatTimer) {\n      clearInterval(this.heartbeatTimer);\n      this.heartbeatTimer = undefined;\n    }\n    super.dispose();\n  }\n\n  /**\n   * Broadcast a connection established event.\n   */\n  broadcastConnected(broadcaster: StreamBroadcasterInterface, connectionId: string): void {\n    broadcaster.broadcastToChannel(SYSTEM_STREAM_CHANNEL.SYSTEM, {\n      event: 'connected',\n      data: this.createResponse(\n        { connectionId, timestamp: Date.now() },\n        SYSTEM_STREAM_CHANNEL.SYSTEM,\n        'Connected'\n      ),\n    });\n  }\n\n  /**\n   * Broadcast a connection closed event.\n   */\n  broadcastDisconnected(broadcaster: StreamBroadcasterInterface, connectionId: string): void {\n    broadcaster.broadcastToChannel(SYSTEM_STREAM_CHANNEL.SYSTEM, {\n      event: 'disconnected',\n      data: this.createResponse(\n        { connectionId, timestamp: Date.now() },\n        SYSTEM_STREAM_CHANNEL.SYSTEM,\n        'Disconnected'\n      ),\n    });\n  }\n}\n","/**\n * System Stream Endpoint\n *\n * Stream endpoint for system-level events like heartbeat and connection lifecycle.\n *\n * @example\n * ```typescript\n * // Register in StreamRegistry\n * await StreamRegistry.initialize({\n *   broadcaster: streamServer.getBroadcaster(),\n *   endpoints: [\n *     { endpoint: SystemStreamEndpoint, config: { enabled: true } },\n *   ],\n * });\n * ```\n */\n\nimport { BaseStreamEndpoint } from '../../base/BaseStreamEndpoint';\nimport { SystemChannelController } from './SystemChannelController';\nimport type { BaseChannelController } from '../../channels/BaseChannelController';\nimport type {\n  StreamEndpointConfig,\n  StreamEndpointCreateOptions,\n  StreamConnection,\n} from '@plyaz/types/core';\n\n/**\n * SystemStreamEndpoint - Handles system-level streaming events\n *\n * Channels managed:\n * - `system` - System events (heartbeat, connected, disconnected)\n */\nexport class SystemStreamEndpoint extends BaseStreamEndpoint {\n  /** Static endpoint key for registry lookup */\n  static readonly endpointKey = 'system';\n\n  /** Heartbeat interval in milliseconds */\n  private readonly heartbeatInterval: number;\n\n  constructor(config: StreamEndpointConfig, options: StreamEndpointCreateOptions) {\n    super(config, options);\n    // Allow configuring heartbeat interval via config\n    const DEFAULT_HEARTBEAT_MS = 30000;\n    this.heartbeatInterval =\n      (config as { heartbeatInterval?: number }).heartbeatInterval ?? DEFAULT_HEARTBEAT_MS;\n  }\n\n  /**\n   * Create channel controller for this endpoint.\n   */\n  protected createChannelController(): BaseChannelController {\n    return new SystemChannelController(this.heartbeatInterval);\n  }\n\n  /**\n   * Initialize event subscriptions.\n   * Called by StreamRegistry during initialization.\n   */\n  initialize(): void {\n    this.logger.debug('Initializing SystemStreamEndpoint');\n\n    // Initialize the channel controller with broadcaster\n    this.channelController.initialize(this.broadcaster);\n\n    this.logger.info('SystemStreamEndpoint initialized', {\n      heartbeatInterval: this.heartbeatInterval,\n    });\n  }\n\n  /**\n   * Called when a new connection is established.\n   * Broadcasts a connected event.\n   */\n  protected override async onConnect(connection: StreamConnection): Promise<void> {\n    const controller = this.channelController as SystemChannelController;\n    controller.broadcastConnected(this.broadcaster, connection.id);\n  }\n\n  /**\n   * Called when a connection is closed.\n   * Broadcasts a disconnected event.\n   */\n  protected override async onDisconnect(connectionId: string): Promise<void> {\n    const controller = this.channelController as SystemChannelController;\n    controller.broadcastDisconnected(this.broadcaster, connectionId);\n  }\n\n  /**\n   * Static factory method for creating endpoint instances.\n   *\n   * @param config - Endpoint configuration\n   * @param options - Create options (broadcaster, auth, etc.)\n   * @returns Promise resolving to endpoint instance\n   */\n  static async create(\n    config: StreamEndpointConfig,\n    options: StreamEndpointCreateOptions\n  ): Promise<SystemStreamEndpoint> {\n    return new SystemStreamEndpoint(config, options);\n  }\n}\n","/**\n * Middleware Chain\n *\n * Runs a chain of middleware functions for stream connections.\n */\n\nimport { CoreLogger } from '@plyaz/logger';\nimport { StreamPackageError } from '@plyaz/errors';\nimport { STREAM_ERROR_CODES } from '@plyaz/types/errors';\nimport type {\n  StreamMiddleware,\n  StreamMiddlewareContext,\n  StreamMiddlewareResult,\n} from '@plyaz/types/core';\n\n/**\n * MiddlewareChain - Runs middleware in sequence\n *\n * Each middleware can:\n * - Continue to next middleware (return { continue: true })\n * - Stop the chain (return { continue: false, error: ... })\n * - Modify context (return { continue: true, context: { ... } })\n *\n * @example\n * ```typescript\n * const chain = new MiddlewareChain();\n * chain.use(rateLimitMiddleware);\n * chain.use(authMiddleware);\n *\n * const result = await chain.run(context);\n * if (!result.continue) {\n *   return new Response(result.error?.message, { status: 429 });\n * }\n * ```\n */\nexport class MiddlewareChain {\n  private readonly logger: CoreLogger;\n  private readonly middlewares: StreamMiddleware[] = [];\n\n  constructor() {\n    this.logger = new CoreLogger({ service: 'MiddlewareChain' });\n  }\n\n  /**\n   * Add a middleware to the chain.\n   *\n   * @param middleware - Middleware function to add\n   * @returns this for chaining\n   */\n  use(middleware: StreamMiddleware): this {\n    this.middlewares.push(middleware);\n    return this;\n  }\n\n  /**\n   * Run all middleware in sequence.\n   *\n   * @param initialContext - Initial context to pass to first middleware\n   * @returns Final result after all middleware have run\n   */\n  async run(initialContext: StreamMiddlewareContext): Promise<StreamMiddlewareResult> {\n    let context = { ...initialContext };\n\n    for (const middleware of this.middlewares) {\n      try {\n        const result = await middleware(context);\n\n        if (!result.continue) {\n          // Middleware stopped the chain\n          this.logger.debug('Middleware stopped chain', {\n            error: result.error?.message,\n          });\n          return result;\n        }\n\n        // Merge context updates\n        if (result.context) {\n          context = { ...context, ...result.context };\n        }\n      } catch (error) {\n        // Middleware threw an error\n        this.logger.error('Middleware error', { error });\n        return {\n          continue: false,\n          error:\n            error instanceof StreamPackageError\n              ? error\n              : new StreamPackageError(\n                  error instanceof Error ? error.message : String(error),\n                  STREAM_ERROR_CODES.UNKNOWN_ERROR\n                ),\n        };\n      }\n    }\n\n    // All middleware passed\n    return {\n      continue: true,\n      context,\n    };\n  }\n\n  /**\n   * Get the number of middleware in the chain.\n   */\n  get length(): number {\n    return this.middlewares.length;\n  }\n\n  /**\n   * Clear all middleware from the chain.\n   */\n  clear(): void {\n    this.middlewares.length = 0;\n  }\n}\n","/**\n * Rate Limit Middleware\n *\n * Limits connections and message rate per IP/user.\n */\n\nimport { StreamPackageError } from '@plyaz/errors';\nimport type {\n  StreamMiddleware,\n  StreamMiddlewareContext,\n  StreamMiddlewareResult,\n  RateLimitConfig,\n} from '@plyaz/types/core';\nimport { STREAM_ERROR_CODES } from '@plyaz/types/errors';\n\n/**\n * Time constants\n */\nconst MS_PER_SECOND = 1000;\n\n/**\n * Default rate limit configuration\n */\nconst DEFAULT_CONFIG: Required<RateLimitConfig> = {\n  maxConnectionsPerIp: 10,\n  maxMessagesPerSecond: 100,\n  windowMs: 60000, // 1 minute\n};\n\n/** Connection count by IP */\nconst connectionsByIp = new Map<string, Set<string>>();\n\n/** Message count by connection ID */\nconst messageCountByConnection = new Map<string, { count: number; resetAt: number }>();\n\n/**\n * Create a rate limit middleware.\n *\n * @param config - Rate limit configuration\n * @returns Middleware function\n *\n * @example\n * ```typescript\n * const middleware = createRateLimitMiddleware({\n *   maxConnectionsPerIp: 5,\n *   maxMessagesPerSecond: 50,\n * });\n *\n * chain.use(middleware);\n * ```\n */\nexport function createRateLimitMiddleware(config: RateLimitConfig = {}): StreamMiddleware {\n  const mergedConfig = { ...DEFAULT_CONFIG, ...config };\n\n  // eslint-disable-next-line complexity\n  return async (context: StreamMiddlewareContext): Promise<StreamMiddlewareResult> => {\n    const { connection } = context;\n\n    // Extract IP from connection metadata or use connection ID\n    const ip = (connection.metadata?.ip as string) ?? connection.id;\n\n    // Check connection limit per IP\n    if (!connectionsByIp.has(ip)) {\n      connectionsByIp.set(ip, new Set());\n    }\n\n    const connections = connectionsByIp.get(ip)!;\n\n    // Only check limit for new connections\n    if (!connections.has(connection.id)) {\n      if (connections.size >= mergedConfig.maxConnectionsPerIp) {\n        return {\n          continue: false,\n          error: new StreamPackageError(\n            `Rate limit exceeded: max ${mergedConfig.maxConnectionsPerIp} connections per IP`,\n            STREAM_ERROR_CODES.RATE_LIMITED\n          ),\n        };\n      }\n      connections.add(connection.id);\n    }\n\n    // Check message rate (if there's a message being processed)\n    if (context.message) {\n      const now = Date.now();\n      const rateInfo = messageCountByConnection.get(connection.id);\n\n      if (!rateInfo || now >= rateInfo.resetAt) {\n        // Reset window\n        messageCountByConnection.set(connection.id, {\n          count: 1,\n          resetAt: now + MS_PER_SECOND, // 1 second window for messages per second\n        });\n      } else {\n        if (rateInfo.count >= mergedConfig.maxMessagesPerSecond) {\n          return {\n            continue: false,\n            error: new StreamPackageError(\n              `Rate limit exceeded: max ${mergedConfig.maxMessagesPerSecond} messages per second`,\n              STREAM_ERROR_CODES.RATE_LIMITED\n            ),\n          };\n        }\n        rateInfo.count++;\n      }\n    }\n\n    return { continue: true };\n  };\n}\n\n/**\n * Remove a connection from IP tracking and clean up empty IP entries.\n */\nfunction removeConnectionFromIp(ipKey: string, connectionId: string): void {\n  const connections = connectionsByIp.get(ipKey);\n  if (!connections) return;\n\n  connections.delete(connectionId);\n  if (connections.size === 0) {\n    connectionsByIp.delete(ipKey);\n  }\n}\n\n/**\n * Find and remove a connection from all IP tracking entries.\n */\nfunction removeConnectionFromAllIps(connectionId: string): void {\n  for (const [ipKey, connections] of connectionsByIp) {\n    if (connections.has(connectionId)) {\n      removeConnectionFromIp(ipKey, connectionId);\n      break;\n    }\n  }\n}\n\n/**\n * Clean up rate limit tracking for a connection.\n * Call when a connection is closed.\n *\n * @param connectionId - Connection ID to clean up\n * @param ip - IP address of the connection\n */\nexport function cleanupRateLimitTracking(connectionId: string, ip?: string): void {\n  // Remove message tracking\n  messageCountByConnection.delete(connectionId);\n\n  // Remove from IP connection tracking\n  if (ip) {\n    removeConnectionFromIp(ip, connectionId);\n  } else {\n    removeConnectionFromAllIps(connectionId);\n  }\n}\n\n/**\n * Get current rate limit stats.\n */\nexport function getRateLimitStats(): {\n  connectionsByIp: Map<string, number>;\n  totalConnections: number;\n} {\n  const stats = new Map<string, number>();\n  let total = 0;\n\n  for (const [ip, connections] of connectionsByIp) {\n    stats.set(ip, connections.size);\n    total += connections.size;\n  }\n\n  return {\n    connectionsByIp: stats,\n    totalConnections: total,\n  };\n}\n"]}