@elevenlabs/react-native 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +200 -0
  3. package/dist/ElevenLabsProvider.d.ts +22 -0
  4. package/dist/ElevenLabsProvider.test.d.ts +1 -0
  5. package/dist/components/LiveKitRoomWrapper.d.ts +20 -0
  6. package/dist/components/MessageHandler.d.ts +12 -0
  7. package/dist/hooks/useConversationCallbacks.d.ts +5 -0
  8. package/dist/hooks/useConversationSession.d.ts +28 -0
  9. package/dist/hooks/useLiveKitRoom.d.ts +12 -0
  10. package/dist/hooks/useMessageSending.d.ts +7 -0
  11. package/dist/index.d.ts +2 -0
  12. package/dist/lib.js +2 -0
  13. package/dist/lib.js.map +1 -0
  14. package/dist/lib.modern.js +2 -0
  15. package/dist/lib.modern.js.map +1 -0
  16. package/dist/lib.module.js +2 -0
  17. package/dist/lib.module.js.map +1 -0
  18. package/dist/lib.umd.js +2 -0
  19. package/dist/lib.umd.js.map +1 -0
  20. package/dist/types.d.ts +109 -0
  21. package/dist/utils/constants.d.ts +1 -0
  22. package/dist/utils/overrides.d.ts +2 -0
  23. package/dist/utils/tokenUtils.d.ts +2 -0
  24. package/dist/version.d.ts +1 -0
  25. package/eslint.config.cjs +1 -0
  26. package/jest.config.cjs +263 -0
  27. package/jest.rn-mock.js +15 -0
  28. package/package.json +64 -0
  29. package/src/ElevenLabsProvider.test.tsx +187 -0
  30. package/src/ElevenLabsProvider.tsx +259 -0
  31. package/src/components/LiveKitRoomWrapper.tsx +63 -0
  32. package/src/components/MessageHandler.tsx +127 -0
  33. package/src/hooks/useConversationCallbacks.ts +15 -0
  34. package/src/hooks/useConversationSession.ts +88 -0
  35. package/src/hooks/useLiveKitRoom.ts +62 -0
  36. package/src/hooks/useMessageSending.ts +33 -0
  37. package/src/index.ts +9 -0
  38. package/src/types.ts +150 -0
  39. package/src/utils/constants.ts +1 -0
  40. package/src/utils/overrides.ts +40 -0
  41. package/src/utils/tokenUtils.ts +31 -0
  42. package/src/version.ts +2 -0
  43. package/tsconfig.json +18 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.module.js","sources":["../src/version.ts","../src/components/MessageHandler.tsx","../src/components/LiveKitRoomWrapper.tsx","../src/ElevenLabsProvider.tsx","../src/utils/constants.ts","../src/hooks/useConversationCallbacks.ts","../src/hooks/useConversationSession.ts","../src/utils/tokenUtils.ts","../src/hooks/useLiveKitRoom.ts","../src/hooks/useMessageSending.ts","../src/utils/overrides.ts"],"sourcesContent":["// This file is auto-generated during build\nexport const PACKAGE_VERSION = \"0.1.0\";\n","import { useEffect } from 'react';\nimport { useLocalParticipant, useDataChannel } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ClientToolsConfig, ClientToolCallEvent } from '../types';\nimport React from 'react';\n\ninterface MessageHandlerProps {\n onReady: (participant: LocalParticipant) => void;\n isConnected: boolean;\n callbacks: Callbacks;\n sendMessage: (message: unknown) => void;\n clientTools?: ClientToolsConfig['clientTools'];\n updateCurrentEventId?: (eventId: number) => void;\n}\n\nexport const MessageHandler = ({\n onReady,\n isConnected,\n callbacks,\n sendMessage,\n clientTools = {},\n updateCurrentEventId\n}: MessageHandlerProps) => {\n const { localParticipant } = useLocalParticipant();\n\n // Track agent response count for synthetic event IDs (WebRTC mode)\n const agentResponseCountRef = React.useRef(1);\n\n useEffect(() => {\n if (isConnected && localParticipant) {\n onReady(localParticipant);\n }\n }, [isConnected, localParticipant, onReady]);\n\n const handleClientToolCall = async (clientToolCall: ClientToolCallEvent) => {\n if (\n Object.prototype.hasOwnProperty.call(\n clientTools,\n clientToolCall.tool_name\n )\n ) {\n try {\n const result =\n (await clientTools[clientToolCall.tool_name](\n clientToolCall.parameters\n )) ?? \"Client tool execution successful.\"; // default client-tool call response\n\n // The API expects result to be a string, so we need to convert it if it's not already a string\n const formattedResult =\n typeof result === \"object\" ? JSON.stringify(result) : String(result);\n\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.tool_call_id,\n result: formattedResult,\n is_error: false,\n });\n } catch (e) {\n const errorMessage = `Client tool execution failed with following error: ${(e as Error)?.message}`;\n callbacks.onError?.(errorMessage, {\n clientToolName: clientToolCall.tool_name,\n });\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.tool_call_id,\n result: `Client tool execution failed: ${(e as Error)?.message}`,\n is_error: true,\n });\n }\n } else {\n if (callbacks.onUnhandledClientToolCall) {\n callbacks.onUnhandledClientToolCall(clientToolCall);\n return;\n }\n\n const errorMessage = `Client tool with name ${clientToolCall.tool_name} is not defined on client`;\n callbacks.onError?.(errorMessage, {\n clientToolName: clientToolCall.tool_name,\n });\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.tool_call_id,\n result: errorMessage,\n is_error: true,\n });\n }\n };\n\n const _ = useDataChannel((msg) => {\n const decoder = new TextDecoder();\n const message = JSON.parse(decoder.decode(msg.payload));\n\n callbacks.onMessage?.({\n message,\n source: msg.from?.isAgent ? 'ai' : 'user',\n });\n\n if (msg.from?.isAgent) {\n callbacks.onModeChange?.({\n mode: msg.from?.isSpeaking ? 'speaking' : 'listening'\n });\n\n // Track agent responses for feedback (WebRTC mode needs synthetic event IDs)\n if (message.type === \"agent_response\" && updateCurrentEventId) {\n const eventId = agentResponseCountRef.current++;\n updateCurrentEventId(eventId);\n }\n }\n\n switch (message.type) {\n case \"ping\":\n sendMessage({\n type: \"pong\",\n event_id: message.ping_event.event_id,\n });\n break;\n case \"client_tool_call\":\n handleClientToolCall(message.client_tool_call);\n break;\n default:\n callbacks.onDebug?.(message);\n break;\n }\n });\n\n return null;\n};","import React from 'react';\nimport { LiveKitRoom } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ClientToolsConfig } from '../types';\nimport { MessageHandler } from './MessageHandler';\n\ninterface LiveKitRoomWrapperProps {\n children: React.ReactNode;\n serverUrl: string;\n token: string;\n connect: boolean;\n onConnected: () => void;\n onDisconnected: () => void;\n onError: (error: Error) => void;\n roomConnected: boolean;\n callbacks: Callbacks;\n onParticipantReady: (participant: LocalParticipant) => void;\n sendMessage: (message: unknown) => void;\n clientTools: ClientToolsConfig['clientTools'];\n updateCurrentEventId?: (eventId: number) => void;\n}\n\nexport const LiveKitRoomWrapper = ({\n children,\n serverUrl,\n token,\n connect,\n onConnected,\n onDisconnected,\n onError,\n roomConnected,\n callbacks,\n onParticipantReady,\n sendMessage,\n clientTools,\n updateCurrentEventId,\n}: LiveKitRoomWrapperProps) => {\n return (\n <LiveKitRoom\n serverUrl={serverUrl}\n token={token}\n connect={connect}\n audio={true}\n video={false}\n options={{\n adaptiveStream: { pixelDensity: 'screen' },\n }}\n onConnected={onConnected}\n onDisconnected={onDisconnected}\n onError={onError}\n >\n <MessageHandler\n onReady={onParticipantReady}\n isConnected={roomConnected}\n callbacks={callbacks}\n sendMessage={sendMessage}\n clientTools={clientTools}\n updateCurrentEventId={updateCurrentEventId}\n />\n {children}\n </LiveKitRoom>\n );\n};","import React from 'react';\nimport { createContext, useContext, useState } from 'react';\nimport { registerGlobals } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ConversationConfig, ConversationStatus, ClientToolsConfig } from './types';\nimport { constructOverrides } from './utils/overrides';\nimport { DEFAULT_SERVER_URL } from './utils/constants';\nimport { useConversationCallbacks } from './hooks/useConversationCallbacks';\nimport { useConversationSession } from './hooks/useConversationSession';\nimport { useLiveKitRoom } from './hooks/useLiveKitRoom';\nimport { useMessageSending } from './hooks/useMessageSending';\nimport { LiveKitRoomWrapper } from './components/LiveKitRoomWrapper';\n\ninterface ConversationOptions extends Callbacks, Partial<ClientToolsConfig> {\n serverUrl?: string;\n}\n\ninterface Conversation {\n startSession: (config: ConversationConfig) => Promise<void>;\n endSession: () => Promise<void>;\n status: ConversationStatus;\n isSpeaking: boolean;\n // TODO: Implement setVolume when LiveKit React Native supports it\n // setVolume: (volume: number) => void;\n canSendFeedback: boolean;\n sendFeedback: (like: boolean) => void;\n sendContextualUpdate: (text: string) => void;\n sendUserMessage: (text: string) => void;\n sendUserActivity: () => void;\n}\n\ninterface ElevenLabsContextType {\n conversation: Conversation;\n callbacksRef: { current: Callbacks };\n serverUrl: string;\n clientTools: ClientToolsConfig['clientTools'];\n setCallbacks: (callbacks: Callbacks) => void;\n setServerUrl: (url: string) => void;\n setClientTools: (tools: ClientToolsConfig['clientTools']) => void;\n}\n\nconst ElevenLabsContext = createContext<ElevenLabsContextType | null>(null);\n\nexport const useConversation = (options: ConversationOptions = {}): Conversation => {\n const context = useContext(ElevenLabsContext);\n if (!context) {\n throw new Error('useConversation must be used within ElevenLabsProvider');\n }\n\n const { serverUrl, clientTools, ...callbacks } = options;\n\n React.useEffect(() => {\n if (serverUrl) {\n context.setServerUrl(serverUrl);\n }\n }, [context, serverUrl]);\n\n if (clientTools) {\n context.setClientTools(clientTools);\n }\n\n context.setCallbacks(callbacks);\n\n return context.conversation;\n};\n\ninterface ElevenLabsProviderProps {\n children: React.ReactNode;\n}\n\nexport const ElevenLabsProvider: React.FC<ElevenLabsProviderProps> = ({ children }) => {\n // Initialize globals on mount\n registerGlobals();\n\n // State management\n const [token, setToken] = useState('');\n const [connect, setConnect] = useState(false);\n const [status, setStatus] = useState<ConversationStatus>('disconnected');\n const [serverUrl, setServerUrl] = useState(DEFAULT_SERVER_URL);\n const [roomId, setRoomId] = useState<string>('');\n const [isSpeaking, setIsSpeaking] = useState(false);\n const [canSendFeedback, setCanSendFeedback] = useState(false);\n\n // Feedback state tracking\n const currentEventIdRef = React.useRef(1);\n const lastFeedbackEventIdRef = React.useRef(1);\n\n // Use ref for clientTools to avoid re-renders (like callbacks)\n const clientToolsRef = React.useRef<ClientToolsConfig['clientTools']>({});\n\n // Custom hooks\n const { callbacksRef, setCallbacks: setCallbacksBase } = useConversationCallbacks();\n\n // Enhanced setCallbacks that wraps onModeChange to update isSpeaking state\n const setCallbacks = React.useCallback((callbacks: Callbacks) => {\n const wrappedCallbacks = {\n ...callbacks,\n onModeChange: (event: { mode: 'speaking' | 'listening' }) => {\n setIsSpeaking(event.mode === 'speaking');\n callbacks.onModeChange?.(event);\n }\n };\n setCallbacksBase(wrappedCallbacks);\n }, [setCallbacksBase]);\n\n const {\n startSession,\n endSession,\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n } = useConversationSession(callbacksRef, setStatus, setConnect, setToken, setRoomId);\n\n const {\n roomConnected,\n localParticipant,\n handleParticipantReady,\n handleConnected,\n handleDisconnected,\n handleError,\n } = useLiveKitRoom(callbacksRef, setStatus, roomId);\n\n // Enhanced connection handler to initialize feedback state\n const handleConnectedWithFeedback = React.useCallback(() => {\n // Reset feedback state when connecting\n currentEventIdRef.current = 1;\n lastFeedbackEventIdRef.current = 1;\n setCanSendFeedback(false);\n callbacksRef.current.onCanSendFeedbackChange?.({ canSendFeedback: false });\n\n handleConnected();\n }, [handleConnected, callbacksRef]);\n\n // Enhanced disconnection handler to reset feedback state\n const handleDisconnectedWithFeedback = React.useCallback(() => {\n setCanSendFeedback(false);\n handleDisconnected();\n }, [handleDisconnected]);\n\n const { sendMessage } = useMessageSending(status, localParticipant, callbacksRef);\n\n const updateCanSendFeedback = React.useCallback(() => {\n const newCanSendFeedback = currentEventIdRef.current !== lastFeedbackEventIdRef.current;\n\n if (canSendFeedback !== newCanSendFeedback) {\n setCanSendFeedback(newCanSendFeedback);\n callbacksRef.current.onCanSendFeedbackChange?.({ canSendFeedback: newCanSendFeedback });\n }\n }, [canSendFeedback, callbacksRef]);\n\n const sendFeedback = React.useCallback((like: boolean) => {\n if (!canSendFeedback) {\n console.warn(\n lastFeedbackEventIdRef.current === 0\n ? \"Cannot send feedback: the conversation has not started yet.\"\n : \"Cannot send feedback: feedback has already been sent for the current response.\"\n );\n return;\n }\n\n const feedbackMessage = {\n type: \"feedback\",\n score: like ? \"like\" : \"dislike\",\n event_id: currentEventIdRef.current,\n };\n\n sendMessage(feedbackMessage);\n lastFeedbackEventIdRef.current = currentEventIdRef.current;\n updateCanSendFeedback();\n }, [canSendFeedback, sendMessage, updateCanSendFeedback]);\n\n // setVolume placeholder (to be implemented when LiveKit supports it)\n const setVolume = React.useCallback((volume: number) => {\n console.warn('setVolume is not yet implemented in React Native SDK');\n }, []);\n\n // Update current event ID for feedback tracking\n const updateCurrentEventId = React.useCallback((eventId: number) => {\n currentEventIdRef.current = eventId;\n updateCanSendFeedback();\n }, [updateCanSendFeedback]);\n\n // Handle participant ready with overrides\n const handleParticipantReadyWithOverrides = React.useCallback((participant: LocalParticipant) => {\n handleParticipantReady(participant);\n\n if (localParticipant) {\n const overridesEvent = constructOverrides({\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n });\n sendMessage(overridesEvent);\n }\n }, [handleParticipantReady, localParticipant, overrides, customLlmExtraBody, dynamicVariables, sendMessage]);\n\n const conversation: Conversation = {\n startSession,\n endSession,\n status,\n isSpeaking,\n // setVolume,\n canSendFeedback,\n sendFeedback,\n sendContextualUpdate: (text: string) => {\n sendMessage({\n type: \"contextual_update\",\n text,\n });\n },\n sendUserMessage: (text: string) => {\n sendMessage({\n type: \"user_message\",\n text,\n });\n },\n sendUserActivity: () => {\n sendMessage({\n type: \"user_activity\",\n });\n },\n };\n\n // Create setClientTools function that only updates ref\n const setClientTools = React.useCallback((tools: ClientToolsConfig['clientTools']) => {\n clientToolsRef.current = tools;\n }, []);\n\n const contextValue: ElevenLabsContextType = {\n conversation,\n callbacksRef,\n serverUrl,\n clientTools: clientToolsRef.current,\n setCallbacks,\n setServerUrl,\n setClientTools,\n };\n\n return (\n <ElevenLabsContext.Provider value={contextValue}>\n <LiveKitRoomWrapper\n serverUrl={serverUrl}\n token={token}\n connect={connect}\n onConnected={handleConnectedWithFeedback}\n onDisconnected={handleDisconnectedWithFeedback}\n onError={handleError}\n roomConnected={roomConnected}\n callbacks={callbacksRef.current}\n onParticipantReady={handleParticipantReadyWithOverrides}\n sendMessage={sendMessage}\n clientTools={clientToolsRef.current}\n updateCurrentEventId={updateCurrentEventId}\n >\n {children}\n </LiveKitRoomWrapper>\n </ElevenLabsContext.Provider>\n );\n};","export const DEFAULT_SERVER_URL = \"wss://livekit.rtc.elevenlabs.io\";\n","import { useRef, useCallback } from \"react\";\nimport type { Callbacks } from \"../types\";\n\nexport const useConversationCallbacks = () => {\n const callbacksRef = useRef<Callbacks>({});\n\n const setCallbacks = useCallback((callbacks: Callbacks) => {\n callbacksRef.current = callbacks;\n }, []);\n\n return {\n callbacksRef,\n setCallbacks,\n };\n};\n","import { useState, useCallback } from \"react\";\nimport type {\n ConversationConfig,\n ConversationStatus,\n Callbacks,\n} from \"../types\";\nimport {\n getConversationToken,\n extractRoomIdFromToken,\n} from \"../utils/tokenUtils\";\n\nexport const useConversationSession = (\n callbacksRef: { current: Callbacks },\n setStatus: (status: ConversationStatus) => void,\n setConnect: (connect: boolean) => void,\n setToken: (token: string) => void,\n setRoomId: (roomId: string) => void\n) => {\n const [overrides, setOverrides] = useState<ConversationConfig[\"overrides\"]>(\n {}\n );\n const [customLlmExtraBody, setCustomLlmExtraBody] =\n useState<ConversationConfig[\"customLlmExtraBody\"]>(null);\n const [dynamicVariables, setDynamicVariables] = useState<\n ConversationConfig[\"dynamicVariables\"]\n >({});\n\n const startSession = useCallback(\n async (config: ConversationConfig) => {\n try {\n setStatus(\"connecting\");\n callbacksRef.current.onStatusChange?.({ status: \"connecting\" });\n\n setOverrides(config.overrides || {});\n setCustomLlmExtraBody(config.customLlmExtraBody || null);\n setDynamicVariables(config.dynamicVariables || {});\n\n let conversationToken: string;\n\n if (config.conversationToken) {\n conversationToken = config.conversationToken;\n } else if (config.agentId) {\n console.info(\n \"Getting conversation token for agentId:\",\n config.agentId\n );\n conversationToken = await getConversationToken(config.agentId);\n } else {\n throw new Error(\"Either conversationToken or agentId is required\");\n }\n\n // Extract room ID from token\n const extractedRoomId = extractRoomIdFromToken(conversationToken);\n setRoomId(extractedRoomId);\n\n setToken(conversationToken);\n setConnect(true);\n } catch (error) {\n setStatus(\"disconnected\");\n callbacksRef.current.onStatusChange?.({ status: \"disconnected\" });\n callbacksRef.current.onError?.(error as string);\n throw error;\n }\n },\n [callbacksRef, setStatus, setConnect, setToken, setRoomId]\n );\n\n const endSession = useCallback(async () => {\n try {\n setConnect(false);\n setToken(\"\");\n setStatus(\"disconnected\");\n callbacksRef.current.onStatusChange?.({ status: \"disconnected\" });\n callbacksRef.current.onDisconnect?.(\"User ended conversation\");\n } catch (error) {\n callbacksRef.current.onError?.(error as string);\n throw error;\n }\n }, [callbacksRef, setConnect, setToken, setStatus]);\n\n return {\n startSession,\n endSession,\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n };\n};\n","import { PACKAGE_VERSION } from \"../version\";\n\nexport const extractRoomIdFromToken = (token: string): string => {\n try {\n const tokenPayload = JSON.parse(atob(token.split(\".\")[1]));\n return tokenPayload.video?.room || \"\";\n } catch (error) {\n console.warn(\"Could not extract room ID from token\");\n return \"\";\n }\n};\n\nexport const getConversationToken = async (\n agentId: string\n): Promise<string> => {\n const response = await fetch(\n `https://api.elevenlabs.io/v1/convai/conversation/token?agent_id=${agentId}&source=react_native_sdk&version=${PACKAGE_VERSION}`\n );\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(`Failed to get conversation token: ${data.detail.message}`);\n }\n\n if (!data.token) {\n throw new Error(\"No conversation token received from API\");\n }\n\n return data.token;\n};\n","import { useState, useEffect, useCallback } from \"react\";\nimport { AudioSession } from \"@livekit/react-native\";\nimport type { LocalParticipant } from \"livekit-client\";\nimport type { ConversationStatus, Callbacks } from \"../types\";\n\nexport const useLiveKitRoom = (\n callbacksRef: { current: Callbacks },\n setStatus: (status: ConversationStatus) => void,\n roomId: string\n) => {\n const [roomConnected, setRoomConnected] = useState(false);\n const [localParticipant, setLocalParticipant] =\n useState<LocalParticipant | null>(null);\n\n useEffect(() => {\n const start = async () => {\n await AudioSession.startAudioSession();\n };\n\n start();\n return () => {\n AudioSession.stopAudioSession();\n };\n }, []);\n\n const handleParticipantReady = useCallback(\n (participant: LocalParticipant) => {\n setLocalParticipant(participant);\n },\n []\n );\n\n const handleConnected = useCallback(() => {\n setRoomConnected(true);\n setStatus(\"connected\");\n callbacksRef.current.onConnect?.({ conversationId: roomId });\n }, [roomId, callbacksRef, setStatus]);\n\n const handleDisconnected = useCallback(() => {\n setRoomConnected(false);\n setStatus(\"disconnected\");\n setLocalParticipant(null);\n callbacksRef.current.onDisconnect?.(\"disconnected\");\n }, [callbacksRef, setStatus]);\n\n const handleError = useCallback(\n (error: Error) => {\n console.error(\"LiveKit error:\", error);\n callbacksRef.current.onError?.(error.message, undefined);\n },\n [callbacksRef]\n );\n\n return {\n roomConnected,\n localParticipant,\n handleParticipantReady,\n handleConnected,\n handleDisconnected,\n handleError,\n };\n};\n","import { useCallback } from \"react\";\nimport type { LocalParticipant } from \"livekit-client\";\nimport type { ConversationStatus, Callbacks } from \"../types\";\n\nexport const useMessageSending = (\n status: ConversationStatus,\n localParticipant: LocalParticipant | null,\n callbacksRef: { current: Callbacks }\n) => {\n const sendMessage = useCallback(\n async (message: unknown) => {\n if (status !== \"connected\" || !localParticipant) {\n console.warn(\n \"Cannot send message: room not connected or no local participant\"\n );\n return;\n }\n try {\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify(message));\n\n await localParticipant.publishData(data, { reliable: true });\n } catch (error) {\n console.error(\"Failed to send message via WebRTC:\", error);\n console.error(\"Error details:\", error);\n callbacksRef.current.onError?.(error as string);\n }\n },\n [status, localParticipant, callbacksRef]\n );\n\n return { sendMessage };\n};\n","import type { ConversationConfig, InitiationClientDataEvent } from \"../types\";\nimport { PACKAGE_VERSION } from \"../version\";\n\nexport function constructOverrides(\n config: ConversationConfig\n): InitiationClientDataEvent {\n const overridesEvent: InitiationClientDataEvent = {\n type: \"conversation_initiation_client_data\",\n };\n\n if (config.overrides) {\n overridesEvent.conversation_config_override = {\n agent: {\n prompt: config.overrides.agent?.prompt,\n first_message: config.overrides.agent?.firstMessage,\n language: config.overrides.agent?.language,\n },\n tts: {\n voice_id: config.overrides.tts?.voiceId,\n },\n conversation: {\n text_only: config.overrides.conversation?.textOnly,\n },\n client: {\n source: config.overrides?.client?.source || \"react_native_sdk\",\n version: config.overrides?.client?.version || PACKAGE_VERSION,\n },\n };\n }\n\n if (config.customLlmExtraBody) {\n overridesEvent.custom_llm_extra_body = config.customLlmExtraBody;\n }\n\n if (config.dynamicVariables) {\n overridesEvent.dynamic_variables = config.dynamicVariables;\n }\n\n return overridesEvent;\n}\n"],"names":["PACKAGE_VERSION","MessageHandler","_ref","onReady","isConnected","callbacks","sendMessage","_ref$clientTools","clientTools","updateCurrentEventId","localParticipant","useLocalParticipant","agentResponseCountRef","React","useRef","useEffect","useDataChannel","msg","_msg$from","_msg$from2","_msg$from3","decoder","TextDecoder","message","JSON","parse","decode","payload","onMessage","source","from","isAgent","onModeChange","mode","isSpeaking","type","eventId","current","event_id","ping_event","clientToolCall","Promise","resolve","Object","prototype","hasOwnProperty","call","tool_name","_temp","parameters","then","result","formattedResult","stringify","String","tool_call_id","is_error","_catch","e","onError","clientToolName","onUnhandledClientToolCall","errorMessage","reject","handleClientToolCall","client_tool_call","onDebug","LiveKitRoomWrapper","children","createElement","LiveKitRoom","serverUrl","token","connect","audio","video","options","adaptiveStream","pixelDensity","onConnected","onDisconnected","onParticipantReady","roomConnected","_excluded","ElevenLabsContext","createContext","useConversation","context","useContext","Error","_objectWithoutPropertiesLoose","setServerUrl","setClientTools","setCallbacks","conversation","ElevenLabsProvider","registerGlobals","_useState","useState","setToken","_useState2","setConnect","_useState3","status","setStatus","_useState4","_useState5","roomId","setRoomId","_useState6","setIsSpeaking","_useState7","canSendFeedback","setCanSendFeedback","currentEventIdRef","lastFeedbackEventIdRef","clientToolsRef","_useConversationCallb","callbacksRef","useCallback","useConversationCallbacks","setCallbacksBase","wrappedCallbacks","_extends","event","_useConversationSessi","overrides","setOverrides","customLlmExtraBody","setCustomLlmExtraBody","dynamicVariables","setDynamicVariables","startSession","config","_temp2","_result2","extractedRoomId","_tokenPayload$video","atob","split","room","error","console","warn","extractRoomIdFromToken","conversationToken","onStatusChange","agentId","info","fetch","response","json","data","ok","detail","getConversationToken","_getConversationToken","endSession","onDisconnect","useConversationSession","_useLiveKitRoom","setRoomConnected","setLocalParticipant","AudioSession","startAudioSession","start","stopAudioSession","handleParticipantReady","participant","handleConnected","onConnect","conversationId","handleDisconnected","handleError","undefined","useLiveKitRoom","handleConnectedWithFeedback","onCanSendFeedbackChange","handleDisconnectedWithFeedback","_useMessageSending","TextEncoder","encode","publishData","reliable","useMessageSending","updateCanSendFeedback","newCanSendFeedback","sendFeedback","like","score","volume","handleParticipantReadyWithOverrides","overridesEvent","_config$overrides$age","_config$overrides$age2","_config$overrides$age3","_config$overrides$tts","_config$overrides$con","_config$overrides","_config$overrides2","conversation_config_override","agent","prompt","first_message","firstMessage","language","tts","voice_id","voiceId","text_only","textOnly","client","version","custom_llm_extra_body","dynamic_variables","constructOverrides","sendContextualUpdate","text","sendUserMessage","sendUserActivity","tools","Provider","value"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react"),require("@livekit/react-native")):"function"==typeof define&&define.amd?define(["exports","react","@livekit/react-native"],n):n((e||self).reactNative={},e.react,e.reactNative)}(this,function(e,n,t){function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=/*#__PURE__*/r(n);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},a.apply(null,arguments)}var c="0.1.0",i=function(e){var r=e.onReady,a=e.isConnected,c=e.callbacks,i=e.sendMessage,l=e.clientTools,s=void 0===l?{}:l,u=e.updateCurrentEventId,d=t.useLocalParticipant().localParticipant,f=o.default.useRef(1);return n.useEffect(function(){a&&d&&r(d)},[a,d,r]),t.useDataChannel(function(e){var n,t,r,o=new TextDecoder,a=JSON.parse(o.decode(e.payload));if(null==c.onMessage||c.onMessage({message:a,source:null!=(n=e.from)&&n.isAgent?"ai":"user"}),null!=(t=e.from)&&t.isAgent&&(null==c.onModeChange||c.onModeChange({mode:null!=(r=e.from)&&r.isSpeaking?"speaking":"listening"}),"agent_response"===a.type&&u)){var l=f.current++;u(l)}switch(a.type){case"ping":i({type:"pong",event_id:a.ping_event.event_id});break;case"client_tool_call":!function(e){try{return Promise.resolve(function(){if(Object.prototype.hasOwnProperty.call(s,e.tool_name)){var n=function(n,t){try{var r=Promise.resolve(s[e.tool_name](e.parameters)).then(function(n){var t="object"==typeof n?JSON.stringify(n):String(n);i({type:"client_tool_result",tool_call_id:e.tool_call_id,result:t,is_error:!1})})}catch(e){return t(e)}return r&&r.then?r.then(void 0,t):r}(0,function(n){null==c.onError||c.onError("Client tool execution failed with following error: "+(null==n?void 0:n.message),{clientToolName:e.tool_name}),i({type:"client_tool_result",tool_call_id:e.tool_call_id,result:"Client tool execution failed: "+(null==n?void 0:n.message),is_error:!0})});if(n&&n.then)return n.then(function(){})}else{if(c.onUnhandledClientToolCall)return void c.onUnhandledClientToolCall(e);var t="Client tool with name "+e.tool_name+" is not defined on client";null==c.onError||c.onError(t,{clientToolName:e.tool_name}),i({type:"client_tool_result",tool_call_id:e.tool_call_id,result:t,is_error:!0})}}())}catch(e){return Promise.reject(e)}}(a.client_tool_call);break;default:null==c.onDebug||c.onDebug(a)}}),null},l=function(e){var n=e.children;/*#__PURE__*/return o.default.createElement(t.LiveKitRoom,{serverUrl:e.serverUrl,token:e.token,connect:e.connect,audio:!0,video:!1,options:{adaptiveStream:{pixelDensity:"screen"}},onConnected:e.onConnected,onDisconnected:e.onDisconnected,onError:e.onError},/*#__PURE__*/o.default.createElement(i,{onReady:e.onParticipantReady,isConnected:e.roomConnected,callbacks:e.callbacks,sendMessage:e.sendMessage,clientTools:e.clientTools,updateCurrentEventId:e.updateCurrentEventId}),n)},s=["serverUrl","clientTools"],u=/*#__PURE__*/n.createContext(null);e.ElevenLabsProvider=function(e){var r=e.children;t.registerGlobals();var i=n.useState(""),s=i[0],d=i[1],f=n.useState(!1),v=f[0],m=f[1],h=n.useState("disconnected"),C=h[0],g=h[1],b=n.useState("wss://livekit.rtc.elevenlabs.io"),p=b[0],k=b[1],y=n.useState(""),_=y[0],S=y[1],E=n.useState(!1),P=E[0],w=E[1],x=n.useState(!1),T=x[0],D=x[1],R=o.default.useRef(1),M=o.default.useRef(1),U=o.default.useRef({}),j=function(){var e=n.useRef({}),t=n.useCallback(function(n){e.current=n},[]);return{callbacksRef:e,setCallbacks:t}}(),I=j.callbacksRef,O=j.setCallbacks,L=o.default.useCallback(function(e){var n=a({},e,{onModeChange:function(n){w("speaking"===n.mode),null==e.onModeChange||e.onModeChange(n)}});O(n)},[O]),F=function(e,t,r,o,a){var i=n.useState({}),l=i[0],s=i[1],u=n.useState(null),d=u[0],f=u[1],v=n.useState({}),m=v[0],h=v[1];return{startSession:n.useCallback(function(n){try{return Promise.resolve(function(i,l){try{var u=function(){function i(e){var n=function(e){try{var n;return(null==(n=JSON.parse(atob(e.split(".")[1])).video)?void 0:n.room)||""}catch(e){return console.warn("Could not extract room ID from token"),""}}(l);a(n),o(l),r(!0)}var l;t("connecting"),null==e.current.onStatusChange||e.current.onStatusChange({status:"connecting"}),s(n.overrides||{}),f(n.customLlmExtraBody||null),h(n.dynamicVariables||{});var u=function(){if(!n.conversationToken)return function(){if(n.agentId)return console.info("Getting conversation token for agentId:",n.agentId),Promise.resolve(function(e){try{return Promise.resolve(fetch("https://api.elevenlabs.io/v1/convai/conversation/token?agent_id="+e+"&source=react_native_sdk&version="+c)).then(function(e){return Promise.resolve(e.json()).then(function(n){if(!e.ok)throw new Error("Failed to get conversation token: "+n.detail.message);if(!n.token)throw new Error("No conversation token received from API");return n.token})})}catch(e){return Promise.reject(e)}}(n.agentId)).then(function(e){l=e});throw new Error("Either conversationToken or agentId is required")}();l=n.conversationToken}();return u&&u.then?u.then(i):i()}()}catch(e){return l(e)}return u&&u.then?u.then(void 0,l):u}(0,function(n){throw t("disconnected"),null==e.current.onStatusChange||e.current.onStatusChange({status:"disconnected"}),null==e.current.onError||e.current.onError(n),n}))}catch(e){return Promise.reject(e)}},[e,t,r,o,a]),endSession:n.useCallback(function(){try{try{r(!1),o(""),t("disconnected"),null==e.current.onStatusChange||e.current.onStatusChange({status:"disconnected"}),null==e.current.onDisconnect||e.current.onDisconnect("User ended conversation")}catch(n){throw null==e.current.onError||e.current.onError(n),n}return Promise.resolve()}catch(e){return Promise.reject(e)}},[e,r,o,t]),overrides:l,customLlmExtraBody:d,dynamicVariables:m}}(I,g,m,d,S),N=F.startSession,A=F.endSession,V=F.overrides,B=F.customLlmExtraBody,J=F.dynamicVariables,q=function(e,r,o){var a=n.useState(!1),c=a[0],i=a[1],l=n.useState(null),s=l[0],u=l[1];return n.useEffect(function(){return function(){try{return Promise.resolve(t.AudioSession.startAudioSession()).then(function(){})}catch(e){return Promise.reject(e)}}(),function(){t.AudioSession.stopAudioSession()}},[]),{roomConnected:c,localParticipant:s,handleParticipantReady:n.useCallback(function(e){u(e)},[]),handleConnected:n.useCallback(function(){i(!0),r("connected"),null==e.current.onConnect||e.current.onConnect({conversationId:o})},[o,e,r]),handleDisconnected:n.useCallback(function(){i(!1),r("disconnected"),u(null),null==e.current.onDisconnect||e.current.onDisconnect("disconnected")},[e,r]),handleError:n.useCallback(function(n){console.error("LiveKit error:",n),null==e.current.onError||e.current.onError(n.message,void 0)},[e])}}(I,g,_),K=q.roomConnected,G=q.localParticipant,W=q.handleParticipantReady,z=q.handleConnected,H=q.handleDisconnected,Q=q.handleError,X=o.default.useCallback(function(){R.current=1,M.current=1,D(!1),null==I.current.onCanSendFeedbackChange||I.current.onCanSendFeedbackChange({canSendFeedback:!1}),z()},[z,I]),Y=o.default.useCallback(function(){D(!1),H()},[H]),Z=function(e,t,r){return{sendMessage:n.useCallback(function(n){try{if("connected"!==e||!t)return console.warn("Cannot send message: room not connected or no local participant"),Promise.resolve();var o=function(e,r){try{var o=(a=(new TextEncoder).encode(JSON.stringify(n)),Promise.resolve(t.publishData(a,{reliable:!0})).then(function(){}))}catch(e){return r(e)}var a;return o&&o.then?o.then(void 0,r):o}(0,function(e){console.error("Failed to send message via WebRTC:",e),console.error("Error details:",e),null==r.current.onError||r.current.onError(e)});return Promise.resolve(o&&o.then?o.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},[e,t,r])}}(C,G,I),$=Z.sendMessage,ee=o.default.useCallback(function(){var e=R.current!==M.current;T!==e&&(D(e),null==I.current.onCanSendFeedbackChange||I.current.onCanSendFeedbackChange({canSendFeedback:e}))},[T,I]),ne=o.default.useCallback(function(e){T?($({type:"feedback",score:e?"like":"dislike",event_id:R.current}),M.current=R.current,ee()):console.warn(0===M.current?"Cannot send feedback: the conversation has not started yet.":"Cannot send feedback: feedback has already been sent for the current response.")},[T,$,ee]);o.default.useCallback(function(e){console.warn("setVolume is not yet implemented in React Native SDK")},[]);var te=o.default.useCallback(function(e){R.current=e,ee()},[ee]),re=o.default.useCallback(function(e){if(W(e),G){var n=function(e){var n,t,r,o,a,i,l,s={type:"conversation_initiation_client_data"};return e.overrides&&(s.conversation_config_override={agent:{prompt:null==(n=e.overrides.agent)?void 0:n.prompt,first_message:null==(t=e.overrides.agent)?void 0:t.firstMessage,language:null==(r=e.overrides.agent)?void 0:r.language},tts:{voice_id:null==(o=e.overrides.tts)?void 0:o.voiceId},conversation:{text_only:null==(a=e.overrides.conversation)?void 0:a.textOnly},client:{source:(null==(i=e.overrides)||null==(i=i.client)?void 0:i.source)||"react_native_sdk",version:(null==(l=e.overrides)||null==(l=l.client)?void 0:l.version)||c}}),e.customLlmExtraBody&&(s.custom_llm_extra_body=e.customLlmExtraBody),e.dynamicVariables&&(s.dynamic_variables=e.dynamicVariables),s}({overrides:V,customLlmExtraBody:B,dynamicVariables:J});$(n)}},[W,G,V,B,J,$]),oe={startSession:N,endSession:A,status:C,isSpeaking:P,canSendFeedback:T,sendFeedback:ne,sendContextualUpdate:function(e){$({type:"contextual_update",text:e})},sendUserMessage:function(e){$({type:"user_message",text:e})},sendUserActivity:function(){$({type:"user_activity"})}},ae=o.default.useCallback(function(e){U.current=e},[]);/*#__PURE__*/return o.default.createElement(u.Provider,{value:{conversation:oe,callbacksRef:I,serverUrl:p,clientTools:U.current,setCallbacks:L,setServerUrl:k,setClientTools:ae}},/*#__PURE__*/o.default.createElement(l,{serverUrl:p,token:s,connect:v,onConnected:X,onDisconnected:Y,onError:Q,roomConnected:K,callbacks:I.current,onParticipantReady:re,sendMessage:$,clientTools:U.current,updateCurrentEventId:te},r))},e.useConversation=function(e){void 0===e&&(e={});var t=n.useContext(u);if(!t)throw new Error("useConversation must be used within ElevenLabsProvider");var r=e.serverUrl,a=e.clientTools,c=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,s);return o.default.useEffect(function(){r&&t.setServerUrl(r)},[t,r]),a&&t.setClientTools(a),t.setCallbacks(c),t.conversation}});
