@solomonai/cache
Version:
<div align="center"> <h1 align="center">@solomonai/cache</h1> <h5>Cache all the things</h5> </div>
1 lines • 16.6 kB
Source Map (JSON)
{"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"]}