{"version":3,"file":"index.cjs","names":["cache"],"sources":["../../../../../../cache/src/CacheManager.ts","../../../../../../cache/src/config.ts","../../../../../../cache/src/drivers/isForbiddenKey.ts","../../../../../../cache/src/drivers/BaseCacheEngine.ts","../../../../../../cache/src/errors.ts","../../../../../../cache/src/drivers/IndexedDBDriver.ts","../../../../../../cache/src/drivers/EncryptedIndexedDBDriver.ts","../../../../../../cache/src/drivers/PlainLocalStorageDriver.ts","../../../../../../cache/src/drivers/EncryptedLocalStorageDriver.ts","../../../../../../cache/src/drivers/EncryptedSessionStorageDriver.ts","../../../../../../cache/src/drivers/PlainSessionStorageDriver.ts","../../../../../../cache/src/drivers/RunTimeDriver.ts","../../../../../../cache/src/index.ts"],"sourcesContent":["import { CacheDriverInterface, CacheManagerInterface } from \"./types\";\r\n\r\n/**\r\n * The cache facade.\r\n *\r\n * Every storage-touching method forwards to the active driver and\r\n * returns the driver's promise, so swapping localStorage for IndexedDB\r\n * (or for a driver of your own that talks to a remote store) does not\r\n * change a single call site. Driver configuration — prefix, value\r\n * parser, value converter — stays synchronous and chainable.\r\n */\r\nexport class CacheManager implements CacheManagerInterface {\r\n  /**\r\n   * Cache Driver Engine\r\n   */\r\n  private driver!: CacheDriverInterface;\r\n\r\n  /**\r\n   * Set driver engine\r\n   */\r\n  public setDriver(driver: CacheDriverInterface) {\r\n    this.driver = driver;\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Get driver engine\r\n   */\r\n  public getDriver(): CacheDriverInterface {\r\n    return this.driver;\r\n  }\r\n\r\n  /**\r\n   * Set cache into storage\r\n   */\r\n  public async set(key: string, value: any, expiresAfter?: number) {\r\n    await this.driver.set(key, value, expiresAfter);\r\n    return this as any;\r\n  }\r\n\r\n  /**\r\n   * Get value from cache engine, if key does not exist return default value\r\n   */\r\n  public get(key: string, defaultValue: any = null) {\r\n    return this.driver.get(key, defaultValue);\r\n  }\r\n\r\n  /**\r\n   * Determine whether the cache engine has the given key\r\n   */\r\n  public has(key: string) {\r\n    return this.driver.has(key);\r\n  }\r\n\r\n  /**\r\n   * Remove the given key from the cache storage\r\n   */\r\n  public async remove(key: string) {\r\n    await this.driver.remove(key);\r\n    return this as any;\r\n  }\r\n\r\n  /**\r\n   * List the caller-facing keys owned by the active driver\r\n   */\r\n  public keys(): Promise<string[]> {\r\n    return this.driver.keys();\r\n  }\r\n\r\n  /**\r\n   * Read every live entry owned by the active driver\r\n   */\r\n  public getAll(): Promise<Record<string, any>> {\r\n    return this.driver.getAll();\r\n  }\r\n\r\n  /**\r\n   * Set prefix key\r\n   */\r\n  public setPrefixKey(key: string) {\r\n    this.driver.setPrefixKey(key);\r\n    return this as any;\r\n  }\r\n\r\n  /**\r\n   * Get prefix key\r\n   */\r\n  public getPrefixKey(): string {\r\n    return this.driver.getPrefixKey();\r\n  }\r\n\r\n  /**\r\n   * {@inheritDoc}\r\n   */\r\n  public setValueParser(parser: any): CacheDriverInterface {\r\n    this.driver.setValueParser(parser);\r\n\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * {@inheritDoc}\r\n   */\r\n  public setValueConverter(converter: any): CacheDriverInterface {\r\n    this.driver.setValueConverter(converter);\r\n\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Clear the cache storage\r\n   */\r\n  public async clear() {\r\n    await this.driver.clear();\r\n\r\n    return this;\r\n  }\r\n}\r\n\r\nconst cacheManager = new CacheManager();\r\n\r\nexport default cacheManager;\r\n","import cache from \"./CacheManager\";\r\nimport { CacheConfigurations } from \"./types\";\r\n\r\nlet configuration: Partial<CacheConfigurations> = {};\r\n\r\nexport function setCacheConfigurations(newConfiguration: CacheConfigurations) {\r\n  if (newConfiguration.driver) {\r\n    cache.setDriver(newConfiguration.driver);\r\n  }\r\n\r\n  if (newConfiguration.prefix) {\r\n    cache.getDriver().setPrefixKey(newConfiguration.prefix);\r\n  }\r\n\r\n  if (newConfiguration.valueConverter) {\r\n    cache.getDriver().setValueConverter(newConfiguration.valueConverter);\r\n  }\r\n\r\n  if (newConfiguration.valueParer) {\r\n    cache.getDriver().setValueParser(newConfiguration.valueParer);\r\n  }\r\n\r\n  configuration = { ...configuration, ...newConfiguration };\r\n}\r\n\r\nexport function getCacheConfigurations() {\r\n  return configuration;\r\n}\r\n\r\nexport function getCacheConfig<Key extends keyof CacheConfigurations>(\r\n  key: Key\r\n): CacheConfigurations[Key] | undefined {\r\n  return configuration[key];\r\n}\r\n","/**\r\n * Keys that reach `Object.prototype` (or any other prototype) when they\r\n * are assigned onto a plain object, polluting every object in the\r\n * runtime.\r\n *\r\n * Cache keys are caller-controlled — and on a shared origin they are\r\n * also *storage*-controlled, since anything else running on the origin\r\n * can write a key of its choosing into localStorage or the cache\r\n * database. Any helper that turns stored keys back into object\r\n * properties has to filter these out first.\r\n */\r\nexport const FORBIDDEN_KEYS = [\"__proto__\", \"constructor\", \"prototype\"];\r\n\r\n/**\r\n * Check whether `key` is a prototype-pollution vector.\r\n *\r\n * Note that storing such a key is perfectly safe in every driver: the\r\n * runtime driver is backed by a `Map`, Web Storage keys are strings in a\r\n * separate namespace, and IndexedDB keys are structured-clone values —\r\n * none of them do prototype-chain lookups. The guard exists for the one\r\n * place where keys become object properties again: bulk reads that\r\n * return a plain `{ key: value }` record.\r\n */\r\nexport default function isForbiddenKey(key: string): boolean {\r\n  return FORBIDDEN_KEYS.includes(key);\r\n}\r\n","import { getCacheConfig } from \"../config\";\r\nimport { CacheDriverInterface } from \"../types\";\r\nimport isForbiddenKey from \"./isForbiddenKey\";\r\n\r\n/**\r\n * Base engine for the synchronous storage backends (Web Storage and the\r\n * in-memory runtime store).\r\n *\r\n * The backends themselves answer synchronously; every public method here\r\n * lifts their result into a promise (`Promise.resolve(...)`, through the\r\n * `read` / `write` / `delete` helpers) so that all drivers — including\r\n * the IndexedDB one, which cannot be synchronous — expose the exact same\r\n * async contract. No behavior changes for the Web Storage drivers: the\r\n * work still happens in the same tick, only the return type differs.\r\n */\r\nexport default class BaseCacheEngine implements CacheDriverInterface {\r\n  /**\r\n   * Cache storage engine\r\n   */\r\n  public storage: any;\r\n\r\n  /**\r\n   * Prefix key\r\n   */\r\n  public prefixKey: string = \"\";\r\n\r\n  /**\r\n   * Value parser\r\n   */\r\n  protected _valueParser = this.parseValue.bind(this);\r\n\r\n  /**\r\n   * Value converter\r\n   */\r\n  protected _valueConverter = this.convertValue.bind(this);\r\n\r\n  /**\r\n   * set value parser\r\n   */\r\n  public setValueParser(parser: any) {\r\n    this._valueParser = parser;\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Set value converter\r\n   */\r\n  public setValueConverter(converter: any) {\r\n    this._valueConverter = converter;\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Read a raw entry from the underlying (synchronous) storage\r\n   */\r\n  protected read(storageKey: string): Promise<any> {\r\n    return Promise.resolve(this.storage.getItem(storageKey));\r\n  }\r\n\r\n  /**\r\n   * Write a raw entry into the underlying (synchronous) storage\r\n   */\r\n  protected write(storageKey: string, value: any): Promise<void> {\r\n    return Promise.resolve(this.storage.setItem(storageKey, value));\r\n  }\r\n\r\n  /**\r\n   * Delete a raw entry from the underlying (synchronous) storage\r\n   */\r\n  protected delete(storageKey: string): Promise<void> {\r\n    return Promise.resolve(this.storage.removeItem(storageKey));\r\n  }\r\n\r\n  /**\r\n   * Get vale from storage engine\r\n   */\r\n  public async get(key: string, defaultValue?: any) {\r\n    const value = await this.read(this.getKey(key));\r\n\r\n    if (value === null || value === undefined) return defaultValue;\r\n\r\n    try {\r\n      const cachedData = this._valueParser(value);\r\n\r\n      // check if there is a cache timestamp\r\n      // if it is lower than current timestamp\r\n      // then remove the key from storage\r\n      if (cachedData.expiresAt && cachedData.expiresAt < new Date().getTime()) {\r\n        await this.remove(key);\r\n        return defaultValue;\r\n      }\r\n\r\n      return cachedData.data;\r\n    } catch (error) {\r\n      await this.remove(key);\r\n      return defaultValue;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Set data into storage engine\r\n   */\r\n  public async set(key: string, value: any, expiresAfter?: number) {\r\n    const expireTime: number | false =\r\n      expiresAfter !== undefined\r\n        ? expiresAfter\r\n        : ((getCacheConfig(\"expiresAfter\") || 0) as number);\r\n\r\n    const expiresAt = expireTime\r\n      ? new Date().getTime() + expireTime * 1000\r\n      : undefined;\r\n\r\n    await this.write(\r\n      this.getKey(key),\r\n      this._valueConverter({\r\n        data: value,\r\n        expiresAt,\r\n      })\r\n    );\r\n\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Parse stored value\r\n   */\r\n  protected parseValue(value: any) {\r\n    try {\r\n      return JSON.parse(value);\r\n    } catch (error) {\r\n      return value;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Set the mechanism to store data\r\n   */\r\n  protected convertValue(value: any) {\r\n    return JSON.stringify(value);\r\n  }\r\n\r\n  /**\r\n   * Determine whether the cache engine has a live entry for the key\r\n   *\r\n   * An expired entry counts as absent — and is evicted on the spot —\r\n   * so `has()` and `get()` agree on every plain engine. Before 2.0.0 the\r\n   * Web Storage engines reported an expired entry as present while the\r\n   * runtime driver reported it as absent; consumers that branched on\r\n   * `has()` then read `get()` saw a value appear and vanish.\r\n   *\r\n   * The encrypted engines override this: their payload is opaque until\r\n   * decrypted, so they answer on presence alone.\r\n   */\r\n  public async has(key: string): Promise<boolean> {\r\n    const value = await this.read(this.getKey(key));\r\n\r\n    if (value === null || value === undefined) return false;\r\n\r\n    try {\r\n      const cachedData = this._valueParser(value);\r\n\r\n      if (cachedData.expiresAt && cachedData.expiresAt < new Date().getTime()) {\r\n        await this.remove(key);\r\n        return false;\r\n      }\r\n    } catch (error) {\r\n      // Unreadable but present: report it as present and let `get()`\r\n      // do the self-healing eviction on the next read.\r\n      return true;\r\n    }\r\n\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * Remove key from storage\r\n   */\r\n  public async remove(key: string) {\r\n    await this.delete(this.getKey(key));\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Get a proper key\r\n   */\r\n  public getKey(key: string): string {\r\n    key = (this.getPrefixKey() || \"\") + key;\r\n\r\n    return key;\r\n  }\r\n\r\n  /**\r\n   * Get prefix key\r\n   */\r\n  public getPrefixKey(): string {\r\n    return this.prefixKey;\r\n  }\r\n\r\n  /**\r\n   * Set prefix key\r\n   */\r\n  public setPrefixKey(key: string) {\r\n    this.prefixKey = key;\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * List the keys currently held by the storage engine\r\n   *\r\n   * The returned array is a snapshot: Web Storage re-indexes itself on\r\n   * every removal, so iterating `storage.length` while removing entries\r\n   * silently skips keys.\r\n   */\r\n  protected async storageKeys(): Promise<string[]> {\r\n    const storage = this.storage;\r\n\r\n    if (!storage) return [];\r\n\r\n    // Web Storage exposes an ordered `length` + `key(index)` pair.\r\n    if (\r\n      typeof storage.key === \"function\" &&\r\n      typeof storage.length === \"number\"\r\n    ) {\r\n      const keys: string[] = [];\r\n\r\n      for (let index = 0; index < storage.length; index++) {\r\n        const key = storage.key(index);\r\n\r\n        if (key !== null) keys.push(key);\r\n      }\r\n\r\n      return keys;\r\n    }\r\n\r\n    return Object.keys(storage);\r\n  }\r\n\r\n  /**\r\n   * List the caller-facing keys owned by this engine\r\n   *\r\n   * With a prefix configured, only the owned keys are listed and the\r\n   * prefix is stripped so the result can be passed straight back to\r\n   * `get()` / `remove()`. Without one the engine owns the whole\r\n   * namespace, so everything in storage is returned.\r\n   */\r\n  public async keys(): Promise<string[]> {\r\n    const prefix = this.getPrefixKey();\r\n    const keys = await this.storageKeys();\r\n\r\n    if (!prefix) return keys;\r\n\r\n    return keys\r\n      .filter(key => key.startsWith(prefix))\r\n      .map(key => key.slice(prefix.length));\r\n  }\r\n\r\n  /**\r\n   * Read every live entry owned by this engine\r\n   *\r\n   * Built on top of `keys()` / `get()`, so it costs one read per owned\r\n   * key. The returned object has a null prototype and every key is\r\n   * defined as an own property, so a stored key of `__proto__`,\r\n   * `constructor` or `prototype` lands as inert data instead of reaching\r\n   * a prototype setter.\r\n   */\r\n  public async getAll(): Promise<Record<string, any>> {\r\n    const entries: Record<string, any> = Object.create(null);\r\n    const missing = Symbol(\"missing\");\r\n\r\n    for (const key of await this.keys()) {\r\n      const value = await this.get(key, missing);\r\n\r\n      if (value === missing) continue;\r\n\r\n      if (isForbiddenKey(key)) {\r\n        Object.defineProperty(entries, key, {\r\n          value,\r\n          writable: true,\r\n          enumerable: true,\r\n          configurable: true,\r\n        });\r\n\r\n        continue;\r\n      }\r\n\r\n      entries[key] = value;\r\n    }\r\n\r\n    return entries;\r\n  }\r\n\r\n  /**\r\n   * Clear the cache storage\r\n   *\r\n   * Only the keys owned by this engine's prefix are removed, so several\r\n   * apps sharing the same origin (and therefore the same localStorage /\r\n   * sessionStorage) can clear their own namespace without destroying\r\n   * each other's data.\r\n   *\r\n   * When no prefix is configured the engine owns the whole namespace,\r\n   * so the historical behavior is kept and the entire storage is wiped.\r\n   */\r\n  public async clear() {\r\n    const prefix = this.getPrefixKey();\r\n\r\n    if (!prefix) {\r\n      await Promise.resolve(this.storage.clear());\r\n\r\n      return this;\r\n    }\r\n\r\n    for (const key of await this.storageKeys()) {\r\n      if (key.startsWith(prefix)) {\r\n        await this.delete(key);\r\n      }\r\n    }\r\n\r\n    return this;\r\n  }\r\n}\r\n","/**\r\n * Thrown when a driver needs `indexedDB` and the runtime does not have\r\n * it — server-side rendering, a Node build step, a worker without the\r\n * API, or a browser running in a mode that blocks storage entirely.\r\n *\r\n * Failing loudly beats silently degrading to \"cache miss\": a cache that\r\n * quietly stops persisting looks like a working cache right up until the\r\n * data that was supposed to be there is gone.\r\n */\r\nexport class IndexedDBUnavailableError extends Error {\r\n  public constructor(\r\n    message = \"IndexedDB unavailable: `indexedDB` is not defined in this environment (server-side rendering, or storage is blocked). Use a different cache driver on the server.\"\r\n  ) {\r\n    super(message);\r\n    this.name = \"IndexedDBUnavailableError\";\r\n  }\r\n}\r\n\r\n/**\r\n * Thrown when the storage backend refuses a write because the origin is\r\n * out of quota.\r\n *\r\n * The browser's own `QuotaExceededError` is a `DOMException` whose\r\n * message says nothing about which cache overflowed, so it is wrapped\r\n * with the offending key and the original error kept as `cause`.\r\n */\r\nexport class CacheQuotaExceededError extends Error {\r\n  public constructor(\r\n    public readonly key: string,\r\n    public readonly cause?: unknown\r\n  ) {\r\n    super(\r\n      `Cache quota exceeded while writing \"${key}\": the storage backend is full. Remove entries, lower the TTL, or store less per key.`\r\n    );\r\n    this.name = \"CacheQuotaExceededError\";\r\n  }\r\n}\r\n\r\n/**\r\n * Thrown when a driver is asked to open a database that another tab is\r\n * holding open at an older version.\r\n */\r\nexport class IndexedDBBlockedError extends Error {\r\n  public constructor(databaseName: string) {\r\n    super(\r\n      `IndexedDB upgrade for \"${databaseName}\" is blocked by another open connection — close other tabs of this app and retry.`\r\n    );\r\n    this.name = \"IndexedDBBlockedError\";\r\n  }\r\n}\r\n","import { getCacheConfig } from \"../config\";\r\nimport {\r\n  CacheQuotaExceededError,\r\n  IndexedDBBlockedError,\r\n  IndexedDBUnavailableError,\r\n} from \"../errors\";\r\nimport {\r\n  CacheDriverInterface,\r\n  IndexedDBCacheRecord,\r\n  IndexedDBDriverOptions,\r\n} from \"../types\";\r\nimport isForbiddenKey from \"./isForbiddenKey\";\r\n\r\n/**\r\n * Defaults for the IndexedDB driver.\r\n *\r\n * Exported so a consumer can reuse the same database from their own\r\n * tooling (a \"clear all caches\" button, a devtools panel) without\r\n * hard-coding the strings.\r\n */\r\nexport const DEFAULT_INDEXED_DB_NAME = \"mongez-cache\";\r\nexport const DEFAULT_INDEXED_DB_STORE = \"cache\";\r\nexport const DEFAULT_INDEXED_DB_VERSION = 1;\r\n\r\n/**\r\n * IndexedDB cache driver — opt-in.\r\n *\r\n * Unlike the Web Storage drivers this one is never wired up for you:\r\n * opening a database is a side effect, and a package import should not\r\n * create one. Pass an instance explicitly:\r\n *\r\n * ```ts\r\n * setCacheConfigurations({ driver: new IndexedDBDriver() });\r\n * ```\r\n *\r\n * Storage layout: a single object store with out-of-line keys, where the\r\n * key is the (prefixed) cache key and the record is\r\n * `{ value, expiresAt }`. Values go through the structured clone\r\n * algorithm, so `Date`, `Map`, `Set`, `ArrayBuffer` and friends survive\r\n * a round-trip untouched — no JSON pass by default. Values that are not\r\n * cloneable (functions, class instances with methods, DOM nodes) are\r\n * rejected by the browser; give the driver a `setValueConverter` /\r\n * `setValueParser` pair if you need to serialize those yourself.\r\n *\r\n * Why IndexedDB is not the default: it is asynchronous, per-origin\r\n * quota'd, and unavailable during server-side rendering, while\r\n * localStorage is present in every browser context the other drivers\r\n * already support. Consumers who need more than the ~5MB Web Storage\r\n * budget, or structured values, opt in.\r\n */\r\nexport default class IndexedDBDriver implements CacheDriverInterface {\r\n  /**\r\n   * Prefix key\r\n   */\r\n  public prefixKey: string = \"\";\r\n\r\n  /**\r\n   * Database name\r\n   */\r\n  public readonly databaseName: string;\r\n\r\n  /**\r\n   * Object store name\r\n   */\r\n  public readonly storeName: string;\r\n\r\n  /**\r\n   * Database version\r\n   */\r\n  public readonly version: number;\r\n\r\n  /**\r\n   * Migration hook\r\n   */\r\n  protected readonly onUpgrade?: IndexedDBDriverOptions[\"onUpgrade\"];\r\n\r\n  /**\r\n   * The memoized open-database promise\r\n   *\r\n   * Every operation awaits this one promise, so N concurrent calls made\r\n   * before the database is open share a single `open()` request instead\r\n   * of racing each other into N connections.\r\n   */\r\n  protected connection?: Promise<IDBDatabase>;\r\n\r\n  /**\r\n   * Value parser\r\n   */\r\n  protected _valueParser = this.parseValue.bind(this);\r\n\r\n  /**\r\n   * Value converter\r\n   */\r\n  protected _valueConverter = this.convertValue.bind(this);\r\n\r\n  public constructor(options: IndexedDBDriverOptions = {}) {\r\n    this.databaseName = options.databaseName ?? DEFAULT_INDEXED_DB_NAME;\r\n    this.storeName = options.storeName ?? DEFAULT_INDEXED_DB_STORE;\r\n    this.version = options.version ?? DEFAULT_INDEXED_DB_VERSION;\r\n    this.onUpgrade = options.onUpgrade;\r\n  }\r\n\r\n  /**\r\n   * Determine whether the current runtime can use this driver\r\n   *\r\n   * Use it to pick a driver at bootstrap instead of catching the\r\n   * `IndexedDBUnavailableError` thrown by the first read.\r\n   */\r\n  public static isSupported(): boolean {\r\n    return (\r\n      typeof globalThis !== \"undefined\" &&\r\n      Boolean((globalThis as any).indexedDB)\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Resolve the `indexedDB` factory or fail loudly\r\n   *\r\n   * Looked up lazily — at call time, never at import or construction\r\n   * time — so that a module that merely *mentions* this driver can be\r\n   * bundled into a server-rendered app without exploding on import.\r\n   */\r\n  protected factory(): IDBFactory {\r\n    const factory =\r\n      typeof globalThis !== \"undefined\"\r\n        ? ((globalThis as any).indexedDB as IDBFactory | undefined)\r\n        : undefined;\r\n\r\n    if (!factory) {\r\n      throw new IndexedDBUnavailableError();\r\n    }\r\n\r\n    return factory;\r\n  }\r\n\r\n  /**\r\n   * Open (once) and return the database connection\r\n   */\r\n  protected database(): Promise<IDBDatabase> {\r\n    if (this.connection) return this.connection;\r\n\r\n    const factory = this.factory();\r\n\r\n    const connection = new Promise<IDBDatabase>((resolve, reject) => {\r\n      const request = factory.open(this.databaseName, this.version);\r\n\r\n      request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\r\n        const database = request.result;\r\n        const transaction = request.transaction as IDBTransaction;\r\n\r\n        // Created on first open, reused on every later version bump so\r\n        // that a migration keeps the existing entries.\r\n        const store = database.objectStoreNames.contains(this.storeName)\r\n          ? transaction.objectStore(this.storeName)\r\n          : database.createObjectStore(this.storeName);\r\n\r\n        this.onUpgrade?.({\r\n          database,\r\n          store,\r\n          transaction,\r\n          oldVersion: event.oldVersion,\r\n          newVersion: event.newVersion ?? this.version,\r\n        });\r\n      };\r\n\r\n      // Another tab still holds an older version open, so this upgrade\r\n      // can never run. Reject instead of hanging forever.\r\n      request.onblocked = () => {\r\n        reject(new IndexedDBBlockedError(this.databaseName));\r\n      };\r\n\r\n      request.onsuccess = () => {\r\n        const database = request.result;\r\n\r\n        // When another tab upgrades the schema, drop this connection so\r\n        // it does not block that upgrade; the next operation reopens.\r\n        database.onversionchange = () => {\r\n          database.close();\r\n          this.connection = undefined;\r\n        };\r\n\r\n        resolve(database);\r\n      };\r\n\r\n      request.onerror = () => reject(request.error);\r\n    });\r\n\r\n    // A failed open must not be memoized forever — a transient failure\r\n    // (a blocked upgrade that later clears) would otherwise poison the\r\n    // driver for the lifetime of the page.\r\n    this.connection = connection;\r\n    connection.catch(() => {\r\n      if (this.connection === connection) this.connection = undefined;\r\n    });\r\n\r\n    return connection;\r\n  }\r\n\r\n  /**\r\n   * Close the database connection\r\n   *\r\n   * The next operation reopens it. Mostly useful in tests and in code\r\n   * that deletes the database.\r\n   */\r\n  public async close(): Promise<this> {\r\n    const connection = this.connection;\r\n\r\n    this.connection = undefined;\r\n\r\n    if (!connection) return this;\r\n\r\n    try {\r\n      (await connection).close();\r\n    } catch (error) {\r\n      // Nothing to close — the open failed in the first place.\r\n    }\r\n\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Run a single request against the object store\r\n   */\r\n  protected async request<T>(\r\n    mode: IDBTransactionMode,\r\n    run: (store: IDBObjectStore) => IDBRequest\r\n  ): Promise<T> {\r\n    const database = await this.database();\r\n\r\n    return new Promise<T>((resolve, reject) => {\r\n      let request: IDBRequest;\r\n\r\n      try {\r\n        const transaction = database.transaction(this.storeName, mode);\r\n        request = run(transaction.objectStore(this.storeName));\r\n      } catch (error) {\r\n        // Structured-clone failures and closed-database errors are\r\n        // thrown synchronously, not delivered as an error event.\r\n        return reject(error);\r\n      }\r\n\r\n      request.onsuccess = () => resolve(request.result as T);\r\n      request.onerror = () => reject(request.error);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Determine whether an error is the browser's out-of-quota signal\r\n   */\r\n  protected isQuotaError(error: any): boolean {\r\n    if (!error) return false;\r\n\r\n    return (\r\n      error.name === \"QuotaExceededError\" ||\r\n      // Firefox's historical name for the same condition.\r\n      error.name === \"NS_ERROR_DOM_QUOTA_REACHED\" ||\r\n      error.code === 22\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Parse a stored value\r\n   *\r\n   * Identity by default: IndexedDB stores structured clones, so there\r\n   * is nothing to decode.\r\n   */\r\n  protected parseValue(value: any) {\r\n    return value;\r\n  }\r\n\r\n  /**\r\n   * Convert a value before storing it\r\n   */\r\n  protected convertValue(value: any) {\r\n    return value;\r\n  }\r\n\r\n  /**\r\n   * Set value parser\r\n   */\r\n  public setValueParser(parser: any) {\r\n    this._valueParser = parser;\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Set value converter\r\n   */\r\n  public setValueConverter(converter: any) {\r\n    this._valueConverter = converter;\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Get a proper key\r\n   */\r\n  public getKey(key: string): string {\r\n    return (this.getPrefixKey() || \"\") + key;\r\n  }\r\n\r\n  /**\r\n   * Get prefix key\r\n   */\r\n  public getPrefixKey(): string {\r\n    return this.prefixKey;\r\n  }\r\n\r\n  /**\r\n   * Set prefix key\r\n   */\r\n  public setPrefixKey(key: string) {\r\n    this.prefixKey = key;\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Compute the absolute expiry timestamp for a write\r\n   */\r\n  protected expiryOf(expiresAfter?: number): number | undefined {\r\n    const expireTime: number | false =\r\n      expiresAfter !== undefined\r\n        ? expiresAfter\r\n        : ((getCacheConfig(\"expiresAfter\") || 0) as number);\r\n\r\n    return expireTime ? new Date().getTime() + expireTime * 1000 : undefined;\r\n  }\r\n\r\n  /**\r\n   * Read the raw record stored under a cache key\r\n   */\r\n  protected async record(\r\n    key: string\r\n  ): Promise<IndexedDBCacheRecord | undefined> {\r\n    return this.request<IndexedDBCacheRecord | undefined>(\r\n      \"readonly\",\r\n      store => store.get(this.getKey(key))\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Determine whether a record is past its expiry\r\n   */\r\n  protected isExpired(record: IndexedDBCacheRecord): boolean {\r\n    return Boolean(record.expiresAt && record.expiresAt < new Date().getTime());\r\n  }\r\n\r\n  /**\r\n   * Get value from cache engine, if key does not exist return default value\r\n   */\r\n  public async get(key: string, defaultValue: any = null) {\r\n    const record = await this.record(key);\r\n\r\n    if (record === undefined || record === null) return defaultValue;\r\n\r\n    // Same TTL model as the other drivers: expiry is enforced on read,\r\n    // and the dead entry is dropped rather than left to rot.\r\n    if (this.isExpired(record)) {\r\n      await this.remove(key);\r\n      return defaultValue;\r\n    }\r\n\r\n    return this._valueParser(record.value);\r\n  }\r\n\r\n  /**\r\n   * Set cache into storage\r\n   */\r\n  public async set(key: string, value: any, expiresAfter?: number) {\r\n    const record: IndexedDBCacheRecord = {\r\n      value: this._valueConverter(value),\r\n      expiresAt: this.expiryOf(expiresAfter),\r\n    };\r\n\r\n    try {\r\n      await this.request(\"readwrite\", store =>\r\n        store.put(record, this.getKey(key))\r\n      );\r\n    } catch (error) {\r\n      if (this.isQuotaError(error)) {\r\n        throw new CacheQuotaExceededError(key, error);\r\n      }\r\n\r\n      throw error;\r\n    }\r\n\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Determine whether the cache engine has a live entry for the key\r\n   */\r\n  public async has(key: string): Promise<boolean> {\r\n    const record = await this.record(key);\r\n\r\n    if (record === undefined || record === null) return false;\r\n\r\n    if (this.isExpired(record)) {\r\n      await this.remove(key);\r\n      return false;\r\n    }\r\n\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * Remove the given key from the cache storage\r\n   */\r\n  public async remove(key: string) {\r\n    await this.request(\"readwrite\", store => store.delete(this.getKey(key)));\r\n\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * List every key held in the object store\r\n   */\r\n  protected async storageKeys(): Promise<string[]> {\r\n    const keys = await this.request<IDBValidKey[]>(\"readonly\", store =>\r\n      store.getAllKeys()\r\n    );\r\n\r\n    return keys.map(key => String(key));\r\n  }\r\n\r\n  /**\r\n   * List the caller-facing keys owned by this engine\r\n   */\r\n  public async keys(): Promise<string[]> {\r\n    const prefix = this.getPrefixKey();\r\n    const keys = await this.storageKeys();\r\n\r\n    if (!prefix) return keys;\r\n\r\n    return keys\r\n      .filter(key => key.startsWith(prefix))\r\n      .map(key => key.slice(prefix.length));\r\n  }\r\n\r\n  /**\r\n   * Read every live entry owned by this engine in one transaction\r\n   *\r\n   * The returned object has a null prototype and every key is defined\r\n   * as an own property, so a cache key of `__proto__`, `constructor` or\r\n   * `prototype` — which any script sharing the origin can write into\r\n   * the database — lands as plain data instead of reaching a prototype\r\n   * setter and polluting every object in the runtime.\r\n   */\r\n  public async getAll(): Promise<Record<string, any>> {\r\n    const prefix = this.getPrefixKey();\r\n    const entries: Record<string, any> = Object.create(null);\r\n\r\n    await this.eachRecord((key, record) => {\r\n      if (prefix && !key.startsWith(prefix)) return;\r\n      if (this.isExpired(record)) return;\r\n\r\n      const cacheKey = prefix ? key.slice(prefix.length) : key;\r\n      const value = this._valueParser(record.value);\r\n\r\n      if (isForbiddenKey(cacheKey)) {\r\n        // Belt and braces: a plain assignment is already safe on a\r\n        // null-prototype object, but `defineProperty` cannot ever hit\r\n        // an inherited setter even if this object gains a prototype.\r\n        Object.defineProperty(entries, cacheKey, {\r\n          value,\r\n          writable: true,\r\n          enumerable: true,\r\n          configurable: true,\r\n        });\r\n\r\n        return;\r\n      }\r\n\r\n      entries[cacheKey] = value;\r\n    });\r\n\r\n    return entries;\r\n  }\r\n\r\n  /**\r\n   * Walk every record in the store inside a single transaction\r\n   */\r\n  protected async eachRecord(\r\n    handle: (key: string, record: IndexedDBCacheRecord) => void\r\n  ): Promise<void> {\r\n    const database = await this.database();\r\n\r\n    return new Promise<void>((resolve, reject) => {\r\n      let transaction: IDBTransaction;\r\n\r\n      try {\r\n        transaction = database.transaction(this.storeName, \"readonly\");\r\n      } catch (error) {\r\n        return reject(error);\r\n      }\r\n\r\n      const request = transaction.objectStore(this.storeName).openCursor();\r\n\r\n      request.onsuccess = () => {\r\n        const cursor = request.result;\r\n\r\n        if (!cursor) return;\r\n\r\n        handle(String(cursor.key), cursor.value as IndexedDBCacheRecord);\r\n        cursor.continue();\r\n      };\r\n\r\n      request.onerror = () => reject(request.error);\r\n      transaction.oncomplete = () => resolve();\r\n      transaction.onabort = () => reject(transaction.error);\r\n      transaction.onerror = () => reject(transaction.error);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Clear the cache storage\r\n   *\r\n   * Prefix-scoped exactly like the Web Storage engines: the cache\r\n   * database is shared by every driver instance pointed at it, so an\r\n   * app that namespaced its keys must not wipe its neighbour's. With no\r\n   * prefix the engine owns the whole store and clears it.\r\n   */\r\n  public async clear() {\r\n    const prefix = this.getPrefixKey();\r\n\r\n    if (!prefix) {\r\n      await this.request(\"readwrite\", store => store.clear());\r\n\r\n      return this;\r\n    }\r\n\r\n    const database = await this.database();\r\n\r\n    await new Promise<void>((resolve, reject) => {\r\n      let transaction: IDBTransaction;\r\n\r\n      try {\r\n        transaction = database.transaction(this.storeName, \"readwrite\");\r\n      } catch (error) {\r\n        return reject(error);\r\n      }\r\n\r\n      // A cursor keeps the deletions inside one transaction: issuing\r\n      // them one promise at a time would let the transaction commit\r\n      // between deletes and leave a half-cleared namespace behind.\r\n      const request = transaction.objectStore(this.storeName).openCursor();\r\n\r\n      request.onsuccess = () => {\r\n        const cursor = request.result;\r\n\r\n        if (!cursor) return;\r\n\r\n        if (String(cursor.key).startsWith(prefix)) {\r\n          cursor.delete();\r\n        }\r\n\r\n        cursor.continue();\r\n      };\r\n\r\n      request.onerror = () => reject(request.error);\r\n      transaction.oncomplete = () => resolve();\r\n      transaction.onabort = () => reject(transaction.error);\r\n      transaction.onerror = () => reject(transaction.error);\r\n    });\r\n\r\n    return this;\r\n  }\r\n}\r\n","import { getCacheConfig } from \"../config\";\r\nimport { CacheQuotaExceededError } from \"../errors\";\r\nimport { CacheDriverInterface, IndexedDBCacheRecord } from \"../types\";\r\nimport IndexedDBDriver from \"./IndexedDBDriver\";\r\n\r\n/**\r\n * IndexedDB driver whose payload is encrypted at rest.\r\n *\r\n * The whole `{data, expiresAt}` envelope is encrypted — the same shape\r\n * the encrypted Web Storage drivers write — so the expiry travels\r\n * *inside* the authenticated cypher and cannot be extended by anyone who\r\n * can write to the database.\r\n *\r\n * `expiresAt` is ALSO stored in the clear on the record, because the\r\n * driver has to evict expired entries without decrypting every row\r\n * (a rotated key would otherwise leave the database growing forever).\r\n * The two are checked in order, so the effective expiry is the earlier\r\n * of the two: pushing the plaintext copy further out buys an attacker\r\n * nothing, and pulling it in only evicts an entry they could have\r\n * deleted outright anyway. What the plaintext copy does leak is *when*\r\n * an entry expires — a session length, roughly. If that matters more\r\n * than unbounded growth on a stale key, set no TTL.\r\n */\r\nexport default class EncryptedIndexedDBDriver\r\n  extends IndexedDBDriver\r\n  implements CacheDriverInterface\r\n{\r\n  /**\r\n   * Set cache into storage\r\n   */\r\n  public async set(key: string, value: any, expiresAfter?: number) {\r\n    const expiresAt = this.expiryOf(expiresAfter);\r\n\r\n    const cypher = await getCacheConfig(\"encryption\")?.encrypt({\r\n      data: value,\r\n      expiresAt,\r\n    });\r\n\r\n    const record: IndexedDBCacheRecord = { value: cypher, expiresAt };\r\n\r\n    try {\r\n      await this.request(\"readwrite\", store =>\r\n        store.put(record, this.getKey(key))\r\n      );\r\n    } catch (error) {\r\n      if (this.isQuotaError(error)) {\r\n        throw new CacheQuotaExceededError(key, error);\r\n      }\r\n\r\n      throw error;\r\n    }\r\n\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Get value from cache engine, if key does not exist return default value\r\n   *\r\n   * A cypher that fails to decrypt — tampered record, rotated key,\r\n   * truncated write — is evicted and the default value returned, so one\r\n   * poisoned row cannot make every later read throw. With AES-GCM the\r\n   * failed authentication tag lands here too, which makes eviction the\r\n   * tamper response as well.\r\n   */\r\n  public async get(key: string, defaultValue: any = null) {\r\n    const record = await this.record(key);\r\n\r\n    if (record === undefined || record === null) return defaultValue;\r\n\r\n    if (this.isExpired(record)) {\r\n      await this.remove(key);\r\n      return defaultValue;\r\n    }\r\n\r\n    try {\r\n      const decrypted = await getCacheConfig(\"encryption\")?.decrypt(\r\n        record.value\r\n      );\r\n\r\n      // Legacy / non-envelope cyphers: return whatever came out, with\r\n      // no expiry, matching the encrypted Web Storage drivers.\r\n      if (\r\n        decrypted === null ||\r\n        decrypted === undefined ||\r\n        typeof decrypted !== \"object\" ||\r\n        !(\"data\" in decrypted)\r\n      ) {\r\n        return decrypted === null || decrypted === undefined\r\n          ? defaultValue\r\n          : decrypted;\r\n      }\r\n\r\n      // The authenticated copy of the expiry wins over the plaintext\r\n      // one on the record.\r\n      if (decrypted.expiresAt && decrypted.expiresAt < new Date().getTime()) {\r\n        await this.remove(key);\r\n        return defaultValue;\r\n      }\r\n\r\n      return decrypted.data;\r\n    } catch (error) {\r\n      await this.remove(key);\r\n      return defaultValue;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Read every live entry owned by this engine\r\n   *\r\n   * Overridden because the base implementation reads records in one\r\n   * transaction and cannot `await` a decrypt inside it — the records\r\n   * are collected first, then decrypted key by key through `get()`.\r\n   */\r\n  public async getAll(): Promise<Record<string, any>> {\r\n    const entries: Record<string, any> = Object.create(null);\r\n\r\n    for (const key of await this.keys()) {\r\n      const value = await this.get(key, undefined);\r\n\r\n      if (value === undefined) continue;\r\n\r\n      Object.defineProperty(entries, key, {\r\n        value,\r\n        writable: true,\r\n        enumerable: true,\r\n        configurable: true,\r\n      });\r\n    }\r\n\r\n    return entries;\r\n  }\r\n}\r\n","import { CacheDriverInterface } from \"../types\";\r\nimport BaseCacheEngine from \"./BaseCacheEngine\";\r\n\r\nexport default class PlainLocalStorageDriver\r\n  extends BaseCacheEngine\r\n  implements CacheDriverInterface\r\n{\r\n  /**\r\n   * Set the storage engine\r\n   *\r\n   * `localStorage` is synchronous; `BaseCacheEngine` wraps every call to\r\n   * it in `Promise.resolve(...)` so this driver exposes the same async\r\n   * contract as the IndexedDB one. Nothing about the timing of the write\r\n   * itself changes.\r\n   */\r\n  public storage = localStorage;\r\n}\r\n","import { getCacheConfig } from \"../config\";\r\nimport { CacheDriverInterface } from \"../types\";\r\nimport PlainLocalStorageDriver from \"./PlainLocalStorageDriver\";\r\n\r\nexport default class EncryptedLocalStorageDriver\r\n  extends PlainLocalStorageDriver\r\n  implements CacheDriverInterface\r\n{\r\n  /**\r\n   * Set data into storage engine\r\n   *\r\n   * Wraps the value in a `{data, expiresAt}` envelope (matching the\r\n   * plain driver shape) BEFORE encrypting, so the encrypted variant\r\n   * honors `expiresAfter` just like the plain drivers do.\r\n   *\r\n   * The configured `encrypt` is awaited: @mongez/encryption 2.x returns\r\n   * a promise (WebCrypto AES-GCM cannot be synchronous), while 1.x\r\n   * returned a string. `await` accepts both.\r\n   */\r\n  public async set(key: string, value: any, expiresAfter?: number) {\r\n    const expireTime: number | false =\r\n      expiresAfter !== undefined\r\n        ? expiresAfter\r\n        : ((getCacheConfig(\"expiresAfter\") || 0) as number);\r\n\r\n    const expiresAt = expireTime\r\n      ? new Date().getTime() + expireTime * 1000\r\n      : undefined;\r\n\r\n    const encryption = getCacheConfig(\"encryption\");\r\n\r\n    const cypher = await encryption?.encrypt({\r\n      data: value,\r\n      expiresAt,\r\n    });\r\n\r\n    await this.write(this.getKey(key), cypher);\r\n\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Get value from storage engine\r\n   *\r\n   * Decrypts then unwraps the `{data, expiresAt}` envelope and checks\r\n   * expiry. For backward compatibility with legacy cyphers that were\r\n   * written before the envelope was introduced (no `data` / `expiresAt`\r\n   * keys), the decrypted value is returned as-is with no expiration.\r\n   *\r\n   * A cypher that fails to decrypt (tampered entry, rotated key,\r\n   * truncated write) must not make every subsequent read throw, so the\r\n   * poisoned entry is evicted and the default value is returned —\r\n   * the same self-healing behavior `BaseCacheEngine.get()` implements.\r\n   * With an authenticated cipher (AES-GCM) that eviction is also the\r\n   * tamper response: a modified cypher fails the tag check, so it is\r\n   * dropped rather than returned as data.\r\n   */\r\n  public async get(key: string, defaultValue: any = null) {\r\n    const value = await this.read(this.getKey(key));\r\n\r\n    if (!value) return defaultValue;\r\n\r\n    try {\r\n      const decrypted = await getCacheConfig(\"encryption\")?.decrypt(value);\r\n\r\n      // Legacy format detection: pre-envelope cyphers decrypt to\r\n      // arbitrary user data (string / number / object without\r\n      // `data` + `expiresAt` keys). Treat those as immortal entries.\r\n      if (\r\n        decrypted === null ||\r\n        decrypted === undefined ||\r\n        typeof decrypted !== \"object\" ||\r\n        !(\"data\" in decrypted)\r\n      ) {\r\n        return decrypted === null || decrypted === undefined\r\n          ? defaultValue\r\n          : decrypted;\r\n      }\r\n\r\n      if (decrypted.expiresAt && decrypted.expiresAt < new Date().getTime()) {\r\n        await this.remove(key);\r\n        return defaultValue;\r\n      }\r\n\r\n      return decrypted.data;\r\n    } catch (error) {\r\n      await this.remove(key);\r\n      return defaultValue;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Determine whether the cache engine has a live entry for the key\r\n   *\r\n   * Presence is decided without decrypting: the cypher is opaque, and\r\n   * running the (now async) decrypt on every `has()` would leak both\r\n   * CPU and, on a rotated key, entries — an eviction is a write, and a\r\n   * read-shaped call should not silently rewrite storage. Expiry is\r\n   * therefore enforced by `get()`, which has to decrypt anyway.\r\n   */\r\n  public async has(key: string): Promise<boolean> {\r\n    const value = await this.read(this.getKey(key));\r\n\r\n    return value !== null && value !== undefined;\r\n  }\r\n\r\n  /**\r\n   * Remove key from storage\r\n   */\r\n  public async remove(key: string) {\r\n    await this.delete(this.getKey(key));\r\n\r\n    return this;\r\n  }\r\n}\r\n","import { CacheDriverInterface } from \"../types\";\r\nimport EncryptedLocalStorageDriver from \"./EncryptedLocalStorageDriver\";\r\n\r\nexport default class EncryptedSessionStorageDriver\r\n  extends EncryptedLocalStorageDriver\r\n  implements CacheDriverInterface\r\n{\r\n  /**\r\n   * Set the storage engine\r\n   */\r\n  public storage = sessionStorage;\r\n}\r\n","import { CacheDriverInterface } from \"../types\";\r\nimport BaseCacheEngine from \"./BaseCacheEngine\";\r\n\r\nexport default class PlainSessionStorageDriver\r\n  extends BaseCacheEngine\r\n  implements CacheDriverInterface\r\n{\r\n  /**\r\n   * Set the storage engine\r\n   *\r\n   * `sessionStorage` is synchronous; `BaseCacheEngine` wraps every call\r\n   * to it in `Promise.resolve(...)` so this driver exposes the same\r\n   * async contract as the IndexedDB one.\r\n   */\r\n  public storage = sessionStorage;\r\n}\r\n","import { CacheDriverInterface } from \"../types\";\r\nimport BaseCacheEngine from \"./BaseCacheEngine\";\r\n\r\nexport default class RunTimeDriver\r\n  extends BaseCacheEngine\r\n  implements CacheDriverInterface\r\n{\r\n  /**\r\n   * Set the storage engine\r\n   *\r\n   * The driver is its own backend: `getItem` / `setItem` / `removeItem`\r\n   * below stay synchronous, and `BaseCacheEngine` lifts them into\r\n   * promises so this driver satisfies the async contract shared with\r\n   * IndexedDB without paying for real asynchrony.\r\n   */\r\n  public storage = this;\r\n\r\n  /**\r\n   * Data list\r\n   *\r\n   * Backed by a `Map` rather than a plain object: cache keys are\r\n   * caller-controlled, and on a plain object keys like `__proto__`,\r\n   * `constructor` or `toString` resolve through the prototype chain.\r\n   * That made `has(\"constructor\")` report `true` without anything\r\n   * being set, `set(\"__proto__\", value)` write to the store's\r\n   * prototype instead of the store, and `remove(\"__proto__\")` a silent\r\n   * no-op. A `Map` has no prototype-chain lookup, so every key is\r\n   * treated as plain data.\r\n   */\r\n  public data = new Map<string, any>();\r\n\r\n  /**\r\n   * Get item\r\n   *\r\n   * Returns `null` for missing keys (when no `defaultValue` is given)\r\n   * to match the Web Storage API contract. The previous implementation\r\n   * returned `undefined`, which broke `BaseCacheEngine.has()` — the\r\n   * base engine checks `getItem(...) !== null` and `undefined !== null`\r\n   * is `true`, so `has(missingKey)` reported `true` on this driver.\r\n   */\r\n  public getItem(key: string, defaultValue: any = null) {\r\n    const data = this.data.get(key);\r\n\r\n    if (!data) return defaultValue;\r\n\r\n    if (data.expiresAt && data.expiresAt < new Date().getTime()) {\r\n      this.removeItem(key);\r\n      return defaultValue;\r\n    }\r\n\r\n    return data.value;\r\n  }\r\n\r\n  /**\r\n   * Set item\r\n   */\r\n  public setItem(key: string, value: any, expiresAfter?: number) {\r\n    this.data.set(key, {\r\n      value,\r\n      expiresAt: expiresAfter\r\n        ? new Date().getTime() + expiresAfter * 1000\r\n        : undefined,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Remove item\r\n   */\r\n  public removeItem(key: string) {\r\n    this.data.delete(key);\r\n  }\r\n\r\n  /**\r\n   * {@inheritDoc}\r\n   */\r\n  protected convertValue(value: any) {\r\n    return value;\r\n  }\r\n\r\n  /**\r\n   * {@inheritDoc}\r\n   */\r\n  protected parseValue(value: any) {\r\n    return value;\r\n  }\r\n\r\n  /**\r\n   * {@inheritDoc}\r\n   */\r\n  protected async storageKeys(): Promise<string[]> {\r\n    return [...this.data.keys()];\r\n  }\r\n\r\n  /**\r\n   * Clear the cache storage\r\n   *\r\n   * Overridden because `storage` points back at the driver itself, so\r\n   * the base implementation's `storage.clear()` fallback would recurse\r\n   * into this very method. Prefix scoping matches the base engine: with\r\n   * a prefix only the owned keys are dropped, without one the whole\r\n   * in-memory store is wiped.\r\n   */\r\n  public async clear() {\r\n    const prefix = this.getPrefixKey();\r\n\r\n    if (!prefix) {\r\n      this.data.clear();\r\n\r\n      return this;\r\n    }\r\n\r\n    for (const key of await this.storageKeys()) {\r\n      if (key.startsWith(prefix)) {\r\n        this.data.delete(key);\r\n      }\r\n    }\r\n\r\n    return this;\r\n  }\r\n}\r\n","import cache from \"./CacheManager\";\r\nexport { CacheManager } from \"./CacheManager\";\r\nexport * from \"./config\";\r\nexport { default as BaseCacheEngine } from \"./drivers/BaseCacheEngine\";\r\nexport { default as EncryptedIndexedDBDriver } from \"./drivers/EncryptedIndexedDBDriver\";\r\nexport { default as EncryptedLocalStorageDriver } from \"./drivers/EncryptedLocalStorageDriver\";\r\nexport { default as EncryptedSessionStorageDriver } from \"./drivers/EncryptedSessionStorageDriver\";\r\nexport {\r\n  DEFAULT_INDEXED_DB_NAME,\r\n  DEFAULT_INDEXED_DB_STORE,\r\n  DEFAULT_INDEXED_DB_VERSION,\r\n  default as IndexedDBDriver,\r\n} from \"./drivers/IndexedDBDriver\";\r\nexport { default as PlainLocalStorageDriver } from \"./drivers/PlainLocalStorageDriver\";\r\nexport { default as PlainSessionStorageDriver } from \"./drivers/PlainSessionStorageDriver\";\r\nexport { default as RunTimeDriver } from \"./drivers/RunTimeDriver\";\r\nexport * from \"./errors\";\r\nexport * from \"./types\";\r\n\r\nexport default cache;\r\n"],"mappings":"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"}