Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions examples-cloudflare/e2e/experimental/open-next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export default defineCloudflareConfig({
},
}),
queue: doQueue,
enableCacheInterception: true,
});
9 changes: 1 addition & 8 deletions examples/experimental/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,7 @@ const nextConfig: NextConfig = {
/* config options here */
cleanDistDir: true,
output: "standalone",
eslint: {
ignoreDuringBuilds: true,
},
experimental: {
ppr: "incremental",
nodeMiddleware: true,
dynamicIO: true,
},
cacheComponents: true,
};

export default nextConfig;
24 changes: 0 additions & 24 deletions examples/experimental/open-next.config.local.ts

This file was deleted.

33 changes: 24 additions & 9 deletions examples/experimental/open-next.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
const config = {
import type { OpenNextConfig } from "@opennextjs/aws/types/open-next.js";

export default {
default: {
override: {
wrapper: "aws-lambda-streaming",
queue: "sqs-lite",
incrementalCache: "s3-lite",
tagCache: "dynamodb-lite",
wrapper: "express-dev",
converter: "node",
incrementalCache: "fs-dev",
queue: "direct",
tagCache: "fs-dev-nextMode",
},
},
functions: {},
buildCommand: "npx turbo build",
};

export default config;
imageOptimization: {
override: {
wrapper: "dummy",
converter: "dummy",
},
loader: "fs-dev",
},

dangerous: {
enableCacheInterception: true,
useAdapterOutputs: true,
},

// You can override the build command here so that you don't have to rebuild next every time you make a change
//buildCommand: "echo 'No build command'",
} satisfies OpenNextConfig;
20 changes: 13 additions & 7 deletions examples/experimental/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,29 @@
"version": "0.1.0",
"private": true,
"scripts": {
"openbuild": "node ../../packages/open-next/dist/index.js build",
"openbuild:local": "node ../../packages/open-next/dist/index.js build",
"openbuild:local:start": "PORT=3004 node .open-next/server-functions/default/index.mjs",
"dev": "next dev --turbopack --port 3004",
"build": "next build",
"start": "next start --port 3004",
"lint": "next lint",
"clean": "rm -rf .turbo node_modules .next .open-next"
},
"dependencies": {
"next": "15.4.0-canary.14",
"react": "catalog:aws",
"react-dom": "catalog:aws"
"next": "16.2.0-canary.45",
"react": "19.2.4",
"react-dom": "19.2.4"
},
"devDependencies": {
"@opennextjs/aws": "workspace:*",
"@types/node": "catalog:aws",
"@types/react": "catalog:aws",
"@types/react-dom": "catalog:aws",
"@types/react": "19.2.14",
"@types/react-dom": "19.2.3",
"typescript": "catalog:aws"
},
"pnpm": {
"overrides": {
"@types/react": "19.2.14",
"@types/react-dom": "19.2.3"
}
}
}
2 changes: 1 addition & 1 deletion examples/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/experimental/src/app/ppr/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { Suspense } from "react";
import { DynamicComponent } from "@/components/dynamic";
import { StaticComponent } from "@/components/static";

export const experimental_ppr = true;

