search/app/composables/useDocMetaCache.ts

57 lines
1.6 KiB
TypeScript

export interface CachedDocMeta {
id: string
title: string
date?: string
timestamp?: number
place?: string
city?: string
state?: string
country?: string
type?: string
slug?: string
draft?: string
[key: string]: unknown
}
const MAX_ENTRIES = 500
function cacheKey(collection: string, id: string): string {
return `${collection}:${id}`
}
/**
* Caché de metadata de documentos (título, fecha, lugar...) compartida entre
* páginas de búsqueda, con vida de sesión (sobrevive entre queries, no se
* vacía al buscar de nuevo). Clave `collection:id` porque los IDs no son
* únicos entre colecciones (p.ej. `conferences` vs `activities`).
*
* Tope de tamaño con eviction LRU simple: en cada lectura/escritura la
* entrada se reinserta al final del Map (orden de inserción = recencia), así
* que la más antigua a evictar siempre es `.keys().next().value`.
*/
export function useDocMetaCache() {
const cache = useState<Map<string, CachedDocMeta>>('doc-meta-cache', () => new Map())
function get(collection: string, id: string): CachedDocMeta | undefined {
const key = cacheKey(collection, id)
const entry = cache.value.get(key)
if (entry) {
cache.value.delete(key)
cache.value.set(key, entry)
}
return entry
}
function set(collection: string, id: string, meta: CachedDocMeta) {
const key = cacheKey(collection, id)
cache.value.delete(key)
cache.value.set(key, meta)
if (cache.value.size > MAX_ENTRIES) {
const oldestKey = cache.value.keys().next().value
if (oldestKey !== undefined) cache.value.delete(oldestKey)
}
}
return { get, set }
}