@botonic/webchat-core 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +247 -0
  2. package/PR-LOCALE-SUPPORT.md +156 -0
  3. package/README.md +11 -0
  4. package/package.json +29 -0
  5. package/src/index.d.ts +11 -0
  6. package/src/index.js +15 -0
  7. package/src/index.js.map +1 -0
  8. package/src/lib/controllers/index.d.ts +2 -0
  9. package/src/lib/controllers/index.js +3 -0
  10. package/src/lib/controllers/index.js.map +1 -0
  11. package/src/lib/controllers/public.d.ts +383 -0
  12. package/src/lib/controllers/public.js +194 -0
  13. package/src/lib/controllers/public.js.map +1 -0
  14. package/src/lib/controllers/webchat.d.ts +414 -0
  15. package/src/lib/controllers/webchat.js +255 -0
  16. package/src/lib/controllers/webchat.js.map +1 -0
  17. package/src/lib/domain/index.d.ts +50 -0
  18. package/src/lib/domain/index.js +11 -0
  19. package/src/lib/domain/index.js.map +1 -0
  20. package/src/lib/infra/clients/hubtype-api.d.ts +53 -0
  21. package/src/lib/infra/clients/hubtype-api.js +189 -0
  22. package/src/lib/infra/clients/hubtype-api.js.map +1 -0
  23. package/src/lib/infra/clients/index.d.ts +3 -0
  24. package/src/lib/infra/clients/index.js +4 -0
  25. package/src/lib/infra/clients/index.js.map +1 -0
  26. package/src/lib/infra/clients/realtime.d.ts +92 -0
  27. package/src/lib/infra/clients/realtime.js +277 -0
  28. package/src/lib/infra/clients/realtime.js.map +1 -0
  29. package/src/lib/infra/clients/types.d.ts +21 -0
  30. package/src/lib/infra/clients/types.js +2 -0
  31. package/src/lib/infra/clients/types.js.map +1 -0
  32. package/src/lib/infra/repositories/index.d.ts +1 -0
  33. package/src/lib/infra/repositories/index.js +2 -0
  34. package/src/lib/infra/repositories/index.js.map +1 -0
  35. package/src/lib/infra/repositories/storage/base-storage.d.ts +23 -0
  36. package/src/lib/infra/repositories/storage/base-storage.js +102 -0
  37. package/src/lib/infra/repositories/storage/base-storage.js.map +1 -0
  38. package/src/lib/infra/repositories/storage/browser-storage.d.ts +9 -0
  39. package/src/lib/infra/repositories/storage/browser-storage.js +46 -0
  40. package/src/lib/infra/repositories/storage/browser-storage.js.map +1 -0
  41. package/src/lib/infra/repositories/storage/factory.d.ts +2 -0
  42. package/src/lib/infra/repositories/storage/factory.js +20 -0
  43. package/src/lib/infra/repositories/storage/factory.js.map +1 -0
  44. package/src/lib/infra/repositories/storage/in-memory.d.ts +9 -0
  45. package/src/lib/infra/repositories/storage/in-memory.js +21 -0
  46. package/src/lib/infra/repositories/storage/in-memory.js.map +1 -0
  47. package/src/lib/infra/repositories/storage/index.d.ts +7 -0
  48. package/src/lib/infra/repositories/storage/index.js +7 -0
  49. package/src/lib/infra/repositories/storage/index.js.map +1 -0
  50. package/src/lib/infra/repositories/storage/local-storage.d.ts +4 -0
  51. package/src/lib/infra/repositories/storage/local-storage.js +7 -0
  52. package/src/lib/infra/repositories/storage/local-storage.js.map +1 -0
  53. package/src/lib/infra/repositories/storage/session-storage.d.ts +4 -0
  54. package/src/lib/infra/repositories/storage/session-storage.js +7 -0
  55. package/src/lib/infra/repositories/storage/session-storage.js.map +1 -0
  56. package/src/lib/infra/repositories/storage/types.d.ts +30 -0
  57. package/src/lib/infra/repositories/storage/types.js +2 -0
  58. package/src/lib/infra/repositories/storage/types.js.map +1 -0
  59. package/src/lib/machines/message.d.ts +200 -0
  60. package/src/lib/machines/message.js +210 -0
  61. package/src/lib/machines/message.js.map +1 -0
  62. package/src/lib/machines/overlay.d.ts +299 -0
  63. package/src/lib/machines/overlay.js +217 -0
  64. package/src/lib/machines/overlay.js.map +1 -0
  65. package/src/lib/machines/webchat.d.ts +641 -0
  66. package/src/lib/machines/webchat.js +768 -0
  67. package/src/lib/machines/webchat.js.map +1 -0
  68. package/src/lib/services/webchat-service.d.ts +125 -0
  69. package/src/lib/services/webchat-service.js +339 -0
  70. package/src/lib/services/webchat-service.js.map +1 -0
  71. package/src/lib/utils/locale-detection.d.ts +2 -0
  72. package/src/lib/utils/locale-detection.js +20 -0
  73. package/src/lib/utils/locale-detection.js.map +1 -0
  74. package/src/lib/utils/timezone-to-country.d.ts +1 -0
  75. package/src/lib/utils/timezone-to-country.js +105 -0
  76. package/src/lib/utils/timezone-to-country.js.map +1 -0
  77. package/src/lib/webview/constants.d.ts +10 -0
  78. package/src/lib/webview/constants.js +10 -0
  79. package/src/lib/webview/constants.js.map +1 -0
  80. package/src/lib/webview/index.d.ts +3 -0
  81. package/src/lib/webview/index.js +4 -0
  82. package/src/lib/webview/index.js.map +1 -0
  83. package/src/lib/webview/types.d.ts +35 -0
  84. package/src/lib/webview/types.js +16 -0
  85. package/src/lib/webview/types.js.map +1 -0
  86. package/src/lib/webview/utils.d.ts +9 -0
  87. package/src/lib/webview/utils.js +33 -0
  88. package/src/lib/webview/utils.js.map +1 -0
