@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,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.LinguAPI = void 0;
|
|
7
|
+
var _axios = _interopRequireDefault(require("axios"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
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; }
|
|
10
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
11
|
+
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); } /**
|
|
12
|
+
* Lingu API Client
|
|
13
|
+
* Handles all communication with the Lingu backend API
|
|
14
|
+
* Now with comprehensive logging
|
|
15
|
+
*/
|
|
16
|
+
const LOG_PREFIX = '[LinguAPI]';
|
|
17
|
+
class LinguAPI {
|
|
18
|
+
constructor(apiKey, baseURL = 'https://api.uselingu.app/api') {
|
|
19
|
+
_defineProperty(this, "client", void 0);
|
|
20
|
+
_defineProperty(this, "apiKey", void 0);
|
|
21
|
+
_defineProperty(this, "sessionId", null);
|
|
22
|
+
console.log(`${LOG_PREFIX} Initializing API client:`, {
|
|
23
|
+
baseURL,
|
|
24
|
+
apiKeyPrefix: apiKey.substring(0, 20) + '...'
|
|
25
|
+
});
|
|
26
|
+
this.apiKey = apiKey;
|
|
27
|
+
this.client = _axios.default.create({
|
|
28
|
+
baseURL,
|
|
29
|
+
headers: {
|
|
30
|
+
'Content-Type': 'application/json'
|
|
31
|
+
},
|
|
32
|
+
timeout: 30000 // 30 seconds
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Add request interceptor for logging
|
|
36
|
+
this.client.interceptors.request.use(config => {
|
|
37
|
+
var _config$method;
|
|
38
|
+
console.log(`${LOG_PREFIX} → Request:`, {
|
|
39
|
+
method: (_config$method = config.method) === null || _config$method === void 0 ? void 0 : _config$method.toUpperCase(),
|
|
40
|
+
url: config.url,
|
|
41
|
+
hasData: !!config.data
|
|
42
|
+
});
|
|
43
|
+
return config;
|
|
44
|
+
}, error => {
|
|
45
|
+
console.error(`${LOG_PREFIX} ❌ Request setup failed:`, error);
|
|
46
|
+
return Promise.reject(error);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Add response interceptor for error handling and logging
|
|
50
|
+
this.client.interceptors.response.use(response => {
|
|
51
|
+
console.log(`${LOG_PREFIX} ← Response:`, {
|
|
52
|
+
status: response.status,
|
|
53
|
+
url: response.config.url,
|
|
54
|
+
dataSize: JSON.stringify(response.data).length
|
|
55
|
+
});
|
|
56
|
+
return response;
|
|
57
|
+
}, error => {
|
|
58
|
+
if (error.response) {
|
|
59
|
+
var _error$config;
|
|
60
|
+
console.error(`${LOG_PREFIX} ❌ HTTP Error:`, {
|
|
61
|
+
status: error.response.status,
|
|
62
|
+
statusText: error.response.statusText,
|
|
63
|
+
url: (_error$config = error.config) === null || _error$config === void 0 ? void 0 : _error$config.url,
|
|
64
|
+
data: error.response.data
|
|
65
|
+
});
|
|
66
|
+
} else if (error.request) {
|
|
67
|
+
var _error$config2, _error$config3;
|
|
68
|
+
console.error(`${LOG_PREFIX} ❌ Network Error:`, {
|
|
69
|
+
message: error.message,
|
|
70
|
+
url: (_error$config2 = error.config) === null || _error$config2 === void 0 ? void 0 : _error$config2.url,
|
|
71
|
+
baseURL: (_error$config3 = error.config) === null || _error$config3 === void 0 ? void 0 : _error$config3.baseURL
|
|
72
|
+
});
|
|
73
|
+
} else {
|
|
74
|
+
console.error(`${LOG_PREFIX} ❌ Request Error:`, error.message);
|
|
75
|
+
}
|
|
76
|
+
return Promise.reject(error);
|
|
77
|
+
});
|
|
78
|
+
console.log(`${LOG_PREFIX} ✅ API client initialized successfully`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get widget configuration from the API
|
|
83
|
+
*/
|
|
84
|
+
async getConfig() {
|
|
85
|
+
console.log(`${LOG_PREFIX} Fetching widget configuration...`);
|
|
86
|
+
try {
|
|
87
|
+
const startTime = Date.now();
|
|
88
|
+
const response = await this.client.get('/chatbot-settings/widget/config', {
|
|
89
|
+
headers: {
|
|
90
|
+
'X-API-Key': this.apiKey
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
const duration = Date.now() - startTime;
|
|
94
|
+
console.log(`${LOG_PREFIX} ✅ Config loaded in ${duration}ms:`, {
|
|
95
|
+
theme: response.data.data.theme,
|
|
96
|
+
primaryColor: response.data.data.primaryColor,
|
|
97
|
+
brandName: response.data.data.brandName
|
|
98
|
+
});
|
|
99
|
+
return response.data.data;
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error(`${LOG_PREFIX} ❌ Failed to get config:`, error);
|
|
102
|
+
throw new Error('Failed to load widget configuration');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Start a new chat session
|
|
108
|
+
* Note: Backend manages sessions automatically, we just generate a client-side ID
|
|
109
|
+
*/
|
|
110
|
+
async startSession() {
|
|
111
|
+
console.log(`${LOG_PREFIX} Starting new chat session (client-side)...`);
|
|
112
|
+
try {
|
|
113
|
+
// Generate a unique session ID client-side
|
|
114
|
+
const sessionId = `session_${Date.now()}_${Math.random().toString(36).substring(7)}`;
|
|
115
|
+
this.sessionId = sessionId;
|
|
116
|
+
console.log(`${LOG_PREFIX} ✅ Session created:`, sessionId);
|
|
117
|
+
return this.sessionId;
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.error(`${LOG_PREFIX} ❌ Failed to start session:`, error);
|
|
120
|
+
throw new Error('Failed to start chat session');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Send a message to the AI
|
|
126
|
+
*/
|
|
127
|
+
async sendMessage(message, sessionId) {
|
|
128
|
+
console.log(`${LOG_PREFIX} Sending message:`, {
|
|
129
|
+
sessionId,
|
|
130
|
+
messageLength: message.length,
|
|
131
|
+
preview: message.substring(0, 50) + (message.length > 50 ? '...' : '')
|
|
132
|
+
});
|
|
133
|
+
try {
|
|
134
|
+
const startTime = Date.now();
|
|
135
|
+
const response = await this.client.post('/chat/widget', {
|
|
136
|
+
apiKey: this.apiKey,
|
|
137
|
+
message,
|
|
138
|
+
sessionId
|
|
139
|
+
});
|
|
140
|
+
const duration = Date.now() - startTime;
|
|
141
|
+
const aiResponse = response.data.data.message;
|
|
142
|
+
console.log(`${LOG_PREFIX} ✅ AI response received in ${duration}ms:`, {
|
|
143
|
+
responseLength: aiResponse.length,
|
|
144
|
+
preview: aiResponse.substring(0, 50) + (aiResponse.length > 50 ? '...' : '')
|
|
145
|
+
});
|
|
146
|
+
return aiResponse;
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error(`${LOG_PREFIX} ❌ Failed to send message:`, error);
|
|
149
|
+
throw new Error('Failed to send message');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* End the current chat session
|
|
155
|
+
* Note: Backend doesn't have explicit session end, sessions timeout automatically
|
|
156
|
+
*/
|
|
157
|
+
async endSession(sessionId) {
|
|
158
|
+
console.log(`${LOG_PREFIX} Ending session (client-side only):`, sessionId);
|
|
159
|
+
try {
|
|
160
|
+
this.sessionId = null;
|
|
161
|
+
console.log(`${LOG_PREFIX} ✅ Session ended successfully`);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.error(`${LOG_PREFIX} ⚠️ Failed to end session:`, error);
|
|
164
|
+
// Don't throw - session will timeout anyway
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Send heartbeat to keep session alive
|
|
170
|
+
*/
|
|
171
|
+
async sendHeartbeat(sessionId) {
|
|
172
|
+
console.log(`${LOG_PREFIX} Sending heartbeat for session:`, sessionId);
|
|
173
|
+
try {
|
|
174
|
+
// Send special heartbeat message
|
|
175
|
+
await this.client.post('/chat/widget', {
|
|
176
|
+
apiKey: this.apiKey,
|
|
177
|
+
message: '__HEARTBEAT__',
|
|
178
|
+
sessionId
|
|
179
|
+
});
|
|
180
|
+
console.log(`${LOG_PREFIX} ✅ Heartbeat sent successfully`);
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.error(`${LOG_PREFIX} ⚠️ Heartbeat failed (will retry):`, error);
|
|
183
|
+
// Don't throw - will retry on next heartbeat
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Get the current session ID
|
|
189
|
+
*/
|
|
190
|
+
getSessionId() {
|
|
191
|
+
console.log(`${LOG_PREFIX} Current session ID:`, this.sessionId || 'none');
|
|
192
|
+
return this.sessionId;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
exports.LinguAPI = LinguAPI;
|
|
196
|
+
//# sourceMappingURL=LinguAPI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_axios","_interopRequireDefault","require","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","LOG_PREFIX","LinguAPI","constructor","apiKey","baseURL","console","log","apiKeyPrefix","substring","client","axios","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","exports"],"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,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SessionManager = void 0;
|
|
7
|
+
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; }
|
|
8
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
9
|
+
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); }
|
|
10
|
+
/**
|
|
11
|
+
* Session Manager
|
|
12
|
+
* Handles session lifecycle, heartbeat, and cleanup
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
class SessionManager {
|
|
16
|
+
constructor(api, callbacks) {
|
|
17
|
+
_defineProperty(this, "api", void 0);
|
|
18
|
+
_defineProperty(this, "sessionId", null);
|
|
19
|
+
_defineProperty(this, "heartbeatInterval", null);
|
|
20
|
+
_defineProperty(this, "heartbeatIntervalMs", 30000);
|
|
21
|
+
// 30 seconds
|
|
22
|
+
_defineProperty(this, "onSessionStart", void 0);
|
|
23
|
+
_defineProperty(this, "onSessionEnd", void 0);
|
|
24
|
+
this.api = api;
|
|
25
|
+
this.onSessionStart = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onSessionStart;
|
|
26
|
+
this.onSessionEnd = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onSessionEnd;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Start a new session
|
|
31
|
+
*/
|
|
32
|
+
async start() {
|
|
33
|
+
try {
|
|
34
|
+
var _this$onSessionStart;
|
|
35
|
+
// End existing session if any
|
|
36
|
+
if (this.sessionId) {
|
|
37
|
+
await this.end();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Start new session
|
|
41
|
+
this.sessionId = await this.api.startSession();
|
|
42
|
+
|
|
43
|
+
// Start heartbeat
|
|
44
|
+
this.startHeartbeat();
|
|
45
|
+
|
|
46
|
+
// Notify callback
|
|
47
|
+
(_this$onSessionStart = this.onSessionStart) === null || _this$onSessionStart === void 0 || _this$onSessionStart.call(this, this.sessionId);
|
|
48
|
+
return this.sessionId;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error('[SessionManager] Failed to start session:', error);
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* End the current session
|
|
57
|
+
*/
|
|
58
|
+
async end() {
|
|
59
|
+
if (!this.sessionId) return;
|
|
60
|
+
try {
|
|
61
|
+
var _this$onSessionEnd;
|
|
62
|
+
// Stop heartbeat
|
|
63
|
+
this.stopHeartbeat();
|
|
64
|
+
|
|
65
|
+
// End session on server
|
|
66
|
+
await this.api.endSession(this.sessionId);
|
|
67
|
+
|
|
68
|
+
// Notify callback
|
|
69
|
+
(_this$onSessionEnd = this.onSessionEnd) === null || _this$onSessionEnd === void 0 || _this$onSessionEnd.call(this, this.sessionId);
|
|
70
|
+
this.sessionId = null;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error('[SessionManager] Failed to end session:', error);
|
|
73
|
+
// Still clear local session
|
|
74
|
+
this.sessionId = null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Start sending heartbeats to keep session alive
|
|
80
|
+
*/
|
|
81
|
+
startHeartbeat() {
|
|
82
|
+
if (this.heartbeatInterval) {
|
|
83
|
+
clearInterval(this.heartbeatInterval);
|
|
84
|
+
}
|
|
85
|
+
this.heartbeatInterval = setInterval(() => {
|
|
86
|
+
if (this.sessionId) {
|
|
87
|
+
this.api.sendHeartbeat(this.sessionId).catch(error => {
|
|
88
|
+
console.error('[SessionManager] Heartbeat failed:', error);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}, this.heartbeatIntervalMs);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Stop sending heartbeats
|
|
96
|
+
*/
|
|
97
|
+
stopHeartbeat() {
|
|
98
|
+
if (this.heartbeatInterval) {
|
|
99
|
+
clearInterval(this.heartbeatInterval);
|
|
100
|
+
this.heartbeatInterval = null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Get the current session ID
|
|
106
|
+
*/
|
|
107
|
+
getSessionId() {
|
|
108
|
+
return this.sessionId;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Check if a session is active
|
|
113
|
+
*/
|
|
114
|
+
isActive() {
|
|
115
|
+
return this.sessionId !== null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Cleanup on unmount
|
|
120
|
+
*/
|
|
121
|
+
cleanup() {
|
|
122
|
+
this.stopHeartbeat();
|
|
123
|
+
if (this.sessionId) {
|
|
124
|
+
// Fire and forget - don't wait for response
|
|
125
|
+
this.api.endSession(this.sessionId).catch(() => {});
|
|
126
|
+
this.sessionId = null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
exports.SessionManager = SessionManager;
|
|
131
|
+
//# 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","exports"],"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,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.StorageManager = void 0;
|
|
7
|
+
var _asyncStorage = _interopRequireDefault(require("@react-native-async-storage/async-storage"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
/**
|
|
10
|
+
* Storage Manager
|
|
11
|
+
* Handles message persistence using AsyncStorage
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const STORAGE_KEY_PREFIX = '@lingu_chat_';
|
|
15
|
+
const MAX_STORED_MESSAGES = 100; // Limit stored messages per session
|
|
16
|
+
|
|
17
|
+
class StorageManager {
|
|
18
|
+
/**
|
|
19
|
+
* Save messages for a session
|
|
20
|
+
*/
|
|
21
|
+
static async saveMessages(sessionId, messages) {
|
|
22
|
+
try {
|
|
23
|
+
const key = `${STORAGE_KEY_PREFIX}${sessionId}`;
|
|
24
|
+
// Keep only the last MAX_STORED_MESSAGES
|
|
25
|
+
const messagesToStore = messages.slice(-MAX_STORED_MESSAGES);
|
|
26
|
+
await _asyncStorage.default.setItem(key, JSON.stringify(messagesToStore));
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error('[StorageManager] Failed to save messages:', error);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Load messages for a session
|
|
34
|
+
*/
|
|
35
|
+
static async loadMessages(sessionId) {
|
|
36
|
+
try {
|
|
37
|
+
const key = `${STORAGE_KEY_PREFIX}${sessionId}`;
|
|
38
|
+
const data = await _asyncStorage.default.getItem(key);
|
|
39
|
+
if (data) {
|
|
40
|
+
const messages = JSON.parse(data);
|
|
41
|
+
// Convert timestamp strings back to Date objects
|
|
42
|
+
return messages.map(msg => ({
|
|
43
|
+
...msg,
|
|
44
|
+
timestamp: new Date(msg.timestamp)
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
return [];
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error('[StorageManager] Failed to load messages:', error);
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Clear messages for a session
|
|
56
|
+
*/
|
|
57
|
+
static async clearMessages(sessionId) {
|
|
58
|
+
try {
|
|
59
|
+
const key = `${STORAGE_KEY_PREFIX}${sessionId}`;
|
|
60
|
+
await _asyncStorage.default.removeItem(key);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.error('[StorageManager] Failed to clear messages:', error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get all stored session IDs
|
|
68
|
+
*/
|
|
69
|
+
static async getAllSessionIds() {
|
|
70
|
+
try {
|
|
71
|
+
const keys = await _asyncStorage.default.getAllKeys();
|
|
72
|
+
return keys.filter(key => key.startsWith(STORAGE_KEY_PREFIX)).map(key => key.replace(STORAGE_KEY_PREFIX, ''));
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error('[StorageManager] Failed to get session IDs:', error);
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Save current session ID
|
|
81
|
+
*/
|
|
82
|
+
static async saveCurrentSessionId(sessionId) {
|
|
83
|
+
try {
|
|
84
|
+
await _asyncStorage.default.setItem(`${STORAGE_KEY_PREFIX}current`, sessionId);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error('[StorageManager] Failed to save current session ID:', error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get current session ID
|
|
92
|
+
*/
|
|
93
|
+
static async getCurrentSessionId() {
|
|
94
|
+
try {
|
|
95
|
+
return await _asyncStorage.default.getItem(`${STORAGE_KEY_PREFIX}current`);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
console.error('[StorageManager] Failed to get current session ID:', error);
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Clear all chat data
|
|
104
|
+
*/
|
|
105
|
+
static async clearAll() {
|
|
106
|
+
try {
|
|
107
|
+
const keys = await _asyncStorage.default.getAllKeys();
|
|
108
|
+
const chatKeys = keys.filter(key => key.startsWith(STORAGE_KEY_PREFIX));
|
|
109
|
+
await _asyncStorage.default.multiRemove(chatKeys);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error('[StorageManager] Failed to clear all data:', error);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.StorageManager = StorageManager;
|
|
116
|
+
//# sourceMappingURL=StorageManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_asyncStorage","_interopRequireDefault","require","e","__esModule","default","STORAGE_KEY_PREFIX","MAX_STORED_MESSAGES","StorageManager","saveMessages","sessionId","messages","key","messagesToStore","slice","AsyncStorage","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","exports"],"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":"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","ignoreList":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useTheme = exports.ThemeProvider = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _theme = require("./theme");
|
|
9
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
10
|
+
/**
|
|
11
|
+
* Theme Provider
|
|
12
|
+
* Provides theme context to all child components
|
|
13
|
+
* Theme is derived from backend widget configuration
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const ThemeContext = /*#__PURE__*/(0, _react.createContext)(undefined);
|
|
17
|
+
const ThemeProvider = ({
|
|
18
|
+
config,
|
|
19
|
+
children
|
|
20
|
+
}) => {
|
|
21
|
+
const theme = (0, _react.useMemo)(() => {
|
|
22
|
+
if (!config) {
|
|
23
|
+
// Return default theme if config not loaded yet
|
|
24
|
+
return (0, _theme.createTheme)();
|
|
25
|
+
}
|
|
26
|
+
return (0, _theme.createTheme)(config.primaryColor, config.backgroundColor, config.textColor, config.theme === 'dark' ? 'dark' : 'light');
|
|
27
|
+
}, [config]);
|
|
28
|
+
const value = (0, _react.useMemo)(() => ({
|
|
29
|
+
theme,
|
|
30
|
+
config
|
|
31
|
+
}), [theme, config]);
|
|
32
|
+
return /*#__PURE__*/_react.default.createElement(ThemeContext.Provider, {
|
|
33
|
+
value: value
|
|
34
|
+
}, children);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Hook to access theme context
|
|
39
|
+
*/
|
|
40
|
+
exports.ThemeProvider = ThemeProvider;
|
|
41
|
+
const useTheme = () => {
|
|
42
|
+
const context = (0, _react.useContext)(ThemeContext);
|
|
43
|
+
if (context === undefined) {
|
|
44
|
+
throw new Error('useTheme must be used within a ThemeProvider');
|
|
45
|
+
}
|
|
46
|
+
return context;
|
|
47
|
+
};
|
|
48
|
+
exports.useTheme = useTheme;
|
|
49
|
+
//# sourceMappingURL=ThemeProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_theme","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","ThemeContext","createContext","undefined","ThemeProvider","config","children","theme","useMemo","createTheme","primaryColor","backgroundColor","textColor","value","createElement","Provider","exports","useTheme","context","useContext","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":";;;;;;AAMA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AAA6C,SAAAD,wBAAAG,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAL,uBAAA,YAAAA,CAAAG,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA,GAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA,gBAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA,WAAAO,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAP7C;AACA;AACA;AACA;AACA;;AAWA,MAAMkB,YAAY,gBAAG,IAAAC,oBAAa,EAAgCC,SAAS,CAAC;AAOrE,MAAMC,aAA2C,GAAGA,CAAC;EAAEC,MAAM;EAAEC;AAAS,CAAC,KAAK;EAClF,MAAMC,KAAK,GAAG,IAAAC,cAAO,EAAC,MAAM;IACzB,IAAI,CAACH,MAAM,EAAE;MACV;MACA,OAAO,IAAAI,kBAAW,EAAC,CAAC;IACvB;IAEA,OAAO,IAAAA,kBAAW,EACfJ,MAAM,CAACK,YAAY,EACnBL,MAAM,CAACM,eAAe,EACtBN,MAAM,CAACO,SAAS,EAChBP,MAAM,CAACE,KAAK,KAAK,MAAM,GAAG,MAAM,GAAG,OACtC,CAAC;EACJ,CAAC,EAAE,CAACF,MAAM,CAAC,CAAC;EAEZ,MAAMQ,KAAK,GAAG,IAAAL,cAAO,EAClB,OAAO;IACJD,KAAK;IACLF;EACH,CAAC,CAAC,EACF,CAACE,KAAK,EAAEF,MAAM,CACjB,CAAC;EAED,oBAAO3B,MAAA,CAAAc,OAAA,CAAAsB,aAAA,CAACb,YAAY,CAACc,QAAQ;IAACF,KAAK,EAAEA;EAAM,GAAEP,QAAgC,CAAC;AACjF,CAAC;;AAED;AACA;AACA;AAFAU,OAAA,CAAAZ,aAAA,GAAAA,aAAA;AAGO,MAAMa,QAAQ,GAAGA,CAAA,KAAyB;EAC9C,MAAMC,OAAO,GAAG,IAAAC,iBAAU,EAAClB,YAAY,CAAC;EACxC,IAAIiB,OAAO,KAAKf,SAAS,EAAE;IACxB,MAAM,IAAIiB,KAAK,CAAC,8CAA8C,CAAC;EAClE;EACA,OAAOF,OAAO;AACjB,CAAC;AAACF,OAAA,CAAAC,QAAA,GAAAA,QAAA","ignoreList":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _theme = require("./theme");
|
|
7
|
+
Object.keys(_theme).forEach(function (key) {
|
|
8
|
+
if (key === "default" || key === "__esModule") return;
|
|
9
|
+
if (key in exports && exports[key] === _theme[key]) return;
|
|
10
|
+
Object.defineProperty(exports, key, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () {
|
|
13
|
+
return _theme[key];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
var _ThemeProvider = require("./ThemeProvider");
|
|
18
|
+
Object.keys(_ThemeProvider).forEach(function (key) {
|
|
19
|
+
if (key === "default" || key === "__esModule") return;
|
|
20
|
+
if (key in exports && exports[key] === _ThemeProvider[key]) return;
|
|
21
|
+
Object.defineProperty(exports, key, {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
get: function () {
|
|
24
|
+
return _ThemeProvider[key];
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_theme","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_ThemeProvider"],"sources":["index.ts"],"sourcesContent":["/**\n * Theme exports\n */\n\nexport * from './theme';\nexport * from './ThemeProvider';\n"],"mappings":";;;;;AAIA,IAAAA,MAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,MAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,MAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,MAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,cAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,cAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,cAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,cAAA,CAAAL,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
|