Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
5 changes: 5 additions & 0 deletions .changeset/calm-parents-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@opennextjs/cloudflare": patch
---

Support composable cache in Next 16
7 changes: 1 addition & 6 deletions examples/e2e/experimental/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,11 @@ const nextConfig: NextConfig = {
/* config options here */
cleanDistDir: true,
output: "standalone",
eslint: {
ignoreDuringBuilds: true,
},
cacheComponents: true,
typescript: {
// Ignore type errors during build for now, we'll need to figure this out later
ignoreBuildErrors: true,
},
experimental: {
cacheComponents: true,
},
};

export default nextConfig;
6 changes: 3 additions & 3 deletions examples/e2e/experimental/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
"private": true,
"scripts": {
"dev": "next dev --turbopack --port 3004",
"build": "next build",
"build": "next build --webpack",
"start": "next start --port 3004",
"lint": "next lint",
"clean": "rm -rf .turbo node_modules .next .open-next",
"build:worker": "pnpm opennextjs-cloudflare build",
"build:worker": "pnpm opennextjs-cloudflare build --noMinify",
Comment thread
vicb marked this conversation as resolved.
Outdated
Comment thread
vicb marked this conversation as resolved.
Outdated
"preview:worker": "pnpm opennextjs-cloudflare preview",
"preview": "pnpm build:worker && pnpm preview:worker",
"e2e": "playwright test -c e2e/playwright.config.ts"
},
"dependencies": {
"@opennextjs/cloudflare": "workspace:*",
"next": "15.4.2-canary.29",
"next": "catalog:e2e",
"react": "catalog:e2e",
"react-dom": "catalog:e2e"
},
Expand Down
2 changes: 1 addition & 1 deletion examples/e2e/experimental/src/app/api/revalidate/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { revalidateTag } from "next/cache";

export function GET() {
revalidateTag("fullyTagged");
revalidateTag("fullyTagged", "max");
return new Response("DONE");
}
2 changes: 0 additions & 2 deletions examples/e2e/experimental/src/app/ppr/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { DynamicComponent } from "@/components/dynamic";
import { StaticComponent } from "@/components/static";
import { Suspense } from "react";

export const experimental_ppr = true;

