diff --git a/src/services/persistent-cache.ts b/src/services/persistent-cache.ts index 0208f836d..6b1d9cc5a 100644 --- a/src/services/persistent-cache.ts +++ b/src/services/persistent-cache.ts @@ -82,9 +82,13 @@ async function deleteFromIndexedDbByPrefix(prefix: string): Promise { request.onsuccess = () => { const cursor = request.result; if (!cursor) return; - - store.delete(cursor.primaryKey); - cursor.continue(); + // iOS Safari kills in-flight IDB transactions when the tab backgrounds; + // prefix-invalidation is idempotent so swallow TransactionInactiveError + // and let the next invalidation call resume. + try { + store.delete(cursor.primaryKey); + cursor.continue(); + } catch { /* tx died mid-iteration */ } }; request.onerror = () => reject(request.error); }); diff --git a/src/services/storage.ts b/src/services/storage.ts index ae7992ccc..934b1590f 100644 --- a/src/services/storage.ts +++ b/src/services/storage.ts @@ -214,7 +214,10 @@ export async function cleanOldSnapshots(): Promise { const request = store.index('by_time').openCursor(IDBKeyRange.upperBound(cutoff)); request.onsuccess = () => { const cursor = request.result; - if (cursor) { cursor.delete(); cursor.continue(); } + if (!cursor) return; + // iOS Safari kills in-flight IDB transactions when the tab backgrounds; + // cleanup is idempotent so swallow TransactionInactiveError and resume next run. + try { cursor.delete(); cursor.continue(); } catch { /* tx died mid-cleanup */ } }; void tx; },