Islamic3 / cache.js
Ghada-99-Ragab's picture
Upload 31 files
c08b36a verified
Raw History Blame Contribute Delete
1.64 kB
/* Small JSON cache on top of localStorage (all calls are failure-safe: the cache is only an optimisation). */
(function () {
const cfg = window.ICV_CONFIG, P = "icv:" + cfg.CACHE_VERSION + ":";
const hash = (s) => { let h = 2166136261; for (let i = 0; i < s.length; i++) { h ^= s.charCodeAt(i); h = Math.imul(h, 16777619); } return (h >>> 0).toString(36) + s.length.toString(36); };
const get = (key) => { try { const v = JSON.parse(localStorage.getItem(P + key)); return v ? v.d : null; } catch (e) { return null; } };
function set(key, data) {
try {
localStorage.setItem(P + key, JSON.stringify({ t: Date.now(), d: data }));
const keys = Object.keys(localStorage).filter((k) => k.startsWith(P + "r:"));
if (keys.length > cfg.CACHE_MAX_ENTRIES) { // drop the oldest results
keys.map((k) => [k, (JSON.parse(localStorage.getItem(k)) || {}).t || 0]).sort((a, b) => a[1] - b[1])
.slice(0, keys.length - cfg.CACHE_MAX_ENTRIES).forEach(([k]) => localStorage.removeItem(k));
}
} catch (e) { /* quota or private mode */ }
}
function purgeOld() { try { Object.keys(localStorage).filter((k) => k.startsWith("icv:") && !k.startsWith(P)).forEach((k) => localStorage.removeItem(k)); } catch (e) {} }
async function json(url) { // stale-while-revalidate for small JSON files such as the demo examples
const cached = get("j:" + url);
const fresh = fetch(url).then((r) => r.json()).then((d) => { set("j:" + url, d); return d; });
if (cached) { fresh.catch(() => {}); return cached; }
return fresh;
}
purgeOld();
window.icvCache = { hash, get, set, json };
})();