@elqnt/chat 2.0.7 → 3.0.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 +386 -0
- package/dist/api/index.d.mts +308 -0
- package/dist/api/index.d.ts +308 -0
- package/dist/api/index.js +220 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/index.mjs +183 -0
- package/dist/api/index.mjs.map +1 -0
- package/dist/hooks/index.d.mts +78 -0
- package/dist/hooks/index.d.ts +78 -0
- package/dist/hooks/index.js +709 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +683 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/index.d.mts +4 -109
- package/dist/index.d.ts +4 -109
- package/dist/index.js +699 -3607
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +690 -3584
- package/dist/index.mjs.map +1 -1
- package/dist/models/index.d.mts +76 -6
- package/dist/models/index.d.ts +76 -6
- package/dist/models/index.js +21 -0
- package/dist/models/index.js.map +1 -1
- package/dist/models/index.mjs +14 -0
- package/dist/models/index.mjs.map +1 -1
- package/dist/transport/index.d.mts +243 -0
- package/dist/transport/index.d.ts +243 -0
- package/dist/transport/index.js +875 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/index.mjs +843 -0
- package/dist/transport/index.mjs.map +1 -0
- package/dist/types-BB5nRdZs.d.mts +222 -0
- package/dist/types-CNvuxtcv.d.ts +222 -0
- package/package.json +32 -40
- package/dist/hooks/use-websocket-chat-admin.d.mts +0 -17
- package/dist/hooks/use-websocket-chat-admin.d.ts +0 -17
- package/dist/hooks/use-websocket-chat-admin.js +0 -1196
- package/dist/hooks/use-websocket-chat-admin.js.map +0 -1
- package/dist/hooks/use-websocket-chat-admin.mjs +0 -1172
- package/dist/hooks/use-websocket-chat-admin.mjs.map +0 -1
- package/dist/hooks/use-websocket-chat-base.d.mts +0 -81
- package/dist/hooks/use-websocket-chat-base.d.ts +0 -81
- package/dist/hooks/use-websocket-chat-base.js +0 -1025
- package/dist/hooks/use-websocket-chat-base.js.map +0 -1
- package/dist/hooks/use-websocket-chat-base.mjs +0 -1001
- package/dist/hooks/use-websocket-chat-base.mjs.map +0 -1
- package/dist/hooks/use-websocket-chat-customer.d.mts +0 -24
- package/dist/hooks/use-websocket-chat-customer.d.ts +0 -24
- package/dist/hooks/use-websocket-chat-customer.js +0 -1092
- package/dist/hooks/use-websocket-chat-customer.js.map +0 -1
- package/dist/hooks/use-websocket-chat-customer.mjs +0 -1068
- package/dist/hooks/use-websocket-chat-customer.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../hooks/index.ts","../../hooks/use-chat.ts","../../transport/types.ts","../../transport/sse.ts"],"sourcesContent":["/**\n * Chat Hooks\n *\n * React hooks for chat functionality.\n *\n * @example\n * ```tsx\n * import { useChat } from \"@elqnt/chat/hooks\";\n *\n * function ChatComponent() {\n * const {\n * connect,\n * sendMessage,\n * messages,\n * isConnected,\n * } = useChat({\n * baseUrl: \"https://api.example.com/chat\",\n * orgId: \"org-123\",\n * userId: \"user-456\",\n * });\n *\n * // ...\n * }\n * ```\n */\n\nexport { useChat } from \"./use-chat\";\nexport type { UseChatOptions, UseChatReturn } from \"./use-chat\";\n","\"use client\";\n\n/**\n * useChat Hook\n *\n * A unified React hook for chat functionality with support for\n * multiple transport types (SSE, fetch-based SSE, custom transports).\n *\n * @example Basic usage\n * ```tsx\n * function ChatComponent() {\n * const {\n * connect,\n * sendMessage,\n * messages,\n * isConnected,\n * } = useChat({\n * baseUrl: \"https://api.example.com/chat\",\n * orgId: \"org-123\",\n * userId: \"user-456\",\n * });\n *\n * useEffect(() => {\n * connect();\n * return () => disconnect();\n * }, []);\n *\n * return (\n * <div>\n * {messages.map(msg => <Message key={msg.id} {...msg} />)}\n * <input onSubmit={(content) => sendMessage(content)} />\n * </div>\n * );\n * }\n * ```\n *\n * @example With custom transport\n * ```tsx\n * import { createFetchSSETransport } from \"@elqnt/chat/transport\";\n *\n * const transport = createFetchSSETransport();\n *\n * function App() {\n * const chat = useChat({\n * baseUrl: \"...\",\n * orgId: \"...\",\n * userId: \"...\",\n * transport,\n * });\n * }\n * ```\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { Chat, ChatEvent, ChatMessage } from \"../models\";\nimport type {\n ChatTransport,\n TransportState,\n TransportError,\n ConnectionMetrics,\n RetryConfig,\n Unsubscribe,\n} from \"../transport/types\";\nimport { createSSETransport } from \"../transport/sse\";\n\n/**\n * Chat hook options\n */\nexport interface UseChatOptions {\n /** Base URL for the chat server (e.g., \"https://api.example.com/chat\") */\n baseUrl: string;\n /** Organization ID */\n orgId: string;\n /** User ID */\n userId: string;\n /** Client type for routing */\n clientType?: \"customer\" | \"humanAgent\" | \"observer\";\n /** Transport instance or type */\n transport?: ChatTransport | \"sse\" | \"sse-fetch\";\n /** Callback for all incoming events */\n onMessage?: (event: ChatEvent) => void;\n /** Callback for errors */\n onError?: (error: TransportError) => void;\n /** Callback when connection state changes */\n onConnectionChange?: (state: TransportState) => void;\n /** Auto-connect on mount */\n autoConnect?: boolean;\n /** Retry configuration */\n retryConfig?: RetryConfig;\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Chat hook return type\n */\nexport interface UseChatReturn {\n // Connection\n /** Connect to the chat server */\n connect: () => Promise<void>;\n /** Disconnect from the server */\n disconnect: () => void;\n /** Current connection state */\n connectionState: TransportState;\n /** Whether currently connected */\n isConnected: boolean;\n\n // Chat operations\n /** Start a new chat session */\n startChat: (metadata?: Record<string, unknown>) => Promise<string>;\n /** Load an existing chat */\n loadChat: (chatKey: string) => Promise<void>;\n /** Send a text message */\n sendMessage: (content: string, attachments?: unknown[]) => Promise<void>;\n /** End the current chat */\n endChat: (reason?: string) => Promise<void>;\n\n // Typing indicators\n /** Signal that user is typing */\n startTyping: () => void;\n /** Signal that user stopped typing */\n stopTyping: () => void;\n\n // State\n /** Current chat object */\n currentChat: Chat | null;\n /** Current chat key */\n chatKey: string | null;\n /** Chat messages */\n messages: ChatMessage[];\n /** Current error */\n error: TransportError | null;\n /** Connection metrics */\n metrics: ConnectionMetrics;\n\n // Event subscription\n /** Subscribe to specific event type */\n on: (eventType: string, handler: (event: ChatEvent) => void) => Unsubscribe;\n /** Clear current error */\n clearError: () => void;\n}\n\n/**\n * Default transport factory\n */\nfunction getDefaultTransport(\n type: \"sse\" | \"sse-fetch\" | undefined,\n debug: boolean\n): ChatTransport {\n // For now, always use SSE. In the future, detect environment\n // and use fetch-based SSE for React Native\n return createSSETransport({ debug });\n}\n\n/**\n * useChat Hook\n *\n * Platform-agnostic chat hook with SSE transport support.\n */\nexport function useChat(options: UseChatOptions): UseChatReturn {\n const {\n baseUrl,\n orgId,\n userId,\n clientType = \"customer\",\n transport: transportOption,\n onMessage,\n onError,\n onConnectionChange,\n autoConnect = false,\n retryConfig,\n debug = false,\n } = options;\n\n // State\n const [connectionState, setConnectionState] = useState<TransportState>(\"disconnected\");\n const [currentChat, setCurrentChat] = useState<Chat | null>(null);\n const [chatKey, setChatKey] = useState<string | null>(null);\n const [messages, setMessages] = useState<ChatMessage[]>([]);\n const [error, setError] = useState<TransportError | null>(null);\n const [metrics, setMetrics] = useState<ConnectionMetrics>({\n latency: 0,\n messagesSent: 0,\n messagesReceived: 0,\n messagesQueued: 0,\n reconnectCount: 0,\n });\n\n // Refs\n const transportRef = useRef<ChatTransport | null>(null);\n const mountedRef = useRef(false);\n const onMessageRef = useRef(onMessage);\n const onErrorRef = useRef(onError);\n const chatCreationResolverRef = useRef<{\n resolve: (chatKey: string) => void;\n reject: (error: Error) => void;\n } | null>(null);\n const typingTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Update callback refs\n useEffect(() => {\n onMessageRef.current = onMessage;\n onErrorRef.current = onError;\n }, [onMessage, onError]);\n\n // Initialize transport\n useEffect(() => {\n if (typeof transportOption === \"object\") {\n transportRef.current = transportOption;\n } else {\n transportRef.current = getDefaultTransport(\n transportOption as \"sse\" | \"sse-fetch\" | undefined,\n debug\n );\n }\n }, [transportOption, debug]);\n\n // Handle incoming events\n const handleEvent = useCallback((event: ChatEvent) => {\n if (!mountedRef.current) return;\n\n // Update metrics\n setMetrics((prev) => ({\n ...prev,\n messagesReceived: prev.messagesReceived + 1,\n lastMessageAt: Date.now(),\n }));\n\n // Handle specific event types\n switch (event.type) {\n case \"new_chat_created\":\n const newChatKey = event.data?.chatKey as string;\n if (newChatKey) {\n setChatKey(newChatKey);\n if (chatCreationResolverRef.current) {\n chatCreationResolverRef.current.resolve(newChatKey);\n chatCreationResolverRef.current = null;\n }\n }\n break;\n\n case \"load_chat_response\":\n const chat = event.data?.chat as Chat;\n if (chat) {\n setCurrentChat(chat);\n setChatKey(chat.key);\n setMessages(chat.messages || []);\n }\n break;\n\n case \"message\":\n if (event.message) {\n setMessages((prev) => [...prev, event.message!]);\n }\n break;\n\n case \"chat_ended\":\n setCurrentChat(null);\n setChatKey(null);\n break;\n\n case \"error\":\n const errorMsg = event.data?.message as string;\n if (errorMsg) {\n const transportError: TransportError = {\n code: \"NETWORK_ERROR\",\n message: errorMsg,\n retryable: true,\n timestamp: Date.now(),\n };\n setError(transportError);\n onErrorRef.current?.(transportError);\n }\n break;\n }\n\n // Call user's onMessage handler\n onMessageRef.current?.(event);\n }, []);\n\n // Connect to the chat server\n const connect = useCallback(async (): Promise<void> => {\n const transport = transportRef.current;\n if (!transport) {\n throw new Error(\"Transport not initialized\");\n }\n\n if (!orgId) {\n const err: TransportError = {\n code: \"CONNECTION_FAILED\",\n message: \"orgId is required\",\n retryable: false,\n timestamp: Date.now(),\n };\n setError(err);\n throw err;\n }\n\n setConnectionState(\"connecting\");\n\n try {\n // Subscribe to events before connecting\n const unsubscribe = transport.onMessage(handleEvent);\n\n await transport.connect({\n baseUrl,\n orgId,\n userId,\n clientType,\n chatKey: chatKey || undefined,\n debug,\n });\n\n setConnectionState(\"connected\");\n setError(null);\n setMetrics(transport.getMetrics());\n onConnectionChange?.(\"connected\");\n\n // Return cleanup in case caller wants it\n return;\n } catch (err) {\n const transportError = err as TransportError;\n setConnectionState(\"disconnected\");\n setError(transportError);\n onErrorRef.current?.(transportError);\n throw err;\n }\n }, [baseUrl, orgId, userId, clientType, chatKey, debug, handleEvent, onConnectionChange]);\n\n // Disconnect from the server\n const disconnect = useCallback((): void => {\n const transport = transportRef.current;\n if (transport) {\n transport.disconnect(true);\n }\n setConnectionState(\"disconnected\");\n onConnectionChange?.(\"disconnected\");\n }, [onConnectionChange]);\n\n // Start a new chat\n const startChat = useCallback(\n async (metadata?: Record<string, unknown>): Promise<string> => {\n const transport = transportRef.current;\n if (!transport) {\n throw new Error(\"Transport not initialized\");\n }\n\n return new Promise((resolve, reject) => {\n chatCreationResolverRef.current = { resolve, reject };\n\n transport\n .send({\n type: \"new_chat\",\n orgId,\n chatKey: \"\",\n userId,\n timestamp: Date.now(),\n data: metadata,\n })\n .catch((err) => {\n chatCreationResolverRef.current = null;\n reject(err);\n });\n\n // Timeout after 30 seconds\n setTimeout(() => {\n if (chatCreationResolverRef.current) {\n chatCreationResolverRef.current = null;\n reject(new Error(\"Chat creation timed out\"));\n }\n }, 30000);\n });\n },\n [orgId, userId]\n );\n\n // Load an existing chat\n const loadChat = useCallback(\n async (key: string): Promise<void> => {\n const transport = transportRef.current;\n if (!transport) {\n throw new Error(\"Transport not initialized\");\n }\n\n setChatKey(key);\n\n await transport.send({\n type: \"load_chat\",\n orgId,\n chatKey: key,\n userId,\n timestamp: Date.now(),\n });\n },\n [orgId, userId]\n );\n\n // Send a message\n const sendMessage = useCallback(\n async (content: string, attachments?: unknown[]): Promise<void> => {\n const transport = transportRef.current;\n if (!transport) {\n throw new Error(\"Transport not initialized\");\n }\n if (!chatKey) {\n throw new Error(\"No active chat\");\n }\n\n const message: ChatMessage = {\n id: `msg_${Date.now()}_${Math.random().toString(36).slice(2)}`,\n role: \"user\",\n content,\n time: Date.now(),\n status: \"sending\",\n senderId: userId,\n createdAt: Date.now(),\n attachments: attachments as ChatMessage[\"attachments\"],\n };\n\n // Optimistically add message\n setMessages((prev) => [...prev, message]);\n\n await transport.send({\n type: \"message\",\n orgId,\n chatKey,\n userId,\n timestamp: Date.now(),\n message,\n });\n\n setMetrics((prev) => ({\n ...prev,\n messagesSent: prev.messagesSent + 1,\n }));\n },\n [orgId, chatKey, userId]\n );\n\n // End the current chat\n const endChat = useCallback(\n async (reason?: string): Promise<void> => {\n const transport = transportRef.current;\n if (!transport) {\n throw new Error(\"Transport not initialized\");\n }\n if (!chatKey) {\n return;\n }\n\n await transport.send({\n type: \"end_chat\",\n orgId,\n chatKey,\n userId,\n timestamp: Date.now(),\n data: reason ? { reason } : undefined,\n });\n\n setCurrentChat(null);\n setChatKey(null);\n },\n [orgId, chatKey, userId]\n );\n\n // Start typing indicator\n const startTyping = useCallback((): void => {\n const transport = transportRef.current;\n if (!transport || !chatKey) return;\n\n // Clear existing timeout\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n }\n\n transport\n .send({\n type: \"typing\",\n orgId,\n chatKey,\n userId,\n timestamp: Date.now(),\n })\n .catch(() => {});\n\n // Auto-stop typing after 3 seconds\n typingTimeoutRef.current = setTimeout(() => {\n stopTyping();\n }, 3000);\n }, [orgId, chatKey, userId]);\n\n // Stop typing indicator\n const stopTyping = useCallback((): void => {\n const transport = transportRef.current;\n if (!transport || !chatKey) return;\n\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n typingTimeoutRef.current = null;\n }\n\n transport\n .send({\n type: \"stopped_typing\",\n orgId,\n chatKey,\n userId,\n timestamp: Date.now(),\n })\n .catch(() => {});\n }, [orgId, chatKey, userId]);\n\n // Subscribe to specific event type\n const on = useCallback(\n (eventType: string, handler: (event: ChatEvent) => void): Unsubscribe => {\n const transport = transportRef.current;\n if (!transport) {\n return () => {};\n }\n return transport.on(eventType, handler);\n },\n []\n );\n\n // Clear error\n const clearError = useCallback((): void => {\n setError(null);\n transportRef.current?.clearError();\n }, []);\n\n // Mount/unmount lifecycle\n useEffect(() => {\n mountedRef.current = true;\n\n if (autoConnect) {\n connect().catch(() => {});\n }\n\n return () => {\n mountedRef.current = false;\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n }\n disconnect();\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Computed state\n const isConnected = connectionState === \"connected\";\n\n return {\n // Connection\n connect,\n disconnect,\n connectionState,\n isConnected,\n\n // Chat operations\n startChat,\n loadChat,\n sendMessage,\n endChat,\n\n // Typing\n startTyping,\n stopTyping,\n\n // State\n currentChat,\n chatKey,\n messages,\n error,\n metrics,\n\n // Events\n on,\n clearError,\n };\n}\n","/**\n * Transport Abstraction Layer Types\n *\n * Platform-agnostic transport interfaces for chat communication.\n * Supports browser SSE, React Native fetch-based SSE, and extensible\n * transports like WhatsApp Business API.\n */\n\nimport type { ChatEvent, ChatMessage } from \"../models\";\n\n/**\n * Transport connection state\n */\nexport type TransportState =\n | \"disconnected\"\n | \"connecting\"\n | \"connected\"\n | \"reconnecting\";\n\n/**\n * Transport error with retry information\n */\nexport interface TransportError {\n code:\n | \"CONNECTION_FAILED\"\n | \"PARSE_ERROR\"\n | \"SEND_FAILED\"\n | \"TIMEOUT\"\n | \"NETWORK_ERROR\"\n | \"AUTH_FAILED\";\n message: string;\n retryable: boolean;\n timestamp: number;\n originalError?: unknown;\n}\n\n/**\n * Configuration for transport connection\n */\nexport interface TransportConfig {\n /** Base URL for the chat server */\n baseUrl: string;\n /** Organization ID */\n orgId: string;\n /** User ID for authentication */\n userId: string;\n /** Client type for routing */\n clientType: \"customer\" | \"humanAgent\" | \"observer\";\n /** Optional current chat key for reconnection */\n chatKey?: string;\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Retry configuration for connection attempts\n */\nexport interface RetryConfig {\n /** Maximum number of retry attempts */\n maxRetries?: number;\n /** Initial retry intervals in milliseconds */\n intervals?: number[];\n /** Multiplier for exponential backoff */\n backoffMultiplier?: number;\n /** Maximum backoff time in milliseconds */\n maxBackoffTime?: number;\n}\n\n/**\n * Connection metrics for monitoring\n */\nexport interface ConnectionMetrics {\n /** Round-trip latency in milliseconds */\n latency: number;\n /** Total messages sent */\n messagesSent: number;\n /** Total messages received */\n messagesReceived: number;\n /** Messages waiting to be sent */\n messagesQueued: number;\n /** Number of reconnection attempts */\n reconnectCount: number;\n /** Last error encountered */\n lastError?: TransportError;\n /** Timestamp when connection was established */\n connectedAt?: number;\n /** Timestamp of last message */\n lastMessageAt?: number;\n /** Current transport type */\n transportType?: string;\n}\n\n/**\n * Event handler function type\n */\nexport type EventHandler<T = ChatEvent> = (event: T) => void;\n\n/**\n * Unsubscribe function returned by event subscription\n */\nexport type Unsubscribe = () => void;\n\n/**\n * Send message options\n */\nexport interface SendMessageOptions {\n /** Message content */\n content: string;\n /** Optional attachments */\n attachments?: unknown[];\n /** Optional message metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Create chat options\n */\nexport interface CreateChatOptions {\n /** Organization ID */\n orgId: string;\n /** User ID */\n userId: string;\n /** Optional chat metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Load chat options\n */\nexport interface LoadChatOptions {\n /** Organization ID */\n orgId: string;\n /** Chat key to load */\n chatKey: string;\n /** User ID */\n userId: string;\n}\n\n/**\n * End chat options\n */\nexport interface EndChatOptions {\n /** Organization ID */\n orgId: string;\n /** Chat key to end */\n chatKey: string;\n /** User ID */\n userId: string;\n /** Optional end reason */\n reason?: string;\n}\n\n/**\n * Core transport interface\n *\n * Implementations must handle:\n * - Connection lifecycle (connect, disconnect, reconnect)\n * - Message sending (POST requests)\n * - Event receiving (SSE stream)\n * - Error handling and recovery\n */\nexport interface ChatTransport {\n /**\n * Connect to the chat server\n * @param config - Transport configuration\n * @returns Promise that resolves when connected\n */\n connect(config: TransportConfig): Promise<void>;\n\n /**\n * Disconnect from the server\n * @param intentional - Whether disconnect was user-initiated\n */\n disconnect(intentional?: boolean): void;\n\n /**\n * Send a chat event to the server\n * @param event - Chat event to send\n */\n send(event: ChatEvent): Promise<void>;\n\n /**\n * Send a message in the current chat\n * @param message - Message to send\n */\n sendMessage(message: ChatMessage): Promise<void>;\n\n /**\n * Subscribe to incoming events\n * @param handler - Event handler function\n * @returns Unsubscribe function\n */\n onMessage(handler: EventHandler): Unsubscribe;\n\n /**\n * Subscribe to specific event type\n * @param eventType - Type of event to listen for\n * @param handler - Event handler function\n * @returns Unsubscribe function\n */\n on(eventType: string, handler: EventHandler): Unsubscribe;\n\n /**\n * Get current connection state\n */\n getState(): TransportState;\n\n /**\n * Get connection metrics\n */\n getMetrics(): ConnectionMetrics;\n\n /**\n * Get last error\n */\n getError(): TransportError | undefined;\n\n /**\n * Clear error state\n */\n clearError(): void;\n}\n\n/**\n * Transport factory function type\n */\nexport type TransportFactory = (config?: Partial<TransportConfig>) => ChatTransport;\n\n/**\n * Logger interface for transport debugging\n */\nexport interface TransportLogger {\n debug: (message: string, ...args: unknown[]) => void;\n info: (message: string, ...args: unknown[]) => void;\n warn: (message: string, ...args: unknown[]) => void;\n error: (message: string, ...args: unknown[]) => void;\n}\n\n/**\n * Create a default logger\n * @param debug - Enable debug logging\n */\nexport function createLogger(debug: boolean = false): TransportLogger {\n return {\n debug: debug ? console.log.bind(console, \"[chat]\") : () => {},\n info: console.info.bind(console, \"[chat]\"),\n warn: console.warn.bind(console, \"[chat]\"),\n error: console.error.bind(console, \"[chat]\"),\n };\n}\n\n/**\n * Default retry configuration\n */\nexport const DEFAULT_RETRY_CONFIG: Required<RetryConfig> = {\n maxRetries: 10,\n intervals: [1000, 2000, 5000],\n backoffMultiplier: 1.5,\n maxBackoffTime: 30000,\n};\n\n/**\n * Calculate retry interval with exponential backoff\n * @param retryCount - Current retry attempt number\n * @param config - Retry configuration\n */\nexport function calculateRetryInterval(\n retryCount: number,\n config: RetryConfig = DEFAULT_RETRY_CONFIG\n): number {\n const {\n intervals = DEFAULT_RETRY_CONFIG.intervals,\n backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,\n maxBackoffTime = DEFAULT_RETRY_CONFIG.maxBackoffTime,\n } = config;\n\n if (retryCount < intervals.length) {\n return intervals[retryCount];\n }\n\n const baseInterval = intervals[intervals.length - 1] || 5000;\n const backoffTime =\n baseInterval * Math.pow(backoffMultiplier, retryCount - intervals.length + 1);\n return Math.min(backoffTime, maxBackoffTime);\n}\n","/**\n * SSE Transport (Browser)\n *\n * Uses native EventSource for receiving server events and fetch POST for sending.\n * This is the default transport for browser environments.\n *\n * @example\n * ```typescript\n * import { createSSETransport } from \"@elqnt/chat/transport\";\n *\n * const transport = createSSETransport();\n * await transport.connect({ baseUrl, orgId, userId, clientType: \"customer\" });\n * ```\n */\n\nimport type { ChatEvent, ChatMessage } from \"../models\";\nimport type {\n ChatTransport,\n TransportConfig,\n TransportState,\n TransportError,\n ConnectionMetrics,\n EventHandler,\n Unsubscribe,\n RetryConfig,\n TransportLogger,\n} from \"./types\";\nimport { createLogger, calculateRetryInterval, DEFAULT_RETRY_CONFIG } from \"./types\";\n\n/**\n * SSE Transport options\n */\nexport interface SSETransportOptions {\n /** Retry configuration */\n retryConfig?: RetryConfig;\n /** Enable debug logging */\n debug?: boolean;\n /** Custom logger */\n logger?: TransportLogger;\n}\n\n/**\n * Create an SSE transport for browser environments\n */\nexport function createSSETransport(options: SSETransportOptions = {}): ChatTransport {\n const {\n retryConfig = DEFAULT_RETRY_CONFIG,\n debug = false,\n logger = createLogger(debug),\n } = options;\n\n // Internal state\n let eventSource: EventSource | undefined;\n let config: TransportConfig | undefined;\n let state: TransportState = \"disconnected\";\n let error: TransportError | undefined;\n let retryCount = 0;\n let reconnectTimeout: ReturnType<typeof setTimeout> | undefined;\n let intentionalDisconnect = false;\n\n // Metrics\n const metrics: ConnectionMetrics = {\n latency: 0,\n messagesSent: 0,\n messagesReceived: 0,\n messagesQueued: 0,\n reconnectCount: 0,\n transportType: \"sse\",\n };\n\n // Event handlers\n const globalHandlers = new Set<EventHandler>();\n const typeHandlers = new Map<string, Set<EventHandler>>();\n\n // Helper to emit events\n function emit(event: ChatEvent): void {\n // Update metrics\n metrics.messagesReceived++;\n metrics.lastMessageAt = Date.now();\n\n // Call global handlers\n globalHandlers.forEach((handler) => {\n try {\n handler(event);\n } catch (err) {\n logger.error(\"Error in message handler:\", err);\n }\n });\n\n // Call type-specific handlers\n const handlers = typeHandlers.get(event.type);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(event);\n } catch (err) {\n logger.error(`Error in ${event.type} handler:`, err);\n }\n });\n }\n }\n\n // REST API helper\n async function sendRest(endpoint: string, body: Record<string, unknown>): Promise<unknown> {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n const url = `${config.baseUrl}/${endpoint}`;\n logger.debug(`POST ${endpoint}`, body);\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`API error: ${response.status} - ${errorText}`);\n }\n\n return response.json();\n }\n\n // Handle SSE message\n function handleMessage(event: MessageEvent): void {\n if (!event.data || event.data === \"\") return;\n\n try {\n const data = JSON.parse(event.data) as ChatEvent;\n logger.debug(\"Received:\", data.type);\n emit(data);\n } catch (err) {\n logger.error(\"Failed to parse SSE message:\", err);\n }\n }\n\n // Setup SSE event listeners\n function setupEventListeners(es: EventSource): void {\n // Generic message handler\n es.addEventListener(\"message\", handleMessage);\n\n // Add handlers for known event types\n const eventTypes = [\n \"reconnected\", \"typing\", \"stopped_typing\", \"waiting\",\n \"waiting_for_agent\", \"human_agent_joined\", \"human_agent_left\",\n \"chat_ended\", \"chat_updated\", \"load_chat_response\",\n \"new_chat_created\", \"show_csat_survey\", \"csat_response\",\n \"user_suggested_actions\", \"agent_execution_started\",\n \"agent_execution_ended\", \"agent_context_update\",\n \"plan_pending_approval\", \"step_started\", \"step_completed\",\n \"step_failed\", \"plan_completed\", \"skills_changed\", \"summary_update\",\n ];\n\n eventTypes.forEach((type) => {\n es.addEventListener(type, handleMessage);\n });\n }\n\n // Schedule reconnect\n function scheduleReconnect(): void {\n if (intentionalDisconnect || !config) return;\n\n const maxRetries = retryConfig.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries;\n if (retryCount >= maxRetries) {\n logger.error(`Max retries (${maxRetries}) exceeded`);\n error = {\n code: \"CONNECTION_FAILED\",\n message: `Max retries (${maxRetries}) exceeded`,\n retryable: false,\n timestamp: Date.now(),\n };\n return;\n }\n\n const interval = calculateRetryInterval(retryCount, retryConfig);\n retryCount++;\n metrics.reconnectCount++;\n\n logger.info(`Reconnecting in ${interval}ms (attempt ${retryCount})`);\n state = \"reconnecting\";\n\n reconnectTimeout = setTimeout(() => {\n if (config) {\n transport.connect(config).catch((err) => {\n logger.error(\"Reconnect failed:\", err);\n });\n }\n }, interval);\n }\n\n const transport: ChatTransport = {\n async connect(cfg: TransportConfig): Promise<void> {\n config = cfg;\n intentionalDisconnect = false;\n\n // Clean up existing connection\n if (eventSource) {\n eventSource.close();\n eventSource = undefined;\n }\n if (reconnectTimeout) {\n clearTimeout(reconnectTimeout);\n reconnectTimeout = undefined;\n }\n\n state = retryCount > 0 ? \"reconnecting\" : \"connecting\";\n\n return new Promise((resolve, reject) => {\n const connectionStart = Date.now();\n const url = `${cfg.baseUrl}/stream?orgId=${cfg.orgId}&userId=${cfg.userId}&clientType=${cfg.clientType}${cfg.chatKey ? `&chatId=${cfg.chatKey}` : \"\"}`;\n\n logger.debug(\"Connecting to:\", url);\n const es = new EventSource(url);\n\n es.onopen = () => {\n const connectionTime = Date.now() - connectionStart;\n logger.info(`Connected in ${connectionTime}ms`);\n\n state = \"connected\";\n error = undefined;\n retryCount = 0;\n metrics.connectedAt = Date.now();\n metrics.latency = connectionTime;\n\n setupEventListeners(es);\n resolve();\n };\n\n es.onerror = () => {\n if (es.readyState === EventSource.CLOSED) {\n const sseError: TransportError = {\n code: \"CONNECTION_FAILED\",\n message: \"SSE connection failed\",\n retryable: true,\n timestamp: Date.now(),\n };\n error = sseError;\n metrics.lastError = sseError;\n state = \"disconnected\";\n\n if (!intentionalDisconnect) {\n scheduleReconnect();\n }\n\n // Only reject if this is the initial connection attempt\n if (retryCount === 0) {\n reject(sseError);\n }\n }\n };\n\n eventSource = es;\n });\n },\n\n disconnect(intentional = true): void {\n logger.info(\"Disconnecting\", { intentional });\n intentionalDisconnect = intentional;\n\n if (reconnectTimeout) {\n clearTimeout(reconnectTimeout);\n reconnectTimeout = undefined;\n }\n\n if (eventSource) {\n eventSource.close();\n eventSource = undefined;\n }\n\n state = \"disconnected\";\n retryCount = 0;\n },\n\n async send(event: ChatEvent): Promise<void> {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n // Map event types to REST endpoints\n switch (event.type) {\n case \"message\":\n await sendRest(\"send\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n message: event.message,\n });\n break;\n\n case \"typing\":\n await sendRest(\"typing\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n typing: true,\n });\n break;\n\n case \"stopped_typing\":\n await sendRest(\"typing\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n typing: false,\n });\n break;\n\n case \"load_chat\":\n await sendRest(\"load\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n });\n break;\n\n case \"new_chat\":\n await sendRest(\"create\", {\n orgId: event.orgId,\n userId: event.userId,\n metadata: event.data,\n });\n break;\n\n case \"end_chat\":\n await sendRest(\"end\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n data: event.data,\n });\n break;\n\n default:\n // Generic event endpoint for other types\n await sendRest(\"event\", {\n type: event.type,\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n data: event.data,\n });\n }\n\n metrics.messagesSent++;\n },\n\n async sendMessage(message: ChatMessage): Promise<void> {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n await sendRest(\"send\", {\n orgId: config.orgId,\n chatKey: config.chatKey,\n userId: config.userId,\n message,\n });\n\n metrics.messagesSent++;\n },\n\n onMessage(handler: EventHandler): Unsubscribe {\n globalHandlers.add(handler);\n return () => globalHandlers.delete(handler);\n },\n\n on(eventType: string, handler: EventHandler): Unsubscribe {\n if (!typeHandlers.has(eventType)) {\n typeHandlers.set(eventType, new Set());\n }\n typeHandlers.get(eventType)!.add(handler);\n return () => {\n const handlers = typeHandlers.get(eventType);\n if (handlers) {\n handlers.delete(handler);\n if (handlers.size === 0) {\n typeHandlers.delete(eventType);\n }\n }\n };\n },\n\n getState(): TransportState {\n return state;\n },\n\n getMetrics(): ConnectionMetrics {\n return { ...metrics };\n },\n\n getError(): TransportError | undefined {\n return error;\n },\n\n clearError(): void {\n error = undefined;\n },\n };\n\n return transport;\n}\n"],"mappings":"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","names":[]}
|