wrongmove/frontend/src/services/listingCache.ts

46 lines
1.4 KiB
TypeScript
Raw Normal View History

/**
* In-memory LRU cache for streaming listing results.
*
* Keyed by a deterministic hash of query parameters so that repeat visits
* to the same filter combination are instant (no network request).
*/
import type { PropertyFeature } from '@/types';
import type { ParameterValues } from '@/components/FilterPanel';
interface CacheEntry {
features: PropertyFeature[];
timestamp: number;
}
const cache = new Map<string, CacheEntry>();
const MAX_ENTRIES = 5;
export function makeCacheKey(params: ParameterValues): string {
const sorted = Object.entries(params)
.filter(([, v]) => v !== undefined && v !== null && v !== '')
.sort(([a], [b]) => a.localeCompare(b))
.map(([k, v]) => `${k}=${v instanceof Date ? v.toISOString() : v}`);
return sorted.join('&');
}
export function getCached(params: ParameterValues): PropertyFeature[] | null {
const key = makeCacheKey(params);
const entry = cache.get(key);
if (!entry) return null;
return entry.features;
}
export function setCached(params: ParameterValues, features: PropertyFeature[]): void {
const key = makeCacheKey(params);
if (cache.size >= MAX_ENTRIES && !cache.has(key)) {
// Evict oldest entry (first inserted)
const oldest = cache.keys().next().value;
if (oldest) cache.delete(oldest);
}
cache.set(key, { features, timestamp: Date.now() });
}
export function invalidateAll(): void {
cache.clear();
}