UNPKG

vibe-coder-mcp

Version:

Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.

180 lines (179 loc) 6.87 kB
import path from 'path'; import logger from '../../../logger.js'; import { FileCache } from './fileCache.js'; import { TieredCache } from './tieredCache.js'; import { getCacheDirectory } from '../directoryUtils.js'; const cacheInstances = new Map(); export function createCacheManager(config) { const cacheDir = getCacheDirectory(config); async function getFileCache(name, options) { if (cacheInstances.has(name)) { const cache = cacheInstances.get(name); if (cache instanceof FileCache) { return cache; } else { throw new Error(`Cache ${name} exists but is not a FileCache`); } } const cacheOptions = { name, cacheDir: path.join(cacheDir, name), maxEntries: options?.maxEntries || config.cache?.maxEntries, maxAge: options?.maxAge || config.cache?.maxAge, validateOnGet: options?.validateOnGet, pruneOnStartup: options?.pruneOnStartup, pruneInterval: options?.pruneInterval, serialize: options?.serialize, deserialize: options?.deserialize, }; const cache = new FileCache(cacheOptions); await cache.init(); cacheInstances.set(name, cache); logger.debug(`Created file cache instance: ${name}`); return cache; } async function getTieredCache(name, options) { if (cacheInstances.has(name)) { const cache = cacheInstances.get(name); if (cache instanceof TieredCache) { return cache; } else { throw new Error(`Cache ${name} exists but is not a TieredCache`); } } const cacheOptions = { name, cacheDir: path.join(cacheDir, name), maxEntries: options?.maxEntries || config.cache?.maxEntries, maxAge: options?.maxAge || config.cache?.maxAge, validateOnGet: options?.validateOnGet, pruneOnStartup: options?.pruneOnStartup, pruneInterval: options?.pruneInterval, serialize: options?.serialize, deserialize: options?.deserialize, useMemoryCache: options?.useMemoryCache ?? config.cache?.useMemoryCache ?? true, memoryMaxEntries: options?.memoryMaxEntries, memoryMaxAge: options?.memoryMaxAge, memoryThreshold: options?.memoryThreshold, memorySizeCalculator: options?.memorySizeCalculator }; const cache = new TieredCache(cacheOptions); await cache.init(); cacheInstances.set(name, cache); logger.debug(`Created tiered cache instance: ${name}`); return cache; } async function getCache(name, options) { return getFileCache(name, options); } async function clearCache(name) { const cache = cacheInstances.get(name); if (cache) { await cache.clear(); logger.debug(`Cleared cache: ${name}`); } } async function clearAllCaches() { const clearPromises = Array.from(cacheInstances.entries()).map(async ([name, cache]) => { await cache.clear(); logger.debug(`Cleared cache: ${name}`); }); await Promise.all(clearPromises); logger.info(`Cleared all caches (${cacheInstances.size} instances)`); } async function pruneCache(name) { const cache = cacheInstances.get(name); if (cache) { const prunedCount = await cache.prune(); logger.debug(`Pruned ${prunedCount} entries from cache: ${name}`); return prunedCount; } return 0; } async function pruneAllCaches() { let totalPruned = 0; const prunePromises = Array.from(cacheInstances.entries()).map(async ([name, cache]) => { const prunedCount = await cache.prune(); logger.debug(`Pruned ${prunedCount} entries from cache: ${name}`); return prunedCount; }); const results = await Promise.all(prunePromises); totalPruned = results.reduce((total, count) => total + count, 0); logger.info(`Pruned ${totalPruned} entries from all caches (${cacheInstances.size} instances)`); return totalPruned; } async function getCacheStats(name) { const cache = cacheInstances.get(name); if (cache) { const stats = cache.getStats(); return stats instanceof Promise ? await stats : stats; } return undefined; } async function getAllCacheStats() { const stats = {}; for (const [name, cache] of cacheInstances.entries()) { const cacheStats = cache.getStats(); stats[name] = cacheStats instanceof Promise ? await cacheStats : cacheStats; } return stats; } function closeAllCaches() { for (const [name, cache] of cacheInstances.entries()) { cache.close(); logger.debug(`Closed cache: ${name}`); } cacheInstances.clear(); logger.info('Closed all cache instances'); } return { getCache, getFileCache, getTieredCache, clearCache, clearAllCaches, pruneCache, pruneAllCaches, getCacheStats, getAllCacheStats, closeAllCaches, }; } export async function clearAllCaches() { const clearPromises = Array.from(cacheInstances.entries()).map(async ([name, cache]) => { await cache.clear(); logger.debug(`Cleared cache: ${name}`); }); await Promise.all(clearPromises); logger.info(`Cleared all caches (${cacheInstances.size} instances)`); } export async function pruneAllCaches() { let totalPruned = 0; const prunePromises = Array.from(cacheInstances.entries()).map(async ([name, cache]) => { const prunedCount = await cache.prune(); logger.debug(`Pruned ${prunedCount} entries from cache: ${name}`); return prunedCount; }); const results = await Promise.all(prunePromises); totalPruned = results.reduce((total, count) => total + count, 0); logger.info(`Pruned ${totalPruned} entries from all caches (${cacheInstances.size} instances)`); return totalPruned; } export async function getCacheStats() { const stats = {}; for (const [name, cache] of cacheInstances.entries()) { const cacheStats = cache.getStats(); stats[name] = cacheStats instanceof Promise ? await cacheStats : cacheStats; } return stats; } export function closeAllCaches() { for (const [name, cache] of cacheInstances.entries()) { cache.close(); logger.debug(`Closed cache: ${name}`); } cacheInstances.clear(); logger.info('Closed all cache instances'); }