export default function PPRPage() {
return (
<div>
Expand Down
7 changes: 4 additions & 3 deletions examples/experimental/src/components/cached.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { unstable_cacheLife, unstable_cacheTag } from "next/cache";
import { cacheLife, cacheTag } from "next/cache";

export async function FullyCachedComponent() {
"use cache";
cacheLife("max");
return (
<div>
<p data-testid="fully-cached">{Date.now()}</p>
Expand All @@ -11,7 +12,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 +22,7 @@ export async function FullyCachedComponentWithTag() {

export async function ISRComponent() {
"use cache";
unstable_cacheLife({
cacheLife({
stale: 1,
revalidate: 5,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import crypto from "node:crypto";

import { type NextRequest, NextResponse } from "next/server";

export default function middleware(request: NextRequest) {
export default function proxy(request: NextRequest) {
if (request.nextUrl.pathname === "/api/hello") {
return NextResponse.json({
name: "World",
Expand All @@ -22,7 +22,3 @@ export default function middleware(request: NextRequest) {
},
});
}

export const config = {
runtime: "nodejs",
};
64 changes: 39 additions & 25 deletions examples/experimental/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,41 @@
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
"compilerOptions": {
"target": "ES2017",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": [
"./src/*"
]
}
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}
7 changes: 4 additions & 3 deletions packages/cloudflare/src/cli/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,13 @@ export default {
...nextConfig,
cacheHandler: cache.cache, //TODO: compute that here,
cacheMaxMemorySize: 0,
// cacheHandlers: {
// default: cache.composableCache,
// remote: cache.composableCache,
// },
experimental: {
...nextConfig.experimental,
trustHostHeader: true,
cacheHandlers: {
default: cache.composableCache,
},
},
};
},
Expand Down
57 changes: 56 additions & 1 deletion packages/cloudflare/src/cli/templates/worker.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { InternalResult } from "@opennextjs/aws/types/open-next.js";

//@ts-expect-error: Will be resolved by wrangler build
import { handleImageRequest } from "./cloudflare/images.js";
//@ts-expect-error: Will be resolved by wrangler build
Expand Down Expand Up @@ -46,7 +48,8 @@ export default {
}

// - `Request`s are handled by the Next server
const reqOrResp = await middlewareHandler(request, env, ctx);
const reqOrResp: Response | Request | { initialResponse: InternalResult; request: Request } =
await middlewareHandler(request, env, ctx);

if (reqOrResp instanceof Response) {
return reqOrResp;
Expand All @@ -55,6 +58,58 @@ export default {
// @ts-expect-error: resolved by wrangler build
const { handler } = await import("./server-functions/default/handler.mjs");

//This is PPR response, we need to handle it differently
// We'll likely change that when we'll make the StreamCreator mandatory.
if ("initialResponse" in reqOrResp) {
// We need to create a ReadableStream for the body
const body = new ReadableStream({
async start(controller) {
const initialBodyReader = reqOrResp.initialResponse.body?.getReader();
if (initialBodyReader) {
while (true) {
const { done, value } = await initialBodyReader.read();
if (done) {
break;
}
controller.enqueue(value);
}
}
const resp: Response = await handler(reqOrResp.request, env, ctx, request.signal);
const reader = resp.body?.getReader();
if (!reader) {
controller.close();
return;
}
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
controller.enqueue(value);
}
controller.close();
},
});

const headers = new Headers();
for (const [key, value] of Object.entries(reqOrResp.initialResponse.headers)) {
if (Array.isArray(value)) {
for (const v of value) {
headers.append(key, v);
}
} else {
headers.set(key, value);
}
}

headers.set("content-encoding", "identity"); // To fix PPR locally

return new Response(body, {
status: reqOrResp.initialResponse.statusCode,
headers: headers,
});
}

return handler(reqOrResp, env, ctx, request.signal);
});
},
Expand Down
7 changes: 4 additions & 3 deletions packages/open-next/src/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,14 @@ export default {
return {
...nextConfig,
cacheHandler: cache.cache, //TODO: compute that here,
cacheHandlers: {
default: cache.composableCache,
remote: cache.composableCache,
},
cacheMaxMemorySize: 0,
experimental: {
...nextConfig.experimental,
trustHostHeader: true,
cacheHandlers: {
default: cache.composableCache,
},
},
};
},
Expand Down
10 changes: 9 additions & 1 deletion packages/open-next/src/adapters/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,13 @@ export default class Cache {
break;
}
case "APP_PAGE": {
const { html, rscData, headers, status } = data;
const { html, rscData, headers, status, segmentData, postponed } = data;
const segmentToWrite: Record<string, string> = {};
if (segmentData) {
for (const [segmentPath, segmentContent] of segmentData.entries()) {
segmentToWrite[segmentPath] = segmentContent.toString("utf8");
}
}
await globalThis.incrementalCache.set(
key,
{
Expand All @@ -254,8 +260,10 @@ export default class Cache {
meta: {
status,
headers,
postponed,
},
revalidate,
segmentData: segmentData ? segmentToWrite : undefined,
},
"cache"
);
Expand Down
1 change: 1 addition & 0 deletions packages/open-next/src/adapters/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ const defaultHandler = async (
isISR: result.isISR,
initialURL: result.initialURL,
resolvedRoutes: result.resolvedRoutes,
initialResponse: result.initialResponse,
};
}
try {
Expand Down
Loading
Loading