@elqnt/chat 1.0.11 → 1.0.14

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../hooks/use-websocket-chat-customer.ts","../../hooks/use-websocket-chat-base.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useState } from \"react\";\nimport { Chat, ChatEvent, ChatMessage, ChatUser } from \"../models\";\nimport {\n useWebSocketChatBase,\n UseWebSocketChatBaseConfig,\n UseWebSocketChatBaseReturn,\n} from \"./use-websocket-chat-base\";\n\nexport interface UseWebSocketChatCustomerReturn\n extends UseWebSocketChatBaseReturn {\n title: string | undefined;\n messages: ChatMessage[];\n users: ChatUser[];\n isWaiting: boolean;\n isWaitingForAgent: boolean;\n aiEngaged: boolean;\n humanAgentEngaged: boolean;\n metadata: Record<string, string>;\n status: string | undefined;\n chatKey: string;\n}\n\nexport interface UseWebSocketChatCustomerConfig\n extends Omit<UseWebSocketChatBaseConfig, \"clientType\" | \"onMessage\"> {\n chatKey: string;\n}\n\nexport const useWebSocketChatCustomer = ({\n serverBaseUrl,\n orgId,\n chatKey,\n product,\n}: UseWebSocketChatCustomerConfig): UseWebSocketChatCustomerReturn => {\n const [currentChat, setCurrentChat] = useState<Chat | undefined>(undefined);\n\n const handleMessage = useCallback((chatEvent: ChatEvent) => {\n console.log(\"Received event:\", chatEvent.type);\n\n switch (chatEvent.type) {\n case \"message\":\n if (!chatEvent.message) return;\n\n console.log(\n \"got message:\",\n chatEvent.message.role,\n \":\",\n chatEvent.message.content\n );\n // if (\n // chatEvent.message?.toolCalls?.length &&\n // chatEvent.message.toolCalls.length > 0\n // )\n // return;\n setCurrentChat((prev) => {\n if (!prev) return prev;\n return {\n ...prev,\n messages: [...prev.messages, chatEvent.message!],\n };\n });\n break;\n\n case \"chat_updated\":\n const chat = chatEvent.data?.chat?.value as Chat;\n if (chat) {\n setCurrentChat(chat);\n }\n break;\n\n case \"load_chat\":\n const history = chatEvent.data?.chat as Chat;\n if (!history) return;\n setCurrentChat(history);\n break;\n\n default:\n // console.log(\"unhandled event:\", chatEvent.type);\n break;\n }\n }, []);\n\n const base = useWebSocketChatBase({\n serverBaseUrl,\n orgId,\n clientType: \"customer\",\n onMessage: handleMessage,\n product,\n });\n\n return {\n ...base,\n chatKey,\n title: currentChat?.title,\n messages: currentChat?.messages ?? [],\n users: currentChat?.users ?? [],\n isWaiting: currentChat?.isWaiting ?? false,\n isWaitingForAgent: currentChat?.isWaitingForAgent ?? false,\n aiEngaged: currentChat?.aiEngaged ?? false,\n humanAgentEngaged: currentChat?.humanAgentEngaged ?? false,\n metadata: currentChat?.metadata ?? {},\n status: currentChat?.status,\n };\n};\n","\"use client\";\n\nimport { ProductNameTS } from \"@elqnt/types\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { ChatEvent } from \"../models\";\n\n// Connection state enum\nexport type ConnectionState =\n | \"disconnected\"\n | \"connecting\"\n | \"connected\"\n | \"reconnecting\";\n\n// Transport type - WebSocket or SSE\nexport type TransportType = \"websocket\" | \"sse\";\n\n// Error types\nexport interface WebSocketError {\n code:\n | \"CONNECTION_FAILED\"\n | \"PARSE_ERROR\"\n | \"SEND_FAILED\"\n | \"TIMEOUT\"\n | \"NETWORK_ERROR\";\n message: string;\n retryable: boolean;\n timestamp: number;\n}\n\n// Retry configuration\nexport interface RetryConfig {\n maxRetries?: number;\n intervals?: number[];\n backoffMultiplier?: number;\n maxBackoffTime?: number;\n}\n\n// Connection metrics\nexport interface ConnectionMetrics {\n latency: number;\n messagesSent: number;\n messagesReceived: number;\n messagesQueued: number;\n reconnectCount: number;\n lastError?: WebSocketError;\n connectedAt?: number;\n lastMessageAt?: number;\n transportType?: TransportType;\n}\n\n// Message queue configuration\nexport interface QueueConfig {\n maxSize?: number;\n dropStrategy?: \"oldest\" | \"newest\";\n}\n\n// Logger interface\nexport interface Logger {\n debug: (message: string, ...args: any[]) => void;\n info: (message: string, ...args: any[]) => void;\n warn: (message: string, ...args: any[]) => void;\n error: (message: string, ...args: any[]) => void;\n}\n\n// Default logger (can be overridden)\nconst createDefaultLogger = (debug: boolean): Logger => ({\n debug: debug ? console.log : () => {},\n info: console.info,\n warn: console.warn,\n error: console.error,\n});\n\nexport interface UseWebSocketChatBaseConfig {\n serverBaseUrl: string;\n orgId: string;\n clientType: \"customer\" | \"humanAgent\" | \"observer\";\n product: ProductNameTS;\n onMessage?: (event: ChatEvent) => void;\n retryConfig?: RetryConfig;\n queueConfig?: QueueConfig;\n debug?: boolean;\n logger?: Logger;\n heartbeatInterval?: number; // in milliseconds, 0 to disable\n heartbeatTimeout?: number; // in milliseconds\n /**\n * Transport type to use for the connection.\n * - 'websocket': Traditional WebSocket connection (default)\n * - 'sse': Server-Sent Events for receiving + REST API for sending\n *\n * SSE provides automatic browser reconnection and simpler infrastructure\n * (no sticky sessions required), following the pattern used by Claude.ai and ChatGPT.\n */\n transport?: TransportType;\n}\n\nexport interface UseWebSocketChatBaseReturn {\n connectionState: ConnectionState;\n isConnected: boolean;\n sendMessage: (\n event: Omit<ChatEvent, \"timestamp\">,\n overrideUserId?: string\n ) => Promise<void>;\n error: WebSocketError | undefined;\n connect: (userId: string) => Promise<void>;\n startNewChat: (\n userId: string,\n data?: { [key: string]: any }\n ) => Promise<string>;\n startTime: Date | undefined;\n disconnect: (intentional?: boolean) => void;\n metrics: ConnectionMetrics;\n on: (eventType: string, handler: (data: any) => void) => () => void;\n off: (eventType: string, handler: (data: any) => void) => void;\n clearError: () => void;\n}\n\n// Default configurations\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 10,\n intervals: [1000, 2000, 5000],\n backoffMultiplier: 1.5,\n maxBackoffTime: 30000,\n};\n\nconst DEFAULT_QUEUE_CONFIG: QueueConfig = {\n maxSize: 100,\n dropStrategy: \"oldest\",\n};\n\nconst DEFAULT_HEARTBEAT_INTERVAL = 30000; // 30 seconds\nconst DEFAULT_HEARTBEAT_TIMEOUT = 5000; // 5 seconds\nconst DEFAULT_TRANSPORT: TransportType = \"websocket\";\n\n// Type guards\nfunction isChatEvent(data: any): data is ChatEvent {\n return (\n data &&\n typeof data === \"object\" &&\n (typeof data.type === \"string\" || data.message)\n );\n}\n\nfunction hasValidChatKey(data: any): boolean {\n return data?.chatKey && typeof data.chatKey === \"string\";\n}\n\nexport const useWebSocketChatBase = ({\n serverBaseUrl,\n orgId,\n clientType,\n product,\n onMessage,\n retryConfig = DEFAULT_RETRY_CONFIG,\n queueConfig = DEFAULT_QUEUE_CONFIG,\n debug = false,\n logger = createDefaultLogger(debug),\n heartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL,\n heartbeatTimeout = DEFAULT_HEARTBEAT_TIMEOUT,\n transport = DEFAULT_TRANSPORT,\n}: UseWebSocketChatBaseConfig): UseWebSocketChatBaseReturn => {\n // State\n const [connectionState, setConnectionState] =\n useState<ConnectionState>(\"disconnected\");\n const [error, setError] = useState<WebSocketError | undefined>(undefined);\n const [startTime, setStartTime] = useState<Date | undefined>(undefined);\n const [metrics, setMetrics] = useState<ConnectionMetrics>({\n latency: 0,\n messagesSent: 0,\n messagesReceived: 0,\n messagesQueued: 0,\n reconnectCount: 0,\n transportType: transport,\n });\n\n // Refs\n const wsRef = useRef<WebSocket | undefined>(undefined);\n const sseRef = useRef<EventSource | undefined>(undefined);\n const transportRef = useRef<TransportType>(transport);\n\n // Sync transportRef with transport prop\n useEffect(() => {\n transportRef.current = transport;\n }, [transport]);\n const reconnectTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);\n const retryCountRef = useRef(0);\n const messageQueueRef = useRef<ChatEvent[]>([]);\n const mountedRef = useRef(false);\n const currentChatKeyRef = useRef<string | undefined>(undefined);\n const currentUserIdRef = useRef<string | undefined>(undefined);\n const intentionalDisconnectRef = useRef(false);\n const eventHandlersRef = useRef<Map<string, Set<(data: any) => void>>>(\n new Map()\n );\n const onMessageRef = useRef(onMessage);\n const pendingMessagesRef = useRef<\n Map<\n string,\n {\n resolve: () => void;\n reject: (error: Error) => void;\n timeout: NodeJS.Timeout;\n }\n >\n >(new Map());\n const heartbeatIntervalRef = useRef<NodeJS.Timeout | undefined>(undefined);\n const heartbeatTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);\n const lastPongRef = useRef<number>(Date.now());\n const chatCreationPromiseRef = useRef<{\n resolve: (value: string) => void;\n reject: (reason?: any) => void;\n } | null>(null);\n\n // Load chat retry state\n const loadChatRetryMapRef = useRef<Map<string, {\n retryCount: number;\n timeoutId: NodeJS.Timeout | null;\n }>>(new Map());\n\n // Update onMessage ref when it changes\n useEffect(() => {\n onMessageRef.current = onMessage;\n }, [onMessage]);\n\n // Computed state\n const isConnected = connectionState === \"connected\";\n\n // Event subscription system\n const on = useCallback((eventType: string, handler: (data: any) => void) => {\n if (!eventHandlersRef.current.has(eventType)) {\n eventHandlersRef.current.set(eventType, new Set());\n }\n eventHandlersRef.current.get(eventType)!.add(handler);\n\n // Return unsubscribe function\n return () => off(eventType, handler);\n }, []);\n\n const off = useCallback((eventType: string, handler: (data: any) => void) => {\n const handlers = eventHandlersRef.current.get(eventType);\n if (handlers) {\n handlers.delete(handler);\n if (handlers.size === 0) {\n eventHandlersRef.current.delete(eventType);\n }\n }\n }, []);\n\n // Emit event to all registered handlers\n const emit = useCallback(\n (eventType: string, data: any) => {\n const handlers = eventHandlersRef.current.get(eventType);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n logger.error(`Error in event handler for ${eventType}:`, error);\n }\n });\n }\n },\n [logger]\n );\n\n // Update metrics\n const updateMetrics = useCallback((updates: Partial<ConnectionMetrics>) => {\n setMetrics((prev) => ({ ...prev, ...updates }));\n }, []);\n\n // Queue management\n const addToQueue = useCallback(\n (event: ChatEvent) => {\n const currentQueueSize = messageQueueRef.current.length;\n const maxSize = queueConfig.maxSize || DEFAULT_QUEUE_CONFIG.maxSize!;\n\n if (currentQueueSize >= maxSize) {\n if (queueConfig.dropStrategy === \"newest\") {\n logger.warn(\"Message queue full, dropping new message\");\n return false;\n } else {\n // Drop oldest\n const dropped = messageQueueRef.current.shift();\n logger.warn(\"Message queue full, dropped oldest message\", dropped);\n }\n }\n\n messageQueueRef.current.push(event);\n updateMetrics({ messagesQueued: messageQueueRef.current.length });\n return true;\n },\n [queueConfig, logger, updateMetrics]\n );\n\n // Calculate retry interval\n const calculateRetryInterval = useCallback(\n (retryCount: number): number => {\n const config = { ...DEFAULT_RETRY_CONFIG, ...retryConfig };\n const {\n intervals = [],\n backoffMultiplier = 1.5,\n maxBackoffTime = 30000,\n } = config;\n\n if (retryCount < intervals.length) {\n return intervals[retryCount];\n }\n\n // Exponential backoff after predefined intervals\n const baseInterval = intervals[intervals.length - 1] || 5000;\n const backoffTime =\n baseInterval *\n Math.pow(backoffMultiplier, retryCount - intervals.length + 1);\n return Math.min(backoffTime, maxBackoffTime);\n },\n [retryConfig]\n );\n\n // Heartbeat mechanism\n const startHeartbeat = useCallback(() => {\n if (!heartbeatInterval || heartbeatInterval <= 0) return;\n\n const sendPing = () => {\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n const pingTime = Date.now();\n wsRef.current.send(\n JSON.stringify({ type: \"ping\", timestamp: pingTime })\n );\n\n // Set timeout for pong response\n heartbeatTimeoutRef.current = setTimeout(() => {\n logger.warn(\"Heartbeat timeout - no pong received\");\n // Force reconnection\n if (wsRef.current) {\n wsRef.current.close(4000, \"Heartbeat timeout\");\n }\n }, heartbeatTimeout);\n }\n };\n\n // Clear existing interval\n if (heartbeatIntervalRef.current) {\n clearInterval(heartbeatIntervalRef.current);\n }\n\n // Start new interval\n heartbeatIntervalRef.current = setInterval(sendPing, heartbeatInterval);\n logger.debug(\"Heartbeat started\");\n }, [heartbeatInterval, heartbeatTimeout, logger]);\n\n const stopHeartbeat = useCallback(() => {\n if (heartbeatIntervalRef.current) {\n clearInterval(heartbeatIntervalRef.current);\n heartbeatIntervalRef.current = undefined;\n }\n if (heartbeatTimeoutRef.current) {\n clearTimeout(heartbeatTimeoutRef.current);\n heartbeatTimeoutRef.current = undefined;\n }\n logger.debug(\"Heartbeat stopped\");\n }, [logger]);\n\n // Cleanup function\n const cleanup = useCallback(() => {\n // Cleanup WebSocket\n if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {\n wsRef.current.close(1000, \"Cleanup\");\n }\n wsRef.current = undefined;\n\n // Cleanup SSE\n if (sseRef.current) {\n sseRef.current.close();\n sseRef.current = undefined;\n }\n\n if (reconnectTimeoutRef.current) {\n clearTimeout(reconnectTimeoutRef.current);\n reconnectTimeoutRef.current = undefined;\n }\n stopHeartbeat();\n\n // Clear pending message promises\n pendingMessagesRef.current.forEach(({ reject, timeout }) => {\n clearTimeout(timeout);\n reject(new Error(\"Connection closed\"));\n });\n pendingMessagesRef.current.clear();\n\n // Clear load chat retry timeouts\n loadChatRetryMapRef.current.forEach((retryState) => {\n if (retryState.timeoutId) {\n clearTimeout(retryState.timeoutId);\n }\n });\n loadChatRetryMapRef.current.clear();\n }, [stopHeartbeat]);\n\n // SSE REST API helper - converts WebSocket URL to REST API URL\n const getRestApiUrl = useCallback((endpoint: string): string => {\n // serverBaseUrl is like \"wss://chat.example.com/v1/chat\" or \"ws://localhost:8888/v1/chat\"\n // Convert to \"https://chat.example.com/v1/chat/{endpoint}\" or \"http://localhost:8888/v1/chat/{endpoint}\"\n const httpUrl = serverBaseUrl\n .replace(/^wss:/, \"https:\")\n .replace(/^ws:/, \"http:\");\n return `${httpUrl}/${endpoint}`;\n }, [serverBaseUrl]);\n\n // SSE REST API call helper\n const sendRestMessage = useCallback(\n async (endpoint: string, body: Record<string, any>): Promise<any> => {\n const url = getRestApiUrl(endpoint);\n logger.debug(`SSE REST API call: POST ${endpoint}`, body);\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`REST API error: ${response.status} - ${errorText}`);\n }\n\n const data = await response.json();\n return data;\n } catch (error) {\n logger.error(`SSE REST API error for ${endpoint}:`, error);\n throw error;\n }\n },\n [getRestApiUrl, logger]\n );\n\n // Connect function\n const connect = useCallback(\n async (userId: string): Promise<void> => {\n if (!mountedRef.current) {\n mountedRef.current = true;\n }\n\n // Guard: Don't connect if orgId is not available\n if (!orgId) {\n const error: WebSocketError = {\n code: \"CONNECTION_FAILED\",\n message: \"Cannot connect: orgId is undefined\",\n retryable: false,\n timestamp: Date.now(),\n };\n logger.error(\"Cannot connect: orgId is undefined\");\n setError(error);\n return Promise.reject(error);\n }\n\n // Check if already connected (WebSocket or SSE)\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n logger.debug(\"Already connected (WebSocket)\");\n return Promise.resolve();\n }\n if (sseRef.current?.readyState === EventSource.OPEN) {\n logger.debug(\"Already connected (SSE)\");\n return Promise.resolve();\n }\n\n if (\n connectionState === \"connecting\" ||\n connectionState === \"reconnecting\"\n ) {\n logger.debug(\"Connection already in progress\");\n return Promise.resolve();\n }\n\n // Check max retries\n const maxRetries =\n retryConfig.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries!;\n if (\n retryCountRef.current >= maxRetries &&\n !intentionalDisconnectRef.current\n ) {\n const error: WebSocketError = {\n code: \"CONNECTION_FAILED\",\n message: `Max retries (${maxRetries}) exceeded`,\n retryable: false,\n timestamp: Date.now(),\n };\n setError(error);\n updateMetrics({ lastError: error });\n return Promise.reject(error);\n }\n\n cleanup();\n setConnectionState(\n retryCountRef.current > 0 ? \"reconnecting\" : \"connecting\"\n );\n intentionalDisconnectRef.current = false;\n\n return new Promise<void>((resolve, reject) => {\n try {\n const connectionStartTime = Date.now();\n\n logger.info(`🔄 Connecting with transport: ${transportRef.current}`);\n\n // SSE Transport\n if (transportRef.current === \"sse\") {\n const sseUrl = getRestApiUrl(`stream?orgId=${orgId}&userId=${userId}&clientType=${clientType}&chatId=${currentChatKeyRef.current || \"\"}`);\n\n logger.debug(\"Connecting to SSE:\", sseUrl);\n console.log(`⏳ Initiating SSE connection to ${serverBaseUrl}...`);\n\n const eventSource = new EventSource(sseUrl);\n\n eventSource.onopen = () => {\n if (!mountedRef.current) {\n eventSource.close();\n reject(new Error(\"Component unmounted\"));\n return;\n }\n\n const connectionTimeMs = Date.now() - connectionStartTime;\n const connectionTimeSec = (connectionTimeMs / 1000).toFixed(2);\n\n logger.info(\"✅ SSE connected\", {\n userId,\n retryCount: retryCountRef.current,\n connectionTime: `${connectionTimeSec}s (${connectionTimeMs}ms)`,\n });\n\n console.log(`🔌 SSE connection established in ${connectionTimeSec} seconds`);\n\n setConnectionState(\"connected\");\n setError(undefined);\n const wasReconnecting = retryCountRef.current > 0;\n retryCountRef.current = 0;\n\n // Update metrics\n updateMetrics({\n connectedAt: Date.now(),\n latency: connectionTimeMs,\n transportType: \"sse\",\n reconnectCount: wasReconnecting\n ? metrics.reconnectCount + 1\n : metrics.reconnectCount,\n });\n\n // Store the userId for reconnection\n currentUserIdRef.current = userId;\n\n // If we have a chat key, load the chat via REST\n if (currentChatKeyRef.current) {\n logger.info(\"Loading chat after SSE reconnection:\", currentChatKeyRef.current);\n sendRestMessage(\"load\", {\n orgId,\n chatKey: currentChatKeyRef.current,\n userId,\n }).then((response) => {\n if (response.success && response.data?.chat) {\n const chatEvent: ChatEvent = {\n type: \"load_chat_response\",\n orgId,\n chatKey: currentChatKeyRef.current!,\n userId,\n timestamp: Date.now(),\n data: response.data,\n };\n emit(\"load_chat_response\", chatEvent);\n if (onMessageRef.current) {\n onMessageRef.current(chatEvent);\n }\n }\n }).catch((err) => {\n logger.error(\"Failed to load chat after SSE reconnection:\", err);\n });\n }\n\n // Emit connected event\n emit(\"connected\", { userId, wasReconnecting, transport: \"sse\" });\n\n resolve();\n };\n\n // Handle SSE messages - each event type is a separate event\n const handleSSEMessage = (event: MessageEvent) => {\n if (!mountedRef.current) return;\n\n try {\n const data = JSON.parse(event.data);\n\n if (!isChatEvent(data)) {\n logger.warn(\"Received invalid SSE message format:\", data);\n return;\n }\n\n const chatEvent = data as ChatEvent;\n logger.debug(\"SSE message received:\", chatEvent.type);\n\n // Update metrics\n updateMetrics({\n messagesReceived: metrics.messagesReceived + 1,\n lastMessageAt: Date.now(),\n });\n\n // Handle specific events internally\n switch (chatEvent.type) {\n case \"new_chat_created\":\n const newChatKey = chatEvent.data?.chatKey as string;\n if (newChatKey) {\n logger.info(\"New chat created with key:\", newChatKey);\n currentChatKeyRef.current = newChatKey;\n\n if (chatCreationPromiseRef.current) {\n chatCreationPromiseRef.current.resolve(newChatKey);\n chatCreationPromiseRef.current = null;\n }\n }\n break;\n\n case \"load_chat_response\":\n const chat = chatEvent.data?.chat;\n if (chat && chat.key) {\n logger.info(\"Chat loaded with key:\", chat.key);\n currentChatKeyRef.current = chat.key;\n }\n break;\n\n case \"chat_ended\":\n logger.info(\"Chat ended, clearing key\");\n currentChatKeyRef.current = undefined;\n break;\n }\n\n // Emit event to subscribers\n emit(chatEvent.type || \"message\", chatEvent);\n\n // Call the legacy onMessage handler\n if (onMessageRef.current) {\n onMessageRef.current(chatEvent);\n }\n } catch (error) {\n logger.error(\"Failed to parse SSE message:\", error);\n }\n };\n\n // Subscribe to all event types\n eventSource.addEventListener(\"message\", handleSSEMessage);\n eventSource.addEventListener(\"reconnected\", handleSSEMessage);\n eventSource.addEventListener(\"typing\", handleSSEMessage);\n eventSource.addEventListener(\"stopped_typing\", handleSSEMessage);\n eventSource.addEventListener(\"waiting\", handleSSEMessage);\n eventSource.addEventListener(\"waiting_for_agent\", handleSSEMessage);\n eventSource.addEventListener(\"human_agent_joined\", handleSSEMessage);\n eventSource.addEventListener(\"human_agent_left\", handleSSEMessage);\n eventSource.addEventListener(\"chat_ended\", handleSSEMessage);\n eventSource.addEventListener(\"chat_updated\", handleSSEMessage);\n eventSource.addEventListener(\"load_chat_response\", handleSSEMessage);\n eventSource.addEventListener(\"new_chat_created\", handleSSEMessage);\n eventSource.addEventListener(\"error\", handleSSEMessage);\n eventSource.addEventListener(\"show_csat_survey\", handleSSEMessage);\n eventSource.addEventListener(\"csat_response\", handleSSEMessage);\n eventSource.addEventListener(\"user_suggested_actions\", handleSSEMessage);\n eventSource.addEventListener(\"agent_execution_started\", handleSSEMessage);\n eventSource.addEventListener(\"agent_execution_ended\", handleSSEMessage);\n eventSource.addEventListener(\"agent_context_update\", handleSSEMessage);\n eventSource.addEventListener(\"plan_pending_approval\", handleSSEMessage);\n eventSource.addEventListener(\"step_started\", handleSSEMessage);\n eventSource.addEventListener(\"step_completed\", handleSSEMessage);\n eventSource.addEventListener(\"step_failed\", handleSSEMessage);\n eventSource.addEventListener(\"plan_completed\", handleSSEMessage);\n eventSource.addEventListener(\"skills_changed\", handleSSEMessage);\n eventSource.addEventListener(\"summary_update\", handleSSEMessage);\n\n eventSource.onerror = (error) => {\n logger.error(\"SSE error:\", error);\n if (!mountedRef.current) return;\n\n // EventSource automatically reconnects on error, so we just log it\n // Only set error state if the connection is permanently closed\n if (eventSource.readyState === EventSource.CLOSED) {\n const sseError: WebSocketError = {\n code: \"CONNECTION_FAILED\",\n message: \"SSE connection failed\",\n retryable: true,\n timestamp: Date.now(),\n };\n setError(sseError);\n updateMetrics({ lastError: sseError });\n setConnectionState(\"disconnected\");\n emit(\"disconnected\", { reason: \"SSE error\" });\n\n // Handle manual reconnection if EventSource doesn't auto-reconnect\n if (!intentionalDisconnectRef.current && mountedRef.current) {\n const retryInterval = calculateRetryInterval(retryCountRef.current);\n retryCountRef.current++;\n\n logger.info(`SSE reconnecting in ${retryInterval}ms (attempt ${retryCountRef.current})`);\n\n if (reconnectTimeoutRef.current) {\n clearTimeout(reconnectTimeoutRef.current);\n }\n reconnectTimeoutRef.current = setTimeout(() => {\n connect(userId);\n }, retryInterval);\n }\n }\n };\n\n sseRef.current = eventSource;\n return;\n }\n\n // WebSocket Transport (default)\n const wsUrl = `${serverBaseUrl}?orgId=${orgId}&userId=${userId}&clientType=${clientType}&product=${product}`;\n\n logger.debug(\"Connecting to WebSocket:\", wsUrl);\n console.log(`⏳ Initiating WebSocket connection to ${serverBaseUrl}...`);\n\n const ws = new WebSocket(wsUrl);\n\n ws.onopen = () => {\n if (!mountedRef.current) {\n ws.close(1000, \"Component unmounted\");\n reject(new Error(\"Component unmounted\"));\n return;\n }\n\n const connectionTimeMs = Date.now() - connectionStartTime;\n const connectionTimeSec = (connectionTimeMs / 1000).toFixed(2);\n\n logger.info(\"✅ WebSocket connected\", {\n userId,\n retryCount: retryCountRef.current,\n connectionTime: `${connectionTimeSec}s (${connectionTimeMs}ms)`,\n });\n\n console.log(`🔌 WebSocket connection established in ${connectionTimeSec} seconds`);\n\n setConnectionState(\"connected\");\n setError(undefined);\n const wasReconnecting = retryCountRef.current > 0;\n retryCountRef.current = 0;\n\n // Update metrics\n updateMetrics({\n connectedAt: Date.now(),\n latency: connectionTimeMs,\n reconnectCount: wasReconnecting\n ? metrics.reconnectCount + 1\n : metrics.reconnectCount,\n });\n\n // Process queued messages\n while (\n messageQueueRef.current.length > 0 &&\n ws.readyState === WebSocket.OPEN\n ) {\n const event = messageQueueRef.current.shift();\n if (event) {\n ws.send(JSON.stringify({ ...event, timestamp: Date.now() }));\n updateMetrics({\n messagesSent: metrics.messagesSent + 1,\n messagesQueued: messageQueueRef.current.length,\n });\n }\n }\n\n // Store the userId for reconnection\n currentUserIdRef.current = userId;\n\n // If we have a chat key, resubscribe to the chat\n if (currentChatKeyRef.current) {\n if (!orgId) {\n logger.error(\"Cannot resubscribe to chat: orgId is undefined\");\n } else {\n logger.info(\n \"Resubscribing to chat after reconnection:\",\n currentChatKeyRef.current\n );\n const resubscribeEvent: ChatEvent = {\n type: \"load_chat\",\n orgId,\n chatKey: currentChatKeyRef.current,\n userId,\n timestamp: Date.now(),\n data: {},\n };\n ws.send(JSON.stringify(resubscribeEvent));\n }\n }\n\n // Start heartbeat\n startHeartbeat();\n\n // Emit connected event\n emit(\"connected\", { userId, wasReconnecting });\n\n // Resolve the promise\n resolve();\n };\n\n ws.onmessage = (event) => {\n if (!mountedRef.current) return;\n\n try {\n const data = JSON.parse(event.data);\n\n if (!isChatEvent(data)) {\n logger.warn(\"Received invalid message format:\", data);\n return;\n }\n\n const chatEvent = data as ChatEvent;\n logger.debug(\"Message received:\", chatEvent.type);\n\n // Update metrics\n updateMetrics({\n messagesReceived: metrics.messagesReceived + 1,\n lastMessageAt: Date.now(),\n });\n\n // Handle pong response\n if (chatEvent.type === \"pong\") {\n if (heartbeatTimeoutRef.current) {\n clearTimeout(heartbeatTimeoutRef.current);\n heartbeatTimeoutRef.current = undefined;\n }\n const latency =\n Date.now() - (chatEvent.timestamp || Date.now());\n lastPongRef.current = Date.now();\n updateMetrics({ latency });\n return;\n }\n\n // Handle specific events internally for connection management\n switch (chatEvent.type) {\n case \"new_chat_created\":\n const newChatKey = chatEvent.data?.chatKey as string;\n if (newChatKey) {\n logger.info(\"New chat created with key:\", newChatKey);\n currentChatKeyRef.current = newChatKey;\n\n // Resolve the promise if waiting for chat creation\n if (chatCreationPromiseRef.current) {\n chatCreationPromiseRef.current.resolve(newChatKey);\n chatCreationPromiseRef.current = null;\n }\n\n // Send load_chat to subscribe to the new chat (only if orgId is valid)\n if (!orgId) {\n logger.error(\"Cannot send load_chat: orgId is undefined\");\n return;\n }\n\n const loadChatEvent: ChatEvent = {\n type: \"load_chat\",\n orgId,\n chatKey: newChatKey,\n userId: currentUserIdRef.current || userId,\n timestamp: Date.now(),\n data: {},\n };\n ws.send(JSON.stringify(loadChatEvent));\n }\n break;\n\n case \"load_chat_response\":\n const chat = chatEvent.data?.chat;\n if (chat && chat.key) {\n logger.info(\"Chat loaded with key:\", chat.key);\n currentChatKeyRef.current = chat.key;\n\n // Clear retry state for this chat on success\n const retryState = loadChatRetryMapRef.current.get(chat.key);\n if (retryState) {\n if (retryState.timeoutId) {\n clearTimeout(retryState.timeoutId);\n }\n loadChatRetryMapRef.current.delete(chat.key);\n }\n } else if (!chat) {\n logger.warn(\"Chat load failed, clearing key\");\n currentChatKeyRef.current = undefined;\n }\n break;\n\n case \"chat_ended\":\n logger.info(\"Chat ended, clearing key\");\n currentChatKeyRef.current = undefined;\n break;\n\n case \"error\":\n const errorMessage =\n chatEvent.data?.message || \"Unknown error\";\n logger.error(\"Received error from server:\", errorMessage);\n\n // Check if this is a \"key not found\" error for load_chat\n if (errorMessage.includes(\"nats: key not found\") || errorMessage.includes(\"Failed to load chat\")) {\n const chatKeyFromError = currentChatKeyRef.current;\n if (chatKeyFromError) {\n const maxRetries = 5;\n let retryState = loadChatRetryMapRef.current.get(chatKeyFromError);\n\n if (!retryState) {\n retryState = { retryCount: 0, timeoutId: null };\n loadChatRetryMapRef.current.set(chatKeyFromError, retryState);\n }\n\n if (retryState.retryCount < maxRetries) {\n // Exponential backoff: 200ms, 400ms, 800ms, 1.6s, 3.2s\n const delay = 200 * Math.pow(2, retryState.retryCount);\n retryState.retryCount++;\n\n logger.info(\n `Chat load failed, retrying (${retryState.retryCount}/${maxRetries}) in ${delay}ms...`,\n chatKeyFromError\n );\n\n retryState.timeoutId = setTimeout(() => {\n if (!wsRef.current || !mountedRef.current) return;\n\n // Check if orgId is valid before retrying\n if (!orgId) {\n logger.error(\"Cannot retry load_chat: orgId is undefined\", chatKeyFromError);\n loadChatRetryMapRef.current.delete(chatKeyFromError);\n return;\n }\n\n logger.debug(\"Retrying load_chat:\", chatKeyFromError);\n const retryLoadEvent: ChatEvent = {\n type: \"load_chat\",\n orgId,\n chatKey: chatKeyFromError,\n userId: currentUserIdRef.current || \"\",\n timestamp: Date.now(),\n data: {},\n };\n ws.send(JSON.stringify(retryLoadEvent));\n }, delay);\n } else {\n logger.error(\"Max retries reached for loading chat:\", chatKeyFromError);\n loadChatRetryMapRef.current.delete(chatKeyFromError);\n }\n }\n }\n\n const wsError: WebSocketError = {\n code: \"NETWORK_ERROR\",\n message: errorMessage,\n retryable: true,\n timestamp: Date.now(),\n };\n setError(wsError);\n updateMetrics({ lastError: wsError });\n break;\n }\n\n // Emit event to subscribers\n emit(chatEvent.type || \"message\", chatEvent);\n\n // Call the legacy onMessage handler\n if (onMessageRef.current) {\n onMessageRef.current(chatEvent);\n }\n } catch (error) {\n logger.error(\"Failed to parse WebSocket message:\", error);\n const parseError: WebSocketError = {\n code: \"PARSE_ERROR\",\n message: \"Failed to parse message\",\n retryable: false,\n timestamp: Date.now(),\n };\n setError(parseError);\n updateMetrics({ lastError: parseError });\n }\n };\n\n ws.onclose = (event) => {\n if (!mountedRef.current) return;\n\n logger.info(\"WebSocket closed\", {\n code: event.code,\n reason: event.reason,\n });\n setConnectionState(\"disconnected\");\n wsRef.current = undefined;\n stopHeartbeat();\n\n // Emit disconnected event\n emit(\"disconnected\", { code: event.code, reason: event.reason });\n\n // Handle reconnection\n if (\n event.code !== 1000 &&\n !intentionalDisconnectRef.current &&\n mountedRef.current\n ) {\n const retryInterval = calculateRetryInterval(\n retryCountRef.current\n );\n retryCountRef.current++;\n\n logger.info(\n `Reconnecting in ${retryInterval}ms (attempt ${retryCountRef.current})`\n );\n\n if (reconnectTimeoutRef.current) {\n clearTimeout(reconnectTimeoutRef.current);\n }\n reconnectTimeoutRef.current = setTimeout(() => {\n connect(userId);\n }, retryInterval);\n }\n };\n\n ws.onerror = (error) => {\n logger.error(\"WebSocket error:\", error);\n if (!mountedRef.current) return;\n\n const wsError: WebSocketError = {\n code: \"CONNECTION_FAILED\",\n message: \"WebSocket connection failed\",\n retryable: true,\n timestamp: Date.now(),\n };\n setError(wsError);\n updateMetrics({ lastError: wsError });\n\n // Reject the promise on error\n reject(wsError);\n };\n\n wsRef.current = ws;\n } catch (error) {\n logger.error(\"Failed to create WebSocket:\", error);\n const wsError: WebSocketError = {\n code: \"CONNECTION_FAILED\",\n message:\n error instanceof Error\n ? error.message\n : \"Failed to create connection\",\n retryable: true,\n timestamp: Date.now(),\n };\n setError(wsError);\n updateMetrics({ lastError: wsError });\n reject(wsError);\n }\n });\n },\n [\n serverBaseUrl,\n orgId,\n clientType,\n product,\n connectionState,\n logger,\n retryConfig,\n metrics,\n updateMetrics,\n cleanup,\n calculateRetryInterval,\n startHeartbeat,\n emit,\n ]\n );\n\n // Send message with promise\n const sendMessage = useCallback(\n (\n event: Omit<ChatEvent, \"timestamp\">,\n overrideUserId?: string\n ): Promise<void> => {\n return new Promise(async (resolve, reject) => {\n if (!mountedRef.current) {\n reject(new Error(\"Component not mounted\"));\n return;\n }\n\n const fullEvent: ChatEvent = {\n ...event,\n timestamp: Date.now(),\n };\n\n logger.debug(\"Sending message:\", fullEvent.type);\n\n // SSE Transport - use REST API\n if (transportRef.current === \"sse\") {\n // Check if SSE is connected\n if (!sseRef.current || sseRef.current.readyState !== EventSource.OPEN) {\n logger.debug(\"SSE not connected, attempting to connect\");\n if (connectionState === \"disconnected\" && overrideUserId) {\n try {\n await connect(overrideUserId);\n } catch (error) {\n reject(error);\n return;\n }\n } else {\n reject(new Error(\"SSE not connected\"));\n return;\n }\n }\n\n try {\n // Map event types to REST endpoints\n switch (fullEvent.type) {\n case \"message\":\n await sendRestMessage(\"send\", {\n orgId: fullEvent.orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n userId: fullEvent.userId,\n message: fullEvent.message,\n });\n break;\n\n case \"typing\":\n await sendRestMessage(\"typing\", {\n orgId: fullEvent.orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n userId: fullEvent.userId,\n typing: true,\n });\n break;\n\n case \"stopped_typing\":\n await sendRestMessage(\"typing\", {\n orgId: fullEvent.orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n userId: fullEvent.userId,\n typing: false,\n });\n break;\n\n case \"load_chat\":\n const loadResponse = await sendRestMessage(\"load\", {\n orgId: fullEvent.orgId,\n chatKey: fullEvent.chatKey,\n userId: fullEvent.userId,\n });\n // Emit the response as if it came from the SSE stream\n if (loadResponse.success && loadResponse.data?.chat) {\n currentChatKeyRef.current = loadResponse.data.chat.key;\n const chatEvent: ChatEvent = {\n type: \"load_chat_response\",\n orgId: fullEvent.orgId,\n chatKey: loadResponse.data.chat.key,\n userId: fullEvent.userId,\n timestamp: Date.now(),\n data: loadResponse.data,\n };\n emit(\"load_chat_response\", chatEvent);\n if (onMessageRef.current) {\n onMessageRef.current(chatEvent);\n }\n }\n break;\n\n case \"new_chat\":\n const createResponse = await sendRestMessage(\"create\", {\n orgId: fullEvent.orgId,\n userId: fullEvent.userId,\n metadata: fullEvent.data,\n });\n if (createResponse.success && createResponse.data?.chatKey) {\n currentChatKeyRef.current = createResponse.data.chatKey;\n // Emit new_chat_created event\n const newChatEvent: ChatEvent = {\n type: \"new_chat_created\",\n orgId: fullEvent.orgId,\n chatKey: createResponse.data.chatKey,\n userId: fullEvent.userId,\n timestamp: Date.now(),\n data: { chatKey: createResponse.data.chatKey },\n };\n emit(\"new_chat_created\", newChatEvent);\n if (onMessageRef.current) {\n onMessageRef.current(newChatEvent);\n }\n // Resolve chat creation promise if waiting\n if (chatCreationPromiseRef.current) {\n chatCreationPromiseRef.current.resolve(createResponse.data.chatKey);\n chatCreationPromiseRef.current = null;\n }\n }\n break;\n\n case \"end_chat\":\n await sendRestMessage(\"end\", {\n orgId: fullEvent.orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n userId: fullEvent.userId,\n data: fullEvent.data,\n });\n break;\n\n case \"human_agent_join\":\n await sendRestMessage(\"agent-join\", {\n orgId: fullEvent.orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n user: fullEvent.data?.user,\n });\n break;\n\n case \"human_agent_leave\":\n await sendRestMessage(\"agent-leave\", {\n orgId: fullEvent.orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n user: fullEvent.data?.user,\n });\n break;\n\n default:\n // For unrecognized event types, log and continue\n logger.warn(\"Unrecognized event type for SSE REST:\", fullEvent.type);\n break;\n }\n\n updateMetrics({ messagesSent: metrics.messagesSent + 1 });\n logger.debug(\"SSE REST message sent successfully\");\n resolve();\n } catch (error) {\n logger.error(\"Failed to send SSE REST message:\", error);\n const sendError: WebSocketError = {\n code: \"SEND_FAILED\",\n message:\n error instanceof Error\n ? error.message\n : \"Failed to send message\",\n retryable: true,\n timestamp: Date.now(),\n };\n setError(sendError);\n updateMetrics({ lastError: sendError });\n reject(sendError);\n }\n return;\n }\n\n // WebSocket Transport (default)\n if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {\n // Queue the message\n if (addToQueue(fullEvent)) {\n logger.debug(\"Message queued, attempting to connect\");\n if (connectionState === \"disconnected\" && overrideUserId) {\n connect(overrideUserId)\n .then(() => resolve())\n .catch(reject);\n } else {\n // Message is queued, will be sent when connected\n resolve();\n }\n } else {\n reject(new Error(\"Message queue full\"));\n }\n return;\n }\n\n try {\n wsRef.current.send(JSON.stringify(fullEvent));\n updateMetrics({ messagesSent: metrics.messagesSent + 1 });\n logger.debug(\"Message sent successfully\");\n resolve();\n } catch (error) {\n logger.error(\"Failed to send message:\", error);\n if (addToQueue(fullEvent)) {\n // Message queued for retry\n resolve();\n } else {\n const sendError: WebSocketError = {\n code: \"SEND_FAILED\",\n message:\n error instanceof Error\n ? error.message\n : \"Failed to send message\",\n retryable: true,\n timestamp: Date.now(),\n };\n setError(sendError);\n updateMetrics({ lastError: sendError });\n reject(sendError);\n }\n }\n });\n },\n [connectionState, connect, addToQueue, logger, metrics, updateMetrics, sendRestMessage, emit]\n );\n\n // Start new chat with promise\n const startNewChat = useCallback(\n (userId: string, data?: { [key: string]: any }): Promise<string> => {\n return new Promise((resolve, reject) => {\n if (!userId) {\n reject(new Error(\"User ID is required\"));\n return;\n }\n\n logger.info(\"Requesting new chat from server with userId:\", userId);\n setStartTime(new Date());\n\n // Set up promise handlers\n chatCreationPromiseRef.current = { resolve, reject };\n\n // Send request to server to create new chat\n sendMessage(\n {\n type: \"new_chat\",\n orgId,\n chatKey: \"\", // Server will generate\n userId,\n data: data ?? {},\n },\n userId\n ).catch((error) => {\n chatCreationPromiseRef.current = null;\n reject(error);\n });\n\n // Set timeout for chat creation\n setTimeout(() => {\n if (chatCreationPromiseRef.current) {\n chatCreationPromiseRef.current = null;\n reject(new Error(\"Chat creation timed out\"));\n }\n }, 30000); // 30 second timeout\n });\n },\n [sendMessage, orgId, logger]\n );\n\n // Disconnect function\n const disconnect = useCallback(\n (intentional: boolean = true) => {\n logger.info(\"Disconnecting\", { intentional, transport: transportRef.current });\n intentionalDisconnectRef.current = intentional;\n cleanup();\n setConnectionState(\"disconnected\");\n messageQueueRef.current = [];\n retryCountRef.current = 0;\n mountedRef.current = false;\n currentChatKeyRef.current = undefined;\n currentUserIdRef.current = undefined;\n },\n [cleanup, logger]\n );\n\n // Clear error\n const clearError = useCallback(() => {\n setError(undefined);\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n disconnect(true);\n };\n }, []);\n\n return {\n connectionState,\n isConnected,\n sendMessage,\n error,\n connect,\n startNewChat,\n startTime,\n disconnect,\n metrics,\n on,\n off,\n clearError,\n };\n};\n"],"mappings":"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","names":["useCallback","useState","error","maxRetries","useState","useCallback"]}
1
+ {"version":3,"sources":["../../hooks/use-websocket-chat-customer.ts","../../hooks/use-websocket-chat-base.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useState } from \"react\";\nimport { Chat, ChatEvent, ChatMessage, ChatUser } from \"../models\";\nimport {\n useWebSocketChatBase,\n UseWebSocketChatBaseConfig,\n UseWebSocketChatBaseReturn,\n} from \"./use-websocket-chat-base\";\n\nexport interface UseWebSocketChatCustomerReturn\n extends UseWebSocketChatBaseReturn {\n title: string | undefined;\n messages: ChatMessage[];\n users: ChatUser[];\n isWaiting: boolean;\n isWaitingForAgent: boolean;\n aiEngaged: boolean;\n humanAgentEngaged: boolean;\n metadata: Record<string, string>;\n status: string | undefined;\n chatKey: string;\n}\n\nexport interface UseWebSocketChatCustomerConfig\n extends Omit<UseWebSocketChatBaseConfig, \"clientType\" | \"onMessage\"> {\n chatKey: string;\n}\n\nexport const useWebSocketChatCustomer = ({\n serverBaseUrl,\n orgId,\n chatKey,\n product,\n}: UseWebSocketChatCustomerConfig): UseWebSocketChatCustomerReturn => {\n const [currentChat, setCurrentChat] = useState<Chat | undefined>(undefined);\n\n const handleMessage = useCallback((chatEvent: ChatEvent) => {\n console.log(\"Received event:\", chatEvent.type);\n\n switch (chatEvent.type) {\n case \"message\":\n if (!chatEvent.message) return;\n\n console.log(\n \"got message:\",\n chatEvent.message.role,\n \":\",\n chatEvent.message.content\n );\n // if (\n // chatEvent.message?.toolCalls?.length &&\n // chatEvent.message.toolCalls.length > 0\n // )\n // return;\n setCurrentChat((prev) => {\n if (!prev) return prev;\n return {\n ...prev,\n messages: [...prev.messages, chatEvent.message!],\n };\n });\n break;\n\n case \"chat_updated\":\n const chat = chatEvent.data?.chat?.value as Chat;\n if (chat) {\n setCurrentChat(chat);\n }\n break;\n\n case \"load_chat\":\n const history = chatEvent.data?.chat as Chat;\n if (!history) return;\n setCurrentChat(history);\n break;\n\n default:\n // console.log(\"unhandled event:\", chatEvent.type);\n break;\n }\n }, []);\n\n const base = useWebSocketChatBase({\n serverBaseUrl,\n orgId,\n clientType: \"customer\",\n onMessage: handleMessage,\n product,\n });\n\n return {\n ...base,\n chatKey,\n title: currentChat?.title,\n messages: currentChat?.messages ?? [],\n users: currentChat?.users ?? [],\n isWaiting: currentChat?.isWaiting ?? false,\n isWaitingForAgent: currentChat?.isWaitingForAgent ?? false,\n aiEngaged: currentChat?.aiEngaged ?? false,\n humanAgentEngaged: currentChat?.humanAgentEngaged ?? false,\n metadata: currentChat?.metadata ?? {},\n status: currentChat?.status,\n };\n};\n","\"use client\";\n\nimport { ProductNameTS } from \"@elqnt/types\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { ChatEvent } from \"../models\";\n\n// Connection state enum\nexport type ConnectionState =\n | \"disconnected\"\n | \"connecting\"\n | \"connected\"\n | \"reconnecting\";\n\n// Transport type - WebSocket or SSE\nexport type TransportType = \"websocket\" | \"sse\";\n\n// Error types\nexport interface WebSocketError {\n code:\n | \"CONNECTION_FAILED\"\n | \"PARSE_ERROR\"\n | \"SEND_FAILED\"\n | \"TIMEOUT\"\n | \"NETWORK_ERROR\";\n message: string;\n retryable: boolean;\n timestamp: number;\n}\n\n// Retry configuration\nexport interface RetryConfig {\n maxRetries?: number;\n intervals?: number[];\n backoffMultiplier?: number;\n maxBackoffTime?: number;\n}\n\n// Connection metrics\nexport interface ConnectionMetrics {\n latency: number;\n messagesSent: number;\n messagesReceived: number;\n messagesQueued: number;\n reconnectCount: number;\n lastError?: WebSocketError;\n connectedAt?: number;\n lastMessageAt?: number;\n transportType?: TransportType;\n}\n\n// Message queue configuration\nexport interface QueueConfig {\n maxSize?: number;\n dropStrategy?: \"oldest\" | \"newest\";\n}\n\n// Logger interface\nexport interface Logger {\n debug: (message: string, ...args: any[]) => void;\n info: (message: string, ...args: any[]) => void;\n warn: (message: string, ...args: any[]) => void;\n error: (message: string, ...args: any[]) => void;\n}\n\n// Default logger (can be overridden)\nconst createDefaultLogger = (debug: boolean): Logger => ({\n debug: debug ? console.log : () => {},\n info: console.info,\n warn: console.warn,\n error: console.error,\n});\n\nexport interface UseWebSocketChatBaseConfig {\n serverBaseUrl: string;\n orgId: string;\n clientType: \"customer\" | \"humanAgent\" | \"observer\";\n product: ProductNameTS;\n onMessage?: (event: ChatEvent) => void;\n retryConfig?: RetryConfig;\n queueConfig?: QueueConfig;\n debug?: boolean;\n logger?: Logger;\n heartbeatInterval?: number; // in milliseconds, 0 to disable\n heartbeatTimeout?: number; // in milliseconds\n /**\n * Transport type to use for the connection.\n * - 'websocket': Traditional WebSocket connection (default)\n * - 'sse': Server-Sent Events for receiving + REST API for sending\n *\n * SSE provides automatic browser reconnection and simpler infrastructure\n * (no sticky sessions required), following the pattern used by Claude.ai and ChatGPT.\n */\n transport?: TransportType;\n}\n\nexport interface UseWebSocketChatBaseReturn {\n connectionState: ConnectionState;\n isConnected: boolean;\n sendMessage: (\n event: Omit<ChatEvent, \"timestamp\">,\n overrideUserId?: string\n ) => Promise<void>;\n error: WebSocketError | undefined;\n connect: (userId: string) => Promise<void>;\n startNewChat: (\n userId: string,\n data?: { [key: string]: any }\n ) => Promise<string>;\n startTime: Date | undefined;\n disconnect: (intentional?: boolean) => void;\n metrics: ConnectionMetrics;\n on: (eventType: string, handler: (data: any) => void) => () => void;\n off: (eventType: string, handler: (data: any) => void) => void;\n clearError: () => void;\n}\n\n// Default configurations\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 10,\n intervals: [1000, 2000, 5000],\n backoffMultiplier: 1.5,\n maxBackoffTime: 30000,\n};\n\nconst DEFAULT_QUEUE_CONFIG: QueueConfig = {\n maxSize: 100,\n dropStrategy: \"oldest\",\n};\n\nconst DEFAULT_HEARTBEAT_INTERVAL = 30000; // 30 seconds\nconst DEFAULT_HEARTBEAT_TIMEOUT = 5000; // 5 seconds\nconst DEFAULT_TRANSPORT: TransportType = \"websocket\";\n\n// Type guards\nfunction isChatEvent(data: any): data is ChatEvent {\n return (\n data &&\n typeof data === \"object\" &&\n (typeof data.type === \"string\" || data.message)\n );\n}\n\nfunction hasValidChatKey(data: any): boolean {\n return data?.chatKey && typeof data.chatKey === \"string\";\n}\n\nexport const useWebSocketChatBase = ({\n serverBaseUrl,\n orgId,\n clientType,\n product,\n onMessage,\n retryConfig = DEFAULT_RETRY_CONFIG,\n queueConfig = DEFAULT_QUEUE_CONFIG,\n debug = false,\n logger = createDefaultLogger(debug),\n heartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL,\n heartbeatTimeout = DEFAULT_HEARTBEAT_TIMEOUT,\n transport = DEFAULT_TRANSPORT,\n}: UseWebSocketChatBaseConfig): UseWebSocketChatBaseReturn => {\n // State\n const [connectionState, setConnectionState] =\n useState<ConnectionState>(\"disconnected\");\n const [error, setError] = useState<WebSocketError | undefined>(undefined);\n const [startTime, setStartTime] = useState<Date | undefined>(undefined);\n const [metrics, setMetrics] = useState<ConnectionMetrics>({\n latency: 0,\n messagesSent: 0,\n messagesReceived: 0,\n messagesQueued: 0,\n reconnectCount: 0,\n transportType: transport,\n });\n\n // Refs\n const wsRef = useRef<WebSocket | undefined>(undefined);\n const sseRef = useRef<EventSource | undefined>(undefined);\n const transportRef = useRef<TransportType>(transport);\n\n // Sync transportRef with transport prop\n useEffect(() => {\n transportRef.current = transport;\n }, [transport]);\n const reconnectTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);\n const retryCountRef = useRef(0);\n const messageQueueRef = useRef<ChatEvent[]>([]);\n const mountedRef = useRef(false);\n const currentChatKeyRef = useRef<string | undefined>(undefined);\n const currentUserIdRef = useRef<string | undefined>(undefined);\n const intentionalDisconnectRef = useRef(false);\n const eventHandlersRef = useRef<Map<string, Set<(data: any) => void>>>(\n new Map()\n );\n const onMessageRef = useRef(onMessage);\n const pendingMessagesRef = useRef<\n Map<\n string,\n {\n resolve: () => void;\n reject: (error: Error) => void;\n timeout: NodeJS.Timeout;\n }\n >\n >(new Map());\n const heartbeatIntervalRef = useRef<NodeJS.Timeout | undefined>(undefined);\n const heartbeatTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);\n const lastPongRef = useRef<number>(Date.now());\n const chatCreationPromiseRef = useRef<{\n resolve: (value: string) => void;\n reject: (reason?: any) => void;\n } | null>(null);\n\n // Load chat retry state\n const loadChatRetryMapRef = useRef<Map<string, {\n retryCount: number;\n timeoutId: NodeJS.Timeout | null;\n }>>(new Map());\n\n // Update onMessage ref when it changes\n useEffect(() => {\n onMessageRef.current = onMessage;\n }, [onMessage]);\n\n // Computed state\n const isConnected = connectionState === \"connected\";\n\n // Event subscription system\n const on = useCallback((eventType: string, handler: (data: any) => void) => {\n if (!eventHandlersRef.current.has(eventType)) {\n eventHandlersRef.current.set(eventType, new Set());\n }\n eventHandlersRef.current.get(eventType)!.add(handler);\n\n // Return unsubscribe function\n return () => off(eventType, handler);\n }, []);\n\n const off = useCallback((eventType: string, handler: (data: any) => void) => {\n const handlers = eventHandlersRef.current.get(eventType);\n if (handlers) {\n handlers.delete(handler);\n if (handlers.size === 0) {\n eventHandlersRef.current.delete(eventType);\n }\n }\n }, []);\n\n // Emit event to all registered handlers\n const emit = useCallback(\n (eventType: string, data: any) => {\n const handlers = eventHandlersRef.current.get(eventType);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n logger.error(`Error in event handler for ${eventType}:`, error);\n }\n });\n }\n },\n [logger]\n );\n\n // Update metrics\n const updateMetrics = useCallback((updates: Partial<ConnectionMetrics>) => {\n setMetrics((prev) => ({ ...prev, ...updates }));\n }, []);\n\n // Queue management\n const addToQueue = useCallback(\n (event: ChatEvent) => {\n const currentQueueSize = messageQueueRef.current.length;\n const maxSize = queueConfig.maxSize || DEFAULT_QUEUE_CONFIG.maxSize!;\n\n if (currentQueueSize >= maxSize) {\n if (queueConfig.dropStrategy === \"newest\") {\n logger.warn(\"Message queue full, dropping new message\");\n return false;\n } else {\n // Drop oldest\n const dropped = messageQueueRef.current.shift();\n logger.warn(\"Message queue full, dropped oldest message\", dropped);\n }\n }\n\n messageQueueRef.current.push(event);\n updateMetrics({ messagesQueued: messageQueueRef.current.length });\n return true;\n },\n [queueConfig, logger, updateMetrics]\n );\n\n // Calculate retry interval\n const calculateRetryInterval = useCallback(\n (retryCount: number): number => {\n const config = { ...DEFAULT_RETRY_CONFIG, ...retryConfig };\n const {\n intervals = [],\n backoffMultiplier = 1.5,\n maxBackoffTime = 30000,\n } = config;\n\n if (retryCount < intervals.length) {\n return intervals[retryCount];\n }\n\n // Exponential backoff after predefined intervals\n const baseInterval = intervals[intervals.length - 1] || 5000;\n const backoffTime =\n baseInterval *\n Math.pow(backoffMultiplier, retryCount - intervals.length + 1);\n return Math.min(backoffTime, maxBackoffTime);\n },\n [retryConfig]\n );\n\n // Heartbeat mechanism\n const startHeartbeat = useCallback(() => {\n if (!heartbeatInterval || heartbeatInterval <= 0) return;\n\n const sendPing = () => {\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n const pingTime = Date.now();\n wsRef.current.send(\n JSON.stringify({ type: \"ping\", timestamp: pingTime })\n );\n\n // Set timeout for pong response\n heartbeatTimeoutRef.current = setTimeout(() => {\n logger.warn(\"Heartbeat timeout - no pong received\");\n // Force reconnection\n if (wsRef.current) {\n wsRef.current.close(4000, \"Heartbeat timeout\");\n }\n }, heartbeatTimeout);\n }\n };\n\n // Clear existing interval\n if (heartbeatIntervalRef.current) {\n clearInterval(heartbeatIntervalRef.current);\n }\n\n // Start new interval\n heartbeatIntervalRef.current = setInterval(sendPing, heartbeatInterval);\n logger.debug(\"Heartbeat started\");\n }, [heartbeatInterval, heartbeatTimeout, logger]);\n\n const stopHeartbeat = useCallback(() => {\n if (heartbeatIntervalRef.current) {\n clearInterval(heartbeatIntervalRef.current);\n heartbeatIntervalRef.current = undefined;\n }\n if (heartbeatTimeoutRef.current) {\n clearTimeout(heartbeatTimeoutRef.current);\n heartbeatTimeoutRef.current = undefined;\n }\n logger.debug(\"Heartbeat stopped\");\n }, [logger]);\n\n // Cleanup function\n const cleanup = useCallback(() => {\n // Cleanup WebSocket\n if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {\n wsRef.current.close(1000, \"Cleanup\");\n }\n wsRef.current = undefined;\n\n // Cleanup SSE\n if (sseRef.current) {\n sseRef.current.close();\n sseRef.current = undefined;\n }\n\n if (reconnectTimeoutRef.current) {\n clearTimeout(reconnectTimeoutRef.current);\n reconnectTimeoutRef.current = undefined;\n }\n stopHeartbeat();\n\n // Clear pending message promises\n pendingMessagesRef.current.forEach(({ reject, timeout }) => {\n clearTimeout(timeout);\n reject(new Error(\"Connection closed\"));\n });\n pendingMessagesRef.current.clear();\n\n // Clear load chat retry timeouts\n loadChatRetryMapRef.current.forEach((retryState) => {\n if (retryState.timeoutId) {\n clearTimeout(retryState.timeoutId);\n }\n });\n loadChatRetryMapRef.current.clear();\n }, [stopHeartbeat]);\n\n // SSE REST API helper - converts WebSocket URL to REST API URL\n const getRestApiUrl = useCallback((endpoint: string): string => {\n // serverBaseUrl is like \"wss://chat.example.com/v1/chat\" or \"ws://localhost:8888/v1/chat\"\n // Convert to \"https://chat.example.com/v1/chat/{endpoint}\" or \"http://localhost:8888/v1/chat/{endpoint}\"\n const httpUrl = serverBaseUrl\n .replace(/^wss:/, \"https:\")\n .replace(/^ws:/, \"http:\");\n return `${httpUrl}/${endpoint}`;\n }, [serverBaseUrl]);\n\n // SSE REST API call helper\n const sendRestMessage = useCallback(\n async (endpoint: string, body: Record<string, any>): Promise<any> => {\n const url = getRestApiUrl(endpoint);\n logger.debug(`SSE REST API call: POST ${endpoint}`, body);\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`REST API error: ${response.status} - ${errorText}`);\n }\n\n const data = await response.json();\n return data;\n } catch (error) {\n logger.error(`SSE REST API error for ${endpoint}:`, error);\n throw error;\n }\n },\n [getRestApiUrl, logger]\n );\n\n // Connect function\n const connect = useCallback(\n async (userId: string): Promise<void> => {\n if (!mountedRef.current) {\n mountedRef.current = true;\n }\n\n // Guard: Don't connect if orgId is not available\n if (!orgId) {\n const error: WebSocketError = {\n code: \"CONNECTION_FAILED\",\n message: \"Cannot connect: orgId is undefined\",\n retryable: false,\n timestamp: Date.now(),\n };\n logger.error(\"Cannot connect: orgId is undefined\");\n setError(error);\n return Promise.reject(error);\n }\n\n // Check if already connected (WebSocket or SSE)\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n logger.debug(\"Already connected (WebSocket)\");\n return Promise.resolve();\n }\n if (sseRef.current?.readyState === EventSource.OPEN) {\n logger.debug(\"Already connected (SSE)\");\n return Promise.resolve();\n }\n\n if (\n connectionState === \"connecting\" ||\n connectionState === \"reconnecting\"\n ) {\n logger.debug(\"Connection already in progress\");\n return Promise.resolve();\n }\n\n // Check max retries\n const maxRetries =\n retryConfig.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries!;\n if (\n retryCountRef.current >= maxRetries &&\n !intentionalDisconnectRef.current\n ) {\n const error: WebSocketError = {\n code: \"CONNECTION_FAILED\",\n message: `Max retries (${maxRetries}) exceeded`,\n retryable: false,\n timestamp: Date.now(),\n };\n setError(error);\n updateMetrics({ lastError: error });\n return Promise.reject(error);\n }\n\n cleanup();\n setConnectionState(\n retryCountRef.current > 0 ? \"reconnecting\" : \"connecting\"\n );\n intentionalDisconnectRef.current = false;\n\n return new Promise<void>((resolve, reject) => {\n try {\n const connectionStartTime = Date.now();\n\n logger.info(`🔄 Connecting with transport: ${transportRef.current}`);\n\n // SSE Transport\n if (transportRef.current === \"sse\") {\n const sseUrl = getRestApiUrl(`stream?orgId=${orgId}&userId=${userId}&clientType=${clientType}&chatId=${currentChatKeyRef.current || \"\"}`);\n\n logger.debug(\"Connecting to SSE:\", sseUrl);\n console.log(`⏳ Initiating SSE connection to ${sseUrl}...`);\n\n const eventSource = new EventSource(sseUrl);\n\n eventSource.onopen = () => {\n if (!mountedRef.current) {\n eventSource.close();\n reject(new Error(\"Component unmounted\"));\n return;\n }\n\n const connectionTimeMs = Date.now() - connectionStartTime;\n const connectionTimeSec = (connectionTimeMs / 1000).toFixed(2);\n\n logger.info(\"✅ SSE connected\", {\n userId,\n retryCount: retryCountRef.current,\n connectionTime: `${connectionTimeSec}s (${connectionTimeMs}ms)`,\n });\n\n console.log(`🔌 SSE connection established in ${connectionTimeSec} seconds`);\n\n setConnectionState(\"connected\");\n setError(undefined);\n const wasReconnecting = retryCountRef.current > 0;\n retryCountRef.current = 0;\n\n // Update metrics\n updateMetrics({\n connectedAt: Date.now(),\n latency: connectionTimeMs,\n transportType: \"sse\",\n reconnectCount: wasReconnecting\n ? metrics.reconnectCount + 1\n : metrics.reconnectCount,\n });\n\n // Store the userId for reconnection\n currentUserIdRef.current = userId;\n\n // If we have a chat key, load the chat via REST\n if (currentChatKeyRef.current) {\n logger.info(\"Loading chat after SSE reconnection:\", currentChatKeyRef.current);\n sendRestMessage(\"load\", {\n orgId,\n chatKey: currentChatKeyRef.current,\n userId,\n }).then((response) => {\n if (response.success && response.data?.chat) {\n const chatEvent: ChatEvent = {\n type: \"load_chat_response\",\n orgId,\n chatKey: currentChatKeyRef.current!,\n userId,\n timestamp: Date.now(),\n data: response.data,\n };\n emit(\"load_chat_response\", chatEvent);\n if (onMessageRef.current) {\n onMessageRef.current(chatEvent);\n }\n }\n }).catch((err) => {\n logger.error(\"Failed to load chat after SSE reconnection:\", err);\n });\n }\n\n // Emit connected event\n emit(\"connected\", { userId, wasReconnecting, transport: \"sse\" });\n\n resolve();\n };\n\n // Handle SSE messages - each event type is a separate event\n const handleSSEMessage = (event: MessageEvent) => {\n if (!mountedRef.current) return;\n\n // Skip if no data (e.g., heartbeat or connection event)\n if (!event.data || event.data === \"\") {\n return;\n }\n\n try {\n const data = JSON.parse(event.data);\n\n if (!isChatEvent(data)) {\n logger.warn(\"Received invalid SSE message format:\", data);\n return;\n }\n\n const chatEvent = data as ChatEvent;\n logger.debug(\"SSE message received:\", chatEvent.type);\n\n // Update metrics\n updateMetrics({\n messagesReceived: metrics.messagesReceived + 1,\n lastMessageAt: Date.now(),\n });\n\n // Handle specific events internally\n switch (chatEvent.type) {\n case \"new_chat_created\":\n const newChatKey = chatEvent.data?.chatKey as string;\n if (newChatKey) {\n logger.info(\"New chat created with key:\", newChatKey);\n currentChatKeyRef.current = newChatKey;\n\n if (chatCreationPromiseRef.current) {\n chatCreationPromiseRef.current.resolve(newChatKey);\n chatCreationPromiseRef.current = null;\n }\n }\n break;\n\n case \"load_chat_response\":\n const chat = chatEvent.data?.chat;\n if (chat && chat.key) {\n logger.info(\"Chat loaded with key:\", chat.key);\n currentChatKeyRef.current = chat.key;\n }\n break;\n\n case \"chat_ended\":\n logger.info(\"Chat ended, clearing key\");\n currentChatKeyRef.current = undefined;\n break;\n }\n\n // Emit event to subscribers\n emit(chatEvent.type || \"message\", chatEvent);\n\n // Call the legacy onMessage handler\n if (onMessageRef.current) {\n onMessageRef.current(chatEvent);\n }\n } catch (error) {\n logger.error(\"Failed to parse SSE message:\", error);\n }\n };\n\n // Subscribe to all event types\n eventSource.addEventListener(\"message\", handleSSEMessage);\n eventSource.addEventListener(\"reconnected\", handleSSEMessage);\n eventSource.addEventListener(\"typing\", handleSSEMessage);\n eventSource.addEventListener(\"stopped_typing\", handleSSEMessage);\n eventSource.addEventListener(\"waiting\", handleSSEMessage);\n eventSource.addEventListener(\"waiting_for_agent\", handleSSEMessage);\n eventSource.addEventListener(\"human_agent_joined\", handleSSEMessage);\n eventSource.addEventListener(\"human_agent_left\", handleSSEMessage);\n eventSource.addEventListener(\"chat_ended\", handleSSEMessage);\n eventSource.addEventListener(\"chat_updated\", handleSSEMessage);\n eventSource.addEventListener(\"load_chat_response\", handleSSEMessage);\n eventSource.addEventListener(\"new_chat_created\", handleSSEMessage);\n // Note: \"error\" event type from server is different from connection errors\n // Server-sent \"error\" events have data, connection errors don't\n eventSource.addEventListener(\"show_csat_survey\", handleSSEMessage);\n eventSource.addEventListener(\"csat_response\", handleSSEMessage);\n eventSource.addEventListener(\"user_suggested_actions\", handleSSEMessage);\n eventSource.addEventListener(\"agent_execution_started\", handleSSEMessage);\n eventSource.addEventListener(\"agent_execution_ended\", handleSSEMessage);\n eventSource.addEventListener(\"agent_context_update\", handleSSEMessage);\n eventSource.addEventListener(\"plan_pending_approval\", handleSSEMessage);\n eventSource.addEventListener(\"step_started\", handleSSEMessage);\n eventSource.addEventListener(\"step_completed\", handleSSEMessage);\n eventSource.addEventListener(\"step_failed\", handleSSEMessage);\n eventSource.addEventListener(\"plan_completed\", handleSSEMessage);\n eventSource.addEventListener(\"skills_changed\", handleSSEMessage);\n eventSource.addEventListener(\"summary_update\", handleSSEMessage);\n\n eventSource.onerror = (error) => {\n logger.error(\"SSE error:\", error);\n if (!mountedRef.current) return;\n\n // EventSource automatically reconnects on error, so we just log it\n // Only set error state if the connection is permanently closed\n if (eventSource.readyState === EventSource.CLOSED) {\n const sseError: WebSocketError = {\n code: \"CONNECTION_FAILED\",\n message: \"SSE connection failed\",\n retryable: true,\n timestamp: Date.now(),\n };\n setError(sseError);\n updateMetrics({ lastError: sseError });\n setConnectionState(\"disconnected\");\n emit(\"disconnected\", { reason: \"SSE error\" });\n\n // Handle manual reconnection if EventSource doesn't auto-reconnect\n if (!intentionalDisconnectRef.current && mountedRef.current) {\n const retryInterval = calculateRetryInterval(retryCountRef.current);\n retryCountRef.current++;\n\n logger.info(`SSE reconnecting in ${retryInterval}ms (attempt ${retryCountRef.current})`);\n\n if (reconnectTimeoutRef.current) {\n clearTimeout(reconnectTimeoutRef.current);\n }\n reconnectTimeoutRef.current = setTimeout(() => {\n connect(userId);\n }, retryInterval);\n }\n }\n };\n\n sseRef.current = eventSource;\n return;\n }\n\n // WebSocket Transport (default)\n const wsUrl = `${serverBaseUrl}?orgId=${orgId}&userId=${userId}&clientType=${clientType}&product=${product}`;\n\n logger.debug(\"Connecting to WebSocket:\", wsUrl);\n console.log(`⏳ Initiating WebSocket connection to ${serverBaseUrl}...`);\n\n const ws = new WebSocket(wsUrl);\n\n ws.onopen = () => {\n if (!mountedRef.current) {\n ws.close(1000, \"Component unmounted\");\n reject(new Error(\"Component unmounted\"));\n return;\n }\n\n const connectionTimeMs = Date.now() - connectionStartTime;\n const connectionTimeSec = (connectionTimeMs / 1000).toFixed(2);\n\n logger.info(\"✅ WebSocket connected\", {\n userId,\n retryCount: retryCountRef.current,\n connectionTime: `${connectionTimeSec}s (${connectionTimeMs}ms)`,\n });\n\n console.log(`🔌 WebSocket connection established in ${connectionTimeSec} seconds`);\n\n setConnectionState(\"connected\");\n setError(undefined);\n const wasReconnecting = retryCountRef.current > 0;\n retryCountRef.current = 0;\n\n // Update metrics\n updateMetrics({\n connectedAt: Date.now(),\n latency: connectionTimeMs,\n reconnectCount: wasReconnecting\n ? metrics.reconnectCount + 1\n : metrics.reconnectCount,\n });\n\n // Process queued messages\n while (\n messageQueueRef.current.length > 0 &&\n ws.readyState === WebSocket.OPEN\n ) {\n const event = messageQueueRef.current.shift();\n if (event) {\n ws.send(JSON.stringify({ ...event, timestamp: Date.now() }));\n updateMetrics({\n messagesSent: metrics.messagesSent + 1,\n messagesQueued: messageQueueRef.current.length,\n });\n }\n }\n\n // Store the userId for reconnection\n currentUserIdRef.current = userId;\n\n // If we have a chat key, resubscribe to the chat\n if (currentChatKeyRef.current) {\n if (!orgId) {\n logger.error(\"Cannot resubscribe to chat: orgId is undefined\");\n } else {\n logger.info(\n \"Resubscribing to chat after reconnection:\",\n currentChatKeyRef.current\n );\n const resubscribeEvent: ChatEvent = {\n type: \"load_chat\",\n orgId,\n chatKey: currentChatKeyRef.current,\n userId,\n timestamp: Date.now(),\n data: {},\n };\n ws.send(JSON.stringify(resubscribeEvent));\n }\n }\n\n // Start heartbeat\n startHeartbeat();\n\n // Emit connected event\n emit(\"connected\", { userId, wasReconnecting });\n\n // Resolve the promise\n resolve();\n };\n\n ws.onmessage = (event) => {\n if (!mountedRef.current) return;\n\n try {\n const data = JSON.parse(event.data);\n\n if (!isChatEvent(data)) {\n logger.warn(\"Received invalid message format:\", data);\n return;\n }\n\n const chatEvent = data as ChatEvent;\n logger.debug(\"Message received:\", chatEvent.type);\n\n // Update metrics\n updateMetrics({\n messagesReceived: metrics.messagesReceived + 1,\n lastMessageAt: Date.now(),\n });\n\n // Handle pong response\n if (chatEvent.type === \"pong\") {\n if (heartbeatTimeoutRef.current) {\n clearTimeout(heartbeatTimeoutRef.current);\n heartbeatTimeoutRef.current = undefined;\n }\n const latency =\n Date.now() - (chatEvent.timestamp || Date.now());\n lastPongRef.current = Date.now();\n updateMetrics({ latency });\n return;\n }\n\n // Handle specific events internally for connection management\n switch (chatEvent.type) {\n case \"new_chat_created\":\n const newChatKey = chatEvent.data?.chatKey as string;\n if (newChatKey) {\n logger.info(\"New chat created with key:\", newChatKey);\n currentChatKeyRef.current = newChatKey;\n\n // Resolve the promise if waiting for chat creation\n if (chatCreationPromiseRef.current) {\n chatCreationPromiseRef.current.resolve(newChatKey);\n chatCreationPromiseRef.current = null;\n }\n\n // Send load_chat to subscribe to the new chat (only if orgId is valid)\n if (!orgId) {\n logger.error(\"Cannot send load_chat: orgId is undefined\");\n return;\n }\n\n const loadChatEvent: ChatEvent = {\n type: \"load_chat\",\n orgId,\n chatKey: newChatKey,\n userId: currentUserIdRef.current || userId,\n timestamp: Date.now(),\n data: {},\n };\n ws.send(JSON.stringify(loadChatEvent));\n }\n break;\n\n case \"load_chat_response\":\n const chat = chatEvent.data?.chat;\n if (chat && chat.key) {\n logger.info(\"Chat loaded with key:\", chat.key);\n currentChatKeyRef.current = chat.key;\n\n // Clear retry state for this chat on success\n const retryState = loadChatRetryMapRef.current.get(chat.key);\n if (retryState) {\n if (retryState.timeoutId) {\n clearTimeout(retryState.timeoutId);\n }\n loadChatRetryMapRef.current.delete(chat.key);\n }\n } else if (!chat) {\n logger.warn(\"Chat load failed, clearing key\");\n currentChatKeyRef.current = undefined;\n }\n break;\n\n case \"chat_ended\":\n logger.info(\"Chat ended, clearing key\");\n currentChatKeyRef.current = undefined;\n break;\n\n case \"error\":\n const errorMessage =\n chatEvent.data?.message || \"Unknown error\";\n logger.error(\"Received error from server:\", errorMessage);\n\n // Check if this is a \"key not found\" error for load_chat\n if (errorMessage.includes(\"nats: key not found\") || errorMessage.includes(\"Failed to load chat\")) {\n const chatKeyFromError = currentChatKeyRef.current;\n if (chatKeyFromError) {\n const maxRetries = 5;\n let retryState = loadChatRetryMapRef.current.get(chatKeyFromError);\n\n if (!retryState) {\n retryState = { retryCount: 0, timeoutId: null };\n loadChatRetryMapRef.current.set(chatKeyFromError, retryState);\n }\n\n if (retryState.retryCount < maxRetries) {\n // Exponential backoff: 200ms, 400ms, 800ms, 1.6s, 3.2s\n const delay = 200 * Math.pow(2, retryState.retryCount);\n retryState.retryCount++;\n\n logger.info(\n `Chat load failed, retrying (${retryState.retryCount}/${maxRetries}) in ${delay}ms...`,\n chatKeyFromError\n );\n\n retryState.timeoutId = setTimeout(() => {\n if (!wsRef.current || !mountedRef.current) return;\n\n // Check if orgId is valid before retrying\n if (!orgId) {\n logger.error(\"Cannot retry load_chat: orgId is undefined\", chatKeyFromError);\n loadChatRetryMapRef.current.delete(chatKeyFromError);\n return;\n }\n\n logger.debug(\"Retrying load_chat:\", chatKeyFromError);\n const retryLoadEvent: ChatEvent = {\n type: \"load_chat\",\n orgId,\n chatKey: chatKeyFromError,\n userId: currentUserIdRef.current || \"\",\n timestamp: Date.now(),\n data: {},\n };\n ws.send(JSON.stringify(retryLoadEvent));\n }, delay);\n } else {\n logger.error(\"Max retries reached for loading chat:\", chatKeyFromError);\n loadChatRetryMapRef.current.delete(chatKeyFromError);\n }\n }\n }\n\n const wsError: WebSocketError = {\n code: \"NETWORK_ERROR\",\n message: errorMessage,\n retryable: true,\n timestamp: Date.now(),\n };\n setError(wsError);\n updateMetrics({ lastError: wsError });\n break;\n }\n\n // Emit event to subscribers\n emit(chatEvent.type || \"message\", chatEvent);\n\n // Call the legacy onMessage handler\n if (onMessageRef.current) {\n onMessageRef.current(chatEvent);\n }\n } catch (error) {\n logger.error(\"Failed to parse WebSocket message:\", error);\n const parseError: WebSocketError = {\n code: \"PARSE_ERROR\",\n message: \"Failed to parse message\",\n retryable: false,\n timestamp: Date.now(),\n };\n setError(parseError);\n updateMetrics({ lastError: parseError });\n }\n };\n\n ws.onclose = (event) => {\n if (!mountedRef.current) return;\n\n logger.info(\"WebSocket closed\", {\n code: event.code,\n reason: event.reason,\n });\n setConnectionState(\"disconnected\");\n wsRef.current = undefined;\n stopHeartbeat();\n\n // Emit disconnected event\n emit(\"disconnected\", { code: event.code, reason: event.reason });\n\n // Handle reconnection\n if (\n event.code !== 1000 &&\n !intentionalDisconnectRef.current &&\n mountedRef.current\n ) {\n const retryInterval = calculateRetryInterval(\n retryCountRef.current\n );\n retryCountRef.current++;\n\n logger.info(\n `Reconnecting in ${retryInterval}ms (attempt ${retryCountRef.current})`\n );\n\n if (reconnectTimeoutRef.current) {\n clearTimeout(reconnectTimeoutRef.current);\n }\n reconnectTimeoutRef.current = setTimeout(() => {\n connect(userId);\n }, retryInterval);\n }\n };\n\n ws.onerror = (error) => {\n logger.error(\"WebSocket error:\", error);\n if (!mountedRef.current) return;\n\n const wsError: WebSocketError = {\n code: \"CONNECTION_FAILED\",\n message: \"WebSocket connection failed\",\n retryable: true,\n timestamp: Date.now(),\n };\n setError(wsError);\n updateMetrics({ lastError: wsError });\n\n // Reject the promise on error\n reject(wsError);\n };\n\n wsRef.current = ws;\n } catch (error) {\n logger.error(\"Failed to create WebSocket:\", error);\n const wsError: WebSocketError = {\n code: \"CONNECTION_FAILED\",\n message:\n error instanceof Error\n ? error.message\n : \"Failed to create connection\",\n retryable: true,\n timestamp: Date.now(),\n };\n setError(wsError);\n updateMetrics({ lastError: wsError });\n reject(wsError);\n }\n });\n },\n [\n serverBaseUrl,\n orgId,\n clientType,\n product,\n connectionState,\n logger,\n retryConfig,\n metrics,\n updateMetrics,\n cleanup,\n calculateRetryInterval,\n startHeartbeat,\n emit,\n ]\n );\n\n // Send message with promise\n const sendMessage = useCallback(\n (\n event: Omit<ChatEvent, \"timestamp\">,\n overrideUserId?: string\n ): Promise<void> => {\n return new Promise(async (resolve, reject) => {\n if (!mountedRef.current) {\n reject(new Error(\"Component not mounted\"));\n return;\n }\n\n const fullEvent: ChatEvent = {\n ...event,\n timestamp: Date.now(),\n };\n\n logger.debug(\"Sending message:\", fullEvent.type);\n\n // SSE Transport - use REST API\n if (transportRef.current === \"sse\") {\n // Check if SSE is connected\n if (!sseRef.current || sseRef.current.readyState !== EventSource.OPEN) {\n logger.debug(\"SSE not connected, attempting to connect\");\n if (connectionState === \"disconnected\" && overrideUserId) {\n try {\n await connect(overrideUserId);\n } catch (error) {\n reject(error);\n return;\n }\n } else {\n reject(new Error(\"SSE not connected\"));\n return;\n }\n }\n\n try {\n // Map event types to REST endpoints\n switch (fullEvent.type) {\n case \"message\":\n await sendRestMessage(\"send\", {\n orgId: fullEvent.orgId || orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n userId: fullEvent.userId,\n message: fullEvent.message,\n });\n break;\n\n case \"typing\":\n await sendRestMessage(\"typing\", {\n orgId: fullEvent.orgId || orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n userId: fullEvent.userId,\n typing: true,\n });\n break;\n\n case \"stopped_typing\":\n await sendRestMessage(\"typing\", {\n orgId: fullEvent.orgId || orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n userId: fullEvent.userId,\n typing: false,\n });\n break;\n\n case \"load_chat\":\n const loadResponse = await sendRestMessage(\"load\", {\n orgId: fullEvent.orgId || orgId,\n chatKey: fullEvent.chatKey,\n userId: fullEvent.userId,\n });\n // Emit the response as if it came from the SSE stream\n if (loadResponse.success && loadResponse.data?.chat) {\n currentChatKeyRef.current = loadResponse.data.chat.key;\n const chatEvent: ChatEvent = {\n type: \"load_chat_response\",\n orgId: fullEvent.orgId,\n chatKey: loadResponse.data.chat.key,\n userId: fullEvent.userId,\n timestamp: Date.now(),\n data: loadResponse.data,\n };\n emit(\"load_chat_response\", chatEvent);\n if (onMessageRef.current) {\n onMessageRef.current(chatEvent);\n }\n }\n break;\n\n case \"new_chat\":\n const createResponse = await sendRestMessage(\"create\", {\n orgId: fullEvent.orgId || orgId,\n userId: fullEvent.userId,\n metadata: fullEvent.data,\n });\n if (createResponse.success && createResponse.data?.chatKey) {\n currentChatKeyRef.current = createResponse.data.chatKey;\n // Emit new_chat_created event\n const newChatEvent: ChatEvent = {\n type: \"new_chat_created\",\n orgId: fullEvent.orgId,\n chatKey: createResponse.data.chatKey,\n userId: fullEvent.userId,\n timestamp: Date.now(),\n data: { chatKey: createResponse.data.chatKey },\n };\n emit(\"new_chat_created\", newChatEvent);\n if (onMessageRef.current) {\n onMessageRef.current(newChatEvent);\n }\n // Resolve chat creation promise if waiting\n if (chatCreationPromiseRef.current) {\n chatCreationPromiseRef.current.resolve(createResponse.data.chatKey);\n chatCreationPromiseRef.current = null;\n }\n }\n break;\n\n case \"end_chat\":\n await sendRestMessage(\"end\", {\n orgId: fullEvent.orgId || orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n userId: fullEvent.userId,\n data: fullEvent.data,\n });\n break;\n\n case \"human_agent_join\":\n await sendRestMessage(\"agent-join\", {\n orgId: fullEvent.orgId || orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n user: fullEvent.data?.user,\n });\n break;\n\n case \"human_agent_leave\":\n await sendRestMessage(\"agent-leave\", {\n orgId: fullEvent.orgId || orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n user: fullEvent.data?.user,\n });\n break;\n\n // Event types that use the generic /event endpoint\n case \"load_agent_context\":\n case \"skill_activate\":\n case \"skill_deactivate\":\n case \"sync_metadata\":\n case \"plan_approved\":\n case \"plan_rejected\":\n await sendRestMessage(\"event\", {\n type: fullEvent.type,\n orgId: fullEvent.orgId || orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n userId: fullEvent.userId,\n data: fullEvent.data,\n });\n break;\n\n default:\n // For truly unrecognized event types, log a warning\n // but still try to send via the generic endpoint\n logger.warn(\"Sending unrecognized event type via generic endpoint:\", fullEvent.type);\n await sendRestMessage(\"event\", {\n type: fullEvent.type,\n orgId: fullEvent.orgId || orgId,\n chatKey: fullEvent.chatKey || currentChatKeyRef.current,\n userId: fullEvent.userId,\n data: fullEvent.data,\n });\n break;\n }\n\n updateMetrics({ messagesSent: metrics.messagesSent + 1 });\n logger.debug(\"SSE REST message sent successfully\");\n resolve();\n } catch (error) {\n logger.error(\"Failed to send SSE REST message:\", error);\n const sendError: WebSocketError = {\n code: \"SEND_FAILED\",\n message:\n error instanceof Error\n ? error.message\n : \"Failed to send message\",\n retryable: true,\n timestamp: Date.now(),\n };\n setError(sendError);\n updateMetrics({ lastError: sendError });\n reject(sendError);\n }\n return;\n }\n\n // WebSocket Transport (default)\n if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {\n // Queue the message\n if (addToQueue(fullEvent)) {\n logger.debug(\"Message queued, attempting to connect\");\n if (connectionState === \"disconnected\" && overrideUserId) {\n connect(overrideUserId)\n .then(() => resolve())\n .catch(reject);\n } else {\n // Message is queued, will be sent when connected\n resolve();\n }\n } else {\n reject(new Error(\"Message queue full\"));\n }\n return;\n }\n\n try {\n wsRef.current.send(JSON.stringify(fullEvent));\n updateMetrics({ messagesSent: metrics.messagesSent + 1 });\n logger.debug(\"Message sent successfully\");\n resolve();\n } catch (error) {\n logger.error(\"Failed to send message:\", error);\n if (addToQueue(fullEvent)) {\n // Message queued for retry\n resolve();\n } else {\n const sendError: WebSocketError = {\n code: \"SEND_FAILED\",\n message:\n error instanceof Error\n ? error.message\n : \"Failed to send message\",\n retryable: true,\n timestamp: Date.now(),\n };\n setError(sendError);\n updateMetrics({ lastError: sendError });\n reject(sendError);\n }\n }\n });\n },\n [connectionState, connect, addToQueue, logger, metrics, updateMetrics, sendRestMessage, emit]\n );\n\n // Start new chat with promise\n const startNewChat = useCallback(\n (userId: string, data?: { [key: string]: any }): Promise<string> => {\n return new Promise((resolve, reject) => {\n if (!userId) {\n reject(new Error(\"User ID is required\"));\n return;\n }\n\n logger.info(\"Requesting new chat from server with userId:\", userId);\n setStartTime(new Date());\n\n // Set up promise handlers\n chatCreationPromiseRef.current = { resolve, reject };\n\n // Send request to server to create new chat\n sendMessage(\n {\n type: \"new_chat\",\n orgId,\n chatKey: \"\", // Server will generate\n userId,\n data: data ?? {},\n },\n userId\n ).catch((error) => {\n chatCreationPromiseRef.current = null;\n reject(error);\n });\n\n // Set timeout for chat creation\n setTimeout(() => {\n if (chatCreationPromiseRef.current) {\n chatCreationPromiseRef.current = null;\n reject(new Error(\"Chat creation timed out\"));\n }\n }, 30000); // 30 second timeout\n });\n },\n [sendMessage, orgId, logger]\n );\n\n // Disconnect function\n const disconnect = useCallback(\n (intentional: boolean = true) => {\n logger.info(\"Disconnecting\", { intentional, transport: transportRef.current });\n intentionalDisconnectRef.current = intentional;\n cleanup();\n setConnectionState(\"disconnected\");\n messageQueueRef.current = [];\n retryCountRef.current = 0;\n mountedRef.current = false;\n currentChatKeyRef.current = undefined;\n currentUserIdRef.current = undefined;\n },\n [cleanup, logger]\n );\n\n // Clear error\n const clearError = useCallback(() => {\n setError(undefined);\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n disconnect(true);\n };\n }, []);\n\n return {\n connectionState,\n isConnected,\n sendMessage,\n error,\n connect,\n startNewChat,\n startTime,\n disconnect,\n metrics,\n on,\n off,\n clearError,\n };\n};\n"],"mappings":"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","names":["useCallback","useState","error","maxRetries","useState","useCallback"]}
package/dist/index.js CHANGED
@@ -910,7 +910,7 @@ var useWebSocketChatBase = ({
910
910
  if (transportRef.current === "sse") {
911
911
  const sseUrl = getRestApiUrl(`stream?orgId=${orgId}&userId=${userId}&clientType=${clientType}&chatId=${currentChatKeyRef.current || ""}`);
912
912
  logger.debug("Connecting to SSE:", sseUrl);
913
- console.log(`\u23F3 Initiating SSE connection to ${serverBaseUrl}...`);
913
+ console.log(`\u23F3 Initiating SSE connection to ${sseUrl}...`);
914
914
  const eventSource = new EventSource(sseUrl);
915
915
  eventSource.onopen = () => {
916
916
  if (!mountedRef.current) {
@@ -967,6 +967,9 @@ var useWebSocketChatBase = ({
967
967
  };
968
968
  const handleSSEMessage = (event) => {
969
969
  if (!mountedRef.current) return;
970
+ if (!event.data || event.data === "") {
971
+ return;
972
+ }
970
973
  try {
971
974
  const data = JSON.parse(event.data);
972
975
  if (!isChatEvent(data)) {
@@ -1023,7 +1026,6 @@ var useWebSocketChatBase = ({
1023
1026
  eventSource.addEventListener("chat_updated", handleSSEMessage);
1024
1027
  eventSource.addEventListener("load_chat_response", handleSSEMessage);
1025
1028
  eventSource.addEventListener("new_chat_created", handleSSEMessage);
1026
- eventSource.addEventListener("error", handleSSEMessage);
1027
1029
  eventSource.addEventListener("show_csat_survey", handleSSEMessage);
1028
1030
  eventSource.addEventListener("csat_response", handleSSEMessage);
1029
1031
  eventSource.addEventListener("user_suggested_actions", handleSSEMessage);
@@ -1368,7 +1370,7 @@ var useWebSocketChatBase = ({
1368
1370
  switch (fullEvent.type) {
1369
1371
  case "message":
1370
1372
  await sendRestMessage("send", {
1371
- orgId: fullEvent.orgId,
1373
+ orgId: fullEvent.orgId || orgId,
1372
1374
  chatKey: fullEvent.chatKey || currentChatKeyRef.current,
1373
1375
  userId: fullEvent.userId,
1374
1376
  message: fullEvent.message
@@ -1376,7 +1378,7 @@ var useWebSocketChatBase = ({
1376
1378
  break;
1377
1379
  case "typing":
1378
1380
  await sendRestMessage("typing", {
1379
- orgId: fullEvent.orgId,
1381
+ orgId: fullEvent.orgId || orgId,
1380
1382
  chatKey: fullEvent.chatKey || currentChatKeyRef.current,
1381
1383
  userId: fullEvent.userId,
1382
1384
  typing: true
@@ -1384,7 +1386,7 @@ var useWebSocketChatBase = ({
1384
1386
  break;
1385
1387
  case "stopped_typing":
1386
1388
  await sendRestMessage("typing", {
1387
- orgId: fullEvent.orgId,
1389
+ orgId: fullEvent.orgId || orgId,
1388
1390
  chatKey: fullEvent.chatKey || currentChatKeyRef.current,
1389
1391
  userId: fullEvent.userId,
1390
1392
  typing: false
@@ -1392,7 +1394,7 @@ var useWebSocketChatBase = ({
1392
1394
  break;
1393
1395
  case "load_chat":
1394
1396
  const loadResponse = await sendRestMessage("load", {
1395
- orgId: fullEvent.orgId,
1397
+ orgId: fullEvent.orgId || orgId,
1396
1398
  chatKey: fullEvent.chatKey,
1397
1399
  userId: fullEvent.userId
1398
1400
  });
@@ -1414,7 +1416,7 @@ var useWebSocketChatBase = ({
1414
1416
  break;
1415
1417
  case "new_chat":
1416
1418
  const createResponse = await sendRestMessage("create", {
1417
- orgId: fullEvent.orgId,
1419
+ orgId: fullEvent.orgId || orgId,
1418
1420
  userId: fullEvent.userId,
1419
1421
  metadata: fullEvent.data
1420
1422
  });
@@ -1440,7 +1442,7 @@ var useWebSocketChatBase = ({
1440
1442
  break;
1441
1443
  case "end_chat":
1442
1444
  await sendRestMessage("end", {
1443
- orgId: fullEvent.orgId,
1445
+ orgId: fullEvent.orgId || orgId,
1444
1446
  chatKey: fullEvent.chatKey || currentChatKeyRef.current,
1445
1447
  userId: fullEvent.userId,
1446
1448
  data: fullEvent.data
@@ -1448,20 +1450,42 @@ var useWebSocketChatBase = ({
1448
1450
  break;
1449
1451
  case "human_agent_join":
1450
1452
  await sendRestMessage("agent-join", {
1451
- orgId: fullEvent.orgId,
1453
+ orgId: fullEvent.orgId || orgId,
1452
1454
  chatKey: fullEvent.chatKey || currentChatKeyRef.current,
1453
1455
  user: fullEvent.data?.user
1454
1456
  });
1455
1457
  break;
1456
1458
  case "human_agent_leave":
1457
1459
  await sendRestMessage("agent-leave", {
1458
- orgId: fullEvent.orgId,
1460
+ orgId: fullEvent.orgId || orgId,
1459
1461
  chatKey: fullEvent.chatKey || currentChatKeyRef.current,
1460
1462
  user: fullEvent.data?.user
1461
1463
  });
1462
1464
  break;
1465
+ // Event types that use the generic /event endpoint
1466
+ case "load_agent_context":
1467
+ case "skill_activate":
1468
+ case "skill_deactivate":
1469
+ case "sync_metadata":
1470
+ case "plan_approved":
1471
+ case "plan_rejected":
1472
+ await sendRestMessage("event", {
1473
+ type: fullEvent.type,
1474
+ orgId: fullEvent.orgId || orgId,
1475
+ chatKey: fullEvent.chatKey || currentChatKeyRef.current,
1476
+ userId: fullEvent.userId,
1477
+ data: fullEvent.data
1478
+ });
1479
+ break;
1463
1480
  default:
1464
- logger.warn("Unrecognized event type for SSE REST:", fullEvent.type);
1481
+ logger.warn("Sending unrecognized event type via generic endpoint:", fullEvent.type);
1482
+ await sendRestMessage("event", {
1483
+ type: fullEvent.type,
1484
+ orgId: fullEvent.orgId || orgId,
1485
+ chatKey: fullEvent.chatKey || currentChatKeyRef.current,
1486
+ userId: fullEvent.userId,
1487
+ data: fullEvent.data
1488
+ });
1465
1489
  break;
1466
1490
  }
1467
1491
  updateMetrics({ messagesSent: metrics.messagesSent + 1 });