/** * Generic storage adapter interface for key/value persistence */ export interface StorageAdapter { get(key: string): Promise; set(key: string, value: string): Promise; remove(key: string): Promise; getAll(): Promise>; } /** * LocalStorage implementation */ export class LocalStorageAdapter implements StorageAdapter { async get(key: string): Promise { return localStorage.getItem(key); } async set(key: string, value: string): Promise { localStorage.setItem(key, value); } async remove(key: string): Promise { localStorage.removeItem(key); } async getAll(): Promise> { const result: Record = {}; for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); if (key) { const value = localStorage.getItem(key); if (value) result[key] = value; } } return result; } } /** * Chrome/Firefox extension storage implementation */ export class ChromeStorageAdapter implements StorageAdapter { private readonly storage: any; constructor() { const isBrowser = typeof globalThis !== "undefined"; const hasChrome = isBrowser && (globalThis as any).chrome?.storage; const hasBrowser = isBrowser && (globalThis as any).browser?.storage; if (hasBrowser) { this.storage = (globalThis as any).browser.storage.local; } else if (hasChrome) { this.storage = (globalThis as any).chrome.storage.local; } else { throw new Error("Chrome/Browser storage not available"); } } async get(key: string): Promise { const result = await this.storage.get(key); return result[key] || null; } async set(key: string, value: string): Promise { await this.storage.set({ [key]: value }); } async remove(key: string): Promise { await this.storage.remove(key); } async getAll(): Promise> { const result = await this.storage.get(); return result || {}; } }