@aichatkit/localstorage-adapter
Version:
LocalStorage adapter for Hypermode ChatKit
245 lines (244 loc) • 8.8 kB
JavaScript
// src/index.ts
import { StorageAdapter } from "@aichatkit/storage-adapter";
var LocalStorageAdapter = class extends StorageAdapter {
constructor(options = {}) {
super();
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";
}
async initialize() {
if (typeof localStorage === "undefined") {
throw new Error("localStorage is not available in this environment");
}
if (!localStorage.getItem(this.conversationIdsKey)) {
localStorage.setItem(this.conversationIdsKey, JSON.stringify([]));
}
if (!localStorage.getItem(this.activeConversationKey)) {
localStorage.setItem(this.activeConversationKey, "");
}
if (!localStorage.getItem(this.agentMappingKey)) {
localStorage.setItem(this.agentMappingKey, JSON.stringify({}));
}
}
getActiveConversationId() {
if (typeof localStorage === "undefined") return "";
return localStorage.getItem(this.activeConversationKey) || "";
}
setActiveConversationId(id) {
if (typeof localStorage === "undefined") return;
localStorage.setItem(this.activeConversationKey, id);
}
async saveConversation(conversation) {
if (typeof localStorage === "undefined") {
throw new Error("localStorage is not available in this environment");
}
try {
localStorage.setItem(
`${this.conversationPrefix}${conversation.id}`,
JSON.stringify(conversation)
);
const ids = this.getConversationIds();
if (!ids.includes(conversation.id)) {
ids.push(conversation.id);
localStorage.setItem(this.conversationIdsKey, JSON.stringify(ids));
}
} catch (error) {
console.error("Failed to save conversation to localStorage:", error);
throw error;
}
}
async getConversation(id) {
if (typeof localStorage === "undefined") {
throw new Error("localStorage is not available in this environment");
}
try {
const data = localStorage.getItem(`${this.conversationPrefix}${id}`);
return data ? JSON.parse(data) : null;
} catch (error) {
console.error("Failed to retrieve conversation from localStorage:", error);
return null;
}
}
async getAllConversations() {
if (typeof localStorage === "undefined") {
throw new Error("localStorage is not available in this environment");
}
try {
const ids = this.getConversationIds();
const conversations = [];
for (const id of ids) {
const data = localStorage.getItem(`${this.conversationPrefix}${id}`);
if (data) {
conversations.push(JSON.parse(data));
}
}
return conversations;
} catch (error) {
console.error(
"Failed to retrieve all conversations from localStorage:",
error
);
return [];
}
}
async deleteConversation(id) {
if (typeof localStorage === "undefined") {
throw new Error("localStorage is not available in this environment");
}
try {
localStorage.removeItem(`${this.conversationPrefix}${id}`);
const ids = this.getConversationIds().filter((convId) => convId !== id);
localStorage.setItem(this.conversationIdsKey, JSON.stringify(ids));
if (this.getActiveConversationId() === id) {
this.setActiveConversationId("");
}
await this.removeConversationAgent(id);
return true;
} catch (error) {
console.error("Failed to delete conversation from localStorage:", error);
return false;
}
}
async addMessage(conversationId, message) {
const conversation = await this.getConversation(conversationId);
if (!conversation) {
return null;
}
conversation.messages.push(message);
await this.saveConversation(conversation);
return conversation;
}
async getConversationHistory(conversationId) {
var _a;
const agentId = await this.getConversationAgent(conversationId);
if (agentId && ((_a = this.callbacks) == null ? void 0 : _a.getConversationHistory)) {
try {
const backendMessages = await this.callbacks.getConversationHistory(agentId);
const conversation2 = await this.getConversation(conversationId);
if (conversation2) {
conversation2.messages = backendMessages;
await this.saveConversation(conversation2);
}
return backendMessages;
} catch (error) {
console.error(
"Failed to sync conversation history from backend:",
error
);
}
}
const conversation = await this.getConversation(conversationId);
const localMessages = (conversation == null ? void 0 : conversation.messages) || [];
return localMessages;
}
/**
* Sync all conversations with backend on app reload/initialization
*/
async syncAllConversationsWithBackend() {
var _a;
if (!((_a = this.callbacks) == null ? void 0 : _a.getConversationHistory)) {
return;
}
const conversations = await this.getAllConversations();
for (const conversation of conversations) {
const agentId = await this.getConversationAgent(conversation.id);
if (agentId) {
try {
const backendMessages = await this.callbacks.getConversationHistory(agentId);
conversation.messages = backendMessages;
await this.saveConversation(conversation);
} catch (error) {
console.error(
`Failed to sync conversation ${conversation.id}:`,
error
);
}
} else {
console.warn(`No agent ID found for conversation ${conversation.id}`);
}
}
}
async clearConversationHistory(conversationId) {
var _a;
const agentId = await this.getConversationAgent(conversationId);
if (agentId && ((_a = this.callbacks) == null ? void 0 : _a.clearConversationHistory)) {
try {
await this.callbacks.clearConversationHistory(agentId);
} catch (error) {
console.error("Failed to clear conversation history on backend:", error);
}
}
const conversation = await this.getConversation(conversationId);
if (conversation) {
conversation.messages = [];
await this.saveConversation(conversation);
}
}
async setConversationAgent(conversationId, agentId) {
if (typeof localStorage === "undefined") {
throw new Error("localStorage is not available in this environment");
}
try {
const mappingData = localStorage.getItem(this.agentMappingKey);
const mapping = mappingData ? JSON.parse(mappingData) : {};
mapping[conversationId] = agentId;
localStorage.setItem(this.agentMappingKey, JSON.stringify(mapping));
} catch (error) {
console.error("Failed to set conversation agent mapping:", error);
throw error;
}
}
async getConversationAgent(conversationId) {
if (typeof localStorage === "undefined") {
throw new Error("localStorage is not available in this environment");
}
try {
const mappingData = localStorage.getItem(this.agentMappingKey);
const mapping = mappingData ? JSON.parse(mappingData) : {};
return mapping[conversationId] || null;
} catch (error) {
console.error("Failed to get conversation agent mapping:", error);
return null;
}
}
async clearAllConversations() {
if (typeof localStorage === "undefined") {
throw new Error("localStorage is not available in this environment");
}
try {
const ids = this.getConversationIds();
for (const id of ids) {
localStorage.removeItem(`${this.conversationPrefix}${id}`);
}
localStorage.removeItem(this.conversationIdsKey);
localStorage.removeItem(this.activeConversationKey);
localStorage.removeItem(this.agentMappingKey);
return true;
} catch (error) {
console.error(
"Failed to clear all conversations from localStorage:",
error
);
return false;
}
}
getConversationIds() {
const data = localStorage.getItem(this.conversationIdsKey);
return data ? JSON.parse(data) : [];
}
async removeConversationAgent(conversationId) {
try {
const mappingData = localStorage.getItem(this.agentMappingKey);
const mapping = mappingData ? JSON.parse(mappingData) : {};
delete mapping[conversationId];
localStorage.setItem(this.agentMappingKey, JSON.stringify(mapping));
} catch (error) {
console.error("Failed to remove conversation agent mapping:", error);
}
}
};
export {
LocalStorageAdapter
};