A Redis cache implementation with TypeScript support, automatic JSON handling, and connection management.
- 🔄 Singleton pattern for consistent cache access
- 📦 Automatic JSON serialization/deserialization
- ⏱️ TTL support for cache entries
- 🚀 Bulk operations support
- 📝 Custom logger injection
- 🔍 Pattern-based key search
- 🔄 Connection retry strategy
- 🧪 Test environment support
npm install @heyatlas/cacheimport{cacheInstance}from"@heyatlas/cache";// Initialize cacheconstcache=cacheInstance({host: "redis.example.com",port: 6379,username: "user",// optionalpassword: "pass",// optional});// Connect to Redisawaitcache.connect();// Set a valueawaitcache.set("myKey",{foo: "bar"});// Get a valueconstvalue=awaitcache.get("myKey");// value = { foo: "bar" }// Set with TTL (in seconds)awaitcache.set("tempKey","value",60);// Delete a keyawaitcache.del("myKey");import{Logger}from"@heyatlas/logger";import{cacheInstance}from"@heyatlas/cache";constlogger=newLogger({name: "my-cache",// ... logger configuration});constcache=cacheInstance({host: "redis.example.com",logger: logger,});constitems=[{key: "key1",value: "value1"},{key: "key2",value: {nested: "object"}},{key: "key3",value: "value3",ttl: 3600},];awaitcache.setBulk(items);// Find all keys matching a patternconstkeys=awaitcache.keys("user:*");constresults=awaitcache.executePipeline<string|number>((pipeline)=>{pipeline.set("key1","value1");pipeline.incr("counter");pipeline.get("key1");});The cache store provides a higher-level abstraction with namespace isolation and simplified interface.
import{createCacheStore}from"@heyatlas/cache";// Create a store with a namespaceconstuserStore=createCacheStore({namespace: "users",defaultTTL: 3600,// optional, in seconds});// Check if item exists in cacheconstisNew=awaituserStore.isNewItem("user-123");// Save item to cacheawaituserStore.saveItem("user-123",{name: "John Doe",email: "john@example.com",});// Save with custom TTL (overrides default)awaituserStore.saveItem("user-456",userData,1800);Each store operates independently with its own namespace:
// Create separate stores for different featuresconstuserStore=createCacheStore({namespace: "users"});constproductStore=createCacheStore({namespace: "products"});constsessionStore=createCacheStore({namespace: "sessions",defaultTTL: 1800,// 30 minutes});// Each store manages its own keysawaituserStore.saveItem("123",userData);awaitproductStore.saveItem("123",productData);// These don't conflict despite same keyinterfaceCacheStoreOptions{// Required unique namespace for this storenamespace: string;// Optional default TTL in secondsdefaultTTL?: number;// Optional custom loggerlogger?: Logger;}The store automatically handles:
- Namespace prefixing for keys
- JSON serialization/deserialization
- TTL management
- Connection lifecycle
| Option | Type | Required | Description |
|---|---|---|---|
| host | string | Yes | Redis host |
| port | string | number | No | Redis port (default: 6379) |
| username | string | No | Redis username |
| password | string | No | Redis password |
| tlsEnabled | boolean | No | Enable TLS connection |
| logger | Logger | No | Custom logger instance |
The cache automatically prefixes keys with 'test:' when NODE_ENV is set to 'test'. This helps isolate test data from production data.
consttestCache=cacheInstance({host: "localhost",});// With NODE_ENV=testawaittestCache.set("key","value");// Actual key in Redis: 'test:key'The cache implements various error handling strategies:
- Connection retry with exponential backoff
- Automatic reconnection on connection loss
- Proper error propagation for failed operations
- Validation for null/undefined values
try{awaitcache.set("key",null);}catch(error){// Throws: "Value is null or undefined"}MIT