Browse Source

feat(02-03): create model caching utility

Add in-memory cache for provider model lists with 10-minute TTL.
Includes get/set/invalidate functions and cache key generation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
handoff-20260429-1057
shrimbly 6 months ago
parent
commit
83ef0b4dc4
  1. 116
      src/lib/providers/cache.ts

116
src/lib/providers/cache.ts

@ -0,0 +1,116 @@
/**
* Model Caching Utility
*
* Simple in-memory cache for model lists from providers.
* Reduces API calls to external providers by caching results with TTL.
*
* Features:
* - 10-minute default TTL
* - Per-provider cache keys
* - Optional search query in cache key
* - Manual invalidation support
*
* Note: Cache is cleared on server restart (no persistence).
*/
import { ProviderModel } from "./types";
import { ProviderType } from "@/types";
/**
* Cache entry with data and timestamp
*/
interface CacheEntry<T> {
data: T;
timestamp: number;
}
/**
* Default cache TTL: 10 minutes
*/
const DEFAULT_TTL = 10 * 60 * 1000;
/**
* In-memory cache storage
*/
const cache: Map<string, CacheEntry<ProviderModel[]>> = new Map();
/**
* Get cached models for a key if not expired
*
* @param key - Cache key (use getCacheKey to generate)
* @param ttl - Optional custom TTL in milliseconds
* @returns Cached models or null if not in cache or expired
*/
export function getCachedModels(
key: string,
ttl: number = DEFAULT_TTL
): ProviderModel[] | null {
const entry = cache.get(key);
if (!entry) {
return null;
}
const now = Date.now();
if (now - entry.timestamp > ttl) {
// Cache expired, remove entry
cache.delete(key);
return null;
}
return entry.data;
}
/**
* Store models in cache with current timestamp
*
* @param key - Cache key (use getCacheKey to generate)
* @param models - Models to cache
*/
export function setCachedModels(key: string, models: ProviderModel[]): void {
cache.set(key, {
data: models,
timestamp: Date.now(),
});
}
/**
* Invalidate cache entries
*
* @param key - Optional specific key to invalidate. If not provided, clears entire cache.
*/
export function invalidateCache(key?: string): void {
if (key) {
cache.delete(key);
} else {
cache.clear();
}
}
/**
* Generate a cache key for provider models
*
* @param provider - Provider type
* @param search - Optional search query
* @returns Cache key string
*
* @example
* getCacheKey("replicate") // "replicate:models"
* getCacheKey("fal", "flux") // "fal:search:flux"
*/
export function getCacheKey(provider: ProviderType, search?: string): string {
if (search) {
return `${provider}:search:${search}`;
}
return `${provider}:models`;
}
/**
* Get cache statistics (for debugging)
*/
export function getCacheStats(): { size: number; keys: string[] } {
return {
size: cache.size,
keys: Array.from(cache.keys()),
};
}
Loading…
Cancel
Save