|
1 | | -import { get, set, del, clear } from 'idb-keyval'; |
2 | 1 | import { CacheEntry } from './types'; |
3 | 2 |
|
| 3 | +const DB_NAME = 'react-local-fetch'; |
| 4 | +const STORE_NAME = 'keyval'; |
| 5 | +const DB_VERSION = 1; |
| 6 | + |
| 7 | +/** |
| 8 | + * Promise wrapper for IndexedDB. |
| 9 | + */ |
| 10 | +function getDB(): Promise<IDBDatabase> { |
| 11 | + return new Promise((resolve, reject) => { |
| 12 | + const request = indexedDB.open(DB_NAME, DB_VERSION); |
| 13 | + |
| 14 | + request.onupgradeneeded = () => { |
| 15 | + const db = request.result; |
| 16 | + if (!db.objectStoreNames.contains(STORE_NAME)) { |
| 17 | + db.createObjectStore(STORE_NAME); |
| 18 | + } |
| 19 | + }; |
| 20 | + |
| 21 | + request.onsuccess = () => resolve(request.result); |
| 22 | + request.onerror = () => reject(request.error); |
| 23 | + }); |
| 24 | +} |
| 25 | + |
4 | 26 | /** |
5 | 27 | * Saves data to IndexedDB. |
6 | 28 | */ |
7 | 29 | export async function saveToStorage<T>(key: string, entry: CacheEntry<T>): Promise<void> { |
8 | 30 | if (typeof window === 'undefined') return; |
9 | | - await set(`rlf_${key}`, entry); |
| 31 | + const db = await getDB(); |
| 32 | + return new Promise((resolve, reject) => { |
| 33 | + const transaction = db.transaction(STORE_NAME, 'readwrite'); |
| 34 | + const store = transaction.objectStore(STORE_NAME); |
| 35 | + const request = store.put(entry, `rlf_${key}`); |
| 36 | + request.onsuccess = () => resolve(); |
| 37 | + request.onerror = () => reject(request.error); |
| 38 | + }); |
10 | 39 | } |
11 | 40 |
|
12 | 41 | /** |
13 | 42 | * Retrieves data from IndexedDB. |
14 | 43 | */ |
15 | 44 | export async function getFromStorage<T>(key: string): Promise<CacheEntry<T> | undefined> { |
16 | 45 | if (typeof window === 'undefined') return undefined; |
17 | | - return await get(`rlf_${key}`); |
| 46 | + const db = await getDB(); |
| 47 | + return new Promise((resolve, reject) => { |
| 48 | + const transaction = db.transaction(STORE_NAME, 'readonly'); |
| 49 | + const store = transaction.objectStore(STORE_NAME); |
| 50 | + const request = store.get(`rlf_${key}`); |
| 51 | + request.onsuccess = () => resolve(request.result); |
| 52 | + request.onerror = () => reject(request.error); |
| 53 | + }); |
18 | 54 | } |
19 | 55 |
|
20 | 56 | /** |
21 | 57 | * Deletes a specific key from IndexedDB. |
22 | 58 | */ |
23 | 59 | export async function removeFromStorage(key: string): Promise<void> { |
24 | 60 | if (typeof window === 'undefined') return; |
25 | | - await del(`rlf_${key}`); |
| 61 | + const db = await getDB(); |
| 62 | + return new Promise((resolve, reject) => { |
| 63 | + const transaction = db.transaction(STORE_NAME, 'readwrite'); |
| 64 | + const store = transaction.objectStore(STORE_NAME); |
| 65 | + const request = store.delete(`rlf_${key}`); |
| 66 | + request.onsuccess = () => resolve(); |
| 67 | + request.onerror = () => reject(request.error); |
| 68 | + }); |
26 | 69 | } |
27 | 70 |
|
28 | 71 | /** |
29 | 72 | * Clears all react-local-fetch data from IndexedDB. |
30 | 73 | */ |
31 | 74 | export async function clearAllStorage(): Promise<void> { |
32 | 75 | if (typeof window === 'undefined') return; |
33 | | - // This is a bit aggressive, but we could filter keys if needed. |
34 | | - // For now, let's use a simple clear or filtered clear. |
35 | | - await clear(); |
| 76 | + const db = await getDB(); |
| 77 | + return new Promise((resolve, reject) => { |
| 78 | + const transaction = db.transaction(STORE_NAME, 'readwrite'); |
| 79 | + const store = transaction.objectStore(STORE_NAME); |
| 80 | + const request = store.clear(); |
| 81 | + request.onsuccess = () => resolve(); |
| 82 | + request.onerror = () => reject(request.error); |
| 83 | + }); |
36 | 84 | } |
0 commit comments