fix: séparation du cache client et serveur pour résoudre l'erreur localStorage
This commit is contained in:
121
src/lib/services/client-cache.service.ts
Normal file
121
src/lib/services/client-cache.service.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import { TTLConfig } from "@/types/cache";
|
||||
|
||||
class ClientCacheService {
|
||||
private static instance: ClientCacheService;
|
||||
private cache: Map<string, { data: unknown; expiry: number }> = 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<T>(
|
||||
key: string,
|
||||
fetcher: () => Promise<T>,
|
||||
type: keyof typeof ClientCacheService.DEFAULT_TTL = "DEFAULT"
|
||||
): Promise<T> {
|
||||
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();
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
8
src/types/cache.ts
Normal file
8
src/types/cache.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export interface TTLConfig {
|
||||
defaultTTL: number;
|
||||
homeTTL: number;
|
||||
librariesTTL: number;
|
||||
seriesTTL: number;
|
||||
booksTTL: number;
|
||||
imagesTTL: number;
|
||||
}
|
||||
Reference in New Issue
Block a user