| | import type { Dispatch } from 'react' |
| | import React, { use, useMemo } from 'react' |
| | import { isThenable } from '../../shared/lib/is-thenable' |
| | import type { AppRouterActionQueue } from './app-router-instance' |
| | import type { |
| | AppRouterState, |
| | ReducerActions, |
| | ReducerState, |
| | } from './router-reducer/router-reducer-types' |
| |
|
| | |
| | |
| | |
| | let dispatch: Dispatch<ReducerActions> | null = null |
| |
|
| | export function dispatchAppRouterAction(action: ReducerActions) { |
| | if (dispatch === null) { |
| | throw new Error( |
| | 'Internal Next.js error: Router action dispatched before initialization.' |
| | ) |
| | } |
| | dispatch(action) |
| | } |
| |
|
| | const __DEV__ = process.env.NODE_ENV !== 'production' |
| | const promisesWithDebugInfo: WeakMap< |
| | Promise<AppRouterState>, |
| | Promise<AppRouterState> & { _debugInfo?: Array<unknown> } |
| | > = __DEV__ ? new WeakMap() : (null as any) |
| |
|
| | export function useActionQueue( |
| | actionQueue: AppRouterActionQueue |
| | ): AppRouterState { |
| | const [state, setState] = React.useState<ReducerState>(actionQueue.state) |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | if (process.env.NODE_ENV !== 'production') { |
| | const { useAppDevRenderingIndicator } = |
| | require('../../next-devtools/userspace/use-app-dev-rendering-indicator') as typeof import('../../next-devtools/userspace/use-app-dev-rendering-indicator') |
| | |
| | const appDevRenderingIndicator = useAppDevRenderingIndicator() |
| |
|
| | dispatch = (action: ReducerActions) => { |
| | appDevRenderingIndicator(() => { |
| | actionQueue.dispatch(action, setState) |
| | }) |
| | } |
| | } else { |
| | dispatch = (action: ReducerActions) => |
| | actionQueue.dispatch(action, setState) |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | const stateWithDebugInfo = useMemo(() => { |
| | if (!__DEV__) { |
| | return state |
| | } |
| |
|
| | if (isThenable(state)) { |
| | |
| | |
| | let promiseWithDebugInfo = promisesWithDebugInfo.get(state) |
| | if (promiseWithDebugInfo === undefined) { |
| | const debugInfo: Array<unknown> = [] |
| | promiseWithDebugInfo = Promise.resolve(state).then((asyncState) => { |
| | if (asyncState.debugInfo !== null) { |
| | debugInfo.push(...asyncState.debugInfo) |
| | } |
| | return asyncState |
| | }) as Promise<AppRouterState> & { _debugInfo?: Array<unknown> } |
| | promiseWithDebugInfo._debugInfo = debugInfo |
| |
|
| | promisesWithDebugInfo.set(state, promiseWithDebugInfo) |
| | } |
| |
|
| | return promiseWithDebugInfo |
| | } |
| | return state |
| | }, [state]) |
| |
|
| | return isThenable(stateWithDebugInfo) |
| | ? use(stateWithDebugInfo) |
| | : stateWithDebugInfo |
| | } |
| |
|