{"version":3,"sources":["../src/index.ts","../src/stores/memory.ts","../src/stores/redis.ts","../src/context.ts","../src/key.ts","../src/utils.ts","../src/swr-cache.ts","../src/tiered-store.ts","../src/query-cache.ts"],"sourcesContent":["export * from './stores';\nexport * from './context';\nexport * from './query-cache';\n","import type { Entry } from './entry';\nimport type { Store } from './interface';\n\nexport type MemoryStoreConfig<TValue> = {\n  persistentMap: Map<string, TValue>;\n};\n\nexport class MemoryStore implements Store {\n  private readonly state: Map<string, { expires: number; entry: Entry<any> }>;\n\n  public readonly name = 'memory';\n\n  constructor(\n    config: MemoryStoreConfig<{ expires: number; entry: Entry<any> }>,\n  ) {\n    this.state = config.persistentMap;\n  }\n\n  public async get<Result>(key: string): Promise<Entry<Result> | undefined> {\n    const value = this.state.get(key);\n    if (!value) {\n      return Promise.resolve(undefined);\n    }\n    if (value.expires <= Date.now()) {\n      await this.remove(key);\n    }\n    return Promise.resolve(value.entry);\n  }\n\n  public async set<Result>(key: string, entry: Entry<Result>): Promise<void> {\n    this.state.set(key, {\n      expires: entry.staleUntil,\n      entry,\n    });\n\n    return Promise.resolve();\n  }\n\n  public async remove(keys: string | string[]): Promise<void> {\n    const cacheKeys = Array.isArray(keys) ? keys : [keys];\n\n    for (const key of cacheKeys) {\n      this.state.delete(key);\n    }\n    return Promise.resolve();\n  }\n\n  public async removeByPrefix(prefix: string): Promise<void> {\n    for (const key of this.state.keys()) {\n      if (key.startsWith(prefix)) {\n        this.state.delete(key);\n      }\n    }\n  }\n}\n","import type { Redis } from 'ioredis';\n\nimport type { Entry } from './entry';\nimport type { Store } from './interface';\n\nexport type RedisStoreConfig = {\n  redis: Redis;\n  prefix?: string;\n};\n\nexport class RedisStore implements Store {\n  private readonly redis: Redis;\n  public readonly name = 'redis';\n  private readonly prefix: string;\n\n  constructor(config: RedisStoreConfig) {\n    this.redis = config.redis;\n    this.prefix = config.prefix || 'sbch';\n  }\n\n  private buildCacheKey(key: string): string {\n    return [this.prefix, key].join('::');\n  }\n\n  public async get<Result>(key: string): Promise<Entry<Result> | undefined> {\n    const res = await this.redis.get(this.buildCacheKey(key));\n    if (!res) return;\n\n    return JSON.parse(res) as Entry<Result>;\n  }\n\n  public async set<Result>(key: string, entry: Entry<Result>): Promise<void> {\n    await this.redis.set(\n      this.buildCacheKey(key),\n      JSON.stringify(entry),\n      'PXAT',\n      entry.staleUntil,\n    );\n  }\n\n  public async remove(keys: string | string[]): Promise<void> {\n    const cacheKeys = (Array.isArray(keys) ? keys : [keys]).map((key) =>\n      this.buildCacheKey(key).toString(),\n    );\n    this.redis.del(...cacheKeys);\n  }\n\n  public async removeByPrefix(prefix: string): Promise<void> {\n    const pattern = `${prefix}*`;\n    let cursor = '0';\n\n    do {\n      const [nextCursor, keys] = await this.redis.scan(\n        cursor,\n        'MATCH',\n        pattern,\n        'COUNT',\n        100,\n      );\n      cursor = nextCursor;\n\n      if (keys.length > 0) {\n        await this.redis.del(...keys);\n      }\n    } while (cursor !== '0');\n  }\n}\n","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 {\n  AnyPostgrestResponse,\n  PostgrestParser,\n  isPostgrestBuilder,\n} from '@supabase-cache-helpers/postgrest-core';\n\nconst SEPARATOR = '$';\n\nexport function encode<Result>(\n  query: PromiseLike<AnyPostgrestResponse<Result>>,\n) {\n  if (!isPostgrestBuilder<Result>(query)) {\n    throw new Error('Query is not a PostgrestBuilder');\n  }\n\n  const parser = new PostgrestParser<Result>(query);\n  return [\n    parser.schema,\n    parser.table,\n    parser.queryKey,\n    parser.bodyKey ?? 'null',\n    `count=${parser.count}`,\n    `head=${parser.isHead}`,\n    parser.orderByKey,\n  ].join(SEPARATOR);\n}\n\nexport function buildTablePrefix(schema: string, table: string) {\n  return [schema, table].join(SEPARATOR);\n}\n","import { Value } from './stores/entry';\n\n/**\n * A result is empty if\n * - it does not contain a truhty data field\n * - it does not contain a count field\n * - data is an empty array\n *\n * @template Result - The Result of the query\n * @param result - The value to check\n * @returns true if the result is empty\n */\nexport function isEmpty<Result>(result: Value<Result>) {\n  if (typeof result.count === 'number') {\n    return false;\n  }\n\n  if (!result.data) {\n    return true;\n  }\n\n  if (Array.isArray(result.data)) {\n    return result.data.length === 0;\n  }\n\n  return false;\n}\n","import type { Context } from './context';\nimport { Value } from './stores/entry';\nimport { Store } from './stores/interface';\nimport { isEmpty } from './utils';\n\nexport type SwrCacheOpts = {\n  ctx: Context;\n  store: Store;\n  fresh: number;\n  stale: number;\n};\n\n/**\n * Internal cache implementation for an individual namespace\n */\nexport class SwrCache {\n  private readonly ctx: Context;\n  private readonly store: Store;\n  private readonly fresh: number;\n  private readonly stale: number;\n\n  constructor({ ctx, store, fresh, stale }: SwrCacheOpts) {\n    this.ctx = ctx;\n    this.store = store;\n    this.fresh = fresh;\n    this.stale = stale;\n  }\n\n  /**\n   * Invalidate all keys that start with the given prefix\n   **/\n  async removeByPrefix(prefix: string) {\n    return this.store.removeByPrefix(prefix);\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<Result>(key: string): Promise<Value<Result> | undefined> {\n    const res = await this._get<Result>(key);\n    return res.value;\n  }\n\n  private async _get<Result>(\n    key: string,\n  ): Promise<{ value: Value<Result> | undefined; revalidate?: boolean }> {\n    const res = await this.store.get<Result>(key);\n\n    const now = Date.now();\n    if (!res) {\n      return { value: undefined };\n    }\n\n    if (now >= res.staleUntil) {\n      this.ctx.waitUntil(this.remove(key));\n      return { value: undefined };\n    }\n    if (now >= res.freshUntil) {\n      return { value: res.value, revalidate: true };\n    }\n\n    return { value: res.value };\n  }\n\n  /**\n   * Set the value\n   */\n  public async set<Result>(\n    key: string,\n    value: Value<Result>,\n    opts?: {\n      fresh?: number;\n      stale?: number;\n    },\n  ): Promise<void> {\n    const now = Date.now();\n    return this.store.set(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(key: string): Promise<void> {\n    return this.store.remove(key);\n  }\n\n  public async swr<Result>(\n    key: string,\n    loadFromOrigin: (key: string) => Promise<Value<Result>>,\n    opts?: {\n      fresh: number;\n      stale: number;\n    },\n  ): Promise<Value<Result>> {\n    const res = await this._get<Result>(key);\n\n    const { value, revalidate } = res;\n\n    if (typeof value !== 'undefined') {\n      if (revalidate) {\n        this.ctx.waitUntil(\n          loadFromOrigin(key).then((res) => {\n            if (!isEmpty(res)) {\n              this.set(key, res, opts);\n            }\n          }),\n        );\n      }\n\n      return value;\n    }\n\n    const loadedValue = await loadFromOrigin(key);\n    if (!isEmpty(loadedValue)) {\n      this.ctx.waitUntil(this.set(key, loadedValue));\n    }\n    return loadedValue;\n  }\n}\n","import type { Context } from './context';\nimport { Entry } from './stores/entry';\nimport { Store } from './stores/interface';\n\n/**\n * TieredCache is a cache that will first check the memory cache, then the zone cache.\n */\nexport class TieredStore implements Store {\n  private ctx: Context;\n  private readonly tiers: Store[];\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 | undefined)[]) {\n    this.ctx = ctx;\n    this.tiers = stores.filter(Boolean) as Store[];\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<Result>(key: string): Promise<Entry<Result> | undefined> {\n    if (this.tiers.length === 0) {\n      return;\n    }\n\n    for (let i = 0; i < this.tiers.length; i++) {\n      const res = await this.tiers[i].get<Result>(key);\n\n      if (!res) {\n        return;\n      }\n\n      // Fill all lower caches\n      this.ctx.waitUntil(\n        Promise.all(\n          this.tiers.filter((_, j) => j < i).map((t) => () => t.set(key, res)),\n        ),\n      );\n\n      return res;\n    }\n  }\n\n  /**\n   * Sets the value for the given key.\n   */\n  public async set<Result>(key: string, value: Entry<Result>): Promise<void> {\n    await Promise.all(this.tiers.map((t) => t.set(key, value)));\n  }\n\n  /**\n   * Removes the key from the cache.\n   */\n  public async remove(key: string): Promise<void> {\n    await Promise.all(this.tiers.map((t) => t.remove(key)));\n  }\n\n  /**\n   * Removes all keys with the given prefix.\n   */\n  public async removeByPrefix(prefix: string): Promise<void> {\n    await Promise.all(this.tiers.map((t) => t.removeByPrefix(prefix)));\n  }\n}\n","import { type AnyPostgrestResponse } from '@supabase-cache-helpers/postgrest-core';\nimport type {\n  PostgrestMaybeSingleResponse,\n  PostgrestResponse,\n  PostgrestSingleResponse,\n} from '@supabase/postgrest-js';\n\nimport { Context } from './context';\nimport { buildTablePrefix, encode } from './key';\nimport { Value } from './stores/entry';\nimport { Store } from './stores/interface';\nimport { SwrCache } from './swr-cache';\nimport { TieredStore } from './tiered-store';\nimport { isEmpty } from './utils';\n\nexport type QueryCacheOpts = {\n  stores: Store[];\n  fresh: number;\n  stale: number;\n};\n\nexport type OperationOpts = Pick<QueryCacheOpts, 'fresh' | 'stale'>;\n\nexport class QueryCache {\n  private readonly inner: SwrCache;\n\n  /**\n   * To prevent concurrent requests of the same data, all queries are deduplicated using\n   * this map.\n   */\n  private readonly runningQueries: Map<\n    string,\n    PromiseLike<AnyPostgrestResponse<any>>\n  > = new Map();\n\n  constructor(ctx: Context, opts: QueryCacheOpts) {\n    const tieredStore = new TieredStore(ctx, opts.stores);\n\n    this.inner = new SwrCache({\n      ctx,\n      store: tieredStore,\n      fresh: opts.fresh,\n      stale: opts.stale,\n    });\n  }\n\n  /**\n   * Invalidate all cache entries for a given table\n   */\n  async invalidateQueries({\n    schema,\n    table,\n  }: { schema: string; table: string }) {\n    const prefix = buildTablePrefix(schema, table);\n    return this.inner.removeByPrefix(prefix);\n  }\n\n  /**\n   * Perform a cached postgrest query\n   */\n  query<Result>(\n    query: PromiseLike<PostgrestSingleResponse<Result>>,\n    opts?: Partial<OperationOpts> & {\n      store?: (result: PostgrestSingleResponse<Result>) => boolean;\n    },\n  ): Promise<PostgrestSingleResponse<Result>>;\n  /**\n   * Perform a cached postgrest query\n   */\n  query<Result>(\n    query: PromiseLike<PostgrestMaybeSingleResponse<Result>>,\n    opts?: Partial<OperationOpts> & {\n      store?: (result: PostgrestMaybeSingleResponse<Result>) => boolean;\n    },\n  ): Promise<PostgrestMaybeSingleResponse<Result>>;\n  /**\n   * Perform a cached postgrest query\n   */\n  query<Result>(\n    query: PromiseLike<PostgrestResponse<Result>>,\n    opts?: Partial<OperationOpts> & {\n      store?: (result: PostgrestResponse<Result>) => boolean;\n    },\n  ): Promise<PostgrestResponse<Result>>;\n  async query<Result>(\n    query: PromiseLike<AnyPostgrestResponse<Result>>,\n    opts?: Partial<OperationOpts> & {\n      store?: (result: AnyPostgrestResponse<Result>) => boolean;\n    },\n  ): Promise<AnyPostgrestResponse<Result>> {\n    const key = encode(query);\n\n    const value = await this.inner.get<Result>(key);\n\n    if (value) return value;\n\n    const result = await this.dedupeQuery(query);\n\n    if (!isEmpty(result) && (!opts?.store || opts.store(result))) {\n      await this.inner.set(key, result, opts);\n    }\n\n    return result;\n  }\n\n  /**\n   * Perform a cached postgrest query\n   */\n  swr<Result>(\n    query: PromiseLike<PostgrestSingleResponse<Result>>,\n    opts?: OperationOpts,\n  ): Promise<PostgrestSingleResponse<Result>>;\n  /**\n   * Perform a cached postgrest query\n   */\n  swr<Result>(\n    query: PromiseLike<PostgrestMaybeSingleResponse<Result>>,\n    opts?: OperationOpts,\n  ): Promise<PostgrestMaybeSingleResponse<Result>>;\n  /**\n   * Perform a cached postgrest query\n   */\n  swr<Result>(\n    query: PromiseLike<PostgrestResponse<Result>>,\n    opts?: OperationOpts,\n  ): Promise<PostgrestResponse<Result>>;\n  async swr<Result>(\n    query: PromiseLike<AnyPostgrestResponse<Result>>,\n    opts?: OperationOpts,\n  ): Promise<AnyPostgrestResponse<Result>> {\n    return await this.inner.swr(\n      encode(query),\n      () => this.dedupeQuery(query),\n      opts,\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 dedupeQuery<Result>(\n    query: PromiseLike<AnyPostgrestResponse<Result>>,\n  ): Promise<Value<Result>> {\n    const key = encode(query);\n    try {\n      const querying = this.runningQueries.get(key);\n      if (querying) {\n        return querying;\n      }\n\n      this.runningQueries.set(key, query);\n      return await query;\n    } finally {\n      this.runningQueries.delete(key);\n    }\n  }\n}\n"],"mappings":"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","names":["res"]}