AutoLoop / lib /cache.ts
shubhjn's picture
feat: Introduce a comprehensive automation and content management system with workflow management, social media integration, and email capabilities.
b8dc207
// Caching Strategy for Improved Performance
// Implements in-memory caching with TTL
interface CacheEntry<T> {
value: T;
expiresAt: number;
}
class Cache {
private store: Map<string, CacheEntry<unknown>> = new Map();
private cleanupInterval: NodeJS.Timeout | null = null;
constructor() {
// Cleanup expired entries every 5 minutes
this.cleanupInterval = setInterval(() => this.cleanup(), 5 * 60 * 1000);
}
set<T>(key: string, value: T, ttlSeconds: number = 300): void {
const expiresAt = Date.now() + (ttlSeconds * 1000);
this.store.set(key, { value, expiresAt });
}
get<T>(key: string): T | null {
const entry = this.store.get(key);
if (!entry) return null;
// Check if expired
if (Date.now() > entry.expiresAt) {
this.store.delete(key);
return null;
}
return entry.value as T;
}
has(key: string): boolean {
const entry = this.store.get(key);
if (!entry) return false;
if (Date.now() > entry.expiresAt) {
this.store.delete(key);
return false;
}
return true;
}
delete(key: string): void {
this.store.delete(key);
}
clear(): void {
this.store.clear();
}
private cleanup(): void {
const now = Date.now();
for (const [key, entry] of this.store.entries()) {
if (now > entry.expiresAt) {
this.store.delete(key);
}
}
}
destroy(): void {
if (this.cleanupInterval) {
clearInterval(this.cleanupInterval);
this.cleanupInterval = null;
}
this.clear();
}
}
// Global cache instance
export const cache = new Cache();
// Helper function for cache-aside pattern
export async function getCached<T>(
key: string,
fetcher: () => Promise<T>,
ttlSeconds: number = 300
): Promise<T> {
// Try to get from cache
const cached = cache.get<T>(key);
if (cached !== null) {
return cached;
}
// Fetch fresh data
const data = await fetcher();
// Store in cache
cache.set(key, data, ttlSeconds);
return data;
}
// Cache key generators for common patterns
export const cacheKeys = {
user: (userId: string) => `user:${userId}`,
businesses: (userId: string) => `businesses:${userId}`,
templates: (userId: string) => `templates:${userId}`,
stats: (userId: string) => `stats:${userId}`,
analytics: (userId: string, period: string) => `analytics:${userId}:${period}`,
};