{"version":3,"file":"storage.es.mjs","names":[],"sources":["../src/storage/canUseLocalStorage.ts","../src/storage/createLocalStorageCache.ts"],"sourcesContent":["/**\n * Reports whether `window.localStorage` is usable in the current environment.\n *\n * Access can throw (sandboxed iframes, disabled storage, SSR), so the probe is\n * wrapped in try/catch and treats any failure as unavailable.\n * @returns {boolean} True when localStorage can be read and written.\n */\nexport const canUseLocalStorage = (): boolean => {\n  try {\n    return (\n      typeof window !== 'undefined' &&\n      typeof window.localStorage !== 'undefined'\n    )\n  } catch {\n    return false\n  }\n}\n","import type { LocalStorageCache } from '../types/storage/LocalStorageCache'\nimport { canUseLocalStorage } from './canUseLocalStorage'\n\ninterface CacheEnvelope<T> {\n  updatedAt: number\n  value: T\n}\n\n/**\n * Creates a TTL-bounded localStorage cache for a single JSON-serializable value.\n *\n * Generalizes the per-widget option caches (e.g. the alerts channel-options\n * cache): entries older than `ttlMs` read as null, all access is guarded so it\n * never throws (storage disabled, quota, SSR), and malformed entries are\n * treated as a miss. The value is wrapped with a timestamp under `key`.\n * @template T The cached value type.\n * @param {string} key - The localStorage key.\n * @param {number} ttlMs - Time-to-live in milliseconds.\n * @returns {LocalStorageCache<T>} The cache handle (read/write/clear).\n */\nexport const createLocalStorageCache = <T>(\n  key: string,\n  ttlMs: number,\n): LocalStorageCache<T> => ({\n  read() {\n    if (!canUseLocalStorage()) return null\n    try {\n      const raw = window.localStorage.getItem(key)\n      if (!raw) return null\n      const parsed = JSON.parse(raw) as CacheEnvelope<T>\n      if (!parsed || typeof parsed.updatedAt !== 'number') return null\n      if (Date.now() - parsed.updatedAt > ttlMs) return null\n      return parsed.value\n    } catch {\n      return null\n    }\n  },\n  write(value: T) {\n    if (!canUseLocalStorage()) return\n    try {\n      const envelope: CacheEnvelope<T> = { updatedAt: Date.now(), value }\n      window.localStorage.setItem(key, JSON.stringify(envelope))\n    } catch {\n      // Ignore quota/serialization failures: the cache is best-effort.\n    }\n  },\n  clear() {\n    if (!canUseLocalStorage()) return\n    try {\n      window.localStorage.removeItem(key)\n    } catch {\n      // Ignore.\n    }\n  },\n})\n"],"mappings":";AAOA,IAAa,UAAoC;CAC/C,IAAI;EACF,OACE,OAAO,SAAW,OACX,OAAO,iBAAiB;CAEnC,QAAQ;EACN,OAAO;CACT;AACF,GCIa,KACX,GACA,OAC0B;CAC1B,OAAO;EACL,IAAI,CAAC,EAAmB,GAAG,OAAO;EAClC,IAAI;GACF,IAAM,IAAM,OAAO,aAAa,QAAQ,CAAG;GAC3C,IAAI,CAAC,GAAK,OAAO;GACjB,IAAM,IAAS,KAAK,MAAM,CAAG;GAG7B,OAFI,CAAC,KAAU,OAAO,EAAO,aAAc,YACvC,KAAK,IAAI,IAAI,EAAO,YAAY,IAAc,OAC3C,EAAO;EAChB,QAAQ;GACN,OAAO;EACT;CACF;CACA,MAAM,GAAU;EACT,MAAmB,GACxB,IAAI;GACF,IAAM,IAA6B;IAAE,WAAW,KAAK,IAAI;IAAG;GAAM;GAClE,OAAO,aAAa,QAAQ,GAAK,KAAK,UAAU,CAAQ,CAAC;EAC3D,QAAQ,CAER;CACF;CACA,QAAQ;EACD,MAAmB,GACxB,IAAI;GACF,OAAO,aAAa,WAAW,CAAG;EACpC,QAAQ,CAER;CACF;AACF"}