Skip to main content
Glama

NodeJS API Docs MCP Server

by lirantal
cache-service.ts3.17 kB
import { initLogger, type Logger } from '../utils/logger.ts' interface CacheEntry<T> { data: T expiresAt: number } interface CacheOptions { ttlDays?: number } export class CacheService { private logger: Logger private cache: Map<string, CacheEntry<any>> constructor () { this.logger = initLogger() this.cache = new Map() } /** * Fetches data with caching. If cached data exists and hasn't expired, returns it. * Otherwise, fetches fresh data using the provided fetcher function. */ async fetchWithCache<T>( key: string, fetcher: () => Promise<T>, options: CacheOptions = {} ): Promise<T> { const { ttlDays = 7 } = options const now = Date.now() // Check if we have valid cached data const cached = this.cache.get(key) if (cached && cached.expiresAt > now) { this.logger.info({ msg: `Cache hit for key: ${key}` }) return cached.data } // Cache miss or expired - fetch fresh data this.logger.info({ msg: `Cache miss for key: ${key}, fetching fresh data...` }) try { const data = await fetcher() // Calculate expiration time const expiresAt = now + (ttlDays * 24 * 60 * 60 * 1000) // Store in cache this.cache.set(key, { data, expiresAt }) this.logger.info({ msg: `Cached data for key: ${key}`, expiresAt: new Date(expiresAt).toISOString(), ttlDays }) return data } catch (error) { this.logger.error({ err: error, msg: `Failed to fetch data for key: ${key}` }) throw error } } /** * Convenience method for fetching HTTP resources with caching */ async fetchHttpWithCache ( url: string, options: CacheOptions & { responseType?: 'json' | 'text' } = {} ): Promise<any> { const { responseType = 'json', ...cacheOptions } = options return this.fetchWithCache( url, async () => { this.logger.info({ msg: `Fetching HTTP resource: ${url}` }) const response = await fetch(url) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status} ${response.statusText}`) } const data = responseType === 'json' ? await response.json() : await response.text() this.logger.info({ msg: `Successfully fetched HTTP resource: ${url}` }) return data }, cacheOptions ) } /** * Clear a specific cache entry */ clearCache (key: string): void { this.cache.delete(key) this.logger.info({ msg: `Cleared cache for key: ${key}` }) } /** * Clear all expired cache entries */ clearExpiredCache (): void { const now = Date.now() let clearedCount = 0 for (const [key, entry] of this.cache.entries()) { if (entry.expiresAt <= now) { this.cache.delete(key) clearedCount++ } } if (clearedCount > 0) { this.logger.info({ msg: `Cleared ${clearedCount} expired cache entries` }) } } /** * Get cache statistics */ getCacheStats (): { size: number; keys: string[] } { return { size: this.cache.size, keys: Array.from(this.cache.keys()) } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lirantal/mcp-server-nodejs-api-docs'

If you have feedback or need assistance with the MCP directory API, please join our Discord server