UNPKG

apple-dev-mcp

Version:

Complete Apple development guidance: Human Interface Guidelines (design) + Technical Documentation for iOS, macOS, watchOS, tvOS, and visionOS

148 lines 4 kB
/** * Content caching layer with TTL and graceful degradation */ import NodeCache from 'node-cache'; export class HIGCache { cache; defaultTTL; constructor(defaultTTL = 3600) { this.cache = new NodeCache({ stdTTL: defaultTTL, checkperiod: 600, // Check for expired keys every 10 minutes useClones: false }); this.defaultTTL = defaultTTL; } /** * Set a cache entry with custom TTL */ set(key, data, ttl) { const entry = { data, timestamp: new Date(), ttl: ttl || this.defaultTTL }; return this.cache.set(key, entry, ttl || this.defaultTTL); } /** * Get a cache entry */ get(key) { const entry = this.cache.get(key); if (!entry) { return null; } return entry.data; } /** * Get a cache entry with metadata */ getWithMetadata(key) { return this.cache.get(key) || null; } /** * Check if a key exists and is not expired */ has(key) { return this.cache.has(key); } /** * Delete a cache entry */ delete(key) { return this.cache.del(key); } /** * Clear all cache entries */ clear() { this.cache.flushAll(); } /** * Get cache statistics */ getStats() { return this.cache.getStats(); } /** * Get all keys in cache */ getKeys() { return this.cache.keys(); } /** * Check if cached data is stale (expired but available for graceful degradation) */ isStale(key) { const entry = this.cache.get(key); if (!entry) { return false; } const now = Date.now(); const entryAge = now - entry.timestamp.getTime(); return entryAge > (entry.ttl * 1000); } /** * Get stale data for graceful degradation * Returns data even if expired, useful when fresh data fetch fails */ getStale(key) { // First try to get non-expired data const fresh = this.get(key); if (fresh) { return fresh; } // If no fresh data, try to get from internal cache even if expired const allData = this.cache.keys().map(k => ({ key: k, value: this.cache.get(k) })); const staleEntry = allData.find(item => item.key === key); return staleEntry?.value?.data || null; } /** * Set cache entry that persists longer for graceful degradation */ setWithGracefulDegradation(key, data, normalTTL, gracefulTTL) { const ttl = normalTTL || this.defaultTTL; const graceTTL = gracefulTTL || (ttl * 24); // Keep stale data 24x longer // Set the normal cache entry const normalResult = this.set(key, data, ttl); // Also set a backup entry with longer TTL for graceful degradation const backupKey = `${key}:backup`; const backupResult = this.set(backupKey, data, graceTTL); return normalResult && backupResult; } /** * Get data with graceful degradation fallback */ getWithGracefulFallback(key) { // Try to get fresh data first const freshData = this.get(key); if (freshData) { return { data: freshData, isStale: false }; } // Try to get backup data if fresh data is not available const backupKey = `${key}:backup`; const staleData = this.get(backupKey); return { data: staleData, isStale: staleData !== null }; } /** * Preload cache with critical data */ preload(entries) { entries.forEach(entry => { this.set(entry.key, entry.data, entry.ttl); }); } /** * Clean up cache resources */ destroy() { this.cache.close(); } } //# sourceMappingURL=cache.js.map