UNPKG

@aichatkit/localstorage-adapter

Version:
572 lines (570 loc) 20.3 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { LocalStorageAdapter: () => LocalStorageAdapter }); module.exports = __toCommonJS(index_exports); var import_storage_adapter = require("@aichatkit/storage-adapter"); var LocalStorageAdapter = class extends import_storage_adapter.StorageAdapter { constructor(options = {}) { super(); this.isClient = false; this.conversationPrefix = options.conversationPrefix || "chatkit_conversation_"; this.conversationIdsKey = options.conversationIdsKey || "chatkit_conversation_ids"; this.activeConversationKey = options.activeConversationKey || "chatkit_active_conversation"; this.agentMappingKey = options.agentMappingKey || "chatkit_agent_mapping"; } checkClient() { if (typeof window === "undefined") { console.warn("[LocalStorageAdapter] Not in browser environment"); return false; } if (!window.localStorage) { console.warn("[LocalStorageAdapter] localStorage not available"); return false; } return true; } async initialize() { console.log("[LocalStorageAdapter] Initializing..."); if (typeof window === "undefined") { console.log("[LocalStorageAdapter] Server-side, skipping initialization"); return; } await new Promise((resolve) => setTimeout(resolve, 100)); this.isClient = this.checkClient(); if (!this.isClient) { throw new Error("localStorage is not available in this environment"); } try { const existingIds = localStorage.getItem(this.conversationIdsKey); if (!existingIds) { console.log("[LocalStorageAdapter] Initializing conversation IDs"); localStorage.setItem(this.conversationIdsKey, JSON.stringify([])); } const existingActive = localStorage.getItem(this.activeConversationKey); if (!existingActive) { console.log("[LocalStorageAdapter] Initializing active conversation"); localStorage.setItem(this.activeConversationKey, ""); } const existingMapping = localStorage.getItem(this.agentMappingKey); if (!existingMapping) { console.log("[LocalStorageAdapter] Initializing agent mapping"); localStorage.setItem(this.agentMappingKey, JSON.stringify({})); } console.log("[LocalStorageAdapter] Initialized successfully"); } catch (error) { console.error("[LocalStorageAdapter] Failed to initialize:", error); throw error; } } getActiveConversationId() { if (!this.checkClient()) return ""; try { const active = localStorage.getItem(this.activeConversationKey) || ""; console.log( `[LocalStorageAdapter] Getting active conversation: ${active}` ); return active; } catch (error) { console.error( "[LocalStorageAdapter] Failed to get active conversation ID:", error ); return ""; } } setActiveConversationId(id) { if (!this.checkClient()) return; try { console.log(`[LocalStorageAdapter] Setting active conversation: ${id}`); localStorage.setItem(this.activeConversationKey, id); } catch (error) { console.error( "[LocalStorageAdapter] Failed to set active conversation ID:", error ); } } async saveConversation(conversation) { if (!this.checkClient()) { throw new Error("localStorage is not available in this environment"); } try { const conversationToSave = { id: conversation.id, title: conversation.title || "Untitled Conversation", items: Array.isArray(conversation.items) ? conversation.items : [] }; console.log( `[LocalStorageAdapter] Saving conversation: ${conversation.id} with ${conversationToSave.items.length} items` ); const conversationKey = `${this.conversationPrefix}${conversation.id}`; localStorage.setItem(conversationKey, JSON.stringify(conversationToSave)); const ids = this.getConversationIds(); if (!ids.includes(conversation.id)) { ids.push(conversation.id); localStorage.setItem(this.conversationIdsKey, JSON.stringify(ids)); console.log( `[LocalStorageAdapter] Added conversation ID to list: ${conversation.id}` ); } console.log( `[LocalStorageAdapter] Successfully saved conversation: ${conversation.id}` ); } catch (error) { console.error("[LocalStorageAdapter] Failed to save conversation:", error); throw error; } } async getConversation(id) { if (!this.checkClient()) { console.warn( "[LocalStorageAdapter] Cannot get conversation - not in client environment" ); return null; } if (!id || typeof id !== "string") { console.warn( "[LocalStorageAdapter] Invalid conversation ID provided:", id ); return null; } try { const conversationKey = `${this.conversationPrefix}${id}`; const data = localStorage.getItem(conversationKey); if (!data) { console.log(`[LocalStorageAdapter] Conversation not found: ${id}`); return null; } const conversation = JSON.parse(data); const safeConversation = { id: conversation.id || id, title: conversation.title || "Untitled Conversation", items: Array.isArray(conversation.items) ? conversation.items : [] }; console.log( `[LocalStorageAdapter] Retrieved conversation: ${id} (${safeConversation.items.length} items)` ); return safeConversation; } catch (error) { console.error( `[LocalStorageAdapter] Failed to retrieve conversation ${id}:`, error ); return null; } } async getAllConversations() { if (!this.checkClient()) { console.warn( "[LocalStorageAdapter] Cannot get conversations - not in client environment" ); return []; } try { const ids = this.getConversationIds(); console.log( `[LocalStorageAdapter] Getting all conversations for IDs:`, ids ); const conversations = []; for (const id of ids) { if (!id || typeof id !== "string") { console.warn( `[LocalStorageAdapter] Skipping invalid conversation ID:`, id ); continue; } try { const conversationKey = `${this.conversationPrefix}${id}`; const data = localStorage.getItem(conversationKey); if (data) { const conversation = JSON.parse(data); const safeConversation = { id: conversation.id || id, title: conversation.title || "Untitled Conversation", items: Array.isArray(conversation.items) ? conversation.items : [] }; conversations.push(safeConversation); console.log( `[LocalStorageAdapter] Loaded conversation: ${id} (${safeConversation.items.length} items)` ); } else { console.warn( `[LocalStorageAdapter] Conversation data not found for ID: ${id}` ); this.removeConversationId(id); } } catch (parseError) { console.error( `[LocalStorageAdapter] Failed to parse conversation ${id}:`, parseError ); this.removeConversationId(id); } } console.log( `[LocalStorageAdapter] Retrieved ${conversations.length} conversations` ); return conversations; } catch (error) { console.error( "[LocalStorageAdapter] Failed to get all conversations:", error ); return []; } } async deleteConversation(id) { if (!this.checkClient()) { throw new Error("localStorage is not available in this environment"); } if (!id || typeof id !== "string") { console.warn( "[LocalStorageAdapter] Invalid conversation ID for deletion:", id ); return false; } try { console.log(`[LocalStorageAdapter] Deleting conversation: ${id}`); const conversationKey = `${this.conversationPrefix}${id}`; localStorage.removeItem(conversationKey); this.removeConversationId(id); if (this.getActiveConversationId() === id) { this.setActiveConversationId(""); console.log(`[LocalStorageAdapter] Cleared active conversation`); } await this.removeConversationAgent(id); console.log( `[LocalStorageAdapter] Successfully deleted conversation: ${id}` ); return true; } catch (error) { console.error( `[LocalStorageAdapter] Failed to delete conversation ${id}:`, error ); return false; } } async addItem(conversationId, item) { if (!conversationId || typeof conversationId !== "string") { console.error( "[LocalStorageAdapter] Invalid conversation ID for adding item:", conversationId ); return null; } if (!item || typeof item !== "object") { console.error("[LocalStorageAdapter] Invalid item for adding:", item); return null; } try { console.log( `[LocalStorageAdapter] Adding item to conversation: ${conversationId}` ); let conversation = await this.getConversation(conversationId); if (!conversation) { console.log( `[LocalStorageAdapter] Conversation not found, creating new one: ${conversationId}` ); conversation = { id: conversationId, title: "New Conversation", items: [] }; await this.saveConversation(conversation); } if (!Array.isArray(conversation.items)) { conversation.items = []; } conversation.items.push(item); await this.saveConversation(conversation); console.log( `[LocalStorageAdapter] Added item to conversation: ${conversationId} (now has ${conversation.items.length} items)` ); return conversation; } catch (error) { console.error("[LocalStorageAdapter] Failed to add item:", error); return null; } } async getConversationItems(conversationId) { var _a; if (!conversationId || typeof conversationId !== "string") { console.warn( "[LocalStorageAdapter] Invalid conversation ID for getting items:", conversationId ); return []; } console.log( `[LocalStorageAdapter] Getting conversation items: ${conversationId}` ); const agentId = await this.getConversationAgent(conversationId); if (agentId && ((_a = this.callbacks) == null ? void 0 : _a.getConversationItems)) { try { console.log( `[LocalStorageAdapter] Syncing with backend agent: ${agentId}` ); const backendItems = await this.callbacks.getConversationItems(agentId); const safeBackendItems = Array.isArray(backendItems) ? backendItems : []; const conversation2 = await this.getConversation(conversationId); if (conversation2) { conversation2.items = safeBackendItems; await this.saveConversation(conversation2); console.log( `[LocalStorageAdapter] Updated local storage with ${safeBackendItems.length} items from backend` ); } return safeBackendItems; } catch (error) { console.error( "[LocalStorageAdapter] Backend sync failed, using local data:", error ); } } const conversation = await this.getConversation(conversationId); const localItems = Array.isArray(conversation == null ? void 0 : conversation.items) ? conversation.items : []; console.log( `[LocalStorageAdapter] Retrieved ${localItems.length} items from local storage` ); return localItems; } async syncAllConversationsWithBackend() { var _a; if (!((_a = this.callbacks) == null ? void 0 : _a.getConversationItems)) { console.log("[LocalStorageAdapter] No backend sync callback available"); return; } try { const conversations = await this.getAllConversations(); console.log( `[LocalStorageAdapter] Syncing ${conversations.length} conversations with backend` ); for (const conversation of conversations) { if (!conversation || !conversation.id) { console.warn( "[LocalStorageAdapter] Skipping invalid conversation during sync" ); continue; } const agentId = await this.getConversationAgent(conversation.id); if (agentId) { try { console.log( `[LocalStorageAdapter] Syncing conversation ${conversation.id} with agent ${agentId}` ); const backendItems = await this.callbacks.getConversationItems(agentId); const safeBackendItems = Array.isArray(backendItems) ? backendItems : []; conversation.items = safeBackendItems; await this.saveConversation(conversation); console.log( `[LocalStorageAdapter] Successfully synced conversation ${conversation.id}` ); } catch (error) { console.error( `[LocalStorageAdapter] Failed to sync conversation ${conversation.id}:`, error ); } } else { console.warn( `[LocalStorageAdapter] No agent ID found for conversation ${conversation.id}` ); } } } catch (error) { console.error( "[LocalStorageAdapter] Failed to sync conversations with backend:", error ); } } async clearConversationHistory(conversationId) { var _a; if (!conversationId || typeof conversationId !== "string") { console.warn( "[LocalStorageAdapter] Invalid conversation ID for clearing history:", conversationId ); return; } console.log( `[LocalStorageAdapter] Clearing conversation history: ${conversationId}` ); const agentId = await this.getConversationAgent(conversationId); if (agentId && ((_a = this.callbacks) == null ? void 0 : _a.clearConversationHistory)) { try { console.log( `[LocalStorageAdapter] Clearing backend history for agent: ${agentId}` ); await this.callbacks.clearConversationHistory(agentId); } catch (error) { console.error( "[LocalStorageAdapter] Failed to clear backend history:", error ); } } const conversation = await this.getConversation(conversationId); if (conversation) { conversation.items = []; await this.saveConversation(conversation); console.log( `[LocalStorageAdapter] Cleared local history for conversation: ${conversationId}` ); } } async setConversationAgent(conversationId, agentId) { if (!this.checkClient()) { throw new Error("localStorage is not available in this environment"); } if (!conversationId || typeof conversationId !== "string") { throw new Error("Invalid conversation ID"); } if (!agentId || typeof agentId !== "string") { throw new Error("Invalid agent ID"); } try { console.log( `[LocalStorageAdapter] Setting agent mapping: ${conversationId} -> ${agentId}` ); const mappingData = localStorage.getItem(this.agentMappingKey); const mapping = mappingData ? JSON.parse(mappingData) : {}; mapping[conversationId] = agentId; localStorage.setItem(this.agentMappingKey, JSON.stringify(mapping)); console.log(`[LocalStorageAdapter] Agent mapping saved successfully`); } catch (error) { console.error("[LocalStorageAdapter] Failed to set agent mapping:", error); throw error; } } async getConversationAgent(conversationId) { if (!this.checkClient()) { console.warn( "[LocalStorageAdapter] Cannot get agent mapping - not in client environment" ); return null; } if (!conversationId || typeof conversationId !== "string") { console.warn( "[LocalStorageAdapter] Invalid conversation ID for getting agent:", conversationId ); return null; } try { const mappingData = localStorage.getItem(this.agentMappingKey); const mapping = mappingData ? JSON.parse(mappingData) : {}; const agentId = mapping[conversationId] || null; console.log( `[LocalStorageAdapter] Agent for conversation ${conversationId}: ${agentId}` ); return agentId; } catch (error) { console.error("[LocalStorageAdapter] Failed to get agent mapping:", error); return null; } } async clearAllConversations() { if (!this.checkClient()) { throw new Error("localStorage is not available in this environment"); } try { console.log("[LocalStorageAdapter] Clearing all conversations"); const ids = this.getConversationIds(); for (const id of ids) { if (id && typeof id === "string") { const conversationKey = `${this.conversationPrefix}${id}`; localStorage.removeItem(conversationKey); } } localStorage.removeItem(this.conversationIdsKey); localStorage.removeItem(this.activeConversationKey); localStorage.removeItem(this.agentMappingKey); console.log("[LocalStorageAdapter] All conversations cleared"); return true; } catch (error) { console.error( "[LocalStorageAdapter] Failed to clear all conversations:", error ); return false; } } getConversationIds() { if (!this.checkClient()) return []; try { const data = localStorage.getItem(this.conversationIdsKey); const parsed = data ? JSON.parse(data) : []; const ids = Array.isArray(parsed) ? parsed.filter((id) => id && typeof id === "string") : []; console.log(`[LocalStorageAdapter] Retrieved conversation IDs:`, ids); return ids; } catch (error) { console.error( "[LocalStorageAdapter] Failed to get conversation IDs:", error ); return []; } } removeConversationId(id) { if (!this.checkClient() || !id || typeof id !== "string") return; try { const ids = this.getConversationIds().filter((convId) => convId !== id); localStorage.setItem(this.conversationIdsKey, JSON.stringify(ids)); console.log(`[LocalStorageAdapter] Removed conversation ID: ${id}`); } catch (error) { console.error( `[LocalStorageAdapter] Failed to remove conversation ID ${id}:`, error ); } } async removeConversationAgent(conversationId) { if (!this.checkClient() || !conversationId || typeof conversationId !== "string") return; try { const mappingData = localStorage.getItem(this.agentMappingKey); const mapping = mappingData ? JSON.parse(mappingData) : {}; delete mapping[conversationId]; localStorage.setItem(this.agentMappingKey, JSON.stringify(mapping)); console.log( `[LocalStorageAdapter] Removed agent mapping for: ${conversationId}` ); } catch (error) { console.error( `[LocalStorageAdapter] Failed to remove agent mapping for ${conversationId}:`, error ); } } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { LocalStorageAdapter });