@tgomareli/macos-tools-mcp
Version:
MCP server for advanced macOS system monitoring and file search capabilities
104 lines • 2.95 kB
JavaScript
import NodeCache from "node-cache";
class PerformanceCache {
cache;
constructor(config) {
this.cache = new NodeCache({
stdTTL: config.stdTTL,
checkperiod: config.checkperiod,
maxKeys: config.maxKeys || 1000,
useClones: false,
});
}
async get(key, fetcher, ttl) {
const cached = this.cache.get(key);
if (cached !== undefined) {
return cached;
}
const data = await fetcher();
if (ttl !== undefined) {
this.cache.set(key, data, ttl);
}
else {
this.cache.set(key, data);
}
return data;
}
set(key, value, ttl) {
if (ttl !== undefined) {
return this.cache.set(key, value, ttl);
}
else {
return this.cache.set(key, value);
}
}
del(key) {
return this.cache.del(key);
}
flush() {
this.cache.flushAll();
}
getStats() {
return this.cache.getStats();
}
}
// Cache instances for different purposes
export const systemMetricsCache = new PerformanceCache({
stdTTL: 5, // 5 seconds for real-time metrics
checkperiod: 10,
});
export const processListCache = new PerformanceCache({
stdTTL: 3, // 3 seconds for process lists
checkperiod: 5,
});
export const searchIndexCache = new PerformanceCache({
stdTTL: 300, // 5 minutes for search results
checkperiod: 60,
maxKeys: 500,
});
export const fileTagsCache = new PerformanceCache({
stdTTL: 600, // 10 minutes for file tags
checkperiod: 120,
maxKeys: 2000,
});
// Helper to create cache key from complex objects
export function createCacheKey(prefix, params) {
const sortedKeys = Object.keys(params).sort();
const keyParts = sortedKeys
.filter(key => params[key] !== undefined)
.map(key => `${key}:${JSON.stringify(params[key])}`);
return `${prefix}:${keyParts.join(",")}`;
}
// Debounce helper for expensive operations
export function debounce(func, wait) {
let timeout = null;
return function (...args) {
if (timeout)
clearTimeout(timeout);
timeout = setTimeout(() => func(...args), wait);
};
}
// Rate limiter for API calls
export class RateLimiter {
requests = [];
maxRequests;
windowMs;
constructor(maxRequests, windowMs) {
this.maxRequests = maxRequests;
this.windowMs = windowMs;
}
async checkLimit() {
const now = Date.now();
this.requests = this.requests.filter(time => now - time < this.windowMs);
if (this.requests.length >= this.maxRequests) {
return false;
}
this.requests.push(now);
return true;
}
async waitForSlot() {
while (!(await this.checkLimit())) {
await new Promise(resolve => setTimeout(resolve, 100));
}
}
}
//# sourceMappingURL=cache.js.map