ChemPal Documentation - v1.6.0
    Preparing search index...
    • Wraps an async function with a persistent, time-to-live cache backed by chrome.storage.local. The returned function checks the cache first and only invokes fn on a miss or when the cached entry has expired. Only defined results are cached, so a failed or empty lookup (undefined) is never negatively cached. Any storage error is swallowed and the call falls through to fn, so the wrapper can never break a caller that runs without chrome.storage.

      Type Parameters

      • Args extends unknown[]
      • Result

      Parameters

      Returns (...args: Args) => Promise<Result>

      A drop-in replacement for fn that serves from cache when possible

      const getCidsByCas = withTtlCache(getCidsByCasUncached, { namespace: "cidsByCas" });
      await getCidsByCas("15681-89-7"); // fetches, then caches for 3 days
      await getCidsByCas("15681-89-7"); // served from cache, no network call
      export function withTtlCache<Args extends unknown[], Result>(
      fn: (...args: Args) => Promise<Result>,
      options: TtlCacheOptions<Args>,
      ): (...args: Args) => Promise<Result> {
      const { namespace, ttlMs = THREE_DAYS_MS } = options;
      const keyFromArgs = options.keyFromArgs ?? ((...args: Args) => JSON.stringify(args));

      return async (...args: Args): Promise<Result> => {
      const storageKey = `${CACHE_KEY_PREFIX}:${namespace}:${keyFromArgs(...args)}`;

      // Try the cache first; any storage failure falls through to the source.
      try {
      const stored = await cstorage.local.get(storageKey);
      const entry = stored[storageKey];
      if (isCacheEntry<Result>(entry) && Date.now() - entry.cachedAt < ttlMs) {
      return entry.value;
      }
      } catch (error) {
      console.debug(`Cache read failed for "${storageKey}"; querying source`, error);
      }

      const result = await fn(...args);

      // Skip caching undefined so failed/empty lookups aren't negatively cached for the whole TTL.
      if (result !== undefined) {
      try {
      await cstorage.local.set({ [storageKey]: { cachedAt: Date.now(), value: result } });
      } catch (error) {
      console.debug(`Cache write failed for "${storageKey}"`, error);
      }
      }

      return result;
      };
      }