{"version":3,"sources":["../src/errors.ts","../src/stores/cloudflare.ts","../src/stores/memory.ts","../src/stores/upstash-redis.ts","../src/stores/libsql.ts"],"names":["Ok","key"],"mappings":";;;;AAEO,IAAM,UAAA,GAAN,cAAyB,SAAA,CAAU;AAAA,EACxB,IAAA,GAAO,YAAA;AAAA,EACP,KAAA,GAAQ,KAAA;AAAA,EAER,IAAA;AAAA,EACA,GAAA;AAAA,EAEhB,YAAY,IAAA,EAIT;AACD,IAAA,KAAA,CAAM,IAAI,CAAA;AACV,IAAA,IAAA,CAAK,IAAA,GAAO,YAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA;AAAA,EAClB;AACF,CAAA;;;ACMO,IAAM,kBAAN,MAEP;AAAA,EACmB,MAAA;AAAA,EACD,IAAA,GAAO,YAAA;AAAA,EAEvB,YAAY,MAAA,EAA+B;AACzC,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA,EAEQ,cAAA,CAAe,WAAuB,GAAA,EAAkB;AAC9D,IAAA,OAAO,IAAI,GAAA;AAAA,MACT,CAAA,QAAA,EAAW,KAAK,MAAA,CAAO,MAAM,UAAU,IAAA,CAAK,MAAA,CAAO,WAAA,IAAe,IAAI,CAAA,CAAA,EAAI,MAAA;AAAA,QACxE;AAAA,OACD,IAAI,GAAG,CAAA;AAAA,KACV;AAAA,EACF;AAAA,EAEA,MAAa,GAAA,CACX,SAAA,EACA,GAAA,EACwD;AACxD,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AAEF,MAAA,GAAA,GAAM,MAAM,MAAA,CAAO,OAAA,CAAQ,KAAA,CAAM,IAAI,OAAA,CAAQ,IAAA,CAAK,cAAA,CAAe,SAAA,EAAW,GAAG,CAAC,CAAC,CAAA;AAAA,IACnF,SAAS,GAAA,EAAK;AACZ,MAAA,OAAO,GAAA;AAAA,QACL,IAAI,UAAA,CAAW;AAAA,UACb,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,GAAA;AAAA,UACA,SAAU,GAAA,CAAc;AAAA,SACzB;AAAA,OACH;AAAA,IACF;AACA,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAO,GAAG,MAAS,CAAA;AAAA,IACrB;AACA,IAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,IAAA,EAAK;AAC3B,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,KAAA,CAAM,GAAG,CAAA;AACjC,MAAA,OAAO,GAAG,KAAK,CAAA;AAAA,IACjB,SAAS,GAAA,EAAK;AACZ,MAAA,OAAO,GAAA;AAAA,QACL,IAAI,UAAA,CAAW;AAAA,UACb,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,GAAA;AAAA,UACA,SAAU,GAAA,CAAc;AAAA,SACzB;AAAA,OACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAa,GAAA,CACX,SAAA,EACA,GAAA,EACA,KAAA,EACmC;AACnC,IAAA,MAAM,MAAM,IAAI,OAAA,CAAQ,KAAK,cAAA,CAAe,SAAA,EAAW,GAAG,CAAC,CAAA;AAC3D,IAAA,MAAM,MAAM,IAAI,QAAA,CAAS,SAAA,CAAU,SAAA,CAAU,KAAK,CAAA,EAAG;AAAA,MACnD,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,iBAAiB,CAAA,gBAAA,EAAmB,IAAA,CAAK,MAAM,KAAA,CAAM,UAAA,GAAa,GAAI,CAAC,CAAA;AAAA;AACzE,KACD,CAAA;AACD,IAAA,IAAI;AAEF,MAAA,MAAM,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,GAAG,CAAA;AACjC,MAAA,OAAO,EAAA,EAAG;AAAA,IACZ,SAAS,GAAA,EAAK;AACZ,MAAA,OAAO,GAAA;AAAA,QACL,IAAI,UAAA,CAAW;AAAA,UACb,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,GAAA;AAAA,UACA,SAAU,GAAA,CAAc;AAAA,SACzB;AAAA,OACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAa,MAAA,CACX,SAAA,EACA,IAAA,EACmC;AACnC,IAAA,MAAM,SAAA,GAAA,CAAa,MAAM,OAAA,CAAQ,IAAI,IAAI,IAAA,GAAO,CAAC,IAAI,CAAA,EAAG,GAAA;AAAA,MAAI,CAAC,GAAA,KAC3D,IAAA,CAAK,cAAA,CAAe,WAAW,GAAG;AAAA,KACpC;AAGA,IAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,SAAA,CAAU,GAAA,CAAI,CAAC,GAAA,KAAQ,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAEpE,IAAA,OAAO,MAAM,KAAA;AAAA,MACX,CAAA,0CAAA,EAA6C,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,YAAA,CAAA;AAAA,MAC/D;AAAA,QACE,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAA,CAAO,gBAAgB,CAAA,CAAA;AAAA,UACrD,cAAA,EAAgB;AAAA,SAClB;AAAA,QACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,OAAO,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU;AAAA,SACzC;AAAA;AACH,KACF,CACG,IAAA,CAAK,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAA,EAAM,MAAA,EAAQ,CAAA,CAChC,IAAA,CAAK,MAAM,EAAA,EAAI,CAAA,CACf,KAAA;AAAA,MAAM,CAAC,GAAA,KACN,GAAA;AAAA,QACE,IAAI,UAAA,CAAW;AAAA,UACb,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,GAAA,EAAK,KAAK,QAAA,EAAS;AAAA,UACnB,SAAU,GAAA,CAAc;AAAA,SACzB;AAAA;AACH,KACF;AAAA,EACJ;AACF;AC9GO,IAAM,cAAN,MAEP;AAAA,EACmB,KAAA;AAAA,EACA,kBAAA;AAAA,EAED,IAAA,GAAO,QAAA;AAAA,EAEvB,YAAY,MAAA,EAAsE;AAChF,IAAA,IAAA,CAAK,QAAQ,MAAA,CAAO,aAAA;AACpB,IAAA,IAAA,CAAK,qBAAqB,MAAA,CAAO,kBAAA;AAAA,EACnC;AAAA,EAEQ,aAAA,CAAc,WAAuB,GAAA,EAAqB;AAChE,IAAA,OAAO,CAAC,SAAA,EAAW,GAAG,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,EACnC;AAAA,EAEA,MAAa,GAAA,CACX,SAAA,EACA,GAAA,EACwD;AACxD,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,CAAM,GAAA,CAAI,KAAK,aAAA,CAAc,SAAA,EAAW,GAAG,CAAC,CAAA;AAC/D,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,OAAO,OAAA,CAAQ,OAAA,CAAQA,EAAAA,CAAG,MAAS,CAAC,CAAA;AAAA,IACtC;AACA,IAAA,IAAI,KAAA,CAAM,OAAA,IAAW,IAAA,CAAK,GAAA,EAAI,EAAG;AAC/B,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,SAAA,EAAW,GAAG,CAAA;AAAA,IAClC;AACA,IAAA,OAAO,OAAA,CAAQ,OAAA,CAAQA,EAAAA,CAAG,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EACxC;AAAA,EAEA,MAAa,GAAA,CACX,SAAA,EACA,GAAA,EACA,KAAA,EACmC;AACnC,IAAA,IAAA,CAAK,MAAM,GAAA,CAAI,IAAA,CAAK,aAAA,CAAc,SAAA,EAAW,GAAG,CAAA,EAAG;AAAA,MACjD,SAAS,KAAA,CAAM,UAAA;AAAA,MACf;AAAA,KACD,CAAA;AAED,IAAA,IAAI,KAAK,kBAAA,IAAsB,IAAA,CAAK,QAAO,GAAI,IAAA,CAAK,mBAAmB,SAAA,EAAW;AAIhF,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,IAAA,CAAK,KAAA,CAAM,OAAA,CAAQ,CAAC,KAAA,EAAOC,MAAK,GAAA,KAAQ;AACtC,QAAA,IAAI,KAAA,CAAM,UAAU,GAAA,EAAK;AACvB,UAAA,GAAA,CAAI,OAAOA,IAAG,CAAA;AAAA,QAChB;AAAA,MACF,CAAC,CAAA;AAKD,MAAA,KAAA,MAAW,CAAC,CAAC,CAAA,IAAK,IAAA,CAAK,KAAA,EAAO;AAC5B,QAAA,IAAI,IAAA,CAAK,KAAA,CAAM,IAAA,IAAQ,IAAA,CAAK,mBAAoB,QAAA,EAAU;AACxD,UAAA;AAAA,QACF;AAEA,QAAA,IAAA,CAAK,KAAA,CAAM,OAAO,CAAC,CAAA;AAAA,MACrB;AAAA,IACF;AAEA,IAAA,OAAO,OAAA,CAAQ,OAAA,CAAQD,EAAAA,EAAI,CAAA;AAAA,EAC7B;AAAA,EAEA,MAAa,MAAA,CACX,SAAA,EACA,IAAA,EACmC;AACnC,IAAA,MAAM,SAAA,GAAA,CAAa,MAAM,OAAA,CAAQ,IAAI,IAAI,IAAA,GAAO,CAAC,IAAI,CAAA,EAAG,GAAA;AAAA,MAAI,CAAC,GAAA,KAC3D,IAAA,CAAK,cAAc,SAAA,EAAW,GAAG,EAAE,QAAA;AAAS,KAC9C;AACA,IAAA,KAAA,MAAW,OAAO,SAAA,EAAW;AAC3B,MAAA,IAAA,CAAK,KAAA,CAAM,OAAO,GAAG,CAAA;AAAA,IACvB;AACA,IAAA,OAAO,OAAA,CAAQ,OAAA,CAAQA,EAAAA,EAAI,CAAA;AAAA,EAC7B;AACF;ACpGO,IAAM,oBAAN,MAEP;AAAA,EACmB,KAAA;AAAA,EACD,IAAA,GAAO,eAAA;AAAA,EAEvB,YAAY,MAAA,EAAiC;AAC3C,IAAA,IAAA,CAAK,QAAQ,MAAA,CAAO,KAAA;AAAA,EACtB;AAAA,EAEQ,aAAA,CAAc,WAAuB,GAAA,EAAqB;AAChE,IAAA,OAAO,CAAC,SAAA,EAAW,GAAG,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,EACnC;AAAA,EAEA,MAAa,GAAA,CACX,SAAA,EACA,GAAA,EACwD;AACxD,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,KAAA,CAAM,IAAmB,IAAA,CAAK,aAAA,CAAc,SAAA,EAAW,GAAG,CAAC,CAAA;AACpF,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,OAAOA,GAAG,MAAS,CAAA;AAAA,IACrB;AACA,IAAA,OAAOA,GAAG,KAAK,CAAA;AAAA,EACjB;AAAA,EAEA,MAAa,GAAA,CACX,SAAA,EACA,GAAA,EACA,KAAA,EACmC;AACnC,IAAA,MAAM,IAAA,CAAK,MAAM,GAAA,CAAmB,IAAA,CAAK,cAAc,SAAA,EAAW,GAAG,GAAG,KAAA,EAAO;AAAA,MAC7E,MAAM,KAAA,CAAM;AAAA,KACb,CAAA;AACD,IAAA,OAAOA,EAAAA,EAAG;AAAA,EACZ;AAAA,EAEA,MAAa,MAAA,CACX,SAAA,EACA,IAAA,EACmC;AACnC,IAAA,MAAM,SAAA,GAAA,CAAa,MAAM,OAAA,CAAQ,IAAI,IAAI,IAAA,GAAO,CAAC,IAAI,CAAA,EAAG,GAAA;AAAA,MAAI,CAAC,GAAA,KAC3D,IAAA,CAAK,cAAc,SAAA,EAAW,GAAG,EAAE,QAAA;AAAS,KAC9C;AACA,IAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,GAAG,SAAS,CAAA;AAC3B,IAAA,OAAOA,EAAAA,EAAG;AAAA,EACZ;AACF;AC7CO,IAAM,cAAN,MAEP;AAAA,EACmB,SAAA;AAAA,EACA,MAAA;AAAA,EACD,IAAA,GAAO,QAAA;AAAA,EAEvB,YAAY,MAAA,EAA2B;AACrC,IAAA,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA;AACrB,IAAA,IAAA,CAAK,SAAA,GAAY,OAAO,SAAA,IAAa,OAAA;AAAA,EACvC;AAAA,EAEQ,aAAA,CAAc,WAAuB,GAAA,EAAqB;AAChE,IAAA,OAAO,CAAA,EAAG,SAAS,CAAA,EAAA,EAAK,GAAG,CAAA,CAAA;AAAA,EAC7B;AAAA,EAEA,MAAa,GAAA,CACX,SAAA,EACA,GAAA,EACwD;AACxD,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ;AAAA,QACvC,GAAA,EAAK,CAAA,0CAAA,EAA6C,IAAA,CAAK,SAAS,CAAA,cAAA,CAAA;AAAA,QAChE,MAAM,CAAC,IAAA,CAAK,aAAA,CAAc,SAAA,EAAW,GAAG,CAAC;AAAA,OAC1C,CAAA;AAED,MAAA,IAAI,MAAA,CAAO,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AAC5B,QAAA,OAAOA,GAAG,KAAA,CAAS,CAAA;AAAA,MACrB;AAEA,MAAA,MAAM,GAAA,GAAM,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA;AACzB,MAAA,MAAM,KAAA,GAAuB;AAAA,QAC3B,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,KAAe,CAAA;AAAA,QACrC,UAAA,EAAY,MAAA,CAAO,GAAA,CAAI,UAAU,CAAA;AAAA,QACjC,UAAA,EAAY,MAAA,CAAO,GAAA,CAAI,UAAU;AAAA,OACnC;AAEA,MAAA,OAAOA,GAAG,KAAK,CAAA;AAAA,IACjB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAOA,GAAG,MAAS,CAAA;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAa,GAAA,CACX,SAAA,EACA,GAAA,EACA,KAAA,EACmC;AACnC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,OAAO,OAAA,CAAQ;AAAA,QACxB,GAAA,EAAK,CAAA,uBAAA,EAA0B,IAAA,CAAK,SAAS,CAAA;AAAA,iCAAA,CAAA;AAAA,QAE7C,IAAA,EAAM;AAAA,UACJ,IAAA,CAAK,aAAA,CAAc,SAAA,EAAW,GAAG,CAAA;AAAA,UACjC,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,KAAK,CAAA;AAAA,UAC1B,KAAA,CAAM,UAAA;AAAA,UACN,KAAA,CAAM;AAAA;AACR,OACD,CAAA;AAED,MAAA,OAAOA,EAAAA,EAAG;AAAA,IACZ,CAAA,CAAA,MAAQ;AACN,MAAA,OAAOA,EAAAA,EAAG;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,MAAa,MAAA,CACX,SAAA,EACA,IAAA,EACmC;AACnC,IAAA,MAAM,SAAA,GAAA,CAAa,MAAM,OAAA,CAAQ,IAAI,IAAI,IAAA,GAAO,CAAC,IAAI,CAAA,EAAG,GAAA;AAAA,MAAI,CAAC,GAAA,KAC3D,IAAA,CAAK,cAAc,SAAA,EAAW,GAAG,EAAE,QAAA;AAAS,KAC9C;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,QACZ,SAAA,CAAU,GAAA;AAAA,UAAI,CAAC,QAAA,KACb,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ;AAAA,YAClB,GAAA,EAAK,CAAA,YAAA,EAAe,IAAA,CAAK,SAAS,CAAA,cAAA,CAAA;AAAA,YAClC,IAAA,EAAM,CAAC,QAAQ;AAAA,WAChB;AAAA;AACH,OACF;AAEA,MAAA,OAAOA,EAAAA,EAAG;AAAA,IACZ,CAAA,CAAA,MAAQ;AACN,MAAA,OAAOA,EAAAA,EAAG;AAAA,IACZ;AAAA,EACF;AACF","file":"stores.mjs","sourcesContent":["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 { Err, Ok, type Result } from \"@unkey/error\";\nimport superjson from \"superjson\";\nimport { CacheError } from \"../errors\";\nimport type { Entry, Store } from \"./interface\";\n\nexport type CloudflareStoreConfig = {\n  domain: string;\n  zoneId: string;\n  /**\n   * This token must have at least\n   */\n  cloudflareApiKey: string;\n\n  /**\n   * As your data changes, it is important to keep backwards compatibility in mind. If your cached\n   * values are no longer backwards compatible, it can cause problems. For example when a value\n   * changes from optional to required. In these cases you should purge the entire cache by setting\n   * a new `cacheBuster` value. The `cacheBuster` is used as part of the cache key and changes\n   * ensure you are not reading old data anymore.\n   *\n   * @default \"v1\"\n   */\n  cacheBuster?: string;\n};\n\nexport class CloudflareStore<TNamespace extends string, TValue = any>\n  implements Store<TNamespace, TValue>\n{\n  private readonly config: CloudflareStoreConfig;\n  public readonly name = \"cloudflare\";\n\n  constructor(config: CloudflareStoreConfig) {\n    this.config = config;\n  }\n\n  private createCacheKey(namespace: TNamespace, key: string): URL {\n    return new URL(\n      `https://${this.config.domain}/cache/${this.config.cacheBuster ?? \"v1\"}/${String(\n        namespace,\n      )}/${key}`,\n    );\n  }\n\n  public async get(\n    namespace: TNamespace,\n    key: string,\n  ): Promise<Result<Entry<TValue> | undefined, CacheError>> {\n    let res: Response;\n    try {\n      // @ts-expect-error I don't know why this is not working\n      res = await caches.default.match(new Request(this.createCacheKey(namespace, key)));\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    if (!res) {\n      return Ok(undefined);\n    }\n    const raw = await res.text();\n    try {\n      const entry = superjson.parse(raw) as Entry<TValue>;\n      return Ok(entry);\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  public async set(\n    namespace: TNamespace,\n    key: string,\n    entry: Entry<TValue>,\n  ): Promise<Result<void, CacheError>> {\n    const req = new Request(this.createCacheKey(namespace, key));\n    const res = new Response(superjson.stringify(entry), {\n      headers: {\n        \"Content-Type\": \"application/json\",\n        \"Cache-Control\": `public, max-age=${Math.floor(entry.staleUntil / 1000)}`,\n      },\n    });\n    try {\n      // @ts-expect-error I don't know why this is not working\n      await caches.default.put(req, res);\n      return Ok();\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  public async remove(\n    namespace: TNamespace,\n    keys: string | string[],\n  ): Promise<Result<void, CacheError>> {\n    const cacheKeys = (Array.isArray(keys) ? keys : [keys]).map((key) =>\n      this.createCacheKey(namespace, key),\n    );\n\n    // @ts-expect-error I don't know why this is not working\n    await Promise.all(cacheKeys.map((key) => caches.default.delete(key)));\n\n    return await fetch(\n      `https://api.cloudflare.com/client/v4zones/${this.config.zoneId}/purge_cache`,\n      {\n        method: \"POST\",\n        headers: {\n          Authorization: `Bearer ${this.config.cloudflareApiKey}`,\n          \"Content-Type\": \"application/json\",\n        },\n        body: JSON.stringify({\n          files: cacheKeys.map((k) => k.toString()),\n        }),\n      },\n    )\n      .then((res) => res.body?.cancel())\n      .then(() => Ok())\n      .catch((err) =>\n        Err(\n          new CacheError({\n            tier: this.name,\n            key: keys.toString(),\n            message: (err as Error).message,\n          }),\n        ),\n      );\n  }\n}\n","import { Ok, type Result } from \"@unkey/error\";\nimport type { CacheError } from \"../errors\";\nimport type { Entry, Store } from \"./interface\";\n\nexport type MemoryStoreConfig<TValue> = {\n  /**\n   * Remove expired entries on every `set` operation\n   *\n   * This flag is unstable and may be changed or removed later.\n   *\n   * ```\n   */\n  unstableEvictOnSet?: {\n    /**\n     * Provide a number between 0 and 1 to calculate whether eviction should run on each set.\n     * @example\n     * ```\n     * 1 -> run eviction on every `set`\n     * 0.5 -> run eviction on every 2nd `set`\n     * 0 or undefined -> disable\n     */\n    frequency: number;\n\n    /**\n     * Remove items until the number of items in the map is lower than `maxItems`\n     */\n    maxItems: number;\n  };\n  persistentMap: Map<string, TValue>;\n};\n\nexport class MemoryStore<TNamespace extends string, TValue = any>\n  implements Store<TNamespace, TValue>\n{\n  private readonly state: Map<string, { expires: number; entry: Entry<TValue> }>;\n  private readonly unstableEvictOnSet?: { frequency: number; maxItems: number };\n\n  public readonly name = \"memory\";\n\n  constructor(config: MemoryStoreConfig<{ expires: number; entry: Entry<TValue> }>) {\n    this.state = config.persistentMap;\n    this.unstableEvictOnSet = config.unstableEvictOnSet;\n  }\n\n  private buildCacheKey(namespace: TNamespace, key: string): string {\n    return [namespace, key].join(\"::\");\n  }\n\n  public async get(\n    namespace: TNamespace,\n    key: string,\n  ): Promise<Result<Entry<TValue> | undefined, CacheError>> {\n    const value = this.state.get(this.buildCacheKey(namespace, key));\n    if (!value) {\n      return Promise.resolve(Ok(undefined));\n    }\n    if (value.expires <= Date.now()) {\n      await this.remove(namespace, key);\n    }\n    return Promise.resolve(Ok(value.entry));\n  }\n\n  public async set(\n    namespace: TNamespace,\n    key: string,\n    entry: Entry<TValue>,\n  ): Promise<Result<void, CacheError>> {\n    this.state.set(this.buildCacheKey(namespace, key), {\n      expires: entry.staleUntil,\n      entry,\n    });\n\n    if (this.unstableEvictOnSet && Math.random() < this.unstableEvictOnSet.frequency) {\n      /**\n       * First delete all the expired ones\n       */\n      const now = Date.now();\n      this.state.forEach((value, key, map) => {\n        if (value.expires < now) {\n          map.delete(key);\n        }\n      });\n\n      /**\n       * If that's not enough, we delete oldest first\n       */\n      for (const [k] of this.state) {\n        if (this.state.size <= this.unstableEvictOnSet!.maxItems) {\n          break;\n        }\n\n        this.state.delete(k);\n      }\n    }\n\n    return Promise.resolve(Ok());\n  }\n\n  public async remove(\n    namespace: TNamespace,\n    keys: string | string[],\n  ): Promise<Result<void, CacheError>> {\n    const cacheKeys = (Array.isArray(keys) ? keys : [keys]).map((key) =>\n      this.buildCacheKey(namespace, key).toString(),\n    );\n    for (const key of cacheKeys) {\n      this.state.delete(key);\n    }\n    return Promise.resolve(Ok());\n  }\n}\n","import { Ok, type Result } from \"@unkey/error\";\nimport type { Redis } from \"@upstash/redis\";\n\nimport type { CacheError } from \"../errors\";\nimport type { Entry, Store } from \"./interface\";\n\nexport type UpstashRedisStoreConfig = {\n  redis: Redis;\n};\n\nexport class UpstashRedisStore<TNamespace extends string, TValue = any>\n  implements Store<TNamespace, TValue>\n{\n  private readonly redis: Redis;\n  public readonly name = \"upstash-redis\";\n\n  constructor(config: UpstashRedisStoreConfig) {\n    this.redis = config.redis;\n  }\n\n  private buildCacheKey(namespace: TNamespace, key: string): string {\n    return [namespace, key].join(\"::\");\n  }\n\n  public async get(\n    namespace: TNamespace,\n    key: string,\n  ): Promise<Result<Entry<TValue> | undefined, CacheError>> {\n    const value = await this.redis.get<Entry<TValue>>(this.buildCacheKey(namespace, key));\n    if (!value) {\n      return Ok(undefined);\n    }\n    return Ok(value);\n  }\n\n  public async set(\n    namespace: TNamespace,\n    key: string,\n    entry: Entry<TValue>,\n  ): Promise<Result<void, CacheError>> {\n    await this.redis.set<Entry<TValue>>(this.buildCacheKey(namespace, key), entry, {\n      pxat: entry.staleUntil,\n    });\n    return Ok();\n  }\n\n  public async remove(\n    namespace: TNamespace,\n    keys: string | string[],\n  ): Promise<Result<void, CacheError>> {\n    const cacheKeys = (Array.isArray(keys) ? keys : [keys]).map((key) =>\n      this.buildCacheKey(namespace, key).toString(),\n    );\n    this.redis.del(...cacheKeys);\n    return Ok();\n  }\n}\n","import type { Client } from \"@libsql/client\";\nimport { Ok, type Result } from \"@unkey/error\";\n\nimport type { CacheError } from \"../errors\";\nimport type { Entry, Store } from \"./interface\";\n\nexport type LibsqlStoreConfig = {\n  client: Client;\n  tableName?: string;\n};\n\nexport class LibSQLStore<TNamespace extends string, TValue = any>\n  implements Store<TNamespace, TValue>\n{\n  private readonly tableName: string;\n  private readonly client: Client;\n  public readonly name = \"libsql\";\n\n  constructor(config: LibsqlStoreConfig) {\n    this.client = config.client;\n    this.tableName = config.tableName || \"cache\";\n  }\n\n  private buildCacheKey(namespace: TNamespace, key: string): string {\n    return `${namespace}::${key}`;\n  }\n\n  public async get(\n    namespace: TNamespace,\n    key: string,\n  ): Promise<Result<Entry<TValue> | undefined, CacheError>> {\n    try {\n      const result = await this.client.execute({\n        sql: `SELECT value, freshUntil, staleUntil FROM ${this.tableName} WHERE key = ?`,\n        args: [this.buildCacheKey(namespace, key)],\n      });\n\n      if (result.rows.length === 0) {\n        return Ok(undefined);\n      }\n\n      const row = result.rows[0];\n      const entry: Entry<TValue> = {\n        value: JSON.parse(row.value as string),\n        freshUntil: Number(row.freshUntil),\n        staleUntil: Number(row.staleUntil),\n      };\n\n      return Ok(entry);\n    } catch {\n      return Ok(undefined);\n    }\n  }\n\n  public async set(\n    namespace: TNamespace,\n    key: string,\n    entry: Entry<TValue>,\n  ): Promise<Result<void, CacheError>> {\n    try {\n      await this.client.execute({\n        sql: `INSERT OR REPLACE INTO ${this.tableName} (key, value, freshUntil, staleUntil)\n              VALUES (?, ?, ?, ?)`,\n        args: [\n          this.buildCacheKey(namespace, key),\n          JSON.stringify(entry.value),\n          entry.freshUntil,\n          entry.staleUntil,\n        ],\n      });\n\n      return Ok();\n    } catch {\n      return Ok();\n    }\n  }\n\n  public async remove(\n    namespace: TNamespace,\n    keys: string | string[],\n  ): Promise<Result<void, CacheError>> {\n    const cacheKeys = (Array.isArray(keys) ? keys : [keys]).map((key) =>\n      this.buildCacheKey(namespace, key).toString(),\n    );\n\n    try {\n      await Promise.all(\n        cacheKeys.map((cacheKey) =>\n          this.client.execute({\n            sql: `DELETE FROM ${this.tableName} WHERE key = ?`,\n            args: [cacheKey],\n          }),\n        ),\n      );\n\n      return Ok();\n    } catch {\n      return Ok();\n    }\n  }\n}\n"]}