@real-router/react 0.13.1 → 0.14.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/README.md CHANGED
@@ -170,6 +170,27 @@ const LazyDashboard = lazy(() => import("./Dashboard"));
170
170
 
171
171
  `fallback` and `keepAlive` work together — `<Activity>` wraps the whole match including the `<Suspense>` boundary.
172
172
 
173
+ ### `<RouterErrorBoundary>`
174
+
175
+ Declarative error handling for navigation errors. Shows a fallback **alongside** children (not instead of) when a guard rejects or a route is not found.
176
+
177
+ ```tsx
178
+ <RouterErrorBoundary
179
+ fallback={(error, resetError) => (
180
+ <div className="toast">
181
+ {error.code} <button onClick={resetError}>Dismiss</button>
182
+ </div>
183
+ )}
184
+ onError={(error) => analytics.track("nav_error", { code: error.code })}
185
+ >
186
+ <Link routeName="protected">Go to Protected</Link>
187
+ </RouterErrorBoundary>
188
+ ```
189
+
190
+ Auto-resets on next successful navigation. Works with both `<Link>` and imperative `router.navigate()`.
191
+
192
+ Available from both `@real-router/react` and `@real-router/react/legacy`.
193
+
173
194
  ## React 18 Migration
174
195
 
175
196
  One import path change — all hooks and `Link` work identically:
@@ -189,6 +210,7 @@ One import path change — all hooks and `Link` work identically:
189
210
  | `useRouter`, `useRoute`, `useRouteNode` | Yes | Yes |
190
211
  | `RouteView` with `keepAlive` | No | Yes (React 19.2+) |
191
212
  | `useNavigator`, `useRouteUtils`, `useRouterTransition` | No | Yes |
213
+ | `RouterErrorBoundary` (declarative error handling) | No | Yes |
192
214
  | `withRouter`, `withRoute`, `routeNode` (HOCs) | Yes | No — use hooks |
193
215
  | `Router`, `Route`, `RouteNode` (render props) | Yes | No — use hooks |
194
216
 
@@ -208,7 +230,7 @@ When enabled, a visually hidden `aria-live` region announces each navigation. Fo
208
230
 
