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:
1 parent
ee5fb17c6b
commit
8c4f60d635
6 files changed
+140
-7
No files matched your search
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user