{"version":3,"sources":["../../../../../src/server/lib/incremental-cache/file-system-cache.ts"],"sourcesContent":["import type { RouteMetadata } from '../../../export/routes/types'\nimport type { CacheHandler, CacheHandlerContext, CacheHandlerValue } from '.'\nimport type { CacheFs } from '../../../shared/lib/utils'\nimport type { TagManifestEntry } from './tags-manifest.external'\nimport {\n  CachedRouteKind,\n  IncrementalCacheKind,\n  type CachedFetchValue,\n  type IncrementalCacheValue,\n  type SetIncrementalFetchCacheContext,\n  type SetIncrementalResponseCacheContext,\n} from '../../response-cache'\n\nimport type { LRUCache } from '../lru-cache'\nimport path from '../../../shared/lib/isomorphic/path'\nimport {\n  NEXT_CACHE_TAGS_HEADER,\n  NEXT_DATA_SUFFIX,\n  NEXT_META_SUFFIX,\n  RSC_SEGMENT_SUFFIX,\n  RSC_SEGMENTS_DIR_SUFFIX,\n  RSC_SUFFIX,\n} from '../../../lib/constants'\nimport { areTagsExpired, tagsManifest } from './tags-manifest.external'\nimport { MultiFileWriter } from '../../../lib/multi-file-writer'\nimport { getMemoryCache } from './memory-cache.external'\n\ntype FileSystemCacheContext = Omit<\n  CacheHandlerContext,\n  'fs' | 'serverDistDir'\n> & {\n  fs: CacheFs\n  serverDistDir: string\n}\n\nexport default class FileSystemCache implements CacheHandler {\n  private fs: FileSystemCacheContext['fs']\n  private flushToDisk?: FileSystemCacheContext['flushToDisk']\n  private serverDistDir: FileSystemCacheContext['serverDistDir']\n  private revalidatedTags: string[]\n  private static debug: boolean = !!process.env.NEXT_PRIVATE_DEBUG_CACHE\n  private static memoryCache: LRUCache<CacheHandlerValue> | undefined\n\n  constructor(ctx: FileSystemCacheContext) {\n    this.fs = ctx.fs\n    this.flushToDisk = ctx.flushToDisk\n    this.serverDistDir = ctx.serverDistDir\n    this.revalidatedTags = ctx.revalidatedTags\n\n    if (ctx.maxMemoryCacheSize) {\n      if (!FileSystemCache.memoryCache) {\n        if (FileSystemCache.debug) {\n          console.log('FileSystemCache: using memory store for fetch cache')\n        }\n\n        FileSystemCache.memoryCache = getMemoryCache(ctx.maxMemoryCacheSize)\n      } else if (FileSystemCache.debug) {\n        console.log('FileSystemCache: memory store already initialized')\n      }\n    } else if (FileSystemCache.debug) {\n      console.log('FileSystemCache: not using memory store for fetch cache')\n    }\n  }\n\n  public resetRequestCache(): void {}\n\n  public async revalidateTag(\n    tags: string | string[],\n    durations?: { expire?: number }\n  ) {\n    tags = typeof tags === 'string' ? [tags] : tags\n\n    if (FileSystemCache.debug) {\n      console.log('FileSystemCache: revalidateTag', tags, durations)\n    }\n\n    if (tags.length === 0) {\n      return\n    }\n\n    const now = Date.now()\n\n    for (const tag of tags) {\n      const existingEntry = tagsManifest.get(tag) || {}\n\n      if (durations) {\n        // Use provided durations directly\n        const updates: TagManifestEntry = { ...existingEntry }\n\n        // mark as stale immediately\n        updates.stale = now\n\n        if (durations.expire !== undefined) {\n          updates.expired = now + durations.expire * 1000 // Convert seconds to ms\n        }\n\n        tagsManifest.set(tag, updates)\n      } else {\n        // Update expired field for immediate expiration (default behavior when no durations provided)\n        tagsManifest.set(tag, { ...existingEntry, expired: now })\n      }\n    }\n  }\n\n  public async get(...args: Parameters<CacheHandler['get']>) {\n    const [key, ctx] = args\n    const { kind } = ctx\n\n    let data = FileSystemCache.memoryCache?.get(key)\n\n    if (FileSystemCache.debug) {\n      if (kind === IncrementalCacheKind.FETCH) {\n        console.log('FileSystemCache: get', key, ctx.tags, kind, !!data)\n      } else {\n        console.log('FileSystemCache: get', key, kind, !!data)\n      }\n    }\n\n    // let's check the disk for seed data\n    if (!data && process.env.NEXT_RUNTIME !== 'edge') {\n      try {\n        if (kind === IncrementalCacheKind.APP_ROUTE) {\n          const filePath = this.getFilePath(\n            `${key}.body`,\n            IncrementalCacheKind.APP_ROUTE\n          )\n          const fileData = await this.fs.readFile(filePath)\n          const { mtime } = await this.fs.stat(filePath)\n\n          const meta = JSON.parse(\n            await this.fs.readFile(\n              filePath.replace(/\\.body$/, NEXT_META_SUFFIX),\n              'utf8'\n            )\n          )\n\n          data = {\n            lastModified: mtime.getTime(),\n            value: {\n              kind: CachedRouteKind.APP_ROUTE,\n              body: fileData,\n              headers: meta.headers,\n              status: meta.status,\n            },\n          }\n        } else {\n          const filePath = this.getFilePath(\n            kind === IncrementalCacheKind.FETCH ? key : `${key}.html`,\n            kind\n          )\n\n          const fileData = await this.fs.readFile(filePath, 'utf8')\n          const { mtime } = await this.fs.stat(filePath)\n\n          if (kind === IncrementalCacheKind.FETCH) {\n            const { tags, fetchIdx, fetchUrl } = ctx\n\n            if (!this.flushToDisk) return null\n\n            const lastModified = mtime.getTime()\n            const parsedData: CachedFetchValue = JSON.parse(fileData)\n            data = {\n              lastModified,\n              value: parsedData,\n            }\n\n            if (data.value?.kind === CachedRouteKind.FETCH) {\n              const storedTags = data.value?.tags\n\n              // update stored tags if a new one is being added\n              // TODO: remove this when we can send the tags\n              // via header on GET same as SET\n              if (!tags?.every((tag) => storedTags?.includes(tag))) {\n                if (FileSystemCache.debug) {\n                  console.log(\n                    'FileSystemCache: tags vs storedTags mismatch',\n                    tags,\n                    storedTags\n                  )\n                }\n                await this.set(key, data.value, {\n                  fetchCache: true,\n                  tags,\n                  fetchIdx,\n                  fetchUrl,\n                })\n              }\n            }\n          } else if (kind === IncrementalCacheKind.APP_PAGE) {\n            // We try to load the metadata file, but if it fails, we don't\n            // error. We also don't load it if this is a fallback.\n            let meta: RouteMetadata | undefined\n            try {\n              meta = JSON.parse(\n                await this.fs.readFile(\n                  filePath.replace(/\\.html$/, NEXT_META_SUFFIX),\n                  'utf8'\n                )\n              )\n            } catch {}\n\n            let maybeSegmentData: Map<string, Buffer> | undefined\n            if (meta?.segmentPaths) {\n              // Collect all the segment data for this page.\n              // TODO: To optimize file system reads, we should consider creating\n              // separate cache entries for each segment, rather than storing them\n              // all on the page's entry. Though the behavior is\n              // identical regardless.\n              const segmentData: Map<string, Buffer> = new Map()\n              maybeSegmentData = segmentData\n              const segmentsDir = key + RSC_SEGMENTS_DIR_SUFFIX\n              await Promise.all(\n                meta.segmentPaths.map(async (segmentPath: string) => {\n                  const segmentDataFilePath = this.getFilePath(\n                    segmentsDir + segmentPath + RSC_SEGMENT_SUFFIX,\n                    IncrementalCacheKind.APP_PAGE\n                  )\n                  try {\n                    segmentData.set(\n                      segmentPath,\n                      await this.fs.readFile(segmentDataFilePath)\n                    )\n                  } catch {\n                    // This shouldn't happen, but if for some reason we fail to\n                    // load a segment from the filesystem, treat it the same as if\n                    // the segment is dynamic and does not have a prefetch.\n                  }\n                })\n              )\n            }\n\n            let rscData: Buffer | undefined\n            if (\n              !ctx.isFallback &&\n              (!ctx.isRoutePPREnabled || meta?.postponed == null)\n            ) {\n              rscData = await this.fs.readFile(\n                this.getFilePath(\n                  `${key}${RSC_SUFFIX}`,\n                  IncrementalCacheKind.APP_PAGE\n                )\n              )\n            }\n\n            data = {\n              lastModified: mtime.getTime(),\n              value: {\n                kind: CachedRouteKind.APP_PAGE,\n                html: fileData,\n                rscData,\n                postponed: meta?.postponed,\n                headers: meta?.headers,\n                status: meta?.status,\n                segmentData: maybeSegmentData,\n              },\n            }\n          } else if (kind === IncrementalCacheKind.PAGES) {\n            let meta: RouteMetadata | undefined\n            let pageData: string | object = {}\n\n            if (!ctx.isFallback) {\n              pageData = JSON.parse(\n                await this.fs.readFile(\n                  this.getFilePath(\n                    `${key}${NEXT_DATA_SUFFIX}`,\n                    IncrementalCacheKind.PAGES\n                  ),\n                  'utf8'\n                )\n              )\n            }\n\n            data = {\n              lastModified: mtime.getTime(),\n              value: {\n                kind: CachedRouteKind.PAGES,\n                html: fileData,\n                pageData,\n                headers: meta?.headers,\n                status: meta?.status,\n              },\n            }\n          } else {\n            throw new Error(\n              `Invariant: Unexpected route kind ${kind} in file system cache.`\n            )\n          }\n        }\n\n        if (data) {\n          FileSystemCache.memoryCache?.set(key, data)\n        }\n      } catch {\n        return null\n      }\n    }\n\n    if (\n      data?.value?.kind === CachedRouteKind.APP_PAGE ||\n      data?.value?.kind === CachedRouteKind.APP_ROUTE ||\n      data?.value?.kind === CachedRouteKind.PAGES\n    ) {\n      const tagsHeader = data.value.headers?.[NEXT_CACHE_TAGS_HEADER]\n      if (typeof tagsHeader === 'string') {\n        const cacheTags = tagsHeader.split(',')\n\n        // we trigger a blocking validation if an ISR page\n        // had a tag revalidated, if we want to be a background\n        // revalidation instead we return data.lastModified = -1\n        if (\n          cacheTags.length > 0 &&\n          areTagsExpired(cacheTags, data.lastModified)\n        ) {\n          if (FileSystemCache.debug) {\n            console.log('FileSystemCache: expired tags', cacheTags)\n          }\n\n          return null\n        }\n      }\n    } else if (data?.value?.kind === CachedRouteKind.FETCH) {\n      const combinedTags =\n        ctx.kind === IncrementalCacheKind.FETCH\n          ? [...(ctx.tags || []), ...(ctx.softTags || [])]\n          : []\n\n      // When revalidate tag is called we don't return stale data so it's\n      // updated right away.\n      if (combinedTags.some((tag) => this.revalidatedTags.includes(tag))) {\n        if (FileSystemCache.debug) {\n          console.log('FileSystemCache: was revalidated', combinedTags)\n        }\n\n        return null\n      }\n\n      if (areTagsExpired(combinedTags, data.lastModified)) {\n        if (FileSystemCache.debug) {\n          console.log('FileSystemCache: expired tags', combinedTags)\n        }\n\n        return null\n      }\n    }\n\n    return data ?? null\n  }\n\n  public async set(\n    key: string,\n    data: IncrementalCacheValue | null,\n    ctx: SetIncrementalFetchCacheContext | SetIncrementalResponseCacheContext\n  ) {\n    FileSystemCache.memoryCache?.set(key, {\n      value: data,\n      lastModified: Date.now(),\n    })\n\n    if (FileSystemCache.debug) {\n      console.log('FileSystemCache: set', key)\n    }\n\n    if (!this.flushToDisk || !data) return\n\n    // Create a new writer that will prepare to write all the files to disk\n    // after their containing directory is created.\n    const writer = new MultiFileWriter(this.fs)\n\n    if (data.kind === CachedRouteKind.APP_ROUTE) {\n      const filePath = this.getFilePath(\n        `${key}.body`,\n        IncrementalCacheKind.APP_ROUTE\n      )\n\n      writer.append(filePath, data.body)\n\n      const meta: RouteMetadata = {\n        headers: data.headers,\n        status: data.status,\n        postponed: undefined,\n        segmentPaths: undefined,\n        prefetchHints: undefined,\n      }\n\n      writer.append(\n        filePath.replace(/\\.body$/, NEXT_META_SUFFIX),\n        JSON.stringify(meta, null, 2)\n      )\n    } else if (\n      data.kind === CachedRouteKind.PAGES ||\n      data.kind === CachedRouteKind.APP_PAGE\n    ) {\n      const isAppPath = data.kind === CachedRouteKind.APP_PAGE\n      const htmlPath = this.getFilePath(\n        `${key}.html`,\n        isAppPath ? IncrementalCacheKind.APP_PAGE : IncrementalCacheKind.PAGES\n      )\n\n      writer.append(htmlPath, data.html)\n\n      // Fallbacks don't generate a data file.\n      if (!ctx.fetchCache && !ctx.isFallback && !ctx.isRoutePPREnabled) {\n        writer.append(\n          this.getFilePath(\n            `${key}${isAppPath ? RSC_SUFFIX : NEXT_DATA_SUFFIX}`,\n            isAppPath\n              ? IncrementalCacheKind.APP_PAGE\n              : IncrementalCacheKind.PAGES\n          ),\n          isAppPath ? data.rscData! : JSON.stringify(data.pageData)\n        )\n      }\n\n      if (data?.kind === CachedRouteKind.APP_PAGE) {\n        let segmentPaths: string[] | undefined\n        if (data.segmentData) {\n          segmentPaths = []\n          const segmentsDir = htmlPath.replace(\n            /\\.html$/,\n            RSC_SEGMENTS_DIR_SUFFIX\n          )\n\n          for (const [segmentPath, buffer] of data.segmentData) {\n            segmentPaths.push(segmentPath)\n            const segmentDataFilePath =\n              segmentsDir + segmentPath + RSC_SEGMENT_SUFFIX\n            writer.append(segmentDataFilePath, buffer)\n          }\n        }\n\n        const meta: RouteMetadata = {\n          headers: data.headers,\n          status: data.status,\n          postponed: data.postponed,\n          segmentPaths,\n          prefetchHints: undefined,\n        }\n\n        writer.append(\n          htmlPath.replace(/\\.html$/, NEXT_META_SUFFIX),\n          JSON.stringify(meta)\n        )\n      }\n    } else if (data.kind === CachedRouteKind.FETCH) {\n      const filePath = this.getFilePath(key, IncrementalCacheKind.FETCH)\n      writer.append(\n        filePath,\n        JSON.stringify({\n          ...data,\n          tags: ctx.fetchCache ? ctx.tags : [],\n        })\n      )\n    }\n\n    // Wait for all FS operations to complete.\n    await writer.wait()\n  }\n\n  private getFilePath(pathname: string, kind: IncrementalCacheKind): string {\n    switch (kind) {\n      case IncrementalCacheKind.FETCH:\n        // we store in .next/cache/fetch-cache so it can be persisted\n        // across deploys\n        return path.join(\n          this.serverDistDir,\n          '..',\n          'cache',\n          'fetch-cache',\n          pathname\n        )\n      case IncrementalCacheKind.PAGES:\n        return path.join(this.serverDistDir, 'pages', pathname)\n      case IncrementalCacheKind.IMAGE:\n      case IncrementalCacheKind.APP_PAGE:\n      case IncrementalCacheKind.APP_ROUTE:\n        return path.join(this.serverDistDir, 'app', pathname)\n      default:\n        throw new Error(`Unexpected file path kind: ${kind}`)\n    }\n  }\n}\n"],"names":["CachedRouteKind","IncrementalCacheKind","path","NEXT_CACHE_TAGS_HEADER","NEXT_DATA_SUFFIX","NEXT_META_SUFFIX","RSC_SEGMENT_SUFFIX","RSC_SEGMENTS_DIR_SUFFIX","RSC_SUFFIX","areTagsExpired","tagsManifest","MultiFileWriter","getMemoryCache","FileSystemCache","debug","process","env","NEXT_PRIVATE_DEBUG_CACHE","constructor","ctx","fs","flushToDisk","serverDistDir","revalidatedTags","maxMemoryCacheSize","memoryCache","console","log","resetRequestCache","revalidateTag","tags","durations","length","now","Date","tag","existingEntry","get","updates","stale","expire","undefined","expired","set","args","data","key","kind","FETCH","NEXT_RUNTIME","APP_ROUTE","filePath","getFilePath","fileData","readFile","mtime","stat","meta","JSON","parse","replace","lastModified","getTime","value","body","headers","status","fetchIdx","fetchUrl","parsedData","storedTags","every","includes","fetchCache","APP_PAGE","maybeSegmentData","segmentPaths","segmentData","Map","segmentsDir","Promise","all","map","segmentPath","segmentDataFilePath","rscData","isFallback","isRoutePPREnabled","postponed","html","PAGES","pageData","Error","tagsHeader","cacheTags","split","combinedTags","softTags","some","writer","append","prefetchHints","stringify","isAppPath","htmlPath","buffer","push","wait","pathname","join","IMAGE"],"mappings":"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","ignoreList":[0]}