209
231
  Full documentation: [Wiki](https://github.com/greydragon888/real-router/wiki)
210
232
 
211
- - [RouterProvider](https://github.com/greydragon888/real-router/wiki/RouterProvider) · [RouteView](https://github.com/greydragon888/real-router/wiki/RouteView) · [Link](https://github.com/greydragon888/real-router/wiki/Link)
233
+ - [RouterProvider](https://github.com/greydragon888/real-router/wiki/RouterProvider) · [RouteView](https://github.com/greydragon888/real-router/wiki/RouteView) · [RouterErrorBoundary](https://github.com/greydragon888/real-router/wiki/RouterErrorBoundary) · [Link](https://github.com/greydragon888/real-router/wiki/Link)
212
234
  - [useRouter](https://github.com/greydragon888/real-router/wiki/useRouter) · [useRoute](https://github.com/greydragon888/real-router/wiki/useRoute) · [useRouteNode](https://github.com/greydragon888/real-router/wiki/useRouteNode) · [useNavigator](https://github.com/greydragon888/real-router/wiki/useNavigator) · [useRouteUtils](https://github.com/greydragon888/real-router/wiki/useRouteUtils) · [useRouterTransition](https://github.com/greydragon888/real-router/wiki/useRouterTransition)
213
235
 
214
236
  ## Examples
@@ -1,5 +1,5 @@
1
1
  import { ReactNode, ReactElement } from 'react';
2
- export { Link, LinkProps, RouterProvider, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition } from './legacy.js';
2
+ export { Link, LinkProps, RouterErrorBoundary, RouterErrorBoundaryProps, RouterProvider, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition } from './legacy.js';
3
3
  export { Navigator } from '@real-router/core';
4
4
  export { RouterTransitionSnapshot } from '@real-router/sources';
5
5
  import '@real-router/route-utils';
package/dist/cjs/index.js CHANGED
@@ -1 +1 @@
1
- var e=require("react"),t=require("@real-router/core"),r=require("@real-router/route-utils"),o=require("react/jsx-runtime"),n=require("@real-router/sources"),u=require("dom-utils"),s=require("@real-router/core/api");function i(e){return null}function a(e){return null}function c(e,t,o){return o?e===t:r.startsWithSegment(e,t)}function l(t,r){for(const o of e.Children.toArray(t))e.isValidElement(o)&&(o.type===i||o.type===a?r.push(o):l(o.props.children,r))}function d(t,r,n,u,s){const i=void 0===s?t:o.jsx(e.Suspense,{fallback:s,children:t});return n?o.jsx(e.Activity,{mode:u,children:i},r):o.jsx(e.Fragment,{children:i},r)}i.displayName="RouteView.Match",a.displayName="RouteView.NotFound";var p=e.createContext(null),m=e.createContext(null),h=e.createContext(null),v=()=>{const t=e.useContext(m);if(!t)throw new Error("useRouter must be used within a RouterProvider");return t};function g(r){const o=v(),u=e.useMemo(()=>n.createRouteNodeSource(o,r),[o,r]),{route:s,previousRoute:i}=e.useSyncExternalStore(u.subscribe,u.getSnapshot,u.getSnapshot),a=e.useMemo(()=>t.getNavigator(o),[o]);return e.useMemo(()=>({navigator:a,route:s,previousRoute:i}),[a,s,i])}function f({nodeName:r,children:n}){const{route:u}=g(r),s=e.useRef(new Set);if(!u)return null;const i=[];l(n,i);const{rendered:p}=function(r,n,u,s){let i=null,l=!1;const p=[];for(const e of r){if(e.type===a){i=e.props.children;continue}const{segment:t,exact:r=!1,keepAlive:o=!1,fallback:m}=e.props,h=u?`${u}.${t}`:t;!l&&c(n,h,r)?(l=!0,s.add(h),p.push(d(e.props.children,h,o,"visible",m))):o&&s.has(h)&&p.push(d(e.props.children,h,o,"hidden",m))}return l||n!==t.UNKNOWN_ROUTE||null===i||p.push(o.jsx(e.Fragment,{children:i},"__route-view-not-found__")),{rendered:p,activeMatchFound:l}}(i,u.name,r,s.current);return p.length>0?o.jsx(o.Fragment,{children:p}):null}f.displayName="RouteView";var N=Object.assign(f,{Match:i,NotFound:a}),S=Object.freeze({}),x=Object.freeze({});function R(t){const r=JSON.stringify(t);return e.useMemo(()=>t,[r])}var y=e.memo(({routeName:t,routeParams:r=S,routeOptions:s=x,className:i,activeClassName:a="active",activeStrict:c=!1,ignoreQueryParams:l=!0,onClick:d,target:p,children:m,...h})=>{const g=v(),f=R(r),N=R(s),y=function(t,r,o=!1,u=!0){const s=v(),i=R(r),a=e.useMemo(()=>n.createActiveRouteSource(s,t,i,{strict:o,ignoreQueryParams:u}),[s,t,i,o,u]);return e.useSyncExternalStore(a.subscribe,a.getSnapshot,a.getSnapshot)}(t,f,c,l),b=e.useMemo(()=>u.buildHref(g,t,f),[g,t,f]),C=e.useCallback(e=>{d&&(d(e),e.defaultPrevented)||u.shouldNavigate(e.nativeEvent)&&"_blank"!==p&&(e.preventDefault(),g.navigate(t,f,N).catch(()=>{}))},[d,p,g,t,f,N]),w=e.useMemo(()=>u.buildActiveClassName(y,a,i),[y,a,i]);return o.jsx("a",{...h,href:b,className:w,onClick:C,children:m})},function(e,t){return e.routeName===t.routeName&&e.className===t.className&&e.activeClassName===t.activeClassName&&e.activeStrict===t.activeStrict&&e.ignoreQueryParams===t.ignoreQueryParams&&e.onClick===t.onClick&&e.target===t.target&&e.style===t.style&&e.children===t.children&&JSON.stringify(e.routeParams)===JSON.stringify(t.routeParams)&&JSON.stringify(e.routeOptions)===JSON.stringify(t.routeOptions)});y.displayName="Link",exports.Link=y,exports.RouteView=N,exports.RouterProvider=({router:r,children:s,announceNavigation:i})=>{e.useEffect(()=>{if(!i)return;const e=u.createRouteAnnouncer(r);return()=>{e.destroy()}},[i,r]);const a=e.useMemo(()=>t.getNavigator(r),[r]),c=e.useMemo(()=>n.createRouteSource(r),[r]),{route:l,previousRoute:d}=e.useSyncExternalStore(c.subscribe,c.getSnapshot,c.getSnapshot),v=e.useMemo(()=>({navigator:a,route:l,previousRoute:d}),[a,l,d]);return o.jsx(m,{value:r,children:o.jsx(h,{value:a,children:o.jsx(p,{value:v,children:s})})})},exports.useNavigator=()=>{const t=e.useContext(h);if(!t)throw new Error("useNavigator must be used within a RouterProvider");return t},exports.useRoute=()=>{const t=e.useContext(p);if(!t)throw new Error("useRoute must be used within a RouteProvider");return t},exports.useRouteNode=g,exports.useRouteUtils=()=>{const e=v();return r.getRouteUtils(s.getPluginApi(e).getTree())},exports.useRouter=v,exports.useRouterTransition=function(){const t=v(),r=e.useMemo(()=>n.createTransitionSource(t),[t]);return e.useSyncExternalStore(r.subscribe,r.getSnapshot,r.getSnapshot)};//# sourceMappingURL=index.js.map
1
+ var e=require("react"),r=require("@real-router/core"),t=require("@real-router/route-utils"),o=require("react/jsx-runtime"),n=require("@real-router/sources"),u=require("dom-utils"),s=require("@real-router/core/api");function i(e){return null}function a(e){return null}function c(e,r,o){return o?e===r:t.startsWithSegment(e,r)}function l(r,t){for(const o of e.Children.toArray(r))e.isValidElement(o)&&(o.type===i||o.type===a?t.push(o):l(o.props.children,t))}function d(r,t,n,u,s){const i=void 0===s?r:o.jsx(e.Suspense,{fallback:s,children:r});return n?o.jsx(e.Activity,{mode:u,children:i},t):o.jsx(e.Fragment,{children:i},t)}i.displayName="RouteView.Match",a.displayName="RouteView.NotFound";var p=e.createContext(null),m=e.createContext(null),h=e.createContext(null),v=()=>{const r=e.useContext(m);if(!r)throw new Error("useRouter must be used within a RouterProvider");return r};function f(t){const o=v(),u=e.useMemo(()=>n.createRouteNodeSource(o,t),[o,t]),{route:s,previousRoute:i}=e.useSyncExternalStore(u.subscribe,u.getSnapshot,u.getSnapshot),a=e.useMemo(()=>r.getNavigator(o),[o]);return e.useMemo(()=>({navigator:a,route:s,previousRoute:i}),[a,s,i])}function g({nodeName:t,children:n}){const{route:u}=f(t),s=e.useRef(new Set);if(!u)return null;const i=[];l(n,i);const{rendered:p}=function(t,n,u,s){let i=null,l=!1;const p=[];for(const e of t){if(e.type===a){i=e.props.children;continue}const{segment:r,exact:t=!1,keepAlive:o=!1,fallback:m}=e.props,h=u?`${u}.${r}`:r;!l&&c(n,h,t)?(l=!0,s.add(h),p.push(d(e.props.children,h,o,"visible",m))):o&&s.has(h)&&p.push(d(e.props.children,h,o,"hidden",m))}return l||n!==r.UNKNOWN_ROUTE||null===i||p.push(o.jsx(e.Fragment,{children:i},"__route-view-not-found__")),{rendered:p,activeMatchFound:l}}(i,u.name,t,s.current);return p.length>0?o.jsx(o.Fragment,{children:p}):null}g.displayName="RouteView";var S=Object.assign(g,{Match:i,NotFound:a}),N=Object.freeze({}),x=Object.freeze({});function R(r){const t=JSON.stringify(r);return e.useMemo(()=>r,[t])}var y=e.memo(({routeName:r,routeParams:t=N,routeOptions:s=x,className:i,activeClassName:a="active",activeStrict:c=!1,ignoreQueryParams:l=!0,onClick:d,target:p,children:m,...h})=>{const f=v(),g=R(t),S=R(s),y=function(r,t,o=!1,u=!0){const s=v(),i=R(t),a=e.useMemo(()=>n.createActiveRouteSource(s,r,i,{strict:o,ignoreQueryParams:u}),[s,r,i,o,u]);return e.useSyncExternalStore(a.subscribe,a.getSnapshot,a.getSnapshot)}(r,g,c,l),b=e.useMemo(()=>u.buildHref(f,r,g),[f,r,g]),C=e.useCallback(e=>{d&&(d(e),e.defaultPrevented)||u.shouldNavigate(e.nativeEvent)&&"_blank"!==p&&(e.preventDefault(),f.navigate(r,g,S).catch(()=>{}))},[d,p,f,r,g,S]),w=e.useMemo(()=>u.buildActiveClassName(y,a,i),[y,a,i]);return o.jsx("a",{...h,href:b,className:w,onClick:C,children:m})},function(e,r){return e.routeName===r.routeName&&e.className===r.className&&e.activeClassName===r.activeClassName&&e.activeStrict===r.activeStrict&&e.ignoreQueryParams===r.ignoreQueryParams&&e.onClick===r.onClick&&e.target===r.target&&e.style===r.style&&e.children===r.children&&JSON.stringify(e.routeParams)===JSON.stringify(r.routeParams)&&JSON.stringify(e.routeOptions)===JSON.stringify(r.routeOptions)});y.displayName="Link";var b=new WeakMap;exports.Link=y,exports.RouteView=S,exports.RouterErrorBoundary=function({children:r,fallback:t,onError:u}){const s=function(){const r=v(),t=e.useMemo(()=>{let e=b.get(r);return e||(e=n.createErrorSource(r),b.set(r,e)),e},[r]);return e.useSyncExternalStore(t.subscribe,t.getSnapshot,t.getSnapshot)}(),[i,a]=e.useState(-1),c=e.useRef(u);c.current=u,e.useEffect(()=>{s.error&&c.current?.(s.error,s.toRoute,s.fromRoute)},[s.version]);const l=s.version>i?s.error:null,d=e.useCallback(()=>{a(s.version)},[s.version]);return o.jsxs(o.Fragment,{children:[r,l?t(l,d):null]})},exports.RouterProvider=({router:t,children:s,announceNavigation:i})=>{e.useEffect(()=>{if(!i)return;const e=u.createRouteAnnouncer(t);return()=>{e.destroy()}},[i,t]);const a=e.useMemo(()=>r.getNavigator(t),[t]),c=e.useMemo(()=>n.createRouteSource(t),[t]),{route:l,previousRoute:d}=e.useSyncExternalStore(c.subscribe,c.getSnapshot,c.getSnapshot),v=e.useMemo(()=>({navigator:a,route:l,previousRoute:d}),[a,l,d]);return o.jsx(m,{value:t,children:o.jsx(h,{value:a,children:o.jsx(p,{value:v,children:s})})})},exports.useNavigator=()=>{const r=e.useContext(h);if(!r)throw new Error("useNavigator must be used within a RouterProvider");return r},exports.useRoute=()=>{const r=e.useContext(p);if(!r)throw new Error("useRoute must be used within a RouteProvider");return r},exports.useRouteNode=f,exports.useRouteUtils=()=>{const e=v();return t.getRouteUtils(s.getPluginApi(e).getTree())},exports.useRouter=v,exports.useRouterTransition=function(){const r=v(),t=e.useMemo(()=>n.createTransitionSource(r),[r]);return e.useSyncExternalStore(t.subscribe,t.getSnapshot,t.getSnapshot)};//# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/modern/RouteView/components.tsx","../../src/components/modern/RouteView/helpers.tsx","../../src/context.ts","../../src/hooks/useRouter.tsx","../../src/hooks/useRouteNode.tsx","../../src/components/modern/RouteView/RouteView.tsx","../../src/constants.ts","../../src/hooks/useStableValue.tsx","../../src/hooks/useIsActiveRoute.tsx","../../src/components/Link.tsx","../../src/hooks/useNavigator.tsx","../../src/hooks/useRouteUtils.tsx","../../src/hooks/useRoute.tsx","../../src/hooks/useRouterTransition.tsx","../../src/RouterProvider.tsx"],"names":["startsWithSegment","Children","isValidElement","jsx","Suspense","Activity","Fragment","UNKNOWN_ROUTE","createContext","useContext","useMemo","createRouteNodeSource","useSyncExternalStore","getNavigator","useRef","createActiveRouteSource","memo","buildHref","useCallback","shouldNavigate","buildActiveClassName","getRouteUtils","getPluginApi","createTransitionSource","useEffect","createRouteAnnouncer","createRouteSource"],"mappings":"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","file":"index.js","sourcesContent":["import type { MatchProps, NotFoundProps } from \"./types\";\n\nexport function Match(_props: MatchProps): null {\n return null;\n}\n\nMatch.displayName = \"RouteView.Match\";\n\nexport function NotFound(_props: NotFoundProps): null {\n return null;\n}\n\nNotFound.displayName = \"RouteView.NotFound\";\n","import { UNKNOWN_ROUTE } from \"@real-router/core\";\nimport { startsWithSegment } from \"@real-router/route-utils\";\nimport { Activity, Children, Fragment, Suspense, isValidElement } from \"react\";\n\nimport { Match, NotFound } from \"./components\";\n\nimport type { MatchProps, NotFoundProps } from \"./types\";\nimport type { ReactElement, ReactNode } from \"react\";\n\nfunction isSegmentMatch(\n routeName: string,\n fullSegmentName: string,\n exact: boolean,\n): boolean {\n if (exact) {\n return routeName === fullSegmentName;\n }\n\n return startsWithSegment(routeName, fullSegmentName);\n}\n\nexport function collectElements(\n children: ReactNode,\n result: ReactElement[],\n): void {\n // eslint-disable-next-line @eslint-react/no-children-to-array\n for (const child of Children.toArray(children)) {\n if (!isValidElement(child)) {\n continue;\n }\n\n if (child.type === Match || child.type === NotFound) {\n result.push(child);\n } else {\n collectElements(\n (child.props as { readonly children: ReactNode }).children,\n result,\n );\n }\n }\n}\n\nfunction renderMatchElement(\n matchChildren: ReactNode,\n fullSegmentName: string,\n keepAlive: boolean,\n mode: \"visible\" | \"hidden\",\n fallback?: ReactNode,\n): ReactElement {\n const content =\n fallback === undefined ? (\n matchChildren\n ) : (\n <Suspense fallback={fallback}>{matchChildren}</Suspense>\n );\n\n if (keepAlive) {\n return (\n <Activity mode={mode} key={fullSegmentName}>\n {content}\n </Activity>\n );\n }\n\n return <Fragment key={fullSegmentName}>{content}</Fragment>;\n}\n\nexport function buildRenderList(\n elements: ReactElement[],\n routeName: string,\n nodeName: string,\n hasBeenActivated: Set<string>,\n): { rendered: ReactElement[]; activeMatchFound: boolean } {\n let notFoundChildren: ReactNode = null;\n let activeMatchFound = false;\n const rendered: ReactElement[] = [];\n\n for (const child of elements) {\n if (child.type === NotFound) {\n notFoundChildren = (child.props as NotFoundProps).children;\n continue;\n }\n\n const {\n segment,\n exact = false,\n keepAlive = false,\n fallback,\n } = child.props as MatchProps;\n const fullSegmentName = nodeName ? `${nodeName}.${segment}` : segment;\n const isActive =\n !activeMatchFound && isSegmentMatch(routeName, fullSegmentName, exact);\n\n if (isActive) {\n activeMatchFound = true;\n hasBeenActivated.add(fullSegmentName);\n rendered.push(\n renderMatchElement(\n (child.props as MatchProps).children,\n fullSegmentName,\n keepAlive,\n \"visible\",\n fallback,\n ),\n );\n } else if (keepAlive && hasBeenActivated.has(fullSegmentName)) {\n rendered.push(\n renderMatchElement(\n (child.props as MatchProps).children,\n fullSegmentName,\n keepAlive,\n \"hidden\",\n fallback,\n ),\n );\n }\n }\n\n if (\n !activeMatchFound &&\n routeName === UNKNOWN_ROUTE &&\n notFoundChildren !== null\n ) {\n rendered.push(\n <Fragment key=\"__route-view-not-found__\">{notFoundChildren}</Fragment>,\n );\n }\n\n return { rendered, activeMatchFound };\n}\n","// packages/react/modules/context.ts\n\nimport { createContext } from \"react\";\n\nimport type { RouteContext as RouteContextType } from \"./types\";\nimport type { Router, Navigator } from \"@real-router/core\";\n\nexport const RouteContext = createContext<RouteContextType | null>(null);\n\nexport const RouterContext = createContext<Router | null>(null);\n\nexport const NavigatorContext = createContext<Navigator | null>(null);\n","// packages/react/modules/hooks/useRouter.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouterContext } from \"../context\";\n\nimport type { Router } from \"@real-router/core\";\n\nexport const useRouter = (): Router => {\n const router = useContext(RouterContext);\n\n if (!router) {\n throw new Error(\"useRouter must be used within a RouterProvider\");\n }\n\n return router;\n};\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteContext } from \"../types\";\n\nexport function useRouteNode(nodeName: string): RouteContext {\n const router = useRouter();\n\n const store = useMemo(\n () => createRouteNodeSource(router, nodeName),\n [router, nodeName],\n );\n\n const { route, previousRoute } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n return useMemo(\n (): RouteContext => ({ navigator, route, previousRoute }),\n [navigator, route, previousRoute],\n );\n}\n","import { useRef } from \"react\";\n\nimport { Match, NotFound } from \"./components\";\nimport { buildRenderList, collectElements } from \"./helpers\";\nimport { useRouteNode } from \"../../../hooks/useRouteNode\";\n\nimport type { RouteViewProps } from \"./types\";\nimport type { ReactElement } from \"react\";\n\nfunction RouteViewRoot({\n nodeName,\n children,\n}: Readonly<RouteViewProps>): ReactElement | null {\n const { route } = useRouteNode(nodeName);\n const hasBeenActivatedRef = useRef<Set<string>>(new Set());\n\n if (!route) {\n return null;\n }\n\n const elements: ReactElement[] = [];\n\n collectElements(children, elements);\n\n const { rendered } = buildRenderList(\n elements,\n route.name,\n nodeName,\n hasBeenActivatedRef.current,\n );\n\n if (rendered.length > 0) {\n return <>{rendered}</>;\n }\n\n return null;\n}\n\nRouteViewRoot.displayName = \"RouteView\";\n\nexport const RouteView = Object.assign(RouteViewRoot, { Match, NotFound });\n\nexport type {\n RouteViewProps,\n MatchProps as RouteViewMatchProps,\n NotFoundProps as RouteViewNotFoundProps,\n} from \"./types\";\n","// packages/react/modules/constants.ts\n\n/**\n * Stable empty object for default params\n */\nexport const EMPTY_PARAMS = Object.freeze({});\n\n/**\n * Stable empty options object\n */\nexport const EMPTY_OPTIONS = Object.freeze({});\n","// packages/react/modules/hooks/useStableValue.tsx\n\nimport { useMemo } from \"react\";\n\n/**\n * Stabilizes a value reference based on deep equality (via JSON serialization).\n * Returns the same reference until the serialized value changes.\n *\n * Useful for object/array dependencies in hooks like useMemo, useCallback, useEffect\n * to prevent unnecessary re-renders when the value is structurally the same.\n *\n * @example\n * ```tsx\n * const stableParams = useStableValue(routeParams);\n * const href = useMemo(() => {\n * return router.buildUrl(routeName, stableParams);\n * }, [router, routeName, stableParams]);\n * ```\n *\n * @param value - The value to stabilize\n * @returns A stable reference to the value\n */\nexport function useStableValue<T>(value: T): T {\n const serialized = JSON.stringify(value);\n\n // We intentionally use serialized in deps to detect deep changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => value, [serialized]);\n}\n","import { createActiveRouteSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\nimport { useStableValue } from \"./useStableValue\";\n\nimport type { Params } from \"@real-router/core\";\n\nexport function useIsActiveRoute(\n routeName: string,\n params?: Params,\n strict = false,\n ignoreQueryParams = true,\n): boolean {\n const router = useRouter();\n\n // useStableValue: JSON.stringify memoization of params object.\n // Without it, every render with a new params reference (e.g.,\n // <Link routeParams={{ id: '123' }} />) would recreate the store.\n const stableParams = useStableValue(params);\n\n const store = useMemo(\n () =>\n createActiveRouteSource(router, routeName, stableParams, {\n strict,\n ignoreQueryParams,\n }),\n [router, routeName, stableParams, strict, ignoreQueryParams],\n );\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n}\n","import { shouldNavigate, buildHref, buildActiveClassName } from \"dom-utils\";\nimport { memo, useCallback, useMemo } from \"react\";\n\nimport { EMPTY_PARAMS, EMPTY_OPTIONS } from \"../constants\";\nimport { useIsActiveRoute } from \"../hooks/useIsActiveRoute\";\nimport { useRouter } from \"../hooks/useRouter\";\nimport { useStableValue } from \"../hooks/useStableValue\";\n\nimport type { LinkProps } from \"../types\";\nimport type { FC, MouseEvent } from \"react\";\n\nfunction areLinkPropsEqual(\n prev: Readonly<LinkProps>,\n next: Readonly<LinkProps>,\n): boolean {\n return (\n prev.routeName === next.routeName &&\n prev.className === next.className &&\n prev.activeClassName === next.activeClassName &&\n prev.activeStrict === next.activeStrict &&\n prev.ignoreQueryParams === next.ignoreQueryParams &&\n prev.onClick === next.onClick &&\n prev.target === next.target &&\n prev.style === next.style &&\n prev.children === next.children &&\n JSON.stringify(prev.routeParams) === JSON.stringify(next.routeParams) &&\n JSON.stringify(prev.routeOptions) === JSON.stringify(next.routeOptions)\n );\n}\n\nexport const Link: FC<LinkProps> = memo(\n ({\n routeName,\n routeParams = EMPTY_PARAMS,\n routeOptions = EMPTY_OPTIONS,\n className,\n activeClassName = \"active\",\n activeStrict = false,\n ignoreQueryParams = true,\n onClick,\n target,\n children,\n ...props\n }) => {\n const router = useRouter();\n\n const stableParams = useStableValue(routeParams);\n const stableOptions = useStableValue(routeOptions);\n\n const isActive = useIsActiveRoute(\n routeName,\n stableParams,\n activeStrict,\n ignoreQueryParams,\n );\n\n const href = useMemo(\n () => buildHref(router, routeName, stableParams),\n [router, routeName, stableParams],\n );\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLAnchorElement>) => {\n if (onClick) {\n onClick(evt);\n\n if (evt.defaultPrevented) {\n return;\n }\n }\n\n if (!shouldNavigate(evt.nativeEvent) || target === \"_blank\") {\n return;\n }\n\n evt.preventDefault();\n router.navigate(routeName, stableParams, stableOptions).catch(() => {});\n },\n [onClick, target, router, routeName, stableParams, stableOptions],\n );\n\n const finalClassName = useMemo(\n () => buildActiveClassName(isActive, activeClassName, className),\n [isActive, activeClassName, className],\n );\n\n return (\n <a\n {...props}\n href={href}\n className={finalClassName}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n },\n areLinkPropsEqual,\n);\n\nLink.displayName = \"Link\";\n","// packages/react/modules/hooks/useNavigator.tsx\n\nimport { useContext } from \"react\";\n\nimport { NavigatorContext } from \"../context\";\n\nimport type { Navigator } from \"@real-router/core\";\n\nexport const useNavigator = (): Navigator => {\n const navigator = useContext(NavigatorContext);\n\n if (!navigator) {\n throw new Error(\"useNavigator must be used within a RouterProvider\");\n }\n\n return navigator;\n};\n","// packages/react/modules/hooks/useRouteUtils.tsx\n\nimport { getPluginApi } from \"@real-router/core/api\";\nimport { getRouteUtils } from \"@real-router/route-utils\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteUtils } from \"@real-router/route-utils\";\n\n/**\n * Returns a pre-computed {@link RouteUtils} instance for the current router.\n *\n * Internally retrieves the route tree via `getPluginApi` and delegates\n * to `getRouteUtils`, which caches instances per tree reference (WeakMap).\n *\n * @returns RouteUtils instance with pre-computed chains and siblings\n *\n * @example\n * ```tsx\n * const utils = useRouteUtils();\n *\n * utils.getChain(\"users.profile\");\n * // → [\"users\", \"users.profile\"]\n *\n * utils.getSiblings(\"users\");\n * // → [\"admin\"]\n *\n * utils.isDescendantOf(\"users.profile\", \"users\");\n * // → true\n * ```\n */\nexport const useRouteUtils = (): RouteUtils => {\n const router = useRouter();\n\n return getRouteUtils(getPluginApi(router).getTree());\n};\n","// packages/react/modules/hooks/useRoute.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouteContext } from \"../context\";\n\nimport type { RouteContext as RouteContextType } from \"../types\";\n\nexport const useRoute = (): RouteContextType => {\n const routeContext = useContext(RouteContext);\n\n if (!routeContext) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n\n return routeContext;\n};\n","import { createTransitionSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouterTransitionSnapshot } from \"@real-router/sources\";\n\nexport function useRouterTransition(): RouterTransitionSnapshot {\n const router = useRouter();\n\n const store = useMemo(() => createTransitionSource(router), [router]);\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteSource } from \"@real-router/sources\";\nimport { createRouteAnnouncer } from \"dom-utils\";\nimport { useEffect, useMemo, useSyncExternalStore } from \"react\";\n\nimport { NavigatorContext, RouteContext, RouterContext } from \"./context\";\n\nimport type { Router } from \"@real-router/core\";\nimport type { FC, ReactNode } from \"react\";\n\nexport interface RouteProviderProps {\n router: Router;\n children: ReactNode;\n announceNavigation?: boolean;\n}\n\nexport const RouterProvider: FC<RouteProviderProps> = ({\n router,\n children,\n announceNavigation,\n}) => {\n useEffect(() => {\n if (!announceNavigation) {\n return;\n }\n\n const announcer = createRouteAnnouncer(router);\n\n return () => {\n announcer.destroy();\n };\n }, [announceNavigation, router]);\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n // useSyncExternalStore manages the router subscription lifecycle:\n // subscribe connects to router on first listener, unsubscribes on last.\n // This is Strict Mode safe — no useEffect cleanup needed.\n const store = useMemo(() => createRouteSource(router), [router]);\n const { route, previousRoute } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const routeContextValue = useMemo(\n () => ({ navigator, route, previousRoute }),\n [navigator, route, previousRoute],\n );\n\n return (\n <RouterContext value={router}>\n <NavigatorContext value={navigator}>\n <RouteContext value={routeContextValue}>{children}</RouteContext>\n </NavigatorContext>\n </RouterContext>\n );\n};\n"]}
1
+ {"version":3,"sources":["../../src/components/modern/RouteView/components.tsx","../../src/components/modern/RouteView/helpers.tsx","../../src/context.ts","../../src/hooks/useRouter.tsx","../../src/hooks/useRouteNode.tsx","../../src/components/modern/RouteView/RouteView.tsx","../../src/constants.ts","../../src/hooks/useStableValue.tsx","../../src/hooks/useIsActiveRoute.tsx","../../src/components/Link.tsx","../../src/hooks/useRouterError.tsx","../../src/components/RouterErrorBoundary.tsx","../../src/hooks/useNavigator.tsx","../../src/hooks/useRouteUtils.tsx","../../src/hooks/useRoute.tsx","../../src/hooks/useRouterTransition.tsx","../../src/RouterProvider.tsx"],"names":["startsWithSegment","Children","isValidElement","jsx","Suspense","Activity","Fragment","UNKNOWN_ROUTE","createContext","useContext","useMemo","createRouteNodeSource","useSyncExternalStore","getNavigator","useRef","createActiveRouteSource","memo","buildHref","useCallback","shouldNavigate","buildActiveClassName","createErrorSource","useState","useEffect","jsxs","getRouteUtils","getPluginApi","createTransitionSource","createRouteAnnouncer","createRouteSource"],"mappings":"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","file":"index.js","sourcesContent":["import type { MatchProps, NotFoundProps } from \"./types\";\n\nexport function Match(_props: MatchProps): null {\n return null;\n}\n\nMatch.displayName = \"RouteView.Match\";\n\nexport function NotFound(_props: NotFoundProps): null {\n return null;\n}\n\nNotFound.displayName = \"RouteView.NotFound\";\n","import { UNKNOWN_ROUTE } from \"@real-router/core\";\nimport { startsWithSegment } from \"@real-router/route-utils\";\nimport { Activity, Children, Fragment, Suspense, isValidElement } from \"react\";\n\nimport { Match, NotFound } from \"./components\";\n\nimport type { MatchProps, NotFoundProps } from \"./types\";\nimport type { ReactElement, ReactNode } from \"react\";\n\nfunction isSegmentMatch(\n routeName: string,\n fullSegmentName: string,\n exact: boolean,\n): boolean {\n if (exact) {\n return routeName === fullSegmentName;\n }\n\n return startsWithSegment(routeName, fullSegmentName);\n}\n\nexport function collectElements(\n children: ReactNode,\n result: ReactElement[],\n): void {\n // eslint-disable-next-line @eslint-react/no-children-to-array\n for (const child of Children.toArray(children)) {\n if (!isValidElement(child)) {\n continue;\n }\n\n if (child.type === Match || child.type === NotFound) {\n result.push(child);\n } else {\n collectElements(\n (child.props as { readonly children: ReactNode }).children,\n result,\n );\n }\n }\n}\n\nfunction renderMatchElement(\n matchChildren: ReactNode,\n fullSegmentName: string,\n keepAlive: boolean,\n mode: \"visible\" | \"hidden\",\n fallback?: ReactNode,\n): ReactElement {\n const content =\n fallback === undefined ? (\n matchChildren\n ) : (\n <Suspense fallback={fallback}>{matchChildren}</Suspense>\n );\n\n if (keepAlive) {\n return (\n <Activity mode={mode} key={fullSegmentName}>\n {content}\n </Activity>\n );\n }\n\n return <Fragment key={fullSegmentName}>{content}</Fragment>;\n}\n\nexport function buildRenderList(\n elements: ReactElement[],\n routeName: string,\n nodeName: string,\n hasBeenActivated: Set<string>,\n): { rendered: ReactElement[]; activeMatchFound: boolean } {\n let notFoundChildren: ReactNode = null;\n let activeMatchFound = false;\n const rendered: ReactElement[] = [];\n\n for (const child of elements) {\n if (child.type === NotFound) {\n notFoundChildren = (child.props as NotFoundProps).children;\n continue;\n }\n\n const {\n segment,\n exact = false,\n keepAlive = false,\n fallback,\n } = child.props as MatchProps;\n const fullSegmentName = nodeName ? `${nodeName}.${segment}` : segment;\n const isActive =\n !activeMatchFound && isSegmentMatch(routeName, fullSegmentName, exact);\n\n if (isActive) {\n activeMatchFound = true;\n hasBeenActivated.add(fullSegmentName);\n rendered.push(\n renderMatchElement(\n (child.props as MatchProps).children,\n fullSegmentName,\n keepAlive,\n \"visible\",\n fallback,\n ),\n );\n } else if (keepAlive && hasBeenActivated.has(fullSegmentName)) {\n rendered.push(\n renderMatchElement(\n (child.props as MatchProps).children,\n fullSegmentName,\n keepAlive,\n \"hidden\",\n fallback,\n ),\n );\n }\n }\n\n if (\n !activeMatchFound &&\n routeName === UNKNOWN_ROUTE &&\n notFoundChildren !== null\n ) {\n rendered.push(\n <Fragment key=\"__route-view-not-found__\">{notFoundChildren}</Fragment>,\n );\n }\n\n return { rendered, activeMatchFound };\n}\n","// packages/react/modules/context.ts\n\nimport { createContext } from \"react\";\n\nimport type { RouteContext as RouteContextType } from \"./types\";\nimport type { Router, Navigator } from \"@real-router/core\";\n\nexport const RouteContext = createContext<RouteContextType | null>(null);\n\nexport const RouterContext = createContext<Router | null>(null);\n\nexport const NavigatorContext = createContext<Navigator | null>(null);\n","// packages/react/modules/hooks/useRouter.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouterContext } from \"../context\";\n\nimport type { Router } from \"@real-router/core\";\n\nexport const useRouter = (): Router => {\n const router = useContext(RouterContext);\n\n if (!router) {\n throw new Error(\"useRouter must be used within a RouterProvider\");\n }\n\n return router;\n};\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteContext } from \"../types\";\n\nexport function useRouteNode(nodeName: string): RouteContext {\n const router = useRouter();\n\n const store = useMemo(\n () => createRouteNodeSource(router, nodeName),\n [router, nodeName],\n );\n\n const { route, previousRoute } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n return useMemo(\n (): RouteContext => ({ navigator, route, previousRoute }),\n [navigator, route, previousRoute],\n );\n}\n","import { useRef } from \"react\";\n\nimport { Match, NotFound } from \"./components\";\nimport { buildRenderList, collectElements } from \"./helpers\";\nimport { useRouteNode } from \"../../../hooks/useRouteNode\";\n\nimport type { RouteViewProps } from \"./types\";\nimport type { ReactElement } from \"react\";\n\nfunction RouteViewRoot({\n nodeName,\n children,\n}: Readonly<RouteViewProps>): ReactElement | null {\n const { route } = useRouteNode(nodeName);\n const hasBeenActivatedRef = useRef<Set<string>>(new Set());\n\n if (!route) {\n return null;\n }\n\n const elements: ReactElement[] = [];\n\n collectElements(children, elements);\n\n const { rendered } = buildRenderList(\n elements,\n route.name,\n nodeName,\n hasBeenActivatedRef.current,\n );\n\n if (rendered.length > 0) {\n return <>{rendered}</>;\n }\n\n return null;\n}\n\nRouteViewRoot.displayName = \"RouteView\";\n\nexport const RouteView = Object.assign(RouteViewRoot, { Match, NotFound });\n\nexport type {\n RouteViewProps,\n MatchProps as RouteViewMatchProps,\n NotFoundProps as RouteViewNotFoundProps,\n} from \"./types\";\n","// packages/react/modules/constants.ts\n\n/**\n * Stable empty object for default params\n */\nexport const EMPTY_PARAMS = Object.freeze({});\n\n/**\n * Stable empty options object\n */\nexport const EMPTY_OPTIONS = Object.freeze({});\n","// packages/react/modules/hooks/useStableValue.tsx\n\nimport { useMemo } from \"react\";\n\n/**\n * Stabilizes a value reference based on deep equality (via JSON serialization).\n * Returns the same reference until the serialized value changes.\n *\n * Useful for object/array dependencies in hooks like useMemo, useCallback, useEffect\n * to prevent unnecessary re-renders when the value is structurally the same.\n *\n * @example\n * ```tsx\n * const stableParams = useStableValue(routeParams);\n * const href = useMemo(() => {\n * return router.buildUrl(routeName, stableParams);\n * }, [router, routeName, stableParams]);\n * ```\n *\n * @param value - The value to stabilize\n * @returns A stable reference to the value\n */\nexport function useStableValue<T>(value: T): T {\n const serialized = JSON.stringify(value);\n\n // We intentionally use serialized in deps to detect deep changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => value, [serialized]);\n}\n","import { createActiveRouteSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\nimport { useStableValue } from \"./useStableValue\";\n\nimport type { Params } from \"@real-router/core\";\n\nexport function useIsActiveRoute(\n routeName: string,\n params?: Params,\n strict = false,\n ignoreQueryParams = true,\n): boolean {\n const router = useRouter();\n\n // useStableValue: JSON.stringify memoization of params object.\n // Without it, every render with a new params reference (e.g.,\n // <Link routeParams={{ id: '123' }} />) would recreate the store.\n const stableParams = useStableValue(params);\n\n const store = useMemo(\n () =>\n createActiveRouteSource(router, routeName, stableParams, {\n strict,\n ignoreQueryParams,\n }),\n [router, routeName, stableParams, strict, ignoreQueryParams],\n );\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n}\n","import { shouldNavigate, buildHref, buildActiveClassName } from \"dom-utils\";\nimport { memo, useCallback, useMemo } from \"react\";\n\nimport { EMPTY_PARAMS, EMPTY_OPTIONS } from \"../constants\";\nimport { useIsActiveRoute } from \"../hooks/useIsActiveRoute\";\nimport { useRouter } from \"../hooks/useRouter\";\nimport { useStableValue } from \"../hooks/useStableValue\";\n\nimport type { LinkProps } from \"../types\";\nimport type { FC, MouseEvent } from \"react\";\n\nfunction areLinkPropsEqual(\n prev: Readonly<LinkProps>,\n next: Readonly<LinkProps>,\n): boolean {\n return (\n prev.routeName === next.routeName &&\n prev.className === next.className &&\n prev.activeClassName === next.activeClassName &&\n prev.activeStrict === next.activeStrict &&\n prev.ignoreQueryParams === next.ignoreQueryParams &&\n prev.onClick === next.onClick &&\n prev.target === next.target &&\n prev.style === next.style &&\n prev.children === next.children &&\n JSON.stringify(prev.routeParams) === JSON.stringify(next.routeParams) &&\n JSON.stringify(prev.routeOptions) === JSON.stringify(next.routeOptions)\n );\n}\n\nexport const Link: FC<LinkProps> = memo(\n ({\n routeName,\n routeParams = EMPTY_PARAMS,\n routeOptions = EMPTY_OPTIONS,\n className,\n activeClassName = \"active\",\n activeStrict = false,\n ignoreQueryParams = true,\n onClick,\n target,\n children,\n ...props\n }) => {\n const router = useRouter();\n\n const stableParams = useStableValue(routeParams);\n const stableOptions = useStableValue(routeOptions);\n\n const isActive = useIsActiveRoute(\n routeName,\n stableParams,\n activeStrict,\n ignoreQueryParams,\n );\n\n const href = useMemo(\n () => buildHref(router, routeName, stableParams),\n [router, routeName, stableParams],\n );\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLAnchorElement>) => {\n if (onClick) {\n onClick(evt);\n\n if (evt.defaultPrevented) {\n return;\n }\n }\n\n if (!shouldNavigate(evt.nativeEvent) || target === \"_blank\") {\n return;\n }\n\n evt.preventDefault();\n router.navigate(routeName, stableParams, stableOptions).catch(() => {});\n },\n [onClick, target, router, routeName, stableParams, stableOptions],\n );\n\n const finalClassName = useMemo(\n () => buildActiveClassName(isActive, activeClassName, className),\n [isActive, activeClassName, className],\n );\n\n return (\n <a\n {...props}\n href={href}\n className={finalClassName}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n },\n areLinkPropsEqual,\n);\n\nLink.displayName = \"Link\";\n","import { createErrorSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { Router } from \"@real-router/core\";\nimport type { RouterErrorSnapshot, RouterSource } from \"@real-router/sources\";\n\nconst cache = new WeakMap<Router, RouterSource<RouterErrorSnapshot>>();\n\nexport function useRouterError(): RouterErrorSnapshot {\n const router = useRouter();\n const store = useMemo(() => {\n let source = cache.get(router);\n\n if (!source) {\n source = createErrorSource(router);\n cache.set(router, source);\n }\n\n return source;\n }, [router]);\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useRouterError } from \"../hooks/useRouterError\";\n\nimport type { RouterError, State } from \"@real-router/core\";\nimport type { ReactNode, JSX } from \"react\";\n\nexport interface RouterErrorBoundaryProps {\n readonly children: ReactNode;\n readonly fallback: (error: RouterError, resetError: () => void) => ReactNode;\n readonly onError?: (\n error: RouterError,\n toRoute: State | null,\n fromRoute: State | null,\n ) => void;\n}\n\nexport function RouterErrorBoundary({\n children,\n fallback,\n onError,\n}: RouterErrorBoundaryProps): JSX.Element {\n const snapshot = useRouterError();\n const [dismissedVersion, setDismissedVersion] = useState(-1);\n\n const onErrorRef = useRef(onError);\n\n onErrorRef.current = onError;\n\n useEffect(() => {\n if (snapshot.error) {\n onErrorRef.current?.(\n snapshot.error,\n snapshot.toRoute,\n snapshot.fromRoute,\n );\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- onError tracked via ref, snapshot fields accessed inside callback\n }, [snapshot.version]);\n\n const visibleError =\n snapshot.version > dismissedVersion ? snapshot.error : null;\n\n const resetError = useCallback(() => {\n setDismissedVersion(snapshot.version);\n }, [snapshot.version]);\n\n return (\n <>\n {children}\n {visibleError ? fallback(visibleError, resetError) : null}\n </>\n );\n}\n","// packages/react/modules/hooks/useNavigator.tsx\n\nimport { useContext } from \"react\";\n\nimport { NavigatorContext } from \"../context\";\n\nimport type { Navigator } from \"@real-router/core\";\n\nexport const useNavigator = (): Navigator => {\n const navigator = useContext(NavigatorContext);\n\n if (!navigator) {\n throw new Error(\"useNavigator must be used within a RouterProvider\");\n }\n\n return navigator;\n};\n","// packages/react/modules/hooks/useRouteUtils.tsx\n\nimport { getPluginApi } from \"@real-router/core/api\";\nimport { getRouteUtils } from \"@real-router/route-utils\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteUtils } from \"@real-router/route-utils\";\n\n/**\n * Returns a pre-computed {@link RouteUtils} instance for the current router.\n *\n * Internally retrieves the route tree via `getPluginApi` and delegates\n * to `getRouteUtils`, which caches instances per tree reference (WeakMap).\n *\n * @returns RouteUtils instance with pre-computed chains and siblings\n *\n * @example\n * ```tsx\n * const utils = useRouteUtils();\n *\n * utils.getChain(\"users.profile\");\n * // → [\"users\", \"users.profile\"]\n *\n * utils.getSiblings(\"users\");\n * // → [\"admin\"]\n *\n * utils.isDescendantOf(\"users.profile\", \"users\");\n * // → true\n * ```\n */\nexport const useRouteUtils = (): RouteUtils => {\n const router = useRouter();\n\n return getRouteUtils(getPluginApi(router).getTree());\n};\n","// packages/react/modules/hooks/useRoute.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouteContext } from \"../context\";\n\nimport type { RouteContext as RouteContextType } from \"../types\";\n\nexport const useRoute = (): RouteContextType => {\n const routeContext = useContext(RouteContext);\n\n if (!routeContext) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n\n return routeContext;\n};\n","import { createTransitionSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouterTransitionSnapshot } from \"@real-router/sources\";\n\nexport function useRouterTransition(): RouterTransitionSnapshot {\n const router = useRouter();\n\n const store = useMemo(() => createTransitionSource(router), [router]);\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteSource } from \"@real-router/sources\";\nimport { createRouteAnnouncer } from \"dom-utils\";\nimport { useEffect, useMemo, useSyncExternalStore } from \"react\";\n\nimport { NavigatorContext, RouteContext, RouterContext } from \"./context\";\n\nimport type { Router } from \"@real-router/core\";\nimport type { FC, ReactNode } from \"react\";\n\nexport interface RouteProviderProps {\n router: Router;\n children: ReactNode;\n announceNavigation?: boolean;\n}\n\nexport const RouterProvider: FC<RouteProviderProps> = ({\n router,\n children,\n announceNavigation,\n}) => {\n useEffect(() => {\n if (!announceNavigation) {\n return;\n }\n\n const announcer = createRouteAnnouncer(router);\n\n return () => {\n announcer.destroy();\n };\n }, [announceNavigation, router]);\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n // useSyncExternalStore manages the router subscription lifecycle:\n // subscribe connects to router on first listener, unsubscribes on last.\n // This is Strict Mode safe — no useEffect cleanup needed.\n const store = useMemo(() => createRouteSource(router), [router]);\n const { route, previousRoute } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const routeContextValue = useMemo(\n () => ({ navigator, route, previousRoute }),\n [navigator, route, previousRoute],\n );\n\n return (\n <RouterContext value={router}>\n <NavigatorContext value={navigator}>\n <RouteContext value={routeContextValue}>{children}</RouteContext>\n </NavigatorContext>\n </RouterContext>\n );\n};\n"]}
@@ -1,6 +1,6 @@
1
- import { Params, NavigationOptions, Navigator, State, Router } from '@real-router/core';
1
+ import { Params, NavigationOptions, Navigator, State, RouterError, Router } from '@real-router/core';
2
2
  export { Navigator } from '@real-router/core';
3
- import { HTMLAttributes, MouseEventHandler, FC, ReactNode } from 'react';
3
+ import { HTMLAttributes, MouseEventHandler, FC, ReactNode, JSX } from 'react';
4
4
  import { RouteUtils } from '@real-router/route-utils';
5
5
  import { RouterTransitionSnapshot } from '@real-router/sources';
6
6
  export { RouterTransitionSnapshot } from '@real-router/sources';
@@ -26,6 +26,13 @@ interface LinkProps<P extends Params = Params> extends HTMLAttributes<HTMLAnchor
26
26
 
27
27
  declare const Link: FC<LinkProps>;
28
28
 
29
+ interface RouterErrorBoundaryProps {
30
+ readonly children: ReactNode;
31
+ readonly fallback: (error: RouterError, resetError: () => void) => ReactNode;
32
+ readonly onError?: (error: RouterError, toRoute: State | null, fromRoute: State | null) => void;
33
+ }
34
+ declare function RouterErrorBoundary({ children, fallback, onError, }: RouterErrorBoundaryProps): JSX.Element;
35
+
29
36
  declare const useRouter: () => Router;
30
37
 
31
38
  declare const useNavigator: () => Navigator;
@@ -67,4 +74,4 @@ interface RouteProviderProps {
67
74
  }
68
75
  declare const RouterProvider: FC<RouteProviderProps>;
69
76
 
70
- export { Link, type LinkProps, RouterProvider, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition };
77
+ export { Link, type LinkProps, RouterErrorBoundary, type RouterErrorBoundaryProps, RouterProvider, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition };
@@ -1 +1 @@
1
- var e=require("dom-utils"),t=require("react"),r=require("@real-router/sources"),o=require("react/jsx-runtime"),u=require("@real-router/core"),s=require("@real-router/core/api"),n=require("@real-router/route-utils"),a=Object.freeze({}),i=Object.freeze({}),c=t.createContext(null),l=t.createContext(null),m=t.createContext(null),g=()=>{const e=t.useContext(l);if(!e)throw new Error("useRouter must be used within a RouterProvider");return e};function v(e){const r=JSON.stringify(e);return t.useMemo(()=>e,[r])}var S=t.memo(({routeName:u,routeParams:s=a,routeOptions:n=i,className:c,activeClassName:l="active",activeStrict:m=!1,ignoreQueryParams:S=!0,onClick:p,target:d,children:h,...N})=>{const x=g(),f=v(s),R=v(n),b=function(e,o,u=!1,s=!0){const n=g(),a=v(o),i=t.useMemo(()=>r.createActiveRouteSource(n,e,a,{strict:u,ignoreQueryParams:s}),[n,e,a,u,s]);return t.useSyncExternalStore(i.subscribe,i.getSnapshot,i.getSnapshot)}(u,f,m,S),y=t.useMemo(()=>e.buildHref(x,u,f),[x,u,f]),C=t.useCallback(t=>{p&&(p(t),t.defaultPrevented)||e.shouldNavigate(t.nativeEvent)&&"_blank"!==d&&(t.preventDefault(),x.navigate(u,f,R).catch(()=>{}))},[p,d,x,u,f,R]),P=t.useMemo(()=>e.buildActiveClassName(b,l,c),[b,l,c]);return o.jsx("a",{...N,href:y,className:P,onClick:C,children:h})},function(e,t){return e.routeName===t.routeName&&e.className===t.className&&e.activeClassName===t.activeClassName&&e.activeStrict===t.activeStrict&&e.ignoreQueryParams===t.ignoreQueryParams&&e.onClick===t.onClick&&e.target===t.target&&e.style===t.style&&e.children===t.children&&JSON.stringify(e.routeParams)===JSON.stringify(t.routeParams)&&JSON.stringify(e.routeOptions)===JSON.stringify(t.routeOptions)});S.displayName="Link",exports.Link=S,exports.RouterProvider=({router:s,children:n,announceNavigation:a})=>{t.useEffect(()=>{if(!a)return;const t=e.createRouteAnnouncer(s);return()=>{t.destroy()}},[a,s]);const i=t.useMemo(()=>u.getNavigator(s),[s]),g=t.useMemo(()=>r.createRouteSource(s),[s]),{route:v,previousRoute:S}=t.useSyncExternalStore(g.subscribe,g.getSnapshot,g.getSnapshot),p=t.useMemo(()=>({navigator:i,route:v,previousRoute:S}),[i,v,S]);return o.jsx(l,{value:s,children:o.jsx(m,{value:i,children:o.jsx(c,{value:p,children:n})})})},exports.useNavigator=()=>{const e=t.useContext(m);if(!e)throw new Error("useNavigator must be used within a RouterProvider");return e},exports.useRoute=()=>{const e=t.useContext(c);if(!e)throw new Error("useRoute must be used within a RouteProvider");return e},exports.useRouteNode=function(e){const o=g(),s=t.useMemo(()=>r.createRouteNodeSource(o,e),[o,e]),{route:n,previousRoute:a}=t.useSyncExternalStore(s.subscribe,s.getSnapshot,s.getSnapshot),i=t.useMemo(()=>u.getNavigator(o),[o]);return t.useMemo(()=>({navigator:i,route:n,previousRoute:a}),[i,n,a])},exports.useRouteUtils=()=>{const e=g();return n.getRouteUtils(s.getPluginApi(e).getTree())},exports.useRouter=g,exports.useRouterTransition=function(){const e=g(),o=t.useMemo(()=>r.createTransitionSource(e),[e]);return t.useSyncExternalStore(o.subscribe,o.getSnapshot,o.getSnapshot)};//# sourceMappingURL=legacy.js.map
1
+ var e=require("dom-utils"),r=require("react"),t=require("@real-router/sources"),o=require("react/jsx-runtime"),u=require("@real-router/core"),s=require("@real-router/core/api"),n=require("@real-router/route-utils"),a=Object.freeze({}),i=Object.freeze({}),c=r.createContext(null),l=r.createContext(null),m=r.createContext(null),v=()=>{const e=r.useContext(l);if(!e)throw new Error("useRouter must be used within a RouterProvider");return e};function g(e){const t=JSON.stringify(e);return r.useMemo(()=>e,[t])}var S=r.memo(({routeName:u,routeParams:s=a,routeOptions:n=i,className:c,activeClassName:l="active",activeStrict:m=!1,ignoreQueryParams:S=!0,onClick:p,target:f,children:h,...d})=>{const x=v(),N=g(s),R=g(n),b=function(e,o,u=!1,s=!0){const n=v(),a=g(o),i=r.useMemo(()=>t.createActiveRouteSource(n,e,a,{strict:u,ignoreQueryParams:s}),[n,e,a,u,s]);return r.useSyncExternalStore(i.subscribe,i.getSnapshot,i.getSnapshot)}(u,N,m,S),y=r.useMemo(()=>e.buildHref(x,u,N),[x,u,N]),C=r.useCallback(r=>{p&&(p(r),r.defaultPrevented)||e.shouldNavigate(r.nativeEvent)&&"_blank"!==f&&(r.preventDefault(),x.navigate(u,N,R).catch(()=>{}))},[p,f,x,u,N,R]),E=r.useMemo(()=>e.buildActiveClassName(b,l,c),[b,l,c]);return o.jsx("a",{...d,href:y,className:E,onClick:C,children:h})},function(e,r){return e.routeName===r.routeName&&e.className===r.className&&e.activeClassName===r.activeClassName&&e.activeStrict===r.activeStrict&&e.ignoreQueryParams===r.ignoreQueryParams&&e.onClick===r.onClick&&e.target===r.target&&e.style===r.style&&e.children===r.children&&JSON.stringify(e.routeParams)===JSON.stringify(r.routeParams)&&JSON.stringify(e.routeOptions)===JSON.stringify(r.routeOptions)});S.displayName="Link";var p=new WeakMap;exports.Link=S,exports.RouterErrorBoundary=function({children:e,fallback:u,onError:s}){const n=function(){const e=v(),o=r.useMemo(()=>{let r=p.get(e);return r||(r=t.createErrorSource(e),p.set(e,r)),r},[e]);return r.useSyncExternalStore(o.subscribe,o.getSnapshot,o.getSnapshot)}(),[a,i]=r.useState(-1),c=r.useRef(s);c.current=s,r.useEffect(()=>{n.error&&c.current?.(n.error,n.toRoute,n.fromRoute)},[n.version]);const l=n.version>a?n.error:null,m=r.useCallback(()=>{i(n.version)},[n.version]);return o.jsxs(o.Fragment,{children:[e,l?u(l,m):null]})},exports.RouterProvider=({router:s,children:n,announceNavigation:a})=>{r.useEffect(()=>{if(!a)return;const r=e.createRouteAnnouncer(s);return()=>{r.destroy()}},[a,s]);const i=r.useMemo(()=>u.getNavigator(s),[s]),v=r.useMemo(()=>t.createRouteSource(s),[s]),{route:g,previousRoute:S}=r.useSyncExternalStore(v.subscribe,v.getSnapshot,v.getSnapshot),p=r.useMemo(()=>({navigator:i,route:g,previousRoute:S}),[i,g,S]);return o.jsx(l,{value:s,children:o.jsx(m,{value:i,children:o.jsx(c,{value:p,children:n})})})},exports.useNavigator=()=>{const e=r.useContext(m);if(!e)throw new Error("useNavigator must be used within a RouterProvider");return e},exports.useRoute=()=>{const e=r.useContext(c);if(!e)throw new Error("useRoute must be used within a RouteProvider");return e},exports.useRouteNode=function(e){const o=v(),s=r.useMemo(()=>t.createRouteNodeSource(o,e),[o,e]),{route:n,previousRoute:a}=r.useSyncExternalStore(s.subscribe,s.getSnapshot,s.getSnapshot),i=r.useMemo(()=>u.getNavigator(o),[o]);return r.useMemo(()=>({navigator:i,route:n,previousRoute:a}),[i,n,a])},exports.useRouteUtils=()=>{const e=v();return n.getRouteUtils(s.getPluginApi(e).getTree())},exports.useRouter=v,exports.useRouterTransition=function(){const e=v(),o=r.useMemo(()=>t.createTransitionSource(e),[e]);return r.useSyncExternalStore(o.subscribe,o.getSnapshot,o.getSnapshot)};//# sourceMappingURL=legacy.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/constants.ts","../../src/context.ts","../../src/hooks/useRouter.tsx","../../src/hooks/useStableValue.tsx","../../src/hooks/useIsActiveRoute.tsx","../../src/components/Link.tsx","../../src/hooks/useRouteNode.tsx","../../src/hooks/useRoute.tsx","../../src/hooks/useNavigator.tsx","../../src/hooks/useRouteUtils.tsx","../../src/hooks/useRouterTransition.tsx","../../src/RouterProvider.tsx"],"names":["createContext","useContext","useMemo","createActiveRouteSource","useSyncExternalStore","memo","buildHref","useCallback","shouldNavigate","buildActiveClassName","jsx","createRouteNodeSource","getNavigator","getRouteUtils","getPluginApi","createTransitionSource","useEffect","createRouteAnnouncer","createRouteSource"],"mappings":"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","file":"legacy.js","sourcesContent":["// packages/react/modules/constants.ts\n\n/**\n * Stable empty object for default params\n */\nexport const EMPTY_PARAMS = Object.freeze({});\n\n/**\n * Stable empty options object\n */\nexport const EMPTY_OPTIONS = Object.freeze({});\n","// packages/react/modules/context.ts\n\nimport { createContext } from \"react\";\n\nimport type { RouteContext as RouteContextType } from \"./types\";\nimport type { Router, Navigator } from \"@real-router/core\";\n\nexport const RouteContext = createContext<RouteContextType | null>(null);\n\nexport const RouterContext = createContext<Router | null>(null);\n\nexport const NavigatorContext = createContext<Navigator | null>(null);\n","// packages/react/modules/hooks/useRouter.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouterContext } from \"../context\";\n\nimport type { Router } from \"@real-router/core\";\n\nexport const useRouter = (): Router => {\n const router = useContext(RouterContext);\n\n if (!router) {\n throw new Error(\"useRouter must be used within a RouterProvider\");\n }\n\n return router;\n};\n","// packages/react/modules/hooks/useStableValue.tsx\n\nimport { useMemo } from \"react\";\n\n/**\n * Stabilizes a value reference based on deep equality (via JSON serialization).\n * Returns the same reference until the serialized value changes.\n *\n * Useful for object/array dependencies in hooks like useMemo, useCallback, useEffect\n * to prevent unnecessary re-renders when the value is structurally the same.\n *\n * @example\n * ```tsx\n * const stableParams = useStableValue(routeParams);\n * const href = useMemo(() => {\n * return router.buildUrl(routeName, stableParams);\n * }, [router, routeName, stableParams]);\n * ```\n *\n * @param value - The value to stabilize\n * @returns A stable reference to the value\n */\nexport function useStableValue<T>(value: T): T {\n const serialized = JSON.stringify(value);\n\n // We intentionally use serialized in deps to detect deep changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => value, [serialized]);\n}\n","import { createActiveRouteSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\nimport { useStableValue } from \"./useStableValue\";\n\nimport type { Params } from \"@real-router/core\";\n\nexport function useIsActiveRoute(\n routeName: string,\n params?: Params,\n strict = false,\n ignoreQueryParams = true,\n): boolean {\n const router = useRouter();\n\n // useStableValue: JSON.stringify memoization of params object.\n // Without it, every render with a new params reference (e.g.,\n // <Link routeParams={{ id: '123' }} />) would recreate the store.\n const stableParams = useStableValue(params);\n\n const store = useMemo(\n () =>\n createActiveRouteSource(router, routeName, stableParams, {\n strict,\n ignoreQueryParams,\n }),\n [router, routeName, stableParams, strict, ignoreQueryParams],\n );\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n}\n","import { shouldNavigate, buildHref, buildActiveClassName } from \"dom-utils\";\nimport { memo, useCallback, useMemo } from \"react\";\n\nimport { EMPTY_PARAMS, EMPTY_OPTIONS } from \"../constants\";\nimport { useIsActiveRoute } from \"../hooks/useIsActiveRoute\";\nimport { useRouter } from \"../hooks/useRouter\";\nimport { useStableValue } from \"../hooks/useStableValue\";\n\nimport type { LinkProps } from \"../types\";\nimport type { FC, MouseEvent } from \"react\";\n\nfunction areLinkPropsEqual(\n prev: Readonly<LinkProps>,\n next: Readonly<LinkProps>,\n): boolean {\n return (\n prev.routeName === next.routeName &&\n prev.className === next.className &&\n prev.activeClassName === next.activeClassName &&\n prev.activeStrict === next.activeStrict &&\n prev.ignoreQueryParams === next.ignoreQueryParams &&\n prev.onClick === next.onClick &&\n prev.target === next.target &&\n prev.style === next.style &&\n prev.children === next.children &&\n JSON.stringify(prev.routeParams) === JSON.stringify(next.routeParams) &&\n JSON.stringify(prev.routeOptions) === JSON.stringify(next.routeOptions)\n );\n}\n\nexport const Link: FC<LinkProps> = memo(\n ({\n routeName,\n routeParams = EMPTY_PARAMS,\n routeOptions = EMPTY_OPTIONS,\n className,\n activeClassName = \"active\",\n activeStrict = false,\n ignoreQueryParams = true,\n onClick,\n target,\n children,\n ...props\n }) => {\n const router = useRouter();\n\n const stableParams = useStableValue(routeParams);\n const stableOptions = useStableValue(routeOptions);\n\n const isActive = useIsActiveRoute(\n routeName,\n stableParams,\n activeStrict,\n ignoreQueryParams,\n );\n\n const href = useMemo(\n () => buildHref(router, routeName, stableParams),\n [router, routeName, stableParams],\n );\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLAnchorElement>) => {\n if (onClick) {\n onClick(evt);\n\n if (evt.defaultPrevented) {\n return;\n }\n }\n\n if (!shouldNavigate(evt.nativeEvent) || target === \"_blank\") {\n return;\n }\n\n evt.preventDefault();\n router.navigate(routeName, stableParams, stableOptions).catch(() => {});\n },\n [onClick, target, router, routeName, stableParams, stableOptions],\n );\n\n const finalClassName = useMemo(\n () => buildActiveClassName(isActive, activeClassName, className),\n [isActive, activeClassName, className],\n );\n\n return (\n <a\n {...props}\n href={href}\n className={finalClassName}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n },\n areLinkPropsEqual,\n);\n\nLink.displayName = \"Link\";\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteContext } from \"../types\";\n\nexport function useRouteNode(nodeName: string): RouteContext {\n const router = useRouter();\n\n const store = useMemo(\n () => createRouteNodeSource(router, nodeName),\n [router, nodeName],\n );\n\n const { route, previousRoute } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n return useMemo(\n (): RouteContext => ({ navigator, route, previousRoute }),\n [navigator, route, previousRoute],\n );\n}\n","// packages/react/modules/hooks/useRoute.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouteContext } from \"../context\";\n\nimport type { RouteContext as RouteContextType } from \"../types\";\n\nexport const useRoute = (): RouteContextType => {\n const routeContext = useContext(RouteContext);\n\n if (!routeContext) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n\n return routeContext;\n};\n","// packages/react/modules/hooks/useNavigator.tsx\n\nimport { useContext } from \"react\";\n\nimport { NavigatorContext } from \"../context\";\n\nimport type { Navigator } from \"@real-router/core\";\n\nexport const useNavigator = (): Navigator => {\n const navigator = useContext(NavigatorContext);\n\n if (!navigator) {\n throw new Error(\"useNavigator must be used within a RouterProvider\");\n }\n\n return navigator;\n};\n","// packages/react/modules/hooks/useRouteUtils.tsx\n\nimport { getPluginApi } from \"@real-router/core/api\";\nimport { getRouteUtils } from \"@real-router/route-utils\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteUtils } from \"@real-router/route-utils\";\n\n/**\n * Returns a pre-computed {@link RouteUtils} instance for the current router.\n *\n * Internally retrieves the route tree via `getPluginApi` and delegates\n * to `getRouteUtils`, which caches instances per tree reference (WeakMap).\n *\n * @returns RouteUtils instance with pre-computed chains and siblings\n *\n * @example\n * ```tsx\n * const utils = useRouteUtils();\n *\n * utils.getChain(\"users.profile\");\n * // → [\"users\", \"users.profile\"]\n *\n * utils.getSiblings(\"users\");\n * // → [\"admin\"]\n *\n * utils.isDescendantOf(\"users.profile\", \"users\");\n * // → true\n * ```\n */\nexport const useRouteUtils = (): RouteUtils => {\n const router = useRouter();\n\n return getRouteUtils(getPluginApi(router).getTree());\n};\n","import { createTransitionSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouterTransitionSnapshot } from \"@real-router/sources\";\n\nexport function useRouterTransition(): RouterTransitionSnapshot {\n const router = useRouter();\n\n const store = useMemo(() => createTransitionSource(router), [router]);\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteSource } from \"@real-router/sources\";\nimport { createRouteAnnouncer } from \"dom-utils\";\nimport { useEffect, useMemo, useSyncExternalStore } from \"react\";\n\nimport { NavigatorContext, RouteContext, RouterContext } from \"./context\";\n\nimport type { Router } from \"@real-router/core\";\nimport type { FC, ReactNode } from \"react\";\n\nexport interface RouteProviderProps {\n router: Router;\n children: ReactNode;\n announceNavigation?: boolean;\n}\n\nexport const RouterProvider: FC<RouteProviderProps> = ({\n router,\n children,\n announceNavigation,\n}) => {\n useEffect(() => {\n if (!announceNavigation) {\n return;\n }\n\n const announcer = createRouteAnnouncer(router);\n\n return () => {\n announcer.destroy();\n };\n }, [announceNavigation, router]);\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n // useSyncExternalStore manages the router subscription lifecycle:\n // subscribe connects to router on first listener, unsubscribes on last.\n // This is Strict Mode safe — no useEffect cleanup needed.\n const store = useMemo(() => createRouteSource(router), [router]);\n const { route, previousRoute } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const routeContextValue = useMemo(\n () => ({ navigator, route, previousRoute }),\n [navigator, route, previousRoute],\n );\n\n return (\n <RouterContext value={router}>\n <NavigatorContext value={navigator}>\n <RouteContext value={routeContextValue}>{children}</RouteContext>\n </NavigatorContext>\n </RouterContext>\n );\n};\n"]}
1
+ {"version":3,"sources":["../../src/constants.ts","../../src/context.ts","../../src/hooks/useRouter.tsx","../../src/hooks/useStableValue.tsx","../../src/hooks/useIsActiveRoute.tsx","../../src/components/Link.tsx","../../src/hooks/useRouterError.tsx","../../src/components/RouterErrorBoundary.tsx","../../src/hooks/useRouteNode.tsx","../../src/hooks/useRoute.tsx","../../src/hooks/useNavigator.tsx","../../src/hooks/useRouteUtils.tsx","../../src/hooks/useRouterTransition.tsx","../../src/RouterProvider.tsx"],"names":["createContext","useContext","useMemo","createActiveRouteSource","useSyncExternalStore","memo","buildHref","useCallback","shouldNavigate","buildActiveClassName","jsx","createErrorSource","useState","useRef","useEffect","jsxs","Fragment","createRouteNodeSource","getNavigator","getRouteUtils","getPluginApi","createTransitionSource","createRouteAnnouncer","createRouteSource"],"mappings":"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","file":"legacy.js","sourcesContent":["// packages/react/modules/constants.ts\n\n/**\n * Stable empty object for default params\n */\nexport const EMPTY_PARAMS = Object.freeze({});\n\n/**\n * Stable empty options object\n */\nexport const EMPTY_OPTIONS = Object.freeze({});\n","// packages/react/modules/context.ts\n\nimport { createContext } from \"react\";\n\nimport type { RouteContext as RouteContextType } from \"./types\";\nimport type { Router, Navigator } from \"@real-router/core\";\n\nexport const RouteContext = createContext<RouteContextType | null>(null);\n\nexport const RouterContext = createContext<Router | null>(null);\n\nexport const NavigatorContext = createContext<Navigator | null>(null);\n","// packages/react/modules/hooks/useRouter.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouterContext } from \"../context\";\n\nimport type { Router } from \"@real-router/core\";\n\nexport const useRouter = (): Router => {\n const router = useContext(RouterContext);\n\n if (!router) {\n throw new Error(\"useRouter must be used within a RouterProvider\");\n }\n\n return router;\n};\n","// packages/react/modules/hooks/useStableValue.tsx\n\nimport { useMemo } from \"react\";\n\n/**\n * Stabilizes a value reference based on deep equality (via JSON serialization).\n * Returns the same reference until the serialized value changes.\n *\n * Useful for object/array dependencies in hooks like useMemo, useCallback, useEffect\n * to prevent unnecessary re-renders when the value is structurally the same.\n *\n * @example\n * ```tsx\n * const stableParams = useStableValue(routeParams);\n * const href = useMemo(() => {\n * return router.buildUrl(routeName, stableParams);\n * }, [router, routeName, stableParams]);\n * ```\n *\n * @param value - The value to stabilize\n * @returns A stable reference to the value\n */\nexport function useStableValue<T>(value: T): T {\n const serialized = JSON.stringify(value);\n\n // We intentionally use serialized in deps to detect deep changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => value, [serialized]);\n}\n","import { createActiveRouteSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\nimport { useStableValue } from \"./useStableValue\";\n\nimport type { Params } from \"@real-router/core\";\n\nexport function useIsActiveRoute(\n routeName: string,\n params?: Params,\n strict = false,\n ignoreQueryParams = true,\n): boolean {\n const router = useRouter();\n\n // useStableValue: JSON.stringify memoization of params object.\n // Without it, every render with a new params reference (e.g.,\n // <Link routeParams={{ id: '123' }} />) would recreate the store.\n const stableParams = useStableValue(params);\n\n const store = useMemo(\n () =>\n createActiveRouteSource(router, routeName, stableParams, {\n strict,\n ignoreQueryParams,\n }),\n [router, routeName, stableParams, strict, ignoreQueryParams],\n );\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n}\n","import { shouldNavigate, buildHref, buildActiveClassName } from \"dom-utils\";\nimport { memo, useCallback, useMemo } from \"react\";\n\nimport { EMPTY_PARAMS, EMPTY_OPTIONS } from \"../constants\";\nimport { useIsActiveRoute } from \"../hooks/useIsActiveRoute\";\nimport { useRouter } from \"../hooks/useRouter\";\nimport { useStableValue } from \"../hooks/useStableValue\";\n\nimport type { LinkProps } from \"../types\";\nimport type { FC, MouseEvent } from \"react\";\n\nfunction areLinkPropsEqual(\n prev: Readonly<LinkProps>,\n next: Readonly<LinkProps>,\n): boolean {\n return (\n prev.routeName === next.routeName &&\n prev.className === next.className &&\n prev.activeClassName === next.activeClassName &&\n prev.activeStrict === next.activeStrict &&\n prev.ignoreQueryParams === next.ignoreQueryParams &&\n prev.onClick === next.onClick &&\n prev.target === next.target &&\n prev.style === next.style &&\n prev.children === next.children &&\n JSON.stringify(prev.routeParams) === JSON.stringify(next.routeParams) &&\n JSON.stringify(prev.routeOptions) === JSON.stringify(next.routeOptions)\n );\n}\n\nexport const Link: FC<LinkProps> = memo(\n ({\n routeName,\n routeParams = EMPTY_PARAMS,\n routeOptions = EMPTY_OPTIONS,\n className,\n activeClassName = \"active\",\n activeStrict = false,\n ignoreQueryParams = true,\n onClick,\n target,\n children,\n ...props\n }) => {\n const router = useRouter();\n\n const stableParams = useStableValue(routeParams);\n const stableOptions = useStableValue(routeOptions);\n\n const isActive = useIsActiveRoute(\n routeName,\n stableParams,\n activeStrict,\n ignoreQueryParams,\n );\n\n const href = useMemo(\n () => buildHref(router, routeName, stableParams),\n [router, routeName, stableParams],\n );\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLAnchorElement>) => {\n if (onClick) {\n onClick(evt);\n\n if (evt.defaultPrevented) {\n return;\n }\n }\n\n if (!shouldNavigate(evt.nativeEvent) || target === \"_blank\") {\n return;\n }\n\n evt.preventDefault();\n router.navigate(routeName, stableParams, stableOptions).catch(() => {});\n },\n [onClick, target, router, routeName, stableParams, stableOptions],\n );\n\n const finalClassName = useMemo(\n () => buildActiveClassName(isActive, activeClassName, className),\n [isActive, activeClassName, className],\n );\n\n return (\n <a\n {...props}\n href={href}\n className={finalClassName}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n },\n areLinkPropsEqual,\n);\n\nLink.displayName = \"Link\";\n","import { createErrorSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { Router } from \"@real-router/core\";\nimport type { RouterErrorSnapshot, RouterSource } from \"@real-router/sources\";\n\nconst cache = new WeakMap<Router, RouterSource<RouterErrorSnapshot>>();\n\nexport function useRouterError(): RouterErrorSnapshot {\n const router = useRouter();\n const store = useMemo(() => {\n let source = cache.get(router);\n\n if (!source) {\n source = createErrorSource(router);\n cache.set(router, source);\n }\n\n return source;\n }, [router]);\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useRouterError } from \"../hooks/useRouterError\";\n\nimport type { RouterError, State } from \"@real-router/core\";\nimport type { ReactNode, JSX } from \"react\";\n\nexport interface RouterErrorBoundaryProps {\n readonly children: ReactNode;\n readonly fallback: (error: RouterError, resetError: () => void) => ReactNode;\n readonly onError?: (\n error: RouterError,\n toRoute: State | null,\n fromRoute: State | null,\n ) => void;\n}\n\nexport function RouterErrorBoundary({\n children,\n fallback,\n onError,\n}: RouterErrorBoundaryProps): JSX.Element {\n const snapshot = useRouterError();\n const [dismissedVersion, setDismissedVersion] = useState(-1);\n\n const onErrorRef = useRef(onError);\n\n onErrorRef.current = onError;\n\n useEffect(() => {\n if (snapshot.error) {\n onErrorRef.current?.(\n snapshot.error,\n snapshot.toRoute,\n snapshot.fromRoute,\n );\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- onError tracked via ref, snapshot fields accessed inside callback\n }, [snapshot.version]);\n\n const visibleError =\n snapshot.version > dismissedVersion ? snapshot.error : null;\n\n const resetError = useCallback(() => {\n setDismissedVersion(snapshot.version);\n }, [snapshot.version]);\n\n return (\n <>\n {children}\n {visibleError ? fallback(visibleError, resetError) : null}\n </>\n );\n}\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteContext } from \"../types\";\n\nexport function useRouteNode(nodeName: string): RouteContext {\n const router = useRouter();\n\n const store = useMemo(\n () => createRouteNodeSource(router, nodeName),\n [router, nodeName],\n );\n\n const { route, previousRoute } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n return useMemo(\n (): RouteContext => ({ navigator, route, previousRoute }),\n [navigator, route, previousRoute],\n );\n}\n","// packages/react/modules/hooks/useRoute.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouteContext } from \"../context\";\n\nimport type { RouteContext as RouteContextType } from \"../types\";\n\nexport const useRoute = (): RouteContextType => {\n const routeContext = useContext(RouteContext);\n\n if (!routeContext) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n\n return routeContext;\n};\n","// packages/react/modules/hooks/useNavigator.tsx\n\nimport { useContext } from \"react\";\n\nimport { NavigatorContext } from \"../context\";\n\nimport type { Navigator } from \"@real-router/core\";\n\nexport const useNavigator = (): Navigator => {\n const navigator = useContext(NavigatorContext);\n\n if (!navigator) {\n throw new Error(\"useNavigator must be used within a RouterProvider\");\n }\n\n return navigator;\n};\n","// packages/react/modules/hooks/useRouteUtils.tsx\n\nimport { getPluginApi } from \"@real-router/core/api\";\nimport { getRouteUtils } from \"@real-router/route-utils\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteUtils } from \"@real-router/route-utils\";\n\n/**\n * Returns a pre-computed {@link RouteUtils} instance for the current router.\n *\n * Internally retrieves the route tree via `getPluginApi` and delegates\n * to `getRouteUtils`, which caches instances per tree reference (WeakMap).\n *\n * @returns RouteUtils instance with pre-computed chains and siblings\n *\n * @example\n * ```tsx\n * const utils = useRouteUtils();\n *\n * utils.getChain(\"users.profile\");\n * // → [\"users\", \"users.profile\"]\n *\n * utils.getSiblings(\"users\");\n * // → [\"admin\"]\n *\n * utils.isDescendantOf(\"users.profile\", \"users\");\n * // → true\n * ```\n */\nexport const useRouteUtils = (): RouteUtils => {\n const router = useRouter();\n\n return getRouteUtils(getPluginApi(router).getTree());\n};\n","import { createTransitionSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouterTransitionSnapshot } from \"@real-router/sources\";\n\nexport function useRouterTransition(): RouterTransitionSnapshot {\n const router = useRouter();\n\n const store = useMemo(() => createTransitionSource(router), [router]);\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteSource } from \"@real-router/sources\";\nimport { createRouteAnnouncer } from \"dom-utils\";\nimport { useEffect, useMemo, useSyncExternalStore } from \"react\";\n\nimport { NavigatorContext, RouteContext, RouterContext } from \"./context\";\n\nimport type { Router } from \"@real-router/core\";\nimport type { FC, ReactNode } from \"react\";\n\nexport interface RouteProviderProps {\n router: Router;\n children: ReactNode;\n announceNavigation?: boolean;\n}\n\nexport const RouterProvider: FC<RouteProviderProps> = ({\n router,\n children,\n announceNavigation,\n}) => {\n useEffect(() => {\n if (!announceNavigation) {\n return;\n }\n\n const announcer = createRouteAnnouncer(router);\n\n return () => {\n announcer.destroy();\n };\n }, [announceNavigation, router]);\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n // useSyncExternalStore manages the router subscription lifecycle:\n // subscribe connects to router on first listener, unsubscribes on last.\n // This is Strict Mode safe — no useEffect cleanup needed.\n const store = useMemo(() => createRouteSource(router), [router]);\n const { route, previousRoute } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const routeContextValue = useMemo(\n () => ({ navigator, route, previousRoute }),\n [navigator, route, previousRoute],\n );\n\n return (\n <RouterContext value={router}>\n <NavigatorContext value={navigator}>\n <RouteContext value={routeContextValue}>{children}</RouteContext>\n </NavigatorContext>\n </RouterContext>\n );\n};\n"]}
@@ -1 +1 @@
1
- {"inputs":{"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js":{"bytes":569,"imports":[],"format":"esm"},"src/components/modern/RouteView/components.tsx":{"bytes":286,"imports":[{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/components/modern/RouteView/helpers.tsx":{"bytes":3208,"imports":[{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/components/modern/RouteView/components.tsx","kind":"import-statement","original":"./components"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/context.ts":{"bytes":416,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRouter.tsx":{"bytes":378,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"../context"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRouteNode.tsx":{"bytes":837,"imports":[{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/components/modern/RouteView/RouteView.tsx":{"bytes":1073,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/components/modern/RouteView/components.tsx","kind":"import-statement","original":"./components"},{"path":"src/components/modern/RouteView/helpers.tsx","kind":"import-statement","original":"./helpers"},{"path":"src/hooks/useRouteNode.tsx","kind":"import-statement","original":"../../../hooks/useRouteNode"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/components/modern/RouteView/index.ts":{"bytes":145,"imports":[{"path":"src/components/modern/RouteView/RouteView.tsx","kind":"import-statement","original":"./RouteView"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/constants.ts":{"bytes":225,"imports":[{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useStableValue.tsx":{"bytes":976,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useIsActiveRoute.tsx":{"bytes":1060,"imports":[{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"},{"path":"src/hooks/useStableValue.tsx","kind":"import-statement","original":"./useStableValue"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/components/Link.tsx":{"bytes":2703,"imports":[{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/constants.ts","kind":"import-statement","original":"../constants"},{"path":"src/hooks/useIsActiveRoute.tsx","kind":"import-statement","original":"../hooks/useIsActiveRoute"},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"../hooks/useRouter"},{"path":"src/hooks/useStableValue.tsx","kind":"import-statement","original":"../hooks/useStableValue"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useNavigator.tsx":{"bytes":408,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"../context"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRouteUtils.tsx":{"bytes":981,"imports":[{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRoute.tsx":{"bytes":417,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"../context"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRouterTransition.tsx":{"bytes":508,"imports":[{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/RouterProvider.tsx":{"bytes":1710,"imports":[{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"./context"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":849,"imports":[{"path":"src/components/modern/RouteView/index.ts","kind":"import-statement","original":"./components/modern/RouteView"},{"path":"src/components/Link.tsx","kind":"import-statement","original":"./components/Link"},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./hooks/useRouter"},{"path":"src/hooks/useNavigator.tsx","kind":"import-statement","original":"./hooks/useNavigator"},{"path":"src/hooks/useRouteUtils.tsx","kind":"import-statement","original":"./hooks/useRouteUtils"},{"path":"src/hooks/useRoute.tsx","kind":"import-statement","original":"./hooks/useRoute"},{"path":"src/hooks/useRouteNode.tsx","kind":"import-statement","original":"./hooks/useRouteNode"},{"path":"src/hooks/useRouterTransition.tsx","kind":"import-statement","original":"./hooks/useRouterTransition"},{"path":"src/RouterProvider.tsx","kind":"import-statement","original":"./RouterProvider"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/legacy.ts":{"bytes":667,"imports":[{"path":"src/components/Link.tsx","kind":"import-statement","original":"./components/Link"},{"path":"src/hooks/useRouteNode.tsx","kind":"import-statement","original":"./hooks/useRouteNode"},{"path":"src/hooks/useRoute.tsx","kind":"import-statement","original":"./hooks/useRoute"},{"path":"src/hooks/useNavigator.tsx","kind":"import-statement","original":"./hooks/useNavigator"},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./hooks/useRouter"},{"path":"src/hooks/useRouteUtils.tsx","kind":"import-statement","original":"./hooks/useRouteUtils"},{"path":"src/hooks/useRouterTransition.tsx","kind":"import-statement","original":"./hooks/useRouterTransition"},{"path":"src/RouterProvider.tsx","kind":"import-statement","original":"./RouterProvider"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/cjs/index.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":23205},"dist/cjs/index.js":{"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"exports":["Link","RouteView","RouterProvider","useNavigator","useRoute","useRouteNode","useRouteUtils","useRouter","useRouterTransition"],"entryPoint":"src/index.ts","inputs":{"src/components/modern/RouteView/RouteView.tsx":{"bytesInOutput":712},"src/components/modern/RouteView/components.tsx":{"bytesInOutput":171},"src/components/modern/RouteView/helpers.tsx":{"bytesInOutput":2545},"src/hooks/useRouteNode.tsx":{"bytesInOutput":701},"src/hooks/useRouter.tsx":{"bytesInOutput":216},"src/context.ts":{"bytesInOutput":164},"src/components/modern/RouteView/index.ts":{"bytesInOutput":0},"src/index.ts":{"bytesInOutput":0},"src/components/Link.tsx":{"bytesInOutput":2287},"src/constants.ts":{"bytesInOutput":77},"src/hooks/useIsActiveRoute.tsx":{"bytesInOutput":697},"src/hooks/useStableValue.tsx":{"bytesInOutput":170},"src/hooks/useNavigator.tsx":{"bytesInOutput":250},"src/hooks/useRouteUtils.tsx":{"bytesInOutput":229},"src/hooks/useRoute.tsx":{"bytesInOutput":246},"src/hooks/useRouterTransition.tsx":{"bytesInOutput":397},"src/RouterProvider.tsx":{"bytesInOutput":1296}},"bytes":10975},"dist/cjs/legacy.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":16108},"dist/cjs/legacy.js":{"imports":[{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"exports":["Link","RouterProvider","useNavigator","useRoute","useRouteNode","useRouteUtils","useRouter","useRouterTransition"],"entryPoint":"src/legacy.ts","inputs":{"src/components/Link.tsx":{"bytesInOutput":2278},"src/constants.ts":{"bytesInOutput":77},"src/hooks/useIsActiveRoute.tsx":{"bytesInOutput":671},"src/hooks/useRouter.tsx":{"bytesInOutput":216},"src/context.ts":{"bytesInOutput":164},"src/hooks/useStableValue.tsx":{"bytesInOutput":157},"src/legacy.ts":{"bytesInOutput":0},"src/hooks/useRouteNode.tsx":{"bytesInOutput":742},"src/hooks/useRoute.tsx":{"bytesInOutput":246},"src/hooks/useNavigator.tsx":{"bytesInOutput":250},"src/hooks/useRouteUtils.tsx":{"bytesInOutput":229},"src/hooks/useRouterTransition.tsx":{"bytesInOutput":397},"src/RouterProvider.tsx":{"bytesInOutput":1296}},"bytes":7297}}}
1
+ {"inputs":{"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js":{"bytes":569,"imports":[],"format":"esm"},"src/components/modern/RouteView/components.tsx":{"bytes":286,"imports":[{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/components/modern/RouteView/helpers.tsx":{"bytes":3208,"imports":[{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/components/modern/RouteView/components.tsx","kind":"import-statement","original":"./components"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/context.ts":{"bytes":416,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRouter.tsx":{"bytes":378,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"../context"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRouteNode.tsx":{"bytes":837,"imports":[{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/components/modern/RouteView/RouteView.tsx":{"bytes":1073,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/components/modern/RouteView/components.tsx","kind":"import-statement","original":"./components"},{"path":"src/components/modern/RouteView/helpers.tsx","kind":"import-statement","original":"./helpers"},{"path":"src/hooks/useRouteNode.tsx","kind":"import-statement","original":"../../../hooks/useRouteNode"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/components/modern/RouteView/index.ts":{"bytes":145,"imports":[{"path":"src/components/modern/RouteView/RouteView.tsx","kind":"import-statement","original":"./RouteView"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/constants.ts":{"bytes":225,"imports":[{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useStableValue.tsx":{"bytes":976,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useIsActiveRoute.tsx":{"bytes":1060,"imports":[{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"},{"path":"src/hooks/useStableValue.tsx","kind":"import-statement","original":"./useStableValue"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/components/Link.tsx":{"bytes":2703,"imports":[{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/constants.ts","kind":"import-statement","original":"../constants"},{"path":"src/hooks/useIsActiveRoute.tsx","kind":"import-statement","original":"../hooks/useIsActiveRoute"},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"../hooks/useRouter"},{"path":"src/hooks/useStableValue.tsx","kind":"import-statement","original":"../hooks/useStableValue"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRouterError.tsx":{"bytes":755,"imports":[{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/components/RouterErrorBoundary.tsx":{"bytes":1437,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouterError.tsx","kind":"import-statement","original":"../hooks/useRouterError"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useNavigator.tsx":{"bytes":408,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"../context"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRouteUtils.tsx":{"bytes":981,"imports":[{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRoute.tsx":{"bytes":417,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"../context"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRouterTransition.tsx":{"bytes":508,"imports":[{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/RouterProvider.tsx":{"bytes":1710,"imports":[{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"./context"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":1005,"imports":[{"path":"src/components/modern/RouteView/index.ts","kind":"import-statement","original":"./components/modern/RouteView"},{"path":"src/components/Link.tsx","kind":"import-statement","original":"./components/Link"},{"path":"src/components/RouterErrorBoundary.tsx","kind":"import-statement","original":"./components/RouterErrorBoundary"},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./hooks/useRouter"},{"path":"src/hooks/useNavigator.tsx","kind":"import-statement","original":"./hooks/useNavigator"},{"path":"src/hooks/useRouteUtils.tsx","kind":"import-statement","original":"./hooks/useRouteUtils"},{"path":"src/hooks/useRoute.tsx","kind":"import-statement","original":"./hooks/useRoute"},{"path":"src/hooks/useRouteNode.tsx","kind":"import-statement","original":"./hooks/useRouteNode"},{"path":"src/hooks/useRouterTransition.tsx","kind":"import-statement","original":"./hooks/useRouterTransition"},{"path":"src/RouterProvider.tsx","kind":"import-statement","original":"./RouterProvider"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/legacy.ts":{"bytes":823,"imports":[{"path":"src/components/Link.tsx","kind":"import-statement","original":"./components/Link"},{"path":"src/components/RouterErrorBoundary.tsx","kind":"import-statement","original":"./components/RouterErrorBoundary"},{"path":"src/hooks/useRouteNode.tsx","kind":"import-statement","original":"./hooks/useRouteNode"},{"path":"src/hooks/useRoute.tsx","kind":"import-statement","original":"./hooks/useRoute"},{"path":"src/hooks/useNavigator.tsx","kind":"import-statement","original":"./hooks/useNavigator"},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./hooks/useRouter"},{"path":"src/hooks/useRouteUtils.tsx","kind":"import-statement","original":"./hooks/useRouteUtils"},{"path":"src/hooks/useRouterTransition.tsx","kind":"import-statement","original":"./hooks/useRouterTransition"},{"path":"src/RouterProvider.tsx","kind":"import-statement","original":"./RouterProvider"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/cjs/index.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":26731},"dist/cjs/index.js":{"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"exports":["Link","RouteView","RouterErrorBoundary","RouterProvider","useNavigator","useRoute","useRouteNode","useRouteUtils","useRouter","useRouterTransition"],"entryPoint":"src/index.ts","inputs":{"src/components/modern/RouteView/RouteView.tsx":{"bytesInOutput":712},"src/components/modern/RouteView/components.tsx":{"bytesInOutput":171},"src/components/modern/RouteView/helpers.tsx":{"bytesInOutput":2545},"src/hooks/useRouteNode.tsx":{"bytesInOutput":701},"src/hooks/useRouter.tsx":{"bytesInOutput":216},"src/context.ts":{"bytesInOutput":164},"src/components/modern/RouteView/index.ts":{"bytesInOutput":0},"src/index.ts":{"bytesInOutput":0},"src/components/Link.tsx":{"bytesInOutput":2287},"src/constants.ts":{"bytesInOutput":77},"src/hooks/useIsActiveRoute.tsx":{"bytesInOutput":697},"src/hooks/useStableValue.tsx":{"bytesInOutput":170},"src/components/RouterErrorBoundary.tsx":{"bytesInOutput":927},"src/hooks/useRouterError.tsx":{"bytesInOutput":560},"src/hooks/useNavigator.tsx":{"bytesInOutput":250},"src/hooks/useRouteUtils.tsx":{"bytesInOutput":229},"src/hooks/useRoute.tsx":{"bytesInOutput":246},"src/hooks/useRouterTransition.tsx":{"bytesInOutput":397},"src/RouterProvider.tsx":{"bytesInOutput":1311}},"bytes":12619},"dist/cjs/legacy.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":19572},"dist/cjs/legacy.js":{"imports":[{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"exports":["Link","RouterErrorBoundary","RouterProvider","useNavigator","useRoute","useRouteNode","useRouteUtils","useRouter","useRouterTransition"],"entryPoint":"src/legacy.ts","inputs":{"src/components/Link.tsx":{"bytesInOutput":2278},"src/constants.ts":{"bytesInOutput":77},"src/hooks/useIsActiveRoute.tsx":{"bytesInOutput":671},"src/hooks/useRouter.tsx":{"bytesInOutput":216},"src/context.ts":{"bytesInOutput":164},"src/hooks/useStableValue.tsx":{"bytesInOutput":157},"src/legacy.ts":{"bytesInOutput":0},"src/components/RouterErrorBoundary.tsx":{"bytesInOutput":901},"src/hooks/useRouterError.tsx":{"bytesInOutput":560},"src/hooks/useRouteNode.tsx":{"bytesInOutput":742},"src/hooks/useRoute.tsx":{"bytesInOutput":246},"src/hooks/useNavigator.tsx":{"bytesInOutput":250},"src/hooks/useRouteUtils.tsx":{"bytesInOutput":229},"src/hooks/useRouterTransition.tsx":{"bytesInOutput":397},"src/RouterProvider.tsx":{"bytesInOutput":1311}},"bytes":8915}}}
@@ -0,0 +1 @@
1
+ import{createContext as r,memo as e,useMemo as t,useCallback as o,useContext as n,useSyncExternalStore as i,useState as a,useRef as u,useEffect as s}from"react";import{getNavigator as c}from"@real-router/core";import{createActiveRouteSource as l,createRouteNodeSource as m,createTransitionSource as v,createRouteSource as f,createErrorSource as g}from"@real-router/sources";import{buildHref as p,shouldNavigate as h,buildActiveClassName as d,createRouteAnnouncer as N}from"dom-utils";import{jsx as S,jsxs as b,Fragment as y}from"react/jsx-runtime";import{getPluginApi as P}from"@real-router/core/api";import{getRouteUtils as R}from"@real-router/route-utils";var w=r(null),O=r(null),k=r(null),C=()=>{const r=n(O);if(!r)throw new Error("useRouter must be used within a RouterProvider");return r};function E(r){const e=C(),o=t(()=>m(e,r),[e,r]),{route:n,previousRoute:a}=i(o.subscribe,o.getSnapshot,o.getSnapshot),u=t(()=>c(e),[e]);return t(()=>({navigator:u,route:n,previousRoute:a}),[u,n,a])}var J=Object.freeze({}),Q=Object.freeze({});function j(r){const e=JSON.stringify(r);return t(()=>r,[e])}var x=e(({routeName:r,routeParams:e=J,routeOptions:n=Q,className:a,activeClassName:u="active",activeStrict:s=!1,ignoreQueryParams:c=!0,onClick:m,target:v,children:f,...g})=>{const N=C(),b=j(e),y=j(n),P=function(r,e,o=!1,n=!0){const a=C(),u=j(e),s=t(()=>l(a,r,u,{strict:o,ignoreQueryParams:n}),[a,r,u,o,n]);return i(s.subscribe,s.getSnapshot,s.getSnapshot)}(r,b,s,c),R=t(()=>p(N,r,b),[N,r,b]),w=o(e=>{m&&(m(e),e.defaultPrevented)||h(e.nativeEvent)&&"_blank"!==v&&(e.preventDefault(),N.navigate(r,b,y).catch(()=>{}))},[m,v,N,r,b,y]),O=t(()=>d(P,u,a),[P,u,a]);return S("a",{...g,href:R,className:O,onClick:w,children:f})},function(r,e){return r.routeName===e.routeName&&r.className===e.className&&r.activeClassName===e.activeClassName&&r.activeStrict===e.activeStrict&&r.ignoreQueryParams===e.ignoreQueryParams&&r.onClick===e.onClick&&r.target===e.target&&r.style===e.style&&r.children===e.children&&JSON.stringify(r.routeParams)===JSON.stringify(e.routeParams)&&JSON.stringify(r.routeOptions)===JSON.stringify(e.routeOptions)});x.displayName="Link";var z=new WeakMap;function D({children:r,fallback:e,onError:n}){const c=function(){const r=C(),e=t(()=>{let e=z.get(r);return e||(e=g(r),z.set(r,e)),e},[r]);return i(e.subscribe,e.getSnapshot,e.getSnapshot)}(),[l,m]=a(-1),v=u(n);v.current=n,s(()=>{c.error&&v.current?.(c.error,c.toRoute,c.fromRoute)},[c.version]);const f=c.version>l?c.error:null,p=o(()=>{m(c.version)},[c.version]);return b(y,{children:[r,f?e(f,p):null]})}var L=()=>{const r=n(k);if(!r)throw new Error("useNavigator must be used within a RouterProvider");return r},M=()=>{const r=C();return R(P(r).getTree())},T=()=>{const r=n(w);if(!r)throw new Error("useRoute must be used within a RouteProvider");return r};function W(){const r=C(),e=t(()=>v(r),[r]);return i(e.subscribe,e.getSnapshot,e.getSnapshot)}var _=({router:r,children:e,announceNavigation:o})=>{s(()=>{if(!o)return;const e=N(r);return()=>{e.destroy()}},[o,r]);const n=t(()=>c(r),[r]),a=t(()=>f(r),[r]),{route:u,previousRoute:l}=i(a.subscribe,a.getSnapshot,a.getSnapshot),m=t(()=>({navigator:n,route:u,previousRoute:l}),[n,u,l]);return S(O,{value:r,children:S(k,{value:n,children:S(w,{value:m,children:e})})})};export{x as Link,D as RouterErrorBoundary,_ as RouterProvider,L as useNavigator,T as useRoute,E as useRouteNode,M as useRouteUtils,C as useRouter,W as useRouterTransition};//# sourceMappingURL=chunk-IDJALABF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/context.ts","../../src/hooks/useRouter.tsx","../../src/hooks/useRouteNode.tsx","../../src/constants.ts","../../src/hooks/useStableValue.tsx","../../src/hooks/useIsActiveRoute.tsx","../../src/components/Link.tsx","../../src/hooks/useRouterError.tsx","../../src/components/RouterErrorBoundary.tsx","../../src/hooks/useNavigator.tsx","../../src/hooks/useRouteUtils.tsx","../../src/hooks/useRoute.tsx","../../src/hooks/useRouterTransition.tsx","../../src/RouterProvider.tsx"],"names":["useMemo","useSyncExternalStore","useCallback","useContext","useEffect","getNavigator","jsx"],"mappings":"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","file":"chunk-IDJALABF.mjs","sourcesContent":["// packages/react/modules/context.ts\n\nimport { createContext } from \"react\";\n\nimport type { RouteContext as RouteContextType } from \"./types\";\nimport type { Router, Navigator } from \"@real-router/core\";\n\nexport const RouteContext = createContext<RouteContextType | null>(null);\n\nexport const RouterContext = createContext<Router | null>(null);\n\nexport const NavigatorContext = createContext<Navigator | null>(null);\n","// packages/react/modules/hooks/useRouter.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouterContext } from \"../context\";\n\nimport type { Router } from \"@real-router/core\";\n\nexport const useRouter = (): Router => {\n const router = useContext(RouterContext);\n\n if (!router) {\n throw new Error(\"useRouter must be used within a RouterProvider\");\n }\n\n return router;\n};\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteContext } from \"../types\";\n\nexport function useRouteNode(nodeName: string): RouteContext {\n const router = useRouter();\n\n const store = useMemo(\n () => createRouteNodeSource(router, nodeName),\n [router, nodeName],\n );\n\n const { route, previousRoute } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n return useMemo(\n (): RouteContext => ({ navigator, route, previousRoute }),\n [navigator, route, previousRoute],\n );\n}\n","// packages/react/modules/constants.ts\n\n/**\n * Stable empty object for default params\n */\nexport const EMPTY_PARAMS = Object.freeze({});\n\n/**\n * Stable empty options object\n */\nexport const EMPTY_OPTIONS = Object.freeze({});\n","// packages/react/modules/hooks/useStableValue.tsx\n\nimport { useMemo } from \"react\";\n\n/**\n * Stabilizes a value reference based on deep equality (via JSON serialization).\n * Returns the same reference until the serialized value changes.\n *\n * Useful for object/array dependencies in hooks like useMemo, useCallback, useEffect\n * to prevent unnecessary re-renders when the value is structurally the same.\n *\n * @example\n * ```tsx\n * const stableParams = useStableValue(routeParams);\n * const href = useMemo(() => {\n * return router.buildUrl(routeName, stableParams);\n * }, [router, routeName, stableParams]);\n * ```\n *\n * @param value - The value to stabilize\n * @returns A stable reference to the value\n */\nexport function useStableValue<T>(value: T): T {\n const serialized = JSON.stringify(value);\n\n // We intentionally use serialized in deps to detect deep changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => value, [serialized]);\n}\n","import { createActiveRouteSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\nimport { useStableValue } from \"./useStableValue\";\n\nimport type { Params } from \"@real-router/core\";\n\nexport function useIsActiveRoute(\n routeName: string,\n params?: Params,\n strict = false,\n ignoreQueryParams = true,\n): boolean {\n const router = useRouter();\n\n // useStableValue: JSON.stringify memoization of params object.\n // Without it, every render with a new params reference (e.g.,\n // <Link routeParams={{ id: '123' }} />) would recreate the store.\n const stableParams = useStableValue(params);\n\n const store = useMemo(\n () =>\n createActiveRouteSource(router, routeName, stableParams, {\n strict,\n ignoreQueryParams,\n }),\n [router, routeName, stableParams, strict, ignoreQueryParams],\n );\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n}\n","import { shouldNavigate, buildHref, buildActiveClassName } from \"dom-utils\";\nimport { memo, useCallback, useMemo } from \"react\";\n\nimport { EMPTY_PARAMS, EMPTY_OPTIONS } from \"../constants\";\nimport { useIsActiveRoute } from \"../hooks/useIsActiveRoute\";\nimport { useRouter } from \"../hooks/useRouter\";\nimport { useStableValue } from \"../hooks/useStableValue\";\n\nimport type { LinkProps } from \"../types\";\nimport type { FC, MouseEvent } from \"react\";\n\nfunction areLinkPropsEqual(\n prev: Readonly<LinkProps>,\n next: Readonly<LinkProps>,\n): boolean {\n return (\n prev.routeName === next.routeName &&\n prev.className === next.className &&\n prev.activeClassName === next.activeClassName &&\n prev.activeStrict === next.activeStrict &&\n prev.ignoreQueryParams === next.ignoreQueryParams &&\n prev.onClick === next.onClick &&\n prev.target === next.target &&\n prev.style === next.style &&\n prev.children === next.children &&\n JSON.stringify(prev.routeParams) === JSON.stringify(next.routeParams) &&\n JSON.stringify(prev.routeOptions) === JSON.stringify(next.routeOptions)\n );\n}\n\nexport const Link: FC<LinkProps> = memo(\n ({\n routeName,\n routeParams = EMPTY_PARAMS,\n routeOptions = EMPTY_OPTIONS,\n className,\n activeClassName = \"active\",\n activeStrict = false,\n ignoreQueryParams = true,\n onClick,\n target,\n children,\n ...props\n }) => {\n const router = useRouter();\n\n const stableParams = useStableValue(routeParams);\n const stableOptions = useStableValue(routeOptions);\n\n const isActive = useIsActiveRoute(\n routeName,\n stableParams,\n activeStrict,\n ignoreQueryParams,\n );\n\n const href = useMemo(\n () => buildHref(router, routeName, stableParams),\n [router, routeName, stableParams],\n );\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLAnchorElement>) => {\n if (onClick) {\n onClick(evt);\n\n if (evt.defaultPrevented) {\n return;\n }\n }\n\n if (!shouldNavigate(evt.nativeEvent) || target === \"_blank\") {\n return;\n }\n\n evt.preventDefault();\n router.navigate(routeName, stableParams, stableOptions).catch(() => {});\n },\n [onClick, target, router, routeName, stableParams, stableOptions],\n );\n\n const finalClassName = useMemo(\n () => buildActiveClassName(isActive, activeClassName, className),\n [isActive, activeClassName, className],\n );\n\n return (\n <a\n {...props}\n href={href}\n className={finalClassName}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n },\n areLinkPropsEqual,\n);\n\nLink.displayName = \"Link\";\n","import { createErrorSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { Router } from \"@real-router/core\";\nimport type { RouterErrorSnapshot, RouterSource } from \"@real-router/sources\";\n\nconst cache = new WeakMap<Router, RouterSource<RouterErrorSnapshot>>();\n\nexport function useRouterError(): RouterErrorSnapshot {\n const router = useRouter();\n const store = useMemo(() => {\n let source = cache.get(router);\n\n if (!source) {\n source = createErrorSource(router);\n cache.set(router, source);\n }\n\n return source;\n }, [router]);\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useRouterError } from \"../hooks/useRouterError\";\n\nimport type { RouterError, State } from \"@real-router/core\";\nimport type { ReactNode, JSX } from \"react\";\n\nexport interface RouterErrorBoundaryProps {\n readonly children: ReactNode;\n readonly fallback: (error: RouterError, resetError: () => void) => ReactNode;\n readonly onError?: (\n error: RouterError,\n toRoute: State | null,\n fromRoute: State | null,\n ) => void;\n}\n\nexport function RouterErrorBoundary({\n children,\n fallback,\n onError,\n}: RouterErrorBoundaryProps): JSX.Element {\n const snapshot = useRouterError();\n const [dismissedVersion, setDismissedVersion] = useState(-1);\n\n const onErrorRef = useRef(onError);\n\n onErrorRef.current = onError;\n\n useEffect(() => {\n if (snapshot.error) {\n onErrorRef.current?.(\n snapshot.error,\n snapshot.toRoute,\n snapshot.fromRoute,\n );\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- onError tracked via ref, snapshot fields accessed inside callback\n }, [snapshot.version]);\n\n const visibleError =\n snapshot.version > dismissedVersion ? snapshot.error : null;\n\n const resetError = useCallback(() => {\n setDismissedVersion(snapshot.version);\n }, [snapshot.version]);\n\n return (\n <>\n {children}\n {visibleError ? fallback(visibleError, resetError) : null}\n </>\n );\n}\n","// packages/react/modules/hooks/useNavigator.tsx\n\nimport { useContext } from \"react\";\n\nimport { NavigatorContext } from \"../context\";\n\nimport type { Navigator } from \"@real-router/core\";\n\nexport const useNavigator = (): Navigator => {\n const navigator = useContext(NavigatorContext);\n\n if (!navigator) {\n throw new Error(\"useNavigator must be used within a RouterProvider\");\n }\n\n return navigator;\n};\n","// packages/react/modules/hooks/useRouteUtils.tsx\n\nimport { getPluginApi } from \"@real-router/core/api\";\nimport { getRouteUtils } from \"@real-router/route-utils\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteUtils } from \"@real-router/route-utils\";\n\n/**\n * Returns a pre-computed {@link RouteUtils} instance for the current router.\n *\n * Internally retrieves the route tree via `getPluginApi` and delegates\n * to `getRouteUtils`, which caches instances per tree reference (WeakMap).\n *\n * @returns RouteUtils instance with pre-computed chains and siblings\n *\n * @example\n * ```tsx\n * const utils = useRouteUtils();\n *\n * utils.getChain(\"users.profile\");\n * // → [\"users\", \"users.profile\"]\n *\n * utils.getSiblings(\"users\");\n * // → [\"admin\"]\n *\n * utils.isDescendantOf(\"users.profile\", \"users\");\n * // → true\n * ```\n */\nexport const useRouteUtils = (): RouteUtils => {\n const router = useRouter();\n\n return getRouteUtils(getPluginApi(router).getTree());\n};\n","// packages/react/modules/hooks/useRoute.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouteContext } from \"../context\";\n\nimport type { RouteContext as RouteContextType } from \"../types\";\n\nexport const useRoute = (): RouteContextType => {\n const routeContext = useContext(RouteContext);\n\n if (!routeContext) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n\n return routeContext;\n};\n","import { createTransitionSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouterTransitionSnapshot } from \"@real-router/sources\";\n\nexport function useRouterTransition(): RouterTransitionSnapshot {\n const router = useRouter();\n\n const store = useMemo(() => createTransitionSource(router), [router]);\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteSource } from \"@real-router/sources\";\nimport { createRouteAnnouncer } from \"dom-utils\";\nimport { useEffect, useMemo, useSyncExternalStore } from \"react\";\n\nimport { NavigatorContext, RouteContext, RouterContext } from \"./context\";\n\nimport type { Router } from \"@real-router/core\";\nimport type { FC, ReactNode } from \"react\";\n\nexport interface RouteProviderProps {\n router: Router;\n children: ReactNode;\n announceNavigation?: boolean;\n}\n\nexport const RouterProvider: FC<RouteProviderProps> = ({\n router,\n children,\n announceNavigation,\n}) => {\n useEffect(() => {\n if (!announceNavigation) {\n return;\n }\n\n const announcer = createRouteAnnouncer(router);\n\n return () => {\n announcer.destroy();\n };\n }, [announceNavigation, router]);\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n // useSyncExternalStore manages the router subscription lifecycle:\n // subscribe connects to router on first listener, unsubscribes on last.\n // This is Strict Mode safe — no useEffect cleanup needed.\n const store = useMemo(() => createRouteSource(router), [router]);\n const { route, previousRoute } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const routeContextValue = useMemo(\n () => ({ navigator, route, previousRoute }),\n [navigator, route, previousRoute],\n );\n\n return (\n <RouterContext value={router}>\n <NavigatorContext value={navigator}>\n <RouteContext value={routeContextValue}>{children}</RouteContext>\n </NavigatorContext>\n </RouterContext>\n );\n};\n"]}
@@ -1,5 +1,5 @@
1
1
  import { ReactNode, ReactElement } from 'react';
2
- export { Link, LinkProps, RouterProvider, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition } from './legacy.mjs';
2
+ export { Link, LinkProps, RouterErrorBoundary, RouterErrorBoundaryProps, RouterProvider, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition } from './legacy.mjs';
3
3
  export { Navigator } from '@real-router/core';
4
4
  export { RouterTransitionSnapshot } from '@real-router/sources';
5
5
  import '@real-router/route-utils';
@@ -1 +1 @@
1
- import{useRouteNode as e}from"./chunk-SQL27477.mjs";export{Link,RouterProvider,useNavigator,useRoute,useRouteNode,useRouteUtils,useRouter,useRouterTransition}from"./chunk-SQL27477.mjs";import{useRef as r,Children as t,isValidElement as n,Fragment as o,Activity as u,Suspense as i}from"react";import{UNKNOWN_ROUTE as c}from"@real-router/core";import{startsWithSegment as s}from"@real-router/route-utils";import{jsx as l,Fragment as a}from"react/jsx-runtime";function d(e){return null}function p(e){return null}function f(e,r,t){return t?e===r:s(e,r)}function h(e,r){for(const o of t.toArray(e))n(o)&&(o.type===d||o.type===p?r.push(o):h(o.props.children,r))}function m(e,r,t,n,c){const s=void 0===c?e:l(i,{fallback:c,children:e});return t?l(u,{mode:n,children:s},r):l(o,{children:s},r)}function R({nodeName:t,children:n}){const{route:u}=e(t),i=r(new Set);if(!u)return null;const s=[];h(n,s);const{rendered:d}=function(e,r,t,n){let u=null,i=!1;const s=[];for(const o of e){if(o.type===p){u=o.props.children;continue}const{segment:e,exact:c=!1,keepAlive:l=!1,fallback:a}=o.props,d=t?`${t}.${e}`:e;!i&&f(r,d,c)?(i=!0,n.add(d),s.push(m(o.props.children,d,l,"visible",a))):l&&n.has(d)&&s.push(m(o.props.children,d,l,"hidden",a))}return i||r!==c||null===u||s.push(l(o,{children:u},"__route-view-not-found__")),{rendered:s,activeMatchFound:i}}(s,u.name,t,i.current);return d.length>0?l(a,{children:d}):null}d.displayName="RouteView.Match",p.displayName="RouteView.NotFound",R.displayName="RouteView";var v=Object.assign(R,{Match:d,NotFound:p});export{v as RouteView};//# sourceMappingURL=index.mjs.map
1
+ import{useRouteNode as e}from"./chunk-IDJALABF.mjs";export{Link,RouterErrorBoundary,RouterProvider,useNavigator,useRoute,useRouteNode,useRouteUtils,useRouter,useRouterTransition}from"./chunk-IDJALABF.mjs";import{useRef as r,Children as o,isValidElement as t,Fragment as n,Activity as u,Suspense as i}from"react";import{UNKNOWN_ROUTE as c}from"@real-router/core";import{startsWithSegment as s}from"@real-router/route-utils";import{jsx as l,Fragment as a}from"react/jsx-runtime";function d(e){return null}function p(e){return null}function f(e,r,o){return o?e===r:s(e,r)}function h(e,r){for(const n of o.toArray(e))t(n)&&(n.type===d||n.type===p?r.push(n):h(n.props.children,r))}function m(e,r,o,t,c){const s=void 0===c?e:l(i,{fallback:c,children:e});return o?l(u,{mode:t,children:s},r):l(n,{children:s},r)}function R({nodeName:o,children:t}){const{route:u}=e(o),i=r(new Set);if(!u)return null;const s=[];h(t,s);const{rendered:d}=function(e,r,o,t){let u=null,i=!1;const s=[];for(const n of e){if(n.type===p){u=n.props.children;continue}const{segment:e,exact:c=!1,keepAlive:l=!1,fallback:a}=n.props,d=o?`${o}.${e}`:e;!i&&f(r,d,c)?(i=!0,t.add(d),s.push(m(n.props.children,d,l,"visible",a))):l&&t.has(d)&&s.push(m(n.props.children,d,l,"hidden",a))}return i||r!==c||null===u||s.push(l(n,{children:u},"__route-view-not-found__")),{rendered:s,activeMatchFound:i}}(s,u.name,o,i.current);return d.length>0?l(a,{children:d}):null}d.displayName="RouteView.Match",p.displayName="RouteView.NotFound",R.displayName="RouteView";var v=Object.assign(R,{Match:d,NotFound:p});export{v as RouteView};//# sourceMappingURL=index.mjs.map
@@ -1,6 +1,6 @@
1
- import { Params, NavigationOptions, Navigator, State, Router } from '@real-router/core';
1
+ import { Params, NavigationOptions, Navigator, State, RouterError, Router } from '@real-router/core';
2
2
  export { Navigator } from '@real-router/core';
3
- import { HTMLAttributes, MouseEventHandler, FC, ReactNode } from 'react';
3
+ import { HTMLAttributes, MouseEventHandler, FC, ReactNode, JSX } from 'react';
4
4
  import { RouteUtils } from '@real-router/route-utils';
5
5
  import { RouterTransitionSnapshot } from '@real-router/sources';
6
6
  export { RouterTransitionSnapshot } from '@real-router/sources';
@@ -26,6 +26,13 @@ interface LinkProps<P extends Params = Params> extends HTMLAttributes<HTMLAnchor
26
26
 
27
27
  declare const Link: FC<LinkProps>;
28
28
 
29
+ interface RouterErrorBoundaryProps {
30
+ readonly children: ReactNode;
31
+ readonly fallback: (error: RouterError, resetError: () => void) => ReactNode;
32
+ readonly onError?: (error: RouterError, toRoute: State | null, fromRoute: State | null) => void;
33
+ }
34
+ declare function RouterErrorBoundary({ children, fallback, onError, }: RouterErrorBoundaryProps): JSX.Element;
35
+
29
36
  declare const useRouter: () => Router;
30
37
 
31
38
  declare const useNavigator: () => Navigator;
@@ -67,4 +74,4 @@ interface RouteProviderProps {
67
74
  }
68
75
  declare const RouterProvider: FC<RouteProviderProps>;
69
76
 
70
- export { Link, type LinkProps, RouterProvider, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition };
77
+ export { Link, type LinkProps, RouterErrorBoundary, type RouterErrorBoundaryProps, RouterProvider, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition };
@@ -1 +1 @@
1
- export{Link,RouterProvider,useNavigator,useRoute,useRouteNode,useRouteUtils,useRouter,useRouterTransition}from"./chunk-SQL27477.mjs";//# sourceMappingURL=legacy.mjs.map
1
+ export{Link,RouterErrorBoundary,RouterProvider,useNavigator,useRoute,useRouteNode,useRouteUtils,useRouter,useRouterTransition}from"./chunk-IDJALABF.mjs";//# sourceMappingURL=legacy.mjs.map
@@ -1 +1 @@
1
- {"inputs":{"src/components/modern/RouteView/components.tsx":{"bytes":286,"imports":[],"format":"esm"},"src/components/modern/RouteView/helpers.tsx":{"bytes":3208,"imports":[{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/components/modern/RouteView/components.tsx","kind":"import-statement","original":"./components"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/context.ts":{"bytes":416,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRouter.tsx":{"bytes":378,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"../context"}],"format":"esm"},"src/hooks/useRouteNode.tsx":{"bytes":837,"imports":[{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"}],"format":"esm"},"src/components/modern/RouteView/RouteView.tsx":{"bytes":1073,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/components/modern/RouteView/components.tsx","kind":"import-statement","original":"./components"},{"path":"src/components/modern/RouteView/helpers.tsx","kind":"import-statement","original":"./helpers"},{"path":"src/hooks/useRouteNode.tsx","kind":"import-statement","original":"../../../hooks/useRouteNode"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/components/modern/RouteView/index.ts":{"bytes":145,"imports":[{"path":"src/components/modern/RouteView/RouteView.tsx","kind":"import-statement","original":"./RouteView"}],"format":"esm"},"src/constants.ts":{"bytes":225,"imports":[],"format":"esm"},"src/hooks/useStableValue.tsx":{"bytes":976,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useIsActiveRoute.tsx":{"bytes":1060,"imports":[{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"},{"path":"src/hooks/useStableValue.tsx","kind":"import-statement","original":"./useStableValue"}],"format":"esm"},"src/components/Link.tsx":{"bytes":2703,"imports":[{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/constants.ts","kind":"import-statement","original":"../constants"},{"path":"src/hooks/useIsActiveRoute.tsx","kind":"import-statement","original":"../hooks/useIsActiveRoute"},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"../hooks/useRouter"},{"path":"src/hooks/useStableValue.tsx","kind":"import-statement","original":"../hooks/useStableValue"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useNavigator.tsx":{"bytes":408,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"../context"}],"format":"esm"},"src/hooks/useRouteUtils.tsx":{"bytes":981,"imports":[{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"}],"format":"esm"},"src/hooks/useRoute.tsx":{"bytes":417,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"../context"}],"format":"esm"},"src/hooks/useRouterTransition.tsx":{"bytes":508,"imports":[{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"}],"format":"esm"},"src/RouterProvider.tsx":{"bytes":1710,"imports":[{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"./context"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":849,"imports":[{"path":"src/components/modern/RouteView/index.ts","kind":"import-statement","original":"./components/modern/RouteView"},{"path":"src/components/Link.tsx","kind":"import-statement","original":"./components/Link"},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./hooks/useRouter"},{"path":"src/hooks/useNavigator.tsx","kind":"import-statement","original":"./hooks/useNavigator"},{"path":"src/hooks/useRouteUtils.tsx","kind":"import-statement","original":"./hooks/useRouteUtils"},{"path":"src/hooks/useRoute.tsx","kind":"import-statement","original":"./hooks/useRoute"},{"path":"src/hooks/useRouteNode.tsx","kind":"import-statement","original":"./hooks/useRouteNode"},{"path":"src/hooks/useRouterTransition.tsx","kind":"import-statement","original":"./hooks/useRouterTransition"},{"path":"src/RouterProvider.tsx","kind":"import-statement","original":"./RouterProvider"}],"format":"esm"},"src/legacy.ts":{"bytes":667,"imports":[{"path":"src/components/Link.tsx","kind":"import-statement","original":"./components/Link"},{"path":"src/hooks/useRouteNode.tsx","kind":"import-statement","original":"./hooks/useRouteNode"},{"path":"src/hooks/useRoute.tsx","kind":"import-statement","original":"./hooks/useRoute"},{"path":"src/hooks/useNavigator.tsx","kind":"import-statement","original":"./hooks/useNavigator"},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./hooks/useRouter"},{"path":"src/hooks/useRouteUtils.tsx","kind":"import-statement","original":"./hooks/useRouteUtils"},{"path":"src/hooks/useRouterTransition.tsx","kind":"import-statement","original":"./hooks/useRouterTransition"},{"path":"src/RouterProvider.tsx","kind":"import-statement","original":"./RouterProvider"}],"format":"esm"}},"outputs":{"dist/esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":7176},"dist/esm/index.mjs":{"imports":[{"path":"dist/esm/chunk-SQL27477.mjs","kind":"import-statement"},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"exports":["Link","RouteView","RouterProvider","useNavigator","useRoute","useRouteNode","useRouteUtils","useRouter","useRouterTransition"],"entryPoint":"src/index.ts","inputs":{"src/components/modern/RouteView/RouteView.tsx":{"bytesInOutput":712},"src/components/modern/RouteView/components.tsx":{"bytesInOutput":171},"src/components/modern/RouteView/helpers.tsx":{"bytesInOutput":2545},"src/components/modern/RouteView/index.ts":{"bytesInOutput":0},"src/index.ts":{"bytesInOutput":0}},"bytes":3936},"dist/esm/legacy.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"dist/esm/legacy.mjs":{"imports":[{"path":"dist/esm/chunk-SQL27477.mjs","kind":"import-statement"}],"exports":["Link","RouterProvider","useNavigator","useRoute","useRouteNode","useRouteUtils","useRouter","useRouterTransition"],"entryPoint":"src/legacy.ts","inputs":{"src/legacy.ts":{"bytesInOutput":0}},"bytes":296},"dist/esm/chunk-SQL27477.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":16098},"dist/esm/chunk-SQL27477.mjs":{"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"exports":["Link","RouterProvider","useNavigator","useRoute","useRouteNode","useRouteUtils","useRouter","useRouterTransition"],"inputs":{"src/hooks/useRouter.tsx":{"bytesInOutput":216},"src/context.ts":{"bytesInOutput":164},"src/hooks/useRouteNode.tsx":{"bytesInOutput":701},"src/components/Link.tsx":{"bytesInOutput":2278},"src/constants.ts":{"bytesInOutput":77},"src/hooks/useIsActiveRoute.tsx":{"bytesInOutput":697},"src/hooks/useStableValue.tsx":{"bytesInOutput":170},"src/hooks/useNavigator.tsx":{"bytesInOutput":250},"src/hooks/useRouteUtils.tsx":{"bytesInOutput":229},"src/hooks/useRoute.tsx":{"bytesInOutput":246},"src/hooks/useRouterTransition.tsx":{"bytesInOutput":397},"src/RouterProvider.tsx":{"bytesInOutput":1296}},"bytes":7296}}}
1
+ {"inputs":{"src/components/modern/RouteView/components.tsx":{"bytes":286,"imports":[],"format":"esm"},"src/components/modern/RouteView/helpers.tsx":{"bytes":3208,"imports":[{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/components/modern/RouteView/components.tsx","kind":"import-statement","original":"./components"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/context.ts":{"bytes":416,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRouter.tsx":{"bytes":378,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"../context"}],"format":"esm"},"src/hooks/useRouteNode.tsx":{"bytes":837,"imports":[{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"}],"format":"esm"},"src/components/modern/RouteView/RouteView.tsx":{"bytes":1073,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/components/modern/RouteView/components.tsx","kind":"import-statement","original":"./components"},{"path":"src/components/modern/RouteView/helpers.tsx","kind":"import-statement","original":"./helpers"},{"path":"src/hooks/useRouteNode.tsx","kind":"import-statement","original":"../../../hooks/useRouteNode"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/components/modern/RouteView/index.ts":{"bytes":145,"imports":[{"path":"src/components/modern/RouteView/RouteView.tsx","kind":"import-statement","original":"./RouteView"}],"format":"esm"},"src/constants.ts":{"bytes":225,"imports":[],"format":"esm"},"src/hooks/useStableValue.tsx":{"bytes":976,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useIsActiveRoute.tsx":{"bytes":1060,"imports":[{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"},{"path":"src/hooks/useStableValue.tsx","kind":"import-statement","original":"./useStableValue"}],"format":"esm"},"src/components/Link.tsx":{"bytes":2703,"imports":[{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/constants.ts","kind":"import-statement","original":"../constants"},{"path":"src/hooks/useIsActiveRoute.tsx","kind":"import-statement","original":"../hooks/useIsActiveRoute"},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"../hooks/useRouter"},{"path":"src/hooks/useStableValue.tsx","kind":"import-statement","original":"../hooks/useStableValue"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useRouterError.tsx":{"bytes":755,"imports":[{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"}],"format":"esm"},"src/components/RouterErrorBoundary.tsx":{"bytes":1437,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouterError.tsx","kind":"import-statement","original":"../hooks/useRouterError"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/useNavigator.tsx":{"bytes":408,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"../context"}],"format":"esm"},"src/hooks/useRouteUtils.tsx":{"bytes":981,"imports":[{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"}],"format":"esm"},"src/hooks/useRoute.tsx":{"bytes":417,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"../context"}],"format":"esm"},"src/hooks/useRouterTransition.tsx":{"bytes":508,"imports":[{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./useRouter"}],"format":"esm"},"src/RouterProvider.tsx":{"bytes":1710,"imports":[{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/context.ts","kind":"import-statement","original":"./context"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":1005,"imports":[{"path":"src/components/modern/RouteView/index.ts","kind":"import-statement","original":"./components/modern/RouteView"},{"path":"src/components/Link.tsx","kind":"import-statement","original":"./components/Link"},{"path":"src/components/RouterErrorBoundary.tsx","kind":"import-statement","original":"./components/RouterErrorBoundary"},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./hooks/useRouter"},{"path":"src/hooks/useNavigator.tsx","kind":"import-statement","original":"./hooks/useNavigator"},{"path":"src/hooks/useRouteUtils.tsx","kind":"import-statement","original":"./hooks/useRouteUtils"},{"path":"src/hooks/useRoute.tsx","kind":"import-statement","original":"./hooks/useRoute"},{"path":"src/hooks/useRouteNode.tsx","kind":"import-statement","original":"./hooks/useRouteNode"},{"path":"src/hooks/useRouterTransition.tsx","kind":"import-statement","original":"./hooks/useRouterTransition"},{"path":"src/RouterProvider.tsx","kind":"import-statement","original":"./RouterProvider"}],"format":"esm"},"src/legacy.ts":{"bytes":823,"imports":[{"path":"src/components/Link.tsx","kind":"import-statement","original":"./components/Link"},{"path":"src/components/RouterErrorBoundary.tsx","kind":"import-statement","original":"./components/RouterErrorBoundary"},{"path":"src/hooks/useRouteNode.tsx","kind":"import-statement","original":"./hooks/useRouteNode"},{"path":"src/hooks/useRoute.tsx","kind":"import-statement","original":"./hooks/useRoute"},{"path":"src/hooks/useNavigator.tsx","kind":"import-statement","original":"./hooks/useNavigator"},{"path":"src/hooks/useRouter.tsx","kind":"import-statement","original":"./hooks/useRouter"},{"path":"src/hooks/useRouteUtils.tsx","kind":"import-statement","original":"./hooks/useRouteUtils"},{"path":"src/hooks/useRouterTransition.tsx","kind":"import-statement","original":"./hooks/useRouterTransition"},{"path":"src/RouterProvider.tsx","kind":"import-statement","original":"./RouterProvider"}],"format":"esm"}},"outputs":{"dist/esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":7177},"dist/esm/index.mjs":{"imports":[{"path":"dist/esm/chunk-IDJALABF.mjs","kind":"import-statement"},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"exports":["Link","RouteView","RouterErrorBoundary","RouterProvider","useNavigator","useRoute","useRouteNode","useRouteUtils","useRouter","useRouterTransition"],"entryPoint":"src/index.ts","inputs":{"src/components/modern/RouteView/RouteView.tsx":{"bytesInOutput":712},"src/components/modern/RouteView/components.tsx":{"bytesInOutput":171},"src/components/modern/RouteView/helpers.tsx":{"bytesInOutput":2545},"src/components/modern/RouteView/index.ts":{"bytesInOutput":0},"src/index.ts":{"bytesInOutput":0}},"bytes":3982},"dist/esm/legacy.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"dist/esm/legacy.mjs":{"imports":[{"path":"dist/esm/chunk-IDJALABF.mjs","kind":"import-statement"}],"exports":["Link","RouterErrorBoundary","RouterProvider","useNavigator","useRoute","useRouteNode","useRouteUtils","useRouter","useRouterTransition"],"entryPoint":"src/legacy.ts","inputs":{"src/legacy.ts":{"bytesInOutput":0}},"bytes":342},"dist/esm/chunk-IDJALABF.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":19562},"dist/esm/chunk-IDJALABF.mjs":{"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"@real-router/route-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"@real-router/sources","kind":"import-statement","external":true},{"path":"dom-utils","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"exports":["Link","RouterErrorBoundary","RouterProvider","useNavigator","useRoute","useRouteNode","useRouteUtils","useRouter","useRouterTransition"],"inputs":{"src/hooks/useRouter.tsx":{"bytesInOutput":216},"src/context.ts":{"bytesInOutput":164},"src/hooks/useRouteNode.tsx":{"bytesInOutput":701},"src/components/Link.tsx":{"bytesInOutput":2278},"src/constants.ts":{"bytesInOutput":77},"src/hooks/useIsActiveRoute.tsx":{"bytesInOutput":697},"src/hooks/useStableValue.tsx":{"bytesInOutput":170},"src/components/RouterErrorBoundary.tsx":{"bytesInOutput":901},"src/hooks/useRouterError.tsx":{"bytesInOutput":560},"src/hooks/useNavigator.tsx":{"bytesInOutput":250},"src/hooks/useRouteUtils.tsx":{"bytesInOutput":229},"src/hooks/useRoute.tsx":{"bytesInOutput":246},"src/hooks/useRouterTransition.tsx":{"bytesInOutput":397},"src/RouterProvider.tsx":{"bytesInOutput":1311}},"bytes":8914}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@real-router/react",
3
- "version": "0.13.1",
3
+ "version": "0.14.0",
4
4
  "type": "commonjs",
5
5
  "description": "React integration for Real-Router",
6
6
  "main": "./dist/cjs/index.js",
@@ -64,10 +64,10 @@
64
64
  "license": "MIT",
65
65
  "sideEffects": false,
66
66
  "dependencies": {
67
- "@real-router/core": "^0.39.0",
67
+ "@real-router/core": "^0.40.1",
68
68
  "@real-router/route-utils": "^0.1.6",
69
- "@real-router/sources": "^0.2.6",
70
- "dom-utils": "^0.2.1"
69
+ "@real-router/sources": "^0.3.0",
70
+ "dom-utils": "^0.2.2"
71
71
  },
72
72
  "devDependencies": {
73
73
  "@testing-library/dom": "10.4.1",
@@ -75,7 +75,7 @@
75
75
  "@testing-library/react": "16.3.2",
76
76
  "@testing-library/user-event": "14.6.1",
77
77
  "vitest-react-profiler": "1.12.0",
78
- "@real-router/browser-plugin": "^0.10.4"
78
+ "@real-router/browser-plugin": "^0.10.6"
79
79
  },
80
80
  "peerDependencies": {
81
81
  "@types/react": ">=18.0.0",
@@ -90,6 +90,7 @@
90
90
  "type-check": "tsc --noEmit",
91
91
  "lint": "eslint --cache --ext .ts,.tsx src/ tests/ --fix --max-warnings 0",
92
92
  "lint:package": "publint",
93
- "lint:types": "attw --pack ."
93
+ "lint:types": "attw --pack .",
94
+ "build:dist-only": "tsup"
94
95
  }
95
96
  }
@@ -0,0 +1,54 @@
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+
3
+ import { useRouterError } from "../hooks/useRouterError";
4
+
5
+ import type { RouterError, State } from "@real-router/core";
6
+ import type { ReactNode, JSX } from "react";
7
+
8
+ export interface RouterErrorBoundaryProps {
9
+ readonly children: ReactNode;
10
+ readonly fallback: (error: RouterError, resetError: () => void) => ReactNode;
11
+ readonly onError?: (
12
+ error: RouterError,
13
+ toRoute: State | null,
14
+ fromRoute: State | null,
15
+ ) => void;
16
+ }
17
+
18
+ export function RouterErrorBoundary({
19
+ children,
20
+ fallback,
21
+ onError,
22
+ }: RouterErrorBoundaryProps): JSX.Element {
23
+ const snapshot = useRouterError();
24
+ const [dismissedVersion, setDismissedVersion] = useState(-1);
25
+
26
+ const onErrorRef = useRef(onError);
27
+
28
+ onErrorRef.current = onError;
29
+
30
+ useEffect(() => {
31
+ if (snapshot.error) {
32
+ onErrorRef.current?.(
33
+ snapshot.error,
34
+ snapshot.toRoute,
35
+ snapshot.fromRoute,
36
+ );
37
+ }
38
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- onError tracked via ref, snapshot fields accessed inside callback
39
+ }, [snapshot.version]);
40
+
41
+ const visibleError =
42
+ snapshot.version > dismissedVersion ? snapshot.error : null;
43
+
44
+ const resetError = useCallback(() => {
45
+ setDismissedVersion(snapshot.version);
46
+ }, [snapshot.version]);
47
+
48
+ return (
49
+ <>
50
+ {children}
51
+ {visibleError ? fallback(visibleError, resetError) : null}
52
+ </>
53
+ );
54
+ }
@@ -0,0 +1,29 @@
1
+ import { createErrorSource } from "@real-router/sources";
2
+ import { useMemo, useSyncExternalStore } from "react";
3
+
4
+ import { useRouter } from "./useRouter";
5
+
6
+ import type { Router } from "@real-router/core";
7
+ import type { RouterErrorSnapshot, RouterSource } from "@real-router/sources";
8
+
9
+ const cache = new WeakMap<Router, RouterSource<RouterErrorSnapshot>>();
10
+
11
+ export function useRouterError(): RouterErrorSnapshot {
12
+ const router = useRouter();
13
+ const store = useMemo(() => {
14
+ let source = cache.get(router);
15
+
16
+ if (!source) {
17
+ source = createErrorSource(router);
18
+ cache.set(router, source);
19
+ }
20
+
21
+ return source;
22
+ }, [router]);
23
+
24
+ return useSyncExternalStore(
25
+ store.subscribe,
26
+ store.getSnapshot,
27
+ store.getSnapshot,
28
+ );
29
+ }
package/src/index.ts CHANGED
@@ -5,6 +5,8 @@ export { RouteView } from "./components/modern/RouteView";
5
5
 
6
6
  export { Link } from "./components/Link";
7
7
 
8
+ export { RouterErrorBoundary } from "./components/RouterErrorBoundary";
9
+
8
10
  // Hooks
9
11
  export { useRouter } from "./hooks/useRouter";
10
12
 
@@ -30,6 +32,8 @@ export type {
30
32
  RouteViewNotFoundProps,
31
33
  } from "./components/modern/RouteView";
32
34
 
35
+ export type { RouterErrorBoundaryProps } from "./components/RouterErrorBoundary";
36
+
33
37
  export type { Navigator } from "@real-router/core";
34
38
 
35
39
  export type { RouterTransitionSnapshot } from "@real-router/sources";
package/src/legacy.ts CHANGED
@@ -3,6 +3,8 @@
3
3
  // Components
4
4
  export { Link } from "./components/Link";
5
5
 
6
+ export { RouterErrorBoundary } from "./components/RouterErrorBoundary";
7
+
6
8
  // Hooks
7
9
  export { useRouteNode } from "./hooks/useRouteNode";
8
10
 
@@ -22,6 +24,8 @@ export { RouterProvider } from "./RouterProvider";
22
24
  // Types
23
25
  export type { LinkProps } from "./types";
24
26
 
27
+ export type { RouterErrorBoundaryProps } from "./components/RouterErrorBoundary";
28
+
25
29
  export type { Navigator } from "@real-router/core";
26
30
 
27
31
  export type { RouterTransitionSnapshot } from "@real-router/sources";
@@ -1 +0,0 @@
1
- import{createContext as r,memo as e,useMemo as t,useCallback as o,useContext as n,useSyncExternalStore as a,useEffect as i}from"react";import{getNavigator as u}from"@real-router/core";import{createActiveRouteSource as s,createRouteNodeSource as c,createTransitionSource as l,createRouteSource as m}from"@real-router/sources";import{buildHref as v,shouldNavigate as f,buildActiveClassName as g,createRouteAnnouncer as p}from"dom-utils";import{jsx as h}from"react/jsx-runtime";import{getPluginApi as d}from"@real-router/core/api";import{getRouteUtils as N}from"@real-router/route-utils";var S=r(null),b=r(null),y=r(null),P=()=>{const r=n(b);if(!r)throw new Error("useRouter must be used within a RouterProvider");return r};function O(r){const e=P(),o=t(()=>c(e,r),[e,r]),{route:n,previousRoute:i}=a(o.subscribe,o.getSnapshot,o.getSnapshot),s=t(()=>u(e),[e]);return t(()=>({navigator:s,route:n,previousRoute:i}),[s,n,i])}var w=Object.freeze({}),R=Object.freeze({});function C(r){const e=JSON.stringify(r);return t(()=>r,[e])}var k=e(({routeName:r,routeParams:e=w,routeOptions:n=R,className:i,activeClassName:u="active",activeStrict:c=!1,ignoreQueryParams:l=!0,onClick:m,target:p,children:d,...N})=>{const S=P(),b=C(e),y=C(n),O=function(r,e,o=!1,n=!0){const i=P(),u=C(e),c=t(()=>s(i,r,u,{strict:o,ignoreQueryParams:n}),[i,r,u,o,n]);return a(c.subscribe,c.getSnapshot,c.getSnapshot)}(r,b,c,l),k=t(()=>v(S,r,b),[S,r,b]),J=o(e=>{m&&(m(e),e.defaultPrevented)||f(e.nativeEvent)&&"_blank"!==p&&(e.preventDefault(),S.navigate(r,b,y).catch(()=>{}))},[m,p,S,r,b,y]),E=t(()=>g(O,u,i),[O,u,i]);return h("a",{...N,href:k,className:E,onClick:J,children:d})},function(r,e){return r.routeName===e.routeName&&r.className===e.className&&r.activeClassName===e.activeClassName&&r.activeStrict===e.activeStrict&&r.ignoreQueryParams===e.ignoreQueryParams&&r.onClick===e.onClick&&r.target===e.target&&r.style===e.style&&r.children===e.children&&JSON.stringify(r.routeParams)===JSON.stringify(e.routeParams)&&JSON.stringify(r.routeOptions)===JSON.stringify(e.routeOptions)});k.displayName="Link";var J=()=>{const r=n(y);if(!r)throw new Error("useNavigator must be used within a RouterProvider");return r},E=()=>{const r=P();return N(d(r).getTree())},Q=()=>{const r=n(S);if(!r)throw new Error("useRoute must be used within a RouteProvider");return r};function j(){const r=P(),e=t(()=>l(r),[r]);return a(e.subscribe,e.getSnapshot,e.getSnapshot)}var x=({router:r,children:e,announceNavigation:o})=>{i(()=>{if(!o)return;const e=p(r);return()=>{e.destroy()}},[o,r]);const n=t(()=>u(r),[r]),s=t(()=>m(r),[r]),{route:c,previousRoute:l}=a(s.subscribe,s.getSnapshot,s.getSnapshot),v=t(()=>({navigator:n,route:c,previousRoute:l}),[n,c,l]);return h(b,{value:r,children:h(y,{value:n,children:h(S,{value:v,children:e})})})};export{k as Link,x as RouterProvider,J as useNavigator,Q as useRoute,O as useRouteNode,E as useRouteUtils,P as useRouter,j as useRouterTransition};//# sourceMappingURL=chunk-SQL27477.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/context.ts","../../src/hooks/useRouter.tsx","../../src/hooks/useRouteNode.tsx","../../src/constants.ts","../../src/hooks/useStableValue.tsx","../../src/hooks/useIsActiveRoute.tsx","../../src/components/Link.tsx","../../src/hooks/useNavigator.tsx","../../src/hooks/useRouteUtils.tsx","../../src/hooks/useRoute.tsx","../../src/hooks/useRouterTransition.tsx","../../src/RouterProvider.tsx"],"names":["useMemo","useSyncExternalStore","useContext","getNavigator","jsx"],"mappings":"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","file":"chunk-SQL27477.mjs","sourcesContent":["// packages/react/modules/context.ts\n\nimport { createContext } from \"react\";\n\nimport type { RouteContext as RouteContextType } from \"./types\";\nimport type { Router, Navigator } from \"@real-router/core\";\n\nexport const RouteContext = createContext<RouteContextType | null>(null);\n\nexport const RouterContext = createContext<Router | null>(null);\n\nexport const NavigatorContext = createContext<Navigator | null>(null);\n","// packages/react/modules/hooks/useRouter.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouterContext } from \"../context\";\n\nimport type { Router } from \"@real-router/core\";\n\nexport const useRouter = (): Router => {\n const router = useContext(RouterContext);\n\n if (!router) {\n throw new Error(\"useRouter must be used within a RouterProvider\");\n }\n\n return router;\n};\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteContext } from \"../types\";\n\nexport function useRouteNode(nodeName: string): RouteContext {\n const router = useRouter();\n\n const store = useMemo(\n () => createRouteNodeSource(router, nodeName),\n [router, nodeName],\n );\n\n const { route, previousRoute } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n return useMemo(\n (): RouteContext => ({ navigator, route, previousRoute }),\n [navigator, route, previousRoute],\n );\n}\n","// packages/react/modules/constants.ts\n\n/**\n * Stable empty object for default params\n */\nexport const EMPTY_PARAMS = Object.freeze({});\n\n/**\n * Stable empty options object\n */\nexport const EMPTY_OPTIONS = Object.freeze({});\n","// packages/react/modules/hooks/useStableValue.tsx\n\nimport { useMemo } from \"react\";\n\n/**\n * Stabilizes a value reference based on deep equality (via JSON serialization).\n * Returns the same reference until the serialized value changes.\n *\n * Useful for object/array dependencies in hooks like useMemo, useCallback, useEffect\n * to prevent unnecessary re-renders when the value is structurally the same.\n *\n * @example\n * ```tsx\n * const stableParams = useStableValue(routeParams);\n * const href = useMemo(() => {\n * return router.buildUrl(routeName, stableParams);\n * }, [router, routeName, stableParams]);\n * ```\n *\n * @param value - The value to stabilize\n * @returns A stable reference to the value\n */\nexport function useStableValue<T>(value: T): T {\n const serialized = JSON.stringify(value);\n\n // We intentionally use serialized in deps to detect deep changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => value, [serialized]);\n}\n","import { createActiveRouteSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\nimport { useStableValue } from \"./useStableValue\";\n\nimport type { Params } from \"@real-router/core\";\n\nexport function useIsActiveRoute(\n routeName: string,\n params?: Params,\n strict = false,\n ignoreQueryParams = true,\n): boolean {\n const router = useRouter();\n\n // useStableValue: JSON.stringify memoization of params object.\n // Without it, every render with a new params reference (e.g.,\n // <Link routeParams={{ id: '123' }} />) would recreate the store.\n const stableParams = useStableValue(params);\n\n const store = useMemo(\n () =>\n createActiveRouteSource(router, routeName, stableParams, {\n strict,\n ignoreQueryParams,\n }),\n [router, routeName, stableParams, strict, ignoreQueryParams],\n );\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n}\n","import { shouldNavigate, buildHref, buildActiveClassName } from \"dom-utils\";\nimport { memo, useCallback, useMemo } from \"react\";\n\nimport { EMPTY_PARAMS, EMPTY_OPTIONS } from \"../constants\";\nimport { useIsActiveRoute } from \"../hooks/useIsActiveRoute\";\nimport { useRouter } from \"../hooks/useRouter\";\nimport { useStableValue } from \"../hooks/useStableValue\";\n\nimport type { LinkProps } from \"../types\";\nimport type { FC, MouseEvent } from \"react\";\n\nfunction areLinkPropsEqual(\n prev: Readonly<LinkProps>,\n next: Readonly<LinkProps>,\n): boolean {\n return (\n prev.routeName === next.routeName &&\n prev.className === next.className &&\n prev.activeClassName === next.activeClassName &&\n prev.activeStrict === next.activeStrict &&\n prev.ignoreQueryParams === next.ignoreQueryParams &&\n prev.onClick === next.onClick &&\n prev.target === next.target &&\n prev.style === next.style &&\n prev.children === next.children &&\n JSON.stringify(prev.routeParams) === JSON.stringify(next.routeParams) &&\n JSON.stringify(prev.routeOptions) === JSON.stringify(next.routeOptions)\n );\n}\n\nexport const Link: FC<LinkProps> = memo(\n ({\n routeName,\n routeParams = EMPTY_PARAMS,\n routeOptions = EMPTY_OPTIONS,\n className,\n activeClassName = \"active\",\n activeStrict = false,\n ignoreQueryParams = true,\n onClick,\n target,\n children,\n ...props\n }) => {\n const router = useRouter();\n\n const stableParams = useStableValue(routeParams);\n const stableOptions = useStableValue(routeOptions);\n\n const isActive = useIsActiveRoute(\n routeName,\n stableParams,\n activeStrict,\n ignoreQueryParams,\n );\n\n const href = useMemo(\n () => buildHref(router, routeName, stableParams),\n [router, routeName, stableParams],\n );\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLAnchorElement>) => {\n if (onClick) {\n onClick(evt);\n\n if (evt.defaultPrevented) {\n return;\n }\n }\n\n if (!shouldNavigate(evt.nativeEvent) || target === \"_blank\") {\n return;\n }\n\n evt.preventDefault();\n router.navigate(routeName, stableParams, stableOptions).catch(() => {});\n },\n [onClick, target, router, routeName, stableParams, stableOptions],\n );\n\n const finalClassName = useMemo(\n () => buildActiveClassName(isActive, activeClassName, className),\n [isActive, activeClassName, className],\n );\n\n return (\n <a\n {...props}\n href={href}\n className={finalClassName}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n },\n areLinkPropsEqual,\n);\n\nLink.displayName = \"Link\";\n","// packages/react/modules/hooks/useNavigator.tsx\n\nimport { useContext } from \"react\";\n\nimport { NavigatorContext } from \"../context\";\n\nimport type { Navigator } from \"@real-router/core\";\n\nexport const useNavigator = (): Navigator => {\n const navigator = useContext(NavigatorContext);\n\n if (!navigator) {\n throw new Error(\"useNavigator must be used within a RouterProvider\");\n }\n\n return navigator;\n};\n","// packages/react/modules/hooks/useRouteUtils.tsx\n\nimport { getPluginApi } from \"@real-router/core/api\";\nimport { getRouteUtils } from \"@real-router/route-utils\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteUtils } from \"@real-router/route-utils\";\n\n/**\n * Returns a pre-computed {@link RouteUtils} instance for the current router.\n *\n * Internally retrieves the route tree via `getPluginApi` and delegates\n * to `getRouteUtils`, which caches instances per tree reference (WeakMap).\n *\n * @returns RouteUtils instance with pre-computed chains and siblings\n *\n * @example\n * ```tsx\n * const utils = useRouteUtils();\n *\n * utils.getChain(\"users.profile\");\n * // → [\"users\", \"users.profile\"]\n *\n * utils.getSiblings(\"users\");\n * // → [\"admin\"]\n *\n * utils.isDescendantOf(\"users.profile\", \"users\");\n * // → true\n * ```\n */\nexport const useRouteUtils = (): RouteUtils => {\n const router = useRouter();\n\n return getRouteUtils(getPluginApi(router).getTree());\n};\n","// packages/react/modules/hooks/useRoute.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouteContext } from \"../context\";\n\nimport type { RouteContext as RouteContextType } from \"../types\";\n\nexport const useRoute = (): RouteContextType => {\n const routeContext = useContext(RouteContext);\n\n if (!routeContext) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n\n return routeContext;\n};\n","import { createTransitionSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouterTransitionSnapshot } from \"@real-router/sources\";\n\nexport function useRouterTransition(): RouterTransitionSnapshot {\n const router = useRouter();\n\n const store = useMemo(() => createTransitionSource(router), [router]);\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteSource } from \"@real-router/sources\";\nimport { createRouteAnnouncer } from \"dom-utils\";\nimport { useEffect, useMemo, useSyncExternalStore } from \"react\";\n\nimport { NavigatorContext, RouteContext, RouterContext } from \"./context\";\n\nimport type { Router } from \"@real-router/core\";\nimport type { FC, ReactNode } from \"react\";\n\nexport interface RouteProviderProps {\n router: Router;\n children: ReactNode;\n announceNavigation?: boolean;\n}\n\nexport const RouterProvider: FC<RouteProviderProps> = ({\n router,\n children,\n announceNavigation,\n}) => {\n useEffect(() => {\n if (!announceNavigation) {\n return;\n }\n\n const announcer = createRouteAnnouncer(router);\n\n return () => {\n announcer.destroy();\n };\n }, [announceNavigation, router]);\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n // useSyncExternalStore manages the router subscription lifecycle:\n // subscribe connects to router on first listener, unsubscribes on last.\n // This is Strict Mode safe — no useEffect cleanup needed.\n const store = useMemo(() => createRouteSource(router), [router]);\n const { route, previousRoute } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const routeContextValue = useMemo(\n () => ({ navigator, route, previousRoute }),\n [navigator, route, previousRoute],\n );\n\n return (\n <RouterContext value={router}>\n <NavigatorContext value={navigator}>\n <RouteContext value={routeContextValue}>{children}</RouteContext>\n </NavigatorContext>\n </RouterContext>\n );\n};\n"]}