import { CacheHandler, CacheHandlerValue, CacheHandlerContext } from "next/dist/server/lib/incremental-cache"; import type { IncrementalCacheValue, GetIncrementalFetchCacheContext, GetIncrementalResponseCacheContext, SetIncrementalFetchCacheContext, SetIncrementalResponseCacheContext } from "next/dist/server/response-cache"; /** * Orchestrator cache handler that conditionally instantiates handlers based on environment */ export default class CdkNextjsCacheHandler implements CacheHandler { /** * Shared singleton handlers for runtime. * * Next.js creates multiple cache handler instances (one each for APP_PAGE, APP_ROUTE, FETCH, etc). * Using singleton pattern provides: * - Single S3 client connection pool shared across all cache types * - Unified memory cache accessible by all instances (cache hits benefit all) * - Lower memory footprint and faster initialization * - Same CacheHandlerContext for all instances, so no configuration loss */ private static sharedMemoryHandler; private static sharedS3DynamoHandler; private readonly isBuildTime; private readonly debug; private localFileHandler; private memoryHandler; private s3DynamoHandler; constructor(options: CacheHandlerContext); /** * Get cache entry * - Build time: Not implemented (build doesn't read cache) * - Runtime: Try memory first, then S3/DynamoDB */ get(cacheKey: string, ctx: GetIncrementalFetchCacheContext | GetIncrementalResponseCacheContext): Promise; /** * Set cache entry * - Build time: Write to local file cache only (or delete if data is null) * - Runtime: Write to both memory and S3/DynamoDB (or delete if data is null) */ set(cacheKey: string, data: IncrementalCacheValue | null, ctx: SetIncrementalFetchCacheContext | SetIncrementalResponseCacheContext): Promise; /** * Revalidate tags * - Build time: Not implemented * - Runtime: Delegate to S3/DynamoDB handler */ revalidateTag(tag: string): Promise; /** * Reset request cache (called between requests) */ resetRequestCache(): Promise; }