{"version":3,"file":"Match.cjs","sources":["../../src/Match.tsx"],"sourcesContent":["import * as React from 'react'\nimport invariant from 'tiny-invariant'\nimport warning from 'tiny-warning'\nimport {\n  createControlledPromise,\n  getLocationChangeInfo,\n  pick,\n  rootRouteId,\n} from '@tanstack/router-core'\nimport { CatchBoundary, ErrorComponent } from './CatchBoundary'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport { CatchNotFound, isNotFound } from './not-found'\nimport { isRedirect } from './redirects'\nimport { matchContext } from './matchContext'\nimport { SafeFragment } from './SafeFragment'\nimport { renderRouteNotFound } from './renderRouteNotFound'\nimport { ScrollRestoration } from './scroll-restoration'\nimport type { AnyRoute, ParsedLocation } from '@tanstack/router-core'\n\nexport const Match = React.memo(function MatchImpl({\n  matchId,\n}: {\n  matchId: string\n}) {\n  const router = useRouter()\n  const routeId = useRouterState({\n    select: (s) => s.matches.find((d) => d.id === matchId)?.routeId as string,\n  })\n\n  invariant(\n    routeId,\n    `Could not find routeId for matchId \"${matchId}\". Please file an issue!`,\n  )\n\n  const route: AnyRoute = router.routesById[routeId]\n\n  const PendingComponent =\n    route.options.pendingComponent ?? router.options.defaultPendingComponent\n\n  const pendingElement = PendingComponent ? <PendingComponent /> : null\n\n  const routeErrorComponent =\n    route.options.errorComponent ?? router.options.defaultErrorComponent\n\n  const routeOnCatch = route.options.onCatch ?? router.options.defaultOnCatch\n\n  const routeNotFoundComponent = route.isRoot\n    ? // If it's the root route, use the globalNotFound option, with fallback to the notFoundRoute's component\n      (route.options.notFoundComponent ??\n      router.options.notFoundRoute?.options.component)\n    : route.options.notFoundComponent\n\n  const ResolvedSuspenseBoundary =\n    // If we're on the root route, allow forcefully wrapping in suspense\n    (!route.isRoot || route.options.wrapInSuspense) &&\n    (route.options.wrapInSuspense ??\n      PendingComponent ??\n      (route.options.errorComponent as any)?.preload)\n      ? React.Suspense\n      : SafeFragment\n\n  const ResolvedCatchBoundary = routeErrorComponent\n    ? CatchBoundary\n    : SafeFragment\n\n  const ResolvedNotFoundBoundary = routeNotFoundComponent\n    ? CatchNotFound\n    : SafeFragment\n\n  const resetKey = useRouterState({\n    select: (s) => s.loadedAt,\n  })\n\n  const parentRouteId = useRouterState({\n    select: (s) => {\n      const index = s.matches.findIndex((d) => d.id === matchId)\n      return s.matches[index - 1]?.routeId as string\n    },\n  })\n\n  return (\n    <>\n      <matchContext.Provider value={matchId}>\n        <ResolvedSuspenseBoundary fallback={pendingElement}>\n          <ResolvedCatchBoundary\n            getResetKey={() => resetKey}\n            errorComponent={routeErrorComponent || ErrorComponent}\n            onCatch={(error, errorInfo) => {\n              // Forward not found errors (we don't want to show the error component for these)\n              if (isNotFound(error)) throw error\n              warning(false, `Error in route match: ${matchId}`)\n              routeOnCatch?.(error, errorInfo)\n            }}\n          >\n            <ResolvedNotFoundBoundary\n              fallback={(error) => {\n                // If the current not found handler doesn't exist or it has a\n                // route ID which doesn't match the current route, rethrow the error\n                if (\n                  !routeNotFoundComponent ||\n                  (error.routeId && error.routeId !== routeId) ||\n                  (!error.routeId && !route.isRoot)\n                )\n                  throw error\n\n                return React.createElement(routeNotFoundComponent, error as any)\n              }}\n            >\n              <MatchInner matchId={matchId} />\n            </ResolvedNotFoundBoundary>\n          </ResolvedCatchBoundary>\n        </ResolvedSuspenseBoundary>\n      </matchContext.Provider>\n      {parentRouteId === rootRouteId && router.options.scrollRestoration ? (\n        <>\n          <OnRendered />\n          <ScrollRestoration />\n        </>\n      ) : null}\n    </>\n  )\n})\n\n// On Rendered can't happen above the root layout because it actually\n// renders a dummy dom element to track the rendered state of the app.\n// We render a script tag with a key that changes based on the current\n// location state.key. Also, because it's below the root layout, it\n// allows us to fire onRendered events even after a hydration mismatch\n// error that occurred above the root layout (like bad head/link tags,\n// which is common).\nfunction OnRendered() {\n  const router = useRouter()\n\n  const prevLocationRef = React.useRef<undefined | ParsedLocation<{}>>(\n    undefined,\n  )\n\n  return (\n    <script\n      key={router.state.resolvedLocation?.state.key}\n      suppressHydrationWarning\n      ref={(el) => {\n        if (\n          el &&\n          (prevLocationRef.current === undefined ||\n            prevLocationRef.current.href !==\n              router.state.resolvedLocation?.href)\n        ) {\n          router.emit({\n            type: 'onRendered',\n            ...getLocationChangeInfo(router.state),\n          })\n          prevLocationRef.current = router.state.resolvedLocation\n        }\n      }}\n    />\n  )\n}\n\nexport const MatchInner = React.memo(function MatchInnerImpl({\n  matchId,\n}: {\n  matchId: string\n}): any {\n  const router = useRouter()\n\n  const { match, key, routeId } = useRouterState({\n    select: (s) => {\n      const matchIndex = s.matches.findIndex((d) => d.id === matchId)\n      const match = s.matches[matchIndex]!\n      const routeId = match.routeId as string\n\n      const remountFn =\n        (router.routesById[routeId] as AnyRoute).options.remountDeps ??\n        router.options.defaultRemountDeps\n      const remountDeps = remountFn?.({\n        routeId,\n        loaderDeps: match.loaderDeps,\n        params: match._strictParams,\n        search: match._strictSearch,\n      })\n      const key = remountDeps ? JSON.stringify(remountDeps) : undefined\n\n      return {\n        key,\n        routeId,\n        match: pick(match, ['id', 'status', 'error']),\n      }\n    },\n    structuralSharing: true as any,\n  })\n\n  const route = router.routesById[routeId] as AnyRoute\n\n  const out = React.useMemo(() => {\n    const Comp = route.options.component ?? router.options.defaultComponent\n    if (Comp) {\n      return <Comp key={key} />\n    }\n    return <Outlet />\n  }, [key, route.options.component, router.options.defaultComponent])\n\n  const RouteErrorComponent =\n    (route.options.errorComponent ?? router.options.defaultErrorComponent) ||\n    ErrorComponent\n\n  if (match.status === 'notFound') {\n    invariant(isNotFound(match.error), 'Expected a notFound error')\n    return renderRouteNotFound(router, route, match.error)\n  }\n\n  if (match.status === 'redirected') {\n    // Redirects should be handled by the router transition. If we happen to\n    // encounter a redirect here, it's a bug. Let's warn, but render nothing.\n    invariant(isRedirect(match.error), 'Expected a redirect error')\n\n    // warning(\n    //   false,\n    //   'Tried to render a redirected route match! This is a weird circumstance, please file an issue!',\n    // )\n    throw router.getMatch(match.id)?.loadPromise\n  }\n\n  if (match.status === 'error') {\n    // If we're on the server, we need to use React's new and super\n    // wonky api for throwing errors from a server side render inside\n    // of a suspense boundary. This is the only way to get\n    // renderToPipeableStream to not hang indefinitely.\n    // We'll serialize the error and rethrow it on the client.\n    if (router.isServer) {\n      return (\n        <RouteErrorComponent\n          error={match.error as any}\n          reset={undefined as any}\n          info={{\n            componentStack: '',\n          }}\n        />\n      )\n    }\n\n    throw match.error\n  }\n\n  if (match.status === 'pending') {\n    // We're pending, and if we have a minPendingMs, we need to wait for it\n    const pendingMinMs =\n      route.options.pendingMinMs ?? router.options.defaultPendingMinMs\n\n    if (pendingMinMs && !router.getMatch(match.id)?.minPendingPromise) {\n      // Create a promise that will resolve after the minPendingMs\n      if (!router.isServer) {\n        const minPendingPromise = createControlledPromise<void>()\n\n        Promise.resolve().then(() => {\n          router.updateMatch(match.id, (prev) => ({\n            ...prev,\n            minPendingPromise,\n          }))\n        })\n\n        setTimeout(() => {\n          minPendingPromise.resolve()\n\n          // We've handled the minPendingPromise, so we can delete it\n          router.updateMatch(match.id, (prev) => ({\n            ...prev,\n            minPendingPromise: undefined,\n          }))\n        }, pendingMinMs)\n      }\n    }\n    throw router.getMatch(match.id)?.loadPromise\n  }\n\n  return out\n})\n\nexport const Outlet = React.memo(function OutletImpl() {\n  const router = useRouter()\n  const matchId = React.useContext(matchContext)\n  const routeId = useRouterState({\n    select: (s) => s.matches.find((d) => d.id === matchId)?.routeId as string,\n  })\n\n  const route = router.routesById[routeId]!\n\n  const parentGlobalNotFound = useRouterState({\n    select: (s) => {\n      const matches = s.matches\n      const parentMatch = matches.find((d) => d.id === matchId)\n      invariant(\n        parentMatch,\n        `Could not find parent match for matchId \"${matchId}\"`,\n      )\n      return parentMatch.globalNotFound\n    },\n  })\n\n  const childMatchId = useRouterState({\n    select: (s) => {\n      const matches = s.matches\n      const index = matches.findIndex((d) => d.id === matchId)\n      return matches[index + 1]?.id\n    },\n  })\n\n  if (parentGlobalNotFound) {\n    return renderRouteNotFound(router, route, undefined)\n  }\n\n  if (!childMatchId) {\n    return null\n  }\n\n  const nextMatch = <Match matchId={childMatchId} />\n\n  const pendingElement = router.options.defaultPendingComponent ? (\n    <router.options.defaultPendingComponent />\n  ) : null\n\n  if (matchId === rootRouteId) {\n    return (\n      <React.Suspense fallback={pendingElement}>{nextMatch}</React.Suspense>\n    )\n  }\n\n  return nextMatch\n})\n"],"names":["React","useRouter","useRouterState","_a","jsx","SafeFragment","CatchBoundary","CatchNotFound","jsxs","Fragment","matchContext","ErrorComponent","isNotFound","rootRouteId","ScrollRestoration","getLocationChangeInfo","match","routeId","key","pick","renderRouteNotFound","isRedirect","createControlledPromise"],"mappings":"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"}