bbeaf081ae
Leverages `AsyncLocalStorage` when available for handling static generation context and falls back to requiring render to be isolated when `AsyncLocalStorage` is not available. Note: most changes are spacing so toggling to ignore spacing may make reviewing easier
55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
import type { AsyncLocalStorage } from 'async_hooks'
|
|
import { useContext } from 'react'
|
|
import {
|
|
HeadersContext,
|
|
PreviewDataContext,
|
|
CookiesContext,
|
|
DynamicServerError,
|
|
} from './hooks-server-context'
|
|
|
|
export interface StaticGenerationStore {
|
|
inUse?: boolean
|
|
pathname?: string
|
|
revalidate?: number
|
|
fetchRevalidate?: number
|
|
isStaticGeneration?: boolean
|
|
}
|
|
|
|
export let staticGenerationAsyncStorage:
|
|
| AsyncLocalStorage<StaticGenerationStore>
|
|
| StaticGenerationStore = {}
|
|
|
|
if (process.env.NEXT_RUNTIME !== 'edge' && typeof window === 'undefined') {
|
|
staticGenerationAsyncStorage =
|
|
new (require('async_hooks').AsyncLocalStorage)()
|
|
}
|
|
|
|
function useStaticGenerationBailout(reason: string) {
|
|
const staticGenerationStore =
|
|
staticGenerationAsyncStorage && 'getStore' in staticGenerationAsyncStorage
|
|
? staticGenerationAsyncStorage?.getStore()
|
|
: staticGenerationAsyncStorage
|
|
|
|
if (staticGenerationStore?.isStaticGeneration) {
|
|
// TODO: honor the dynamic: 'force-static'
|
|
if (staticGenerationStore) {
|
|
staticGenerationStore.revalidate = 0
|
|
}
|
|
throw new DynamicServerError(reason)
|
|
}
|
|
}
|
|
|
|
export function useHeaders() {
|
|
useStaticGenerationBailout('useHeaders')
|
|
return useContext(HeadersContext)
|
|
}
|
|
|
|
export function usePreviewData() {
|
|
useStaticGenerationBailout('usePreviewData')
|
|
return useContext(PreviewDataContext)
|
|
}
|
|
|
|
export function useCookies() {
|
|
useStaticGenerationBailout('useCookies')
|
|
return useContext(CookiesContext)
|
|
}
|