File size: 1,638 Bytes
c08b36a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/* 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 };
})();