From d7c0d11499e848eb18622b6f8b03cba279621f39 Mon Sep 17 00:00:00 2001 From: Dorseuil Nicolas Date: Wed, 16 Apr 2025 14:19:26 +0200 Subject: [PATCH 1/3] pass revalidate for isr incremental cache --- packages/open-next/src/adapters/cache.ts | 27 ++++++++++++- packages/open-next/src/types/cache.ts | 48 +++++++++++++++++++---- packages/open-next/src/types/overrides.ts | 7 +++- 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/packages/open-next/src/adapters/cache.ts b/packages/open-next/src/adapters/cache.ts index fe573f7d7..e7ab10157 100644 --- a/packages/open-next/src/adapters/cache.ts +++ b/packages/open-next/src/adapters/cache.ts @@ -207,6 +207,7 @@ export default class Cache { if (data === null || data === undefined) { await globalThis.incrementalCache.delete(key); } else { + const revalidate = this.extractRevalidateForSet(ctx); switch (data.kind) { case "ROUTE": case "APP_ROUTE": { @@ -224,6 +225,7 @@ export default class Cache { status, headers, }, + revalidate, }, false, ); @@ -244,6 +246,7 @@ export default class Cache { status, headers, }, + revalidate, }, false, ); @@ -254,6 +257,7 @@ export default class Cache { type: "page", html, json: pageData, + revalidate, }, false, ); @@ -272,6 +276,7 @@ export default class Cache { status, headers, }, + revalidate, }, false, ); @@ -286,6 +291,7 @@ export default class Cache { { type: "redirect", props: data.props, + revalidate, }, false, ); @@ -424,7 +430,8 @@ export default class Cache { // If we use an in house version of getDerivedTags in build we should use it here instead of next's one const derivedTags: string[] = data?.kind === "FETCH" - ? (ctx?.tags ?? data?.data?.tags ?? []) // before version 14 next.js used data?.data?.tags so we keep it for backward compatibility + ? //@ts-expect-error - On older versions of next, ctx was a number, but for these cases we use data?.data?.tags + (ctx?.tags ?? data?.data?.tags ?? []) // before version 14 next.js used data?.data?.tags so we keep it for backward compatibility : data?.kind === "PAGE" ? (data.headers?.["x-next-cache-tags"]?.split(",") ?? []) : []; @@ -446,4 +453,22 @@ export default class Cache { ); } } + + private extractRevalidateForSet( + ctx?: IncrementalCacheContext, + ): number | false | undefined { + if (ctx === undefined) { + return undefined; + } + if (typeof ctx === "number" || ctx === false) { + return ctx; + } + if ("revalidate" in ctx) { + return ctx.revalidate; + } + if ("cacheControl" in ctx) { + return ctx.cacheControl?.revalidate; + } + return undefined; + } } diff --git a/packages/open-next/src/types/cache.ts b/packages/open-next/src/types/cache.ts index b37997f38..ebd19de0f 100644 --- a/packages/open-next/src/types/cache.ts +++ b/packages/open-next/src/types/cache.ts @@ -98,10 +98,44 @@ export type TagCacheMetaFile = { revalidatedAt: { N: string }; }; -export type IncrementalCacheContext = { - revalidate?: number | false | undefined; - fetchCache?: boolean | undefined; - fetchUrl?: string | undefined; - fetchIdx?: number | undefined; - tags?: string[] | undefined; -}; +// Cache context since https://github.com/vercel/next.js/pull/76207 +interface SetIncrementalFetchCacheContext { + fetchCache: true; + fetchUrl?: string; + fetchIdx?: number; + tags?: string[]; +} + +interface SetIncrementalResponseCacheContext { + fetchCache?: false; + cacheControl?: { + revalidate: number | false; + expire?: number; + }; + + /** + * True if the route is enabled for PPR. + */ + isRoutePPREnabled?: boolean; + + /** + * True if this is a fallback request. + */ + isFallback?: boolean; +} + +// Before #76207 revalidate was passed this way +interface SetIncrementalCacheContext { + revalidate?: number | false; + isRoutePPREnabled?: boolean; + isFallback?: boolean; +} + +// Before https://github.com/vercel/next.js/pull/53321 context on set was just the revalidate +type OldSetIncrementalCacheContext = number | false | undefined; + +export type IncrementalCacheContext = + | OldSetIncrementalCacheContext + | SetIncrementalCacheContext + | SetIncrementalFetchCacheContext + | SetIncrementalResponseCacheContext; diff --git a/packages/open-next/src/types/overrides.ts b/packages/open-next/src/types/overrides.ts index 81325c8b8..8363835c4 100644 --- a/packages/open-next/src/types/overrides.ts +++ b/packages/open-next/src/types/overrides.ts @@ -79,7 +79,12 @@ export type WithLastModified = { export type CacheValue = (IsFetch extends true ? CachedFetchValue - : CachedFile) & { revalidate?: number | false }; + : CachedFile) & { + /** + * This is available for page cache entry, but only at runtime. + */ + revalidate?: number | false; +}; export type IncrementalCache = { get( From ca975575097d390d15fff37902c9ded0cc487c38 Mon Sep 17 00:00:00 2001 From: Dorseuil Nicolas Date: Wed, 16 Apr 2025 14:46:41 +0200 Subject: [PATCH 2/3] changeset --- .changeset/lucky-ghosts-knock.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/lucky-ghosts-knock.md diff --git a/.changeset/lucky-ghosts-knock.md b/.changeset/lucky-ghosts-knock.md new file mode 100644 index 000000000..d973d0f52 --- /dev/null +++ b/.changeset/lucky-ghosts-knock.md @@ -0,0 +1,5 @@ +--- +"@opennextjs/aws": patch +--- + +pass revalidate for ISR/SSG cache From ade16e1858cadd83516b02105d60922f59731910 Mon Sep 17 00:00:00 2001 From: Dorseuil Nicolas Date: Tue, 29 Apr 2025 10:30:36 +0200 Subject: [PATCH 3/3] review fix --- packages/open-next/src/types/cache.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/open-next/src/types/cache.ts b/packages/open-next/src/types/cache.ts index ebd19de0f..ca3c4ffde 100644 --- a/packages/open-next/src/types/cache.ts +++ b/packages/open-next/src/types/cache.ts @@ -98,7 +98,7 @@ export type TagCacheMetaFile = { revalidatedAt: { N: string }; }; -// Cache context since https://github.com/vercel/next.js/pull/76207 +// Cache context since vercel/next.js#76207 interface SetIncrementalFetchCacheContext { fetchCache: true; fetchUrl?: string; @@ -124,14 +124,14 @@ interface SetIncrementalResponseCacheContext { isFallback?: boolean; } -// Before #76207 revalidate was passed this way +// Before vercel/next.js#76207 revalidate was passed this way interface SetIncrementalCacheContext { revalidate?: number | false; isRoutePPREnabled?: boolean; isFallback?: boolean; } -// Before https://github.com/vercel/next.js/pull/53321 context on set was just the revalidate +// Before vercel/next.js#53321 context on set was just the revalidate type OldSetIncrementalCacheContext = number | false | undefined; export type IncrementalCacheContext =