From 3c3b1970e722255343639a717e2f2c25c9e2450a Mon Sep 17 00:00:00 2001 From: Dorseuil Nicolas Date: Thu, 12 Sep 2024 14:52:27 +0200 Subject: [PATCH 1/3] fix for next 15 --- packages/open-next/src/adapters/cache.ts | 58 +++++++++++++++++++++--- packages/open-next/src/build.ts | 6 ++- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/packages/open-next/src/adapters/cache.ts b/packages/open-next/src/adapters/cache.ts index 8ebd93998..716c0d926 100644 --- a/packages/open-next/src/adapters/cache.ts +++ b/packages/open-next/src/adapters/cache.ts @@ -21,7 +21,7 @@ interface CachedRedirectValue { } interface CachedRouteValue { - kind: "ROUTE"; + kind: "ROUTE" | "APP_ROUTE"; // this needs to be a RenderResult so since renderResponse // expects that type instead of a string body: Buffer; @@ -39,7 +39,7 @@ interface CachedImageValue { } interface IncrementalCachedPageValue { - kind: "PAGE"; + kind: "PAGE" | "PAGES"; // this needs to be a string since the cache expects to store // the string value html: string; @@ -48,9 +48,21 @@ interface IncrementalCachedPageValue { headers?: Record; } +interface IncrementalCachedAppPageValue { + kind: "APP_PAGE"; + // this needs to be a string since the cache expects to store + // the string value + html: string; + rscData: Buffer; + headers?: Record; + postponed?: string; + status?: number; +} + type IncrementalCacheValue = | CachedRedirectValue | IncrementalCachedPageValue + | IncrementalCachedAppPageValue | CachedImageValue | CachedFetchValue | CachedRouteValue; @@ -94,6 +106,7 @@ declare global { var disableDynamoDBCache: boolean; var disableIncrementalCache: boolean; var lastModified: Record; + var isNextAfter15: boolean; } // We need to use globalThis client here as this class can be defined at load time in next 12 but client is not available at load time export default class S3Cache { @@ -203,7 +216,7 @@ export default class S3Cache { return { lastModified: _lastModified, value: { - kind: "ROUTE", + kind: globalThis.isNextAfter15 ? "APP_ROUTE" : "ROUTE", body: Buffer.from( cacheData.body ?? Buffer.alloc(0), isBinaryContentType(String(meta?.headers?.["content-type"])) @@ -215,10 +228,22 @@ export default class S3Cache { }, } as CacheHandlerValue; } else if (cacheData?.type === "page" || cacheData?.type === "app") { + if (globalThis.isNextAfter15 && cacheData?.type === "app") { + return { + lastModified: _lastModified, + value: { + kind: "APP_PAGE", + html: cacheData.html, + rscData: Buffer.from(cacheData.rsc), + status: meta?.status, + headers: meta?.headers, + }, + } as CacheHandlerValue; + } return { lastModified: _lastModified, value: { - kind: "PAGE", + kind: globalThis.isNextAfter15 ? "PAGES" : "PAGE", html: cacheData.html, pageData: cacheData.type === "page" ? cacheData.json : cacheData.rsc, @@ -259,7 +284,7 @@ export default class S3Cache { .getStore() ?.pendingPromiseRunner.withResolvers(); try { - if (data?.kind === "ROUTE") { + if (data?.kind === "ROUTE" || data?.kind === "APP_ROUTE") { const { body, status, headers } = data; await globalThis.incrementalCache.set( key, @@ -277,8 +302,8 @@ export default class S3Cache { }, false, ); - } else if (data?.kind === "PAGE") { - const { html, pageData } = data; + } else if (data?.kind === "PAGE" || data?.kind === "PAGES") { + const { html, pageData, status, headers } = data; const isAppPath = typeof pageData === "string"; if (isAppPath) { await globalThis.incrementalCache.set( @@ -287,6 +312,10 @@ export default class S3Cache { type: "app", html, rsc: pageData, + meta: { + status, + headers, + }, }, false, ); @@ -301,6 +330,21 @@ export default class S3Cache { false, ); } + } else if (data?.kind === "APP_PAGE") { + const { html, rscData, headers, status } = data; + await globalThis.incrementalCache.set( + key, + { + type: "app", + html, + rsc: rscData.toString("utf8"), + meta: { + status, + headers, + }, + }, + false, + ); } else if (data?.kind === "FETCH") { await globalThis.incrementalCache.set(key, data, true); } else if (data?.kind === "REDIRECT") { diff --git a/packages/open-next/src/build.ts b/packages/open-next/src/build.ts index 72f8d555c..b120bcc45 100755 --- a/packages/open-next/src/build.ts +++ b/packages/open-next/src/build.ts @@ -378,7 +378,7 @@ async function createImageOptimizationBundle(config: OpenNextConfig) { esbuildSync( { entryPoints: [path.join(outputPath, "index.mjs")], - external: ["sharp"], + external: ["sharp", "@opentelemetry/api"], allowOverwrite: true, outfile: path.join(outputPath, "index.mjs"), banner: { @@ -685,6 +685,9 @@ async function createCacheAssets(monorepoRoot: string) { export function compileCache(format: "cjs" | "esm" = "cjs") { const ext = format === "cjs" ? "cjs" : "mjs"; const outfile = path.join(options.outputDir, ".build", `cache.${ext}`); + + const isAfter15 = compareSemver(options.nextVersion, "14.9.9") >= 0; + esbuildSync( { external: ["next", "styled-jsx", "react", "@aws-sdk/*"], @@ -700,6 +703,7 @@ export function compileCache(format: "cjs" | "esm" = "cjs") { `globalThis.disableDynamoDBCache = ${ config.dangerous?.disableTagCache ?? false };`, + `globalThis.isNextAfter15 = ${isAfter15};`, ].join(""), }, }, From 643aa52f5eb2427783e23a7c9b6aed7fcb196bcf Mon Sep 17 00:00:00 2001 From: Dorseuil Nicolas Date: Fri, 13 Sep 2024 10:07:40 +0200 Subject: [PATCH 2/3] review fix --- packages/open-next/src/build.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/open-next/src/build.ts b/packages/open-next/src/build.ts index b120bcc45..d72b908b0 100755 --- a/packages/open-next/src/build.ts +++ b/packages/open-next/src/build.ts @@ -374,7 +374,8 @@ async function createImageOptimizationBundle(config: OpenNextConfig) { // Build Lambda code (2nd pass) // note: bundle in user's Next.js app again b/c the adapter relies on the // "next" package. And the "next" package from user's app should - // be used. + // be used. We also set @opentelemetry/api as external because it seems to be + // required by Next 15 even though it's not used. esbuildSync( { entryPoints: [path.join(outputPath, "index.mjs")], @@ -686,7 +687,7 @@ export function compileCache(format: "cjs" | "esm" = "cjs") { const ext = format === "cjs" ? "cjs" : "mjs"; const outfile = path.join(options.outputDir, ".build", `cache.${ext}`); - const isAfter15 = compareSemver(options.nextVersion, "14.9.9") >= 0; + const isAfter15 = compareSemver(options.nextVersion, "15.0.0") >= 0; esbuildSync( { From b583b0d9a621be7f5f418498bed45310e28c1ed8 Mon Sep 17 00:00:00 2001 From: conico974 Date: Thu, 19 Sep 2024 19:24:52 +0200 Subject: [PATCH 3/3] Create tasty-cherries-sort.md --- .changeset/tasty-cherries-sort.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tasty-cherries-sort.md diff --git a/.changeset/tasty-cherries-sort.md b/.changeset/tasty-cherries-sort.md new file mode 100644 index 000000000..d716b7401 --- /dev/null +++ b/.changeset/tasty-cherries-sort.md @@ -0,0 +1,5 @@ +--- +"open-next": patch +--- + +fix incremental cache for next 15