{"version":3,"file":"IndexedDBAdapter.cjs","sources":["../../../src/storage/IndexedDBAdapter.ts"],"sourcesContent":["import { BaseStorageAdapter } from './StorageAdapter'\n\nexport class IndexedDBAdapter extends BaseStorageAdapter {\n  private dbName: string\n  private storeName: string\n  private db: IDBDatabase | null = null\n\n  constructor(dbName = `offline-transactions`, storeName = `transactions`) {\n    super()\n    this.dbName = dbName\n    this.storeName = storeName\n  }\n\n  /**\n   * Probe IndexedDB availability by attempting to open a test database.\n   * This catches private mode and other restrictions that block IndexedDB.\n   */\n  static async probe(): Promise<{ available: boolean; error?: Error }> {\n    // Check if IndexedDB exists\n    if (typeof indexedDB === `undefined`) {\n      return {\n        available: false,\n        error: new Error(`IndexedDB is not available in this environment`),\n      }\n    }\n\n    // Try to actually open a test database to verify it works\n    try {\n      const testDbName = `__offline-tx-probe__`\n      const request = indexedDB.open(testDbName, 1)\n\n      return new Promise((resolve) => {\n        request.onerror = () => {\n          const error = request.error || new Error(`IndexedDB open failed`)\n          resolve({ available: false, error })\n        }\n\n        request.onsuccess = () => {\n          // Clean up test database\n          const db = request.result\n          db.close()\n          indexedDB.deleteDatabase(testDbName)\n          resolve({ available: true })\n        }\n\n        request.onblocked = () => {\n          resolve({\n            available: false,\n            error: new Error(`IndexedDB is blocked`),\n          })\n        }\n      })\n    } catch (error) {\n      return {\n        available: false,\n        error: error instanceof Error ? error : new Error(String(error)),\n      }\n    }\n  }\n\n  private async openDB(): Promise<IDBDatabase> {\n    if (this.db) {\n      return this.db\n    }\n\n    return new Promise((resolve, reject) => {\n      const request = indexedDB.open(this.dbName, 1)\n\n      request.onerror = () => reject(request.error)\n      request.onsuccess = () => {\n        this.db = request.result\n        resolve(this.db)\n      }\n\n      request.onupgradeneeded = (event) => {\n        const db = (event.target as IDBOpenDBRequest).result\n        if (!db.objectStoreNames.contains(this.storeName)) {\n          db.createObjectStore(this.storeName)\n        }\n      }\n    })\n  }\n\n  private async getStore(\n    mode: IDBTransactionMode = `readonly`,\n  ): Promise<IDBObjectStore> {\n    const db = await this.openDB()\n    const transaction = db.transaction([this.storeName], mode)\n    return transaction.objectStore(this.storeName)\n  }\n\n  async get(key: string): Promise<string | null> {\n    try {\n      const store = await this.getStore(`readonly`)\n      return new Promise((resolve, reject) => {\n        const request = store.get(key)\n        request.onerror = () => reject(request.error)\n        request.onsuccess = () => resolve(request.result ?? null)\n      })\n    } catch (error) {\n      console.warn(`IndexedDB get failed:`, error)\n      return null\n    }\n  }\n\n  async set(key: string, value: string): Promise<void> {\n    try {\n      const store = await this.getStore(`readwrite`)\n      return new Promise((resolve, reject) => {\n        const request = store.put(value, key)\n        request.onerror = () => reject(request.error)\n        request.onsuccess = () => resolve()\n      })\n    } catch (error) {\n      if (\n        error instanceof DOMException &&\n        error.name === `QuotaExceededError`\n      ) {\n        throw new Error(\n          `Storage quota exceeded. Consider clearing old transactions.`,\n        )\n      }\n      throw error\n    }\n  }\n\n  async delete(key: string): Promise<void> {\n    try {\n      const store = await this.getStore(`readwrite`)\n      return new Promise((resolve, reject) => {\n        const request = store.delete(key)\n        request.onerror = () => reject(request.error)\n        request.onsuccess = () => resolve()\n      })\n    } catch (error) {\n      console.warn(`IndexedDB delete failed:`, error)\n    }\n  }\n\n  async keys(): Promise<Array<string>> {\n    try {\n      const store = await this.getStore(`readonly`)\n      return new Promise((resolve, reject) => {\n        const request = store.getAllKeys()\n        request.onerror = () => reject(request.error)\n        request.onsuccess = () => resolve(request.result as Array<string>)\n      })\n    } catch (error) {\n      console.warn(`IndexedDB keys failed:`, error)\n      return []\n    }\n  }\n\n  async clear(): Promise<void> {\n    try {\n      const store = await this.getStore(`readwrite`)\n      return new Promise((resolve, reject) => {\n        const request = store.clear()\n        request.onerror = () => reject(request.error)\n        request.onsuccess = () => resolve()\n      })\n    } catch (error) {\n      console.warn(`IndexedDB clear failed:`, error)\n    }\n  }\n}\n"],"names":["BaseStorageAdapter"],"mappings":"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"}