{"version":3,"sources":["../../../src/client/components/use-action-queue.ts"],"sourcesContent":["import type { Dispatch } from 'react'\nimport React, { use, useMemo, useOptimistic } from 'react'\nimport { isThenable } from '../../shared/lib/is-thenable'\nimport type { AppRouterActionQueue } from './app-router-instance'\nimport {\n  ACTION_REFRESH,\n  type AppRouterState,\n  type ReducerActions,\n  type ReducerState,\n} from './router-reducer/router-reducer-types'\n\n// The app router state lives outside of React, so we can import the dispatch\n// method directly wherever we need it, rather than passing it around via props\n// or context.\nlet dispatch: Dispatch<ReducerActions> | null = null\n\n/**\n * Called when the instant navigation test lock is released. If the router\n * is initialized, dispatches a soft refresh to fetch dynamic data. If not\n * (e.g. the lock was released before hydration finished), falls back to a\n * hard reload.\n */\nexport function refreshOnInstantNavigationUnlock() {\n  if (process.env.__NEXT_EXPOSE_TESTING_API) {\n    if (dispatch !== null) {\n      dispatch({ type: ACTION_REFRESH, bypassCacheInvalidation: true })\n    } else {\n      window.location.reload()\n    }\n  }\n}\n\nexport function dispatchAppRouterAction(action: ReducerActions) {\n  if (dispatch === null) {\n    throw new Error(\n      'Internal Next.js error: Router action dispatched before initialization.'\n    )\n  }\n  dispatch(action)\n}\n\n// Optimistic state setter for experimental_gesturePush. Only should be used\n// during a gesture transition.\nlet setGestureRouterState: ((state: ReducerState) => void) | null = null\n\nexport function dispatchGestureState(state: ReducerState) {\n  if (setGestureRouterState === null) {\n    throw new Error(\n      'Internal Next.js error: Router action dispatched before initialization.'\n    )\n  }\n  setGestureRouterState(state)\n}\n\nconst __DEV__ = process.env.NODE_ENV !== 'production'\nconst promisesWithDebugInfo: WeakMap<\n  Promise<AppRouterState>,\n  Promise<AppRouterState> & { _debugInfo?: Array<unknown> }\n> = __DEV__ ? new WeakMap() : (null as any)\n\nexport function useActionQueue(\n  actionQueue: AppRouterActionQueue\n): AppRouterState {\n  const [canonicalState, setState] = React.useState<ReducerState>(\n    actionQueue.state\n  )\n\n  // Wrap the canonical state in useOptimistic to support\n  // experimental_gesturePush. During a gesture transition, this returns a fork\n  // of the router state that represents the eventual target if/when the gesture\n  // completes. Otherwise it returns the canonical state.\n  const [state, setGesture] = useOptimistic(canonicalState)\n  if (typeof window !== 'undefined') {\n    setGestureRouterState = setGesture\n  }\n\n  // Because of a known issue that requires to decode Flight streams inside the\n  // render phase, we have to be a bit clever and assign the dispatch method to\n  // a module-level variable upon initialization. The useState hook in this\n  // module only exists to synchronize state that lives outside of React.\n  // Ideally, what we'd do instead is pass the state as a prop to root.render;\n  // this is conceptually how we're modeling the app router state, despite the\n  // weird implementation details.\n  let nextDispatch: Dispatch<ReducerActions>\n\n  if (process.env.NODE_ENV !== 'production') {\n    const { useAppDevRenderingIndicator } =\n      require('../../next-devtools/userspace/use-app-dev-rendering-indicator') as typeof import('../../next-devtools/userspace/use-app-dev-rendering-indicator')\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    const appDevRenderingIndicator = useAppDevRenderingIndicator()\n\n    nextDispatch = (action: ReducerActions) => {\n      appDevRenderingIndicator(() => {\n        actionQueue.dispatch(action, setState)\n      })\n    }\n  } else {\n    nextDispatch = (action: ReducerActions) =>\n      actionQueue.dispatch(action, setState)\n  }\n\n  if (typeof window !== 'undefined') {\n    dispatch = nextDispatch\n  }\n\n  // When navigating to a non-prefetched route, then App Router state will be\n  // blocked until the server responds. We need to transfer the `_debugInfo`\n  // from the underlying Flight response onto the top-level promise that is\n  // passed to React (via `use`) so that the latency is accurately represented\n  // in the React DevTools.\n  const stateWithDebugInfo = useMemo(() => {\n    if (!__DEV__) {\n      return state\n    }\n\n    if (isThenable(state)) {\n      // useMemo can't be used to cache a Promise since the memoized value is thrown\n      // away when we suspend. So we use a WeakMap to cache the Promise with debug info.\n      let promiseWithDebugInfo = promisesWithDebugInfo.get(state)\n      if (promiseWithDebugInfo === undefined) {\n        const debugInfo: Array<unknown> = []\n        promiseWithDebugInfo = Promise.resolve(state).then((asyncState) => {\n          if (asyncState.debugInfo !== null) {\n            debugInfo.push(...asyncState.debugInfo)\n          }\n          return asyncState\n        }) as Promise<AppRouterState> & { _debugInfo?: Array<unknown> }\n        promiseWithDebugInfo._debugInfo = debugInfo\n\n        promisesWithDebugInfo.set(state, promiseWithDebugInfo)\n      }\n\n      return promiseWithDebugInfo\n    }\n    return state\n  }, [state])\n\n  return isThenable(stateWithDebugInfo)\n    ? use(stateWithDebugInfo)\n    : stateWithDebugInfo\n}\n"],"names":["dispatchAppRouterAction","dispatchGestureState","refreshOnInstantNavigationUnlock","useActionQueue","dispatch","process","env","__NEXT_EXPOSE_TESTING_API","type","ACTION_REFRESH","bypassCacheInvalidation","window","location","reload","action","Error","setGestureRouterState","state","__DEV__","NODE_ENV","promisesWithDebugInfo","WeakMap","actionQueue","canonicalState","setState","React","useState","setGesture","useOptimistic","nextDispatch","useAppDevRenderingIndicator","require","appDevRenderingIndicator","stateWithDebugInfo","useMemo","isThenable","promiseWithDebugInfo","get","undefined","debugInfo","Promise","resolve","then","asyncState","push","_debugInfo","set","use"],"mappings":"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","ignoreList":[0]}