This cache library provides a unified interface for different caching strategies, including Redis, in-memory LRU caching. It's designed to be modular, type-safe, and easily extensible.
Redis, LRU memory caching, and Custom providers.LoggerDecorator, FallbackDecorator for enhanced functionality.CacheFactory for handler creation and custom registration.ICacheHandler interface.CacheError, manage connection failures.To install this package, execute the following commands in your terminal:
# Set the APM registry to local (one-time process)
npm set @koadz:registry <registry_url>
npm install @koadz/cache
import { Cache } from "@koadz/cache";
const cache = new Cache({
type: "redis",
clientUrl: "redis://localhost:6379",
});
The Cache repository is a unified class for storing and retrieving data from different cache providers. It's designed to be type-safe and easily extensible.
// Generic type `I` is used to represent the cache handler type.
// Generic type `T` is used to represent the cache data type.
class Cache<I, T> {}
// Custom data type
type Data = {
data: any;
createdAt: Date;
};
// Usage
const cache = new Cache<LRUMemoryHandler, Data>({
// ...
});
The Redis handler is used to cache data in Redis which internally uses the ioredis library. It provides methods for storing, retrieving, and deleting data from the cache.
Note: Install
ioredisbefore using this handler.
npm install ioredis
get(key: string): Retrieves data from the cache.set(key: string, value: any): Stores data in the cache.delete(key: string): Deletes data from the cache.clear(): Clears all data from the cache.has(key: string): Checks if a key exists in the cache.expire(key: string, ttl: number): Sets the expiration time for a key in the cache.disconnect(): Closes the Redis connection.flush(keys: string | string[]): Flushes specified keys from the cache.restart(options?: RestartOptions): Restarts the Redis connection. If options include flushAll, all cache is flushed. If flushKeys is provided, only specified keys are flushed.setBatch(entries: Record<string, any>): Sets multiple keys in the cache using a single Redis pipeline.list(): Retrieves a list of all keys in the cache.const redisCache = new Cache<RedisHandler, { id: number; name: string }>({
type: "redis",
clientUrl: "redis://localhost:6379",
ttl: 3600, // optional global TTL in seconds
});
await redisCache.set("user:123", { id: 123, name: "John" });
const user = await redisCache.get("user:123");
console.log(user); // { id: 123, name: "John" }
await redisCache.setBatch({
"user:456": { id: 456, name: "Jane" },
"user:789": { id: 789, name: "Bob" },
});
await redisCache.handler.expire("user:123", 1800); // Set TTL for specific key
await redisCache.handler.disconnect(); // Clean up connection
// Restart Redis connection
await redisHandler.handler.restart({
flushAll: true, // Optional
// or
flushKeys: ["user:123", "some-key"], // Optional
});
A simple in-memory LRU(Least Recently Used) cache.
get(key: string): Retrieves data from the cache.set(key: string, value: any): Stores data in the cache.delete(key: string): Deletes data from the cache.has(key: string): Checks if a key exists in the cache.clear(): Clears all data from the cache.expire(key: string, ttl: number): Sets the expiration time for a key in the cache.size(): Returns the current size of the cache.getOldestKey(): Returns the oldest key in the cache.const memoryCache = new Cache<LRUMemoryHandler>({
type: "lru-memory",
maxSize: 100, // Maximum number of items to store
ttl: 3600, // Time-to-live in seconds
});
await memoryCache.set("stats", { visits: 100 });
const stats = await memoryCache.get("stats");
// Check if key exists in Cache
const exists = await memoryCache.has("some-key");
console.log(exists); // Output: true
// Get oldest key in Cache
const oldestKey = await memoryCache.getOldestKey();
console.log(oldestKey); // Output: "some-key"
The logger decorator is used to log cache operations. It provides methods for logging cache hits and misses. Options can be provided to configure the logger.
// Add logging to any cache handler
const redisCache = new Cache<RedisHandler>({
type: "redis",
clientUrl: "redis://localhost:6379",
});
const loggedCache = new Cache({
type: "custom",
handler: new LoggerDecorator(redisCache.handler, {
// ...LoggerConfig
}),
});
await loggedCache.set("key", "value"); // Will log operations
The fallback handler is used to provide a fallback cache mechanism. It provides methods for storing, retrieving, and deleting data from the cache. The FallbackDecorator provides a way to combine two cache handlers with automatic fallback behavior.
get(key: string): Retrieves data from the cache.set(key: string, value: any): Stores data in the cache.has(key: string): Checks if a key exists in the cache.delete(key: string): Deletes data from the cache.clear(): Clears all data from the cache.// Primary: Memory, Fallback: Redis
const memoryCache = new LRUMemoryHandler({
type: "lru-memory",
maxSize: 1000,
});
const redisCache = new RedisHandler({
type: "redis",
clientUrl: "redis://localhost:6379",
});
const fallbackHandler = new Cache({
type: "custom",
handler: new FallbackDecorator(
memoryCache.handler, // Primary (faster)
redisCache.handler // Fallback (more reliable)
),
});
// Will try memory first, then Redis if not found
const value = await fallbackHandler.get("my-key");
// Get from Cache
const data = await fallbackHandler.get("some-key");
console.log(data); // Output: "some-value"
// Create a multi-layer cache setup
const memoryCache = new LRUMemoryHandler({
type: "lru-memory",
maxSize: 100,
});
const redisCache = new RedisHandler({
type: "redis",
clientUrl: "redis://localhost:6379",
});
// Add logging to Redis cache
const loggedRedis = new LoggerDecorator(redisCache.handler);
// Create fallback chain: Memory -> Logged Redis
const fallbackHandler = new FallbackDecorator(memoryCache.handler, loggedRedis);
const cache = new Cache({
type: "custom",
handler: fallbackHandler,
});
// Usage
await cache.set("key", "value");
// 1. Tries to set in memory
// 2. Also sets in Redis
// 3. Logs the Redis operation
const value = await cache.get("key");
// 1. Tries to get from memory
// 2. If not found, tries Redis
// 3. If found in Redis, populates memory cache
// 4. Logs the Redis operation if used