{"version":3,"sources":["../src/context.ts","../src/errors.ts","../src/cache.ts","../src/tiered.ts","../src/swr.ts","../src/namespace.ts"],"names":["Err","Ok","res","value"],"mappings":"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","file":"index.mjs","sourcesContent":["export interface Context {\n  waitUntil: (p: Promise<unknown>) => void;\n}\n\nexport class DefaultStatefulContext implements Context {\n  public waitUntil<TPromise = unknown>(_p: Promise<TPromise>) {\n    // do nothing, the promise will resolve on its own\n  }\n}\n","import { BaseError } from \"@unkey/error\";\n\nexport class CacheError extends BaseError {\n  public readonly name = \"CacheError\";\n  public readonly retry = false;\n\n  public readonly tier: string;\n  public readonly key: string;\n\n  constructor(opts: {\n    tier: string;\n    key: string;\n    message: string;\n  }) {\n    super(opts);\n    this.name = \"CacheError\";\n    this.tier = opts.tier;\n    this.key = opts.key;\n  }\n}\n","import type { Cache } from \"./interface\";\nimport type { Namespace } from \"./namespace\";\n\nexport function createCache<\n  TNamespaces extends Record<string, unknown>,\n  TNamespace extends keyof TNamespaces = keyof TNamespaces,\n>(\n  namespaces: {\n    [TName in keyof TNamespaces]: Namespace<TNamespaces[TName]>;\n  },\n): Cache<TNamespaces> {\n  return Object.entries(namespaces).reduce(\n    (acc, [n, c]) => {\n      acc[n as TNamespace] = {\n        get: (key) => c.get(n, key),\n        set: (key, value, opts) => c.set(n, key, value, opts),\n        remove: (key) => c.remove(n, key),\n        swr: (key, loadFromOrigin) => c.swr(n, key, loadFromOrigin),\n      };\n      return acc;\n    },\n    {} as Cache<TNamespaces>,\n  );\n}\n","import { Err, Ok, type Result } from \"@unkey/error\";\nimport type { Context } from \"./context\";\nimport { CacheError } from \"./errors\";\nimport type { Entry, Store } from \"./stores\";\n\n/**\n * TieredCache is a cache that will first check the memory cache, then the zone cache.\n */\nexport class TieredStore<TNamespace extends string, TValue> implements Store<TNamespace, TValue> {\n  private ctx: Context;\n  private readonly tiers: Store<TNamespace, TValue>[];\n  public readonly name = \"tiered\";\n\n  /**\n   * Create a new tiered store\n   * Stored are checked in the order they are provided\n   * The first store to return a value will be used to populate all previous stores\n   *\n   *\n   * `stores` can accept `undefined` as members to allow you to construct the tiers dynamically\n   * @example\n   * ```ts\n   * new TieredStore(ctx, [\n   *   new MemoryStore(..),\n   *   process.env.ENABLE_X_STORE ? new XStore(..) : undefined\n   * ])\n   * ```\n   */\n  constructor(ctx: Context, stores: (Store<TNamespace, TValue> | undefined)[]) {\n    this.ctx = ctx;\n    this.tiers = stores.filter(Boolean) as Store<TNamespace, TValue>[];\n  }\n\n  /**\n   * Return the cached value\n   *\n   * The response will be `undefined` for cache misses or `null` when the key was not found in the origin\n   */\n  public async get(\n    namespace: TNamespace,\n    key: string,\n  ): Promise<Result<Entry<TValue> | undefined, CacheError>> {\n    if (this.tiers.length === 0) {\n      return Ok(undefined);\n    }\n\n    for (let i = 0; i < this.tiers.length; i++) {\n      const res = await this.tiers[i].get(namespace, key);\n      if (res.err) {\n        return res;\n      }\n      if (typeof res.val !== \"undefined\") {\n        // Fill all lower caches\n        this.ctx.waitUntil(\n          Promise.all(\n            this.tiers.filter((_, j) => j < i).map((t) => () => t.set(namespace, key, res.val!)),\n          ).catch((err) => {\n            return Err(\n              new CacheError({\n                tier: this.name,\n                key,\n                message: (err as Error).message,\n              }),\n            );\n          }),\n        );\n\n        return Ok(res.val);\n      }\n    }\n    return Ok(undefined);\n  }\n\n  /**\n   * Sets the value for the given key.\n   */\n  public async set(\n    namespace: TNamespace,\n    key: string,\n    value: Entry<TValue>,\n  ): Promise<Result<void, CacheError>> {\n    return Promise.all(this.tiers.map((t) => t.set(namespace, key, value)))\n      .then(() => Ok())\n      .catch((err) =>\n        Err(\n          new CacheError({\n            tier: this.name,\n            key,\n            message: (err as Error).message,\n          }),\n        ),\n      );\n  }\n\n  /**\n   * Removes the key from the cache.\n   */\n  public async remove(namespace: TNamespace, key: string): Promise<Result<void, CacheError>> {\n    return Promise.all(this.tiers.map((t) => t.remove(namespace, key)))\n      .then(() => Ok())\n      .catch((err) =>\n        Err(\n          new CacheError({\n            tier: this.name,\n            key,\n            message: (err as Error).message,\n          }),\n        ),\n      );\n  }\n}\n","import { Err, Ok, type Result } from \"@unkey/error\";\nimport type { Context } from \"./context\";\nimport { CacheError } from \"./errors\";\nimport type { Store } from \"./stores\";\n\n/**\n * Internal cache implementation for an individual namespace\n */\nexport class SwrCache<TNamespace extends string, TValue> {\n  private readonly ctx: Context;\n  private readonly store: Store<TNamespace, TValue | undefined>;\n  private readonly fresh: number;\n  private readonly stale: number;\n\n  /**\n   * To prevent concurrent revalidation of the same data, all revalidations are deduplicated using\n   * this map.\n   */\n  private readonly revalidating: Map<string, Promise<TValue | undefined>> = new Map();\n\n  constructor(\n    ctx: Context,\n    store: Store<TNamespace, TValue | undefined>,\n    fresh: number,\n    stale: number,\n  ) {\n    this.ctx = ctx;\n    this.store = store;\n    this.fresh = fresh;\n    this.stale = stale;\n  }\n\n  /**\n   * Return the cached value\n   *\n   * The response will be `undefined` for cache misses or `null` when the key was not found in the origin\n   */\n  public async get(\n    namespace: TNamespace,\n    key: string,\n  ): Promise<Result<TValue | undefined, CacheError>> {\n    const res = await this._get(namespace, key);\n    if (res.err) {\n      return Err(res.err);\n    }\n    return Ok(res.val.value);\n  }\n\n  private async _get(\n    namespace: TNamespace,\n    key: string,\n  ): Promise<Result<{ value: TValue | undefined; revalidate?: boolean }, CacheError>> {\n    const res = await this.store.get(namespace, key);\n    if (res.err) {\n      return Err(res.err);\n    }\n\n    const now = Date.now();\n    if (!res.val) {\n      return Ok({ value: undefined });\n    }\n\n    if (now >= res.val.staleUntil) {\n      this.ctx.waitUntil(this.remove(namespace, key));\n      return Ok({ value: undefined });\n    }\n    if (now >= res.val.freshUntil) {\n      return Ok({ value: res.val.value, revalidate: true });\n    }\n\n    return Ok({ value: res.val.value });\n  }\n\n  /**\n   * Set the value\n   */\n  public async set(\n    namespace: TNamespace,\n    key: string,\n    value: TValue | undefined,\n    opts?: {\n      fresh: number;\n      stale: number;\n    },\n  ): Promise<Result<void, CacheError>> {\n    const now = Date.now();\n    return this.store.set(namespace, key, {\n      value,\n      freshUntil: now + (opts?.fresh ?? this.fresh),\n      staleUntil: now + (opts?.stale ?? this.stale),\n    });\n  }\n\n  /**\n   * Removes the key from the cache.\n   */\n  public async remove(namespace: TNamespace, key: string): Promise<Result<void, CacheError>> {\n    return this.store.remove(namespace, key);\n  }\n\n  public async swr(\n    namespace: TNamespace,\n    key: string,\n    loadFromOrigin: (key: string) => Promise<TValue | undefined>,\n  ): Promise<Result<TValue | undefined, CacheError>> {\n    const res = await this._get(namespace, key);\n    if (res.err) {\n      return Err(res.err);\n    }\n    const { value, revalidate } = res.val;\n    if (typeof value !== \"undefined\") {\n      if (revalidate) {\n        this.ctx.waitUntil(\n          this.deduplicateLoadFromOrigin(namespace, key, loadFromOrigin).then((res) =>\n            this.set(namespace, key, res),\n          ),\n        );\n      }\n\n      return Ok(value);\n    }\n\n    try {\n      const value = await this.deduplicateLoadFromOrigin(namespace, key, loadFromOrigin);\n      this.ctx.waitUntil(this.set(namespace, key, value));\n      return Ok(value);\n    } catch (err) {\n      return Err(\n        new CacheError({\n          tier: \"cache\",\n          key,\n          message: (err as Error).message,\n        }),\n      );\n    }\n  }\n\n  /**\n   * Deduplicating the origin load helps when the same value is requested many times at once and is\n   * not yet in the cache. If we don't deduplicate, we'd create a lot of unnecessary load on the db.\n   */\n  private async deduplicateLoadFromOrigin(\n    namespace: TNamespace,\n    key: string,\n    loadFromOrigin: (key: string) => Promise<TValue | undefined>,\n  ): Promise<TValue | undefined> {\n    const revalidateKey = [namespace, key].join(\"::\");\n    try {\n      const revalidating = this.revalidating.get(revalidateKey);\n      if (revalidating) {\n        return await revalidating;\n      }\n\n      const p = loadFromOrigin(key);\n      this.revalidating.set(revalidateKey, p);\n      return await p;\n    } finally {\n      this.revalidating.delete(revalidateKey);\n    }\n  }\n}\n","import type { Context } from \"./context\";\nimport type { Store } from \"./stores\";\nimport { SwrCache } from \"./swr\";\nimport { TieredStore } from \"./tiered\";\n\nexport class Namespace<TValue> extends SwrCache<string, TValue> {\n  constructor(\n    ctx: Context,\n    opts: {\n      stores: Array<Store<string, TValue>>;\n      fresh: number;\n      stale: number;\n    },\n  ) {\n    const tieredStore = new TieredStore<string, TValue>(ctx, opts.stores);\n\n    super(ctx, tieredStore, opts.fresh, opts.stale);\n  }\n}\n"]}