/** * Cache Manager * * High-level cache operations for different data types. * Provides typed access to update results, MC versions, etc. */ import type { CacheConfig, CacheLoadResult, CachedSourceMetadata, CachedUpdateResult, FailedDownloadsCache, MinecraftVersionsCache, ServerJarVersionsCache, SourceMetadataCache, UpdateResultsCache } from './types.js'; import { CACHE_ENTRIES } from './types.js'; /** * Cache manager class */ export declare class CacheManager { private storage; private config; /** * Per-entry write chains serializing read-modify-write cycles. * See {@link withWriteLock}. */ private writeChains; constructor(config?: Partial); /** * Serialize writes to a cache entry through an in-process promise chain. * * Every mutator in this class is load → mutate → save-whole-file; without * serialization, concurrent writers (e.g. `downloadBatch` running 2-5 * downloads, each calling `updatePluginResult` + `clearDownloadFailure`) * interleave reads and silently lose each other's updates (June 9 2026 * audit, workflows-infra 5.2). Cross-process coordination is handled * separately (see infrastructure/process-lock.ts); in production a single * `getCacheManager()` singleton funnels all writers through this chain. * * A rejected operation does not poison the chain — the stored link always * settles resolved. */ private withWriteLock; /** * Get cached update results */ getUpdateResults(): Promise>; /** * Get a single plugin's cached update result */ getPluginUpdateResult(pluginName: string): Promise<{ result: CachedUpdateResult | null; isFresh: boolean; lastChecked: string | null; }>; /** * Save update results, REPLACING the whole results map. * * Destructive by design — entries absent from `results` are dropped. Only * use when `results` is the complete intended cache state (e.g. test * seeding). Partial check runs must use {@link mergeUpdateResults}: a * sourceType-filtered or mostly-cache-hit run otherwise wipes every entry * it didn't re-check (June 9 2026 audit, workflows-infra 5.1). */ saveUpdateResults(results: Record): Promise; /** * Merge freshly-checked results into the cached map (merge-by-plugin). * * Entries for plugins NOT in `results` survive — partial check runs * (cache hits, sourceType filters, enabledOnly) must call this so the * stale-cache fallback keeps working for everything they skipped. */ mergeUpdateResults(results: Record): Promise; /** * Update a single plugin's cached result (merge with existing) */ updatePluginResult(pluginName: string, result: CachedUpdateResult): Promise; /** * Write the results map to storage. Callers must hold the UPDATE_RESULTS * write lock (see {@link withWriteLock}). */ private writeUpdateResults; /** * Check if update results cache is fresh */ isUpdateResultsFresh(): Promise; /** * Get cached Minecraft versions */ getMinecraftVersions(): Promise>; /** * Save Minecraft versions */ saveMinecraftVersions(versions: string[]): Promise; /** * Check if MC versions cache is fresh */ isMinecraftVersionsFresh(): Promise; /** * Get cached source metadata */ getSourceMetadata(): Promise>; /** * Get a single source's cached metadata */ getSourceMetadataEntry(cacheKey: string): Promise; /** * Save source metadata entry */ saveSourceMetadataEntry(cacheKey: string, metadata: CachedSourceMetadata): Promise; /** * Get cached server JAR versions */ getServerJarVersions(): Promise>; /** * Get versions for a specific server type */ getServerJarVersionsFor(serverType: string): Promise<{ versions: string[] | null; isFresh: boolean; fetchedAt: string | null; }>; /** * Save server JAR versions for a specific server type */ saveServerJarVersions(serverType: string, versions: string[]): Promise; /** * Get failed downloads cache */ getFailedDownloads(): Promise>; /** * Get all plugin names that have failed downloads */ getFailedDownloadNames(): Promise>; /** * Check if a plugin has a failed download */ hasFailedDownload(pluginName: string): Promise; /** * Record a download failure */ recordDownloadFailure(pluginName: string, errorMessage: string, statusCode?: number): Promise; /** * Clear a download failure (e.g., after successful download or source change) */ clearDownloadFailure(pluginName: string): Promise; /** * Clear all caches */ clearAll(): Promise; /** * Delete a specific cache entry by name */ clearEntry(entryName: keyof typeof CACHE_ENTRIES): Promise; /** * Get cache statistics */ getStats(): Promise<{ entryCount: number; entries: Array<{ name: string; updatedAt: string; ageMs: number; isFresh: boolean; ttlMs: number; }>; }>; /** * Format age for display (e.g., "5 minutes ago", "2 hours ago") */ static formatAge(ageMs: number): string; } /** * Get or create the global cache manager instance */ export declare function getCacheManager(config?: Partial): CacheManager; /** * Reset the global cache manager (mainly for testing) */ export declare function resetCacheManager(): void; //# sourceMappingURL=manager.d.ts.map