@@ -0,0 +1,277 @@
1
+ import { __awaiter } from "tslib";
2
+ import PusherWithEncryption from 'pusher-js/with-encryption';
3
+ import { ConnectionStatus } from '../../domain';
4
+ /**
5
+ * Improved platform-agnostic realtime client
6
+ * Handles WebSocket connections via Pusher with encryption
7
+ */
8
+ export class RealtimeClient {
9
+ constructor() {
10
+ this.subscribedChannels = new Map();
11
+ this.eventCallbacks = new Map();
12
+ this.isInitialized = false;
13
+ this._connectionState = {
14
+ status: ConnectionStatus.Disconnected,
15
+ connectionAttempts: 0,
16
+ };
17
+ this.maxReconnectionAttempts = 5;
18
+ this.reconnectionDelay = 1000;
19
+ this.enableHeartbeat = true;
20
+ }
21
+ initialize(config, authContext) {
22
+ var _a;
23
+ this.authContext = authContext;
24
+ if (this.pusher) {
25
+ console.warn('RealtimeClient already initialized');
26
+ return;
27
+ }
28
+ this.maxReconnectionAttempts = config.maxReconnectionAttempts || 5;
29
+ this.reconnectionDelay = config.reconnectionDelay || 1000;
30
+ this.enableHeartbeat = (_a = config.enableHeartbeat) !== null && _a !== void 0 ? _a : false;
31
+ const pusherConfig = {
32
+ cluster: config.pusherCluster,
33
+ activityTimeout: config.activityTimeout || 15000,
34
+ pongTimeout: config.pongTimeout || 10000,
35
+ authorizer: ((channel) => {
36
+ return {
37
+ authorize: (socketId, callback) => __awaiter(this, void 0, void 0, function* () {
38
+ try {
39
+ const pusherAuthResponse = yield config.customAuthorizer(socketId, channel.name, this.authContext);
40
+ if (config.onAuthData) {
41
+ config.onAuthData(pusherAuthResponse);
42
+ }
43
+ callback(null, pusherAuthResponse);
44
+ }
45
+ catch (err) {
46
+ callback(err instanceof Error ? err : new Error(String(err)), {
47
+ auth: '',
48
+ shared_secret: '',
49
+ channel_data: '',
50
+ });
51
+ }
52
+ }),
53
+ };
54
+ }),
55
+ enableStats: false,
56
+ forceTLS: true,
57
+ };
58
+ this.pusher = new PusherWithEncryption(config.pusherAppKey, pusherConfig);
59
+ this.isInitialized = true;
60
+ this.setupConnectionHandlers();
61
+ if (this.enableHeartbeat) {
62
+ this.startHeartbeat();
63
+ }
64
+ }
65
+ setupConnectionHandlers() {
66
+ if (!this.pusher)
67
+ return;
68
+ this.pusher.connection.bind('state_change', (states) => {
69
+ const newState = states.current;
70
+ const previousState = states.previous;
71
+ console.log(`🔄 Pusher state change: ${previousState} → ${newState}`);
72
+ this.updateConnectionState(newState);
73
+ if (newState === ConnectionStatus.Unavailable &&
74
+ previousState === ConnectionStatus.Connecting) {
75
+ console.log('⚠️ Connection became unavailable after connecting attempt');
76
+ }
77
+ if (newState === ConnectionStatus.Connected) {
78
+ this._connectionState.lastConnected = new Date();
79
+ this._connectionState.connectionAttempts = 0;
80
+ console.log('Pusher connected');
81
+ if (this.reconnectionTimer) {
82
+ clearTimeout(this.reconnectionTimer);
83
+ this.reconnectionTimer = undefined;
84
+ }
85
+ }
86
+ else if (newState === ConnectionStatus.Disconnected ||
87
+ newState === ConnectionStatus.Failed) {
88
+ if (this._connectionState.connectionAttempts <
89
+ this.maxReconnectionAttempts) {
90
+ this.scheduleReconnection();
91
+ }
92
+ }
93
+ });
94
+ this.pusher.connection.bind('error', (error) => {
95
+ this._connectionState.lastError = error;
96
+ console.error('Pusher connection error:', JSON.stringify(error));
97
+ });
98
+ }
99
+ updateConnectionState(newState, error) {
100
+ const previousState = this._connectionState.status;
101
+ this._connectionState.status = newState;
102
+ if (error) {
103
+ this._connectionState.lastError = error;
104
+ }
105
+ if (this.onConnectionStateChange && previousState !== newState) {
106
+ this.onConnectionStateChange(this._connectionState);
107
+ }
108
+ }
109
+ scheduleReconnection() {
110
+ if (this.reconnectionTimer)
111
+ return;
112
+ this._connectionState.connectionAttempts++;
113
+ const delay = this.reconnectionDelay *
114
+ Math.pow(2, this._connectionState.connectionAttempts - 1); // Exponential backoff
115
+ console.log(`Scheduling reconnection attempt ${this._connectionState.connectionAttempts} in ${delay}ms`);
116
+ this.reconnectionTimer = setTimeout(() => {
117
+ this.updateConnectionState(ConnectionStatus.Reconnecting);
118
+ this.attemptReconnection();
119
+ }, delay);
120
+ }
121
+ attemptReconnection() {
122
+ if (!this.pusher)
123
+ return;
124
+ console.log('Attempting to reconnect...');
125
+ this.pusher.connect();
126
+ }
127
+ startHeartbeat() {
128
+ if (this.heartbeatInterval)
129
+ return;
130
+ const heartbeatFrequency = 5000; // Every 5 seconds - good balance between speed and quota usage
131
+ this.heartbeatInterval = setInterval(() => {
132
+ if (this.isConnected && this.pusher) {
133
+ const connection = this.pusher.connection;
134
+ const isHealthy = connection.state === ConnectionStatus.Connected;
135
+ if (!isHealthy) {
136
+ console.warn('Connection health check failed - state:', connection.state);
137
+ if (connection.state === ConnectionStatus.Disconnected ||
138
+ connection.state === ConnectionStatus.Failed) {
139
+ this.attemptReconnection();
140
+ }
141
+ }
142
+ else {
143
+ console.debug('Connection health check passed');
144
+ }
145
+ }
146
+ else {
147
+ console.warn('Heartbeat detected disconnected state, attempting reconnection');
148
+ this.attemptReconnection();
149
+ }
150
+ }, heartbeatFrequency);
151
+ }
152
+ stopHeartbeat() {
153
+ if (this.heartbeatInterval) {
154
+ clearInterval(this.heartbeatInterval);
155
+ this.heartbeatInterval = undefined;
156
+ }
157
+ }
158
+ /**
159
+ * Subscribe to a channel - matches original pattern
160
+ */
161
+ subscribe(channelName, subscriptionCallback) {
162
+ if (!this.pusher) {
163
+ console.error('Pusher client not initialized. Call initialize() first.');
164
+ return undefined;
165
+ }
166
+ const subscribedChannel = this.pusher.subscribe(channelName);
167
+ this.subscribedChannels.set(channelName, {
168
+ name: channelName,
169
+ channel: subscribedChannel,
170
+ isSubscribed: false,
171
+ });
172
+ if (subscriptionCallback && typeof subscriptionCallback === 'function') {
173
+ subscribedChannel.bind('pusher:subscription_succeeded', () => {
174
+ const realtimeChannel = this.subscribedChannels.get(channelName);
175
+ if (realtimeChannel) {
176
+ realtimeChannel.isSubscribed = true;
177
+ }
178
+ subscriptionCallback();
179
+ });
180
+ }
181
+ return subscribedChannel;
182
+ }
183
+ /**
184
+ * Bind an event to a channel - matches original pattern
185
+ */
186
+ bind(channelName, eventName, callback) {
187
+ if (!this.pusher) {
188
+ console.error('Pusher client not initialized. Call initialize() first.');
189
+ return;
190
+ }
191
+ const channel = this.subscribedChannels.get(channelName) ||
192
+ this.pusher.channel(channelName);
193
+ if (!channel) {
194
+ console.error(`Channel "${channelName}" does not exist or has not been subscribed to.`);
195
+ return;
196
+ }
197
+ const actualChannel = 'channel' in channel ? channel.channel : channel;
198
+ actualChannel.bind(eventName, callback);
199
+ }
200
+ /**
201
+ * Unbind an event from a channel - matches original pattern
202
+ */
203
+ unbind(channelName, eventName, callback) {
204
+ if (!this.pusher)
205
+ return;
206
+ const channel = this.subscribedChannels.get(channelName) ||
207
+ this.pusher.channel(channelName);
208
+ if (channel) {
209
+ const actualChannel = 'channel' in channel ? channel.channel : channel;
210
+ actualChannel.unbind(eventName, callback);
211
+ }
212
+ }
213
+ /**
214
+ * Bind event listener to a channel
215
+ */
216
+ bindChannelEvent(channelName, eventName, callback) {
217
+ this.bind(channelName, eventName, (data) => callback(data.message));
218
+ }
219
+ /**
220
+ * Unbind event listener from a channel
221
+ */
222
+ unbindChannelEvent(channelName, eventName, callback) {
223
+ if (callback) {
224
+ this.unbind(channelName, eventName, callback);
225
+ }
226
+ }
227
+ /**
228
+ * Unsubscribe from a channel
229
+ */
230
+ unsubscribeFromChannel(channelName) {
231
+ var _a;
232
+ const realtimeChannel = this.subscribedChannels.get(channelName);
233
+ if (realtimeChannel) {
234
+ (_a = this.pusher) === null || _a === void 0 ? void 0 : _a.unsubscribe(channelName);
235
+ this.subscribedChannels.delete(channelName);
236
+ this.eventCallbacks.delete(channelName);
237
+ console.log(`Unsubscribed from channel: ${channelName}`);
238
+ }
239
+ }
240
+ get connectionState() {
241
+ return this._connectionState.status;
242
+ }
243
+ get isConnected() {
244
+ return this._connectionState.status === ConnectionStatus.Connected;
245
+ }
246
+ /**
247
+ * Update the last message ID in auth context for reconnection
248
+ */
249
+ updateLastMessageId(messageId) {
250
+ if (this.authContext) {
251
+ this.authContext.lastMessageId = messageId;
252
+ }
253
+ }
254
+ /**
255
+ * Disconnect and cleanup
256
+ */
257
+ disconnect() {
258
+ if (this.reconnectionTimer) {
259
+ clearTimeout(this.reconnectionTimer);
260
+ this.reconnectionTimer = undefined;
261
+ }
262
+ this.stopHeartbeat();
263
+ if (this.pusher) {
264
+ this.pusher.disconnect();
265
+ this.subscribedChannels.clear();
266
+ this.eventCallbacks.clear();
267
+ this.isInitialized = false;
268
+ this.pusher = undefined;
269
+ this._connectionState = {
270
+ status: ConnectionStatus.Disconnected,
271
+ connectionAttempts: 0,
272
+ };
273
+ console.log('RealtimeClient disconnected and cleaned up');
274
+ }
275
+ }
276
+ }
277
+ //# sourceMappingURL=realtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime.js","sourceRoot":"","sources":["../../../../../../../../libs/botonic/webchat-core/src/lib/infra/clients/realtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { WebchatRealtimeAuthContext } from './hubtype-api';
2
+ export interface PusherAuthResponse {
3
+ auth: string;
4
+ channel_data: string;
5
+ shared_secret?: string;
6
+ }
7
+ export interface PusherAuthParsedChannelData {
8
+ botId: string;
9
+ chatId: string;
10
+ }
11
+ export type PusherCustomAuthorizerFunction = (socketId: string, channelName: string, authContext?: WebchatRealtimeAuthContext) => Promise<PusherAuthResponse>;
12
+ /** Matches backend _PusherAppSerializer (key, cluster, status_channel) */
13
+ export interface PusherAppSettings {
14
+ key: string;
15
+ cluster: string;
16
+ status_channel?: string;
17
+ }
18
+ /** Matches backend WebchatSettingsSerializer response */
19
+ export interface WebchatSettingsResponse {
20
+ pusher: PusherAppSettings;
21
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../../libs/botonic/webchat-core/src/lib/infra/clients/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export * from './storage';
@@ -0,0 +1,2 @@
1
+ export * from './storage';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../libs/botonic/webchat-core/src/lib/infra/repositories/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA"}
@@ -0,0 +1,23 @@
1
+ import { type HubtypeUser } from '@botonic/shared';
2
+ import { ConversationData, StorageRepository, StoredMessage } from './types';
3
+ export declare abstract class BaseStorageRepository implements StorageRepository {
4
+ protected keyPrefix: string;
5
+ constructor(keyPrefix?: string);
6
+ protected getConversationKey(appId: string, userId: string): string;
7
+ protected getAppStoragePrefix(appId: string): string;
8
+ protected abstract getData(key: string): ConversationData | null;
9
+ protected abstract setData(key: string, data: ConversationData): void;
10
+ protected abstract deleteData(key: string): void;
11
+ protected abstract getKeysWithPrefix(prefix: string): string[];
12
+ protected getConversationData(appId: string, userId: string): ConversationData;
13
+ protected saveConversationData(appId: string, userId: string, data: ConversationData): void;
14
+ saveMessage(appId: string, userId: string, message: StoredMessage): Promise<void>;
15
+ saveAllMessages(appId: string, userId: string, messages: StoredMessage[]): Promise<void>;
16
+ findMessagesByConversation(appId: string, userId: string): Promise<StoredMessage[]>;
17
+ saveUser(appId: string, user: HubtypeUser): Promise<void>;
18
+ findUserById(appId: string, userId: string): Promise<HubtypeUser | null>;
19
+ saveLastUserSession(appId: string, user: HubtypeUser): Promise<void>;
20
+ findLastUserSession(appId: string): Promise<HubtypeUser | null>;
21
+ clearConversation(appId: string, userId: string): Promise<void>;
22
+ clearAppData(appId: string): Promise<void>;
23
+ }
@@ -0,0 +1,102 @@
1
+ import { __awaiter } from "tslib";
2
+ const DEFAULT_KEY_PREFIX = 'botonic-webchat';
3
+ export class BaseStorageRepository {
4
+ constructor(keyPrefix = DEFAULT_KEY_PREFIX) {
5
+ this.keyPrefix = keyPrefix;
6
+ }
7
+ getConversationKey(appId, userId) {
8
+ return `${this.keyPrefix}:${appId}:${userId}`;
9
+ }
10
+ getAppStoragePrefix(appId) {
11
+ return `${this.keyPrefix}:${appId}:`;
12
+ }
13
+ getConversationData(appId, userId) {
14
+ const key = this.getConversationKey(appId, userId);
15
+ const data = this.getData(key);
16
+ return data !== null && data !== void 0 ? data : { messages: [], user: null };
17
+ }
18
+ saveConversationData(appId, userId, data) {
19
+ const key = this.getConversationKey(appId, userId);
20
+ this.setData(key, data);
21
+ }
22
+ saveMessage(appId, userId, message) {
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ const data = this.getConversationData(appId, userId);
25
+ const existingIndex = data.messages.findIndex(sm => sm.id === message.id);
26
+ if (existingIndex >= 0) {
27
+ data.messages[existingIndex] = message;
28
+ }
29
+ else {
30
+ data.messages.push(message);
31
+ }
32
+ data.messages.sort((a, b) => b.id.localeCompare(a.id));
33
+ this.saveConversationData(appId, userId, data);
34
+ });
35
+ }
36
+ saveAllMessages(appId, userId, messages) {
37
+ return __awaiter(this, void 0, void 0, function* () {
38
+ const data = this.getConversationData(appId, userId);
39
+ data.messages = messages;
40
+ this.saveConversationData(appId, userId, data);
41
+ });
42
+ }
43
+ findMessagesByConversation(appId, userId) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ const data = this.getConversationData(appId, userId);
46
+ return data.messages;
47
+ });
48
+ }
49
+ saveUser(appId, user) {
50
+ return __awaiter(this, void 0, void 0, function* () {
51
+ const data = this.getConversationData(appId, user.id);
52
+ const webchatUser = Object.assign(Object.assign({}, user), { lastActiveAt: new Date().toISOString() });
53
+ data.user = webchatUser;
54
+ this.saveConversationData(appId, user.id, data);
55
+ });
56
+ }
57
+ findUserById(appId, userId) {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ const data = this.getConversationData(appId, userId);
60
+ return data.user;
61
+ });
62
+ }
63
+ saveLastUserSession(appId, user) {
64
+ return __awaiter(this, void 0, void 0, function* () {
65
+ return this.saveUser(appId, user);
66
+ });
67
+ }
68
+ findLastUserSession(appId) {
69
+ return __awaiter(this, void 0, void 0, function* () {
70
+ var _a;
71
+ const prefix = this.getAppStoragePrefix(appId);
72
+ const keys = this.getKeysWithPrefix(prefix);
73
+ let mostRecentUser = null;
74
+ let mostRecentTimestamp = null;
75
+ for (const key of keys) {
76
+ const data = this.getData(key);
77
+ if ((_a = data === null || data === void 0 ? void 0 : data.user) === null || _a === void 0 ? void 0 : _a.lastActiveAt) {
78
+ if (!mostRecentTimestamp ||
79
+ new Date(data.user.lastActiveAt) > new Date(mostRecentTimestamp)) {
80
+ mostRecentUser = data.user;
81
+ mostRecentTimestamp = data.user.lastActiveAt;
82
+ }
83
+ }
84
+ }
85
+ return mostRecentUser;
86
+ });
87
+ }
88
+ clearConversation(appId, userId) {
89
+ return __awaiter(this, void 0, void 0, function* () {
90
+ const key = this.getConversationKey(appId, userId);
91
+ this.deleteData(key);
92
+ });
93
+ }
94
+ clearAppData(appId) {
95
+ return __awaiter(this, void 0, void 0, function* () {
96
+ const prefix = this.getAppStoragePrefix(appId);
97
+ const keys = this.getKeysWithPrefix(prefix);
98
+ keys.forEach(key => this.deleteData(key));
99
+ });
100
+ }
101
+ }
102
+ //# sourceMappingURL=base-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-storage.js","sourceRoot":"","sources":["../../../../../../../../../libs/botonic/webchat-core/src/lib/infra/repositories/storage/base-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { BaseStorageRepository } from './base-storage';
2
+ import { ConversationData } from './types';
3
+ export declare abstract class BrowserStorageRepository extends BaseStorageRepository {
4
+ protected abstract get storage(): Storage;
5
+ protected getData(key: string): ConversationData | null;
6
+ protected setData(key: string, data: ConversationData): void;
7
+ protected deleteData(key: string): void;
8
+ protected getKeysWithPrefix(prefix: string): string[];
9
+ }
@@ -0,0 +1,46 @@
1
+ import { BaseStorageRepository } from './base-storage';
2
+ export class BrowserStorageRepository extends BaseStorageRepository {
3
+ getData(key) {
4
+ const stored = this.storage.getItem(key);
5
+ if (stored) {
6
+ try {
7
+ const parsed = JSON.parse(stored);
8
+ return {
9
+ messages: Array.isArray(parsed.messages) ? parsed.messages : [],
10
+ user: parsed.user || null,
11
+ };
12
+ }
13
+ catch (error) {
14
+ console.error('Failed to parse conversation data:', error);
15
+ }
16
+ }
17
+ return null;
18
+ }
19
+ setData(key, data) {
20
+ try {
21
+ this.storage.setItem(key, JSON.stringify(data));
22
+ }
23
+ catch (error) {
24
+ const isQuotaError = error instanceof Error &&
25
+ (error.name === 'QuotaExceededError' || error.message.includes('quota'));
26
+ if (isQuotaError) {
27
+ console.warn('Storage quota exceeded, unable to save conversation data');
28
+ }
29
+ throw error;
30
+ }
31
+ }
32
+ deleteData(key) {
33
+ this.storage.removeItem(key);
34
+ }
35
+ getKeysWithPrefix(prefix) {
36
+ const keys = [];
37
+ for (let i = 0; i < this.storage.length; i++) {
38
+ const key = this.storage.key(i);
39
+ if (key && key.startsWith(prefix)) {
40
+ keys.push(key);
41
+ }
42
+ }
43
+ return keys;
44
+ }
45
+ }
46
+ //# sourceMappingURL=browser-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-storage.js","sourceRoot":"","sources":["../../../../../../../../../libs/botonic/webchat-core/src/lib/infra/repositories/storage/browser-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAGtD,MAAM,OAAgB,wBAAyB,SAAQ,qBAAqB;IAGhE,OAAO,CAAC,GAAW;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAExC,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;gBACjC,OAAO;oBACL,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;oBAC/D,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI;iBAC1B,CAAA;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAA;YAC5D,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAES,OAAO,CAAC,GAAW,EAAE,IAAsB;QACnD,IAAI,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK;gBACtB,CAAC,KAAK,CAAC,IAAI,KAAK,oBAAoB,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;YAC1E,IAAI,YAAY,EAAE,CAAC;gBACjB,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAA;YAC1E,CAAC;YACD,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IAES,UAAU,CAAC,GAAW;QAC9B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;IAC9B,CAAC;IAES,iBAAiB,CAAC,MAAc;QACxC,MAAM,IAAI,GAAa,EAAE,CAAA;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;YAC/B,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAChB,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ import { StorageConfig, StorageRepository } from './types';
2
+ export declare function createStorageRepository(config?: StorageConfig): StorageRepository;
@@ -0,0 +1,20 @@
1
+ import { InMemoryRepository } from './in-memory';
2
+ import { LocalStorageRepository } from './local-storage';
3
+ import { SessionStorageRepository } from './session-storage';
4
+ export function createStorageRepository(config) {
5
+ const { type = 'localStorage', keyPrefix = 'botonic-webchat' } = config || {};
6
+ if (type === 'inMemory') {
7
+ return new InMemoryRepository();
8
+ }
9
+ if (typeof window === 'undefined') {
10
+ return new InMemoryRepository();
11
+ }
12
+ if (type === 'sessionStorage' && window.sessionStorage) {
13
+ return new SessionStorageRepository(keyPrefix);
14
+ }
15
+ if (type === 'localStorage' && window.localStorage) {
16
+ return new LocalStorageRepository(keyPrefix);
17
+ }
18
+ return new InMemoryRepository();
19
+ }
20
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../../../../../../../libs/botonic/webchat-core/src/lib/infra/repositories/storage/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAG5D,MAAM,UAAU,uBAAuB,CACrC,MAAsB;IAEtB,MAAM,EAAE,IAAI,GAAG,cAAc,EAAE,SAAS,GAAG,iBAAiB,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;IAE7E,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,OAAO,IAAI,kBAAkB,EAAE,CAAA;IACjC,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,IAAI,kBAAkB,EAAE,CAAA;IACjC,CAAC;IAED,IAAI,IAAI,KAAK,gBAAgB,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QACvD,OAAO,IAAI,wBAAwB,CAAC,SAAS,CAAC,CAAA;IAChD,CAAC;IAED,IAAI,IAAI,KAAK,cAAc,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACnD,OAAO,IAAI,sBAAsB,CAAC,SAAS,CAAC,CAAA;IAC9C,CAAC;IAED,OAAO,IAAI,kBAAkB,EAAE,CAAA;AACjC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { BaseStorageRepository } from './base-storage';
2
+ import { ConversationData } from './types';
3
+ export declare class InMemoryRepository extends BaseStorageRepository {
4
+ private storage;
5
+ protected getData(key: string): ConversationData | null;
6
+ protected setData(key: string, data: ConversationData): void;
7
+ protected deleteData(key: string): void;
8
+ protected getKeysWithPrefix(prefix: string): string[];
9
+ }
@@ -0,0 +1,21 @@
1
+ import { BaseStorageRepository } from './base-storage';
2
+ export class InMemoryRepository extends BaseStorageRepository {
3
+ constructor() {
4
+ super(...arguments);
5
+ this.storage = new Map();
6
+ }
7
+ getData(key) {
8
+ var _a;
9
+ return (_a = this.storage.get(key)) !== null && _a !== void 0 ? _a : null;
10
+ }
11
+ setData(key, data) {
12
+ this.storage.set(key, data);
13
+ }
14
+ deleteData(key) {
15
+ this.storage.delete(key);
16
+ }
17
+ getKeysWithPrefix(prefix) {
18
+ return Array.from(this.storage.keys()).filter(key => key.startsWith(prefix));
19
+ }
20
+ }
21
+ //# sourceMappingURL=in-memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory.js","sourceRoot":"","sources":["../../../../../../../../../libs/botonic/webchat-core/src/lib/infra/repositories/storage/in-memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAGtD,MAAM,OAAO,kBAAmB,SAAQ,qBAAqB;IAA7D;;QACU,YAAO,GAAG,IAAI,GAAG,EAA4B,CAAA;IAiBvD,CAAC;IAfW,OAAO,CAAC,GAAW;;QAC3B,OAAO,MAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,mCAAI,IAAI,CAAA;IACtC,CAAC;IAES,OAAO,CAAC,GAAW,EAAE,IAAsB;QACnD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC;IAES,UAAU,CAAC,GAAW;QAC9B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC;IAES,iBAAiB,CAAC,MAAc;QACxC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAA;IAC9E,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ export { BaseStorageRepository } from './base-storage';
2
+ export { BrowserStorageRepository } from './browser-storage';
3
+ export { createStorageRepository } from './factory';
4
+ export { InMemoryRepository } from './in-memory';
5
+ export { LocalStorageRepository } from './local-storage';
6
+ export { SessionStorageRepository } from './session-storage';
7
+ export type { ConversationData, StorageConfig, StorageRepository, StorageType, StoredMessage, WebchatHubtypeUser, } from './types';
@@ -0,0 +1,7 @@
1
+ export { BaseStorageRepository } from './base-storage';
2
+ export { BrowserStorageRepository } from './browser-storage';
3
+ export { createStorageRepository } from './factory';
4
+ export { InMemoryRepository } from './in-memory';
5
+ export { LocalStorageRepository } from './local-storage';
6
+ export { SessionStorageRepository } from './session-storage';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../../libs/botonic/webchat-core/src/lib/infra/repositories/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { BrowserStorageRepository } from './browser-storage';
2
+ export declare class LocalStorageRepository extends BrowserStorageRepository {
3
+ protected get storage(): Storage;
4
+ }
@@ -0,0 +1,7 @@
1
+ import { BrowserStorageRepository } from './browser-storage';
2
+ export class LocalStorageRepository extends BrowserStorageRepository {
3
+ get storage() {
4
+ return localStorage;
5
+ }
6
+ }
7
+ //# sourceMappingURL=local-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-storage.js","sourceRoot":"","sources":["../../../../../../../../../libs/botonic/webchat-core/src/lib/infra/repositories/storage/local-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAE5D,MAAM,OAAO,sBAAuB,SAAQ,wBAAwB;IAClE,IAAc,OAAO;QACnB,OAAO,YAAY,CAAA;IACrB,CAAC;CACF"}
@@ -0,0 +1,4 @@
1
+ import { BrowserStorageRepository } from './browser-storage';
2
+ export declare class SessionStorageRepository extends BrowserStorageRepository {
3
+ protected get storage(): Storage;
4
+ }