/** * Unified Discovery Cache (CLOUD-008) * * A unified caching layer for all discovery modules that provides: * - Pluggable backends: in-memory (default) and Redis (optional) * - Tenant isolation via cache key prefixes * - LRU eviction with configurable max size * - Failed domain tracking with exponential backoff cooldown * - Type-safe cache entries with automatic TTL expiration * * This replaces the individual in-memory Maps in each discovery module: * - openapi-discovery.ts (specCache) * - robots-sitemap-discovery.ts (discoveryCache) * - asyncapi-discovery.ts (specCache) * - alt-spec-discovery.ts (specCache) * - backend-framework-fingerprinting.ts (frameworkCache) * - api-documentation-discovery.ts (discoveryCache) */ /** * Cache entry wrapper with metadata */ export interface CacheEntry { /** The cached value */ value: T; /** When the entry was cached (Unix timestamp ms) */ cachedAt: number; /** When the entry expires (Unix timestamp ms) */ expiresAt: number; /** Number of times this entry has been accessed */ hitCount: number; /** Last access time for LRU eviction */ lastAccessedAt: number; } /** * Failed domain tracking entry */ export interface FailedDomain { /** Domain that failed */ domain: string; /** Discovery source that failed (e.g., 'openapi', 'asyncapi') */ source: string; /** Number of consecutive failures */ failureCount: number; /** First failure timestamp */ firstFailureAt: number; /** Last failure timestamp */ lastFailureAt: number; /** When the cooldown expires and retry is allowed */ cooldownUntil: number; /** Last error message */ lastError?: string; } /** * Discovery cache configuration */ export interface DiscoveryCacheConfig { /** Maximum number of entries per source type */ maxEntriesPerSource?: number; /** Default TTL in milliseconds */ defaultTtlMs?: number; /** Tenant ID for multi-tenant isolation */ tenantId?: string; /** Base cooldown time for failed domains (ms) */ baseCooldownMs?: number; /** Maximum cooldown time for failed domains (ms) */ maxCooldownMs?: number; /** Enable Redis backend if available */ useRedis?: boolean; } /** * Cache statistics */ export interface DiscoveryCacheStats { /** Number of entries by source */ entriesBySource: Record; /** Total entries across all sources */ totalEntries: number; /** Number of failed domains being tracked */ failedDomains: number; /** Hit rate since last reset */ hitRate: number; /** Total hits */ hits: number; /** Total misses */ misses: number; /** Backend type in use */ backend: 'memory' | 'redis'; } /** * Backend interface for pluggable storage */ export interface CacheBackend { get(key: string): Promise | null>; set(key: string, entry: CacheEntry): Promise; delete(key: string): Promise; clear(prefix?: string): Promise; keys(prefix?: string): Promise; size(prefix?: string): Promise; } /** Discovery source types */ export type DiscoverySource = 'openapi' | 'asyncapi' | 'alt-spec' | 'robots-sitemap' | 'backend-framework' | 'docs-page' | 'graphql' | 'links'; /** * Unified discovery cache with pluggable backends */ export declare class DiscoveryCache { private backend; private config; private failedDomains; private hits; private misses; private backendType; constructor(config?: DiscoveryCacheConfig); /** * Initialize Redis backend if available and configured */ initializeRedis(redis: import('ioredis').default): Promise; /** * Build cache key with source and tenant isolation */ private buildKey; /** * Build failed domain key */ private buildFailedKey; /** * Get cached discovery result */ get(source: DiscoverySource, domain: string): Promise; /** * Store discovery result in cache */ set(source: DiscoverySource, domain: string, value: T, ttlMs?: number): Promise; /** * Delete cached entry */ delete(source: DiscoverySource, domain: string): Promise; /** * Clear cache for a specific source or all sources */ clear(source?: DiscoverySource): Promise; /** * LRU eviction to enforce max entries per source */ private enforceMaxEntries; /** * Check if a domain is in cooldown after failures */ isInCooldown(source: DiscoverySource, domain: string): boolean; /** * Get cooldown info for a domain */ getCooldownInfo(source: DiscoverySource, domain: string): FailedDomain | null; /** * Record a discovery failure for a domain */ recordFailure(source: DiscoverySource, domain: string, error?: string): void; /** * Clear failed domain tracking (on success) */ clearFailedDomain(source: DiscoverySource, domain: string): void; /** * Get all failed domains */ getFailedDomains(): FailedDomain[]; /** * Get cache statistics */ getStats(): Promise; /** * Reset statistics */ resetStats(): void; /** * Wrapper for cached discovery operations */ withCache(source: DiscoverySource, domain: string, discoveryFn: () => Promise, options?: { ttlMs?: number; skipCooldownCheck?: boolean; }): Promise; } /** * Get or create the global discovery cache */ export declare function getDiscoveryCache(config?: DiscoveryCacheConfig): DiscoveryCache; /** * Create a new discovery cache (for testing or multi-tenant scenarios) */ export declare function createDiscoveryCache(config?: DiscoveryCacheConfig): DiscoveryCache; /** * Reset the global cache (for testing) */ export declare function resetGlobalDiscoveryCache(): void; //# sourceMappingURL=discovery-cache.d.ts.map