1
1
import { debug , error } from "@opennextjs/aws/adapters/logger.js" ;
2
2
import type { OpenNextConfig } from "@opennextjs/aws/types/open-next.js" ;
3
3
import type { TagCache } from "@opennextjs/aws/types/overrides.js" ;
4
+ import { RecoverableError } from "@opennextjs/aws/utils/error.js" ;
4
5
5
6
import { getCloudflareContext } from "./cloudflare-context.js" ;
6
7
@@ -36,7 +37,7 @@ class D1TagCache implements TagCache {
36
37
. bind ( path )
37
38
. all < { tag : string } > ( ) ;
38
39
39
- if ( ! success ) throw new Error ( `D1 select failed for ${ path } ` ) ;
40
+ if ( ! success ) throw new RecoverableError ( `D1 select failed for ${ path } ` ) ;
40
41
41
42
const tags = results ?. map ( ( item ) => this . removeBuildId ( item . tag ) ) ;
42
43
@@ -60,7 +61,7 @@ class D1TagCache implements TagCache {
60
61
. bind ( tag )
61
62
. all < { path : string } > ( ) ;
62
63
63
- if ( ! success ) throw new Error ( `D1 select failed for ${ tag } ` ) ;
64
+ if ( ! success ) throw new RecoverableError ( `D1 select failed for ${ tag } ` ) ;
64
65
65
66
const paths = results ?. map ( ( item ) => this . removeBuildId ( item . path ) ) ;
66
67
@@ -86,7 +87,7 @@ class D1TagCache implements TagCache {
86
87
. bind ( this . getCacheKey ( path ) , lastModified ?? 0 )
87
88
. all < { tag : string } > ( ) ;
88
89
89
- if ( ! success ) throw new Error ( `D1 select failed for ${ path } - ${ lastModified ?? 0 } ` ) ;
90
+ if ( ! success ) throw new RecoverableError ( `D1 select failed for ${ path } - ${ lastModified ?? 0 } ` ) ;
90
91
91
92
debug ( "revalidatedTags" , results ) ;
92
93
return results ?. length > 0 ? - 1 : ( lastModified ?? Date . now ( ) ) ;
@@ -101,26 +102,36 @@ class D1TagCache implements TagCache {
101
102
if ( isDisabled || tags . length === 0 ) return ;
102
103
103
104
try {
105
+ const uniqueTags = new Set < string > ( ) ;
104
106
const results = await db . batch (
105
- tags . map ( ( { tag, path, revalidatedAt } ) => {
107
+ tags . reduce < D1PreparedStatement [ ] > ( ( acc , { tag, path, revalidatedAt } ) => {
106
108
if ( revalidatedAt === 1 ) {
107
109
// new tag/path mapping from set
108
- return db
109
- . prepare ( `INSERT INTO ${ table . tags } (tag, path) VALUES (?, ?)` )
110
- . bind ( this . getCacheKey ( tag ) , this . getCacheKey ( path ) ) ;
110
+ acc . push (
111
+ db
112
+ . prepare ( `INSERT INTO ${ table . tags } (tag, path) VALUES (?, ?)` )
113
+ . bind ( this . getCacheKey ( tag ) , this . getCacheKey ( path ) )
114
+ ) ;
111
115
}
112
116
113
- // tag was revalidated
114
- return db
115
- . prepare ( `INSERT INTO ${ table . revalidations } (tag, revalidatedAt) VALUES (?, ?)` )
116
- . bind ( this . getCacheKey ( tag ) , revalidatedAt ?? Date . now ( ) ) ;
117
- } )
117
+ if ( ! uniqueTags . has ( tag ) && revalidatedAt !== - 1 ) {
118
+ // tag was revalidated
119
+ uniqueTags . add ( tag ) ;
120
+ acc . push (
121
+ db
122
+ . prepare ( `INSERT INTO ${ table . revalidations } (tag, revalidatedAt) VALUES (?, ?)` )
123
+ . bind ( this . getCacheKey ( tag ) , revalidatedAt ?? Date . now ( ) )
124
+ ) ;
125
+ }
126
+
127
+ return acc ;
128
+ } , [ ] )
118
129
) ;
119
130
120
131
const failedResults = results . filter ( ( res ) => ! res . success ) ;
121
132
122
133
if ( failedResults . length > 0 ) {
123
- throw new Error ( `${ failedResults . length } tags failed to write` ) ;
134
+ throw new RecoverableError ( `${ failedResults . length } tags failed to write` ) ;
124
135
}
125
136
} catch ( e ) {
126
137
error ( "Failed to batch write tags" , e ) ;
0 commit comments