@chaterafrikang/sdk 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -0
- package/dist/index.cjs +2119 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1072 -0
- package/dist/index.d.ts +1072 -0
- package/dist/index.js +2098 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/ConnectionState.ts","../src/utils/logger.ts","../src/websocket/WebSocketClient.ts","../src/auth/TokenManager.ts","../src/messages/Message.ts","../src/receipts/ReceiptManager.ts","../src/messages/MessageManager.ts","../src/typing/TypingManager.ts","../src/conversations/Conversation.ts","../src/conversations/ConversationManager.ts","../src/presence/PresenceManager.ts","../src/support/SupportSession.ts","../src/support/SupportManager.ts","../src/core/ChatAfrika.ts","../src/utils/retry.ts","../src/utils/guards.ts"],"names":["ConnectionState","EventEmitter","uuidv4"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Connection state enumeration for the SDK\n */\nexport enum ConnectionState {\n DISCONNECTED = 'disconnected',\n CONNECTING = 'connecting',\n CONNECTED = 'connected',\n RECONNECTING = 'reconnecting',\n ERROR = 'error',\n}\n\n","/**\n * Simple logger utility\n */\nexport class Logger {\n private enabled: boolean;\n\n constructor(enabled: boolean = false) {\n this.enabled = enabled;\n }\n\n setEnabled(enabled: boolean): void {\n this.enabled = enabled;\n }\n\n debug(...args: unknown[]): void {\n if (this.enabled) {\n console.debug('[ChatAfrika SDK]', ...args);\n }\n }\n\n info(...args: unknown[]): void {\n if (this.enabled) {\n console.info('[ChatAfrika SDK]', ...args);\n }\n }\n\n warn(...args: unknown[]): void {\n if (this.enabled) {\n console.warn('[ChatAfrika SDK]', ...args);\n }\n }\n\n error(...args: unknown[]): void {\n if (this.enabled) {\n console.error('[ChatAfrika SDK]', ...args);\n }\n }\n}\n\n","import { EventEmitter } from 'eventemitter3';\nimport { ClientMessage, ServerMessage } from './protocol';\nimport { Logger } from '../utils/logger';\n\n// Detect if we're in Node.js environment\nconst isNodeEnv = typeof process !== 'undefined' && \n process.versions != null && \n process.versions.node != null;\n\n// Lazy load ws package for Node.js (only when needed)\nlet wsModule: any = null;\nlet wsLoading: Promise<any> | null = null;\n\nasync function getWsModule(): Promise<any> {\n if (!isNodeEnv) return null;\n if (wsModule) return wsModule;\n if (wsLoading) return wsLoading;\n \n wsLoading = (async () => {\n try {\n // Try ESM dynamic import first (works in ESM builds)\n try {\n const ws = await import('ws');\n wsModule = ws;\n return wsModule;\n } catch (esmErr) {\n // If ESM import fails, try CommonJS require (works in CJS builds)\n if (typeof require !== 'undefined') {\n // Use createRequire for ESM compatibility\n const { createRequire } = await import('module');\n const requireFn = createRequire(import.meta.url || __filename);\n wsModule = requireFn('ws');\n return wsModule;\n }\n throw esmErr;\n }\n } catch (err) {\n // ws package not available\n return null;\n } finally {\n wsLoading = null;\n }\n })();\n \n return wsLoading;\n}\n\n/**\n * Low-level WebSocket client for handling connections\n */\nexport class WebSocketClient extends EventEmitter {\n private ws: WebSocket | null = null;\n private url: string;\n private token: string | null = null;\n private reconnectAttempts = 0;\n private maxReconnectAttempts: number;\n private autoReconnect: boolean;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private isManuallyDisconnected = false;\n private isTokenExpired = false; // Track if token is expired\n private logger: Logger;\n\n constructor(\n url: string,\n options: {\n autoReconnect?: boolean;\n maxReconnectAttempts?: number;\n reconnectDelay?: number;\n debug?: boolean;\n } = {}\n ) {\n super();\n this.url = url;\n this.autoReconnect = options.autoReconnect ?? true;\n this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;\n this.logger = new Logger(options.debug ?? false);\n }\n\n /**\n * Connect to the WebSocket server with authentication token\n */\n connect(token: string): Promise<void> {\n if (!token || token.length === 0) {\n const error = new Error('Token is required for connection');\n this.emit('error', error);\n return Promise.reject(error);\n }\n\n this.token = token;\n this.isManuallyDisconnected = false;\n this.isTokenExpired = false; // Reset token expiration flag\n return this.attemptConnection();\n }\n\n /**\n * Attempt a WebSocket connection\n */\n private async attemptConnection(): Promise<void> {\n const wsUrl = new URL(this.url);\n const token = this.token ?? '';\n \n if (isNodeEnv) {\n // Node.js: Try to use ws package with Authorization header\n const ws = await getWsModule();\n this.logger.debug('ws module loaded:', !!ws);\n if (ws && ws.WebSocket) {\n this.logger.debug('Using ws package with Authorization header');\n return new Promise((resolve, reject) => {\n try {\n const wsInstance = new ws.WebSocket(wsUrl.toString(), {\n headers: {\n 'Authorization': `Bearer ${token}`,\n },\n });\n \n this.ws = wsInstance as unknown as WebSocket;\n \n // Handle HTTP errors during handshake (e.g., 401)\n // In ws package, HTTP errors are emitted as 'error' events before 'open'\n let handshakeErrorHandled = false;\n const errorHandler = (error: any) => {\n if (handshakeErrorHandled) return;\n handshakeErrorHandled = true;\n \n const errorMsg = String(error?.message || error || '').toLowerCase();\n if (errorMsg.includes('401') || \n errorMsg.includes('unauthorized') ||\n (error?.code && String(error.code).includes('401'))) {\n this.handleTokenExpiration();\n const tokenError = new Error('Token expired or invalid. Please refresh your token and reconnect.');\n tokenError.name = 'TokenExpiredError';\n this.emit('error', tokenError);\n reject(tokenError);\n return;\n }\n };\n \n // Set up temporary error handler for handshake errors\n // Use addEventListener for compatibility (ws package supports both)\n if (typeof wsInstance.addEventListener === 'function') {\n wsInstance.addEventListener('error', errorHandler);\n wsInstance.addEventListener('open', () => {\n wsInstance.removeEventListener('error', errorHandler);\n });\n } else if (typeof (wsInstance as any).once === 'function') {\n // Fallback for ws package's once method\n (wsInstance as any).once('error', errorHandler);\n (wsInstance as any).once('open', () => {\n // Error handler will be removed by setupEventHandlers\n });\n }\n \n this.setupEventHandlers(resolve, reject);\n } catch (error) {\n this.logger.error('Failed to create ws.WebSocket:', error);\n reject(error);\n }\n });\n } else {\n this.logger.warn('ws package not available, falling back to native WebSocket');\n }\n }\n \n // Browser or fallback: Use native WebSocket with query parameter\n // Browsers don't allow custom headers, and Sec-WebSocket-Protocol has length limits for JWT tokens\n // So we pass the token as a query parameter instead\n this.logger.debug('Using native WebSocket with query parameter', { url: wsUrl.toString(), hasToken: !!token });\n return new Promise((resolve, reject) => {\n try {\n if (!token || token.length === 0) {\n const error = new Error('Token is required for WebSocket connection');\n this.logger.error(error.message);\n reject(error);\n return;\n }\n \n // Add token as query parameter (browser-friendly approach)\n const urlWithToken = new URL(wsUrl.toString());\n urlWithToken.searchParams.set('token', token);\n \n this.ws = new globalThis.WebSocket(urlWithToken.toString());\n this.logger.debug('WebSocket instance created', { \n readyState: this.ws.readyState,\n url: this.ws.url,\n protocol: this.ws.protocol \n });\n\n const wsRef = this.ws;\n \n this.setupEventHandlers(resolve, reject);\n\n setTimeout(() => {\n if (wsRef.readyState === WebSocket.CLOSED || wsRef.readyState === WebSocket.CLOSING) {\n this.logger.warn('WebSocket closed immediately after creation', {\n readyState: wsRef.readyState,\n url: wsRef.url\n });\n }\n }, 100);\n } catch (error) {\n this.logger.error('Failed to create native WebSocket:', error);\n reject(error);\n }\n });\n }\n\n /**\n * Set up WebSocket event handlers\n */\n private setupEventHandlers(resolve: () => void, reject: (error: Error) => void): void {\n if (!this.ws) return;\n\n this.ws.onopen = () => {\n this.reconnectAttempts = 0;\n this.isTokenExpired = false;\n \n const ws = this.ws;\n if (!ws) {\n this.logger.error('WebSocket is null in onopen handler');\n reject(new Error('WebSocket instance lost'));\n return;\n }\n \n this.logger.debug('WebSocket connected', { \n readyState: ws.readyState,\n url: ws.url,\n protocol: ws.protocol,\n extensions: ws.extensions\n });\n \n // Verify connection is actually open\n if (ws.readyState !== WebSocket.OPEN) {\n this.logger.error('WebSocket readyState is not OPEN after onopen', { readyState: ws.readyState });\n reject(new Error(`WebSocket not open: readyState=${ws.readyState}`));\n return;\n }\n \n // Set up ping/pong handler for server keepalive\n // The server sends ping messages every 54 seconds\n // Browser WebSocket automatically responds with pong, but we log it for debugging\n \n this.emit('connected');\n resolve();\n };\n\n this.ws.onmessage = (event) => {\n try {\n const message = JSON.parse(event.data) as ServerMessage;\n this.logger.debug('Received message:', message);\n this.emit('message', message);\n } catch (error) {\n const parseError = error instanceof Error \n ? error \n : new Error('Failed to parse message');\n this.logger.error('Failed to parse message:', parseError);\n this.emit('error', parseError);\n }\n };\n\n this.ws.onerror = (error: any) => {\n this.logger.error('WebSocket error:', error);\n \n // Convert browser Event to Error object for consistency\n let errorToEmit: Error;\n \n if (error instanceof Error) {\n errorToEmit = error;\n } else if (error && error.message) {\n // Node.js ws package error\n errorToEmit = error instanceof Error ? error : new Error(String(error.message));\n } else {\n // Browser Event object - create a proper Error\n errorToEmit = new Error('WebSocket connection error');\n }\n \n // Check for 401 Unauthorized (token expired/invalid)\n // In Node.js with ws package, we can check the error response\n if (isNodeEnv && error && error.message) {\n const errorMsg = String(error.message).toLowerCase();\n if (errorMsg.includes('401') || errorMsg.includes('unauthorized')) {\n this.handleTokenExpiration();\n const tokenError = new Error('Token expired or invalid. Please refresh your token and reconnect.');\n tokenError.name = 'TokenExpiredError';\n this.emit('error', tokenError);\n reject(tokenError);\n return;\n }\n }\n \n this.emit('error', errorToEmit);\n // Don't reject here - let onclose handle reconnection\n };\n\n this.ws.onclose = (event) => {\n this.logger.debug('WebSocket closed:', { \n code: event.code, \n reason: event.reason, \n wasClean: event.wasClean \n });\n \n // Log abnormal closures for debugging\n if (event.code === 1006) {\n this.logger.warn('Abnormal closure (1006) - connection closed without proper handshake. Possible causes: network issue, server closed connection, CORS issue, or protocol mismatch.');\n }\n \n // Check for 401 Unauthorized via close code or reason\n // Close code 1008 = Policy Violation (often used for auth failures)\n // Close code 1002 = Protocol Error (sometimes used for auth failures)\n const isAuthFailure = event.code === 1008 || \n event.code === 1002 ||\n (event.reason && event.reason.toLowerCase().includes('unauthorized')) ||\n (event.reason && event.reason.toLowerCase().includes('401'));\n \n if (isAuthFailure) {\n this.handleTokenExpiration();\n const tokenError = new Error('Token expired or invalid. Please refresh your token and reconnect.');\n tokenError.name = 'TokenExpiredError';\n this.emit('error', tokenError);\n this.emit('disconnected', { code: event.code, reason: event.reason, tokenExpired: true });\n return;\n }\n \n this.emit('disconnected', { code: event.code, reason: event.reason });\n \n // Only attempt reconnection if not manually disconnected and token is not expired\n if (!this.isManuallyDisconnected && !this.isTokenExpired && this.autoReconnect) {\n if (this.reconnectAttempts < this.maxReconnectAttempts) {\n this.scheduleReconnect();\n } else {\n this.logger.warn('Max reconnection attempts reached');\n this.emit('error', new Error('Max reconnection attempts reached'));\n }\n } else if (this.isTokenExpired) {\n this.logger.warn('Not reconnecting: token is expired');\n }\n };\n }\n\n /**\n * Handle token expiration - stop reconnection attempts\n */\n private handleTokenExpiration(): void {\n this.isTokenExpired = true;\n this.autoReconnect = false; // Stop auto-reconnecting with expired token\n \n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n\n /**\n * Disconnect from the WebSocket server\n */\n disconnect(): void {\n this.isManuallyDisconnected = true;\n this.autoReconnect = false;\n \n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n \n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n \n this.logger.debug('WebSocket disconnected');\n }\n\n /**\n * Send a message to the server\n */\n send(message: ClientMessage): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n const error = new Error('WebSocket is not connected');\n this.logger.error(error.message);\n this.emit('error', error);\n throw error;\n }\n\n try {\n const messageStr = JSON.stringify(message);\n this.logger.debug('Sending message:', message);\n this.ws.send(messageStr);\n } catch (error) {\n const sendError = error instanceof Error \n ? error \n : new Error('Failed to send message');\n this.logger.error('Send error:', sendError);\n this.emit('error', sendError);\n throw sendError;\n }\n }\n\n /**\n * Check if the WebSocket is connected\n */\n isConnected(): boolean {\n return this.ws !== null && this.ws.readyState === WebSocket.OPEN;\n }\n\n /**\n * Get current reconnection attempt count\n */\n getReconnectAttempts(): number {\n return this.reconnectAttempts;\n }\n\n /**\n * Schedule a reconnection attempt with exponential backoff\n * Backoff: 1s → 2s → 5s → 10s (max)\n */\n private scheduleReconnect(): void {\n if (this.reconnectTimer || !this.token) {\n return;\n }\n\n this.reconnectAttempts++;\n \n // Exponential backoff: 1s → 2s → 5s → 10s (max)\n const backoffDelays = [1000, 2000, 5000, 10000];\n const delay = backoffDelays[Math.min(this.reconnectAttempts - 1, backoffDelays.length - 1)];\n \n this.logger.debug(`Scheduling reconnect attempt ${this.reconnectAttempts} in ${delay}ms`);\n this.emit('reconnecting', { attempt: this.reconnectAttempts, delay });\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.attemptConnection().catch(() => {\n // Reconnection failed, will be handled by close handler\n });\n }, delay);\n }\n}\n","/**\n * Manages SDK token storage and validation\n * \n * Note: This manager only CONSUMES tokens.\n * Token issuance is handled by the backend API.\n */\nexport class TokenManager {\n private token: string | null = null;\n\n /**\n * Set the SDK token\n */\n setToken(token: string): void {\n if (!this.isValidFormat(token)) {\n throw new Error('Invalid token format');\n }\n this.token = token;\n }\n\n /**\n * Get the current SDK token\n */\n getToken(): string | null {\n return this.token;\n }\n\n /**\n * Check if a token is set\n */\n hasToken(): boolean {\n return this.token !== null && this.token.length > 0;\n }\n\n /**\n * Clear the token\n */\n clearToken(): void {\n this.token = null;\n }\n\n /**\n * Replace the current token with a new one (token rotation)\n */\n rotateToken(newToken: string): void {\n if (!this.isValidFormat(newToken)) {\n throw new Error('Invalid token format');\n }\n this.token = newToken;\n }\n\n /**\n * Validate token format (basic validation)\n */\n isValidFormat(token: string): boolean {\n // Basic validation - token should not be empty\n return typeof token === 'string' && token.length > 0;\n }\n\n /**\n * Validate that a token is present before operations\n */\n validateTokenPresence(): void {\n if (!this.hasToken()) {\n throw new Error('Token is required but not set');\n }\n }\n}\n","import { BroadcastMessagePayload } from '../websocket/protocol';\n\n/**\n * Receipt state enumeration (monotonic progression)\n */\nexport type ReceiptState = 'sent' | 'delivered' | 'read';\n\n/**\n * Message model with lifecycle awareness\n */\nexport interface Message {\n id: string;\n conversationId: string;\n content: string;\n senderId?: string;\n senderType?: 'user' | 'sdk' | 'bot';\n messageType: 'text' | 'system';\n createdAt?: Date;\n optimistic: boolean;\n receiptState?: ReceiptState;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Static helpers for Message creation\n */\nexport class MessageFactory {\n /**\n * Create an optimistic message (client-generated, not yet confirmed by server)\n */\n static createOptimistic(\n conversationId: string,\n messageId: string,\n content: string,\n messageType: 'text' | 'system' = 'text',\n metadata?: Record<string, unknown>\n ): Message {\n return {\n id: messageId,\n conversationId,\n content,\n messageType,\n optimistic: true,\n receiptState: 'sent',\n createdAt: new Date(),\n metadata,\n };\n }\n\n /**\n * Create a message from server payload (confirmed message)\n */\n static fromServerPayload(\n conversationId: string,\n payload: BroadcastMessagePayload\n ): Message {\n return {\n id: payload.message_id,\n conversationId,\n content: payload.content,\n senderId: payload.sender_id,\n senderType: payload.sender_type as 'user' | 'sdk' | 'bot' | undefined,\n messageType: payload.message_type === 'system' ? 'system' : 'text',\n optimistic: false,\n receiptState: 'sent',\n createdAt: payload.sent_at ? new Date(payload.sent_at) : new Date(),\n };\n }\n\n /**\n * Convert an optimistic message to confirmed (reconciliation)\n */\n static confirmOptimistic(\n optimisticMessage: Message,\n serverPayload: BroadcastMessagePayload\n ): Message {\n return {\n ...optimisticMessage,\n optimistic: false,\n senderId: serverPayload.sender_id,\n senderType: serverPayload.sender_type as 'user' | 'sdk' | 'bot' | undefined,\n receiptState: optimisticMessage.receiptState ?? 'sent',\n createdAt: serverPayload.sent_at ? new Date(serverPayload.sent_at) : optimisticMessage.createdAt,\n };\n }\n\n /**\n * Update receipt state on a message (immutable update)\n */\n static updateReceiptState(\n message: Message,\n receiptState: ReceiptState\n ): Message {\n return {\n ...message,\n receiptState,\n };\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport { Logger } from '../utils/logger';\n\n/**\n * Receipt state enumeration (monotonic progression)\n * \n * Note: This is also exported from messages/Message.ts for consistency\n */\nexport type ReceiptState = 'sent' | 'delivered' | 'read';\n\n/**\n * Receipt event payload\n */\nexport interface ReceiptEvent {\n messageId: string;\n state: 'delivered' | 'read';\n userId?: string;\n}\n\n/**\n * Manages receipt lifecycle with monotonic state transitions\n * \n * This manager:\n * - Tracks receipt state per message\n * - Enforces valid state transitions (sent → delivered → read)\n * - Deduplicates receipt events\n * - Emits only meaningful transitions\n */\nexport class ReceiptManager extends EventEmitter {\n /**\n * Track receipt state per message\n * Map<messageId, ReceiptState>\n */\n private receiptState: Map<string, ReceiptState> = new Map();\n \n private logger: Logger;\n\n constructor(debug: boolean = false) {\n super();\n this.logger = new Logger(debug);\n }\n\n /**\n * Get receipt state for a message\n */\n getReceiptState(messageId: string): ReceiptState | undefined {\n return this.receiptState.get(messageId);\n }\n\n /**\n * Handle a delivered receipt\n * \n * Rules:\n * - Only update if current state < delivered\n * - Ignore duplicate or regressive updates\n */\n handleDelivered(messageId: string, userId?: string): boolean {\n if (!messageId) {\n this.logger.warn('Invalid delivered receipt: missing messageId');\n return false;\n }\n\n const currentState = this.receiptState.get(messageId) ?? 'sent';\n\n // State progression: sent < delivered < read\n // Only update if current state is less than delivered\n if (this.compareStates(currentState, 'delivered') < 0) {\n this.receiptState.set(messageId, 'delivered');\n \n this.emit('receipt', {\n messageId,\n state: 'delivered',\n userId,\n } as ReceiptEvent);\n \n this.logger.debug('Receipt delivered:', messageId);\n return true;\n } else {\n // Duplicate or regressive update, ignore\n this.logger.debug('Delivered receipt ignored (already delivered or read):', messageId);\n return false;\n }\n }\n\n /**\n * Handle a read receipt\n * \n * Rules:\n * - Only update if current state < read\n * - Ignore duplicate or regressive updates\n */\n handleRead(messageId: string, userId?: string): boolean {\n if (!messageId) {\n this.logger.warn('Invalid read receipt: missing messageId');\n return false;\n }\n\n const currentState = this.receiptState.get(messageId) ?? 'sent';\n\n // State progression: sent < delivered < read\n // Only update if current state is less than read\n if (this.compareStates(currentState, 'read') < 0) {\n this.receiptState.set(messageId, 'read');\n \n this.emit('receipt', {\n messageId,\n state: 'read',\n userId,\n } as ReceiptEvent);\n \n this.logger.debug('Receipt read:', messageId);\n return true;\n } else {\n // Duplicate or regressive update, ignore\n this.logger.debug('Read receipt ignored (already read):', messageId);\n return false;\n }\n }\n\n /**\n * Compare two receipt states\n * Returns: -1 if a < b, 0 if a === b, 1 if a > b\n */\n private compareStates(a: ReceiptState, b: ReceiptState): number {\n const order: ReceiptState[] = ['sent', 'delivered', 'read'];\n const aIndex = order.indexOf(a);\n const bIndex = order.indexOf(b);\n \n if (aIndex === -1 || bIndex === -1) {\n return 0; // Invalid state, treat as equal\n }\n \n return aIndex - bIndex;\n }\n\n /**\n * Clear receipt state for a conversation\n * Note: We track by messageId, so we need to clear all messages for a conversation\n * This is called when leaving a conversation\n */\n clearConversation(conversationId: string, messageIds: string[]): void {\n let cleared = 0;\n for (const messageId of messageIds) {\n if (this.receiptState.has(messageId)) {\n this.receiptState.delete(messageId);\n cleared++;\n }\n }\n if (cleared > 0) {\n this.logger.debug('Cleared receipt state for conversation:', conversationId, `(${cleared} messages)`);\n }\n }\n\n /**\n * Clear receipt state for a specific message\n */\n clearMessage(messageId: string): void {\n if (this.receiptState.delete(messageId)) {\n this.logger.debug('Cleared receipt state for message:', messageId);\n }\n }\n\n /**\n * Clear all receipt state\n */\n clear(): void {\n this.receiptState.clear();\n this.logger.debug('Cleared all receipt state');\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport { Message, MessageFactory, ReceiptState } from './Message';\nimport { BroadcastMessagePayload } from '../websocket/protocol';\nimport { ReceiptManager } from '../receipts/ReceiptManager';\nimport { ReceiptEvent } from '../receipts/ReceiptManager';\nimport { Logger } from '../utils/logger';\n\n/**\n * Manages message lifecycle: optimistic messages, deduplication, and reconciliation\n * \n * This manager does NOT store message history.\n * It only tracks message IDs for deduplication and optimistic messages for reconciliation.\n */\nexport class MessageManager extends EventEmitter {\n /**\n * Track seen message IDs per conversation to prevent duplicates\n * Map<conversationId, Set<message_id>>\n */\n private seenMessageIds: Map<string, Set<string>> = new Map();\n\n /**\n * Track optimistic messages that are waiting for server confirmation\n * Map<conversationId, Map<message_id, Message>>\n */\n private optimisticMessages: Map<string, Map<string, Message>> = new Map();\n\n /**\n * Track confirmed messages for receipt updates\n * Map<conversationId, Map<message_id, Message>>\n */\n private confirmedMessages: Map<string, Map<string, Message>> = new Map();\n\n /**\n * Receipt manager for handling receipt lifecycle\n */\n private receiptManager: ReceiptManager;\n\n private logger: Logger;\n\n constructor(debug: boolean = false) {\n super();\n this.logger = new Logger(debug);\n this.receiptManager = new ReceiptManager(debug);\n\n this.receiptManager.on('receipt', (event: ReceiptEvent) => {\n this.updateMessageReceiptState(event);\n });\n }\n\n /**\n * Create an optimistic message and emit it immediately\n * \n * @returns The created optimistic message\n */\n createOptimisticMessage(\n conversationId: string,\n messageId: string,\n content: string,\n messageType: 'text' | 'system' = 'text',\n metadata?: Record<string, unknown>\n ): Message {\n const message = MessageFactory.createOptimistic(\n conversationId,\n messageId,\n content,\n messageType,\n metadata\n );\n\n this.trackOptimisticMessage(conversationId, messageId, message);\n\n this.trackMessageId(conversationId, messageId);\n\n this.emit('message', message);\n this.logger.debug('Created optimistic message:', messageId);\n\n return message;\n }\n\n /**\n * Handle an incoming message from the server\n * \n * This method:\n * - Checks for duplicates\n * - Reconciles optimistic messages if message_id matches\n * - Emits confirmed messages\n * \n * @returns The message (reconciled if optimistic, new if not), or null if duplicate\n */\n handleIncomingMessage(\n conversationId: string,\n serverPayload: BroadcastMessagePayload\n ): Message | null {\n const messageId = serverPayload.message_id;\n\n const optimisticMessage = this.getOptimisticMessage(conversationId, messageId);\n \n if (optimisticMessage) {\n const reconciledMessage = this.reconcileOptimisticMessage(optimisticMessage, serverPayload);\n \n this.removeOptimisticMessage(conversationId, messageId);\n \n this.trackMessageId(conversationId, messageId);\n\n this.trackConfirmedMessage(conversationId, messageId, reconciledMessage);\n \n return reconciledMessage;\n }\n\n if (this.hasSeenMessage(conversationId, messageId)) {\n this.logger.debug('Duplicate message ignored:', messageId);\n return null;\n }\n\n this.trackMessageId(conversationId, messageId);\n\n const message = MessageFactory.fromServerPayload(conversationId, serverPayload);\n\n this.trackConfirmedMessage(conversationId, messageId, message);\n\n this.emit('message', message);\n this.logger.debug('Handled incoming message:', messageId);\n\n return message;\n }\n\n /**\n * Handle a receipt update\n * \n * This method:\n * - Routes receipt to ReceiptManager\n * - Updates message receipt state if message exists\n * - Emits updated message\n */\n handleReceipt(\n _conversationId: string,\n messageId: string,\n receiptState: 'delivered' | 'read',\n userId?: string\n ): void {\n if (receiptState === 'delivered') {\n this.receiptManager.handleDelivered(messageId, userId);\n } else if (receiptState === 'read') {\n this.receiptManager.handleRead(messageId, userId);\n }\n\n }\n\n /**\n * Update message receipt state and emit updated message\n */\n private updateMessageReceiptState(event: ReceiptEvent): void {\n for (const [, messages] of this.confirmedMessages.entries()) {\n const message = messages.get(event.messageId);\n if (message) {\n const updatedMessage = MessageFactory.updateReceiptState(\n message,\n event.state as ReceiptState\n );\n\n messages.set(event.messageId, updatedMessage);\n\n this.emit('message', updatedMessage);\n this.logger.debug('Updated message receipt state:', event.messageId, event.state);\n return;\n }\n }\n\n for (const [, messages] of this.optimisticMessages.entries()) {\n const message = messages.get(event.messageId);\n if (message) {\n const updatedMessage = MessageFactory.updateReceiptState(\n message,\n event.state as ReceiptState\n );\n\n messages.set(event.messageId, updatedMessage);\n\n this.emit('message', updatedMessage);\n this.logger.debug('Updated optimistic message receipt state:', event.messageId, event.state);\n return;\n }\n }\n\n this.logger.warn('Receipt for unknown message:', event.messageId);\n }\n\n /**\n * Reconcile an optimistic message with a server confirmation\n * \n * This is called when we receive a server message with the same message_id\n * as an optimistic message we previously created.\n * \n * @returns The reconciled (confirmed) message\n */\n private reconcileOptimisticMessage(\n optimisticMessage: Message,\n serverPayload: BroadcastMessagePayload\n ): Message {\n const confirmedMessage = MessageFactory.confirmOptimistic(optimisticMessage, serverPayload);\n\n this.emit('message', confirmedMessage);\n this.logger.debug('Reconciled optimistic message:', optimisticMessage.id);\n\n return confirmedMessage;\n }\n\n /**\n * Check if we've already seen a message ID for a conversation\n */\n hasSeenMessage(conversationId: string, messageId: string): boolean {\n const seenIds = this.seenMessageIds.get(conversationId);\n return seenIds?.has(messageId) ?? false;\n }\n\n /**\n * Track a message ID for a conversation (for deduplication)\n */\n private trackMessageId(conversationId: string, messageId: string): void {\n let seenIds = this.seenMessageIds.get(conversationId);\n if (!seenIds) {\n seenIds = new Set();\n this.seenMessageIds.set(conversationId, seenIds);\n }\n seenIds.add(messageId);\n }\n\n /**\n * Track an optimistic message for later reconciliation\n */\n private trackOptimisticMessage(conversationId: string, messageId: string, message: Message): void {\n let conversationOptimistic = this.optimisticMessages.get(conversationId);\n if (!conversationOptimistic) {\n conversationOptimistic = new Map();\n this.optimisticMessages.set(conversationId, conversationOptimistic);\n }\n conversationOptimistic.set(messageId, message);\n }\n\n /**\n * Get an optimistic message by ID\n */\n private getOptimisticMessage(conversationId: string, messageId: string): Message | undefined {\n const conversationOptimistic = this.optimisticMessages.get(conversationId);\n return conversationOptimistic?.get(messageId);\n }\n\n /**\n * Remove an optimistic message from tracking\n */\n private removeOptimisticMessage(conversationId: string, messageId: string): void {\n const conversationOptimistic = this.optimisticMessages.get(conversationId);\n if (conversationOptimistic) {\n conversationOptimistic.delete(messageId);\n if (conversationOptimistic.size === 0) {\n this.optimisticMessages.delete(conversationId);\n }\n }\n }\n\n /**\n * Track a confirmed message for receipt updates\n */\n private trackConfirmedMessage(conversationId: string, messageId: string, message: Message): void {\n let conversationMessages = this.confirmedMessages.get(conversationId);\n if (!conversationMessages) {\n conversationMessages = new Map();\n this.confirmedMessages.set(conversationId, conversationMessages);\n }\n conversationMessages.set(messageId, message);\n }\n\n /**\n * Get all message IDs for a conversation (for receipt clearing)\n */\n getMessageIds(conversationId: string): string[] {\n const confirmed = this.confirmedMessages.get(conversationId);\n const optimistic = this.optimisticMessages.get(conversationId);\n \n const ids = new Set<string>();\n if (confirmed) {\n for (const id of confirmed.keys()) {\n ids.add(id);\n }\n }\n if (optimistic) {\n for (const id of optimistic.keys()) {\n ids.add(id);\n }\n }\n \n return Array.from(ids);\n }\n\n /**\n * Clear tracked message IDs and optimistic messages for a conversation\n */\n clearConversation(conversationId: string): void {\n this.seenMessageIds.delete(conversationId);\n this.optimisticMessages.delete(conversationId);\n \n const messageIds = this.getMessageIds(conversationId);\n this.receiptManager.clearConversation(conversationId, messageIds);\n this.confirmedMessages.delete(conversationId);\n \n this.logger.debug('Cleared message tracking for conversation:', conversationId);\n }\n\n /**\n * Clear all tracked message IDs and optimistic messages\n */\n clear(): void {\n this.seenMessageIds.clear();\n this.optimisticMessages.clear();\n this.confirmedMessages.clear();\n this.receiptManager.clear();\n this.logger.debug('Cleared all message tracking');\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport { Logger } from '../utils/logger';\n\n/**\n * Typing event payload\n */\nexport interface TypingEvent {\n conversationId: string;\n userId: string;\n state: 'start' | 'stop';\n}\n\n/**\n * Manages typing indicators with automatic lifecycle management\n * \n * This manager:\n * - Tracks typing state per conversation per user\n * - Automatically expires typing after 5 seconds\n * - Prevents duplicate events\n * - Emits clean, minimal events\n */\nexport class TypingManager extends EventEmitter {\n /**\n * Track active typing timers per conversation per user\n * Map<conversationId, Map<userId, timeout>>\n */\n private typingTimers: Map<string, Map<string, ReturnType<typeof setTimeout>>> = new Map();\n \n /**\n * Track who is currently typing per conversation\n * Map<conversationId, Set<userId>>\n */\n private activeTyping: Map<string, Set<string>> = new Map();\n \n private logger: Logger;\n private readonly TYPING_TIMEOUT_MS = 5000; // 5 seconds\n\n constructor(debug: boolean = false) {\n super();\n this.logger = new Logger(debug);\n }\n\n /**\n * Handle a typing_start event\n * \n * Rules:\n * - Emit only once per user until stopped\n * - Restart timeout if typing_start repeats\n */\n handleTypingStart(conversationId: string, userId: string): void {\n if (!conversationId || !userId) {\n this.logger.warn('Invalid typing_start: missing conversationId or userId');\n return;\n }\n\n // Get or create conversation typing state\n let conversationTyping = this.activeTyping.get(conversationId);\n if (!conversationTyping) {\n conversationTyping = new Set();\n this.activeTyping.set(conversationId, conversationTyping);\n }\n\n // Get or create conversation timers\n let conversationTimers = this.typingTimers.get(conversationId);\n if (!conversationTimers) {\n conversationTimers = new Map();\n this.typingTimers.set(conversationId, conversationTimers);\n }\n\n const wasTyping = conversationTyping.has(userId);\n\n // Clear existing timer if any\n const existingTimer = conversationTimers.get(userId);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n\n // Mark as typing\n conversationTyping.add(userId);\n\n // Set up auto-expiry timer\n const timer = setTimeout(() => {\n this.handleTypingStop(conversationId, userId);\n }, this.TYPING_TIMEOUT_MS);\n\n conversationTimers.set(userId, timer);\n\n // Emit typing start only if user wasn't already typing\n if (!wasTyping) {\n this.emit('typing', {\n conversationId,\n userId,\n state: 'start',\n } as TypingEvent);\n this.logger.debug('Typing started:', conversationId, userId);\n } else {\n // User was already typing, just restart the timer (no event)\n this.logger.debug('Typing timer restarted:', conversationId, userId);\n }\n }\n\n /**\n * Handle a typing_stop event\n * \n * Rules:\n * - Emit only if user was typing\n */\n handleTypingStop(conversationId: string, userId: string): void {\n if (!conversationId || !userId) {\n this.logger.warn('Invalid typing_stop: missing conversationId or userId');\n return;\n }\n\n const conversationTyping = this.activeTyping.get(conversationId);\n const conversationTimers = this.typingTimers.get(conversationId);\n\n if (!conversationTyping || !conversationTyping.has(userId)) {\n // User wasn't typing, ignore\n this.logger.debug('Typing stop ignored (user not typing):', conversationId, userId);\n return;\n }\n\n // Clear timer\n const timer = conversationTimers?.get(userId);\n if (timer) {\n clearTimeout(timer);\n conversationTimers?.delete(userId);\n }\n\n // Remove from active typing\n conversationTyping.delete(userId);\n\n // Clean up empty maps\n if (conversationTyping.size === 0) {\n this.activeTyping.delete(conversationId);\n }\n if (conversationTimers && conversationTimers.size === 0) {\n this.typingTimers.delete(conversationId);\n }\n\n // Emit typing stop\n this.emit('typing', {\n conversationId,\n userId,\n state: 'stop',\n } as TypingEvent);\n this.logger.debug('Typing stopped:', conversationId, userId);\n }\n\n /**\n * Clear all typing state for a conversation\n */\n clearConversation(conversationId: string): void {\n const conversationTyping = this.activeTyping.get(conversationId);\n const conversationTimers = this.typingTimers.get(conversationId);\n\n if (conversationTyping) {\n // Emit stop events for all active typing users\n for (const userId of conversationTyping) {\n this.emit('typing', {\n conversationId,\n userId,\n state: 'stop',\n } as TypingEvent);\n }\n this.activeTyping.delete(conversationId);\n }\n\n if (conversationTimers) {\n // Clear all timers\n for (const timer of conversationTimers.values()) {\n clearTimeout(timer);\n }\n this.typingTimers.delete(conversationId);\n }\n\n this.logger.debug('Cleared typing state for conversation:', conversationId);\n }\n\n /**\n * Clear all typing state\n */\n clear(): void {\n // Clear all timers\n for (const conversationTimers of this.typingTimers.values()) {\n for (const timer of conversationTimers.values()) {\n clearTimeout(timer);\n }\n }\n\n this.typingTimers.clear();\n this.activeTyping.clear();\n this.logger.debug('Cleared all typing state');\n }\n\n /**\n * Get currently typing users for a conversation\n */\n getTypingUsers(conversationId: string): string[] {\n const conversationTyping = this.activeTyping.get(conversationId);\n return conversationTyping ? Array.from(conversationTyping) : [];\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport { v4 as uuidv4 } from 'uuid';\nimport {\n SendMessageMessage,\n BroadcastMessagePayload,\n TypingPayload,\n PresencePayload,\n TypingStartMessage,\n TypingStopMessage,\n} from '../websocket/protocol';\nimport { MessageManager } from '../messages/MessageManager';\nimport { Message } from '../messages/Message';\nimport { TypingManager } from '../typing/TypingManager';\nimport { TypingEvent } from '../typing/TypingManager';\nimport { ReceiptEvent } from '../receipts/ReceiptManager';\n\n/**\n * Conversation class representing a single conversation\n * \n * This class provides a scoped API for conversation-level operations.\n * It does NOT persist messages or store history.\n */\nexport class Conversation extends EventEmitter {\n public readonly id: string;\n private _isJoined: boolean = false;\n private messageManager: MessageManager;\n private typingManager: TypingManager;\n\n /**\n * Callback function to send messages via WebSocket\n * Set by ConversationManager\n */\n private sendMessageHandler?: (message: SendMessageMessage) => void;\n\n /**\n * Callback function to send typing events via WebSocket\n * Set by ConversationManager\n */\n private sendTypingHandler?: (message: TypingStartMessage | TypingStopMessage) => void;\n\n constructor(conversationId: string, debug: boolean = false) {\n super();\n this.id = conversationId;\n this.messageManager = new MessageManager(debug);\n this.typingManager = new TypingManager(debug);\n\n // Forward MessageManager events to Conversation\n this.messageManager.on('message', (message: Message) => {\n // Only emit if this message belongs to this conversation\n if (message.conversationId === this.id) {\n this.emit('message', message);\n }\n });\n\n // Forward receipt events from MessageManager\n this.messageManager.on('receipt', (event: ReceiptEvent) => {\n // Only emit if this receipt belongs to this conversation\n // We need to check if the message belongs to this conversation\n // Since we don't have conversationId in ReceiptEvent, we'll emit it\n // and let the consumer filter if needed\n this.emit('receipt', event);\n });\n\n // Forward TypingManager events to Conversation\n this.typingManager.on('typing', (event: TypingEvent) => {\n // Only emit if this typing event belongs to this conversation\n if (event.conversationId === this.id) {\n this.emit('typing', {\n userId: event.userId,\n state: event.state,\n });\n }\n });\n }\n\n /**\n * Check if this conversation is currently joined\n */\n get isJoined(): boolean {\n return this._isJoined;\n }\n\n /**\n * Set the send message handler (called by ConversationManager)\n */\n setSendMessageHandler(handler: (message: SendMessageMessage) => void): void {\n this.sendMessageHandler = handler;\n }\n\n /**\n * Set the send typing handler (called by ConversationManager)\n */\n setSendTypingHandler(handler: (message: TypingStartMessage | TypingStopMessage) => void): void {\n this.sendTypingHandler = handler;\n }\n\n /**\n * Mark conversation as joined\n */\n markJoined(): void {\n if (!this._isJoined) {\n this._isJoined = true;\n this.emit('joined', { conversation_id: this.id });\n }\n }\n\n /**\n * Mark conversation as left\n */\n markLeft(): void {\n if (this._isJoined) {\n this._isJoined = false;\n this.emit('left', { conversation_id: this.id });\n }\n }\n\n /**\n * Send a message to this conversation\n * \n * This method:\n * 1. Generates a message_id (UUID v4)\n * 2. Creates an optimistic Message\n * 3. Emits the optimistic message immediately\n * 4. Sends the message via transport\n */\n sendMessage(\n content: string,\n messageType: 'text' | 'system' = 'text',\n metadata?: Record<string, unknown>\n ): void {\n if (!this.sendMessageHandler) {\n const error = new Error('Conversation is not connected. Call join() first.');\n this.emit('error', error);\n throw error;\n }\n\n if (!this._isJoined) {\n const error = new Error('Conversation is not joined. Call join() first.');\n this.emit('error', error);\n throw error;\n }\n\n // Generate client-side message ID\n const messageId = uuidv4();\n\n // Create optimistic message (emits immediately via MessageManager)\n this.messageManager.createOptimisticMessage(\n this.id,\n messageId,\n content,\n messageType,\n metadata\n );\n\n // Send to server via transport\n const protocolMessage: SendMessageMessage = {\n type: 'message',\n conversation_id: this.id,\n payload: {\n message_id: messageId,\n content,\n message_type: messageType,\n },\n };\n\n try {\n this.sendMessageHandler(protocolMessage);\n } catch (error) {\n const sendError = error instanceof Error \n ? error \n : new Error('Failed to send message');\n this.emit('error', sendError);\n throw sendError;\n }\n }\n\n /**\n * Handle an incoming message from the server\n * Called by ConversationManager when routing messages\n */\n handleIncomingMessage(payload: BroadcastMessagePayload): void {\n // Route through MessageManager (handles deduplication and reconciliation)\n const message = this.messageManager.handleIncomingMessage(this.id, payload);\n \n // MessageManager emits the message event, which we forward to Conversation\n // If message is null, it was a duplicate and already handled\n if (message) {\n // The message was already emitted by MessageManager, which we listen to\n // So we don't need to emit again\n }\n }\n\n /**\n * Handle a receipt update\n * Called by ConversationManager when routing receipt messages\n */\n handleReceipt(messageId: string, receiptState: 'delivered' | 'read', userId?: string): void {\n // Route through MessageManager's ReceiptManager\n this.messageManager.handleReceipt(this.id, messageId, receiptState, userId);\n // Receipt events are emitted by MessageManager, which we forward to Conversation\n }\n\n /**\n * Handle a typing event from the server\n * Called by ConversationManager when routing typing messages\n */\n handleTyping(payload: TypingPayload): void {\n // Route through TypingManager (handles lifecycle, timers, deduplication)\n if (payload.state === 'start') {\n this.typingManager.handleTypingStart(this.id, payload.user_id);\n } else if (payload.state === 'stop') {\n this.typingManager.handleTypingStop(this.id, payload.user_id);\n }\n // TypingManager emits events, which we forward to Conversation\n }\n\n /**\n * Emit a presence event (called by ConversationManager when routing)\n * Note: Presence is SDK-global, but we emit it here for convenience\n */\n emitPresence(payload: PresencePayload): void {\n this.emit('presence', {\n userId: payload.user_id,\n state: payload.state,\n });\n }\n\n /**\n * Clear message tracking for this conversation\n */\n clearMessages(): void {\n this.messageManager.clearConversation(this.id);\n }\n\n /**\n * Clear typing state for this conversation\n */\n clearTyping(): void {\n this.typingManager.clearConversation(this.id);\n }\n\n /**\n * Start typing indicator\n * \n * This method sends a typing_start message to the server.\n * The TypingManager will handle debouncing and auto-expiry.\n */\n startTyping(): void {\n if (!this.sendTypingHandler) {\n const error = new Error('Conversation is not connected. Call join() first.');\n this.emit('error', error);\n throw error;\n }\n\n if (!this._isJoined) {\n const error = new Error('Conversation is not joined. Call join() first.');\n this.emit('error', error);\n throw error;\n }\n\n const typingMessage: TypingStartMessage = {\n type: 'typing_start',\n conversation_id: this.id,\n };\n\n try {\n this.sendTypingHandler(typingMessage);\n } catch (error) {\n const sendError = error instanceof Error \n ? error \n : new Error('Failed to send typing_start');\n this.emit('error', sendError);\n throw sendError;\n }\n }\n\n /**\n * Stop typing indicator\n * \n * This method sends a typing_stop message to the server.\n */\n stopTyping(): void {\n if (!this.sendTypingHandler) {\n const error = new Error('Conversation is not connected. Call join() first.');\n this.emit('error', error);\n throw error;\n }\n\n if (!this._isJoined) {\n const error = new Error('Conversation is not joined. Call join() first.');\n this.emit('error', error);\n throw error;\n }\n\n const typingMessage: TypingStopMessage = {\n type: 'typing_stop',\n conversation_id: this.id,\n };\n\n try {\n this.sendTypingHandler(typingMessage);\n } catch (error) {\n const sendError = error instanceof Error \n ? error \n : new Error('Failed to send typing_stop');\n this.emit('error', sendError);\n throw sendError;\n }\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport { Conversation } from './Conversation';\nimport { Logger } from '../utils/logger';\nimport {\n ServerMessage,\n ReceivedMessageMessage,\n TypingMessage,\n PresenceMessage,\n ReceiptMessage,\n SupportMessage,\n JoinedMessage,\n SendMessageMessage,\n TypingStartMessage,\n TypingStopMessage,\n} from '../websocket/protocol';\n\n/**\n * Manages Conversation instances and routes incoming protocol messages\n */\nexport class ConversationManager extends EventEmitter {\n private conversations: Map<string, Conversation> = new Map();\n private sendMessageHandler?: (message: SendMessageMessage) => void;\n private sendTypingHandler?: (message: TypingStartMessage | TypingStopMessage) => void;\n private supportMessageHandler?: (conversationId: string, eventType: string, payload?: Record<string, unknown>) => void;\n private logger: Logger;\n private debug: boolean;\n\n constructor(\n sendMessageHandler: (message: SendMessageMessage) => void,\n debug: boolean = false,\n supportMessageHandler?: (conversationId: string, eventType: string, payload?: Record<string, unknown>) => void,\n sendTypingHandler?: (message: TypingStartMessage | TypingStopMessage) => void\n ) {\n super();\n this.sendMessageHandler = sendMessageHandler;\n this.sendTypingHandler = sendTypingHandler;\n this.supportMessageHandler = supportMessageHandler;\n this.debug = debug;\n this.logger = new Logger(debug);\n }\n\n /**\n * Set the support message handler (called by ChatAfrika)\n */\n setSupportMessageHandler(handler: (conversationId: string, eventType: string, payload?: Record<string, unknown>) => void): void {\n this.supportMessageHandler = handler;\n }\n\n /**\n * Set the send typing handler (called by ChatAfrika)\n */\n setSendTypingHandler(handler: (message: TypingStartMessage | TypingStopMessage) => void): void {\n this.sendTypingHandler = handler;\n // Update all existing conversations with the new handler\n for (const conversation of this.conversations.values()) {\n conversation.setSendTypingHandler(handler);\n }\n }\n\n /**\n * Get or create a Conversation instance\n * Conversations are lazy-created\n */\n get(conversationId: string): Conversation {\n if (!conversationId || conversationId.length === 0) {\n throw new Error('Conversation ID is required');\n }\n\n let conversation = this.conversations.get(conversationId);\n \n if (!conversation) {\n conversation = new Conversation(conversationId, this.debug);\n \n // Set up the send message handler\n if (this.sendMessageHandler) {\n conversation.setSendMessageHandler(this.sendMessageHandler);\n }\n \n // Set up the send typing handler\n if (this.sendTypingHandler) {\n conversation.setSendTypingHandler(this.sendTypingHandler);\n }\n \n this.conversations.set(conversationId, conversation);\n this.logger.debug('Created conversation instance:', conversationId);\n }\n\n return conversation;\n }\n\n /**\n * Check if a conversation instance exists\n */\n has(conversationId: string): boolean {\n return this.conversations.has(conversationId);\n }\n\n /**\n * Join a conversation\n * This delegates to the transport layer (ChatAfrika)\n */\n async join(conversationId: string, joinHandler: (conversationId: string) => Promise<void>): Promise<void> {\n if (!conversationId || conversationId.length === 0) {\n throw new Error('Conversation ID is required');\n }\n\n // Get or create the conversation (ensures it exists)\n this.get(conversationId);\n\n // Delegate join to transport layer\n await joinHandler(conversationId);\n \n // Note: The conversation will be marked as joined when we receive the 'joined' message\n this.logger.debug('Join requested for conversation:', conversationId);\n }\n\n /**\n * Leave a conversation\n * This delegates to the transport layer (ChatAfrika)\n */\n async leave(conversationId: string, leaveHandler: (conversationId: string) => Promise<void>): Promise<void> {\n if (!conversationId || conversationId.length === 0) {\n throw new Error('Conversation ID is required');\n }\n\n const conversation = this.conversations.get(conversationId);\n \n if (conversation) {\n // Clear typing state when leaving\n conversation.clearTyping();\n \n // Delegate leave to transport layer\n await leaveHandler(conversationId);\n \n // Mark as left\n conversation.markLeft();\n this.logger.debug('Left conversation:', conversationId);\n } else {\n // Still attempt to leave (might be a race condition)\n await leaveHandler(conversationId);\n this.logger.warn('Attempted to leave unknown conversation:', conversationId);\n }\n }\n\n /**\n * Route an incoming protocol message to the appropriate Conversation\n * \n * Messages are routed through MessageManager for lifecycle handling.\n * Typing events are routed through TypingManager.\n * Only messages for joined conversations are processed.\n */\n routeIncomingMessage(message: ServerMessage): void {\n // Extract conversation_id from message\n let conversationId: string | undefined;\n\n switch (message.type) {\n case 'joined':\n conversationId = (message as JoinedMessage).payload?.conversation_id || message.conversation_id;\n if (conversationId) {\n const conversation = this.get(conversationId);\n conversation.markJoined();\n }\n break;\n\n case 'message':\n conversationId = (message as ReceivedMessageMessage).conversation_id;\n if (conversationId) {\n const conversation = this.conversations.get(conversationId);\n \n if (conversation) {\n // Only process messages for joined conversations\n if (conversation.isJoined) {\n // Route through Conversation's MessageManager (handles deduplication and reconciliation)\n conversation.handleIncomingMessage((message as ReceivedMessageMessage).payload);\n } else {\n this.logger.warn('Received message for conversation that is not joined:', conversationId);\n }\n } else {\n this.logger.warn('Received message for unknown conversation:', conversationId);\n }\n }\n break;\n\n case 'typing':\n conversationId = (message as TypingMessage).conversation_id;\n if (conversationId) {\n const conversation = this.conversations.get(conversationId);\n \n if (conversation) {\n // Only process typing events for joined conversations\n if (conversation.isJoined) {\n // Route through Conversation's TypingManager (handles lifecycle, timers, deduplication)\n conversation.handleTyping((message as TypingMessage).payload);\n } else {\n this.logger.warn('Received typing indicator for conversation that is not joined:', conversationId);\n }\n } else {\n this.logger.warn('Received typing indicator for unknown conversation:', conversationId);\n }\n }\n break;\n\n case 'receipt':\n conversationId = (message as ReceiptMessage).conversation_id;\n if (conversationId) {\n const conversation = this.conversations.get(conversationId);\n \n if (conversation) {\n // Only process receipts for joined conversations\n if (conversation.isJoined) {\n const receiptMsg = message as ReceiptMessage;\n // Route through Conversation's MessageManager (handles receipt lifecycle)\n conversation.handleReceipt(\n receiptMsg.payload.message_id,\n receiptMsg.payload.state,\n receiptMsg.payload.user_id\n );\n } else {\n this.logger.warn('Received receipt for conversation that is not joined:', conversationId);\n }\n } else {\n this.logger.warn('Received receipt for unknown conversation:', conversationId);\n }\n }\n break;\n\n case 'support':\n // Support messages are routed separately via routeSupportMessage\n // This is handled in ChatAfrika\n break;\n\n case 'presence':\n // Presence is SDK-global, not conversation-scoped\n // We'll handle this in ChatAfrika, not here\n // But we can still emit it to conversations for convenience\n conversationId = (message as PresenceMessage).conversation_id;\n if (conversationId) {\n const conversation = this.conversations.get(conversationId);\n if (conversation && conversation.isJoined) {\n conversation.emitPresence((message as PresenceMessage).payload);\n }\n }\n break;\n\n case 'error':\n // Errors are not conversation-scoped, so we don't route them\n this.logger.error('Received error message:', (message as { error: string }).error);\n break;\n }\n }\n\n /**\n * Route a support protocol message to SupportManager\n */\n routeSupportMessage(message: SupportMessage): void {\n if (!this.supportMessageHandler) {\n this.logger.warn('Support message handler not set, ignoring support message');\n return;\n }\n\n const conversationId = message.conversation_id;\n if (!conversationId) {\n this.logger.warn('Support message missing conversation_id');\n return;\n }\n\n const eventType = message.payload?.event;\n if (!eventType) {\n this.logger.warn('Support message missing event type');\n return;\n }\n\n // Route to support message handler (SupportManager)\n this.supportMessageHandler(conversationId, eventType, message.payload);\n }\n\n /**\n * Remove a conversation instance\n */\n remove(conversationId: string): void {\n const conversation = this.conversations.get(conversationId);\n if (conversation) {\n conversation.markLeft();\n conversation.clearMessages();\n conversation.clearTyping();\n this.conversations.delete(conversationId);\n this.logger.debug('Removed conversation instance:', conversationId);\n }\n }\n\n /**\n * Get all conversation IDs\n */\n getAllIds(): string[] {\n return Array.from(this.conversations.keys());\n }\n\n /**\n * Clear all conversations\n */\n clear(): void {\n for (const conversation of this.conversations.values()) {\n conversation.markLeft();\n conversation.clearMessages();\n conversation.clearTyping();\n }\n this.conversations.clear();\n this.logger.debug('Cleared all conversations');\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport { Logger } from '../utils/logger';\n\n/**\n * Presence event payload\n */\nexport interface PresenceEvent {\n userId: string;\n state: 'online' | 'offline';\n}\n\n/**\n * Manages user presence with state tracking and deduplication\n * \n * This manager:\n * - Tracks presence state per user (SDK-global, not conversation-scoped)\n * - Emits only on state changes\n * - Deduplicates duplicate events\n */\nexport class PresenceManager extends EventEmitter {\n /**\n * Track current presence state per user\n * Map<userId, \"online\" | \"offline\">\n */\n private presenceState: Map<string, 'online' | 'offline'> = new Map();\n \n private logger: Logger;\n\n constructor(debug: boolean = false) {\n super();\n this.logger = new Logger(debug);\n }\n\n /**\n * Handle a presence event\n * \n * Rules:\n * - Emit only on state change\n * - Ignore duplicate online/online or offline/offline events\n */\n handlePresence(userId: string, state: 'online' | 'offline'): void {\n if (!userId) {\n this.logger.warn('Invalid presence event: missing userId');\n return;\n }\n\n if (state !== 'online' && state !== 'offline') {\n this.logger.warn('Invalid presence state:', state);\n return;\n }\n\n const currentState = this.presenceState.get(userId);\n\n // Only emit if state changed\n if (currentState !== state) {\n this.presenceState.set(userId, state);\n \n this.emit('presence', {\n userId,\n state,\n } as PresenceEvent);\n \n this.logger.debug('Presence changed:', userId, state);\n } else {\n // Duplicate event, ignore\n this.logger.debug('Duplicate presence event ignored:', userId, state);\n }\n }\n\n /**\n * Get current presence state for a user\n */\n getPresence(userId: string): 'online' | 'offline' | undefined {\n return this.presenceState.get(userId);\n }\n\n /**\n * Get presence state for multiple users\n */\n getPresences(userIds: string[]): Map<string, 'online' | 'offline'> {\n const result = new Map<string, 'online' | 'offline'>();\n for (const userId of userIds) {\n const state = this.presenceState.get(userId);\n if (state) {\n result.set(userId, state);\n }\n }\n return result;\n }\n\n /**\n * Clear presence for a user\n */\n clearPresence(userId: string): void {\n const hadState = this.presenceState.has(userId);\n this.presenceState.delete(userId);\n \n if (hadState) {\n this.logger.debug('Cleared presence for user:', userId);\n }\n }\n\n /**\n * Clear all presence state\n */\n clear(): void {\n this.presenceState.clear();\n this.logger.debug('Cleared all presence state');\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport { Conversation } from '../conversations/Conversation';\nimport { Logger } from '../utils/logger';\n\n/**\n * Support session role\n */\nexport type SupportRole = 'customer' | 'agent';\n\n/**\n * Support session status\n */\nexport type SupportStatus = 'queued' | 'assigned' | 'active' | 'closed';\n\n/**\n * SupportSession wraps a Conversation and adds support-specific semantics\n * \n * This is a thin semantic layer that provides:\n * - Role awareness (customer vs agent)\n * - Assignment state tracking\n * - Bot handover awareness\n * \n * It does NOT replace Conversation - it wraps it.\n */\nexport class SupportSession extends EventEmitter {\n public readonly conversationId: string;\n private conversation: Conversation;\n private role: SupportRole;\n private assignedAgentId?: string;\n private botActive: boolean = false;\n private status: SupportStatus = 'queued';\n private logger: Logger;\n\n constructor(\n conversationId: string,\n conversation: Conversation,\n role: SupportRole,\n debug: boolean = false\n ) {\n super();\n this.conversationId = conversationId;\n this.conversation = conversation;\n this.role = role;\n this.logger = new Logger(debug);\n\n // Forward conversation events\n this.conversation.on('message', (msg) => this.emit('message', msg));\n this.conversation.on('typing', (event) => this.emit('typing', event));\n this.conversation.on('presence', (event) => this.emit('presence', event));\n this.conversation.on('joined', (event) => this.emit('joined', event));\n this.conversation.on('left', (event) => this.emit('left', event));\n this.conversation.on('error', (error) => this.emit('error', error));\n }\n\n /**\n * Get the underlying Conversation instance\n */\n getConversation(): Conversation {\n return this.conversation;\n }\n\n /**\n * Check if this session is for a customer\n */\n isCustomer(): boolean {\n return this.role === 'customer';\n }\n\n /**\n * Check if this session is for an agent\n */\n isAgent(): boolean {\n return this.role === 'agent';\n }\n\n /**\n * Get the current role\n */\n getRole(): SupportRole {\n return this.role;\n }\n\n /**\n * Check if bot is currently active\n */\n isBotActive(): boolean {\n return this.botActive;\n }\n\n /**\n * Get the assigned agent ID (if any)\n */\n getAssignedAgent(): string | undefined {\n return this.assignedAgentId;\n }\n\n /**\n * Get the current status\n */\n getStatus(): SupportStatus {\n return this.status;\n }\n\n /**\n * Handle assignment of an agent\n */\n handleAssigned(agentId: string): void {\n if (this.assignedAgentId === agentId) {\n // Already assigned to this agent, ignore\n return;\n }\n\n const previousAgentId = this.assignedAgentId;\n const wasAssigned = previousAgentId !== undefined;\n this.assignedAgentId = agentId;\n\n if (this.status === 'queued') {\n this.status = 'assigned';\n } else if (this.status === 'assigned' || this.status === 'active') {\n // Status remains assigned or active\n }\n\n if (!wasAssigned) {\n this.emit('assigned', { agentId });\n this.logger.debug('Support session assigned:', this.conversationId, agentId);\n } else {\n // Reassignment\n this.emit('assigned', { agentId, previousAgentId });\n this.logger.debug('Support session reassigned:', this.conversationId, agentId, 'from', previousAgentId);\n }\n }\n\n /**\n * Handle unassignment of an agent\n */\n handleUnassigned(): void {\n if (this.assignedAgentId === undefined) {\n // Already unassigned, ignore\n return;\n }\n\n const previousAgentId = this.assignedAgentId;\n this.assignedAgentId = undefined;\n\n if (this.status === 'assigned' || this.status === 'active') {\n this.status = 'queued';\n }\n\n this.emit('unassigned', { previousAgentId });\n this.logger.debug('Support session unassigned:', this.conversationId);\n }\n\n /**\n * Handle bot takeover\n */\n handleBotTakeover(): void {\n if (this.botActive) {\n // Already active, ignore\n return;\n }\n\n this.botActive = true;\n this.emit('bot_takeover', {});\n this.logger.debug('Bot took over support session:', this.conversationId);\n }\n\n /**\n * Handle bot release\n */\n handleBotReleased(): void {\n if (!this.botActive) {\n // Already released, ignore\n return;\n }\n\n this.botActive = false;\n this.emit('bot_released', {});\n this.logger.debug('Bot released support session:', this.conversationId);\n }\n\n /**\n * Handle session closed\n */\n handleClosed(): void {\n if (this.status === 'closed') {\n // Already closed, ignore\n return;\n }\n\n const previousStatus = this.status;\n this.status = 'closed';\n this.emit('closed', { previousStatus });\n this.logger.debug('Support session closed:', this.conversationId);\n }\n\n /**\n * Handle session reopened\n */\n handleReopened(): void {\n if (this.status !== 'closed') {\n // Not closed, ignore\n return;\n }\n\n this.status = this.assignedAgentId ? 'assigned' : 'queued';\n this.emit('reopened', {});\n this.logger.debug('Support session reopened:', this.conversationId);\n }\n\n /**\n * Send a message (delegates to Conversation)\n */\n sendMessage(\n content: string,\n messageType: 'text' | 'system' = 'text',\n metadata?: Record<string, unknown>\n ): void {\n this.conversation.sendMessage(content, messageType, metadata);\n }\n\n /**\n * Join the conversation (delegates to Conversation)\n */\n async join(): Promise<void> {\n // This will be handled by ConversationManager\n // SupportSession doesn't manage join/leave directly\n }\n\n /**\n * Leave the conversation (delegates to Conversation)\n */\n async leave(): Promise<void> {\n // This will be handled by ConversationManager\n // SupportSession doesn't manage join/leave directly\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport { SupportSession, SupportRole } from './SupportSession';\nimport { Conversation } from '../conversations/Conversation';\nimport { Logger } from '../utils/logger';\n\n/**\n * Manages SupportSession instances\n * \n * This manager:\n * - Creates SupportSession instances lazily\n * - Tracks support sessions by conversation ID\n * - Provides role-aware access to support conversations\n */\nexport class SupportManager extends EventEmitter {\n private sessions: Map<string, SupportSession> = new Map();\n private getConversationHandler: (conversationId: string) => Conversation;\n private logger: Logger;\n private debug: boolean;\n\n constructor(\n getConversationHandler: (conversationId: string) => Conversation,\n debug: boolean = false\n ) {\n super();\n this.getConversationHandler = getConversationHandler;\n this.debug = debug;\n this.logger = new Logger(debug);\n }\n\n /**\n * Get or create a SupportSession for a conversation\n * \n * Note: This assumes the conversation is a support conversation.\n * The role is determined by the SDK user's context (not inferred).\n * \n * @param conversationId - The conversation ID\n * @param role - The role of the current user ('customer' or 'agent')\n * @returns SupportSession instance\n */\n get(conversationId: string, role: SupportRole = 'customer'): SupportSession {\n if (!conversationId || conversationId.length === 0) {\n throw new Error('Conversation ID is required');\n }\n\n let session = this.sessions.get(conversationId);\n\n if (!session) {\n // Get or create the underlying conversation\n const conversation = this.getConversationHandler(conversationId);\n\n // Create support session wrapper\n session = new SupportSession(conversationId, conversation, role, this.debug);\n\n // Forward session events\n session.on('assigned', (data) => this.emit('assigned', { conversationId, ...data }));\n session.on('unassigned', (data) => this.emit('unassigned', { conversationId, ...data }));\n session.on('bot_takeover', () => this.emit('bot_takeover', { conversationId }));\n session.on('bot_released', () => this.emit('bot_released', { conversationId }));\n session.on('closed', (data) => this.emit('closed', { conversationId, ...data }));\n session.on('reopened', () => this.emit('reopened', { conversationId }));\n\n this.sessions.set(conversationId, session);\n this.logger.debug('Created support session:', conversationId, role);\n }\n\n return session;\n }\n\n /**\n * Check if a support session exists\n */\n has(conversationId: string): boolean {\n return this.sessions.has(conversationId);\n }\n\n /**\n * Get a support session if it exists\n */\n getSession(conversationId: string): SupportSession | undefined {\n return this.sessions.get(conversationId);\n }\n\n /**\n * Handle a support protocol event\n */\n handleSupportEvent(\n conversationId: string,\n eventType: 'assigned' | 'unassigned' | 'bot_takeover' | 'bot_released' | 'closed' | 'reopened',\n payload?: Record<string, unknown>\n ): void {\n const session = this.sessions.get(conversationId);\n\n if (!session) {\n // Session doesn't exist yet - might be created later\n // For now, we'll create it if we have enough info\n if (eventType === 'assigned' && payload?.agent_id) {\n // We can infer this is a support conversation\n // But we don't know the role yet, so we'll default to 'customer'\n // The user can call get() with the correct role later\n this.logger.debug('Support event for unknown session, will be handled when session is created:', conversationId);\n } else {\n this.logger.warn('Support event for unknown session:', conversationId, eventType);\n }\n return;\n }\n\n // Route event to session\n switch (eventType) {\n case 'assigned':\n if (payload?.agent_id && typeof payload.agent_id === 'string') {\n session.handleAssigned(payload.agent_id);\n }\n break;\n case 'unassigned':\n session.handleUnassigned();\n break;\n case 'bot_takeover':\n session.handleBotTakeover();\n break;\n case 'bot_released':\n session.handleBotReleased();\n break;\n case 'closed':\n session.handleClosed();\n break;\n case 'reopened':\n session.handleReopened();\n break;\n }\n }\n\n /**\n * Remove a support session\n */\n remove(conversationId: string): void {\n const session = this.sessions.get(conversationId);\n if (session) {\n this.sessions.delete(conversationId);\n this.logger.debug('Removed support session:', conversationId);\n }\n }\n\n /**\n * Clear all support sessions\n */\n clear(): void {\n this.sessions.clear();\n this.logger.debug('Cleared all support sessions');\n }\n}\n\n","import { EventEmitter } from 'eventemitter3';\nimport { ClientConfig } from './ClientConfig';\nimport { ConnectionState } from './ConnectionState';\nimport { WebSocketClient } from '../websocket/WebSocketClient';\nimport { TokenManager } from '../auth/TokenManager';\nimport { ConversationManager } from '../conversations/ConversationManager';\nimport { Conversation } from '../conversations/Conversation';\nimport { PresenceManager } from '../presence/PresenceManager';\nimport { PresenceEvent } from '../presence/PresenceManager';\nimport { SupportManager } from '../support/SupportManager';\nimport { SupportSession } from '../support/SupportSession';\nimport { Logger } from '../utils/logger';\nimport {\n ServerMessage,\n JoinMessage,\n LeaveMessage,\n SendMessageMessage,\n PresenceMessage,\n SupportMessage,\n TypingStartMessage,\n TypingStopMessage,\n} from '../websocket/protocol';\n\n/**\n * Main ChatAfrika SDK class\n * \n * This is the primary entry point for the SDK.\n * It manages the connection state and provides access to all SDK features.\n */\nexport class ChatAfrika extends EventEmitter {\n private config: Required<ClientConfig>;\n private connectionState: ConnectionState = ConnectionState.DISCONNECTED;\n private wsClient: WebSocketClient | null = null;\n private tokenManager: TokenManager;\n private conversationManager: ConversationManager;\n private presenceManager: PresenceManager;\n private supportManager: SupportManager;\n private logger: Logger;\n\n constructor(config: ClientConfig) {\n super();\n \n this.config = {\n autoReconnect: true,\n maxReconnectAttempts: 5,\n reconnectDelay: 1000,\n debug: false,\n apiUrl: '',\n ...config,\n };\n\n this.tokenManager = new TokenManager();\n this.tokenManager.setToken(config.token);\n this.logger = new Logger(this.config.debug);\n\n // Initialize WebSocket client\n this.wsClient = new WebSocketClient(this.config.wsUrl, {\n autoReconnect: this.config.autoReconnect,\n maxReconnectAttempts: this.config.maxReconnectAttempts,\n reconnectDelay: this.config.reconnectDelay,\n debug: this.config.debug,\n });\n\n // Initialize SupportManager first (needed for ConversationManager)\n this.supportManager = new SupportManager(\n (conversationId: string) => this.conversationManager.get(conversationId),\n this.config.debug\n );\n\n // Initialize ConversationManager with send message handler and typing handler\n this.conversationManager = new ConversationManager(\n (message: SendMessageMessage) => {\n if (!this.wsClient) {\n throw new Error('WebSocket client not initialized');\n }\n this.wsClient.send(message);\n },\n this.config.debug,\n undefined, // supportMessageHandler (set later)\n (message: TypingStartMessage | TypingStopMessage) => {\n if (!this.wsClient) {\n throw new Error('WebSocket client not initialized');\n }\n this.wsClient.send(message);\n }\n );\n\n // Initialize PresenceManager\n this.presenceManager = new PresenceManager(this.config.debug);\n\n // Forward PresenceManager events to SDK level\n this.presenceManager.on('presence', (event: PresenceEvent) => {\n this.emit('presence', event);\n });\n\n // Wire WebSocket events\n this.setupWebSocketHandlers();\n }\n\n /**\n * Set up WebSocket event handlers\n */\n private setupWebSocketHandlers(): void {\n if (!this.wsClient) {\n return;\n }\n\n this.wsClient.on('connected', () => {\n this.connectionState = ConnectionState.CONNECTED;\n this.emit('connected');\n this.emit('state', this.connectionState);\n this.logger.debug('SDK connected');\n });\n\n this.wsClient.on('disconnected', (data) => {\n this.connectionState = ConnectionState.DISCONNECTED;\n this.emit('disconnected', data);\n this.emit('state', this.connectionState);\n this.logger.debug('SDK disconnected');\n });\n\n this.wsClient.on('reconnecting', (data) => {\n this.connectionState = ConnectionState.RECONNECTING;\n this.emit('reconnecting', data);\n this.emit('state', this.connectionState);\n this.logger.debug('SDK reconnecting', data);\n });\n\n this.wsClient.on('message', (message: ServerMessage) => {\n // Re-emit raw messages\n this.emit('message', message);\n\n // Route to ConversationManager (handles messages, typing, receipts, and conversation-scoped presence)\n this.conversationManager.routeIncomingMessage(message);\n\n // Route presence messages to PresenceManager (SDK-global)\n if (message.type === 'presence') {\n const presenceMsg = message as PresenceMessage;\n if (presenceMsg.payload) {\n this.presenceManager.handlePresence(\n presenceMsg.payload.user_id,\n presenceMsg.payload.state\n );\n }\n }\n\n // Route support messages to SupportManager via ConversationManager\n if (message.type === 'support') {\n this.conversationManager.routeSupportMessage(message as SupportMessage);\n }\n\n // Emit typed events based on message type\n switch (message.type) {\n case 'joined':\n this.emit('joined', message);\n break;\n case 'message':\n this.emit('message', message);\n break;\n case 'typing':\n this.emit('typing', message);\n break;\n case 'receipt':\n // Receipt events are emitted by Conversation's MessageManager, which we forward\n // No need to emit at SDK level, conversation-scoped only\n break;\n case 'support':\n // Support events are emitted by SupportSession, which we forward\n // No need to emit at SDK level, conversation-scoped only\n break;\n case 'presence':\n // Presence events are emitted by PresenceManager, which we forward\n break;\n case 'error':\n this.emit('error', message);\n break;\n }\n });\n\n this.wsClient.on('error', (error: Error | Event) => {\n this.connectionState = ConnectionState.ERROR;\n \n const errorMessage = error instanceof Error ? error.message : '';\n const errorName = error instanceof Error ? error.name : '';\n \n if (errorName === 'TokenExpiredError' || (errorMessage && errorMessage.includes('Token expired'))) {\n this.logger.error('Token expired:', errorMessage);\n this.logger.warn('To reconnect, call sdk.updateToken(newToken) then sdk.connect()');\n } else {\n this.logger.error('SDK error:', error);\n }\n \n // Emit a proper Error instance if we received an Event\n const errorToEmit = error instanceof Error ? error : new Error('WebSocket connection error');\n this.emit('error', errorToEmit);\n this.emit('state', this.connectionState);\n });\n }\n\n /**\n * Get the current connection state\n */\n getState(): ConnectionState {\n return this.connectionState;\n }\n\n /**\n * Get the current configuration\n */\n getConfig(): Readonly<Required<ClientConfig>> {\n return { ...this.config };\n }\n\n /**\n * Connect to the ChatAfrika service\n */\n async connect(): Promise<void> {\n if (this.connectionState === ConnectionState.CONNECTED) {\n this.logger.warn('Already connected');\n return;\n }\n\n if (this.connectionState === ConnectionState.CONNECTING) {\n this.logger.warn('Connection already in progress');\n return;\n }\n\n // Validate token\n this.tokenManager.validateTokenPresence();\n const token = this.tokenManager.getToken();\n if (!token) {\n throw new Error('Token is required for connection');\n }\n\n this.connectionState = ConnectionState.CONNECTING;\n this.emit('state', this.connectionState);\n this.logger.debug('Connecting...');\n\n try {\n if (!this.wsClient) {\n throw new Error('WebSocket client not initialized');\n }\n\n await this.wsClient.connect(token);\n // Connection state will be updated by the 'connected' event handler\n } catch (error) {\n this.connectionState = ConnectionState.ERROR;\n this.emit('state', this.connectionState);\n const connectionError = error instanceof Error \n ? error \n : new Error('Connection failed');\n this.emit('error', connectionError);\n throw connectionError;\n }\n }\n\n /**\n * Disconnect from the ChatAfrika service\n */\n async disconnect(): Promise<void> {\n if (this.connectionState === ConnectionState.DISCONNECTED) {\n return;\n }\n\n this.logger.debug('Disconnecting...');\n\n // Clear all conversations\n this.conversationManager.clear();\n\n // Clear presence state\n this.presenceManager.clear();\n\n // Clear support sessions\n this.supportManager.clear();\n\n if (this.wsClient) {\n this.wsClient.disconnect();\n }\n\n this.connectionState = ConnectionState.DISCONNECTED;\n this.emit('disconnected');\n this.emit('state', this.connectionState);\n }\n\n /**\n * Check if the client is connected\n */\n isConnected(): boolean {\n return this.connectionState === ConnectionState.CONNECTED && \n this.wsClient?.isConnected() === true;\n }\n\n /**\n * Update the authentication token\n * Use this when your token expires and you need to refresh it\n * After updating, call connect() to reconnect with the new token\n */\n updateToken(newToken: string): void {\n if (!newToken || newToken.length === 0) {\n throw new Error('Token cannot be empty');\n }\n \n this.tokenManager.setToken(newToken);\n this.logger.debug('Token updated');\n \n // If currently connected, disconnect first (will reconnect with new token)\n if (this.isConnected()) {\n this.logger.warn('Token updated while connected. Disconnecting to reconnect with new token...');\n this.disconnect();\n }\n }\n\n /**\n * Get the conversations manager\n * Exposes: sdk.conversations.get(id), sdk.conversations.join(id), etc.\n */\n get conversations(): {\n get: (id: string) => Conversation;\n has: (id: string) => boolean;\n join: (id: string) => Promise<void>;\n leave: (id: string) => Promise<void>;\n } {\n return {\n get: (id: string) => this.conversationManager.get(id),\n has: (id: string) => this.conversationManager.has(id),\n join: (id: string) => this.conversationManager.join(id, (conversationId) => this.joinConversation(conversationId)),\n leave: (id: string) => this.conversationManager.leave(id, (conversationId) => this.leaveConversation(conversationId)),\n };\n }\n\n /**\n * Get the support manager\n * Exposes: sdk.support.get(conversationId, role?)\n */\n get support(): {\n get: (id: string, role?: 'customer' | 'agent') => SupportSession;\n has: (id: string) => boolean;\n } {\n return {\n get: (id: string, role: 'customer' | 'agent' = 'customer') => this.supportManager.get(id, role),\n has: (id: string) => this.supportManager.has(id),\n };\n }\n\n /**\n * Join a conversation room (internal method used by ConversationManager)\n */\n private async joinConversation(conversationId: string): Promise<void> {\n if (!this.isConnected()) {\n throw new Error('Must be connected before joining a conversation');\n }\n\n if (!conversationId || conversationId.length === 0) {\n throw new Error('Conversation ID is required');\n }\n\n if (!this.wsClient) {\n throw new Error('WebSocket client not initialized');\n }\n\n const message: JoinMessage = {\n type: 'join',\n conversation_id: conversationId,\n };\n\n try {\n this.wsClient.send(message);\n this.logger.debug('Join conversation sent:', conversationId);\n } catch (error) {\n const sendError = error instanceof Error \n ? error \n : new Error('Failed to join conversation');\n this.emit('error', sendError);\n throw sendError;\n }\n }\n\n /**\n * Leave a conversation room (internal method used by ConversationManager)\n */\n private async leaveConversation(conversationId: string): Promise<void> {\n if (!this.isConnected()) {\n throw new Error('Must be connected before leaving a conversation');\n }\n\n if (!conversationId || conversationId.length === 0) {\n throw new Error('Conversation ID is required');\n }\n\n if (!this.wsClient) {\n throw new Error('WebSocket client not initialized');\n }\n\n const message: LeaveMessage = {\n type: 'leave',\n conversation_id: conversationId,\n };\n\n try {\n this.wsClient.send(message);\n this.logger.debug('Leave conversation sent:', conversationId);\n } catch (error) {\n const sendError = error instanceof Error \n ? error \n : new Error('Failed to leave conversation');\n this.emit('error', sendError);\n throw sendError;\n }\n }\n\n /**\n * Rotate the authentication token\n */\n rotateToken(newToken: string): void {\n this.tokenManager.rotateToken(newToken);\n this.logger.debug('Token rotated');\n \n // If connected, we might need to reconnect with new token\n // For now, just update the token - reconnection will use it\n if (this.isConnected()) {\n this.logger.warn('Token rotated while connected. Reconnect may be required.');\n }\n }\n\n /**\n * Get the token manager (for advanced use cases)\n */\n getTokenManager(): TokenManager {\n return this.tokenManager;\n }\n}\n","/**\n * Retry utility for async operations\n */\nexport interface RetryOptions {\n maxAttempts?: number;\n delay?: number;\n backoff?: boolean;\n onRetry?: (attempt: number, error: Error) => void;\n}\n\n/**\n * Retry an async function with exponential backoff\n */\nexport async function retry<T>(\n fn: () => Promise<T>,\n options: RetryOptions = {}\n): Promise<T> {\n const {\n maxAttempts = 3,\n delay = 1000,\n backoff = true,\n onRetry,\n } = options;\n\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt < maxAttempts) {\n const waitTime = backoff ? delay * Math.pow(2, attempt - 1) : delay;\n onRetry?.(attempt, lastError);\n await new Promise((resolve) => setTimeout(resolve, waitTime));\n }\n }\n }\n\n throw lastError ?? new Error('Retry failed');\n}\n\n","/**\n * Type guards and validation utilities\n */\n\n/**\n * Check if a value is a non-empty string\n */\nexport function isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * Check if a value is a valid URL string\n */\nexport function isValidUrl(value: unknown): value is string {\n if (!isNonEmptyString(value)) {\n return false;\n }\n\n try {\n new URL(value);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a value is a number\n */\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number' && !isNaN(value);\n}\n\n/**\n * Check if a value is a positive integer\n */\nexport function isPositiveInteger(value: unknown): value is number {\n return isNumber(value) && Number.isInteger(value) && value > 0;\n}\n\n"]}
|