UNPKG

fortify2-js

Version:

MOST POWERFUL JavaScript Security Library! Military-grade cryptography + 19 enhanced object methods + quantum-resistant algorithms + perfect TypeScript support. More powerful than Lodash with built-in security.

1,201 lines (1,198 loc) 39.2 kB
import path__default from 'path'; import '../../types.js'; import { Hash } from '../../core/hash/hash-core.js'; import '../../core/hash/hash-types.js'; import 'crypto'; import '../../core/hash/hash-security.js'; import '../../core/hash/hash-advanced.js'; import '../../algorithms/hash-algorithms.js'; import '../../core/keys/keys-types.js'; import '../../core/keys/keys-logger.js'; import '../../core/keys/keys-utils.js'; import '../../core/keys/algorithms/mods/PBKDF2Algo.js'; import '../../core/random/random-types.js'; import '../../core/random/random-sources.js'; import 'nehonix-uri-processor'; import '../../utils/memory/index.js'; import 'argon2'; import 'child_process'; import '../../types/secure-memory.js'; import 'https'; import '../runtime-verification.js'; import '../tamper-evident-logging.js'; import '../secure-string/advanced/entropy-analyzer.js'; import '../secure-string/advanced/quantum-safe.js'; import '../secure-string/advanced/performance-monitor.js'; import 'nehoid'; import '../../core/password/index.js'; import { SecureInMemoryCache as SIMC } from './useCache.js'; import 'util'; import 'zlib'; import 'events'; import { DEFAULT_FILE_CACHE_CONFIG } from './config/cache.config.js'; export { CONFIG as DEFAULT_CACHE_CONFIG } from './config/cache.config.js'; import { FileCache } from './cacheSys.js'; /*************************************************************************** * FortifyJS - Secure Array Types * * This file contains type definitions for the SecureArray modular architecture * * @author Nehonix * @license MIT * * Copyright (c) 2025 Nehonix. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. ***************************************************************************** */ /** * @fileoverview FortifyJS Unified Cache System - Enterprise-Grade Caching Solution * * A comprehensive, caching solution combining multiple strategies * with military-grade security and ultra-fast performance optimization. * * ## Cache Strategies * - **Memory Cache**: Ultra-fast in-process storage with LRU eviction * - **File Cache**: Persistent cross-process storage with real disk monitoring * - **Hybrid Cache**: Automatic optimization between memory and file storage * - **Redis Cache**: Distributed scalable storage (via integrations) * * ## Security Features * - AES-256-GCM encryption for all cached data * - PBKDF2 key derivation with automatic key rotation * - Tamper-evident storage with integrity verification * - Secure key management and access pattern monitoring * - Memory-safe operations with automatic cleanup * * ## Performance Features * - Zlib compression for large values (configurable threshold) * - LRU eviction with intelligent memory pressure management * - Real-time disk space monitoring and automatic cleanup * - Atomic file operations for data consistency * - Sub-millisecond cache hits with object pooling * - Configurable TTL with background expiration cleanup * * ## Production Features * - Comprehensive error handling with graceful degradation * - Real-time performance metrics and health monitoring * - Configurable naming strategies (flat, hierarchical, dated, direct) * - Cross-platform compatibility (Windows, macOS, Linux) * - Zero-dependency core with optional integrations * - TypeScript support with complete type definitions * * @example * ```typescript * // Quick start with default memory cache * import { Cache } from "fortify2-js"; * * await Cache.set('user:123', { name: 'John', role: 'admin' }, { ttl: 3600000 }); * const user = await Cache.get('user:123'); * * // File-based persistent cache * import { FileCache } from "fortify2-js"; * * const fileCache = new FileCache({ * directory: './cache', * encrypt: true, * compress: true, * maxCacheSize: 1024 * 1024 * 100 // 100MB * }); * * await fileCache.set('session:abc', sessionData, { ttl: 86400000 }); * * // Hybrid cache for optimal performance * import { createOptimalCache } from "fortify2-js"; * * const hybridCache = createOptimalCache({ * type: 'hybrid', * config: { encrypt: true, compress: true } * }); * ``` * * @version 4.2.3 * @author NEHONIX * @since 2024-12-19 * @license MIT */ // ======================================== // MAIN CACHE EXPORTS // ======================================== /** * Default secure in-memory cache instance * * Pre-configured singleton instance with optimal security settings for immediate use. * Features AES-256-GCM encryption, LRU eviction, and automatic memory management. * * @example * ```typescript * import { Cache } from "fortify2-js"; * * // Store user session with 1-hour TTL * await Cache.set('session:user123', { * userId: 123, * permissions: ['read', 'write'], * loginTime: Date.now() * }, { ttl: 3600000 }); * * // Retrieve cached data * const session = await Cache.get('session:user123'); * * // Check cache statistics * const stats = Cache.getStats(); * console.log(`Hit rate: ${stats.hitRate}%`); * ``` * * @since 4.2.2 */ const Cache = new SIMC(); // ======================================== // FILE CACHE UTILITIES // ======================================== /** * Generate a secure file path for cache storage * * Creates secure, collision-resistant file paths using configurable naming strategies. * All keys are hashed using SHA-256 to prevent directory traversal attacks and * ensure consistent path generation across platforms. * * @param key - The cache key to generate a path for * @param options - Optional configuration for path generation * @returns Secure file path for the given key * * @example * ```typescript * import { generateFilePath } from "fortify2-js"; * * // Hierarchical structure (recommended for large caches) * const path1 = generateFilePath('user:123', { * namingStrategy: 'hierarchical', * directory: './cache' * }); * // Result: ./cache/a1/b2/a1b2c3d4...cache * * // Date-based organization (good for time-series data) * const path2 = generateFilePath('daily-report', { * namingStrategy: 'dated', * directory: './reports' * }); * // Result: ./reports/2024/12/19/hash...cache * * // Direct naming (human-readable, limited special chars) * const path3 = generateFilePath('config-settings', { * namingStrategy: 'direct', * directory: './config' * }); * // Result: ./config/config-settings.cache * ``` * * @since 4.2.2 */ const generateFilePath = (key, options = {}) => { const config = { ...DEFAULT_FILE_CACHE_CONFIG, ...options }; const sanitized = Hash.create(key, { outputFormat: "hex" }); let filePath; switch (config.namingStrategy) { case "hierarchical": const dir = sanitized.substring(0, 2); const subdir = sanitized.substring(2, 4); filePath = path__default.resolve(config.directory, dir, subdir, `${sanitized}${config.extension}`); break; case "dated": const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, "0"); const day = String(now.getDate()).padStart(2, "0"); filePath = path__default.resolve(config.directory, String(year), month, day, `${sanitized}${config.extension}`); break; case "direct": const safeKey = key.replace(/[^a-zA-Z0-9_-]/g, "_"); filePath = path__default.resolve(config.directory, `${safeKey}${config.extension}`); break; case "flat": default: filePath = path__default.resolve(config.directory, `${sanitized}${config.extension}`); break; } return filePath; }; // ======================================== // FILE CACHE EXPORTS // ======================================== /** * Default FileCache instance with lazy initialization * * Pre-configured file cache instance optimized for general use cases. * Features encryption, compression, and real disk space monitoring. * Uses lazy initialization to avoid circular dependency issues. * * @example * ```typescript * import { defaultFileCache } from "fortify2-js"; * * // Store large dataset with compression * await defaultFileCache.set('analytics:daily', bigDataSet, { * ttl: 86400000, // 24 hours * compress: true * }); * * // Check cache health * const info = await defaultFileCache.getCacheInfo(); * if (!info.health.healthy) { * console.warn('Cache issues:', info.health.issues); * } * ``` * * @since 4.2.0 */ let _defaultFileCache = null; const defaultFileCache = new Proxy({}, { get(target, prop) { if (!_defaultFileCache) { _defaultFileCache = new FileCache(); } const value = _defaultFileCache[prop]; return typeof value === "function" ? value.bind(_defaultFileCache) : value; }, }); /** * Write data to file cache with automatic optimization * * Stores data in the file cache with intelligent compression and encryption. * Automatically handles large objects and provides atomic write operations. * * @param key - Unique identifier for the cached data * @param data - Data to cache (any serializable type) * @param options - Optional cache configuration * @returns Promise resolving to true if successful * * @example * ```typescript * import { writeFileCache } from "fortify2-js"; * * // Cache user profile with encryption * const success = await writeFileCache('profile:user123', { * name: 'John Doe', * preferences: { theme: 'dark', lang: 'en' } * }, { * encrypt: true, * ttl: 3600000 // 1 hour * }); * ``` * * @since 4.2.2 */ const writeFileCache = async (key, data, options) => { return defaultFileCache.set(key, data, options); }; /** * Read data from file cache with automatic decryption * * Retrieves and automatically decrypts/decompresses cached data. * Returns null for expired or non-existent entries. * * @param key - Unique identifier for the cached data * @returns Promise resolving to cached data or null * * @example * ```typescript * import { readFileCache } from "fortify2-js"; * * const userData = await readFileCache('profile:user123'); * if (userData) { * console.log('Welcome back,', userData.name); * } else { * console.log('Cache miss - loading from database'); * } * ``` * * @since 4.2.2 */ const readFileCache = async (key) => { return defaultFileCache.get(key); }; /** * Remove specific entry from file cache * * Permanently deletes a cache entry and updates disk usage statistics. * Safe to call on non-existent keys. * * @param key - Unique identifier for the cached data * @returns Promise resolving to true if entry was deleted * * @example * ```typescript * import { removeFileCache } from "fortify2-js"; * * // Remove expired session * const removed = await removeFileCache('session:expired123'); * console.log(removed ? 'Session cleared' : 'Session not found'); * ``` * * @since 4.2.2 */ const removeFileCache = async (key) => { return defaultFileCache.delete(key); }; /** * Check if file cache entry exists and is valid * * Verifies cache entry existence without loading the data. * Automatically removes expired entries during check. * * @param key - Unique identifier for the cached data * @returns Promise resolving to true if entry exists and is valid * * @example * ```typescript * import { hasFileCache } from "fortify2-js"; * * if (await hasFileCache('config:app-settings')) { * const config = await readFileCache('config:app-settings'); * } else { * // Load from default configuration * } * ``` * * @since 4.2.2 */ const hasFileCache = async (key) => { return defaultFileCache.has(key); }; /** * Clear all file cache entries * * Removes all cached files and resets statistics. * Use with caution in production environments. * * @example * ```typescript * import { clearFileCache } from "fortify2-js"; * * // Clear cache during maintenance * await clearFileCache(); * console.log('Cache cleared successfully'); * ``` * * @since 4.2.2 */ const clearFileCache = async () => { return defaultFileCache.clear(); }; /** * Get comprehensive file cache statistics * * Returns real-time statistics including disk usage, hit rates, * and performance metrics with health assessment. * * @returns Promise resolving to detailed cache statistics * * @example * ```typescript * import { getFileCacheStats } from "fortify2-js"; * * const stats = await getFileCacheStats(); * console.log(`Cache efficiency: ${stats.hitRate}%`); * console.log(`Disk usage: ${stats.diskUsage.percentage}%`); * console.log(`Average response time: ${stats.avgResponseTime}ms`); * ``` * * @since 4.2.2 */ const getFileCacheStats = async () => { return defaultFileCache.getStats(); }; /** * Clean up expired file cache entries * * Removes expired entries and optimizes disk usage. * Automatically runs in background but can be triggered manually. * * @param options - Optional cleanup configuration * @returns Promise resolving to cleanup results * * @example * ```typescript * import { cleanupFileCache } from "fortify2-js"; * * const result = await cleanupFileCache(); * console.log(`Cleaned ${result.cleaned} files, freed ${result.totalSize} bytes`); * ``` * * @since 4.2.2 */ const cleanupFileCache = async (options) => { return defaultFileCache.cleanup(options); }; // ======================================== // MEMORY CACHE API // ======================================== /** * Read data from memory cache with fallback * * Retrieves data from the default memory cache instance. * Returns empty object if key is not found (legacy behavior). * * @param args - Arguments passed to Cache.get() * @returns Promise resolving to cached data or empty object * * @example * ```typescript * import { readCache } from "fortify2-js"; * * const sessionData = await readCache('session:user123'); * console.log('User ID:', sessionData.userId || 'Not found'); * ``` * * @since 4.2.2 */ const readCache = async (...args) => { const result = await Cache.get(...args); return result || {}; }; /** * Write data to memory cache * * Stores data in the default memory cache instance with encryption * and automatic compression for large values. * * @param args - Arguments passed to Cache.set() * @returns Promise resolving to true if successful * * @example * ```typescript * import { writeCache } from "fortify2-js"; * * await writeCache('user:profile', userData, { ttl: 1800000 }); // 30 min * ``` * * @since 4.2.2 */ const writeCache = async (...args) => { return Cache.set(...args); }; /** * Get memory cache performance statistics * * Returns comprehensive statistics including hit rates, memory usage, * and performance metrics for the default cache instance. * * @returns Current cache statistics * * @example * ```typescript * import { getCacheStats } from "fortify2-js"; * * const stats = getCacheStats(); * console.log(`Hit rate: ${stats.hitRate}%`); * console.log(`Memory usage: ${stats.memoryUsage} bytes`); * ``` * * @since 4.2.2 */ const getCacheStats = () => { return Cache.getStats; }; /** * Remove entry from memory cache * * Immediately removes a cache entry and frees associated memory. * Safe to call on non-existent keys. * * @param key - Cache key to remove * @returns Promise that resolves when deletion is complete * * @example * ```typescript * import { expireCache } from "fortify2-js"; * * await expireCache('session:expired123'); * console.log('Session removed from cache'); * ``` * * @since 4.2.2 */ const expireCache = (key) => { Cache.delete(key); return Promise.resolve(); }; /** * Clear all memory cache entries * * Removes all cached data and resets statistics. * Use with caution in production environments. * * @returns Promise that resolves when cache is cleared * * @example * ```typescript * import { clearAllCache } from "fortify2-js"; * * await clearAllCache(); * console.log('Memory cache cleared'); * ``` * * @since 4.2.2 */ const clearAllCache = () => { Cache.clear(); return Promise.resolve(); }; /** * Legacy filepath function * @deprecated use generateFilePath instead */ const filepath = (origin) => { return generateFilePath(origin, { namingStrategy: "hierarchical" }); }; // ======================================== // UTILITY FUNCTIONS // ======================================== /** * Create optimal cache instance based on performance requirements * * Factory function that creates the most suitable cache instance for your use case. * Automatically configures security settings and performance optimizations. * * @param options - Cache configuration options * @param options.type - Cache strategy: 'memory' (fastest), 'file' (persistent), 'hybrid' (balanced) * @param options.config - Optional file cache configuration (ignored for memory-only) * @returns Configured cache instance optimized for the specified requirements * * @example * ```typescript * import { createOptimalCache } from "fortify2-js"; * * // Ultra-fast memory cache for session data * const sessionCache = createOptimalCache({ type: 'memory' }); * * // Persistent file cache for application data * const appCache = createOptimalCache({ * type: 'file', * config: { * directory: './app-cache', * encrypt: true, * maxCacheSize: 100 * 1024 * 1024 // 100MB * } * }); * * // Hybrid cache for optimal performance and persistence * const hybridCache = createOptimalCache({ * type: 'hybrid', * config: { encrypt: true, compress: true } * }); * * // Use hybrid cache (memory-first with file backup) * await hybridCache.set('user:123', userData); * const user = await hybridCache.get('user:123'); // Served from memory * ``` * * @since 4.2.2 */ const createOptimalCache = (options) => { switch (options.type) { case "memory": return new SIMC(); case "file": return new FileCache(options.config); case "hybrid": // Return both memory cache and file cache in a wrapper return { memory: new SIMC(), file: new FileCache(options.config), async get(key) { // Try memory first, then file let result = await this.memory.get(key); if (!result) { result = await this.file.get(key); if (result) { // Cache in memory for faster access await this.memory.set(key, result); } } return result; }, async set(key, value, options) { // Set in both caches const memoryResult = await this.memory.set(key, value, options); const fileResult = await this.file.set(key, value, options); return memoryResult && fileResult; }, }; default: return new SIMC(); } }; // ======================================== // ADDITIONAL EXPORTS // ======================================== /** * Legacy file cache function names for backward compatibility * @deprecated Use the new function names for better clarity */ const deleteFileCache = removeFileCache; // ======================================== // GRACEFUL SHUTDOWN HANDLING // ======================================== /** * Graceful shutdown handler for cache system * * Automatically registered to handle SIGTERM and SIGINT signals. * Ensures all cache operations complete before process termination. * * @internal * @since 4.2.2 */ const handleGracefulShutdown = () => { console.log("Shutting down FortifyJS CS gracefully..."); try { Cache.shutdown(); } catch (error) { console.error("Error during cache shutdown:", error); } }; // Register shutdown handlers process.on("SIGTERM", handleGracefulShutdown); process.on("SIGINT", handleGracefulShutdown); // ======================================== // MODULE METADATA // ======================================== /** * Cache module version and metadata * @since 4.2.0 */ const CACHE_VERSION = "4.2.3"; const CACHE_BUILD_DATE = "2025-04-06"; /** * SecureCacheClient - Enterprise-grade secure caching solution * * A high-performance, secure cache client that supports multiple backend strategies * including memory-only, Redis-only, and hybrid (memory + Redis) configurations. * Features military-grade AES-256-GCM encryption, intelligent compression, and * comprehensive monitoring capabilities. * * ## Features * - **Multi-Strategy Support**: Memory, Redis, or Hybrid caching * - **Military-Grade Security**: AES-256-GCM encryption with key rotation * - **High Availability**: Redis Cluster and Sentinel support * - **Performance Optimized**: Intelligent compression and hot data promotion * - **Production Ready**: Comprehensive monitoring and health checks * - **Type Safe**: Full TypeScript support with detailed interfaces * * ## Supported Cache Strategies * - `memory`: Ultra-fast in-memory caching with LRU eviction * - `redis`: Distributed Redis caching with clustering support * - `hybrid`: Memory-first with Redis backup for optimal performance * * ## Security Features * - AES-256-GCM encryption for all cached data * - Automatic key rotation and tamper detection * - Secure serialization with integrity verification * - Access pattern monitoring and anomaly detection * * @example Basic Redis Configuration * ```typescript * import { SecureCacheClient } from "fortify2-js"; * * const cache = new SecureCacheClient({ * strategy: "redis", * redis: { * host: "localhost", * port: 6379, * password: "your-secure-password" * } * }); * * await cache.connect(); * await cache.set("user:123", { name: "John", role: "admin" }, { ttl: 3600 }); * const user = await cache.get("user:123"); * ``` * * @example Hybrid Strategy with Encryption * ```typescript * const cache = new SecureCacheClient({ * strategy: "hybrid", * memory: { * maxSize: 100, // 100MB * maxEntries: 10000 * }, * redis: { * host: "redis-cluster.example.com", * port: 6379, * cluster: { * enabled: true, * nodes: [ * { host: "redis-1", port: 6379 }, * { host: "redis-2", port: 6379 } * ] * } * }, * security: { * encryption: true, * keyRotation: true * } * }); * ``` * * @example Advanced Usage with Tags and Monitoring * ```typescript * // Store data with tags for bulk invalidation * await cache.set("product:123", productData, { * ttl: 1800, * tags: ["products", "category:electronics"] * }); * * // Batch operations for better performance * await cache.mset({ * "user:1": userData1, * "user:2": userData2 * }, { ttl: 3600 }); * * // Invalidate by tags * await cache.invalidateByTags(["products"]); * * // Monitor cache health * const health = cache.getHealth(); * if (health.status !== "healthy") { * console.warn("Cache issues:", health.details); * } * * // Get performance statistics * const stats = await cache.getStats(); * console.log(`Hit rate: ${stats.memory.hitRate * 100}%`); * ``` * * @since 4.2.3 * @version 4.2.3 * @author NEHONIX * @see {@link ICacheAdapter} for the complete interface definition * @see {@link https://lab.nehonix.space/nehonix_viewer/_doc/Nehonix%20FortifyJs} for detailed documentation */ class SecureCacheClient { /** * Creates a new SecureCacheClient instance * * @param config - Cache configuration object * @param config.strategy - Cache strategy: "memory", "redis", or "hybrid" * @param config.redis - Redis configuration (required for "redis" and "hybrid" strategies) * @param config.redis.host - Redis server hostname * @param config.redis.port - Redis server port * @param config.redis.password - Redis authentication password * @param config.redis.cluster - Redis cluster configuration * @param config.memory - Memory cache configuration (for "memory" and "hybrid" strategies) * @param config.memory.maxSize - Maximum memory cache size in MB * @param config.memory.maxEntries - Maximum number of cache entries * @param config.security - Security configuration * @param config.security.encryption - Enable AES-256-GCM encryption * @param config.security.keyRotation - Enable automatic key rotation * @param config.monitoring - Monitoring and health check configuration * * @example * ```typescript * const cache = new SecureCacheClient({ * strategy: "hybrid", * redis: { host: "localhost", port: 6379 }, * memory: { maxSize: 100, maxEntries: 10000 }, * security: { encryption: true } * }); * ``` */ constructor(config) { this.adapter = null; this.config = config; // Adapter will be created lazily on first use } /** * Ensures the cache adapter is initialized * @private * @returns Promise resolving to the initialized adapter */ async ensureAdapter() { if (!this.adapter) { // Use dynamic import for production compatibility const { SecureCacheAdapter } = await import('../../integrations/express/cache/SecureCacheAdapter.js'); this.adapter = new SecureCacheAdapter(this.config); } return this.adapter; // Non-null assertion since we just created it } /** * Retrieves a value from the cache * * @param key - The cache key to retrieve * @returns Promise resolving to the cached value, or null if not found * * @example * ```typescript * const user = await cache.read<User>("user:123"); * if (user) { * console.log("Found user:", user.name); * } * ``` */ async read(key) { const adapter = await this.ensureAdapter(); return adapter.get(key); } /** * Stores a value in the cache with optional TTL and tags * * @param key - The cache key to store the value under * @param value - The value to cache (will be automatically serialized) * @param options - Optional caching options * @param options.ttl - Time to live in seconds (default: configured TTL) * @param options.tags - Array of tags for bulk invalidation * @returns Promise resolving to true if successful, false otherwise * * @example * ```typescript * // Basic usage * await cache.write("user:123", { name: "John", role: "admin" }); * * // With TTL (1 hour) * await cache.write("session:abc", sessionData, { ttl: 3600 }); * * // With tags for bulk invalidation * await cache.write("product:456", productData, { * ttl: 1800, * tags: ["products", "category:electronics"] * }); * ``` */ async write(key, value, options) { const adapter = await this.ensureAdapter(); return adapter.set(key, value, options); } /** * Deletes a value from the cache * * @param key - The cache key to delete * @returns Promise resolving to true if the key was deleted, false if not found * * @example * ```typescript * const deleted = await cache.delete("user:123"); * if (deleted) { * console.log("User cache cleared"); * } * ``` */ async delete(key) { const adapter = await this.ensureAdapter(); return adapter.delete(key); } /** * Checks if a key exists in the cache * * @param key - The cache key to check * @returns Promise resolving to true if the key exists, false otherwise * * @example * ```typescript * if (await cache.exists("user:123")) { * console.log("User is cached"); * } * ``` */ async exists(key) { const adapter = await this.ensureAdapter(); return adapter.exists(key); } /** * Clears all cached data * * ⚠️ **Warning**: This operation is irreversible and will remove all cached data * * @returns Promise that resolves when the cache is cleared * * @example * ```typescript * await cache.clear(); * console.log("All cache data cleared"); * ``` */ async clear() { const adapter = await this.ensureAdapter(); return adapter.clear(); } /** * Establishes connection to the cache backend * * Must be called before using the cache. For Redis strategies, this establishes * the connection to the Redis server(s). For memory-only strategy, this initializes * the in-memory cache. * * @returns Promise that resolves when the connection is established * @throws {Error} If connection fails * * @example * ```typescript * try { * await cache.connect(); * console.log("Cache connected successfully"); * } catch (error) { * console.error("Failed to connect to cache:", error); * } * ``` */ async connect() { const adapter = await this.ensureAdapter(); return adapter.connect(); } /** * Closes the connection to the cache backend * * Gracefully closes all connections and cleans up resources. Should be called * when shutting down the application. * * @returns Promise that resolves when the connection is closed * * @example * ```typescript * process.on('SIGTERM', async () => { * await cache.disconnect(); * console.log("Cache disconnected"); * }); * ``` */ async disconnect() { const adapter = await this.ensureAdapter(); return adapter.disconnect(); } /** * Retrieves comprehensive cache performance statistics * * @returns Promise resolving to detailed statistics including hit rates, memory usage, and performance metrics * * @example * ```typescript * const stats = await cache.getStats(); * console.log(`Memory hit rate: ${stats.memory.hitRate * 100}%`); * console.log(`Redis hit rate: ${stats.redis?.hitRate * 100}%`); * console.log(`Total operations: ${stats.operations.total}`); * console.log(`Average response time: ${stats.performance.avgResponseTime}ms`); * ``` */ async getStats() { const adapter = await this.ensureAdapter(); const stats = await adapter.getStats(); // Transform the adapter stats to match our interface return { memory: { hitRate: stats.memory?.hitRate || 0, missRate: stats.memory?.missRate || 0, size: stats.memory?.size || 0, entries: stats.memory?.entries || 0, maxSize: stats.memory?.maxSize || 0, maxEntries: stats.memory?.maxEntries || 0, }, redis: stats.redis ? { hitRate: stats.redis.hitRate || 0, missRate: stats.redis.missRate || 0, connected: stats.redis.connected || false, memoryUsage: stats.redis.memoryUsage || 0, keyCount: stats.redis.keyCount || 0, } : undefined, operations: { total: stats.operations?.total || stats.total || 0, gets: stats.operations?.gets || stats.gets || 0, sets: stats.operations?.sets || stats.sets || 0, deletes: stats.operations?.deletes || stats.deletes || 0, errors: stats.operations?.errors || stats.errors || 0, }, performance: { avgResponseTime: stats.performance?.avgResponseTime || stats.avgResponseTime || 0, p95ResponseTime: stats.performance?.p95ResponseTime || stats.p95ResponseTime || 0, p99ResponseTime: stats.performance?.p99ResponseTime || stats.p99ResponseTime || 0, }, }; } /** * Retrieves multiple values from the cache in a single operation * * @param keys - Array of cache keys to retrieve * @returns Promise resolving to an object with key-value pairs (missing keys are omitted) * * @example * ```typescript * const users = await cache.mread<User>(["user:1", "user:2", "user:3"]); * console.log(users); // { "user:1": {...}, "user:2": {...} } * ``` */ async mread(keys) { const adapter = await this.ensureAdapter(); return adapter.mget(keys); } /** * Stores multiple key-value pairs in a single operation * * @param entries - Object with key-value pairs or array of [key, value] tuples * @param options - Optional caching options applied to all entries * @param options.ttl - Time to live in seconds for all entries * @param options.tags - Array of tags applied to all entries * @returns Promise resolving to true if successful, false otherwise * * @example * ```typescript * // Using object notation * await cache.mwrite({ * "user:1": { name: "Alice" }, * "user:2": { name: "Bob" } * }, { ttl: 3600 }); * * // Using array notation * await cache.mwrite([ * ["session:abc", sessionData1], * ["session:def", sessionData2] * ], { ttl: 1800, tags: ["sessions"] }); * ``` */ async mwrite(entries, options) { const adapter = await this.ensureAdapter(); return adapter.mset(entries, options); } /** * Invalidates all cache entries that have any of the specified tags * * @param tags - Array of tags to invalidate * @returns Promise resolving to the number of entries invalidated * * @example * ```typescript * // Invalidate all product-related cache entries * const count = await cache.invalidateByTags(["products", "inventory"]); * console.log(`Invalidated ${count} cache entries`); * ``` */ async invalidateByTags(tags) { const adapter = await this.ensureAdapter(); return adapter.invalidateByTags(tags); } /** * Gets the remaining time-to-live for a cache key * * @param key - The cache key to check * @returns Promise resolving to TTL in seconds, or -1 if key doesn't exist, -2 if no TTL set * * @example * ```typescript * const ttl = await cache.getTTL("user:123"); * if (ttl > 0) { * console.log(`Key expires in ${ttl} seconds`); * } * ``` */ async getTTL(key) { const adapter = await this.ensureAdapter(); return adapter.getTTL(key); } /** * Sets or updates the expiration time for a cache key * * @param key - The cache key to set expiration for * @param ttl - Time to live in seconds * @returns Promise resolving to true if successful, false if key doesn't exist * * @example * ```typescript * // Extend expiration to 1 hour * await cache.expire("user:123", 3600); * * // Set short expiration for temporary data * await cache.expire("temp:data", 60); * ``` */ async expire(key, ttl) { const adapter = await this.ensureAdapter(); return adapter.expire(key, ttl); } /** * Retrieves all cache keys matching an optional pattern * * ⚠️ **Warning**: Use with caution in production as this can be expensive for large caches * * @param pattern - Optional glob-style pattern to filter keys (Redis syntax) * @returns Promise resolving to array of matching keys * * @example * ```typescript * // Get all keys * const allKeys = await cache.keys(); * * // Get user-related keys * const userKeys = await cache.keys("user:*"); * * // Get session keys with pattern * const sessionKeys = await cache.keys("session:*:active"); * ``` */ async keys(pattern) { const adapter = await this.ensureAdapter(); return adapter.keys(pattern); } /** * Gets the current health status of the cache system * * @returns Health status object with overall status and detailed information * * @example * ```typescript * const health = cache.getHealth(); * * switch (health.status) { * case "healthy": * console.log("Cache is operating normally"); * break; * case "degraded": * console.warn("Cache has issues but is functional:", health.details); * break; * case "unhealthy": * console.error("Cache is not functional:", health.details); * break; * } * * // Check specific metrics * if (health.details.redis?.connected === false) { * console.error("Redis connection lost"); * } * ``` */ getHealth() { if (!this.adapter) { return { status: "unhealthy", details: { errors: ["Cache adapter not initialized"], lastCheck: new Date(), }, }; } return this.adapter.getHealth(); } } export { CACHE_BUILD_DATE, CACHE_VERSION, Cache, DEFAULT_FILE_CACHE_CONFIG, FileCache, SecureCacheClient as SCC, SecureCacheClient, SIMC as SecureInMemoryCache, cleanupFileCache, clearAllCache, clearFileCache, createOptimalCache, defaultFileCache, deleteFileCache, expireCache, filepath, generateFilePath, getCacheStats, getFileCacheStats, hasFileCache, readCache, readFileCache, removeFileCache, writeCache, writeFileCache }; //# sourceMappingURL=index.js.map