fs-cachebox
Version:
A lightweight file-based caching library for Node.js. Stores key-value data on the filesystem with optional TTL support.
288 lines (285 loc) • 7.44 kB
text/typescript
import { EventEmitter } from 'node:events';
/**
* Custom error class for cache operations
*/
declare class CacheError extends Error {
operation: string;
key?: string | undefined;
originalError?: Error | undefined;
constructor(message: string, operation: string, key?: string | undefined, originalError?: Error | undefined);
}
/**
* Enhanced configuration options for CacheBox initialization
*/
interface CacheBoxOptions {
/** Directory path where cache files will be stored. Defaults to '.cache' */
cacheDir?: string;
/** Enable automatic compression for cached values. Defaults to false */
enableCompression?: boolean;
/** Minimum size (in bytes) before compression kicks in. Defaults to 1024 */
compressionThreshold?: number;
/** Compression level (1-9, where 9 is best compression). Defaults to 6 */
compressionLevel?: number;
/** Maximum number of cache entries. Defaults to unlimited */
maxSize?: number;
/** Maximum size per cache file in bytes. Defaults to 50MB */
maxFileSize?: number;
/** Default TTL for entries in milliseconds. Defaults to 0 (no expiration) */
defaultTTL?: number;
/** Auto-cleanup interval in milliseconds. Defaults to 300000 (5 minutes) */
cleanupInterval?: number;
/** Enable automatic cleanup of expired entries. Defaults to true */
enableAutoCleanup?: boolean;
/** Enable detailed logging. Defaults to false */
enableLogging?: boolean;
}
/**
* Event types emitted by CacheBox
*/
interface CacheBoxEvents {
/** Emitted when cache is initialized and ready */
ready: {
entriesLoaded: number;
cacheDir: string;
};
/** Emitted when cache data is modified */
change: {
operation: string;
key: string;
value?: any;
};
/** Emitted when any error occurs */
error: CacheError;
/** Emitted when cache entry expires */
expire: {
key: string;
ttl: number;
};
/** Emitted when cache is cleared */
clear: {
entriesRemoved: number;
};
/** Emitted during cleanup operations */
cleanup: {
expired: number;
removed: number;
};
}
type EventMapToTuplePayload<T> = {
[K in keyof T]: [T[K]];
};
/**
* Enhanced file-based cache system with comprehensive features
*
* Features:
* - Async and sync operations
* - Compression support with configurable thresholds
* - Key validation and security
* - Event-driven architecture
* - Performance monitoring
* - Automatic cleanup
* - Batch operations
* - Type safety with generics
* - LRU eviction when size limits are reached
*/
declare class CacheBox extends EventEmitter<EventMapToTuplePayload<CacheBoxEvents>> {
private _cache;
private _cacheDir;
private _enableCompression;
private _compressionThreshold;
private _compressionLevel;
private _maxSize?;
private _maxFileSize;
private _defaultTTL;
private _cleanupInterval;
private _enableAutoCleanup;
private _enableLogging;
private _cleanupTimer?;
private _stats;
constructor(options?: CacheBoxOptions);
/**
* Validates cache key for security and filesystem compatibility
*/
private validateKey;
/**
* Logs messages if logging is enabled
*/
private log;
/**
* Serializes and optionally compresses data
*/
private serialize;
/**
* Deserializes and optionally decompresses data
*/
private deserialize;
/**
* Parses filename to extract metadata
*/
private parseFileName;
/**
* Generates filename with metadata
*/
private generateFileName;
/**
* Removes expired entries and enforces size limits
*/
private performCleanup;
/**
* Starts automatic cleanup timer
*/
private startAutoCleanup;
/**
* Emits error events with consistent formatting
*/
private emitError;
/**
* Initializes the cache system
*/
private load;
/**
* Synchronizes memory cache with filesystem
*/
private syncMemoryCache;
/**
* Checks if a cache key exists and is not expired
*/
has(key: string): boolean;
/**
* Retrieves a cached value by key
*/
get<T>(key: string): T | null;
/**
* Stores a value in the cache
*/
set(key: string, value: any, ttl?: number): boolean;
/**
* Removes a cache entry
*/
delete(key: string): boolean;
/**
* Clears all cache entries
*/
clear(): boolean;
/**
* Batch set multiple entries
*/
setMany(entries: Array<{
key: string;
value: any;
ttl?: number;
}>): {
success: number;
failed: number;
results: boolean[];
};
/**
* Batch get multiple entries
*/
getMany<T>(keys: string[]): Array<{
key: string;
value: T | null;
found: boolean;
}>;
/**
* Async version of get method
*/
getAsync<T>(key: string): Promise<T | null>;
/**
* Async version of set method
*/
setAsync(key: string, value: any, ttl?: number): Promise<boolean>;
/**
* Async version of delete method
*/
deleteAsync(key: string): Promise<boolean>;
/**
* Async batch operations
*/
setManyAsync(entries: Array<{
key: string;
value: any;
ttl?: number;
}>): Promise<{
success: number;
failed: number;
results: boolean[];
}>;
getManyAsync<T>(keys: string[]): Promise<Array<{
key: string;
value: T | null;
found: boolean;
}>>;
/**
* Returns current cache size
*/
size(): number;
/**
* Returns all valid cache keys
*/
keys(): string[];
/**
* Returns comprehensive cache statistics
*/
stats(): {
entries: number;
memoryEntries: number;
totalSize: number;
averageSize: number;
cacheDir: string;
configuration: {
maxSize: number | undefined;
maxFileSize: number;
defaultTTL: number;
compressionEnabled: boolean;
compressionThreshold: number;
compressionLevel: number;
};
performance: {
hits: number;
misses: number;
hitRate: number;
sets: number;
deletes: number;
errors: number;
};
compression: {
totalEntries: number;
compressedEntries: number;
uncompressedEntries: number;
compressionRatio: number;
enabled: boolean;
threshold: number;
level: number;
};
};
/**
* Returns compression-specific statistics
*/
compressionStats(): {
totalEntries: number;
compressedEntries: number;
uncompressedEntries: number;
compressionRatio: number;
enabled: boolean;
threshold: number;
level: number;
};
/**
* Manually trigger cleanup
*/
cleanup(): {
expired: number;
removed: number;
};
/**
* Stops auto-cleanup timer and closes cache
*/
close(): void;
/**
* Resets all statistics
*/
resetStats(): void;
}
export { CacheBox, CacheError };
export type { CacheBoxEvents, CacheBoxOptions };