UNPKG

limitless-ai-mcp-server

Version:

MCP server for integrating Limitless AI Pendant recordings with AI assistants

151 lines 4.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.searchCache = exports.lifelogArrayCache = exports.lifelogCache = exports.LRUCache = void 0; exports.buildLifelogCacheKey = buildLifelogCacheKey; exports.buildDateCacheKey = buildDateCacheKey; exports.buildSearchCacheKey = buildSearchCacheKey; exports.buildRecentCacheKey = buildRecentCacheKey; const logger_1 = require("../utils/logger"); class LRUCache { cache; options; _stats; constructor(options = {}) { this.options = { maxSize: options.maxSize || 100, ttl: options.ttl || 5 * 60 * 1000, // 5 minutes default onEvict: options.onEvict || (() => { }), }; this.cache = new Map(); this._stats = { hits: 0, misses: 0, evictions: 0, size: 0, maxSize: this.options.maxSize, }; logger_1.logger.info('LRU cache initialized', { maxSize: this.options.maxSize, ttl: this.options.ttl, }); } get(key) { const entry = this.cache.get(key); if (!entry) { this._stats.misses++; logger_1.logger.debug('Cache miss', { key }); return undefined; } // Check if entry is expired if (this.isExpired(entry)) { this.delete(key); this._stats.misses++; logger_1.logger.debug('Cache entry expired', { key }); return undefined; } // Move to end (most recently used) this.cache.delete(key); entry.hits++; this.cache.set(key, entry); this._stats.hits++; logger_1.logger.debug('Cache hit', { key, hits: entry.hits }); return entry.data; } set(key, value) { // Delete existing entry if present if (this.cache.has(key)) { this.cache.delete(key); } else { this._stats.size++; } // Check if we need to evict if (this.cache.size >= this.options.maxSize) { this.evictOldest(); } const entry = { data: value, timestamp: Date.now(), hits: 0, }; this.cache.set(key, entry); logger_1.logger.debug('Cache set', { key, size: this.cache.size }); } has(key) { const entry = this.cache.get(key); if (!entry) return false; if (this.isExpired(entry)) { this.delete(key); return false; } return true; } delete(key) { const existed = this.cache.delete(key); if (existed) { this._stats.size--; logger_1.logger.debug('Cache entry deleted', { key }); } return existed; } clear() { const size = this.cache.size; this.cache.clear(); this._stats.size = 0; logger_1.logger.info('Cache cleared', { entriesCleared: size }); } size() { return this.cache.size; } stats() { return { ...this._stats }; } isExpired(entry) { return Date.now() - entry.timestamp > this.options.ttl; } evictOldest() { const firstKey = this.cache.keys().next().value; if (firstKey !== undefined) { const entry = this.cache.get(firstKey); this.cache.delete(firstKey); this._stats.evictions++; this._stats.size--; if (entry) { this.options.onEvict(firstKey, entry); } logger_1.logger.debug('Cache entry evicted', { key: firstKey }); } } } exports.LRUCache = LRUCache; // Global cache instances exports.lifelogCache = new LRUCache({ maxSize: parseInt(process.env.CACHE_MAX_SIZE || '100'), ttl: parseInt(process.env.CACHE_TTL || String(5 * 60 * 1000)), // 5 minutes }); exports.lifelogArrayCache = new LRUCache({ maxSize: parseInt(process.env.CACHE_MAX_SIZE || '100'), ttl: parseInt(process.env.CACHE_TTL || String(5 * 60 * 1000)), // 5 minutes }); exports.searchCache = new LRUCache({ maxSize: parseInt(process.env.SEARCH_CACHE_MAX_SIZE || '50'), ttl: parseInt(process.env.SEARCH_CACHE_TTL || String(3 * 60 * 1000)), // 3 minutes }); // Cache key builders function buildLifelogCacheKey(id) { return `lifelog:${id}`; } function buildDateCacheKey(date, options) { const optStr = options ? JSON.stringify(options) : ''; return `date:${date}:${optStr}`; } function buildSearchCacheKey(searchTerm, options) { const optStr = options ? JSON.stringify(options) : ''; return `search:${searchTerm}:${optStr}`; } function buildRecentCacheKey(options) { const optStr = options ? JSON.stringify(options) : ''; return `recent:${optStr}`; } //# sourceMappingURL=cache.js.map