@uselingu/react-native-sdk 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.
- package/README.md +279 -0
- package/lib/commonjs/components/LinguChat.js +283 -0
- package/lib/commonjs/components/LinguChat.js.map +1 -0
- package/lib/commonjs/components/LinguWebView.js +203 -0
- package/lib/commonjs/components/LinguWebView.js.map +1 -0
- package/lib/commonjs/components/MessageBubble.js +91 -0
- package/lib/commonjs/components/MessageBubble.js.map +1 -0
- package/lib/commonjs/components/NativeChatUI.js +192 -0
- package/lib/commonjs/components/NativeChatUI.js.map +1 -0
- package/lib/commonjs/components/TypingIndicator.js +92 -0
- package/lib/commonjs/components/TypingIndicator.js.map +1 -0
- package/lib/commonjs/context/LinguProvider.js +47 -0
- package/lib/commonjs/context/LinguProvider.js.map +1 -0
- package/lib/commonjs/context/index.js +17 -0
- package/lib/commonjs/context/index.js.map +1 -0
- package/lib/commonjs/hooks/useLinguChat.js +295 -0
- package/lib/commonjs/hooks/useLinguChat.js.map +1 -0
- package/lib/commonjs/index.js +129 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/services/LinguAPI.js +196 -0
- package/lib/commonjs/services/LinguAPI.js.map +1 -0
- package/lib/commonjs/services/SessionManager.js +131 -0
- package/lib/commonjs/services/SessionManager.js.map +1 -0
- package/lib/commonjs/services/StorageManager.js +116 -0
- package/lib/commonjs/services/StorageManager.js.map +1 -0
- package/lib/commonjs/theme/ThemeProvider.js +49 -0
- package/lib/commonjs/theme/ThemeProvider.js.map +1 -0
- package/lib/commonjs/theme/index.js +28 -0
- package/lib/commonjs/theme/index.js.map +1 -0
- package/lib/commonjs/theme/theme.js +150 -0
- package/lib/commonjs/theme/theme.js.map +1 -0
- package/lib/commonjs/types/index.js +2 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/utils/animations.js +118 -0
- package/lib/commonjs/utils/animations.js.map +1 -0
- package/lib/commonjs/utils/formatters.js +89 -0
- package/lib/commonjs/utils/formatters.js.map +1 -0
- package/lib/commonjs/utils/index.js +28 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/module/components/LinguChat.js +277 -0
- package/lib/module/components/LinguChat.js.map +1 -0
- package/lib/module/components/LinguWebView.js +195 -0
- package/lib/module/components/LinguWebView.js.map +1 -0
- package/lib/module/components/MessageBubble.js +83 -0
- package/lib/module/components/MessageBubble.js.map +1 -0
- package/lib/module/components/NativeChatUI.js +184 -0
- package/lib/module/components/NativeChatUI.js.map +1 -0
- package/lib/module/components/TypingIndicator.js +84 -0
- package/lib/module/components/TypingIndicator.js.map +1 -0
- package/lib/module/context/LinguProvider.js +38 -0
- package/lib/module/context/LinguProvider.js.map +1 -0
- package/lib/module/context/index.js +6 -0
- package/lib/module/context/index.js.map +1 -0
- package/lib/module/hooks/useLinguChat.js +288 -0
- package/lib/module/hooks/useLinguChat.js.map +1 -0
- package/lib/module/index.js +30 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/services/LinguAPI.js +190 -0
- package/lib/module/services/LinguAPI.js.map +1 -0
- package/lib/module/services/SessionManager.js +124 -0
- package/lib/module/services/SessionManager.js.map +1 -0
- package/lib/module/services/StorageManager.js +108 -0
- package/lib/module/services/StorageManager.js.map +1 -0
- package/lib/module/theme/ThemeProvider.js +40 -0
- package/lib/module/theme/ThemeProvider.js.map +1 -0
- package/lib/module/theme/index.js +7 -0
- package/lib/module/theme/index.js.map +1 -0
- package/lib/module/theme/theme.js +142 -0
- package/lib/module/theme/theme.js.map +1 -0
- package/lib/module/types/index.js +2 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/utils/animations.js +106 -0
- package/lib/module/utils/animations.js.map +1 -0
- package/lib/module/utils/formatters.js +78 -0
- package/lib/module/utils/formatters.js.map +1 -0
- package/lib/module/utils/index.js +7 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/typescript/components/LinguChat.d.ts +18 -0
- package/lib/typescript/components/LinguChat.d.ts.map +1 -0
- package/lib/typescript/components/LinguWebView.d.ts +16 -0
- package/lib/typescript/components/LinguWebView.d.ts.map +1 -0
- package/lib/typescript/components/MessageBubble.d.ts +13 -0
- package/lib/typescript/components/MessageBubble.d.ts.map +1 -0
- package/lib/typescript/components/NativeChatUI.d.ts +16 -0
- package/lib/typescript/components/NativeChatUI.d.ts.map +1 -0
- package/lib/typescript/components/TypingIndicator.d.ts +7 -0
- package/lib/typescript/components/TypingIndicator.d.ts.map +1 -0
- package/lib/typescript/context/LinguProvider.d.ts +32 -0
- package/lib/typescript/context/LinguProvider.d.ts.map +1 -0
- package/lib/typescript/context/index.d.ts +5 -0
- package/lib/typescript/context/index.d.ts.map +1 -0
- package/lib/typescript/hooks/useLinguChat.d.ts +18 -0
- package/lib/typescript/hooks/useLinguChat.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +19 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/services/LinguAPI.d.ts +39 -0
- package/lib/typescript/services/LinguAPI.d.ts.map +1 -0
- package/lib/typescript/services/SessionManager.d.ts +46 -0
- package/lib/typescript/services/SessionManager.d.ts.map +1 -0
- package/lib/typescript/services/StorageManager.d.ts +36 -0
- package/lib/typescript/services/StorageManager.d.ts.map +1 -0
- package/lib/typescript/theme/ThemeProvider.d.ts +23 -0
- package/lib/typescript/theme/ThemeProvider.d.ts.map +1 -0
- package/lib/typescript/theme/index.d.ts +6 -0
- package/lib/typescript/theme/index.d.ts.map +1 -0
- package/lib/typescript/theme/theme.d.ts +130 -0
- package/lib/typescript/theme/theme.d.ts.map +1 -0
- package/lib/typescript/types/index.d.ts +50 -0
- package/lib/typescript/types/index.d.ts.map +1 -0
- package/lib/typescript/utils/animations.d.ts +34 -0
- package/lib/typescript/utils/animations.d.ts.map +1 -0
- package/lib/typescript/utils/formatters.d.ts +25 -0
- package/lib/typescript/utils/formatters.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +6 -0
- package/lib/typescript/utils/index.d.ts.map +1 -0
- package/package.json +98 -0
- package/src/components/LinguChat.tsx +309 -0
- package/src/components/LinguWebView.tsx +216 -0
- package/src/components/MessageBubble.tsx +120 -0
- package/src/components/NativeChatUI.tsx +247 -0
- package/src/components/TypingIndicator.tsx +84 -0
- package/src/context/LinguProvider.tsx +53 -0
- package/src/context/index.ts +5 -0
- package/src/hooks/useLinguChat.ts +314 -0
- package/src/index.ts +43 -0
- package/src/services/LinguAPI.ts +214 -0
- package/src/services/SessionManager.ts +131 -0
- package/src/services/StorageManager.ts +111 -0
- package/src/theme/ThemeProvider.tsx +58 -0
- package/src/theme/index.ts +6 -0
- package/src/theme/theme.ts +254 -0
- package/src/types/index.ts +59 -0
- package/src/utils/animations.ts +141 -0
- package/src/utils/formatters.ts +80 -0
- package/src/utils/index.ts +6 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useState","useEffect","useCallback","useRef","LinguAPI","SessionManager","StorageManager","LOG_PREFIX","useLinguChat","linguConfig","_linguConfig$apiKey","console","log","apiKey","substring","baseURL","autoOpen","messages","setMessages","isLoading","setIsLoading","config","setConfig","isSessionActive","setIsSessionActive","apiRef","sessionManagerRef","currentSessionIdRef","api","current","sessionManager","onSessionStart","sessionId","_linguConfig$onSessio","saveCurrentSessionId","savedMessages","loadMessages","length","call","onSessionEnd","_linguConfig$onSessio2","saveMessages","getConfig","then","fetchedConfig","_fetchedConfig$greeti","theme","primaryColor","brandName","greetingMessage","catch","error","restorePreviousSession","_sessionManagerRef$cu","cleanup","previousSessionId","getCurrentSessionId","startSession","start","greetingMsg","id","Date","now","text","sender","timestamp","endSession","end","clearHistory","clearMessages","sendMessage","_linguConfig$onMessag","getSessionId","messageLength","preview","userMessage","prev","onMessageSent","_linguConfig$onMessag2","startTime","response","duration","responseLength","botMessage","onMessageReceived","errorMessage","messagesCount","hasConfig","currentSessionId"],"sources":["useLinguChat.ts"],"sourcesContent":["/**\n * Custom hook for managing Lingu chat state and operations\n * Now with message persistence and comprehensive logging\n */\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport { LinguAPI } from '../services/LinguAPI';\nimport { SessionManager } from '../services/SessionManager';\nimport { StorageManager } from '../services/StorageManager';\nimport type { Message, WidgetConfig, LinguConfig } from '../types';\n\nconst LOG_PREFIX = '[useLinguChat]';\n\ninterface UseLinguChatReturn {\n messages: Message[];\n isLoading: boolean;\n config: WidgetConfig | null;\n sendMessage: (text: string) => Promise<void>;\n startSession: () => Promise<void>;\n endSession: () => Promise<void>;\n isSessionActive: boolean;\n clearHistory: () => Promise<void>;\n}\n\nexport const useLinguChat = (linguConfig: LinguConfig): UseLinguChatReturn => {\n console.log(`${LOG_PREFIX} Initializing hook with config:`, {\n apiKey: linguConfig.apiKey?.substring(0, 20) + '...',\n baseURL: linguConfig.baseURL,\n autoOpen: linguConfig.autoOpen,\n });\n\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [config, setConfig] = useState<WidgetConfig | null>(null);\n const [isSessionActive, setIsSessionActive] = useState(false);\n\n const apiRef = useRef<LinguAPI | null>(null);\n const sessionManagerRef = useRef<SessionManager | null>(null);\n const currentSessionIdRef = useRef<string | null>(null);\n\n // Initialize API client and session manager\n useEffect(() => {\n console.log(`${LOG_PREFIX} Setting up API client and session manager`);\n\n const baseURL = linguConfig.baseURL || 'https://api.uselingu.app/api';\n console.log(`${LOG_PREFIX} API Base URL:`, baseURL);\n\n const api = new LinguAPI(linguConfig.apiKey, baseURL);\n apiRef.current = api;\n\n const sessionManager = new SessionManager(api, {\n onSessionStart: async (sessionId) => {\n console.log(`${LOG_PREFIX} ✅ Session started:`, sessionId);\n currentSessionIdRef.current = sessionId;\n setIsSessionActive(true);\n\n // Save session ID\n await StorageManager.saveCurrentSessionId(sessionId);\n console.log(`${LOG_PREFIX} Session ID saved to storage`);\n\n // Try to load previous messages for this session\n const savedMessages = await StorageManager.loadMessages(sessionId);\n if (savedMessages.length > 0) {\n console.log(`${LOG_PREFIX} Loaded ${savedMessages.length} messages from storage`);\n setMessages(savedMessages);\n } else {\n console.log(`${LOG_PREFIX} No previous messages found for this session`);\n }\n\n linguConfig.onSessionStart?.(sessionId);\n },\n onSessionEnd: async (sessionId) => {\n console.log(`${LOG_PREFIX} Session ending:`, sessionId);\n\n // Save messages before ending\n if (messages.length > 0) {\n console.log(`${LOG_PREFIX} Saving ${messages.length} messages before session end`);\n await StorageManager.saveMessages(sessionId, messages);\n }\n\n currentSessionIdRef.current = null;\n setIsSessionActive(false);\n console.log(`${LOG_PREFIX} ✅ Session ended successfully`);\n linguConfig.onSessionEnd?.(sessionId);\n },\n });\n sessionManagerRef.current = sessionManager;\n\n // Load widget configuration\n console.log(`${LOG_PREFIX} Fetching widget configuration...`);\n api\n .getConfig()\n .then((fetchedConfig) => {\n console.log(`${LOG_PREFIX} ✅ Widget config loaded:`, {\n theme: fetchedConfig.theme,\n primaryColor: fetchedConfig.primaryColor,\n brandName: fetchedConfig.brandName,\n greetingMessage: fetchedConfig.greetingMessage?.substring(0, 50),\n });\n setConfig(fetchedConfig);\n })\n .catch((error) => {\n console.error(`${LOG_PREFIX} ❌ Failed to load config:`, error);\n });\n\n // Try to restore previous session\n console.log(`${LOG_PREFIX} Attempting to restore previous session...`);\n restorePreviousSession();\n\n // Cleanup on unmount\n return () => {\n console.log(`${LOG_PREFIX} Component unmounting, cleaning up...`);\n // Save messages before cleanup\n if (currentSessionIdRef.current && messages.length > 0) {\n console.log(`${LOG_PREFIX} Saving messages on unmount`);\n StorageManager.saveMessages(currentSessionIdRef.current, messages);\n }\n sessionManagerRef.current?.cleanup();\n console.log(`${LOG_PREFIX} Cleanup complete`);\n };\n }, [linguConfig.apiKey, linguConfig.baseURL]);\n\n // Save messages whenever they change\n useEffect(() => {\n if (currentSessionIdRef.current && messages.length > 0) {\n console.log(`${LOG_PREFIX} Auto-saving ${messages.length} messages`);\n StorageManager.saveMessages(currentSessionIdRef.current, messages);\n }\n }, [messages]);\n\n /**\n * Try to restore previous session\n */\n const restorePreviousSession = async () => {\n try {\n const previousSessionId = await StorageManager.getCurrentSessionId();\n if (previousSessionId) {\n console.log(`${LOG_PREFIX} Found previous session:`, previousSessionId);\n const savedMessages = await StorageManager.loadMessages(previousSessionId);\n if (savedMessages.length > 0) {\n console.log(`${LOG_PREFIX} ✅ Restored ${savedMessages.length} messages from previous session`);\n setMessages(savedMessages);\n currentSessionIdRef.current = previousSessionId;\n } else {\n console.log(`${LOG_PREFIX} Previous session had no messages`);\n }\n } else {\n console.log(`${LOG_PREFIX} No previous session found`);\n }\n } catch (error) {\n console.error(`${LOG_PREFIX} ❌ Failed to restore previous session:`, error);\n }\n };\n\n /**\n * Start a new chat session\n */\n const startSession = useCallback(async () => {\n if (!sessionManagerRef.current) {\n console.error(`${LOG_PREFIX} ❌ Session manager not initialized`);\n return;\n }\n\n try {\n console.log(`${LOG_PREFIX} Starting new session...`);\n await sessionManagerRef.current.start();\n\n // Add greeting message if configured and no previous messages\n if (config?.greetingMessage && messages.length === 0) {\n console.log(`${LOG_PREFIX} Adding greeting message`);\n const greetingMsg: Message = {\n id: `greeting-${Date.now()}`,\n text: config.greetingMessage,\n sender: 'bot',\n timestamp: new Date(),\n };\n setMessages([greetingMsg]);\n }\n } catch (error) {\n console.error(`${LOG_PREFIX} ❌ Failed to start session:`, error);\n }\n }, [config, messages.length]);\n\n /**\n * End the current chat session\n */\n const endSession = useCallback(async () => {\n if (!sessionManagerRef.current) {\n console.error(`${LOG_PREFIX} ❌ Session manager not initialized`);\n return;\n }\n\n try {\n console.log(`${LOG_PREFIX} Ending session...`);\n await sessionManagerRef.current.end();\n // Don't clear messages - they're saved in storage\n console.log(`${LOG_PREFIX} ✅ Session ended, messages preserved`);\n } catch (error) {\n console.error(`${LOG_PREFIX} ❌ Failed to end session:`, error);\n }\n }, []);\n\n /**\n * Clear chat history\n */\n const clearHistory = useCallback(async () => {\n console.log(`${LOG_PREFIX} Clearing chat history...`);\n if (currentSessionIdRef.current) {\n await StorageManager.clearMessages(currentSessionIdRef.current);\n console.log(`${LOG_PREFIX} ✅ Storage cleared for session:`, currentSessionIdRef.current);\n }\n setMessages([]);\n console.log(`${LOG_PREFIX} ✅ Messages cleared from state`);\n }, []);\n\n /**\n * Send a message to the AI\n */\n const sendMessage = useCallback(\n async (text: string) => {\n if (!apiRef.current || !sessionManagerRef.current) {\n console.error(`${LOG_PREFIX} ❌ API or session manager not initialized`);\n return;\n }\n\n const sessionId = sessionManagerRef.current.getSessionId();\n if (!sessionId) {\n console.error(`${LOG_PREFIX} ❌ No active session`);\n return;\n }\n\n console.log(`${LOG_PREFIX} Sending message:`, {\n sessionId,\n messageLength: text.length,\n preview: text.substring(0, 50),\n });\n\n // Add user message\n const userMessage: Message = {\n id: `user-${Date.now()}`,\n text,\n sender: 'user',\n timestamp: new Date(),\n };\n setMessages((prev) => {\n console.log(`${LOG_PREFIX} Adding user message to state (total: ${prev.length + 1})`);\n return [...prev, userMessage];\n });\n linguConfig.onMessageSent?.(text);\n\n // Send to API\n setIsLoading(true);\n console.log(`${LOG_PREFIX} Waiting for AI response...`);\n try {\n const startTime = Date.now();\n const response = await apiRef.current.sendMessage(text, sessionId);\n const duration = Date.now() - startTime;\n\n console.log(`${LOG_PREFIX} ✅ Received AI response in ${duration}ms:`, {\n responseLength: response.length,\n preview: response.substring(0, 50),\n });\n\n // Add bot response\n const botMessage: Message = {\n id: `bot-${Date.now()}`,\n text: response,\n sender: 'bot',\n timestamp: new Date(),\n };\n setMessages((prev) => {\n console.log(`${LOG_PREFIX} Adding bot message to state (total: ${prev.length + 1})`);\n return [...prev, botMessage];\n });\n linguConfig.onMessageReceived?.(response);\n } catch (error) {\n console.error(`${LOG_PREFIX} ❌ Failed to send message:`, error);\n\n // Add error message\n const errorMessage: Message = {\n id: `error-${Date.now()}`,\n text: 'Sorry, I encountered an error. Please try again.',\n sender: 'bot',\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n console.log(`${LOG_PREFIX} Added error message to state`);\n } finally {\n setIsLoading(false);\n console.log(`${LOG_PREFIX} Message send complete`);\n }\n },\n [linguConfig]\n );\n\n console.log(`${LOG_PREFIX} Current state:`, {\n messagesCount: messages.length,\n isLoading,\n hasConfig: !!config,\n isSessionActive,\n currentSessionId: currentSessionIdRef.current,\n });\n\n return {\n messages,\n isLoading,\n config,\n sendMessage,\n startSession,\n endSession,\n isSessionActive,\n clearHistory,\n };\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lingu React Native SDK
|
|
3
|
+
* Standalone AI chat SDK with native UI and theme support
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Main components
|
|
7
|
+
export { LinguChat } from './components/LinguChat';
|
|
8
|
+
export { NativeChatUI } from './components/NativeChatUI';
|
|
9
|
+
export { LinguWebView } from './components/LinguWebView';
|
|
10
|
+
export { MessageBubble } from './components/MessageBubble';
|
|
11
|
+
export { TypingIndicator } from './components/TypingIndicator';
|
|
12
|
+
|
|
13
|
+
// Context and state management
|
|
14
|
+
export { LinguProvider, useLinguContext } from './context';
|
|
15
|
+
|
|
16
|
+
// Theme system
|
|
17
|
+
export { ThemeProvider, useTheme, createTheme } from './theme';
|
|
18
|
+
// Hooks
|
|
19
|
+
export { useLinguChat } from './hooks/useLinguChat';
|
|
20
|
+
|
|
21
|
+
// Services
|
|
22
|
+
export { LinguAPI } from './services/LinguAPI';
|
|
23
|
+
export { SessionManager } from './services/SessionManager';
|
|
24
|
+
export { StorageManager } from './services/StorageManager';
|
|
25
|
+
|
|
26
|
+
// Utils
|
|
27
|
+
export * from './utils';
|
|
28
|
+
|
|
29
|
+
// Types
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["LinguChat","NativeChatUI","LinguWebView","MessageBubble","TypingIndicator","LinguProvider","useLinguContext","ThemeProvider","useTheme","createTheme","useLinguChat","LinguAPI","SessionManager","StorageManager"],"sources":["index.ts"],"sourcesContent":["/**\n * Lingu React Native SDK\n * Standalone AI chat SDK with native UI and theme support\n */\n\n// Main components\nexport { LinguChat } from './components/LinguChat';\nexport { NativeChatUI } from './components/NativeChatUI';\nexport { LinguWebView } from './components/LinguWebView';\nexport { MessageBubble } from './components/MessageBubble';\nexport { TypingIndicator } from './components/TypingIndicator';\n\n// Context and state management\nexport { LinguProvider, useLinguContext } from './context';\n\n// Theme system\nexport { ThemeProvider, useTheme, createTheme } from './theme';\nexport type { Theme, ThemeColors } from './theme';\n\n// Hooks\nexport { useLinguChat } from './hooks/useLinguChat';\n\n// Services\nexport { LinguAPI } from './services/LinguAPI';\nexport { SessionManager } from './services/SessionManager';\nexport { StorageManager } from './services/StorageManager';\n\n// Utils\nexport * from './utils';\n\n// Types\nexport type {\n LinguConfig,\n ChatPosition,\n ThemeMode,\n Message,\n MessageSender,\n WidgetConfig,\n SessionData,\n ApiResponse,\n ChatResponse,\n SessionResponse,\n} from './types';\n"],"mappings":"AAAA;AACA;AACA;AACA;;AAEA;AACA,SAASA,SAAS,QAAQ,wBAAwB;AAClD,SAASC,YAAY,QAAQ,2BAA2B;AACxD,SAASC,YAAY,QAAQ,2BAA2B;AACxD,SAASC,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,eAAe,QAAQ,8BAA8B;;AAE9D;AACA,SAASC,aAAa,EAAEC,eAAe,QAAQ,WAAW;;AAE1D;AACA,SAASC,aAAa,EAAEC,QAAQ,EAAEC,WAAW,QAAQ,SAAS;AAG9D;AACA,SAASC,YAAY,QAAQ,sBAAsB;;AAEnD;AACA,SAASC,QAAQ,QAAQ,qBAAqB;AAC9C,SAASC,cAAc,QAAQ,2BAA2B;AAC1D,SAASC,cAAc,QAAQ,2BAA2B;;AAE1D;AACA,cAAc,SAAS;;AAEvB","ignoreList":[]}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
2
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
3
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
4
|
+
/**
|
|
5
|
+
* Lingu API Client
|
|
6
|
+
* Handles all communication with the Lingu backend API
|
|
7
|
+
* Now with comprehensive logging
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import axios from 'axios';
|
|
11
|
+
const LOG_PREFIX = '[LinguAPI]';
|
|
12
|
+
export class LinguAPI {
|
|
13
|
+
constructor(apiKey, baseURL = 'https://api.uselingu.app/api') {
|
|
14
|
+
_defineProperty(this, "client", void 0);
|
|
15
|
+
_defineProperty(this, "apiKey", void 0);
|
|
16
|
+
_defineProperty(this, "sessionId", null);
|
|
17
|
+
console.log(`${LOG_PREFIX} Initializing API client:`, {
|
|
18
|
+
baseURL,
|
|
19
|
+
apiKeyPrefix: apiKey.substring(0, 20) + '...'
|
|
20
|
+
});
|
|
21
|
+
this.apiKey = apiKey;
|
|
22
|
+
this.client = axios.create({
|
|
23
|
+
baseURL,
|
|
24
|
+
headers: {
|
|
25
|
+
'Content-Type': 'application/json'
|
|
26
|
+
},
|
|
27
|
+
timeout: 30000 // 30 seconds
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Add request interceptor for logging
|
|
31
|
+
this.client.interceptors.request.use(config => {
|
|
32
|
+
var _config$method;
|
|
33
|
+
console.log(`${LOG_PREFIX} → Request:`, {
|
|
34
|
+
method: (_config$method = config.method) === null || _config$method === void 0 ? void 0 : _config$method.toUpperCase(),
|
|
35
|
+
url: config.url,
|
|
36
|
+
hasData: !!config.data
|
|
37
|
+
});
|
|
38
|
+
return config;
|
|
39
|
+
}, error => {
|
|
40
|
+
console.error(`${LOG_PREFIX} ❌ Request setup failed:`, error);
|
|
41
|
+
return Promise.reject(error);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Add response interceptor for error handling and logging
|
|
45
|
+
this.client.interceptors.response.use(response => {
|
|
46
|
+
console.log(`${LOG_PREFIX} ← Response:`, {
|
|
47
|
+
status: response.status,
|
|
48
|
+
url: response.config.url,
|
|
49
|
+
dataSize: JSON.stringify(response.data).length
|
|
50
|
+
});
|
|
51
|
+
return response;
|
|
52
|
+
}, error => {
|
|
53
|
+
if (error.response) {
|
|
54
|
+
var _error$config;
|
|
55
|
+
console.error(`${LOG_PREFIX} ❌ HTTP Error:`, {
|
|
56
|
+
status: error.response.status,
|
|
57
|
+
statusText: error.response.statusText,
|
|
58
|
+
url: (_error$config = error.config) === null || _error$config === void 0 ? void 0 : _error$config.url,
|
|
59
|
+
data: error.response.data
|
|
60
|
+
});
|
|
61
|
+
} else if (error.request) {
|
|
62
|
+
var _error$config2, _error$config3;
|
|
63
|
+
console.error(`${LOG_PREFIX} ❌ Network Error:`, {
|
|
64
|
+
message: error.message,
|
|
65
|
+
url: (_error$config2 = error.config) === null || _error$config2 === void 0 ? void 0 : _error$config2.url,
|
|
66
|
+
baseURL: (_error$config3 = error.config) === null || _error$config3 === void 0 ? void 0 : _error$config3.baseURL
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
console.error(`${LOG_PREFIX} ❌ Request Error:`, error.message);
|
|
70
|
+
}
|
|
71
|
+
return Promise.reject(error);
|
|
72
|
+
});
|
|
73
|
+
console.log(`${LOG_PREFIX} ✅ API client initialized successfully`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Get widget configuration from the API
|
|
78
|
+
*/
|
|
79
|
+
async getConfig() {
|
|
80
|
+
console.log(`${LOG_PREFIX} Fetching widget configuration...`);
|
|
81
|
+
try {
|
|
82
|
+
const startTime = Date.now();
|
|
83
|
+
const response = await this.client.get('/chatbot-settings/widget/config', {
|
|
84
|
+
headers: {
|
|
85
|
+
'X-API-Key': this.apiKey
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
const duration = Date.now() - startTime;
|
|
89
|
+
console.log(`${LOG_PREFIX} ✅ Config loaded in ${duration}ms:`, {
|
|
90
|
+
theme: response.data.data.theme,
|
|
91
|
+
primaryColor: response.data.data.primaryColor,
|
|
92
|
+
brandName: response.data.data.brandName
|
|
93
|
+
});
|
|
94
|
+
return response.data.data;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error(`${LOG_PREFIX} ❌ Failed to get config:`, error);
|
|
97
|
+
throw new Error('Failed to load widget configuration');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Start a new chat session
|
|
103
|
+
* Note: Backend manages sessions automatically, we just generate a client-side ID
|
|
104
|
+
*/
|
|
105
|
+
async startSession() {
|
|
106
|
+
console.log(`${LOG_PREFIX} Starting new chat session (client-side)...`);
|
|
107
|
+
try {
|
|
108
|
+
// Generate a unique session ID client-side
|
|
109
|
+
const sessionId = `session_${Date.now()}_${Math.random().toString(36).substring(7)}`;
|
|
110
|
+
this.sessionId = sessionId;
|
|
111
|
+
console.log(`${LOG_PREFIX} ✅ Session created:`, sessionId);
|
|
112
|
+
return this.sessionId;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error(`${LOG_PREFIX} ❌ Failed to start session:`, error);
|
|
115
|
+
throw new Error('Failed to start chat session');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Send a message to the AI
|
|
121
|
+
*/
|
|
122
|
+
async sendMessage(message, sessionId) {
|
|
123
|
+
console.log(`${LOG_PREFIX} Sending message:`, {
|
|
124
|
+
sessionId,
|
|
125
|
+
messageLength: message.length,
|
|
126
|
+
preview: message.substring(0, 50) + (message.length > 50 ? '...' : '')
|
|
127
|
+
});
|
|
128
|
+
try {
|
|
129
|
+
const startTime = Date.now();
|
|
130
|
+
const response = await this.client.post('/chat/widget', {
|
|
131
|
+
apiKey: this.apiKey,
|
|
132
|
+
message,
|
|
133
|
+
sessionId
|
|
134
|
+
});
|
|
135
|
+
const duration = Date.now() - startTime;
|
|
136
|
+
const aiResponse = response.data.data.message;
|
|
137
|
+
console.log(`${LOG_PREFIX} ✅ AI response received in ${duration}ms:`, {
|
|
138
|
+
responseLength: aiResponse.length,
|
|
139
|
+
preview: aiResponse.substring(0, 50) + (aiResponse.length > 50 ? '...' : '')
|
|
140
|
+
});
|
|
141
|
+
return aiResponse;
|
|
142
|
+
} catch (error) {
|
|
143
|
+
console.error(`${LOG_PREFIX} ❌ Failed to send message:`, error);
|
|
144
|
+
throw new Error('Failed to send message');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* End the current chat session
|
|
150
|
+
* Note: Backend doesn't have explicit session end, sessions timeout automatically
|
|
151
|
+
*/
|
|
152
|
+
async endSession(sessionId) {
|
|
153
|
+
console.log(`${LOG_PREFIX} Ending session (client-side only):`, sessionId);
|
|
154
|
+
try {
|
|
155
|
+
this.sessionId = null;
|
|
156
|
+
console.log(`${LOG_PREFIX} ✅ Session ended successfully`);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error(`${LOG_PREFIX} ⚠️ Failed to end session:`, error);
|
|
159
|
+
// Don't throw - session will timeout anyway
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Send heartbeat to keep session alive
|
|
165
|
+
*/
|
|
166
|
+
async sendHeartbeat(sessionId) {
|
|
167
|
+
console.log(`${LOG_PREFIX} Sending heartbeat for session:`, sessionId);
|
|
168
|
+
try {
|
|
169
|
+
// Send special heartbeat message
|
|
170
|
+
await this.client.post('/chat/widget', {
|
|
171
|
+
apiKey: this.apiKey,
|
|
172
|
+
message: '__HEARTBEAT__',
|
|
173
|
+
sessionId
|
|
174
|
+
});
|
|
175
|
+
console.log(`${LOG_PREFIX} ✅ Heartbeat sent successfully`);
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.error(`${LOG_PREFIX} ⚠️ Heartbeat failed (will retry):`, error);
|
|
178
|
+
// Don't throw - will retry on next heartbeat
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get the current session ID
|
|
184
|
+
*/
|
|
185
|
+
getSessionId() {
|
|
186
|
+
console.log(`${LOG_PREFIX} Current session ID:`, this.sessionId || 'none');
|
|
187
|
+
return this.sessionId;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=LinguAPI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["axios","LOG_PREFIX","LinguAPI","constructor","apiKey","baseURL","_defineProperty","console","log","apiKeyPrefix","substring","client","create","headers","timeout","interceptors","request","use","config","_config$method","method","toUpperCase","url","hasData","data","error","Promise","reject","response","status","dataSize","JSON","stringify","length","_error$config","statusText","_error$config2","_error$config3","message","getConfig","startTime","Date","now","get","duration","theme","primaryColor","brandName","Error","startSession","sessionId","Math","random","toString","sendMessage","messageLength","preview","post","aiResponse","responseLength","endSession","sendHeartbeat","getSessionId"],"sources":["LinguAPI.ts"],"sourcesContent":["/**\n * Lingu API Client\n * Handles all communication with the Lingu backend API\n * Now with comprehensive logging\n */\n\nimport axios, { AxiosInstance, AxiosError } from 'axios';\nimport type {\n WidgetConfig,\n ChatResponse,\n ApiResponse,\n} from '../types';\n\nconst LOG_PREFIX = '[LinguAPI]';\n\nexport class LinguAPI {\n private client: AxiosInstance;\n private apiKey: string;\n private sessionId: string | null = null;\n\n constructor(apiKey: string, baseURL: string = 'https://api.uselingu.app/api') {\n console.log(`${LOG_PREFIX} Initializing API client:`, {\n baseURL,\n apiKeyPrefix: apiKey.substring(0, 20) + '...',\n });\n\n this.apiKey = apiKey;\n this.client = axios.create({\n baseURL,\n headers: {\n 'Content-Type': 'application/json',\n },\n timeout: 30000, // 30 seconds\n });\n\n // Add request interceptor for logging\n this.client.interceptors.request.use(\n (config) => {\n console.log(`${LOG_PREFIX} → Request:`, {\n method: config.method?.toUpperCase(),\n url: config.url,\n hasData: !!config.data,\n });\n return config;\n },\n (error) => {\n console.error(`${LOG_PREFIX} ❌ Request setup failed:`, error);\n return Promise.reject(error);\n }\n );\n\n // Add response interceptor for error handling and logging\n this.client.interceptors.response.use(\n (response) => {\n console.log(`${LOG_PREFIX} ← Response:`, {\n status: response.status,\n url: response.config.url,\n dataSize: JSON.stringify(response.data).length,\n });\n return response;\n },\n (error: AxiosError) => {\n if (error.response) {\n console.error(`${LOG_PREFIX} ❌ HTTP Error:`, {\n status: error.response.status,\n statusText: error.response.statusText,\n url: error.config?.url,\n data: error.response.data,\n });\n } else if (error.request) {\n console.error(`${LOG_PREFIX} ❌ Network Error:`, {\n message: error.message,\n url: error.config?.url,\n baseURL: error.config?.baseURL,\n });\n } else {\n console.error(`${LOG_PREFIX} ❌ Request Error:`, error.message);\n }\n return Promise.reject(error);\n }\n );\n\n console.log(`${LOG_PREFIX} ✅ API client initialized successfully`);\n }\n\n /**\n * Get widget configuration from the API\n */\n async getConfig(): Promise<WidgetConfig> {\n console.log(`${LOG_PREFIX} Fetching widget configuration...`);\n\n try {\n const startTime = Date.now();\n const response = await this.client.get<ApiResponse<WidgetConfig>>(\n '/chatbot-settings/widget/config',\n {\n headers: { 'X-API-Key': this.apiKey },\n }\n );\n const duration = Date.now() - startTime;\n\n console.log(`${LOG_PREFIX} ✅ Config loaded in ${duration}ms:`, {\n theme: response.data.data.theme,\n primaryColor: response.data.data.primaryColor,\n brandName: response.data.data.brandName,\n });\n\n return response.data.data;\n } catch (error) {\n console.error(`${LOG_PREFIX} ❌ Failed to get config:`, error);\n throw new Error('Failed to load widget configuration');\n }\n }\n\n /**\n * Start a new chat session\n * Note: Backend manages sessions automatically, we just generate a client-side ID\n */\n async startSession(): Promise<string> {\n console.log(`${LOG_PREFIX} Starting new chat session (client-side)...`);\n\n try {\n // Generate a unique session ID client-side\n const sessionId = `session_${Date.now()}_${Math.random().toString(36).substring(7)}`;\n this.sessionId = sessionId;\n\n console.log(`${LOG_PREFIX} ✅ Session created:`, sessionId);\n\n return this.sessionId;\n } catch (error) {\n console.error(`${LOG_PREFIX} ❌ Failed to start session:`, error);\n throw new Error('Failed to start chat session');\n }\n }\n\n /**\n * Send a message to the AI\n */\n async sendMessage(message: string, sessionId: string): Promise<string> {\n console.log(`${LOG_PREFIX} Sending message:`, {\n sessionId,\n messageLength: message.length,\n preview: message.substring(0, 50) + (message.length > 50 ? '...' : ''),\n });\n\n try {\n const startTime = Date.now();\n const response = await this.client.post<ApiResponse<ChatResponse>>(\n '/chat/widget',\n {\n apiKey: this.apiKey,\n message,\n sessionId,\n }\n );\n const duration = Date.now() - startTime;\n\n const aiResponse = response.data.data.message;\n console.log(`${LOG_PREFIX} ✅ AI response received in ${duration}ms:`, {\n responseLength: aiResponse.length,\n preview: aiResponse.substring(0, 50) + (aiResponse.length > 50 ? '...' : ''),\n });\n\n return aiResponse;\n } catch (error) {\n console.error(`${LOG_PREFIX} ❌ Failed to send message:`, error);\n throw new Error('Failed to send message');\n }\n }\n\n /**\n * End the current chat session\n * Note: Backend doesn't have explicit session end, sessions timeout automatically\n */\n async endSession(sessionId: string): Promise<void> {\n console.log(`${LOG_PREFIX} Ending session (client-side only):`, sessionId);\n\n try {\n this.sessionId = null;\n console.log(`${LOG_PREFIX} ✅ Session ended successfully`);\n } catch (error) {\n console.error(`${LOG_PREFIX} ⚠️ Failed to end session:`, error);\n // Don't throw - session will timeout anyway\n }\n }\n\n /**\n * Send heartbeat to keep session alive\n */\n async sendHeartbeat(sessionId: string): Promise<void> {\n console.log(`${LOG_PREFIX} Sending heartbeat for session:`, sessionId);\n\n try {\n // Send special heartbeat message\n await this.client.post('/chat/widget', {\n apiKey: this.apiKey,\n message: '__HEARTBEAT__',\n sessionId,\n });\n console.log(`${LOG_PREFIX} ✅ Heartbeat sent successfully`);\n } catch (error) {\n console.error(`${LOG_PREFIX} ⚠️ Heartbeat failed (will retry):`, error);\n // Don't throw - will retry on next heartbeat\n }\n }\n\n /**\n * Get the current session ID\n */\n getSessionId(): string | null {\n console.log(`${LOG_PREFIX} Current session ID:`, this.sessionId || 'none');\n return this.sessionId;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
2
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
3
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
4
|
+
/**
|
|
5
|
+
* Session Manager
|
|
6
|
+
* Handles session lifecycle, heartbeat, and cleanup
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export class SessionManager {
|
|
10
|
+
constructor(api, callbacks) {
|
|
11
|
+
_defineProperty(this, "api", void 0);
|
|
12
|
+
_defineProperty(this, "sessionId", null);
|
|
13
|
+
_defineProperty(this, "heartbeatInterval", null);
|
|
14
|
+
_defineProperty(this, "heartbeatIntervalMs", 30000);
|
|
15
|
+
// 30 seconds
|
|
16
|
+
_defineProperty(this, "onSessionStart", void 0);
|
|
17
|
+
_defineProperty(this, "onSessionEnd", void 0);
|
|
18
|
+
this.api = api;
|
|
19
|
+
this.onSessionStart = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onSessionStart;
|
|
20
|
+
this.onSessionEnd = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onSessionEnd;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Start a new session
|
|
25
|
+
*/
|
|
26
|
+
async start() {
|
|
27
|
+
try {
|
|
28
|
+
var _this$onSessionStart;
|
|
29
|
+
// End existing session if any
|
|
30
|
+
if (this.sessionId) {
|
|
31
|
+
await this.end();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Start new session
|
|
35
|
+
this.sessionId = await this.api.startSession();
|
|
36
|
+
|
|
37
|
+
// Start heartbeat
|
|
38
|
+
this.startHeartbeat();
|
|
39
|
+
|
|
40
|
+
// Notify callback
|
|
41
|
+
(_this$onSessionStart = this.onSessionStart) === null || _this$onSessionStart === void 0 || _this$onSessionStart.call(this, this.sessionId);
|
|
42
|
+
return this.sessionId;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error('[SessionManager] Failed to start session:', error);
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* End the current session
|
|
51
|
+
*/
|
|
52
|
+
async end() {
|
|
53
|
+
if (!this.sessionId) return;
|
|
54
|
+
try {
|
|
55
|
+
var _this$onSessionEnd;
|
|
56
|
+
// Stop heartbeat
|
|
57
|
+
this.stopHeartbeat();
|
|
58
|
+
|
|
59
|
+
// End session on server
|
|
60
|
+
await this.api.endSession(this.sessionId);
|
|
61
|
+
|
|
62
|
+
// Notify callback
|
|
63
|
+
(_this$onSessionEnd = this.onSessionEnd) === null || _this$onSessionEnd === void 0 || _this$onSessionEnd.call(this, this.sessionId);
|
|
64
|
+
this.sessionId = null;
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error('[SessionManager] Failed to end session:', error);
|
|
67
|
+
// Still clear local session
|
|
68
|
+
this.sessionId = null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Start sending heartbeats to keep session alive
|
|
74
|
+
*/
|
|
75
|
+
startHeartbeat() {
|
|
76
|
+
if (this.heartbeatInterval) {
|
|
77
|
+
clearInterval(this.heartbeatInterval);
|
|
78
|
+
}
|
|
79
|
+
this.heartbeatInterval = setInterval(() => {
|
|
80
|
+
if (this.sessionId) {
|
|
81
|
+
this.api.sendHeartbeat(this.sessionId).catch(error => {
|
|
82
|
+
console.error('[SessionManager] Heartbeat failed:', error);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}, this.heartbeatIntervalMs);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Stop sending heartbeats
|
|
90
|
+
*/
|
|
91
|
+
stopHeartbeat() {
|
|
92
|
+
if (this.heartbeatInterval) {
|
|
93
|
+
clearInterval(this.heartbeatInterval);
|
|
94
|
+
this.heartbeatInterval = null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get the current session ID
|
|
100
|
+
*/
|
|
101
|
+
getSessionId() {
|
|
102
|
+
return this.sessionId;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Check if a session is active
|
|
107
|
+
*/
|
|
108
|
+
isActive() {
|
|
109
|
+
return this.sessionId !== null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Cleanup on unmount
|
|
114
|
+
*/
|
|
115
|
+
cleanup() {
|
|
116
|
+
this.stopHeartbeat();
|
|
117
|
+
if (this.sessionId) {
|
|
118
|
+
// Fire and forget - don't wait for response
|
|
119
|
+
this.api.endSession(this.sessionId).catch(() => {});
|
|
120
|
+
this.sessionId = null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=SessionManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["SessionManager","constructor","api","callbacks","_defineProperty","onSessionStart","onSessionEnd","start","_this$onSessionStart","sessionId","end","startSession","startHeartbeat","call","error","console","_this$onSessionEnd","stopHeartbeat","endSession","heartbeatInterval","clearInterval","setInterval","sendHeartbeat","catch","heartbeatIntervalMs","getSessionId","isActive","cleanup"],"sources":["SessionManager.ts"],"sourcesContent":["/**\n * Session Manager\n * Handles session lifecycle, heartbeat, and cleanup\n */\n\nimport { LinguAPI } from './LinguAPI';\n\nexport class SessionManager {\n private api: LinguAPI;\n private sessionId: string | null = null;\n private heartbeatInterval: NodeJS.Timeout | null = null;\n private heartbeatIntervalMs: number = 30000; // 30 seconds\n\n private onSessionStart?: (sessionId: string) => void;\n private onSessionEnd?: (sessionId: string) => void;\n\n constructor(\n api: LinguAPI,\n callbacks?: {\n onSessionStart?: (sessionId: string) => void;\n onSessionEnd?: (sessionId: string) => void;\n }\n ) {\n this.api = api;\n this.onSessionStart = callbacks?.onSessionStart;\n this.onSessionEnd = callbacks?.onSessionEnd;\n }\n\n /**\n * Start a new session\n */\n async start(): Promise<string> {\n try {\n // End existing session if any\n if (this.sessionId) {\n await this.end();\n }\n\n // Start new session\n this.sessionId = await this.api.startSession();\n\n // Start heartbeat\n this.startHeartbeat();\n\n // Notify callback\n this.onSessionStart?.(this.sessionId);\n\n return this.sessionId;\n } catch (error) {\n console.error('[SessionManager] Failed to start session:', error);\n throw error;\n }\n }\n\n /**\n * End the current session\n */\n async end(): Promise<void> {\n if (!this.sessionId) return;\n\n try {\n // Stop heartbeat\n this.stopHeartbeat();\n\n // End session on server\n await this.api.endSession(this.sessionId);\n\n // Notify callback\n this.onSessionEnd?.(this.sessionId);\n\n this.sessionId = null;\n } catch (error) {\n console.error('[SessionManager] Failed to end session:', error);\n // Still clear local session\n this.sessionId = null;\n }\n }\n\n /**\n * Start sending heartbeats to keep session alive\n */\n private startHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n }\n\n this.heartbeatInterval = setInterval(() => {\n if (this.sessionId) {\n this.api.sendHeartbeat(this.sessionId).catch((error) => {\n console.error('[SessionManager] Heartbeat failed:', error);\n });\n }\n }, this.heartbeatIntervalMs);\n }\n\n /**\n * Stop sending heartbeats\n */\n private stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n }\n }\n\n /**\n * Get the current session ID\n */\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n /**\n * Check if a session is active\n */\n isActive(): boolean {\n return this.sessionId !== null;\n }\n\n /**\n * Cleanup on unmount\n */\n cleanup(): void {\n this.stopHeartbeat();\n if (this.sessionId) {\n // Fire and forget - don't wait for response\n this.api.endSession(this.sessionId).catch(() => { });\n this.sessionId = null;\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage Manager
|
|
3
|
+
* Handles message persistence using AsyncStorage
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
7
|
+
const STORAGE_KEY_PREFIX = '@lingu_chat_';
|
|
8
|
+
const MAX_STORED_MESSAGES = 100; // Limit stored messages per session
|
|
9
|
+
|
|
10
|
+
export class StorageManager {
|
|
11
|
+
/**
|
|
12
|
+
* Save messages for a session
|
|
13
|
+
*/
|
|
14
|
+
static async saveMessages(sessionId, messages) {
|
|
15
|
+
try {
|
|
16
|
+
const key = `${STORAGE_KEY_PREFIX}${sessionId}`;
|
|
17
|
+
// Keep only the last MAX_STORED_MESSAGES
|
|
18
|
+
const messagesToStore = messages.slice(-MAX_STORED_MESSAGES);
|
|
19
|
+
await AsyncStorage.setItem(key, JSON.stringify(messagesToStore));
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error('[StorageManager] Failed to save messages:', error);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Load messages for a session
|
|
27
|
+
*/
|
|
28
|
+
static async loadMessages(sessionId) {
|
|
29
|
+
try {
|
|
30
|
+
const key = `${STORAGE_KEY_PREFIX}${sessionId}`;
|
|
31
|
+
const data = await AsyncStorage.getItem(key);
|
|
32
|
+
if (data) {
|
|
33
|
+
const messages = JSON.parse(data);
|
|
34
|
+
// Convert timestamp strings back to Date objects
|
|
35
|
+
return messages.map(msg => ({
|
|
36
|
+
...msg,
|
|
37
|
+
timestamp: new Date(msg.timestamp)
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
return [];
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error('[StorageManager] Failed to load messages:', error);
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Clear messages for a session
|
|
49
|
+
*/
|
|
50
|
+
static async clearMessages(sessionId) {
|
|
51
|
+
try {
|
|
52
|
+
const key = `${STORAGE_KEY_PREFIX}${sessionId}`;
|
|
53
|
+
await AsyncStorage.removeItem(key);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error('[StorageManager] Failed to clear messages:', error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get all stored session IDs
|
|
61
|
+
*/
|
|
62
|
+
static async getAllSessionIds() {
|
|
63
|
+
try {
|
|
64
|
+
const keys = await AsyncStorage.getAllKeys();
|
|
65
|
+
return keys.filter(key => key.startsWith(STORAGE_KEY_PREFIX)).map(key => key.replace(STORAGE_KEY_PREFIX, ''));
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error('[StorageManager] Failed to get session IDs:', error);
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Save current session ID
|
|
74
|
+
*/
|
|
75
|
+
static async saveCurrentSessionId(sessionId) {
|
|
76
|
+
try {
|
|
77
|
+
await AsyncStorage.setItem(`${STORAGE_KEY_PREFIX}current`, sessionId);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error('[StorageManager] Failed to save current session ID:', error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Get current session ID
|
|
85
|
+
*/
|
|
86
|
+
static async getCurrentSessionId() {
|
|
87
|
+
try {
|
|
88
|
+
return await AsyncStorage.getItem(`${STORAGE_KEY_PREFIX}current`);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error('[StorageManager] Failed to get current session ID:', error);
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Clear all chat data
|
|
97
|
+
*/
|
|
98
|
+
static async clearAll() {
|
|
99
|
+
try {
|
|
100
|
+
const keys = await AsyncStorage.getAllKeys();
|
|
101
|
+
const chatKeys = keys.filter(key => key.startsWith(STORAGE_KEY_PREFIX));
|
|
102
|
+
await AsyncStorage.multiRemove(chatKeys);
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error('[StorageManager] Failed to clear all data:', error);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=StorageManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["AsyncStorage","STORAGE_KEY_PREFIX","MAX_STORED_MESSAGES","StorageManager","saveMessages","sessionId","messages","key","messagesToStore","slice","setItem","JSON","stringify","error","console","loadMessages","data","getItem","parse","map","msg","timestamp","Date","clearMessages","removeItem","getAllSessionIds","keys","getAllKeys","filter","startsWith","replace","saveCurrentSessionId","getCurrentSessionId","clearAll","chatKeys","multiRemove"],"sources":["StorageManager.ts"],"sourcesContent":["/**\n * Storage Manager\n * Handles message persistence using AsyncStorage\n */\n\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport type { Message } from '../types';\n\nconst STORAGE_KEY_PREFIX = '@lingu_chat_';\nconst MAX_STORED_MESSAGES = 100; // Limit stored messages per session\n\nexport class StorageManager {\n /**\n * Save messages for a session\n */\n static async saveMessages(sessionId: string, messages: Message[]): Promise<void> {\n try {\n const key = `${STORAGE_KEY_PREFIX}${sessionId}`;\n // Keep only the last MAX_STORED_MESSAGES\n const messagesToStore = messages.slice(-MAX_STORED_MESSAGES);\n await AsyncStorage.setItem(key, JSON.stringify(messagesToStore));\n } catch (error) {\n console.error('[StorageManager] Failed to save messages:', error);\n }\n }\n\n /**\n * Load messages for a session\n */\n static async loadMessages(sessionId: string): Promise<Message[]> {\n try {\n const key = `${STORAGE_KEY_PREFIX}${sessionId}`;\n const data = await AsyncStorage.getItem(key);\n if (data) {\n const messages = JSON.parse(data);\n // Convert timestamp strings back to Date objects\n return messages.map((msg: any) => ({\n ...msg,\n timestamp: new Date(msg.timestamp),\n }));\n }\n return [];\n } catch (error) {\n console.error('[StorageManager] Failed to load messages:', error);\n return [];\n }\n }\n\n /**\n * Clear messages for a session\n */\n static async clearMessages(sessionId: string): Promise<void> {\n try {\n const key = `${STORAGE_KEY_PREFIX}${sessionId}`;\n await AsyncStorage.removeItem(key);\n } catch (error) {\n console.error('[StorageManager] Failed to clear messages:', error);\n }\n }\n\n /**\n * Get all stored session IDs\n */\n static async getAllSessionIds(): Promise<string[]> {\n try {\n const keys = await AsyncStorage.getAllKeys();\n return keys\n .filter((key) => key.startsWith(STORAGE_KEY_PREFIX))\n .map((key) => key.replace(STORAGE_KEY_PREFIX, ''));\n } catch (error) {\n console.error('[StorageManager] Failed to get session IDs:', error);\n return [];\n }\n }\n\n /**\n * Save current session ID\n */\n static async saveCurrentSessionId(sessionId: string): Promise<void> {\n try {\n await AsyncStorage.setItem(`${STORAGE_KEY_PREFIX}current`, sessionId);\n } catch (error) {\n console.error('[StorageManager] Failed to save current session ID:', error);\n }\n }\n\n /**\n * Get current session ID\n */\n static async getCurrentSessionId(): Promise<string | null> {\n try {\n return await AsyncStorage.getItem(`${STORAGE_KEY_PREFIX}current`);\n } catch (error) {\n console.error('[StorageManager] Failed to get current session ID:', error);\n return null;\n }\n }\n\n /**\n * Clear all chat data\n */\n static async clearAll(): Promise<void> {\n try {\n const keys = await AsyncStorage.getAllKeys();\n const chatKeys = keys.filter((key) => key.startsWith(STORAGE_KEY_PREFIX));\n await AsyncStorage.multiRemove(chatKeys);\n } catch (error) {\n console.error('[StorageManager] Failed to clear all data:', error);\n }\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;;AAEA,OAAOA,YAAY,MAAM,2CAA2C;AAGpE,MAAMC,kBAAkB,GAAG,cAAc;AACzC,MAAMC,mBAAmB,GAAG,GAAG,CAAC,CAAC;;AAEjC,OAAO,MAAMC,cAAc,CAAC;EACzB;AACH;AACA;EACG,aAAaC,YAAYA,CAACC,SAAiB,EAAEC,QAAmB,EAAiB;IAC9E,IAAI;MACD,MAAMC,GAAG,GAAG,GAAGN,kBAAkB,GAAGI,SAAS,EAAE;MAC/C;MACA,MAAMG,eAAe,GAAGF,QAAQ,CAACG,KAAK,CAAC,CAACP,mBAAmB,CAAC;MAC5D,MAAMF,YAAY,CAACU,OAAO,CAACH,GAAG,EAAEI,IAAI,CAACC,SAAS,CAACJ,eAAe,CAAC,CAAC;IACnE,CAAC,CAAC,OAAOK,KAAK,EAAE;MACbC,OAAO,CAACD,KAAK,CAAC,2CAA2C,EAAEA,KAAK,CAAC;IACpE;EACH;;EAEA;AACH;AACA;EACG,aAAaE,YAAYA,CAACV,SAAiB,EAAsB;IAC9D,IAAI;MACD,MAAME,GAAG,GAAG,GAAGN,kBAAkB,GAAGI,SAAS,EAAE;MAC/C,MAAMW,IAAI,GAAG,MAAMhB,YAAY,CAACiB,OAAO,CAACV,GAAG,CAAC;MAC5C,IAAIS,IAAI,EAAE;QACP,MAAMV,QAAQ,GAAGK,IAAI,CAACO,KAAK,CAACF,IAAI,CAAC;QACjC;QACA,OAAOV,QAAQ,CAACa,GAAG,CAAEC,GAAQ,KAAM;UAChC,GAAGA,GAAG;UACNC,SAAS,EAAE,IAAIC,IAAI,CAACF,GAAG,CAACC,SAAS;QACpC,CAAC,CAAC,CAAC;MACN;MACA,OAAO,EAAE;IACZ,CAAC,CAAC,OAAOR,KAAK,EAAE;MACbC,OAAO,CAACD,KAAK,CAAC,2CAA2C,EAAEA,KAAK,CAAC;MACjE,OAAO,EAAE;IACZ;EACH;;EAEA;AACH;AACA;EACG,aAAaU,aAAaA,CAAClB,SAAiB,EAAiB;IAC1D,IAAI;MACD,MAAME,GAAG,GAAG,GAAGN,kBAAkB,GAAGI,SAAS,EAAE;MAC/C,MAAML,YAAY,CAACwB,UAAU,CAACjB,GAAG,CAAC;IACrC,CAAC,CAAC,OAAOM,KAAK,EAAE;MACbC,OAAO,CAACD,KAAK,CAAC,4CAA4C,EAAEA,KAAK,CAAC;IACrE;EACH;;EAEA;AACH;AACA;EACG,aAAaY,gBAAgBA,CAAA,EAAsB;IAChD,IAAI;MACD,MAAMC,IAAI,GAAG,MAAM1B,YAAY,CAAC2B,UAAU,CAAC,CAAC;MAC5C,OAAOD,IAAI,CACPE,MAAM,CAAErB,GAAG,IAAKA,GAAG,CAACsB,UAAU,CAAC5B,kBAAkB,CAAC,CAAC,CACnDkB,GAAG,CAAEZ,GAAG,IAAKA,GAAG,CAACuB,OAAO,CAAC7B,kBAAkB,EAAE,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,OAAOY,KAAK,EAAE;MACbC,OAAO,CAACD,KAAK,CAAC,6CAA6C,EAAEA,KAAK,CAAC;MACnE,OAAO,EAAE;IACZ;EACH;;EAEA;AACH;AACA;EACG,aAAakB,oBAAoBA,CAAC1B,SAAiB,EAAiB;IACjE,IAAI;MACD,MAAML,YAAY,CAACU,OAAO,CAAC,GAAGT,kBAAkB,SAAS,EAAEI,SAAS,CAAC;IACxE,CAAC,CAAC,OAAOQ,KAAK,EAAE;MACbC,OAAO,CAACD,KAAK,CAAC,qDAAqD,EAAEA,KAAK,CAAC;IAC9E;EACH;;EAEA;AACH;AACA;EACG,aAAamB,mBAAmBA,CAAA,EAA2B;IACxD,IAAI;MACD,OAAO,MAAMhC,YAAY,CAACiB,OAAO,CAAC,GAAGhB,kBAAkB,SAAS,CAAC;IACpE,CAAC,CAAC,OAAOY,KAAK,EAAE;MACbC,OAAO,CAACD,KAAK,CAAC,oDAAoD,EAAEA,KAAK,CAAC;MAC1E,OAAO,IAAI;IACd;EACH;;EAEA;AACH;AACA;EACG,aAAaoB,QAAQA,CAAA,EAAkB;IACpC,IAAI;MACD,MAAMP,IAAI,GAAG,MAAM1B,YAAY,CAAC2B,UAAU,CAAC,CAAC;MAC5C,MAAMO,QAAQ,GAAGR,IAAI,CAACE,MAAM,CAAErB,GAAG,IAAKA,GAAG,CAACsB,UAAU,CAAC5B,kBAAkB,CAAC,CAAC;MACzE,MAAMD,YAAY,CAACmC,WAAW,CAACD,QAAQ,CAAC;IAC3C,CAAC,CAAC,OAAOrB,KAAK,EAAE;MACbC,OAAO,CAACD,KAAK,CAAC,4CAA4C,EAAEA,KAAK,CAAC;IACrE;EACH;AACH","ignoreList":[]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Provider
|
|
3
|
+
* Provides theme context to all child components
|
|
4
|
+
* Theme is derived from backend widget configuration
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React, { createContext, useContext, useMemo } from 'react';
|
|
8
|
+
import { createTheme } from './theme';
|
|
9
|
+
const ThemeContext = /*#__PURE__*/createContext(undefined);
|
|
10
|
+
export const ThemeProvider = ({
|
|
11
|
+
config,
|
|
12
|
+
children
|
|
13
|
+
}) => {
|
|
14
|
+
const theme = useMemo(() => {
|
|
15
|
+
if (!config) {
|
|
16
|
+
// Return default theme if config not loaded yet
|
|
17
|
+
return createTheme();
|
|
18
|
+
}
|
|
19
|
+
return createTheme(config.primaryColor, config.backgroundColor, config.textColor, config.theme === 'dark' ? 'dark' : 'light');
|
|
20
|
+
}, [config]);
|
|
21
|
+
const value = useMemo(() => ({
|
|
22
|
+
theme,
|
|
23
|
+
config
|
|
24
|
+
}), [theme, config]);
|
|
25
|
+
return /*#__PURE__*/React.createElement(ThemeContext.Provider, {
|
|
26
|
+
value: value
|
|
27
|
+
}, children);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Hook to access theme context
|
|
32
|
+
*/
|
|
33
|
+
export const useTheme = () => {
|
|
34
|
+
const context = useContext(ThemeContext);
|
|
35
|
+
if (context === undefined) {
|
|
36
|
+
throw new Error('useTheme must be used within a ThemeProvider');
|
|
37
|
+
}
|
|
38
|
+
return context;
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=ThemeProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","createContext","useContext","useMemo","createTheme","ThemeContext","undefined","ThemeProvider","config","children","theme","primaryColor","backgroundColor","textColor","value","createElement","Provider","useTheme","context","Error"],"sources":["ThemeProvider.tsx"],"sourcesContent":["/**\n * Theme Provider\n * Provides theme context to all child components\n * Theme is derived from backend widget configuration\n */\n\nimport React, { createContext, useContext, useMemo, ReactNode } from 'react';\nimport { createTheme, Theme } from './theme';\nimport type { WidgetConfig } from '../types';\n\ninterface ThemeContextValue {\n theme: Theme;\n config: WidgetConfig | null;\n}\n\nconst ThemeContext = createContext<ThemeContextValue | undefined>(undefined);\n\ninterface ThemeProviderProps {\n config: WidgetConfig | null;\n children: ReactNode;\n}\n\nexport const ThemeProvider: React.FC<ThemeProviderProps> = ({ config, children }) => {\n const theme = useMemo(() => {\n if (!config) {\n // Return default theme if config not loaded yet\n return createTheme();\n }\n\n return createTheme(\n config.primaryColor,\n config.backgroundColor,\n config.textColor,\n config.theme === 'dark' ? 'dark' : 'light'\n );\n }, [config]);\n\n const value = useMemo(\n () => ({\n theme,\n config,\n }),\n [theme, config]\n );\n\n return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;\n};\n\n/**\n * Hook to access theme context\n */\nexport const useTheme = (): ThemeContextValue => {\n const context = useContext(ThemeContext);\n if (context === undefined) {\n throw new Error('useTheme must be used within a ThemeProvider');\n }\n return context;\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;;AAEA,OAAOA,KAAK,IAAIC,aAAa,EAAEC,UAAU,EAAEC,OAAO,QAAmB,OAAO;AAC5E,SAASC,WAAW,QAAe,SAAS;AAQ5C,MAAMC,YAAY,gBAAGJ,aAAa,CAAgCK,SAAS,CAAC;AAO5E,OAAO,MAAMC,aAA2C,GAAGA,CAAC;EAAEC,MAAM;EAAEC;AAAS,CAAC,KAAK;EAClF,MAAMC,KAAK,GAAGP,OAAO,CAAC,MAAM;IACzB,IAAI,CAACK,MAAM,EAAE;MACV;MACA,OAAOJ,WAAW,CAAC,CAAC;IACvB;IAEA,OAAOA,WAAW,CACfI,MAAM,CAACG,YAAY,EACnBH,MAAM,CAACI,eAAe,EACtBJ,MAAM,CAACK,SAAS,EAChBL,MAAM,CAACE,KAAK,KAAK,MAAM,GAAG,MAAM,GAAG,OACtC,CAAC;EACJ,CAAC,EAAE,CAACF,MAAM,CAAC,CAAC;EAEZ,MAAMM,KAAK,GAAGX,OAAO,CAClB,OAAO;IACJO,KAAK;IACLF;EACH,CAAC,CAAC,EACF,CAACE,KAAK,EAAEF,MAAM,CACjB,CAAC;EAED,oBAAOR,KAAA,CAAAe,aAAA,CAACV,YAAY,CAACW,QAAQ;IAACF,KAAK,EAAEA;EAAM,GAAEL,QAAgC,CAAC;AACjF,CAAC;;AAED;AACA;AACA;AACA,OAAO,MAAMQ,QAAQ,GAAGA,CAAA,KAAyB;EAC9C,MAAMC,OAAO,GAAGhB,UAAU,CAACG,YAAY,CAAC;EACxC,IAAIa,OAAO,KAAKZ,SAAS,EAAE;IACxB,MAAM,IAAIa,KAAK,CAAC,8CAA8C,CAAC;EAClE;EACA,OAAOD,OAAO;AACjB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["/**\n * Theme exports\n */\n\nexport * from './theme';\nexport * from './ThemeProvider';\n"],"mappings":"AAAA;AACA;AACA;;AAEA,cAAc,SAAS;AACvB,cAAc,iBAAiB","ignoreList":[]}
|