-
Notifications
You must be signed in to change notification settings - Fork 27.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'canary' into fix-bug-60532-get-static-props-and-generat…
…e-static-params
- Loading branch information
Showing
30 changed files
with
1,038 additions
and
190 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
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
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
6 changes: 6 additions & 0 deletions
6
...ransforms/__testfixtures__/next-async-request-api-dynamic-props/access-props-32.input.tsx
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,6 @@ | ||
export async function GET( | ||
req: NextRequest, | ||
ctx: any, | ||
): Promise<Response> { | ||
callback(ctx.propDoesNotExist); | ||
} |
6 changes: 6 additions & 0 deletions
6
...ansforms/__testfixtures__/next-async-request-api-dynamic-props/access-props-32.output.tsx
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,6 @@ | ||
export async function GET( | ||
req: NextRequest, | ||
ctx: any, | ||
): Promise<Response> { | ||
callback(ctx.propDoesNotExist); | ||
} |
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
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
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,143 @@ | ||
import { workUnitAsyncStorage } from '../app-render/work-unit-async-storage.external' | ||
|
||
export type CacheLife = { | ||
// How long the client can cache a value without checking with the server. | ||
stale?: number | ||
// How frequently you want the cache to refresh on the server. | ||
// Stale values may be served while revalidating. | ||
revalidate?: number | ||
// In the worst case scenario, where you haven't had traffic in a while, | ||
// how stale can a value be until you prefer deopting to dynamic. | ||
// Must be longer than revalidate. | ||
expire?: number | ||
} | ||
// The equivalent header is kind of like: | ||
// Cache-Control: max-age=[stale],s-max-age=[revalidate],stale-while-revalidate=[expire-revalidate],stale-if-error=[expire-revalidate] | ||
// Except that stale-while-revalidate/stale-if-error only applies to shared caches - not private caches. | ||
|
||
const cacheLifeProfileMap: Map<string, CacheLife> = new Map() | ||
|
||
// The default revalidates relatively frequently but doesn't expire to ensure it's always | ||
// able to serve fast results but by default doesn't hang. | ||
|
||
export const defaultCacheLife = { | ||
stale: Number(process.env.__NEXT_CLIENT_ROUTER_STATIC_STALETIME), | ||
revalidate: 15 * 60, // Note: This is a new take on the defaults. | ||
expire: Infinity, | ||
} | ||
|
||
cacheLifeProfileMap.set('default', defaultCacheLife) | ||
|
||
type CacheLifeProfiles = 'default' // TODO: Generate from the config | ||
|
||
function validateCacheLife(profile: CacheLife) { | ||
if (profile.stale !== undefined) { | ||
if ((profile.stale as any) === false) { | ||
throw new Error( | ||
'Pass `Infinity` instead of `false` if you want to cache on the client forever ' + | ||
'without checking with the server.' | ||
) | ||
} else if (typeof profile.stale !== 'number') { | ||
throw new Error('The stale option must be a number of seconds.') | ||
} | ||
} | ||
if (profile.revalidate !== undefined) { | ||
if ((profile.revalidate as any) === false) { | ||
throw new Error( | ||
'Pass `Infinity` instead of `false` if you do not want to revalidate by time.' | ||
) | ||
} else if (typeof profile.revalidate !== 'number') { | ||
throw new Error('The revalidate option must be a number of seconds.') | ||
} | ||
} | ||
if (profile.expire !== undefined) { | ||
if ((profile.expire as any) === false) { | ||
throw new Error( | ||
'Pass `Infinity` instead of `false` if you want to cache on the client forever ' + | ||
'without checking with the server.' | ||
) | ||
} else if (typeof profile.expire !== 'number') { | ||
throw new Error('The expire option must be a number of seconds.') | ||
} | ||
} | ||
|
||
if (profile.revalidate !== undefined && profile.expire !== undefined) { | ||
if (profile.revalidate > profile.expire) { | ||
throw new Error( | ||
'If providing both the revalidate and expire options, ' + | ||
'the expire option must be greater than the revalidate option.' + | ||
'The expire option indicates how many seconds from the start ' + | ||
'until it can no longer be used.' | ||
) | ||
} | ||
} | ||
|
||
if (profile.stale !== undefined && profile.expire !== undefined) { | ||
if (profile.stale > profile.expire) { | ||
throw new Error( | ||
'If providing both the stale and expire options, ' + | ||
'the expire option must be greater than the stale option.' + | ||
'The expire option indicates how many seconds from the start ' + | ||
'until it can no longer be used.' | ||
) | ||
} | ||
} | ||
} | ||
|
||
export function cacheLife(profile: CacheLifeProfiles | CacheLife): void { | ||
if (!process.env.__NEXT_DYNAMIC_IO) { | ||
throw new Error( | ||
'cacheLife() is only available with the experimental.dynamicIO config.' | ||
) | ||
} | ||
|
||
const workUnitStore = workUnitAsyncStorage.getStore() | ||
if (!workUnitStore || workUnitStore.type !== 'cache') { | ||
throw new Error( | ||
'cacheLife() can only be called inside a "use cache" function.' | ||
) | ||
} | ||
|
||
if (typeof profile === 'string') { | ||
const configuredProfile = cacheLifeProfileMap.get(profile) | ||
if (configuredProfile === undefined) { | ||
if (cacheLifeProfileMap.has(profile.trim())) { | ||
throw new Error( | ||
`Unknown cacheLife profile "${profile}" is not configured in next.config.js\n` + | ||
`Did you mean "${profile.trim()}" without the spaces?` | ||
) | ||
} | ||
throw new Error( | ||
`Unknown cacheLife profile "${profile}" is not configured in next.config.js\n` + | ||
'module.exports = {\n' + | ||
' experimental: {\n' + | ||
' cacheLife: {\n' + | ||
` "${profile}": ...\n` + | ||
' }\n' + | ||
' }\n' + | ||
'}' | ||
) | ||
} | ||
profile = configuredProfile | ||
} else if ( | ||
typeof profile !== 'object' || | ||
profile === null || | ||
Array.isArray(profile) | ||
) { | ||
throw new Error( | ||
'Invalid cacheLife() option. Either pass a profile name or object.' | ||
) | ||
} else { | ||
validateCacheLife(profile) | ||
} | ||
|
||
if (profile.revalidate !== undefined) { | ||
// Track the explicit revalidate time. | ||
if ( | ||
workUnitStore.explicitRevalidate === undefined || | ||
workUnitStore.explicitRevalidate > profile.revalidate | ||
) { | ||
workUnitStore.explicitRevalidate = profile.revalidate | ||
} | ||
} | ||
} |
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 { workUnitAsyncStorage } from '../app-render/work-unit-async-storage.external' | ||
import { validateTags } from '../lib/patch-fetch' | ||
|
||
export function cacheTag(...tags: string[]): void { | ||
if (!process.env.__NEXT_DYNAMIC_IO) { | ||
throw new Error( | ||
'cacheTag() is only available with the experimental.dynamicIO config.' | ||
) | ||
} | ||
|
||
const workUnitStore = workUnitAsyncStorage.getStore() | ||
if (!workUnitStore || workUnitStore.type !== 'cache') { | ||
throw new Error( | ||
'cacheTag() can only be called inside a "use cache" function.' | ||
) | ||
} | ||
|
||
const validTags = validateTags(tags, 'cacheTag()') | ||
|
||
if (!workUnitStore.tags) { | ||
workUnitStore.tags = validTags | ||
} else { | ||
workUnitStore.tags.push(...validTags) | ||
} | ||
} |
Oops, something went wrong.