118 lines
3.5 KiB
TypeScript
118 lines
3.5 KiB
TypeScript
import { cache } from './redis';
|
|
|
|
// API Response caching
|
|
export const apiCache = {
|
|
// Generate cache key based on query parameters
|
|
generateProjectsKey(params: Record<string, string | null> = {}) {
|
|
const { page = '1', limit = '50', category, featured, published, difficulty, search } = params;
|
|
const keyParts = ['api:projects'];
|
|
|
|
if (page !== '1') keyParts.push(`page:${page}`);
|
|
if (limit !== '50') keyParts.push(`limit:${limit}`);
|
|
if (category) keyParts.push(`cat:${category}`);
|
|
if (featured !== null) keyParts.push(`feat:${featured}`);
|
|
if (published !== null) keyParts.push(`pub:${published}`);
|
|
if (difficulty) keyParts.push(`diff:${difficulty}`);
|
|
if (search) keyParts.push(`search:${search}`);
|
|
|
|
return keyParts.join(':');
|
|
},
|
|
|
|
async getProjects(params: Record<string, string | null> = {}) {
|
|
const key = this.generateProjectsKey(params);
|
|
return await cache.get(key);
|
|
},
|
|
|
|
async setProjects(params: Record<string, string | null> = {}, projects: unknown, ttlSeconds = 300) {
|
|
const key = this.generateProjectsKey(params);
|
|
return await cache.set(key, projects, ttlSeconds);
|
|
},
|
|
|
|
async getProject(id: number) {
|
|
return await cache.get(`api:project:${id}`);
|
|
},
|
|
|
|
async setProject(id: number, project: unknown, ttlSeconds = 300) {
|
|
return await cache.set(`api:project:${id}`, project, ttlSeconds);
|
|
},
|
|
|
|
async invalidateProject(id: number) {
|
|
await cache.del(`api:project:${id}`);
|
|
// Invalidate all project list caches
|
|
await this.invalidateAllProjectLists();
|
|
},
|
|
|
|
async invalidateAllProjectLists() {
|
|
// Clear all project list caches by pattern
|
|
// This is a simplified approach - in production you'd use Redis SCAN
|
|
const commonKeys = [
|
|
'api:projects',
|
|
'api:projects:pub:true',
|
|
'api:projects:feat:true:pub:true:limit:6',
|
|
'api:projects:page:1:limit:50',
|
|
'api:projects:pub:true:page:1:limit:50'
|
|
];
|
|
|
|
for (const key of commonKeys) {
|
|
await cache.del(key);
|
|
}
|
|
},
|
|
|
|
async invalidateAll() {
|
|
await this.invalidateAllProjectLists();
|
|
// Clear all project caches
|
|
const keys = await this.getAllProjectKeys();
|
|
for (const key of keys) {
|
|
await cache.del(key);
|
|
}
|
|
},
|
|
|
|
async getAllProjectKeys() {
|
|
// This would need to be implemented with Redis SCAN
|
|
// For now, we'll use a simple approach
|
|
return [];
|
|
}
|
|
};
|
|
|
|
// Performance metrics caching
|
|
export const performanceCache = {
|
|
async getMetrics(url: string) {
|
|
return await cache.get(`perf:${url}`);
|
|
},
|
|
|
|
async setMetrics(url: string, metrics: unknown, ttlSeconds = 600) {
|
|
return await cache.set(`perf:${url}`, metrics, ttlSeconds);
|
|
},
|
|
|
|
async getWebVitals() {
|
|
return await cache.get('perf:webvitals');
|
|
},
|
|
|
|
async setWebVitals(vitals: unknown, ttlSeconds = 300) {
|
|
return await cache.set('perf:webvitals', vitals, ttlSeconds);
|
|
}
|
|
};
|
|
|
|
// User session caching
|
|
export const userCache = {
|
|
async getSession(sessionId: string) {
|
|
return await cache.get(`user:session:${sessionId}`);
|
|
},
|
|
|
|
async setSession(sessionId: string, data: unknown, ttlSeconds = 86400) {
|
|
return await cache.set(`user:session:${sessionId}`, data, ttlSeconds);
|
|
},
|
|
|
|
async deleteSession(sessionId: string) {
|
|
return await cache.del(`user:session:${sessionId}`);
|
|
},
|
|
|
|
async getUserPreferences(userId: string) {
|
|
return await cache.get(`user:prefs:${userId}`);
|
|
},
|
|
|
|
async setUserPreferences(userId: string, prefs: unknown, ttlSeconds = 86400) {
|
|
return await cache.set(`user:prefs:${userId}`, prefs, ttlSeconds);
|
|
}
|
|
};
|