@nestjs-redisx/cache 1.0.2 → 1.0.4
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.
- package/dist/cache.plugin.d.ts +1 -1
- package/dist/cache.plugin.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/constants/index.ts","../src/cache/api/decorators/cached.decorator.ts","../src/invalidation/infrastructure/decorators/invalidate-on.decorator.ts","../src/cache/application/services/cache-decorator-initializer.service.ts","../src/shared/errors/index.ts","../src/cache/domain/value-objects/cache-entry.vo.ts","../src/cache/domain/value-objects/cache-key.vo.ts","../src/cache/domain/value-objects/tag.vo.ts","../src/cache/domain/value-objects/tags.vo.ts","../src/cache/domain/value-objects/ttl.vo.ts","../src/cache/application/services/cache.service.ts","../src/cache/application/services/warmup.service.ts","../src/cache/domain/services/serializer.service.ts","../src/cache/infrastructure/adapters/l1-memory-store.adapter.ts","../src/cache/infrastructure/adapters/l2-redis-store.adapter.ts","../src/cache.service.ts","../src/invalidation/application/services/event-invalidation.service.ts","../src/invalidation/application/services/invalidation-registry.service.ts","../src/invalidation/domain/value-objects/event-pattern.vo.ts","../src/invalidation/domain/value-objects/tag-template.vo.ts","../src/invalidation/domain/entities/invalidation-rule.entity.ts","../src/invalidation/infrastructure/adapters/amqp-event-source.adapter.ts","../src/stampede/infrastructure/stampede-protection.service.ts","../src/swr/infrastructure/swr-manager.service.ts","../src/tags/infrastructure/repositories/tag-index.repository.ts","../src/tags/infrastructure/scripts/lua-scripts.ts","../src/tags/infrastructure/services/lua-script-loader.service.ts","../src/cache.plugin.ts","../src/cache/api/decorators/invalidate-tags.decorator.ts","../src/decorators/cacheable.decorator.ts","../src/decorators/cache-put.decorator.ts","../src/decorators/cache-evict.decorator.ts","../src/decorators/key-generator.util.ts","../src/decorators/cache.interceptor.ts","../src/strategies/lru.strategy.ts","../src/strategies/fifo.strategy.ts","../src/strategies/lfu.strategy.ts","../src/serializers/json.serializer.ts","../src/serializers/msgpack.serializer.ts","../src/key-builder.ts"],"names":["Logger","Injectable","Optional","RedisXError","ErrorCode","Inject","REDIS_DRIVER","CacheService","EventInvalidationService","EventEmitter","createHash","InvalidationRegistryService","Reflector","logger","SetMetadata","CacheInterceptor","from","switchMap","of","tap"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Shared constants for Cache plugin.\n */\n\n/**\n * Injection tokens.\n */\nexport const CACHE_PLUGIN_OPTIONS = Symbol.for('CACHE_PLUGIN_OPTIONS');\nexport const CACHE_SERVICE = Symbol.for('CACHE_SERVICE');\nexport const L1_CACHE_STORE = Symbol.for('L1_CACHE_STORE');\nexport const L2_CACHE_STORE = Symbol.for('L2_CACHE_STORE');\nexport const STAMPEDE_PROTECTION = Symbol.for('STAMPEDE_PROTECTION');\nexport const TAG_INDEX = Symbol.for('TAG_INDEX');\nexport const SWR_MANAGER = Symbol.for('SWR_MANAGER');\nexport const TAG_CONFIG = Symbol.for('TAG_CONFIG');\nexport const SERIALIZER = Symbol.for('SERIALIZER');\nexport const INVALIDATION_REGISTRY = Symbol.for('INVALIDATION_REGISTRY');\nexport const EVENT_INVALIDATION_SERVICE = Symbol.for('EVENT_INVALIDATION_SERVICE');\nexport const LUA_SCRIPT_LOADER = Symbol.for('LUA_SCRIPT_LOADER');\nexport const INVALIDATION_RULES_INIT = Symbol.for('INVALIDATION_RULES_INIT');\nexport const AMQP_CONNECTION = Symbol.for('AMQP_CONNECTION');\n\n/**\n * Metadata keys for decorators.\n */\nexport const CACHE_OPTIONS_KEY = 'cache:options';\nexport const INVALIDATE_TAGS_KEY = 'cache:invalidate:tags';\n\n/**\n * Default configuration values.\n */\nexport const DEFAULT_CACHE_CONFIG = {\n l1: {\n enabled: true,\n maxSize: 1000,\n ttl: 60,\n evictionPolicy: 'lru' as const,\n },\n l2: {\n enabled: true,\n defaultTtl: 3600,\n maxTtl: 86400,\n keyPrefix: 'cache:',\n clientName: 'default',\n },\n stampede: {\n enabled: true,\n lockTimeout: 5000,\n waitTimeout: 10000,\n fallback: 'load' as const,\n },\n swr: {\n enabled: false,\n defaultStaleTime: 60,\n },\n tags: {\n enabled: true,\n indexPrefix: '_tag:',\n maxTagsPerKey: 10,\n },\n warmup: {\n enabled: false,\n concurrency: 10,\n },\n keys: {\n maxLength: 1024,\n version: 'v1',\n separator: ':',\n },\n invalidation: {\n enabled: true,\n source: 'internal' as const,\n deduplicationTtl: 60,\n },\n} as const;\n","/**\n * @Cached decorator for method-level caching.\n *\n * Uses immediate proxy-based wrapping (not deferred to module init).\n * Works on ANY Injectable class methods (services, repositories, etc).\n */\n\nimport { Logger } from '@nestjs/common';\nimport 'reflect-metadata';\nimport { CACHE_OPTIONS_KEY } from '../../../shared/constants';\n\nconst logger = new Logger('Cached');\n\n/**\n * Cache service interface for decorator use.\n * Minimal subset of ICacheService needed by decorators.\n */\ninterface IDecoratorCacheService {\n get<T>(key: string): Promise<T | null>;\n set<T>(\n key: string,\n value: T,\n options?: {\n ttl?: number;\n tags?: string[];\n strategy?: 'l1-only' | 'l2-only' | 'l1-l2';\n },\n ): Promise<void>;\n getOrSet<T>(\n key: string,\n loader: () => Promise<T>,\n options?: {\n ttl?: number;\n tags?: string[];\n strategy?: 'l1-only' | 'l2-only' | 'l1-l2';\n swr?: { enabled?: boolean; staleTime?: number };\n unless?: (result: unknown) => boolean;\n },\n ): Promise<T>;\n invalidateTags(tags: string[]): Promise<number>;\n deleteMany(keys: string[]): Promise<number>;\n}\n\n/**\n * Context provider interface for decorator use.\n */\ninterface IDecoratorContextProvider {\n get<T = unknown>(key: string): T | undefined;\n}\n\n/**\n * Plugin options subset needed by decorators for context enrichment.\n */\ninterface IDecoratorPluginOptions {\n contextProvider?: IDecoratorContextProvider;\n contextKeys?: string[];\n keys?: {\n separator?: string;\n };\n}\n\n// Global service registry for lazy injection\nlet globalCacheServiceGetter: (() => IDecoratorCacheService) | null = null;\nlet globalPluginOptions: IDecoratorPluginOptions | null = null;\n\n/**\n * Register cache service getter for lazy injection.\n * Called by CacheDecoratorInitializerService during initialization.\n */\nexport function registerCacheServiceGetter(getter: () => IDecoratorCacheService): void {\n globalCacheServiceGetter = getter;\n}\n\n/**\n * Register plugin options for context enrichment in decorators.\n * Called by CacheDecoratorInitializerService during initialization.\n */\nexport function registerCachePluginOptions(options: IDecoratorPluginOptions): void {\n globalPluginOptions = options;\n}\n\n/**\n * Get the registered cache service.\n * Used by other cache decorators (@InvalidateTags, etc.)\n */\nexport function getCacheService(): IDecoratorCacheService | null {\n return globalCacheServiceGetter ? globalCacheServiceGetter() : null;\n}\n\nexport interface ICachedOptions {\n /**\n * Cache key template. Use {0}, {1}, etc. for method arguments.\n * Example: 'user:{0}' for first argument.\n *\n * If omitted, key is auto-generated as `ClassName:methodName:args`.\n */\n key?: string;\n\n /**\n * TTL in seconds. Defaults to plugin's defaultTtl.\n */\n ttl?: number;\n\n /**\n * Tags for invalidation. Can be static array or function of args.\n */\n tags?: string[] | ((...args: unknown[]) => string[]);\n\n /**\n * Cache strategy: where to store the cached value.\n * - 'l1-only': Only in-memory cache\n * - 'l2-only': Only Redis cache\n * - 'l1-l2': Both layers (default)\n */\n strategy?: 'l1-only' | 'l2-only' | 'l1-l2';\n\n /**\n * Condition to check BEFORE method execution.\n * If returns false, skip caching and execute method.\n */\n condition?: (...args: unknown[]) => boolean;\n\n /**\n * Condition to check AFTER method execution.\n * If returns true, don't cache the result.\n */\n unless?: (result: unknown, ...args: unknown[]) => boolean;\n\n /**\n * Additional context keys to vary cache by.\n * Values are resolved from contextProvider at call time.\n * Adds to (not replaces) global contextKeys.\n *\n * Works on any Injectable — values come from contextProvider (CLS, AsyncLocalStorage, etc.),\n * not from HTTP headers. Ignored if contextProvider is not configured.\n *\n * @example\n * ```typescript\n * @Cached({\n * key: 'products',\n * varyBy: ['locale', 'currency'] // resolved from contextProvider\n * })\n * ```\n */\n varyBy?: string[];\n\n /**\n * Stale-while-revalidate configuration.\n * If enabled, serves stale data while revalidating in background.\n */\n swr?: {\n enabled?: boolean;\n staleTime?: number;\n };\n\n /**\n * Context keys to include in cache key (from contextProvider).\n * Overrides global contextKeys for this method.\n */\n contextKeys?: string[];\n\n /**\n * Disable context enrichment for this method.\n * Set to true to prevent automatic context keys from being added.\n *\n * @default false\n */\n skipContext?: boolean;\n}\n\n/**\n * Caches method return value using immediate proxy-based wrapping.\n *\n * Works on any Injectable class method, not just controllers.\n * Wrapping happens immediately when decorator is applied.\n *\n * @example\n * ```typescript\n * @Injectable()\n * class UserService {\n * @Cached({ key: 'user:{0}', ttl: 3600, tags: ['users'] })\n * async getUser(id: string): Promise<User> {\n * return this.userRepository.findById(id);\n * }\n * }\n * ```\n */\nexport function Cached(options: ICachedOptions = {}): MethodDecorator {\n return (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n const originalMethod = descriptor.value as (...args: unknown[]) => Promise<unknown>;\n\n // Replace method with caching proxy\n descriptor.value = async function (...args: unknown[]): Promise<unknown> {\n // Lazy inject cache service on first call\n if (!globalCacheServiceGetter) {\n logger.warn(`@Cached: CacheService not yet available, executing method without cache`);\n return originalMethod.apply(this, args);\n }\n\n const cacheService = globalCacheServiceGetter();\n if (!cacheService) {\n logger.warn(`@Cached: CacheService getter returned null, executing method without cache`);\n return originalMethod.apply(this, args);\n }\n\n // Check condition (before execution) — if false, bypass cache entirely\n if (options.condition && !options.condition(...args)) {\n return originalMethod.apply(this, args);\n }\n\n // Build cache key with context enrichment\n const key = buildCacheKey(this, propertyKey.toString(), args, options);\n\n // Resolve tags (static array or function of args)\n const tags = typeof options.tags === 'function' ? options.tags(...args) : options.tags;\n\n // Delegate to getOrSet — stampede protection is handled internally\n try {\n return await cacheService.getOrSet(key, () => originalMethod.apply(this, args), {\n ttl: options.ttl,\n tags,\n strategy: options.strategy,\n swr: options.swr,\n unless: options.unless ? (result: unknown) => options.unless!(result, ...args) : undefined,\n });\n } catch (error) {\n logger.error(`@Cached: getOrSet error for key ${key}:`, error);\n // Fail-open: execute method without cache\n return originalMethod.apply(this, args);\n }\n };\n\n // Preserve original method name\n Object.defineProperty(descriptor.value, 'name', {\n value: originalMethod.name,\n writable: false,\n });\n\n // Store metadata on WRAPPER function for reflection (after replacement)\n Reflect.defineMetadata(CACHE_OPTIONS_KEY, options, descriptor.value);\n\n return descriptor;\n };\n}\n\n/**\n * Builds cache key from template and arguments, then enriches with context.\n *\n * Key pipeline:\n * 1. Base key: from template ({0}, {1}) or auto-generated (Class:method:args)\n * 2. Context enrichment: contextKeys + varyBy resolved from contextProvider\n * Format: `baseKey:_ctx_:key1.val1:key2.val2`\n */\nfunction buildCacheKey(instance: object, methodName: string, args: unknown[], options: ICachedOptions): string {\n const className = (instance.constructor as { name: string }).name;\n\n // Step 1: Build base key\n let baseKey: string;\n if (options.key) {\n baseKey = interpolateKey(options.key, args);\n } else {\n const argKeys = args.map((arg) => serializeArg(arg)).join(':');\n baseKey = `${className}:${methodName}:${argKeys}`;\n }\n\n // Step 2: Enrich with context (contextKeys + varyBy)\n return enrichWithContext(baseKey, options);\n}\n\n/**\n * Enriches a base key with context values from contextProvider.\n * Uses the same _ctx_ marker format as the internal cache service\n * so enrichKeyWithContext() won't double-enrich.\n */\nfunction enrichWithContext(key: string, options: ICachedOptions): string {\n // Skip if explicitly disabled\n if (options.skipContext) return key;\n\n const pluginOpts = globalPluginOptions;\n if (!pluginOpts?.contextProvider) return key;\n\n const separator = pluginOpts.keys?.separator ?? ':';\n const marker = `${separator}_ctx_${separator}`;\n\n const contextMap = new Map<string, string>();\n\n // Determine which context keys to use:\n // - Per-decorator contextKeys override global ones\n // - varyBy adds additional keys on top\n const contextKeys = options.contextKeys ?? pluginOpts.contextKeys ?? [];\n\n // Resolve context keys from provider\n for (const ctxKey of contextKeys) {\n const value = pluginOpts.contextProvider.get<string>(ctxKey);\n if (value !== undefined && value !== null) {\n if (typeof value === 'object') {\n logger.warn(`Context key \"${ctxKey}\" has object value, skipping (use primitives for context keys)`);\n continue;\n }\n contextMap.set(ctxKey, String(value));\n }\n }\n\n // Resolve varyBy keys from provider (additional to contextKeys)\n if (options.varyBy) {\n for (const name of options.varyBy) {\n if (!contextMap.has(name)) {\n const value = pluginOpts.contextProvider.get<string>(name);\n if (value !== undefined && value !== null) {\n if (typeof value === 'object') {\n logger.warn(`varyBy key \"${name}\" has object value, skipping (use primitives for varyBy keys)`);\n continue;\n }\n contextMap.set(name, String(value));\n }\n }\n }\n }\n\n if (contextMap.size === 0) return key;\n\n // Sort for consistent key ordering\n const sortedEntries = [...contextMap.entries()].sort(([a], [b]) => a.localeCompare(b));\n const suffix = sortedEntries.map(([k, v]) => `${sanitizeForKey(k)}.${sanitizeForKey(v)}`).join(separator);\n\n return `${key}${marker}${suffix}`;\n}\n\n/**\n * Sanitizes a value for use in cache key (removes non-allowed characters).\n */\nfunction sanitizeForKey(value: string): string {\n return String(value).replace(/[^a-zA-Z0-9\\-_]/g, '_');\n}\n\n/**\n * Interpolates key template with arguments.\n */\nfunction interpolateKey(template: string, args: unknown[]): string {\n return template.replace(/\\{(\\d+)}/g, (match, index: string) => {\n const argIndex = parseInt(index, 10);\n if (argIndex < args.length) {\n return serializeArg(args[argIndex]);\n }\n return match;\n });\n}\n\n/**\n * Serializes argument to string for cache key.\n * Objects are serialized with sorted keys for deterministic output.\n */\nfunction serializeArg(arg: unknown): string {\n if (arg === null || arg === undefined) {\n return 'null';\n }\n\n if (typeof arg === 'string' || typeof arg === 'number' || typeof arg === 'boolean') {\n return String(arg);\n }\n\n if (typeof arg === 'object') {\n try {\n return stableStringify(arg);\n } catch {\n return 'object';\n }\n }\n\n return 'unknown';\n}\n\n/**\n * Produces a deterministic JSON string by sorting object keys recursively.\n * Ensures {b:2, a:1} and {a:1, b:2} produce the same cache key.\n */\nfunction stableStringify(value: unknown): string {\n if (value === null || value === undefined) {\n return 'null';\n }\n\n // Functions and symbols are not serializable (matches JSON.stringify behavior)\n if (typeof value === 'function' || typeof value === 'symbol') {\n return 'null';\n }\n\n if (typeof value !== 'object') {\n // BigInt throws in JSON.stringify; convert to string for safe key generation\n if (typeof value === 'bigint') {\n return String(value);\n }\n return JSON.stringify(value);\n }\n\n // Arrays: preserve order, serialize undefined/functions as null (matches JSON.stringify)\n if (Array.isArray(value)) {\n return '[' + value.map((item) => (item === undefined || typeof item === 'function' || typeof item === 'symbol' ? 'null' : stableStringify(item))).join(',') + ']';\n }\n\n if (value instanceof Date) {\n return JSON.stringify(value);\n }\n\n // Plain objects: sort keys, skip undefined/function/symbol values (matches JSON.stringify)\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n const parts: string[] = [];\n for (const key of keys) {\n const v = obj[key];\n if (v === undefined || typeof v === 'function' || typeof v === 'symbol') {\n continue; // JSON.stringify skips these in objects\n }\n parts.push(JSON.stringify(key) + ':' + stableStringify(v));\n }\n return '{' + parts.join(',') + '}';\n}\n","/**\n * @InvalidateOn decorator.\n * Automatically invalidates cache after method execution based on events.\n *\n * Uses immediate proxy-based wrapping (not deferred to interceptor).\n * Works on ANY Injectable class methods (services, repositories, etc).\n */\n\nimport 'reflect-metadata';\nimport { getCacheService } from '../../../cache/api/decorators/cached.decorator';\n\nexport const INVALIDATE_ON_OPTIONS = Symbol.for('INVALIDATE_ON_OPTIONS');\n\n/**\n * Event invalidation service interface for decorator use.\n */\ninterface IDecoratorEventInvalidationService {\n emit(event: string, payload: unknown): Promise<void>;\n}\n\n// Global service registry for lazy injection (similar to getCacheService pattern)\nlet globalEventInvalidationServiceGetter: (() => IDecoratorEventInvalidationService) | null = null;\n\n/**\n * Register event invalidation service getter for lazy injection.\n * Called by CacheDecoratorInitializerService during initialization.\n */\nexport function registerEventInvalidationServiceGetter(getter: () => IDecoratorEventInvalidationService): void {\n globalEventInvalidationServiceGetter = getter;\n}\n\n/**\n * Get the registered event invalidation service.\n */\nexport function getEventInvalidationService(): IDecoratorEventInvalidationService | null {\n return globalEventInvalidationServiceGetter ? globalEventInvalidationServiceGetter() : null;\n}\n\nexport interface IInvalidateOnOptions {\n /** Events that trigger invalidation */\n events: string[];\n\n /** Tags to invalidate */\n tags?: string[] | ((result: unknown, args: unknown[]) => string[]);\n\n /** Keys to invalidate */\n keys?: string[] | ((result: unknown, args: unknown[]) => string[]);\n\n /** Condition - only invalidate if returns true */\n condition?: (result: unknown, args: unknown[]) => boolean;\n\n /** Publish event after method execution (for distributed invalidation) */\n publish?: boolean;\n}\n\n/**\n * Decorator that invalidates cache after method execution.\n *\n * Works on any Injectable class method, not just controllers.\n *\n * @param options - Invalidation options\n *\n * @example\n * ```typescript\n * @Injectable()\n * class UserService {\n * @InvalidateOn({\n * events: ['user.updated'],\n * tags: (result, [userId]) => [`user:${userId}`, 'users'],\n * })\n * async updateUser(userId: string, data: UpdateUserDto): Promise<User> {\n * return this.userRepo.update(userId, data);\n * }\n *\n * @InvalidateOn({\n * events: ['user.deleted'],\n * keys: (result, [userId]) => [`user:${userId}`],\n * tags: ['users'],\n * })\n * async deleteUser(userId: string): Promise<void> {\n * await this.userRepo.delete(userId);\n * }\n * }\n * ```\n */\nexport function InvalidateOn(options: IInvalidateOnOptions): MethodDecorator {\n return (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n const originalMethod = descriptor.value as (...args: unknown[]) => Promise<unknown>;\n\n // Replace method with invalidation proxy\n descriptor.value = async function (...args: unknown[]): Promise<unknown> {\n // Execute original method first\n const result = await originalMethod.apply(this, args);\n\n // Get cache service for invalidation\n const cacheService = getCacheService();\n\n if (cacheService) {\n try {\n // Check condition\n if (options.condition && !options.condition(result, args)) {\n return result;\n }\n\n // Resolve tags\n const tags = resolveTags(options.tags, result, args);\n\n // Resolve keys\n const keys = resolveKeys(options.keys, result, args);\n\n // Perform invalidation\n if (tags.length > 0) {\n await cacheService.invalidateTags(tags);\n }\n\n if (keys.length > 0) {\n await cacheService.deleteMany(keys);\n }\n\n // Publish event for distributed invalidation\n if (options.publish) {\n const eventInvalidationService = getEventInvalidationService();\n if (eventInvalidationService) {\n // Emit events with result as payload for distributed invalidation\n for (const event of options.events) {\n await eventInvalidationService.emit(event, {\n result,\n args,\n tags,\n keys,\n timestamp: Date.now(),\n });\n }\n }\n }\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('@InvalidateOn: Invalidation failed:', error);\n // Don't propagate error - method already succeeded\n }\n }\n\n return result;\n };\n\n // Preserve original method name\n Object.defineProperty(descriptor.value, 'name', {\n value: originalMethod.name,\n writable: false,\n });\n\n // Store metadata on WRAPPER function for reflection (after replacement)\n Reflect.defineMetadata(INVALIDATE_ON_OPTIONS, options, descriptor.value);\n\n return descriptor;\n };\n}\n\n/**\n * Resolve tags from options.\n */\nfunction resolveTags(tags: string[] | ((result: unknown, args: unknown[]) => string[]) | undefined, result: unknown, args: unknown[]): string[] {\n if (!tags) {\n return [];\n }\n\n if (typeof tags === 'function') {\n return tags(result, args);\n }\n\n return tags;\n}\n\n/**\n * Resolve keys from options.\n */\nfunction resolveKeys(keys: string[] | ((result: unknown, args: unknown[]) => string[]) | undefined, result: unknown, args: unknown[]): string[] {\n if (!keys) {\n return [];\n }\n\n if (typeof keys === 'function') {\n return keys(result, args);\n }\n\n return keys;\n}\n","/**\n * Service for initializing @Cached decorator with lazy cache service injection.\n *\n * Runs on module initialization and registers a getter function that provides\n * access to CacheService for the @Cached decorator's proxy logic.\n */\n\nimport { Injectable, OnModuleInit, Inject, Logger, Optional } from '@nestjs/common';\nimport { ModuleRef } from '@nestjs/core';\n\nimport { IEventInvalidationService } from '../../../invalidation/application/ports/event-invalidation.port';\nimport { registerEventInvalidationServiceGetter } from '../../../invalidation/infrastructure/decorators/invalidate-on.decorator';\nimport { CACHE_SERVICE, CACHE_PLUGIN_OPTIONS, EVENT_INVALIDATION_SERVICE } from '../../../shared/constants';\nimport { ICachePluginOptions } from '../../../shared/types';\nimport { registerCacheServiceGetter, registerCachePluginOptions } from '../../api/decorators/cached.decorator';\nimport { ICacheService } from '../ports/cache-service.port';\n\n@Injectable()\nexport class CacheDecoratorInitializerService implements OnModuleInit {\n private readonly logger = new Logger(CacheDecoratorInitializerService.name);\n\n constructor(\n private readonly moduleRef: ModuleRef,\n @Inject(CACHE_SERVICE) private readonly cacheService: ICacheService,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly pluginOptions: ICachePluginOptions,\n @Optional() @Inject(EVENT_INVALIDATION_SERVICE) private readonly eventInvalidationService?: IEventInvalidationService,\n ) {}\n\n /**\n * Called after all modules are initialized.\n * Registers cache service getter and plugin options for @Cached decorator.\n */\n // eslint-disable-next-line @typescript-eslint/require-await\n async onModuleInit(): Promise<void> {\n this.logger.debug('Registering CacheService getter for @Cached decorator');\n\n // Register getter that provides cache service to decorator\n registerCacheServiceGetter(() => this.cacheService);\n\n // Register plugin options for context enrichment in decorators\n registerCachePluginOptions(this.pluginOptions);\n\n this.logger.log('@Cached decorator initialized and ready to use');\n\n // Register event invalidation service getter for @InvalidateOn decorator\n if (this.eventInvalidationService) {\n this.logger.debug('Registering EventInvalidationService getter for @InvalidateOn decorator');\n registerEventInvalidationServiceGetter(() => this.eventInvalidationService!);\n this.logger.log('@InvalidateOn decorator event publishing initialized');\n }\n }\n}\n","/**\n * Cache plugin error classes.\n */\n\nimport { RedisXError, ErrorCode } from '@nestjs-redisx/core';\n\n/**\n * Base error for cache operations.\n */\nexport class CacheError extends RedisXError {\n constructor(message: string, code: ErrorCode = ErrorCode.OPERATION_FAILED, cause?: Error) {\n super(message, code, cause);\n this.name = 'CacheError';\n }\n}\n\n/**\n * Error for invalid cache keys.\n */\nexport class CacheKeyError extends CacheError {\n constructor(\n public readonly key: string,\n message: string,\n ) {\n super(`Invalid cache key \"${key}\": ${message}`, ErrorCode.CACHE_KEY_INVALID);\n this.name = 'CacheKeyError';\n }\n}\n\n/**\n * Error for serialization failures.\n */\nexport class SerializationError extends CacheError {\n constructor(message: string, cause?: Error) {\n super(`Serialization error: ${message}`, ErrorCode.SERIALIZATION_FAILED, cause);\n this.name = 'SerializationError';\n }\n}\n\n/**\n * Error for loader function failures.\n */\nexport class LoaderError extends CacheError {\n constructor(\n public readonly key: string,\n cause: Error,\n ) {\n super(`Loader failed for key \"${key}\": ${cause.message}`, ErrorCode.OPERATION_FAILED, cause);\n this.name = 'LoaderError';\n }\n}\n\n/**\n * Error for stampede protection timeout.\n */\nexport class StampedeError extends CacheError {\n constructor(\n public readonly key: string,\n public readonly timeout: number,\n ) {\n super(`Stampede protection timeout for key \"${key}\" after ${timeout}ms`, ErrorCode.OPERATION_TIMEOUT);\n this.name = 'StampedeError';\n }\n}\n\n/**\n * Error for tag invalidation failures.\n */\nexport class TagInvalidationError extends CacheError {\n constructor(\n public readonly tag: string,\n message: string,\n cause?: Error,\n ) {\n super(`Tag invalidation failed for \"${tag}\": ${message}`, ErrorCode.OPERATION_FAILED, cause);\n this.name = 'TagInvalidationError';\n }\n}\n","/**\n * CacheEntry value object.\n * Wraps cached value with metadata.\n */\n\nexport class CacheEntry<T> {\n private constructor(\n public readonly value: T,\n public readonly cachedAt: number,\n public readonly ttl: number,\n public readonly tags?: string[],\n ) {}\n\n /**\n * Creates a cache entry.\n *\n * @param value - Value to cache\n * @param ttl - TTL in seconds\n * @param tags - Optional tags\n * @returns CacheEntry instance\n */\n static create<T>(value: T, ttl: number, tags?: string[]): CacheEntry<T> {\n return new CacheEntry(value, Date.now(), ttl, tags);\n }\n\n /**\n * Checks if entry is expired.\n *\n * @returns true if expired, false otherwise\n */\n isExpired(): boolean {\n const expiresAt = this.cachedAt + this.ttl * 1000;\n return Date.now() > expiresAt;\n }\n\n /**\n * Gets time until expiration in milliseconds.\n *\n * @returns Milliseconds until expiration (0 if expired)\n */\n getTimeToLive(): number {\n const expiresAt = this.cachedAt + this.ttl * 1000;\n const remaining = expiresAt - Date.now();\n return Math.max(0, remaining);\n }\n\n /**\n * Gets age of entry in milliseconds.\n *\n * @returns Age in milliseconds\n */\n getAge(): number {\n return Date.now() - this.cachedAt;\n }\n\n /**\n * Checks if entry has a specific tag.\n *\n * @param tag - Tag to check\n * @returns true if entry has the tag\n */\n hasTag(tag: string): boolean {\n return this.tags?.includes(tag) ?? false;\n }\n\n /**\n * Serializes entry to JSON.\n *\n * @returns JSON representation\n */\n toJSON(): {\n value: T;\n cachedAt: number;\n ttl: number;\n tags?: string[];\n } {\n return {\n value: this.value,\n cachedAt: this.cachedAt,\n ttl: this.ttl,\n tags: this.tags,\n };\n }\n\n /**\n * Deserializes entry from JSON.\n *\n * @param json - JSON representation\n * @returns CacheEntry instance\n */\n static fromJSON<T>(json: { value: T; cachedAt: number; ttl: number; tags?: string[] }): CacheEntry<T> {\n return new CacheEntry(json.value, json.cachedAt, json.ttl, json.tags);\n }\n}\n","/**\n * CacheKey value object.\n * Validates and builds cache keys with prefix, version, and validation.\n */\n\nimport { CacheKeyError } from '../../../shared/errors';\n\nexport interface ICacheKeyOptions {\n maxLength?: number;\n prefix?: string;\n version?: string;\n separator?: string;\n}\n\nconst DEFAULT_OPTIONS: Required<ICacheKeyOptions> = {\n maxLength: 512,\n prefix: '',\n version: '',\n separator: ':',\n};\n\nexport class CacheKey {\n private constructor(\n private readonly rawKey: string,\n private readonly options: Required<ICacheKeyOptions>,\n ) {}\n\n /**\n * Creates a validated cache key.\n *\n * @param key - Raw key\n * @param options - Key options\n * @returns CacheKey instance\n * @throws CacheKeyError if validation fails\n */\n static create(key: string, options: ICacheKeyOptions = {}): CacheKey {\n const opts: Required<ICacheKeyOptions> = {\n ...DEFAULT_OPTIONS,\n ...options,\n };\n\n // Normalize: trim whitespace\n const normalizedKey = key.trim();\n\n // Validate key is not empty\n if (!normalizedKey || normalizedKey.length === 0) {\n throw new CacheKeyError(key, 'Key cannot be empty');\n }\n\n // Validate no whitespace\n if (/\\s/.test(normalizedKey)) {\n throw new CacheKeyError(key, 'Key cannot contain whitespace');\n }\n\n // Validate allowed characters (alphanumeric, -, _, :, .)\n if (!/^[a-zA-Z0-9\\-_:.]+$/.test(normalizedKey)) {\n throw new CacheKeyError(key, 'Invalid characters in key. Only alphanumeric, hyphens, underscores, colons, and dots allowed');\n }\n\n // Build full key\n const fullKey = opts.prefix + opts.version + (opts.version ? opts.separator : '') + normalizedKey;\n\n // Validate length\n if (fullKey.length > opts.maxLength) {\n throw new CacheKeyError(normalizedKey, `Key exceeds maximum length (${fullKey.length} > ${opts.maxLength})`);\n }\n\n return new CacheKey(normalizedKey, opts);\n }\n\n /**\n * Returns the full cache key with prefix and version.\n */\n toString(): string {\n return this.options.prefix + this.options.version + (this.options.version ? this.options.separator : '') + this.rawKey;\n }\n\n /**\n * Returns the raw key without prefix/version.\n */\n getRaw(): string {\n return this.rawKey;\n }\n\n /**\n * Returns the prefix.\n */\n getPrefix(): string {\n return this.options.prefix;\n }\n\n /**\n * Returns the version.\n */\n getVersion(): string {\n return this.options.version;\n }\n\n /**\n * Checks equality with another CacheKey.\n */\n equals(other: CacheKey): boolean {\n return this.toString() === other.toString();\n }\n}\n","/**\n * Tag value object.\n * Validates and normalizes cache tags for invalidation.\n */\n\nimport { ErrorCode } from '@nestjs-redisx/core';\n\nimport { CacheError } from '../../../shared/errors';\n\nconst DEFAULT_MAX_LENGTH = 128;\n\nexport class Tag {\n private constructor(private readonly value: string) {}\n\n /**\n * Creates a validated tag.\n *\n * @param value - Tag value\n * @param maxLength - Maximum tag length (default: 128)\n * @returns Tag instance\n * @throws CacheError if validation fails\n *\n * @example\n * ```typescript\n * const tag = Tag.create('users');\n * const productTag = Tag.create('product:123');\n * ```\n */\n static create(value: string, maxLength: number = DEFAULT_MAX_LENGTH): Tag {\n // Validate not empty\n if (!value || value.length === 0) {\n throw new CacheError('Tag cannot be empty', ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Normalize: trim and lowercase\n const normalized = value.trim().toLowerCase();\n\n // Validate not empty after normalization\n if (normalized.length === 0) {\n throw new CacheError('Tag cannot be empty after normalization', ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Validate no whitespace\n if (/\\s/.test(normalized)) {\n throw new CacheError('Tag cannot contain whitespace', ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Validate allowed characters (alphanumeric, -, _, :, .)\n if (!/^[a-z0-9\\-_:.]+$/.test(normalized)) {\n throw new CacheError('Invalid tag characters. Only lowercase alphanumeric, hyphens, underscores, colons, and dots allowed', ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Validate length\n if (normalized.length > maxLength) {\n throw new CacheError(`Tag exceeds maximum length (${normalized.length} > ${maxLength})`, ErrorCode.CACHE_KEY_INVALID);\n }\n\n return new Tag(normalized);\n }\n\n /**\n * Returns the tag value.\n */\n toString(): string {\n return this.value;\n }\n\n /**\n * Returns the raw tag value.\n */\n getRaw(): string {\n return this.value;\n }\n\n /**\n * Checks equality with another tag.\n */\n equals(other: Tag): boolean {\n return this.value === other.value;\n }\n}\n","/**\n * Tags collection value object.\n * Validates and manages a collection of tags with deduplication.\n */\n\nimport { ErrorCode } from '@nestjs-redisx/core';\n\nimport { Tag } from './tag.vo';\nimport { CacheError } from '../../../shared/errors';\n\nconst DEFAULT_MAX_TAGS = 10;\n\nexport class Tags {\n private constructor(private readonly tags: Tag[]) {}\n\n /**\n * Creates a validated tags collection.\n *\n * @param values - Array of tag values\n * @param maxTags - Maximum number of tags (default: 10)\n * @returns Tags instance\n * @throws CacheError if validation fails\n *\n * @example\n * ```typescript\n * const tags = Tags.create(['users', 'product:123']);\n * const singleTag = Tags.create(['cache']);\n * ```\n */\n static create(values: string[], maxTags: number = DEFAULT_MAX_TAGS): Tags {\n // Validate max tags before processing\n if (values.length > maxTags) {\n throw new CacheError(`Too many tags (${values.length} > ${maxTags})`, ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Convert to Tag objects (validates each tag)\n const tagObjects = values.map((v) => Tag.create(v));\n\n // Remove duplicates by converting to Set and back\n const uniqueValues = Array.from(new Set(tagObjects.map((t) => t.toString())));\n\n // Recreate Tag objects from unique values\n const uniqueTags = uniqueValues.map((v) => Tag.create(v));\n\n return new Tags(uniqueTags);\n }\n\n /**\n * Creates empty tags collection.\n */\n static empty(): Tags {\n return new Tags([]);\n }\n\n /**\n * Returns array of tag strings.\n */\n toStrings(): string[] {\n return this.tags.map((t) => t.toString());\n }\n\n /**\n * Returns array of Tag objects.\n */\n toArray(): Tag[] {\n return [...this.tags];\n }\n\n /**\n * Returns number of tags.\n */\n size(): number {\n return this.tags.length;\n }\n\n /**\n * Checks if collection contains a specific tag.\n */\n has(tag: Tag): boolean {\n return this.tags.some((t) => t.equals(tag));\n }\n\n /**\n * Checks if collection is empty.\n */\n isEmpty(): boolean {\n return this.tags.length === 0;\n }\n\n /**\n * Iterates over tags.\n */\n forEach(callback: (tag: Tag, index: number) => void): void {\n this.tags.forEach(callback);\n }\n\n /**\n * Maps over tags.\n */\n map<T>(callback: (tag: Tag, index: number) => T): T[] {\n return this.tags.map(callback);\n }\n}\n","/**\n * TTL (Time To Live) value object.\n * Validates and normalizes TTL values.\n */\n\nimport { ErrorCode } from '@nestjs-redisx/core';\n\nimport { CacheError } from '../../../shared/errors';\n\n/** Default maximum TTL in seconds (24 hours). */\nconst DEFAULT_MAX_TTL_SECONDS = 86_400;\n\nexport class TTL {\n private constructor(private readonly seconds: number) {}\n\n /**\n * Creates a TTL value object.\n *\n * @param seconds - TTL in seconds\n * @param maxTtl - Maximum allowed TTL\n * @returns TTL instance\n * @throws CacheError if validation fails\n */\n static create(seconds: number, maxTtl: number = DEFAULT_MAX_TTL_SECONDS): TTL {\n // Validate positive\n if (seconds <= 0) {\n throw new CacheError(`TTL must be positive (got ${seconds})`, ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Validate not too large\n if (seconds > maxTtl) {\n throw new CacheError(`TTL exceeds maximum (${seconds} > ${maxTtl})`, ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Round to nearest second\n const rounded = Math.round(seconds);\n\n return new TTL(rounded);\n }\n\n /**\n * Creates TTL from milliseconds.\n *\n * @param milliseconds - TTL in milliseconds\n * @param maxTtl - Maximum allowed TTL in seconds\n * @returns TTL instance\n */\n static fromMilliseconds(milliseconds: number, maxTtl: number = DEFAULT_MAX_TTL_SECONDS): TTL {\n return TTL.create(Math.ceil(milliseconds / 1000), maxTtl);\n }\n\n /**\n * Returns TTL in seconds.\n */\n toSeconds(): number {\n return this.seconds;\n }\n\n /**\n * Returns TTL in milliseconds.\n */\n toMilliseconds(): number {\n return this.seconds * 1000;\n }\n\n /**\n * Checks if TTL is less than another TTL.\n */\n isLessThan(other: TTL): boolean {\n return this.seconds < other.seconds;\n }\n\n /**\n * Checks if TTL is greater than another TTL.\n */\n isGreaterThan(other: TTL): boolean {\n return this.seconds > other.seconds;\n }\n\n /**\n * Returns the minimum of two TTLs.\n */\n static min(a: TTL, b: TTL): TTL {\n return a.isLessThan(b) ? a : b;\n }\n\n /**\n * Returns the maximum of two TTLs.\n */\n static max(a: TTL, b: TTL): TTL {\n return a.isGreaterThan(b) ? a : b;\n }\n\n /**\n * Checks equality with another TTL.\n */\n equals(other: TTL): boolean {\n return this.seconds === other.seconds;\n }\n\n /**\n * Returns string representation.\n */\n toString(): string {\n return `${this.seconds}s`;\n }\n}\n","/**\n * Main cache service implementation.\n * Orchestrates L1/L2 caching with stampede protection, SWR, and tag invalidation.\n */\n\nimport { Injectable, Inject, Logger, Optional } from '@nestjs/common';\nimport { REDIS_DRIVER, IRedisDriver, ErrorCode } from '@nestjs-redisx/core';\n\nimport { L1_CACHE_STORE, L2_CACHE_STORE, STAMPEDE_PROTECTION, TAG_INDEX, SWR_MANAGER, CACHE_PLUGIN_OPTIONS } from '../../../shared/constants';\nimport { CacheError, CacheKeyError } from '../../../shared/errors';\nimport { CacheSetOptions, CacheGetOrSetOptions, CacheStats, ICachePluginOptions } from '../../../shared/types';\nimport { IStampedeProtection } from '../../../stampede/application/ports/stampede-protection.port';\nimport { ISwrManager } from '../../../swr/application/ports/swr-manager.port';\nimport { ITagIndex } from '../../../tags/application/ports/tag-index.port';\nimport { CacheEntry } from '../../domain/value-objects/cache-entry.vo';\nimport { CacheKey } from '../../domain/value-objects/cache-key.vo';\nimport { Tag } from '../../domain/value-objects/tag.vo';\nimport { Tags } from '../../domain/value-objects/tags.vo';\nimport { TTL } from '../../domain/value-objects/ttl.vo';\nimport { ICacheService } from '../ports/cache-service.port';\nimport { IL1CacheStore } from '../ports/l1-cache-store.port';\nimport { IL2CacheStore } from '../ports/l2-cache-store.port';\n\n// Optional metrics integration\nconst METRICS_SERVICE = Symbol.for('METRICS_SERVICE');\n\ninterface IMetricsService {\n incrementCounter(name: string, labels?: Record<string, string>, value?: number): void;\n setGauge(name: string, value: number, labels?: Record<string, string>): void;\n}\n\n// Optional tracing integration\nconst TRACING_SERVICE = Symbol.for('TRACING_SERVICE');\n\ninterface ISpan {\n setAttribute(key: string, value: unknown): this;\n addEvent(name: string, attributes?: Record<string, unknown>): this;\n setStatus(status: 'OK' | 'ERROR'): this;\n recordException(error: Error): this;\n end(): void;\n}\n\ninterface ITracingService {\n startSpan(name: string, options?: { kind?: string; attributes?: Record<string, unknown> }): ISpan;\n}\n\n@Injectable()\nexport class CacheService implements ICacheService {\n private readonly logger = new Logger(CacheService.name);\n private readonly l1Enabled: boolean;\n private readonly l2Enabled: boolean;\n private readonly stampedeEnabled: boolean;\n private readonly swrEnabled: boolean;\n private readonly tagsEnabled: boolean;\n\n private readonly keyPrefix: string;\n\n constructor(\n @Inject(REDIS_DRIVER) private readonly driver: IRedisDriver,\n @Inject(L1_CACHE_STORE) private readonly l1Store: IL1CacheStore,\n @Inject(L2_CACHE_STORE) private readonly l2Store: IL2CacheStore,\n @Inject(STAMPEDE_PROTECTION) private readonly stampede: IStampedeProtection,\n @Inject(TAG_INDEX) private readonly tagIndex: ITagIndex,\n @Inject(SWR_MANAGER) private readonly swrManager: ISwrManager,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly options: ICachePluginOptions,\n @Optional() @Inject(METRICS_SERVICE) private readonly metrics?: IMetricsService,\n @Optional() @Inject(TRACING_SERVICE) private readonly tracing?: ITracingService,\n ) {\n this.l1Enabled = options.l1?.enabled ?? true;\n this.l2Enabled = options.l2?.enabled ?? true;\n this.keyPrefix = options.l2?.keyPrefix ?? 'cache:';\n this.stampedeEnabled = options.stampede?.enabled ?? true;\n this.swrEnabled = options.swr?.enabled ?? false;\n this.tagsEnabled = options.tags?.enabled ?? true;\n }\n\n async get<T>(key: string): Promise<T | null> {\n const span = this.tracing?.startSpan('cache.get', {\n kind: 'INTERNAL',\n attributes: { 'cache.key': key },\n });\n\n try {\n // Validate and normalize key (fail-open on validation error)\n const normalizedKey = this.validateAndNormalizeKey(key);\n const enrichedKey = this.enrichKeyWithContext(normalizedKey);\n\n // Try L1 first\n if (this.l1Enabled) {\n const l1Entry = await this.l1Store.get<T>(enrichedKey);\n if (l1Entry) {\n this.logger.debug(`L1 hit for key: ${key}`);\n this.metrics?.incrementCounter('redisx_cache_hits_total', { layer: 'l1' });\n span?.setAttribute('cache.hit', true);\n span?.setAttribute('cache.layer', 'l1');\n span?.setStatus('OK');\n return l1Entry.value;\n }\n this.metrics?.incrementCounter('redisx_cache_misses_total', { layer: 'l1' });\n }\n\n // Try L2\n if (this.l2Enabled) {\n const l2Entry = await this.l2Store.get<T>(enrichedKey);\n if (l2Entry) {\n this.logger.debug(`L2 hit for key: ${key}`);\n this.metrics?.incrementCounter('redisx_cache_hits_total', { layer: 'l2' });\n span?.setAttribute('cache.hit', true);\n span?.setAttribute('cache.layer', 'l2');\n span?.setStatus('OK');\n\n // Populate L1\n if (this.l1Enabled) {\n await this.l1Store.set(enrichedKey, l2Entry, this.options.l1?.ttl);\n }\n\n return l2Entry.value;\n }\n this.metrics?.incrementCounter('redisx_cache_misses_total', { layer: 'l2' });\n }\n\n span?.setAttribute('cache.hit', false);\n span?.setStatus('OK');\n return null;\n } catch (error) {\n // Fail-open: log and return null (includes validation errors)\n if (error instanceof CacheKeyError) {\n this.logger.warn(`Invalid cache key \"${key}\": ${error.message}`);\n } else {\n this.logger.error(`Cache get failed for key ${key}:`, error);\n }\n span?.recordException(error as Error);\n span?.setStatus('ERROR');\n return null;\n } finally {\n span?.end();\n }\n }\n\n async set<T>(key: string, value: T, options: CacheSetOptions = {}): Promise<void> {\n const span = this.tracing?.startSpan('cache.set', {\n kind: 'INTERNAL',\n attributes: { 'cache.key': key, 'cache.ttl': options.ttl },\n });\n\n try {\n // Validate and normalize key (fail-closed - throw on validation error)\n const normalizedKey = this.validateAndNormalizeKey(key);\n const enrichedKey = this.enrichKeyWithContext(normalizedKey, options.varyBy);\n\n // Validate TTL using TTL value object\n const ttlSeconds = options.ttl ?? this.options.l2?.defaultTtl ?? 3600;\n const maxTtl = this.options.l2?.maxTtl ?? 86400;\n const ttl = TTL.create(ttlSeconds, maxTtl);\n\n const entry = CacheEntry.create(value, ttl.toSeconds());\n\n // Determine cache strategy\n const strategy = options.strategy ?? 'l1-l2';\n span?.setAttribute('cache.strategy', strategy);\n\n // Set in L2 (if not l1-only)\n if (this.l2Enabled && strategy !== 'l1-only') {\n await this.l2Store.set(enrichedKey, entry, ttl.toSeconds());\n }\n\n // Set in L1 (if not l2-only, use minimum of L2 TTL and L1 max TTL)\n if (this.l1Enabled && strategy !== 'l2-only') {\n const l1MaxTtl = TTL.create(this.options.l1?.ttl ?? 60, maxTtl);\n const l1Ttl = TTL.min(ttl, l1MaxTtl);\n await this.l1Store.set(enrichedKey, entry, l1Ttl.toSeconds());\n }\n\n // Add to tag index (only for L2 operations, use full key with prefix)\n if (this.tagsEnabled && options.tags && options.tags.length > 0 && strategy !== 'l1-only') {\n const fullKey = `${this.keyPrefix}${enrichedKey}`;\n await this.tagIndex.addKeyToTags(fullKey, options.tags);\n span?.setAttribute('cache.tags', options.tags.join(','));\n }\n\n span?.setStatus('OK');\n } catch (error) {\n span?.recordException(error as Error);\n span?.setStatus('ERROR');\n // CacheKeyError and CacheError (from TTL validation) will be thrown as-is\n if (error instanceof CacheKeyError || error instanceof CacheError) {\n throw error;\n }\n throw new CacheError(`Failed to set cache for key \"${key}\": ${(error as Error).message}`, ErrorCode.CACHE_SET_FAILED, error as Error);\n } finally {\n span?.end();\n }\n }\n\n async getOrSet<T>(key: string, loader: () => Promise<T>, options: CacheGetOrSetOptions = {}): Promise<T> {\n // Validate key early (fail-closed for write operations)\n const normalizedKey = this.validateAndNormalizeKey(key);\n const enrichedKey = this.enrichKeyWithContext(normalizedKey, options.varyBy);\n\n // Check if SWR is enabled for this call\n const swrEnabled = options.swr?.enabled ?? this.swrEnabled;\n\n if (swrEnabled) {\n // SWR flow\n const swrEntry = await this.l2Store.getSwr<T>(enrichedKey);\n\n if (swrEntry) {\n const isExpired = this.swrManager.isExpired(swrEntry);\n\n if (!isExpired) {\n // Data is valid (fresh or stale)\n const isStale = this.swrManager.isStale(swrEntry);\n\n if (isStale && this.swrManager.shouldRevalidate(enrichedKey)) {\n // Trigger background revalidation\n void this.swrManager.scheduleRevalidation(\n enrichedKey,\n loader,\n async (freshValue) => {\n // Write proper SWR entry (not CacheEntry) to preserve staleAt/expiresAt metadata\n const staleTime = options.swr?.staleTime ?? this.options.swr?.defaultStaleTime ?? 60;\n const ttl = options.ttl ?? this.options.l2?.defaultTtl ?? 3600;\n const swrEntryNew = this.swrManager.createSwrEntry(freshValue, ttl, staleTime);\n await this.l2Store.setSwr(enrichedKey, swrEntryNew);\n\n // Also update L1 for fast reads\n if (this.l1Enabled) {\n const entry = CacheEntry.create(freshValue, ttl);\n await this.l1Store.set(enrichedKey, entry, this.options.l1?.ttl);\n }\n },\n (error) => {\n this.logger.error(`SWR revalidation failed for key ${enrichedKey}:`, error);\n },\n );\n }\n\n return swrEntry.value;\n }\n }\n\n // SWR miss or expired - load and cache with SWR metadata\n const value = await this.loadWithStampede(enrichedKey, loader, options);\n\n if (!options.unless?.(value)) {\n const staleTime = options.swr?.staleTime ?? this.options.swr?.defaultStaleTime ?? 60;\n const ttl = options.ttl ?? this.options.l2?.defaultTtl ?? 3600;\n const swrEntryNew = this.swrManager.createSwrEntry(value, ttl, staleTime);\n\n await this.l2Store.setSwr(enrichedKey, swrEntryNew);\n }\n\n return value;\n }\n\n // Regular flow (no SWR) — use enrichedKey directly to avoid double-enrichment\n const cached = await this.get<T>(enrichedKey);\n if (cached !== null) {\n return cached;\n }\n\n return this.loadWithStampede(enrichedKey, loader, options);\n }\n\n /**\n * Loads value with stampede protection if enabled.\n *\n * @param key - Normalized cache key\n * @param loader - Function to load value\n * @param options - Cache options\n * @returns Loaded value\n * @private\n */\n private async loadWithStampede<T>(key: string, loader: () => Promise<T>, options: CacheGetOrSetOptions): Promise<T> {\n if (this.stampedeEnabled && !options.skipStampede) {\n const result = await this.stampede.protect(key, loader);\n\n if (result.cached) {\n // Stampede was prevented - another request loaded the value\n this.metrics?.incrementCounter('redisx_cache_stampede_prevented_total');\n return result.value;\n }\n\n if (!options.unless?.(result.value)) {\n await this.set(key, result.value, {\n ttl: options.ttl,\n tags: options.tags,\n strategy: options.strategy,\n });\n }\n\n return result.value;\n }\n\n // No stampede protection - direct load\n const value = await loader();\n\n if (!options.unless?.(value)) {\n await this.set(key, value, {\n ttl: options.ttl,\n tags: options.tags,\n strategy: options.strategy,\n });\n }\n\n return value;\n }\n\n async delete(key: string): Promise<boolean> {\n try {\n // Validate key (fail-closed for write operations)\n const normalizedKey = this.validateAndNormalizeKey(key);\n const enrichedKey = this.enrichKeyWithContext(normalizedKey);\n\n let deleted = false;\n\n if (this.l1Enabled) {\n const l1Deleted = await this.l1Store.delete(enrichedKey);\n deleted = deleted || l1Deleted;\n }\n\n if (this.l2Enabled) {\n const l2Deleted = await this.l2Store.delete(enrichedKey);\n deleted = deleted || l2Deleted;\n }\n\n return deleted;\n } catch (error) {\n // CacheKeyError will be thrown as-is\n if (error instanceof CacheKeyError) {\n throw error;\n }\n throw new CacheError(`Failed to delete cache for key \"${key}\": ${(error as Error).message}`, ErrorCode.CACHE_DELETE_FAILED, error as Error);\n }\n }\n\n async deleteMany(keys: string[]): Promise<number> {\n if (keys.length === 0) {\n return 0;\n }\n\n try {\n // Validate, normalize, and enrich all keys (fail-closed for write operations)\n const normalizedKeys = keys\n .map((key) => {\n try {\n const normalized = this.validateAndNormalizeKey(key);\n return this.enrichKeyWithContext(normalized);\n } catch (error) {\n if (error instanceof CacheKeyError) {\n this.logger.warn(`Invalid key in deleteMany \"${key}\": ${error.message}`);\n }\n return null;\n }\n })\n .filter((k): k is string => k !== null);\n\n if (normalizedKeys.length === 0) {\n return 0;\n }\n\n // Track per-key deletion across both layers\n const deleted = new Array<boolean>(normalizedKeys.length).fill(false);\n\n // Delete from L1\n if (this.l1Enabled) {\n for (let i = 0; i < normalizedKeys.length; i++) {\n if (await this.l1Store.delete(normalizedKeys[i]!)) {\n deleted[i] = true;\n }\n }\n }\n\n // Delete from L2 using pipeline for batch operation\n if (this.l2Enabled && normalizedKeys.length > 0) {\n const fullKeys = normalizedKeys.map((k) => `${this.keyPrefix}${k}`);\n const pipeline = this.driver.pipeline();\n\n for (const fullKey of fullKeys) {\n pipeline.del(fullKey);\n }\n\n const results = await pipeline.exec();\n\n if (results) {\n for (let i = 0; i < results.length; i++) {\n const [error, result] = results[i]!;\n if (!error && typeof result === 'number' && result > 0) {\n deleted[i] = true;\n }\n }\n }\n }\n\n return deleted.filter(Boolean).length;\n } catch (error) {\n throw new CacheError(`Failed to delete multiple keys: ${(error as Error).message}`, ErrorCode.CACHE_DELETE_FAILED, error as Error);\n }\n }\n\n async clear(): Promise<void> {\n try {\n if (this.l1Enabled) {\n await this.l1Store.clear();\n }\n\n if (this.l2Enabled) {\n await this.l2Store.clear();\n }\n\n if (this.tagsEnabled) {\n await this.tagIndex.clearAllTags();\n }\n } catch (error) {\n throw new CacheError(`Failed to clear cache: ${(error as Error).message}`, ErrorCode.CACHE_CLEAR_FAILED, error as Error);\n }\n }\n\n async has(key: string): Promise<boolean> {\n try {\n // Validate key (fail-open for read operations)\n const normalizedKey = this.validateAndNormalizeKey(key);\n const enrichedKey = this.enrichKeyWithContext(normalizedKey);\n\n if (this.l1Enabled) {\n const l1Has = await this.l1Store.has(enrichedKey);\n if (l1Has) return true;\n }\n\n if (this.l2Enabled) {\n return await this.l2Store.has(enrichedKey);\n }\n\n return false;\n } catch (error) {\n // Fail-open (includes validation errors)\n if (error instanceof CacheKeyError) {\n this.logger.warn(`Invalid cache key \"${key}\": ${error.message}`);\n }\n return false;\n }\n }\n\n async invalidateTag(tag: string): Promise<number> {\n if (!this.tagsEnabled) {\n return 0;\n }\n\n try {\n // Get all keys for this tag (keys include L2 prefix)\n const keysWithPrefix = await this.tagIndex.getKeysByTag(tag);\n\n // Delete from L1 (needs keys without prefix)\n if (this.l1Enabled) {\n const keysWithoutPrefix = keysWithPrefix.map((key) => (key.startsWith(this.keyPrefix) ? key.slice(this.keyPrefix.length) : key));\n await Promise.all(keysWithoutPrefix.map((key) => this.l1Store.delete(key)));\n }\n\n // Delete from L2 and tag index (handled by tagIndex.invalidateTag)\n return await this.tagIndex.invalidateTag(tag);\n } catch (error) {\n throw new CacheError(`Failed to invalidate tag \"${tag}\": ${(error as Error).message}`, ErrorCode.CACHE_TAG_INVALIDATION_FAILED, error as Error);\n }\n }\n\n async invalidateTags(tags: string[]): Promise<number> {\n if (!this.tagsEnabled || tags.length === 0) {\n return 0;\n }\n\n try {\n let total = 0;\n for (const tag of tags) {\n const count = await this.invalidateTag(tag);\n total += count;\n }\n return total;\n } catch (error) {\n throw new CacheError(`Failed to invalidate tags: ${(error as Error).message}`, ErrorCode.CACHE_TAG_INVALIDATION_FAILED, error as Error);\n }\n }\n\n async getKeysByTag(tag: string): Promise<string[]> {\n if (!this.tagsEnabled) {\n return [];\n }\n\n try {\n // Validate tag using Tag VO\n const validTag = Tag.create(tag);\n const keysWithPrefix = await this.tagIndex.getKeysByTag(validTag.toString());\n\n // Remove L2 prefix from keys\n return keysWithPrefix.map((key) => (key.startsWith(this.keyPrefix) ? key.slice(this.keyPrefix.length) : key));\n } catch (error) {\n // Fail-open: log and return empty array\n this.logger.error(`Failed to get keys for tag ${tag}:`, error);\n return [];\n }\n }\n\n async getMany<T>(keys: string[]): Promise<Array<T | null>> {\n if (keys.length === 0) {\n return [];\n }\n\n try {\n // Validate, normalize, and enrich all keys (fail-open)\n const normalizedKeys = keys.map((key) => {\n try {\n const normalized = this.validateAndNormalizeKey(key);\n return this.enrichKeyWithContext(normalized);\n } catch (error) {\n if (error instanceof CacheKeyError) {\n this.logger.warn(`Invalid cache key in getMany \"${key}\": ${error.message}`);\n }\n return null;\n }\n });\n\n // For simplicity, get from L2 only for getMany\n if (!this.l2Enabled) {\n return keys.map(() => null);\n }\n\n // Filter out null keys (validation failures) and maintain index mapping\n const validKeys: string[] = [];\n const indexMap: Map<number, number> = new Map();\n normalizedKeys.forEach((key, index) => {\n if (key !== null) {\n indexMap.set(validKeys.length, index);\n validKeys.push(key);\n }\n });\n\n if (validKeys.length === 0) {\n return keys.map(() => null);\n }\n\n const entries = await this.l2Store.getMany<T>(validKeys);\n\n // Reconstruct result array with null for invalid keys\n const result: Array<T | null> = keys.map(() => null);\n entries.forEach((entry, validIndex) => {\n const originalIndex = indexMap.get(validIndex);\n if (originalIndex !== undefined) {\n result[originalIndex] = entry ? entry.value : null;\n }\n });\n\n return result;\n } catch (error) {\n // Fail-open\n this.logger.error('Failed to getMany:', error);\n return keys.map(() => null);\n }\n }\n\n async setMany<T>(entries: Array<{ key: string; value: T; ttl?: number; tags?: string[] }>): Promise<void> {\n if (entries.length === 0) {\n return;\n }\n\n try {\n if (!this.l2Enabled) {\n return;\n }\n\n // Validate, normalize, and enrich all keys (fail-closed for write operations)\n const maxTtl = this.options.l2?.maxTtl ?? 86400;\n const defaultTtl = this.options.l2?.defaultTtl ?? 3600;\n const cacheEntries = entries.map(({ key, value, ttl }) => {\n const entryTtl = Math.min(ttl ?? defaultTtl, maxTtl);\n return {\n key: this.enrichKeyWithContext(this.validateAndNormalizeKey(key)),\n entry: CacheEntry.create(value, entryTtl),\n ttl: entryTtl,\n };\n });\n\n await this.l2Store.setMany(cacheEntries);\n\n // Add tags to tag index for entries that have tags\n if (this.tagsEnabled) {\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i]!;\n const { tags } = entry;\n if (tags && tags.length > 0) {\n const enrichedKey = cacheEntries[i]!.key;\n const fullKey = `${this.keyPrefix}${enrichedKey}`;\n const validatedTags = Tags.create(tags).toStrings();\n await this.tagIndex.addKeyToTags(fullKey, validatedTags);\n }\n }\n }\n } catch (error) {\n // CacheKeyError will be thrown as-is\n if (error instanceof CacheKeyError) {\n throw error;\n }\n throw new CacheError(`Failed to setMany: ${(error as Error).message}`, ErrorCode.CACHE_SET_FAILED, error as Error);\n }\n }\n\n async ttl(key: string): Promise<number> {\n if (!this.l2Enabled) {\n return -1;\n }\n\n try {\n // Validate key (fail-open for read operations)\n const normalizedKey = this.validateAndNormalizeKey(key);\n const enrichedKey = this.enrichKeyWithContext(normalizedKey);\n return await this.l2Store.ttl(enrichedKey);\n } catch (error) {\n // Fail-open (includes validation errors)\n if (error instanceof CacheKeyError) {\n this.logger.warn(`Invalid cache key \"${key}\": ${error.message}`);\n }\n return -1;\n }\n }\n\n async getStats(): Promise<CacheStats> {\n const l1Stats = this.l1Enabled ? this.l1Store.getStats() : { hits: 0, misses: 0, size: 0 };\n const l2Stats = this.l2Enabled ? await this.l2Store.getStats() : { hits: 0, misses: 0 };\n const stampedeStats = this.stampedeEnabled ? this.stampede.getStats() : { activeFlights: 0, totalWaiters: 0, oldestFlight: 0, prevented: 0 };\n\n return {\n l1: l1Stats,\n l2: l2Stats,\n stampedePrevented: stampedeStats.prevented,\n };\n }\n\n async invalidateByPattern(pattern: string): Promise<number> {\n if (!this.l2Enabled) {\n return 0;\n }\n\n try {\n // Use SCAN to find matching keys\n const result = await this.l2Store.scan(pattern);\n const keys = result.keys;\n\n if (keys.length === 0) {\n return 0;\n }\n\n // Delete from L1\n if (this.l1Enabled) {\n const keysWithoutPrefix = keys.map((key) => (key.startsWith(this.keyPrefix) ? key.slice(this.keyPrefix.length) : key));\n await Promise.all(keysWithoutPrefix.map((key) => this.l1Store.delete(key)));\n }\n\n // Delete from L2\n let deleted = 0;\n for (const key of keys) {\n const wasDeleted = await this.l2Store.delete(key);\n if (wasDeleted) {\n deleted++;\n }\n }\n\n return deleted;\n } catch (error) {\n throw new CacheError(`Failed to invalidate by pattern \"${pattern}\": ${(error as Error).message}`, ErrorCode.CACHE_DELETE_FAILED, error as Error);\n }\n }\n\n /**\n * Validates and normalizes cache key using CacheKey value object.\n *\n * @param rawKey - Raw key string\n * @returns Normalized key string (without prefix - prefix added by L2 store)\n * @throws CacheKeyError if validation fails\n *\n * @private\n */\n private validateAndNormalizeKey(rawKey: string): string {\n try {\n const keyOptions = {\n maxLength: this.options.keys?.maxLength ?? 1024,\n version: this.options.keys?.version,\n separator: this.options.keys?.separator ?? ':',\n // Don't include prefix here - it's added by L2 store\n prefix: '',\n };\n\n const cacheKey = CacheKey.create(rawKey, keyOptions);\n\n // Return raw key without prefix (L2 store will add its prefix)\n return cacheKey.getRaw();\n } catch (error) {\n if (error instanceof CacheKeyError) {\n throw error;\n }\n throw new CacheKeyError(rawKey, `Invalid cache key: ${(error as Error).message}`);\n }\n }\n\n /**\n * Enriches a normalized key with context values.\n * Appends global context keys and per-call varyBy values as key suffix.\n * Uses a marker (_ctx_) to prevent double-enrichment in internal call chains.\n *\n * @param normalizedKey - Already validated and normalized cache key\n * @param varyBy - Optional per-call context overrides\n * @returns Enriched key with context suffix, or original key if no context\n * @private\n */\n private enrichKeyWithContext(normalizedKey: string, varyBy?: Record<string, string>): string {\n const separator = this.options.keys?.separator ?? ':';\n const marker = `${separator}_ctx_${separator}`;\n\n // Skip if already enriched (prevents double-enrichment in internal calls)\n if (normalizedKey.includes(marker)) {\n return normalizedKey;\n }\n\n const contextProvider = this.options.contextProvider;\n const contextKeys = this.options.contextKeys;\n const contextMap = new Map<string, string>();\n\n // Global context keys (from contextProvider)\n if (contextProvider && contextKeys && contextKeys.length > 0) {\n for (const ctxKey of contextKeys) {\n const value = contextProvider.get<string>(ctxKey);\n if (value !== undefined && value !== null) {\n if (typeof value === 'object') {\n this.logger.warn(`Context key \"${ctxKey}\" has object value, skipping (use primitives for context keys)`);\n continue;\n }\n contextMap.set(ctxKey, String(value));\n }\n }\n }\n\n // Per-call varyBy (overrides global context values)\n if (varyBy) {\n for (const [k, v] of Object.entries(varyBy)) {\n contextMap.set(k, v);\n }\n }\n\n if (contextMap.size === 0) return normalizedKey;\n\n const sortedEntries = [...contextMap.entries()].sort(([a], [b]) => a.localeCompare(b));\n const suffix = sortedEntries.map(([k, v]) => `${this.sanitizeForKey(k)}.${this.sanitizeForKey(v)}`).join(separator);\n\n return `${normalizedKey}${marker}${suffix}`;\n }\n\n /**\n * Sanitizes a value for use in cache key (removes non-allowed characters).\n * @private\n */\n private sanitizeForKey(value: string): string {\n return String(value).replace(/[^a-zA-Z0-9\\-_]/g, '_');\n }\n}\n","/**\n * Cache warmup service.\n * Loads specified keys into cache on application startup.\n */\n\nimport { Injectable, Inject, Logger, OnModuleInit } from '@nestjs/common';\n\nimport { CACHE_SERVICE, CACHE_PLUGIN_OPTIONS } from '../../../shared/constants';\nimport { ICachePluginOptions, IWarmupKey } from '../../../shared/types';\nimport { ICacheService } from '../ports/cache-service.port';\n\n@Injectable()\nexport class WarmupService implements OnModuleInit {\n private readonly logger = new Logger(WarmupService.name);\n private readonly enabled: boolean;\n private readonly keys: IWarmupKey[];\n private readonly concurrency: number;\n\n constructor(\n @Inject(CACHE_SERVICE) private readonly cacheService: ICacheService,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly options: ICachePluginOptions,\n ) {\n this.enabled = options.warmup?.enabled ?? false;\n this.keys = options.warmup?.keys ?? [];\n this.concurrency = options.warmup?.concurrency ?? 10;\n }\n\n async onModuleInit(): Promise<void> {\n if (!this.enabled || this.keys.length === 0) {\n return;\n }\n\n this.logger.log(`Starting cache warmup for ${this.keys.length} keys...`);\n\n const startTime = Date.now();\n\n // Simple concurrency control: split into chunks\n const chunks: IWarmupKey[][] = [];\n for (let i = 0; i < this.keys.length; i += this.concurrency) {\n chunks.push(this.keys.slice(i, i + this.concurrency));\n }\n\n let succeeded = 0;\n let failed = 0;\n\n for (const chunk of chunks) {\n const results = await Promise.allSettled(chunk.map((warmupKey) => this.warmupKey(warmupKey)));\n\n succeeded += results.filter((r) => r.status === 'fulfilled').length;\n failed += results.filter((r) => r.status === 'rejected').length;\n }\n\n const duration = Date.now() - startTime;\n\n this.logger.log(`Cache warmup completed: ${succeeded} succeeded, ${failed} failed (${duration}ms)`);\n }\n\n /**\n * Warms up a single cache key.\n *\n * @param warmupKey - Warmup key configuration\n * @private\n */\n private async warmupKey(warmupKey: IWarmupKey): Promise<void> {\n try {\n this.logger.debug(`Warming up key: ${warmupKey.key}`);\n\n await this.cacheService.getOrSet(warmupKey.key, warmupKey.loader, {\n ttl: warmupKey.ttl,\n tags: warmupKey.tags,\n });\n\n this.logger.debug(`Successfully warmed up key: ${warmupKey.key}`);\n } catch (error) {\n this.logger.error(`Failed to warm up key ${warmupKey.key}:`, error);\n throw error;\n }\n }\n}\n","/**\n * Serializer service for cache values.\n */\n\nimport { Injectable } from '@nestjs/common';\n\nimport { SerializationError } from '../../../shared/errors';\n\n@Injectable()\nexport class Serializer {\n /**\n * Serializes value to string.\n *\n * @param value - Value to serialize\n * @returns Serialized string\n * @throws SerializationError if serialization fails\n */\n serialize<T>(value: T): string {\n try {\n return JSON.stringify(value);\n } catch (error) {\n throw new SerializationError(`Failed to serialize value: ${(error as Error).message}`, error as Error);\n }\n }\n\n /**\n * Deserializes string to value.\n *\n * @param serialized - Serialized string\n * @returns Deserialized value\n * @throws SerializationError if deserialization fails\n */\n deserialize<T>(serialized: string): T {\n try {\n return JSON.parse(serialized) as T;\n } catch (error) {\n throw new SerializationError(`Failed to deserialize value: ${(error as Error).message}`, error as Error);\n }\n }\n\n /**\n * Safely tries to deserialize, returns null on error.\n *\n * @param serialized - Serialized string\n * @returns Deserialized value or null\n */\n tryDeserialize<T>(serialized: string): T | null {\n try {\n return this.deserialize<T>(serialized);\n } catch {\n return null;\n }\n }\n}\n","/**\n * L1 in-memory cache store implementation.\n * Supports LRU and LFU eviction policies.\n */\n\nimport { Injectable, Inject } from '@nestjs/common';\n\nimport { CACHE_PLUGIN_OPTIONS } from '../../../shared/constants';\nimport { ICachePluginOptions } from '../../../shared/types';\nimport { IL1CacheStore } from '../../application/ports/l1-cache-store.port';\nimport { CacheEntry } from '../../domain/value-objects/cache-entry.vo';\n\ninterface ICacheNode<T> {\n key: string;\n entry: CacheEntry<T>;\n prev: ICacheNode<T> | null;\n next: ICacheNode<T> | null;\n expiresAt: number;\n frequency: number;\n}\n\n@Injectable()\nexport class L1MemoryStoreAdapter implements IL1CacheStore {\n private readonly cache = new Map<string, ICacheNode<unknown>>();\n private head: ICacheNode<unknown> | null = null;\n private tail: ICacheNode<unknown> | null = null;\n private readonly maxSize: number;\n private readonly defaultTtl: number;\n private readonly evictionPolicy: 'lru' | 'lfu';\n private hits = 0;\n private misses = 0;\n\n constructor(\n @Inject(CACHE_PLUGIN_OPTIONS)\n private readonly options: ICachePluginOptions,\n ) {\n this.maxSize = options.l1?.maxSize ?? 1000;\n this.defaultTtl = (options.l1?.ttl ?? 60) * 1000; // Convert to ms\n this.evictionPolicy = options.l1?.evictionPolicy ?? 'lru';\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async get<T>(key: string): Promise<CacheEntry<T> | null> {\n const node = this.cache.get(key);\n if (!node) {\n this.misses++;\n return null;\n }\n\n // Check expiration\n if (Date.now() > node.expiresAt) {\n void this.delete(key);\n this.misses++;\n return null;\n }\n\n if (this.evictionPolicy === 'lru') {\n // Move to front (most recently used)\n this.moveToFront(node);\n } else {\n // LFU: increment frequency\n node.frequency++;\n }\n\n this.hits++;\n return node.entry as CacheEntry<T>;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async set<T>(key: string, entry: CacheEntry<T>, ttl?: number): Promise<void> {\n const existingNode = this.cache.get(key);\n\n if (existingNode) {\n // Update existing node\n existingNode.entry = entry;\n existingNode.expiresAt = Date.now() + (ttl ?? this.defaultTtl);\n\n if (this.evictionPolicy === 'lru') {\n this.moveToFront(existingNode);\n } else {\n existingNode.frequency++;\n }\n } else {\n // Evict if at capacity\n if (this.cache.size >= this.maxSize) {\n this.evict();\n }\n\n // Create new node\n const node: ICacheNode<unknown> = {\n key,\n entry,\n prev: null,\n next: this.head,\n expiresAt: Date.now() + (ttl ?? this.defaultTtl),\n frequency: 1,\n };\n\n if (this.head) {\n this.head.prev = node;\n }\n this.head = node;\n\n if (!this.tail) {\n this.tail = node;\n }\n\n this.cache.set(key, node);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async delete(key: string): Promise<boolean> {\n const node = this.cache.get(key);\n if (!node) {\n return false;\n }\n\n this.removeNode(node);\n this.cache.delete(key);\n return true;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async clear(): Promise<void> {\n this.cache.clear();\n this.head = null;\n this.tail = null;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async has(key: string): Promise<boolean> {\n const node = this.cache.get(key);\n if (!node) {\n return false;\n }\n\n // Check expiration\n if (Date.now() > node.expiresAt) {\n void this.delete(key);\n return false;\n }\n\n return true;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async size(): Promise<number> {\n // O(1): returns approximate size (may include expired entries not yet evicted by get/has/set).\n // Expired entries are cleaned lazily on access, not eagerly here.\n return this.cache.size;\n }\n\n private moveToFront(node: ICacheNode<unknown>): void {\n if (node === this.head) {\n return;\n }\n\n this.removeNode(node);\n\n node.prev = null;\n node.next = this.head;\n\n if (this.head) {\n this.head.prev = node;\n }\n\n this.head = node;\n\n if (!this.tail) {\n this.tail = node;\n }\n }\n\n private removeNode(node: ICacheNode<unknown>): void {\n if (node.prev) {\n node.prev.next = node.next;\n } else {\n this.head = node.next;\n }\n\n if (node.next) {\n node.next.prev = node.prev;\n } else {\n this.tail = node.prev;\n }\n }\n\n private evict(): void {\n if (this.evictionPolicy === 'lfu') {\n this.evictLFU();\n } else {\n this.evictLRU();\n }\n }\n\n private evictLRU(): void {\n if (!this.tail) {\n return;\n }\n\n const key = this.tail.key;\n this.removeNode(this.tail);\n this.cache.delete(key);\n }\n\n private evictLFU(): void {\n if (this.cache.size === 0) {\n return;\n }\n\n // Find node with lowest frequency; on tie, use linked list order (tail = oldest)\n let victim: ICacheNode<unknown> | null = null;\n\n let current = this.tail;\n while (current) {\n if (!victim || current.frequency < victim.frequency) {\n victim = current;\n }\n current = current.prev;\n }\n\n if (victim) {\n this.removeNode(victim);\n this.cache.delete(victim.key);\n }\n }\n\n getStats(): { hits: number; misses: number; size: number } {\n return {\n hits: this.hits,\n misses: this.misses,\n size: this.cache.size,\n };\n }\n}\n","/**\n * L2 Redis cache store implementation.\n */\n\nimport { Injectable, Inject } from '@nestjs/common';\nimport { REDIS_DRIVER, IRedisDriver, ErrorCode } from '@nestjs-redisx/core';\n\nimport { CACHE_PLUGIN_OPTIONS, SERIALIZER } from '../../../shared/constants';\nimport { CacheError } from '../../../shared/errors';\nimport { ICachePluginOptions, ScanResult, SwrEntry } from '../../../shared/types';\nimport { IL2CacheStore } from '../../application/ports/l2-cache-store.port';\nimport { Serializer } from '../../domain/services/serializer.service';\nimport { CacheEntry } from '../../domain/value-objects/cache-entry.vo';\n\n/** Default batch size for SCAN and bulk delete operations. */\nconst DEFAULT_BATCH_SIZE = 100;\n\n@Injectable()\nexport class L2RedisStoreAdapter implements IL2CacheStore {\n private readonly keyPrefix: string;\n private readonly defaultTtl: number;\n private hits = 0;\n private misses = 0;\n\n constructor(\n @Inject(REDIS_DRIVER) private readonly driver: IRedisDriver,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly options: ICachePluginOptions,\n @Inject(SERIALIZER) private readonly serializer: Serializer,\n ) {\n this.keyPrefix = options.l2?.keyPrefix ?? 'cache:';\n this.defaultTtl = options.l2?.defaultTtl ?? 3600;\n }\n\n async get<T>(key: string): Promise<CacheEntry<T> | null> {\n try {\n const fullKey = this.buildKey(key);\n const value = await this.driver.get(fullKey);\n\n if (!value) {\n this.misses++;\n return null;\n }\n\n this.hits++;\n return this.serializer.deserialize<CacheEntry<T>>(value);\n } catch {\n // Fail-open: return null on error\n this.misses++;\n return null;\n }\n }\n\n async set<T>(key: string, entry: CacheEntry<T>, ttl?: number): Promise<void> {\n try {\n const fullKey = this.buildKey(key);\n const serialized = this.serializer.serialize(entry);\n const ttlSeconds = ttl ?? this.defaultTtl;\n\n await this.driver.setex(fullKey, ttlSeconds, serialized);\n } catch (error) {\n throw new CacheError(`Failed to set cache entry for key \"${key}\": ${(error as Error).message}`, ErrorCode.CACHE_SET_FAILED, error as Error);\n }\n }\n\n async delete(key: string): Promise<boolean> {\n try {\n const fullKey = this.buildKey(key);\n const result = await this.driver.del(fullKey);\n return result > 0;\n } catch (error) {\n throw new CacheError(`Failed to delete cache entry for key \"${key}\": ${(error as Error).message}`, ErrorCode.CACHE_DELETE_FAILED, error as Error);\n }\n }\n\n async clear(): Promise<void> {\n try {\n const pattern = `${this.keyPrefix}*`;\n const keys = await this.scanKeys(pattern);\n\n if (keys.length === 0) {\n return;\n }\n\n // Cluster-safe: delete keys individually to avoid CROSSSLOT errors\n const batchSize = DEFAULT_BATCH_SIZE;\n for (let i = 0; i < keys.length; i += batchSize) {\n const batch = keys.slice(i, i + batchSize);\n\n // Delete each key individually\n await Promise.all(batch.map((key) => this.driver.del(key)));\n }\n } catch (error) {\n throw new CacheError(`Failed to clear cache: ${(error as Error).message}`, ErrorCode.CACHE_CLEAR_FAILED, error as Error);\n }\n }\n\n async has(key: string): Promise<boolean> {\n try {\n const fullKey = this.buildKey(key);\n const exists = await this.driver.exists(fullKey);\n return exists > 0;\n } catch {\n // Fail-open: return false on error\n return false;\n }\n }\n\n async ttl(key: string): Promise<number> {\n try {\n const fullKey = this.buildKey(key);\n const ttl = await this.driver.ttl(fullKey);\n return ttl;\n } catch {\n return -1;\n }\n }\n\n async expire(key: string, ttl: number): Promise<boolean> {\n try {\n const fullKey = this.buildKey(key);\n const result = await this.driver.expire(fullKey, ttl);\n return result === 1;\n } catch (error) {\n throw new CacheError(`Failed to set expiration for key \"${key}\": ${(error as Error).message}`, ErrorCode.CACHE_OPERATION_FAILED, error as Error);\n }\n }\n\n async scan(pattern: string, count: number = DEFAULT_BATCH_SIZE): Promise<ScanResult> {\n try {\n const fullPattern = `${this.keyPrefix}${pattern}`;\n const keys = await this.scanKeys(fullPattern, count);\n\n // Remove prefix from keys\n const strippedKeys = keys.map((key) => (key.startsWith(this.keyPrefix) ? key.slice(this.keyPrefix.length) : key));\n\n return {\n keys: strippedKeys,\n cursor: '0', // Simplified: full scan completed\n };\n } catch (error) {\n throw new CacheError(`Failed to scan keys with pattern \"${pattern}\": ${(error as Error).message}`, ErrorCode.CACHE_OPERATION_FAILED, error as Error);\n }\n }\n\n async getMany<T>(keys: string[]): Promise<Array<CacheEntry<T> | null>> {\n try {\n if (keys.length === 0) {\n return [];\n }\n\n const fullKeys = keys.map((key) => this.buildKey(key));\n\n // Use driver.mget() - core handles cluster topology automatically\n const values = await this.driver.mget(...fullKeys);\n\n return values.map((value) => {\n if (!value) {\n this.misses++;\n return null;\n }\n this.hits++;\n return this.serializer.tryDeserialize<CacheEntry<T>>(value);\n });\n } catch {\n // Fail-open: return array of nulls\n return keys.map(() => null);\n }\n }\n\n async setMany<T>(entries: Array<{ key: string; entry: CacheEntry<T>; ttl?: number }>): Promise<void> {\n try {\n if (entries.length === 0) {\n return;\n }\n\n // Cluster-safe: set keys individually to avoid CROSSSLOT errors with pipeline\n // In standalone mode this is slightly slower but works everywhere\n await Promise.all(\n entries.map(async ({ key, entry, ttl }) => {\n const fullKey = this.buildKey(key);\n const serialized = this.serializer.serialize(entry);\n const ttlSeconds = ttl ?? this.defaultTtl;\n\n await this.driver.setex(fullKey, ttlSeconds, serialized);\n }),\n );\n } catch (error) {\n throw new CacheError(`Failed to set multiple cache entries: ${(error as Error).message}`, ErrorCode.CACHE_SET_FAILED, error as Error);\n }\n }\n\n private buildKey(key: string): string {\n return `${this.keyPrefix}${key}`;\n }\n\n private async scanKeys(pattern: string, count: number = DEFAULT_BATCH_SIZE): Promise<string[]> {\n const keys: string[] = [];\n let cursor = 0;\n\n do {\n const result = await this.driver.scan(cursor, {\n match: pattern,\n count,\n });\n cursor = parseInt(result[0], 10);\n keys.push(...result[1]);\n } while (cursor !== 0);\n\n return keys;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async getStats(): Promise<{ hits: number; misses: number }> {\n return {\n hits: this.hits,\n misses: this.misses,\n };\n }\n\n async getSwr<T>(key: string): Promise<SwrEntry<T> | null> {\n try {\n const fullKey = this.buildKey(key);\n const value = await this.driver.get(fullKey);\n\n if (!value) {\n this.misses++;\n return null;\n }\n\n this.hits++;\n return this.serializer.deserialize<SwrEntry<T>>(value);\n } catch {\n // Fail-open: return null on error\n this.misses++;\n return null;\n }\n }\n\n async setSwr<T>(key: string, swrEntry: SwrEntry<T>): Promise<void> {\n try {\n const fullKey = this.buildKey(key);\n const serialized = this.serializer.serialize(swrEntry);\n\n // Calculate TTL from expiresAt timestamp\n const now = Date.now();\n const ttlMs = swrEntry.expiresAt - now;\n\n if (ttlMs <= 0) {\n // Entry already expired, don't save it\n return;\n }\n\n const ttlSeconds = Math.max(1, Math.ceil(ttlMs / 1000));\n\n await this.driver.setex(fullKey, ttlSeconds, serialized);\n } catch (error) {\n throw new CacheError(`Failed to set SWR entry for key \"${key}\": ${(error as Error).message}`, ErrorCode.CACHE_SET_FAILED, error as Error);\n }\n }\n}\n","/**\n * Main cache service.\n * Simplified API wrapper over the internal cache implementation.\n */\n\nimport { Injectable, Inject } from '@nestjs/common';\n\nimport { ICacheService as IInternalCacheService } from './cache/application/ports/cache-service.port';\nimport { CACHE_SERVICE } from './shared/constants';\nimport { CacheSetOptions, CacheGetOrSetOptions, CacheStats } from './shared/types';\n\n@Injectable()\nexport class CacheService {\n constructor(\n @Inject(CACHE_SERVICE)\n private readonly internalCache: IInternalCacheService,\n ) {}\n\n /**\n * Gets value from cache.\n *\n * @param key - Cache key\n * @returns Cached value or null if not found\n *\n * @example\n * ```typescript\n * const user = await cacheService.get<User>('user:123');\n * ```\n */\n async get<T>(key: string): Promise<T | null> {\n return this.internalCache.get<T>(key);\n }\n\n /**\n * Sets value in cache with optional TTL and tags.\n *\n * @param key - Cache key\n * @param value - Value to cache\n * @param options - Cache options (ttl, tags, strategy)\n *\n * @example\n * ```typescript\n * await cacheService.set('user:123', user, {\n * ttl: 3600,\n * tags: ['users', 'user:123']\n * });\n * ```\n */\n async set<T>(key: string, value: T, options?: CacheSetOptions): Promise<void> {\n return this.internalCache.set(key, value, options);\n }\n\n /**\n * Deletes key from cache.\n *\n * @param key - Cache key\n * @returns True if key was deleted, false if not found\n *\n * @example\n * ```typescript\n * const deleted = await cacheService.del('user:123');\n * ```\n */\n async del(key: string): Promise<boolean> {\n return this.internalCache.delete(key);\n }\n\n /**\n * Gets multiple values from cache.\n *\n * @param keys - Array of cache keys\n * @returns Array of values (null for missing keys)\n *\n * @example\n * ```typescript\n * const users = await cacheService.getMany<User>(['user:1', 'user:2', 'user:3']);\n * ```\n */\n async getMany<T>(keys: string[]): Promise<Array<T | null>> {\n return this.internalCache.getMany<T>(keys);\n }\n\n /**\n * Sets multiple values in cache.\n *\n * @param entries - Array of key-value-ttl tuples\n *\n * @example\n * ```typescript\n * await cacheService.setMany([\n * { key: 'user:1', value: user1, ttl: 3600 },\n * { key: 'user:2', value: user2, ttl: 3600 }\n * ]);\n * ```\n */\n async setMany<T>(entries: Array<{ key: string; value: T; ttl?: number }>): Promise<void> {\n return this.internalCache.setMany(entries);\n }\n\n /**\n * Gets value from cache or loads it using the provided loader function.\n * Implements cache-aside pattern with anti-stampede protection.\n *\n * @param key - Cache key\n * @param loader - Function to load value if not cached\n * @param options - Cache options\n * @returns Cached or loaded value\n *\n * @example\n * ```typescript\n * const user = await cacheService.getOrSet(\n * 'user:123',\n * async () => {\n * return await userRepository.findById('123');\n * },\n * { ttl: 3600, tags: ['users'] }\n * );\n * ```\n */\n async getOrSet<T>(key: string, loader: () => Promise<T>, options?: CacheGetOrSetOptions): Promise<T> {\n return this.internalCache.getOrSet(key, loader, options);\n }\n\n /**\n * Wraps a function with caching logic.\n * Helper for creating cached functions.\n *\n * @param fn - Function to wrap\n * @param options - Cache options or key builder function\n * @returns Wrapped function with caching\n *\n * @example\n * ```typescript\n * const getCachedUser = cacheService.wrap(\n * async (id: string) => userRepository.findById(id),\n * {\n * key: (id: string) => `user:${id}`,\n * ttl: 3600,\n * tags: (id: string) => [`user:${id}`, 'users']\n * }\n * );\n *\n * const user = await getCachedUser('123');\n * ```\n */\n wrap<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => Promise<TReturn>,\n options: {\n key: (...args: TArgs) => string;\n ttl?: number;\n tags?: string[] | ((...args: TArgs) => string[]);\n },\n ): (...args: TArgs) => Promise<TReturn> {\n return async (...args: TArgs): Promise<TReturn> => {\n const key = options.key(...args);\n const tags = typeof options.tags === 'function' ? options.tags(...args) : options.tags;\n\n return this.getOrSet(key, () => fn(...args), {\n ttl: options.ttl,\n tags,\n });\n };\n }\n\n /**\n * Deletes multiple keys from cache.\n *\n * @param keys - Array of cache keys\n * @returns Number of keys deleted\n *\n * @example\n * ```typescript\n * const count = await cacheService.deleteMany(['user:1', 'user:2', 'user:3']);\n * console.log(`Deleted ${count} keys`);\n * ```\n */\n async deleteMany(keys: string[]): Promise<number> {\n return this.internalCache.deleteMany(keys);\n }\n\n /**\n * Gets all cache keys associated with a tag.\n *\n * @param tag - Tag name\n * @returns Array of cache keys\n *\n * @example\n * ```typescript\n * const keys = await cacheService.getKeysByTag('users');\n * console.log(`Found ${keys.length} cached user keys`);\n * ```\n */\n async getKeysByTag(tag: string): Promise<string[]> {\n return this.internalCache.getKeysByTag(tag);\n }\n\n /**\n * Invalidates cache by tag.\n *\n * @param tag - Tag to invalidate\n * @returns Number of keys invalidated\n *\n * @example\n * ```typescript\n * // Invalidate all user caches\n * const count = await cacheService.invalidate('users');\n * console.log(`Invalidated ${count} keys`);\n * ```\n */\n async invalidate(tag: string): Promise<number> {\n return this.internalCache.invalidateTag(tag);\n }\n\n /**\n * Invalidates multiple tags.\n *\n * @param tags - Array of tags to invalidate\n * @returns Total number of keys invalidated\n *\n * @example\n * ```typescript\n * const count = await cacheService.invalidate(['users', 'products']);\n * ```\n */\n async invalidateTags(tags: string[]): Promise<number> {\n return this.internalCache.invalidateTags(tags);\n }\n\n /**\n * Invalidates cache keys matching a pattern.\n * Uses Redis SCAN for safe iteration.\n *\n * @param pattern - Redis pattern (supports * and ?)\n * @returns Number of keys deleted\n *\n * @example\n * ```typescript\n * // Delete all user-related caches\n * await cacheService.invalidateByPattern('user:*');\n *\n * // Delete specific locale caches\n * await cacheService.invalidateByPattern('*:en_US');\n * ```\n */\n async invalidateByPattern(pattern: string): Promise<number> {\n return this.internalCache.invalidateByPattern(pattern);\n }\n\n /**\n * Checks if key exists in cache.\n *\n * @param key - Cache key\n * @returns True if key exists\n */\n async has(key: string): Promise<boolean> {\n return this.internalCache.has(key);\n }\n\n /**\n * Gets TTL for a cached key.\n *\n * @param key - Cache key\n * @returns TTL in seconds, -1 if no TTL, -2 if key doesn't exist\n */\n async ttl(key: string): Promise<number> {\n return this.internalCache.ttl(key);\n }\n\n /**\n * Clears all cache entries.\n * Use with caution in production.\n *\n * @example\n * ```typescript\n * await cacheService.clear();\n * ```\n */\n async clear(): Promise<void> {\n return this.internalCache.clear();\n }\n\n /**\n * Gets cache statistics.\n *\n * @returns Cache stats (hits, misses, size)\n *\n * @example\n * ```typescript\n * const stats = await cacheService.getStats();\n * console.log(`L1 Hit Rate: ${stats.l1.hits / (stats.l1.hits + stats.l1.misses) * 100}%`);\n * ```\n */\n async getStats(): Promise<CacheStats> {\n return this.internalCache.getStats();\n }\n}\n","/**\n * Event invalidation service.\n * Processes invalidation events and coordinates cache invalidation.\n */\n\nimport { createHash } from 'crypto';\nimport { EventEmitter } from 'events';\n\nimport { Injectable, Inject, Logger, OnModuleInit } from '@nestjs/common';\nimport { REDIS_DRIVER, IRedisDriver } from '@nestjs-redisx/core';\n\nimport { ICacheService } from '../../../cache/application/ports/cache-service.port';\nimport { CACHE_PLUGIN_OPTIONS, CACHE_SERVICE, INVALIDATION_REGISTRY } from '../../../shared/constants';\nimport { ICachePluginOptions } from '../../../shared/types';\nimport { IEventInvalidationService, InvalidationHandler, IInvalidationResult } from '../ports/event-invalidation.port';\nimport { IInvalidationRegistry } from '../ports/invalidation-registry.port';\n\n@Injectable()\nexport class EventInvalidationService implements IEventInvalidationService, OnModuleInit {\n private readonly logger = new Logger(EventInvalidationService.name);\n private readonly handlers = new Set<InvalidationHandler>();\n private readonly eventEmitter = new EventEmitter();\n\n constructor(\n @Inject(INVALIDATION_REGISTRY)\n private readonly registry: IInvalidationRegistry,\n @Inject(CACHE_SERVICE) private readonly cacheService: ICacheService,\n @Inject(REDIS_DRIVER) private readonly driver: IRedisDriver,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly config: ICachePluginOptions,\n ) {}\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async onModuleInit(): Promise<void> {\n // Setup event source based on config\n const source = this.config.invalidation?.source ?? 'internal';\n\n if (source === 'internal') {\n this.setupInternalSource();\n this.logger.log('Event invalidation initialized with internal source');\n }\n // AMQP source is setup via AMQPEventSourceAdapter\n }\n\n async processEvent(event: string, payload: unknown): Promise<IInvalidationResult> {\n const startTime = Date.now();\n\n try {\n // Deduplication check\n const eventId = this.generateEventId(event, payload);\n const isDuplicate = await this.checkDuplicate(eventId);\n\n if (isDuplicate) {\n this.logger.debug(`Skipping duplicate event \"${event}\"`);\n return {\n event,\n tagsInvalidated: [],\n keysInvalidated: [],\n totalKeysDeleted: 0,\n duration: Date.now() - startTime,\n skipped: true,\n skipReason: 'duplicate',\n };\n }\n\n // Resolve what to invalidate\n const resolved = this.registry.resolve(event, payload);\n\n if (resolved.tags.length === 0 && resolved.keys.length === 0) {\n this.logger.debug(`No matching rules for event \"${event}\"`);\n return {\n event,\n tagsInvalidated: [],\n keysInvalidated: [],\n totalKeysDeleted: 0,\n duration: Date.now() - startTime,\n skipped: true,\n skipReason: 'no_matching_rules',\n };\n }\n\n // Perform invalidation\n let totalDeleted = 0;\n\n if (resolved.tags.length > 0) {\n this.logger.debug(`Invalidating tags: ${resolved.tags.join(', ')} for event \"${event}\"`);\n totalDeleted += await this.cacheService.invalidateTags(resolved.tags);\n }\n\n if (resolved.keys.length > 0) {\n this.logger.debug(`Invalidating keys: ${resolved.keys.join(', ')} for event \"${event}\"`);\n totalDeleted += await this.cacheService.deleteMany(resolved.keys);\n }\n\n // Mark as processed\n await this.markProcessed(eventId);\n\n const result: IInvalidationResult = {\n event,\n tagsInvalidated: resolved.tags,\n keysInvalidated: resolved.keys,\n totalKeysDeleted: totalDeleted,\n duration: Date.now() - startTime,\n skipped: false,\n };\n\n this.logger.log(`Processed event \"${event}\": invalidated ${resolved.tags.length} tags, ${resolved.keys.length} keys, deleted ${totalDeleted} cache entries (${result.duration}ms)`);\n\n // Notify handlers\n await this.notifyHandlers(event, payload, result);\n\n return result;\n } catch (error) {\n this.logger.error(`Failed to process event \"${event}\":`, error);\n throw error;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async emit(event: string, payload: unknown): Promise<void> {\n this.eventEmitter.emit('invalidation', { event, payload });\n }\n\n subscribe(handler: InvalidationHandler): () => void {\n this.handlers.add(handler);\n return () => this.handlers.delete(handler);\n }\n\n private setupInternalSource(): void {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.eventEmitter.on('invalidation', async ({ event, payload }) => {\n try {\n await this.processEvent(event, payload);\n } catch (error) {\n this.logger.error(`Internal event processing failed for \"${event}\":`, error);\n }\n });\n }\n\n private async checkDuplicate(eventId: string): Promise<boolean> {\n try {\n const key = `_invalidation:processed:${eventId}`;\n const exists = await this.driver.exists(key);\n return exists > 0;\n } catch (error) {\n this.logger.warn('Deduplication check failed:', error);\n return false; // Fail-open\n }\n }\n\n private async markProcessed(eventId: string): Promise<void> {\n try {\n const key = `_invalidation:processed:${eventId}`;\n const ttl = this.config.invalidation?.deduplicationTtl ?? 60;\n await this.driver.setex(key, ttl, '1');\n } catch (error) {\n this.logger.warn('Failed to mark event as processed:', error);\n // Don't throw - this is not critical\n }\n }\n\n private generateEventId(event: string, payload: unknown): string {\n const hash = createHash('sha256')\n .update(event)\n .update(JSON.stringify(payload ?? {}))\n .digest('hex')\n .slice(0, 16);\n return hash;\n }\n\n private async notifyHandlers(event: string, payload: unknown, result: IInvalidationResult): Promise<void> {\n for (const handler of this.handlers) {\n try {\n await handler(event, payload, result);\n } catch (error) {\n this.logger.error('Invalidation handler error:', error);\n // Don't propagate handler errors\n }\n }\n }\n}\n","/**\n * Invalidation registry service.\n * Manages invalidation rules and resolves what to invalidate for events.\n */\n\nimport { Injectable, Logger } from '@nestjs/common';\n\nimport { InvalidationRule } from '../../domain/entities/invalidation-rule.entity';\nimport { IInvalidationRegistry, IResolvedInvalidation } from '../ports/invalidation-registry.port';\n\n@Injectable()\nexport class InvalidationRegistryService implements IInvalidationRegistry {\n private readonly logger = new Logger(InvalidationRegistryService.name);\n private rules: InvalidationRule[] = [];\n\n register(rule: InvalidationRule): void {\n this.rules.push(rule);\n // Sort by priority (higher first)\n this.rules.sort((a, b) => b.getPriority() - a.getPriority());\n\n this.logger.debug(`Registered invalidation rule for event \"${rule.getEventPattern()}\" with priority ${rule.getPriority()}`);\n }\n\n registerMany(rules: InvalidationRule[]): void {\n for (const rule of rules) {\n this.register(rule);\n }\n }\n\n unregister(event: string): void {\n const initialLength = this.rules.length;\n this.rules = this.rules.filter((r) => r.getEventPattern() !== event);\n\n const removed = initialLength - this.rules.length;\n if (removed > 0) {\n this.logger.debug(`Unregistered ${removed} rule(s) for event \"${event}\"`);\n }\n }\n\n findRules(event: string): InvalidationRule[] {\n return this.rules.filter((rule) => rule.matches(event));\n }\n\n resolve(event: string, payload: unknown): IResolvedInvalidation {\n const matchedRules = this.findRules(event);\n const tagsSet = new Set<string>();\n const keysSet = new Set<string>();\n const applicableRules: InvalidationRule[] = [];\n\n for (const rule of matchedRules) {\n // Test condition\n if (!rule.testCondition(payload)) {\n this.logger.debug(`Rule for event \"${rule.getEventPattern()}\" skipped - condition not met`);\n continue;\n }\n\n applicableRules.push(rule);\n\n // Resolve tags\n if (rule.hasTags()) {\n const tags = rule.resolveTags(payload);\n for (const tag of tags) {\n // Only add if fully resolved (no remaining placeholders)\n if (!tag.includes('{')) {\n tagsSet.add(tag);\n } else {\n this.logger.warn(`Tag template \"${tag}\" has unresolved placeholders for event \"${event}\"`);\n }\n }\n }\n\n // Resolve keys\n if (rule.hasKeys()) {\n const keys = rule.resolveKeys(payload);\n for (const key of keys) {\n // Only add if fully resolved\n if (!key.includes('{')) {\n keysSet.add(key);\n } else {\n this.logger.warn(`Key template \"${key}\" has unresolved placeholders for event \"${event}\"`);\n }\n }\n }\n }\n\n return {\n tags: Array.from(tagsSet),\n keys: Array.from(keysSet),\n matchedRules: applicableRules,\n };\n }\n\n getRules(): InvalidationRule[] {\n return [...this.rules];\n }\n}\n","/**\n * Event pattern value object.\n * Supports AMQP-style wildcards: '*' for one word, '#' for zero or more words.\n */\n\nimport { ErrorCode } from '@nestjs-redisx/core';\n\nimport { CacheError } from '../../../shared/errors';\n\nexport class EventPattern {\n private readonly pattern: string;\n private readonly regex: RegExp;\n\n private constructor(pattern: string, regex: RegExp) {\n this.pattern = pattern;\n this.regex = regex;\n }\n\n /**\n * Creates EventPattern from string pattern.\n * @param pattern - AMQP-style pattern (e.g., 'user.*', 'order.#', 'product.updated')\n */\n static create(pattern: string): EventPattern {\n if (!pattern || pattern.trim().length === 0) {\n throw new CacheError('Event pattern cannot be empty', ErrorCode.VALIDATION_FAILED);\n }\n\n const normalized = pattern.trim();\n\n // Validate pattern format\n if (!/^[a-z0-9*#._-]+$/i.test(normalized)) {\n throw new CacheError(`Invalid event pattern \"${normalized}\". Only alphanumeric, dots, dashes, underscores, *, and # are allowed`, ErrorCode.VALIDATION_FAILED);\n }\n\n // Convert AMQP-style pattern to regex\n // '*' matches exactly one word (one segment between dots)\n // '#' matches zero or more words\n let regexStr = normalized\n .replace(/\\./g, '\\\\.') // Escape dots\n .replace(/\\*/g, '[^.]+') // * = one word\n .replace(/#/g, '.*'); // # = zero or more words\n\n // If pattern ends with .#, make the dot optional to match zero words\n regexStr = regexStr.replace(/\\\\\\.\\.\\*$/, '(?:\\\\..*)?');\n\n const regex = new RegExp(`^${regexStr}$`);\n\n return new EventPattern(normalized, regex);\n }\n\n /**\n * Tests if this pattern matches the given event.\n */\n matches(event: string): boolean {\n return this.regex.test(event);\n }\n\n /**\n * Returns the raw pattern string.\n */\n toString(): string {\n return this.pattern;\n }\n\n /**\n * Checks equality with another pattern.\n */\n equals(other: EventPattern): boolean {\n return this.pattern === other.pattern;\n }\n}\n","/**\n * Tag template value object.\n * Supports placeholders like 'user:{userId}' or 'tenant:{payload.tenantId}'.\n */\n\nimport { ErrorCode } from '@nestjs-redisx/core';\n\nimport { CacheError } from '../../../shared/errors';\n\nexport class TagTemplate {\n private readonly template: string;\n private readonly placeholders: string[];\n\n private constructor(template: string, placeholders: string[]) {\n this.template = template;\n this.placeholders = placeholders;\n }\n\n /**\n * Creates TagTemplate from template string.\n * @param template - Template string with placeholders (e.g., 'user:{userId}')\n */\n static create(template: string): TagTemplate {\n if (!template || template.trim().length === 0) {\n throw new CacheError('Tag template cannot be empty', ErrorCode.VALIDATION_FAILED);\n }\n\n const normalized = template.trim();\n\n // Extract placeholders\n const placeholders: string[] = [];\n const placeholderRegex = /\\{([^}]+)\\}/g;\n let match: RegExpExecArray | null;\n\n while ((match = placeholderRegex.exec(normalized)) !== null) {\n placeholders.push(match[1]!);\n }\n\n return new TagTemplate(normalized, placeholders);\n }\n\n /**\n * Resolves template with given payload.\n * @param payload - Data object to resolve placeholders from\n * @returns Resolved tag string\n */\n resolve(payload: unknown): string {\n return this.template.replace(/\\{([^}]+)\\}/g, (_, path) => {\n const value = this.getNestedValue(payload, path);\n if (value === undefined || value === null) {\n // Keep placeholder unresolved if value not found\n return `{${path}}`;\n }\n return String(value);\n });\n }\n\n /**\n * Returns the raw template string.\n */\n toString(): string {\n return this.template;\n }\n\n /**\n * Returns all placeholders in the template.\n */\n getPlaceholders(): string[] {\n return [...this.placeholders];\n }\n\n /**\n * Checks if template has any placeholders.\n */\n hasPlaceholders(): boolean {\n return this.placeholders.length > 0;\n }\n\n private getNestedValue(obj: unknown, path: string): unknown {\n if (obj === null || obj === undefined) {\n return undefined;\n }\n\n const parts = path.split('.');\n let current: unknown = obj;\n\n for (const part of parts) {\n if (current === null || current === undefined) {\n return undefined;\n }\n\n if (typeof current !== 'object') {\n return undefined;\n }\n\n current = (current as Record<string, unknown>)[part];\n }\n\n return current;\n }\n}\n","/**\n * Invalidation rule entity.\n * Defines what to invalidate when an event occurs.\n */\n\nimport { EventPattern } from '../value-objects/event-pattern.vo';\nimport { TagTemplate } from '../value-objects/tag-template.vo';\n\nexport interface IInvalidationRuleProps {\n event: string;\n tags?: string[];\n keys?: string[];\n condition?: (payload: unknown) => boolean;\n priority?: number;\n}\n\nexport class InvalidationRule {\n private readonly eventPattern: EventPattern;\n private readonly tagTemplates: TagTemplate[];\n private readonly keyTemplates: TagTemplate[];\n private readonly condition?: (payload: unknown) => boolean;\n private readonly priority: number;\n\n private constructor(eventPattern: EventPattern, tagTemplates: TagTemplate[], keyTemplates: TagTemplate[], condition: ((payload: unknown) => boolean) | undefined, priority: number) {\n this.eventPattern = eventPattern;\n this.tagTemplates = tagTemplates;\n this.keyTemplates = keyTemplates;\n this.condition = condition;\n this.priority = priority;\n }\n\n /**\n * Creates InvalidationRule from props.\n */\n static create(props: IInvalidationRuleProps): InvalidationRule {\n const eventPattern = EventPattern.create(props.event);\n\n const tagTemplates = (props.tags ?? []).map((tag) => TagTemplate.create(tag));\n\n const keyTemplates = (props.keys ?? []).map((key) => TagTemplate.create(key));\n\n const priority = props.priority ?? 0;\n\n return new InvalidationRule(eventPattern, tagTemplates, keyTemplates, props.condition, priority);\n }\n\n /**\n * Tests if this rule matches the given event.\n */\n matches(event: string): boolean {\n return this.eventPattern.matches(event);\n }\n\n /**\n * Tests if condition passes for the given payload.\n */\n testCondition(payload: unknown): boolean {\n if (!this.condition) {\n return true;\n }\n\n try {\n return this.condition(payload);\n } catch {\n // If condition throws, treat as not passing\n return false;\n }\n }\n\n /**\n * Resolves tags for the given payload.\n */\n resolveTags(payload: unknown): string[] {\n return this.tagTemplates.map((template) => template.resolve(payload));\n }\n\n /**\n * Resolves keys for the given payload.\n */\n resolveKeys(payload: unknown): string[] {\n return this.keyTemplates.map((template) => template.resolve(payload));\n }\n\n /**\n * Gets rule priority (higher = processed first).\n */\n getPriority(): number {\n return this.priority;\n }\n\n /**\n * Gets the event pattern string.\n */\n getEventPattern(): string {\n return this.eventPattern.toString();\n }\n\n /**\n * Checks if rule has any tags.\n */\n hasTags(): boolean {\n return this.tagTemplates.length > 0;\n }\n\n /**\n * Checks if rule has any keys.\n */\n hasKeys(): boolean {\n return this.keyTemplates.length > 0;\n }\n\n /**\n * Checks if rule has a condition.\n */\n hasCondition(): boolean {\n return this.condition !== undefined;\n }\n}\n","/**\n * AMQP event source adapter.\n * Integrates with RabbitMQ using @golevelup/nestjs-rabbitmq.\n * This is an optional adapter that requires @golevelup/nestjs-rabbitmq to be installed.\n */\n\nimport { Injectable, Inject, OnModuleInit, Logger, Optional } from '@nestjs/common';\n\nimport { AMQP_CONNECTION, CACHE_PLUGIN_OPTIONS, EVENT_INVALIDATION_SERVICE } from '../../../shared/constants';\nimport { ICachePluginOptions } from '../../../shared/types';\nimport { IEventInvalidationService } from '../../application/ports/event-invalidation.port';\n\ninterface IInvalidationMessage {\n payload: unknown;\n timestamp?: number;\n source?: string;\n}\n\n/**\n * AMQP connection interface (from @golevelup/nestjs-rabbitmq).\n * Using minimal interface to avoid tight coupling with the external library.\n */\ninterface IAMQPConnection {\n createSubscriber(\n handler: (msg: IInvalidationMessage, rawMsg: IRawMessage) => Promise<void>,\n options: {\n exchange: string;\n queue: string;\n routingKey: string[];\n queueOptions: { durable: boolean };\n },\n ): Promise<void>;\n}\n\n/**\n * Raw AMQP message interface.\n */\ninterface IRawMessage {\n fields: {\n routingKey: string;\n };\n}\n\n/**\n * AMQP Event Source Adapter.\n * Note: This adapter requires @golevelup/nestjs-rabbitmq to be installed.\n * If not available, the adapter will log a warning and do nothing.\n */\n@Injectable()\nexport class AMQPEventSourceAdapter implements OnModuleInit {\n private readonly logger = new Logger(AMQPEventSourceAdapter.name);\n private amqpConnection: IAMQPConnection | undefined;\n\n constructor(\n @Inject(EVENT_INVALIDATION_SERVICE)\n private readonly invalidationService: IEventInvalidationService,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly config: ICachePluginOptions,\n @Optional() @Inject(AMQP_CONNECTION) amqpConnection?: IAMQPConnection,\n ) {\n this.amqpConnection = amqpConnection;\n }\n\n async onModuleInit(): Promise<void> {\n const source = this.config.invalidation?.source;\n\n if (source !== 'amqp') {\n return;\n }\n\n if (!this.amqpConnection) {\n this.logger.warn('AMQP source configured but @golevelup/nestjs-rabbitmq is not available. ' + 'Install it with: npm install @golevelup/nestjs-rabbitmq');\n return;\n }\n\n const amqpConfig = this.config.invalidation?.amqp;\n if (!amqpConfig) {\n this.logger.warn('AMQP source configured but amqp config is missing');\n return;\n }\n\n const exchange = amqpConfig.exchange ?? 'cache.invalidation';\n const queue = amqpConfig.queue ?? `${this.getServiceName()}.cache.invalidation`;\n const routingKeys = amqpConfig.routingKeys ?? ['#'];\n\n try {\n // Subscribe to invalidation events\n await this.amqpConnection.createSubscriber(\n async (msg: IInvalidationMessage, rawMsg: IRawMessage) => {\n const routingKey = rawMsg.fields.routingKey;\n this.logger.debug(`Received AMQP invalidation event: ${routingKey}`);\n await this.invalidationService.processEvent(routingKey, msg.payload);\n },\n {\n exchange,\n queue,\n routingKey: routingKeys,\n queueOptions: {\n durable: true,\n },\n },\n );\n\n this.logger.log(`AMQP event source initialized: exchange=${exchange}, queue=${queue}, routingKeys=${routingKeys.join(',')}`);\n } catch (error) {\n this.logger.error('Failed to setup AMQP event source:', error);\n throw error;\n }\n }\n\n private getServiceName(): string {\n return process.env.SERVICE_NAME ?? 'app';\n }\n}\n","/**\n * Anti-stampede protection using local singleflight + distributed Redis lock.\n *\n * Two layers of protection:\n * 1. Local singleflight — coalesces concurrent requests within the same process\n * 2. Distributed lock — prevents duplicate loading across multiple instances\n */\n\nimport { Injectable, Inject, Logger } from '@nestjs/common';\nimport { REDIS_DRIVER, IRedisDriver } from '@nestjs-redisx/core';\n\nimport { CACHE_PLUGIN_OPTIONS } from '../../shared/constants';\nimport { StampedeError, LoaderError } from '../../shared/errors';\nimport { ICachePluginOptions, IStampedeResult, IStampedeStats } from '../../shared/types';\nimport { IStampedeProtection } from '../application/ports/stampede-protection.port';\n\n/** Lua script to release lock only if we own it */\nconst RELEASE_LOCK_SCRIPT = `\nif redis.call(\"get\", KEYS[1]) == ARGV[1] then\n return redis.call(\"del\", KEYS[1])\nelse\n return 0\nend\n`.trim();\n\n/** Prefix for stampede lock keys in Redis */\nconst LOCK_PREFIX = '_stampede:';\n\n/** Polling interval when waiting for another loader (ms) */\nconst _POLL_INTERVAL_MS = 50;\n\ninterface IFlight<T> {\n promise: Promise<T>;\n resolve: (value: T) => void;\n reject: (error: Error) => void;\n waiters: number;\n timestamp: number;\n}\n\n@Injectable()\nexport class StampedeProtectionService implements IStampedeProtection {\n private readonly logger = new Logger(StampedeProtectionService.name);\n private readonly flights = new Map<string, IFlight<unknown>>();\n private readonly lockTimeout: number;\n private readonly waitTimeout: number;\n private prevented = 0;\n\n constructor(\n @Inject(CACHE_PLUGIN_OPTIONS)\n private readonly options: ICachePluginOptions,\n @Inject(REDIS_DRIVER)\n private readonly driver: IRedisDriver,\n ) {\n this.lockTimeout = options.stampede?.lockTimeout ?? 5000;\n this.waitTimeout = options.stampede?.waitTimeout ?? 10000;\n }\n\n async protect<T>(key: string, loader: () => Promise<T>): Promise<IStampedeResult<T>> {\n // Layer 1: Local singleflight (same-process deduplication)\n const existingFlight = this.flights.get(key);\n\n if (existingFlight) {\n existingFlight.waiters++;\n this.prevented++;\n const value = await this.waitForFlight<T>(existingFlight as IFlight<T>, key);\n return { value, cached: true, waited: true };\n }\n\n // Create flight SYNCHRONOUSLY before any async work\n // This ensures concurrent calls within the same tick see the flight\n let resolveFunc!: (value: T) => void;\n let rejectFunc!: (error: Error) => void;\n\n const promise = new Promise<T>((resolve, reject) => {\n resolveFunc = resolve;\n rejectFunc = reject;\n });\n\n const flight: IFlight<T> = {\n promise,\n resolve: resolveFunc,\n reject: rejectFunc,\n waiters: 0,\n timestamp: Date.now(),\n };\n\n this.flights.set(key, flight as IFlight<unknown>);\n\n // Layer 2: Try distributed lock (async)\n let lock: { lockKey: string; lockValue: string } | undefined;\n\n try {\n const lockKey = `${LOCK_PREFIX}${key}`;\n const lockValue = this.generateLockValue();\n const lockTtlSeconds = Math.ceil(this.lockTimeout / 1000);\n\n const acquired = await this.tryAcquireLock(lockKey, lockValue, lockTtlSeconds);\n\n if (acquired) {\n lock = { lockKey, lockValue };\n }\n // If not acquired, another instance is loading.\n // We still execute the loader as fallback since we're already the leader\n // in this process (the flight is registered).\n } catch {\n // Lock acquisition failed — proceed without distributed lock\n }\n\n // Execute loader\n try {\n const value = await this.executeLoader(loader, key);\n flight.resolve(value);\n return { value, cached: false, waited: false };\n } catch (error) {\n if (flight.waiters > 0) {\n flight.reject(error as Error);\n }\n throw error;\n } finally {\n setTimeout(() => {\n this.flights.delete(key);\n }, 100);\n\n if (lock) {\n this.releaseLock(lock.lockKey, lock.lockValue).catch((err) => {\n this.logger.warn(`Failed to release lock for \"${key}\": ${err.message}`);\n });\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async clearKey(key: string): Promise<void> {\n const flight = this.flights.get(key);\n if (flight) {\n flight.reject(new Error('Flight cancelled'));\n this.flights.delete(key);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async clearAll(): Promise<void> {\n for (const [, flight] of this.flights.entries()) {\n flight.reject(new Error('All flights cancelled'));\n }\n this.flights.clear();\n }\n\n getStats(): IStampedeStats {\n const stats: IStampedeStats = {\n activeFlights: this.flights.size,\n totalWaiters: 0,\n oldestFlight: 0,\n prevented: this.prevented,\n };\n\n const now = Date.now();\n let oldestTimestamp = now;\n\n for (const flight of this.flights.values()) {\n stats.totalWaiters += flight.waiters;\n if (flight.timestamp < oldestTimestamp) {\n oldestTimestamp = flight.timestamp;\n }\n }\n\n stats.oldestFlight = stats.activeFlights > 0 ? now - oldestTimestamp : 0;\n return stats;\n }\n\n private async waitForFlight<T>(flight: IFlight<T>, key: string): Promise<T> {\n const age = Date.now() - flight.timestamp;\n if (age > this.lockTimeout) {\n throw new StampedeError(key, age);\n }\n\n let timeoutId: NodeJS.Timeout | undefined;\n let timeoutCancelled = false;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n if (!timeoutCancelled) {\n reject(new StampedeError(key, this.waitTimeout));\n }\n }, this.waitTimeout);\n });\n\n try {\n const result = await Promise.race([flight.promise, timeoutPromise]);\n timeoutCancelled = true;\n if (timeoutId) clearTimeout(timeoutId);\n return result;\n } catch (error) {\n timeoutCancelled = true;\n if (timeoutId) clearTimeout(timeoutId);\n throw error;\n }\n }\n\n private async executeLoader<T>(loader: () => Promise<T>, key: string): Promise<T> {\n let timeoutId: NodeJS.Timeout | undefined;\n let timeoutCancelled = false;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n if (!timeoutCancelled) {\n reject(new StampedeError(key, this.lockTimeout));\n }\n }, this.lockTimeout);\n });\n\n try {\n const result = await Promise.race([loader(), timeoutPromise]);\n timeoutCancelled = true;\n if (timeoutId) clearTimeout(timeoutId);\n return result;\n } catch (error) {\n timeoutCancelled = true;\n if (timeoutId) clearTimeout(timeoutId);\n\n if (error instanceof StampedeError) {\n throw error;\n }\n\n throw new LoaderError(key, error as Error);\n }\n }\n\n private async tryAcquireLock(lockKey: string, lockValue: string, ttlSeconds: number): Promise<boolean> {\n try {\n const result = await this.driver.set(lockKey, lockValue, { ex: ttlSeconds, nx: true });\n return result === 'OK';\n } catch (error) {\n this.logger.warn(`Failed to acquire distributed lock: ${(error as Error).message}`);\n return false;\n }\n }\n\n private async releaseLock(lockKey: string, lockValue: string): Promise<void> {\n try {\n await this.driver.eval(RELEASE_LOCK_SCRIPT, [lockKey], [lockValue]);\n } catch (error) {\n this.logger.warn(`Failed to release distributed lock: ${(error as Error).message}`);\n }\n }\n\n private generateLockValue(): string {\n return `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n }\n}\n","/**\n * Stale-While-Revalidate manager.\n * Serves stale data while revalidating in the background.\n */\n\nimport { Injectable, Inject, Logger } from '@nestjs/common';\n\nimport { CACHE_PLUGIN_OPTIONS } from '../../shared/constants';\nimport { ICachePluginOptions, SwrEntry } from '../../shared/types';\nimport { ISwrManager } from '../application/ports/swr-manager.port';\n\ninterface IRevalidationJob<T> {\n key: string;\n loader: () => Promise<T>;\n onSuccess: (value: T) => Promise<void>;\n onError: (error: Error) => void;\n timestamp: number;\n}\n\n@Injectable()\nexport class SwrManagerService implements ISwrManager {\n private readonly logger = new Logger(SwrManagerService.name);\n private readonly jobs = new Map<string, IRevalidationJob<unknown>>();\n private readonly staleTtl: number;\n private readonly enabled: boolean;\n\n constructor(\n @Inject(CACHE_PLUGIN_OPTIONS)\n private readonly options: ICachePluginOptions,\n ) {\n this.enabled = options.swr?.enabled ?? false;\n this.staleTtl = options.swr?.defaultStaleTime ?? 60;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async get<T>(_key: string): Promise<SwrEntry<T> | null> {\n // SWR entries are stored in L2 cache via getSwr/setSwr.\n // This method is not used directly; CacheService accesses L2 store.\n return null;\n }\n\n async set<T>(_key: string, _value: T, _staleTimeSeconds: number): Promise<void> {\n // SWR entries are stored in L2 cache via getSwr/setSwr.\n }\n\n async delete(_key: string): Promise<void> {\n // SWR entries are deleted from L2 cache directly.\n }\n\n isStale<T>(entry: SwrEntry<T>): boolean {\n const now = Date.now();\n return now > entry.staleAt;\n }\n\n isExpired<T>(entry: SwrEntry<T>): boolean {\n const now = Date.now();\n return now > entry.expiresAt;\n }\n\n shouldRevalidate(key: string): boolean {\n // Don't revalidate if job already running\n return !this.jobs.has(key);\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async scheduleRevalidation<T>(key: string, loader: () => Promise<T>, onSuccess: (value: T) => Promise<void>, onError?: (error: Error) => void): Promise<void> {\n // Check if already scheduled\n if (this.jobs.has(key)) {\n this.logger.debug(`Revalidation already scheduled for key: ${key}`);\n return;\n }\n\n const job: IRevalidationJob<T> = {\n key,\n loader,\n onSuccess,\n onError: onError ?? ((error) => this.logger.error(`Revalidation failed for ${key}:`, error)),\n timestamp: Date.now(),\n };\n\n this.jobs.set(key, job as IRevalidationJob<unknown>);\n\n // Execute in background\n setImmediate(() => {\n void this.executeRevalidation(job);\n });\n }\n\n createSwrEntry<T>(value: T, freshTtl: number, staleTtl?: number): SwrEntry<T> {\n const now = Date.now();\n const freshTtlMs = freshTtl * 1000;\n const staleTtlMs = (staleTtl ?? this.staleTtl) * 1000;\n\n return {\n value,\n cachedAt: now,\n staleAt: now + freshTtlMs,\n expiresAt: now + freshTtlMs + staleTtlMs,\n };\n }\n\n getStats() {\n return {\n activeRevalidations: this.jobs.size,\n enabled: this.enabled,\n staleTtl: this.staleTtl,\n };\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async clearRevalidations(): Promise<void> {\n this.jobs.clear();\n }\n\n private async executeRevalidation<T>(job: IRevalidationJob<T>): Promise<void> {\n try {\n this.logger.debug(`Starting revalidation for key: ${job.key}`);\n\n const value = await job.loader();\n\n this.logger.debug(`Revalidation successful for key: ${job.key}`);\n\n await job.onSuccess(value);\n } catch (error) {\n this.logger.error(`Revalidation failed for key: ${job.key}`, error);\n job.onError(error as Error);\n } finally {\n this.jobs.delete(job.key);\n }\n }\n}\n","/**\n * Tag index repository for tag-based cache invalidation.\n * Maintains mapping of tags to cache keys.\n */\n\nimport { Injectable, Inject } from '@nestjs/common';\nimport { REDIS_DRIVER, IRedisDriver } from '@nestjs-redisx/core';\n\nimport { Tag } from '../../../cache/domain/value-objects/tag.vo';\nimport { Tags } from '../../../cache/domain/value-objects/tags.vo';\nimport { CACHE_PLUGIN_OPTIONS, LUA_SCRIPT_LOADER } from '../../../shared/constants';\nimport { TagInvalidationError } from '../../../shared/errors';\nimport { ICachePluginOptions } from '../../../shared/types';\nimport { ITagIndex } from '../../application/ports/tag-index.port';\nimport { LuaScriptLoader } from '../services/lua-script-loader.service';\n\n/** Batch size for tag key deletion and SCAN operations. */\nconst TAG_BATCH_SIZE = 100;\n\n@Injectable()\nexport class TagIndexRepository implements ITagIndex {\n private readonly tagPrefix: string;\n\n constructor(\n @Inject(REDIS_DRIVER) private readonly driver: IRedisDriver,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly options: ICachePluginOptions,\n @Inject(LUA_SCRIPT_LOADER) private readonly luaLoader: LuaScriptLoader,\n ) {\n // Tag prefix should include L2 key prefix\n const l2Prefix = options.l2?.keyPrefix ?? 'cache:';\n const tagIndexPrefix = options.tags?.indexPrefix ?? '_tag:';\n this.tagPrefix = `${l2Prefix}${tagIndexPrefix}`;\n }\n\n async addKeyToTags(key: string, tags: string[]): Promise<void> {\n if (tags.length === 0) {\n return;\n }\n\n try {\n // Validate tags using Tags VO\n const validatedTags = this.validateTags(tags);\n // Tag TTL should be at least as long as the max cache TTL\n // to ensure tag indexes remain valid for all cached entries\n const tagTtl = this.options.tags?.ttl ?? this.options.l2?.maxTtl ?? 86400;\n\n // Cluster-safe: use individual operations instead of Lua script\n // This avoids CROSSSLOT errors when tag keys are on different slots\n const operations = validatedTags.map(async (tag) => {\n const tagKey = this.buildTagKey(tag);\n await this.driver.sadd(tagKey, key);\n await this.driver.expire(tagKey, tagTtl);\n });\n\n await Promise.all(operations);\n } catch (error) {\n throw new TagInvalidationError(tags[0] ?? 'unknown', `Failed to add key \"${key}\" to tags [${tags.join(', ')}]: ${(error as Error).message}`, error as Error);\n }\n }\n\n async removeKeyFromTags(key: string, tags: string[]): Promise<void> {\n if (tags.length === 0) {\n return;\n }\n\n try {\n // Validate tags using Tags VO\n const validatedTags = this.validateTags(tags);\n\n // Cluster-safe: remove from each tag individually\n await Promise.all(\n validatedTags.map(async (tag) => {\n const tagKey = this.buildTagKey(tag);\n await this.driver.srem(tagKey, key);\n }),\n );\n } catch (error) {\n throw new TagInvalidationError(tags[0] ?? 'unknown', `Failed to remove key \"${key}\" from tags [${tags.join(', ')}]: ${(error as Error).message}`, error as Error);\n }\n }\n\n async getKeysByTag(tag: string): Promise<string[]> {\n try {\n // Validate tag using Tag VO\n const validTag = Tag.create(tag);\n const tagKey = this.buildTagKey(validTag.toString());\n const keys = await this.driver.smembers(tagKey);\n return keys;\n } catch (error) {\n throw new TagInvalidationError(tag, `Failed to get keys for tag: ${(error as Error).message}`, error as Error);\n }\n }\n\n async invalidateTag(tag: string): Promise<number> {\n try {\n // Validate tag using Tag VO\n const validTag = Tag.create(tag);\n const tagKey = this.buildTagKey(validTag.toString());\n\n // Get all cache keys for this tag\n const cacheKeys = await this.driver.smembers(tagKey);\n\n if (cacheKeys.length === 0) {\n // Delete empty tag set\n await this.driver.del(tagKey);\n return 0;\n }\n\n // Cluster-safe: delete keys individually to avoid CROSSSLOT errors\n // In standalone/sentinel mode this is slightly slower but works everywhere\n let deletedCount = 0;\n\n // Delete in batches to avoid blocking Redis for too long\n const batchSize = TAG_BATCH_SIZE;\n for (let i = 0; i < cacheKeys.length; i += batchSize) {\n const batch = cacheKeys.slice(i, i + batchSize);\n\n // Delete each key individually (cluster-safe)\n const results = await Promise.all(batch.map((key) => this.driver.del(key)));\n\n deletedCount += results.reduce((sum, result) => sum + result, 0);\n }\n\n // Delete the tag set itself\n await this.driver.del(tagKey);\n\n return deletedCount;\n } catch (error) {\n throw new TagInvalidationError(tag, `Failed to invalidate tag: ${(error as Error).message}`, error as Error);\n }\n }\n\n async invalidateTags(tags: string[]): Promise<number> {\n if (tags.length === 0) {\n return 0;\n }\n\n try {\n // Validate tags using Tags VO\n const validatedTags = this.validateTags(tags);\n\n let totalInvalidated = 0;\n\n for (const tag of validatedTags) {\n const count = await this.invalidateTag(tag);\n totalInvalidated += count;\n }\n\n return totalInvalidated;\n } catch (error) {\n throw new TagInvalidationError(tags[0] ?? 'unknown', `Failed to invalidate tags [${tags.join(', ')}]: ${(error as Error).message}`, error as Error);\n }\n }\n\n async clearAllTags(): Promise<void> {\n try {\n const pattern = `${this.tagPrefix}*`;\n const keys = await this.scanKeys(pattern);\n\n if (keys.length === 0) {\n return;\n }\n\n // Cluster-safe: delete keys individually\n const batchSize = TAG_BATCH_SIZE;\n for (let i = 0; i < keys.length; i += batchSize) {\n const batch = keys.slice(i, i + batchSize);\n\n // Delete each key individually to avoid CROSSSLOT errors\n await Promise.all(batch.map((key) => this.driver.del(key)));\n }\n } catch (error) {\n throw new TagInvalidationError('_all', `Failed to clear all tags: ${(error as Error).message}`, error as Error);\n }\n }\n\n async getTagStats(tag: string): Promise<{ keyCount: number; exists: boolean }> {\n try {\n // Validate tag using Tag VO\n const validTag = Tag.create(tag);\n const tagKey = this.buildTagKey(validTag.toString());\n const exists = (await this.driver.exists(tagKey)) > 0;\n const keyCount = exists ? await this.driver.scard(tagKey) : 0;\n\n return { keyCount, exists };\n } catch {\n return { keyCount: 0, exists: false };\n }\n }\n\n /**\n * Validates tags using Tags value object.\n *\n * @param tags - Array of tag strings\n * @returns Array of validated tag strings\n * @throws CacheError if validation fails\n * @private\n */\n private validateTags(tags: string[]): string[] {\n const maxTags = this.options.tags?.maxTagsPerKey ?? 10;\n const tagsVo = Tags.create(tags, maxTags);\n return tagsVo.toStrings();\n }\n\n private buildTagKey(tag: string): string {\n return `${this.tagPrefix}${tag}`;\n }\n\n private async scanKeys(pattern: string): Promise<string[]> {\n const keys: string[] = [];\n let cursor = 0;\n\n do {\n const result = await this.driver.scan(cursor, {\n match: pattern,\n count: TAG_BATCH_SIZE,\n });\n cursor = parseInt(result[0], 10);\n keys.push(...result[1]);\n } while (cursor !== 0);\n\n return keys;\n }\n}\n","/**\n * Inline Lua scripts for tag-based cache invalidation.\n *\n * Scripts are stored as inline strings to avoid issues with file reading\n * after build (dist directory doesn't contain .lua files).\n */\n\n/**\n * Atomically adds a cache key to multiple tag sets.\n *\n * KEYS[1..N] = tag set keys\n * ARGV[1] = cache key to add\n * ARGV[2] = TTL for tag sets in seconds\n *\n * Returns: number of tag sets updated\n */\nexport const ADD_KEY_TO_TAGS_SCRIPT = `\nlocal cache_key = ARGV[1]\nlocal tag_ttl = tonumber(ARGV[2])\n\nfor i = 1, #KEYS do\n local tag_key = KEYS[i]\n redis.call('SADD', tag_key, cache_key)\n redis.call('EXPIRE', tag_key, tag_ttl)\nend\n\nreturn #KEYS\n`.trim();\n\n/**\n * Atomically invalidates all cache keys for a tag.\n *\n * KEYS[1] = tag set key (e.g., \"cache:_tag:users\")\n *\n * Returns: number of deleted cache keys\n */\nexport const INVALIDATE_TAG_SCRIPT = `\nlocal tag_key = KEYS[1]\n\n-- Get all cache keys for this tag\nlocal cache_keys = redis.call('SMEMBERS', tag_key)\n\nif #cache_keys == 0 then\n -- Delete empty tag set and return 0\n redis.call('DEL', tag_key)\n return 0\nend\n\n-- Delete all cache keys\nlocal deleted = 0\nfor i = 1, #cache_keys do\n local result = redis.call('DEL', cache_keys[i])\n deleted = deleted + result\nend\n\n-- Delete the tag set itself\nredis.call('DEL', tag_key)\n\nreturn deleted\n`.trim();\n","/**\n * Lua script loader service.\n * Loads inline Lua scripts and registers them with Redis.\n *\n * Scripts are stored as inline strings to avoid issues with file reading\n * after build (dist directory doesn't contain .lua files).\n */\n\nimport { Injectable, Inject, OnModuleInit, Logger } from '@nestjs/common';\nimport { REDIS_DRIVER, IRedisDriver } from '@nestjs-redisx/core';\n\nimport { ADD_KEY_TO_TAGS_SCRIPT, INVALIDATE_TAG_SCRIPT } from '../scripts/lua-scripts';\n\n/**\n * Map of script names to their inline content.\n */\nconst SCRIPTS: Record<string, string> = {\n 'invalidate-tag': INVALIDATE_TAG_SCRIPT,\n 'add-key-to-tags': ADD_KEY_TO_TAGS_SCRIPT,\n};\n\n@Injectable()\nexport class LuaScriptLoader implements OnModuleInit {\n private readonly logger = new Logger(LuaScriptLoader.name);\n private readonly scriptShas = new Map<string, string>();\n\n constructor(@Inject(REDIS_DRIVER) private readonly driver: IRedisDriver) {}\n\n async onModuleInit(): Promise<void> {\n await this.loadScripts();\n }\n\n /**\n * Loads all Lua scripts into Redis.\n */\n private async loadScripts(): Promise<void> {\n for (const [scriptName, scriptContent] of Object.entries(SCRIPTS)) {\n try {\n // Load script into Redis and get SHA\n const sha = await this.driver.scriptLoad(scriptContent);\n this.scriptShas.set(scriptName, sha);\n\n this.logger.debug(`Loaded Lua script: ${scriptName} (SHA: ${sha})`);\n } catch (error) {\n this.logger.error(`Failed to load script ${scriptName}:`, error);\n throw error;\n }\n }\n\n this.logger.log(`Successfully loaded ${this.scriptShas.size} Lua scripts`);\n }\n\n /**\n * Executes a Lua script by name using EVALSHA.\n *\n * @param scriptName - Name of the script\n * @param keys - Redis keys to pass to the script\n * @param args - Arguments to pass to the script\n * @returns Script execution result\n */\n async evalSha(scriptName: string, keys: string[], args: (string | number)[]): Promise<unknown> {\n const sha = this.scriptShas.get(scriptName);\n\n if (!sha) {\n throw new Error(`Lua script not loaded: ${scriptName}`);\n }\n\n return this.driver.evalsha(sha, keys, args);\n }\n\n /**\n * Gets the SHA hash of a loaded script.\n *\n * @param scriptName - Name of the script\n * @returns SHA hash or undefined if not loaded\n */\n getSha(scriptName: string): string | undefined {\n return this.scriptShas.get(scriptName);\n }\n\n /**\n * Checks if a script is loaded.\n *\n * @param scriptName - Name of the script\n * @returns True if script is loaded\n */\n isLoaded(scriptName: string): boolean {\n return this.scriptShas.has(scriptName);\n }\n}\n","/**\n * Cache plugin for NestJS RedisX.\n * Provides L1+L2 caching with anti-stampede, SWR, and tag invalidation.\n */\n\nimport { DynamicModule, ForwardReference, Provider, Type } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { IRedisXPlugin, IPluginAsyncOptions } from '@nestjs-redisx/core';\n\nimport { CacheDecoratorInitializerService } from './cache/application/services/cache-decorator-initializer.service';\nimport { CacheService as InternalCacheService } from './cache/application/services/cache.service';\nimport { WarmupService } from './cache/application/services/warmup.service';\nimport { Serializer } from './cache/domain/services/serializer.service';\nimport { L1MemoryStoreAdapter } from './cache/infrastructure/adapters/l1-memory-store.adapter';\nimport { L2RedisStoreAdapter } from './cache/infrastructure/adapters/l2-redis-store.adapter';\nimport { CacheService } from './cache.service';\nimport { EventInvalidationService } from './invalidation/application/services/event-invalidation.service';\nimport { InvalidationRegistryService } from './invalidation/application/services/invalidation-registry.service';\nimport { InvalidationRule } from './invalidation/domain/entities/invalidation-rule.entity';\nimport { AMQPEventSourceAdapter } from './invalidation/infrastructure/adapters/amqp-event-source.adapter';\nimport { CACHE_PLUGIN_OPTIONS, CACHE_SERVICE, DEFAULT_CACHE_CONFIG, INVALIDATION_REGISTRY, EVENT_INVALIDATION_SERVICE, INVALIDATION_RULES_INIT, L1_CACHE_STORE, L2_CACHE_STORE, STAMPEDE_PROTECTION, TAG_INDEX, SWR_MANAGER, SERIALIZER, LUA_SCRIPT_LOADER } from './shared/constants';\nimport { ICachePluginOptions } from './shared/types';\nimport { StampedeProtectionService } from './stampede/infrastructure/stampede-protection.service';\nimport { SwrManagerService } from './swr/infrastructure/swr-manager.service';\nimport { TagIndexRepository } from './tags/infrastructure/repositories/tag-index.repository';\nimport { LuaScriptLoader } from './tags/infrastructure/services/lua-script-loader.service';\n\nexport class CachePlugin implements IRedisXPlugin {\n readonly name = 'cache';\n readonly version = '0.1.0';\n readonly description = 'Advanced caching with L1+L2, anti-stampede, SWR, and tag invalidation';\n\n private asyncOptions?: IPluginAsyncOptions<ICachePluginOptions>;\n\n constructor(private readonly options: ICachePluginOptions = {}) {}\n\n /**\n * Create a CachePlugin with async configuration from DI.\n *\n * @example\n * ```typescript\n * CachePlugin.registerAsync({\n * imports: [ConfigModule],\n * inject: [ConfigService],\n * useFactory: (config: ConfigService) => ({\n * l1: { maxSize: config.get('CACHE_L1_MAX_SIZE', 1000) },\n * swr: { enabled: config.get('CACHE_SWR_ENABLED', false) },\n * }),\n * })\n * ```\n */\n static registerAsync(asyncOptions: IPluginAsyncOptions<ICachePluginOptions>): CachePlugin {\n const plugin = new CachePlugin();\n plugin.asyncOptions = asyncOptions;\n return plugin;\n }\n\n private static mergeDefaults(options: ICachePluginOptions): ICachePluginOptions {\n return {\n l1: { ...DEFAULT_CACHE_CONFIG.l1, ...options.l1 },\n l2: { ...DEFAULT_CACHE_CONFIG.l2, ...options.l2 },\n stampede: { ...DEFAULT_CACHE_CONFIG.stampede, ...options.stampede },\n swr: { ...DEFAULT_CACHE_CONFIG.swr, ...options.swr },\n tags: { ...DEFAULT_CACHE_CONFIG.tags, ...options.tags },\n warmup: { ...DEFAULT_CACHE_CONFIG.warmup, ...options.warmup },\n keys: { ...DEFAULT_CACHE_CONFIG.keys, ...options.keys },\n invalidation: { ...DEFAULT_CACHE_CONFIG.invalidation, ...options.invalidation },\n };\n }\n\n getImports(): Array<Type<unknown> | DynamicModule | ForwardReference> {\n return this.asyncOptions?.imports ?? [];\n }\n\n getProviders(): Provider[] {\n // Options provider: useFactory (async) or useValue (sync)\n const optionsProvider: Provider = this.asyncOptions\n ? {\n provide: CACHE_PLUGIN_OPTIONS,\n useFactory: async (...args: unknown[]) => {\n const userOptions = await this.asyncOptions!.useFactory(...args);\n return CachePlugin.mergeDefaults(userOptions);\n },\n inject: this.asyncOptions.inject || [],\n }\n : {\n provide: CACHE_PLUGIN_OPTIONS,\n useValue: CachePlugin.mergeDefaults(this.options),\n };\n\n return [\n optionsProvider,\n\n // Domain services\n {\n provide: SERIALIZER,\n useClass: Serializer,\n },\n\n // Infrastructure adapters\n {\n provide: L1_CACHE_STORE,\n useClass: L1MemoryStoreAdapter,\n },\n {\n provide: L2_CACHE_STORE,\n useClass: L2RedisStoreAdapter,\n },\n\n // Application services\n {\n provide: CACHE_SERVICE,\n useClass: InternalCacheService,\n },\n {\n provide: STAMPEDE_PROTECTION,\n useClass: StampedeProtectionService,\n },\n {\n provide: TAG_INDEX,\n useClass: TagIndexRepository,\n },\n {\n provide: SWR_MANAGER,\n useClass: SwrManagerService,\n },\n {\n provide: LUA_SCRIPT_LOADER,\n useClass: LuaScriptLoader,\n },\n\n // Invalidation services\n {\n provide: INVALIDATION_REGISTRY,\n useClass: InvalidationRegistryService,\n },\n {\n provide: EVENT_INVALIDATION_SERVICE,\n useClass: EventInvalidationService,\n },\n\n // Invalidation adapters (optional)\n AMQPEventSourceAdapter,\n\n // Public API\n CacheService,\n\n // @Cached decorator initialization\n CacheDecoratorInitializerService,\n\n // Cache warmup (runs on OnModuleInit if enabled)\n WarmupService,\n\n // Reflector is needed for decorator metadata\n Reflector,\n\n // Factory for registering static invalidation rules\n {\n provide: INVALIDATION_RULES_INIT,\n useFactory: (registry: InvalidationRegistryService, config: ICachePluginOptions) => {\n // Register static rules from config\n if (config.invalidation?.rules && config.invalidation.rules.length > 0) {\n const rules = config.invalidation.rules.map((ruleProps) => InvalidationRule.create(ruleProps));\n registry.registerMany(rules);\n }\n return true;\n },\n inject: [INVALIDATION_REGISTRY, CACHE_PLUGIN_OPTIONS],\n },\n ];\n }\n\n getExports(): Array<string | symbol | Provider> {\n return [CACHE_PLUGIN_OPTIONS, CACHE_SERVICE, CacheService, INVALIDATION_REGISTRY, EVENT_INVALIDATION_SERVICE];\n }\n}\n","/**\n * @InvalidateTags decorator for automatic tag invalidation.\n *\n * Uses immediate proxy-based wrapping (not deferred to interceptor).\n * Works on ANY Injectable class methods (services, repositories, etc).\n */\n\nimport { Logger } from '@nestjs/common';\nimport 'reflect-metadata';\nimport { getCacheService } from './cached.decorator';\nimport { INVALIDATE_TAGS_KEY } from '../../../shared/constants';\n\nconst logger = new Logger('InvalidateTags');\n\nexport interface IInvalidateTagsOptions {\n /**\n * Tags to invalidate. Can be static array or function of method args.\n */\n tags: string[] | ((...args: unknown[]) => string[]);\n\n /**\n * When to invalidate: 'before' or 'after' method execution.\n * Default: 'after'\n */\n when?: 'before' | 'after';\n}\n\n/**\n * Invalidates cache tags when method is called.\n *\n * Works on any Injectable class method, not just controllers.\n *\n * @example\n * ```typescript\n * @Injectable()\n * class UserService {\n * @InvalidateTags({\n * tags: (id: string) => [`user:${id}`, 'users'],\n * when: 'after',\n * })\n * async updateUser(id: string, data: UpdateUserDto): Promise<User> {\n * return this.userRepository.update(id, data);\n * }\n *\n * @InvalidateTags({ tags: ['users'] })\n * async deleteUser(id: string): Promise<void> {\n * await this.userRepository.delete(id);\n * }\n * }\n * ```\n */\nexport function InvalidateTags(options: IInvalidateTagsOptions): MethodDecorator {\n return (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n const originalMethod = descriptor.value as (...args: unknown[]) => Promise<unknown>;\n const when = options.when ?? 'after';\n\n // Replace method with invalidation proxy\n descriptor.value = async function (...args: unknown[]): Promise<unknown> {\n const cacheService = getCacheService();\n\n // Resolve tags\n const tags = typeof options.tags === 'function' ? options.tags(...args) : options.tags;\n\n // Invalidate BEFORE if configured\n if (when === 'before' && cacheService && tags.length > 0) {\n try {\n await cacheService.invalidateTags(tags);\n } catch (error) {\n logger.error(`@InvalidateTags: Failed to invalidate tags before method:`, error);\n }\n }\n\n // Execute original method\n const result = await originalMethod.apply(this, args);\n\n // Invalidate AFTER if configured (default)\n if (when === 'after' && cacheService && tags.length > 0) {\n try {\n await cacheService.invalidateTags(tags);\n } catch (error) {\n logger.error(`@InvalidateTags: Failed to invalidate tags after method:`, error);\n }\n }\n\n return result;\n };\n\n // Preserve original method name\n Object.defineProperty(descriptor.value, 'name', {\n value: originalMethod.name,\n writable: false,\n });\n\n // Store metadata on WRAPPER function for reflection (after replacement)\n Reflect.defineMetadata(INVALIDATE_TAGS_KEY, options, descriptor.value);\n\n return descriptor;\n };\n}\n","/**\n * @Cacheable decorator for automatic method result caching.\n *\n * Caches method results and returns cached value on subsequent calls.\n * Supports key templates with parameter interpolation.\n *\n * @example\n * ```typescript\n * class UserService {\n * @Cacheable({\n * key: 'user:{id}',\n * ttl: 3600,\n * tags: ['users']\n * })\n * async getUser(id: string) {\n * return this.repository.findById(id);\n * }\n *\n * @Cacheable({\n * key: 'user:{userId}:posts:{postId}',\n * ttl: 1800\n * })\n * async getUserPost(userId: string, postId: string) {\n * return this.repository.findPost(userId, postId);\n * }\n * }\n * ```\n */\n\nimport { SetMetadata } from '@nestjs/common';\n\n/**\n * Options for @Cacheable decorator.\n */\nexport interface ICacheableOptions {\n /**\n * Cache key template. Supports parameter interpolation.\n * Use {paramName} to interpolate method parameters.\n *\n * @example 'user:{id}'\n * @example 'post:{userId}:{postId}'\n */\n key: string;\n\n /**\n * TTL in seconds.\n * @default 3600\n */\n ttl?: number;\n\n /**\n * Tags for invalidation.\n * Can be static array or function that returns array.\n */\n tags?: string[] | ((...args: unknown[]) => string[]);\n\n /**\n * Condition to determine if result should be cached.\n * Return false to skip caching for specific cases.\n */\n condition?: (...args: unknown[]) => boolean;\n\n /**\n * Custom key generator function.\n * If provided, overrides template-based key generation.\n */\n keyGenerator?: (...args: unknown[]) => string;\n\n /**\n * Namespace prefix for the key.\n * @default ''\n */\n namespace?: string;\n}\n\n/**\n * Metadata key for @Cacheable decorator.\n */\nexport const CACHEABLE_METADATA_KEY = 'cache:cacheable';\n\n/**\n * @Cacheable decorator.\n *\n * Automatically caches method results using the configured key template.\n * Supports parameter interpolation in key templates.\n *\n * @param options - Caching options\n *\n * @example\n * ```typescript\n * @Cacheable({ key: 'user:{id}', ttl: 3600 })\n * async getUser(id: string) {\n * return await this.repository.findById(id);\n * }\n * ```\n */\nexport function Cacheable(options: ICacheableOptions): MethodDecorator {\n return SetMetadata(CACHEABLE_METADATA_KEY, options);\n}\n","/**\n * @CachePut decorator for cache updates.\n *\n * Always executes the method and updates the cache with the result.\n * Unlike @Cacheable, it doesn't check the cache before execution.\n *\n * @example\n * ```typescript\n * class UserService {\n * @CachePut({\n * key: 'user:{id}',\n * tags: ['users']\n * })\n * async updateUser(id: string, data: UpdateUserDto) {\n * const updated = await this.repository.update(id, data);\n * return updated; // This result will be cached\n * }\n *\n * @CachePut({\n * key: 'user:{user.id}',\n * ttl: 1800\n * })\n * async createUser(user: CreateUserDto) {\n * const created = await this.repository.create(user);\n * return created; // This result will be cached\n * }\n * }\n * ```\n */\n\nimport { SetMetadata } from '@nestjs/common';\n\n/**\n * Options for @CachePut decorator.\n */\nexport interface ICachePutOptions {\n /**\n * Cache key template. Supports parameter interpolation.\n * Use {paramName} to interpolate method parameters.\n * Supports nested properties: {user.id}\n *\n * @example 'user:{id}'\n * @example 'user:{user.id}'\n */\n key: string;\n\n /**\n * TTL in seconds.\n * @default 3600\n */\n ttl?: number;\n\n /**\n * Tags for invalidation.\n * Can be static array or function that returns array.\n */\n tags?: string[] | ((...args: unknown[]) => string[]);\n\n /**\n * Condition to determine if result should be cached.\n * Return false to skip caching for specific cases.\n */\n condition?: (...args: unknown[]) => boolean;\n\n /**\n * Custom key generator function.\n * If provided, overrides template-based key generation.\n */\n keyGenerator?: (...args: unknown[]) => string;\n\n /**\n * Namespace prefix for the key.\n * @default ''\n */\n namespace?: string;\n\n /**\n * Whether to cache null/undefined results.\n * @default false\n */\n cacheNullValues?: boolean;\n}\n\n/**\n * Metadata key for @CachePut decorator.\n */\nexport const CACHE_PUT_METADATA_KEY = 'cache:put';\n\n/**\n * @CachePut decorator.\n *\n * Always executes the method and caches the result.\n * Useful for update operations where you want to refresh the cache.\n *\n * @param options - Cache put options\n *\n * @example\n * ```typescript\n * @CachePut({ key: 'user:{id}', ttl: 3600 })\n * async updateUser(id: string, data: UpdateUserDto) {\n * return await this.repository.update(id, data);\n * }\n * ```\n */\nexport function CachePut(options: ICachePutOptions): MethodDecorator {\n return SetMetadata(CACHE_PUT_METADATA_KEY, options);\n}\n","/**\n * @CacheEvict decorator for cache invalidation.\n *\n * Evicts (removes) cache entries after method execution.\n * Supports multiple keys, tags, and patterns.\n *\n * @example\n * ```typescript\n * class UserService {\n * @CacheEvict({\n * keys: ['user:{id}'],\n * tags: ['users']\n * })\n * async updateUser(id: string, data: UpdateUserDto) {\n * return this.repository.update(id, data);\n * }\n *\n * @CacheEvict({\n * keys: ['user:{userId}:posts:*'],\n * beforeInvocation: false\n * })\n * async deleteUserPosts(userId: string) {\n * return this.repository.deletePosts(userId);\n * }\n * }\n * ```\n */\n\nimport { SetMetadata } from '@nestjs/common';\n\n/**\n * Options for @CacheEvict decorator.\n */\nexport interface ICacheEvictOptions {\n /**\n * Cache keys or key templates to evict.\n * Supports parameter interpolation and wildcards.\n *\n * @example ['user:{id}']\n * @example ['user:{userId}:posts:*']\n */\n keys?: string[];\n\n /**\n * Tags to invalidate.\n * All keys with these tags will be evicted.\n */\n tags?: string[];\n\n /**\n * Whether to evict all cache entries.\n * Use with caution - this clears the entire cache.\n *\n * @default false\n */\n allEntries?: boolean;\n\n /**\n * Whether to evict cache before method invocation.\n * - true: evict before execution\n * - false: evict after execution (default)\n *\n * @default false\n */\n beforeInvocation?: boolean;\n\n /**\n * Condition to determine if cache should be evicted.\n * Return false to skip eviction for specific cases.\n */\n condition?: (...args: unknown[]) => boolean;\n\n /**\n * Custom key generator function.\n * If provided, overrides template-based key generation.\n */\n keyGenerator?: (...args: unknown[]) => string[];\n\n /**\n * Namespace prefix for the keys.\n * @default ''\n */\n namespace?: string;\n}\n\n/**\n * Metadata key for @CacheEvict decorator.\n */\nexport const CACHE_EVICT_METADATA_KEY = 'cache:evict';\n\n/**\n * @CacheEvict decorator.\n *\n * Automatically evicts cache entries after (or before) method execution.\n * Supports multiple keys, tags, and pattern matching.\n *\n * @param options - Eviction options\n *\n * @example\n * ```typescript\n * @CacheEvict({ keys: ['user:{id}'], tags: ['users'] })\n * async updateUser(id: string, data: UpdateUserDto) {\n * return await this.repository.update(id, data);\n * }\n * ```\n */\nexport function CacheEvict(options: ICacheEvictOptions = {}): MethodDecorator {\n return SetMetadata(CACHE_EVICT_METADATA_KEY, options);\n}\n","/**\n * Utility functions for cache key generation from templates.\n */\n\nimport { CacheKeyError } from '../shared/errors';\n\n/**\n * Extracts parameter names from method signature.\n *\n * @param method - Method to extract parameters from\n * @returns Array of parameter names\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport function getParameterNames(method: Function): string[] {\n const fnStr = method.toString().replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n const match = fnStr.match(/\\(([^)]*)\\)/);\n\n if (!match?.[1]) {\n return [];\n }\n\n const params = match[1];\n return params\n .split(',')\n .map((param) => param.trim().split('=')[0]?.trim() ?? '')\n .filter((param) => param && param !== '');\n}\n\n/**\n * Gets nested property value from object.\n *\n * @param obj - Object to get value from\n * @param path - Property path (e.g., 'user.id')\n * @returns Property value or undefined\n *\n * @example\n * getNestedValue({ user: { id: '123' } }, 'user.id') // '123'\n */\nexport function getNestedValue(obj: unknown, path: string): unknown {\n if (!obj || typeof obj !== 'object') {\n return undefined;\n }\n\n const keys = path.split('.');\n let value: unknown = obj;\n\n for (const key of keys) {\n if (value === null || value === undefined) {\n return undefined;\n }\n value = (value as Record<string, unknown>)[key];\n }\n\n return value;\n}\n\n/**\n * Generates cache key from template and method arguments.\n *\n * Replaces {paramName} placeholders with actual parameter values.\n * Supports nested properties: {user.id}\n *\n * @param template - Key template (e.g., 'user:{id}')\n * @param method - Method being decorated\n * @param args - Method arguments\n * @param namespace - Optional namespace prefix\n * @returns Generated cache key\n *\n * @throws CacheKeyError if parameter is not found or template is invalid\n *\n * @example\n * ```typescript\n * generateKey('user:{id}', getUserMethod, ['123']) // 'user:123'\n * generateKey('user:{user.id}', updateMethod, [{ id: '456' }]) // 'user:456'\n * ```\n */\nexport function generateKey(\n template: string,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function,\n args: unknown[],\n namespace?: string,\n): string {\n // Extract parameter names from method signature\n const paramNames = getParameterNames(method);\n\n // Build parameter map\n const paramMap = new Map<string, unknown>();\n paramNames.forEach((name, index) => {\n if (index < args.length) {\n paramMap.set(name, args[index]);\n }\n });\n\n // Replace placeholders in template\n let key = template;\n const placeholderRegex = /\\{([^}]+)\\}/g;\n const matches = Array.from(template.matchAll(placeholderRegex));\n\n if (matches.length === 0) {\n // No placeholders, return template as is\n return namespace ? `${namespace}:${template}` : template;\n }\n\n for (const match of matches) {\n const placeholder = match[0]; // e.g., '{id}' or '{user.id}'\n const path = match[1]; // e.g., 'id' or 'user.id'\n\n if (!path) {\n continue; // Skip if no path captured (shouldn't happen)\n }\n\n let value: unknown;\n\n if (path.includes('.')) {\n // Nested property access\n const [rootParam, ...nestedPath] = path.split('.');\n\n if (!rootParam) {\n throw new CacheKeyError(template, 'Invalid nested property path');\n }\n\n const rootValue = paramMap.get(rootParam);\n\n if (rootValue === undefined) {\n throw new CacheKeyError(template, `Parameter '${rootParam}' not found in method signature`);\n }\n\n value = getNestedValue(rootValue, nestedPath.join('.'));\n\n if (value === undefined) {\n throw new CacheKeyError(template, `Nested property '${path}' not found or is undefined`);\n }\n } else {\n // Direct parameter access\n if (!paramMap.has(path)) {\n throw new CacheKeyError(template, `Parameter '${path}' not found in method signature`);\n }\n\n value = paramMap.get(path);\n\n if (value === undefined || value === null) {\n throw new CacheKeyError(template, `Parameter '${path}' is null or undefined`);\n }\n }\n\n // Convert value to string\n const stringValue = String(value);\n\n // Validate value doesn't contain invalid characters\n if (stringValue.includes(':') || stringValue.includes('{') || stringValue.includes('}')) {\n throw new CacheKeyError(template, `Parameter value '${stringValue}' contains invalid characters (:, {, })`);\n }\n\n key = key.replace(placeholder, stringValue);\n }\n\n // Add namespace if provided\n if (namespace) {\n key = `${namespace}:${key}`;\n }\n\n return key;\n}\n\n/**\n * Generates multiple cache keys from templates and method arguments.\n *\n * @param templates - Array of key templates\n * @param method - Method being decorated\n * @param args - Method arguments\n * @param namespace - Optional namespace prefix\n * @returns Array of generated cache keys\n */\nexport function generateKeys(\n templates: string[],\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function,\n args: unknown[],\n namespace?: string,\n): string[] {\n return templates.map((template) => generateKey(template, method, args, namespace));\n}\n\n/**\n * Evaluates tags - either static array or dynamic function.\n *\n * @param tags - Tags definition (array or function)\n * @param args - Method arguments\n * @returns Array of tag names\n */\nexport function evaluateTags(tags: string[] | ((...args: unknown[]) => string[]) | undefined, args: unknown[]): string[] {\n if (!tags) {\n return [];\n }\n\n if (typeof tags === 'function') {\n return tags(...args);\n }\n\n return tags;\n}\n\n/**\n * Evaluates condition - determines if caching should proceed.\n *\n * @param condition - Condition function\n * @param args - Method arguments\n * @returns true if caching should proceed\n */\nexport function evaluateCondition(condition: ((...args: unknown[]) => boolean) | undefined, args: unknown[]): boolean {\n if (!condition) {\n return true;\n }\n\n return condition(...args);\n}\n","/**\n * Cache interceptor for handling @Cacheable, @CachePut, and @CacheEvict decorators.\n */\n\nimport { Injectable, NestInterceptor, ExecutionContext, CallHandler, Logger } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { Observable, from, of } from 'rxjs';\nimport { switchMap, tap } from 'rxjs/operators';\n\nimport { CacheService } from '../cache.service';\nimport { ICacheEvictOptions, CACHE_EVICT_METADATA_KEY } from './cache-evict.decorator';\nimport { ICachePutOptions, CACHE_PUT_METADATA_KEY } from './cache-put.decorator';\nimport { ICacheableOptions, CACHEABLE_METADATA_KEY } from './cacheable.decorator';\nimport { generateKey, generateKeys, evaluateTags, evaluateCondition } from './key-generator.util';\n\n/**\n * Interceptor for cache decorators.\n *\n * Handles:\n * - @Cacheable: Returns cached value or executes and caches result\n * - @CachePut: Always executes and caches result\n * - @CacheEvict: Evicts cache entries before or after execution\n *\n * @example\n * ```typescript\n * @Controller('users')\n * @UseInterceptors(CacheInterceptor)\n * export class UserController {\n * @Get(':id')\n * @Cacheable({ key: 'user:{id}', ttl: 3600 })\n * getUser(@Param('id') id: string) {\n * return this.userService.findOne(id);\n * }\n *\n * @Put(':id')\n * @CachePut({ key: 'user:{id}' })\n * updateUser(@Param('id') id: string, @Body() data: UpdateUserDto) {\n * return this.userService.update(id, data);\n * }\n *\n * @Delete(':id')\n * @CacheEvict({ keys: ['user:{id}'] })\n * deleteUser(@Param('id') id: string) {\n * return this.userService.delete(id);\n * }\n * }\n * ```\n */\n@Injectable()\nexport class CacheInterceptor implements NestInterceptor {\n private readonly logger = new Logger(CacheInterceptor.name);\n\n constructor(\n private readonly cacheService: CacheService,\n private readonly reflector: Reflector,\n ) {}\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {\n const handler = context.getHandler();\n const _target = context.getClass();\n\n // Get metadata from decorators\n const cacheableOptions = this.reflector.get<ICacheableOptions>(CACHEABLE_METADATA_KEY, handler);\n const cachePutOptions = this.reflector.get<ICachePutOptions>(CACHE_PUT_METADATA_KEY, handler);\n const cacheEvictOptions = this.reflector.get<ICacheEvictOptions>(CACHE_EVICT_METADATA_KEY, handler);\n\n // Get method arguments\n const args = context.getArgByIndex(context.getArgs().length - 1) ? context.getArgs() : [];\n\n const method = handler;\n\n // Handle @Cacheable\n if (cacheableOptions) {\n return this.handleCacheable(cacheableOptions, method, args, next);\n }\n\n // Handle @CachePut\n if (cachePutOptions) {\n return this.handleCachePut(cachePutOptions, method, args, next);\n }\n\n // Handle @CacheEvict\n if (cacheEvictOptions) {\n return this.handleCacheEvict(cacheEvictOptions, method, args, next);\n }\n\n // No cache decorator found, proceed normally\n return next.handle();\n }\n\n /**\n * Handles @Cacheable decorator.\n * Returns cached value or executes method and caches result.\n */\n private handleCacheable(\n options: ICacheableOptions,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function,\n args: unknown[],\n next: CallHandler,\n ): Observable<unknown> {\n // Check condition\n if (!evaluateCondition(options.condition, args)) {\n this.logger.debug('Cacheable condition not met, executing method');\n return next.handle();\n }\n\n try {\n // Generate cache key\n const key = options.keyGenerator ? options.keyGenerator(...args) : generateKey(options.key, method, args, options.namespace);\n\n this.logger.debug(`Cacheable: checking cache for key: ${key}`);\n\n // Try to get from cache\n return from(this.cacheService.get(key)).pipe(\n switchMap((cachedValue) => {\n if (cachedValue !== null) {\n this.logger.debug(`Cacheable: cache hit for key: ${key}`);\n return of(cachedValue);\n }\n\n this.logger.debug(`Cacheable: cache miss for key: ${key}, executing method`);\n\n // Cache miss - execute method\n return next.handle().pipe(\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n tap(async (result) => {\n // Cache the result\n const tags = evaluateTags(options.tags, args);\n const ttl = options.ttl ?? 3600;\n\n try {\n await this.cacheService.set(key, result, { ttl, tags });\n this.logger.debug(`Cacheable: cached result for key: ${key}`);\n } catch (error) {\n this.logger.error(`Cacheable: failed to cache result for key ${key}: ${(error as Error).message}`);\n }\n }),\n );\n }),\n );\n } catch (error) {\n this.logger.error(`Cacheable: error processing cache: ${(error as Error).message}`);\n return next.handle();\n }\n }\n\n /**\n * Handles @CachePut decorator.\n * Always executes method and caches the result.\n */\n private handleCachePut(\n options: ICachePutOptions,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function,\n args: unknown[],\n next: CallHandler,\n ): Observable<unknown> {\n // Check condition\n if (!evaluateCondition(options.condition, args)) {\n this.logger.debug('CachePut condition not met, executing method without caching');\n return next.handle();\n }\n\n try {\n // Generate cache key\n const key = options.keyGenerator ? options.keyGenerator(...args) : generateKey(options.key, method, args, options.namespace);\n\n this.logger.debug(`CachePut: executing method for key: ${key}`);\n\n // Execute method\n return next.handle().pipe(\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n tap(async (result) => {\n // Skip caching null/undefined if not allowed\n if ((result === null || result === undefined) && !options.cacheNullValues) {\n this.logger.debug(`CachePut: skipping null/undefined result for key: ${key}`);\n return;\n }\n\n // Cache the result\n const tags = evaluateTags(options.tags, args);\n const ttl = options.ttl ?? 3600;\n\n try {\n await this.cacheService.set(key, result, { ttl, tags });\n this.logger.debug(`CachePut: cached result for key: ${key}`);\n } catch (error) {\n this.logger.error(`CachePut: failed to cache result for key ${key}: ${(error as Error).message}`);\n }\n }),\n );\n } catch (error) {\n this.logger.error(`CachePut: error processing cache: ${(error as Error).message}`);\n return next.handle();\n }\n }\n\n /**\n * Handles @CacheEvict decorator.\n * Evicts cache entries before or after method execution.\n */\n private handleCacheEvict(\n options: ICacheEvictOptions,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function,\n args: unknown[],\n next: CallHandler,\n ): Observable<unknown> {\n // Check condition\n if (!evaluateCondition(options.condition, args)) {\n this.logger.debug('CacheEvict condition not met, executing method without eviction');\n return next.handle();\n }\n\n const evictFn = async () => {\n try {\n // Handle allEntries flag\n if (options.allEntries) {\n this.logger.debug('CacheEvict: clearing all cache entries');\n await this.cacheService.clear();\n return;\n }\n\n // Handle tag-based eviction\n if (options.tags && options.tags.length > 0) {\n this.logger.debug(`CacheEvict: invalidating tags: ${options.tags.join(', ')}`);\n await this.cacheService.invalidateTags(options.tags);\n }\n\n // Handle key-based eviction\n if (options.keys && options.keys.length > 0) {\n const keys = options.keyGenerator ? options.keyGenerator(...args) : generateKeys(options.keys, method, args, options.namespace);\n\n this.logger.debug(`CacheEvict: evicting keys: ${keys.join(', ')}`);\n\n for (const key of keys) {\n // Check if key contains wildcard\n if (key.includes('*')) {\n // Pattern-based invalidation not directly supported\n // Would need to scan all keys or use tags\n this.logger.warn(`CacheEvict: wildcard keys not supported: ${key}. Use tags instead.`);\n } else {\n await this.cacheService.del(key);\n }\n }\n }\n } catch (error) {\n this.logger.error(`CacheEvict: error evicting cache: ${(error as Error).message}`);\n }\n };\n\n // Evict before invocation\n if (options.beforeInvocation) {\n return from(evictFn()).pipe(switchMap(() => next.handle()));\n }\n\n // Evict after invocation (default)\n return next.handle().pipe(\n tap(() => {\n void evictFn();\n }),\n );\n }\n}\n","/**\n * Least Recently Used (LRU) eviction strategy.\n *\n * Evicts the least recently accessed item when cache is full.\n * Uses a Map to maintain insertion order and updates order on access.\n *\n * @example\n * ```typescript\n * const strategy = new LruStrategy<string>();\n *\n * strategy.recordInsert('key1');\n * strategy.recordInsert('key2');\n * strategy.recordAccess('key1'); // key1 is now most recent\n *\n * const victim = strategy.selectVictim(); // Returns 'key2' (least recent)\n * ```\n */\n\nimport { IEvictionStrategy } from './eviction-strategy.interface';\n\nexport class LruStrategy<K = string> implements IEvictionStrategy<K> {\n /**\n * Map maintaining keys in LRU order.\n * JavaScript Map maintains insertion order, so we use delete+set to move to end.\n */\n private readonly keyOrder: Map<K, number>;\n\n /**\n * Timestamp counter for tracking access order\n */\n private timestamp: number;\n\n constructor() {\n this.keyOrder = new Map();\n this.timestamp = 0;\n }\n\n /**\n * Records access to a key, moving it to most recently used position.\n *\n * @param key - Key that was accessed\n */\n recordAccess(key: K): void {\n // Update timestamp for this key\n this.timestamp++;\n this.keyOrder.set(key, this.timestamp);\n }\n\n /**\n * Records insertion of a new key.\n *\n * @param key - Key that was inserted\n */\n recordInsert(key: K): void {\n this.timestamp++;\n this.keyOrder.set(key, this.timestamp);\n }\n\n /**\n * Records deletion of a key.\n *\n * @param key - Key that was deleted\n */\n recordDelete(key: K): void {\n this.keyOrder.delete(key);\n }\n\n /**\n * Selects the least recently used key for eviction.\n *\n * @returns Least recently used key, or undefined if empty\n */\n selectVictim(): K | undefined {\n if (this.keyOrder.size === 0) {\n return undefined;\n }\n\n // Find key with smallest timestamp (least recently used)\n let oldestKey: K | undefined;\n let oldestTimestamp = Infinity;\n\n for (const [key, timestamp] of this.keyOrder.entries()) {\n if (timestamp < oldestTimestamp) {\n oldestTimestamp = timestamp;\n oldestKey = key;\n }\n }\n\n return oldestKey;\n }\n\n /**\n * Clears all tracking data.\n */\n clear(): void {\n this.keyOrder.clear();\n this.timestamp = 0;\n }\n\n /**\n * Gets current number of tracked keys.\n *\n * @returns Number of keys\n */\n size(): number {\n return this.keyOrder.size;\n }\n\n /**\n * Gets all keys in LRU order (oldest to newest).\n *\n * @returns Array of keys sorted by access time\n */\n getKeys(): K[] {\n return Array.from(this.keyOrder.entries())\n .sort(([, a], [, b]) => a - b)\n .map(([key]) => key);\n }\n\n /**\n * Gets keys that should be evicted to reach target size.\n *\n * @param targetSize - Desired size after eviction\n * @returns Array of keys to evict\n */\n getVictims(targetSize: number): K[] {\n const currentSize = this.keyOrder.size;\n if (currentSize <= targetSize) {\n return [];\n }\n\n const numToEvict = currentSize - targetSize;\n const sortedKeys = this.getKeys();\n return sortedKeys.slice(0, numToEvict);\n }\n}\n","/**\n * First In First Out (FIFO) eviction strategy.\n *\n * Evicts the oldest inserted item when cache is full.\n * Does not consider access patterns - only insertion order matters.\n *\n * @example\n * ```typescript\n * const strategy = new FifoStrategy<string>();\n *\n * strategy.recordInsert('key1');\n * strategy.recordInsert('key2');\n * strategy.recordAccess('key1'); // Access doesn't affect order in FIFO\n *\n * const victim = strategy.selectVictim(); // Returns 'key1' (first inserted)\n * ```\n */\n\nimport { IEvictionStrategy } from './eviction-strategy.interface';\n\nexport class FifoStrategy<K = string> implements IEvictionStrategy<K> {\n /**\n * Queue maintaining keys in insertion order.\n * First element is oldest (next to evict).\n */\n private readonly queue: K[];\n\n /**\n * Set for O(1) existence checks\n */\n private readonly keySet: Set<K>;\n\n constructor() {\n this.queue = [];\n this.keySet = new Set();\n }\n\n /**\n * Records access to a key.\n * In FIFO, access doesn't affect eviction order, so this is a no-op.\n *\n * @param _key - Key that was accessed\n */\n recordAccess(_key: K): void {\n // FIFO doesn't care about access - only insertion order matters\n // No-op\n }\n\n /**\n * Records insertion of a new key.\n *\n * @param key - Key that was inserted\n */\n recordInsert(key: K): void {\n // Only add if not already present\n if (!this.keySet.has(key)) {\n this.queue.push(key);\n this.keySet.add(key);\n }\n }\n\n /**\n * Records deletion of a key.\n *\n * @param key - Key that was deleted\n */\n recordDelete(key: K): void {\n if (this.keySet.has(key)) {\n // Remove from queue - O(n) operation but rare\n const index = this.queue.indexOf(key);\n if (index !== -1) {\n this.queue.splice(index, 1);\n }\n this.keySet.delete(key);\n }\n }\n\n /**\n * Selects the oldest inserted key for eviction.\n *\n * @returns Oldest key (first in queue), or undefined if empty\n */\n selectVictim(): K | undefined {\n return this.queue[0];\n }\n\n /**\n * Clears all tracking data.\n */\n clear(): void {\n this.queue.length = 0;\n this.keySet.clear();\n }\n\n /**\n * Gets current number of tracked keys.\n *\n * @returns Number of keys\n */\n size(): number {\n return this.queue.length;\n }\n\n /**\n * Gets all keys in FIFO order (oldest to newest).\n *\n * @returns Array of keys in insertion order\n */\n getKeys(): K[] {\n return [...this.queue];\n }\n\n /**\n * Gets keys that should be evicted to reach target size.\n *\n * @param targetSize - Desired size after eviction\n * @returns Array of keys to evict (oldest first)\n */\n getVictims(targetSize: number): K[] {\n const currentSize = this.queue.length;\n if (currentSize <= targetSize) {\n return [];\n }\n\n const numToEvict = currentSize - targetSize;\n return this.queue.slice(0, numToEvict);\n }\n\n /**\n * Checks if a key is tracked.\n *\n * @param key - Key to check\n * @returns True if key is tracked\n */\n has(key: K): boolean {\n return this.keySet.has(key);\n }\n}\n","/**\n * Least Frequently Used (LFU) eviction strategy.\n *\n * Evicts the least frequently accessed item when cache is full.\n * Tracks access frequency for each key, with insertion order as tiebreaker.\n *\n * @example\n * ```typescript\n * const strategy = new LfuStrategy<string>();\n *\n * strategy.recordInsert('key1');\n * strategy.recordInsert('key2');\n * strategy.recordAccess('key1'); // key1 frequency = 2\n * strategy.recordAccess('key1'); // key1 frequency = 3\n *\n * const victim = strategy.selectVictim(); // Returns 'key2' (frequency = 1)\n * ```\n */\n\nimport { IEvictionStrategy } from './eviction-strategy.interface';\n\ninterface ILfuEntry<K> {\n key: K;\n frequency: number;\n insertOrder: number;\n}\n\nexport class LfuStrategy<K = string> implements IEvictionStrategy<K> {\n private readonly entries: Map<K, ILfuEntry<K>>;\n private insertCounter: number;\n\n constructor() {\n this.entries = new Map();\n this.insertCounter = 0;\n }\n\n /**\n * Records access to a key, incrementing its frequency counter.\n *\n * @param key - Key that was accessed\n */\n recordAccess(key: K): void {\n const entry = this.entries.get(key);\n if (entry) {\n entry.frequency++;\n }\n }\n\n /**\n * Records insertion of a new key with initial frequency of 1.\n *\n * @param key - Key that was inserted\n */\n recordInsert(key: K): void {\n if (!this.entries.has(key)) {\n this.insertCounter++;\n this.entries.set(key, {\n key,\n frequency: 1,\n insertOrder: this.insertCounter,\n });\n }\n }\n\n /**\n * Records deletion of a key.\n *\n * @param key - Key that was deleted\n */\n recordDelete(key: K): void {\n this.entries.delete(key);\n }\n\n /**\n * Selects the least frequently used key for eviction.\n * When frequencies are equal, the oldest inserted key is selected.\n *\n * @returns Least frequently used key, or undefined if empty\n */\n selectVictim(): K | undefined {\n if (this.entries.size === 0) {\n return undefined;\n }\n\n let victim: ILfuEntry<K> | undefined;\n\n for (const entry of this.entries.values()) {\n if (!victim || entry.frequency < victim.frequency || (entry.frequency === victim.frequency && entry.insertOrder < victim.insertOrder)) {\n victim = entry;\n }\n }\n\n return victim?.key;\n }\n\n /**\n * Clears all tracking data.\n */\n clear(): void {\n this.entries.clear();\n this.insertCounter = 0;\n }\n\n /**\n * Gets current number of tracked keys.\n *\n * @returns Number of keys\n */\n size(): number {\n return this.entries.size;\n }\n\n /**\n * Gets all keys sorted by frequency (lowest first), then by insertion order.\n *\n * @returns Array of keys sorted by eviction priority\n */\n getKeys(): K[] {\n return Array.from(this.entries.values())\n .sort((a, b) => a.frequency - b.frequency || a.insertOrder - b.insertOrder)\n .map((entry) => entry.key);\n }\n\n /**\n * Gets keys that should be evicted to reach target size.\n *\n * @param targetSize - Desired size after eviction\n * @returns Array of keys to evict\n */\n getVictims(targetSize: number): K[] {\n const currentSize = this.entries.size;\n if (currentSize <= targetSize) {\n return [];\n }\n\n const numToEvict = currentSize - targetSize;\n const sortedKeys = this.getKeys();\n return sortedKeys.slice(0, numToEvict);\n }\n\n /**\n * Checks if a key is tracked.\n *\n * @param key - Key to check\n * @returns True if key is tracked\n */\n has(key: K): boolean {\n return this.entries.has(key);\n }\n\n /**\n * Gets the frequency count for a key.\n *\n * @param key - Key to check\n * @returns Frequency count, or 0 if key not tracked\n */\n getFrequency(key: K): number {\n return this.entries.get(key)?.frequency ?? 0;\n }\n}\n","/**\n * JSON serializer for cache values.\n *\n * Uses native JSON.stringify/parse for serialization.\n * Best for human-readable data and compatibility.\n *\n * @example\n * ```typescript\n * const serializer = new JsonSerializer();\n *\n * const data = { id: 1, name: 'John' };\n * const serialized = serializer.serialize(data);\n * // '{\"id\":1,\"name\":\"John\"}'\n *\n * const deserialized = serializer.deserialize<User>(serialized);\n * // { id: 1, name: 'John' }\n * ```\n */\n\nimport { ISerializer } from './serializer.interface';\nimport { SerializationError } from '../shared/errors';\n\nexport class JsonSerializer implements ISerializer {\n /**\n * Serializes value to JSON string.\n *\n * @param value - Value to serialize\n * @returns JSON string\n * @throws SerializationError if serialization fails\n */\n serialize<T>(value: T): string {\n try {\n return JSON.stringify(value);\n } catch (error) {\n throw new SerializationError(`JSON serialization failed: ${(error as Error).message}`, error as Error);\n }\n }\n\n /**\n * Deserializes JSON string back to value.\n *\n * @param data - JSON string or buffer\n * @returns Deserialized value\n * @throws SerializationError if deserialization fails\n */\n deserialize<T>(data: string | Buffer): T {\n try {\n const str = Buffer.isBuffer(data) ? data.toString('utf8') : data;\n return JSON.parse(str) as T;\n } catch (error) {\n throw new SerializationError(`JSON deserialization failed: ${(error as Error).message}`, error as Error);\n }\n }\n\n /**\n * Safely tries to deserialize, returns null on error.\n *\n * @param data - JSON string or buffer\n * @returns Deserialized value or null\n */\n tryDeserialize<T>(data: string | Buffer): T | null {\n try {\n return this.deserialize<T>(data);\n } catch {\n return null;\n }\n }\n\n /**\n * Gets content type for JSON.\n *\n * @returns Content type string\n */\n getContentType(): string {\n return 'application/json';\n }\n}\n","/**\n * MessagePack serializer for cache values.\n *\n * Uses msgpackr for binary serialization.\n * More compact and faster than JSON, but requires msgpackr package.\n *\n * Install: npm install msgpackr\n *\n * @example\n * ```typescript\n * const serializer = new MsgpackSerializer();\n *\n * const data = { id: 1, name: 'John', tags: ['user', 'active'] };\n * const serialized = serializer.serialize(data);\n * // Buffer<...> (binary data, ~40% smaller than JSON)\n *\n * const deserialized = serializer.deserialize<User>(serialized);\n * // { id: 1, name: 'John', tags: ['user', 'active'] }\n * ```\n */\n\nimport { ISerializer } from './serializer.interface';\nimport { SerializationError } from '../shared/errors';\n\n/**\n * Msgpackr encoder interface.\n */\ninterface IMsgpackEncoder {\n encode(value: unknown): Buffer;\n}\n\n/**\n * Msgpackr decoder interface.\n */\ninterface IMsgpackDecoder {\n decode(buffer: Buffer): unknown;\n}\n\nexport class MsgpackSerializer implements ISerializer {\n private encoder: IMsgpackEncoder;\n private decoder: IMsgpackDecoder;\n\n constructor() {\n try {\n // Lazy load msgpackr to make it optional\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const msgpackr = require('msgpackr');\n this.encoder = new msgpackr.Encoder({\n useRecords: false, // Don't use msgpack extension records\n structuredClone: true, // Deep clone objects\n });\n this.decoder = new msgpackr.Decoder({\n useRecords: false,\n });\n } catch {\n throw new Error('msgpackr package is required for MsgpackSerializer. Install with: npm install msgpackr');\n }\n }\n\n /**\n * Serializes value to MessagePack buffer.\n *\n * @param value - Value to serialize\n * @returns MessagePack buffer\n * @throws SerializationError if serialization fails\n */\n serialize<T>(value: T): Buffer {\n try {\n return this.encoder.encode(value);\n } catch (error) {\n throw new SerializationError(`MessagePack serialization failed: ${(error as Error).message}`, error as Error);\n }\n }\n\n /**\n * Deserializes MessagePack buffer back to value.\n *\n * @param data - MessagePack buffer or string\n * @returns Deserialized value\n * @throws SerializationError if deserialization fails\n */\n deserialize<T>(data: string | Buffer): T {\n try {\n const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data, 'binary');\n return this.decoder.decode(buffer) as T;\n } catch (error) {\n throw new SerializationError(`MessagePack deserialization failed: ${(error as Error).message}`, error as Error);\n }\n }\n\n /**\n * Safely tries to deserialize, returns null on error.\n *\n * @param data - MessagePack buffer or string\n * @returns Deserialized value or null\n */\n tryDeserialize<T>(data: string | Buffer): T | null {\n try {\n return this.deserialize<T>(data);\n } catch {\n return null;\n }\n }\n\n /**\n * Gets content type for MessagePack.\n *\n * @returns Content type string\n */\n getContentType(): string {\n return 'application/msgpack';\n }\n\n /**\n * Compares serialized size with JSON.\n *\n * @param value - Value to compare\n * @returns Object with sizes and compression ratio\n */\n compareWithJson<T>(value: T): {\n jsonSize: number;\n msgpackSize: number;\n compressionRatio: number;\n } {\n const jsonSize = Buffer.from(JSON.stringify(value), 'utf8').length;\n const msgpackSize = this.serialize(value).length;\n\n return {\n jsonSize,\n msgpackSize,\n compressionRatio: jsonSize / msgpackSize,\n };\n }\n}\n","/**\n * Fluent key builder for cache keys.\n *\n * Provides a convenient API for building cache keys with proper formatting,\n * validation, and separation.\n *\n * @example\n * ```typescript\n * // Simple key\n * const key = KeyBuilder.create()\n * .prefix('app')\n * .segment('user')\n * .segment('123')\n * .build();\n * // 'app:user:123'\n *\n * // With namespace\n * const key = KeyBuilder.create()\n * .namespace('tenant-5')\n * .prefix('cache')\n * .segment('product')\n * .segment('456')\n * .build();\n * // 'tenant-5:cache:product:456'\n *\n * // From template\n * const key = KeyBuilder.fromTemplate('user:{userId}:post:{postId}', {\n * userId: '123',\n * postId: '456',\n * });\n * // 'user:123:post:456'\n *\n * // With versioning\n * const key = KeyBuilder.create()\n * .prefix('cache')\n * .version('v2')\n * .segment('user')\n * .segment('123')\n * .build();\n * // 'cache:v2:user:123'\n * ```\n */\n\nimport { CacheKeyError } from './shared/errors';\n\nexport interface IKeyBuilderOptions {\n /**\n * Separator between segments (default: ':')\n */\n separator?: string;\n\n /**\n * Maximum key length (default: 512)\n */\n maxLength?: number;\n\n /**\n * Whether to validate segments for invalid characters (default: true)\n */\n validate?: boolean;\n\n /**\n * Whether to convert segments to lowercase (default: false)\n */\n lowercase?: boolean;\n}\n\nexport class KeyBuilder {\n private keySegments: string[] = [];\n private options: Required<IKeyBuilderOptions>;\n\n private constructor(options: IKeyBuilderOptions = {}) {\n this.options = {\n separator: options.separator ?? ':',\n maxLength: options.maxLength ?? 512,\n validate: options.validate ?? true,\n lowercase: options.lowercase ?? false,\n };\n }\n\n /**\n * Creates a new KeyBuilder instance.\n *\n * @param options - Builder options\n * @returns New KeyBuilder\n */\n static create(options?: IKeyBuilderOptions): KeyBuilder {\n return new KeyBuilder(options);\n }\n\n /**\n * Creates a key from a template string with placeholders.\n *\n * @param template - Template string (e.g., 'user:{id}:post:{postId}')\n * @param params - Parameter values\n * @param options - Builder options\n * @returns Generated key\n *\n * @example\n * ```typescript\n * KeyBuilder.fromTemplate('user:{id}', { id: '123' })\n * // 'user:123'\n *\n * KeyBuilder.fromTemplate('user:{userId}:post:{postId}', {\n * userId: '123',\n * postId: '456',\n * })\n * // 'user:123:post:456'\n * ```\n */\n static fromTemplate(template: string, params: Record<string, string | number>, options?: IKeyBuilderOptions): string {\n let result = template;\n const placeholderRegex = /\\{([^}]+)\\}/g;\n\n const matches = Array.from(template.matchAll(placeholderRegex));\n\n for (const match of matches) {\n const placeholder = match[0]; // e.g., '{id}'\n const paramName = match[1]; // e.g., 'id'\n\n if (!paramName) {\n continue;\n }\n\n if (!(paramName in params)) {\n throw new CacheKeyError(template, `Parameter '${paramName}' not found in params`);\n }\n\n const value = params[paramName];\n if (value === null || value === undefined) {\n throw new CacheKeyError(template, `Parameter '${paramName}' is null or undefined`);\n }\n\n result = result.replace(placeholder, String(value));\n }\n\n // Validate the final key\n const builder = new KeyBuilder(options);\n builder.validateKey(result);\n\n return result;\n }\n\n /**\n * Creates a key from an array of segments.\n *\n * @param segments - Array of key segments\n * @param options - Builder options\n * @returns Generated key\n */\n static fromSegments(segments: string[], options?: IKeyBuilderOptions): string {\n const builder = new KeyBuilder(options);\n segments.forEach((segment) => builder.segment(segment));\n return builder.build();\n }\n\n /**\n * Adds a namespace segment (first segment).\n *\n * @param ns - Namespace value\n * @returns This builder for chaining\n */\n namespace(ns: string): this {\n this.keySegments.unshift(this.normalizeSegment(ns));\n return this;\n }\n\n /**\n * Adds a prefix segment.\n *\n * @param prefix - Prefix value\n * @returns This builder for chaining\n */\n prefix(prefix: string): this {\n return this.segment(prefix);\n }\n\n /**\n * Adds a version segment.\n *\n * @param version - Version value (e.g., 'v1', 'v2')\n * @returns This builder for chaining\n */\n version(version: string): this {\n return this.segment(version);\n }\n\n /**\n * Adds a segment to the key.\n *\n * @param value - Segment value\n * @returns This builder for chaining\n */\n segment(value: string | number): this {\n this.keySegments.push(this.normalizeSegment(String(value)));\n return this;\n }\n\n /**\n * Adds multiple segments at once.\n *\n * @param values - Array of segment values\n * @returns This builder for chaining\n */\n segments(...values: Array<string | number>): this {\n values.forEach((value) => this.segment(value));\n return this;\n }\n\n /**\n * Adds a tag segment (useful for grouping).\n *\n * @param tag - Tag value\n * @returns This builder for chaining\n */\n tag(tag: string): this {\n this.segment('tag');\n this.segment(tag);\n return this;\n }\n\n /**\n * Adds timestamp segment.\n *\n * @param timestamp - Unix timestamp (default: now)\n * @returns This builder for chaining\n */\n timestamp(timestamp?: number): this {\n return this.segment(timestamp ?? Date.now());\n }\n\n /**\n * Adds a hash segment from an object.\n * Useful for cache keys based on complex objects.\n *\n * @param obj - Object to hash\n * @returns This builder for chaining\n */\n hash(obj: unknown): this {\n const hash = this.simpleHash(JSON.stringify(obj));\n return this.segment(hash);\n }\n\n /**\n * Builds and returns the final key.\n *\n * @returns Generated cache key\n * @throws CacheKeyError if key is invalid\n */\n build(): string {\n if (this.keySegments.length === 0) {\n throw new CacheKeyError('', 'Cannot build key with no segments');\n }\n\n const key = this.keySegments.join(this.options.separator);\n this.validateKey(key);\n\n return key;\n }\n\n /**\n * Resets the builder to initial state.\n *\n * @returns This builder for chaining\n */\n reset(): this {\n this.keySegments = [];\n return this;\n }\n\n /**\n * Gets current segments.\n *\n * @returns Array of segments\n */\n getSegments(): string[] {\n return [...this.keySegments];\n }\n\n /**\n * Normalizes a segment value.\n *\n * @param value - Segment value\n * @returns Normalized value\n */\n private normalizeSegment(value: string): string {\n let normalized = value.trim();\n\n if (this.options.lowercase) {\n normalized = normalized.toLowerCase();\n }\n\n if (this.options.validate) {\n // Check for invalid characters\n const invalidChars = [this.options.separator, '{', '}', ' ', '\\n', '\\r', '\\t'];\n for (const char of invalidChars) {\n if (normalized.includes(char)) {\n throw new CacheKeyError(normalized, `Segment contains invalid character: '${char}'`);\n }\n }\n\n // Check for empty segment\n if (normalized.length === 0) {\n throw new CacheKeyError(normalized, 'Segment cannot be empty');\n }\n }\n\n return normalized;\n }\n\n /**\n * Validates a complete key.\n *\n * @param key - Key to validate\n * @throws CacheKeyError if key is invalid\n */\n private validateKey(key: string): void {\n if (!this.options.validate) {\n return;\n }\n\n if (key.length === 0) {\n throw new CacheKeyError(key, 'Key cannot be empty');\n }\n\n if (key.length > this.options.maxLength) {\n throw new CacheKeyError(key, `Key length ${key.length} exceeds maximum ${this.options.maxLength}`);\n }\n\n // Check for invalid patterns\n if (key.startsWith(this.options.separator) || key.endsWith(this.options.separator)) {\n throw new CacheKeyError(key, 'Key cannot start or end with separator');\n }\n\n // Check for consecutive separators\n const consecutiveSeparators = this.options.separator + this.options.separator;\n if (key.includes(consecutiveSeparators)) {\n throw new CacheKeyError(key, 'Key cannot contain consecutive separators');\n }\n }\n\n /**\n * Simple hash function for objects.\n *\n * @param str - String to hash\n * @returns Hash string\n */\n private simpleHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash).toString(36);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/shared/constants/index.ts","../src/cache/api/decorators/cached.decorator.ts","../src/invalidation/infrastructure/decorators/invalidate-on.decorator.ts","../src/cache/application/services/cache-decorator-initializer.service.ts","../src/shared/errors/index.ts","../src/cache/domain/value-objects/cache-entry.vo.ts","../src/cache/domain/value-objects/cache-key.vo.ts","../src/cache/domain/value-objects/tag.vo.ts","../src/cache/domain/value-objects/tags.vo.ts","../src/cache/domain/value-objects/ttl.vo.ts","../src/cache/application/services/cache.service.ts","../src/cache/application/services/warmup.service.ts","../src/cache/domain/services/serializer.service.ts","../src/cache/infrastructure/adapters/l1-memory-store.adapter.ts","../src/cache/infrastructure/adapters/l2-redis-store.adapter.ts","../src/cache.service.ts","../src/invalidation/application/services/event-invalidation.service.ts","../src/invalidation/application/services/invalidation-registry.service.ts","../src/invalidation/domain/value-objects/event-pattern.vo.ts","../src/invalidation/domain/value-objects/tag-template.vo.ts","../src/invalidation/domain/entities/invalidation-rule.entity.ts","../src/invalidation/infrastructure/adapters/amqp-event-source.adapter.ts","../src/stampede/infrastructure/stampede-protection.service.ts","../src/swr/infrastructure/swr-manager.service.ts","../src/tags/infrastructure/repositories/tag-index.repository.ts","../src/tags/infrastructure/scripts/lua-scripts.ts","../src/tags/infrastructure/services/lua-script-loader.service.ts","../src/cache.plugin.ts","../src/cache/api/decorators/invalidate-tags.decorator.ts","../src/decorators/cacheable.decorator.ts","../src/decorators/cache-put.decorator.ts","../src/decorators/cache-evict.decorator.ts","../src/decorators/key-generator.util.ts","../src/decorators/cache.interceptor.ts","../src/strategies/lru.strategy.ts","../src/strategies/fifo.strategy.ts","../src/strategies/lfu.strategy.ts","../src/serializers/json.serializer.ts","../src/serializers/msgpack.serializer.ts","../src/key-builder.ts"],"names":["Logger","Injectable","Optional","RedisXError","ErrorCode","Inject","REDIS_DRIVER","CacheService","EventInvalidationService","EventEmitter","createHash","InvalidationRegistryService","Reflector","logger","SetMetadata","CacheInterceptor","from","switchMap","of","tap","version"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"name\": \"@nestjs-redisx/cache\",\n \"version\": \"1.0.3\",\n \"description\": \"Advanced caching plugin for NestJS RedisX with L1+L2, anti-stampede, SWR, and tag invalidation\",\n \"author\": \"NestJS RedisX Team\",\n \"license\": \"MIT\",\n \"main\": \"dist/index.js\",\n \"types\": \"dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"require\": \"./dist/index.js\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"test\": \"SKIP_INTEGRATION=true vitest run\",\n \"test:watch\": \"SKIP_INTEGRATION=true vitest\",\n \"test:cov\": \"SKIP_INTEGRATION=true vitest run --coverage\",\n \"test:integration\": \"vitest run test/integration/cache-with-redis.integration.spec.ts\",\n \"test:integration:watch\": \"vitest watch test/integration/cache-with-redis.integration.spec.ts\",\n \"docker:up\": \"docker-compose up -d\",\n \"docker:down\": \"docker-compose down\",\n \"docker:logs\": \"docker-compose logs -f redis\",\n \"test:docker\": \"npm run docker:up && sleep 3 && npm run test:integration; TEST_EXIT=$?; npm run docker:down; exit $TEST_EXIT\",\n \"test:all\": \"npm test && npm run test:integration\",\n \"lint\": \"eslint \\\"{src,test}/**/*.ts\\\"\",\n \"format\": \"prettier --write \\\"{src,test}/**/*.ts\\\"\"\n },\n \"keywords\": [\n \"nestjs\",\n \"redis\",\n \"cache\",\n \"l1\",\n \"l2\",\n \"stampede\",\n \"swr\",\n \"tags\",\n \"invalidation\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/nestjs-redisx/nestjs-redisx.git\",\n \"directory\": \"packages/cache\"\n },\n \"homepage\": \"https://nestjs-redisx.dev/en/reference/cache/\",\n \"bugs\": {\n \"url\": \"https://github.com/nestjs-redisx/nestjs-redisx/issues\"\n },\n \"peerDependencies\": {\n \"@nestjs-redisx/core\": \"^1.0.0\",\n \"@nestjs/common\": \"^10.0.0 || ^11.0.0\",\n \"@nestjs/core\": \"^10.0.0 || ^11.0.0\",\n \"reflect-metadata\": \"^0.2.0\",\n \"rxjs\": \"^7.8.0\"\n },\n \"devDependencies\": {\n \"@nestjs/testing\": \"^10.0.0\",\n \"@types/node\": \"^20.0.0\",\n \"@typescript-eslint/eslint-plugin\": \"^6.0.0\",\n \"@typescript-eslint/parser\": \"^6.0.0\",\n \"eslint\": \"^8.0.0\",\n \"prettier\": \"^3.0.0\",\n \"tsup\": \"^8.0.0\",\n \"typescript\": \"^5.3.0\",\n \"vitest\": \"^1.6.0\",\n \"@vitest/coverage-v8\": \"^1.6.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","/**\n * Shared constants for Cache plugin.\n */\n\n/**\n * Injection tokens.\n */\nexport const CACHE_PLUGIN_OPTIONS = Symbol.for('CACHE_PLUGIN_OPTIONS');\nexport const CACHE_SERVICE = Symbol.for('CACHE_SERVICE');\nexport const L1_CACHE_STORE = Symbol.for('L1_CACHE_STORE');\nexport const L2_CACHE_STORE = Symbol.for('L2_CACHE_STORE');\nexport const STAMPEDE_PROTECTION = Symbol.for('STAMPEDE_PROTECTION');\nexport const TAG_INDEX = Symbol.for('TAG_INDEX');\nexport const SWR_MANAGER = Symbol.for('SWR_MANAGER');\nexport const TAG_CONFIG = Symbol.for('TAG_CONFIG');\nexport const SERIALIZER = Symbol.for('SERIALIZER');\nexport const INVALIDATION_REGISTRY = Symbol.for('INVALIDATION_REGISTRY');\nexport const EVENT_INVALIDATION_SERVICE = Symbol.for('EVENT_INVALIDATION_SERVICE');\nexport const LUA_SCRIPT_LOADER = Symbol.for('LUA_SCRIPT_LOADER');\nexport const INVALIDATION_RULES_INIT = Symbol.for('INVALIDATION_RULES_INIT');\nexport const AMQP_CONNECTION = Symbol.for('AMQP_CONNECTION');\n\n/**\n * Metadata keys for decorators.\n */\nexport const CACHE_OPTIONS_KEY = 'cache:options';\nexport const INVALIDATE_TAGS_KEY = 'cache:invalidate:tags';\n\n/**\n * Default configuration values.\n */\nexport const DEFAULT_CACHE_CONFIG = {\n l1: {\n enabled: true,\n maxSize: 1000,\n ttl: 60,\n evictionPolicy: 'lru' as const,\n },\n l2: {\n enabled: true,\n defaultTtl: 3600,\n maxTtl: 86400,\n keyPrefix: 'cache:',\n clientName: 'default',\n },\n stampede: {\n enabled: true,\n lockTimeout: 5000,\n waitTimeout: 10000,\n fallback: 'load' as const,\n },\n swr: {\n enabled: false,\n defaultStaleTime: 60,\n },\n tags: {\n enabled: true,\n indexPrefix: '_tag:',\n maxTagsPerKey: 10,\n },\n warmup: {\n enabled: false,\n concurrency: 10,\n },\n keys: {\n maxLength: 1024,\n version: 'v1',\n separator: ':',\n },\n invalidation: {\n enabled: true,\n source: 'internal' as const,\n deduplicationTtl: 60,\n },\n} as const;\n","/**\n * @Cached decorator for method-level caching.\n *\n * Uses immediate proxy-based wrapping (not deferred to module init).\n * Works on ANY Injectable class methods (services, repositories, etc).\n */\n\nimport { Logger } from '@nestjs/common';\nimport 'reflect-metadata';\nimport { CACHE_OPTIONS_KEY } from '../../../shared/constants';\n\nconst logger = new Logger('Cached');\n\n/**\n * Cache service interface for decorator use.\n * Minimal subset of ICacheService needed by decorators.\n */\ninterface IDecoratorCacheService {\n get<T>(key: string): Promise<T | null>;\n set<T>(\n key: string,\n value: T,\n options?: {\n ttl?: number;\n tags?: string[];\n strategy?: 'l1-only' | 'l2-only' | 'l1-l2';\n },\n ): Promise<void>;\n getOrSet<T>(\n key: string,\n loader: () => Promise<T>,\n options?: {\n ttl?: number;\n tags?: string[];\n strategy?: 'l1-only' | 'l2-only' | 'l1-l2';\n swr?: { enabled?: boolean; staleTime?: number };\n unless?: (result: unknown) => boolean;\n },\n ): Promise<T>;\n invalidateTags(tags: string[]): Promise<number>;\n deleteMany(keys: string[]): Promise<number>;\n}\n\n/**\n * Context provider interface for decorator use.\n */\ninterface IDecoratorContextProvider {\n get<T = unknown>(key: string): T | undefined;\n}\n\n/**\n * Plugin options subset needed by decorators for context enrichment.\n */\ninterface IDecoratorPluginOptions {\n contextProvider?: IDecoratorContextProvider;\n contextKeys?: string[];\n keys?: {\n separator?: string;\n };\n}\n\n// Global service registry for lazy injection\nlet globalCacheServiceGetter: (() => IDecoratorCacheService) | null = null;\nlet globalPluginOptions: IDecoratorPluginOptions | null = null;\n\n/**\n * Register cache service getter for lazy injection.\n * Called by CacheDecoratorInitializerService during initialization.\n */\nexport function registerCacheServiceGetter(getter: () => IDecoratorCacheService): void {\n globalCacheServiceGetter = getter;\n}\n\n/**\n * Register plugin options for context enrichment in decorators.\n * Called by CacheDecoratorInitializerService during initialization.\n */\nexport function registerCachePluginOptions(options: IDecoratorPluginOptions): void {\n globalPluginOptions = options;\n}\n\n/**\n * Get the registered cache service.\n * Used by other cache decorators (@InvalidateTags, etc.)\n */\nexport function getCacheService(): IDecoratorCacheService | null {\n return globalCacheServiceGetter ? globalCacheServiceGetter() : null;\n}\n\nexport interface ICachedOptions {\n /**\n * Cache key template. Use {0}, {1}, etc. for method arguments.\n * Example: 'user:{0}' for first argument.\n *\n * If omitted, key is auto-generated as `ClassName:methodName:args`.\n */\n key?: string;\n\n /**\n * TTL in seconds. Defaults to plugin's defaultTtl.\n */\n ttl?: number;\n\n /**\n * Tags for invalidation. Can be static array or function of args.\n */\n tags?: string[] | ((...args: unknown[]) => string[]);\n\n /**\n * Cache strategy: where to store the cached value.\n * - 'l1-only': Only in-memory cache\n * - 'l2-only': Only Redis cache\n * - 'l1-l2': Both layers (default)\n */\n strategy?: 'l1-only' | 'l2-only' | 'l1-l2';\n\n /**\n * Condition to check BEFORE method execution.\n * If returns false, skip caching and execute method.\n */\n condition?: (...args: unknown[]) => boolean;\n\n /**\n * Condition to check AFTER method execution.\n * If returns true, don't cache the result.\n */\n unless?: (result: unknown, ...args: unknown[]) => boolean;\n\n /**\n * Additional context keys to vary cache by.\n * Values are resolved from contextProvider at call time.\n * Adds to (not replaces) global contextKeys.\n *\n * Works on any Injectable — values come from contextProvider (CLS, AsyncLocalStorage, etc.),\n * not from HTTP headers. Ignored if contextProvider is not configured.\n *\n * @example\n * ```typescript\n * @Cached({\n * key: 'products',\n * varyBy: ['locale', 'currency'] // resolved from contextProvider\n * })\n * ```\n */\n varyBy?: string[];\n\n /**\n * Stale-while-revalidate configuration.\n * If enabled, serves stale data while revalidating in background.\n */\n swr?: {\n enabled?: boolean;\n staleTime?: number;\n };\n\n /**\n * Context keys to include in cache key (from contextProvider).\n * Overrides global contextKeys for this method.\n */\n contextKeys?: string[];\n\n /**\n * Disable context enrichment for this method.\n * Set to true to prevent automatic context keys from being added.\n *\n * @default false\n */\n skipContext?: boolean;\n}\n\n/**\n * Caches method return value using immediate proxy-based wrapping.\n *\n * Works on any Injectable class method, not just controllers.\n * Wrapping happens immediately when decorator is applied.\n *\n * @example\n * ```typescript\n * @Injectable()\n * class UserService {\n * @Cached({ key: 'user:{0}', ttl: 3600, tags: ['users'] })\n * async getUser(id: string): Promise<User> {\n * return this.userRepository.findById(id);\n * }\n * }\n * ```\n */\nexport function Cached(options: ICachedOptions = {}): MethodDecorator {\n return (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n const originalMethod = descriptor.value as (...args: unknown[]) => Promise<unknown>;\n\n // Replace method with caching proxy\n descriptor.value = async function (...args: unknown[]): Promise<unknown> {\n // Lazy inject cache service on first call\n if (!globalCacheServiceGetter) {\n logger.warn(`@Cached: CacheService not yet available, executing method without cache`);\n return originalMethod.apply(this, args);\n }\n\n const cacheService = globalCacheServiceGetter();\n if (!cacheService) {\n logger.warn(`@Cached: CacheService getter returned null, executing method without cache`);\n return originalMethod.apply(this, args);\n }\n\n // Check condition (before execution) — if false, bypass cache entirely\n if (options.condition && !options.condition(...args)) {\n return originalMethod.apply(this, args);\n }\n\n // Build cache key with context enrichment\n const key = buildCacheKey(this, propertyKey.toString(), args, options);\n\n // Resolve tags (static array or function of args)\n const tags = typeof options.tags === 'function' ? options.tags(...args) : options.tags;\n\n // Delegate to getOrSet — stampede protection is handled internally\n try {\n return await cacheService.getOrSet(key, () => originalMethod.apply(this, args), {\n ttl: options.ttl,\n tags,\n strategy: options.strategy,\n swr: options.swr,\n unless: options.unless ? (result: unknown) => options.unless!(result, ...args) : undefined,\n });\n } catch (error) {\n logger.error(`@Cached: getOrSet error for key ${key}:`, error);\n // Fail-open: execute method without cache\n return originalMethod.apply(this, args);\n }\n };\n\n // Preserve original method name\n Object.defineProperty(descriptor.value, 'name', {\n value: originalMethod.name,\n writable: false,\n });\n\n // Store metadata on WRAPPER function for reflection (after replacement)\n Reflect.defineMetadata(CACHE_OPTIONS_KEY, options, descriptor.value);\n\n return descriptor;\n };\n}\n\n/**\n * Builds cache key from template and arguments, then enriches with context.\n *\n * Key pipeline:\n * 1. Base key: from template ({0}, {1}) or auto-generated (Class:method:args)\n * 2. Context enrichment: contextKeys + varyBy resolved from contextProvider\n * Format: `baseKey:_ctx_:key1.val1:key2.val2`\n */\nfunction buildCacheKey(instance: object, methodName: string, args: unknown[], options: ICachedOptions): string {\n const className = (instance.constructor as { name: string }).name;\n\n // Step 1: Build base key\n let baseKey: string;\n if (options.key) {\n baseKey = interpolateKey(options.key, args);\n } else {\n const argKeys = args.map((arg) => serializeArg(arg)).join(':');\n baseKey = `${className}:${methodName}:${argKeys}`;\n }\n\n // Step 2: Enrich with context (contextKeys + varyBy)\n return enrichWithContext(baseKey, options);\n}\n\n/**\n * Enriches a base key with context values from contextProvider.\n * Uses the same _ctx_ marker format as the internal cache service\n * so enrichKeyWithContext() won't double-enrich.\n */\nfunction enrichWithContext(key: string, options: ICachedOptions): string {\n // Skip if explicitly disabled\n if (options.skipContext) return key;\n\n const pluginOpts = globalPluginOptions;\n if (!pluginOpts?.contextProvider) return key;\n\n const separator = pluginOpts.keys?.separator ?? ':';\n const marker = `${separator}_ctx_${separator}`;\n\n const contextMap = new Map<string, string>();\n\n // Determine which context keys to use:\n // - Per-decorator contextKeys override global ones\n // - varyBy adds additional keys on top\n const contextKeys = options.contextKeys ?? pluginOpts.contextKeys ?? [];\n\n // Resolve context keys from provider\n for (const ctxKey of contextKeys) {\n const value = pluginOpts.contextProvider.get<string>(ctxKey);\n if (value !== undefined && value !== null) {\n if (typeof value === 'object') {\n logger.warn(`Context key \"${ctxKey}\" has object value, skipping (use primitives for context keys)`);\n continue;\n }\n contextMap.set(ctxKey, String(value));\n }\n }\n\n // Resolve varyBy keys from provider (additional to contextKeys)\n if (options.varyBy) {\n for (const name of options.varyBy) {\n if (!contextMap.has(name)) {\n const value = pluginOpts.contextProvider.get<string>(name);\n if (value !== undefined && value !== null) {\n if (typeof value === 'object') {\n logger.warn(`varyBy key \"${name}\" has object value, skipping (use primitives for varyBy keys)`);\n continue;\n }\n contextMap.set(name, String(value));\n }\n }\n }\n }\n\n if (contextMap.size === 0) return key;\n\n // Sort for consistent key ordering\n const sortedEntries = [...contextMap.entries()].sort(([a], [b]) => a.localeCompare(b));\n const suffix = sortedEntries.map(([k, v]) => `${sanitizeForKey(k)}.${sanitizeForKey(v)}`).join(separator);\n\n return `${key}${marker}${suffix}`;\n}\n\n/**\n * Sanitizes a value for use in cache key (removes non-allowed characters).\n */\nfunction sanitizeForKey(value: string): string {\n return String(value).replace(/[^a-zA-Z0-9\\-_]/g, '_');\n}\n\n/**\n * Interpolates key template with arguments.\n */\nfunction interpolateKey(template: string, args: unknown[]): string {\n return template.replace(/\\{(\\d+)}/g, (match, index: string) => {\n const argIndex = parseInt(index, 10);\n if (argIndex < args.length) {\n return serializeArg(args[argIndex]);\n }\n return match;\n });\n}\n\n/**\n * Serializes argument to string for cache key.\n * Objects are serialized with sorted keys for deterministic output.\n */\nfunction serializeArg(arg: unknown): string {\n if (arg === null || arg === undefined) {\n return 'null';\n }\n\n if (typeof arg === 'string' || typeof arg === 'number' || typeof arg === 'boolean') {\n return String(arg);\n }\n\n if (typeof arg === 'object') {\n try {\n return stableStringify(arg);\n } catch {\n return 'object';\n }\n }\n\n return 'unknown';\n}\n\n/**\n * Produces a deterministic JSON string by sorting object keys recursively.\n * Ensures {b:2, a:1} and {a:1, b:2} produce the same cache key.\n */\nfunction stableStringify(value: unknown): string {\n if (value === null || value === undefined) {\n return 'null';\n }\n\n // Functions and symbols are not serializable (matches JSON.stringify behavior)\n if (typeof value === 'function' || typeof value === 'symbol') {\n return 'null';\n }\n\n if (typeof value !== 'object') {\n // BigInt throws in JSON.stringify; convert to string for safe key generation\n if (typeof value === 'bigint') {\n return String(value);\n }\n return JSON.stringify(value);\n }\n\n // Arrays: preserve order, serialize undefined/functions as null (matches JSON.stringify)\n if (Array.isArray(value)) {\n return '[' + value.map((item) => (item === undefined || typeof item === 'function' || typeof item === 'symbol' ? 'null' : stableStringify(item))).join(',') + ']';\n }\n\n if (value instanceof Date) {\n return JSON.stringify(value);\n }\n\n // Plain objects: sort keys, skip undefined/function/symbol values (matches JSON.stringify)\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n const parts: string[] = [];\n for (const key of keys) {\n const v = obj[key];\n if (v === undefined || typeof v === 'function' || typeof v === 'symbol') {\n continue; // JSON.stringify skips these in objects\n }\n parts.push(JSON.stringify(key) + ':' + stableStringify(v));\n }\n return '{' + parts.join(',') + '}';\n}\n","/**\n * @InvalidateOn decorator.\n * Automatically invalidates cache after method execution based on events.\n *\n * Uses immediate proxy-based wrapping (not deferred to interceptor).\n * Works on ANY Injectable class methods (services, repositories, etc).\n */\n\nimport 'reflect-metadata';\nimport { getCacheService } from '../../../cache/api/decorators/cached.decorator';\n\nexport const INVALIDATE_ON_OPTIONS = Symbol.for('INVALIDATE_ON_OPTIONS');\n\n/**\n * Event invalidation service interface for decorator use.\n */\ninterface IDecoratorEventInvalidationService {\n emit(event: string, payload: unknown): Promise<void>;\n}\n\n// Global service registry for lazy injection (similar to getCacheService pattern)\nlet globalEventInvalidationServiceGetter: (() => IDecoratorEventInvalidationService) | null = null;\n\n/**\n * Register event invalidation service getter for lazy injection.\n * Called by CacheDecoratorInitializerService during initialization.\n */\nexport function registerEventInvalidationServiceGetter(getter: () => IDecoratorEventInvalidationService): void {\n globalEventInvalidationServiceGetter = getter;\n}\n\n/**\n * Get the registered event invalidation service.\n */\nexport function getEventInvalidationService(): IDecoratorEventInvalidationService | null {\n return globalEventInvalidationServiceGetter ? globalEventInvalidationServiceGetter() : null;\n}\n\nexport interface IInvalidateOnOptions {\n /** Events that trigger invalidation */\n events: string[];\n\n /** Tags to invalidate */\n tags?: string[] | ((result: unknown, args: unknown[]) => string[]);\n\n /** Keys to invalidate */\n keys?: string[] | ((result: unknown, args: unknown[]) => string[]);\n\n /** Condition - only invalidate if returns true */\n condition?: (result: unknown, args: unknown[]) => boolean;\n\n /** Publish event after method execution (for distributed invalidation) */\n publish?: boolean;\n}\n\n/**\n * Decorator that invalidates cache after method execution.\n *\n * Works on any Injectable class method, not just controllers.\n *\n * @param options - Invalidation options\n *\n * @example\n * ```typescript\n * @Injectable()\n * class UserService {\n * @InvalidateOn({\n * events: ['user.updated'],\n * tags: (result, [userId]) => [`user:${userId}`, 'users'],\n * })\n * async updateUser(userId: string, data: UpdateUserDto): Promise<User> {\n * return this.userRepo.update(userId, data);\n * }\n *\n * @InvalidateOn({\n * events: ['user.deleted'],\n * keys: (result, [userId]) => [`user:${userId}`],\n * tags: ['users'],\n * })\n * async deleteUser(userId: string): Promise<void> {\n * await this.userRepo.delete(userId);\n * }\n * }\n * ```\n */\nexport function InvalidateOn(options: IInvalidateOnOptions): MethodDecorator {\n return (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n const originalMethod = descriptor.value as (...args: unknown[]) => Promise<unknown>;\n\n // Replace method with invalidation proxy\n descriptor.value = async function (...args: unknown[]): Promise<unknown> {\n // Execute original method first\n const result = await originalMethod.apply(this, args);\n\n // Get cache service for invalidation\n const cacheService = getCacheService();\n\n if (cacheService) {\n try {\n // Check condition\n if (options.condition && !options.condition(result, args)) {\n return result;\n }\n\n // Resolve tags\n const tags = resolveTags(options.tags, result, args);\n\n // Resolve keys\n const keys = resolveKeys(options.keys, result, args);\n\n // Perform invalidation\n if (tags.length > 0) {\n await cacheService.invalidateTags(tags);\n }\n\n if (keys.length > 0) {\n await cacheService.deleteMany(keys);\n }\n\n // Publish event for distributed invalidation\n if (options.publish) {\n const eventInvalidationService = getEventInvalidationService();\n if (eventInvalidationService) {\n // Emit events with result as payload for distributed invalidation\n for (const event of options.events) {\n await eventInvalidationService.emit(event, {\n result,\n args,\n tags,\n keys,\n timestamp: Date.now(),\n });\n }\n }\n }\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('@InvalidateOn: Invalidation failed:', error);\n // Don't propagate error - method already succeeded\n }\n }\n\n return result;\n };\n\n // Preserve original method name\n Object.defineProperty(descriptor.value, 'name', {\n value: originalMethod.name,\n writable: false,\n });\n\n // Store metadata on WRAPPER function for reflection (after replacement)\n Reflect.defineMetadata(INVALIDATE_ON_OPTIONS, options, descriptor.value);\n\n return descriptor;\n };\n}\n\n/**\n * Resolve tags from options.\n */\nfunction resolveTags(tags: string[] | ((result: unknown, args: unknown[]) => string[]) | undefined, result: unknown, args: unknown[]): string[] {\n if (!tags) {\n return [];\n }\n\n if (typeof tags === 'function') {\n return tags(result, args);\n }\n\n return tags;\n}\n\n/**\n * Resolve keys from options.\n */\nfunction resolveKeys(keys: string[] | ((result: unknown, args: unknown[]) => string[]) | undefined, result: unknown, args: unknown[]): string[] {\n if (!keys) {\n return [];\n }\n\n if (typeof keys === 'function') {\n return keys(result, args);\n }\n\n return keys;\n}\n","/**\n * Service for initializing @Cached decorator with lazy cache service injection.\n *\n * Runs on module initialization and registers a getter function that provides\n * access to CacheService for the @Cached decorator's proxy logic.\n */\n\nimport { Injectable, OnModuleInit, Inject, Logger, Optional } from '@nestjs/common';\nimport { ModuleRef } from '@nestjs/core';\n\nimport { IEventInvalidationService } from '../../../invalidation/application/ports/event-invalidation.port';\nimport { registerEventInvalidationServiceGetter } from '../../../invalidation/infrastructure/decorators/invalidate-on.decorator';\nimport { CACHE_SERVICE, CACHE_PLUGIN_OPTIONS, EVENT_INVALIDATION_SERVICE } from '../../../shared/constants';\nimport { ICachePluginOptions } from '../../../shared/types';\nimport { registerCacheServiceGetter, registerCachePluginOptions } from '../../api/decorators/cached.decorator';\nimport { ICacheService } from '../ports/cache-service.port';\n\n@Injectable()\nexport class CacheDecoratorInitializerService implements OnModuleInit {\n private readonly logger = new Logger(CacheDecoratorInitializerService.name);\n\n constructor(\n private readonly moduleRef: ModuleRef,\n @Inject(CACHE_SERVICE) private readonly cacheService: ICacheService,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly pluginOptions: ICachePluginOptions,\n @Optional() @Inject(EVENT_INVALIDATION_SERVICE) private readonly eventInvalidationService?: IEventInvalidationService,\n ) {}\n\n /**\n * Called after all modules are initialized.\n * Registers cache service getter and plugin options for @Cached decorator.\n */\n // eslint-disable-next-line @typescript-eslint/require-await\n async onModuleInit(): Promise<void> {\n this.logger.debug('Registering CacheService getter for @Cached decorator');\n\n // Register getter that provides cache service to decorator\n registerCacheServiceGetter(() => this.cacheService);\n\n // Register plugin options for context enrichment in decorators\n registerCachePluginOptions(this.pluginOptions);\n\n this.logger.log('@Cached decorator initialized and ready to use');\n\n // Register event invalidation service getter for @InvalidateOn decorator\n if (this.eventInvalidationService) {\n this.logger.debug('Registering EventInvalidationService getter for @InvalidateOn decorator');\n registerEventInvalidationServiceGetter(() => this.eventInvalidationService!);\n this.logger.log('@InvalidateOn decorator event publishing initialized');\n }\n }\n}\n","/**\n * Cache plugin error classes.\n */\n\nimport { RedisXError, ErrorCode } from '@nestjs-redisx/core';\n\n/**\n * Base error for cache operations.\n */\nexport class CacheError extends RedisXError {\n constructor(message: string, code: ErrorCode = ErrorCode.OPERATION_FAILED, cause?: Error) {\n super(message, code, cause);\n this.name = 'CacheError';\n }\n}\n\n/**\n * Error for invalid cache keys.\n */\nexport class CacheKeyError extends CacheError {\n constructor(\n public readonly key: string,\n message: string,\n ) {\n super(`Invalid cache key \"${key}\": ${message}`, ErrorCode.CACHE_KEY_INVALID);\n this.name = 'CacheKeyError';\n }\n}\n\n/**\n * Error for serialization failures.\n */\nexport class SerializationError extends CacheError {\n constructor(message: string, cause?: Error) {\n super(`Serialization error: ${message}`, ErrorCode.SERIALIZATION_FAILED, cause);\n this.name = 'SerializationError';\n }\n}\n\n/**\n * Error for loader function failures.\n */\nexport class LoaderError extends CacheError {\n constructor(\n public readonly key: string,\n cause: Error,\n ) {\n super(`Loader failed for key \"${key}\": ${cause.message}`, ErrorCode.OPERATION_FAILED, cause);\n this.name = 'LoaderError';\n }\n}\n\n/**\n * Error for stampede protection timeout.\n */\nexport class StampedeError extends CacheError {\n constructor(\n public readonly key: string,\n public readonly timeout: number,\n ) {\n super(`Stampede protection timeout for key \"${key}\" after ${timeout}ms`, ErrorCode.OPERATION_TIMEOUT);\n this.name = 'StampedeError';\n }\n}\n\n/**\n * Error for tag invalidation failures.\n */\nexport class TagInvalidationError extends CacheError {\n constructor(\n public readonly tag: string,\n message: string,\n cause?: Error,\n ) {\n super(`Tag invalidation failed for \"${tag}\": ${message}`, ErrorCode.OPERATION_FAILED, cause);\n this.name = 'TagInvalidationError';\n }\n}\n","/**\n * CacheEntry value object.\n * Wraps cached value with metadata.\n */\n\nexport class CacheEntry<T> {\n private constructor(\n public readonly value: T,\n public readonly cachedAt: number,\n public readonly ttl: number,\n public readonly tags?: string[],\n ) {}\n\n /**\n * Creates a cache entry.\n *\n * @param value - Value to cache\n * @param ttl - TTL in seconds\n * @param tags - Optional tags\n * @returns CacheEntry instance\n */\n static create<T>(value: T, ttl: number, tags?: string[]): CacheEntry<T> {\n return new CacheEntry(value, Date.now(), ttl, tags);\n }\n\n /**\n * Checks if entry is expired.\n *\n * @returns true if expired, false otherwise\n */\n isExpired(): boolean {\n const expiresAt = this.cachedAt + this.ttl * 1000;\n return Date.now() > expiresAt;\n }\n\n /**\n * Gets time until expiration in milliseconds.\n *\n * @returns Milliseconds until expiration (0 if expired)\n */\n getTimeToLive(): number {\n const expiresAt = this.cachedAt + this.ttl * 1000;\n const remaining = expiresAt - Date.now();\n return Math.max(0, remaining);\n }\n\n /**\n * Gets age of entry in milliseconds.\n *\n * @returns Age in milliseconds\n */\n getAge(): number {\n return Date.now() - this.cachedAt;\n }\n\n /**\n * Checks if entry has a specific tag.\n *\n * @param tag - Tag to check\n * @returns true if entry has the tag\n */\n hasTag(tag: string): boolean {\n return this.tags?.includes(tag) ?? false;\n }\n\n /**\n * Serializes entry to JSON.\n *\n * @returns JSON representation\n */\n toJSON(): {\n value: T;\n cachedAt: number;\n ttl: number;\n tags?: string[];\n } {\n return {\n value: this.value,\n cachedAt: this.cachedAt,\n ttl: this.ttl,\n tags: this.tags,\n };\n }\n\n /**\n * Deserializes entry from JSON.\n *\n * @param json - JSON representation\n * @returns CacheEntry instance\n */\n static fromJSON<T>(json: { value: T; cachedAt: number; ttl: number; tags?: string[] }): CacheEntry<T> {\n return new CacheEntry(json.value, json.cachedAt, json.ttl, json.tags);\n }\n}\n","/**\n * CacheKey value object.\n * Validates and builds cache keys with prefix, version, and validation.\n */\n\nimport { CacheKeyError } from '../../../shared/errors';\n\nexport interface ICacheKeyOptions {\n maxLength?: number;\n prefix?: string;\n version?: string;\n separator?: string;\n}\n\nconst DEFAULT_OPTIONS: Required<ICacheKeyOptions> = {\n maxLength: 512,\n prefix: '',\n version: '',\n separator: ':',\n};\n\nexport class CacheKey {\n private constructor(\n private readonly rawKey: string,\n private readonly options: Required<ICacheKeyOptions>,\n ) {}\n\n /**\n * Creates a validated cache key.\n *\n * @param key - Raw key\n * @param options - Key options\n * @returns CacheKey instance\n * @throws CacheKeyError if validation fails\n */\n static create(key: string, options: ICacheKeyOptions = {}): CacheKey {\n const opts: Required<ICacheKeyOptions> = {\n ...DEFAULT_OPTIONS,\n ...options,\n };\n\n // Normalize: trim whitespace\n const normalizedKey = key.trim();\n\n // Validate key is not empty\n if (!normalizedKey || normalizedKey.length === 0) {\n throw new CacheKeyError(key, 'Key cannot be empty');\n }\n\n // Validate no whitespace\n if (/\\s/.test(normalizedKey)) {\n throw new CacheKeyError(key, 'Key cannot contain whitespace');\n }\n\n // Validate allowed characters (alphanumeric, -, _, :, .)\n if (!/^[a-zA-Z0-9\\-_:.]+$/.test(normalizedKey)) {\n throw new CacheKeyError(key, 'Invalid characters in key. Only alphanumeric, hyphens, underscores, colons, and dots allowed');\n }\n\n // Build full key\n const fullKey = opts.prefix + opts.version + (opts.version ? opts.separator : '') + normalizedKey;\n\n // Validate length\n if (fullKey.length > opts.maxLength) {\n throw new CacheKeyError(normalizedKey, `Key exceeds maximum length (${fullKey.length} > ${opts.maxLength})`);\n }\n\n return new CacheKey(normalizedKey, opts);\n }\n\n /**\n * Returns the full cache key with prefix and version.\n */\n toString(): string {\n return this.options.prefix + this.options.version + (this.options.version ? this.options.separator : '') + this.rawKey;\n }\n\n /**\n * Returns the raw key without prefix/version.\n */\n getRaw(): string {\n return this.rawKey;\n }\n\n /**\n * Returns the prefix.\n */\n getPrefix(): string {\n return this.options.prefix;\n }\n\n /**\n * Returns the version.\n */\n getVersion(): string {\n return this.options.version;\n }\n\n /**\n * Checks equality with another CacheKey.\n */\n equals(other: CacheKey): boolean {\n return this.toString() === other.toString();\n }\n}\n","/**\n * Tag value object.\n * Validates and normalizes cache tags for invalidation.\n */\n\nimport { ErrorCode } from '@nestjs-redisx/core';\n\nimport { CacheError } from '../../../shared/errors';\n\nconst DEFAULT_MAX_LENGTH = 128;\n\nexport class Tag {\n private constructor(private readonly value: string) {}\n\n /**\n * Creates a validated tag.\n *\n * @param value - Tag value\n * @param maxLength - Maximum tag length (default: 128)\n * @returns Tag instance\n * @throws CacheError if validation fails\n *\n * @example\n * ```typescript\n * const tag = Tag.create('users');\n * const productTag = Tag.create('product:123');\n * ```\n */\n static create(value: string, maxLength: number = DEFAULT_MAX_LENGTH): Tag {\n // Validate not empty\n if (!value || value.length === 0) {\n throw new CacheError('Tag cannot be empty', ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Normalize: trim and lowercase\n const normalized = value.trim().toLowerCase();\n\n // Validate not empty after normalization\n if (normalized.length === 0) {\n throw new CacheError('Tag cannot be empty after normalization', ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Validate no whitespace\n if (/\\s/.test(normalized)) {\n throw new CacheError('Tag cannot contain whitespace', ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Validate allowed characters (alphanumeric, -, _, :, .)\n if (!/^[a-z0-9\\-_:.]+$/.test(normalized)) {\n throw new CacheError('Invalid tag characters. Only lowercase alphanumeric, hyphens, underscores, colons, and dots allowed', ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Validate length\n if (normalized.length > maxLength) {\n throw new CacheError(`Tag exceeds maximum length (${normalized.length} > ${maxLength})`, ErrorCode.CACHE_KEY_INVALID);\n }\n\n return new Tag(normalized);\n }\n\n /**\n * Returns the tag value.\n */\n toString(): string {\n return this.value;\n }\n\n /**\n * Returns the raw tag value.\n */\n getRaw(): string {\n return this.value;\n }\n\n /**\n * Checks equality with another tag.\n */\n equals(other: Tag): boolean {\n return this.value === other.value;\n }\n}\n","/**\n * Tags collection value object.\n * Validates and manages a collection of tags with deduplication.\n */\n\nimport { ErrorCode } from '@nestjs-redisx/core';\n\nimport { Tag } from './tag.vo';\nimport { CacheError } from '../../../shared/errors';\n\nconst DEFAULT_MAX_TAGS = 10;\n\nexport class Tags {\n private constructor(private readonly tags: Tag[]) {}\n\n /**\n * Creates a validated tags collection.\n *\n * @param values - Array of tag values\n * @param maxTags - Maximum number of tags (default: 10)\n * @returns Tags instance\n * @throws CacheError if validation fails\n *\n * @example\n * ```typescript\n * const tags = Tags.create(['users', 'product:123']);\n * const singleTag = Tags.create(['cache']);\n * ```\n */\n static create(values: string[], maxTags: number = DEFAULT_MAX_TAGS): Tags {\n // Validate max tags before processing\n if (values.length > maxTags) {\n throw new CacheError(`Too many tags (${values.length} > ${maxTags})`, ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Convert to Tag objects (validates each tag)\n const tagObjects = values.map((v) => Tag.create(v));\n\n // Remove duplicates by converting to Set and back\n const uniqueValues = Array.from(new Set(tagObjects.map((t) => t.toString())));\n\n // Recreate Tag objects from unique values\n const uniqueTags = uniqueValues.map((v) => Tag.create(v));\n\n return new Tags(uniqueTags);\n }\n\n /**\n * Creates empty tags collection.\n */\n static empty(): Tags {\n return new Tags([]);\n }\n\n /**\n * Returns array of tag strings.\n */\n toStrings(): string[] {\n return this.tags.map((t) => t.toString());\n }\n\n /**\n * Returns array of Tag objects.\n */\n toArray(): Tag[] {\n return [...this.tags];\n }\n\n /**\n * Returns number of tags.\n */\n size(): number {\n return this.tags.length;\n }\n\n /**\n * Checks if collection contains a specific tag.\n */\n has(tag: Tag): boolean {\n return this.tags.some((t) => t.equals(tag));\n }\n\n /**\n * Checks if collection is empty.\n */\n isEmpty(): boolean {\n return this.tags.length === 0;\n }\n\n /**\n * Iterates over tags.\n */\n forEach(callback: (tag: Tag, index: number) => void): void {\n this.tags.forEach(callback);\n }\n\n /**\n * Maps over tags.\n */\n map<T>(callback: (tag: Tag, index: number) => T): T[] {\n return this.tags.map(callback);\n }\n}\n","/**\n * TTL (Time To Live) value object.\n * Validates and normalizes TTL values.\n */\n\nimport { ErrorCode } from '@nestjs-redisx/core';\n\nimport { CacheError } from '../../../shared/errors';\n\n/** Default maximum TTL in seconds (24 hours). */\nconst DEFAULT_MAX_TTL_SECONDS = 86_400;\n\nexport class TTL {\n private constructor(private readonly seconds: number) {}\n\n /**\n * Creates a TTL value object.\n *\n * @param seconds - TTL in seconds\n * @param maxTtl - Maximum allowed TTL\n * @returns TTL instance\n * @throws CacheError if validation fails\n */\n static create(seconds: number, maxTtl: number = DEFAULT_MAX_TTL_SECONDS): TTL {\n // Validate positive\n if (seconds <= 0) {\n throw new CacheError(`TTL must be positive (got ${seconds})`, ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Validate not too large\n if (seconds > maxTtl) {\n throw new CacheError(`TTL exceeds maximum (${seconds} > ${maxTtl})`, ErrorCode.CACHE_KEY_INVALID);\n }\n\n // Round to nearest second\n const rounded = Math.round(seconds);\n\n return new TTL(rounded);\n }\n\n /**\n * Creates TTL from milliseconds.\n *\n * @param milliseconds - TTL in milliseconds\n * @param maxTtl - Maximum allowed TTL in seconds\n * @returns TTL instance\n */\n static fromMilliseconds(milliseconds: number, maxTtl: number = DEFAULT_MAX_TTL_SECONDS): TTL {\n return TTL.create(Math.ceil(milliseconds / 1000), maxTtl);\n }\n\n /**\n * Returns TTL in seconds.\n */\n toSeconds(): number {\n return this.seconds;\n }\n\n /**\n * Returns TTL in milliseconds.\n */\n toMilliseconds(): number {\n return this.seconds * 1000;\n }\n\n /**\n * Checks if TTL is less than another TTL.\n */\n isLessThan(other: TTL): boolean {\n return this.seconds < other.seconds;\n }\n\n /**\n * Checks if TTL is greater than another TTL.\n */\n isGreaterThan(other: TTL): boolean {\n return this.seconds > other.seconds;\n }\n\n /**\n * Returns the minimum of two TTLs.\n */\n static min(a: TTL, b: TTL): TTL {\n return a.isLessThan(b) ? a : b;\n }\n\n /**\n * Returns the maximum of two TTLs.\n */\n static max(a: TTL, b: TTL): TTL {\n return a.isGreaterThan(b) ? a : b;\n }\n\n /**\n * Checks equality with another TTL.\n */\n equals(other: TTL): boolean {\n return this.seconds === other.seconds;\n }\n\n /**\n * Returns string representation.\n */\n toString(): string {\n return `${this.seconds}s`;\n }\n}\n","/**\n * Main cache service implementation.\n * Orchestrates L1/L2 caching with stampede protection, SWR, and tag invalidation.\n */\n\nimport { Injectable, Inject, Logger, Optional } from '@nestjs/common';\nimport { REDIS_DRIVER, IRedisDriver, ErrorCode } from '@nestjs-redisx/core';\n\nimport { L1_CACHE_STORE, L2_CACHE_STORE, STAMPEDE_PROTECTION, TAG_INDEX, SWR_MANAGER, CACHE_PLUGIN_OPTIONS } from '../../../shared/constants';\nimport { CacheError, CacheKeyError } from '../../../shared/errors';\nimport { CacheSetOptions, CacheGetOrSetOptions, CacheStats, ICachePluginOptions } from '../../../shared/types';\nimport { IStampedeProtection } from '../../../stampede/application/ports/stampede-protection.port';\nimport { ISwrManager } from '../../../swr/application/ports/swr-manager.port';\nimport { ITagIndex } from '../../../tags/application/ports/tag-index.port';\nimport { CacheEntry } from '../../domain/value-objects/cache-entry.vo';\nimport { CacheKey } from '../../domain/value-objects/cache-key.vo';\nimport { Tag } from '../../domain/value-objects/tag.vo';\nimport { Tags } from '../../domain/value-objects/tags.vo';\nimport { TTL } from '../../domain/value-objects/ttl.vo';\nimport { ICacheService } from '../ports/cache-service.port';\nimport { IL1CacheStore } from '../ports/l1-cache-store.port';\nimport { IL2CacheStore } from '../ports/l2-cache-store.port';\n\n// Optional metrics integration\nconst METRICS_SERVICE = Symbol.for('METRICS_SERVICE');\n\ninterface IMetricsService {\n incrementCounter(name: string, labels?: Record<string, string>, value?: number): void;\n setGauge(name: string, value: number, labels?: Record<string, string>): void;\n}\n\n// Optional tracing integration\nconst TRACING_SERVICE = Symbol.for('TRACING_SERVICE');\n\ninterface ISpan {\n setAttribute(key: string, value: unknown): this;\n addEvent(name: string, attributes?: Record<string, unknown>): this;\n setStatus(status: 'OK' | 'ERROR'): this;\n recordException(error: Error): this;\n end(): void;\n}\n\ninterface ITracingService {\n startSpan(name: string, options?: { kind?: string; attributes?: Record<string, unknown> }): ISpan;\n}\n\n@Injectable()\nexport class CacheService implements ICacheService {\n private readonly logger = new Logger(CacheService.name);\n private readonly l1Enabled: boolean;\n private readonly l2Enabled: boolean;\n private readonly stampedeEnabled: boolean;\n private readonly swrEnabled: boolean;\n private readonly tagsEnabled: boolean;\n\n private readonly keyPrefix: string;\n\n constructor(\n @Inject(REDIS_DRIVER) private readonly driver: IRedisDriver,\n @Inject(L1_CACHE_STORE) private readonly l1Store: IL1CacheStore,\n @Inject(L2_CACHE_STORE) private readonly l2Store: IL2CacheStore,\n @Inject(STAMPEDE_PROTECTION) private readonly stampede: IStampedeProtection,\n @Inject(TAG_INDEX) private readonly tagIndex: ITagIndex,\n @Inject(SWR_MANAGER) private readonly swrManager: ISwrManager,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly options: ICachePluginOptions,\n @Optional() @Inject(METRICS_SERVICE) private readonly metrics?: IMetricsService,\n @Optional() @Inject(TRACING_SERVICE) private readonly tracing?: ITracingService,\n ) {\n this.l1Enabled = options.l1?.enabled ?? true;\n this.l2Enabled = options.l2?.enabled ?? true;\n this.keyPrefix = options.l2?.keyPrefix ?? 'cache:';\n this.stampedeEnabled = options.stampede?.enabled ?? true;\n this.swrEnabled = options.swr?.enabled ?? false;\n this.tagsEnabled = options.tags?.enabled ?? true;\n }\n\n async get<T>(key: string): Promise<T | null> {\n const span = this.tracing?.startSpan('cache.get', {\n kind: 'INTERNAL',\n attributes: { 'cache.key': key },\n });\n\n try {\n // Validate and normalize key (fail-open on validation error)\n const normalizedKey = this.validateAndNormalizeKey(key);\n const enrichedKey = this.enrichKeyWithContext(normalizedKey);\n\n // Try L1 first\n if (this.l1Enabled) {\n const l1Entry = await this.l1Store.get<T>(enrichedKey);\n if (l1Entry) {\n this.logger.debug(`L1 hit for key: ${key}`);\n this.metrics?.incrementCounter('redisx_cache_hits_total', { layer: 'l1' });\n span?.setAttribute('cache.hit', true);\n span?.setAttribute('cache.layer', 'l1');\n span?.setStatus('OK');\n return l1Entry.value;\n }\n this.metrics?.incrementCounter('redisx_cache_misses_total', { layer: 'l1' });\n }\n\n // Try L2\n if (this.l2Enabled) {\n const l2Entry = await this.l2Store.get<T>(enrichedKey);\n if (l2Entry) {\n this.logger.debug(`L2 hit for key: ${key}`);\n this.metrics?.incrementCounter('redisx_cache_hits_total', { layer: 'l2' });\n span?.setAttribute('cache.hit', true);\n span?.setAttribute('cache.layer', 'l2');\n span?.setStatus('OK');\n\n // Populate L1\n if (this.l1Enabled) {\n await this.l1Store.set(enrichedKey, l2Entry, this.options.l1?.ttl);\n }\n\n return l2Entry.value;\n }\n this.metrics?.incrementCounter('redisx_cache_misses_total', { layer: 'l2' });\n }\n\n span?.setAttribute('cache.hit', false);\n span?.setStatus('OK');\n return null;\n } catch (error) {\n // Fail-open: log and return null (includes validation errors)\n if (error instanceof CacheKeyError) {\n this.logger.warn(`Invalid cache key \"${key}\": ${error.message}`);\n } else {\n this.logger.error(`Cache get failed for key ${key}:`, error);\n }\n span?.recordException(error as Error);\n span?.setStatus('ERROR');\n return null;\n } finally {\n span?.end();\n }\n }\n\n async set<T>(key: string, value: T, options: CacheSetOptions = {}): Promise<void> {\n const span = this.tracing?.startSpan('cache.set', {\n kind: 'INTERNAL',\n attributes: { 'cache.key': key, 'cache.ttl': options.ttl },\n });\n\n try {\n // Validate and normalize key (fail-closed - throw on validation error)\n const normalizedKey = this.validateAndNormalizeKey(key);\n const enrichedKey = this.enrichKeyWithContext(normalizedKey, options.varyBy);\n\n // Validate TTL using TTL value object\n const ttlSeconds = options.ttl ?? this.options.l2?.defaultTtl ?? 3600;\n const maxTtl = this.options.l2?.maxTtl ?? 86400;\n const ttl = TTL.create(ttlSeconds, maxTtl);\n\n const entry = CacheEntry.create(value, ttl.toSeconds());\n\n // Determine cache strategy\n const strategy = options.strategy ?? 'l1-l2';\n span?.setAttribute('cache.strategy', strategy);\n\n // Set in L2 (if not l1-only)\n if (this.l2Enabled && strategy !== 'l1-only') {\n await this.l2Store.set(enrichedKey, entry, ttl.toSeconds());\n }\n\n // Set in L1 (if not l2-only, use minimum of L2 TTL and L1 max TTL)\n if (this.l1Enabled && strategy !== 'l2-only') {\n const l1MaxTtl = TTL.create(this.options.l1?.ttl ?? 60, maxTtl);\n const l1Ttl = TTL.min(ttl, l1MaxTtl);\n await this.l1Store.set(enrichedKey, entry, l1Ttl.toSeconds());\n }\n\n // Add to tag index (only for L2 operations, use full key with prefix)\n if (this.tagsEnabled && options.tags && options.tags.length > 0 && strategy !== 'l1-only') {\n const fullKey = `${this.keyPrefix}${enrichedKey}`;\n await this.tagIndex.addKeyToTags(fullKey, options.tags);\n span?.setAttribute('cache.tags', options.tags.join(','));\n }\n\n span?.setStatus('OK');\n } catch (error) {\n span?.recordException(error as Error);\n span?.setStatus('ERROR');\n // CacheKeyError and CacheError (from TTL validation) will be thrown as-is\n if (error instanceof CacheKeyError || error instanceof CacheError) {\n throw error;\n }\n throw new CacheError(`Failed to set cache for key \"${key}\": ${(error as Error).message}`, ErrorCode.CACHE_SET_FAILED, error as Error);\n } finally {\n span?.end();\n }\n }\n\n async getOrSet<T>(key: string, loader: () => Promise<T>, options: CacheGetOrSetOptions = {}): Promise<T> {\n // Validate key early (fail-closed for write operations)\n const normalizedKey = this.validateAndNormalizeKey(key);\n const enrichedKey = this.enrichKeyWithContext(normalizedKey, options.varyBy);\n\n // Check if SWR is enabled for this call\n const swrEnabled = options.swr?.enabled ?? this.swrEnabled;\n\n if (swrEnabled) {\n // SWR flow\n const swrEntry = await this.l2Store.getSwr<T>(enrichedKey);\n\n if (swrEntry) {\n const isExpired = this.swrManager.isExpired(swrEntry);\n\n if (!isExpired) {\n // Data is valid (fresh or stale)\n const isStale = this.swrManager.isStale(swrEntry);\n\n if (isStale && this.swrManager.shouldRevalidate(enrichedKey)) {\n // Trigger background revalidation\n void this.swrManager.scheduleRevalidation(\n enrichedKey,\n loader,\n async (freshValue) => {\n // Write proper SWR entry (not CacheEntry) to preserve staleAt/expiresAt metadata\n const staleTime = options.swr?.staleTime ?? this.options.swr?.defaultStaleTime ?? 60;\n const ttl = options.ttl ?? this.options.l2?.defaultTtl ?? 3600;\n const swrEntryNew = this.swrManager.createSwrEntry(freshValue, ttl, staleTime);\n await this.l2Store.setSwr(enrichedKey, swrEntryNew);\n\n // Also update L1 for fast reads\n if (this.l1Enabled) {\n const entry = CacheEntry.create(freshValue, ttl);\n await this.l1Store.set(enrichedKey, entry, this.options.l1?.ttl);\n }\n },\n (error) => {\n this.logger.error(`SWR revalidation failed for key ${enrichedKey}:`, error);\n },\n );\n }\n\n return swrEntry.value;\n }\n }\n\n // SWR miss or expired - load and cache with SWR metadata\n const value = await this.loadWithStampede(enrichedKey, loader, options);\n\n if (!options.unless?.(value)) {\n const staleTime = options.swr?.staleTime ?? this.options.swr?.defaultStaleTime ?? 60;\n const ttl = options.ttl ?? this.options.l2?.defaultTtl ?? 3600;\n const swrEntryNew = this.swrManager.createSwrEntry(value, ttl, staleTime);\n\n await this.l2Store.setSwr(enrichedKey, swrEntryNew);\n }\n\n return value;\n }\n\n // Regular flow (no SWR) — use enrichedKey directly to avoid double-enrichment\n const cached = await this.get<T>(enrichedKey);\n if (cached !== null) {\n return cached;\n }\n\n return this.loadWithStampede(enrichedKey, loader, options);\n }\n\n /**\n * Loads value with stampede protection if enabled.\n *\n * @param key - Normalized cache key\n * @param loader - Function to load value\n * @param options - Cache options\n * @returns Loaded value\n * @private\n */\n private async loadWithStampede<T>(key: string, loader: () => Promise<T>, options: CacheGetOrSetOptions): Promise<T> {\n if (this.stampedeEnabled && !options.skipStampede) {\n const result = await this.stampede.protect(key, loader);\n\n if (result.cached) {\n // Stampede was prevented - another request loaded the value\n this.metrics?.incrementCounter('redisx_cache_stampede_prevented_total');\n return result.value;\n }\n\n if (!options.unless?.(result.value)) {\n await this.set(key, result.value, {\n ttl: options.ttl,\n tags: options.tags,\n strategy: options.strategy,\n });\n }\n\n return result.value;\n }\n\n // No stampede protection - direct load\n const value = await loader();\n\n if (!options.unless?.(value)) {\n await this.set(key, value, {\n ttl: options.ttl,\n tags: options.tags,\n strategy: options.strategy,\n });\n }\n\n return value;\n }\n\n async delete(key: string): Promise<boolean> {\n try {\n // Validate key (fail-closed for write operations)\n const normalizedKey = this.validateAndNormalizeKey(key);\n const enrichedKey = this.enrichKeyWithContext(normalizedKey);\n\n let deleted = false;\n\n if (this.l1Enabled) {\n const l1Deleted = await this.l1Store.delete(enrichedKey);\n deleted = deleted || l1Deleted;\n }\n\n if (this.l2Enabled) {\n const l2Deleted = await this.l2Store.delete(enrichedKey);\n deleted = deleted || l2Deleted;\n }\n\n return deleted;\n } catch (error) {\n // CacheKeyError will be thrown as-is\n if (error instanceof CacheKeyError) {\n throw error;\n }\n throw new CacheError(`Failed to delete cache for key \"${key}\": ${(error as Error).message}`, ErrorCode.CACHE_DELETE_FAILED, error as Error);\n }\n }\n\n async deleteMany(keys: string[]): Promise<number> {\n if (keys.length === 0) {\n return 0;\n }\n\n try {\n // Validate, normalize, and enrich all keys (fail-closed for write operations)\n const normalizedKeys = keys\n .map((key) => {\n try {\n const normalized = this.validateAndNormalizeKey(key);\n return this.enrichKeyWithContext(normalized);\n } catch (error) {\n if (error instanceof CacheKeyError) {\n this.logger.warn(`Invalid key in deleteMany \"${key}\": ${error.message}`);\n }\n return null;\n }\n })\n .filter((k): k is string => k !== null);\n\n if (normalizedKeys.length === 0) {\n return 0;\n }\n\n // Track per-key deletion across both layers\n const deleted = new Array<boolean>(normalizedKeys.length).fill(false);\n\n // Delete from L1\n if (this.l1Enabled) {\n for (let i = 0; i < normalizedKeys.length; i++) {\n if (await this.l1Store.delete(normalizedKeys[i]!)) {\n deleted[i] = true;\n }\n }\n }\n\n // Delete from L2 using pipeline for batch operation\n if (this.l2Enabled && normalizedKeys.length > 0) {\n const fullKeys = normalizedKeys.map((k) => `${this.keyPrefix}${k}`);\n const pipeline = this.driver.pipeline();\n\n for (const fullKey of fullKeys) {\n pipeline.del(fullKey);\n }\n\n const results = await pipeline.exec();\n\n if (results) {\n for (let i = 0; i < results.length; i++) {\n const [error, result] = results[i]!;\n if (!error && typeof result === 'number' && result > 0) {\n deleted[i] = true;\n }\n }\n }\n }\n\n return deleted.filter(Boolean).length;\n } catch (error) {\n throw new CacheError(`Failed to delete multiple keys: ${(error as Error).message}`, ErrorCode.CACHE_DELETE_FAILED, error as Error);\n }\n }\n\n async clear(): Promise<void> {\n try {\n if (this.l1Enabled) {\n await this.l1Store.clear();\n }\n\n if (this.l2Enabled) {\n await this.l2Store.clear();\n }\n\n if (this.tagsEnabled) {\n await this.tagIndex.clearAllTags();\n }\n } catch (error) {\n throw new CacheError(`Failed to clear cache: ${(error as Error).message}`, ErrorCode.CACHE_CLEAR_FAILED, error as Error);\n }\n }\n\n async has(key: string): Promise<boolean> {\n try {\n // Validate key (fail-open for read operations)\n const normalizedKey = this.validateAndNormalizeKey(key);\n const enrichedKey = this.enrichKeyWithContext(normalizedKey);\n\n if (this.l1Enabled) {\n const l1Has = await this.l1Store.has(enrichedKey);\n if (l1Has) return true;\n }\n\n if (this.l2Enabled) {\n return await this.l2Store.has(enrichedKey);\n }\n\n return false;\n } catch (error) {\n // Fail-open (includes validation errors)\n if (error instanceof CacheKeyError) {\n this.logger.warn(`Invalid cache key \"${key}\": ${error.message}`);\n }\n return false;\n }\n }\n\n async invalidateTag(tag: string): Promise<number> {\n if (!this.tagsEnabled) {\n return 0;\n }\n\n try {\n // Get all keys for this tag (keys include L2 prefix)\n const keysWithPrefix = await this.tagIndex.getKeysByTag(tag);\n\n // Delete from L1 (needs keys without prefix)\n if (this.l1Enabled) {\n const keysWithoutPrefix = keysWithPrefix.map((key) => (key.startsWith(this.keyPrefix) ? key.slice(this.keyPrefix.length) : key));\n await Promise.all(keysWithoutPrefix.map((key) => this.l1Store.delete(key)));\n }\n\n // Delete from L2 and tag index (handled by tagIndex.invalidateTag)\n return await this.tagIndex.invalidateTag(tag);\n } catch (error) {\n throw new CacheError(`Failed to invalidate tag \"${tag}\": ${(error as Error).message}`, ErrorCode.CACHE_TAG_INVALIDATION_FAILED, error as Error);\n }\n }\n\n async invalidateTags(tags: string[]): Promise<number> {\n if (!this.tagsEnabled || tags.length === 0) {\n return 0;\n }\n\n try {\n let total = 0;\n for (const tag of tags) {\n const count = await this.invalidateTag(tag);\n total += count;\n }\n return total;\n } catch (error) {\n throw new CacheError(`Failed to invalidate tags: ${(error as Error).message}`, ErrorCode.CACHE_TAG_INVALIDATION_FAILED, error as Error);\n }\n }\n\n async getKeysByTag(tag: string): Promise<string[]> {\n if (!this.tagsEnabled) {\n return [];\n }\n\n try {\n // Validate tag using Tag VO\n const validTag = Tag.create(tag);\n const keysWithPrefix = await this.tagIndex.getKeysByTag(validTag.toString());\n\n // Remove L2 prefix from keys\n return keysWithPrefix.map((key) => (key.startsWith(this.keyPrefix) ? key.slice(this.keyPrefix.length) : key));\n } catch (error) {\n // Fail-open: log and return empty array\n this.logger.error(`Failed to get keys for tag ${tag}:`, error);\n return [];\n }\n }\n\n async getMany<T>(keys: string[]): Promise<Array<T | null>> {\n if (keys.length === 0) {\n return [];\n }\n\n try {\n // Validate, normalize, and enrich all keys (fail-open)\n const normalizedKeys = keys.map((key) => {\n try {\n const normalized = this.validateAndNormalizeKey(key);\n return this.enrichKeyWithContext(normalized);\n } catch (error) {\n if (error instanceof CacheKeyError) {\n this.logger.warn(`Invalid cache key in getMany \"${key}\": ${error.message}`);\n }\n return null;\n }\n });\n\n // For simplicity, get from L2 only for getMany\n if (!this.l2Enabled) {\n return keys.map(() => null);\n }\n\n // Filter out null keys (validation failures) and maintain index mapping\n const validKeys: string[] = [];\n const indexMap: Map<number, number> = new Map();\n normalizedKeys.forEach((key, index) => {\n if (key !== null) {\n indexMap.set(validKeys.length, index);\n validKeys.push(key);\n }\n });\n\n if (validKeys.length === 0) {\n return keys.map(() => null);\n }\n\n const entries = await this.l2Store.getMany<T>(validKeys);\n\n // Reconstruct result array with null for invalid keys\n const result: Array<T | null> = keys.map(() => null);\n entries.forEach((entry, validIndex) => {\n const originalIndex = indexMap.get(validIndex);\n if (originalIndex !== undefined) {\n result[originalIndex] = entry ? entry.value : null;\n }\n });\n\n return result;\n } catch (error) {\n // Fail-open\n this.logger.error('Failed to getMany:', error);\n return keys.map(() => null);\n }\n }\n\n async setMany<T>(entries: Array<{ key: string; value: T; ttl?: number; tags?: string[] }>): Promise<void> {\n if (entries.length === 0) {\n return;\n }\n\n try {\n if (!this.l2Enabled) {\n return;\n }\n\n // Validate, normalize, and enrich all keys (fail-closed for write operations)\n const maxTtl = this.options.l2?.maxTtl ?? 86400;\n const defaultTtl = this.options.l2?.defaultTtl ?? 3600;\n const cacheEntries = entries.map(({ key, value, ttl }) => {\n const entryTtl = Math.min(ttl ?? defaultTtl, maxTtl);\n return {\n key: this.enrichKeyWithContext(this.validateAndNormalizeKey(key)),\n entry: CacheEntry.create(value, entryTtl),\n ttl: entryTtl,\n };\n });\n\n await this.l2Store.setMany(cacheEntries);\n\n // Add tags to tag index for entries that have tags\n if (this.tagsEnabled) {\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i]!;\n const { tags } = entry;\n if (tags && tags.length > 0) {\n const enrichedKey = cacheEntries[i]!.key;\n const fullKey = `${this.keyPrefix}${enrichedKey}`;\n const validatedTags = Tags.create(tags).toStrings();\n await this.tagIndex.addKeyToTags(fullKey, validatedTags);\n }\n }\n }\n } catch (error) {\n // CacheKeyError will be thrown as-is\n if (error instanceof CacheKeyError) {\n throw error;\n }\n throw new CacheError(`Failed to setMany: ${(error as Error).message}`, ErrorCode.CACHE_SET_FAILED, error as Error);\n }\n }\n\n async ttl(key: string): Promise<number> {\n if (!this.l2Enabled) {\n return -1;\n }\n\n try {\n // Validate key (fail-open for read operations)\n const normalizedKey = this.validateAndNormalizeKey(key);\n const enrichedKey = this.enrichKeyWithContext(normalizedKey);\n return await this.l2Store.ttl(enrichedKey);\n } catch (error) {\n // Fail-open (includes validation errors)\n if (error instanceof CacheKeyError) {\n this.logger.warn(`Invalid cache key \"${key}\": ${error.message}`);\n }\n return -1;\n }\n }\n\n async getStats(): Promise<CacheStats> {\n const l1Stats = this.l1Enabled ? this.l1Store.getStats() : { hits: 0, misses: 0, size: 0 };\n const l2Stats = this.l2Enabled ? await this.l2Store.getStats() : { hits: 0, misses: 0 };\n const stampedeStats = this.stampedeEnabled ? this.stampede.getStats() : { activeFlights: 0, totalWaiters: 0, oldestFlight: 0, prevented: 0 };\n\n return {\n l1: l1Stats,\n l2: l2Stats,\n stampedePrevented: stampedeStats.prevented,\n };\n }\n\n async invalidateByPattern(pattern: string): Promise<number> {\n if (!this.l2Enabled) {\n return 0;\n }\n\n try {\n // Use SCAN to find matching keys\n const result = await this.l2Store.scan(pattern);\n const keys = result.keys;\n\n if (keys.length === 0) {\n return 0;\n }\n\n // Delete from L1\n if (this.l1Enabled) {\n const keysWithoutPrefix = keys.map((key) => (key.startsWith(this.keyPrefix) ? key.slice(this.keyPrefix.length) : key));\n await Promise.all(keysWithoutPrefix.map((key) => this.l1Store.delete(key)));\n }\n\n // Delete from L2\n let deleted = 0;\n for (const key of keys) {\n const wasDeleted = await this.l2Store.delete(key);\n if (wasDeleted) {\n deleted++;\n }\n }\n\n return deleted;\n } catch (error) {\n throw new CacheError(`Failed to invalidate by pattern \"${pattern}\": ${(error as Error).message}`, ErrorCode.CACHE_DELETE_FAILED, error as Error);\n }\n }\n\n /**\n * Validates and normalizes cache key using CacheKey value object.\n *\n * @param rawKey - Raw key string\n * @returns Normalized key string (without prefix - prefix added by L2 store)\n * @throws CacheKeyError if validation fails\n *\n * @private\n */\n private validateAndNormalizeKey(rawKey: string): string {\n try {\n const keyOptions = {\n maxLength: this.options.keys?.maxLength ?? 1024,\n version: this.options.keys?.version,\n separator: this.options.keys?.separator ?? ':',\n // Don't include prefix here - it's added by L2 store\n prefix: '',\n };\n\n const cacheKey = CacheKey.create(rawKey, keyOptions);\n\n // Return raw key without prefix (L2 store will add its prefix)\n return cacheKey.getRaw();\n } catch (error) {\n if (error instanceof CacheKeyError) {\n throw error;\n }\n throw new CacheKeyError(rawKey, `Invalid cache key: ${(error as Error).message}`);\n }\n }\n\n /**\n * Enriches a normalized key with context values.\n * Appends global context keys and per-call varyBy values as key suffix.\n * Uses a marker (_ctx_) to prevent double-enrichment in internal call chains.\n *\n * @param normalizedKey - Already validated and normalized cache key\n * @param varyBy - Optional per-call context overrides\n * @returns Enriched key with context suffix, or original key if no context\n * @private\n */\n private enrichKeyWithContext(normalizedKey: string, varyBy?: Record<string, string>): string {\n const separator = this.options.keys?.separator ?? ':';\n const marker = `${separator}_ctx_${separator}`;\n\n // Skip if already enriched (prevents double-enrichment in internal calls)\n if (normalizedKey.includes(marker)) {\n return normalizedKey;\n }\n\n const contextProvider = this.options.contextProvider;\n const contextKeys = this.options.contextKeys;\n const contextMap = new Map<string, string>();\n\n // Global context keys (from contextProvider)\n if (contextProvider && contextKeys && contextKeys.length > 0) {\n for (const ctxKey of contextKeys) {\n const value = contextProvider.get<string>(ctxKey);\n if (value !== undefined && value !== null) {\n if (typeof value === 'object') {\n this.logger.warn(`Context key \"${ctxKey}\" has object value, skipping (use primitives for context keys)`);\n continue;\n }\n contextMap.set(ctxKey, String(value));\n }\n }\n }\n\n // Per-call varyBy (overrides global context values)\n if (varyBy) {\n for (const [k, v] of Object.entries(varyBy)) {\n contextMap.set(k, v);\n }\n }\n\n if (contextMap.size === 0) return normalizedKey;\n\n const sortedEntries = [...contextMap.entries()].sort(([a], [b]) => a.localeCompare(b));\n const suffix = sortedEntries.map(([k, v]) => `${this.sanitizeForKey(k)}.${this.sanitizeForKey(v)}`).join(separator);\n\n return `${normalizedKey}${marker}${suffix}`;\n }\n\n /**\n * Sanitizes a value for use in cache key (removes non-allowed characters).\n * @private\n */\n private sanitizeForKey(value: string): string {\n return String(value).replace(/[^a-zA-Z0-9\\-_]/g, '_');\n }\n}\n","/**\n * Cache warmup service.\n * Loads specified keys into cache on application startup.\n */\n\nimport { Injectable, Inject, Logger, OnModuleInit } from '@nestjs/common';\n\nimport { CACHE_SERVICE, CACHE_PLUGIN_OPTIONS } from '../../../shared/constants';\nimport { ICachePluginOptions, IWarmupKey } from '../../../shared/types';\nimport { ICacheService } from '../ports/cache-service.port';\n\n@Injectable()\nexport class WarmupService implements OnModuleInit {\n private readonly logger = new Logger(WarmupService.name);\n private readonly enabled: boolean;\n private readonly keys: IWarmupKey[];\n private readonly concurrency: number;\n\n constructor(\n @Inject(CACHE_SERVICE) private readonly cacheService: ICacheService,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly options: ICachePluginOptions,\n ) {\n this.enabled = options.warmup?.enabled ?? false;\n this.keys = options.warmup?.keys ?? [];\n this.concurrency = options.warmup?.concurrency ?? 10;\n }\n\n async onModuleInit(): Promise<void> {\n if (!this.enabled || this.keys.length === 0) {\n return;\n }\n\n this.logger.log(`Starting cache warmup for ${this.keys.length} keys...`);\n\n const startTime = Date.now();\n\n // Simple concurrency control: split into chunks\n const chunks: IWarmupKey[][] = [];\n for (let i = 0; i < this.keys.length; i += this.concurrency) {\n chunks.push(this.keys.slice(i, i + this.concurrency));\n }\n\n let succeeded = 0;\n let failed = 0;\n\n for (const chunk of chunks) {\n const results = await Promise.allSettled(chunk.map((warmupKey) => this.warmupKey(warmupKey)));\n\n succeeded += results.filter((r) => r.status === 'fulfilled').length;\n failed += results.filter((r) => r.status === 'rejected').length;\n }\n\n const duration = Date.now() - startTime;\n\n this.logger.log(`Cache warmup completed: ${succeeded} succeeded, ${failed} failed (${duration}ms)`);\n }\n\n /**\n * Warms up a single cache key.\n *\n * @param warmupKey - Warmup key configuration\n * @private\n */\n private async warmupKey(warmupKey: IWarmupKey): Promise<void> {\n try {\n this.logger.debug(`Warming up key: ${warmupKey.key}`);\n\n await this.cacheService.getOrSet(warmupKey.key, warmupKey.loader, {\n ttl: warmupKey.ttl,\n tags: warmupKey.tags,\n });\n\n this.logger.debug(`Successfully warmed up key: ${warmupKey.key}`);\n } catch (error) {\n this.logger.error(`Failed to warm up key ${warmupKey.key}:`, error);\n throw error;\n }\n }\n}\n","/**\n * Serializer service for cache values.\n */\n\nimport { Injectable } from '@nestjs/common';\n\nimport { SerializationError } from '../../../shared/errors';\n\n@Injectable()\nexport class Serializer {\n /**\n * Serializes value to string.\n *\n * @param value - Value to serialize\n * @returns Serialized string\n * @throws SerializationError if serialization fails\n */\n serialize<T>(value: T): string {\n try {\n return JSON.stringify(value);\n } catch (error) {\n throw new SerializationError(`Failed to serialize value: ${(error as Error).message}`, error as Error);\n }\n }\n\n /**\n * Deserializes string to value.\n *\n * @param serialized - Serialized string\n * @returns Deserialized value\n * @throws SerializationError if deserialization fails\n */\n deserialize<T>(serialized: string): T {\n try {\n return JSON.parse(serialized) as T;\n } catch (error) {\n throw new SerializationError(`Failed to deserialize value: ${(error as Error).message}`, error as Error);\n }\n }\n\n /**\n * Safely tries to deserialize, returns null on error.\n *\n * @param serialized - Serialized string\n * @returns Deserialized value or null\n */\n tryDeserialize<T>(serialized: string): T | null {\n try {\n return this.deserialize<T>(serialized);\n } catch {\n return null;\n }\n }\n}\n","/**\n * L1 in-memory cache store implementation.\n * Supports LRU and LFU eviction policies.\n */\n\nimport { Injectable, Inject } from '@nestjs/common';\n\nimport { CACHE_PLUGIN_OPTIONS } from '../../../shared/constants';\nimport { ICachePluginOptions } from '../../../shared/types';\nimport { IL1CacheStore } from '../../application/ports/l1-cache-store.port';\nimport { CacheEntry } from '../../domain/value-objects/cache-entry.vo';\n\ninterface ICacheNode<T> {\n key: string;\n entry: CacheEntry<T>;\n prev: ICacheNode<T> | null;\n next: ICacheNode<T> | null;\n expiresAt: number;\n frequency: number;\n}\n\n@Injectable()\nexport class L1MemoryStoreAdapter implements IL1CacheStore {\n private readonly cache = new Map<string, ICacheNode<unknown>>();\n private head: ICacheNode<unknown> | null = null;\n private tail: ICacheNode<unknown> | null = null;\n private readonly maxSize: number;\n private readonly defaultTtl: number;\n private readonly evictionPolicy: 'lru' | 'lfu';\n private hits = 0;\n private misses = 0;\n\n constructor(\n @Inject(CACHE_PLUGIN_OPTIONS)\n private readonly options: ICachePluginOptions,\n ) {\n this.maxSize = options.l1?.maxSize ?? 1000;\n this.defaultTtl = (options.l1?.ttl ?? 60) * 1000; // Convert to ms\n this.evictionPolicy = options.l1?.evictionPolicy ?? 'lru';\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async get<T>(key: string): Promise<CacheEntry<T> | null> {\n const node = this.cache.get(key);\n if (!node) {\n this.misses++;\n return null;\n }\n\n // Check expiration\n if (Date.now() > node.expiresAt) {\n void this.delete(key);\n this.misses++;\n return null;\n }\n\n if (this.evictionPolicy === 'lru') {\n // Move to front (most recently used)\n this.moveToFront(node);\n } else {\n // LFU: increment frequency\n node.frequency++;\n }\n\n this.hits++;\n return node.entry as CacheEntry<T>;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async set<T>(key: string, entry: CacheEntry<T>, ttl?: number): Promise<void> {\n const existingNode = this.cache.get(key);\n\n if (existingNode) {\n // Update existing node\n existingNode.entry = entry;\n existingNode.expiresAt = Date.now() + (ttl ?? this.defaultTtl);\n\n if (this.evictionPolicy === 'lru') {\n this.moveToFront(existingNode);\n } else {\n existingNode.frequency++;\n }\n } else {\n // Evict if at capacity\n if (this.cache.size >= this.maxSize) {\n this.evict();\n }\n\n // Create new node\n const node: ICacheNode<unknown> = {\n key,\n entry,\n prev: null,\n next: this.head,\n expiresAt: Date.now() + (ttl ?? this.defaultTtl),\n frequency: 1,\n };\n\n if (this.head) {\n this.head.prev = node;\n }\n this.head = node;\n\n if (!this.tail) {\n this.tail = node;\n }\n\n this.cache.set(key, node);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async delete(key: string): Promise<boolean> {\n const node = this.cache.get(key);\n if (!node) {\n return false;\n }\n\n this.removeNode(node);\n this.cache.delete(key);\n return true;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async clear(): Promise<void> {\n this.cache.clear();\n this.head = null;\n this.tail = null;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async has(key: string): Promise<boolean> {\n const node = this.cache.get(key);\n if (!node) {\n return false;\n }\n\n // Check expiration\n if (Date.now() > node.expiresAt) {\n void this.delete(key);\n return false;\n }\n\n return true;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async size(): Promise<number> {\n // O(1): returns approximate size (may include expired entries not yet evicted by get/has/set).\n // Expired entries are cleaned lazily on access, not eagerly here.\n return this.cache.size;\n }\n\n private moveToFront(node: ICacheNode<unknown>): void {\n if (node === this.head) {\n return;\n }\n\n this.removeNode(node);\n\n node.prev = null;\n node.next = this.head;\n\n if (this.head) {\n this.head.prev = node;\n }\n\n this.head = node;\n\n if (!this.tail) {\n this.tail = node;\n }\n }\n\n private removeNode(node: ICacheNode<unknown>): void {\n if (node.prev) {\n node.prev.next = node.next;\n } else {\n this.head = node.next;\n }\n\n if (node.next) {\n node.next.prev = node.prev;\n } else {\n this.tail = node.prev;\n }\n }\n\n private evict(): void {\n if (this.evictionPolicy === 'lfu') {\n this.evictLFU();\n } else {\n this.evictLRU();\n }\n }\n\n private evictLRU(): void {\n if (!this.tail) {\n return;\n }\n\n const key = this.tail.key;\n this.removeNode(this.tail);\n this.cache.delete(key);\n }\n\n private evictLFU(): void {\n if (this.cache.size === 0) {\n return;\n }\n\n // Find node with lowest frequency; on tie, use linked list order (tail = oldest)\n let victim: ICacheNode<unknown> | null = null;\n\n let current = this.tail;\n while (current) {\n if (!victim || current.frequency < victim.frequency) {\n victim = current;\n }\n current = current.prev;\n }\n\n if (victim) {\n this.removeNode(victim);\n this.cache.delete(victim.key);\n }\n }\n\n getStats(): { hits: number; misses: number; size: number } {\n return {\n hits: this.hits,\n misses: this.misses,\n size: this.cache.size,\n };\n }\n}\n","/**\n * L2 Redis cache store implementation.\n */\n\nimport { Injectable, Inject } from '@nestjs/common';\nimport { REDIS_DRIVER, IRedisDriver, ErrorCode } from '@nestjs-redisx/core';\n\nimport { CACHE_PLUGIN_OPTIONS, SERIALIZER } from '../../../shared/constants';\nimport { CacheError } from '../../../shared/errors';\nimport { ICachePluginOptions, ScanResult, SwrEntry } from '../../../shared/types';\nimport { IL2CacheStore } from '../../application/ports/l2-cache-store.port';\nimport { Serializer } from '../../domain/services/serializer.service';\nimport { CacheEntry } from '../../domain/value-objects/cache-entry.vo';\n\n/** Default batch size for SCAN and bulk delete operations. */\nconst DEFAULT_BATCH_SIZE = 100;\n\n@Injectable()\nexport class L2RedisStoreAdapter implements IL2CacheStore {\n private readonly keyPrefix: string;\n private readonly defaultTtl: number;\n private hits = 0;\n private misses = 0;\n\n constructor(\n @Inject(REDIS_DRIVER) private readonly driver: IRedisDriver,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly options: ICachePluginOptions,\n @Inject(SERIALIZER) private readonly serializer: Serializer,\n ) {\n this.keyPrefix = options.l2?.keyPrefix ?? 'cache:';\n this.defaultTtl = options.l2?.defaultTtl ?? 3600;\n }\n\n async get<T>(key: string): Promise<CacheEntry<T> | null> {\n try {\n const fullKey = this.buildKey(key);\n const value = await this.driver.get(fullKey);\n\n if (!value) {\n this.misses++;\n return null;\n }\n\n this.hits++;\n return this.serializer.deserialize<CacheEntry<T>>(value);\n } catch {\n // Fail-open: return null on error\n this.misses++;\n return null;\n }\n }\n\n async set<T>(key: string, entry: CacheEntry<T>, ttl?: number): Promise<void> {\n try {\n const fullKey = this.buildKey(key);\n const serialized = this.serializer.serialize(entry);\n const ttlSeconds = ttl ?? this.defaultTtl;\n\n await this.driver.setex(fullKey, ttlSeconds, serialized);\n } catch (error) {\n throw new CacheError(`Failed to set cache entry for key \"${key}\": ${(error as Error).message}`, ErrorCode.CACHE_SET_FAILED, error as Error);\n }\n }\n\n async delete(key: string): Promise<boolean> {\n try {\n const fullKey = this.buildKey(key);\n const result = await this.driver.del(fullKey);\n return result > 0;\n } catch (error) {\n throw new CacheError(`Failed to delete cache entry for key \"${key}\": ${(error as Error).message}`, ErrorCode.CACHE_DELETE_FAILED, error as Error);\n }\n }\n\n async clear(): Promise<void> {\n try {\n const pattern = `${this.keyPrefix}*`;\n const keys = await this.scanKeys(pattern);\n\n if (keys.length === 0) {\n return;\n }\n\n // Cluster-safe: delete keys individually to avoid CROSSSLOT errors\n const batchSize = DEFAULT_BATCH_SIZE;\n for (let i = 0; i < keys.length; i += batchSize) {\n const batch = keys.slice(i, i + batchSize);\n\n // Delete each key individually\n await Promise.all(batch.map((key) => this.driver.del(key)));\n }\n } catch (error) {\n throw new CacheError(`Failed to clear cache: ${(error as Error).message}`, ErrorCode.CACHE_CLEAR_FAILED, error as Error);\n }\n }\n\n async has(key: string): Promise<boolean> {\n try {\n const fullKey = this.buildKey(key);\n const exists = await this.driver.exists(fullKey);\n return exists > 0;\n } catch {\n // Fail-open: return false on error\n return false;\n }\n }\n\n async ttl(key: string): Promise<number> {\n try {\n const fullKey = this.buildKey(key);\n const ttl = await this.driver.ttl(fullKey);\n return ttl;\n } catch {\n return -1;\n }\n }\n\n async expire(key: string, ttl: number): Promise<boolean> {\n try {\n const fullKey = this.buildKey(key);\n const result = await this.driver.expire(fullKey, ttl);\n return result === 1;\n } catch (error) {\n throw new CacheError(`Failed to set expiration for key \"${key}\": ${(error as Error).message}`, ErrorCode.CACHE_OPERATION_FAILED, error as Error);\n }\n }\n\n async scan(pattern: string, count: number = DEFAULT_BATCH_SIZE): Promise<ScanResult> {\n try {\n const fullPattern = `${this.keyPrefix}${pattern}`;\n const keys = await this.scanKeys(fullPattern, count);\n\n // Remove prefix from keys\n const strippedKeys = keys.map((key) => (key.startsWith(this.keyPrefix) ? key.slice(this.keyPrefix.length) : key));\n\n return {\n keys: strippedKeys,\n cursor: '0', // Simplified: full scan completed\n };\n } catch (error) {\n throw new CacheError(`Failed to scan keys with pattern \"${pattern}\": ${(error as Error).message}`, ErrorCode.CACHE_OPERATION_FAILED, error as Error);\n }\n }\n\n async getMany<T>(keys: string[]): Promise<Array<CacheEntry<T> | null>> {\n try {\n if (keys.length === 0) {\n return [];\n }\n\n const fullKeys = keys.map((key) => this.buildKey(key));\n\n // Use driver.mget() - core handles cluster topology automatically\n const values = await this.driver.mget(...fullKeys);\n\n return values.map((value) => {\n if (!value) {\n this.misses++;\n return null;\n }\n this.hits++;\n return this.serializer.tryDeserialize<CacheEntry<T>>(value);\n });\n } catch {\n // Fail-open: return array of nulls\n return keys.map(() => null);\n }\n }\n\n async setMany<T>(entries: Array<{ key: string; entry: CacheEntry<T>; ttl?: number }>): Promise<void> {\n try {\n if (entries.length === 0) {\n return;\n }\n\n // Cluster-safe: set keys individually to avoid CROSSSLOT errors with pipeline\n // In standalone mode this is slightly slower but works everywhere\n await Promise.all(\n entries.map(async ({ key, entry, ttl }) => {\n const fullKey = this.buildKey(key);\n const serialized = this.serializer.serialize(entry);\n const ttlSeconds = ttl ?? this.defaultTtl;\n\n await this.driver.setex(fullKey, ttlSeconds, serialized);\n }),\n );\n } catch (error) {\n throw new CacheError(`Failed to set multiple cache entries: ${(error as Error).message}`, ErrorCode.CACHE_SET_FAILED, error as Error);\n }\n }\n\n private buildKey(key: string): string {\n return `${this.keyPrefix}${key}`;\n }\n\n private async scanKeys(pattern: string, count: number = DEFAULT_BATCH_SIZE): Promise<string[]> {\n const keys: string[] = [];\n let cursor = 0;\n\n do {\n const result = await this.driver.scan(cursor, {\n match: pattern,\n count,\n });\n cursor = parseInt(result[0], 10);\n keys.push(...result[1]);\n } while (cursor !== 0);\n\n return keys;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async getStats(): Promise<{ hits: number; misses: number }> {\n return {\n hits: this.hits,\n misses: this.misses,\n };\n }\n\n async getSwr<T>(key: string): Promise<SwrEntry<T> | null> {\n try {\n const fullKey = this.buildKey(key);\n const value = await this.driver.get(fullKey);\n\n if (!value) {\n this.misses++;\n return null;\n }\n\n this.hits++;\n return this.serializer.deserialize<SwrEntry<T>>(value);\n } catch {\n // Fail-open: return null on error\n this.misses++;\n return null;\n }\n }\n\n async setSwr<T>(key: string, swrEntry: SwrEntry<T>): Promise<void> {\n try {\n const fullKey = this.buildKey(key);\n const serialized = this.serializer.serialize(swrEntry);\n\n // Calculate TTL from expiresAt timestamp\n const now = Date.now();\n const ttlMs = swrEntry.expiresAt - now;\n\n if (ttlMs <= 0) {\n // Entry already expired, don't save it\n return;\n }\n\n const ttlSeconds = Math.max(1, Math.ceil(ttlMs / 1000));\n\n await this.driver.setex(fullKey, ttlSeconds, serialized);\n } catch (error) {\n throw new CacheError(`Failed to set SWR entry for key \"${key}\": ${(error as Error).message}`, ErrorCode.CACHE_SET_FAILED, error as Error);\n }\n }\n}\n","/**\n * Main cache service.\n * Simplified API wrapper over the internal cache implementation.\n */\n\nimport { Injectable, Inject } from '@nestjs/common';\n\nimport { ICacheService as IInternalCacheService } from './cache/application/ports/cache-service.port';\nimport { CACHE_SERVICE } from './shared/constants';\nimport { CacheSetOptions, CacheGetOrSetOptions, CacheStats } from './shared/types';\n\n@Injectable()\nexport class CacheService {\n constructor(\n @Inject(CACHE_SERVICE)\n private readonly internalCache: IInternalCacheService,\n ) {}\n\n /**\n * Gets value from cache.\n *\n * @param key - Cache key\n * @returns Cached value or null if not found\n *\n * @example\n * ```typescript\n * const user = await cacheService.get<User>('user:123');\n * ```\n */\n async get<T>(key: string): Promise<T | null> {\n return this.internalCache.get<T>(key);\n }\n\n /**\n * Sets value in cache with optional TTL and tags.\n *\n * @param key - Cache key\n * @param value - Value to cache\n * @param options - Cache options (ttl, tags, strategy)\n *\n * @example\n * ```typescript\n * await cacheService.set('user:123', user, {\n * ttl: 3600,\n * tags: ['users', 'user:123']\n * });\n * ```\n */\n async set<T>(key: string, value: T, options?: CacheSetOptions): Promise<void> {\n return this.internalCache.set(key, value, options);\n }\n\n /**\n * Deletes key from cache.\n *\n * @param key - Cache key\n * @returns True if key was deleted, false if not found\n *\n * @example\n * ```typescript\n * const deleted = await cacheService.del('user:123');\n * ```\n */\n async del(key: string): Promise<boolean> {\n return this.internalCache.delete(key);\n }\n\n /**\n * Gets multiple values from cache.\n *\n * @param keys - Array of cache keys\n * @returns Array of values (null for missing keys)\n *\n * @example\n * ```typescript\n * const users = await cacheService.getMany<User>(['user:1', 'user:2', 'user:3']);\n * ```\n */\n async getMany<T>(keys: string[]): Promise<Array<T | null>> {\n return this.internalCache.getMany<T>(keys);\n }\n\n /**\n * Sets multiple values in cache.\n *\n * @param entries - Array of key-value-ttl tuples\n *\n * @example\n * ```typescript\n * await cacheService.setMany([\n * { key: 'user:1', value: user1, ttl: 3600 },\n * { key: 'user:2', value: user2, ttl: 3600 }\n * ]);\n * ```\n */\n async setMany<T>(entries: Array<{ key: string; value: T; ttl?: number }>): Promise<void> {\n return this.internalCache.setMany(entries);\n }\n\n /**\n * Gets value from cache or loads it using the provided loader function.\n * Implements cache-aside pattern with anti-stampede protection.\n *\n * @param key - Cache key\n * @param loader - Function to load value if not cached\n * @param options - Cache options\n * @returns Cached or loaded value\n *\n * @example\n * ```typescript\n * const user = await cacheService.getOrSet(\n * 'user:123',\n * async () => {\n * return await userRepository.findById('123');\n * },\n * { ttl: 3600, tags: ['users'] }\n * );\n * ```\n */\n async getOrSet<T>(key: string, loader: () => Promise<T>, options?: CacheGetOrSetOptions): Promise<T> {\n return this.internalCache.getOrSet(key, loader, options);\n }\n\n /**\n * Wraps a function with caching logic.\n * Helper for creating cached functions.\n *\n * @param fn - Function to wrap\n * @param options - Cache options or key builder function\n * @returns Wrapped function with caching\n *\n * @example\n * ```typescript\n * const getCachedUser = cacheService.wrap(\n * async (id: string) => userRepository.findById(id),\n * {\n * key: (id: string) => `user:${id}`,\n * ttl: 3600,\n * tags: (id: string) => [`user:${id}`, 'users']\n * }\n * );\n *\n * const user = await getCachedUser('123');\n * ```\n */\n wrap<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => Promise<TReturn>,\n options: {\n key: (...args: TArgs) => string;\n ttl?: number;\n tags?: string[] | ((...args: TArgs) => string[]);\n },\n ): (...args: TArgs) => Promise<TReturn> {\n return async (...args: TArgs): Promise<TReturn> => {\n const key = options.key(...args);\n const tags = typeof options.tags === 'function' ? options.tags(...args) : options.tags;\n\n return this.getOrSet(key, () => fn(...args), {\n ttl: options.ttl,\n tags,\n });\n };\n }\n\n /**\n * Deletes multiple keys from cache.\n *\n * @param keys - Array of cache keys\n * @returns Number of keys deleted\n *\n * @example\n * ```typescript\n * const count = await cacheService.deleteMany(['user:1', 'user:2', 'user:3']);\n * console.log(`Deleted ${count} keys`);\n * ```\n */\n async deleteMany(keys: string[]): Promise<number> {\n return this.internalCache.deleteMany(keys);\n }\n\n /**\n * Gets all cache keys associated with a tag.\n *\n * @param tag - Tag name\n * @returns Array of cache keys\n *\n * @example\n * ```typescript\n * const keys = await cacheService.getKeysByTag('users');\n * console.log(`Found ${keys.length} cached user keys`);\n * ```\n */\n async getKeysByTag(tag: string): Promise<string[]> {\n return this.internalCache.getKeysByTag(tag);\n }\n\n /**\n * Invalidates cache by tag.\n *\n * @param tag - Tag to invalidate\n * @returns Number of keys invalidated\n *\n * @example\n * ```typescript\n * // Invalidate all user caches\n * const count = await cacheService.invalidate('users');\n * console.log(`Invalidated ${count} keys`);\n * ```\n */\n async invalidate(tag: string): Promise<number> {\n return this.internalCache.invalidateTag(tag);\n }\n\n /**\n * Invalidates multiple tags.\n *\n * @param tags - Array of tags to invalidate\n * @returns Total number of keys invalidated\n *\n * @example\n * ```typescript\n * const count = await cacheService.invalidate(['users', 'products']);\n * ```\n */\n async invalidateTags(tags: string[]): Promise<number> {\n return this.internalCache.invalidateTags(tags);\n }\n\n /**\n * Invalidates cache keys matching a pattern.\n * Uses Redis SCAN for safe iteration.\n *\n * @param pattern - Redis pattern (supports * and ?)\n * @returns Number of keys deleted\n *\n * @example\n * ```typescript\n * // Delete all user-related caches\n * await cacheService.invalidateByPattern('user:*');\n *\n * // Delete specific locale caches\n * await cacheService.invalidateByPattern('*:en_US');\n * ```\n */\n async invalidateByPattern(pattern: string): Promise<number> {\n return this.internalCache.invalidateByPattern(pattern);\n }\n\n /**\n * Checks if key exists in cache.\n *\n * @param key - Cache key\n * @returns True if key exists\n */\n async has(key: string): Promise<boolean> {\n return this.internalCache.has(key);\n }\n\n /**\n * Gets TTL for a cached key.\n *\n * @param key - Cache key\n * @returns TTL in seconds, -1 if no TTL, -2 if key doesn't exist\n */\n async ttl(key: string): Promise<number> {\n return this.internalCache.ttl(key);\n }\n\n /**\n * Clears all cache entries.\n * Use with caution in production.\n *\n * @example\n * ```typescript\n * await cacheService.clear();\n * ```\n */\n async clear(): Promise<void> {\n return this.internalCache.clear();\n }\n\n /**\n * Gets cache statistics.\n *\n * @returns Cache stats (hits, misses, size)\n *\n * @example\n * ```typescript\n * const stats = await cacheService.getStats();\n * console.log(`L1 Hit Rate: ${stats.l1.hits / (stats.l1.hits + stats.l1.misses) * 100}%`);\n * ```\n */\n async getStats(): Promise<CacheStats> {\n return this.internalCache.getStats();\n }\n}\n","/**\n * Event invalidation service.\n * Processes invalidation events and coordinates cache invalidation.\n */\n\nimport { createHash } from 'crypto';\nimport { EventEmitter } from 'events';\n\nimport { Injectable, Inject, Logger, OnModuleInit } from '@nestjs/common';\nimport { REDIS_DRIVER, IRedisDriver } from '@nestjs-redisx/core';\n\nimport { ICacheService } from '../../../cache/application/ports/cache-service.port';\nimport { CACHE_PLUGIN_OPTIONS, CACHE_SERVICE, INVALIDATION_REGISTRY } from '../../../shared/constants';\nimport { ICachePluginOptions } from '../../../shared/types';\nimport { IEventInvalidationService, InvalidationHandler, IInvalidationResult } from '../ports/event-invalidation.port';\nimport { IInvalidationRegistry } from '../ports/invalidation-registry.port';\n\n@Injectable()\nexport class EventInvalidationService implements IEventInvalidationService, OnModuleInit {\n private readonly logger = new Logger(EventInvalidationService.name);\n private readonly handlers = new Set<InvalidationHandler>();\n private readonly eventEmitter = new EventEmitter();\n\n constructor(\n @Inject(INVALIDATION_REGISTRY)\n private readonly registry: IInvalidationRegistry,\n @Inject(CACHE_SERVICE) private readonly cacheService: ICacheService,\n @Inject(REDIS_DRIVER) private readonly driver: IRedisDriver,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly config: ICachePluginOptions,\n ) {}\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async onModuleInit(): Promise<void> {\n // Setup event source based on config\n const source = this.config.invalidation?.source ?? 'internal';\n\n if (source === 'internal') {\n this.setupInternalSource();\n this.logger.log('Event invalidation initialized with internal source');\n }\n // AMQP source is setup via AMQPEventSourceAdapter\n }\n\n async processEvent(event: string, payload: unknown): Promise<IInvalidationResult> {\n const startTime = Date.now();\n\n try {\n // Deduplication check\n const eventId = this.generateEventId(event, payload);\n const isDuplicate = await this.checkDuplicate(eventId);\n\n if (isDuplicate) {\n this.logger.debug(`Skipping duplicate event \"${event}\"`);\n return {\n event,\n tagsInvalidated: [],\n keysInvalidated: [],\n totalKeysDeleted: 0,\n duration: Date.now() - startTime,\n skipped: true,\n skipReason: 'duplicate',\n };\n }\n\n // Resolve what to invalidate\n const resolved = this.registry.resolve(event, payload);\n\n if (resolved.tags.length === 0 && resolved.keys.length === 0) {\n this.logger.debug(`No matching rules for event \"${event}\"`);\n return {\n event,\n tagsInvalidated: [],\n keysInvalidated: [],\n totalKeysDeleted: 0,\n duration: Date.now() - startTime,\n skipped: true,\n skipReason: 'no_matching_rules',\n };\n }\n\n // Perform invalidation\n let totalDeleted = 0;\n\n if (resolved.tags.length > 0) {\n this.logger.debug(`Invalidating tags: ${resolved.tags.join(', ')} for event \"${event}\"`);\n totalDeleted += await this.cacheService.invalidateTags(resolved.tags);\n }\n\n if (resolved.keys.length > 0) {\n this.logger.debug(`Invalidating keys: ${resolved.keys.join(', ')} for event \"${event}\"`);\n totalDeleted += await this.cacheService.deleteMany(resolved.keys);\n }\n\n // Mark as processed\n await this.markProcessed(eventId);\n\n const result: IInvalidationResult = {\n event,\n tagsInvalidated: resolved.tags,\n keysInvalidated: resolved.keys,\n totalKeysDeleted: totalDeleted,\n duration: Date.now() - startTime,\n skipped: false,\n };\n\n this.logger.log(`Processed event \"${event}\": invalidated ${resolved.tags.length} tags, ${resolved.keys.length} keys, deleted ${totalDeleted} cache entries (${result.duration}ms)`);\n\n // Notify handlers\n await this.notifyHandlers(event, payload, result);\n\n return result;\n } catch (error) {\n this.logger.error(`Failed to process event \"${event}\":`, error);\n throw error;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async emit(event: string, payload: unknown): Promise<void> {\n this.eventEmitter.emit('invalidation', { event, payload });\n }\n\n subscribe(handler: InvalidationHandler): () => void {\n this.handlers.add(handler);\n return () => this.handlers.delete(handler);\n }\n\n private setupInternalSource(): void {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.eventEmitter.on('invalidation', async ({ event, payload }) => {\n try {\n await this.processEvent(event, payload);\n } catch (error) {\n this.logger.error(`Internal event processing failed for \"${event}\":`, error);\n }\n });\n }\n\n private async checkDuplicate(eventId: string): Promise<boolean> {\n try {\n const key = `_invalidation:processed:${eventId}`;\n const exists = await this.driver.exists(key);\n return exists > 0;\n } catch (error) {\n this.logger.warn('Deduplication check failed:', error);\n return false; // Fail-open\n }\n }\n\n private async markProcessed(eventId: string): Promise<void> {\n try {\n const key = `_invalidation:processed:${eventId}`;\n const ttl = this.config.invalidation?.deduplicationTtl ?? 60;\n await this.driver.setex(key, ttl, '1');\n } catch (error) {\n this.logger.warn('Failed to mark event as processed:', error);\n // Don't throw - this is not critical\n }\n }\n\n private generateEventId(event: string, payload: unknown): string {\n const hash = createHash('sha256')\n .update(event)\n .update(JSON.stringify(payload ?? {}))\n .digest('hex')\n .slice(0, 16);\n return hash;\n }\n\n private async notifyHandlers(event: string, payload: unknown, result: IInvalidationResult): Promise<void> {\n for (const handler of this.handlers) {\n try {\n await handler(event, payload, result);\n } catch (error) {\n this.logger.error('Invalidation handler error:', error);\n // Don't propagate handler errors\n }\n }\n }\n}\n","/**\n * Invalidation registry service.\n * Manages invalidation rules and resolves what to invalidate for events.\n */\n\nimport { Injectable, Logger } from '@nestjs/common';\n\nimport { InvalidationRule } from '../../domain/entities/invalidation-rule.entity';\nimport { IInvalidationRegistry, IResolvedInvalidation } from '../ports/invalidation-registry.port';\n\n@Injectable()\nexport class InvalidationRegistryService implements IInvalidationRegistry {\n private readonly logger = new Logger(InvalidationRegistryService.name);\n private rules: InvalidationRule[] = [];\n\n register(rule: InvalidationRule): void {\n this.rules.push(rule);\n // Sort by priority (higher first)\n this.rules.sort((a, b) => b.getPriority() - a.getPriority());\n\n this.logger.debug(`Registered invalidation rule for event \"${rule.getEventPattern()}\" with priority ${rule.getPriority()}`);\n }\n\n registerMany(rules: InvalidationRule[]): void {\n for (const rule of rules) {\n this.register(rule);\n }\n }\n\n unregister(event: string): void {\n const initialLength = this.rules.length;\n this.rules = this.rules.filter((r) => r.getEventPattern() !== event);\n\n const removed = initialLength - this.rules.length;\n if (removed > 0) {\n this.logger.debug(`Unregistered ${removed} rule(s) for event \"${event}\"`);\n }\n }\n\n findRules(event: string): InvalidationRule[] {\n return this.rules.filter((rule) => rule.matches(event));\n }\n\n resolve(event: string, payload: unknown): IResolvedInvalidation {\n const matchedRules = this.findRules(event);\n const tagsSet = new Set<string>();\n const keysSet = new Set<string>();\n const applicableRules: InvalidationRule[] = [];\n\n for (const rule of matchedRules) {\n // Test condition\n if (!rule.testCondition(payload)) {\n this.logger.debug(`Rule for event \"${rule.getEventPattern()}\" skipped - condition not met`);\n continue;\n }\n\n applicableRules.push(rule);\n\n // Resolve tags\n if (rule.hasTags()) {\n const tags = rule.resolveTags(payload);\n for (const tag of tags) {\n // Only add if fully resolved (no remaining placeholders)\n if (!tag.includes('{')) {\n tagsSet.add(tag);\n } else {\n this.logger.warn(`Tag template \"${tag}\" has unresolved placeholders for event \"${event}\"`);\n }\n }\n }\n\n // Resolve keys\n if (rule.hasKeys()) {\n const keys = rule.resolveKeys(payload);\n for (const key of keys) {\n // Only add if fully resolved\n if (!key.includes('{')) {\n keysSet.add(key);\n } else {\n this.logger.warn(`Key template \"${key}\" has unresolved placeholders for event \"${event}\"`);\n }\n }\n }\n }\n\n return {\n tags: Array.from(tagsSet),\n keys: Array.from(keysSet),\n matchedRules: applicableRules,\n };\n }\n\n getRules(): InvalidationRule[] {\n return [...this.rules];\n }\n}\n","/**\n * Event pattern value object.\n * Supports AMQP-style wildcards: '*' for one word, '#' for zero or more words.\n */\n\nimport { ErrorCode } from '@nestjs-redisx/core';\n\nimport { CacheError } from '../../../shared/errors';\n\nexport class EventPattern {\n private readonly pattern: string;\n private readonly regex: RegExp;\n\n private constructor(pattern: string, regex: RegExp) {\n this.pattern = pattern;\n this.regex = regex;\n }\n\n /**\n * Creates EventPattern from string pattern.\n * @param pattern - AMQP-style pattern (e.g., 'user.*', 'order.#', 'product.updated')\n */\n static create(pattern: string): EventPattern {\n if (!pattern || pattern.trim().length === 0) {\n throw new CacheError('Event pattern cannot be empty', ErrorCode.VALIDATION_FAILED);\n }\n\n const normalized = pattern.trim();\n\n // Validate pattern format\n if (!/^[a-z0-9*#._-]+$/i.test(normalized)) {\n throw new CacheError(`Invalid event pattern \"${normalized}\". Only alphanumeric, dots, dashes, underscores, *, and # are allowed`, ErrorCode.VALIDATION_FAILED);\n }\n\n // Convert AMQP-style pattern to regex\n // '*' matches exactly one word (one segment between dots)\n // '#' matches zero or more words\n let regexStr = normalized\n .replace(/\\./g, '\\\\.') // Escape dots\n .replace(/\\*/g, '[^.]+') // * = one word\n .replace(/#/g, '.*'); // # = zero or more words\n\n // If pattern ends with .#, make the dot optional to match zero words\n regexStr = regexStr.replace(/\\\\\\.\\.\\*$/, '(?:\\\\..*)?');\n\n const regex = new RegExp(`^${regexStr}$`);\n\n return new EventPattern(normalized, regex);\n }\n\n /**\n * Tests if this pattern matches the given event.\n */\n matches(event: string): boolean {\n return this.regex.test(event);\n }\n\n /**\n * Returns the raw pattern string.\n */\n toString(): string {\n return this.pattern;\n }\n\n /**\n * Checks equality with another pattern.\n */\n equals(other: EventPattern): boolean {\n return this.pattern === other.pattern;\n }\n}\n","/**\n * Tag template value object.\n * Supports placeholders like 'user:{userId}' or 'tenant:{payload.tenantId}'.\n */\n\nimport { ErrorCode } from '@nestjs-redisx/core';\n\nimport { CacheError } from '../../../shared/errors';\n\nexport class TagTemplate {\n private readonly template: string;\n private readonly placeholders: string[];\n\n private constructor(template: string, placeholders: string[]) {\n this.template = template;\n this.placeholders = placeholders;\n }\n\n /**\n * Creates TagTemplate from template string.\n * @param template - Template string with placeholders (e.g., 'user:{userId}')\n */\n static create(template: string): TagTemplate {\n if (!template || template.trim().length === 0) {\n throw new CacheError('Tag template cannot be empty', ErrorCode.VALIDATION_FAILED);\n }\n\n const normalized = template.trim();\n\n // Extract placeholders\n const placeholders: string[] = [];\n const placeholderRegex = /\\{([^}]+)\\}/g;\n let match: RegExpExecArray | null;\n\n while ((match = placeholderRegex.exec(normalized)) !== null) {\n placeholders.push(match[1]!);\n }\n\n return new TagTemplate(normalized, placeholders);\n }\n\n /**\n * Resolves template with given payload.\n * @param payload - Data object to resolve placeholders from\n * @returns Resolved tag string\n */\n resolve(payload: unknown): string {\n return this.template.replace(/\\{([^}]+)\\}/g, (_, path) => {\n const value = this.getNestedValue(payload, path);\n if (value === undefined || value === null) {\n // Keep placeholder unresolved if value not found\n return `{${path}}`;\n }\n return String(value);\n });\n }\n\n /**\n * Returns the raw template string.\n */\n toString(): string {\n return this.template;\n }\n\n /**\n * Returns all placeholders in the template.\n */\n getPlaceholders(): string[] {\n return [...this.placeholders];\n }\n\n /**\n * Checks if template has any placeholders.\n */\n hasPlaceholders(): boolean {\n return this.placeholders.length > 0;\n }\n\n private getNestedValue(obj: unknown, path: string): unknown {\n if (obj === null || obj === undefined) {\n return undefined;\n }\n\n const parts = path.split('.');\n let current: unknown = obj;\n\n for (const part of parts) {\n if (current === null || current === undefined) {\n return undefined;\n }\n\n if (typeof current !== 'object') {\n return undefined;\n }\n\n current = (current as Record<string, unknown>)[part];\n }\n\n return current;\n }\n}\n","/**\n * Invalidation rule entity.\n * Defines what to invalidate when an event occurs.\n */\n\nimport { EventPattern } from '../value-objects/event-pattern.vo';\nimport { TagTemplate } from '../value-objects/tag-template.vo';\n\nexport interface IInvalidationRuleProps {\n event: string;\n tags?: string[];\n keys?: string[];\n condition?: (payload: unknown) => boolean;\n priority?: number;\n}\n\nexport class InvalidationRule {\n private readonly eventPattern: EventPattern;\n private readonly tagTemplates: TagTemplate[];\n private readonly keyTemplates: TagTemplate[];\n private readonly condition?: (payload: unknown) => boolean;\n private readonly priority: number;\n\n private constructor(eventPattern: EventPattern, tagTemplates: TagTemplate[], keyTemplates: TagTemplate[], condition: ((payload: unknown) => boolean) | undefined, priority: number) {\n this.eventPattern = eventPattern;\n this.tagTemplates = tagTemplates;\n this.keyTemplates = keyTemplates;\n this.condition = condition;\n this.priority = priority;\n }\n\n /**\n * Creates InvalidationRule from props.\n */\n static create(props: IInvalidationRuleProps): InvalidationRule {\n const eventPattern = EventPattern.create(props.event);\n\n const tagTemplates = (props.tags ?? []).map((tag) => TagTemplate.create(tag));\n\n const keyTemplates = (props.keys ?? []).map((key) => TagTemplate.create(key));\n\n const priority = props.priority ?? 0;\n\n return new InvalidationRule(eventPattern, tagTemplates, keyTemplates, props.condition, priority);\n }\n\n /**\n * Tests if this rule matches the given event.\n */\n matches(event: string): boolean {\n return this.eventPattern.matches(event);\n }\n\n /**\n * Tests if condition passes for the given payload.\n */\n testCondition(payload: unknown): boolean {\n if (!this.condition) {\n return true;\n }\n\n try {\n return this.condition(payload);\n } catch {\n // If condition throws, treat as not passing\n return false;\n }\n }\n\n /**\n * Resolves tags for the given payload.\n */\n resolveTags(payload: unknown): string[] {\n return this.tagTemplates.map((template) => template.resolve(payload));\n }\n\n /**\n * Resolves keys for the given payload.\n */\n resolveKeys(payload: unknown): string[] {\n return this.keyTemplates.map((template) => template.resolve(payload));\n }\n\n /**\n * Gets rule priority (higher = processed first).\n */\n getPriority(): number {\n return this.priority;\n }\n\n /**\n * Gets the event pattern string.\n */\n getEventPattern(): string {\n return this.eventPattern.toString();\n }\n\n /**\n * Checks if rule has any tags.\n */\n hasTags(): boolean {\n return this.tagTemplates.length > 0;\n }\n\n /**\n * Checks if rule has any keys.\n */\n hasKeys(): boolean {\n return this.keyTemplates.length > 0;\n }\n\n /**\n * Checks if rule has a condition.\n */\n hasCondition(): boolean {\n return this.condition !== undefined;\n }\n}\n","/**\n * AMQP event source adapter.\n * Integrates with RabbitMQ using @golevelup/nestjs-rabbitmq.\n * This is an optional adapter that requires @golevelup/nestjs-rabbitmq to be installed.\n */\n\nimport { Injectable, Inject, OnModuleInit, Logger, Optional } from '@nestjs/common';\n\nimport { AMQP_CONNECTION, CACHE_PLUGIN_OPTIONS, EVENT_INVALIDATION_SERVICE } from '../../../shared/constants';\nimport { ICachePluginOptions } from '../../../shared/types';\nimport { IEventInvalidationService } from '../../application/ports/event-invalidation.port';\n\ninterface IInvalidationMessage {\n payload: unknown;\n timestamp?: number;\n source?: string;\n}\n\n/**\n * AMQP connection interface (from @golevelup/nestjs-rabbitmq).\n * Using minimal interface to avoid tight coupling with the external library.\n */\ninterface IAMQPConnection {\n createSubscriber(\n handler: (msg: IInvalidationMessage, rawMsg: IRawMessage) => Promise<void>,\n options: {\n exchange: string;\n queue: string;\n routingKey: string[];\n queueOptions: { durable: boolean };\n },\n ): Promise<void>;\n}\n\n/**\n * Raw AMQP message interface.\n */\ninterface IRawMessage {\n fields: {\n routingKey: string;\n };\n}\n\n/**\n * AMQP Event Source Adapter.\n * Note: This adapter requires @golevelup/nestjs-rabbitmq to be installed.\n * If not available, the adapter will log a warning and do nothing.\n */\n@Injectable()\nexport class AMQPEventSourceAdapter implements OnModuleInit {\n private readonly logger = new Logger(AMQPEventSourceAdapter.name);\n private amqpConnection: IAMQPConnection | undefined;\n\n constructor(\n @Inject(EVENT_INVALIDATION_SERVICE)\n private readonly invalidationService: IEventInvalidationService,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly config: ICachePluginOptions,\n @Optional() @Inject(AMQP_CONNECTION) amqpConnection?: IAMQPConnection,\n ) {\n this.amqpConnection = amqpConnection;\n }\n\n async onModuleInit(): Promise<void> {\n const source = this.config.invalidation?.source;\n\n if (source !== 'amqp') {\n return;\n }\n\n if (!this.amqpConnection) {\n this.logger.warn('AMQP source configured but @golevelup/nestjs-rabbitmq is not available. ' + 'Install it with: npm install @golevelup/nestjs-rabbitmq');\n return;\n }\n\n const amqpConfig = this.config.invalidation?.amqp;\n if (!amqpConfig) {\n this.logger.warn('AMQP source configured but amqp config is missing');\n return;\n }\n\n const exchange = amqpConfig.exchange ?? 'cache.invalidation';\n const queue = amqpConfig.queue ?? `${this.getServiceName()}.cache.invalidation`;\n const routingKeys = amqpConfig.routingKeys ?? ['#'];\n\n try {\n // Subscribe to invalidation events\n await this.amqpConnection.createSubscriber(\n async (msg: IInvalidationMessage, rawMsg: IRawMessage) => {\n const routingKey = rawMsg.fields.routingKey;\n this.logger.debug(`Received AMQP invalidation event: ${routingKey}`);\n await this.invalidationService.processEvent(routingKey, msg.payload);\n },\n {\n exchange,\n queue,\n routingKey: routingKeys,\n queueOptions: {\n durable: true,\n },\n },\n );\n\n this.logger.log(`AMQP event source initialized: exchange=${exchange}, queue=${queue}, routingKeys=${routingKeys.join(',')}`);\n } catch (error) {\n this.logger.error('Failed to setup AMQP event source:', error);\n throw error;\n }\n }\n\n private getServiceName(): string {\n return process.env.SERVICE_NAME ?? 'app';\n }\n}\n","/**\n * Anti-stampede protection using local singleflight + distributed Redis lock.\n *\n * Two layers of protection:\n * 1. Local singleflight — coalesces concurrent requests within the same process\n * 2. Distributed lock — prevents duplicate loading across multiple instances\n */\n\nimport { Injectable, Inject, Logger } from '@nestjs/common';\nimport { REDIS_DRIVER, IRedisDriver } from '@nestjs-redisx/core';\n\nimport { CACHE_PLUGIN_OPTIONS } from '../../shared/constants';\nimport { StampedeError, LoaderError } from '../../shared/errors';\nimport { ICachePluginOptions, IStampedeResult, IStampedeStats } from '../../shared/types';\nimport { IStampedeProtection } from '../application/ports/stampede-protection.port';\n\n/** Lua script to release lock only if we own it */\nconst RELEASE_LOCK_SCRIPT = `\nif redis.call(\"get\", KEYS[1]) == ARGV[1] then\n return redis.call(\"del\", KEYS[1])\nelse\n return 0\nend\n`.trim();\n\n/** Prefix for stampede lock keys in Redis */\nconst LOCK_PREFIX = '_stampede:';\n\n/** Polling interval when waiting for another loader (ms) */\nconst _POLL_INTERVAL_MS = 50;\n\ninterface IFlight<T> {\n promise: Promise<T>;\n resolve: (value: T) => void;\n reject: (error: Error) => void;\n waiters: number;\n timestamp: number;\n}\n\n@Injectable()\nexport class StampedeProtectionService implements IStampedeProtection {\n private readonly logger = new Logger(StampedeProtectionService.name);\n private readonly flights = new Map<string, IFlight<unknown>>();\n private readonly lockTimeout: number;\n private readonly waitTimeout: number;\n private prevented = 0;\n\n constructor(\n @Inject(CACHE_PLUGIN_OPTIONS)\n private readonly options: ICachePluginOptions,\n @Inject(REDIS_DRIVER)\n private readonly driver: IRedisDriver,\n ) {\n this.lockTimeout = options.stampede?.lockTimeout ?? 5000;\n this.waitTimeout = options.stampede?.waitTimeout ?? 10000;\n }\n\n async protect<T>(key: string, loader: () => Promise<T>): Promise<IStampedeResult<T>> {\n // Layer 1: Local singleflight (same-process deduplication)\n const existingFlight = this.flights.get(key);\n\n if (existingFlight) {\n existingFlight.waiters++;\n this.prevented++;\n const value = await this.waitForFlight<T>(existingFlight as IFlight<T>, key);\n return { value, cached: true, waited: true };\n }\n\n // Create flight SYNCHRONOUSLY before any async work\n // This ensures concurrent calls within the same tick see the flight\n let resolveFunc!: (value: T) => void;\n let rejectFunc!: (error: Error) => void;\n\n const promise = new Promise<T>((resolve, reject) => {\n resolveFunc = resolve;\n rejectFunc = reject;\n });\n\n const flight: IFlight<T> = {\n promise,\n resolve: resolveFunc,\n reject: rejectFunc,\n waiters: 0,\n timestamp: Date.now(),\n };\n\n this.flights.set(key, flight as IFlight<unknown>);\n\n // Layer 2: Try distributed lock (async)\n let lock: { lockKey: string; lockValue: string } | undefined;\n\n try {\n const lockKey = `${LOCK_PREFIX}${key}`;\n const lockValue = this.generateLockValue();\n const lockTtlSeconds = Math.ceil(this.lockTimeout / 1000);\n\n const acquired = await this.tryAcquireLock(lockKey, lockValue, lockTtlSeconds);\n\n if (acquired) {\n lock = { lockKey, lockValue };\n }\n // If not acquired, another instance is loading.\n // We still execute the loader as fallback since we're already the leader\n // in this process (the flight is registered).\n } catch {\n // Lock acquisition failed — proceed without distributed lock\n }\n\n // Execute loader\n try {\n const value = await this.executeLoader(loader, key);\n flight.resolve(value);\n return { value, cached: false, waited: false };\n } catch (error) {\n if (flight.waiters > 0) {\n flight.reject(error as Error);\n }\n throw error;\n } finally {\n setTimeout(() => {\n this.flights.delete(key);\n }, 100);\n\n if (lock) {\n this.releaseLock(lock.lockKey, lock.lockValue).catch((err) => {\n this.logger.warn(`Failed to release lock for \"${key}\": ${err.message}`);\n });\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async clearKey(key: string): Promise<void> {\n const flight = this.flights.get(key);\n if (flight) {\n flight.reject(new Error('Flight cancelled'));\n this.flights.delete(key);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async clearAll(): Promise<void> {\n for (const [, flight] of this.flights.entries()) {\n flight.reject(new Error('All flights cancelled'));\n }\n this.flights.clear();\n }\n\n getStats(): IStampedeStats {\n const stats: IStampedeStats = {\n activeFlights: this.flights.size,\n totalWaiters: 0,\n oldestFlight: 0,\n prevented: this.prevented,\n };\n\n const now = Date.now();\n let oldestTimestamp = now;\n\n for (const flight of this.flights.values()) {\n stats.totalWaiters += flight.waiters;\n if (flight.timestamp < oldestTimestamp) {\n oldestTimestamp = flight.timestamp;\n }\n }\n\n stats.oldestFlight = stats.activeFlights > 0 ? now - oldestTimestamp : 0;\n return stats;\n }\n\n private async waitForFlight<T>(flight: IFlight<T>, key: string): Promise<T> {\n const age = Date.now() - flight.timestamp;\n if (age > this.lockTimeout) {\n throw new StampedeError(key, age);\n }\n\n let timeoutId: NodeJS.Timeout | undefined;\n let timeoutCancelled = false;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n if (!timeoutCancelled) {\n reject(new StampedeError(key, this.waitTimeout));\n }\n }, this.waitTimeout);\n });\n\n try {\n const result = await Promise.race([flight.promise, timeoutPromise]);\n timeoutCancelled = true;\n if (timeoutId) clearTimeout(timeoutId);\n return result;\n } catch (error) {\n timeoutCancelled = true;\n if (timeoutId) clearTimeout(timeoutId);\n throw error;\n }\n }\n\n private async executeLoader<T>(loader: () => Promise<T>, key: string): Promise<T> {\n let timeoutId: NodeJS.Timeout | undefined;\n let timeoutCancelled = false;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n if (!timeoutCancelled) {\n reject(new StampedeError(key, this.lockTimeout));\n }\n }, this.lockTimeout);\n });\n\n try {\n const result = await Promise.race([loader(), timeoutPromise]);\n timeoutCancelled = true;\n if (timeoutId) clearTimeout(timeoutId);\n return result;\n } catch (error) {\n timeoutCancelled = true;\n if (timeoutId) clearTimeout(timeoutId);\n\n if (error instanceof StampedeError) {\n throw error;\n }\n\n throw new LoaderError(key, error as Error);\n }\n }\n\n private async tryAcquireLock(lockKey: string, lockValue: string, ttlSeconds: number): Promise<boolean> {\n try {\n const result = await this.driver.set(lockKey, lockValue, { ex: ttlSeconds, nx: true });\n return result === 'OK';\n } catch (error) {\n this.logger.warn(`Failed to acquire distributed lock: ${(error as Error).message}`);\n return false;\n }\n }\n\n private async releaseLock(lockKey: string, lockValue: string): Promise<void> {\n try {\n await this.driver.eval(RELEASE_LOCK_SCRIPT, [lockKey], [lockValue]);\n } catch (error) {\n this.logger.warn(`Failed to release distributed lock: ${(error as Error).message}`);\n }\n }\n\n private generateLockValue(): string {\n return `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n }\n}\n","/**\n * Stale-While-Revalidate manager.\n * Serves stale data while revalidating in the background.\n */\n\nimport { Injectable, Inject, Logger } from '@nestjs/common';\n\nimport { CACHE_PLUGIN_OPTIONS } from '../../shared/constants';\nimport { ICachePluginOptions, SwrEntry } from '../../shared/types';\nimport { ISwrManager } from '../application/ports/swr-manager.port';\n\ninterface IRevalidationJob<T> {\n key: string;\n loader: () => Promise<T>;\n onSuccess: (value: T) => Promise<void>;\n onError: (error: Error) => void;\n timestamp: number;\n}\n\n@Injectable()\nexport class SwrManagerService implements ISwrManager {\n private readonly logger = new Logger(SwrManagerService.name);\n private readonly jobs = new Map<string, IRevalidationJob<unknown>>();\n private readonly staleTtl: number;\n private readonly enabled: boolean;\n\n constructor(\n @Inject(CACHE_PLUGIN_OPTIONS)\n private readonly options: ICachePluginOptions,\n ) {\n this.enabled = options.swr?.enabled ?? false;\n this.staleTtl = options.swr?.defaultStaleTime ?? 60;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async get<T>(_key: string): Promise<SwrEntry<T> | null> {\n // SWR entries are stored in L2 cache via getSwr/setSwr.\n // This method is not used directly; CacheService accesses L2 store.\n return null;\n }\n\n async set<T>(_key: string, _value: T, _staleTimeSeconds: number): Promise<void> {\n // SWR entries are stored in L2 cache via getSwr/setSwr.\n }\n\n async delete(_key: string): Promise<void> {\n // SWR entries are deleted from L2 cache directly.\n }\n\n isStale<T>(entry: SwrEntry<T>): boolean {\n const now = Date.now();\n return now > entry.staleAt;\n }\n\n isExpired<T>(entry: SwrEntry<T>): boolean {\n const now = Date.now();\n return now > entry.expiresAt;\n }\n\n shouldRevalidate(key: string): boolean {\n // Don't revalidate if job already running\n return !this.jobs.has(key);\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async scheduleRevalidation<T>(key: string, loader: () => Promise<T>, onSuccess: (value: T) => Promise<void>, onError?: (error: Error) => void): Promise<void> {\n // Check if already scheduled\n if (this.jobs.has(key)) {\n this.logger.debug(`Revalidation already scheduled for key: ${key}`);\n return;\n }\n\n const job: IRevalidationJob<T> = {\n key,\n loader,\n onSuccess,\n onError: onError ?? ((error) => this.logger.error(`Revalidation failed for ${key}:`, error)),\n timestamp: Date.now(),\n };\n\n this.jobs.set(key, job as IRevalidationJob<unknown>);\n\n // Execute in background\n setImmediate(() => {\n void this.executeRevalidation(job);\n });\n }\n\n createSwrEntry<T>(value: T, freshTtl: number, staleTtl?: number): SwrEntry<T> {\n const now = Date.now();\n const freshTtlMs = freshTtl * 1000;\n const staleTtlMs = (staleTtl ?? this.staleTtl) * 1000;\n\n return {\n value,\n cachedAt: now,\n staleAt: now + freshTtlMs,\n expiresAt: now + freshTtlMs + staleTtlMs,\n };\n }\n\n getStats() {\n return {\n activeRevalidations: this.jobs.size,\n enabled: this.enabled,\n staleTtl: this.staleTtl,\n };\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async clearRevalidations(): Promise<void> {\n this.jobs.clear();\n }\n\n private async executeRevalidation<T>(job: IRevalidationJob<T>): Promise<void> {\n try {\n this.logger.debug(`Starting revalidation for key: ${job.key}`);\n\n const value = await job.loader();\n\n this.logger.debug(`Revalidation successful for key: ${job.key}`);\n\n await job.onSuccess(value);\n } catch (error) {\n this.logger.error(`Revalidation failed for key: ${job.key}`, error);\n job.onError(error as Error);\n } finally {\n this.jobs.delete(job.key);\n }\n }\n}\n","/**\n * Tag index repository for tag-based cache invalidation.\n * Maintains mapping of tags to cache keys.\n */\n\nimport { Injectable, Inject } from '@nestjs/common';\nimport { REDIS_DRIVER, IRedisDriver } from '@nestjs-redisx/core';\n\nimport { Tag } from '../../../cache/domain/value-objects/tag.vo';\nimport { Tags } from '../../../cache/domain/value-objects/tags.vo';\nimport { CACHE_PLUGIN_OPTIONS, LUA_SCRIPT_LOADER } from '../../../shared/constants';\nimport { TagInvalidationError } from '../../../shared/errors';\nimport { ICachePluginOptions } from '../../../shared/types';\nimport { ITagIndex } from '../../application/ports/tag-index.port';\nimport { LuaScriptLoader } from '../services/lua-script-loader.service';\n\n/** Batch size for tag key deletion and SCAN operations. */\nconst TAG_BATCH_SIZE = 100;\n\n@Injectable()\nexport class TagIndexRepository implements ITagIndex {\n private readonly tagPrefix: string;\n\n constructor(\n @Inject(REDIS_DRIVER) private readonly driver: IRedisDriver,\n @Inject(CACHE_PLUGIN_OPTIONS) private readonly options: ICachePluginOptions,\n @Inject(LUA_SCRIPT_LOADER) private readonly luaLoader: LuaScriptLoader,\n ) {\n // Tag prefix should include L2 key prefix\n const l2Prefix = options.l2?.keyPrefix ?? 'cache:';\n const tagIndexPrefix = options.tags?.indexPrefix ?? '_tag:';\n this.tagPrefix = `${l2Prefix}${tagIndexPrefix}`;\n }\n\n async addKeyToTags(key: string, tags: string[]): Promise<void> {\n if (tags.length === 0) {\n return;\n }\n\n try {\n // Validate tags using Tags VO\n const validatedTags = this.validateTags(tags);\n // Tag TTL should be at least as long as the max cache TTL\n // to ensure tag indexes remain valid for all cached entries\n const tagTtl = this.options.tags?.ttl ?? this.options.l2?.maxTtl ?? 86400;\n\n // Cluster-safe: use individual operations instead of Lua script\n // This avoids CROSSSLOT errors when tag keys are on different slots\n const operations = validatedTags.map(async (tag) => {\n const tagKey = this.buildTagKey(tag);\n await this.driver.sadd(tagKey, key);\n await this.driver.expire(tagKey, tagTtl);\n });\n\n await Promise.all(operations);\n } catch (error) {\n throw new TagInvalidationError(tags[0] ?? 'unknown', `Failed to add key \"${key}\" to tags [${tags.join(', ')}]: ${(error as Error).message}`, error as Error);\n }\n }\n\n async removeKeyFromTags(key: string, tags: string[]): Promise<void> {\n if (tags.length === 0) {\n return;\n }\n\n try {\n // Validate tags using Tags VO\n const validatedTags = this.validateTags(tags);\n\n // Cluster-safe: remove from each tag individually\n await Promise.all(\n validatedTags.map(async (tag) => {\n const tagKey = this.buildTagKey(tag);\n await this.driver.srem(tagKey, key);\n }),\n );\n } catch (error) {\n throw new TagInvalidationError(tags[0] ?? 'unknown', `Failed to remove key \"${key}\" from tags [${tags.join(', ')}]: ${(error as Error).message}`, error as Error);\n }\n }\n\n async getKeysByTag(tag: string): Promise<string[]> {\n try {\n // Validate tag using Tag VO\n const validTag = Tag.create(tag);\n const tagKey = this.buildTagKey(validTag.toString());\n const keys = await this.driver.smembers(tagKey);\n return keys;\n } catch (error) {\n throw new TagInvalidationError(tag, `Failed to get keys for tag: ${(error as Error).message}`, error as Error);\n }\n }\n\n async invalidateTag(tag: string): Promise<number> {\n try {\n // Validate tag using Tag VO\n const validTag = Tag.create(tag);\n const tagKey = this.buildTagKey(validTag.toString());\n\n // Get all cache keys for this tag\n const cacheKeys = await this.driver.smembers(tagKey);\n\n if (cacheKeys.length === 0) {\n // Delete empty tag set\n await this.driver.del(tagKey);\n return 0;\n }\n\n // Cluster-safe: delete keys individually to avoid CROSSSLOT errors\n // In standalone/sentinel mode this is slightly slower but works everywhere\n let deletedCount = 0;\n\n // Delete in batches to avoid blocking Redis for too long\n const batchSize = TAG_BATCH_SIZE;\n for (let i = 0; i < cacheKeys.length; i += batchSize) {\n const batch = cacheKeys.slice(i, i + batchSize);\n\n // Delete each key individually (cluster-safe)\n const results = await Promise.all(batch.map((key) => this.driver.del(key)));\n\n deletedCount += results.reduce((sum, result) => sum + result, 0);\n }\n\n // Delete the tag set itself\n await this.driver.del(tagKey);\n\n return deletedCount;\n } catch (error) {\n throw new TagInvalidationError(tag, `Failed to invalidate tag: ${(error as Error).message}`, error as Error);\n }\n }\n\n async invalidateTags(tags: string[]): Promise<number> {\n if (tags.length === 0) {\n return 0;\n }\n\n try {\n // Validate tags using Tags VO\n const validatedTags = this.validateTags(tags);\n\n let totalInvalidated = 0;\n\n for (const tag of validatedTags) {\n const count = await this.invalidateTag(tag);\n totalInvalidated += count;\n }\n\n return totalInvalidated;\n } catch (error) {\n throw new TagInvalidationError(tags[0] ?? 'unknown', `Failed to invalidate tags [${tags.join(', ')}]: ${(error as Error).message}`, error as Error);\n }\n }\n\n async clearAllTags(): Promise<void> {\n try {\n const pattern = `${this.tagPrefix}*`;\n const keys = await this.scanKeys(pattern);\n\n if (keys.length === 0) {\n return;\n }\n\n // Cluster-safe: delete keys individually\n const batchSize = TAG_BATCH_SIZE;\n for (let i = 0; i < keys.length; i += batchSize) {\n const batch = keys.slice(i, i + batchSize);\n\n // Delete each key individually to avoid CROSSSLOT errors\n await Promise.all(batch.map((key) => this.driver.del(key)));\n }\n } catch (error) {\n throw new TagInvalidationError('_all', `Failed to clear all tags: ${(error as Error).message}`, error as Error);\n }\n }\n\n async getTagStats(tag: string): Promise<{ keyCount: number; exists: boolean }> {\n try {\n // Validate tag using Tag VO\n const validTag = Tag.create(tag);\n const tagKey = this.buildTagKey(validTag.toString());\n const exists = (await this.driver.exists(tagKey)) > 0;\n const keyCount = exists ? await this.driver.scard(tagKey) : 0;\n\n return { keyCount, exists };\n } catch {\n return { keyCount: 0, exists: false };\n }\n }\n\n /**\n * Validates tags using Tags value object.\n *\n * @param tags - Array of tag strings\n * @returns Array of validated tag strings\n * @throws CacheError if validation fails\n * @private\n */\n private validateTags(tags: string[]): string[] {\n const maxTags = this.options.tags?.maxTagsPerKey ?? 10;\n const tagsVo = Tags.create(tags, maxTags);\n return tagsVo.toStrings();\n }\n\n private buildTagKey(tag: string): string {\n return `${this.tagPrefix}${tag}`;\n }\n\n private async scanKeys(pattern: string): Promise<string[]> {\n const keys: string[] = [];\n let cursor = 0;\n\n do {\n const result = await this.driver.scan(cursor, {\n match: pattern,\n count: TAG_BATCH_SIZE,\n });\n cursor = parseInt(result[0], 10);\n keys.push(...result[1]);\n } while (cursor !== 0);\n\n return keys;\n }\n}\n","/**\n * Inline Lua scripts for tag-based cache invalidation.\n *\n * Scripts are stored as inline strings to avoid issues with file reading\n * after build (dist directory doesn't contain .lua files).\n */\n\n/**\n * Atomically adds a cache key to multiple tag sets.\n *\n * KEYS[1..N] = tag set keys\n * ARGV[1] = cache key to add\n * ARGV[2] = TTL for tag sets in seconds\n *\n * Returns: number of tag sets updated\n */\nexport const ADD_KEY_TO_TAGS_SCRIPT = `\nlocal cache_key = ARGV[1]\nlocal tag_ttl = tonumber(ARGV[2])\n\nfor i = 1, #KEYS do\n local tag_key = KEYS[i]\n redis.call('SADD', tag_key, cache_key)\n redis.call('EXPIRE', tag_key, tag_ttl)\nend\n\nreturn #KEYS\n`.trim();\n\n/**\n * Atomically invalidates all cache keys for a tag.\n *\n * KEYS[1] = tag set key (e.g., \"cache:_tag:users\")\n *\n * Returns: number of deleted cache keys\n */\nexport const INVALIDATE_TAG_SCRIPT = `\nlocal tag_key = KEYS[1]\n\n-- Get all cache keys for this tag\nlocal cache_keys = redis.call('SMEMBERS', tag_key)\n\nif #cache_keys == 0 then\n -- Delete empty tag set and return 0\n redis.call('DEL', tag_key)\n return 0\nend\n\n-- Delete all cache keys\nlocal deleted = 0\nfor i = 1, #cache_keys do\n local result = redis.call('DEL', cache_keys[i])\n deleted = deleted + result\nend\n\n-- Delete the tag set itself\nredis.call('DEL', tag_key)\n\nreturn deleted\n`.trim();\n","/**\n * Lua script loader service.\n * Loads inline Lua scripts and registers them with Redis.\n *\n * Scripts are stored as inline strings to avoid issues with file reading\n * after build (dist directory doesn't contain .lua files).\n */\n\nimport { Injectable, Inject, OnModuleInit, Logger } from '@nestjs/common';\nimport { REDIS_DRIVER, IRedisDriver } from '@nestjs-redisx/core';\n\nimport { ADD_KEY_TO_TAGS_SCRIPT, INVALIDATE_TAG_SCRIPT } from '../scripts/lua-scripts';\n\n/**\n * Map of script names to their inline content.\n */\nconst SCRIPTS: Record<string, string> = {\n 'invalidate-tag': INVALIDATE_TAG_SCRIPT,\n 'add-key-to-tags': ADD_KEY_TO_TAGS_SCRIPT,\n};\n\n@Injectable()\nexport class LuaScriptLoader implements OnModuleInit {\n private readonly logger = new Logger(LuaScriptLoader.name);\n private readonly scriptShas = new Map<string, string>();\n\n constructor(@Inject(REDIS_DRIVER) private readonly driver: IRedisDriver) {}\n\n async onModuleInit(): Promise<void> {\n await this.loadScripts();\n }\n\n /**\n * Loads all Lua scripts into Redis.\n */\n private async loadScripts(): Promise<void> {\n for (const [scriptName, scriptContent] of Object.entries(SCRIPTS)) {\n try {\n // Load script into Redis and get SHA\n const sha = await this.driver.scriptLoad(scriptContent);\n this.scriptShas.set(scriptName, sha);\n\n this.logger.debug(`Loaded Lua script: ${scriptName} (SHA: ${sha})`);\n } catch (error) {\n this.logger.error(`Failed to load script ${scriptName}:`, error);\n throw error;\n }\n }\n\n this.logger.log(`Successfully loaded ${this.scriptShas.size} Lua scripts`);\n }\n\n /**\n * Executes a Lua script by name using EVALSHA.\n *\n * @param scriptName - Name of the script\n * @param keys - Redis keys to pass to the script\n * @param args - Arguments to pass to the script\n * @returns Script execution result\n */\n async evalSha(scriptName: string, keys: string[], args: (string | number)[]): Promise<unknown> {\n const sha = this.scriptShas.get(scriptName);\n\n if (!sha) {\n throw new Error(`Lua script not loaded: ${scriptName}`);\n }\n\n return this.driver.evalsha(sha, keys, args);\n }\n\n /**\n * Gets the SHA hash of a loaded script.\n *\n * @param scriptName - Name of the script\n * @returns SHA hash or undefined if not loaded\n */\n getSha(scriptName: string): string | undefined {\n return this.scriptShas.get(scriptName);\n }\n\n /**\n * Checks if a script is loaded.\n *\n * @param scriptName - Name of the script\n * @returns True if script is loaded\n */\n isLoaded(scriptName: string): boolean {\n return this.scriptShas.has(scriptName);\n }\n}\n","/**\n * Cache plugin for NestJS RedisX.\n * Provides L1+L2 caching with anti-stampede, SWR, and tag invalidation.\n */\n\nimport { DynamicModule, ForwardReference, Provider, Type } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { IRedisXPlugin, IPluginAsyncOptions } from '@nestjs-redisx/core';\n\nimport { version } from '../package.json';\nimport { CacheDecoratorInitializerService } from './cache/application/services/cache-decorator-initializer.service';\nimport { CacheService as InternalCacheService } from './cache/application/services/cache.service';\nimport { WarmupService } from './cache/application/services/warmup.service';\nimport { Serializer } from './cache/domain/services/serializer.service';\nimport { L1MemoryStoreAdapter } from './cache/infrastructure/adapters/l1-memory-store.adapter';\nimport { L2RedisStoreAdapter } from './cache/infrastructure/adapters/l2-redis-store.adapter';\nimport { CacheService } from './cache.service';\nimport { EventInvalidationService } from './invalidation/application/services/event-invalidation.service';\nimport { InvalidationRegistryService } from './invalidation/application/services/invalidation-registry.service';\nimport { InvalidationRule } from './invalidation/domain/entities/invalidation-rule.entity';\nimport { AMQPEventSourceAdapter } from './invalidation/infrastructure/adapters/amqp-event-source.adapter';\nimport { CACHE_PLUGIN_OPTIONS, CACHE_SERVICE, DEFAULT_CACHE_CONFIG, INVALIDATION_REGISTRY, EVENT_INVALIDATION_SERVICE, INVALIDATION_RULES_INIT, L1_CACHE_STORE, L2_CACHE_STORE, STAMPEDE_PROTECTION, TAG_INDEX, SWR_MANAGER, SERIALIZER, LUA_SCRIPT_LOADER } from './shared/constants';\nimport { ICachePluginOptions } from './shared/types';\nimport { StampedeProtectionService } from './stampede/infrastructure/stampede-protection.service';\nimport { SwrManagerService } from './swr/infrastructure/swr-manager.service';\nimport { TagIndexRepository } from './tags/infrastructure/repositories/tag-index.repository';\nimport { LuaScriptLoader } from './tags/infrastructure/services/lua-script-loader.service';\n\nexport class CachePlugin implements IRedisXPlugin {\n readonly name = 'cache';\n readonly version: string = version;\n readonly description = 'Advanced caching with L1+L2, anti-stampede, SWR, and tag invalidation';\n\n private asyncOptions?: IPluginAsyncOptions<ICachePluginOptions>;\n\n constructor(private readonly options: ICachePluginOptions = {}) {}\n\n /**\n * Create a CachePlugin with async configuration from DI.\n *\n * @example\n * ```typescript\n * CachePlugin.registerAsync({\n * imports: [ConfigModule],\n * inject: [ConfigService],\n * useFactory: (config: ConfigService) => ({\n * l1: { maxSize: config.get('CACHE_L1_MAX_SIZE', 1000) },\n * swr: { enabled: config.get('CACHE_SWR_ENABLED', false) },\n * }),\n * })\n * ```\n */\n static registerAsync(asyncOptions: IPluginAsyncOptions<ICachePluginOptions>): CachePlugin {\n const plugin = new CachePlugin();\n plugin.asyncOptions = asyncOptions;\n return plugin;\n }\n\n private static mergeDefaults(options: ICachePluginOptions): ICachePluginOptions {\n return {\n l1: { ...DEFAULT_CACHE_CONFIG.l1, ...options.l1 },\n l2: { ...DEFAULT_CACHE_CONFIG.l2, ...options.l2 },\n stampede: { ...DEFAULT_CACHE_CONFIG.stampede, ...options.stampede },\n swr: { ...DEFAULT_CACHE_CONFIG.swr, ...options.swr },\n tags: { ...DEFAULT_CACHE_CONFIG.tags, ...options.tags },\n warmup: { ...DEFAULT_CACHE_CONFIG.warmup, ...options.warmup },\n keys: { ...DEFAULT_CACHE_CONFIG.keys, ...options.keys },\n invalidation: { ...DEFAULT_CACHE_CONFIG.invalidation, ...options.invalidation },\n };\n }\n\n getImports(): Array<Type<unknown> | DynamicModule | ForwardReference> {\n return this.asyncOptions?.imports ?? [];\n }\n\n getProviders(): Provider[] {\n // Options provider: useFactory (async) or useValue (sync)\n const optionsProvider: Provider = this.asyncOptions\n ? {\n provide: CACHE_PLUGIN_OPTIONS,\n useFactory: async (...args: unknown[]) => {\n const userOptions = await this.asyncOptions!.useFactory(...args);\n return CachePlugin.mergeDefaults(userOptions);\n },\n inject: this.asyncOptions.inject || [],\n }\n : {\n provide: CACHE_PLUGIN_OPTIONS,\n useValue: CachePlugin.mergeDefaults(this.options),\n };\n\n return [\n optionsProvider,\n\n // Domain services\n {\n provide: SERIALIZER,\n useClass: Serializer,\n },\n\n // Infrastructure adapters\n {\n provide: L1_CACHE_STORE,\n useClass: L1MemoryStoreAdapter,\n },\n {\n provide: L2_CACHE_STORE,\n useClass: L2RedisStoreAdapter,\n },\n\n // Application services\n {\n provide: CACHE_SERVICE,\n useClass: InternalCacheService,\n },\n {\n provide: STAMPEDE_PROTECTION,\n useClass: StampedeProtectionService,\n },\n {\n provide: TAG_INDEX,\n useClass: TagIndexRepository,\n },\n {\n provide: SWR_MANAGER,\n useClass: SwrManagerService,\n },\n {\n provide: LUA_SCRIPT_LOADER,\n useClass: LuaScriptLoader,\n },\n\n // Invalidation services\n {\n provide: INVALIDATION_REGISTRY,\n useClass: InvalidationRegistryService,\n },\n {\n provide: EVENT_INVALIDATION_SERVICE,\n useClass: EventInvalidationService,\n },\n\n // Invalidation adapters (optional)\n AMQPEventSourceAdapter,\n\n // Public API\n CacheService,\n\n // @Cached decorator initialization\n CacheDecoratorInitializerService,\n\n // Cache warmup (runs on OnModuleInit if enabled)\n WarmupService,\n\n // Reflector is needed for decorator metadata\n Reflector,\n\n // Factory for registering static invalidation rules\n {\n provide: INVALIDATION_RULES_INIT,\n useFactory: (registry: InvalidationRegistryService, config: ICachePluginOptions) => {\n // Register static rules from config\n if (config.invalidation?.rules && config.invalidation.rules.length > 0) {\n const rules = config.invalidation.rules.map((ruleProps) => InvalidationRule.create(ruleProps));\n registry.registerMany(rules);\n }\n return true;\n },\n inject: [INVALIDATION_REGISTRY, CACHE_PLUGIN_OPTIONS],\n },\n ];\n }\n\n getExports(): Array<string | symbol | Provider> {\n return [CACHE_PLUGIN_OPTIONS, CACHE_SERVICE, CacheService, INVALIDATION_REGISTRY, EVENT_INVALIDATION_SERVICE];\n }\n}\n","/**\n * @InvalidateTags decorator for automatic tag invalidation.\n *\n * Uses immediate proxy-based wrapping (not deferred to interceptor).\n * Works on ANY Injectable class methods (services, repositories, etc).\n */\n\nimport { Logger } from '@nestjs/common';\nimport 'reflect-metadata';\nimport { getCacheService } from './cached.decorator';\nimport { INVALIDATE_TAGS_KEY } from '../../../shared/constants';\n\nconst logger = new Logger('InvalidateTags');\n\nexport interface IInvalidateTagsOptions {\n /**\n * Tags to invalidate. Can be static array or function of method args.\n */\n tags: string[] | ((...args: unknown[]) => string[]);\n\n /**\n * When to invalidate: 'before' or 'after' method execution.\n * Default: 'after'\n */\n when?: 'before' | 'after';\n}\n\n/**\n * Invalidates cache tags when method is called.\n *\n * Works on any Injectable class method, not just controllers.\n *\n * @example\n * ```typescript\n * @Injectable()\n * class UserService {\n * @InvalidateTags({\n * tags: (id: string) => [`user:${id}`, 'users'],\n * when: 'after',\n * })\n * async updateUser(id: string, data: UpdateUserDto): Promise<User> {\n * return this.userRepository.update(id, data);\n * }\n *\n * @InvalidateTags({ tags: ['users'] })\n * async deleteUser(id: string): Promise<void> {\n * await this.userRepository.delete(id);\n * }\n * }\n * ```\n */\nexport function InvalidateTags(options: IInvalidateTagsOptions): MethodDecorator {\n return (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n const originalMethod = descriptor.value as (...args: unknown[]) => Promise<unknown>;\n const when = options.when ?? 'after';\n\n // Replace method with invalidation proxy\n descriptor.value = async function (...args: unknown[]): Promise<unknown> {\n const cacheService = getCacheService();\n\n // Resolve tags\n const tags = typeof options.tags === 'function' ? options.tags(...args) : options.tags;\n\n // Invalidate BEFORE if configured\n if (when === 'before' && cacheService && tags.length > 0) {\n try {\n await cacheService.invalidateTags(tags);\n } catch (error) {\n logger.error(`@InvalidateTags: Failed to invalidate tags before method:`, error);\n }\n }\n\n // Execute original method\n const result = await originalMethod.apply(this, args);\n\n // Invalidate AFTER if configured (default)\n if (when === 'after' && cacheService && tags.length > 0) {\n try {\n await cacheService.invalidateTags(tags);\n } catch (error) {\n logger.error(`@InvalidateTags: Failed to invalidate tags after method:`, error);\n }\n }\n\n return result;\n };\n\n // Preserve original method name\n Object.defineProperty(descriptor.value, 'name', {\n value: originalMethod.name,\n writable: false,\n });\n\n // Store metadata on WRAPPER function for reflection (after replacement)\n Reflect.defineMetadata(INVALIDATE_TAGS_KEY, options, descriptor.value);\n\n return descriptor;\n };\n}\n","/**\n * @Cacheable decorator for automatic method result caching.\n *\n * Caches method results and returns cached value on subsequent calls.\n * Supports key templates with parameter interpolation.\n *\n * @example\n * ```typescript\n * class UserService {\n * @Cacheable({\n * key: 'user:{id}',\n * ttl: 3600,\n * tags: ['users']\n * })\n * async getUser(id: string) {\n * return this.repository.findById(id);\n * }\n *\n * @Cacheable({\n * key: 'user:{userId}:posts:{postId}',\n * ttl: 1800\n * })\n * async getUserPost(userId: string, postId: string) {\n * return this.repository.findPost(userId, postId);\n * }\n * }\n * ```\n */\n\nimport { SetMetadata } from '@nestjs/common';\n\n/**\n * Options for @Cacheable decorator.\n */\nexport interface ICacheableOptions {\n /**\n * Cache key template. Supports parameter interpolation.\n * Use {paramName} to interpolate method parameters.\n *\n * @example 'user:{id}'\n * @example 'post:{userId}:{postId}'\n */\n key: string;\n\n /**\n * TTL in seconds.\n * @default 3600\n */\n ttl?: number;\n\n /**\n * Tags for invalidation.\n * Can be static array or function that returns array.\n */\n tags?: string[] | ((...args: unknown[]) => string[]);\n\n /**\n * Condition to determine if result should be cached.\n * Return false to skip caching for specific cases.\n */\n condition?: (...args: unknown[]) => boolean;\n\n /**\n * Custom key generator function.\n * If provided, overrides template-based key generation.\n */\n keyGenerator?: (...args: unknown[]) => string;\n\n /**\n * Namespace prefix for the key.\n * @default ''\n */\n namespace?: string;\n}\n\n/**\n * Metadata key for @Cacheable decorator.\n */\nexport const CACHEABLE_METADATA_KEY = 'cache:cacheable';\n\n/**\n * @Cacheable decorator.\n *\n * Automatically caches method results using the configured key template.\n * Supports parameter interpolation in key templates.\n *\n * @param options - Caching options\n *\n * @example\n * ```typescript\n * @Cacheable({ key: 'user:{id}', ttl: 3600 })\n * async getUser(id: string) {\n * return await this.repository.findById(id);\n * }\n * ```\n */\nexport function Cacheable(options: ICacheableOptions): MethodDecorator {\n return SetMetadata(CACHEABLE_METADATA_KEY, options);\n}\n","/**\n * @CachePut decorator for cache updates.\n *\n * Always executes the method and updates the cache with the result.\n * Unlike @Cacheable, it doesn't check the cache before execution.\n *\n * @example\n * ```typescript\n * class UserService {\n * @CachePut({\n * key: 'user:{id}',\n * tags: ['users']\n * })\n * async updateUser(id: string, data: UpdateUserDto) {\n * const updated = await this.repository.update(id, data);\n * return updated; // This result will be cached\n * }\n *\n * @CachePut({\n * key: 'user:{user.id}',\n * ttl: 1800\n * })\n * async createUser(user: CreateUserDto) {\n * const created = await this.repository.create(user);\n * return created; // This result will be cached\n * }\n * }\n * ```\n */\n\nimport { SetMetadata } from '@nestjs/common';\n\n/**\n * Options for @CachePut decorator.\n */\nexport interface ICachePutOptions {\n /**\n * Cache key template. Supports parameter interpolation.\n * Use {paramName} to interpolate method parameters.\n * Supports nested properties: {user.id}\n *\n * @example 'user:{id}'\n * @example 'user:{user.id}'\n */\n key: string;\n\n /**\n * TTL in seconds.\n * @default 3600\n */\n ttl?: number;\n\n /**\n * Tags for invalidation.\n * Can be static array or function that returns array.\n */\n tags?: string[] | ((...args: unknown[]) => string[]);\n\n /**\n * Condition to determine if result should be cached.\n * Return false to skip caching for specific cases.\n */\n condition?: (...args: unknown[]) => boolean;\n\n /**\n * Custom key generator function.\n * If provided, overrides template-based key generation.\n */\n keyGenerator?: (...args: unknown[]) => string;\n\n /**\n * Namespace prefix for the key.\n * @default ''\n */\n namespace?: string;\n\n /**\n * Whether to cache null/undefined results.\n * @default false\n */\n cacheNullValues?: boolean;\n}\n\n/**\n * Metadata key for @CachePut decorator.\n */\nexport const CACHE_PUT_METADATA_KEY = 'cache:put';\n\n/**\n * @CachePut decorator.\n *\n * Always executes the method and caches the result.\n * Useful for update operations where you want to refresh the cache.\n *\n * @param options - Cache put options\n *\n * @example\n * ```typescript\n * @CachePut({ key: 'user:{id}', ttl: 3600 })\n * async updateUser(id: string, data: UpdateUserDto) {\n * return await this.repository.update(id, data);\n * }\n * ```\n */\nexport function CachePut(options: ICachePutOptions): MethodDecorator {\n return SetMetadata(CACHE_PUT_METADATA_KEY, options);\n}\n","/**\n * @CacheEvict decorator for cache invalidation.\n *\n * Evicts (removes) cache entries after method execution.\n * Supports multiple keys, tags, and patterns.\n *\n * @example\n * ```typescript\n * class UserService {\n * @CacheEvict({\n * keys: ['user:{id}'],\n * tags: ['users']\n * })\n * async updateUser(id: string, data: UpdateUserDto) {\n * return this.repository.update(id, data);\n * }\n *\n * @CacheEvict({\n * keys: ['user:{userId}:posts:*'],\n * beforeInvocation: false\n * })\n * async deleteUserPosts(userId: string) {\n * return this.repository.deletePosts(userId);\n * }\n * }\n * ```\n */\n\nimport { SetMetadata } from '@nestjs/common';\n\n/**\n * Options for @CacheEvict decorator.\n */\nexport interface ICacheEvictOptions {\n /**\n * Cache keys or key templates to evict.\n * Supports parameter interpolation and wildcards.\n *\n * @example ['user:{id}']\n * @example ['user:{userId}:posts:*']\n */\n keys?: string[];\n\n /**\n * Tags to invalidate.\n * All keys with these tags will be evicted.\n */\n tags?: string[];\n\n /**\n * Whether to evict all cache entries.\n * Use with caution - this clears the entire cache.\n *\n * @default false\n */\n allEntries?: boolean;\n\n /**\n * Whether to evict cache before method invocation.\n * - true: evict before execution\n * - false: evict after execution (default)\n *\n * @default false\n */\n beforeInvocation?: boolean;\n\n /**\n * Condition to determine if cache should be evicted.\n * Return false to skip eviction for specific cases.\n */\n condition?: (...args: unknown[]) => boolean;\n\n /**\n * Custom key generator function.\n * If provided, overrides template-based key generation.\n */\n keyGenerator?: (...args: unknown[]) => string[];\n\n /**\n * Namespace prefix for the keys.\n * @default ''\n */\n namespace?: string;\n}\n\n/**\n * Metadata key for @CacheEvict decorator.\n */\nexport const CACHE_EVICT_METADATA_KEY = 'cache:evict';\n\n/**\n * @CacheEvict decorator.\n *\n * Automatically evicts cache entries after (or before) method execution.\n * Supports multiple keys, tags, and pattern matching.\n *\n * @param options - Eviction options\n *\n * @example\n * ```typescript\n * @CacheEvict({ keys: ['user:{id}'], tags: ['users'] })\n * async updateUser(id: string, data: UpdateUserDto) {\n * return await this.repository.update(id, data);\n * }\n * ```\n */\nexport function CacheEvict(options: ICacheEvictOptions = {}): MethodDecorator {\n return SetMetadata(CACHE_EVICT_METADATA_KEY, options);\n}\n","/**\n * Utility functions for cache key generation from templates.\n */\n\nimport { CacheKeyError } from '../shared/errors';\n\n/**\n * Extracts parameter names from method signature.\n *\n * @param method - Method to extract parameters from\n * @returns Array of parameter names\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport function getParameterNames(method: Function): string[] {\n const fnStr = method.toString().replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n const match = fnStr.match(/\\(([^)]*)\\)/);\n\n if (!match?.[1]) {\n return [];\n }\n\n const params = match[1];\n return params\n .split(',')\n .map((param) => param.trim().split('=')[0]?.trim() ?? '')\n .filter((param) => param && param !== '');\n}\n\n/**\n * Gets nested property value from object.\n *\n * @param obj - Object to get value from\n * @param path - Property path (e.g., 'user.id')\n * @returns Property value or undefined\n *\n * @example\n * getNestedValue({ user: { id: '123' } }, 'user.id') // '123'\n */\nexport function getNestedValue(obj: unknown, path: string): unknown {\n if (!obj || typeof obj !== 'object') {\n return undefined;\n }\n\n const keys = path.split('.');\n let value: unknown = obj;\n\n for (const key of keys) {\n if (value === null || value === undefined) {\n return undefined;\n }\n value = (value as Record<string, unknown>)[key];\n }\n\n return value;\n}\n\n/**\n * Generates cache key from template and method arguments.\n *\n * Replaces {paramName} placeholders with actual parameter values.\n * Supports nested properties: {user.id}\n *\n * @param template - Key template (e.g., 'user:{id}')\n * @param method - Method being decorated\n * @param args - Method arguments\n * @param namespace - Optional namespace prefix\n * @returns Generated cache key\n *\n * @throws CacheKeyError if parameter is not found or template is invalid\n *\n * @example\n * ```typescript\n * generateKey('user:{id}', getUserMethod, ['123']) // 'user:123'\n * generateKey('user:{user.id}', updateMethod, [{ id: '456' }]) // 'user:456'\n * ```\n */\nexport function generateKey(\n template: string,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function,\n args: unknown[],\n namespace?: string,\n): string {\n // Extract parameter names from method signature\n const paramNames = getParameterNames(method);\n\n // Build parameter map\n const paramMap = new Map<string, unknown>();\n paramNames.forEach((name, index) => {\n if (index < args.length) {\n paramMap.set(name, args[index]);\n }\n });\n\n // Replace placeholders in template\n let key = template;\n const placeholderRegex = /\\{([^}]+)\\}/g;\n const matches = Array.from(template.matchAll(placeholderRegex));\n\n if (matches.length === 0) {\n // No placeholders, return template as is\n return namespace ? `${namespace}:${template}` : template;\n }\n\n for (const match of matches) {\n const placeholder = match[0]; // e.g., '{id}' or '{user.id}'\n const path = match[1]; // e.g., 'id' or 'user.id'\n\n if (!path) {\n continue; // Skip if no path captured (shouldn't happen)\n }\n\n let value: unknown;\n\n if (path.includes('.')) {\n // Nested property access\n const [rootParam, ...nestedPath] = path.split('.');\n\n if (!rootParam) {\n throw new CacheKeyError(template, 'Invalid nested property path');\n }\n\n const rootValue = paramMap.get(rootParam);\n\n if (rootValue === undefined) {\n throw new CacheKeyError(template, `Parameter '${rootParam}' not found in method signature`);\n }\n\n value = getNestedValue(rootValue, nestedPath.join('.'));\n\n if (value === undefined) {\n throw new CacheKeyError(template, `Nested property '${path}' not found or is undefined`);\n }\n } else {\n // Direct parameter access\n if (!paramMap.has(path)) {\n throw new CacheKeyError(template, `Parameter '${path}' not found in method signature`);\n }\n\n value = paramMap.get(path);\n\n if (value === undefined || value === null) {\n throw new CacheKeyError(template, `Parameter '${path}' is null or undefined`);\n }\n }\n\n // Convert value to string\n const stringValue = String(value);\n\n // Validate value doesn't contain invalid characters\n if (stringValue.includes(':') || stringValue.includes('{') || stringValue.includes('}')) {\n throw new CacheKeyError(template, `Parameter value '${stringValue}' contains invalid characters (:, {, })`);\n }\n\n key = key.replace(placeholder, stringValue);\n }\n\n // Add namespace if provided\n if (namespace) {\n key = `${namespace}:${key}`;\n }\n\n return key;\n}\n\n/**\n * Generates multiple cache keys from templates and method arguments.\n *\n * @param templates - Array of key templates\n * @param method - Method being decorated\n * @param args - Method arguments\n * @param namespace - Optional namespace prefix\n * @returns Array of generated cache keys\n */\nexport function generateKeys(\n templates: string[],\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function,\n args: unknown[],\n namespace?: string,\n): string[] {\n return templates.map((template) => generateKey(template, method, args, namespace));\n}\n\n/**\n * Evaluates tags - either static array or dynamic function.\n *\n * @param tags - Tags definition (array or function)\n * @param args - Method arguments\n * @returns Array of tag names\n */\nexport function evaluateTags(tags: string[] | ((...args: unknown[]) => string[]) | undefined, args: unknown[]): string[] {\n if (!tags) {\n return [];\n }\n\n if (typeof tags === 'function') {\n return tags(...args);\n }\n\n return tags;\n}\n\n/**\n * Evaluates condition - determines if caching should proceed.\n *\n * @param condition - Condition function\n * @param args - Method arguments\n * @returns true if caching should proceed\n */\nexport function evaluateCondition(condition: ((...args: unknown[]) => boolean) | undefined, args: unknown[]): boolean {\n if (!condition) {\n return true;\n }\n\n return condition(...args);\n}\n","/**\n * Cache interceptor for handling @Cacheable, @CachePut, and @CacheEvict decorators.\n */\n\nimport { Injectable, NestInterceptor, ExecutionContext, CallHandler, Logger } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { Observable, from, of } from 'rxjs';\nimport { switchMap, tap } from 'rxjs/operators';\n\nimport { CacheService } from '../cache.service';\nimport { ICacheEvictOptions, CACHE_EVICT_METADATA_KEY } from './cache-evict.decorator';\nimport { ICachePutOptions, CACHE_PUT_METADATA_KEY } from './cache-put.decorator';\nimport { ICacheableOptions, CACHEABLE_METADATA_KEY } from './cacheable.decorator';\nimport { generateKey, generateKeys, evaluateTags, evaluateCondition } from './key-generator.util';\n\n/**\n * Interceptor for cache decorators.\n *\n * Handles:\n * - @Cacheable: Returns cached value or executes and caches result\n * - @CachePut: Always executes and caches result\n * - @CacheEvict: Evicts cache entries before or after execution\n *\n * @example\n * ```typescript\n * @Controller('users')\n * @UseInterceptors(CacheInterceptor)\n * export class UserController {\n * @Get(':id')\n * @Cacheable({ key: 'user:{id}', ttl: 3600 })\n * getUser(@Param('id') id: string) {\n * return this.userService.findOne(id);\n * }\n *\n * @Put(':id')\n * @CachePut({ key: 'user:{id}' })\n * updateUser(@Param('id') id: string, @Body() data: UpdateUserDto) {\n * return this.userService.update(id, data);\n * }\n *\n * @Delete(':id')\n * @CacheEvict({ keys: ['user:{id}'] })\n * deleteUser(@Param('id') id: string) {\n * return this.userService.delete(id);\n * }\n * }\n * ```\n */\n@Injectable()\nexport class CacheInterceptor implements NestInterceptor {\n private readonly logger = new Logger(CacheInterceptor.name);\n\n constructor(\n private readonly cacheService: CacheService,\n private readonly reflector: Reflector,\n ) {}\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {\n const handler = context.getHandler();\n const _target = context.getClass();\n\n // Get metadata from decorators\n const cacheableOptions = this.reflector.get<ICacheableOptions>(CACHEABLE_METADATA_KEY, handler);\n const cachePutOptions = this.reflector.get<ICachePutOptions>(CACHE_PUT_METADATA_KEY, handler);\n const cacheEvictOptions = this.reflector.get<ICacheEvictOptions>(CACHE_EVICT_METADATA_KEY, handler);\n\n // Get method arguments\n const args = context.getArgByIndex(context.getArgs().length - 1) ? context.getArgs() : [];\n\n const method = handler;\n\n // Handle @Cacheable\n if (cacheableOptions) {\n return this.handleCacheable(cacheableOptions, method, args, next);\n }\n\n // Handle @CachePut\n if (cachePutOptions) {\n return this.handleCachePut(cachePutOptions, method, args, next);\n }\n\n // Handle @CacheEvict\n if (cacheEvictOptions) {\n return this.handleCacheEvict(cacheEvictOptions, method, args, next);\n }\n\n // No cache decorator found, proceed normally\n return next.handle();\n }\n\n /**\n * Handles @Cacheable decorator.\n * Returns cached value or executes method and caches result.\n */\n private handleCacheable(\n options: ICacheableOptions,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function,\n args: unknown[],\n next: CallHandler,\n ): Observable<unknown> {\n // Check condition\n if (!evaluateCondition(options.condition, args)) {\n this.logger.debug('Cacheable condition not met, executing method');\n return next.handle();\n }\n\n try {\n // Generate cache key\n const key = options.keyGenerator ? options.keyGenerator(...args) : generateKey(options.key, method, args, options.namespace);\n\n this.logger.debug(`Cacheable: checking cache for key: ${key}`);\n\n // Try to get from cache\n return from(this.cacheService.get(key)).pipe(\n switchMap((cachedValue) => {\n if (cachedValue !== null) {\n this.logger.debug(`Cacheable: cache hit for key: ${key}`);\n return of(cachedValue);\n }\n\n this.logger.debug(`Cacheable: cache miss for key: ${key}, executing method`);\n\n // Cache miss - execute method\n return next.handle().pipe(\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n tap(async (result) => {\n // Cache the result\n const tags = evaluateTags(options.tags, args);\n const ttl = options.ttl ?? 3600;\n\n try {\n await this.cacheService.set(key, result, { ttl, tags });\n this.logger.debug(`Cacheable: cached result for key: ${key}`);\n } catch (error) {\n this.logger.error(`Cacheable: failed to cache result for key ${key}: ${(error as Error).message}`);\n }\n }),\n );\n }),\n );\n } catch (error) {\n this.logger.error(`Cacheable: error processing cache: ${(error as Error).message}`);\n return next.handle();\n }\n }\n\n /**\n * Handles @CachePut decorator.\n * Always executes method and caches the result.\n */\n private handleCachePut(\n options: ICachePutOptions,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function,\n args: unknown[],\n next: CallHandler,\n ): Observable<unknown> {\n // Check condition\n if (!evaluateCondition(options.condition, args)) {\n this.logger.debug('CachePut condition not met, executing method without caching');\n return next.handle();\n }\n\n try {\n // Generate cache key\n const key = options.keyGenerator ? options.keyGenerator(...args) : generateKey(options.key, method, args, options.namespace);\n\n this.logger.debug(`CachePut: executing method for key: ${key}`);\n\n // Execute method\n return next.handle().pipe(\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n tap(async (result) => {\n // Skip caching null/undefined if not allowed\n if ((result === null || result === undefined) && !options.cacheNullValues) {\n this.logger.debug(`CachePut: skipping null/undefined result for key: ${key}`);\n return;\n }\n\n // Cache the result\n const tags = evaluateTags(options.tags, args);\n const ttl = options.ttl ?? 3600;\n\n try {\n await this.cacheService.set(key, result, { ttl, tags });\n this.logger.debug(`CachePut: cached result for key: ${key}`);\n } catch (error) {\n this.logger.error(`CachePut: failed to cache result for key ${key}: ${(error as Error).message}`);\n }\n }),\n );\n } catch (error) {\n this.logger.error(`CachePut: error processing cache: ${(error as Error).message}`);\n return next.handle();\n }\n }\n\n /**\n * Handles @CacheEvict decorator.\n * Evicts cache entries before or after method execution.\n */\n private handleCacheEvict(\n options: ICacheEvictOptions,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function,\n args: unknown[],\n next: CallHandler,\n ): Observable<unknown> {\n // Check condition\n if (!evaluateCondition(options.condition, args)) {\n this.logger.debug('CacheEvict condition not met, executing method without eviction');\n return next.handle();\n }\n\n const evictFn = async () => {\n try {\n // Handle allEntries flag\n if (options.allEntries) {\n this.logger.debug('CacheEvict: clearing all cache entries');\n await this.cacheService.clear();\n return;\n }\n\n // Handle tag-based eviction\n if (options.tags && options.tags.length > 0) {\n this.logger.debug(`CacheEvict: invalidating tags: ${options.tags.join(', ')}`);\n await this.cacheService.invalidateTags(options.tags);\n }\n\n // Handle key-based eviction\n if (options.keys && options.keys.length > 0) {\n const keys = options.keyGenerator ? options.keyGenerator(...args) : generateKeys(options.keys, method, args, options.namespace);\n\n this.logger.debug(`CacheEvict: evicting keys: ${keys.join(', ')}`);\n\n for (const key of keys) {\n // Check if key contains wildcard\n if (key.includes('*')) {\n // Pattern-based invalidation not directly supported\n // Would need to scan all keys or use tags\n this.logger.warn(`CacheEvict: wildcard keys not supported: ${key}. Use tags instead.`);\n } else {\n await this.cacheService.del(key);\n }\n }\n }\n } catch (error) {\n this.logger.error(`CacheEvict: error evicting cache: ${(error as Error).message}`);\n }\n };\n\n // Evict before invocation\n if (options.beforeInvocation) {\n return from(evictFn()).pipe(switchMap(() => next.handle()));\n }\n\n // Evict after invocation (default)\n return next.handle().pipe(\n tap(() => {\n void evictFn();\n }),\n );\n }\n}\n","/**\n * Least Recently Used (LRU) eviction strategy.\n *\n * Evicts the least recently accessed item when cache is full.\n * Uses a Map to maintain insertion order and updates order on access.\n *\n * @example\n * ```typescript\n * const strategy = new LruStrategy<string>();\n *\n * strategy.recordInsert('key1');\n * strategy.recordInsert('key2');\n * strategy.recordAccess('key1'); // key1 is now most recent\n *\n * const victim = strategy.selectVictim(); // Returns 'key2' (least recent)\n * ```\n */\n\nimport { IEvictionStrategy } from './eviction-strategy.interface';\n\nexport class LruStrategy<K = string> implements IEvictionStrategy<K> {\n /**\n * Map maintaining keys in LRU order.\n * JavaScript Map maintains insertion order, so we use delete+set to move to end.\n */\n private readonly keyOrder: Map<K, number>;\n\n /**\n * Timestamp counter for tracking access order\n */\n private timestamp: number;\n\n constructor() {\n this.keyOrder = new Map();\n this.timestamp = 0;\n }\n\n /**\n * Records access to a key, moving it to most recently used position.\n *\n * @param key - Key that was accessed\n */\n recordAccess(key: K): void {\n // Update timestamp for this key\n this.timestamp++;\n this.keyOrder.set(key, this.timestamp);\n }\n\n /**\n * Records insertion of a new key.\n *\n * @param key - Key that was inserted\n */\n recordInsert(key: K): void {\n this.timestamp++;\n this.keyOrder.set(key, this.timestamp);\n }\n\n /**\n * Records deletion of a key.\n *\n * @param key - Key that was deleted\n */\n recordDelete(key: K): void {\n this.keyOrder.delete(key);\n }\n\n /**\n * Selects the least recently used key for eviction.\n *\n * @returns Least recently used key, or undefined if empty\n */\n selectVictim(): K | undefined {\n if (this.keyOrder.size === 0) {\n return undefined;\n }\n\n // Find key with smallest timestamp (least recently used)\n let oldestKey: K | undefined;\n let oldestTimestamp = Infinity;\n\n for (const [key, timestamp] of this.keyOrder.entries()) {\n if (timestamp < oldestTimestamp) {\n oldestTimestamp = timestamp;\n oldestKey = key;\n }\n }\n\n return oldestKey;\n }\n\n /**\n * Clears all tracking data.\n */\n clear(): void {\n this.keyOrder.clear();\n this.timestamp = 0;\n }\n\n /**\n * Gets current number of tracked keys.\n *\n * @returns Number of keys\n */\n size(): number {\n return this.keyOrder.size;\n }\n\n /**\n * Gets all keys in LRU order (oldest to newest).\n *\n * @returns Array of keys sorted by access time\n */\n getKeys(): K[] {\n return Array.from(this.keyOrder.entries())\n .sort(([, a], [, b]) => a - b)\n .map(([key]) => key);\n }\n\n /**\n * Gets keys that should be evicted to reach target size.\n *\n * @param targetSize - Desired size after eviction\n * @returns Array of keys to evict\n */\n getVictims(targetSize: number): K[] {\n const currentSize = this.keyOrder.size;\n if (currentSize <= targetSize) {\n return [];\n }\n\n const numToEvict = currentSize - targetSize;\n const sortedKeys = this.getKeys();\n return sortedKeys.slice(0, numToEvict);\n }\n}\n","/**\n * First In First Out (FIFO) eviction strategy.\n *\n * Evicts the oldest inserted item when cache is full.\n * Does not consider access patterns - only insertion order matters.\n *\n * @example\n * ```typescript\n * const strategy = new FifoStrategy<string>();\n *\n * strategy.recordInsert('key1');\n * strategy.recordInsert('key2');\n * strategy.recordAccess('key1'); // Access doesn't affect order in FIFO\n *\n * const victim = strategy.selectVictim(); // Returns 'key1' (first inserted)\n * ```\n */\n\nimport { IEvictionStrategy } from './eviction-strategy.interface';\n\nexport class FifoStrategy<K = string> implements IEvictionStrategy<K> {\n /**\n * Queue maintaining keys in insertion order.\n * First element is oldest (next to evict).\n */\n private readonly queue: K[];\n\n /**\n * Set for O(1) existence checks\n */\n private readonly keySet: Set<K>;\n\n constructor() {\n this.queue = [];\n this.keySet = new Set();\n }\n\n /**\n * Records access to a key.\n * In FIFO, access doesn't affect eviction order, so this is a no-op.\n *\n * @param _key - Key that was accessed\n */\n recordAccess(_key: K): void {\n // FIFO doesn't care about access - only insertion order matters\n // No-op\n }\n\n /**\n * Records insertion of a new key.\n *\n * @param key - Key that was inserted\n */\n recordInsert(key: K): void {\n // Only add if not already present\n if (!this.keySet.has(key)) {\n this.queue.push(key);\n this.keySet.add(key);\n }\n }\n\n /**\n * Records deletion of a key.\n *\n * @param key - Key that was deleted\n */\n recordDelete(key: K): void {\n if (this.keySet.has(key)) {\n // Remove from queue - O(n) operation but rare\n const index = this.queue.indexOf(key);\n if (index !== -1) {\n this.queue.splice(index, 1);\n }\n this.keySet.delete(key);\n }\n }\n\n /**\n * Selects the oldest inserted key for eviction.\n *\n * @returns Oldest key (first in queue), or undefined if empty\n */\n selectVictim(): K | undefined {\n return this.queue[0];\n }\n\n /**\n * Clears all tracking data.\n */\n clear(): void {\n this.queue.length = 0;\n this.keySet.clear();\n }\n\n /**\n * Gets current number of tracked keys.\n *\n * @returns Number of keys\n */\n size(): number {\n return this.queue.length;\n }\n\n /**\n * Gets all keys in FIFO order (oldest to newest).\n *\n * @returns Array of keys in insertion order\n */\n getKeys(): K[] {\n return [...this.queue];\n }\n\n /**\n * Gets keys that should be evicted to reach target size.\n *\n * @param targetSize - Desired size after eviction\n * @returns Array of keys to evict (oldest first)\n */\n getVictims(targetSize: number): K[] {\n const currentSize = this.queue.length;\n if (currentSize <= targetSize) {\n return [];\n }\n\n const numToEvict = currentSize - targetSize;\n return this.queue.slice(0, numToEvict);\n }\n\n /**\n * Checks if a key is tracked.\n *\n * @param key - Key to check\n * @returns True if key is tracked\n */\n has(key: K): boolean {\n return this.keySet.has(key);\n }\n}\n","/**\n * Least Frequently Used (LFU) eviction strategy.\n *\n * Evicts the least frequently accessed item when cache is full.\n * Tracks access frequency for each key, with insertion order as tiebreaker.\n *\n * @example\n * ```typescript\n * const strategy = new LfuStrategy<string>();\n *\n * strategy.recordInsert('key1');\n * strategy.recordInsert('key2');\n * strategy.recordAccess('key1'); // key1 frequency = 2\n * strategy.recordAccess('key1'); // key1 frequency = 3\n *\n * const victim = strategy.selectVictim(); // Returns 'key2' (frequency = 1)\n * ```\n */\n\nimport { IEvictionStrategy } from './eviction-strategy.interface';\n\ninterface ILfuEntry<K> {\n key: K;\n frequency: number;\n insertOrder: number;\n}\n\nexport class LfuStrategy<K = string> implements IEvictionStrategy<K> {\n private readonly entries: Map<K, ILfuEntry<K>>;\n private insertCounter: number;\n\n constructor() {\n this.entries = new Map();\n this.insertCounter = 0;\n }\n\n /**\n * Records access to a key, incrementing its frequency counter.\n *\n * @param key - Key that was accessed\n */\n recordAccess(key: K): void {\n const entry = this.entries.get(key);\n if (entry) {\n entry.frequency++;\n }\n }\n\n /**\n * Records insertion of a new key with initial frequency of 1.\n *\n * @param key - Key that was inserted\n */\n recordInsert(key: K): void {\n if (!this.entries.has(key)) {\n this.insertCounter++;\n this.entries.set(key, {\n key,\n frequency: 1,\n insertOrder: this.insertCounter,\n });\n }\n }\n\n /**\n * Records deletion of a key.\n *\n * @param key - Key that was deleted\n */\n recordDelete(key: K): void {\n this.entries.delete(key);\n }\n\n /**\n * Selects the least frequently used key for eviction.\n * When frequencies are equal, the oldest inserted key is selected.\n *\n * @returns Least frequently used key, or undefined if empty\n */\n selectVictim(): K | undefined {\n if (this.entries.size === 0) {\n return undefined;\n }\n\n let victim: ILfuEntry<K> | undefined;\n\n for (const entry of this.entries.values()) {\n if (!victim || entry.frequency < victim.frequency || (entry.frequency === victim.frequency && entry.insertOrder < victim.insertOrder)) {\n victim = entry;\n }\n }\n\n return victim?.key;\n }\n\n /**\n * Clears all tracking data.\n */\n clear(): void {\n this.entries.clear();\n this.insertCounter = 0;\n }\n\n /**\n * Gets current number of tracked keys.\n *\n * @returns Number of keys\n */\n size(): number {\n return this.entries.size;\n }\n\n /**\n * Gets all keys sorted by frequency (lowest first), then by insertion order.\n *\n * @returns Array of keys sorted by eviction priority\n */\n getKeys(): K[] {\n return Array.from(this.entries.values())\n .sort((a, b) => a.frequency - b.frequency || a.insertOrder - b.insertOrder)\n .map((entry) => entry.key);\n }\n\n /**\n * Gets keys that should be evicted to reach target size.\n *\n * @param targetSize - Desired size after eviction\n * @returns Array of keys to evict\n */\n getVictims(targetSize: number): K[] {\n const currentSize = this.entries.size;\n if (currentSize <= targetSize) {\n return [];\n }\n\n const numToEvict = currentSize - targetSize;\n const sortedKeys = this.getKeys();\n return sortedKeys.slice(0, numToEvict);\n }\n\n /**\n * Checks if a key is tracked.\n *\n * @param key - Key to check\n * @returns True if key is tracked\n */\n has(key: K): boolean {\n return this.entries.has(key);\n }\n\n /**\n * Gets the frequency count for a key.\n *\n * @param key - Key to check\n * @returns Frequency count, or 0 if key not tracked\n */\n getFrequency(key: K): number {\n return this.entries.get(key)?.frequency ?? 0;\n }\n}\n","/**\n * JSON serializer for cache values.\n *\n * Uses native JSON.stringify/parse for serialization.\n * Best for human-readable data and compatibility.\n *\n * @example\n * ```typescript\n * const serializer = new JsonSerializer();\n *\n * const data = { id: 1, name: 'John' };\n * const serialized = serializer.serialize(data);\n * // '{\"id\":1,\"name\":\"John\"}'\n *\n * const deserialized = serializer.deserialize<User>(serialized);\n * // { id: 1, name: 'John' }\n * ```\n */\n\nimport { ISerializer } from './serializer.interface';\nimport { SerializationError } from '../shared/errors';\n\nexport class JsonSerializer implements ISerializer {\n /**\n * Serializes value to JSON string.\n *\n * @param value - Value to serialize\n * @returns JSON string\n * @throws SerializationError if serialization fails\n */\n serialize<T>(value: T): string {\n try {\n return JSON.stringify(value);\n } catch (error) {\n throw new SerializationError(`JSON serialization failed: ${(error as Error).message}`, error as Error);\n }\n }\n\n /**\n * Deserializes JSON string back to value.\n *\n * @param data - JSON string or buffer\n * @returns Deserialized value\n * @throws SerializationError if deserialization fails\n */\n deserialize<T>(data: string | Buffer): T {\n try {\n const str = Buffer.isBuffer(data) ? data.toString('utf8') : data;\n return JSON.parse(str) as T;\n } catch (error) {\n throw new SerializationError(`JSON deserialization failed: ${(error as Error).message}`, error as Error);\n }\n }\n\n /**\n * Safely tries to deserialize, returns null on error.\n *\n * @param data - JSON string or buffer\n * @returns Deserialized value or null\n */\n tryDeserialize<T>(data: string | Buffer): T | null {\n try {\n return this.deserialize<T>(data);\n } catch {\n return null;\n }\n }\n\n /**\n * Gets content type for JSON.\n *\n * @returns Content type string\n */\n getContentType(): string {\n return 'application/json';\n }\n}\n","/**\n * MessagePack serializer for cache values.\n *\n * Uses msgpackr for binary serialization.\n * More compact and faster than JSON, but requires msgpackr package.\n *\n * Install: npm install msgpackr\n *\n * @example\n * ```typescript\n * const serializer = new MsgpackSerializer();\n *\n * const data = { id: 1, name: 'John', tags: ['user', 'active'] };\n * const serialized = serializer.serialize(data);\n * // Buffer<...> (binary data, ~40% smaller than JSON)\n *\n * const deserialized = serializer.deserialize<User>(serialized);\n * // { id: 1, name: 'John', tags: ['user', 'active'] }\n * ```\n */\n\nimport { ISerializer } from './serializer.interface';\nimport { SerializationError } from '../shared/errors';\n\n/**\n * Msgpackr encoder interface.\n */\ninterface IMsgpackEncoder {\n encode(value: unknown): Buffer;\n}\n\n/**\n * Msgpackr decoder interface.\n */\ninterface IMsgpackDecoder {\n decode(buffer: Buffer): unknown;\n}\n\nexport class MsgpackSerializer implements ISerializer {\n private encoder: IMsgpackEncoder;\n private decoder: IMsgpackDecoder;\n\n constructor() {\n try {\n // Lazy load msgpackr to make it optional\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const msgpackr = require('msgpackr');\n this.encoder = new msgpackr.Encoder({\n useRecords: false, // Don't use msgpack extension records\n structuredClone: true, // Deep clone objects\n });\n this.decoder = new msgpackr.Decoder({\n useRecords: false,\n });\n } catch {\n throw new Error('msgpackr package is required for MsgpackSerializer. Install with: npm install msgpackr');\n }\n }\n\n /**\n * Serializes value to MessagePack buffer.\n *\n * @param value - Value to serialize\n * @returns MessagePack buffer\n * @throws SerializationError if serialization fails\n */\n serialize<T>(value: T): Buffer {\n try {\n return this.encoder.encode(value);\n } catch (error) {\n throw new SerializationError(`MessagePack serialization failed: ${(error as Error).message}`, error as Error);\n }\n }\n\n /**\n * Deserializes MessagePack buffer back to value.\n *\n * @param data - MessagePack buffer or string\n * @returns Deserialized value\n * @throws SerializationError if deserialization fails\n */\n deserialize<T>(data: string | Buffer): T {\n try {\n const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data, 'binary');\n return this.decoder.decode(buffer) as T;\n } catch (error) {\n throw new SerializationError(`MessagePack deserialization failed: ${(error as Error).message}`, error as Error);\n }\n }\n\n /**\n * Safely tries to deserialize, returns null on error.\n *\n * @param data - MessagePack buffer or string\n * @returns Deserialized value or null\n */\n tryDeserialize<T>(data: string | Buffer): T | null {\n try {\n return this.deserialize<T>(data);\n } catch {\n return null;\n }\n }\n\n /**\n * Gets content type for MessagePack.\n *\n * @returns Content type string\n */\n getContentType(): string {\n return 'application/msgpack';\n }\n\n /**\n * Compares serialized size with JSON.\n *\n * @param value - Value to compare\n * @returns Object with sizes and compression ratio\n */\n compareWithJson<T>(value: T): {\n jsonSize: number;\n msgpackSize: number;\n compressionRatio: number;\n } {\n const jsonSize = Buffer.from(JSON.stringify(value), 'utf8').length;\n const msgpackSize = this.serialize(value).length;\n\n return {\n jsonSize,\n msgpackSize,\n compressionRatio: jsonSize / msgpackSize,\n };\n }\n}\n","/**\n * Fluent key builder for cache keys.\n *\n * Provides a convenient API for building cache keys with proper formatting,\n * validation, and separation.\n *\n * @example\n * ```typescript\n * // Simple key\n * const key = KeyBuilder.create()\n * .prefix('app')\n * .segment('user')\n * .segment('123')\n * .build();\n * // 'app:user:123'\n *\n * // With namespace\n * const key = KeyBuilder.create()\n * .namespace('tenant-5')\n * .prefix('cache')\n * .segment('product')\n * .segment('456')\n * .build();\n * // 'tenant-5:cache:product:456'\n *\n * // From template\n * const key = KeyBuilder.fromTemplate('user:{userId}:post:{postId}', {\n * userId: '123',\n * postId: '456',\n * });\n * // 'user:123:post:456'\n *\n * // With versioning\n * const key = KeyBuilder.create()\n * .prefix('cache')\n * .version('v2')\n * .segment('user')\n * .segment('123')\n * .build();\n * // 'cache:v2:user:123'\n * ```\n */\n\nimport { CacheKeyError } from './shared/errors';\n\nexport interface IKeyBuilderOptions {\n /**\n * Separator between segments (default: ':')\n */\n separator?: string;\n\n /**\n * Maximum key length (default: 512)\n */\n maxLength?: number;\n\n /**\n * Whether to validate segments for invalid characters (default: true)\n */\n validate?: boolean;\n\n /**\n * Whether to convert segments to lowercase (default: false)\n */\n lowercase?: boolean;\n}\n\nexport class KeyBuilder {\n private keySegments: string[] = [];\n private options: Required<IKeyBuilderOptions>;\n\n private constructor(options: IKeyBuilderOptions = {}) {\n this.options = {\n separator: options.separator ?? ':',\n maxLength: options.maxLength ?? 512,\n validate: options.validate ?? true,\n lowercase: options.lowercase ?? false,\n };\n }\n\n /**\n * Creates a new KeyBuilder instance.\n *\n * @param options - Builder options\n * @returns New KeyBuilder\n */\n static create(options?: IKeyBuilderOptions): KeyBuilder {\n return new KeyBuilder(options);\n }\n\n /**\n * Creates a key from a template string with placeholders.\n *\n * @param template - Template string (e.g., 'user:{id}:post:{postId}')\n * @param params - Parameter values\n * @param options - Builder options\n * @returns Generated key\n *\n * @example\n * ```typescript\n * KeyBuilder.fromTemplate('user:{id}', { id: '123' })\n * // 'user:123'\n *\n * KeyBuilder.fromTemplate('user:{userId}:post:{postId}', {\n * userId: '123',\n * postId: '456',\n * })\n * // 'user:123:post:456'\n * ```\n */\n static fromTemplate(template: string, params: Record<string, string | number>, options?: IKeyBuilderOptions): string {\n let result = template;\n const placeholderRegex = /\\{([^}]+)\\}/g;\n\n const matches = Array.from(template.matchAll(placeholderRegex));\n\n for (const match of matches) {\n const placeholder = match[0]; // e.g., '{id}'\n const paramName = match[1]; // e.g., 'id'\n\n if (!paramName) {\n continue;\n }\n\n if (!(paramName in params)) {\n throw new CacheKeyError(template, `Parameter '${paramName}' not found in params`);\n }\n\n const value = params[paramName];\n if (value === null || value === undefined) {\n throw new CacheKeyError(template, `Parameter '${paramName}' is null or undefined`);\n }\n\n result = result.replace(placeholder, String(value));\n }\n\n // Validate the final key\n const builder = new KeyBuilder(options);\n builder.validateKey(result);\n\n return result;\n }\n\n /**\n * Creates a key from an array of segments.\n *\n * @param segments - Array of key segments\n * @param options - Builder options\n * @returns Generated key\n */\n static fromSegments(segments: string[], options?: IKeyBuilderOptions): string {\n const builder = new KeyBuilder(options);\n segments.forEach((segment) => builder.segment(segment));\n return builder.build();\n }\n\n /**\n * Adds a namespace segment (first segment).\n *\n * @param ns - Namespace value\n * @returns This builder for chaining\n */\n namespace(ns: string): this {\n this.keySegments.unshift(this.normalizeSegment(ns));\n return this;\n }\n\n /**\n * Adds a prefix segment.\n *\n * @param prefix - Prefix value\n * @returns This builder for chaining\n */\n prefix(prefix: string): this {\n return this.segment(prefix);\n }\n\n /**\n * Adds a version segment.\n *\n * @param version - Version value (e.g., 'v1', 'v2')\n * @returns This builder for chaining\n */\n version(version: string): this {\n return this.segment(version);\n }\n\n /**\n * Adds a segment to the key.\n *\n * @param value - Segment value\n * @returns This builder for chaining\n */\n segment(value: string | number): this {\n this.keySegments.push(this.normalizeSegment(String(value)));\n return this;\n }\n\n /**\n * Adds multiple segments at once.\n *\n * @param values - Array of segment values\n * @returns This builder for chaining\n */\n segments(...values: Array<string | number>): this {\n values.forEach((value) => this.segment(value));\n return this;\n }\n\n /**\n * Adds a tag segment (useful for grouping).\n *\n * @param tag - Tag value\n * @returns This builder for chaining\n */\n tag(tag: string): this {\n this.segment('tag');\n this.segment(tag);\n return this;\n }\n\n /**\n * Adds timestamp segment.\n *\n * @param timestamp - Unix timestamp (default: now)\n * @returns This builder for chaining\n */\n timestamp(timestamp?: number): this {\n return this.segment(timestamp ?? Date.now());\n }\n\n /**\n * Adds a hash segment from an object.\n * Useful for cache keys based on complex objects.\n *\n * @param obj - Object to hash\n * @returns This builder for chaining\n */\n hash(obj: unknown): this {\n const hash = this.simpleHash(JSON.stringify(obj));\n return this.segment(hash);\n }\n\n /**\n * Builds and returns the final key.\n *\n * @returns Generated cache key\n * @throws CacheKeyError if key is invalid\n */\n build(): string {\n if (this.keySegments.length === 0) {\n throw new CacheKeyError('', 'Cannot build key with no segments');\n }\n\n const key = this.keySegments.join(this.options.separator);\n this.validateKey(key);\n\n return key;\n }\n\n /**\n * Resets the builder to initial state.\n *\n * @returns This builder for chaining\n */\n reset(): this {\n this.keySegments = [];\n return this;\n }\n\n /**\n * Gets current segments.\n *\n * @returns Array of segments\n */\n getSegments(): string[] {\n return [...this.keySegments];\n }\n\n /**\n * Normalizes a segment value.\n *\n * @param value - Segment value\n * @returns Normalized value\n */\n private normalizeSegment(value: string): string {\n let normalized = value.trim();\n\n if (this.options.lowercase) {\n normalized = normalized.toLowerCase();\n }\n\n if (this.options.validate) {\n // Check for invalid characters\n const invalidChars = [this.options.separator, '{', '}', ' ', '\\n', '\\r', '\\t'];\n for (const char of invalidChars) {\n if (normalized.includes(char)) {\n throw new CacheKeyError(normalized, `Segment contains invalid character: '${char}'`);\n }\n }\n\n // Check for empty segment\n if (normalized.length === 0) {\n throw new CacheKeyError(normalized, 'Segment cannot be empty');\n }\n }\n\n return normalized;\n }\n\n /**\n * Validates a complete key.\n *\n * @param key - Key to validate\n * @throws CacheKeyError if key is invalid\n */\n private validateKey(key: string): void {\n if (!this.options.validate) {\n return;\n }\n\n if (key.length === 0) {\n throw new CacheKeyError(key, 'Key cannot be empty');\n }\n\n if (key.length > this.options.maxLength) {\n throw new CacheKeyError(key, `Key length ${key.length} exceeds maximum ${this.options.maxLength}`);\n }\n\n // Check for invalid patterns\n if (key.startsWith(this.options.separator) || key.endsWith(this.options.separator)) {\n throw new CacheKeyError(key, 'Key cannot start or end with separator');\n }\n\n // Check for consecutive separators\n const consecutiveSeparators = this.options.separator + this.options.separator;\n if (key.includes(consecutiveSeparators)) {\n throw new CacheKeyError(key, 'Key cannot contain consecutive separators');\n }\n }\n\n /**\n * Simple hash function for objects.\n *\n * @param str - String to hash\n * @returns Hash string\n */\n private simpleHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash).toString(36);\n }\n}\n"]}
|