2
+ //# sourceMappingURL=lib.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.umd.js","sources":["../src/version.ts","../src/components/MessageHandler.tsx","../src/components/LiveKitRoomWrapper.tsx","../src/ElevenLabsProvider.tsx","../src/utils/constants.ts","../src/hooks/useConversationCallbacks.ts","../src/hooks/useConversationSession.ts","../src/utils/tokenUtils.ts","../src/hooks/useLiveKitRoom.ts","../src/hooks/useMessageSending.ts","../src/utils/overrides.ts"],"sourcesContent":["// This file is auto-generated during build\nexport const PACKAGE_VERSION = \"0.1.0\";\n","import { useEffect } from 'react';\nimport { useLocalParticipant, useDataChannel } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ClientToolsConfig, ClientToolCallEvent } from '../types';\nimport React from 'react';\n\ninterface MessageHandlerProps {\n onReady: (participant: LocalParticipant) => void;\n isConnected: boolean;\n callbacks: Callbacks;\n sendMessage: (message: unknown) => void;\n clientTools?: ClientToolsConfig['clientTools'];\n updateCurrentEventId?: (eventId: number) => void;\n}\n\nexport const MessageHandler = ({\n onReady,\n isConnected,\n callbacks,\n sendMessage,\n clientTools = {},\n updateCurrentEventId\n}: MessageHandlerProps) => {\n const { localParticipant } = useLocalParticipant();\n\n // Track agent response count for synthetic event IDs (WebRTC mode)\n const agentResponseCountRef = React.useRef(1);\n\n useEffect(() => {\n if (isConnected && localParticipant) {\n onReady(localParticipant);\n }\n }, [isConnected, localParticipant, onReady]);\n\n const handleClientToolCall = async (clientToolCall: ClientToolCallEvent) => {\n if (\n Object.prototype.hasOwnProperty.call(\n clientTools,\n clientToolCall.tool_name\n )\n ) {\n try {\n const result =\n (await clientTools[clientToolCall.tool_name](\n clientToolCall.parameters\n )) ?? \"Client tool execution successful.\"; // default client-tool call response\n\n // The API expects result to be a string, so we need to convert it if it's not already a string\n const formattedResult =\n typeof result === \"object\" ? JSON.stringify(result) : String(result);\n\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.tool_call_id,\n result: formattedResult,\n is_error: false,\n });\n } catch (e) {\n const errorMessage = `Client tool execution failed with following error: ${(e as Error)?.message}`;\n callbacks.onError?.(errorMessage, {\n clientToolName: clientToolCall.tool_name,\n });\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.tool_call_id,\n result: `Client tool execution failed: ${(e as Error)?.message}`,\n is_error: true,\n });\n }\n } else {\n if (callbacks.onUnhandledClientToolCall) {\n callbacks.onUnhandledClientToolCall(clientToolCall);\n return;\n }\n\n const errorMessage = `Client tool with name ${clientToolCall.tool_name} is not defined on client`;\n callbacks.onError?.(errorMessage, {\n clientToolName: clientToolCall.tool_name,\n });\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.tool_call_id,\n result: errorMessage,\n is_error: true,\n });\n }\n };\n\n const _ = useDataChannel((msg) => {\n const decoder = new TextDecoder();\n const message = JSON.parse(decoder.decode(msg.payload));\n\n callbacks.onMessage?.({\n message,\n source: msg.from?.isAgent ? 'ai' : 'user',\n });\n\n if (msg.from?.isAgent) {\n callbacks.onModeChange?.({\n mode: msg.from?.isSpeaking ? 'speaking' : 'listening'\n });\n\n // Track agent responses for feedback (WebRTC mode needs synthetic event IDs)\n if (message.type === \"agent_response\" && updateCurrentEventId) {\n const eventId = agentResponseCountRef.current++;\n updateCurrentEventId(eventId);\n }\n }\n\n switch (message.type) {\n case \"ping\":\n sendMessage({\n type: \"pong\",\n event_id: message.ping_event.event_id,\n });\n break;\n case \"client_tool_call\":\n handleClientToolCall(message.client_tool_call);\n break;\n default:\n callbacks.onDebug?.(message);\n break;\n }\n });\n\n return null;\n};","import React from 'react';\nimport { LiveKitRoom } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ClientToolsConfig } from '../types';\nimport { MessageHandler } from './MessageHandler';\n\ninterface LiveKitRoomWrapperProps {\n children: React.ReactNode;\n serverUrl: string;\n token: string;\n connect: boolean;\n onConnected: () => void;\n onDisconnected: () => void;\n onError: (error: Error) => void;\n roomConnected: boolean;\n callbacks: Callbacks;\n onParticipantReady: (participant: LocalParticipant) => void;\n sendMessage: (message: unknown) => void;\n clientTools: ClientToolsConfig['clientTools'];\n updateCurrentEventId?: (eventId: number) => void;\n}\n\nexport const LiveKitRoomWrapper = ({\n children,\n serverUrl,\n token,\n connect,\n onConnected,\n onDisconnected,\n onError,\n roomConnected,\n callbacks,\n onParticipantReady,\n sendMessage,\n clientTools,\n updateCurrentEventId,\n}: LiveKitRoomWrapperProps) => {\n return (\n <LiveKitRoom\n serverUrl={serverUrl}\n token={token}\n connect={connect}\n audio={true}\n video={false}\n options={{\n adaptiveStream: { pixelDensity: 'screen' },\n }}\n onConnected={onConnected}\n onDisconnected={onDisconnected}\n onError={onError}\n >\n <MessageHandler\n onReady={onParticipantReady}\n isConnected={roomConnected}\n callbacks={callbacks}\n sendMessage={sendMessage}\n clientTools={clientTools}\n updateCurrentEventId={updateCurrentEventId}\n />\n {children}\n </LiveKitRoom>\n );\n};","import React from 'react';\nimport { createContext, useContext, useState } from 'react';\nimport { registerGlobals } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ConversationConfig, ConversationStatus, ClientToolsConfig } from './types';\nimport { constructOverrides } from './utils/overrides';\nimport { DEFAULT_SERVER_URL } from './utils/constants';\nimport { useConversationCallbacks } from './hooks/useConversationCallbacks';\nimport { useConversationSession } from './hooks/useConversationSession';\nimport { useLiveKitRoom } from './hooks/useLiveKitRoom';\nimport { useMessageSending } from './hooks/useMessageSending';\nimport { LiveKitRoomWrapper } from './components/LiveKitRoomWrapper';\n\ninterface ConversationOptions extends Callbacks, Partial<ClientToolsConfig> {\n serverUrl?: string;\n}\n\ninterface Conversation {\n startSession: (config: ConversationConfig) => Promise<void>;\n endSession: () => Promise<void>;\n status: ConversationStatus;\n isSpeaking: boolean;\n // TODO: Implement setVolume when LiveKit React Native supports it\n // setVolume: (volume: number) => void;\n canSendFeedback: boolean;\n sendFeedback: (like: boolean) => void;\n sendContextualUpdate: (text: string) => void;\n sendUserMessage: (text: string) => void;\n sendUserActivity: () => void;\n}\n\ninterface ElevenLabsContextType {\n conversation: Conversation;\n callbacksRef: { current: Callbacks };\n serverUrl: string;\n clientTools: ClientToolsConfig['clientTools'];\n setCallbacks: (callbacks: Callbacks) => void;\n setServerUrl: (url: string) => void;\n setClientTools: (tools: ClientToolsConfig['clientTools']) => void;\n}\n\nconst ElevenLabsContext = createContext<ElevenLabsContextType | null>(null);\n\nexport const useConversation = (options: ConversationOptions = {}): Conversation => {\n const context = useContext(ElevenLabsContext);\n if (!context) {\n throw new Error('useConversation must be used within ElevenLabsProvider');\n }\n\n const { serverUrl, clientTools, ...callbacks } = options;\n\n React.useEffect(() => {\n if (serverUrl) {\n context.setServerUrl(serverUrl);\n }\n }, [context, serverUrl]);\n\n if (clientTools) {\n context.setClientTools(clientTools);\n }\n\n context.setCallbacks(callbacks);\n\n return context.conversation;\n};\n\ninterface ElevenLabsProviderProps {\n children: React.ReactNode;\n}\n\nexport const ElevenLabsProvider: React.FC<ElevenLabsProviderProps> = ({ children }) => {\n // Initialize globals on mount\n registerGlobals();\n\n // State management\n const [token, setToken] = useState('');\n const [connect, setConnect] = useState(false);\n const [status, setStatus] = useState<ConversationStatus>('disconnected');\n const [serverUrl, setServerUrl] = useState(DEFAULT_SERVER_URL);\n const [roomId, setRoomId] = useState<string>('');\n const [isSpeaking, setIsSpeaking] = useState(false);\n const [canSendFeedback, setCanSendFeedback] = useState(false);\n\n // Feedback state tracking\n const currentEventIdRef = React.useRef(1);\n const lastFeedbackEventIdRef = React.useRef(1);\n\n // Use ref for clientTools to avoid re-renders (like callbacks)\n const clientToolsRef = React.useRef<ClientToolsConfig['clientTools']>({});\n\n // Custom hooks\n const { callbacksRef, setCallbacks: setCallbacksBase } = useConversationCallbacks();\n\n // Enhanced setCallbacks that wraps onModeChange to update isSpeaking state\n const setCallbacks = React.useCallback((callbacks: Callbacks) => {\n const wrappedCallbacks = {\n ...callbacks,\n onModeChange: (event: { mode: 'speaking' | 'listening' }) => {\n setIsSpeaking(event.mode === 'speaking');\n callbacks.onModeChange?.(event);\n }\n };\n setCallbacksBase(wrappedCallbacks);\n }, [setCallbacksBase]);\n\n const {\n startSession,\n endSession,\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n } = useConversationSession(callbacksRef, setStatus, setConnect, setToken, setRoomId);\n\n const {\n roomConnected,\n localParticipant,\n handleParticipantReady,\n handleConnected,\n handleDisconnected,\n handleError,\n } = useLiveKitRoom(callbacksRef, setStatus, roomId);\n\n // Enhanced connection handler to initialize feedback state\n const handleConnectedWithFeedback = React.useCallback(() => {\n // Reset feedback state when connecting\n currentEventIdRef.current = 1;\n lastFeedbackEventIdRef.current = 1;\n setCanSendFeedback(false);\n callbacksRef.current.onCanSendFeedbackChange?.({ canSendFeedback: false });\n\n handleConnected();\n }, [handleConnected, callbacksRef]);\n\n // Enhanced disconnection handler to reset feedback state\n const handleDisconnectedWithFeedback = React.useCallback(() => {\n setCanSendFeedback(false);\n handleDisconnected();\n }, [handleDisconnected]);\n\n const { sendMessage } = useMessageSending(status, localParticipant, callbacksRef);\n\n const updateCanSendFeedback = React.useCallback(() => {\n const newCanSendFeedback = currentEventIdRef.current !== lastFeedbackEventIdRef.current;\n\n if (canSendFeedback !== newCanSendFeedback) {\n setCanSendFeedback(newCanSendFeedback);\n callbacksRef.current.onCanSendFeedbackChange?.({ canSendFeedback: newCanSendFeedback });\n }\n }, [canSendFeedback, callbacksRef]);\n\n const sendFeedback = React.useCallback((like: boolean) => {\n if (!canSendFeedback) {\n console.warn(\n lastFeedbackEventIdRef.current === 0\n ? \"Cannot send feedback: the conversation has not started yet.\"\n : \"Cannot send feedback: feedback has already been sent for the current response.\"\n );\n return;\n }\n\n const feedbackMessage = {\n type: \"feedback\",\n score: like ? \"like\" : \"dislike\",\n event_id: currentEventIdRef.current,\n };\n\n sendMessage(feedbackMessage);\n lastFeedbackEventIdRef.current = currentEventIdRef.current;\n updateCanSendFeedback();\n }, [canSendFeedback, sendMessage, updateCanSendFeedback]);\n\n // setVolume placeholder (to be implemented when LiveKit supports it)\n const setVolume = React.useCallback((volume: number) => {\n console.warn('setVolume is not yet implemented in React Native SDK');\n }, []);\n\n // Update current event ID for feedback tracking\n const updateCurrentEventId = React.useCallback((eventId: number) => {\n currentEventIdRef.current = eventId;\n updateCanSendFeedback();\n }, [updateCanSendFeedback]);\n\n // Handle participant ready with overrides\n const handleParticipantReadyWithOverrides = React.useCallback((participant: LocalParticipant) => {\n handleParticipantReady(participant);\n\n if (localParticipant) {\n const overridesEvent = constructOverrides({\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n });\n sendMessage(overridesEvent);\n }\n }, [handleParticipantReady, localParticipant, overrides, customLlmExtraBody, dynamicVariables, sendMessage]);\n\n const conversation: Conversation = {\n startSession,\n endSession,\n status,\n isSpeaking,\n // setVolume,\n canSendFeedback,\n sendFeedback,\n sendContextualUpdate: (text: string) => {\n sendMessage({\n type: \"contextual_update\",\n text,\n });\n },\n sendUserMessage: (text: string) => {\n sendMessage({\n type: \"user_message\",\n text,\n });\n },\n sendUserActivity: () => {\n sendMessage({\n type: \"user_activity\",\n });\n },\n };\n\n // Create setClientTools function that only updates ref\n const setClientTools = React.useCallback((tools: ClientToolsConfig['clientTools']) => {\n clientToolsRef.current = tools;\n }, []);\n\n const contextValue: ElevenLabsContextType = {\n conversation,\n callbacksRef,\n serverUrl,\n clientTools: clientToolsRef.current,\n setCallbacks,\n setServerUrl,\n setClientTools,\n };\n\n return (\n <ElevenLabsContext.Provider value={contextValue}>\n <LiveKitRoomWrapper\n serverUrl={serverUrl}\n token={token}\n connect={connect}\n onConnected={handleConnectedWithFeedback}\n onDisconnected={handleDisconnectedWithFeedback}\n onError={handleError}\n roomConnected={roomConnected}\n callbacks={callbacksRef.current}\n onParticipantReady={handleParticipantReadyWithOverrides}\n sendMessage={sendMessage}\n clientTools={clientToolsRef.current}\n updateCurrentEventId={updateCurrentEventId}\n >\n {children}\n </LiveKitRoomWrapper>\n </ElevenLabsContext.Provider>\n );\n};","export const DEFAULT_SERVER_URL = \"wss://livekit.rtc.elevenlabs.io\";\n","import { useRef, useCallback } from \"react\";\nimport type { Callbacks } from \"../types\";\n\nexport const useConversationCallbacks = () => {\n const callbacksRef = useRef<Callbacks>({});\n\n const setCallbacks = useCallback((callbacks: Callbacks) => {\n callbacksRef.current = callbacks;\n }, []);\n\n return {\n callbacksRef,\n setCallbacks,\n };\n};\n","import { useState, useCallback } from \"react\";\nimport type {\n ConversationConfig,\n ConversationStatus,\n Callbacks,\n} from \"../types\";\nimport {\n getConversationToken,\n extractRoomIdFromToken,\n} from \"../utils/tokenUtils\";\n\nexport const useConversationSession = (\n callbacksRef: { current: Callbacks },\n setStatus: (status: ConversationStatus) => void,\n setConnect: (connect: boolean) => void,\n setToken: (token: string) => void,\n setRoomId: (roomId: string) => void\n) => {\n const [overrides, setOverrides] = useState<ConversationConfig[\"overrides\"]>(\n {}\n );\n const [customLlmExtraBody, setCustomLlmExtraBody] =\n useState<ConversationConfig[\"customLlmExtraBody\"]>(null);\n const [dynamicVariables, setDynamicVariables] = useState<\n ConversationConfig[\"dynamicVariables\"]\n >({});\n\n const startSession = useCallback(\n async (config: ConversationConfig) => {\n try {\n setStatus(\"connecting\");\n callbacksRef.current.onStatusChange?.({ status: \"connecting\" });\n\n setOverrides(config.overrides || {});\n setCustomLlmExtraBody(config.customLlmExtraBody || null);\n setDynamicVariables(config.dynamicVariables || {});\n\n let conversationToken: string;\n\n if (config.conversationToken) {\n conversationToken = config.conversationToken;\n } else if (config.agentId) {\n console.info(\n \"Getting conversation token for agentId:\",\n config.agentId\n );\n conversationToken = await getConversationToken(config.agentId);\n } else {\n throw new Error(\"Either conversationToken or agentId is required\");\n }\n\n // Extract room ID from token\n const extractedRoomId = extractRoomIdFromToken(conversationToken);\n setRoomId(extractedRoomId);\n\n setToken(conversationToken);\n setConnect(true);\n } catch (error) {\n setStatus(\"disconnected\");\n callbacksRef.current.onStatusChange?.({ status: \"disconnected\" });\n callbacksRef.current.onError?.(error as string);\n throw error;\n }\n },\n [callbacksRef, setStatus, setConnect, setToken, setRoomId]\n );\n\n const endSession = useCallback(async () => {\n try {\n setConnect(false);\n setToken(\"\");\n setStatus(\"disconnected\");\n callbacksRef.current.onStatusChange?.({ status: \"disconnected\" });\n callbacksRef.current.onDisconnect?.(\"User ended conversation\");\n } catch (error) {\n callbacksRef.current.onError?.(error as string);\n throw error;\n }\n }, [callbacksRef, setConnect, setToken, setStatus]);\n\n return {\n startSession,\n endSession,\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n };\n};\n","import { PACKAGE_VERSION } from \"../version\";\n\nexport const extractRoomIdFromToken = (token: string): string => {\n try {\n const tokenPayload = JSON.parse(atob(token.split(\".\")[1]));\n return tokenPayload.video?.room || \"\";\n } catch (error) {\n console.warn(\"Could not extract room ID from token\");\n return \"\";\n }\n};\n\nexport const getConversationToken = async (\n agentId: string\n): Promise<string> => {\n const response = await fetch(\n `https://api.elevenlabs.io/v1/convai/conversation/token?agent_id=${agentId}&source=react_native_sdk&version=${PACKAGE_VERSION}`\n );\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(`Failed to get conversation token: ${data.detail.message}`);\n }\n\n if (!data.token) {\n throw new Error(\"No conversation token received from API\");\n }\n\n return data.token;\n};\n","import { useState, useEffect, useCallback } from \"react\";\nimport { AudioSession } from \"@livekit/react-native\";\nimport type { LocalParticipant } from \"livekit-client\";\nimport type { ConversationStatus, Callbacks } from \"../types\";\n\nexport const useLiveKitRoom = (\n callbacksRef: { current: Callbacks },\n setStatus: (status: ConversationStatus) => void,\n roomId: string\n) => {\n const [roomConnected, setRoomConnected] = useState(false);\n const [localParticipant, setLocalParticipant] =\n useState<LocalParticipant | null>(null);\n\n useEffect(() => {\n const start = async () => {\n await AudioSession.startAudioSession();\n };\n\n start();\n return () => {\n AudioSession.stopAudioSession();\n };\n }, []);\n\n const handleParticipantReady = useCallback(\n (participant: LocalParticipant) => {\n setLocalParticipant(participant);\n },\n []\n );\n\n const handleConnected = useCallback(() => {\n setRoomConnected(true);\n setStatus(\"connected\");\n callbacksRef.current.onConnect?.({ conversationId: roomId });\n }, [roomId, callbacksRef, setStatus]);\n\n const handleDisconnected = useCallback(() => {\n setRoomConnected(false);\n setStatus(\"disconnected\");\n setLocalParticipant(null);\n callbacksRef.current.onDisconnect?.(\"disconnected\");\n }, [callbacksRef, setStatus]);\n\n const handleError = useCallback(\n (error: Error) => {\n console.error(\"LiveKit error:\", error);\n callbacksRef.current.onError?.(error.message, undefined);\n },\n [callbacksRef]\n );\n\n return {\n roomConnected,\n localParticipant,\n handleParticipantReady,\n handleConnected,\n handleDisconnected,\n handleError,\n };\n};\n","import { useCallback } from \"react\";\nimport type { LocalParticipant } from \"livekit-client\";\nimport type { ConversationStatus, Callbacks } from \"../types\";\n\nexport const useMessageSending = (\n status: ConversationStatus,\n localParticipant: LocalParticipant | null,\n callbacksRef: { current: Callbacks }\n) => {\n const sendMessage = useCallback(\n async (message: unknown) => {\n if (status !== \"connected\" || !localParticipant) {\n console.warn(\n \"Cannot send message: room not connected or no local participant\"\n );\n return;\n }\n try {\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify(message));\n\n await localParticipant.publishData(data, { reliable: true });\n } catch (error) {\n console.error(\"Failed to send message via WebRTC:\", error);\n console.error(\"Error details:\", error);\n callbacksRef.current.onError?.(error as string);\n }\n },\n [status, localParticipant, callbacksRef]\n );\n\n return { sendMessage };\n};\n","import type { ConversationConfig, InitiationClientDataEvent } from \"../types\";\nimport { PACKAGE_VERSION } from \"../version\";\n\nexport function constructOverrides(\n config: ConversationConfig\n): InitiationClientDataEvent {\n const overridesEvent: InitiationClientDataEvent = {\n type: \"conversation_initiation_client_data\",\n };\n\n if (config.overrides) {\n overridesEvent.conversation_config_override = {\n agent: {\n prompt: config.overrides.agent?.prompt,\n first_message: config.overrides.agent?.firstMessage,\n language: config.overrides.agent?.language,\n },\n tts: {\n voice_id: config.overrides.tts?.voiceId,\n },\n conversation: {\n text_only: config.overrides.conversation?.textOnly,\n },\n client: {\n source: config.overrides?.client?.source || \"react_native_sdk\",\n version: config.overrides?.client?.version || PACKAGE_VERSION,\n },\n };\n }\n\n if (config.customLlmExtraBody) {\n overridesEvent.custom_llm_extra_body = config.customLlmExtraBody;\n }\n\n if (config.dynamicVariables) {\n overridesEvent.dynamic_variables = config.dynamicVariables;\n }\n\n return overridesEvent;\n}\n"],"names":["PACKAGE_VERSION","MessageHandler","_ref","onReady","isConnected","callbacks","sendMessage","_ref$clientTools","clientTools","updateCurrentEventId","localParticipant","useLocalParticipant","agentResponseCountRef","React","useRef","useEffect","useDataChannel","msg","_msg$from","_msg$from2","_msg$from3","decoder","TextDecoder","message","JSON","parse","decode","payload","onMessage","source","from","isAgent","onModeChange","mode","isSpeaking","type","eventId","current","event_id","ping_event","clientToolCall","Promise","resolve","Object","prototype","hasOwnProperty","call","tool_name","_temp","parameters","then","result","formattedResult","stringify","String","tool_call_id","is_error","_catch","e","onError","clientToolName","onUnhandledClientToolCall","errorMessage","reject","handleClientToolCall","client_tool_call","onDebug","LiveKitRoomWrapper","children","createElement","LiveKitRoom","serverUrl","token","connect","audio","video","options","adaptiveStream","pixelDensity","onConnected","onDisconnected","onParticipantReady","roomConnected","_excluded","ElevenLabsContext","createContext","registerGlobals","_useState","useState","setToken","_useState2","setConnect","_useState3","status","setStatus","_useState4","setServerUrl","_useState5","roomId","setRoomId","_useState6","setIsSpeaking","_useState7","canSendFeedback","setCanSendFeedback","currentEventIdRef","lastFeedbackEventIdRef","clientToolsRef","_useConversationCallb","callbacksRef","setCallbacks","useCallback","useConversationCallbacks","setCallbacksBase","wrappedCallbacks","_extends","event","_useConversationSessi","overrides","setOverrides","customLlmExtraBody","setCustomLlmExtraBody","dynamicVariables","setDynamicVariables","startSession","config","_temp2","_result2","extractedRoomId","_tokenPayload$video","atob","split","room","error","console","warn","extractRoomIdFromToken","conversationToken","onStatusChange","agentId","info","fetch","response","json","data","ok","Error","detail","getConversationToken","_getConversationToken","endSession","onDisconnect","useConversationSession","_useLiveKitRoom","setRoomConnected","setLocalParticipant","AudioSession","startAudioSession","start","stopAudioSession","handleParticipantReady","participant","handleConnected","onConnect","conversationId","handleDisconnected","handleError","undefined","useLiveKitRoom","handleConnectedWithFeedback","onCanSendFeedbackChange","handleDisconnectedWithFeedback","_useMessageSending","TextEncoder","encode","publishData","reliable","useMessageSending","updateCanSendFeedback","newCanSendFeedback","sendFeedback","like","score","volume","handleParticipantReadyWithOverrides","overridesEvent","_config$overrides$age","_config$overrides$age2","_config$overrides$age3","_config$overrides$tts","_config$overrides$con","_config$overrides","_config$overrides2","conversation_config_override","agent","prompt","first_message","firstMessage","language","tts","voice_id","voiceId","conversation","text_only","textOnly","client","version","custom_llm_extra_body","dynamic_variables","constructOverrides","sendContextualUpdate","text","sendUserMessage","sendUserActivity","setClientTools","tools","Provider","value","context","useContext","_objectWithoutPropertiesLoose"],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Role in the conversation
3
+ */
4
+ export type Role = "user" | "ai";
5
+ /**
6
+ * Current mode of the conversation
7
+ */
8
+ export type Mode = "speaking" | "listening";
9
+ export type ConversationStatus = "disconnected" | "connecting" | "connected";
10
+ /**
11
+ * Language support
12
+ */
13
+ export type Language = "en" | "ja" | "zh" | "de" | "hi" | "fr" | "ko" | "pt" | "pt-br" | "it" | "es" | "id" | "nl" | "tr" | "pl" | "sv" | "bg" | "ro" | "ar" | "cs" | "el" | "fi" | "ms" | "da" | "ta" | "uk" | "ru" | "hu" | "hr" | "sk" | "no" | "vi";
14
+ /**
15
+ * Client tool call event structure
16
+ */
17
+ export type ClientToolCallEvent = {
18
+ tool_name: string;
19
+ tool_call_id: string;
20
+ parameters: unknown;
21
+ expects_response: boolean;
22
+ };
23
+ /**
24
+ * Client tools configuration
25
+ */
26
+ export type ClientToolsConfig = {
27
+ clientTools: Record<string, (parameters: unknown) => Promise<string | number | undefined> | string | number | undefined>;
28
+ };
29
+ /**
30
+ * Options for useConversation hook
31
+ */
32
+ export type ConversationOptions = {
33
+ serverUrl?: string;
34
+ clientTools?: Record<string, (parameters: unknown) => Promise<string | number | undefined> | string | number | undefined>;
35
+ } & Partial<Callbacks>;
36
+ /**
37
+ * Callbacks configuration
38
+ */
39
+ export type Callbacks = {
40
+ onConnect?: (props: {
41
+ conversationId: string;
42
+ }) => void;
43
+ onDebug?: (props: unknown) => void;
44
+ onDisconnect?: (details: string) => void;
45
+ onError?: (message: string, context?: Record<string, unknown>) => void;
46
+ onMessage?: (props: {
47
+ message: string;
48
+ source: Role;
49
+ }) => void;
50
+ onModeChange?: (prop: {
51
+ mode: Mode;
52
+ }) => void;
53
+ onStatusChange?: (prop: {
54
+ status: ConversationStatus;
55
+ }) => void;
56
+ onCanSendFeedbackChange?: (prop: {
57
+ canSendFeedback: boolean;
58
+ }) => void;
59
+ onUnhandledClientToolCall?: (params: ClientToolCallEvent) => void;
60
+ };
61
+ export type ConversationConfig = {
62
+ agentId?: string;
63
+ conversationToken?: string;
64
+ overrides?: {
65
+ agent?: {
66
+ prompt?: {
67
+ prompt?: string;
68
+ };
69
+ firstMessage?: string;
70
+ language?: Language;
71
+ };
72
+ tts?: {
73
+ voiceId?: string;
74
+ };
75
+ conversation?: {
76
+ textOnly?: boolean;
77
+ };
78
+ client?: {
79
+ source?: string;
80
+ version?: string;
81
+ };
82
+ };
83
+ customLlmExtraBody?: unknown;
84
+ dynamicVariables?: Record<string, string | number | boolean>;
85
+ };
86
+ export type InitiationClientDataEvent = {
87
+ type: "conversation_initiation_client_data";
88
+ conversation_config_override?: {
89
+ agent?: {
90
+ prompt?: {
91
+ prompt?: string;
92
+ };
93
+ first_message?: string;
94
+ language?: Language;
95
+ };
96
+ tts?: {
97
+ voice_id?: string;
98
+ };
99
+ conversation?: {
100
+ text_only?: boolean;
101
+ };
102
+ client?: {
103
+ source?: string;
104
+ version?: string;
105
+ };
106
+ };
107
+ custom_llm_extra_body?: unknown;
108
+ dynamic_variables?: Record<string, string | number | boolean>;
109
+ };
@@ -0,0 +1 @@
1
+ export declare const DEFAULT_SERVER_URL = "wss://livekit.rtc.elevenlabs.io";
@@ -0,0 +1,2 @@
1
+ import type { ConversationConfig, InitiationClientDataEvent } from "../types";
2
+ export declare function constructOverrides(config: ConversationConfig): InitiationClientDataEvent;
@@ -0,0 +1,2 @@
1
+ export declare const extractRoomIdFromToken: (token: string) => string;
2
+ export declare const getConversationToken: (agentId: string) => Promise<string>;
@@ -0,0 +1 @@
1
+ export declare const PACKAGE_VERSION = "0.1.0";
@@ -0,0 +1 @@
1
+ module.exports = {};
@@ -0,0 +1,263 @@
1
+ module.exports = {
2
+ // Use React Native preset optimized for TypeScript
3
+ preset: 'ts-jest',
4
+
5
+ // Use node environment with React Native globals
6
+ testEnvironment: 'node',
7
+
8
+ // Define test roots
9
+ roots: ['<rootDir>/src'],
10
+
11
+ // Enhanced test file matching patterns
12
+ testMatch: [
13
+ '**/__tests__/**/*.(test|spec).+(ts|tsx|js|jsx)',
14
+ '**/*.(test|spec).+(ts|tsx|js|jsx)',
15
+ '!**/*.d.ts',
16
+ '!**/node_modules/**',
17
+ ],
18
+
19
+ // TypeScript and JavaScript transformation
20
+ transform: {
21
+ '^.+\\.(ts|tsx)$': ['ts-jest', {
22
+ isolatedModules: true,
23
+ useESM: false,
24
+ tsconfig: {
25
+ target: 'ES2020',
26
+ module: 'commonjs',
27
+ moduleResolution: 'node',
28
+ allowJs: true,
29
+ allowSyntheticDefaultImports: true,
30
+ esModuleInterop: true,
31
+ skipLibCheck: true,
32
+ strict: false, // Relaxed for testing
33
+ resolveJsonModule: true,
34
+ },
35
+ }],
36
+ '^.+\\.(js|jsx)$': 'babel-jest',
37
+ },
38
+
39
+ // File extensions to handle
40
+ moduleFileExtensions: [
41
+ 'ts',
42
+ 'tsx',
43
+ 'js',
44
+ 'jsx',
45
+ 'json',
46
+ 'node',
47
+ 'ios.ts',
48
+ 'ios.tsx',
49
+ 'android.ts',
50
+ 'android.tsx',
51
+ 'native.ts',
52
+ 'native.tsx',
53
+ ],
54
+
55
+ // Minimal module mapping for React Native modules
56
+ moduleNameMapper: {
57
+ '^react-native$': '<rootDir>/jest.rn-mock.js',
58
+ '^react-native/(.*)$': '<rootDir>/jest.rn-mock.js',
59
+ },
60
+
61
+ // Setup files
62
+ setupFiles: [],
63
+
64
+ // Setup files after environment is set up
65
+ setupFilesAfterEnv: [],
66
+
67
+ // Coverage configuration
68
+ collectCoverage: false, // Enable manually with --coverage
69
+ collectCoverageFrom: [
70
+ 'src/**/*.{ts,tsx}',
71
+ '!src/**/*.d.ts',
72
+ '!src/**/*.test.{ts,tsx}',
73
+ '!src/**/*.spec.{ts,tsx}',
74
+ '!src/**/test-*.{ts,tsx}',
75
+ '!src/**/__tests__/**',
76
+ '!src/**/__mocks__/**',
77
+ '!**/node_modules/**',
78
+ ],
79
+
80
+ // Coverage thresholds
81
+ coverageThreshold: {
82
+ global: {
83
+ branches: 80,
84
+ functions: 80,
85
+ lines: 80,
86
+ statements: 80,
87
+ },
88
+ // Per-file thresholds for critical files
89
+ './src/conversation.ts': {
90
+ branches: 90,
91
+ functions: 90,
92
+ lines: 90,
93
+ statements: 90,
94
+ },
95
+ './src/errors.ts': {
96
+ branches: 95,
97
+ functions: 95,
98
+ lines: 95,
99
+ statements: 95,
100
+ },
101
+ },
102
+
103
+ // Coverage reporters
104
+ coverageReporters: [
105
+ 'text',
106
+ 'text-summary',
107
+ 'lcov',
108
+ 'html',
109
+ 'json',
110
+ ],
111
+
112
+ // Coverage directory
113
+ coverageDirectory: '<rootDir>/coverage',
114
+
115
+ // Ignore patterns for coverage
116
+ coveragePathIgnorePatterns: [
117
+ '/node_modules/',
118
+ '/dist/',
119
+ '/build/',
120
+ '/.next/',
121
+ '/coverage/',
122
+ '\\.d\\.ts$',
123
+ '\\.test\\.ts$',
124
+ '\\.spec\\.ts$',
125
+ ],
126
+
127
+ // Test timeout (increased for React Native)
128
+ testTimeout: 15000,
129
+
130
+ // Clear mocks after each test
131
+ clearMocks: true,
132
+
133
+ // Restore mocks after each test
134
+ restoreMocks: true,
135
+
136
+ // Reset modules before each test
137
+ resetModules: false, // Keep false for performance
138
+
139
+ // Verbose output
140
+ verbose: false, // Set to true for debugging
141
+
142
+ // Error handling
143
+ errorOnDeprecated: true,
144
+
145
+ // Performance optimizations
146
+ maxWorkers: '50%', // Use half the available CPU cores
147
+
148
+ // Cache configuration
149
+ cache: true,
150
+ cacheDirectory: '<rootDir>/node_modules/.cache/jest',
151
+
152
+ // Watch mode configuration
153
+ watchPathIgnorePatterns: [
154
+ '/node_modules/',
155
+ '/dist/',
156
+ '/build/',
157
+ '/coverage/',
158
+ '\\.git/',
159
+ ],
160
+
161
+ // Test result processing
162
+ testResultsProcessor: undefined,
163
+
164
+ // Custom environment variables for React Native
165
+ testEnvironmentOptions: {
166
+ url: 'http://localhost',
167
+ },
168
+
169
+ // Resolver configuration for React Native modules
170
+ resolver: undefined, // Use default resolver with moduleNameMapping
171
+
172
+ // Transform ignore patterns (important for React Native)
173
+ transformIgnorePatterns: [
174
+ 'node_modules/(?!(react-native|@react-native|@livekit|livekit-client)/)',
175
+ ],
176
+
177
+ // Module directories
178
+ moduleDirectories: [
179
+ 'node_modules',
180
+ '<rootDir>/src',
181
+ ],
182
+
183
+ // Global setup and teardown
184
+ globalSetup: undefined,
185
+ globalTeardown: undefined,
186
+
187
+ // Custom reporters
188
+ reporters: [
189
+ 'default',
190
+ // Add custom reporters here if needed
191
+ // ['jest-junit', { outputDirectory: 'test-results', outputName: 'junit.xml' }],
192
+ ],
193
+
194
+ // Snapshot configuration
195
+ snapshotSerializers: [],
196
+
197
+ // Test path ignore patterns
198
+ testPathIgnorePatterns: [
199
+ '/node_modules/',
200
+ '/dist/',
201
+ '/build/',
202
+ '/coverage/',
203
+ ],
204
+
205
+ // Silent mode
206
+ silent: false,
207
+
208
+ // Notify configuration
209
+ notify: false,
210
+ notifyMode: 'failure-change',
211
+
212
+ // Force exit
213
+ forceExit: false,
214
+
215
+ // Detect open handles
216
+ detectOpenHandles: false, // Set to true for debugging
217
+
218
+ // Detect leaked handles
219
+ detectLeaks: false, // Set to true for debugging
220
+
221
+ // Bail configuration
222
+ bail: 0, // Run all tests
223
+
224
+ // Collect coverage from untested files
225
+ // collectCoverageOnlyFrom removed - replaced by collectCoverageFrom
226
+
227
+ // Coverage provider
228
+ coverageProvider: 'v8', // Faster than babel
229
+
230
+ // Extensions to ignore
231
+ modulePathIgnorePatterns: [
232
+ '<rootDir>/dist/',
233
+ '<rootDir>/build/',
234
+ ],
235
+
236
+ // Project configuration for monorepo support
237
+ projects: undefined,
238
+
239
+ // Runner configuration
240
+ runner: 'jest-runner',
241
+
242
+ // Test name pattern
243
+ testNamePattern: undefined,
244
+
245
+ // Only changed files
246
+ onlyChanged: false,
247
+
248
+ // Pass with no tests
249
+ passWithNoTests: true,
250
+
251
+ // Use stderr
252
+ useStderr: false,
253
+
254
+ // Watch plugins
255
+ watchPlugins: [
256
+ // Removed jest-watch-typeahead plugins - not installed
257
+ ],
258
+
259
+ // Timezone
260
+ fakeTimers: {
261
+ enableGlobally: false // Use real timers by default
262
+ },
263
+ };
@@ -0,0 +1,15 @@
1
+ // Simple React Native mock for Jest
2
+ module.exports = {
3
+ Platform: {
4
+ OS: 'ios',
5
+ select: jest.fn((options) => options.ios),
6
+ },
7
+ StyleSheet: {
8
+ create: jest.fn((styles) => styles),
9
+ flatten: jest.fn((styles) => styles),
10
+ },
11
+ Dimensions: {
12
+ get: jest.fn(() => ({ width: 375, height: 667 })),
13
+ },
14
+ // Add any other React Native modules as needed
15
+ };