Skip to content

Commit 4aa0d40

Browse files
committed
add solution to removeItem
1 parent 8d3c80e commit 4aa0d40

2 files changed

Lines changed: 40 additions & 7 deletions

File tree

lib/storage/providers/IDBKeyValProvider/index.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,22 @@ const provider: StorageProvider<UseStore | undefined> = {
153153
throw new Error('Store not initialized!');
154154
}
155155

156-
return IDB.del(key, provider.store);
156+
return provider.store('readwrite', (store) => {
157+
store.delete(key);
158+
return promisifyWriteTransaction(store.transaction);
159+
});
157160
},
158161
removeItems(keysParam) {
159162
if (!provider.store) {
160163
throw new Error('Store not initialized!');
161164
}
162165

163-
return IDB.delMany(keysParam, provider.store);
166+
return provider.store('readwrite', (store) => {
167+
for (const key of keysParam) {
168+
store.delete(key);
169+
}
170+
return promisifyWriteTransaction(store.transaction);
171+
});
164172
},
165173
getDatabaseSize() {
166174
if (!provider.store) {

tests/unit/storage/providers/IDBKeyvalProviderTest.ts

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,9 @@ describe('IDBKeyValProvider', () => {
176176

177177
describe('write-error normalization (aborted transactions)', () => {
178178
// A write transaction aborted by something other than its own request (connection close,
179-
// versionchange, a sibling transaction) leaves `transaction.error === null`. idb-keyval
180-
// rejects with that null, which is unclassifiable: it slips past createStore's heal guards
181-
// (they require an Error/DOMException) and renders as the production log line
182-
// "[Onyx] Failed to save to storage. Error: null". Every write path must instead reject
183-
// with a real Error so the failure can be classified and retried sanely.
179+
// versionchange, a sibling transaction) leaves `transaction.error === null`, which idb-keyval
180+
// rejects with as-is. Every write path must instead reject with a real Error so the failure
181+
// can be classified and retried.
184182
function abortTransactionOnPut() {
185183
const originalPut = IDBObjectStore.prototype.put;
186184
jest.spyOn(IDBObjectStore.prototype, 'put').mockImplementation(function put(this: IDBObjectStore, ...args: Parameters<IDBObjectStore['put']>) {
@@ -190,6 +188,15 @@ describe('IDBKeyValProvider', () => {
190188
});
191189
}
192190

191+
function abortTransactionOnDelete() {
192+
const originalDelete = IDBObjectStore.prototype.delete;
193+
jest.spyOn(IDBObjectStore.prototype, 'delete').mockImplementation(function del(this: IDBObjectStore, ...args: Parameters<IDBObjectStore['delete']>) {
194+
const request = originalDelete.apply(this, args);
195+
this.transaction.abort();
196+
return request;
197+
});
198+
}
199+
193200
function expectAbortError(error: unknown) {
194201
expect(error).not.toBeNull();
195202
expect(error).toBeInstanceOf(DOMException);
@@ -218,6 +225,24 @@ describe('IDBKeyValProvider', () => {
218225
const error = await IDBKeyValProvider.multiMerge([[ONYXKEYS.TEST_KEY, 'value']]).catch((e: unknown) => e);
219226
expectAbortError(error);
220227
});
228+
229+
it('should reject setItem(null) with a tagged AbortError, never null', async () => {
230+
abortTransactionOnDelete();
231+
const error = await IDBKeyValProvider.setItem(ONYXKEYS.TEST_KEY, null).catch((e: unknown) => e);
232+
expectAbortError(error);
233+
});
234+
235+
it('should reject removeItem with a tagged AbortError, never null', async () => {
236+
abortTransactionOnDelete();
237+
const error = await IDBKeyValProvider.removeItem(ONYXKEYS.TEST_KEY).catch((e: unknown) => e);
238+
expectAbortError(error);
239+
});
240+
241+
it('should reject removeItems with a tagged AbortError, never null', async () => {
242+
abortTransactionOnDelete();
243+
const error = await IDBKeyValProvider.removeItems([ONYXKEYS.TEST_KEY]).catch((e: unknown) => e);
244+
expectAbortError(error);
245+
});
221246
});
222247

223248
describe('mergeItem', () => {

0 commit comments

Comments
 (0)