|
1 | 1 | import { ShielderTransaction } from '@cardinal-cryptography/shielder-sdk'; |
2 | | -import { openDB, IDBPDatabase } from 'idb'; |
| 2 | +import { openDB, deleteDB, IDBPDatabase } from 'idb'; |
3 | 3 | import { Address, sha256, isAddress } from 'viem'; |
4 | 4 | import { z } from 'zod'; |
5 | 5 |
|
6 | 6 | import isPresent from 'src/domains/misc/utils/isPresent'; |
7 | 7 |
|
8 | | -const DB_NAME = 'SHIELDER_STORAGE'; |
9 | | -const DB_VERSION = 4; |
| 8 | +const DB_INDEX = 1; |
| 9 | +const DB_BASE_NAME = 'SHIELDER_STORAGE'; |
| 10 | +const DB_NAME = `${DB_BASE_NAME}_V${DB_INDEX}`; |
10 | 11 |
|
11 | 12 | const STORE_CLIENTS = 'clients'; |
12 | 13 | const STORE_TRANSACTIONS = 'transactions'; |
@@ -108,16 +109,23 @@ type DBSchema = { |
108 | 109 | [STORE_TRANSACTIONS]: { key: string, value: LocalShielderActivityHistoryByChain }, |
109 | 110 | }; |
110 | 111 |
|
111 | | -const createDB = (): Promise<IDBPDatabase<DBSchema>> => { |
112 | | - return openDB(DB_NAME, DB_VERSION, { |
113 | | - upgrade: db => { |
114 | | - if (db.objectStoreNames.contains(STORE_CLIENTS)) { |
115 | | - db.deleteObjectStore(STORE_CLIENTS); |
116 | | - } |
117 | | - if (db.objectStoreNames.contains(STORE_TRANSACTIONS)) { |
118 | | - db.deleteObjectStore(STORE_TRANSACTIONS); |
119 | | - } |
| 112 | +// Clean up old database versions |
| 113 | +const cleanupOldVersions = async (): Promise<void> => { |
| 114 | + const databases = await indexedDB.databases(); |
| 115 | + const toDelete = databases |
| 116 | + .filter(db => db.name?.includes(DB_BASE_NAME) && db.name !== DB_NAME) |
| 117 | + .map(db => db.name) |
| 118 | + .filter((name): name is string => Boolean(name)); |
| 119 | + |
| 120 | + await Promise.allSettled(toDelete.map(dbName => deleteDB(dbName))); |
| 121 | +}; |
120 | 122 |
|
| 123 | +const createDB = async (): Promise<IDBPDatabase<DBSchema>> => { |
| 124 | + await cleanupOldVersions(); |
| 125 | + |
| 126 | + // Always create version 1 since each DB_VERSION gets its own database |
| 127 | + return openDB<DBSchema>(DB_NAME, 1, { |
| 128 | + upgrade: db => { |
121 | 129 | db.createObjectStore(STORE_CLIENTS); |
122 | 130 | db.createObjectStore(STORE_TRANSACTIONS); |
123 | 131 | }, |
@@ -181,12 +189,7 @@ export const getLocalShielderActivityHistoryIndexedDB = (accountAddress: string) |
181 | 189 | const withTxHash = matches.find(i => isPresent(i.txHash)) ?? {}; |
182 | 190 |
|
183 | 191 | // Merge in order: local data → blockchain data → new activity data |
184 | | - const merged = { |
185 | | - ...localOnly, |
186 | | - ...withTxHash, |
187 | | - ...activity, |
188 | | - }; |
189 | | - |
| 192 | + const merged = { ...localOnly, ...withTxHash, ...activity }; |
190 | 193 | const updated: LocalShielderActivityHistoryArray = [...rest, merged]; |
191 | 194 |
|
192 | 195 | await db.put( |
|
0 commit comments