{"version":3,"sources":["../../../../src/cache/facades/remote-cache.ts","../../../../src/serializers/json.ts","../../../../src/cache/cache-entry/cache-entry.ts"],"sourcesContent":["import { CacheEntry } from '../cache-entry/cache-entry';\nimport type { L2CacheDriver, Logger } from '../../types/main';\nimport type { CacheEntryOptions } from '../cache-entry/cache-entry-options';\n\n/**\n * RemoteCache is a wrapper around a L2 Cache Driver that provides\n * some handy methods for interacting with a remote cache ( redis, database, etc )\n */\nexport class RemoteCache {\n  #driver: L2CacheDriver;\n  #logger: Logger;\n\n  constructor(driver: L2CacheDriver, logger: Logger) {\n    this.#driver = driver;\n    this.#logger = logger.child({ context: 'mastercache.remoteCache' });\n  }\n\n  /**\n   * Try to execute a cache operation and fallback to a default value\n   * if the operation fails\n   */\n  async #tryCacheOperation(\n    operation: string,\n    options: CacheEntryOptions,\n    fallbackValue: unknown,\n    fn: () => any,\n  ) {\n    try {\n      return await fn();\n    } catch (error) {\n      this.#logger.error({ error, opId: options.id }, `(${operation}) failed on remote cache`);\n\n      /**\n       * Rethrow the error if suppressL2Errors is disabled\n       */\n      if (options.suppressL2Errors === false) throw error;\n\n      return fallbackValue;\n    }\n  }\n\n  /**\n   * Get an item from the remote cache\n   */\n  async get(key: string, options: CacheEntryOptions) {\n    return await this.#tryCacheOperation('get', options, undefined, async () => {\n      const value = await this.#driver.get(key);\n      if (value === undefined) return;\n\n      return CacheEntry.fromDriver(key, value);\n    });\n  }\n\n  /**\n   * Set a new item in the remote cache\n   */\n  async set(key: string, value: string, options: CacheEntryOptions) {\n    return await this.#tryCacheOperation('set', options, false, async () => {\n      await this.#driver.set(key, value, options.physicalTtl);\n      return true;\n    });\n  }\n\n  /**\n   * Delete an item from the remote cache\n   */\n  async delete(key: string, options: CacheEntryOptions) {\n    return await this.#tryCacheOperation('delete', options, false, async () => {\n      return await this.#driver.delete(key);\n    });\n  }\n\n  /**\n   * Delete multiple items from the remote cache\n   */\n  async deleteMany(keys: string[], options: CacheEntryOptions) {\n    return await this.#tryCacheOperation('deleteMany', options, false, async () => {\n      return await this.#driver.deleteMany(keys);\n    });\n  }\n\n  /**\n   * Create a new namespace for the remote cache\n   */\n  namespace(namespace: string) {\n    return this.#driver.namespace(namespace) as L2CacheDriver;\n  }\n\n  /**\n   * Check if an item exists in the remote cache\n   */\n  async has(key: string, options: CacheEntryOptions) {\n    return await this.#tryCacheOperation('has', options, false, async () => {\n      return await this.#driver.has(key);\n    });\n  }\n\n  /**\n   * Clear the remote cache\n   */\n  async clear(options: CacheEntryOptions) {\n    return await this.#tryCacheOperation('clear', options, false, async () => {\n      return await this.#driver.clear();\n    });\n  }\n\n  /**\n   * Disconnect from the remote cache\n   */\n  disconnect() {\n    return this.#driver.disconnect();\n  }\n}\n","import type { CacheSerializer } from '../types/main';\n\n/**\n * Simple class to serialize and deserialize values using JSON\n */\nexport class JsonSerializer implements CacheSerializer {\n  serialize(value: unknown) {\n    return JSON.stringify(value);\n  }\n\n  deserialize(value: string) {\n    return JSON.parse(value);\n  }\n}\n","import { JsonSerializer } from '../../serializers/json';\n\n/**\n * Represents a cache entry stored inside a cache driver.\n */\nexport class CacheEntry {\n  /**\n   * The key of the cache item.\n   */\n  #key: string;\n\n  /**\n   * The value of the item.\n   */\n  #value: any;\n\n  /**\n   * The logical expiration is the time in miliseconds when the item\n   * will be considered expired. But, if grace period is enabled,\n   * the item will still be available for a while.\n   */\n  #logicalExpiration: number;\n\n  #earlyExpiration: number;\n\n  static #serializer = new JsonSerializer();\n\n  constructor(key: string, item: Record<string, any>) {\n    this.#key = key;\n    this.#value = item.value;\n    this.#logicalExpiration = item.logicalExpiration;\n    this.#earlyExpiration = item.earlyExpiration;\n  }\n\n  getValue() {\n    return this.#value;\n  }\n\n  getKey() {\n    return this.#key;\n  }\n\n  getLogicalExpiration() {\n    return this.#logicalExpiration;\n  }\n\n  getEarlyExpiration() {\n    return this.#earlyExpiration;\n  }\n\n  isLogicallyExpired() {\n    return Date.now() >= this.#logicalExpiration;\n  }\n\n  isEarlyExpired() {\n    if (!this.#earlyExpiration) {\n      return false;\n    }\n\n    if (this.isLogicallyExpired()) {\n      return false;\n    }\n\n    return Date.now() >= this.#earlyExpiration;\n  }\n\n  static fromDriver(key: string, item: string) {\n    return new CacheEntry(key, this.#serializer.deserialize(item));\n  }\n\n  applyFallbackDuration(duration: number) {\n    this.#logicalExpiration += duration;\n    this.#earlyExpiration = 0;\n    return this;\n  }\n\n  expire() {\n    this.#logicalExpiration = Date.now() - 100;\n    this.#earlyExpiration = 0;\n    return this;\n  }\n\n  serialize() {\n    return CacheEntry.#serializer.serialize({\n      value: this.#value,\n      logicalExpiration: this.#logicalExpiration,\n      earlyExpiration: this.#earlyExpiration,\n    });\n  }\n}\n"],"mappings":"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","names":[]}