@@ -7,12 +7,15 @@ import { getDeployStore, Store } from '@netlify/blobs'
77import { purgeCache } from '@netlify/functions'
88import { type Span } from '@opentelemetry/api'
99import { NEXT_CACHE_TAGS_HEADER } from 'next/dist/lib/constants.js'
10+
1011import type {
1112 CacheHandler ,
1213 CacheHandlerContext ,
13- CacheHandlerValue ,
1414 IncrementalCache ,
15- } from 'next/dist/server/lib/incremental-cache/index.js'
15+ NetlifyCachedRouteValue ,
16+ NetlifyCacheHandlerValue ,
17+ NetlifyIncrementalCacheValue ,
18+ } from '../../shared/cache-types.cjs'
1619
1720import { getRequestContext } from './request-context.cjs'
1821import { getTracer } from './tracer.cjs'
@@ -43,7 +46,7 @@ export class NetlifyCacheHandler implements CacheHandler {
4346 }
4447
4548 private captureResponseCacheLastModified (
46- cacheValue : CacheHandlerValue ,
49+ cacheValue : NetlifyCacheHandlerValue ,
4750 key : string ,
4851 getCacheKeySpan : Span ,
4952 ) {
@@ -90,6 +93,19 @@ export class NetlifyCacheHandler implements CacheHandler {
9093 }
9194 }
9295
96+ private captureRouteRevalidateAndRemoveFromObject (
97+ cacheValue : NetlifyCachedRouteValue ,
98+ ) : Omit < NetlifyCachedRouteValue , 'revalidate' > {
99+ const { revalidate, ...restOfRouteValue } = cacheValue
100+
101+ const requestContext = getRequestContext ( )
102+ if ( requestContext ) {
103+ requestContext . routeHandlerRevalidate = revalidate
104+ }
105+
106+ return restOfRouteValue
107+ }
108+
93109 async get ( ...args : Parameters < CacheHandler [ 'get' ] > ) : ReturnType < CacheHandler [ 'get' ] > {
94110 return this . tracer . withActiveSpan ( 'get cache key' , async ( span ) => {
95111 const [ key , ctx = { } ] = args
@@ -103,7 +119,7 @@ export class NetlifyCacheHandler implements CacheHandler {
103119 return await this . blobStore . get ( blobKey , {
104120 type : 'json' ,
105121 } )
106- } ) ) as CacheHandlerValue | null
122+ } ) ) as NetlifyCacheHandlerValue | null
107123
108124 // if blob is null then we don't have a cache entry
109125 if ( ! blob ) {
@@ -128,15 +144,19 @@ export class NetlifyCacheHandler implements CacheHandler {
128144 value : blob . value ,
129145 }
130146
131- case 'ROUTE' :
147+ case 'ROUTE' : {
132148 span . addEvent ( 'ROUTE' , { lastModified : blob . lastModified , status : blob . value . status } )
149+
150+ const valueWithoutRevalidate = this . captureRouteRevalidateAndRemoveFromObject ( blob . value )
151+
133152 return {
134153 lastModified : blob . lastModified ,
135154 value : {
136- ...blob . value ,
137- body : Buffer . from ( blob . value . body as unknown as string , 'base64' ) ,
155+ ...valueWithoutRevalidate ,
156+ body : Buffer . from ( valueWithoutRevalidate . body as unknown as string , 'base64' ) ,
138157 } ,
139158 }
159+ }
140160 case 'PAGE' :
141161 span . addEvent ( 'PAGE' , { lastModified : blob . lastModified } )
142162 return {
@@ -152,23 +172,22 @@ export class NetlifyCacheHandler implements CacheHandler {
152172
153173 async set ( ...args : Parameters < IncrementalCache [ 'set' ] > ) {
154174 return this . tracer . withActiveSpan ( 'set cache key' , async ( span ) => {
155- const [ key , data ] = args
175+ const [ key , data , context ] = args
156176 const blobKey = await this . encodeBlobKey ( key )
157177 const lastModified = Date . now ( )
158178 span . setAttributes ( { key, lastModified, blobKey } )
159179
160180 console . debug ( `[NetlifyCacheHandler.set]: ${ key } ` )
161181
162- let value = data
163-
164- if ( data ?. kind === 'ROUTE' ) {
165- // don't mutate data, as it's used for the initial response - instead create a new object
166- value = {
167- ...data ,
168- // @ts -expect-error gotta find a better solution for this
169- body : data . body . toString ( 'base64' ) ,
170- }
171- }
182+ const value : NetlifyIncrementalCacheValue | null =
183+ data ?. kind === 'ROUTE'
184+ ? // don't mutate data, as it's used for the initial response - instead create a new object
185+ {
186+ ...data ,
187+ revalidate : context . revalidate ,
188+ body : data . body . toString ( 'base64' ) ,
189+ }
190+ : data
172191
173192 await this . blobStore . setJSON ( blobKey , {
174193 lastModified,
@@ -217,7 +236,7 @@ export class NetlifyCacheHandler implements CacheHandler {
217236 * Checks if a cache entry is stale through on demand revalidated tags
218237 */
219238 private async checkCacheEntryStaleByTags (
220- cacheEntry : CacheHandlerValue ,
239+ cacheEntry : NetlifyCacheHandlerValue ,
221240 tags : string [ ] = [ ] ,
222241 softTags : string [ ] = [ ] ,
223242 ) {
0 commit comments