Added content processing system

This commit is contained in:
adilallo
2025-09-04 10:49:48 -06:00
parent 3d6d4ed251
commit b54ddb16ba
5 changed files with 1192 additions and 77 deletions
+240
View File
@@ -0,0 +1,240 @@
/**
* Content caching utilities for improved performance
*/
// In-memory cache for blog posts
const blogPostCache = new Map();
const blogListCache = new Map();
const tagCache = new Map();
const authorCache = new Map();
// Cache configuration
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes in milliseconds
const MAX_CACHE_SIZE = 100; // Maximum number of cached items
/**
* Cache entry with timestamp
*/
class CacheEntry {
constructor(data) {
this.data = data;
this.timestamp = Date.now();
}
isExpired() {
return Date.now() - this.timestamp > CACHE_TTL;
}
}
/**
* Get cached blog post data
* @param {string} key - Cache key
* @returns {Object|null} Cached data or null if not found/expired
*/
function getCached(key) {
const entry = blogPostCache.get(key);
if (!entry || entry.isExpired()) {
blogPostCache.delete(key);
return null;
}
return entry.data;
}
/**
* Set cached blog post data
* @param {string} key - Cache key
* @param {Object} data - Data to cache
*/
function setCached(key, data) {
// Implement LRU eviction if cache is full
if (blogPostCache.size >= MAX_CACHE_SIZE) {
const oldestKey = blogPostCache.keys().next().value;
blogPostCache.delete(oldestKey);
}
blogPostCache.set(key, new CacheEntry(data));
}
/**
* Clear expired cache entries
*/
function clearExpiredCache() {
for (const [key, entry] of blogPostCache.entries()) {
if (entry.isExpired()) {
blogPostCache.delete(key);
}
}
}
/**
* Clear all caches
*/
export function clearAllCaches() {
blogPostCache.clear();
blogListCache.clear();
tagCache.clear();
authorCache.clear();
}
/**
* Get cached blog post by slug
* @param {string} slug - Blog post slug
* @returns {Object|null} Cached blog post or null
*/
export function getCachedBlogPost(slug) {
return getCached(`post:${slug}`);
}
/**
* Cache blog post data
* @param {string} slug - Blog post slug
* @param {Object} postData - Blog post data
*/
export function cacheBlogPost(slug, postData) {
setCached(`post:${slug}`, postData);
}
/**
* Get cached blog post list
* @param {string} key - Cache key for list (e.g., 'all', 'recent', 'tag:governance')
* @returns {Array|null} Cached list or null
*/
export function getCachedBlogList(key) {
const entry = blogListCache.get(key);
if (!entry || entry.isExpired()) {
blogListCache.delete(key);
return null;
}
return entry.data;
}
/**
* Cache blog post list
* @param {string} key - Cache key
* @param {Array} listData - List data to cache
*/
export function cacheBlogList(key, listData) {
blogListCache.set(key, new CacheEntry(listData));
}
/**
* Get cached tags
* @returns {Array|null} Cached tags or null
*/
export function getCachedTags() {
const entry = tagCache.get("all");
if (!entry || entry.isExpired()) {
tagCache.delete("all");
return null;
}
return entry.data;
}
/**
* Cache tags
* @param {Array} tags - Tags to cache
*/
export function cacheTags(tags) {
tagCache.set("all", new CacheEntry(tags));
}
/**
* Get cached authors
* @returns {Array|null} Cached authors or null
*/
export function getCachedAuthors() {
const entry = authorCache.get("all");
if (!entry || entry.isExpired()) {
authorCache.delete("all");
return null;
}
return entry.data;
}
/**
* Cache authors
* @param {Array} authors - Authors to cache
*/
export function cacheAuthors(authors) {
authorCache.set("all", new CacheEntry(authors));
}
/**
* Invalidate cache for a specific blog post
* @param {string} slug - Blog post slug
*/
export function invalidateBlogPostCache(slug) {
blogPostCache.delete(`post:${slug}`);
// Also invalidate list caches since they might contain this post
blogListCache.clear();
}
/**
* Invalidate all caches
*/
export function invalidateAllCaches() {
clearAllCaches();
}
/**
* Get cache statistics
* @returns {Object} Cache statistics
*/
export function getCacheStats() {
clearExpiredCache();
return {
blogPostCacheSize: blogPostCache.size,
blogListCacheSize: blogListCache.size,
tagCacheSize: tagCache.size,
authorCacheSize: authorCache.size,
totalCacheSize:
blogPostCache.size + blogListCache.size + tagCache.size + authorCacheSize,
maxCacheSize: MAX_CACHE_SIZE,
cacheTTL: CACHE_TTL,
};
}
/**
* Warm up cache with frequently accessed data
* @param {Function} getAllPosts - Function to get all blog posts
* @param {Function} getAllTags - Function to get all tags
*/
export async function warmCache(getAllPosts, getAllTags) {
try {
// Cache all blog posts
const allPosts = getAllPosts();
cacheBlogList("all", allPosts);
// Cache recent posts
const recentPosts = allPosts.slice(0, 5);
cacheBlogList("recent", recentPosts);
// Cache tags
const tags = getAllTags();
cacheTags(tags);
// Cache individual posts (first 10)
allPosts.slice(0, 10).forEach((post) => {
cacheBlogPost(post.slug, post);
});
console.log("Cache warmed up successfully");
} catch (error) {
console.error("Error warming up cache:", error);
}
}
/**
* Check if cache is healthy
* @returns {boolean} True if cache is healthy
*/
export function isCacheHealthy() {
try {
clearExpiredCache();
return blogPostCache.size < MAX_CACHE_SIZE;
} catch (error) {
console.error("Cache health check failed:", error);
return false;
}
}