1
+ import { getStore } from '@netlify/blobs'
2
+ import { purgeCache } from '@netlify/functions'
1
3
import type { CacheHandler , CacheHandlerContext } from 'next/dist/server/lib/incremental-cache/index.js'
2
4
5
+ type TagsManifest = {
6
+ version : 1
7
+ items : { [ tag : string ] : { revalidatedAt : number } }
8
+ }
9
+
10
+ let tagsManifest : TagsManifest | undefined
11
+ const tagsManifestPath = '_netlify/tags-manifest.json'
12
+ const blobStore = getStore ( 'TODO' )
13
+
3
14
/**
4
15
* Netlify Cache Handler
5
16
* (CJS format because Next.js doesn't support ESM yet)
@@ -9,6 +20,8 @@ export default class NetlifyCacheHandler implements CacheHandler {
9
20
10
21
constructor ( options : CacheHandlerContext ) {
11
22
this . options = options
23
+
24
+ this . loadTagsManifest ( )
12
25
}
13
26
14
27
// eslint-disable-next-line require-await, class-methods-use-this
@@ -25,5 +38,32 @@ export default class NetlifyCacheHandler implements CacheHandler {
25
38
// eslint-disable-next-line class-methods-use-this, require-await
26
39
public async revalidateTag ( tag : string ) {
27
40
console . log ( 'NetlifyCacheHandler.revalidateTag' , tag )
41
+
42
+ await this . loadTagsManifest ( )
43
+ if ( ! tagsManifest ) {
44
+ return
45
+ }
46
+
47
+ const data = tagsManifest . items [ tag ] || { }
48
+ data . revalidatedAt = Date . now ( )
49
+ tagsManifest . items [ tag ] = data
50
+
51
+ try {
52
+ blobStore . setJSON ( tagsManifestPath , tagsManifest )
53
+ } catch ( error : any ) {
54
+ console . warn ( 'Failed to update tags manifest.' , error )
55
+ }
56
+
57
+ purgeCache ( { tags : [ tag ] } )
58
+ }
59
+
60
+ // eslint-disable-next-line class-methods-use-this
61
+ private async loadTagsManifest ( ) {
62
+ try {
63
+ tagsManifest = await blobStore . get ( tagsManifestPath , { type : 'json' } )
64
+ } catch ( error : any ) {
65
+ console . warn ( 'Failed to fetch tags manifest.' , error )
66
+ tagsManifest = { version : 1 , items : { } }
67
+ }
28
68
}
29
69
}
0 commit comments