Skip to content
Merged
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 packages/tests-unit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"devDependencies": {
"@types/testing-library__jest-dom": "^5.14.9",
"@vitest/coverage-v8": "^2.1.3",
"diff": "^8.0.2",
"jsdom": "^22.1.0",
"vite": "5.4.9",
"vite-tsconfig-paths": "^5.0.1",
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