/** * P47 — localStorage-Quota-Management. * * Wenn alte Compliance-Check-Ergebnisse den Browser-Storage fuellen, * versucht das setItem mit QuotaExceededError zu fangen, prunet * alte doc-check-result-*-Eintraege (oldest first) und retried. * * Wird von DocCheckTab/BannerCheckTab/etc beim Persistieren der * Result-Bloebs benutzt. */ const RESULT_KEY_PREFIX = 'doc-check-result-' const MAX_KEEP = 10 // Maximal 10 alte Result-Bloebs behalten. export function safeSetItem(key: string, value: string): boolean { try { localStorage.setItem(key, value) return true } catch (err: any) { if (err?.name !== 'QuotaExceededError' && err?.code !== 22 && err?.code !== 1014) { console.warn('localStorage setItem failed:', err) return false } pruneOldResults() try { localStorage.setItem(key, value) return true } catch { // Pruning hat nicht gereicht — aggressiver pruefen pruneOldResults(0) try { localStorage.setItem(key, value) return true } catch { console.warn('localStorage immer noch voll, wert wird verworfen') return false } } } } function pruneOldResults(keep: number = MAX_KEEP): void { try { const keys: { key: string; ts: number }[] = [] for (let i = 0; i < localStorage.length; i++) { const k = localStorage.key(i) if (!k || !k.startsWith(RESULT_KEY_PREFIX)) continue const ts = Number(k.slice(RESULT_KEY_PREFIX.length)) || 0 keys.push({ key: k, ts }) } keys.sort((a, b) => a.ts - b.ts) // oldest first const toRemove = keys.slice(0, Math.max(0, keys.length - keep)) for (const k of toRemove) { try { localStorage.removeItem(k.key) } catch {} } } catch {} } export function getStorageUsageMB(): number { let bytes = 0 try { for (let i = 0; i < localStorage.length; i++) { const k = localStorage.key(i) if (!k) continue const v = localStorage.getItem(k) || '' bytes += k.length + v.length } } catch {} return bytes / (1024 * 1024) }