1
- import { cpSync , existsSync } from "node:fs" ;
1
+ import { cpSync , existsSync , readFileSync , rmSync , writeFileSync } from "node:fs" ;
2
2
import path from "node:path" ;
3
3
4
4
import type { BuildOptions } from "@opennextjs/aws/build/helper.js" ;
@@ -133,7 +133,7 @@ async function populateR2IncrementalCache(
133
133
134
134
async function populateKVIncrementalCache (
135
135
options : BuildOptions ,
136
- populateCacheOptions : { target : WranglerTarget ; environment ?: string }
136
+ populateCacheOptions : { target : WranglerTarget ; environment ?: string ; cacheChunkSize ?: number }
137
137
) {
138
138
logger . info ( "\nPopulating KV incremental cache..." ) ;
139
139
@@ -147,24 +147,36 @@ async function populateKVIncrementalCache(
147
147
148
148
const assets = getCacheAssets ( options ) ;
149
149
150
- for ( const { fullPath, key, buildId, isFetch } of tqdm ( assets ) ) {
151
- const cacheKey = computeCacheKey ( key , {
152
- prefix : proxy . env [ KV_CACHE_PREFIX_ENV_NAME ] ,
153
- buildId,
154
- cacheType : isFetch ? "fetch" : "cache" ,
155
- } ) ;
150
+ const chunkSize = Math . max ( 1 , populateCacheOptions . cacheChunkSize ?? 25 ) ;
151
+ const totalChunks = Math . ceil ( assets . length / chunkSize ) ;
152
+
153
+ logger . info ( `Inserting ${ assets . length } assets to KV in chunks of ${ chunkSize } ` ) ;
154
+
155
+ for ( const i of tqdm ( Array . from ( { length : totalChunks } , ( _ , i ) => i ) ) ) {
156
+ const chunkPath = path . join ( options . outputDir , "cloudflare" , `cache-chunk-${ i } .json` ) ;
157
+
158
+ const kvMapping = assets
159
+ . slice ( i * chunkSize , ( i + 1 ) * chunkSize )
160
+ . map ( ( { fullPath, key, buildId, isFetch } ) => ( {
161
+ key : computeCacheKey ( key , {
162
+ prefix : proxy . env [ KV_CACHE_PREFIX_ENV_NAME ] ,
163
+ buildId,
164
+ cacheType : isFetch ? "fetch" : "cache" ,
165
+ } ) ,
166
+ value : readFileSync ( fullPath , "utf8" ) ,
167
+ } ) ) ;
168
+
169
+ writeFileSync ( chunkPath , JSON . stringify ( kvMapping ) ) ;
156
170
157
171
runWrangler (
158
172
options ,
159
- [
160
- "kv key put" ,
161
- JSON . stringify ( cacheKey ) ,
162
- `--binding ${ JSON . stringify ( KV_CACHE_BINDING_NAME ) } ` ,
163
- `--path ${ JSON . stringify ( fullPath ) } ` ,
164
- ] ,
173
+ [ "kv bulk put" , JSON . stringify ( chunkPath ) , `--binding ${ JSON . stringify ( KV_CACHE_BINDING_NAME ) } ` ] ,
165
174
{ ...populateCacheOptions , logging : "error" }
166
175
) ;
176
+
177
+ rmSync ( chunkPath ) ;
167
178
}
179
+
168
180
logger . info ( `Successfully populated cache with ${ assets . length } assets` ) ;
169
181
}
170
182
@@ -209,7 +221,7 @@ function populateStaticAssetsIncrementalCache(options: BuildOptions) {
209
221
export async function populateCache (
210
222
options : BuildOptions ,
211
223
config : OpenNextConfig ,
212
- populateCacheOptions : { target : WranglerTarget ; environment ?: string }
224
+ populateCacheOptions : { target : WranglerTarget ; environment ?: string ; cacheChunkSize ?: number }
213
225
) {
214
226
const { incrementalCache, tagCache } = config . default . override ?? { } ;
215
227
0 commit comments