import type { IStorageAdapter } from '../core/IStorageAdapter'; /** * IndexedDB-based storage adapter for browser environments. * Provides persistent storage that survives page reloads. */ export class IndexedDBAdapter implements IStorageAdapter { private dbName: string; private storeName: string; constructor(dbName: string = 'wcli-storage', storeName: string = 'data') { this.dbName = dbName; this.storeName = storeName; } private async openDB(): Promise { return new Promise((resolve, reject) => { const request = indexedDB.open(this.dbName, 1); request.onerror = () => reject(request.error); request.onsuccess = () => resolve(request.result); request.onupgradeneeded = (event) => { const db = (event.target as IDBOpenDBRequest).result; if (!db.objectStoreNames.contains(this.storeName)) { db.createObjectStore(this.storeName); } }; }); } async save(key: string, data: any): Promise { try { const db = await this.openDB(); const transaction = db.transaction([this.storeName], 'readwrite'); const store = transaction.objectStore(this.storeName); store.put(data, key); return new Promise((resolve, reject) => { transaction.oncomplete = () => { db.close(); resolve(); }; transaction.onerror = () => { db.close(); reject(transaction.error); }; }); } catch (error) { throw new Error(`Failed to save data: ${error instanceof Error ? error.message : String(error)}`); } } async load(key: string): Promise { try { const db = await this.openDB(); const transaction = db.transaction([this.storeName], 'readonly'); const store = transaction.objectStore(this.storeName); const request = store.get(key); return new Promise((resolve, reject) => { request.onsuccess = () => { db.close(); resolve(request.result || null); }; request.onerror = () => { db.close(); reject(request.error); }; }); } catch (error) { throw new Error(`Failed to load data: ${error instanceof Error ? error.message : String(error)}`); } } async remove(key: string): Promise { try { const db = await this.openDB(); const transaction = db.transaction([this.storeName], 'readwrite'); const store = transaction.objectStore(this.storeName); store.delete(key); return new Promise((resolve, reject) => { transaction.oncomplete = () => { db.close(); resolve(); }; transaction.onerror = () => { db.close(); reject(transaction.error); }; }); } catch (error) { throw new Error(`Failed to remove data: ${error instanceof Error ? error.message : String(error)}`); } } async list(): Promise { try { const db = await this.openDB(); const transaction = db.transaction([this.storeName], 'readonly'); const store = transaction.objectStore(this.storeName); const request = store.getAllKeys(); return new Promise((resolve, reject) => { request.onsuccess = () => { db.close(); resolve(request.result as string[]); }; request.onerror = () => { db.close(); reject(request.error); }; }); } catch (error) { throw new Error(`Failed to list keys: ${error instanceof Error ? error.message : String(error)}`); } } }