11import { isBinaryContentType } from "../utils/binary" ;
22import { debug , error , warn } from "./logger" ;
3+ import { getTagFromValue , hasBeenRevalidated } from "utils/cache" ;
34
45interface CachedFetchValue {
56 kind : "FETCH" ;
@@ -134,14 +135,15 @@ export default class Cache {
134135
135136 if ( cachedEntry ?. value === undefined ) return null ;
136137
137- const _lastModified = await globalThis . tagCache . getLastModified (
138+ const _tags = [ ...( tags ?? [ ] ) , ...( softTags ?? [ ] ) ] ;
139+ const _lastModified = cachedEntry . lastModified ?? Date . now ( ) ;
140+ const _hasBeenRevalidated = await hasBeenRevalidated (
138141 key ,
142+ _tags ,
139143 cachedEntry ?. lastModified ,
140144 ) ;
141- if ( _lastModified === - 1 ) {
142- // If some tags are stale we need to force revalidation
143- return null ;
144- }
145+
146+ if ( _hasBeenRevalidated ) return null ;
145147
146148 // For cases where we don't have tags, we need to ensure that the soft tags are not being revalidated
147149 // We only need to check for the path as it should already contain all the tags
@@ -154,11 +156,12 @@ export default class Cache {
154156 ! tag . endsWith ( "page" ) ,
155157 ) ;
156158 if ( path ) {
157- const pathLastModified = await globalThis . tagCache . getLastModified (
159+ const hasPathBeenUpdated = await hasBeenRevalidated (
158160 path . replace ( "_N_T_/" , "" ) ,
161+ [ ] ,
159162 cachedEntry . lastModified ,
160163 ) ;
161- if ( pathLastModified === - 1 ) {
164+ if ( hasPathBeenUpdated ) {
162165 // In case the path has been revalidated, we don't want to use the fetch cache
163166 return null ;
164167 }
@@ -184,16 +187,17 @@ export default class Cache {
184187 return null ;
185188 }
186189
187- const meta = cachedEntry . value . meta ;
188- const _lastModified = await globalThis . tagCache . getLastModified (
190+ const cacheData = cachedEntry ?. value ;
191+ const meta = cacheData ?. meta ;
192+ const tags = getTagFromValue ( cacheData ) ;
193+ const _lastModified = cachedEntry . lastModified ?? Date . now ( ) ;
194+ const _hasBeenRevalidated = await hasBeenRevalidated (
189195 key ,
190- cachedEntry ?. lastModified ,
196+ tags ,
197+ _lastModified ,
191198 ) ;
192- if ( _lastModified === - 1 ) {
193- // If some tags are stale we need to force revalidation
194- return null ;
195- }
196- const cacheData = cachedEntry ?. value ;
199+ if ( cacheData === undefined || _hasBeenRevalidated ) return null ;
200+
197201 const requestId = globalThis . __openNextAls . getStore ( ) ?. requestId ?? "" ;
198202 globalThis . lastModified [ requestId ] = _lastModified ;
199203 if ( cacheData ?. type === "route" ) {
@@ -370,23 +374,7 @@ export default class Cache {
370374 ? ( data . headers ?. [ "x-next-cache-tags" ] ?. split ( "," ) ?? [ ] )
371375 : [ ] ;
372376 debug ( "derivedTags" , derivedTags ) ;
373- // Get all tags stored in dynamodb for the given key
374- // If any of the derived tags are not stored in dynamodb for the given key, write them
375- const storedTags = await globalThis . tagCache . getByPath ( key ) ;
376- const tagsToWrite = derivedTags . filter (
377- ( tag ) => ! storedTags . includes ( tag ) ,
378- ) ;
379- if ( tagsToWrite . length > 0 ) {
380- await globalThis . tagCache . writeTags (
381- tagsToWrite . map ( ( tag ) => ( {
382- path : key ,
383- tag : tag ,
384- // In case the tags are not there we just need to create them
385- // but we don't want them to return from `getLastModified` as they are not stale
386- revalidatedAt : 1 ,
387- } ) ) ,
388- ) ;
389- }
377+ await this . updateTagsOnSet ( key , derivedTags ) ;
390378 debug ( "Finished setting cache" ) ;
391379 } catch ( e ) {
392380 error ( "Failed to set cache" , e ) ;
@@ -403,6 +391,9 @@ export default class Cache {
403391 }
404392 try {
405393 const _tags = Array . isArray ( tags ) ? tags : [ tags ] ;
394+ if ( globalThis . tagCache . mode === "nextMode" ) {
395+ return globalThis . tagCache . writeTags ( _tags ) ;
396+ }
406397 for ( const tag of _tags ) {
407398 debug ( "revalidateTag" , tag ) ;
408399 // Find all keys with the given tag
@@ -466,4 +457,28 @@ export default class Cache {
466457 error ( "Failed to revalidate tag" , e ) ;
467458 }
468459 }
460+
461+ private async updateTagsOnSet ( key : string , derivedTags : string [ ] ) {
462+ if (
463+ globalThis . openNextConfig . dangerous ?. disableTagCache ||
464+ globalThis . tagCache . mode === "nextMode"
465+ ) {
466+ return ;
467+ }
468+ // Get all tags stored in dynamodb for the given key
469+ // If any of the derived tags are not stored in dynamodb for the given key, write them
470+ const storedTags = await globalThis . tagCache . getByPath ( key ) ;
471+ const tagsToWrite = derivedTags . filter ( ( tag ) => ! storedTags . includes ( tag ) ) ;
472+ if ( tagsToWrite . length > 0 ) {
473+ await globalThis . tagCache . writeTags (
474+ tagsToWrite . map ( ( tag ) => ( {
475+ path : key ,
476+ tag : tag ,
477+ // In case the tags are not there we just need to create them
478+ // but we don't want them to return from `getLastModified` as they are not stale
479+ revalidatedAt : 1 ,
480+ } ) ) ,
481+ ) ;
482+ }
483+ }
469484}
0 commit comments