export default function PPRPage() {
return (
<div>
Expand Down
3 changes: 3 additions & 0 deletions examples/e2e/experimental/src/app/use-cache/ssr/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ export default async function Page() {
<div>
<h1>Cache</h1>
<p>{_headers.get("accept") ?? "No accept headers"}</p>
<h2>cached:</h2>
<Suspense fallback={<p>Loading...</p>}>
<FullyCachedComponent />
</Suspense>
<h2>cached (with tag):</h2>
<Suspense fallback={<p>Loading...</p>}>
<FullyCachedComponentWithTag />
</Suspense>
<h2>isr:</h2>
<Suspense fallback={<p>Loading...</p>}>
<ISRComponent />
</Suspense>
Expand Down
6 changes: 3 additions & 3 deletions examples/e2e/experimental/src/components/cached.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { unstable_cacheLife, unstable_cacheTag } from "next/cache";
import { cacheLife, cacheTag } from "next/cache";

export async function FullyCachedComponent() {
"use cache";
Expand All @@ -11,7 +11,7 @@ export async function FullyCachedComponent() {

export async function FullyCachedComponentWithTag() {
"use cache";
unstable_cacheTag("fullyTagged");
cacheTag("fullyTagged");
return (
<div>
<p data-testid="fully-cached-with-tag">{Date.now()}</p>
Expand All @@ -21,7 +21,7 @@ export async function FullyCachedComponentWithTag() {

export async function ISRComponent() {
"use cache";
unstable_cacheLife({
cacheLife({
stale: 1,
revalidate: 5,
});
Expand Down
4 changes: 2 additions & 2 deletions examples/e2e/experimental/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
Expand All @@ -22,6 +22,6 @@
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
"exclude": ["node_modules"]
}
2 changes: 1 addition & 1 deletion packages/cloudflare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"dependencies": {
"@ast-grep/napi": "0.40.0",
"@dotenvx/dotenvx": "catalog:",
"@opennextjs/aws": "3.9.6",
"@opennextjs/aws": "3.9.7",
"cloudflare": "^4.4.1",
"enquirer": "^2.4.1",
"glob": "catalog:",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from "./next-server.js";

describe("Next Server", () => {
const nextServerCode = `
const next15ServerCode = `
class NextNodeServer extends _baseserver.default {
constructor(options){
// Initialize super class
Expand Down Expand Up @@ -168,8 +168,27 @@ class NextNodeServer extends _baseserver.default {
// ...
}`;

const next16ServerCode = `
class NextNodeServer extends _baseserver.default {
// ...

async loadCustomCacheHandlers() {
const { cacheMaxMemorySize, cacheHandlers } = this.nextConfig;
if (!cacheHandlers) return;
// If we've already initialized the cache handlers interface, don't do it
// again.
if (!(0, _handlers.initializeCacheHandlers)(cacheMaxMemorySize)) return;
for (const [kind, handler] of Object.entries(cacheHandlers)){
if (!handler) continue;
(0, _handlers.setCacheHandler)(kind, (0, _interopdefault.interopDefault)(await dynamicImportEsmDefault((0, _formatdynamicimportpath.formatDynamicImportPath)(this.distDir, handler))));
}
}
// ...
}
`;

test("build ID", () => {
expect(computePatchDiff("next-server.js", nextServerCode, buildIdRule)).toMatchInlineSnapshot(`
expect(computePatchDiff("next-server.js", next15ServerCode, buildIdRule)).toMatchInlineSnapshot(`
"Index: next-server.js
===================================================================
--- next-server.js
Expand Down Expand Up @@ -206,7 +225,7 @@ class NextNodeServer extends _baseserver.default {
});

test("cache handler", () => {
expect(computePatchDiff("next-server.js", nextServerCode, createCacheHandlerRule("manifest")))
expect(computePatchDiff("next-server.js", next15ServerCode, createCacheHandlerRule("manifest")))
.toMatchInlineSnapshot(`
"Index: next-server.js
===================================================================
Expand Down Expand Up @@ -234,9 +253,10 @@ class NextNodeServer extends _baseserver.default {
`);
});

test("composable cache handler", () => {
expect(computePatchDiff("next-server.js", nextServerCode, createComposableCacheHandlersRule("manifest")))
.toMatchInlineSnapshot(`
test("composable cache handler (Next 15)", () => {
expect(
computePatchDiff("next-server.js", next15ServerCode, createComposableCacheHandlersRule("manifest"))
).toMatchInlineSnapshot(`
"Index: next-server.js
===================================================================
--- next-server.js
Expand Down Expand Up @@ -268,8 +288,38 @@ class NextNodeServer extends _baseserver.default {
`);
});

test("composable cache handler (Next 16)", () => {
expect(
computePatchDiff("next-server.js", next16ServerCode, createComposableCacheHandlersRule("manifest"))
).toMatchInlineSnapshot(`
"Index: next-server.js
===================================================================
--- next-server.js
+++ next-server.js
@@ -1,10 +1,15 @@
-
class NextNodeServer extends _baseserver.default {
// ...

async loadCustomCacheHandlers() {
- const { cacheMaxMemorySize, cacheHandlers } = this.nextConfig;
+ const cacheHandlers = null;
+const handlersSymbol = Symbol.for('@next/cache-handlers');
+const handlersMapSymbol = Symbol.for('@next/cache-handlers-map');
+const handlersSetSymbol = Symbol.for('@next/cache-handlers-set');
+globalThis[handlersMapSymbol] = new Map();
+globalThis[handlersMapSymbol].set("default", require('manifest').default);
+globalThis[handlersSetSymbol] = new Set(globalThis[handlersMapSymbol].values());
if (!cacheHandlers) return;
// If we've already initialized the cache handlers interface, don't do it
// again.
if (!(0, _handlers.initializeCacheHandlers)(cacheMaxMemorySize)) return;
"
`);
});

test("disable node middleware", () => {
expect(computePatchDiff("next-server.js", nextServerCode, disableNodeMiddlewareRule))
expect(computePatchDiff("next-server.js", next15ServerCode, disableNodeMiddlewareRule))
.toMatchInlineSnapshot(`
"Index: next-server.js
===================================================================
Expand Down Expand Up @@ -312,7 +362,8 @@ class NextNodeServer extends _baseserver.default {
});

test("attachRequestMeta", () => {
expect(computePatchDiff("next-server.js", nextServerCode, attachRequestMetaRule)).toMatchInlineSnapshot(`
expect(computePatchDiff("next-server.js", next15ServerCode, attachRequestMetaRule))
.toMatchInlineSnapshot(`
"Index: next-server.js
===================================================================
--- next-server.js
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,11 @@ fix: |-
export function createComposableCacheHandlersRule(handlerPath: string) {
return `
rule:
pattern: "const { cacheHandlers } = this.nextConfig.experimental;"
# matches
# - const { cacheHandlers } = this.nextConfig.experimental; pre Next 16
# - const { cacheMaxMemorySize, cacheHandlers } = this.nextConfig; from Next 16
kind: lexical_declaration
regex: cacheHandlers
inside:
kind: method_definition
has:
Expand Down
Loading
Loading