@@ -3,13 +3,7 @@ import type { CacheValue, IncrementalCache, WithLastModified } from "@opennextjs
33import { IgnorableError } from "@opennextjs/aws/utils/error.js" ;
44
55import { getCloudflareContext } from "./cloudflare-context.js" ;
6-
7- type Entry < IsFetch extends boolean > = {
8- value : CacheValue < IsFetch > ;
9- lastModified : number ;
10- } ;
11-
12- const ONE_YEAR_IN_SECONDS = 31536000 ;
6+ import { IncrementalCacheEntry } from "./internal/incremental-cache.js" ;
137
148/**
159 * An instance of the Incremental Cache that uses an R2 bucket (`NEXT_CACHE_R2_BUCKET`) as it's
@@ -24,8 +18,6 @@ const ONE_YEAR_IN_SECONDS = 31536000;
2418class R2IncrementalCache implements IncrementalCache {
2519 readonly name = "r2-incremental-cache" ;
2620
27- protected localCache : Cache | undefined ;
28-
2921 async get < IsFetch extends boolean = false > (
3022 key : string ,
3123 isFetch ?: IsFetch
@@ -36,39 +28,12 @@ class R2IncrementalCache implements IncrementalCache {
3628 debug ( `Get ${ key } ` ) ;
3729
3830 try {
39- const r2Response = r2 . get ( this . getR2Key ( key ) ) ;
40-
41- const localCacheKey = this . getLocalCacheKey ( key , isFetch ) ;
42-
43- // Check for a cached entry as this will be faster than R2.
44- const cachedResponse = await this . getFromLocalCache ( localCacheKey ) ;
45- if ( cachedResponse ) {
46- debug ( ` -> Cached response` ) ;
47- // Update the local cache after the R2 fetch has completed.
48- getCloudflareContext ( ) . ctx . waitUntil (
49- Promise . resolve ( r2Response ) . then ( async ( res ) => {
50- if ( res ) {
51- const entry : Entry < IsFetch > = await res . json ( ) ;
52- await this . putToLocalCache ( localCacheKey , JSON . stringify ( entry ) , entry . value . revalidate ) ;
53- }
54- } )
55- ) ;
56-
57- return cachedResponse . json ( ) ;
58- }
59-
60- const r2Object = await r2Response ;
31+ const r2Object = await r2 . get ( this . getR2Key ( key , isFetch ) ) ;
6132 if ( ! r2Object ) return null ;
62- const entry : Entry < IsFetch > = await r2Object . json ( ) ;
6333
64- // Update the locale cache after retrieving from R2.
65- getCloudflareContext ( ) . ctx . waitUntil (
66- this . putToLocalCache ( localCacheKey , JSON . stringify ( entry ) , entry . value . revalidate )
67- ) ;
68-
69- return entry ;
34+ return r2Object . json ( ) ;
7035 } catch ( e ) {
71- error ( ` Failed to get from cache` , e ) ;
36+ error ( " Failed to get from cache" , e ) ;
7237 return null ;
7338 }
7439 }
@@ -84,24 +49,16 @@ class R2IncrementalCache implements IncrementalCache {
8449 debug ( `Set ${ key } ` ) ;
8550
8651 try {
87- const entry : Entry < IsFetch > = {
52+ const entry : IncrementalCacheEntry < IsFetch > = {
8853 value,
8954 // Note: `Date.now()` returns the time of the last IO rather than the actual time.
9055 // See https://developers.cloudflare.com/workers/reference/security-model/
9156 lastModified : Date . now ( ) ,
9257 } ;
9358
94- await Promise . all ( [
95- r2 . put ( this . getR2Key ( key , isFetch ) , JSON . stringify ( entry ) ) ,
96- // Update the locale cache for faster retrieval.
97- this . putToLocalCache (
98- this . getLocalCacheKey ( key , isFetch ) ,
99- JSON . stringify ( entry ) ,
100- entry . value . revalidate
101- ) ,
102- ] ) ;
59+ await r2 . put ( this . getR2Key ( key , isFetch ) , JSON . stringify ( entry ) ) ;
10360 } catch ( e ) {
104- error ( ` Failed to set to cache` , e ) ;
61+ error ( " Failed to set to cache" , e ) ;
10562 }
10663 }
10764
@@ -112,59 +69,16 @@ class R2IncrementalCache implements IncrementalCache {
11269 debug ( `Delete ${ key } ` ) ;
11370
11471 try {
115- await Promise . all ( [
116- r2 . delete ( this . getR2Key ( key ) ) ,
117- this . deleteFromLocalCache ( this . getLocalCacheKey ( key ) ) ,
118- ] ) ;
72+ await r2 . delete ( this . getR2Key ( key ) ) ;
11973 } catch ( e ) {
120- error ( ` Failed to delete from cache` , e ) ;
74+ error ( " Failed to delete from cache" , e ) ;
12175 }
12276 }
12377
124- protected getBaseCacheKey ( key : string , isFetch ?: boolean ) : string {
125- return `${ process . env . NEXT_BUILD_ID ?? "no-build-id" } /${ key } .${ isFetch ? "fetch" : "cache" } ` ;
126- }
127-
12878 protected getR2Key ( key : string , isFetch ?: boolean ) : string {
12979 const directory = getCloudflareContext ( ) . env . NEXT_CACHE_R2_PREFIX ?? "incremental-cache" ;
130- return `${ directory } /${ this . getBaseCacheKey ( key , isFetch ) } ` ;
131- }
132-
133- protected getLocalCacheKey ( key : string , isFetch ?: boolean ) {
134- return new Request ( new URL ( this . getBaseCacheKey ( key , isFetch ) , "http://cache.local" ) ) ;
135- }
136-
137- protected async getLocalCacheInstance ( ) : Promise < Cache > {
138- if ( this . localCache ) return this . localCache ;
139-
140- this . localCache = await caches . open ( "incremental-cache" ) ;
141- return this . localCache ;
142- }
143-
144- protected async getFromLocalCache ( key : Request ) {
145- const cache = await this . getLocalCacheInstance ( ) ;
146- return cache . match ( key ) ;
147- }
148-
149- protected async putToLocalCache (
150- key : Request ,
151- entry : string ,
152- revalidate : number | false | undefined
153- ) : Promise < void > {
154- const cache = await this . getLocalCacheInstance ( ) ;
155- await cache . put (
156- key ,
157- new Response ( entry , {
158- headers : new Headers ( {
159- "cache-control" : `max-age=${ revalidate || ONE_YEAR_IN_SECONDS } ` ,
160- } ) ,
161- } )
162- ) ;
163- }
16480
165- protected async deleteFromLocalCache ( key : Request ) {
166- const cache = await this . getLocalCacheInstance ( ) ;
167- await cache . delete ( key ) ;
81+ return `${ directory } /${ process . env . NEXT_BUILD_ID ?? "no-build-id" } /${ key } .${ isFetch ? "fetch" : "cache" } ` ;
16882 }
16983}
17084
0 commit comments