1- import { cpSync , existsSync } from "node:fs" ;
1+ import { cpSync , existsSync , readFileSync , rmSync , writeFileSync } from "node:fs" ;
22import path from "node:path" ;
33
44import type { BuildOptions } from "@opennextjs/aws/build/helper.js" ;
@@ -133,7 +133,7 @@ async function populateR2IncrementalCache(
133133
134134async function populateKVIncrementalCache (
135135 options : BuildOptions ,
136- populateCacheOptions : { target : WranglerTarget ; environment ?: string }
136+ populateCacheOptions : { target : WranglerTarget ; environment ?: string ; cacheChunkSize ?: number }
137137) {
138138 logger . info ( "\nPopulating KV incremental cache..." ) ;
139139
@@ -147,24 +147,36 @@ async function populateKVIncrementalCache(
147147
148148 const assets = getCacheAssets ( options ) ;
149149
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 ) ) ;
156170
157171 runWrangler (
158172 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 ) } ` ] ,
165174 { ...populateCacheOptions , logging : "error" }
166175 ) ;
176+
177+ rmSync ( chunkPath ) ;
167178 }
179+
168180 logger . info ( `Successfully populated cache with ${ assets . length } assets` ) ;
169181}
170182
@@ -209,7 +221,7 @@ function populateStaticAssetsIncrementalCache(options: BuildOptions) {
209221export async function populateCache (
210222 options : BuildOptions ,
211223 config : OpenNextConfig ,
212- populateCacheOptions : { target : WranglerTarget ; environment ?: string }
224+ populateCacheOptions : { target : WranglerTarget ; environment ?: string ; cacheChunkSize ?: number }
213225) {
214226 const { incrementalCache, tagCache } = config . default . override ?? { } ;
215227
0 commit comments