@studiolambda/router 1.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/router_react.cjs +1 -1
- package/dist/router_react.cjs.map +1 -1
- package/dist/router_react.js +92 -59
- package/dist/router_react.js.map +1 -1
- package/dist/src/react/components/NotFound.d.ts +5 -2
- package/dist/src/react/components/Router.d.ts +1 -1
- package/dist/src/react/context/NavigationSignalContext.d.ts +6 -1
- package/dist/src/react/context/NavigationTypeContext.d.ts +6 -1
- package/dist/src/react/context/ParamsContext.d.ts +10 -0
- package/dist/src/react/context/PathnameContext.d.ts +5 -4
- package/dist/src/react/context/TransitionContext.d.ts +0 -6
- package/dist/src/react/extractPathname.d.ts +1 -2
- package/dist/src/react/hooks/useNavigate.d.ts +15 -0
- package/dist/src/react/hooks/useNavigation.d.ts +10 -0
- package/dist/src/react/hooks/useNavigationEvents.d.ts +18 -0
- package/dist/src/react/hooks/useNavigationHandlers.d.ts +9 -0
- package/dist/src/react/hooks/useNavigationSignal.d.ts +15 -0
- package/dist/src/react/hooks/useNavigationType.d.ts +18 -0
- package/dist/src/react/hooks/useNextMatch.d.ts +11 -0
- package/dist/src/react/hooks/useParams.d.ts +1 -0
- package/dist/src/react/hooks/usePathname.d.ts +1 -0
- package/dist/src/react/hooks/usePrefetch.d.ts +52 -0
- package/dist/src/react/index.d.ts +1 -1
- package/dist/src/react/navigation/createMemoryNavigation.d.ts +5 -1
- package/package.json +1 -1
- package/dist/src/react/context/PropsContext.d.ts +0 -10
package/dist/router_react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router_react.js","names":["ReactNode","Handler","MiddlewaresProps","value","children","Middlewares","reduceRight","inner","Middleware","index","NotFound","$","_c","t0","Symbol","for","ComponentType","ReactNode","Suspense","use","useEffectEvent","useState","useTransition","Handler","Matcher","ParamsContext","NavigationContext","NavigationSignalContext","NavigationTypeContext","Resolved","Middlewares","NotFound","useNavigationHandlers","useNextMatch","useNavigationEvents","MatcherContext","TransitionContext","PathnameContext","UrlContext","extractPathname","CurrentState","match","signal","AbortSignal","navigationType","NavigationType","pathname","url","RouterProps","matcher","notFound","fallback","navigation","Navigation","transition","ReturnType","onNavigateSuccess","onNavigateError","error","Router","options","$","_c","contextNavigation","window","undefined","Error","internalTransition","t0","next","t1","currentEntry","current","setCurrent","createPrecommitHandler","createHandler","t2","event","canIntercept","hashChange","downloadRequest","destination","formData","handler","formHandler","intercept","scroll","focusReset","precommitHandler","prefetch","params","URL","onNavigate","t3","CurrentComponent","component","middlewares","t4","t5","t6","t7","t8","t9","t10","t11","t12","t13","t14","AnchorHTMLAttributes","useRef","useActiveLinkProps","PrefetchStrategy","usePrefetchEffect","Handler","Matcher","LinkRenderProps","isActive","LinkProps","Omit","HTMLAnchorElement","prefetch","once","matcher","className","props","activeExact","Link","t0","$","_c","href","t1","t2","undefined","ref","t3","exact","activeProps","t4","on","t5","resolvedClassName","t6"],"sources":["../src/react/components/Middlewares.tsx","../node_modules/react/cjs/react-compiler-runtime.production.js","../node_modules/react/cjs/react-compiler-runtime.development.js","../node_modules/react/compiler-runtime.js","../src/react/context/PropsContext.ts","../src/react/context/NavigationContext.ts","../src/react/context/NavigationSignalContext.ts","../src/react/context/NavigationTypeContext.ts","../src/react/components/NotFound.tsx","../src/react/context/TransitionContext.ts","../src/react/hooks/useNavigationHandlers.ts","../src/react/context/MatcherContext.ts","../src/react/hooks/useNextMatch.ts","../src/react/hooks/useNavigationEvents.ts","../src/react/context/PathnameContext.ts","../src/react/context/UrlContext.ts","../src/react/extractPathname.ts","../src/react/components/Router.tsx","../src/react/hooks/useActiveLinkProps.ts","../src/react/hooks/usePrefetch.ts","../src/react/hooks/usePrefetchEffect.ts","../src/react/components/Link.tsx","../src/react/hooks/useNavigation.ts","../src/react/hooks/useNavigate.ts","../src/react/hooks/useNavigationSignal.ts","../src/react/hooks/useNavigationType.ts","../src/react/hooks/useParams.ts","../src/react/hooks/useIsPending.ts","../src/react/hooks/usePathname.ts","../src/react/hooks/useSearchParams.ts","../src/react/hooks/useBack.ts","../src/react/hooks/useForward.ts","../src/react/navigation/createMemoryNavigation.ts","../src/react/createRouter.ts"],"sourcesContent":["import { type ReactNode } from 'react'\nimport { type Handler } from 'router/react:router'\n\n/**\n * Props for the Middlewares wrapper component.\n */\nexport interface MiddlewaresProps {\n /**\n * The array of middleware components to wrap around children.\n * May be `undefined` when the matched route has no middlewares.\n */\n value: Handler['middlewares']\n\n /**\n * The content to wrap inside the middleware chain. Typically\n * the matched route component rendered by the Router.\n */\n children?: ReactNode\n}\n\n/**\n * Wraps children in the given middleware components using\n * `reduceRight` so the first middleware in the array is the\n * outermost wrapper. When no middlewares are provided, renders\n * children directly.\n *\n * Each middleware component receives `children` as its only\n * prop and is responsible for rendering them (or not, in the\n * case of auth guards).\n */\nexport function Middlewares({ value, children }: MiddlewaresProps) {\n return (\n value?.reduceRight(\n (inner, Middleware, index) => <Middleware key={index}>{inner}</Middleware>,\n children\n ) ?? children\n )\n}\n","/**\n * @license React\n * react-compiler-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar ReactSharedInternals =\n require(\"react\").__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;\nexports.c = function (size) {\n return ReactSharedInternals.H.useMemoCache(size);\n};\n","/**\n * @license React\n * react-compiler-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n var ReactSharedInternals =\n require(\"react\").__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;\n exports.c = function (size) {\n var dispatcher = ReactSharedInternals.H;\n null === dispatcher &&\n console.error(\n \"Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\\n1. You might have mismatching versions of React and the renderer (such as React DOM)\\n2. You might be breaking the Rules of Hooks\\n3. You might have more than one copy of React in the same app\\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.\"\n );\n return dispatcher.useMemoCache(size);\n };\n })();\n","/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-compiler-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-compiler-runtime.development.js');\n}\n","import { createContext } from 'react'\n\n/**\n * Provides the route parameters extracted from the matched URL\n * pattern as a string-keyed record. Defaults to an empty object\n * when no route has been matched yet.\n *\n * Consumed via the `useParams` hook. The Router component\n * updates this context on every successful navigation with\n * the newly extracted parameters.\n */\nexport const ParamsContext = createContext<Record<string, string>>({})\n","import { createContext } from 'react'\n\n/**\n * Provides the native browser Navigation object through React context.\n *\n * Defaults to `null` — the Router component provides the real value.\n * This avoids accessing `window.navigation` at module scope, which\n * would crash in SSR, testing, or non-browser environments.\n *\n * The `useNavigation` hook throws a descriptive error when consumed\n * without a provider.\n */\nexport const NavigationContext = createContext<Navigation | null>(null)\n","import { createContext } from 'react'\n\n/**\n * Provides the AbortSignal from the current NavigateEvent.\n * Consumers can use this to cancel in-flight async operations\n * (fetches, transitions, etc.) when a navigation is superseded\n * by another one.\n */\nexport const NavigationSignalContext = createContext<AbortSignal | null>(null)\n","import { createContext } from 'react'\n\n/**\n * Provides the navigation type of the most recent NavigateEvent\n * (`push`, `replace`, `reload`, or `traverse`). Allows route\n * components to vary behavior based on how they were reached.\n */\nexport const NavigationTypeContext = createContext<NavigationType | null>(null)\n","/**\n * Default fallback component rendered when no registered\n * route matches the current URL. Can be overridden via the\n * `notFound` prop on the Router component.\n */\nexport function NotFound() {\n return <div>Not Found</div>\n}\n","import { type TransitionFunction, createContext, useTransition } from 'react'\n\n/**\n * Provides the `[isPending, startTransition]` tuple from\n * `useTransition()` to descendant components. The Router and\n * navigation handlers use this to wrap state updates in\n * concurrent transitions.\n *\n * Defaults to `null` — a parent component must provide a real\n * `useTransition()` tuple via `<TransitionContext value={...}>`.\n * Using the standalone `startTransition` from React as a default\n * would silently break `isPending` tracking, so we require an\n * explicit provider instead.\n */\nexport const TransitionContext = createContext<ReturnType<typeof useTransition> | null>(null)\n\n/**\n * Type alias for the startTransition function extracted from\n * the useTransition tuple.\n */\nexport type StartTransitionFn = (callback: TransitionFunction) => void\n","import { type TransitionFunction, use, useTransition } from 'react'\nimport { TransitionContext } from 'router/react:context/TransitionContext'\nimport { type PrefetchFunc, type PrefetchContext } from 'router/react:router'\n\n/**\n * Options for creating a precommit handler that forwards\n * route context to the prefetch function.\n */\nexport interface PrecommitHandlerOptions {\n /**\n * The prefetch function from the matched route handler.\n * When undefined, no precommit handler is created.\n */\n readonly prefetch?: PrefetchFunc\n\n /**\n * Dynamic route parameters extracted from the matched\n * URL pattern.\n */\n readonly params: Record<string, string>\n\n /**\n * The destination URL being navigated to.\n */\n readonly url: URL\n}\n\n/**\n * Creates handler functions for the Navigation API's\n * `event.intercept()` method. The precommit handler runs\n * prefetch logic before the URL commits; the handler runs\n * the React state transition after the URL commits.\n *\n * Accepts an optional `transition` tuple to use directly.\n * When omitted, reads from TransitionContext instead. The\n * Router component passes its own transition tuple here to\n * avoid a circular dependency — the Router provides the\n * TransitionContext in its JSX return, but needs the\n * handlers during render before that provider exists in\n * the tree.\n *\n * @param transition - Optional `useTransition()` tuple to\n * use instead of reading from TransitionContext. Pass\n * this when calling from within the component that\n * provides TransitionContext.\n * @throws When no transition tuple is provided and the\n * hook is used outside a TransitionContext provider.\n */\nexport function useNavigationHandlers(transition?: ReturnType<typeof useTransition>) {\n const contextTransition = transition ?? use(TransitionContext)\n\n if (contextTransition === null) {\n throw new Error('useNavigationHandlers requires a <Router> or <TransitionContext> provider')\n }\n\n const [, startTransition] = contextTransition\n\n /**\n * Creates a precommit handler that constructs a\n * `PrefetchContext` from the matched route information\n * and forwards it to the route's prefetch function.\n * Runs before the URL commits, so no React state\n * transitions are needed here.\n */\n function createPrecommitHandler(options: PrecommitHandlerOptions) {\n if (options.prefetch === undefined) {\n return undefined\n }\n\n const prefetch = options.prefetch\n\n return async function (controller: NavigationPrecommitController) {\n const context: PrefetchContext = {\n params: options.params,\n url: options.url,\n controller,\n }\n\n await prefetch(context)\n }\n }\n\n /**\n * Creates a post-commit handler that wraps the state\n * update in a React async transition for concurrent\n * rendering. The promise resolves only after the async\n * transition callback completes, ensuring the Navigation\n * API waits for React to finish rendering before firing\n * `navigatesuccess` and performing scroll restoration.\n *\n * @param callback - The transition function containing\n * the state update to perform after the URL commits.\n */\n function createHandler(callback: TransitionFunction) {\n return function handler() {\n return new Promise<void>(function (resolve, reject) {\n startTransition(async function () {\n try {\n await callback()\n resolve()\n } catch (error) {\n reject(error)\n }\n })\n })\n }\n }\n\n return { createPrecommitHandler, createHandler }\n}\n","import { createContext } from 'react'\nimport { type Handler } from 'router/react:router'\nimport { createMatcher, type Matcher } from 'router:matcher'\n\n/**\n * Provides the route Matcher instance through React context.\n * Defaults to an empty matcher with no registered routes.\n *\n * The Router component and hooks like `useNextMatch` and\n * `usePrefetch` consume this context to resolve URLs against\n * registered route patterns. Override by passing a `matcher`\n * prop to Router or wrapping with `<MatcherContext value={...}>`.\n */\nexport const MatcherContext = createContext<Matcher<Handler>>(createMatcher())\n","import { type ComponentType, use } from 'react'\nimport { MatcherContext } from 'router/react:context/MatcherContext'\nimport { type Handler } from 'router/react:router'\nimport { type Matcher, type Resolved } from 'router:matcher'\n\n/**\n * Options for the `useNextMatch` hook.\n */\nexport interface NextMatchOptions {\n /**\n * Optional matcher override. When omitted the hook reads\n * from `MatcherContext`.\n */\n matcher?: Matcher<Handler>\n}\n\n/**\n * Returns a function that resolves a destination URL into a\n * route match. When no route matches, a fallback `Resolved`\n * is returned using the provided `notFound` component.\n *\n * Used internally by the Router to determine which component\n * to render for an incoming navigation event.\n *\n * @param options - Optional matcher override.\n * @returns A resolver function that takes a destination URL\n * and a not-found component, returning the resolved match.\n */\nexport function useNextMatch(options?: NextMatchOptions) {\n const matcher = options?.matcher ?? use(MatcherContext)\n\n /**\n * Resolves a destination URL string into a route match.\n * Falls back to a synthetic match wrapping the `notFound`\n * component when the URL doesn't match any registered route.\n *\n * @param destination - The full destination URL string, or\n * `null` when no URL is available (e.g. initial load\n * without a current entry).\n * @param notFound - The component to render when no route\n * matches the destination.\n * @returns The resolved route match with handler and params.\n */\n return function (destination: string | null, notFound: ComponentType): Resolved<Handler> {\n const handler: Handler = { component: notFound }\n const fallbackResolved: Resolved<Handler> = { handler, params: {} }\n\n if (!destination) {\n return fallbackResolved\n }\n\n return matcher.match(new URL(destination, 'http://localhost').pathname) ?? fallbackResolved\n }\n}\n","import { useEffect, useEffectEvent } from 'react'\n\n/**\n * Callbacks for navigation lifecycle events. All callbacks\n * are optional — only provided callbacks are subscribed.\n */\nexport interface NavigationEventHandlers {\n /**\n * Called when a same-document navigation is initiated.\n * The Router uses this to intercept the event, match\n * the destination URL, and trigger a React transition.\n */\n readonly onNavigate?: (event: NavigateEvent) => void\n\n /**\n * Called after a navigation completes successfully.\n * Fires in sync with the Navigation API's\n * `navigatesuccess` event.\n */\n readonly onNavigateSuccess?: () => void\n\n /**\n * Called when a navigation fails. Receives the error\n * extracted from the Navigation API's `navigateerror`\n * ErrorEvent.\n *\n * @param error - The error that caused the navigation\n * to fail.\n */\n readonly onNavigateError?: (error: unknown) => void\n}\n\n/**\n * Subscribes to the Navigation API's `navigate`,\n * `navigatesuccess`, and `navigateerror` events on the\n * given navigation object. All callbacks are wrapped in\n * `useEffectEvent` so the effects only depend on the\n * navigation instance itself — inline arrow functions\n * from the caller don't cause unnecessary re-subscriptions.\n *\n * Cleans up all listeners on unmount or when the navigation\n * instance changes.\n *\n * @param navigation - The Navigation object to subscribe to.\n * @param handlers - Callbacks for each navigation lifecycle\n * event. All are optional.\n */\nexport function useNavigationEvents(navigation: Navigation, handlers: NavigationEventHandlers) {\n /**\n * Stable wrapper for the navigate event callback. Reads\n * the latest `onNavigate` handler on each invocation\n * without causing the subscription effect to re-run.\n */\n const onNavigate = useEffectEvent(function (event: NavigateEvent) {\n handlers.onNavigate?.(event)\n })\n\n /**\n * Stable wrapper for the navigatesuccess callback.\n */\n const onSuccess = useEffectEvent(function () {\n handlers.onNavigateSuccess?.()\n })\n\n /**\n * Stable wrapper for the navigateerror callback.\n * Extracts the error from the ErrorEvent before\n * forwarding to the handler.\n */\n const onError = useEffectEvent(function (event: Event) {\n handlers.onNavigateError?.((event as ErrorEvent).error)\n })\n\n /**\n * Subscribes to all three navigation lifecycle events.\n * A single effect handles all subscriptions since they\n * share the same dependency (the navigation object) and\n * the same lifecycle (subscribe on mount, clean up on\n * unmount or navigation change).\n */\n useEffect(\n function () {\n navigation.addEventListener('navigate', onNavigate)\n navigation.addEventListener('navigatesuccess', onSuccess)\n navigation.addEventListener('navigateerror', onError)\n\n return function () {\n navigation.removeEventListener('navigate', onNavigate)\n navigation.removeEventListener('navigatesuccess', onSuccess)\n navigation.removeEventListener('navigateerror', onError)\n }\n },\n [navigation]\n )\n}\n","import { createContext } from 'react'\n\n/**\n * Provides the current URL pathname to descendant components.\n * Updated by the Router on every navigation with the pathname\n * extracted from the destination URL.\n *\n * Consumed by the `usePathname` hook and the `Link` component\n * for active link detection. Defaults to `'/'` when no Router\n * is present in the tree.\n */\nexport const PathnameContext = createContext<string>('/')\n","import { createContext } from 'react'\n\n/**\n * Provides the full committed URL string to descendant\n * components. Updated by the Router on every navigation\n * with the destination URL. Defaults to `null` when no\n * Router is present in the tree.\n *\n * Consumed by `useSearchParams` to derive search parameters\n * from React state rather than reading the mutable\n * `navigation.currentEntry` during render — preventing\n * subscription tearing in concurrent mode.\n */\nexport const UrlContext = createContext<string | null>(null)\n","/**\n * Extracts the pathname portion from a URL string. Uses a\n * dummy base URL to handle both absolute and relative paths\n * correctly. Returns `'/'` when the input is null, undefined,\n * or an empty string.\n *\n * Used by the Router (to extract pathname from navigation\n * destination URLs), Link (for active link comparison), and\n * usePrefetch (to match URLs against registered routes).\n *\n * @param url - The URL string to extract a pathname from.\n * May be absolute (`https://example.com/foo`), relative\n * (`/foo/bar`), or nullish.\n * @returns The pathname string, or `'/'` when no URL is\n * provided.\n */\nexport function extractPathname(url: string | null | undefined): string {\n if (!url) {\n return '/'\n }\n\n return new URL(url, 'http://localhost').pathname\n}\n","import {\n type ComponentType,\n type ReactNode,\n Suspense,\n use,\n useEffectEvent,\n useState,\n useTransition,\n} from 'react'\nimport { type Handler } from 'router/react:router'\nimport { type Matcher } from 'router:matcher'\nimport { ParamsContext } from 'router/react:context/PropsContext'\nimport { NavigationContext } from 'router/react:context/NavigationContext'\nimport { NavigationSignalContext } from 'router/react:context/NavigationSignalContext'\nimport { NavigationTypeContext } from 'router/react:context/NavigationTypeContext'\nimport { type Resolved } from 'router:matcher'\nimport { Middlewares } from 'router/react:components/Middlewares'\nimport { NotFound } from 'router/react:components/NotFound'\nimport { useNavigationHandlers } from 'router/react:hooks/useNavigationHandlers'\nimport { useNextMatch } from 'router/react:hooks/useNextMatch'\nimport { useNavigationEvents } from 'router/react:hooks/useNavigationEvents'\nimport { MatcherContext } from 'router/react:context/MatcherContext'\nimport { TransitionContext } from 'router/react:context/TransitionContext'\nimport { PathnameContext } from 'router/react:context/PathnameContext'\nimport { UrlContext } from 'router/react:context/UrlContext'\nimport { extractPathname } from 'router/react:extractPathname'\n\n/**\n * Internal state tracked alongside the resolved route match.\n * Includes the AbortSignal and navigation type from the\n * NavigateEvent that produced this match.\n */\ninterface CurrentState {\n /**\n * The resolved route match containing the handler\n * configuration and extracted URL parameters.\n */\n match: Resolved<Handler>\n\n /**\n * The AbortSignal from the NavigateEvent that produced\n * this match. Aborts when the navigation is cancelled\n * by a newer navigation or the user pressing Stop.\n * Null for the initial render before any navigation event.\n */\n signal: AbortSignal | null\n\n /**\n * The type of navigation that produced this match\n * (`push`, `replace`, `reload`, or `traverse`).\n * Null for the initial render before any navigation event.\n */\n navigationType: NavigationType | null\n\n /**\n * The pathname extracted from the destination URL for this\n * navigation. Used by descendant components to determine\n * active links and read the current location.\n */\n pathname: string\n\n /**\n * The full destination URL string for this navigation.\n * Used by `useSearchParams` to derive search parameters\n * from React state rather than reading the mutable\n * `navigation.currentEntry` during render.\n */\n url: string | null\n}\n\n/**\n * Props accepted by the Router component.\n */\nexport interface RouterProps {\n /**\n * Route matcher instance with registered routes. When\n * omitted, falls back to the value from MatcherContext.\n */\n matcher?: Matcher<Handler>\n\n /**\n * Component to render when no route matches the current\n * URL. Defaults to the built-in NotFound component.\n */\n notFound?: ComponentType\n\n /**\n * Suspense fallback shown while lazy route components\n * or suspended middleware are loading.\n */\n fallback?: ReactNode\n\n /**\n * Native Navigation object override. Defaults to the value\n * from NavigationContext, which itself falls back to\n * `window.navigation`. Useful for testing or providing\n * a custom navigation instance.\n */\n navigation?: Navigation\n\n /**\n * Optional `useTransition()` tuple override. When omitted\n * the Router calls `useTransition()` internally. Provide\n * this when you need to read `isPending` above the Router\n * in the component tree, or to share a single transition\n * across multiple Routers.\n */\n transition?: ReturnType<typeof useTransition>\n\n /**\n * Callback invoked after a navigation completes successfully.\n * Fires in sync with the Navigation API's `navigatesuccess`\n * event. Wrapped in `useEffectEvent` internally so inline\n * arrow functions don't cause effect churn.\n */\n onNavigateSuccess?: () => void\n\n /**\n * Callback invoked when a navigation fails. Receives the\n * error from the Navigation API's `navigateerror` event.\n * Wrapped in `useEffectEvent` internally so inline arrow\n * functions don't cause effect churn.\n *\n * @param error - The error that caused the navigation\n * to fail.\n */\n onNavigateError?: (error: unknown) => void\n}\n\n/**\n * Top-level router component that listens to the Navigation API's\n * `navigate` event, matches the destination URL against registered\n * routes, and renders the matched component inside Suspense with\n * middleware support.\n *\n * Calls `useTransition()` internally to wrap navigation state\n * updates in concurrent transitions. An optional `transition` prop\n * allows overriding this when the consuming code needs to read\n * `isPending` above the Router in the tree.\n *\n * Accepts optional `navigation` and `matcher` overrides; falls back\n * to context values when not provided. The navigation object\n * ultimately falls back to `window.navigation` when neither a prop\n * nor a context value is available.\n *\n * Provides several contexts to descendant components:\n * - `TransitionContext` — the `[isPending, startTransition]` tuple\n * - `NavigationContext` — the Navigation object\n * - `MatcherContext` — the route matcher\n * - `NavigationTypeContext` — the current navigation type\n * - `NavigationSignalContext` — the current AbortSignal\n * - `PathnameContext` — the current URL pathname\n * - `ParamsContext` — the extracted route parameters\n */\nexport function Router(options: RouterProps) {\n const contextNavigation = use(NavigationContext)\n const navigation: Navigation =\n options.navigation ??\n contextNavigation ??\n (typeof window !== 'undefined' ? window.navigation : undefined)!\n\n if (navigation === undefined || navigation === null) {\n throw new Error(\n 'Router requires a navigation prop, NavigationContext provider, ' +\n 'or browser Navigation API support. ' +\n 'Use createMemoryNavigation() for SSR or non-browser environments.'\n )\n }\n const matcher: Matcher<Handler> = options.matcher ?? use(MatcherContext)\n const internalTransition = useTransition()\n const transition = options.transition ?? internalTransition\n const next = useNextMatch({ matcher })\n const notFound = options.notFound ?? NotFound\n\n const [current, setCurrent] = useState<CurrentState>(function () {\n const url = navigation.currentEntry?.url ?? null\n\n return {\n match: next(url, notFound),\n signal: null,\n navigationType: null,\n pathname: extractPathname(url),\n url,\n }\n })\n\n /**\n * Extracts navigation handler factories using the resolved\n * transition tuple directly, bypassing TransitionContext.\n * This is necessary because Router provides TransitionContext\n * in its JSX return, which hasn't rendered at this point.\n */\n const { createPrecommitHandler, createHandler } = useNavigationHandlers(transition)\n\n /**\n * Central navigate event handler. Intercepts all same-document\n * navigations including link clicks, form submissions,\n * back/forward buttons, and programmatic navigation.\n *\n * Skips non-interceptable navigations, hash-only changes,\n * and download requests. For form submissions with a dedicated\n * `formHandler`, delegates to that handler instead of the\n * normal component render flow.\n */\n const onNavigate = useEffectEvent(function (event: NavigateEvent) {\n if (!event.canIntercept || event.hashChange || event.downloadRequest !== null) {\n return\n }\n\n const match = next(event.destination.url, notFound)\n\n if (event.formData !== null && match.handler.formHandler !== undefined) {\n event.intercept({\n scroll: match.handler.scroll,\n focusReset: match.handler.focusReset,\n async handler() {\n await match.handler.formHandler!(event.formData!, event)\n },\n })\n\n return\n }\n\n const precommitHandler = createPrecommitHandler({\n prefetch: match.handler.prefetch,\n params: match.params,\n url: new URL(event.destination.url),\n })\n\n const handler = createHandler(function () {\n setCurrent({\n match,\n signal: event.signal,\n navigationType: event.navigationType,\n pathname: extractPathname(event.destination.url),\n url: event.destination.url,\n })\n })\n\n event.intercept({\n handler,\n precommitHandler,\n scroll: match.handler.scroll,\n focusReset: match.handler.focusReset,\n })\n })\n\n useNavigationEvents(navigation, {\n onNavigate,\n onNavigateSuccess: options.onNavigateSuccess,\n onNavigateError: options.onNavigateError,\n })\n\n const CurrentComponent = current.match.handler.component\n const middlewares = current.match.handler.middlewares\n\n return (\n <TransitionContext value={transition}>\n <NavigationContext value={navigation}>\n <MatcherContext value={matcher}>\n <NavigationTypeContext value={current.navigationType}>\n <NavigationSignalContext value={current.signal}>\n <PathnameContext value={current.pathname}>\n <UrlContext value={current.url}>\n <ParamsContext value={current.match.params}>\n <Suspense fallback={options.fallback}>\n <Middlewares value={middlewares}>\n <CurrentComponent />\n </Middlewares>\n </Suspense>\n </ParamsContext>\n </UrlContext>\n </PathnameContext>\n </NavigationSignalContext>\n </NavigationTypeContext>\n </MatcherContext>\n </NavigationContext>\n </TransitionContext>\n )\n}\n","import { use } from 'react'\nimport { PathnameContext } from 'router/react:context/PathnameContext'\nimport { extractPathname } from 'router/react:extractPathname'\n\n/**\n * Options for the `useActiveLinkProps` hook.\n */\nexport interface ActiveLinkOptions {\n /**\n * When true, the link is only considered active when\n * the current pathname exactly matches the href\n * pathname. When false, the link is active when the\n * current pathname starts with the href pathname,\n * which is useful for parent navigation items that\n * should highlight when any child route is active.\n *\n * Defaults to `true`.\n */\n exact?: boolean\n}\n\n/**\n * Props returned by the hook to spread onto an anchor\n * element for active link styling and accessibility.\n */\nexport interface ActiveLinkProps {\n /**\n * Present (set to `true`) when the link is active.\n * Absent (`undefined`) when inactive. Use the\n * `a[data-active]` CSS selector for styling.\n */\n 'data-active': true | undefined\n\n /**\n * Set to `'page'` when the link is active to indicate\n * to assistive technologies that this link represents\n * the current page. Absent when inactive.\n */\n 'aria-current': 'page' | undefined\n}\n\n/**\n * Computes active link attributes for an anchor element\n * by comparing its href against the current pathname from\n * the Router's PathnameContext.\n *\n * Returns a props object containing `data-active` and\n * `aria-current` attributes ready to spread onto an `<a>`\n * element or any element that should reflect active state.\n *\n * Also returns an `isActive` boolean for conditional logic\n * like dynamic class names.\n *\n * Must be used inside a `<Router>` component tree where\n * `PathnameContext` is provided.\n *\n * @param href - The href to compare against the current\n * pathname. When undefined, the link is never active.\n * @param options - Optional configuration for exact vs\n * prefix matching.\n * @returns An object with `isActive` boolean and `props`\n * to spread onto the element.\n *\n * @example\n * ```tsx\n * function NavItem({ href, children }: NavItemProps) {\n * const { isActive, props } = useActiveLinkProps(href)\n *\n * return (\n * <a href={href} className={isActive ? 'active' : ''} {...props}>\n * {children}\n * </a>\n * )\n * }\n * ```\n */\nexport function useActiveLinkProps(\n href: string | undefined,\n options?: ActiveLinkOptions\n): { isActive: boolean; props: ActiveLinkProps } {\n const currentPathname = use(PathnameContext)\n const isExact = options?.exact ?? true\n\n const isActive = isActiveHref(href, currentPathname, isExact)\n\n return {\n isActive,\n props: {\n 'data-active': isActive || undefined,\n 'aria-current': isActive ? 'page' : undefined,\n },\n }\n}\n\n/**\n * Determines whether an href should be considered active\n * by comparing its pathname against the current router\n * pathname. Handles undefined hrefs, exact matching, and\n * prefix matching for parent-level navigation items.\n *\n * @param href - The href string to test. Returns false\n * when undefined.\n * @param currentPathname - The current pathname from the\n * router's PathnameContext.\n * @param isExact - Whether to require an exact match or\n * allow prefix matching.\n * @returns True when the href should be marked as active.\n */\nfunction isActiveHref(\n href: string | undefined,\n currentPathname: string,\n isExact: boolean\n): boolean {\n if (href === undefined) {\n return false\n }\n\n const linkPathname = extractPathname(href)\n\n if (isExact) {\n return linkPathname === currentPathname\n }\n\n return currentPathname === linkPathname || currentPathname.startsWith(linkPathname + '/')\n}\n","import { use } from 'react'\nimport { MatcherContext } from 'router/react:context/MatcherContext'\nimport { type Handler, type PrefetchContext } from 'router/react:router'\nimport { type Matcher } from 'router:matcher'\n\n/**\n * Options for the `usePrefetch` hook.\n */\nexport interface PrefetchOptions {\n /**\n * Optional matcher override. When omitted the hook reads\n * from `MatcherContext`.\n */\n matcher?: Matcher<Handler>\n}\n\n/**\n * Tracks URL pathnames that have already been prefetched,\n * keyed by matcher instance. Using a WeakMap ensures that\n * each matcher (and therefore each Router) gets its own\n * dedup set, and the set is garbage-collected when the\n * matcher is no longer referenced. This prevents cross-\n * contamination between independent Router instances and\n * between isolated test environments.\n */\nconst prefetchedByMatcher = new WeakMap<Matcher<Handler>, Set<string>>()\n\n/**\n * Returns a function that triggers the prefetch logic for a\n * given URL by resolving it against the matcher and calling\n * the route's prefetch function. Used by the Link component\n * for hover and viewport prefetch strategies.\n *\n * Each pathname is prefetched at most once per matcher\n * instance per page session. Subsequent calls with the same\n * pathname are no-ops, preventing thundering-herd problems\n * when many Links point to the same destination.\n *\n * Since prefetch triggered from Link happens outside of a\n * navigation event, a stub NavigationPrecommitController is\n * passed (the redirect capability is not meaningful here).\n *\n * @param options - Optional matcher override.\n * @returns A function that accepts a URL string and invokes\n * the matched route's prefetch handler, if any.\n */\nexport function usePrefetch(options?: PrefetchOptions) {\n const matcher = options?.matcher ?? use(MatcherContext)\n\n /**\n * Triggers prefetch for the given URL by matching it against\n * registered routes and calling the route's prefetch function\n * with a context containing the matched params, the parsed\n * URL, and a stub controller. Extracts the pathname from the\n * URL before matching to handle both absolute and relative URLs.\n *\n * Returns early without calling the handler when the pathname\n * has already been prefetched or is currently in-flight for\n * this matcher instance.\n *\n * @param url - The URL or path to prefetch data for.\n * @returns The prefetch promise, or undefined if no prefetch\n * handler is registered for the matched route or if the\n * pathname has already been prefetched.\n */\n return function (url: string) {\n const parsed = new URL(url, 'http://localhost')\n const match = matcher.match(parsed.pathname)\n\n if (match?.handler.prefetch === undefined) {\n return\n }\n\n let prefetched = prefetchedByMatcher.get(matcher)\n\n if (prefetched === undefined) {\n prefetched = new Set()\n prefetchedByMatcher.set(matcher, prefetched)\n }\n\n if (prefetched.has(parsed.pathname)) {\n return\n }\n\n prefetched.add(parsed.pathname)\n\n /**\n * Stub controller for prefetch outside of navigation events.\n * Redirect and addHandler are no-ops in this context since\n * there is no actual navigation to modify.\n */\n const stubController: NavigationPrecommitController = {\n redirect() {},\n addHandler() {},\n }\n\n const context: PrefetchContext = {\n params: match.params,\n url: parsed,\n controller: stubController,\n }\n\n return match.handler.prefetch(context)\n }\n}\n","import { type RefObject, useEffect, useEffectEvent } from 'react'\nimport { usePrefetch } from 'router/react:hooks/usePrefetch'\nimport { type Handler } from 'router/react:router'\nimport { type Matcher } from 'router:matcher'\n\n/**\n * Prefetch trigger strategy. Determines which DOM event\n * activates the prefetch for the target element.\n *\n * - `viewport` — prefetch fires when the element enters\n * the viewport via an IntersectionObserver.\n * - `hover` — prefetch fires on `mouseenter`.\n */\nexport type PrefetchStrategy = 'viewport' | 'hover'\n\n/**\n * Options for the `usePrefetchEffect` hook.\n */\nexport interface PrefetchEffectOptions {\n /**\n * The URL to prefetch. When undefined, the effect is\n * a no-op (no observer or listener is attached).\n */\n href: string | undefined\n\n /**\n * Prefetch trigger strategy. When undefined, the effect\n * is a no-op — no proactive prefetch is set up.\n */\n on: PrefetchStrategy | undefined\n\n /**\n * Whether to only prefetch once. When true, hover\n * listeners use the `{ once }` option and viewport\n * observers disconnect after the first intersection.\n * Defaults to `true`.\n */\n once?: boolean\n\n /**\n * Optional matcher override. When omitted, reads from\n * `MatcherContext` via `usePrefetch`.\n */\n matcher?: Matcher<Handler>\n}\n\n/**\n * Attaches prefetch behavior to a DOM element via a ref.\n * Sets up an IntersectionObserver (for `viewport` strategy)\n * or a mouseenter listener (for `hover` strategy) that\n * triggers route prefetching when activated.\n *\n * When `on` is undefined or `href` is undefined, no\n * observer or listener is attached — the hook is a no-op.\n *\n * This hook is used internally by the Link component and\n * can also be used standalone to add prefetch behavior to\n * any DOM element.\n *\n * @param ref - A ref to the DOM element to observe. The\n * element must be mounted before the effect runs.\n * @param options - Configuration for the prefetch behavior\n * including the URL, trigger strategy, and matcher.\n *\n * @example\n * ```tsx\n * function Card({ href }: { href: string }) {\n * const ref = useRef<HTMLDivElement>(null)\n *\n * usePrefetchEffect(ref, { href, on: 'viewport' })\n *\n * return <div ref={ref}>...</div>\n * }\n * ```\n */\nexport function usePrefetchEffect(ref: RefObject<Element | null>, options: PrefetchEffectOptions) {\n const { href, on, once = true, matcher } = options\n const prefetchRoute = usePrefetch({ matcher })\n\n /**\n * IntersectionObserver callback that triggers prefetch\n * when the element enters the viewport. Disconnects\n * the observer after the first intersection when `once`\n * is true.\n */\n const onViewportIntersection = useEffectEvent<IntersectionObserverCallback>(\n function (entries, observer) {\n for (const entry of entries) {\n if (entry.isIntersecting && href !== undefined) {\n void prefetchRoute(href)\n }\n }\n\n if (once) {\n observer.disconnect()\n }\n }\n )\n\n /**\n * Mouse enter callback that triggers prefetch when the\n * user hovers over the element.\n */\n const onHover = useEffectEvent<EventListener>(function () {\n if (href !== undefined) {\n void prefetchRoute(href)\n }\n })\n\n /**\n * Sets up the prefetch observer or listener based on the\n * chosen strategy. When `on` is undefined, no setup is\n * performed. Cleans up on unmount or when the strategy,\n * once flag, or href changes.\n */\n useEffect(\n function () {\n if (on === undefined) {\n return\n }\n\n const current = ref.current\n\n if (current === null) {\n return\n }\n\n switch (on) {\n case 'hover': {\n current.addEventListener('mouseenter', onHover, { once })\n\n return function () {\n current.removeEventListener('mouseenter', onHover)\n }\n }\n case 'viewport': {\n const observer = new IntersectionObserver(onViewportIntersection)\n\n observer.observe(current)\n\n return function () {\n observer.disconnect()\n }\n }\n }\n },\n [on, once, href, ref]\n )\n}\n","import { type AnchorHTMLAttributes, useRef } from 'react'\nimport { useActiveLinkProps } from 'router/react:hooks/useActiveLinkProps'\nimport { type PrefetchStrategy, usePrefetchEffect } from 'router/react:hooks/usePrefetchEffect'\nimport { type Handler } from 'router/react:router'\nimport { type Matcher } from 'router:matcher'\n\n/**\n * State passed to the className function variant, allowing\n * consumers to dynamically compute class names based on the\n * link's active state.\n */\nexport interface LinkRenderProps {\n /**\n * Whether this link's href matches the current pathname.\n * True for both exact and prefix matches depending on\n * the `activeExact` prop.\n */\n readonly isActive: boolean\n}\n\n/**\n * Props for the Link component, extending standard anchor\n * element attributes with router-specific prefetch behavior\n * and active link detection.\n */\nexport interface LinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'className'> {\n /**\n * Prefetch trigger strategy. When set to `'hover'`,\n * prefetch fires on mouseenter. When set to `'viewport'`,\n * prefetch fires when the link enters the viewport via\n * IntersectionObserver. When omitted, no proactive\n * prefetch is performed — the Navigation API handles\n * it during the click navigation.\n */\n prefetch?: PrefetchStrategy\n\n /**\n * Whether to only prefetch once. When true, hover\n * listeners use the `{ once }` option and viewport\n * observers disconnect after the first intersection.\n * Defaults to `true`.\n */\n once?: boolean\n\n /**\n * Optional matcher override. When omitted, reads from\n * `MatcherContext`. Useful when you need to prefetch\n * against a specific set of routes.\n */\n matcher?: Matcher<Handler>\n\n /**\n * CSS class name(s) for the anchor element. Accepts either\n * a static string or a function that receives the link's\n * active state and returns a class name string. The function\n * form is useful for conditional styling based on whether\n * the link is currently active.\n *\n * @example\n * ```tsx\n * <Link\n * href=\"/about\"\n * className={({ isActive }) => isActive ? 'nav-active' : 'nav-link'}\n * />\n * ```\n */\n className?: string | ((props: LinkRenderProps) => string)\n\n /**\n * When true, the link is only considered active when the\n * current pathname exactly matches the href pathname.\n * When false, the link is active when the current\n * pathname starts with the href pathname, which is useful\n * for parent navigation items that should highlight when\n * any child route is active.\n *\n * Defaults to `true`.\n */\n activeExact?: boolean\n}\n\n/**\n * Renders an anchor element that integrates with the router's\n * prefetch system and active link detection. The Navigation\n * API intercepts the click natively, so no `onClick` or\n * `preventDefault` is needed.\n *\n * Supports two proactive prefetch strategies: `hover`\n * (prefetch on mouseenter) and `viewport` (prefetch when\n * the link scrolls into view via IntersectionObserver).\n * When `prefetch` is omitted, no proactive prefetch is\n * performed.\n *\n * When the link's href matches the current pathname, the\n * component adds `data-active` and `aria-current=\"page\"`\n * attributes. The `className` prop can be a function that\n * receives `{ isActive }` for dynamic class computation.\n */\nexport function Link({\n prefetch,\n once = true,\n href,\n matcher,\n className,\n activeExact = true,\n ...props\n}: LinkProps) {\n const ref = useRef<HTMLAnchorElement>(null)\n const { isActive, props: activeProps } = useActiveLinkProps(href, { exact: activeExact })\n\n usePrefetchEffect(ref, { href, on: prefetch, once, matcher })\n\n const resolvedClassName = typeof className === 'function' ? className({ isActive }) : className\n\n return <a ref={ref} href={href} className={resolvedClassName} {...activeProps} {...props} />\n}\n","import { use } from 'react'\nimport { NavigationContext } from 'router/react:context/NavigationContext'\n\n/**\n * Returns the native browser Navigation object from context.\n * Gives full access to the Navigation API: `entries()`,\n * `traverseTo()`, `updateCurrentEntry()`, `canGoBack`,\n * `canGoForward`, `transition`, `currentEntry`, etc.\n *\n * Must be used inside a `<Router>` or a component tree\n * that provides a `<NavigationContext>` value.\n *\n * @returns The Navigation object from the nearest provider.\n * @throws When used outside a NavigationContext provider.\n */\nexport function useNavigation(): Navigation {\n const navigation = use(NavigationContext)\n\n if (navigation === null) {\n throw new Error('useNavigation requires a <Router> or <NavigationContext> provider')\n }\n\n return navigation\n}\n","import { useNavigation } from 'router/react:hooks/useNavigation'\n\n/**\n * Returns a function to programmatically navigate to a URL\n * with full Navigation API options support (`state`, `info`,\n * `history`). This is a thin convenience wrapper around\n * `navigation.navigate()`.\n *\n * @returns A navigate function that accepts a URL string and\n * optional `NavigationNavigateOptions`.\n */\nexport function useNavigate() {\n const navigation = useNavigation()\n\n /**\n * Programmatically navigates to the given URL. Delegates\n * to the native `navigation.navigate()` method, which\n * fires the `navigate` event intercepted by the Router.\n *\n * @param url - The destination URL to navigate to.\n * @param options - Optional Navigation API options including\n * `state`, `info`, and `history` behavior.\n * @returns The NavigationResult from the Navigation API.\n */\n return function (url: string, options?: NavigationNavigateOptions) {\n return navigation.navigate(url, options)\n }\n}\n","import { use } from 'react'\nimport { NavigationSignalContext } from 'router/react:context/NavigationSignalContext'\n\n/**\n * Returns the AbortSignal from the current navigation event.\n * The signal aborts when the navigation is cancelled (e.g.,\n * by the user pressing Stop or a new navigation superseding\n * this one). Pass this to fetch calls or other cancellable\n * async operations to avoid stale work.\n *\n * Returns `null` before any navigation event has occurred\n * (i.e. on the initial render).\n *\n * @returns The current AbortSignal or null.\n */\nexport function useNavigationSignal(): AbortSignal | null {\n return use(NavigationSignalContext)\n}\n","import { use } from 'react'\nimport { NavigationTypeContext } from 'router/react:context/NavigationTypeContext'\n\n/**\n * Returns the navigation type of the most recent navigation\n * (`push`, `replace`, `reload`, or `traverse`). Useful for\n * varying animations, skipping prefetch on reload, or\n * applying different behavior for back/forward traversals.\n *\n * Returns `null` before any navigation event has occurred\n * (i.e. on the initial render).\n *\n * @returns The current NavigationType or null.\n */\nexport function useNavigationType(): NavigationType | null {\n return use(NavigationTypeContext)\n}\n","import { use } from 'react'\nimport { ParamsContext } from 'router/react:context/PropsContext'\n\n/**\n * Returns the dynamic route parameters extracted from the\n * currently matched URL pattern. The keys correspond to the\n * `:param` names defined in the route pattern, and the values\n * are the matching URL segments.\n *\n * Must be used inside a `<Router>` component tree where\n * `ParamsContext` is provided.\n *\n * @returns A record of parameter names to their string values.\n *\n * @example\n * ```tsx\n * // Route pattern: \"/user/:id\"\n * // URL: \"/user/42\"\n * const { id } = useParams() // id === \"42\"\n * ```\n */\nexport function useParams() {\n return use(ParamsContext)\n}\n","import { use } from 'react'\nimport { TransitionContext } from 'router/react:context/TransitionContext'\n\n/**\n * Returns whether a navigation transition is currently pending.\n * This reflects the `isPending` value from the `useTransition`\n * tuple managed by the Router component.\n *\n * Useful for displaying loading indicators, progress bars, or\n * adjusting UI opacity while a route transition is in progress.\n *\n * Must be used inside a `<Router>` component tree or a\n * `<TransitionContext>` provider.\n *\n * @returns `true` while a navigation transition is pending,\n * `false` otherwise.\n * @throws When used outside a TransitionContext provider.\n *\n * @example\n * ```tsx\n * function NavBar() {\n * const isPending = useIsPending()\n *\n * return (\n * <nav style={{ opacity: isPending ? 0.7 : 1 }}>\n * ...\n * </nav>\n * )\n * }\n * ```\n */\nexport function useIsPending(): boolean {\n const transition = use(TransitionContext)\n\n if (transition === null) {\n throw new Error('useIsPending requires a <Router> or <TransitionContext> provider')\n }\n\n return transition[0]\n}\n","import { use } from 'react'\nimport { PathnameContext } from 'router/react:context/PathnameContext'\n\n/**\n * Returns the current URL pathname from the Router's state.\n * The value updates on every navigation and reflects the\n * pathname of the committed destination URL.\n *\n * Useful for active link detection, conditional rendering\n * based on the current route, or building breadcrumbs.\n *\n * Must be used inside a `<Router>` component tree where\n * `PathnameContext` is provided.\n *\n * @returns The current pathname string (e.g. `\"/user/42\"`).\n *\n * @example\n * ```tsx\n * function Breadcrumb() {\n * const pathname = usePathname()\n *\n * return <span>{pathname}</span>\n * }\n * ```\n */\nexport function usePathname(): string {\n return use(PathnameContext)\n}\n","import { use } from 'react'\nimport { UrlContext } from 'router/react:context/UrlContext'\nimport { useNavigation } from 'router/react:hooks/useNavigation'\n\n/**\n * Updater function signature for setting search params.\n * Accepts either a new URLSearchParams instance, a plain\n * record of string key-value pairs, or a function that\n * receives the current params and returns updated params.\n */\nexport type SearchParamsUpdater =\n | URLSearchParams\n | Record<string, string>\n | ((current: URLSearchParams) => URLSearchParams | Record<string, string>)\n\n/**\n * Options for the search params navigation performed by\n * the setter function returned from `useSearchParams`.\n */\nexport interface SetSearchParamsOptions {\n /**\n * History behavior for the navigation. Defaults to\n * `'replace'` since search param changes typically\n * should not create new history entries.\n */\n history?: NavigationHistoryBehavior\n}\n\n/**\n * Returns the current URL's search parameters as a\n * `URLSearchParams` instance and a setter function to\n * update them via navigation.\n *\n * The getter derives search params from `UrlContext` —\n * React state managed by the Router — rather than reading\n * the mutable `navigation.currentEntry` during render.\n * This prevents subscription tearing in concurrent mode\n * where two components could otherwise see different\n * search params if a navigation fires mid-render.\n *\n * The setter preserves the existing hash fragment when\n * updating search parameters.\n *\n * The React Compiler handles memoization of the setter,\n * so no manual `useCallback` is needed.\n *\n * Must be used inside a `<Router>` component tree.\n *\n * @returns A tuple of `[searchParams, setSearchParams]`.\n *\n * @example\n * ```tsx\n * function SearchPage() {\n * const [searchParams, setSearchParams] = useSearchParams()\n * const query = searchParams.get('q') ?? ''\n *\n * return (\n * <input\n * value={query}\n * onChange={function (event) {\n * setSearchParams({ q: event.target.value })\n * }}\n * />\n * )\n * }\n * ```\n */\nexport function useSearchParams(): [\n URLSearchParams,\n (updater: SearchParamsUpdater, options?: SetSearchParamsOptions) => NavigationResult,\n] {\n const navigation = useNavigation()\n const currentUrl = use(UrlContext)\n\n const searchParams = currentUrl\n ? new URL(currentUrl, 'http://localhost').searchParams\n : new URLSearchParams()\n\n /**\n * Navigates to the current pathname with updated search\n * parameters. Accepts a URLSearchParams instance, a plain\n * record, or a function that receives the current params\n * and returns new ones. Preserves the existing hash\n * fragment.\n */\n function setSearchParams(updater: SearchParamsUpdater, options?: SetSearchParamsOptions) {\n const url = new URL(currentUrl ?? '/', 'http://localhost')\n\n const next = typeof updater === 'function' ? updater(url.searchParams) : updater\n\n const nextParams = next instanceof URLSearchParams ? next : new URLSearchParams(next)\n\n const search = nextParams.toString()\n const destination = url.pathname + (search ? '?' + search : '') + url.hash\n\n return navigation.navigate(destination, {\n history: options?.history ?? 'replace',\n })\n }\n\n return [searchParams, setSearchParams]\n}\n","import { useEffect, useState } from 'react'\nimport { useNavigation } from 'router/react:hooks/useNavigation'\n\n/**\n * Return value from the `useBack` hook, providing both\n * a traversal function and a boolean indicating whether\n * backward navigation is possible.\n */\nexport interface UseBackResult {\n /**\n * Navigates backward in the session history. Delegates\n * to `navigation.back()` from the Navigation API.\n *\n * @param options - Optional navigation options such as\n * `info` to pass data to the navigate event handler.\n * @returns The NavigationResult with `committed` and\n * `finished` promises.\n */\n readonly back: (options?: NavigationOptions) => NavigationResult\n\n /**\n * Whether backward navigation is possible. Mirrors\n * `navigation.canGoBack` from the Navigation API.\n * Reactively updates when navigations change the\n * history stack. When false, calling `back()` will throw.\n */\n readonly canGoBack: boolean\n}\n\n/**\n * Provides backward navigation capabilities using the\n * Navigation API. Returns a `back` function and a\n * `canGoBack` boolean that reflects whether the history\n * stack has a previous entry to traverse to.\n *\n * The `canGoBack` value is kept in React state and\n * updated via the `currententrychange` event, ensuring\n * it stays reactive across navigations — including those\n * triggered outside of React (e.g. browser back button).\n *\n * Must be used inside a `<Router>` component tree.\n *\n * @returns An object with `back` and `canGoBack`.\n *\n * @example\n * ```tsx\n * function BackButton() {\n * const { back, canGoBack } = useBack()\n *\n * return (\n * <button onClick={back} disabled={!canGoBack}>\n * Go Back\n * </button>\n * )\n * }\n * ```\n */\nexport function useBack(): UseBackResult {\n const navigation = useNavigation()\n const [canGoBack, setCanGoBack] = useState(navigation.canGoBack)\n\n useEffect(\n function () {\n /**\n * Syncs the React state with the Navigation API's\n * `canGoBack` property whenever the current entry\n * changes.\n */\n function onEntryChange() {\n setCanGoBack(navigation.canGoBack)\n }\n\n navigation.addEventListener('currententrychange', onEntryChange)\n\n return function () {\n navigation.removeEventListener('currententrychange', onEntryChange)\n }\n },\n [navigation]\n )\n\n /**\n * Traverses backward in the session history by\n * delegating to `navigation.back()`.\n */\n function back(options?: NavigationOptions) {\n return navigation.back(options)\n }\n\n return {\n back,\n canGoBack,\n }\n}\n","import { useEffect, useState } from 'react'\nimport { useNavigation } from 'router/react:hooks/useNavigation'\n\n/**\n * Return value from the `useForward` hook, providing both\n * a traversal function and a boolean indicating whether\n * forward navigation is possible.\n */\nexport interface UseForwardResult {\n /**\n * Navigates forward in the session history. Delegates\n * to `navigation.forward()` from the Navigation API.\n *\n * @param options - Optional navigation options such as\n * `info` to pass data to the navigate event handler.\n * @returns The NavigationResult with `committed` and\n * `finished` promises.\n */\n readonly forward: (options?: NavigationOptions) => NavigationResult\n\n /**\n * Whether forward navigation is possible. Mirrors\n * `navigation.canGoForward` from the Navigation API.\n * Reactively updates when navigations change the\n * history stack. When false, calling `forward()` will\n * throw.\n */\n readonly canGoForward: boolean\n}\n\n/**\n * Provides forward navigation capabilities using the\n * Navigation API. Returns a `forward` function and a\n * `canGoForward` boolean that reflects whether the history\n * stack has a next entry to traverse to.\n *\n * The `canGoForward` value is kept in React state and\n * updated via the `currententrychange` event, ensuring\n * it stays reactive across navigations — including those\n * triggered outside of React (e.g. browser forward button).\n *\n * Must be used inside a `<Router>` component tree.\n *\n * @returns An object with `forward` and `canGoForward`.\n *\n * @example\n * ```tsx\n * function ForwardButton() {\n * const { forward, canGoForward } = useForward()\n *\n * return (\n * <button onClick={forward} disabled={!canGoForward}>\n * Go Forward\n * </button>\n * )\n * }\n * ```\n */\nexport function useForward(): UseForwardResult {\n const navigation = useNavigation()\n const [canGoForward, setCanGoForward] = useState(navigation.canGoForward)\n\n useEffect(\n function () {\n /**\n * Syncs the React state with the Navigation API's\n * `canGoForward` property whenever the current entry\n * changes.\n */\n function onEntryChange() {\n setCanGoForward(navigation.canGoForward)\n }\n\n navigation.addEventListener('currententrychange', onEntryChange)\n\n return function () {\n navigation.removeEventListener('currententrychange', onEntryChange)\n }\n },\n [navigation]\n )\n\n /**\n * Traverses forward in the session history by\n * delegating to `navigation.forward()`.\n */\n function forward(options?: NavigationOptions) {\n return navigation.forward(options)\n }\n\n return {\n forward,\n canGoForward,\n }\n}\n","/**\n * Minimal subset of the NavigationHistoryEntry interface\n * needed by the Router component. Only the `url` property\n * is read during rendering. The full NavigationHistoryEntry\n * interface is far larger, but the Router never accesses\n * properties like `key`, `id`, `sameDocument`, `getState`,\n * or the event handlers.\n */\ninterface MemoryNavigationEntry {\n /**\n * The full URL string for this history entry.\n */\n readonly url: string\n}\n\n/**\n * Options for creating a memory navigation instance.\n */\nexport interface MemoryNavigationOptions {\n /**\n * The initial URL for the memory navigation. This is the\n * URL that `currentEntry.url` will return. Typically the\n * request URL from the server for SSR, or a test URL.\n *\n * @example `'https://example.com/user/42?tab=posts'`\n */\n readonly url: string\n}\n\n/**\n * Creates a minimal in-memory Navigation object suitable for\n * server-side rendering and testing environments where the\n * browser Navigation API is unavailable.\n *\n * The returned object satisfies the subset of the `Navigation`\n * interface consumed by the Router component:\n *\n * - `currentEntry.url` — returns the initial URL\n * - `addEventListener` / `removeEventListener` — no-ops\n * (no events fire in a memory environment)\n * - `navigate()` — no-op that returns a NavigationResult\n * with immediately-resolved promises\n * - `canGoBack` / `canGoForward` — always false\n * - `entries()` — returns a single-entry array\n *\n * The object is cast to `Navigation` for compatibility with\n * the Router's `navigation` prop and `NavigationContext`.\n * Properties not listed above are not implemented and will\n * throw if accessed by consumer code outside the Router.\n *\n * @param options - Configuration including the initial URL.\n * @returns A Navigation-compatible object for SSR or testing.\n *\n * @example\n * ```tsx\n * // Server-side rendering\n * const navigation = createMemoryNavigation({\n * url: request.url,\n * })\n *\n * const html = renderToString(\n * <Router navigation={navigation} matcher={matcher}>\n * <App />\n * </Router>\n * )\n * ```\n */\nexport function createMemoryNavigation(options: MemoryNavigationOptions): Navigation {\n const entry: MemoryNavigationEntry = {\n url: options.url,\n }\n\n /**\n * No-op event listener registration. In SSR and testing\n * environments, no navigation events are dispatched, so\n * the Router's effect subscriptions are harmless no-ops.\n */\n function addEventListener() {}\n\n /**\n * No-op event listener removal. Mirrors addEventListener\n * as a symmetric no-op.\n */\n function removeEventListener() {}\n\n /**\n * No-op navigate that returns a NavigationResult with\n * pre-resolved committed and finished promises. In SSR\n * the result is never awaited, but returning valid\n * promises avoids runtime errors if consumer code chains\n * on the result.\n */\n function navigate(): NavigationResult {\n return {\n committed: Promise.resolve(entry as unknown as NavigationHistoryEntry),\n finished: Promise.resolve(entry as unknown as NavigationHistoryEntry),\n }\n }\n\n /**\n * Returns the single-entry history list. The memory\n * adapter only ever has one entry — the initial URL.\n */\n function entries(): NavigationHistoryEntry[] {\n return [entry as unknown as NavigationHistoryEntry]\n }\n\n return {\n currentEntry: entry,\n canGoBack: false,\n canGoForward: false,\n transition: null,\n addEventListener,\n removeEventListener,\n navigate,\n entries,\n } as unknown as Navigation\n}\n","import { type ComponentType } from 'react'\nimport { createMatcher, type Matcher } from 'router:matcher'\nimport {\n type FormHandler,\n type Handler,\n type MiddlewareProps,\n type PrefetchContext,\n type PrefetchFunc,\n type RedirectTarget,\n} from 'router/react:router'\n\n/**\n * Accumulated configuration inherited from parent groups.\n * Passed down through nested `.group()` calls so that child\n * routes merge their own configuration with the parent's.\n */\ninterface InheritedConfig {\n /**\n * Path prefix accumulated from parent groups. Each group\n * that specifies a path appends it to this prefix. Child\n * route paths are concatenated after this prefix when\n * registering on the matcher.\n */\n readonly prefix: string\n\n /**\n * Middleware components inherited from parent groups.\n * Child routes prepend these before their own middlewares\n * so that outermost group middlewares wrap outermost.\n */\n readonly middlewares: ComponentType<MiddlewareProps>[]\n\n /**\n * Prefetch functions inherited from parent groups. When\n * a child route also defines a prefetch, the parent\n * functions run first (in order) followed by the child's.\n */\n readonly prefetches: PrefetchFunc[]\n}\n\n/**\n * Mutable state accumulated on a single route builder\n * instance via its chainable methods. Merged with the\n * inherited config when a terminal method is called.\n */\ninterface BuilderState {\n /**\n * The path segment for this route, or undefined when the\n * builder is used purely for group-level configuration.\n */\n path: string | undefined\n\n /**\n * Middleware components added via `.middleware()` on this\n * builder. Appended after inherited middlewares.\n */\n middlewares: ComponentType<MiddlewareProps>[]\n\n /**\n * Prefetch functions added via `.prefetch()` on this\n * builder. Appended after inherited prefetches.\n */\n prefetches: PrefetchFunc[]\n\n /**\n * Scroll restoration behavior for this route. Set via\n * `.scroll()`. Undefined means the browser default.\n */\n scroll: NavigationScrollBehavior | undefined\n\n /**\n * Focus reset behavior for this route. Set via\n * `.focusReset()`. Undefined means the browser default.\n */\n focusReset: NavigationFocusReset | undefined\n\n /**\n * Form submission handler for this route. Set via\n * `.formHandler()`.\n */\n formHandler: FormHandler | undefined\n}\n\n/**\n * Chainable route builder returned by the `route()` factory.\n * Accumulates handler configuration through method calls and\n * terminates with `.render()`, `.redirect()`, or `.group()`.\n *\n * Chainable methods (return the builder for further chaining):\n * - `.middleware()` — appends middleware components\n * - `.prefetch()` — adds a prefetch function to the chain\n * - `.scroll()` — sets scroll restoration behavior\n * - `.focusReset()` — sets focus reset behavior\n * - `.formHandler()` — sets the form submission handler\n *\n * Terminal methods:\n * - `.render()` — registers a route with a component\n * - `.redirect()` — registers a precommit redirect\n * - `.group()` — returns a scoped `RouteFactory` that\n * inherits this builder's config\n */\nexport interface RouteBuilder {\n /**\n * Appends middleware components to this route or group.\n * Middlewares are applied outermost-first: inherited group\n * middlewares wrap before this route's middlewares, and\n * within the array the first element wraps outermost.\n *\n * @param list - Middleware components to append.\n * @returns The builder for further chaining.\n */\n middleware(list: ComponentType<MiddlewareProps>[]): RouteBuilder\n\n /**\n * Adds a prefetch function to the chain for this route\n * or group. When multiple prefetch functions are chained\n * (from parent groups and the route itself), they execute\n * sequentially: parent prefetches run first, then this\n * route's, in the order they were added.\n *\n * @param fn - The prefetch function to add.\n * @returns The builder for further chaining.\n */\n prefetch(fn: PrefetchFunc): RouteBuilder\n\n /**\n * Sets the scroll restoration behavior for this route.\n * - `'after-transition'` — browser handles scroll after\n * the handler promise resolves (default).\n * - `'manual'` — disables automatic scrolling so the\n * route component can call `event.scroll()` manually.\n *\n * @param behavior - The scroll behavior to use.\n * @returns The builder for further chaining.\n */\n scroll(behavior: NavigationScrollBehavior): RouteBuilder\n\n /**\n * Sets the focus reset behavior for this route.\n * - `'after-transition'` — focuses the first autofocus\n * element after the handler resolves (default).\n * - `'manual'` — disables automatic focus reset.\n *\n * @param behavior - The focus reset behavior to use.\n * @returns The builder for further chaining.\n */\n focusReset(behavior: NavigationFocusReset): RouteBuilder\n\n /**\n * Sets the form submission handler for this route. When\n * a navigation includes FormData and matches this route,\n * the form handler is called instead of rendering the\n * component.\n *\n * @param fn - The form handler function.\n * @returns The builder for further chaining.\n */\n formHandler(fn: FormHandler): RouteBuilder\n\n /**\n * Terminal method that registers this route on the matcher\n * with the given component. Merges inherited and local\n * configuration into a `Handler` and registers it at the\n * full path (group prefix + route path).\n *\n * @param component - The React component to render.\n * @throws When no path was provided to the `route()` call\n * and no group prefix exists.\n */\n render(component: ComponentType): void\n\n /**\n * Terminal method that registers a precommit redirect.\n * When the Navigation API matches this route, the\n * precommit handler calls `controller.redirect(target)`\n * before the URL commits, avoiding any component render\n * or visual flash.\n *\n * The target can be a static absolute path string, or a\n * callback that receives the prefetch context and returns\n * the path. The callback form enables dynamic redirects\n * that carry route parameters to the new location.\n *\n * The resolved target path is absolute and is NOT prefixed\n * by parent groups.\n *\n * @param target - The redirect target: a static path or a\n * callback receiving `PrefetchContext` and returning one.\n * @throws When no path was provided to the `route()` call\n * and no group prefix exists.\n *\n * @example\n * ```ts\n * // Static redirect\n * route('/old').redirect('/new')\n *\n * // Dynamic redirect using route params\n * route('/old-user/:id').redirect(({ params }) => `/user/${params.id}`)\n * ```\n */\n redirect(target: RedirectTarget): void\n\n /**\n * Terminal method that creates a nested route scope.\n * Returns a `RouteFactory` whose routes inherit this\n * builder's middleware and prefetch configuration. When\n * a path was provided, it is prepended to all child\n * route paths as a prefix.\n *\n * @returns A scoped `RouteFactory` for defining child\n * routes that inherit this builder's config.\n *\n * @example\n * ```ts\n * const admin = route('/admin').middleware([Auth]).group()\n * admin('/dashboard').render(Dashboard)\n * admin('/settings').render(Settings)\n * ```\n */\n group(): RouteFactory\n}\n\n/**\n * Factory function that creates a route builder for a given\n * path. When path is omitted, the builder is used purely for\n * group-level configuration (middleware, prefetch) without\n * contributing a path segment.\n *\n * @param path - Optional path pattern for this route. May\n * contain dynamic (`:param`) and wildcard (`*param`)\n * segments.\n * @returns A chainable route builder.\n */\nexport type RouteFactory = (path?: string) => RouteBuilder\n\n/**\n * Joins a group prefix and a route path into a single\n * pattern string. Handles the edge cases of empty prefix,\n * empty path, double slashes, and root-only paths.\n *\n * @param prefix - The accumulated group prefix (e.g.\n * `'/dashboard'`).\n * @param path - The route path (e.g. `'/settings'`).\n * @returns The joined path pattern.\n */\nfunction joinPaths(prefix: string, path: string): string {\n if (prefix === '' && path === '') {\n return ''\n }\n\n if (prefix === '') {\n return path\n }\n\n if (path === '' || path === '/') {\n return prefix\n }\n\n const normalizedPrefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix\n\n const normalizedPath = path.startsWith('/') ? path : '/' + path\n\n return normalizedPrefix + normalizedPath\n}\n\n/**\n * Combines an array of prefetch functions into a single\n * `PrefetchFunc` that calls each one sequentially. Returns\n * `undefined` when the array is empty.\n *\n * @param prefetches - The prefetch functions to chain.\n * @returns A single combined prefetch function, or undefined.\n */\nfunction chainPrefetches(prefetches: PrefetchFunc[]): PrefetchFunc | undefined {\n if (prefetches.length === 0) {\n return undefined\n }\n\n if (prefetches.length === 1) {\n return prefetches[0]\n }\n\n return async function (context: PrefetchContext) {\n for (const fn of prefetches) {\n await fn(context)\n }\n }\n}\n\n/**\n * A no-op React component used as the `component` field for\n * redirect routes. Never actually renders because the\n * precommit redirect fires before the URL commits, but the\n * `Handler` interface requires a component.\n */\nfunction RedirectFallback() {\n return null\n}\n\n/**\n * Creates a route builder bound to a specific matcher and\n * inherited configuration. Each call to the returned factory\n * produces a fresh builder that inherits the given config.\n *\n * @param matcher - The matcher to register routes on.\n * @param inherited - Configuration from parent groups.\n * @param redirects - Shared map collecting static redirect\n * targets for post-registration cycle detection. Keys are\n * source paths, values are target paths. Only populated\n * for string (non-callback) redirect targets.\n * @returns A `RouteFactory` function.\n */\nfunction createRouteFactory(\n matcher: Matcher<Handler>,\n inherited: InheritedConfig,\n redirects: Map<string, string>\n): RouteFactory {\n return function route(path?: string): RouteBuilder {\n const state: BuilderState = {\n path,\n middlewares: [],\n prefetches: [],\n scroll: undefined,\n focusReset: undefined,\n formHandler: undefined,\n }\n\n /**\n * Whether a terminal method (`.render()`, `.redirect()`,\n * or `.group()`) has been called on this builder. Once\n * consumed, further method calls throw to prevent\n * accidental reuse.\n */\n let isConsumed = false\n\n /**\n * Guards against calling builder methods after a terminal\n * method has been invoked. Throws a descriptive error\n * indicating which method was called on a consumed builder.\n *\n * @param method - The method name being called.\n * @throws When the builder has already been consumed.\n */\n function assertNotConsumed(method: string) {\n if (isConsumed) {\n throw new Error(\n `cannot call .${method}() on a route builder that has ` +\n `already been consumed by .render(), .redirect(), or .group()`\n )\n }\n }\n\n /**\n * Computes the full registration path by joining the\n * inherited prefix with this builder's path. Throws\n * when neither a prefix nor a path exists, since a\n * route must have a resolvable path to register.\n *\n * @returns The full path pattern.\n * @throws When both the group prefix and route path\n * are empty or undefined.\n */\n function resolveFullPath(): string {\n const fullPath = joinPaths(inherited.prefix, state.path ?? '')\n\n if (fullPath === '') {\n throw new Error('cannot register a route without a path or group prefix')\n }\n\n return fullPath\n }\n\n /**\n * Merges inherited and local middlewares into a single\n * array. Returns `undefined` when no middlewares exist\n * (to match the optional `Handler.middlewares` field).\n *\n * @returns The merged middleware array, or undefined.\n */\n function resolveMiddlewares(): ComponentType<MiddlewareProps>[] | undefined {\n const merged = [...inherited.middlewares, ...state.middlewares]\n\n return merged.length > 0 ? merged : undefined\n }\n\n /**\n * Merges inherited and local prefetches into a single\n * chained function. Returns `undefined` when no\n * prefetches exist.\n *\n * @returns The chained prefetch function, or undefined.\n */\n function resolvePrefetches(): PrefetchFunc | undefined {\n return chainPrefetches([...inherited.prefetches, ...state.prefetches])\n }\n\n const builder: RouteBuilder = {\n middleware(list) {\n assertNotConsumed('middleware')\n state.middlewares.push(...list)\n\n return builder\n },\n\n prefetch(fn) {\n assertNotConsumed('prefetch')\n state.prefetches.push(fn)\n\n return builder\n },\n\n scroll(behavior) {\n assertNotConsumed('scroll')\n state.scroll = behavior\n\n return builder\n },\n\n focusReset(behavior) {\n assertNotConsumed('focusReset')\n state.focusReset = behavior\n\n return builder\n },\n\n formHandler(fn) {\n assertNotConsumed('formHandler')\n state.formHandler = fn\n\n return builder\n },\n\n render(component) {\n assertNotConsumed('render')\n isConsumed = true\n\n const fullPath = resolveFullPath()\n\n const handler: Handler = {\n component,\n middlewares: resolveMiddlewares(),\n prefetch: resolvePrefetches(),\n scroll: state.scroll,\n focusReset: state.focusReset,\n formHandler: state.formHandler,\n }\n\n matcher.register(fullPath, handler)\n },\n\n redirect(target) {\n assertNotConsumed('redirect')\n isConsumed = true\n\n const fullPath = resolveFullPath()\n\n if (typeof target === 'string') {\n redirects.set(fullPath, target)\n }\n\n const handler: Handler = {\n component: RedirectFallback,\n prefetch: function (context) {\n const resolved = typeof target === 'function' ? target(context) : target\n\n context.controller.redirect(resolved)\n },\n }\n\n matcher.register(fullPath, handler)\n },\n\n group() {\n assertNotConsumed('group')\n isConsumed = true\n\n const childPrefix = joinPaths(inherited.prefix, state.path ?? '')\n\n const childInherited: InheritedConfig = {\n prefix: childPrefix,\n middlewares: [...inherited.middlewares, ...state.middlewares],\n prefetches: [...inherited.prefetches, ...state.prefetches],\n }\n\n return createRouteFactory(matcher, childInherited, redirects)\n },\n }\n\n return builder\n }\n}\n\n/**\n * Detects cycles in static redirect routes. Walks each\n * redirect chain and throws if a cycle is found. Only\n * checks string (non-callback) redirect targets since\n * callback targets are resolved at runtime.\n *\n * @param redirects - Map of source path to target path\n * for all static redirects.\n * @throws When a redirect cycle is detected, with the\n * full cycle path in the error message.\n */\nfunction detectRedirectCycles(redirects: Map<string, string>) {\n for (const [source] of redirects) {\n const visited = new Set<string>()\n let current = source\n\n while (redirects.has(current)) {\n if (visited.has(current)) {\n const cycle = [...visited, current].join(' -> ')\n\n throw new Error(`redirect cycle detected: ${cycle}`)\n }\n\n visited.add(current)\n current = redirects.get(current)!\n }\n }\n}\n\n/**\n * Creates a route matcher using a declarative builder API.\n * Routes are defined inside a callback that receives a\n * `route` factory function for chainable route configuration.\n *\n * The builder supports middleware inheritance, prefetch\n * chaining, nested groups with path prefixing, redirects,\n * and all handler options (scroll, focusReset, formHandler).\n *\n * After all routes are registered, static redirect targets\n * are checked for cycles. Self-redirects and multi-hop loops\n * throw an error at registration time.\n *\n * Returns a `Matcher<Handler>` that plugs directly into the\n * `<Router matcher={...}>` component.\n *\n * @param callback - A function that defines routes using the\n * provided `route` factory.\n * @returns A populated matcher ready for the Router.\n * @throws When a static redirect cycle is detected.\n *\n * @example\n * ```tsx\n * const router = createRouter(function (route) {\n * route('/').render(Home)\n * route('/old').redirect('/new')\n *\n * route('/other')\n * .prefetch(prefetchOther)\n * .scroll('after-transition')\n * .render(Other)\n *\n * const authed = route().middleware([Auth]).group()\n * authed('/dashboard').render(Dashboard)\n * authed('/user/:id').render(User)\n *\n * const admin = authed('/admin')\n * .middleware([AdminOnly])\n * .group()\n * admin('/settings').render(Settings)\n * })\n *\n * <Router matcher={router} />\n * ```\n */\nexport function createRouter(callback: (route: RouteFactory) => void): Matcher<Handler> {\n const matcher = createMatcher<Handler>()\n const redirects = new Map<string, string>()\n\n const rootInherited: InheritedConfig = {\n prefix: '',\n middlewares: [],\n prefetches: [],\n }\n\n const route = createRouteFactory(matcher, rootInherited, redirects)\n\n callback(route)\n\n detectRedirectCycles(redirects)\n\n return matcher\n}\n"],"x_google_ignoreList":[1,2,3],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"router_react.js","names":["ReactNode","Handler","MiddlewaresProps","value","children","Middlewares","reduceRight","inner","Middleware","index","NotFound","$","_c","t0","Symbol","for","ComponentType","ReactNode","Suspense","use","useEffectEvent","useState","useTransition","Handler","Matcher","ParamsContext","NavigationContext","NavigationSignalContext","NavigationTypeContext","Resolved","Middlewares","NotFound","useNavigationHandlers","useNextMatch","useNavigationEvents","MatcherContext","TransitionContext","PathnameContext","UrlContext","extractPathname","CurrentState","match","signal","AbortSignal","navigationType","NavigationType","pathname","url","RouterProps","matcher","notFound","fallback","navigation","Navigation","transition","ReturnType","onNavigateSuccess","onNavigateError","error","Router","props","$","_c","contextNavigation","window","undefined","Error","internalTransition","t0","next","t1","currentEntry","current","setCurrent","createPrecommitHandler","createHandler","t2","event","canIntercept","hashChange","downloadRequest","destination","formData","handler","formHandler","intercept","scroll","focusReset","precommitHandler","prefetch","params","URL","onNavigate","t3","CurrentComponent","component","middlewares","t4","t5","t6","t7","t8","t9","t10","t11","t12","t13","t14","AnchorHTMLAttributes","useRef","useActiveLinkProps","PrefetchStrategy","usePrefetchEffect","Handler","Matcher","LinkRenderProps","isActive","LinkProps","Omit","HTMLAnchorElement","prefetch","once","matcher","className","props","activeExact","Link","t0","$","_c","href","t1","t2","undefined","ref","t3","exact","activeProps","t4","on","t5","resolvedClassName","t6"],"sources":["../src/react/components/Middlewares.tsx","../node_modules/react/cjs/react-compiler-runtime.production.js","../node_modules/react/cjs/react-compiler-runtime.development.js","../node_modules/react/compiler-runtime.js","../src/react/context/ParamsContext.ts","../src/react/context/NavigationContext.ts","../src/react/context/NavigationSignalContext.ts","../src/react/context/NavigationTypeContext.ts","../src/react/components/NotFound.tsx","../src/react/context/TransitionContext.ts","../src/react/hooks/useNavigationHandlers.ts","../src/react/context/MatcherContext.ts","../src/react/hooks/useNextMatch.ts","../src/react/hooks/useNavigationEvents.ts","../src/react/context/PathnameContext.ts","../src/react/context/UrlContext.ts","../src/react/extractPathname.ts","../src/react/components/Router.tsx","../src/react/hooks/useActiveLinkProps.ts","../src/react/hooks/usePrefetch.ts","../src/react/hooks/usePrefetchEffect.ts","../src/react/components/Link.tsx","../src/react/hooks/useNavigation.ts","../src/react/hooks/useNavigate.ts","../src/react/hooks/useNavigationSignal.ts","../src/react/hooks/useNavigationType.ts","../src/react/hooks/useParams.ts","../src/react/hooks/useIsPending.ts","../src/react/hooks/usePathname.ts","../src/react/hooks/useSearchParams.ts","../src/react/hooks/useBack.ts","../src/react/hooks/useForward.ts","../src/react/navigation/createMemoryNavigation.ts","../src/react/createRouter.ts"],"sourcesContent":["import { type ReactNode } from 'react'\nimport { type Handler } from 'router/react:router'\n\n/**\n * Props for the Middlewares wrapper component.\n */\nexport interface MiddlewaresProps {\n /**\n * The array of middleware components to wrap around children.\n * May be `undefined` when the matched route has no middlewares.\n */\n value: Handler['middlewares']\n\n /**\n * The content to wrap inside the middleware chain. Typically\n * the matched route component rendered by the Router.\n */\n children?: ReactNode\n}\n\n/**\n * Wraps children in the given middleware components using\n * `reduceRight` so the first middleware in the array is the\n * outermost wrapper. When no middlewares are provided, renders\n * children directly.\n *\n * Each middleware component receives `children` as its only\n * prop and is responsible for rendering them (or not, in the\n * case of auth guards).\n */\nexport function Middlewares({ value, children }: MiddlewaresProps) {\n return (\n value?.reduceRight(\n (inner, Middleware, index) => <Middleware key={index}>{inner}</Middleware>,\n children\n ) ?? children\n )\n}\n","/**\n * @license React\n * react-compiler-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar ReactSharedInternals =\n require(\"react\").__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;\nexports.c = function (size) {\n return ReactSharedInternals.H.useMemoCache(size);\n};\n","/**\n * @license React\n * react-compiler-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n var ReactSharedInternals =\n require(\"react\").__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;\n exports.c = function (size) {\n var dispatcher = ReactSharedInternals.H;\n null === dispatcher &&\n console.error(\n \"Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\\n1. You might have mismatching versions of React and the renderer (such as React DOM)\\n2. You might be breaking the Rules of Hooks\\n3. You might have more than one copy of React in the same app\\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.\"\n );\n return dispatcher.useMemoCache(size);\n };\n })();\n","/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-compiler-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-compiler-runtime.development.js');\n}\n","import { createContext } from 'react'\n\n/**\n * Provides the route parameters extracted from the matched URL\n * pattern as a string-keyed record. Defaults to `null` when no\n * Router is present in the tree — the `useParams` hook throws\n * a descriptive error in this case.\n *\n * The Router component updates this context on every successful\n * navigation with the newly extracted parameters.\n */\nexport const ParamsContext = createContext<Record<string, string> | null>(null)\n","import { createContext } from 'react'\n\n/**\n * Provides the native browser Navigation object through React context.\n *\n * Defaults to `null` — the Router component provides the real value.\n * This avoids accessing `window.navigation` at module scope, which\n * would crash in SSR, testing, or non-browser environments.\n *\n * The `useNavigation` hook throws a descriptive error when consumed\n * without a provider.\n */\nexport const NavigationContext = createContext<Navigation | null>(null)\n","import { createContext } from 'react'\n\n/**\n * Provides the AbortSignal from the current NavigateEvent.\n * Consumers can use this to cancel in-flight async operations\n * (fetches, transitions, etc.) when a navigation is superseded\n * by another one.\n *\n * Defaults to `undefined` when no Router is present — the\n * `useNavigationSignal` hook throws in this case. The Router\n * provides `null` on initial render (before any navigation\n * event), which is distinct from the `undefined` sentinel.\n */\nexport const NavigationSignalContext = createContext<AbortSignal | null | undefined>(undefined)\n","import { createContext } from 'react'\n\n/**\n * Provides the navigation type of the most recent NavigateEvent\n * (`push`, `replace`, `reload`, or `traverse`). Allows route\n * components to vary behavior based on how they were reached.\n *\n * Defaults to `undefined` when no Router is present — the\n * `useNavigationType` hook throws in this case. The Router\n * provides `null` on initial render (before any navigation\n * event), which is distinct from the `undefined` sentinel.\n */\nexport const NavigationTypeContext = createContext<NavigationType | null | undefined>(undefined)\n","/**\n * Default fallback component rendered when no registered\n * route matches the current URL. Uses an `<h1>` heading\n * for semantic document structure and accessibility.\n *\n * Can be overridden via the `notFound` prop on the Router\n * component for custom 404 pages.\n */\nexport function NotFound() {\n return <h1>Not Found</h1>\n}\n","import { createContext, useTransition } from 'react'\n\n/**\n * Provides the `[isPending, startTransition]` tuple from\n * `useTransition()` to descendant components. The Router and\n * navigation handlers use this to wrap state updates in\n * concurrent transitions.\n *\n * Defaults to `null` — a parent component must provide a real\n * `useTransition()` tuple via `<TransitionContext value={...}>`.\n * Using the standalone `startTransition` from React as a default\n * would silently break `isPending` tracking, so we require an\n * explicit provider instead.\n */\nexport const TransitionContext = createContext<ReturnType<typeof useTransition> | null>(null)\n","import { type TransitionFunction, use, useTransition } from 'react'\nimport { TransitionContext } from 'router/react:context/TransitionContext'\nimport { type PrefetchFunc, type PrefetchContext } from 'router/react:router'\n\n/**\n * Options for creating a precommit handler that forwards\n * route context to the prefetch function.\n */\nexport interface PrecommitHandlerOptions {\n /**\n * The prefetch function from the matched route handler.\n * When undefined, no precommit handler is created.\n */\n readonly prefetch?: PrefetchFunc\n\n /**\n * Dynamic route parameters extracted from the matched\n * URL pattern.\n */\n readonly params: Record<string, string>\n\n /**\n * The destination URL being navigated to.\n */\n readonly url: URL\n}\n\n/**\n * Creates handler functions for the Navigation API's\n * `event.intercept()` method. The precommit handler runs\n * prefetch logic before the URL commits; the handler runs\n * the React state transition after the URL commits.\n *\n * Accepts an optional `transition` tuple to use directly.\n * When omitted, reads from TransitionContext instead. The\n * Router component passes its own transition tuple here to\n * avoid a circular dependency — the Router provides the\n * TransitionContext in its JSX return, but needs the\n * handlers during render before that provider exists in\n * the tree.\n *\n * @param transition - Optional `useTransition()` tuple to\n * use instead of reading from TransitionContext. Pass\n * this when calling from within the component that\n * provides TransitionContext.\n * @throws When no transition tuple is provided and the\n * hook is used outside a TransitionContext provider.\n *\n * @example\n * ```tsx\n * function CustomRouter() {\n * const transition = useTransition()\n * const { createHandler } = useNavigationHandlers(transition)\n * // use createHandler to build intercept handlers\n * }\n * ```\n */\nexport function useNavigationHandlers(transition?: ReturnType<typeof useTransition>) {\n const contextTransition = transition ?? use(TransitionContext)\n\n if (contextTransition === null) {\n throw new Error('useNavigationHandlers requires a <Router> or <TransitionContext> provider')\n }\n\n const [, startTransition] = contextTransition\n\n /**\n * Creates a precommit handler that constructs a\n * `PrefetchContext` from the matched route information\n * and forwards it to the route's prefetch function.\n * Runs before the URL commits, so no React state\n * transitions are needed here.\n */\n function createPrecommitHandler(options: PrecommitHandlerOptions) {\n if (options.prefetch === undefined) {\n return undefined\n }\n\n const prefetch = options.prefetch\n\n return async function (controller: NavigationPrecommitController) {\n const context: PrefetchContext = {\n params: options.params,\n url: options.url,\n controller,\n }\n\n await prefetch(context)\n }\n }\n\n /**\n * Creates a post-commit handler that wraps the state\n * update in a React async transition for concurrent\n * rendering. The promise resolves only after the async\n * transition callback completes, ensuring the Navigation\n * API waits for React to finish rendering before firing\n * `navigatesuccess` and performing scroll restoration.\n *\n * @param callback - The transition function containing\n * the state update to perform after the URL commits.\n */\n function createHandler(callback: TransitionFunction) {\n return function handler() {\n return new Promise<void>(function (resolve, reject) {\n startTransition(async function () {\n try {\n await callback()\n resolve()\n } catch (error) {\n reject(error)\n }\n })\n })\n }\n }\n\n return { createPrecommitHandler, createHandler }\n}\n","import { createContext } from 'react'\nimport { type Handler } from 'router/react:router'\nimport { createMatcher, type Matcher } from 'router:matcher'\n\n/**\n * Provides the route Matcher instance through React context.\n * Defaults to an empty matcher with no registered routes.\n *\n * The Router component and hooks like `useNextMatch` and\n * `usePrefetch` consume this context to resolve URLs against\n * registered route patterns. Override by passing a `matcher`\n * prop to Router or wrapping with `<MatcherContext value={...}>`.\n */\nexport const MatcherContext = createContext<Matcher<Handler>>(createMatcher())\n","import { type ComponentType, use } from 'react'\nimport { MatcherContext } from 'router/react:context/MatcherContext'\nimport { type Handler } from 'router/react:router'\nimport { type Matcher, type Resolved } from 'router:matcher'\n\n/**\n * Options for the `useNextMatch` hook.\n */\nexport interface NextMatchOptions {\n /**\n * Optional matcher override. When omitted the hook reads\n * from `MatcherContext`.\n */\n matcher?: Matcher<Handler>\n}\n\n/**\n * Returns a function that resolves a destination URL into a\n * route match. When no route matches, a fallback `Resolved`\n * is returned using the provided `notFound` component.\n *\n * Used internally by the Router to determine which component\n * to render for an incoming navigation event.\n *\n * @param options - Optional matcher override.\n * @returns A resolver function that takes a destination URL\n * and a not-found component, returning the resolved match.\n *\n * @example\n * ```tsx\n * function CustomRouter() {\n * const resolve = useNextMatch()\n * const match = resolve(window.location.href, NotFound)\n * const Component = match.handler.component\n *\n * return <Component />\n * }\n * ```\n */\nexport function useNextMatch(options?: NextMatchOptions) {\n const matcher = options?.matcher ?? use(MatcherContext)\n\n /**\n * Resolves a destination URL string into a route match.\n * Falls back to a synthetic match wrapping the `notFound`\n * component when the URL doesn't match any registered route.\n *\n * @param destination - The full destination URL string, or\n * `null` when no URL is available (e.g. initial load\n * without a current entry).\n * @param notFound - The component to render when no route\n * matches the destination.\n * @returns The resolved route match with handler and params.\n */\n return function (destination: string | null, notFound: ComponentType): Resolved<Handler> {\n const handler: Handler = { component: notFound }\n const fallbackResolved: Resolved<Handler> = { handler, params: {} }\n\n if (!destination) {\n return fallbackResolved\n }\n\n return matcher.match(new URL(destination, 'http://localhost').pathname) ?? fallbackResolved\n }\n}\n","import { useEffect, useEffectEvent } from 'react'\n\n/**\n * Callbacks for navigation lifecycle events. All callbacks\n * are optional — only provided callbacks are subscribed.\n */\nexport interface NavigationEventHandlers {\n /**\n * Called when a same-document navigation is initiated.\n * The Router uses this to intercept the event, match\n * the destination URL, and trigger a React transition.\n */\n readonly onNavigate?: (event: NavigateEvent) => void\n\n /**\n * Called after a navigation completes successfully.\n * Fires in sync with the Navigation API's\n * `navigatesuccess` event.\n */\n readonly onNavigateSuccess?: () => void\n\n /**\n * Called when a navigation fails. Receives the error\n * extracted from the Navigation API's `navigateerror`\n * ErrorEvent.\n *\n * @param error - The error that caused the navigation\n * to fail.\n */\n readonly onNavigateError?: (error: unknown) => void\n}\n\n/**\n * Subscribes to the Navigation API's `navigate`,\n * `navigatesuccess`, and `navigateerror` events on the\n * given navigation object. All callbacks are wrapped in\n * `useEffectEvent` so the effects only depend on the\n * navigation instance itself — inline arrow functions\n * from the caller don't cause unnecessary re-subscriptions.\n *\n * Cleans up all listeners on unmount or when the navigation\n * instance changes.\n *\n * @param navigation - The Navigation object to subscribe to.\n * @param handlers - Callbacks for each navigation lifecycle\n * event. All are optional.\n *\n * @example\n * ```tsx\n * function NavigationLogger() {\n * const navigation = useNavigation()\n *\n * useNavigationEvents(navigation, {\n * onNavigateSuccess() {\n * console.log('navigation completed')\n * },\n * onNavigateError(error) {\n * console.error('navigation failed', error)\n * },\n * })\n *\n * return null\n * }\n * ```\n */\nexport function useNavigationEvents(navigation: Navigation, handlers: NavigationEventHandlers) {\n /**\n * Stable wrapper for the navigate event callback. Reads\n * the latest `onNavigate` handler on each invocation\n * without causing the subscription effect to re-run.\n */\n const onNavigate = useEffectEvent(function (event: NavigateEvent) {\n handlers.onNavigate?.(event)\n })\n\n /**\n * Stable wrapper for the navigatesuccess callback.\n */\n const onSuccess = useEffectEvent(function () {\n handlers.onNavigateSuccess?.()\n })\n\n /**\n * Stable wrapper for the navigateerror callback.\n * Extracts the error from the ErrorEvent before\n * forwarding to the handler.\n */\n const onError = useEffectEvent(function (event: Event) {\n handlers.onNavigateError?.((event as ErrorEvent).error)\n })\n\n /**\n * Subscribes to all three navigation lifecycle events.\n * A single effect handles all subscriptions since they\n * share the same dependency (the navigation object) and\n * the same lifecycle (subscribe on mount, clean up on\n * unmount or navigation change).\n */\n useEffect(\n function () {\n navigation.addEventListener('navigate', onNavigate)\n navigation.addEventListener('navigatesuccess', onSuccess)\n navigation.addEventListener('navigateerror', onError)\n\n return function () {\n navigation.removeEventListener('navigate', onNavigate)\n navigation.removeEventListener('navigatesuccess', onSuccess)\n navigation.removeEventListener('navigateerror', onError)\n }\n },\n [navigation]\n )\n}\n","import { createContext } from 'react'\n\n/**\n * Provides the current URL pathname to descendant components.\n * Updated by the Router on every navigation with the pathname\n * extracted from the destination URL.\n *\n * Defaults to `null` when no Router is present in the tree —\n * the `usePathname` hook throws a descriptive error in this\n * case. Consumed by the `usePathname` hook and the `Link`\n * component for active link detection.\n */\nexport const PathnameContext = createContext<string | null>(null)\n","import { createContext } from 'react'\n\n/**\n * Provides the full committed URL string to descendant\n * components. Updated by the Router on every navigation\n * with the destination URL. Defaults to `null` when no\n * Router is present in the tree.\n *\n * Consumed by `useSearchParams` to derive search parameters\n * from React state rather than reading the mutable\n * `navigation.currentEntry` during render — preventing\n * subscription tearing in concurrent mode.\n */\nexport const UrlContext = createContext<string | null>(null)\n","/**\n * Extracts the pathname portion from a URL string. Uses a\n * dummy base URL to handle both absolute and relative paths\n * correctly. Returns `'/'` when the input is null or undefined.\n *\n * Used by the Router (to extract pathname from navigation\n * destination URLs), Link (for active link comparison), and\n * usePrefetch (to match URLs against registered routes).\n *\n * @param url - The URL string to extract a pathname from.\n * May be absolute (`https://example.com/foo`), relative\n * (`/foo/bar`), or nullish.\n * @returns The pathname string, or `'/'` when no URL is\n * provided.\n */\nexport function extractPathname(url: string | null | undefined): string {\n if (url === null || url === undefined) {\n return '/'\n }\n\n return new URL(url, 'http://localhost').pathname\n}\n","import {\n type ComponentType,\n type ReactNode,\n Suspense,\n use,\n useEffectEvent,\n useState,\n useTransition,\n} from 'react'\nimport { type Handler } from 'router/react:router'\nimport { type Matcher } from 'router:matcher'\nimport { ParamsContext } from 'router/react:context/ParamsContext'\nimport { NavigationContext } from 'router/react:context/NavigationContext'\nimport { NavigationSignalContext } from 'router/react:context/NavigationSignalContext'\nimport { NavigationTypeContext } from 'router/react:context/NavigationTypeContext'\nimport { type Resolved } from 'router:matcher'\nimport { Middlewares } from 'router/react:components/Middlewares'\nimport { NotFound } from 'router/react:components/NotFound'\nimport { useNavigationHandlers } from 'router/react:hooks/useNavigationHandlers'\nimport { useNextMatch } from 'router/react:hooks/useNextMatch'\nimport { useNavigationEvents } from 'router/react:hooks/useNavigationEvents'\nimport { MatcherContext } from 'router/react:context/MatcherContext'\nimport { TransitionContext } from 'router/react:context/TransitionContext'\nimport { PathnameContext } from 'router/react:context/PathnameContext'\nimport { UrlContext } from 'router/react:context/UrlContext'\nimport { extractPathname } from 'router/react:extractPathname'\n\n/**\n * Internal state tracked alongside the resolved route match.\n * Includes the AbortSignal and navigation type from the\n * NavigateEvent that produced this match.\n */\ninterface CurrentState {\n /**\n * The resolved route match containing the handler\n * configuration and extracted URL parameters.\n */\n match: Resolved<Handler>\n\n /**\n * The AbortSignal from the NavigateEvent that produced\n * this match. Aborts when the navigation is cancelled\n * by a newer navigation or the user pressing Stop.\n * Null for the initial render before any navigation event.\n */\n signal: AbortSignal | null\n\n /**\n * The type of navigation that produced this match\n * (`push`, `replace`, `reload`, or `traverse`).\n * Null for the initial render before any navigation event.\n */\n navigationType: NavigationType | null\n\n /**\n * The pathname extracted from the destination URL for this\n * navigation. Used by descendant components to determine\n * active links and read the current location.\n */\n pathname: string\n\n /**\n * The full destination URL string for this navigation.\n * Used by `useSearchParams` to derive search parameters\n * from React state rather than reading the mutable\n * `navigation.currentEntry` during render.\n */\n url: string | null\n}\n\n/**\n * Props accepted by the Router component.\n */\nexport interface RouterProps {\n /**\n * Route matcher instance with registered routes. When\n * omitted, falls back to the value from MatcherContext.\n */\n matcher?: Matcher<Handler>\n\n /**\n * Component to render when no route matches the current\n * URL. Defaults to the built-in NotFound component.\n */\n notFound?: ComponentType\n\n /**\n * Suspense fallback shown while lazy route components\n * or suspended middleware are loading.\n */\n fallback?: ReactNode\n\n /**\n * Native Navigation object override. Defaults to the value\n * from NavigationContext, which itself falls back to\n * `window.navigation`. Useful for testing or providing\n * a custom navigation instance.\n */\n navigation?: Navigation\n\n /**\n * Optional `useTransition()` tuple override. When omitted\n * the Router calls `useTransition()` internally. Provide\n * this when you need to read `isPending` above the Router\n * in the component tree, or to share a single transition\n * across multiple Routers.\n */\n transition?: ReturnType<typeof useTransition>\n\n /**\n * Callback invoked after a navigation completes successfully.\n * Fires in sync with the Navigation API's `navigatesuccess`\n * event. Wrapped in `useEffectEvent` internally so inline\n * arrow functions don't cause effect churn.\n */\n onNavigateSuccess?: () => void\n\n /**\n * Callback invoked when a navigation fails. Receives the\n * error from the Navigation API's `navigateerror` event.\n * Wrapped in `useEffectEvent` internally so inline arrow\n * functions don't cause effect churn.\n *\n * @param error - The error that caused the navigation\n * to fail.\n */\n onNavigateError?: (error: unknown) => void\n}\n\n/**\n * Top-level router component that listens to the Navigation API's\n * `navigate` event, matches the destination URL against registered\n * routes, and renders the matched component inside Suspense with\n * middleware support.\n *\n * Calls `useTransition()` internally to wrap navigation state\n * updates in concurrent transitions. An optional `transition` prop\n * allows overriding this when the consuming code needs to read\n * `isPending` above the Router in the tree.\n *\n * Accepts optional `navigation` and `matcher` overrides; falls back\n * to context values when not provided. The navigation object\n * ultimately falls back to `window.navigation` when neither a prop\n * nor a context value is available.\n *\n * Provides several contexts to descendant components:\n * - `TransitionContext` — the `[isPending, startTransition]` tuple\n * - `NavigationContext` — the Navigation object\n * - `MatcherContext` — the route matcher\n * - `NavigationTypeContext` — the current navigation type\n * - `NavigationSignalContext` — the current AbortSignal\n * - `PathnameContext` — the current URL pathname\n * - `ParamsContext` — the extracted route parameters\n */\nexport function Router(props: RouterProps) {\n const contextNavigation = use(NavigationContext)\n const navigation: Navigation =\n props.navigation ??\n contextNavigation ??\n (typeof window !== 'undefined' ? window.navigation : undefined)!\n\n if (navigation === undefined || navigation === null) {\n throw new Error(\n 'Router requires a navigation prop, NavigationContext provider, ' +\n 'or browser Navigation API support. ' +\n 'Use createMemoryNavigation() for SSR or non-browser environments.'\n )\n }\n const matcher: Matcher<Handler> = props.matcher ?? use(MatcherContext)\n const internalTransition = useTransition()\n const transition = props.transition ?? internalTransition\n const next = useNextMatch({ matcher })\n const notFound = props.notFound ?? NotFound\n\n const [current, setCurrent] = useState<CurrentState>(function () {\n const url = navigation.currentEntry?.url ?? null\n\n return {\n match: next(url, notFound),\n signal: null,\n navigationType: null,\n pathname: extractPathname(url),\n url,\n }\n })\n\n /**\n * Extracts navigation handler factories using the resolved\n * transition tuple directly, bypassing TransitionContext.\n * This is necessary because Router provides TransitionContext\n * in its JSX return, which hasn't rendered at this point.\n */\n const { createPrecommitHandler, createHandler } = useNavigationHandlers(transition)\n\n /**\n * Central navigate event handler. Intercepts all same-document\n * navigations including link clicks, form submissions,\n * back/forward buttons, and programmatic navigation.\n *\n * Skips non-interceptable navigations, hash-only changes,\n * and download requests. For form submissions with a dedicated\n * `formHandler`, delegates to that handler instead of the\n * normal component render flow.\n */\n const onNavigate = useEffectEvent(function (event: NavigateEvent) {\n if (!event.canIntercept || event.hashChange || event.downloadRequest !== null) {\n return\n }\n\n const match = next(event.destination.url, notFound)\n\n if (event.formData !== null && match.handler.formHandler !== undefined) {\n event.intercept({\n scroll: match.handler.scroll,\n focusReset: match.handler.focusReset,\n async handler() {\n await match.handler.formHandler!(event.formData!, event)\n },\n })\n\n return\n }\n\n const precommitHandler = createPrecommitHandler({\n prefetch: match.handler.prefetch,\n params: match.params,\n url: new URL(event.destination.url),\n })\n\n const handler = createHandler(function () {\n setCurrent({\n match,\n signal: event.signal,\n navigationType: event.navigationType,\n pathname: extractPathname(event.destination.url),\n url: event.destination.url,\n })\n })\n\n event.intercept({\n handler,\n precommitHandler,\n scroll: match.handler.scroll,\n focusReset: match.handler.focusReset,\n })\n })\n\n useNavigationEvents(navigation, {\n onNavigate,\n onNavigateSuccess: props.onNavigateSuccess,\n onNavigateError: props.onNavigateError,\n })\n\n const CurrentComponent = current.match.handler.component\n const middlewares = current.match.handler.middlewares\n\n return (\n <TransitionContext value={transition}>\n <NavigationContext value={navigation}>\n <MatcherContext value={matcher}>\n <NavigationTypeContext value={current.navigationType}>\n <NavigationSignalContext value={current.signal}>\n <PathnameContext value={current.pathname}>\n <UrlContext value={current.url}>\n <ParamsContext value={current.match.params}>\n <Suspense fallback={props.fallback}>\n <Middlewares value={middlewares}>\n <CurrentComponent />\n </Middlewares>\n </Suspense>\n </ParamsContext>\n </UrlContext>\n </PathnameContext>\n </NavigationSignalContext>\n </NavigationTypeContext>\n </MatcherContext>\n </NavigationContext>\n </TransitionContext>\n )\n}\n","import { use } from 'react'\nimport { PathnameContext } from 'router/react:context/PathnameContext'\nimport { extractPathname } from 'router/react:extractPathname'\n\n/**\n * Options for the `useActiveLinkProps` hook.\n */\nexport interface ActiveLinkOptions {\n /**\n * When true, the link is only considered active when\n * the current pathname exactly matches the href\n * pathname. When false, the link is active when the\n * current pathname starts with the href pathname,\n * which is useful for parent navigation items that\n * should highlight when any child route is active.\n *\n * Defaults to `true`.\n */\n exact?: boolean\n}\n\n/**\n * Props returned by the hook to spread onto an anchor\n * element for active link styling and accessibility.\n */\nexport interface ActiveLinkProps {\n /**\n * Present (set to `true`) when the link is active.\n * Absent (`undefined`) when inactive. Use the\n * `a[data-active]` CSS selector for styling.\n */\n 'data-active': true | undefined\n\n /**\n * Set to `'page'` when the link is active to indicate\n * to assistive technologies that this link represents\n * the current page. Absent when inactive.\n */\n 'aria-current': 'page' | undefined\n}\n\n/**\n * Computes active link attributes for an anchor element\n * by comparing its href against the current pathname from\n * the Router's PathnameContext.\n *\n * Returns a props object containing `data-active` and\n * `aria-current` attributes ready to spread onto an `<a>`\n * element or any element that should reflect active state.\n *\n * Also returns an `isActive` boolean for conditional logic\n * like dynamic class names.\n *\n * Must be used inside a `<Router>` component tree where\n * `PathnameContext` is provided.\n *\n * @param href - The href to compare against the current\n * pathname. When undefined, the link is never active.\n * @param options - Optional configuration for exact vs\n * prefix matching.\n * @returns An object with `isActive` boolean and `props`\n * to spread onto the element.\n *\n * @example\n * ```tsx\n * function NavItem({ href, children }: NavItemProps) {\n * const { isActive, props } = useActiveLinkProps(href)\n *\n * return (\n * <a href={href} className={isActive ? 'active' : ''} {...props}>\n * {children}\n * </a>\n * )\n * }\n * ```\n */\nexport function useActiveLinkProps(\n href: string | undefined,\n options?: ActiveLinkOptions\n): { isActive: boolean; props: ActiveLinkProps } {\n const currentPathname = use(PathnameContext)\n\n if (currentPathname === null) {\n return {\n isActive: false,\n props: {\n 'data-active': undefined,\n 'aria-current': undefined,\n },\n }\n }\n\n const isExact = options?.exact ?? true\n\n const isActive = isActiveHref(href, currentPathname, isExact)\n\n return {\n isActive,\n props: {\n 'data-active': isActive || undefined,\n 'aria-current': isActive ? 'page' : undefined,\n },\n }\n}\n\n/**\n * Determines whether an href should be considered active\n * by comparing its pathname against the current router\n * pathname. Handles undefined hrefs, exact matching, and\n * prefix matching for parent-level navigation items.\n *\n * @param href - The href string to test. Returns false\n * when undefined.\n * @param currentPathname - The current pathname from the\n * router's PathnameContext.\n * @param isExact - Whether to require an exact match or\n * allow prefix matching.\n * @returns True when the href should be marked as active.\n */\nfunction isActiveHref(\n href: string | undefined,\n currentPathname: string,\n isExact: boolean\n): boolean {\n if (href === undefined) {\n return false\n }\n\n const linkPathname = extractPathname(href)\n\n if (isExact) {\n return linkPathname === currentPathname\n }\n\n return currentPathname === linkPathname || currentPathname.startsWith(linkPathname + '/')\n}\n","import { use } from 'react'\nimport { MatcherContext } from 'router/react:context/MatcherContext'\nimport { type Handler, type PrefetchContext } from 'router/react:router'\nimport { type Matcher } from 'router:matcher'\n\n/**\n * Options for the `usePrefetch` hook.\n */\nexport interface PrefetchOptions {\n /**\n * Optional matcher override. When omitted the hook reads\n * from `MatcherContext`.\n */\n matcher?: Matcher<Handler>\n}\n\n/**\n * Tracks URL pathnames that have already been prefetched,\n * keyed by matcher instance. Using a WeakMap ensures that\n * each matcher (and therefore each Router) gets its own\n * dedup set, and the set is garbage-collected when the\n * matcher is no longer referenced. This prevents cross-\n * contamination between independent Router instances and\n * between isolated test environments.\n */\nconst prefetchedByMatcher = new WeakMap<Matcher<Handler>, Set<string>>()\n\n/**\n * Clears the prefetch deduplication cache for a specific\n * matcher instance. After clearing, subsequent calls to the\n * prefetch function will re-execute handlers for pathnames\n * that were previously skipped.\n *\n * Useful when cached data becomes stale — for example after\n * a user logs out, a form submission invalidates server\n * state, or a known data expiry occurs.\n *\n * When called without a matcher argument, has no effect.\n * The cache is automatically garbage-collected when the\n * matcher instance is no longer referenced, so explicit\n * clearing is only needed for long-lived matchers.\n *\n * @param matcher - The matcher whose prefetch cache should\n * be cleared.\n *\n * @example\n * ```tsx\n * function LogoutButton() {\n * const navigate = useNavigate()\n * const matcher = use(MatcherContext)\n *\n * return (\n * <button onClick={function () {\n * clearPrefetchCache(matcher)\n * navigate('/login', { history: 'replace' })\n * }}>\n * Log Out\n * </button>\n * )\n * }\n * ```\n */\nexport function clearPrefetchCache(matcher: Matcher<Handler>) {\n prefetchedByMatcher.delete(matcher)\n}\n\n/**\n * Returns a function that triggers the prefetch logic for a\n * given URL by resolving it against the matcher and calling\n * the route's prefetch function. Used by the Link component\n * for hover and viewport prefetch strategies.\n *\n * Each pathname is prefetched at most once per matcher\n * instance per page session. Subsequent calls with the same\n * pathname are no-ops, preventing thundering-herd problems\n * when many Links point to the same destination.\n *\n * Since prefetch triggered from Link happens outside of a\n * navigation event, a stub NavigationPrecommitController is\n * passed (the redirect capability is not meaningful here).\n *\n * @param options - Optional matcher override.\n * @returns A function that accepts a URL string and invokes\n * the matched route's prefetch handler, if any.\n *\n * @example\n * ```tsx\n * function PrefetchOnHover({ href, children }: Props) {\n * const prefetch = usePrefetch()\n *\n * return (\n * <a\n * href={href}\n * onMouseEnter={function () { prefetch(href) }}\n * >\n * {children}\n * </a>\n * )\n * }\n * ```\n */\nexport function usePrefetch(options?: PrefetchOptions) {\n const matcher = options?.matcher ?? use(MatcherContext)\n\n /**\n * Triggers prefetch for the given URL by matching it against\n * registered routes and calling the route's prefetch function\n * with a context containing the matched params, the parsed\n * URL, and a stub controller. Extracts the pathname from the\n * URL before matching to handle both absolute and relative URLs.\n *\n * Returns early without calling the handler when the pathname\n * has already been prefetched or is currently in-flight for\n * this matcher instance.\n *\n * @param url - The URL or path to prefetch data for.\n * @returns The prefetch promise, or undefined if no prefetch\n * handler is registered for the matched route or if the\n * pathname has already been prefetched.\n */\n return function (url: string) {\n const parsed = new URL(url, 'http://localhost')\n const match = matcher.match(parsed.pathname)\n\n if (match?.handler.prefetch === undefined) {\n return\n }\n\n let prefetched = prefetchedByMatcher.get(matcher)\n\n if (prefetched === undefined) {\n prefetched = new Set()\n prefetchedByMatcher.set(matcher, prefetched)\n }\n\n if (prefetched.has(parsed.pathname)) {\n return\n }\n\n prefetched.add(parsed.pathname)\n\n /**\n * Stub controller for prefetch outside of navigation events.\n * Redirect and addHandler are no-ops in this context since\n * there is no actual navigation to modify.\n */\n const stubController: NavigationPrecommitController = {\n redirect() {},\n addHandler() {},\n }\n\n const context: PrefetchContext = {\n params: match.params,\n url: parsed,\n controller: stubController,\n }\n\n return match.handler.prefetch(context)\n }\n}\n","import { type RefObject, useEffect, useEffectEvent } from 'react'\nimport { usePrefetch } from 'router/react:hooks/usePrefetch'\nimport { type Handler } from 'router/react:router'\nimport { type Matcher } from 'router:matcher'\n\n/**\n * Prefetch trigger strategy. Determines which DOM event\n * activates the prefetch for the target element.\n *\n * - `viewport` — prefetch fires when the element enters\n * the viewport via an IntersectionObserver.\n * - `hover` — prefetch fires on `mouseenter`.\n */\nexport type PrefetchStrategy = 'viewport' | 'hover'\n\n/**\n * Options for the `usePrefetchEffect` hook.\n */\nexport interface PrefetchEffectOptions {\n /**\n * The URL to prefetch. When undefined, the effect is\n * a no-op (no observer or listener is attached).\n */\n href: string | undefined\n\n /**\n * Prefetch trigger strategy. When undefined, the effect\n * is a no-op — no proactive prefetch is set up.\n */\n on: PrefetchStrategy | undefined\n\n /**\n * Whether to only prefetch once. When true, hover\n * listeners use the `{ once }` option and viewport\n * observers disconnect after the first intersection.\n * Defaults to `true`.\n */\n once?: boolean\n\n /**\n * Optional matcher override. When omitted, reads from\n * `MatcherContext` via `usePrefetch`.\n */\n matcher?: Matcher<Handler>\n}\n\n/**\n * Attaches prefetch behavior to a DOM element via a ref.\n * Sets up an IntersectionObserver (for `viewport` strategy)\n * or a mouseenter listener (for `hover` strategy) that\n * triggers route prefetching when activated.\n *\n * When `on` is undefined or `href` is undefined, no\n * observer or listener is attached — the hook is a no-op.\n *\n * This hook is used internally by the Link component and\n * can also be used standalone to add prefetch behavior to\n * any DOM element.\n *\n * @param ref - A ref to the DOM element to observe. The\n * element must be mounted before the effect runs.\n * @param options - Configuration for the prefetch behavior\n * including the URL, trigger strategy, and matcher.\n *\n * @example\n * ```tsx\n * function Card({ href }: { href: string }) {\n * const ref = useRef<HTMLDivElement>(null)\n *\n * usePrefetchEffect(ref, { href, on: 'viewport' })\n *\n * return <div ref={ref}>...</div>\n * }\n * ```\n */\nexport function usePrefetchEffect(ref: RefObject<Element | null>, options: PrefetchEffectOptions) {\n const { href, on, once = true, matcher } = options\n const prefetchRoute = usePrefetch({ matcher })\n\n /**\n * IntersectionObserver callback that triggers prefetch\n * when the element enters the viewport. Disconnects\n * the observer after the first intersection when `once`\n * is true.\n */\n const onViewportIntersection = useEffectEvent<IntersectionObserverCallback>(\n function (entries, observer) {\n for (const entry of entries) {\n if (entry.isIntersecting && href !== undefined) {\n void prefetchRoute(href)\n }\n }\n\n if (once) {\n observer.disconnect()\n }\n }\n )\n\n /**\n * Mouse enter callback that triggers prefetch when the\n * user hovers over the element.\n */\n const onHover = useEffectEvent<EventListener>(function () {\n if (href !== undefined) {\n void prefetchRoute(href)\n }\n })\n\n /**\n * Sets up the prefetch observer or listener based on the\n * chosen strategy. When `on` is undefined, no setup is\n * performed. Cleans up on unmount or when the strategy,\n * once flag, or href changes.\n */\n useEffect(\n function () {\n if (on === undefined) {\n return\n }\n\n const current = ref.current\n\n if (current === null) {\n return\n }\n\n switch (on) {\n case 'hover': {\n current.addEventListener('mouseenter', onHover, { once })\n\n return function () {\n current.removeEventListener('mouseenter', onHover)\n }\n }\n case 'viewport': {\n const observer = new IntersectionObserver(onViewportIntersection)\n\n observer.observe(current)\n\n return function () {\n observer.disconnect()\n }\n }\n }\n },\n [on, once, href, ref]\n )\n}\n","import { type AnchorHTMLAttributes, useRef } from 'react'\nimport { useActiveLinkProps } from 'router/react:hooks/useActiveLinkProps'\nimport { type PrefetchStrategy, usePrefetchEffect } from 'router/react:hooks/usePrefetchEffect'\nimport { type Handler } from 'router/react:router'\nimport { type Matcher } from 'router:matcher'\n\n/**\n * State passed to the className function variant, allowing\n * consumers to dynamically compute class names based on the\n * link's active state.\n */\nexport interface LinkRenderProps {\n /**\n * Whether this link's href matches the current pathname.\n * True for both exact and prefix matches depending on\n * the `activeExact` prop.\n */\n readonly isActive: boolean\n}\n\n/**\n * Props for the Link component, extending standard anchor\n * element attributes with router-specific prefetch behavior\n * and active link detection.\n */\nexport interface LinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'className'> {\n /**\n * Prefetch trigger strategy. When set to `'hover'`,\n * prefetch fires on mouseenter. When set to `'viewport'`,\n * prefetch fires when the link enters the viewport via\n * IntersectionObserver. When omitted, no proactive\n * prefetch is performed — the Navigation API handles\n * it during the click navigation.\n */\n prefetch?: PrefetchStrategy\n\n /**\n * Whether to only prefetch once. When true, hover\n * listeners use the `{ once }` option and viewport\n * observers disconnect after the first intersection.\n * Defaults to `true`.\n */\n once?: boolean\n\n /**\n * Optional matcher override. When omitted, reads from\n * `MatcherContext`. Useful when you need to prefetch\n * against a specific set of routes.\n */\n matcher?: Matcher<Handler>\n\n /**\n * CSS class name(s) for the anchor element. Accepts either\n * a static string or a function that receives the link's\n * active state and returns a class name string. The function\n * form is useful for conditional styling based on whether\n * the link is currently active.\n *\n * @example\n * ```tsx\n * <Link\n * href=\"/about\"\n * className={({ isActive }) => isActive ? 'nav-active' : 'nav-link'}\n * />\n * ```\n */\n className?: string | ((props: LinkRenderProps) => string)\n\n /**\n * When true, the link is only considered active when the\n * current pathname exactly matches the href pathname.\n * When false, the link is active when the current\n * pathname starts with the href pathname, which is useful\n * for parent navigation items that should highlight when\n * any child route is active.\n *\n * Defaults to `true`.\n */\n activeExact?: boolean\n}\n\n/**\n * Renders an anchor element that integrates with the router's\n * prefetch system and active link detection. The Navigation\n * API intercepts the click natively, so no `onClick` or\n * `preventDefault` is needed.\n *\n * Supports two proactive prefetch strategies: `hover`\n * (prefetch on mouseenter) and `viewport` (prefetch when\n * the link scrolls into view via IntersectionObserver).\n * When `prefetch` is omitted, no proactive prefetch is\n * performed.\n *\n * When the link's href matches the current pathname, the\n * component adds `data-active` and `aria-current=\"page\"`\n * attributes. The `className` prop can be a function that\n * receives `{ isActive }` for dynamic class computation.\n */\nexport function Link({\n prefetch,\n once = true,\n href,\n matcher,\n className,\n activeExact = true,\n ...props\n}: LinkProps) {\n const ref = useRef<HTMLAnchorElement>(null)\n const { isActive, props: activeProps } = useActiveLinkProps(href, { exact: activeExact })\n\n usePrefetchEffect(ref, { href, on: prefetch, once, matcher })\n\n const resolvedClassName = typeof className === 'function' ? className({ isActive }) : className\n\n return <a ref={ref} href={href} className={resolvedClassName} {...activeProps} {...props} />\n}\n","import { use } from 'react'\nimport { NavigationContext } from 'router/react:context/NavigationContext'\n\n/**\n * Returns the native browser Navigation object from context.\n * Gives full access to the Navigation API: `entries()`,\n * `traverseTo()`, `updateCurrentEntry()`, `canGoBack`,\n * `canGoForward`, `transition`, `currentEntry`, etc.\n *\n * Must be used inside a `<Router>` or a component tree\n * that provides a `<NavigationContext>` value.\n *\n * @returns The Navigation object from the nearest provider.\n * @throws When used outside a NavigationContext provider.\n *\n * @example\n * ```tsx\n * function HistoryDebug() {\n * const navigation = useNavigation()\n * const entries = navigation.entries()\n *\n * return <pre>{JSON.stringify(entries.map(e => e.url))}</pre>\n * }\n * ```\n */\nexport function useNavigation(): Navigation {\n const navigation = use(NavigationContext)\n\n if (navigation === null) {\n throw new Error('useNavigation requires a <Router> or <NavigationContext> provider')\n }\n\n return navigation\n}\n","import { useNavigation } from 'router/react:hooks/useNavigation'\n\n/**\n * Returns a function to programmatically navigate to a URL\n * with full Navigation API options support (`state`, `info`,\n * `history`). This is a thin convenience wrapper around\n * `navigation.navigate()`.\n *\n * @returns A navigate function that accepts a URL string and\n * optional `NavigationNavigateOptions`.\n *\n * @example\n * ```tsx\n * function LogoutButton() {\n * const navigate = useNavigate()\n *\n * return (\n * <button onClick={function () {\n * navigate('/login', { history: 'replace' })\n * }}>\n * Log Out\n * </button>\n * )\n * }\n * ```\n */\nexport function useNavigate() {\n const navigation = useNavigation()\n\n /**\n * Programmatically navigates to the given URL. Delegates\n * to the native `navigation.navigate()` method, which\n * fires the `navigate` event intercepted by the Router.\n *\n * @param url - The destination URL to navigate to.\n * @param options - Optional Navigation API options including\n * `state`, `info`, and `history` behavior.\n * @returns The NavigationResult from the Navigation API.\n */\n return function (url: string, options?: NavigationNavigateOptions) {\n return navigation.navigate(url, options)\n }\n}\n","import { use } from 'react'\nimport { NavigationSignalContext } from 'router/react:context/NavigationSignalContext'\n\n/**\n * Returns the AbortSignal from the current navigation event.\n * The signal aborts when the navigation is cancelled (e.g.,\n * by the user pressing Stop or a new navigation superseding\n * this one). Pass this to fetch calls or other cancellable\n * async operations to avoid stale work.\n *\n * Returns `null` before any navigation event has occurred\n * (i.e. on the initial render).\n *\n * Must be used inside a `<Router>` component tree.\n *\n * @returns The current AbortSignal or null.\n * @throws When used outside a Router or NavigationSignalContext\n * provider.\n *\n * @example\n * ```tsx\n * function UserProfile({ id }: { id: string }) {\n * const signal = useNavigationSignal()\n *\n * useEffect(function () {\n * fetch(`/api/user/${id}`, { signal })\n * }, [id, signal])\n * }\n * ```\n */\nexport function useNavigationSignal(): AbortSignal | null {\n const signal = use(NavigationSignalContext)\n\n if (signal === undefined) {\n throw new Error('useNavigationSignal requires a <Router> or <NavigationSignalContext> provider')\n }\n\n return signal\n}\n","import { use } from 'react'\nimport { NavigationTypeContext } from 'router/react:context/NavigationTypeContext'\n\n/**\n * Returns the navigation type of the most recent navigation\n * (`push`, `replace`, `reload`, or `traverse`). Useful for\n * varying animations, skipping prefetch on reload, or\n * applying different behavior for back/forward traversals.\n *\n * Returns `null` before any navigation event has occurred\n * (i.e. on the initial render).\n *\n * Must be used inside a `<Router>` component tree.\n *\n * @returns The current NavigationType or null.\n * @throws When used outside a Router or NavigationTypeContext\n * provider.\n *\n * @example\n * ```tsx\n * function PageTransition({ children }: { children: ReactNode }) {\n * const type = useNavigationType()\n * const isTraversal = type === 'traverse'\n *\n * return (\n * <div className={isTraversal ? 'slide' : 'fade'}>\n * {children}\n * </div>\n * )\n * }\n * ```\n */\nexport function useNavigationType(): NavigationType | null {\n const navigationType = use(NavigationTypeContext)\n\n if (navigationType === undefined) {\n throw new Error('useNavigationType requires a <Router> or <NavigationTypeContext> provider')\n }\n\n return navigationType\n}\n","import { use } from 'react'\nimport { ParamsContext } from 'router/react:context/ParamsContext'\n\n/**\n * Returns the dynamic route parameters extracted from the\n * currently matched URL pattern. The keys correspond to the\n * `:param` names defined in the route pattern, and the values\n * are the matching URL segments.\n *\n * Must be used inside a `<Router>` component tree where\n * `ParamsContext` is provided.\n *\n * @returns A record of parameter names to their string values.\n * @throws When used outside a Router or ParamsContext provider.\n *\n * @example\n * ```tsx\n * // Route pattern: \"/user/:id\"\n * // URL: \"/user/42\"\n * const { id } = useParams() // id === \"42\"\n * ```\n */\nexport function useParams(): Record<string, string> {\n const params = use(ParamsContext)\n\n if (params === null) {\n throw new Error('useParams requires a <Router> or <ParamsContext> provider')\n }\n\n return params\n}\n","import { use } from 'react'\nimport { TransitionContext } from 'router/react:context/TransitionContext'\n\n/**\n * Returns whether a navigation transition is currently pending.\n * This reflects the `isPending` value from the `useTransition`\n * tuple managed by the Router component.\n *\n * Useful for displaying loading indicators, progress bars, or\n * adjusting UI opacity while a route transition is in progress.\n *\n * Must be used inside a `<Router>` component tree or a\n * `<TransitionContext>` provider.\n *\n * @returns `true` while a navigation transition is pending,\n * `false` otherwise.\n * @throws When used outside a TransitionContext provider.\n *\n * @example\n * ```tsx\n * function NavBar() {\n * const isPending = useIsPending()\n *\n * return (\n * <nav style={{ opacity: isPending ? 0.7 : 1 }}>\n * ...\n * </nav>\n * )\n * }\n * ```\n */\nexport function useIsPending(): boolean {\n const transition = use(TransitionContext)\n\n if (transition === null) {\n throw new Error('useIsPending requires a <Router> or <TransitionContext> provider')\n }\n\n return transition[0]\n}\n","import { use } from 'react'\nimport { PathnameContext } from 'router/react:context/PathnameContext'\n\n/**\n * Returns the current URL pathname from the Router's state.\n * The value updates on every navigation and reflects the\n * pathname of the committed destination URL.\n *\n * Useful for active link detection, conditional rendering\n * based on the current route, or building breadcrumbs.\n *\n * Must be used inside a `<Router>` component tree where\n * `PathnameContext` is provided.\n *\n * @returns The current pathname string (e.g. `\"/user/42\"`).\n * @throws When used outside a Router or PathnameContext provider.\n *\n * @example\n * ```tsx\n * function Breadcrumb() {\n * const pathname = usePathname()\n *\n * return <span>{pathname}</span>\n * }\n * ```\n */\nexport function usePathname(): string {\n const pathname = use(PathnameContext)\n\n if (pathname === null) {\n throw new Error('usePathname requires a <Router> or <PathnameContext> provider')\n }\n\n return pathname\n}\n","import { use } from 'react'\nimport { UrlContext } from 'router/react:context/UrlContext'\nimport { useNavigation } from 'router/react:hooks/useNavigation'\n\n/**\n * Updater function signature for setting search params.\n * Accepts either a new URLSearchParams instance, a plain\n * record of string key-value pairs, or a function that\n * receives the current params and returns updated params.\n */\nexport type SearchParamsUpdater =\n | URLSearchParams\n | Record<string, string>\n | ((current: URLSearchParams) => URLSearchParams | Record<string, string>)\n\n/**\n * Options for the search params navigation performed by\n * the setter function returned from `useSearchParams`.\n */\nexport interface SetSearchParamsOptions {\n /**\n * History behavior for the navigation. Defaults to\n * `'replace'` since search param changes typically\n * should not create new history entries.\n */\n history?: NavigationHistoryBehavior\n}\n\n/**\n * Returns the current URL's search parameters as a\n * `URLSearchParams` instance and a setter function to\n * update them via navigation.\n *\n * The getter derives search params from `UrlContext` —\n * React state managed by the Router — rather than reading\n * the mutable `navigation.currentEntry` during render.\n * This prevents subscription tearing in concurrent mode\n * where two components could otherwise see different\n * search params if a navigation fires mid-render.\n *\n * The setter preserves the existing hash fragment when\n * updating search parameters.\n *\n * The React Compiler handles memoization of the setter,\n * so no manual `useCallback` is needed.\n *\n * Must be used inside a `<Router>` component tree.\n *\n * @returns A tuple of `[searchParams, setSearchParams]`.\n *\n * @example\n * ```tsx\n * function SearchPage() {\n * const [searchParams, setSearchParams] = useSearchParams()\n * const query = searchParams.get('q') ?? ''\n *\n * return (\n * <input\n * value={query}\n * onChange={function (event) {\n * setSearchParams({ q: event.target.value })\n * }}\n * />\n * )\n * }\n * ```\n */\nexport function useSearchParams(): [\n URLSearchParams,\n (updater: SearchParamsUpdater, options?: SetSearchParamsOptions) => NavigationResult,\n] {\n const navigation = useNavigation()\n const currentUrl = use(UrlContext)\n\n const searchParams = currentUrl\n ? new URL(currentUrl, 'http://localhost').searchParams\n : new URLSearchParams()\n\n /**\n * Navigates to the current pathname with updated search\n * parameters. Accepts a URLSearchParams instance, a plain\n * record, or a function that receives the current params\n * and returns new ones. Preserves the existing hash\n * fragment.\n */\n function setSearchParams(updater: SearchParamsUpdater, options?: SetSearchParamsOptions) {\n const url = new URL(currentUrl ?? '/', 'http://localhost')\n\n const next = typeof updater === 'function' ? updater(url.searchParams) : updater\n\n const nextParams = next instanceof URLSearchParams ? next : new URLSearchParams(next)\n\n const search = nextParams.toString()\n const destination = url.pathname + (search ? '?' + search : '') + url.hash\n\n return navigation.navigate(destination, {\n history: options?.history ?? 'replace',\n })\n }\n\n return [searchParams, setSearchParams]\n}\n","import { useEffect, useState } from 'react'\nimport { useNavigation } from 'router/react:hooks/useNavigation'\n\n/**\n * Return value from the `useBack` hook, providing both\n * a traversal function and a boolean indicating whether\n * backward navigation is possible.\n */\nexport interface UseBackResult {\n /**\n * Navigates backward in the session history. Delegates\n * to `navigation.back()` from the Navigation API.\n *\n * @param options - Optional navigation options such as\n * `info` to pass data to the navigate event handler.\n * @returns The NavigationResult with `committed` and\n * `finished` promises.\n */\n readonly back: (options?: NavigationOptions) => NavigationResult\n\n /**\n * Whether backward navigation is possible. Mirrors\n * `navigation.canGoBack` from the Navigation API.\n * Reactively updates when navigations change the\n * history stack. When false, calling `back()` will throw.\n */\n readonly canGoBack: boolean\n}\n\n/**\n * Provides backward navigation capabilities using the\n * Navigation API. Returns a `back` function and a\n * `canGoBack` boolean that reflects whether the history\n * stack has a previous entry to traverse to.\n *\n * The `canGoBack` value is kept in React state and\n * updated via the `currententrychange` event, ensuring\n * it stays reactive across navigations — including those\n * triggered outside of React (e.g. browser back button).\n *\n * Must be used inside a `<Router>` component tree.\n *\n * @returns An object with `back` and `canGoBack`.\n *\n * @example\n * ```tsx\n * function BackButton() {\n * const { back, canGoBack } = useBack()\n *\n * return (\n * <button onClick={back} disabled={!canGoBack}>\n * Go Back\n * </button>\n * )\n * }\n * ```\n */\nexport function useBack(): UseBackResult {\n const navigation = useNavigation()\n const [canGoBack, setCanGoBack] = useState(navigation.canGoBack)\n\n useEffect(\n function () {\n /**\n * Syncs the React state with the Navigation API's\n * `canGoBack` property whenever the current entry\n * changes.\n */\n function onEntryChange() {\n setCanGoBack(navigation.canGoBack)\n }\n\n navigation.addEventListener('currententrychange', onEntryChange)\n\n return function () {\n navigation.removeEventListener('currententrychange', onEntryChange)\n }\n },\n [navigation]\n )\n\n /**\n * Traverses backward in the session history by\n * delegating to `navigation.back()`.\n */\n function back(options?: NavigationOptions) {\n return navigation.back(options)\n }\n\n return {\n back,\n canGoBack,\n }\n}\n","import { useEffect, useState } from 'react'\nimport { useNavigation } from 'router/react:hooks/useNavigation'\n\n/**\n * Return value from the `useForward` hook, providing both\n * a traversal function and a boolean indicating whether\n * forward navigation is possible.\n */\nexport interface UseForwardResult {\n /**\n * Navigates forward in the session history. Delegates\n * to `navigation.forward()` from the Navigation API.\n *\n * @param options - Optional navigation options such as\n * `info` to pass data to the navigate event handler.\n * @returns The NavigationResult with `committed` and\n * `finished` promises.\n */\n readonly forward: (options?: NavigationOptions) => NavigationResult\n\n /**\n * Whether forward navigation is possible. Mirrors\n * `navigation.canGoForward` from the Navigation API.\n * Reactively updates when navigations change the\n * history stack. When false, calling `forward()` will\n * throw.\n */\n readonly canGoForward: boolean\n}\n\n/**\n * Provides forward navigation capabilities using the\n * Navigation API. Returns a `forward` function and a\n * `canGoForward` boolean that reflects whether the history\n * stack has a next entry to traverse to.\n *\n * The `canGoForward` value is kept in React state and\n * updated via the `currententrychange` event, ensuring\n * it stays reactive across navigations — including those\n * triggered outside of React (e.g. browser forward button).\n *\n * Must be used inside a `<Router>` component tree.\n *\n * @returns An object with `forward` and `canGoForward`.\n *\n * @example\n * ```tsx\n * function ForwardButton() {\n * const { forward, canGoForward } = useForward()\n *\n * return (\n * <button onClick={forward} disabled={!canGoForward}>\n * Go Forward\n * </button>\n * )\n * }\n * ```\n */\nexport function useForward(): UseForwardResult {\n const navigation = useNavigation()\n const [canGoForward, setCanGoForward] = useState(navigation.canGoForward)\n\n useEffect(\n function () {\n /**\n * Syncs the React state with the Navigation API's\n * `canGoForward` property whenever the current entry\n * changes.\n */\n function onEntryChange() {\n setCanGoForward(navigation.canGoForward)\n }\n\n navigation.addEventListener('currententrychange', onEntryChange)\n\n return function () {\n navigation.removeEventListener('currententrychange', onEntryChange)\n }\n },\n [navigation]\n )\n\n /**\n * Traverses forward in the session history by\n * delegating to `navigation.forward()`.\n */\n function forward(options?: NavigationOptions) {\n return navigation.forward(options)\n }\n\n return {\n forward,\n canGoForward,\n }\n}\n","/**\n * Minimal subset of the NavigationHistoryEntry interface\n * needed by the Router component and associated hooks. Only\n * the `url` property is read during rendering. The full\n * NavigationHistoryEntry interface is far larger, but the\n * Router never accesses properties like `key`, `id`,\n * `sameDocument`, `getState`, or the event handlers.\n */\ninterface MemoryNavigationEntry {\n /**\n * The full URL string for this history entry.\n */\n readonly url: string\n}\n\n/**\n * Options for creating a memory navigation instance.\n */\nexport interface MemoryNavigationOptions {\n /**\n * The initial URL for the memory navigation. This is the\n * URL that `currentEntry.url` will return. Typically the\n * request URL from the server for SSR, or a test URL.\n *\n * @example `'https://example.com/user/42?tab=posts'`\n */\n readonly url: string\n}\n\n/**\n * Creates a minimal in-memory Navigation object suitable for\n * server-side rendering and testing environments where the\n * browser Navigation API is unavailable.\n *\n * The returned object satisfies the subset of the `Navigation`\n * interface consumed by the Router component and hooks:\n *\n * - `currentEntry.url` — returns the initial URL\n * - `addEventListener` / `removeEventListener` — no-ops\n * (no events fire in a memory environment)\n * - `navigate()` — no-op that returns a NavigationResult\n * with immediately-resolved promises\n * - `back()` / `forward()` — no-ops that return a\n * NavigationResult with immediately-resolved promises\n * - `traverseTo()` — no-op that returns a NavigationResult\n * - `updateCurrentEntry()` — no-op\n * - `canGoBack` / `canGoForward` — always false\n * - `entries()` — returns a single-entry array\n *\n * The object is cast to `Navigation` for compatibility with\n * the Router's `navigation` prop and `NavigationContext`.\n * Properties not listed above are not implemented and will\n * throw if accessed by consumer code outside the Router.\n *\n * @param options - Configuration including the initial URL.\n * @returns A Navigation-compatible object for SSR or testing.\n *\n * @example\n * ```tsx\n * // Server-side rendering\n * const navigation = createMemoryNavigation({\n * url: request.url,\n * })\n *\n * const html = renderToString(\n * <Router navigation={navigation} matcher={matcher}>\n * <App />\n * </Router>\n * )\n * ```\n */\nexport function createMemoryNavigation(options: MemoryNavigationOptions): Navigation {\n const entry: MemoryNavigationEntry = {\n url: options.url,\n }\n\n const entryAsHistoryEntry = entry as unknown as NavigationHistoryEntry\n\n /**\n * Pre-built NavigationResult returned by all navigation\n * methods. Uses the same entry cast as a history entry\n * with immediately-resolved promises. Allocated once to\n * avoid per-call object creation.\n */\n const result: NavigationResult = {\n committed: Promise.resolve(entryAsHistoryEntry),\n finished: Promise.resolve(entryAsHistoryEntry),\n }\n\n /**\n * No-op event listener registration. In SSR and testing\n * environments, no navigation events are dispatched, so\n * the Router's effect subscriptions are harmless no-ops.\n */\n function addEventListener() {}\n\n /**\n * No-op event listener removal. Mirrors addEventListener\n * as a symmetric no-op.\n */\n function removeEventListener() {}\n\n /**\n * No-op navigate that returns a NavigationResult with\n * pre-resolved committed and finished promises. In SSR\n * the result is never awaited, but returning valid\n * promises avoids runtime errors if consumer code chains\n * on the result.\n */\n function navigate(): NavigationResult {\n return result\n }\n\n /**\n * No-op backward navigation. Returns pre-resolved promises\n * matching the NavigationResult interface. In a memory\n * environment there is no history stack to traverse.\n */\n function back(): NavigationResult {\n return result\n }\n\n /**\n * No-op forward navigation. Returns pre-resolved promises\n * matching the NavigationResult interface. In a memory\n * environment there is no history stack to traverse.\n */\n function forward(): NavigationResult {\n return result\n }\n\n /**\n * No-op history traversal to a specific entry key. Returns\n * pre-resolved promises. In a memory environment there is\n * only a single entry, so traversal is meaningless.\n */\n function traverseTo(): NavigationResult {\n return result\n }\n\n /**\n * No-op current entry state update. In a memory environment\n * entry state is not tracked, so this is silently ignored.\n */\n function updateCurrentEntry() {}\n\n /**\n * Returns the single-entry history list. The memory\n * adapter only ever has one entry — the initial URL.\n */\n function entries(): NavigationHistoryEntry[] {\n return [entryAsHistoryEntry]\n }\n\n return {\n currentEntry: entry,\n canGoBack: false,\n canGoForward: false,\n transition: null,\n addEventListener,\n removeEventListener,\n navigate,\n back,\n forward,\n traverseTo,\n updateCurrentEntry,\n entries,\n } as unknown as Navigation\n}\n","import { type ComponentType } from 'react'\nimport { createMatcher, type Matcher } from 'router:matcher'\nimport {\n type FormHandler,\n type Handler,\n type MiddlewareProps,\n type PrefetchContext,\n type PrefetchFunc,\n type RedirectTarget,\n} from 'router/react:router'\n\n/**\n * Accumulated configuration inherited from parent groups.\n * Passed down through nested `.group()` calls so that child\n * routes merge their own configuration with the parent's.\n */\ninterface InheritedConfig {\n /**\n * Path prefix accumulated from parent groups. Each group\n * that specifies a path appends it to this prefix. Child\n * route paths are concatenated after this prefix when\n * registering on the matcher.\n */\n readonly prefix: string\n\n /**\n * Middleware components inherited from parent groups.\n * Child routes prepend these before their own middlewares\n * so that outermost group middlewares wrap outermost.\n */\n readonly middlewares: ComponentType<MiddlewareProps>[]\n\n /**\n * Prefetch functions inherited from parent groups. When\n * a child route also defines a prefetch, the parent\n * functions run first (in order) followed by the child's.\n */\n readonly prefetches: PrefetchFunc[]\n}\n\n/**\n * Mutable state accumulated on a single route builder\n * instance via its chainable methods. Merged with the\n * inherited config when a terminal method is called.\n */\ninterface BuilderState {\n /**\n * The path segment for this route, or undefined when the\n * builder is used purely for group-level configuration.\n */\n path: string | undefined\n\n /**\n * Middleware components added via `.middleware()` on this\n * builder. Appended after inherited middlewares.\n */\n middlewares: ComponentType<MiddlewareProps>[]\n\n /**\n * Prefetch functions added via `.prefetch()` on this\n * builder. Appended after inherited prefetches.\n */\n prefetches: PrefetchFunc[]\n\n /**\n * Scroll restoration behavior for this route. Set via\n * `.scroll()`. Undefined means the browser default.\n */\n scroll: NavigationScrollBehavior | undefined\n\n /**\n * Focus reset behavior for this route. Set via\n * `.focusReset()`. Undefined means the browser default.\n */\n focusReset: NavigationFocusReset | undefined\n\n /**\n * Form submission handler for this route. Set via\n * `.formHandler()`.\n */\n formHandler: FormHandler | undefined\n}\n\n/**\n * Chainable route builder returned by the `route()` factory.\n * Accumulates handler configuration through method calls and\n * terminates with `.render()`, `.redirect()`, or `.group()`.\n *\n * Chainable methods (return the builder for further chaining):\n * - `.middleware()` — appends middleware components\n * - `.prefetch()` — adds a prefetch function to the chain\n * - `.scroll()` — sets scroll restoration behavior\n * - `.focusReset()` — sets focus reset behavior\n * - `.formHandler()` — sets the form submission handler\n *\n * Terminal methods:\n * - `.render()` — registers a route with a component\n * - `.redirect()` — registers a precommit redirect\n * - `.group()` — returns a scoped `RouteFactory` that\n * inherits this builder's config\n */\nexport interface RouteBuilder {\n /**\n * Appends middleware components to this route or group.\n * Middlewares are applied outermost-first: inherited group\n * middlewares wrap before this route's middlewares, and\n * within the array the first element wraps outermost.\n *\n * @param list - Middleware components to append.\n * @returns The builder for further chaining.\n */\n middleware(list: ComponentType<MiddlewareProps>[]): RouteBuilder\n\n /**\n * Adds a prefetch function to the chain for this route\n * or group. When multiple prefetch functions are chained\n * (from parent groups and the route itself), they execute\n * sequentially: parent prefetches run first, then this\n * route's, in the order they were added.\n *\n * @param fn - The prefetch function to add.\n * @returns The builder for further chaining.\n */\n prefetch(fn: PrefetchFunc): RouteBuilder\n\n /**\n * Sets the scroll restoration behavior for this route.\n * - `'after-transition'` — browser handles scroll after\n * the handler promise resolves (default).\n * - `'manual'` — disables automatic scrolling so the\n * route component can call `event.scroll()` manually.\n *\n * @param behavior - The scroll behavior to use.\n * @returns The builder for further chaining.\n */\n scroll(behavior: NavigationScrollBehavior): RouteBuilder\n\n /**\n * Sets the focus reset behavior for this route.\n * - `'after-transition'` — focuses the first autofocus\n * element after the handler resolves (default).\n * - `'manual'` — disables automatic focus reset.\n *\n * @param behavior - The focus reset behavior to use.\n * @returns The builder for further chaining.\n */\n focusReset(behavior: NavigationFocusReset): RouteBuilder\n\n /**\n * Sets the form submission handler for this route. When\n * a navigation includes FormData and matches this route,\n * the form handler is called instead of rendering the\n * component.\n *\n * @param fn - The form handler function.\n * @returns The builder for further chaining.\n */\n formHandler(fn: FormHandler): RouteBuilder\n\n /**\n * Terminal method that registers this route on the matcher\n * with the given component. Merges inherited and local\n * configuration into a `Handler` and registers it at the\n * full path (group prefix + route path).\n *\n * @param component - The React component to render.\n * @throws When no path was provided to the `route()` call\n * and no group prefix exists.\n */\n render(component: ComponentType): void\n\n /**\n * Terminal method that registers a precommit redirect.\n * When the Navigation API matches this route, the\n * precommit handler calls `controller.redirect(target)`\n * before the URL commits, avoiding any component render\n * or visual flash.\n *\n * The target can be a static absolute path string, or a\n * callback that receives the prefetch context and returns\n * the path. The callback form enables dynamic redirects\n * that carry route parameters to the new location.\n *\n * The resolved target path is absolute and is NOT prefixed\n * by parent groups.\n *\n * @param target - The redirect target: a static path or a\n * callback receiving `PrefetchContext` and returning one.\n * @throws When no path was provided to the `route()` call\n * and no group prefix exists.\n *\n * @example\n * ```ts\n * // Static redirect\n * route('/old').redirect('/new')\n *\n * // Dynamic redirect using route params\n * route('/old-user/:id').redirect(({ params }) => `/user/${params.id}`)\n * ```\n */\n redirect(target: RedirectTarget): void\n\n /**\n * Terminal method that creates a nested route scope.\n * Returns a `RouteFactory` whose routes inherit this\n * builder's middleware and prefetch configuration. When\n * a path was provided, it is prepended to all child\n * route paths as a prefix.\n *\n * @returns A scoped `RouteFactory` for defining child\n * routes that inherit this builder's config.\n *\n * @example\n * ```ts\n * const admin = route('/admin').middleware([Auth]).group()\n * admin('/dashboard').render(Dashboard)\n * admin('/settings').render(Settings)\n * ```\n */\n group(): RouteFactory\n}\n\n/**\n * Factory function that creates a route builder for a given\n * path. When path is omitted, the builder is used purely for\n * group-level configuration (middleware, prefetch) without\n * contributing a path segment.\n *\n * @param path - Optional path pattern for this route. May\n * contain dynamic (`:param`) and wildcard (`*param`)\n * segments.\n * @returns A chainable route builder.\n */\nexport type RouteFactory = (path?: string) => RouteBuilder\n\n/**\n * Joins a group prefix and a route path into a single\n * pattern string. Handles the edge cases of empty prefix,\n * empty path, double slashes, and root-only paths.\n *\n * @param prefix - The accumulated group prefix (e.g.\n * `'/dashboard'`).\n * @param path - The route path (e.g. `'/settings'`).\n * @returns The joined path pattern.\n */\nfunction joinPaths(prefix: string, path: string): string {\n if (prefix === '' && path === '') {\n return ''\n }\n\n if (prefix === '') {\n return path\n }\n\n if (path === '' || path === '/') {\n return prefix\n }\n\n const normalizedPrefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix\n\n const normalizedPath = path.startsWith('/') ? path : '/' + path\n\n return normalizedPrefix + normalizedPath\n}\n\n/**\n * Combines an array of prefetch functions into a single\n * `PrefetchFunc` that calls each one sequentially. Returns\n * `undefined` when the array is empty.\n *\n * @param prefetches - The prefetch functions to chain.\n * @returns A single combined prefetch function, or undefined.\n */\nfunction chainPrefetches(prefetches: PrefetchFunc[]): PrefetchFunc | undefined {\n if (prefetches.length === 0) {\n return undefined\n }\n\n if (prefetches.length === 1) {\n return prefetches[0]\n }\n\n return async function (context: PrefetchContext) {\n for (const fn of prefetches) {\n await fn(context)\n }\n }\n}\n\n/**\n * A no-op React component used as the `component` field for\n * redirect routes. Never actually renders because the\n * precommit redirect fires before the URL commits, but the\n * `Handler` interface requires a component.\n */\nfunction RedirectFallback() {\n return null\n}\n\n/**\n * Creates a route builder bound to a specific matcher and\n * inherited configuration. Each call to the returned factory\n * produces a fresh builder that inherits the given config.\n *\n * @param matcher - The matcher to register routes on.\n * @param inherited - Configuration from parent groups.\n * @param redirects - Shared map collecting static redirect\n * targets for post-registration cycle detection. Keys are\n * source paths, values are target paths. Only populated\n * for string (non-callback) redirect targets.\n * @returns A `RouteFactory` function.\n */\nfunction createRouteFactory(\n matcher: Matcher<Handler>,\n inherited: InheritedConfig,\n redirects: Map<string, string>\n): RouteFactory {\n return function route(path?: string): RouteBuilder {\n const state: BuilderState = {\n path,\n middlewares: [],\n prefetches: [],\n scroll: undefined,\n focusReset: undefined,\n formHandler: undefined,\n }\n\n /**\n * Whether a terminal method (`.render()`, `.redirect()`,\n * or `.group()`) has been called on this builder. Once\n * consumed, further method calls throw to prevent\n * accidental reuse.\n */\n let isConsumed = false\n\n /**\n * Guards against calling builder methods after a terminal\n * method has been invoked. Throws a descriptive error\n * indicating which method was called on a consumed builder.\n *\n * @param method - The method name being called.\n * @throws When the builder has already been consumed.\n */\n function assertNotConsumed(method: string) {\n if (isConsumed) {\n throw new Error(\n `cannot call .${method}() on a route builder that has ` +\n `already been consumed by .render(), .redirect(), or .group()`\n )\n }\n }\n\n /**\n * Computes the full registration path by joining the\n * inherited prefix with this builder's path. Throws\n * when neither a prefix nor a path exists, since a\n * route must have a resolvable path to register.\n *\n * @returns The full path pattern.\n * @throws When both the group prefix and route path\n * are empty or undefined.\n */\n function resolveFullPath(): string {\n const fullPath = joinPaths(inherited.prefix, state.path ?? '')\n\n if (fullPath === '') {\n throw new Error('cannot register a route without a path or group prefix')\n }\n\n return fullPath\n }\n\n /**\n * Merges inherited and local middlewares into a single\n * array. Returns `undefined` when no middlewares exist\n * (to match the optional `Handler.middlewares` field).\n *\n * @returns The merged middleware array, or undefined.\n */\n function resolveMiddlewares(): ComponentType<MiddlewareProps>[] | undefined {\n const merged = [...inherited.middlewares, ...state.middlewares]\n\n return merged.length > 0 ? merged : undefined\n }\n\n /**\n * Merges inherited and local prefetches into a single\n * chained function. Returns `undefined` when no\n * prefetches exist.\n *\n * @returns The chained prefetch function, or undefined.\n */\n function resolvePrefetches(): PrefetchFunc | undefined {\n return chainPrefetches([...inherited.prefetches, ...state.prefetches])\n }\n\n const builder: RouteBuilder = {\n middleware(list) {\n assertNotConsumed('middleware')\n state.middlewares.push(...list)\n\n return builder\n },\n\n prefetch(fn) {\n assertNotConsumed('prefetch')\n state.prefetches.push(fn)\n\n return builder\n },\n\n scroll(behavior) {\n assertNotConsumed('scroll')\n state.scroll = behavior\n\n return builder\n },\n\n focusReset(behavior) {\n assertNotConsumed('focusReset')\n state.focusReset = behavior\n\n return builder\n },\n\n formHandler(fn) {\n assertNotConsumed('formHandler')\n state.formHandler = fn\n\n return builder\n },\n\n render(component) {\n assertNotConsumed('render')\n isConsumed = true\n\n const fullPath = resolveFullPath()\n\n const handler: Handler = {\n component,\n middlewares: resolveMiddlewares(),\n prefetch: resolvePrefetches(),\n scroll: state.scroll,\n focusReset: state.focusReset,\n formHandler: state.formHandler,\n }\n\n matcher.register(fullPath, handler)\n },\n\n redirect(target) {\n assertNotConsumed('redirect')\n isConsumed = true\n\n const fullPath = resolveFullPath()\n\n if (typeof target === 'string') {\n redirects.set(fullPath, target)\n }\n\n const handler: Handler = {\n component: RedirectFallback,\n prefetch: function (context) {\n const resolved = typeof target === 'function' ? target(context) : target\n\n context.controller.redirect(resolved)\n },\n }\n\n matcher.register(fullPath, handler)\n },\n\n group() {\n assertNotConsumed('group')\n isConsumed = true\n\n const childPrefix = joinPaths(inherited.prefix, state.path ?? '')\n\n const childInherited: InheritedConfig = {\n prefix: childPrefix,\n middlewares: [...inherited.middlewares, ...state.middlewares],\n prefetches: [...inherited.prefetches, ...state.prefetches],\n }\n\n return createRouteFactory(matcher, childInherited, redirects)\n },\n }\n\n return builder\n }\n}\n\n/**\n * Detects cycles in static redirect routes. Walks each\n * redirect chain and throws if a cycle is found. Only\n * checks string (non-callback) redirect targets since\n * callback targets are resolved at runtime.\n *\n * @param redirects - Map of source path to target path\n * for all static redirects.\n * @throws When a redirect cycle is detected, with the\n * full cycle path in the error message.\n */\nfunction detectRedirectCycles(redirects: Map<string, string>) {\n for (const [source] of redirects) {\n const visited = new Set<string>()\n let current = source\n\n while (redirects.has(current)) {\n if (visited.has(current)) {\n const cycle = [...visited, current].join(' -> ')\n\n throw new Error(`redirect cycle detected: ${cycle}`)\n }\n\n visited.add(current)\n current = redirects.get(current)!\n }\n }\n}\n\n/**\n * Creates a route matcher using a declarative builder API.\n * Routes are defined inside a callback that receives a\n * `route` factory function for chainable route configuration.\n *\n * The builder supports middleware inheritance, prefetch\n * chaining, nested groups with path prefixing, redirects,\n * and all handler options (scroll, focusReset, formHandler).\n *\n * After all routes are registered, static redirect targets\n * are checked for cycles. Self-redirects and multi-hop loops\n * throw an error at registration time.\n *\n * Returns a `Matcher<Handler>` that plugs directly into the\n * `<Router matcher={...}>` component.\n *\n * @param callback - A function that defines routes using the\n * provided `route` factory.\n * @returns A populated matcher ready for the Router.\n * @throws When a static redirect cycle is detected.\n *\n * @example\n * ```tsx\n * const router = createRouter(function (route) {\n * route('/').render(Home)\n * route('/old').redirect('/new')\n *\n * route('/other')\n * .prefetch(prefetchOther)\n * .scroll('after-transition')\n * .render(Other)\n *\n * const authed = route().middleware([Auth]).group()\n * authed('/dashboard').render(Dashboard)\n * authed('/user/:id').render(User)\n *\n * const admin = authed('/admin')\n * .middleware([AdminOnly])\n * .group()\n * admin('/settings').render(Settings)\n * })\n *\n * <Router matcher={router} />\n * ```\n */\nexport function createRouter(callback: (route: RouteFactory) => void): Matcher<Handler> {\n const matcher = createMatcher<Handler>()\n const redirects = new Map<string, string>()\n\n const rootInherited: InheritedConfig = {\n prefix: '',\n middlewares: [],\n prefetches: [],\n }\n\n const route = createRouteFactory(matcher, rootInherited, redirects)\n\n callback(route)\n\n detectRedirectCycles(redirects)\n\n return matcher\n}\n"],"x_google_ignoreList":[1,2,3],"mappings":"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"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Default fallback component rendered when no registered
|
|
3
|
-
* route matches the current URL.
|
|
4
|
-
*
|
|
3
|
+
* route matches the current URL. Uses an `<h1>` heading
|
|
4
|
+
* for semantic document structure and accessibility.
|
|
5
|
+
*
|
|
6
|
+
* Can be overridden via the `notFound` prop on the Router
|
|
7
|
+
* component for custom 404 pages.
|
|
5
8
|
*/
|
|
6
9
|
export declare function NotFound(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -78,4 +78,4 @@ export interface RouterProps {
|
|
|
78
78
|
* - `PathnameContext` — the current URL pathname
|
|
79
79
|
* - `ParamsContext` — the extracted route parameters
|
|
80
80
|
*/
|
|
81
|
-
export declare function Router(
|
|
81
|
+
export declare function Router(props: RouterProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,5 +3,10 @@
|
|
|
3
3
|
* Consumers can use this to cancel in-flight async operations
|
|
4
4
|
* (fetches, transitions, etc.) when a navigation is superseded
|
|
5
5
|
* by another one.
|
|
6
|
+
*
|
|
7
|
+
* Defaults to `undefined` when no Router is present — the
|
|
8
|
+
* `useNavigationSignal` hook throws in this case. The Router
|
|
9
|
+
* provides `null` on initial render (before any navigation
|
|
10
|
+
* event), which is distinct from the `undefined` sentinel.
|
|
6
11
|
*/
|
|
7
|
-
export declare const NavigationSignalContext: import('react').Context<AbortSignal | null>;
|
|
12
|
+
export declare const NavigationSignalContext: import('react').Context<AbortSignal | null | undefined>;
|
|
@@ -2,5 +2,10 @@
|
|
|
2
2
|
* Provides the navigation type of the most recent NavigateEvent
|
|
3
3
|
* (`push`, `replace`, `reload`, or `traverse`). Allows route
|
|
4
4
|
* components to vary behavior based on how they were reached.
|
|
5
|
+
*
|
|
6
|
+
* Defaults to `undefined` when no Router is present — the
|
|
7
|
+
* `useNavigationType` hook throws in this case. The Router
|
|
8
|
+
* provides `null` on initial render (before any navigation
|
|
9
|
+
* event), which is distinct from the `undefined` sentinel.
|
|
5
10
|
*/
|
|
6
|
-
export declare const NavigationTypeContext: import('react').Context<NavigationType | null>;
|
|
11
|
+
export declare const NavigationTypeContext: import('react').Context<NavigationType | null | undefined>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides the route parameters extracted from the matched URL
|
|
3
|
+
* pattern as a string-keyed record. Defaults to `null` when no
|
|
4
|
+
* Router is present in the tree — the `useParams` hook throws
|
|
5
|
+
* a descriptive error in this case.
|
|
6
|
+
*
|
|
7
|
+
* The Router component updates this context on every successful
|
|
8
|
+
* navigation with the newly extracted parameters.
|
|
9
|
+
*/
|
|
10
|
+
export declare const ParamsContext: import('react').Context<Record<string, string> | null>;
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* Updated by the Router on every navigation with the pathname
|
|
4
4
|
* extracted from the destination URL.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Defaults to `null` when no Router is present in the tree —
|
|
7
|
+
* the `usePathname` hook throws a descriptive error in this
|
|
8
|
+
* case. Consumed by the `usePathname` hook and the `Link`
|
|
9
|
+
* component for active link detection.
|
|
9
10
|
*/
|
|
10
|
-
export declare const PathnameContext: import('react').Context<string>;
|
|
11
|
+
export declare const PathnameContext: import('react').Context<string | null>;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { TransitionFunction } from 'react';
|
|
2
1
|
/**
|
|
3
2
|
* Provides the `[isPending, startTransition]` tuple from
|
|
4
3
|
* `useTransition()` to descendant components. The Router and
|
|
@@ -12,8 +11,3 @@ import { TransitionFunction } from 'react';
|
|
|
12
11
|
* explicit provider instead.
|
|
13
12
|
*/
|
|
14
13
|
export declare const TransitionContext: import('react').Context<[boolean, import('react').TransitionStartFunction] | null>;
|
|
15
|
-
/**
|
|
16
|
-
* Type alias for the startTransition function extracted from
|
|
17
|
-
* the useTransition tuple.
|
|
18
|
-
*/
|
|
19
|
-
export type StartTransitionFn = (callback: TransitionFunction) => void;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Extracts the pathname portion from a URL string. Uses a
|
|
3
3
|
* dummy base URL to handle both absolute and relative paths
|
|
4
|
-
* correctly. Returns `'/'` when the input is null
|
|
5
|
-
* or an empty string.
|
|
4
|
+
* correctly. Returns `'/'` when the input is null or undefined.
|
|
6
5
|
*
|
|
7
6
|
* Used by the Router (to extract pathname from navigation
|
|
8
7
|
* destination URLs), Link (for active link comparison), and
|