:globe_showing_Americas:
Code Snippet - July 2, 2026LocalStorage with TTL and Auto-CleanuplocalStorage data that never expires? This wrapper adds per-key expiration, auto-cleanup, quota awareness, and in-memory fallback.
class TTLStorage {
constructor(prefix = 'ttl_') {
this.prefix = prefix;
this._avail = (() => {
try { localStorage.setItem('t', '1'); localStorage.removeItem('t'); return true; }
catch { return false; }
})();
this._mem = new Map();
}
set(name, value, opts = {}) {
const ttl = opts.ttl ?? 86400;
const d = JSON.stringify({ v: value, e: ttl === 0 ? 0 : Date.now() + ttl * 1000 });
if (!this._avail) return this._mem.set(name, d);
try { return localStorage.setItem(this.prefix + name, d); }
catch (err) {
if (err.name === 'QuotaExceededError') { this.cleanup(); try { return localStorage.setItem(this.prefix + name, d); } catch { return false; } }
throw err;
}
}
get(name) {
const raw = this._avail ? localStorage.getItem(this.prefix + name) : this._mem.get(name);
if (!raw) return null;
try { const { v, e } = JSON.parse(raw); return (e === 0 || Date.now() > e) ? null : v; } catch { return null; }
}
cleanup() {
let n = 0;
if (this._avail) for (let i = 0; i < localStorage.length; i++) {
const k = localStorage.key(i);
if (!k || !k.startsWith(this.prefix)) continue;
try { const { e } = JSON.parse(localStorage.getItem(k)); if (e === 0 || Date.now() > e) { localStorage.removeItem(k); n++; } }
catch { localStorage.removeItem(k); n++; }
}
return n;
}
}
const s = new TTLStorage();
s.set('token', 'abc', { ttl: 3600 }); // 1h
s.set('prefs', { theme: 'dark' }); // 24h default
s.set('sess', true, { ttl: 0 }); // expires on reload
s.cleanup(); // run on startup
:bulb: Auto-cleans, respects quotas, falls back to memory.