Skip to content

Commit 8dcc672

Browse files
committed
fix(cache): preserve legacy io probe parity
1 parent 7ba74a2 commit 8dcc672

4 files changed

Lines changed: 32 additions & 2 deletions

File tree

packages/vinext/src/server/app-rsc-handler.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2012,7 +2012,10 @@ export function createAppRscHandler<TRoute extends AppRscHandlerRoute>(
20122012
? markUnverifiedInterceptionResponseUncacheable(response)
20132013
: response;
20142014
},
2015-
{ route: () => new URL(request.url).pathname },
2015+
{
2016+
cacheComponents: options.createPprFallbackShells !== undefined,
2017+
route: () => new URL(request.url).pathname,
2018+
},
20162019
),
20172020
);
20182021
let response: Response;

packages/vinext/src/server/prerender-work-unit-setup.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ import { NO_STORE_CACHE_CONTROL } from "./cache-control.js";
1717

1818
export function runWithPrerenderWorkUnit(
1919
fn: () => Promise<Response>,
20-
options?: { route?: string | (() => string) },
20+
options?: { cacheComponents?: boolean; route?: string | (() => string) },
2121
): Promise<Response> {
2222
if (process.env.VINEXT_PRERENDER === "1" || isRouteCacheabilityProbe()) {
23+
if (options?.cacheComponents !== true) {
24+
return workUnitAsyncStorage.run({ type: "prerender-legacy" }, fn);
25+
}
2326
return runWithPrerenderWorkUnitOwner(fn, options);
2427
}
2528
return fn();

tests/e2e/ppr-impact-demo/cacheability-probe.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,17 @@ test("classifies completed App Page renders inside workerd", async ({ request })
142142
state: "static-candidate",
143143
version: 1,
144144
});
145+
146+
// Ported from Next.js: packages/next/src/server/request/io.ts
147+
// https://github.com/vercel/next.js/blob/canary/packages/next/src/server/request/io.ts
148+
const legacyIoProbe = await request.get("/cacheability/explicit-io", { headers });
149+
await expect(legacyIoProbe.json()).resolves.toMatchObject({
150+
kind: "app-page",
151+
pattern: "/cacheability/explicit-io",
152+
state: "static-candidate",
153+
status: 200,
154+
version: 1,
155+
});
145156
});
146157

147158
test("rejects forged probes without exposing capability headers to user code", async ({
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// `io()` is implemented by vinext for Next.js parity but is not declared by
2+
// the stable Next.js types installed in this fixture yet.
3+
// @ts-expect-error -- experimental Next.js Cache Components API
4+
import { io } from "next/cache";
5+
6+
export const revalidate = 60;
7+
8+
export default async function ExplicitIoPage() {
9+
// Next.js resolves io() immediately in a prerender-legacy work unit. It only
10+
// suspends and makes the route dynamic when Cache Components are enabled.
11+
await io();
12+
return <p id="cacheability-result">legacy io completed</p>;
13+
}

0 commit comments

Comments
 (0)