Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix cache for next 15 #512

Merged
merged 3 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 51 additions & 7 deletions packages/open-next/src/adapters/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
}

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;
Expand All @@ -39,7 +39,7 @@
}

interface IncrementalCachedPageValue {
kind: "PAGE";
kind: "PAGE" | "PAGES";
// this needs to be a string since the cache expects to store
// the string value
html: string;
Expand All @@ -48,9 +48,21 @@
headers?: Record<string, undefined | string>;
}

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<string, undefined | string | string[]>;
postponed?: string;
status?: number;
}

type IncrementalCacheValue =
| CachedRedirectValue
| IncrementalCachedPageValue
| IncrementalCachedAppPageValue
| CachedImageValue
| CachedFetchValue
| CachedRouteValue;
Expand Down Expand Up @@ -94,6 +106,7 @@
var disableDynamoDBCache: boolean;
var disableIncrementalCache: boolean;
var lastModified: Record<string, number>;
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 {
Expand Down Expand Up @@ -203,7 +216,7 @@
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"]))
Expand All @@ -215,10 +228,22 @@
},
} 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,
Expand All @@ -245,7 +270,7 @@
}
}

async set(

Check warning on line 273 in packages/open-next/src/adapters/cache.ts

View workflow job for this annotation

GitHub Actions / validate

Refactor this function to reduce its Cognitive Complexity from 22 to the 20 allowed
key: string,
data?: IncrementalCacheValue,
ctx?: IncrementalCacheContext,
Expand All @@ -259,7 +284,7 @@
.getStore()
?.pendingPromiseRunner.withResolvers<void>();
try {
if (data?.kind === "ROUTE") {
if (data?.kind === "ROUTE" || data?.kind === "APP_ROUTE") {
const { body, status, headers } = data;
await globalThis.incrementalCache.set(
key,
Expand All @@ -277,8 +302,8 @@
},
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(
Expand All @@ -287,6 +312,10 @@
type: "app",
html,
rsc: pageData,
meta: {
status,
headers,
},
},
false,
);
Expand All @@ -301,6 +330,21 @@
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<true>(key, data, true);
} else if (data?.kind === "REDIRECT") {
Expand Down
9 changes: 7 additions & 2 deletions packages/open-next/src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,11 +374,12 @@ 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")],
external: ["sharp"],
external: ["sharp", "@opentelemetry/api"],
conico974 marked this conversation as resolved.
Show resolved Hide resolved
allowOverwrite: true,
outfile: path.join(outputPath, "index.mjs"),
banner: {
Expand Down Expand Up @@ -685,6 +686,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, "15.0.0") >= 0;

esbuildSync(
{
external: ["next", "styled-jsx", "react", "@aws-sdk/*"],
Expand All @@ -700,6 +704,7 @@ export function compileCache(format: "cjs" | "esm" = "cjs") {
`globalThis.disableDynamoDBCache = ${
config.dangerous?.disableTagCache ?? false
};`,
`globalThis.isNextAfter15 = ${isAfter15};`,
].join(""),
},
},
Expand Down
Loading