Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 packages/open-next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"@types/aws-lambda": "^8.10.109",
"@types/express": "5.0.0",
"@types/node": "catalog:",
"diff": "^8.0.2",
"tsc-alias": "^1.8.8",
"typescript": "catalog:"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { describe, expect, test } from "vitest";

import { patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js";
import { rule } from "@opennextjs/aws/build/patch/patches/patchFetchCacheWaitUntil.js";
import { computePatchDiff } from "./util.js";

describe("patchFetchCacheSetMissingWaitUntil", () => {
test("on minified code", () => {
Expand Down Expand Up @@ -139,115 +140,39 @@ describe("patchFetchCacheSetMissingWaitUntil", () => {
}
`;

expect(patchCode(code, rule)).toMatchInlineSnapshot(`
"if (
res.status === 200 &&
incrementalCache &&
cacheKey &&
(isCacheableRevalidate ||
useCacheOrRequestStore?.serverComponentsHmrCache)
) {
const normalizedRevalidate =
finalRevalidate >= INFINITE_CACHE
? CACHE_ONE_YEAR
: finalRevalidate
const externalRevalidate =
finalRevalidate >= INFINITE_CACHE ? false : finalRevalidate

if (workUnitStore && workUnitStore.type === 'prerender') {
// We are prerendering at build time or revalidate time with dynamicIO so we need to
// buffer the response so we can guarantee it can be read in a microtask
const bodyBuffer = await res.arrayBuffer()

const fetchedData = {
headers: Object.fromEntries(res.headers.entries()),
body: Buffer.from(bodyBuffer).toString('base64'),
status: res.status,
url: res.url,
}

// We can skip checking the serverComponentsHmrCache because we aren't in
// dev mode.

await incrementalCache.set(
cacheKey,
{
kind: CachedRouteKind.FETCH,
data: fetchedData,
revalidate: normalizedRevalidate,
},
{
fetchCache: true,
revalidate: externalRevalidate,
fetchUrl,
fetchIdx,
tags,
}
)
await handleUnlock()

// We return a new Response to the caller.
return new Response(bodyBuffer, {
headers: res.headers,
status: res.status,
statusText: res.statusText,
})
} else {
// We're cloning the response using this utility because there
// exists a bug in the undici library around response cloning.
// See the following pull request for more details:
// https://github.com/vercel/next.js/pull/73274

const [cloned1, cloned2] = cloneResponse(res)

// We are dynamically rendering including dev mode. We want to return
// the response to the caller as soon as possible because it might stream
// over a very long time.
globalThis.__openNextAls?.getStore()?.pendingPromiseRunner.add(cloned1
.arrayBuffer()
.then(async (arrayBuffer) => {
const bodyBuffer = Buffer.from(arrayBuffer)

const fetchedData = {
headers: Object.fromEntries(cloned1.headers.entries()),
body: bodyBuffer.toString('base64'),
status: cloned1.status,
url: cloned1.url,
}

useCacheOrRequestStore?.serverComponentsHmrCache?.set(
cacheKey,
fetchedData
)

if (isCacheableRevalidate) {
await incrementalCache.set(
cacheKey,
{
kind: CachedRouteKind.FETCH,
data: fetchedData,
revalidate: normalizedRevalidate,
},
{
fetchCache: true,
revalidate: externalRevalidate,
fetchUrl,
fetchIdx,
tags,
}
)
}
})
.catch((error) =>
console.warn(\`Failed to set fetch cache\`, input, error)
)
.finally(handleUnlock))


return cloned2
}
}
"
expect(
computePatchDiff("patch-fetch.js", code, rule),
).toMatchInlineSnapshot(`
"Index: patch-fetch.js
===================================================================
--- patch-fetch.js
+++ patch-fetch.js
@@ -60,9 +60,9 @@

// We are dynamically rendering including dev mode. We want to return
// the response to the caller as soon as possible because it might stream
// over a very long time.
- cloned1
+ globalThis.__openNextAls?.getStore()?.pendingPromiseRunner.add(cloned1
.arrayBuffer()
.then(async (arrayBuffer) => {
const bodyBuffer = Buffer.from(arrayBuffer)

@@ -98,10 +98,11 @@
})
.catch((error) =>
console.warn(\`Failed to set fetch cache\`, input, error)
)
- .finally(handleUnlock)
+ .finally(handleUnlock))

+
return cloned2
}
}

\\ No newline at end of file
"
`);
});

Expand Down Expand Up @@ -353,107 +278,38 @@ describe("patchFetchCacheSetMissingWaitUntil", () => {
}
}`;

expect(patchCode(code, rule)).toMatchInlineSnapshot(`
"if (
res.status === 200 &&
incrementalCache &&
cacheKey &&
(isCacheableRevalidate || requestStore?.serverComponentsHmrCache)
) {
const normalizedRevalidate =
finalRevalidate >= INFINITE_CACHE
? CACHE_ONE_YEAR
: finalRevalidate
const externalRevalidate =
finalRevalidate >= INFINITE_CACHE ? false : finalRevalidate

if (workUnitStore && workUnitStore.type === 'prerender') {
// We are prerendering at build time or revalidate time with dynamicIO so we need to
// buffer the response so we can guarantee it can be read in a microtask
const bodyBuffer = await res.arrayBuffer()

const fetchedData = {
headers: Object.fromEntries(res.headers.entries()),
body: Buffer.from(bodyBuffer).toString('base64'),
status: res.status,
url: res.url,
}

// We can skip checking the serverComponentsHmrCache because we aren't in
// dev mode.

await incrementalCache.set(
cacheKey,
{
kind: CachedRouteKind.FETCH,
data: fetchedData,
revalidate: normalizedRevalidate,
},
{
fetchCache: true,
revalidate: externalRevalidate,
fetchUrl,
fetchIdx,
tags,
}
)
await handleUnlock()

// We we return a new Response to the caller.
return new Response(bodyBuffer, {
headers: res.headers,
status: res.status,
statusText: res.statusText,
})
} else {
// We are dynamically rendering including dev mode. We want to return
// the response to the caller as soon as possible because it might stream
// over a very long time.
globalThis.__openNextAls?.getStore()?.pendingPromiseRunner.add(res
.clone()
.arrayBuffer()
.then(async (arrayBuffer) => {
const bodyBuffer = Buffer.from(arrayBuffer)

const fetchedData = {
headers: Object.fromEntries(res.headers.entries()),
body: bodyBuffer.toString('base64'),
status: res.status,
url: res.url,
}

requestStore?.serverComponentsHmrCache?.set(
cacheKey,
fetchedData
)

if (isCacheableRevalidate) {
await incrementalCache.set(
cacheKey,
{
kind: CachedRouteKind.FETCH,
data: fetchedData,
revalidate: normalizedRevalidate,
},
{
fetchCache: true,
revalidate: externalRevalidate,
fetchUrl,
fetchIdx,
tags,
}
)
}
})
.catch((error) =>
console.warn(\`Failed to set fetch cache\`, input, error)
)
.finally(handleUnlock))


return res
}
}"
expect(
computePatchDiff("patch-fetch.js", code, rule),
).toMatchInlineSnapshot(`
"Index: patch-fetch.js
===================================================================
--- patch-fetch.js
+++ patch-fetch.js
@@ -52,9 +52,9 @@
} else {
// We are dynamically rendering including dev mode. We want to return
// the response to the caller as soon as possible because it might stream
// over a very long time.
- res
+ globalThis.__openNextAls?.getStore()?.pendingPromiseRunner.add(res
.clone()
.arrayBuffer()
.then(async (arrayBuffer) => {
const bodyBuffer = Buffer.from(arrayBuffer)
@@ -91,9 +91,10 @@
})
.catch((error) =>
console.warn(\`Failed to set fetch cache\`, input, error)
)
- .finally(handleUnlock)
+ .finally(handleUnlock))

+
return res
}
}
\\ No newline at end of file
"
`);
});
});
Expand Down
Loading