-
Notifications
You must be signed in to change notification settings - Fork 27k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for
dynamicIO
experiment to route.ts
modules
`dyanmicIO` enables a semantic where any uncached IO will be excluded from prerenders. Before PPR this means any uncached IO would bail out of static generation at build time and during revalidates. Route hanlders have a similar ability to be statically generated at build and revlidate time however we recently changed the behavior to only be enabled if you explicitly opt into this using an API like `export const revalidate` or `export const dynamic = "force-static"`. With dynamic IO though we don't really need to be this restrictive. For one those configs are going to be non-operational eventually with dynamicIO but additionally almost nothing would be static if it didn anything non-trivially static or if it was already opted into caching. This commit updates the static generation rules for when `dynamicIO` is on to continue to try to statically generate GET route handlers. It also implements the logic for excluding IO and for when you use dynamic apis like `cookies()`.
- Loading branch information
Showing
17 changed files
with
694 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
test/e2e/app-dir/dynamic-io/app/routes/dynamic-cookies/route.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import type { NextRequest } from 'next/server' | ||
|
||
import { cookies } from 'next/headers' | ||
|
||
import { getSentinelValue } from '../../getSentinelValue' | ||
|
||
export async function GET(request: NextRequest, { params }: { params: {} }) { | ||
const sentinel = cookies().get('x-sentinel') | ||
return new Response( | ||
JSON.stringify({ | ||
value: getSentinelValue(), | ||
type: 'cookies', | ||
'x-sentinel': sentinel, | ||
}) | ||
) | ||
} |
16 changes: 16 additions & 0 deletions
16
test/e2e/app-dir/dynamic-io/app/routes/dynamic-headers/route.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import type { NextRequest } from 'next/server' | ||
|
||
import { headers } from 'next/headers' | ||
|
||
import { getSentinelValue } from '../../getSentinelValue' | ||
|
||
export async function GET(request: NextRequest, { params }: { params: {} }) { | ||
const sentinel = headers().get('x-sentinel') | ||
return new Response( | ||
JSON.stringify({ | ||
value: getSentinelValue(), | ||
type: 'headers', | ||
'x-sentinel': sentinel, | ||
}) | ||
) | ||
} |
27 changes: 27 additions & 0 deletions
27
test/e2e/app-dir/dynamic-io/app/routes/dynamic-stream/route.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import type { NextRequest } from 'next/server' | ||
|
||
import { getSentinelValue } from '../../getSentinelValue' | ||
|
||
export async function GET(request: NextRequest, { params }: { params: {} }) { | ||
const result = JSON.stringify({ | ||
value: getSentinelValue(), | ||
message: 'dynamic stream', | ||
}) | ||
const part1 = result.slice(0, result.length / 2) | ||
const part2 = result.slice(result.length / 2) | ||
|
||
const encoder = new TextEncoder() | ||
const chunks = [encoder.encode(part1), encoder.encode(part2)] | ||
|
||
let sent = 0 | ||
const stream = new ReadableStream({ | ||
async pull(controller) { | ||
controller.enqueue(chunks[sent++]) | ||
await new Promise((r) => setTimeout(r, 1)) | ||
if (sent === chunks.length) { | ||
controller.close() | ||
} | ||
}, | ||
}) | ||
return new Response(stream) | ||
} |
13 changes: 13 additions & 0 deletions
13
test/e2e/app-dir/dynamic-io/app/routes/dynamic-url/route.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import type { NextRequest } from 'next/server' | ||
|
||
import { getSentinelValue } from '../../getSentinelValue' | ||
|
||
export async function GET(request: NextRequest, { params }: { params: {} }) { | ||
const search = request.nextUrl.search | ||
return new Response( | ||
JSON.stringify({ | ||
value: getSentinelValue(), | ||
search, | ||
}) | ||
) | ||
} |
23 changes: 23 additions & 0 deletions
23
test/e2e/app-dir/dynamic-io/app/routes/fetch-cached/route.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type { NextRequest } from 'next/server' | ||
|
||
import { getSentinelValue } from '../../getSentinelValue' | ||
|
||
export async function GET(request: NextRequest, { params }: { params: {} }) { | ||
const fetcheda = await fetchRandomCached('a') | ||
const fetchedb = await fetchRandomCached('b') | ||
return new Response( | ||
JSON.stringify({ | ||
value: getSentinelValue(), | ||
random1: fetcheda, | ||
random2: fetchedb, | ||
}) | ||
) | ||
} | ||
|
||
const fetchRandomCached = async (entropy: string) => { | ||
const response = await fetch( | ||
'https://next-data-api-endpoint.vercel.app/api/random?b=' + entropy, | ||
{ cache: 'force-cache' } | ||
) | ||
return response.text() | ||
} |
30 changes: 30 additions & 0 deletions
30
test/e2e/app-dir/dynamic-io/app/routes/fetch-mixed/route.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import type { NextRequest } from 'next/server' | ||
|
||
import { getSentinelValue } from '../../getSentinelValue' | ||
|
||
export async function GET(request: NextRequest, { params }: { params: {} }) { | ||
const fetcheda = await fetchRandomCached('a') | ||
const fetchedb = await fetchRandomUncached('b') | ||
return new Response( | ||
JSON.stringify({ | ||
value: getSentinelValue(), | ||
random1: fetcheda, | ||
random2: fetchedb, | ||
}) | ||
) | ||
} | ||
|
||
const fetchRandomCached = async (entropy: string) => { | ||
const response = await fetch( | ||
'https://next-data-api-endpoint.vercel.app/api/random?b=' + entropy, | ||
{ cache: 'force-cache' } | ||
) | ||
return response.text() | ||
} | ||
|
||
const fetchRandomUncached = async (entropy: string) => { | ||
const response = await fetch( | ||
'https://next-data-api-endpoint.vercel.app/api/random?b=' + entropy | ||
) | ||
return response.text() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import type { NextRequest } from 'next/server' | ||
|
||
import { unstable_cache as cache } from 'next/cache' | ||
|
||
import { getSentinelValue } from '../../getSentinelValue' | ||
|
||
export async function GET(request: NextRequest, { params }: { params: {} }) { | ||
const messagea = await getCachedMessage('hello cached fast', 0) | ||
const messageb = await getCachedMessage('hello cached slow', 20) | ||
return new Response( | ||
JSON.stringify({ | ||
value: getSentinelValue(), | ||
message1: messagea, | ||
message2: messageb, | ||
}) | ||
) | ||
} | ||
|
||
async function getMessage(echo, delay) { | ||
const tag = ((Math.random() * 10000) | 0).toString(16) | ||
await new Promise((r) => setTimeout(r, delay)) | ||
return `${tag}:${echo}` | ||
} | ||
|
||
const getCachedMessage = cache(getMessage) |
Oops, something went wrong.