diff --git a/src/lib/services/client-cache.service.ts b/src/lib/services/client-cache.service.ts new file mode 100644 index 0000000..138ed26 --- /dev/null +++ b/src/lib/services/client-cache.service.ts @@ -0,0 +1,121 @@ +import { TTLConfig } from "@/types/cache"; + +class ClientCacheService { + private static instance: ClientCacheService; + private cache: Map = new Map(); + + private static readonly DEFAULT_TTL = { + DEFAULT: 5 * 60, + HOME: 5 * 60, + LIBRARIES: 24 * 60 * 60, + SERIES: 5 * 60, + BOOKS: 5 * 60, + IMAGES: 24 * 60 * 60, + }; + + private constructor() { + // Private constructor to prevent external instantiation + } + + public static getInstance(): ClientCacheService { + if (!ClientCacheService.instance) { + ClientCacheService.instance = new ClientCacheService(); + } + return ClientCacheService.instance; + } + + /** + * Retourne le TTL pour un type de données spécifique + */ + public getTTL(type: keyof typeof ClientCacheService.DEFAULT_TTL): number { + try { + const ttlConfig = localStorage.getItem("ttlConfig"); + if (ttlConfig) { + const config = JSON.parse(ttlConfig) as TTLConfig; + const key = `${type.toLowerCase()}TTL` as keyof TTLConfig; + if (config[key]) { + // Convertir les minutes en secondes + return config[key] * 60; + } + } + } catch (error) { + console.error("Erreur lors de la lecture de la configuration TTL:", error); + } + + return ClientCacheService.DEFAULT_TTL[type]; + } + + /** + * Met en cache des données avec une durée de vie + */ + set(key: string, data: any, type: keyof typeof ClientCacheService.DEFAULT_TTL = "DEFAULT"): void { + this.cache.set(key, { + data, + expiry: Date.now() + this.getTTL(type) * 1000, + }); + } + + /** + * Récupère des données du cache si elles sont valides + */ + get(key: string): any | null { + const cached = this.cache.get(key); + if (!cached) return null; + + const now = Date.now(); + if (cached.expiry > now) { + return cached.data; + } + + this.cache.delete(key); + return null; + } + + /** + * Supprime une entrée du cache + */ + delete(key: string): void { + this.cache.delete(key); + } + + /** + * Vide le cache + */ + clear(): void { + this.cache.clear(); + } + + /** + * Récupère des données du cache ou exécute la fonction si nécessaire + */ + async getOrSet( + key: string, + fetcher: () => Promise, + type: keyof typeof ClientCacheService.DEFAULT_TTL = "DEFAULT" + ): Promise { + const now = Date.now(); + const cached = this.cache.get(key); + + if (cached && cached.expiry > now) { + console.log("Cache hit for key:", key); + return cached.data as T; + } + + try { + const data = await fetcher(); + this.cache.set(key, { + data, + expiry: now + this.getTTL(type) * 1000, + }); + return data; + } catch (error) { + throw error; + } + } + + invalidate(key: string): void { + this.cache.delete(key); + } +} + +export const clientCacheService = ClientCacheService.getInstance(); diff --git a/src/lib/services/server-cache.service.ts b/src/lib/services/server-cache.service.ts index 2a97eda..2ce5999 100644 --- a/src/lib/services/server-cache.service.ts +++ b/src/lib/services/server-cache.service.ts @@ -39,22 +39,7 @@ class ServerCacheService { * Retourne le TTL pour un type de données spécifique */ public getTTL(type: keyof typeof ServerCacheService.DEFAULT_TTL): number { - // Essayer de récupérer la configuration utilisateur - try { - const ttlConfig = localStorage.getItem("ttlConfig"); - if (ttlConfig) { - const config = JSON.parse(ttlConfig); - const key = `${type.toLowerCase()}TTL` as keyof typeof config; - if (config[key]) { - // Convertir les minutes en secondes - return config[key] * 60; - } - } - } catch (error) { - console.error("Erreur lors de la lecture de la configuration TTL:", error); - } - - // Utiliser la valeur par défaut si pas de configuration utilisateur + // Utiliser directement la valeur par défaut return ServerCacheService.DEFAULT_TTL[type]; } diff --git a/src/types/cache.ts b/src/types/cache.ts new file mode 100644 index 0000000..6ecb2ab --- /dev/null +++ b/src/types/cache.ts @@ -0,0 +1,8 @@ +export interface TTLConfig { + defaultTTL: number; + homeTTL: number; + librariesTTL: number; + seriesTTL: number; + booksTTL: number; + imagesTTL: number; +}