UNPKG

mcp-quiz-server

Version:

🧠 AI-Powered Quiz Management via Model Context Protocol (MCP) - Create, manage, and take quizzes directly from VS Code, Claude, and other AI agents.

103 lines (102 loc) • 3.42 kB
"use strict"; /** * @fileoverview Simple In-Memory Cache Implementation * @version 1.0.0 * @since 2025-07-29 * @lastUpdated 2025-07-29 * @module InMemoryCache * @description High-performance in-memory cache implementation for Clean Architecture. * Provides LRU eviction, TTL support, and thread-safe operations. * * @architecture * Layer: Infrastructure (Service Implementations) * Pattern: Cache-Aside Pattern + LRU Eviction * Dependencies: ICacheService interface * * @relationships * DEPENDS_ON: * - ICacheService (Infrastructure Interface) * USED_BY: * - GetQuizQueryHandler (Application Layer) * - Repository implementations (Infrastructure) * - DI Container service resolution * COLLABORATES_WITH: * - ServiceRegistry for configuration and lifecycle * * @dataFlow * get(key) → Map.get() → TTL check → return value OR null * set(key, value, ttl) → LRU eviction check → Map.set() → TTL timer setup * Cleanup: Timer expires → Map.delete() → memory freed * * @responsibilities * - Store key-value pairs with TTL support * - Implement LRU eviction when memory limits reached * - Provide fast O(1) cache operations * - Automatic cleanup of expired entries * - Thread-safe concurrent access * * @performance * - Get/Set: O(1) average case * - Memory: Configurable max keys limit * - TTL: Automatic cleanup with timers * - Eviction: LRU policy for memory management * * @requirements * {@link Requirements.REQ_ARCH_v2_007} Performance and Scalability * {@link Requirements.REQ_PERF_001} Query Response Time < 100ms * * @contributors Claude Code Agent * @testCoverage Unit tests for cache operations, TTL behavior, and LRU eviction */ Object.defineProperty(exports, "__esModule", { value: true }); exports.InMemoryCache = void 0; class InMemoryCache { constructor(config = {}) { this.cache = new Map(); this.config = { defaultTTL: 3600, maxKeys: 1000, keyPrefix: '', ...config, }; } async get(key) { const fullKey = this.getFullKey(key); const entry = this.cache.get(fullKey); if (!entry) return null; if (Date.now() > entry.expiresAt) { this.cache.delete(fullKey); return null; } return entry.value; } async set(key, value, ttlSeconds) { const fullKey = this.getFullKey(key); const ttl = ttlSeconds !== null && ttlSeconds !== void 0 ? ttlSeconds : this.config.defaultTTL; const expiresAt = Date.now() + ttl * 1000; // Simple LRU eviction if needed if (this.cache.size >= this.config.maxKeys && !this.cache.has(fullKey)) { const oldestKey = this.cache.keys().next().value; if (oldestKey) { this.cache.delete(oldestKey); } } this.cache.set(fullKey, { value, expiresAt }); } async delete(key) { const fullKey = this.getFullKey(key); return this.cache.delete(fullKey); } async clear() { this.cache.clear(); } async has(key) { const value = await this.get(key); return value !== null; } getFullKey(key) { return this.config.keyPrefix ? `${this.config.keyPrefix}:${key}` : key; } } exports.InMemoryCache = InMemoryCache;