| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| type CacheEntry<T> = { |
| value: T; |
| expiresAt: number; |
| }; |
|
|
| class TTLCache<T> { |
| private cache = new Map<string, CacheEntry<T>>(); |
| private readonly ttlMs: number; |
|
|
| constructor(ttlMs: number) { |
| this.ttlMs = ttlMs; |
| } |
|
|
| get(key: string): T | undefined { |
| const entry = this.cache.get(key); |
| if (!entry) return undefined; |
| if (Date.now() > entry.expiresAt) { |
| this.cache.delete(key); |
| return undefined; |
| } |
| return entry.value; |
| } |
|
|
| set(key: string, value: T): void { |
| this.cache.set(key, { value, expiresAt: Date.now() + this.ttlMs }); |
| } |
|
|
| invalidate(key?: string): void { |
| if (key) { |
| this.cache.delete(key); |
| } else { |
| this.cache.clear(); |
| } |
| } |
| } |
|
|
| |
| |
| const SETTINGS_TTL_MS = 5_000; |
| const PRICING_TTL_MS = 30_000; |
| const CONNECTIONS_TTL_MS = 5_000; |
|
|
| const settingsCache = new TTLCache<Record<string, unknown>>(SETTINGS_TTL_MS); |
| const pricingCache = new TTLCache<Record<string, unknown>>(PRICING_TTL_MS); |
| const connectionsCache = new TTLCache<unknown[]>(CONNECTIONS_TTL_MS); |
|
|
| |
| |
| |
| |
| export async function getCachedSettings(): Promise<Record<string, unknown>> { |
| const cached = settingsCache.get("settings"); |
| if (cached) return cached; |
|
|
| const { getSettings } = await import("@/lib/db/settings"); |
| const value = await getSettings(); |
| settingsCache.set("settings", value); |
| return value; |
| } |
|
|
| |
| |
| |
| |
| export async function getCachedPricing(): Promise<Record<string, unknown>> { |
| const cached = pricingCache.get("pricing"); |
| if (cached) return cached as Record<string, unknown>; |
|
|
| const { getPricing } = await import("@/lib/db/settings"); |
| const value = await getPricing(); |
| pricingCache.set("pricing", value); |
| return value; |
| } |
|
|
| |
| |
| |
| |
| export async function getCachedProviderConnections( |
| filter?: Record<string, unknown> |
| ): Promise<unknown[]> { |
| |
| if (filter && Object.keys(filter).length > 0) { |
| const { getProviderConnections } = await import("@/lib/db/providers"); |
| return getProviderConnections(filter); |
| } |
|
|
| const cached = connectionsCache.get("all"); |
| if (cached) return cached; |
|
|
| const { getProviderConnections } = await import("@/lib/db/providers"); |
| const value = await getProviderConnections(); |
| connectionsCache.set("all", value); |
| return value; |
| } |
|
|
| |
|
|
| const lkgpCache = new TTLCache<string | null>(SETTINGS_TTL_MS); |
|
|
| export async function getCachedLKGP(comboName: string, modelId: string): Promise<string | null> { |
| const cacheKey = `lkgp:${comboName}:${modelId}`; |
| const cached = lkgpCache.get(cacheKey); |
| if (cached !== undefined) return cached; |
|
|
| const { getLKGP } = await import("@/lib/db/settings"); |
| const value = await getLKGP(comboName, modelId); |
| lkgpCache.set(cacheKey, value); |
| return value; |
| } |
|
|
| export async function setCachedLKGP( |
| comboName: string, |
| modelId: string, |
| providerId: string |
| ): Promise<void> { |
| const { setLKGP } = await import("@/lib/db/settings"); |
| await setLKGP(comboName, modelId, providerId); |
| lkgpCache.invalidate(`lkgp:${comboName}:${modelId}`); |
| } |
|
|
| |
| |
| |
| export function invalidateDbCache(scope?: "settings" | "pricing" | "connections"): void { |
| if (!scope || scope === "settings") settingsCache.invalidate(); |
| if (!scope || scope === "pricing") pricingCache.invalidate(); |
| if (!scope || scope === "connections") connectionsCache.invalidate(); |
| } |
|
|