opticore-cache 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,597 @@
1
+ import { ILoggerConfig } from 'opticore-logger';
2
+ import { Request, Response, NextFunction } from 'opticore-express';
3
+
4
+ /**
5
+ * Cache usage statistics
6
+ */
7
+ interface CacheStatistics {
8
+ /** Number of successful cache reads */
9
+ hits: number;
10
+ /** Number of read failures (miss cache) */
11
+ misses: number;
12
+ /** Number of writes to the cache */
13
+ writes: number;
14
+ /** Number of entries currently in the cache */
15
+ size: number;
16
+ /** Maximum configured cache size */
17
+ maxSize: number;
18
+ /** Success rate (hits / (hits + misses)) */
19
+ hitRate: number;
20
+ /** Usage Percentage (size / maxSize) */
21
+ usagePercentage: number;
22
+ }
23
+
24
+ /**
25
+ * Interface defining the contract for a cache repository
26
+ * Follows the Repository pattern for persistence abstraction
27
+ */
28
+ interface ICacheRepository {
29
+ /**
30
+ * Stores a value in the cache
31
+ *
32
+ * @param key - Unique key for the entry
33
+ * @param value - Value to store
34
+ * @param ttl - Time to live in milliseconds (optional)
35
+ * @returns Promise<void>
36
+ */
37
+ set<T>(key: string, value: T, ttl?: number): Promise<void>;
38
+ /**
39
+ * Retrieves a value from the cache
40
+ *
41
+ * @param key - Key of the entry to retrieve
42
+ * @returns Promise<T | null> - The value or null if not found/expired
43
+ */
44
+ get<T>(key: string): Promise<T | null>;
45
+ /**
46
+ * Deletes an entry from the cache
47
+ *
48
+ * @param key - Key of the entry to delete
49
+ * @returns Promise<void>
50
+ */
51
+ delete(key: string): Promise<void>;
52
+ /**
53
+ * Checks if a key exists in the cache (not expired)
54
+ *
55
+ * @param key - Key to check
56
+ * @returns Promise<boolean>
57
+ */
58
+ has(key: string): Promise<boolean>;
59
+ /**
60
+ * Deletes all entries from the cache
61
+ *
62
+ * @returns Promise<void>
63
+ */
64
+ clear(): Promise<void>;
65
+ /**
66
+ * Retrieves all valid keys from the cache
67
+ *
68
+ * @returns Promise<string[]> - List of keys
69
+ */
70
+ keys(): Promise<string[]>;
71
+ /**
72
+ * Retrieves cache usage statistics
73
+ *
74
+ * @returns Promise<CacheStatistics>
75
+ */
76
+ getStatistics(): Promise<CacheStatistics>;
77
+ /**
78
+ * Invalidates entries whose key matches the pattern
79
+ *
80
+ * @param pattern - Pattern of keys to invalidate
81
+ * @returns Promise<number> - Number of entries invalidated
82
+ */
83
+ invalidate(pattern: string): Promise<number>;
84
+ }
85
+
86
+ /**
87
+ * Factory pour créer des instances de cache selon la configuration
88
+ * Implémente le pattern Factory Method
89
+ */
90
+ declare class CacheFactoryRepository {
91
+ /**
92
+ * Crée une instance de cache basée sur la configuration
93
+ *
94
+ * @param customConfig - Configuration personnalisée (optionnel)
95
+ * @returns CacheRepository | null - Instance de cache ou null si désactivé
96
+ */
97
+ static createCache(customConfig?: Partial<any>): ICacheRepository | null;
98
+ /**
99
+ * Crée un cache avec une configuration minimale
100
+ *
101
+ * @param enabled - Activer le cache
102
+ * @param maxSize - Taille maximale
103
+ * @returns CacheRepository | null
104
+ */
105
+ static createSimpleCache(enabled: boolean, maxSize?: number): ICacheRepository | null;
106
+ }
107
+
108
+ /**
109
+ * Application caching service that exposes a simple API to controllers
110
+ * Acts as a facade for domain use cases
111
+ */
112
+ declare class CacheService {
113
+ private readonly cacheUseCase;
114
+ private readonly cacheRepository;
115
+ private readonly localLang;
116
+ private readonly configLogger;
117
+ /**
118
+ * Creates a CacheService instance
119
+ *
120
+ * @param cacheRepository - Cache repository (may be null if disabled)
121
+ * @param localLang
122
+ * @param configLogger
123
+ */
124
+ constructor(cacheRepository: ICacheRepository | null, localLang: string, configLogger?: Partial<ILoggerConfig>);
125
+ /**
126
+ * Retrieves a value or adds it if absent
127
+ *
128
+ * @param key - Input key
129
+ * @param fetcher - Function to retrieve the value if absent
130
+ * @param ttl - Specific time to live
131
+ * @returns Promise<T> - Cache value or fetch result
132
+ */
133
+ getOrSet<T>(key: string, fetcher: () => Promise<T>, ttl?: number): Promise<T>;
134
+ /**
135
+ * Stores a value directly in the cache
136
+ *
137
+ * @param key - Input key
138
+ * @param value - Value to store
139
+ * @param ttl - Time to live
140
+ * @returns Promise<void>
141
+ */
142
+ set<T>(key: string, value: T, ttl?: number): Promise<void>;
143
+ /**
144
+ * Retrieves a value from the cache
145
+ *
146
+ * @param key - Input key
147
+ * @returns Promise<T | null>
148
+ */
149
+ get<T>(key: string): Promise<T | null>;
150
+ /**
151
+ * Removes an entry from the cache
152
+ *
153
+ * @param key - Entry key
154
+ * @returns Promise<void>
155
+ */
156
+ delete(key: string): Promise<void>;
157
+ /**
158
+ * Invalidates entries matching the pattern
159
+ *
160
+ * @param pattern - Pattern for selecting entries
161
+ * @returns Promise<number> - Number of invalidated entries
162
+ */
163
+ invalidate(pattern: string): Promise<number>;
164
+ /**
165
+ * Clear cache completely
166
+ *
167
+ * @returns Promise<void>
168
+ */
169
+ clear(): Promise<void>;
170
+ /**
171
+ * Get cache stats
172
+ *
173
+ * @returns Promise<CacheStatistics>
174
+ */
175
+ getStatistics(): Promise<CacheStatistics>;
176
+ /**
177
+ * Check the cache health status
178
+ *
179
+ * @returns Promise<{ healthy: boolean; message: string }>
180
+ */
181
+ healthCheck(): Promise<{
182
+ healthy: boolean;
183
+ message: string;
184
+ }>;
185
+ /**
186
+ * Check if the cache is enabled
187
+ * @returns boolean
188
+ */
189
+ isEnabled(): boolean;
190
+ /**
191
+ * Retrieves all keys from the cache
192
+ *
193
+ * @returns Promise<string[]> - List of keys
194
+ */
195
+ getKeys(): Promise<string[]>;
196
+ /**
197
+ * Checks if a key exists in the cache
198
+ *
199
+ * @param key - Key to check
200
+ * @returns Promise<boolean>
201
+ */
202
+ has(key: string): Promise<boolean>;
203
+ /**
204
+ * Creates and configures a full cache service
205
+ *
206
+ * @param customConfig - Custom configuration (optional)
207
+ * @returns CacheService - Cache service configured
208
+ */
209
+ createCache(customConfig?: Partial<any>): CacheService;
210
+ /**
211
+ *
212
+ * @private
213
+ */
214
+ private translatorConfig;
215
+ private logger;
216
+ }
217
+
218
+ /**
219
+ * Options de configuration du middleware de cache
220
+ */
221
+ interface ICacheMiddlewareOptions {
222
+ /** Durée de vie spécifique pour cette route */
223
+ timeToLive?: number;
224
+ /** Fonction pour générer la clé de cache */
225
+ keyGenerator?: (req: Request) => string;
226
+ /** Fonction pour déterminer si la requête doit être ignorée */
227
+ shouldSkip?: (req: Request) => boolean;
228
+ /** Fonction pour transformer la réponse avant stockage */
229
+ responseTransformer?: (body: any) => any;
230
+ /** Activer/désactiver le cache pour ce middleware */
231
+ enabled?: boolean;
232
+ }
233
+
234
+ type TCreateMiddlewareResponseType = (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
235
+
236
+ type TCreateStatsMiddlewareResponse = Promise<Response<any, Record<string, any>> | undefined>;
237
+
238
+ /**
239
+ * Middleware Express pour la mise en cache automatique des réponses
240
+ */
241
+ declare class CacheMiddleware {
242
+ private readonly routeValidator;
243
+ private readonly config;
244
+ /**
245
+ * Crée une instance de CacheMiddleware
246
+ */
247
+ constructor();
248
+ /**
249
+ * Crée un middleware Express configurable
250
+ * @param cacheRepository - Repository de cache à utiliser
251
+ * @param options - Options de configuration du middleware
252
+ * @returns Middleware Express
253
+ */
254
+ createMiddleware(cacheRepository: ICacheRepository | null, options?: ICacheMiddlewareOptions): TCreateMiddlewareResponseType;
255
+ /**
256
+ * Détermine si une requête doit être skipée
257
+ * @param req - Requête Express
258
+ * @param options - Options du middleware
259
+ * @returns boolean
260
+ * @private
261
+ */
262
+ private shouldSkipRequest;
263
+ /**
264
+ * Générateur de clé par défaut
265
+ * @param req - Requête Express
266
+ * @returns string - Clé de cache
267
+ * @private
268
+ */
269
+ private defaultKeyGenerator;
270
+ /**
271
+ * Normalizes a path for the cache
272
+ *
273
+ * @param path - Path to be standardized
274
+ * @returns string
275
+ * @private
276
+ */
277
+ private normalizePath;
278
+ /**
279
+ * Adds HTTP headers related to the cache
280
+ *
281
+ * @param res - Express Response
282
+ * @param status - Cache status (HIT/MISS)
283
+ * @param key - Cache key
284
+ * @param ttl - Lifespan (optional)
285
+ * @private
286
+ */
287
+ private addCacheHeaders;
288
+ /**
289
+ * Creates middleware to display cache statistics
290
+ * @param cacheRepository - Cache repository
291
+ * @returns Middleware Express
292
+ */
293
+ createStatsMiddleware(cacheRepository: ICacheRepository | null): (req: Request, res: Response, next: NextFunction) => TCreateStatsMiddlewareResponse;
294
+ /**
295
+ * Create a middleware to clear the cache
296
+ *
297
+ * @param cacheRepository - Cache repository
298
+ * @returns Middleware Express
299
+ */
300
+ createClearMiddleware(cacheRepository: ICacheRepository | null): (req: Request, res: Response, next: NextFunction) => Promise<Response<any, Record<string, any>> | undefined>;
301
+ }
302
+
303
+ /**
304
+ * Charge et valide la configuration depuis les variables d'environnement
305
+ * Implémente le pattern Singleton pour garantir une seule instance
306
+ */
307
+ declare class EnvironmentLoader {
308
+ private static instance;
309
+ private configuration;
310
+ /**
311
+ * Constructeur privé pour forcer l'utilisation de getInstance()
312
+ */
313
+ private constructor();
314
+ /**
315
+ * Récupère l'instance unique du EnvironmentLoader
316
+ *
317
+ * @returns EnvironmentLoader
318
+ */
319
+ static getInstance(): EnvironmentLoader;
320
+ /**
321
+ * Charge et parse la configuration depuis process.env
322
+ *
323
+ * @private
324
+ */
325
+ private loadConfiguration;
326
+ /**
327
+ * Parse une valeur booléenne depuis les variables d'environnement
328
+ *
329
+ * @param key - Clé de la variable d'environnement
330
+ * @param defaultValue - Valeur par défaut si non définie
331
+ * @returns boolean
332
+ */
333
+ private parseBoolean;
334
+ /**
335
+ * Parse un nombre depuis les variables d'environnement
336
+ *
337
+ * @param key - Clé de la variable d'environnement
338
+ * @param defaultValue - Valeur par défaut si non définie ou invalide
339
+ * @returns number
340
+ */
341
+ private parseNumber;
342
+ /**
343
+ * Parse la stratégie d'éviction depuis les variables d'environnement
344
+ *
345
+ * @param key - Clé de la variable d'environnement
346
+ * @param defaultValue - Valeur par défaut
347
+ * @returns 'lru' | 'fifo' | 'lfu'
348
+ */
349
+ private parseEvictionStrategy;
350
+ /**
351
+ * Parse la liste des routes à ignorer depuis les variables d'environnement
352
+ *
353
+ * @param key - Clé de la variable d'environnement
354
+ * @returns string[] - Liste des routes à ignorer
355
+ */
356
+ private parseSkipRoutes;
357
+ /**
358
+ * Récupère la configuration complète
359
+ *
360
+ * @returns CacheConfiguration
361
+ */
362
+ getConfig(): any;
363
+ /**
364
+ * Met à jour la configuration (pour les tests)
365
+ *
366
+ * @param updates - Mises à jour partielles de configuration
367
+ */
368
+ updateConfig(updates: Partial<any>): void;
369
+ }
370
+
371
+ /**
372
+ * Pattern de route avec sa méthode HTTP associée
373
+ */
374
+ interface IRoutePattern {
375
+ /** Méthode HTTP (undefined = toutes méthodes) */
376
+ method?: string;
377
+ /** Chemin de la route */
378
+ path: string;
379
+ /** Expression régulière compilée pour le matching */
380
+ regexPattern: RegExp;
381
+ }
382
+
383
+ /**
384
+ * Valide et match les routes contre des patterns configurés
385
+ * Gère les wildcards et les méthodes HTTP
386
+ */
387
+ declare class RouteValidator {
388
+ private readonly skipRoutes;
389
+ private readonly enableWildcards;
390
+ private routePatterns;
391
+ /**
392
+ * Crée une instance de RouteValidator
393
+ *
394
+ * @param skipRoutes - Liste des routes à ignorer
395
+ * @param enableWildcards - Activer le support des wildcards
396
+ */
397
+ constructor(skipRoutes?: string[], enableWildcards?: boolean);
398
+ /**
399
+ * Compile les patterns de route en expressions régulières
400
+ *
401
+ * @private
402
+ */
403
+ private compileRoutePatterns;
404
+ /**
405
+ * Parse un pattern de route en méthode et chemin
406
+ *
407
+ * @param routePattern - Pattern à parser (format: "METHOD:path" ou "path")
408
+ * @returns {{ method?: string; path: string }}
409
+ */
410
+ private parseRoutePattern;
411
+ /**
412
+ * Compile un chemin en expression régulière
413
+ *
414
+ * @param path - Chemin à compiler
415
+ * @param enableWildcards - Activer le support des wildcards
416
+ * @returns RegExp
417
+ */
418
+ private compileToRegex;
419
+ /**
420
+ * Échappe les caractères spéciaux pour les expressions régulières
421
+ *
422
+ * @param string - Chaîne à échapper
423
+ * @returns string
424
+ */
425
+ private escapeRegex;
426
+ /**
427
+ * Vérifie si une requête correspond à un pattern de route ignorée
428
+ *
429
+ * @param request - Requête Express à vérifier
430
+ * @returns boolean - True si la route doit être ignorée
431
+ */
432
+ shouldSkipRoute(request: Request): boolean;
433
+ /**
434
+ * Normalise un chemin (supprime les slashes de fin)
435
+ *
436
+ * @param path - Chemin à normaliser
437
+ * @returns string - Chemin normalisé
438
+ */
439
+ private normalizePath;
440
+ /**
441
+ * Récupère la liste des patterns compilés (pour debug)
442
+ *
443
+ * @returns RoutePattern[]
444
+ */
445
+ getCompiledPatterns(): IRoutePattern[];
446
+ }
447
+
448
+ type CreateStatsMiddlewareResponseType = (req: Request, res: Response, next: NextFunction) => TCreateStatsMiddlewareResponse;
449
+
450
+ type CreateClearMiddlewareResponseType = (req: Request, res: Response, next: NextFunction) => Promise<Response<any, Record<string, any>> | undefined>;
451
+
452
+ /**
453
+ *
454
+ */
455
+ declare class SCacheMiddleware {
456
+ /**
457
+ * Create and configure a complete caching service
458
+ *
459
+ * @param customConfig - Custom configuration (optional)
460
+ * @returns CacheService - Cache service configured
461
+ */
462
+ static cacheService(customConfig?: Partial<any>): CacheService;
463
+ /**
464
+ * Creates an Express middleware for automatic caching
465
+ *
466
+ * @param customConfig - Custom configuration (optional)
467
+ * @returns Express middleware configured
468
+ */
469
+ static cacheMiddleware(customConfig?: Partial<any>): TCreateMiddlewareResponseType;
470
+ /**
471
+ * Creates a middleware for cache statistics
472
+ *
473
+ * @returns Middleware Express
474
+ */
475
+ static createStatsMiddleware(): CreateStatsMiddlewareResponseType;
476
+ /**
477
+ * Create a middleware to clear the cache
478
+ *
479
+ * @returns Middleware Express
480
+ */
481
+ static createClearMiddleware(): CreateClearMiddlewareResponseType;
482
+ }
483
+
484
+ interface HttpCacheStats {
485
+ totalRequests: number;
486
+ cacheHits: number;
487
+ cacheMisses: number;
488
+ cacheSize: number;
489
+ hitRate: number;
490
+ cachedUrls: string[];
491
+ timestamp: string;
492
+ enabled: boolean;
493
+ }
494
+
495
+ /**
496
+ * Interface de base pour les options de cache
497
+ * Peut être étendue par différents types de cache
498
+ */
499
+ interface BaseCacheOptions {
500
+ /** Durée de vie en millisecondes */
501
+ timeToLive?: number;
502
+ /** Activer/désactiver le cache */
503
+ enabled?: boolean;
504
+ /** Stratégie de cache */
505
+ strategy?: string;
506
+ /** Clé personnalisée */
507
+ customKey?: string;
508
+ }
509
+
510
+ interface HttpCacheOptions extends BaseCacheOptions {
511
+ bypassCache?: boolean;
512
+ customKey?: string;
513
+ namespace?: string;
514
+ }
515
+
516
+ interface IHttpCacheService {
517
+ /**
518
+ * Execute une requête GET avec cache
519
+ */
520
+ getWithCache<T>(url: string, options?: RequestInit, cacheOptions?: HttpCacheOptions): Promise<T & {
521
+ _metadata: any;
522
+ }>;
523
+ /**
524
+ * Execute une requête POST avec mise en cache optionnelle
525
+ */
526
+ postWithCache<T>(url: string, data: any, options?: RequestInit, cacheResponse?: boolean, cacheOptions?: HttpCacheOptions): Promise<T>;
527
+ /**
528
+ * Invalide le cache pour une URL spécifique ou un pattern
529
+ */
530
+ invalidateCache(urlOrPattern: string): Promise<number>;
531
+ /**
532
+ * Vide complètement le cache HTTP
533
+ */
534
+ clearHttpCache(): Promise<void>;
535
+ /**
536
+ * Récupère les statistiques du cache HTTP
537
+ */
538
+ getStats(): Promise<HttpCacheStats>;
539
+ /**
540
+ *
541
+ */
542
+ isEnabled(): boolean;
543
+ }
544
+
545
+ type HttpClientType = "fetch" | "node-http" | "axios" | "curl";
546
+
547
+ declare class HttpCacheFactory {
548
+ private static instances;
549
+ static create(appName?: string, config?: {
550
+ namespace?: string;
551
+ localLang?: string;
552
+ storageType?: "memory" | "disk" | "hybrid";
553
+ diskDir?: string;
554
+ maxSize?: number;
555
+ defaultTTL?: number;
556
+ clientType?: HttpClientType;
557
+ clientOptions?: any;
558
+ }): IHttpCacheService;
559
+ static createFromExistingCache(cacheService: any, namespace?: string): IHttpCacheService;
560
+ static destroy(appName?: string, clientType?: HttpClientType): void;
561
+ }
562
+
563
+ /**
564
+ * Represents a cache entry with its metadata
565
+ * @template T - Type of the stored value
566
+ */
567
+ interface CacheEntry<T = any> {
568
+ /** Unique key identifying the entry */
569
+ key: string;
570
+ /** Value stored in the cache */
571
+ value: T;
572
+ /** Time to live in milliseconds */
573
+ timeToLive: number;
574
+ /** Creation timestamp in milliseconds */
575
+ createdAt: number;
576
+ /** Expiration timestamp in milliseconds */
577
+ expiresAt: number;
578
+ /** Number of accesses to this entry (for LFU) */
579
+ accessCount: number;
580
+ /** Last access timestamp (for LRU) */
581
+ lastAccessedAt: number;
582
+ }
583
+
584
+ /**
585
+ * Default export object with all features
586
+ */
587
+ declare const _default: {
588
+ SCacheMiddleware: typeof SCacheMiddleware;
589
+ CacheService: typeof CacheService;
590
+ CacheMiddleware: typeof CacheMiddleware;
591
+ CacheFactoryRepository: typeof CacheFactoryRepository;
592
+ RouteValidator: typeof RouteValidator;
593
+ EnvironmentLoader: typeof EnvironmentLoader;
594
+ HttpCacheFactory: typeof HttpCacheFactory;
595
+ };
596
+
597
+ export { type CacheEntry, type ICacheRepository, type IHttpCacheService, _default as default };