UNPKG

@discoveryjs/discovery

Version:

Frontend framework for rapid data (JSON) analysis, shareable serverless reports and dashboards

109 lines (108 loc) 3.1 kB
import { Observer } from "../observer.js"; export const getSessionStorageEntry = /* @__PURE__ */ createStorageEntryFactory("sessionStorage"); export const getSessionStorageValue = /* @__PURE__ */ createStorageReader("sessionStorage"); export const getLocalStorageEntry = /* @__PURE__ */ createStorageEntryFactory("localStorage"); export const getLocalStorageValue = /* @__PURE__ */ createStorageReader("localStorage"); const storageMaps = /* @__PURE__ */ new Map(); function createStorageEntryFactory(type) { const storage = getStorage(type); const map = /* @__PURE__ */ new Map(); return function getOrCreateStorageEntry(key) { let persistentKey = map.get(key); if (persistentKey === void 0) { persistentKey = new PersistentStorageEntry(storage, key); map.set(key, persistentKey); registerStorageMap(storage, map); } return persistentKey; }; } function createStorageReader(type) { const storage = getStorage(type); return function getStorageValue(key) { return storage?.getItem(key) ?? null; }; } function getStorage(type) { const key = "__storage_test__" + Math.random(); let storage; try { storage = window[type]; } catch { return null; } try { storage.setItem(key, key); storage.removeItem(key); } catch (e) { const ok = e instanceof DOMException && // everything except Firefox (e.code === 22 || // Firefox e.code === 1014 || // test name field too, because code might not be present // everything except Firefox e.name === "QuotaExceededError" || // Firefox e.name === "NS_ERROR_DOM_QUOTA_REACHED") && // acknowledge QuotaExceededError only if there's something already stored storage.length !== 0; if (!ok) { return null; } } return storage; } function registerStorageMap(storage, map) { if (storage !== null && !storageMaps.has(storage)) { storageMaps.set(storage, map); if (storageMaps.size === 1) { addEventListener("storage", (e) => { const map2 = storageMaps.get(e.storageArea); if (map2 !== void 0) { const persistentKey = map2.get(e.key); if (persistentKey) { persistentKey.forceSync(); } } }); } } } export class PersistentStorageEntry extends Observer { #storage; #key; constructor(storage, key) { super(storage?.getItem(key) ?? null); this.#storage = storage; this.#key = key; } #readStorageValue() { return this.#storage?.getItem(this.#key) ?? null; } get storage() { return this.#storage; } get key() { return this.#key; } get() { return this.value; } set(value) { if (this.#storage) { const storageValue = this.#readStorageValue(); if (value !== storageValue) { this.#storage.setItem(this.#key, value); return super.set(value); } } return false; } delete() { if (this.#storage) { this.#storage.removeItem(this.#key); } } forceSync() { if (this.#storage) { return super.set(this.#readStorageValue()); } return false; } }