Package Exports
- frache
- frache/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (frache) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Frache ๐
Advanced and intelligent caching for Node.js using ioredis and queueing.
Frache is a powerful, feature-rich caching library that provides intelligent caching strategies, warmup tasks, and advanced Redis operations for Node.js applications. Built with TypeScript and designed for production use.
โจ Features
๐ฏ Core Caching
- Simple API:
set(),get(),del(),clear()with intuitive options - Singleton Pattern: Thread-safe singleton with custom Redis client support
- TypeScript First: Full TypeScript support with comprehensive type definitions
- Flexible TTL: Per-key TTL with intelligent defaults
- Namespace Support: Organize cache keys with namespaces
๐ง Intelligent Caching
- Cache-aside Pattern:
getOrSet()for seamless cache-aside implementation - Compression: Automatic compression for large values
- Serialization: Smart JSON serialization with fallback handling
- Tag-based Invalidation: Group and invalidate related cache entries
- Batch Operations:
setMany(),getMany(),delMany()for efficiency
๐ฅ Advanced Features
- Warmup Tasks: Proactive cache warming with priority queues
- Data Structures: Lists, sets, counters with Redis-native operations
- Memory Management: Intelligent memory usage with configurable limits
- Event System: Comprehensive event emission for monitoring
- Statistics: Built-in performance metrics and hit/miss tracking
๐ Monitoring & Observability
- Performance Metrics: Hit rates, response times, memory usage
- Event Listeners: Cache hits, misses, errors, warmup events
- Health Checks: Built-in health monitoring
- Debug Support: Comprehensive logging and error handling
๐ Quick Start
Installation
npm install frache ioredisBasic Usage
import { Cache } from 'frache';
// Initialize cache (singleton)
const cache = Cache.getInstance({
defaultTtl: 3600, // 1 hour
defaultNamespace: 'myapp',
});
// Basic operations
await cache.set('user:123', { name: 'John', age: 30 });
const user = await cache.get('user:123');
await cache.del('user:123');
// Cache-aside pattern
const user = await cache.getOrSet('user:456', async () => {
return await database.getUser(456);
}, { ttl: 1800 });Advanced Usage
import { AdvancedCache } from 'frache';
const cache = AdvancedCache.getInstance();
// Batch operations
await cache.setMany([
{ key: 'user:1', value: { name: 'Alice' } },
{ key: 'user:2', value: { name: 'Bob' } },
]);
const users = await cache.getMany(['user:1', 'user:2']);
// Data structures
await cache.listPush('recent-users', 'user:123');
await cache.setAdd('active-users', 'user:456');
await cache.increment('page-views', 1);
// Tag-based invalidation
await cache.set('product:1', product, { tags: ['products', 'category:electronics'] });
await cache.clear({ tags: ['products'] }); // Clear all product cache๐ฏ Cache-aside Pattern
Perfect for database caching scenarios:
class UserService {
async getUser(id: number) {
return cache.getOrSet(`user:${id}`, async () => {
// This only runs on cache miss
return await database.users.findById(id);
}, {
ttl: 3600,
tags: ['users', `user:${id}`]
});
}
async updateUser(id: number, data: any) {
const user = await database.users.update(id, data);
// Invalidate related cache
await cache.clear({ tags: [`user:${id}`] });
return user;
}
}๐ฅ Warmup Tasks
Proactively warm your cache for better performance:
// Register warmup tasks
cache.registerWarmupTask({
id: 'popular-products',
name: 'Cache Popular Products',
priority: 1,
execute: async () => {
const products = await database.getPopularProducts();
for (const product of products) {
await cache.set(`product:${product.id}`, product, { ttl: 7200 });
}
}
});
// Queue for execution
cache.queueWarmupTask('popular-products');
// Or run immediately
await cache.runWarmupTask('popular-products');๐ Monitoring & Events
// Listen to cache events
cache.on('hit', (event) => {
console.log(`Cache hit: ${event.key}`);
});
cache.on('miss', (event) => {
console.log(`Cache miss: ${event.key}`);
});
cache.on('warmup', (event) => {
console.log(`Warmup task ${event.data.task.name}: ${event.data.status}`);
});
// Get performance statistics
const stats = cache.getStats();
console.log(`Hit rate: ${(stats.hits / (stats.hits + stats.misses) * 100).toFixed(2)}%`);โ๏ธ Configuration
const cache = Cache.getInstance({
// Redis configuration
redis: new Redis('redis://localhost:6379'),
// Cache settings
defaultTtl: 3600,
defaultNamespace: 'myapp',
keyPrefix: 'cache',
// Performance settings
enableCompression: true,
maxMemory: 100 * 1024 * 1024, // 100MB
// Warmup settings
enableWarmup: true,
warmupInterval: 60000, // 1 minute
});๐๏ธ Architecture
Frache is built with a clean, extensible architecture:
- Cache: Core caching functionality with singleton pattern
- AdvancedCache: Extended functionality with data structures
- Utils: Serialization, compression, key generation utilities
- Types: Comprehensive TypeScript definitions
- Events: Event-driven architecture for monitoring
๐ Performance
Frache is designed for high performance:
- Memory Efficient: Smart compression and TTL management
- Network Optimized: Batch operations reduce Redis round trips
- CPU Friendly: Efficient serialization and key generation
- Scalable: Singleton pattern prevents connection proliferation
Benchmarks
Cache Operations (1000 iterations):
โโโ set(): ~0.5ms avg
โโโ get(): ~0.3ms avg (hit)
โโโ getOrSet(): ~0.4ms avg (hit), ~15ms avg (miss)
โโโ batch operations: ~60% faster than individual calls๐ง API Reference
Core Methods
| Method | Description | Example |
|---|---|---|
set(key, value, options?) |
Store a value | cache.set('key', 'value', { ttl: 300 }) |
get(key, options?) |
Retrieve a value | cache.get('key') |
del(key, options?) |
Delete a value | cache.del('key') |
clear(options?) |
Clear multiple values | cache.clear({ namespace: 'users' }) |
getOrSet(key, factory, options?) |
Cache-aside pattern | cache.getOrSet('key', () => fetchData()) |
Advanced Methods
| Method | Description | Example |
|---|---|---|
setMany(entries) |
Set multiple values | cache.setMany([{key: 'k1', value: 'v1'}]) |
getMany(keys) |
Get multiple values | cache.getMany(['k1', 'k2']) |
increment(key, amount?) |
Increment counter | cache.increment('views', 1) |
listPush(key, value) |
Add to list | cache.listPush('queue', item) |
setAdd(key, value) |
Add to set | cache.setAdd('tags', 'important') |
Warmup Methods
| Method | Description | Example |
|---|---|---|
registerWarmupTask(task) |
Register warmup task | cache.registerWarmupTask({id: 'task1', ...}) |
queueWarmupTask(id, options?) |
Queue task for execution | cache.queueWarmupTask('task1') |
runWarmupTask(id) |
Run task immediately | cache.runWarmupTask('task1') |
๐ Examples
- Express + SQLite Example: Complete Express.js application with SQLite database
- Basic Usage: Simple caching examples
- Advanced Patterns: Complex caching strategies
๐งช Testing
Frache includes comprehensive tests:
npm test # Run all tests
npm run test:watch # Watch mode
npm run test:coverage # Coverage reportTest Coverage: 96+ tests covering all functionality
๐ค Contributing
We welcome contributions! Please see our Contributing Guide for details.
๐ License
MIT ยฉ Your Name
๐ Links
Made with โค๏ธ for the Node.js community