Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1142752

Browse files
authored
fix: support segment data in cache entries (#3093)
1 parent bfed78e commit 1142752

File tree

3 files changed

+52
-6
lines changed

3 files changed

+52
-6
lines changed

‎src/build/content/prerendered.ts‎

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { join } from 'node:path'
55
import { trace } from '@opentelemetry/api'
66
import { wrapTracer } from '@opentelemetry/api/experimental'
77
import { glob } from 'fast-glob'
8+
import type { RouteMetadata } from 'next-with-cache-handler-v2/dist/export/routes/types.js'
89
import pLimit from 'p-limit'
910
import { satisfies } from 'semver'
1011

@@ -69,21 +70,44 @@ const buildPagesCacheValue = async (
6970
revalidate: initialRevalidateSeconds,
7071
})
7172

73+
const RSC_SEGMENTS_DIR_SUFFIX = '.segments'
74+
const RSC_SEGMENT_SUFFIX = '.segment.rsc'
75+
7276
const buildAppCacheValue = async (
7377
path: string,
7478
shouldUseAppPageKind: boolean,
7579
): Promise<NetlifyCachedAppPageValue | NetlifyCachedPageValue> => {
76-
const meta = JSON.parse(await readFile(`${path}.meta`, 'utf-8'))
80+
const meta = JSON.parse(await readFile(`${path}.meta`, 'utf-8'))asRouteMetadata
7781
const html = await readFile(`${path}.html`, 'utf-8')
7882

7983
// supporting both old and new cache kind for App Router pages - https://github.com/vercel/next.js/pull/65988
8084
if (shouldUseAppPageKind) {
85+
// segments are normalized and outputted separately for each segment, we denormalize it here and stitch
86+
// fully constructed segmentData to avoid data fetch waterfalls later in cache handler at runtime
87+
// https://github.com/vercel/next.js/blob/def2c6ba75dff754767379afb44c26c30bd3d96b/packages/next/src/server/lib/incremental-cache/file-system-cache.ts#L185
88+
let segmentData: NetlifyCachedAppPageValue['segmentData']
89+
if (meta.segmentPaths) {
90+
const segmentsDir = path + RSC_SEGMENTS_DIR_SUFFIX
91+
92+
segmentData = Object.fromEntries(
93+
await Promise.all(
94+
meta.segmentPaths.map(async (segmentPath: string) => {
95+
const segmentDataFilePath = segmentsDir + segmentPath + RSC_SEGMENT_SUFFIX
96+
97+
const segmentContent = await readFile(segmentDataFilePath, 'base64')
98+
return [segmentPath, segmentContent]
99+
}),
100+
),
101+
)
102+
}
103+
81104
return {
82105
kind: 'APP_PAGE',
83106
html,
84107
rscData: await readFile(`${path}.rsc`, 'base64').catch(() =>
85108
readFile(`${path}.prefetch.rsc`, 'base64'),
86109
),
110+
segmentData,
87111
...meta,
88112
}
89113
}
@@ -97,7 +121,10 @@ const buildAppCacheValue = async (
97121
if (
98122
!meta.status &&
99123
rsc.includes('NEXT_NOT_FOUND') &&
100-
!meta.headers['x-next-cache-tags'].includes('/@')
124+
!(
125+
typeof meta.headers?.['x-next-cache-tags'] === 'string' &&
126+
meta.headers?.['x-next-cache-tags'].includes('/@')
127+
)
101128
) {
102129
meta.status = 404
103130
}

‎src/run/handlers/cache.cts‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
364364
requestContext.isCacheableAppPage = true
365365
}
366366

367-
const { revalidate, rscData, ...restOfPageValue } = blob.value
367+
const { revalidate, rscData, segmentData,...restOfPageValue } = blob.value
368368

369369
span.addEvent(blob.value?.kind, { lastModified: blob.lastModified, revalidate, ttl })
370370

@@ -375,6 +375,14 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
375375
value: {
376376
...restOfPageValue,
377377
rscData: rscData ? Buffer.from(rscData, 'base64') : undefined,
378+
segmentData: segmentData
379+
? new Map(
380+
Object.entries(segmentData).map(([segmentPath, base64EncodedSegment]) => [
381+
segmentPath,
382+
Buffer.from(base64EncodedSegment, 'base64'),
383+
]),
384+
)
385+
: undefined,
378386
},
379387
}
380388
}
@@ -416,6 +424,14 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
416424
revalidate: context.revalidate ?? context.cacheControl?.revalidate,
417425
cacheControl: context.cacheControl,
418426
rscData: data.rscData?.toString('base64'),
427+
segmentData: data.segmentData
428+
? Object.fromEntries(
429+
[...data.segmentData.entries()].map(([segmentPath, base64EncodedSegment]) => [
430+
segmentPath,
431+
base64EncodedSegment.toString('base64'),
432+
]),
433+
)
434+
: undefined,
419435
}
420436
}
421437

‎src/shared/cache-types.cts‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type {
99
IncrementalCachedPageValue,
1010
IncrementalCacheValue,
1111
} from 'next/dist/server/response-cache/types.js'
12+
import type { IncrementalCachedAppPageValue as IncrementalCachedAppPageValueForNewVersions } from 'next-with-cache-handler-v2/dist/server/response-cache/types.js'
1213

1314
export type { CacheHandlerContext } from 'next/dist/server/lib/incremental-cache/index.js'
1415

@@ -44,17 +45,19 @@ type IncrementalCachedAppPageValueForMultipleVersions = Omit<
4445
'kind'
4546
> & {
4647
kind: 'APP_PAGE'
47-
}
48+
}&Pick<IncrementalCachedAppPageValueForNewVersions,'segmentData'>
4849

4950
/**
5051
* Used for storing in blobs and reading from blobs
5152
*/
5253
export type NetlifyCachedAppPageValue = Omit<
5354
IncrementalCachedAppPageValueForMultipleVersions,
54-
'rscData'
55+
'rscData'|'segmentData'
5556
> & {
56-
// Next.js stores rscData as buffer, while we store it as base64 encoded string
57+
// Next.js stores rscData as Buffer, while we store it as base64 encoded string
5758
rscData: string | undefined
59+
// Next.js stores segmentData as Map<string, Buffer>, while we store it as Record<string, string>, where value is base64 encoded string
60+
segmentData: Record<string, string> | undefined
5861
revalidate?: Parameters<CacheHandler['set']>[2]['revalidate']
5962
cacheControl?: CacheControl
6063
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /