feat: precache resilience — circuit breaker, forensic diag log, safe version check

- Circuit breaker: abort preload after 5 consecutive network failures
  (success or 404 resets streak) instead of grinding doomed retries
- localStorage diag ring buffer (survives cache wipes): preload-start/
  done/abort, manifest-unavailable, version events; shown in Settings
- checkDataVersion: no longer wipes IDB on transient read errors
  (DataCache.has tri-state probe); logs old value on real migrations
- loadManifest: null result no longer cached forever (per-session fallback lock-in)
This commit is contained in:
catarrh committed 2026-08-22 22:39:37 +03:00
1 parent ee5fb17c6b
commit 8c4f60d635
6 files changed
+140 -7

No files matched your search

+18
View File
@@ -93,6 +93,24 @@ export class DataCache {
}
}
/**
* Tri-state presence probe: true/false when known, null on read error.
* Unlike get(), lets callers distinguish "absent" from "unreadable".
*/
static async has(key: string): Promise<boolean | null> {
try {
const db = await getDB();
return await new Promise<boolean | null>((resolve) => {
const tx = db.transaction(STORE_NAME, 'readonly');
const request = tx.objectStore(STORE_NAME).count(IDBKeyRange.only(key));
request.onsuccess = () => resolve(request.result > 0);
request.onerror = () => resolve(null);
});
} catch {
return null;
}
}
/**
* Store a value in the cache.
*/