Socket
Socket
Sign inDemoInstall

@tanstack/router

Package Overview
Dependencies
Maintainers
2
Versions
104
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tanstack/router - npm Package Compare versions

Comparing version 0.0.1-beta.89 to 0.0.1-beta.90

build/types/history.d.ts

27

build/cjs/path.js

@@ -130,12 +130,21 @@ /**

function matchByPath(basepath, from, matchLocation) {
if (!from.startsWith(basepath)) {
return undefined;
}
// Remove the base path from the pathname
from = basepath != '/' ? from.substring(basepath.length) : from;
// Default to to $ (wildcard)
const to = `${matchLocation.to ?? '$'}`;
// Parse the from and to
const baseSegments = parsePathname(from);
const to = `${matchLocation.to ?? '$'}`;
const routeSegments = parsePathname(to);
if (utils.last(baseSegments)?.value === '/') {
baseSegments.pop();
if (!from.startsWith('/')) {
baseSegments.unshift({
type: 'pathname',
value: '/'
});
}
if (!to.startsWith('/')) {
routeSegments.unshift({
type: 'pathname',
value: '/'
});
}
const params = {};

@@ -146,4 +155,4 @@ let isMatch = (() => {

const routeSegment = routeSegments[i];
const isLastRouteSegment = i === routeSegments.length - 1;
const isLastBaseSegment = i === baseSegments.length - 1;
const isLastBaseSegment = i >= baseSegments.length - 1;
const isLastRouteSegment = i >= routeSegments.length - 1;
if (routeSegment) {

@@ -183,3 +192,3 @@ if (routeSegment.type === 'wildcard') {

}
if (isLastRouteSegment && !isLastBaseSegment) {
if (!isLastBaseSegment && isLastRouteSegment) {
return !!matchLocation.fuzzy;

@@ -186,0 +195,0 @@ }

@@ -275,66 +275,135 @@ /**

matchRoutes = (pathname, opts) => {
const matches = [];
// If there's no route tree, we can't match anything
if (!this.routeTree) {
return matches;
return [];
}
// Existing matches are matches that are already loaded along with
// pending matches that are still loading
const existingMatches = [...this.state.currentMatches, ...(this.state.pendingMatches ?? [])];
const findInRouteTree = async routes => {
const parentMatch = utils.last(matches);
let params = parentMatch?.params ?? {};
const filteredRoutes = this.options.filterRoutes?.(routes) ?? routes;
let matchingRoutes = [];
const findMatchInRoutes = (parentRoutes, routes) => {
routes.some(route => {
const children = route.children;
if (!route.path && children?.length) {
return findMatchInRoutes([...matchingRoutes, route], children);
// We need to "flatten" layout routes, but only process as many
// routes as we need to in order to find the best match
// This mean no looping over all of the routes (even though the
// user could technically do this in their own routes filter code,
// but that's their choice).
// Time to bust out the recursion... As we iterate over the routes,
// we'll keep track of the best match thus far by pushing or popping
// it onto the `matchingRoutes` array. In the case of a layout route,
// we'll assume that it matches and just recurse into its children.
// If we come up with nothing, we'll pop it off and try the next route.
// This way the user can have as many routes, including layout routes,
// as they want without worrying about performance.
// It does make one assumption though: that route branches are ordered from
// most specific to least specific. This is a good assumption to make IMO.
// Tools like Remix and React Router auto-rank routes, which is a neat trick
// that unfortunately requires looping over all of the routes.
// I'd rather err on the side of performance here
// and rely on the fact that to use TanStack Router, you already have to
// be thinking about your routes more intimately. We're smart enough
// to write switch statements, so we're smart enough to (keep) ordering
// our routes like we have been doing for years.
let matchingRoutesAndParams = [];
// For any given array of branching routes, find the best route match
// and push it onto the `matchingRoutes` array
const findRoutes = routes => {
let found;
// Given a list of routes, find the first route that matches
routes.some(route => {
const children = route.children;
// If there is no path, but there are children,
// this is a layout route, so recurse again
if (!route.path) {
if (children?.length) {
// Preemptively push the route onto the matchingRoutes array
matchingRoutesAndParams.push({
route
});
const childMatch = findRoutes(children);
// If we found a child match, mark it as found
// and return true to stop the loop
if (childMatch) {
found = childMatch;
return true;
}
// If there was no child match, pop our optimistic route off the array
// and return false to keep trying
matchingRoutesAndParams.pop();
return false;
}
const fuzzy = !!(route.path !== '/' || children?.length);
const matchParams = path.matchPathname(this.basepath, pathname, {
to: route.fullPath,
fuzzy,
caseSensitive: route.options.caseSensitive ?? this.options.caseSensitive
});
if (matchParams) {
let parsedParams;
try {
parsedParams = route.options.parseParams?.(matchParams) ?? matchParams;
} catch (err) {
if (opts?.strictParseParams) {
throw err;
}
// It's a layout route, but for some reason it has no children
// so we'll just ignore it and keep matching
return false;
}
// If the route isn't an index route or it has children,
// fuzzy match the path
const fuzzy = route.path !== '/' || !!children?.length;
const matchedParams = path.matchPathname(this.basepath, pathname, {
to: route.fullPath,
fuzzy,
caseSensitive: route.options.caseSensitive ?? this.options.caseSensitive
});
// This was a match!
if (matchedParams) {
// Let's parse the params using the route's `parseParams` function
let parsedParams;
try {
parsedParams = route.options.parseParams?.(matchedParams) ?? matchedParams;
} catch (err) {
if (opts?.strictParseParams) {
throw err;
}
params = {
...params,
...parsedParams
};
}
if (!!matchParams) {
matchingRoutes = [...parentRoutes, route];
}
return !!matchingRoutes.length;
});
return !!matchingRoutes.length;
};
findMatchInRoutes([], filteredRoutes);
if (!matchingRoutes.length) {
return;
matchingRoutesAndParams.push({
route,
params: parsedParams
});
found = route;
return true;
}
return false;
});
// If we didn't find a match in this route branch
// return early.
if (!found) {
return undefined;
}
matchingRoutes.forEach(foundRoute => {
const interpolatedPath = path.interpolatePath(foundRoute.path, params);
const matchId = path.interpolatePath(foundRoute.id, params, true);
const match = existingMatches.find(d => d.id === matchId) || new routeMatch.RouteMatch(this, foundRoute, {
id: matchId,
params,
pathname: path.joinPaths([this.basepath, interpolatedPath])
});
matches.push(match);
});
const foundRoute = utils.last(matchingRoutes);
const foundChildren = foundRoute.children;
// If the found route has children, recurse again
const foundChildren = found.children;
if (foundChildren?.length) {
findInRouteTree(foundChildren);
return findRoutes(foundChildren);
}
return found;
};
findInRouteTree([this.routeTree]);
findRoutes([this.routeTree]);
// Alright, by now we should have all of our
// matching routes and their param pairs, let's
// Turn them into actual `Match` objects and
// accumulate the params into a single params bag
let allParams = {};
const matches = matchingRoutesAndParams.map(({
route,
params
}) => {
// Add the parsed params to the accumulated params bag
Object.assign(allParams, params);
const interpolatedPath = path.interpolatePath(route.path, params);
const matchId = path.interpolatePath(route.id, params, true);
// Waste not, want not. If we already have a match for this route,
// reuse it. This is important for layout routes, which might stick
// around between navigation actions that only change leaf routes.
return existingMatches.find(d => d.id === matchId) || new routeMatch.RouteMatch(this, route, {
id: matchId,
params: allParams,
pathname: path.joinPaths([this.basepath, interpolatedPath])
});
});
return matches;

@@ -341,0 +410,0 @@ };

@@ -14,7 +14,7 @@ {

"name": "tiny-invariant@1.3.1/node_modules/tiny-invariant/dist/esm/tiny-invariant.js",
"uid": "786f-35"
"uid": "a441-49"
},
{
"name": "tiny-warning@1.0.3/node_modules/tiny-warning/dist/tiny-warning.esm.js",
"uid": "786f-37"
"uid": "a441-51"
}

@@ -30,39 +30,39 @@ ]

{
"uid": "786f-39",
"uid": "a441-53",
"name": "history.ts"
},
{
"uid": "786f-41",
"uid": "a441-55",
"name": "utils.ts"
},
{
"uid": "786f-43",
"uid": "a441-57",
"name": "path.ts"
},
{
"uid": "786f-45",
"uid": "a441-59",
"name": "qss.ts"
},
{
"uid": "786f-53",
"uid": "a441-67",
"name": "react.tsx"
},
{
"uid": "786f-55",
"uid": "a441-69",
"name": "route.ts"
},
{
"uid": "786f-57",
"uid": "a441-71",
"name": "searchParams.ts"
},
{
"uid": "786f-59",
"uid": "a441-73",
"name": "router.ts"
},
{
"uid": "786f-61",
"uid": "a441-75",
"name": "routeMatch.ts"
},
{
"uid": "786f-63",
"uid": "a441-77",
"name": "index.ts"

@@ -74,7 +74,7 @@ }

"name": "store/build/esm/index.js",
"uid": "786f-49"
"uid": "a441-63"
},
{
"name": "react-store/build/esm/index.js",
"uid": "786f-51"
"uid": "a441-65"
}

@@ -84,3 +84,3 @@ ]

{
"uid": "786f-47",
"uid": "a441-61",
"name": "\u0000rollupPluginBabelHelpers.js"

@@ -94,98 +94,98 @@ }

"nodeParts": {
"786f-35": {
"a441-49": {
"renderedLength": 199,
"gzipLength": 134,
"brotliLength": 0,
"mainUid": "786f-34"
"mainUid": "a441-48"
},
"786f-37": {
"a441-51": {
"renderedLength": 48,
"gzipLength": 65,
"brotliLength": 0,
"mainUid": "786f-36"
"mainUid": "a441-50"
},
"786f-39": {
"a441-53": {
"renderedLength": 5639,
"gzipLength": 1385,
"brotliLength": 0,
"mainUid": "786f-38"
"mainUid": "a441-52"
},
"786f-41": {
"a441-55": {
"renderedLength": 2821,
"gzipLength": 990,
"brotliLength": 0,
"mainUid": "786f-40"
"mainUid": "a441-54"
},
"786f-43": {
"renderedLength": 5705,
"gzipLength": 1352,
"a441-57": {
"renderedLength": 5930,
"gzipLength": 1410,
"brotliLength": 0,
"mainUid": "786f-42"
"mainUid": "a441-56"
},
"786f-45": {
"a441-59": {
"renderedLength": 1395,
"gzipLength": 558,
"brotliLength": 0,
"mainUid": "786f-44"
"mainUid": "a441-58"
},
"786f-47": {
"a441-61": {
"renderedLength": 457,
"gzipLength": 241,
"brotliLength": 0,
"mainUid": "786f-46"
"mainUid": "a441-60"
},
"786f-49": {
"renderedLength": 1413,
"gzipLength": 495,
"a441-63": {
"renderedLength": 1436,
"gzipLength": 529,
"brotliLength": 0,
"mainUid": "786f-48"
"mainUid": "a441-62"
},
"786f-51": {
"a441-65": {
"renderedLength": 1042,
"gzipLength": 465,
"brotliLength": 0,
"mainUid": "786f-50"
"mainUid": "a441-64"
},
"786f-53": {
"a441-67": {
"renderedLength": 13748,
"gzipLength": 3309,
"brotliLength": 0,
"mainUid": "786f-52"
"mainUid": "a441-66"
},
"786f-55": {
"a441-69": {
"renderedLength": 3424,
"gzipLength": 897,
"brotliLength": 0,
"mainUid": "786f-54"
"mainUid": "a441-68"
},
"786f-57": {
"a441-71": {
"renderedLength": 1387,
"gzipLength": 483,
"brotliLength": 0,
"mainUid": "786f-56"
"mainUid": "a441-70"
},
"786f-59": {
"renderedLength": 26722,
"gzipLength": 6118,
"a441-73": {
"renderedLength": 30007,
"gzipLength": 7334,
"brotliLength": 0,
"mainUid": "786f-58"
"mainUid": "a441-72"
},
"786f-61": {
"a441-75": {
"renderedLength": 7564,
"gzipLength": 1752,
"brotliLength": 0,
"mainUid": "786f-60"
"mainUid": "a441-74"
},
"786f-63": {
"a441-77": {
"renderedLength": 0,
"gzipLength": 0,
"brotliLength": 0,
"mainUid": "786f-62"
"mainUid": "a441-76"
}
},
"nodeMetas": {
"786f-34": {
"a441-48": {
"id": "/node_modules/.pnpm/tiny-invariant@1.3.1/node_modules/tiny-invariant/dist/esm/tiny-invariant.js",
"moduleParts": {
"index.production.js": "786f-35"
"index.production.js": "a441-49"
},

@@ -195,19 +195,19 @@ "imported": [],

{
"uid": "786f-62"
"uid": "a441-76"
},
{
"uid": "786f-54"
"uid": "a441-68"
},
{
"uid": "786f-58"
"uid": "a441-72"
},
{
"uid": "786f-52"
"uid": "a441-66"
}
]
},
"786f-36": {
"a441-50": {
"id": "/node_modules/.pnpm/tiny-warning@1.0.3/node_modules/tiny-warning/dist/tiny-warning.esm.js",
"moduleParts": {
"index.production.js": "786f-37"
"index.production.js": "a441-51"
},

@@ -217,13 +217,13 @@ "imported": [],

{
"uid": "786f-62"
"uid": "a441-76"
},
{
"uid": "786f-52"
"uid": "a441-66"
}
]
},
"786f-38": {
"a441-52": {
"id": "/packages/router/src/history.ts",
"moduleParts": {
"index.production.js": "786f-39"
"index.production.js": "a441-53"
},

@@ -233,13 +233,13 @@ "imported": [],

{
"uid": "786f-62"
"uid": "a441-76"
},
{
"uid": "786f-58"
"uid": "a441-72"
}
]
},
"786f-40": {
"a441-54": {
"id": "/packages/router/src/utils.ts",
"moduleParts": {
"index.production.js": "786f-41"
"index.production.js": "a441-55"
},

@@ -249,26 +249,26 @@ "imported": [],

{
"uid": "786f-62"
"uid": "a441-76"
},
{
"uid": "786f-42"
"uid": "a441-56"
},
{
"uid": "786f-60"
"uid": "a441-74"
},
{
"uid": "786f-58"
"uid": "a441-72"
},
{
"uid": "786f-52"
"uid": "a441-66"
}
]
},
"786f-42": {
"a441-56": {
"id": "/packages/router/src/path.ts",
"moduleParts": {
"index.production.js": "786f-43"
"index.production.js": "a441-57"
},
"imported": [
{
"uid": "786f-40"
"uid": "a441-54"
}

@@ -278,16 +278,16 @@ ],

{
"uid": "786f-62"
"uid": "a441-76"
},
{
"uid": "786f-54"
"uid": "a441-68"
},
{
"uid": "786f-58"
"uid": "a441-72"
}
]
},
"786f-44": {
"a441-58": {
"id": "/packages/router/src/qss.ts",
"moduleParts": {
"index.production.js": "786f-45"
"index.production.js": "a441-59"
},

@@ -297,13 +297,13 @@ "imported": [],

{
"uid": "786f-62"
"uid": "a441-76"
},
{
"uid": "786f-56"
"uid": "a441-70"
}
]
},
"786f-46": {
"a441-60": {
"id": "\u0000rollupPluginBabelHelpers.js",
"moduleParts": {
"index.production.js": "786f-47"
"index.production.js": "a441-61"
},

@@ -313,10 +313,10 @@ "imported": [],

{
"uid": "786f-52"
"uid": "a441-66"
}
]
},
"786f-48": {
"a441-62": {
"id": "/packages/store/build/esm/index.js",
"moduleParts": {
"index.production.js": "786f-49"
"index.production.js": "a441-63"
},

@@ -326,17 +326,17 @@ "imported": [],

{
"uid": "786f-50"
"uid": "a441-64"
}
]
},
"786f-50": {
"a441-64": {
"id": "/packages/react-store/build/esm/index.js",
"moduleParts": {
"index.production.js": "786f-51"
"index.production.js": "a441-65"
},
"imported": [
{
"uid": "786f-67"
"uid": "a441-81"
},
{
"uid": "786f-48"
"uid": "a441-62"
}

@@ -346,35 +346,35 @@ ],

{
"uid": "786f-60"
"uid": "a441-74"
},
{
"uid": "786f-58"
"uid": "a441-72"
},
{
"uid": "786f-52"
"uid": "a441-66"
}
]
},
"786f-52": {
"a441-66": {
"id": "/packages/router/src/react.tsx",
"moduleParts": {
"index.production.js": "786f-53"
"index.production.js": "a441-67"
},
"imported": [
{
"uid": "786f-46"
"uid": "a441-60"
},
{
"uid": "786f-66"
"uid": "a441-80"
},
{
"uid": "786f-50"
"uid": "a441-64"
},
{
"uid": "786f-34"
"uid": "a441-48"
},
{
"uid": "786f-36"
"uid": "a441-50"
},
{
"uid": "786f-40"
"uid": "a441-54"
}

@@ -384,23 +384,23 @@ ],

{
"uid": "786f-62"
"uid": "a441-76"
},
{
"uid": "786f-54"
"uid": "a441-68"
}
]
},
"786f-54": {
"a441-68": {
"id": "/packages/router/src/route.ts",
"moduleParts": {
"index.production.js": "786f-55"
"index.production.js": "a441-69"
},
"imported": [
{
"uid": "786f-34"
"uid": "a441-48"
},
{
"uid": "786f-42"
"uid": "a441-56"
},
{
"uid": "786f-52"
"uid": "a441-66"
}

@@ -410,14 +410,14 @@ ],

{
"uid": "786f-62"
"uid": "a441-76"
}
]
},
"786f-56": {
"a441-70": {
"id": "/packages/router/src/searchParams.ts",
"moduleParts": {
"index.production.js": "786f-57"
"index.production.js": "a441-71"
},
"imported": [
{
"uid": "786f-44"
"uid": "a441-58"
}

@@ -427,35 +427,35 @@ ],

{
"uid": "786f-62"
"uid": "a441-76"
},
{
"uid": "786f-58"
"uid": "a441-72"
}
]
},
"786f-58": {
"a441-72": {
"id": "/packages/router/src/router.ts",
"moduleParts": {
"index.production.js": "786f-59"
"index.production.js": "a441-73"
},
"imported": [
{
"uid": "786f-50"
"uid": "a441-64"
},
{
"uid": "786f-34"
"uid": "a441-48"
},
{
"uid": "786f-42"
"uid": "a441-56"
},
{
"uid": "786f-60"
"uid": "a441-74"
},
{
"uid": "786f-56"
"uid": "a441-70"
},
{
"uid": "786f-40"
"uid": "a441-54"
},
{
"uid": "786f-38"
"uid": "a441-52"
}

@@ -465,23 +465,23 @@ ],

{
"uid": "786f-62"
"uid": "a441-76"
},
{
"uid": "786f-60"
"uid": "a441-74"
}
]
},
"786f-60": {
"a441-74": {
"id": "/packages/router/src/routeMatch.ts",
"moduleParts": {
"index.production.js": "786f-61"
"index.production.js": "a441-75"
},
"imported": [
{
"uid": "786f-50"
"uid": "a441-64"
},
{
"uid": "786f-58"
"uid": "a441-72"
},
{
"uid": "786f-40"
"uid": "a441-54"
}

@@ -491,53 +491,53 @@ ],

{
"uid": "786f-62"
"uid": "a441-76"
},
{
"uid": "786f-58"
"uid": "a441-72"
}
]
},
"786f-62": {
"a441-76": {
"id": "/packages/router/src/index.ts",
"moduleParts": {
"index.production.js": "786f-63"
"index.production.js": "a441-77"
},
"imported": [
{
"uid": "786f-34"
"uid": "a441-48"
},
{
"uid": "786f-36"
"uid": "a441-50"
},
{
"uid": "786f-38"
"uid": "a441-52"
},
{
"uid": "786f-64"
"uid": "a441-78"
},
{
"uid": "786f-42"
"uid": "a441-56"
},
{
"uid": "786f-44"
"uid": "a441-58"
},
{
"uid": "786f-54"
"uid": "a441-68"
},
{
"uid": "786f-65"
"uid": "a441-79"
},
{
"uid": "786f-60"
"uid": "a441-74"
},
{
"uid": "786f-58"
"uid": "a441-72"
},
{
"uid": "786f-56"
"uid": "a441-70"
},
{
"uid": "786f-40"
"uid": "a441-54"
},
{
"uid": "786f-52"
"uid": "a441-66"
}

@@ -548,3 +548,3 @@ ],

},
"786f-64": {
"a441-78": {
"id": "/packages/router/src/link.ts",

@@ -555,7 +555,7 @@ "moduleParts": {},

{
"uid": "786f-62"
"uid": "a441-76"
}
]
},
"786f-65": {
"a441-79": {
"id": "/packages/router/src/routeInfo.ts",

@@ -566,7 +566,7 @@ "moduleParts": {},

{
"uid": "786f-62"
"uid": "a441-76"
}
]
},
"786f-66": {
"a441-80": {
"id": "react",

@@ -577,3 +577,3 @@ "moduleParts": {},

{
"uid": "786f-52"
"uid": "a441-66"
}

@@ -583,3 +583,3 @@ ],

},
"786f-67": {
"a441-81": {
"id": "use-sync-external-store/shim/with-selector",

@@ -590,3 +590,3 @@ "moduleParts": {},

{
"uid": "786f-50"
"uid": "a441-64"
}

@@ -593,0 +593,0 @@ ],

@@ -1,797 +0,13 @@

/**
* router
*
* Copyright (c) TanStack
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
export { default as invariant } from 'tiny-invariant';
export { default as warning } from 'tiny-warning';
import { Store, NoInfer as NoInfer$1 } from '@tanstack/react-store';
export { useStore } from '@tanstack/react-store';
import * as React$1 from 'react';
interface RouterHistory {
location: RouterLocation;
listen: (cb: () => void) => () => void;
push: (path: string, state: any) => void;
replace: (path: string, state: any) => void;
go: (index: number) => void;
back: () => void;
forward: () => void;
createHref: (href: string) => string;
block: (blockerFn: BlockerFn) => () => void;
}
interface ParsedPath {
href: string;
pathname: string;
search: string;
hash: string;
}
interface RouterLocation extends ParsedPath {
state: any;
}
type BlockerFn = (retry: () => void, cancel: () => void) => void;
declare function createBrowserHistory(opts?: {
getHref?: () => string;
createHref?: (path: string) => string;
}): RouterHistory;
declare function createHashHistory(): RouterHistory;
declare function createMemoryHistory(opts?: {
initialEntries: string[];
initialIndex?: number;
}): RouterHistory;
type NoInfer<T> = [T][T extends any ? 0 : never];
type IsAny<T, Y, N> = 1 extends 0 & T ? Y : N;
type IsAnyBoolean<T> = 1 extends 0 & T ? true : false;
type IsKnown<T, Y, N> = unknown extends T ? N : Y;
type PickAsRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
type PickAsPartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type PickUnsafe<T, K> = K extends keyof T ? Pick<T, K> : never;
type PickExtra<T, K> = {
[TKey in keyof K as string extends TKey ? never : TKey extends keyof T ? never : TKey]: K[TKey];
};
type PickRequired<T> = {
[K in keyof T as undefined extends T[K] ? never : K]: T[K];
};
type Expand<T> = T extends object ? T extends infer O ? {
[K in keyof O]: O[K];
} : never : T;
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => any ? I : never;
type Compute<T> = {
[K in keyof T]: T[K];
} | never;
type AllKeys<T> = T extends any ? keyof T : never;
type MergeUnion<T, Keys extends keyof T = keyof T> = Compute<{
[K in Keys]: T[Keys];
} & {
[K in AllKeys<T>]?: T extends any ? K extends keyof T ? T[K] : never : never;
}>;
type Values<O> = O[ValueKeys<O>];
type ValueKeys<O> = Extract<keyof O, PropertyKey>;
type DeepAwaited<T> = T extends Promise<infer A> ? DeepAwaited<A> : T extends Record<infer A, Promise<infer B>> ? {
[K in A]: DeepAwaited<B>;
} : T;
type PathParamMask<TRoutePath extends string> = TRoutePath extends `${infer L}/$${infer C}/${infer R}` ? PathParamMask<`${L}/${string}/${R}`> : TRoutePath extends `${infer L}/$${infer C}` ? PathParamMask<`${L}/${string}`> : TRoutePath;
type Timeout = ReturnType<typeof setTimeout>;
type Updater<TPrevious, TResult = TPrevious> = TResult | ((prev?: TPrevious) => TResult);
type PickExtract<T, U> = {
[K in keyof T as T[K] extends U ? K : never]: T[K];
};
type PickExclude<T, U> = {
[K in keyof T as T[K] extends U ? never : K]: T[K];
};
declare function last<T>(arr: T[]): T | undefined;
declare function functionalUpdate<TResult>(updater: Updater<TResult>, previous: TResult): TResult;
declare function pick<T, K extends keyof T>(parent: T, keys: K[]): Pick<T, K>;
/**
* This function returns `a` if `b` is deeply equal.
* If not, it will replace any deeply equal children of `b` with those of `a`.
* This can be used for structural sharing between immutable JSON values for example.
* Do not use this with signals
*/
declare function replaceEqualDeep<T>(prev: any, _next: T): T;
declare function isPlainObject(o: any): boolean;
declare function partialDeepEqual(a: any, b: any): boolean;
declare global {
interface Window {
__DEHYDRATED__?: Record<string, any>;
}
}
interface Register {
}
type AnyRouter = Router<any, any, any>;
type RegisteredRouter = Register extends {
router: Router<infer TRoute, infer TRoutesInfo>;
} ? Router<TRoute, TRoutesInfo> : Router;
type RegisteredRoutesInfo = Register extends {
router: Router<infer TRoute, infer TRoutesInfo>;
} ? TRoutesInfo : AnyRoutesInfo;
interface LocationState {
}
interface ParsedLocation<TSearchObj extends AnySearchSchema = {}, TState extends LocationState = LocationState> {
href: string;
pathname: string;
search: TSearchObj;
searchStr: string;
state: TState;
hash: string;
key?: string;
}
interface FromLocation {
pathname: string;
search?: unknown;
key?: string;
hash?: string;
}
type SearchSerializer = (searchObj: Record<string, any>) => string;
type SearchParser = (searchStr: string) => Record<string, any>;
type FilterRoutesFn = <TRoute extends AnyRoute>(routes: TRoute[]) => TRoute[];
type RouterContextOptions<TRouteTree extends AnyRoute> = AnyContext extends TRouteTree['__types']['routerContext'] ? {
context?: TRouteTree['__types']['routerContext'];
} : {
context: TRouteTree['__types']['routerContext'];
};
interface RouterOptions<TRouteTree extends AnyRoute, TDehydrated extends Record<string, any>> {
history?: RouterHistory;
stringifySearch?: SearchSerializer;
parseSearch?: SearchParser;
filterRoutes?: FilterRoutesFn;
defaultPreload?: false | 'intent';
defaultPreloadDelay?: number;
defaultComponent?: RouteComponent;
defaultErrorComponent?: RouteComponent<{
error: Error;
info: {
componentStack: string;
};
}>;
defaultPendingComponent?: RouteComponent;
defaultLoaderMaxAge?: number;
defaultLoaderGcMaxAge?: number;
caseSensitive?: boolean;
routeTree?: TRouteTree;
basepath?: string;
createRoute?: (opts: {
route: AnyRoute;
router: AnyRouter;
}) => void;
onRouteChange?: () => void;
fetchServerDataFn?: FetchServerDataFn;
context?: TRouteTree['__types']['routerContext'];
Provider?: React.ComponentType<{
children: any;
}>;
dehydrate?: () => TDehydrated;
hydrate?: (dehydrated: TDehydrated) => void;
}
type FetchServerDataFn = (ctx: {
router: AnyRouter;
routeMatch: RouteMatch;
}) => Promise<any>;
interface RouterState<TRoutesInfo extends AnyRoutesInfo = AnyRoutesInfo, TState extends LocationState = LocationState> {
status: 'idle' | 'pending';
latestLocation: ParsedLocation<TRoutesInfo['fullSearchSchema'], TState>;
currentMatches: RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[];
currentLocation: ParsedLocation<TRoutesInfo['fullSearchSchema'], TState>;
pendingMatches?: RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[];
pendingLocation?: ParsedLocation<TRoutesInfo['fullSearchSchema'], TState>;
lastUpdated: number;
}
type ListenerFn = () => void;
interface BuildNextOptions {
to?: string | number | null;
params?: true | Updater<unknown>;
search?: true | Updater<unknown>;
hash?: true | Updater<string>;
state?: LocationState;
key?: string;
from?: string;
fromCurrent?: boolean;
__matches?: RouteMatch[];
}
type MatchCacheEntry = {
gc: number;
match: RouteMatch;
};
interface MatchLocation {
to?: string | number | null;
fuzzy?: boolean;
caseSensitive?: boolean;
from?: string;
fromCurrent?: boolean;
}
interface MatchRouteOptions {
pending?: boolean;
caseSensitive?: boolean;
includeSearch?: boolean;
fuzzy?: boolean;
}
interface DehydratedRouterState extends Pick<RouterState, 'status' | 'latestLocation' | 'currentLocation' | 'lastUpdated'> {
}
interface DehydratedRouter {
state: DehydratedRouterState;
}
type MatchCache = Record<string, MatchCacheEntry>;
declare const defaultFetchServerDataFn: FetchServerDataFn;
type RouterConstructorOptions<TRouteTree extends AnyRoute, TDehydrated extends Record<string, any>> = Omit<RouterOptions<TRouteTree, TDehydrated>, 'context'> & RouterContextOptions<TRouteTree>;
declare class Router<TRouteTree extends AnyRoute = AnyRoute, TRoutesInfo extends AnyRoutesInfo = RoutesInfo<TRouteTree>, TDehydrated extends Record<string, any> = Record<string, any>> {
#private;
types: {
RootRoute: TRouteTree;
RoutesInfo: TRoutesInfo;
};
options: PickAsRequired<RouterOptions<TRouteTree, TDehydrated>, 'stringifySearch' | 'parseSearch' | 'context'>;
context: NonNullable<TRouteTree['__types']['routerContext']>;
history: RouterHistory;
basepath: string;
routeTree: RootRoute;
routesById: RoutesById<TRoutesInfo>;
navigateTimeout: undefined | Timeout;
nextAction: undefined | 'push' | 'replace';
navigationPromise: undefined | Promise<void>;
__store: Store<RouterState<TRoutesInfo>>;
state: RouterState<TRoutesInfo>;
startedLoadingAt: number;
resolveNavigation: () => void;
constructor(options?: RouterConstructorOptions<TRouteTree, TDehydrated>);
reset: () => void;
mount: () => () => void;
hydrate: (__do_not_use_server_ctx?: any) => Promise<void>;
update: (opts?: RouterOptions<any, any>) => this;
buildNext: (opts: BuildNextOptions) => ParsedLocation;
cancelMatches: () => void;
safeLoad: (opts?: {
next?: ParsedLocation;
}) => void;
load: (opts?: {
next?: ParsedLocation;
}) => Promise<void>;
getRoute: <TId extends keyof TRoutesInfo["routesById"]>(id: TId) => TRoutesInfo["routesById"][TId];
loadRoute: (navigateOpts?: BuildNextOptions) => Promise<RouteMatch[]>;
preloadRoute: (navigateOpts?: BuildNextOptions) => Promise<AnyRouteMatch[]>;
matchRoutes: (pathname: string, opts?: {
strictParseParams?: boolean;
}) => AnyRouteMatch[];
loadMatches: (resolvedMatches: RouteMatch[], location: ParsedLocation, opts?: {
preload?: boolean;
}) => Promise<void>;
reload: () => void;
resolvePath: (from: string, path: string) => string;
navigate: <TFrom extends ValidFromPath<TRoutesInfo> = "/", TTo extends string = "">({ from, to, search, hash, replace, params, }: NavigateOptions<TRoutesInfo, TFrom, TTo>) => Promise<void>;
matchRoute: <TFrom extends ValidFromPath<TRoutesInfo> = "/", TTo extends string = "", TResolved extends string = ResolveRelativePath<TFrom, NoInfer<TTo>>>(location: ToOptions<TRoutesInfo, TFrom, TTo, ResolveRelativePath<TFrom, NoInfer<TTo>>>, opts?: MatchRouteOptions) => false | TRoutesInfo["routesById"][TResolved]["__types"]["allParams"];
buildLink: <TFrom extends ValidFromPath<TRoutesInfo> = "/", TTo extends string = "">({ from, to, search, params, hash, target, replace, activeOptions, preload, preloadDelay: userPreloadDelay, disabled, }: LinkOptions<TRoutesInfo, TFrom, TTo>) => LinkInfo;
}
type AnyRedirect = Redirect<any, any, any>;
type Redirect<TRoutesInfo extends AnyRoutesInfo = RegisteredRoutesInfo, TFrom extends TRoutesInfo['routePaths'] = '/', TTo extends string = ''> = NavigateOptions<TRoutesInfo, TFrom, TTo> & {
code?: number;
};
declare function redirect<TRoutesInfo extends AnyRoutesInfo = RegisteredRoutesInfo, TFrom extends TRoutesInfo['routePaths'] = '/', TTo extends string = ''>(opts: Redirect<TRoutesInfo, TFrom, TTo>): Redirect<TRoutesInfo, TFrom, TTo>;
declare function isRedirect(obj: any): obj is AnyRedirect;
type ReactNode = any;
type SyncRouteComponent<TProps = {}> = (props: TProps) => ReactNode;
type RouteComponent<TProps = {}> = SyncRouteComponent<TProps> & {
preload?: () => Promise<void>;
};
declare function lazy(importer: () => Promise<{
default: SyncRouteComponent;
}>): RouteComponent;
type LinkPropsOptions<TFrom extends RegisteredRoutesInfo['routePaths'] = '/', TTo extends string = ''> = LinkOptions<RegisteredRoutesInfo, TFrom, TTo> & {
activeProps?: React$1.AnchorHTMLAttributes<HTMLAnchorElement> | (() => React$1.AnchorHTMLAttributes<HTMLAnchorElement>);
inactiveProps?: React$1.AnchorHTMLAttributes<HTMLAnchorElement> | (() => React$1.AnchorHTMLAttributes<HTMLAnchorElement>);
};
type MakeUseMatchRouteOptions<TFrom extends RegisteredRoutesInfo['routePaths'] = '/', TTo extends string = ''> = ToOptions<RegisteredRoutesInfo, TFrom, TTo> & MatchRouteOptions;
type MakeMatchRouteOptions<TFrom extends RegisteredRoutesInfo['routePaths'] = '/', TTo extends string = ''> = ToOptions<RegisteredRoutesInfo, TFrom, TTo> & MatchRouteOptions & {
children?: ReactNode | ((params: RouteByPath<RegisteredRoutesInfo, ResolveRelativePath<TFrom, NoInfer$1<TTo>>>['__types']['allParams']) => ReactNode);
};
type MakeLinkPropsOptions<TFrom extends ValidFromPath<RegisteredRoutesInfo> = '/', TTo extends string = ''> = LinkPropsOptions<TFrom, TTo> & React$1.AnchorHTMLAttributes<HTMLAnchorElement>;
type MakeLinkOptions<TFrom extends RegisteredRoutesInfo['routePaths'] = '/', TTo extends string = ''> = LinkPropsOptions<TFrom, TTo> & React$1.AnchorHTMLAttributes<HTMLAnchorElement> & Omit<React$1.AnchorHTMLAttributes<HTMLAnchorElement>, 'children'> & {
children?: ReactNode | ((state: {
isActive: boolean;
}) => ReactNode);
};
type PromptProps = {
message: string;
condition?: boolean | any;
children?: ReactNode;
};
declare function useLinkProps<TFrom extends ValidFromPath<RegisteredRoutesInfo> = '/', TTo extends string = ''>(options: MakeLinkPropsOptions<TFrom, TTo>): React$1.AnchorHTMLAttributes<HTMLAnchorElement>;
interface LinkFn<TDefaultFrom extends RegisteredRoutesInfo['routePaths'] = '/', TDefaultTo extends string = ''> {
<TFrom extends RegisteredRoutesInfo['routePaths'] = TDefaultFrom, TTo extends string = TDefaultTo>(props: MakeLinkOptions<TFrom, TTo> & React$1.RefAttributes<HTMLAnchorElement>): ReactNode;
}
declare const Link: LinkFn;
declare function Navigate<TFrom extends RegisteredRoutesInfo['routePaths'] = '/', TTo extends string = ''>(props: NavigateOptions<RegisteredRoutesInfo, TFrom, TTo>): null;
type MatchesContextValue = AnyRouteMatch[];
declare const matchesContext: React$1.Context<MatchesContextValue>;
declare const routerContext: React$1.Context<{
router: RegisteredRouter;
}>;
type MatchesProviderProps = {
value: MatchesContextValue;
children: ReactNode;
};
type RouterProps<TRouteConfig extends AnyRoute = AnyRoute, TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo, TDehydrated extends Record<string, any> = Record<string, any>> = RouterOptions<TRouteConfig, TDehydrated> & {
router: Router<TRouteConfig, TRoutesInfo>;
};
declare function RouterProvider<TRouteConfig extends AnyRoute = AnyRoute, TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo, TDehydrated extends Record<string, any> = Record<string, any>>({ router, ...rest }: RouterProps<TRouteConfig, TRoutesInfo, TDehydrated>): JSX.Element;
declare function useRouterContext(): RegisteredRouter;
declare function useRouter<T = RouterState>(track?: (state: Router['__store']) => T): RegisteredRouter;
declare function useMatches(): RouteMatch[];
declare function useMatch<TFrom extends keyof RegisteredRoutesInfo['routesById'], TStrict extends boolean = true, TRouteMatch = RouteMatch<RegisteredRoutesInfo, RegisteredRoutesInfo['routesById'][TFrom]>>(opts?: {
from: TFrom;
strict?: TStrict;
track?: (match: TRouteMatch) => any;
}): TStrict extends true ? TRouteMatch : TRouteMatch | undefined;
type RouteFromIdOrRoute<T> = T extends RegisteredRoutesInfo['routeUnion'] ? T : T extends keyof RegisteredRoutesInfo['routesById'] ? RegisteredRoutesInfo['routesById'][T] : T extends string ? keyof RegisteredRoutesInfo['routesById'] : never;
declare function useLoader<TFrom extends keyof RegisteredRoutesInfo['routesById'], TStrict extends boolean = true, TLoader = RegisteredRoutesInfo['routesById'][TFrom]['__types']['loader'], TSelected = TLoader>(opts?: {
from: TFrom;
strict?: TStrict;
track?: (search: TLoader) => TSelected;
}): TStrict extends true ? TSelected : TSelected | undefined;
declare function useSearch<TFrom extends keyof RegisteredRoutesInfo['routesById'], TStrict extends boolean = true, TSearch = RegisteredRoutesInfo['routesById'][TFrom]['__types']['fullSearchSchema'], TSelected = TSearch>(opts?: {
from: TFrom;
strict?: TStrict;
track?: (search: TSearch) => TSelected;
}): TStrict extends true ? TSelected : TSelected | undefined;
declare function useParams<TFrom extends keyof RegisteredRoutesInfo['routesById'] = '/', TDefaultSelected = RegisteredRoutesInfo['allParams'] & RegisteredRoutesInfo['routesById'][TFrom]['__types']['allParams'], TSelected = TDefaultSelected>(opts?: {
from: TFrom;
track?: (search: TDefaultSelected) => TSelected;
}): TSelected;
declare function useNavigate<TDefaultFrom extends keyof RegisteredRoutesInfo['routesById'] = '/'>(defaultOpts?: {
from?: TDefaultFrom;
}): <TFrom extends string = TDefaultFrom, TTo extends string = "">(opts?: MakeLinkOptions<TFrom, TTo> | undefined) => Promise<void>;
declare function useMatchRoute(): <TFrom extends ValidFromPath<AnyRoutesInfo> = "/", TTo extends string = "">(opts: MakeUseMatchRouteOptions<TFrom, TTo>) => any;
declare function MatchRoute<TFrom extends ValidFromPath<RegisteredRoutesInfo> = '/', TTo extends string = ''>(props: MakeMatchRouteOptions<TFrom, TTo>): any;
declare function Outlet(): JSX.Element | null;
declare function ErrorComponent({ error }: {
error: any;
}): JSX.Element;
declare function useBlocker(message: string, condition?: boolean | any): void;
declare function Block({ message, condition, children }: PromptProps): any;
interface RouteMatchState<TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo, TRoute extends AnyRoute = Route> {
routeSearch: TRoute['__types']['searchSchema'];
search: TRoutesInfo['fullSearchSchema'] & TRoute['__types']['fullSearchSchema'];
status: 'idle' | 'pending' | 'success' | 'error';
error?: unknown;
updatedAt: number;
loader: TRoute['__types']['loader'];
}
interface PendingRouteMatchInfo {
state: RouteMatchState<any, any>;
routeContext: {};
context: {};
}
interface AnyRouteMatch extends RouteMatch<any, any> {
}
declare class RouteMatch<TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo, TRoute extends AnyRoute = AnyRoute> {
#private;
route: TRoute;
router: Router<TRoutesInfo['routeTree'], TRoutesInfo>;
__store: Store<RouteMatchState<TRoutesInfo, TRoute>>;
state: RouteMatchState<TRoutesInfo, TRoute>;
id: string;
pathname: string;
params: TRoute['__types']['allParams'];
routeContext?: TRoute['__types']['routeContext'];
context: TRoute['__types']['context'];
component?: RouteComponent<{
useLoader: TRoute['useLoader'];
useMatch: TRoute['useMatch'];
useContext: TRoute['useContext'];
useSearch: TRoute['useSearch'];
}>;
errorComponent?: RouteComponent<{
error: Error;
info: {
componentStack: string;
};
}>;
pendingComponent?: RouteComponent;
abortController: AbortController;
parentMatch?: RouteMatch;
pendingInfo?: PendingRouteMatchInfo;
__loadPromise?: Promise<void>;
__onExit?: void | ((matchContext: {
params: TRoute['__types']['allParams'];
search: TRoute['__types']['fullSearchSchema'];
}) => void);
constructor(router: AnyRouter, route: TRoute, opts: {
id: string;
params: TRoute['__types']['allParams'];
pathname: string;
});
__commit: () => void;
cancel: () => void;
__load: (opts: {
parentMatch: RouteMatch | undefined;
preload?: boolean;
location: ParsedLocation;
}) => Promise<void>;
}
declare const rootRouteId: "__root__";
type RootRouteId = typeof rootRouteId;
type AnyPathParams = {};
type AnySearchSchema = {};
type AnyContext = {};
interface RouteMeta {
}
interface RouteContext {
}
type RouteOptionsBase<TCustomId, TPath> = {
path: TPath;
} | {
id: TCustomId;
};
type RouteOptionsBaseIntersection<TCustomId, TPath> = UnionToIntersection<RouteOptionsBase<TCustomId, TPath>>;
type MetaOptions = keyof PickRequired<RouteMeta> extends never ? {
meta?: RouteMeta;
} : {
meta: RouteMeta;
};
type GetContextFn<TParentRoute, TAllParams, TFullSearchSchema, TParentContext, TAllParentContext, TRouteContext> = (opts: {
params: TAllParams;
search: TFullSearchSchema;
} & (TParentRoute extends undefined ? {
context?: TAllParentContext;
parentContext?: TParentContext;
} : {
context: TAllParentContext;
parentContext: TParentContext;
})) => TRouteContext;
type ContextOptions<TParentRoute, TAllParams, TFullSearchSchema, TParentContext, TAllParentContext, TRouteContext> = keyof PickRequired<RouteContext> extends never ? {
getContext?: GetContextFn<TParentRoute, TAllParams, TFullSearchSchema, TParentContext, TAllParentContext, TRouteContext>;
} : {
getContext: GetContextFn<TParentRoute, TAllParams, TFullSearchSchema, TParentContext, TAllParentContext, TRouteContext>;
};
type RouteProps<TParentRoute extends AnyRoute, TPath extends string, TFullPath extends ResolveFullPath<TParentRoute, TPath, RoutePrefix<TParentRoute['fullPath'], TPath>>, TCustomId extends string, TId extends ResolveId<TParentRoute, TCustomId, TPath>, TLoader, TSearchSchema extends AnySearchSchema, TFullSearchSchema extends AnySearchSchema, TAllParams, TParentContext, TAllParentContext extends IsAny<TParentRoute['__types']['allParams'], TParentContext, TParentRoute['__types']['allParams'] & TParentContext>, TRouteContext, TContext, TRouterContext extends AnyContext> = {
useMatch: () => RouteMatch<AnyRoutesInfo, Route<TParentRoute, TPath, TFullPath, TCustomId, TId, TLoader, TSearchSchema, TFullSearchSchema, TParentContext, TAllParentContext, TRouteContext, TContext, TRouterContext, any, any>>;
useLoader: () => TLoader;
useSearch: <TStrict extends boolean = true, TSearch = TFullSearchSchema, TSelected = TSearch>(opts?: {
strict?: TStrict;
track?: (search: TSearch) => TSelected;
}) => TStrict extends true ? TSelected : TSelected | undefined;
useParams: <TDefaultSelected = TAllParams, TSelected = TDefaultSelected>(opts?: {
track?: (search: TDefaultSelected) => TSelected;
}) => TSelected;
useContext: () => TContext;
};
type RouteOptions<TParentRoute extends AnyRoute = AnyRoute, TCustomId extends string = string, TPath extends string = string, TLoader = unknown, TParentSearchSchema extends {} = {}, TSearchSchema extends AnySearchSchema = {}, TFullSearchSchema extends AnySearchSchema = TSearchSchema, TParentParams extends AnyPathParams = {}, TParams = Record<ParsePathParams<TPath>, string>, TAllParams = TParams, TParentContext extends AnyContext = AnyContext, TAllParentContext extends IsAny<TParentRoute['__types']['allParams'], TParentContext, TParentRoute['__types']['allParams'] & TParentContext> = IsAny<TParentRoute['__types']['allParams'], TParentContext, TParentRoute['__types']['allParams'] & TParentContext>, TRouteContext extends RouteContext = RouteContext, TContext extends MergeFromParent<TAllParentContext, TRouteContext> = MergeFromParent<TAllParentContext, TRouteContext>> = RouteOptionsBase<TCustomId, TPath> & {
getParentRoute: () => TParentRoute;
caseSensitive?: boolean;
preSearchFilters?: SearchFilter<TFullSearchSchema>[];
postSearchFilters?: SearchFilter<TFullSearchSchema>[];
component?: RouteComponent<RouteProps<TParentRoute, TPath, ResolveFullPath<TParentRoute, TPath>, TCustomId, ResolveId<TParentRoute, TCustomId, TPath>, TLoader, TSearchSchema, TFullSearchSchema, TAllParams, TParentContext, TAllParentContext, TRouteContext, TContext, NoInfer<TRouteContext>>>;
errorComponent?: RouteComponent<{
error: Error;
info: {
componentStack: string;
};
}>;
pendingComponent?: RouteComponent<RouteProps<TParentRoute, TPath, ResolveFullPath<TParentRoute, TPath>, TCustomId, ResolveId<TParentRoute, TCustomId, TPath>, TLoader, TSearchSchema, TFullSearchSchema, TAllParams, TParentContext, TAllParentContext, TRouteContext, TContext, NoInfer<TRouteContext>>>;
wrapInSuspense?: boolean;
beforeLoad?: (opts: {
router: AnyRouter;
match: RouteMatch;
}) => Promise<void> | void;
onBeforeLoadError?: (err: any) => void;
validateSearch?: SearchSchemaValidator<TSearchSchema, TParentSearchSchema>;
onValidateSearchError?: (err: any) => void;
loader?: OnLoadFn<TLoader, TSearchSchema, TFullSearchSchema, TAllParams, NoInfer<TRouteContext>, TContext>;
onLoadError?: (err: any) => void;
onError?: (err: any) => void;
onLoaded?: (matchContext: {
params: TAllParams;
search: TFullSearchSchema;
}) => void | undefined | ((match: {
params: TAllParams;
search: TFullSearchSchema;
}) => void);
onTransition?: (match: {
params: TAllParams;
search: TFullSearchSchema;
}) => void;
} & MetaOptions & ContextOptions<TParentRoute, TAllParams, TFullSearchSchema, TParentContext, TAllParentContext, TRouteContext> & ({
parseParams?: (rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>) => TParams extends Record<ParsePathParams<TPath>, any> ? TParams : 'parseParams must return an object';
stringifyParams?: (params: NoInfer<TParams>) => Record<ParsePathParams<TPath>, string>;
} | {
stringifyParams?: never;
parseParams?: never;
}) & (PickUnsafe<TParentParams, ParsePathParams<TPath>> extends never ? {
test?: PickUnsafe<TParentParams, ParsePathParams<TPath>>;
} : 'Cannot redefined path params in child routes!');
type SearchSchemaValidator<TReturn, TParentSchema> = SearchSchemaValidatorObj<TReturn, TParentSchema> | SearchSchemaValidatorFn<TReturn, TParentSchema>;
type SearchSchemaValidatorObj<TReturn, TParentSchema> = {
parse?: SearchSchemaValidatorFn<TReturn, TParentSchema>;
};
type SearchSchemaValidatorFn<TReturn, TParentSchema> = (searchObj: Record<string, unknown>) => {} extends TParentSchema ? TReturn : keyof TReturn extends keyof TParentSchema ? {
error: 'Top level search params cannot be redefined by child routes!';
keys: keyof TReturn & keyof TParentSchema;
} : TReturn;
type DefinedPathParamWarning = 'Path params cannot be redefined by child routes!';
type ParentParams<TParentParams> = AnyPathParams extends TParentParams ? {} : {
[Key in keyof TParentParams]?: DefinedPathParamWarning;
};
type OnLoadFn<TLoader = unknown, TSearchSchema extends AnySearchSchema = {}, TFullSearchSchema extends AnySearchSchema = {}, TAllParams = {}, TContext extends AnyContext = AnyContext, TAllContext extends AnyContext = AnyContext> = (loaderContext: LoaderContext<TSearchSchema, TFullSearchSchema, TAllParams, TContext, TAllContext>) => Promise<TLoader> | TLoader;
interface LoaderContext<TSearchSchema extends AnySearchSchema = {}, TFullSearchSchema extends AnySearchSchema = {}, TAllParams = {}, TContext extends AnyContext = AnyContext, TAllContext extends AnyContext = AnyContext> {
params: TAllParams;
routeSearch: TSearchSchema;
search: TFullSearchSchema;
signal?: AbortSignal;
preload: boolean;
routeContext: TContext;
context: TAllContext;
}
type UnloaderFn<TPath extends string> = (routeMatch: RouteMatch<any, Route>) => void;
type SearchFilter<T, U = T> = (prev: T) => U;
type ResolveId<TParentRoute, TCustomId extends string, TPath extends string> = TParentRoute extends {
id: infer TParentId extends string;
} ? RoutePrefix<TParentId, string extends TCustomId ? TPath : TCustomId> : RootRouteId;
type InferFullSearchSchema<TRoute> = TRoute extends {
isRoot: true;
__types: {
searchSchema: infer TSearchSchema;
};
} ? TSearchSchema : TRoute extends {
__types: {
fullSearchSchema: infer TFullSearchSchema;
};
} ? TFullSearchSchema : {};
type ResolveFullSearchSchema<TParentRoute, TSearchSchema> = InferFullSearchSchema<TParentRoute> & TSearchSchema;
interface AnyRoute extends Route<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any> {
}
type MergeFromParent<T, U> = IsAny<T, U, T & U>;
declare class Route<TParentRoute extends AnyRoute = AnyRoute, TPath extends string = string, TFullPath extends ResolveFullPath<TParentRoute, TPath> = ResolveFullPath<TParentRoute, TPath>, TCustomId extends string = string, TId extends ResolveId<TParentRoute, TCustomId, TPath> = ResolveId<TParentRoute, TCustomId, TPath>, TLoader = unknown, TSearchSchema extends AnySearchSchema = {}, TFullSearchSchema extends AnySearchSchema = ResolveFullSearchSchema<TParentRoute, TSearchSchema>, TParams extends Record<ParsePathParams<TPath>, any> = Record<ParsePathParams<TPath>, string>, TAllParams extends MergeFromParent<TParentRoute['__types']['allParams'], TParams> = MergeFromParent<TParentRoute['__types']['allParams'], TParams>, TParentContext extends TParentRoute['__types']['routeContext'] = TParentRoute['__types']['routeContext'], TAllParentContext extends TParentRoute['__types']['context'] = TParentRoute['__types']['context'], TRouteContext extends RouteContext = RouteContext, TContext extends MergeFromParent<TParentRoute['__types']['context'], TRouteContext> = MergeFromParent<TParentRoute['__types']['context'], TRouteContext>, TRouterContext extends AnyContext = AnyContext, TChildren extends unknown = unknown, TRoutesInfo extends DefaultRoutesInfo = DefaultRoutesInfo> {
__types: {
parentRoute: TParentRoute;
path: TPath;
fullPath: TFullPath;
customId: TCustomId;
id: TId;
loader: TLoader;
searchSchema: TSearchSchema;
fullSearchSchema: TFullSearchSchema;
params: TParams;
allParams: TAllParams;
parentContext: TParentContext;
allParentContext: TAllParentContext;
routeContext: TRouteContext;
context: TContext;
children: TChildren;
routesInfo: TRoutesInfo;
routerContext: TRouterContext;
};
isRoot: TParentRoute extends Route<any> ? true : false;
options: RouteOptions<TParentRoute, TCustomId, TPath, TLoader, InferFullSearchSchema<TParentRoute>, TSearchSchema, InferFullSearchSchema<TParentRoute> & TSearchSchema, TParentRoute['__types']['allParams'], TParams, TAllParams, TParentContext, TAllParentContext, TRouteContext, TContext>;
parentRoute: TParentRoute;
id: TId;
path: TPath;
fullPath: TFullPath;
children?: TChildren;
originalIndex?: number;
router?: Router<TRoutesInfo['routeTree'], TRoutesInfo>;
constructor(options: RouteOptions<TParentRoute, TCustomId, TPath, TLoader, InferFullSearchSchema<TParentRoute>, TSearchSchema, TFullSearchSchema, TParentRoute['__types']['allParams'], TParams, TAllParams, TParentContext, TAllParentContext, TRouteContext, TContext>);
init: (opts: {
originalIndex: number;
router: AnyRouter;
}) => void;
addChildren: <TNewChildren extends AnyRoute[]>(children: TNewChildren) => Route<TParentRoute, TPath, TFullPath, TCustomId, TId, TLoader, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TParentContext, TAllParentContext, TRouteContext, TContext, TRouterContext, TNewChildren, TRoutesInfo>;
useMatch: <TStrict extends boolean = true, TSelected = TContext>(opts?: {
strict?: TStrict | undefined;
track?: ((search: TContext) => TSelected) | undefined;
} | undefined) => TStrict extends true ? TSelected : TSelected | undefined;
useLoader: <TStrict extends boolean = true, TSelected = TLoader>(opts?: {
strict?: TStrict | undefined;
track?: ((search: TLoader) => TSelected) | undefined;
} | undefined) => TStrict extends true ? TSelected : TSelected | undefined;
useContext: <TStrict extends boolean = true, TSelected = TContext>(opts?: {
strict?: TStrict | undefined;
track?: ((search: TContext) => TSelected) | undefined;
} | undefined) => TStrict extends true ? TSelected : TSelected | undefined;
useSearch: <TStrict extends boolean = true, TSelected = TFullSearchSchema>(opts?: {
strict?: TStrict | undefined;
track?: ((search: TFullSearchSchema) => TSelected) | undefined;
} | undefined) => TStrict extends true ? TSelected : TSelected | undefined;
}
type AnyRootRoute = RootRoute<any, any, any, any>;
declare class RootRoute<TLoader = unknown, TSearchSchema extends AnySearchSchema = {}, TContext extends RouteContext = RouteContext, TRouterContext extends {} = {}> extends Route<any, '/', '/', string, RootRouteId, TLoader, TSearchSchema, TSearchSchema, {}, {}, TRouterContext, TRouterContext, MergeFromParent<TRouterContext, TContext>, MergeFromParent<TRouterContext, TContext>, TRouterContext, any, any> {
constructor(options?: Omit<RouteOptions<AnyRoute, RootRouteId, '', TLoader, {}, TSearchSchema, NoInfer<TSearchSchema>, {}, TRouterContext, TRouterContext, TContext, NoInfer<TContext>>, 'path' | 'id' | 'getParentRoute' | 'caseSensitive' | 'parseParams' | 'stringifyParams'>);
static withRouterContext: <TRouterContext_1 extends {}>() => <TLoader_1 = unknown, TSearchSchema_1 extends AnySearchSchema = {}, TContext_1 extends {} = {}>(options?: Omit<RouteOptions<AnyRoute, "__root__", "", TLoader_1, {}, TSearchSchema_1, NoInfer<TSearchSchema_1>, {}, TRouterContext_1, TRouterContext_1, TContext_1, TRouterContext_1 & TContext_1, RouteContext, IsAny<TRouterContext_1 & TContext_1, RouteContext, TRouterContext_1 & TContext_1 & RouteContext>>, "caseSensitive" | "id" | "path" | "getParentRoute"> | undefined) => RootRoute<TLoader_1, TSearchSchema_1, TContext_1, TRouterContext_1>;
}
type ResolveFullPath<TParentRoute extends AnyRoute, TPath extends string, TPrefixed extends RoutePrefix<TParentRoute['fullPath'], TPath> = RoutePrefix<TParentRoute['fullPath'], TPath>> = TPrefixed extends RootRouteId ? '/' : TrimPathRight<`${TPrefixed}`>;
type RoutePrefix<TPrefix extends string, TId extends string> = string extends TId ? RootRouteId : TId extends string ? TPrefix extends RootRouteId ? TId extends '/' ? '/' : `/${TrimPath<TId>}` : `${TPrefix}/${TId}` extends '/' ? '/' : `/${TrimPathLeft<`${TrimPathRight<TPrefix>}/${TrimPath<TId>}`>}` : never;
type TrimPath<T extends string> = '' extends T ? '' : TrimPathRight<TrimPathLeft<T>>;
type TrimPathLeft<T extends string> = T extends `${RootRouteId}/${infer U}` ? TrimPathLeft<U> : T extends `/${infer U}` ? TrimPathLeft<U> : T;
type TrimPathRight<T extends string> = T extends '/' ? '/' : T extends `${infer U}/` ? TrimPathRight<U> : T;
interface AnyRoutesInfo {
routeTree: AnyRoute;
routeUnion: AnyRoute;
routesById: Record<string, AnyRoute>;
routesByFullPath: Record<string, AnyRoute>;
routeIds: any;
routePaths: any;
routeIntersection: AnyRoute;
fullSearchSchema: Record<string, any>;
allParams: Record<string, any>;
}
interface DefaultRoutesInfo {
routeTree: AnyRoute;
routeUnion: AnyRoute;
routesById: Record<string, Route>;
routesByFullPath: Record<string, Route>;
routeIds: string;
routePaths: string;
routeIntersection: AnyRoute;
fullSearchSchema: AnySearchSchema;
allParams: AnyPathParams;
}
interface RoutesInfo<TRouteTree extends AnyRoute = Route> extends RoutesInfoInner<TRouteTree, ParseRoute<TRouteTree>> {
}
interface RoutesInfoInner<TRouteTree extends AnyRoute, TRouteUnion extends AnyRoute = Route, TRoutesById = {
'/': TRouteUnion;
} & {
[TRoute in TRouteUnion as TRoute['id']]: TRoute;
}, TRoutesByFullPath = {
'/': TRouteUnion;
} & {
[TRoute in TRouteUnion as TRoute['fullPath'] extends RootRouteId ? never : string extends TRoute['fullPath'] ? never : TRoute['fullPath']]: TRoute;
}> {
routeTree: TRouteTree;
routeUnion: TRouteUnion;
routesById: TRoutesById;
routesByFullPath: TRoutesByFullPath;
routeIds: keyof TRoutesById;
routePaths: keyof TRoutesByFullPath;
routeIntersection: Route<TRouteUnion['__types']['parentRoute'], // TParentRoute,
TRouteUnion['__types']['path'], // TPath,
TRouteUnion['__types']['fullPath'], // TFullPath,
TRouteUnion['__types']['customId'], // TCustomId,
TRouteUnion['__types']['id'], // TId,
TRouteUnion['__types']['loader'], // TId,
// TId,
MergeUnion<TRouteUnion['__types']['searchSchema']> & {}, // TSearchSchema,
// TSearchSchema,
MergeUnion<TRouteUnion['__types']['fullSearchSchema']> & {}, // TFullSearchSchema,
MergeUnion<TRouteUnion['__types']['params']>, // TParams,
MergeUnion<TRouteUnion['__types']['allParams']>, // TAllParams,
MergeUnion<TRouteUnion['__types']['parentContext']>, // TParentContext,
MergeUnion<TRouteUnion['__types']['allParentContext']>, // TAllParentContext,
// TAllParentContext,
MergeUnion<TRouteUnion['__types']['routeContext']> & {}, // TRouteContext,
// TRouteContext,
MergeUnion<TRouteUnion['__types']['context']> & {}, // TContext,
// TContext,
MergeUnion<TRouteUnion['__types']['routerContext']> & {}, // TRouterContext,
TRouteUnion['__types']['children'], // TChildren,
TRouteUnion['__types']['routesInfo']>;
fullSearchSchema: Partial<MergeUnion<TRouteUnion['__types']['fullSearchSchema']>>;
allParams: Partial<MergeUnion<TRouteUnion['__types']['allParams']>>;
}
type ParseRoute<TRouteTree> = TRouteTree extends AnyRoute ? TRouteTree | ParseRouteChildren<TRouteTree> : never;
type ParseRouteChildren<TRouteTree> = TRouteTree extends Route<any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, infer TChildren, any> ? unknown extends TChildren ? never : TChildren extends AnyRoute[] ? Values<{
[TId in TChildren[number]['id']]: ParseRouteChild<TChildren[number], TId>;
}> : never : never;
type ParseRouteChild<TRoute, TId> = TRoute extends AnyRoute ? ParseRoute<TRoute> : never;
type RoutesById<TRoutesInfo extends AnyRoutesInfo> = {
[K in keyof TRoutesInfo['routesById']]: TRoutesInfo['routesById'][K];
};
type RouteById<TRoutesInfo extends AnyRoutesInfo, TId> = TId extends keyof TRoutesInfo['routesById'] ? IsAny<TRoutesInfo['routesById'][TId]['id'], Route, TRoutesInfo['routesById'][TId]> : never;
type RouteByPath<TRoutesInfo extends AnyRoutesInfo, TPath> = TPath extends keyof TRoutesInfo['routesByFullPath'] ? IsAny<TRoutesInfo['routesByFullPath'][TPath]['id'], Route, TRoutesInfo['routesByFullPath'][TPath]> : never;
type LinkInfo = {
type: 'external';
href: string;
} | {
type: 'internal';
next: ParsedLocation;
handleFocus: (e: any) => void;
handleClick: (e: any) => void;
handleEnter: (e: any) => void;
handleLeave: (e: any) => void;
handleTouchStart: (e: any) => void;
isActive: boolean;
disabled?: boolean;
};
type CleanPath<T extends string> = T extends `${infer L}//${infer R}` ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`> : T extends `${infer L}//` ? `${CleanPath<L>}/` : T extends `//${infer L}` ? `/${CleanPath<L>}` : T;
type Split<S, TIncludeTrailingSlash = true> = S extends unknown ? string extends S ? string[] : S extends string ? CleanPath<S> extends '' ? [] : TIncludeTrailingSlash extends true ? CleanPath<S> extends `${infer T}/` ? [...Split<T>, '/'] : CleanPath<S> extends `/${infer U}` ? Split<U> : CleanPath<S> extends `${infer T}/${infer U}` ? [...Split<T>, ...Split<U>] : [S] : CleanPath<S> extends `${infer T}/${infer U}` ? [...Split<T>, ...Split<U>] : S extends string ? [S] : never : never : never;
type ParsePathParams<T extends string> = Split<T>[number] extends infer U ? U extends `$${infer V}` ? V : never : never;
type Join<T> = T extends [] ? '' : T extends [infer L extends string] ? L : T extends [infer L extends string, ...infer Tail extends [...string[]]] ? CleanPath<`${L}/${Join<Tail>}`> : never;
type RelativeToPathAutoComplete<AllPaths extends string, TFrom extends string, TTo extends string, SplitPaths extends string[] = Split<AllPaths, false>> = TTo extends `..${infer _}` ? SplitPaths extends [
...Split<ResolveRelativePath<TFrom, TTo>, false>,
...infer TToRest
] ? `${CleanPath<Join<[
...Split<TTo, false>,
...(TToRest | (Split<ResolveRelativePath<TFrom, TTo>, false>['length'] extends 1 ? never : ['../']))
]>>}` : never : TTo extends `./${infer RestTTo}` ? SplitPaths extends [
...Split<TFrom, false>,
...Split<RestTTo, false>,
...infer RestPath
] ? `${TTo}${Join<RestPath>}` : never : (TFrom extends `/` ? never : SplitPaths extends [...Split<TFrom, false>, ...infer RestPath] ? Join<RestPath> extends {
length: 0;
} ? never : './' : never) | (TFrom extends `/` ? never : '../') | AllPaths;
type NavigateOptions<TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo, TFrom extends TRoutesInfo['routePaths'] = '/', TTo extends string = ''> = ToOptions<TRoutesInfo, TFrom, TTo> & {
replace?: boolean;
};
type ToOptions<TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo, TFrom extends TRoutesInfo['routePaths'] = '/', TTo extends string = '', TResolvedTo = ResolveRelativePath<TFrom, NoInfer<TTo>>> = {
to?: ToPathOption<TRoutesInfo, TFrom, TTo>;
hash?: Updater<string>;
state?: LocationState;
from?: TFrom;
} & CheckPath<TRoutesInfo, NoInfer<TResolvedTo>, {}> & SearchParamOptions<TRoutesInfo, TFrom, TResolvedTo> & PathParamOptions<TRoutesInfo, TFrom, TResolvedTo>;
type SearchParamOptions<TRoutesInfo extends AnyRoutesInfo, TFrom, TTo, TFromSchema = UnionToIntersection<TRoutesInfo['fullSearchSchema'] & RouteByPath<TRoutesInfo, TFrom> extends never ? {} : RouteByPath<TRoutesInfo, TFrom>['__types']['fullSearchSchema']>, TToSchema = Partial<RouteByPath<TRoutesInfo, TFrom>['__types']['fullSearchSchema']> & Omit<RouteByPath<TRoutesInfo, TTo>['__types']['fullSearchSchema'], keyof PickRequired<RouteByPath<TRoutesInfo, TFrom>['__types']['fullSearchSchema']>>, TFromFullSchema = UnionToIntersection<TRoutesInfo['fullSearchSchema'] & TFromSchema>, TToFullSchema = UnionToIntersection<TRoutesInfo['fullSearchSchema'] & TToSchema>> = keyof PickRequired<TToSchema> extends never ? {
search?: true | SearchReducer<TFromFullSchema, TToFullSchema>;
} : {
search: SearchReducer<TFromFullSchema, TToFullSchema>;
};
type SearchReducer<TFrom, TTo> = {
[TKey in keyof TTo]: TTo[TKey];
} | ((current: TFrom) => TTo);
type PathParamOptions<TRoutesInfo extends AnyRoutesInfo, TFrom, TTo, TFromSchema = UnionToIntersection<RouteByPath<TRoutesInfo, TFrom> extends never ? {} : RouteByPath<TRoutesInfo, TFrom>['__types']['allParams']>, TToSchema = Partial<RouteByPath<TRoutesInfo, TFrom>['__types']['allParams']> & Omit<RouteByPath<TRoutesInfo, TTo>['__types']['allParams'], keyof PickRequired<RouteByPath<TRoutesInfo, TFrom>['__types']['allParams']>>, TFromFullParams = UnionToIntersection<TRoutesInfo['allParams'] & TFromSchema>, TToFullParams = UnionToIntersection<TRoutesInfo['allParams'] & TToSchema>> = keyof PickRequired<TToSchema> extends never ? {
params?: ParamsReducer<TFromFullParams, TToFullParams>;
} : {
params: ParamsReducer<TFromFullParams, TToFullParams>;
};
type ParamsReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo);
type ToPathOption<TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo, TFrom extends TRoutesInfo['routePaths'] = '/', TTo extends string = ''> = TTo | RelativeToPathAutoComplete<TRoutesInfo['routePaths'], NoInfer<TFrom> extends string ? NoInfer<TFrom> : '', NoInfer<TTo> & string>;
type ToIdOption<TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo, TFrom extends TRoutesInfo['routePaths'] = '/', TTo extends string = ''> = TTo | RelativeToPathAutoComplete<TRoutesInfo['routeIds'], NoInfer<TFrom> extends string ? NoInfer<TFrom> : '', NoInfer<TTo> & string>;
interface ActiveOptions {
exact?: boolean;
includeHash?: boolean;
includeSearch?: boolean;
}
type LinkOptions<TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo, TFrom extends TRoutesInfo['routePaths'] = '/', TTo extends string = ''> = NavigateOptions<TRoutesInfo, TFrom, TTo> & {
target?: HTMLAnchorElement['target'];
activeOptions?: ActiveOptions;
preload?: false | 'intent';
preloadDelay?: number;
disabled?: boolean;
};
type CheckRelativePath<TRoutesInfo extends AnyRoutesInfo, TFrom, TTo> = TTo extends string ? TFrom extends string ? ResolveRelativePath<TFrom, TTo> extends TRoutesInfo['routePaths'] ? {} : {
Error: `${TFrom} + ${TTo} resolves to ${ResolveRelativePath<TFrom, TTo>}, which is not a valid route path.`;
'Valid Route Paths': TRoutesInfo['routePaths'];
} : {} : {};
type CheckPath<TRoutesInfo extends AnyRoutesInfo, TPath, TPass> = Exclude<TPath, TRoutesInfo['routePaths']> extends never ? TPass : CheckPathError<TRoutesInfo, Exclude<TPath, TRoutesInfo['routePaths']>>;
type CheckPathError<TRoutesInfo extends AnyRoutesInfo, TInvalids> = {
Error: `${TInvalids extends string ? TInvalids : never} is not a valid route path.`;
'Valid Route Paths': TRoutesInfo['routePaths'];
};
type CheckId<TRoutesInfo extends AnyRoutesInfo, TPath, TPass> = Exclude<TPath, TRoutesInfo['routeIds']> extends never ? TPass : CheckIdError<TRoutesInfo, Exclude<TPath, TRoutesInfo['routeIds']>>;
type CheckIdError<TRoutesInfo extends AnyRoutesInfo, TInvalids> = {
Error: `${TInvalids extends string ? TInvalids : never} is not a valid route ID.`;
'Valid Route IDs': TRoutesInfo['routeIds'];
};
type ResolveRelativePath<TFrom, TTo = '.'> = TFrom extends string ? TTo extends string ? TTo extends '.' ? TFrom : TTo extends `./` ? Join<[TFrom, '/']> : TTo extends `./${infer TRest}` ? ResolveRelativePath<TFrom, TRest> : TTo extends `/${infer TRest}` ? TTo : Split<TTo> extends ['..', ...infer ToRest] ? Split<TFrom> extends [...infer FromRest, infer FromTail] ? ToRest extends ['/'] ? Join<[...FromRest, '/']> : ResolveRelativePath<Join<FromRest>, Join<ToRest>> : never : Split<TTo> extends ['.', ...infer ToRest] ? ToRest extends ['/'] ? Join<[TFrom, '/']> : ResolveRelativePath<TFrom, Join<ToRest>> : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>> : never : never;
type ValidFromPath<TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo> = undefined | (string extends TRoutesInfo['routePaths'] ? string : TRoutesInfo['routePaths']);
interface Segment {
type: 'pathname' | 'param' | 'wildcard';
value: string;
}
declare function joinPaths(paths: (string | undefined)[]): string;
declare function cleanPath(path: string): string;
declare function trimPathLeft(path: string): string;
declare function trimPathRight(path: string): string;
declare function trimPath(path: string): string;
declare function resolvePath(basepath: string, base: string, to: string): string;
declare function parsePathname(pathname?: string): Segment[];
declare function interpolatePath(path: string | undefined, params: any, leaveWildcard?: boolean): string;
declare function matchPathname(basepath: string, currentPathname: string, matchLocation: Pick<MatchLocation, 'to' | 'fuzzy' | 'caseSensitive'>): AnyPathParams | undefined;
declare function matchByPath(basepath: string, from: string, matchLocation: Pick<MatchLocation, 'to' | 'caseSensitive' | 'fuzzy'>): Record<string, string> | undefined;
declare function encode(obj: any, pfx?: string): string;
declare function decode(str: any): {};
declare const defaultParseSearch: (searchStr: string) => AnySearchSchema;
declare const defaultStringifySearch: (search: Record<string, any>) => string;
declare function parseSearchWith(parser: (str: string) => any): (searchStr: string) => AnySearchSchema;
declare function stringifySearchWith(stringify: (search: any) => string): (search: Record<string, any>) => string;
export { ActiveOptions, AnyContext, AnyPathParams, AnyRedirect, AnyRootRoute, AnyRoute, AnyRouteMatch, AnyRouter, AnyRoutesInfo, AnySearchSchema, Block, BuildNextOptions, CheckId, CheckIdError, CheckPath, CheckPathError, CheckRelativePath, ContextOptions, DeepAwaited, DefaultRoutesInfo, DefinedPathParamWarning, DehydratedRouter, DehydratedRouterState, ErrorComponent, Expand, FilterRoutesFn, FromLocation, InferFullSearchSchema, IsAny, IsAnyBoolean, IsKnown, Link, LinkFn, LinkInfo, LinkOptions, LinkPropsOptions, ListenerFn, LoaderContext, LocationState, MakeLinkOptions, MakeLinkPropsOptions, MakeMatchRouteOptions, MakeUseMatchRouteOptions, MatchCache, MatchCacheEntry, MatchLocation, MatchRoute, MatchRouteOptions, MatchesProviderProps, MergeUnion, MetaOptions, Navigate, NavigateOptions, NoInfer, OnLoadFn, Outlet, ParentParams, ParsePathParams, ParseRoute, ParseRouteChild, ParseRouteChildren, ParsedLocation, ParsedPath, PathParamMask, PathParamOptions, PendingRouteMatchInfo, PickAsPartial, PickAsRequired, PickExclude, PickExtra, PickExtract, PickRequired, PickUnsafe, PromptProps, Redirect, Register, RegisteredRouter, RegisteredRoutesInfo, RelativeToPathAutoComplete, ResolveFullSearchSchema, ResolveRelativePath, RootRoute, RootRouteId, Route, RouteById, RouteByPath, RouteComponent, RouteContext, RouteFromIdOrRoute, RouteMatch, RouteMatchState, RouteMeta, RouteOptions, RouteOptionsBase, RouteOptionsBaseIntersection, RouteProps, Router, RouterConstructorOptions, RouterHistory, RouterLocation, RouterOptions, RouterProps, RouterProvider, RouterState, RoutesById, RoutesInfo, RoutesInfoInner, SearchFilter, SearchParamOptions, SearchParser, SearchSchemaValidator, SearchSchemaValidatorFn, SearchSchemaValidatorObj, SearchSerializer, Segment, Split, SyncRouteComponent, Timeout, ToIdOption, ToOptions, ToPathOption, UnionToIntersection, UnloaderFn, Updater, ValidFromPath, ValueKeys, Values, cleanPath, createBrowserHistory, createHashHistory, createMemoryHistory, decode, defaultFetchServerDataFn, defaultParseSearch, defaultStringifySearch, encode, functionalUpdate, interpolatePath, isPlainObject, isRedirect, joinPaths, last, lazy, matchByPath, matchPathname, matchesContext, parsePathname, parseSearchWith, partialDeepEqual, pick, redirect, replaceEqualDeep, resolvePath, rootRouteId, routerContext, stringifySearchWith, trimPath, trimPathLeft, trimPathRight, useBlocker, useLinkProps, useLoader, useMatch, useMatchRoute, useMatches, useNavigate, useParams, useRouter, useRouterContext, useSearch };
export * from './history';
export * from './link';
export * from './path';
export * from './qss';
export * from './route';
export * from './routeInfo';
export * from './routeMatch';
export * from './router';
export * from './searchParams';
export * from './utils';
export * from './react';

@@ -11,3 +11,3 @@ /**

*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react"),require("use-sync-external-store/shim/with-selector")):"function"==typeof define&&define.amd?define(["exports","react","use-sync-external-store/shim/with-selector"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).RouterCore={},t.React,t.withSelector)}(this,(function(t,e,r){"use strict";function o(t){if(t&&t.__esModule)return t;var e=Object.create(null);return t&&Object.keys(t).forEach((function(r){if("default"!==r){var o=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,o.get?o:{enumerable:!0,get:function(){return t[r]}})}})),e.default=t,Object.freeze(e)}var a=o(e);function s(t,e){if(!t)throw new Error("Invariant failed")}function n(t,e){}const i="popstate",c="beforeunload",h=t=>(t.preventDefault(),t.returnValue=""),u=()=>{removeEventListener(c,h,{capture:!0})};function l(t){let e=t.getLocation(),r=()=>{},o=new Set,a=[],s=[];const n=()=>{if(a.length)a[0]?.(n,(()=>{a=[],u()}));else{for(;s.length;)s.shift()?.();l()}},i=t=>{s.push(t),n()},l=()=>{e=t.getLocation(),o.forEach((t=>t()))};return{get location(){return e},listen:e=>(0===o.size&&(r=t.listener(l)),o.add(e),()=>{o.delete(e),0===o.size&&r()}),push:(e,r)=>{i((()=>{t.pushState(e,r)}))},replace:(e,r)=>{i((()=>{t.replaceState(e,r)}))},go:e=>{i((()=>{t.go(e)}))},back:()=>{i((()=>{t.back()}))},forward:()=>{i((()=>{t.forward()}))},createHref:e=>t.createHref(e),block:t=>(a.push(t),1===a.length&&addEventListener(c,h,{capture:!0}),()=>{a=a.filter((e=>e!==t)),a.length||u()})}}function d(t){const e=t?.getHref??(()=>`${window.location.pathname}${window.location.hash}${window.location.search}`),r=t?.createHref??(t=>t);return l({getLocation:()=>f(e(),history.state),listener:t=>(window.addEventListener(i,t),()=>{window.removeEventListener(i,t)}),pushState:(t,e)=>{window.history.pushState({...e,key:m()},"",r(t))},replaceState:(t,e)=>{window.history.replaceState({...e,key:m()},"",r(t))},back:()=>window.history.back(),forward:()=>window.history.forward(),go:t=>window.history.go(t),createHref:t=>r(t)})}function p(t={initialEntries:["/"]}){const e=t.initialEntries;let r=t.initialIndex??e.length-1,o={};return l({getLocation:()=>f(e[r],o),listener:()=>()=>{},pushState:(t,a)=>{o={...a,key:m()},e.push(t),r++},replaceState:(t,a)=>{o={...a,key:m()},e[r]=t},back:()=>{r--},forward:()=>{r=Math.min(r+1,e.length-1)},go:t=>window.history.go(t),createHref:t=>t})}function f(t,e){let r=t.indexOf("#"),o=t.indexOf("?");return{href:t,pathname:t.substring(0,r>0?o>0?Math.min(r,o):r:o>0?o:t.length),hash:r>-1?t.substring(r,o):"",search:o>-1?t.substring(o):"",state:e}}function m(){return(Math.random()+1).toString(36).substring(7)}function y(t){return t[t.length-1]}function g(t,e){return"function"==typeof t?t(e):t}function v(t,e){if(t===e)return t;const r=e,o=Array.isArray(t)&&Array.isArray(r);if(o||w(t)&&w(r)){const e=o?t.length:Object.keys(t).length,a=o?r:Object.keys(r),s=a.length,n=o?[]:{};let i=0;for(let e=0;e<s;e++){const s=o?e:a[e];n[s]=v(t[s],r[s]),n[s]===t[s]&&i++}return e===s&&i===e?t:n}return r}function w(t){if(!_(t))return!1;const e=t.constructor;if(void 0===e)return!0;const r=e.prototype;return!!_(r)&&!!r.hasOwnProperty("isPrototypeOf")}function _(t){return"[object Object]"===Object.prototype.toString.call(t)}function b(t,e){return t===e||typeof t==typeof e&&(w(t)&&w(e)?!Object.keys(e).some((r=>!b(t[r],e[r]))):!(!Array.isArray(t)||!Array.isArray(e))&&(t.length===e.length&&t.every(((t,r)=>b(t,e[r])))))}function S(t){return L(t.filter(Boolean).join("/"))}function L(t){return t.replace(/\/{2,}/g,"/")}function E(t){return"/"===t?t:t.replace(/^\/{1,}/,"")}function x(t){return"/"===t?t:t.replace(/\/{1,}$/,"")}function P(t){return x(E(t))}function C(t,e,r){e=e.replace(new RegExp(`^${t}`),"/"),r=r.replace(new RegExp(`^${t}`),"/");let o=R(e);const a=R(r);a.forEach(((t,e)=>{if("/"===t.value)e?e===a.length-1&&o.push(t):o=[t];else if(".."===t.value)o.length>1&&"/"===y(o)?.value&&o.pop(),o.pop();else{if("."===t.value)return;o.push(t)}}));return L(S([t,...o.map((t=>t.value))]))}function R(t){if(!t)return[];const e=[];if("/"===(t=L(t)).slice(0,1)&&(t=t.substring(1),e.push({type:"pathname",value:"/"})),!t)return e;const r=t.split("/").filter(Boolean);return e.push(...r.map((t=>"$"===t||"*"===t?{type:"wildcard",value:t}:"$"===t.charAt(0)?{type:"param",value:t}:{type:"pathname",value:t}))),"/"===t.slice(-1)&&(t=t.substring(1),e.push({type:"pathname",value:"/"})),e}function M(t,e,r){return S(R(t).map((t=>["$","*"].includes(t.value)&&!r?"":"param"===t.type?e[t.value.substring(1)]??"":t.value)))}function k(t,e,r){const o=O(t,e,r);if(!r.to||o)return o??{}}function O(t,e,r){if(!e.startsWith(t))return;const o=R(e="/"!=t?e.substring(t.length):e),a=R(`${r.to??"$"}`);"/"===y(o)?.value&&o.pop();const s={};return(()=>{for(let t=0;t<Math.max(o.length,a.length);t++){const e=o[t],n=a[t],i=t===a.length-1,c=t===o.length-1;if(n){if("wildcard"===n.type)return!!e?.value&&(s["*"]=S(o.slice(t).map((t=>t.value))),!0);if("pathname"===n.type){if("/"===n.value&&!e?.value)return!0;if(e)if(r.caseSensitive){if(n.value!==e.value)return!1}else if(n.value.toLowerCase()!==e.value.toLowerCase())return!1}if(!e)return!1;if("param"===n.type){if("/"===e?.value)return!1;"$"!==e.value.charAt(0)&&(s[n.value.substring(1)]=e.value)}}if(i&&!c)return!!r.fuzzy}return!0})()?s:void 0}function j(t,e){var r,o,a,s="";for(r in t)if(void 0!==(a=t[r]))if(Array.isArray(a))for(o=0;o<a.length;o++)s&&(s+="&"),s+=encodeURIComponent(r)+"="+encodeURIComponent(a[o]);else s&&(s+="&"),s+=encodeURIComponent(r)+"="+encodeURIComponent(a);return(e||"")+s}function A(t){if(!t)return"";var e=decodeURIComponent(t);return"false"!==e&&("true"===e||("0"===e.charAt(0)?e:0*+e==0?+e:e))}function I(t){for(var e,r,o={},a=t.split("&");e=a.shift();)void 0!==o[r=(e=e.split("=")).shift()]?o[r]=[].concat(o[r],A(e.shift())):o[r]=A(e.shift());return o}function $(){return $=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(t[o]=r[o])}return t},$.apply(this,arguments)}
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react"),require("use-sync-external-store/shim/with-selector")):"function"==typeof define&&define.amd?define(["exports","react","use-sync-external-store/shim/with-selector"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).RouterCore={},t.React,t.withSelector)}(this,(function(t,e,r){"use strict";function o(t){if(t&&t.__esModule)return t;var e=Object.create(null);return t&&Object.keys(t).forEach((function(r){if("default"!==r){var o=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,o.get?o:{enumerable:!0,get:function(){return t[r]}})}})),e.default=t,Object.freeze(e)}var a=o(e);function s(t,e){if(!t)throw new Error("Invariant failed")}function n(t,e){}const i="popstate",c="beforeunload",h=t=>(t.preventDefault(),t.returnValue=""),u=()=>{removeEventListener(c,h,{capture:!0})};function l(t){let e=t.getLocation(),r=()=>{},o=new Set,a=[],s=[];const n=()=>{if(a.length)a[0]?.(n,(()=>{a=[],u()}));else{for(;s.length;)s.shift()?.();l()}},i=t=>{s.push(t),n()},l=()=>{e=t.getLocation(),o.forEach((t=>t()))};return{get location(){return e},listen:e=>(0===o.size&&(r=t.listener(l)),o.add(e),()=>{o.delete(e),0===o.size&&r()}),push:(e,r)=>{i((()=>{t.pushState(e,r)}))},replace:(e,r)=>{i((()=>{t.replaceState(e,r)}))},go:e=>{i((()=>{t.go(e)}))},back:()=>{i((()=>{t.back()}))},forward:()=>{i((()=>{t.forward()}))},createHref:e=>t.createHref(e),block:t=>(a.push(t),1===a.length&&addEventListener(c,h,{capture:!0}),()=>{a=a.filter((e=>e!==t)),a.length||u()})}}function d(t){const e=t?.getHref??(()=>`${window.location.pathname}${window.location.hash}${window.location.search}`),r=t?.createHref??(t=>t);return l({getLocation:()=>f(e(),history.state),listener:t=>(window.addEventListener(i,t),()=>{window.removeEventListener(i,t)}),pushState:(t,e)=>{window.history.pushState({...e,key:m()},"",r(t))},replaceState:(t,e)=>{window.history.replaceState({...e,key:m()},"",r(t))},back:()=>window.history.back(),forward:()=>window.history.forward(),go:t=>window.history.go(t),createHref:t=>r(t)})}function p(t={initialEntries:["/"]}){const e=t.initialEntries;let r=t.initialIndex??e.length-1,o={};return l({getLocation:()=>f(e[r],o),listener:()=>()=>{},pushState:(t,a)=>{o={...a,key:m()},e.push(t),r++},replaceState:(t,a)=>{o={...a,key:m()},e[r]=t},back:()=>{r--},forward:()=>{r=Math.min(r+1,e.length-1)},go:t=>window.history.go(t),createHref:t=>t})}function f(t,e){let r=t.indexOf("#"),o=t.indexOf("?");return{href:t,pathname:t.substring(0,r>0?o>0?Math.min(r,o):r:o>0?o:t.length),hash:r>-1?t.substring(r,o):"",search:o>-1?t.substring(o):"",state:e}}function m(){return(Math.random()+1).toString(36).substring(7)}function y(t){return t[t.length-1]}function g(t,e){return"function"==typeof t?t(e):t}function v(t,e){if(t===e)return t;const r=e,o=Array.isArray(t)&&Array.isArray(r);if(o||_(t)&&_(r)){const e=o?t.length:Object.keys(t).length,a=o?r:Object.keys(r),s=a.length,n=o?[]:{};let i=0;for(let e=0;e<s;e++){const s=o?e:a[e];n[s]=v(t[s],r[s]),n[s]===t[s]&&i++}return e===s&&i===e?t:n}return r}function _(t){if(!w(t))return!1;const e=t.constructor;if(void 0===e)return!0;const r=e.prototype;return!!w(r)&&!!r.hasOwnProperty("isPrototypeOf")}function w(t){return"[object Object]"===Object.prototype.toString.call(t)}function b(t,e){return t===e||typeof t==typeof e&&(_(t)&&_(e)?!Object.keys(e).some((r=>!b(t[r],e[r]))):!(!Array.isArray(t)||!Array.isArray(e))&&(t.length===e.length&&t.every(((t,r)=>b(t,e[r])))))}function S(t){return L(t.filter(Boolean).join("/"))}function L(t){return t.replace(/\/{2,}/g,"/")}function E(t){return"/"===t?t:t.replace(/^\/{1,}/,"")}function x(t){return"/"===t?t:t.replace(/\/{1,}$/,"")}function P(t){return x(E(t))}function C(t,e,r){e=e.replace(new RegExp(`^${t}`),"/"),r=r.replace(new RegExp(`^${t}`),"/");let o=R(e);const a=R(r);a.forEach(((t,e)=>{if("/"===t.value)e?e===a.length-1&&o.push(t):o=[t];else if(".."===t.value)o.length>1&&"/"===y(o)?.value&&o.pop(),o.pop();else{if("."===t.value)return;o.push(t)}}));return L(S([t,...o.map((t=>t.value))]))}function R(t){if(!t)return[];const e=[];if("/"===(t=L(t)).slice(0,1)&&(t=t.substring(1),e.push({type:"pathname",value:"/"})),!t)return e;const r=t.split("/").filter(Boolean);return e.push(...r.map((t=>"$"===t||"*"===t?{type:"wildcard",value:t}:"$"===t.charAt(0)?{type:"param",value:t}:{type:"pathname",value:t}))),"/"===t.slice(-1)&&(t=t.substring(1),e.push({type:"pathname",value:"/"})),e}function M(t,e,r){return S(R(t).map((t=>["$","*"].includes(t.value)&&!r?"":"param"===t.type?e[t.value.substring(1)]??"":t.value)))}function k(t,e,r){const o=O(t,e,r);if(!r.to||o)return o??{}}function O(t,e,r){e="/"!=t?e.substring(t.length):e;const o=`${r.to??"$"}`,a=R(e),s=R(o);e.startsWith("/")||a.unshift({type:"pathname",value:"/"}),o.startsWith("/")||s.unshift({type:"pathname",value:"/"});const n={};return(()=>{for(let t=0;t<Math.max(a.length,s.length);t++){const e=a[t],o=s[t],i=t>=a.length-1,c=t>=s.length-1;if(o){if("wildcard"===o.type)return!!e?.value&&(n["*"]=S(a.slice(t).map((t=>t.value))),!0);if("pathname"===o.type){if("/"===o.value&&!e?.value)return!0;if(e)if(r.caseSensitive){if(o.value!==e.value)return!1}else if(o.value.toLowerCase()!==e.value.toLowerCase())return!1}if(!e)return!1;if("param"===o.type){if("/"===e?.value)return!1;"$"!==e.value.charAt(0)&&(n[o.value.substring(1)]=e.value)}}if(!i&&c)return!!r.fuzzy}return!0})()?n:void 0}function j(t,e){var r,o,a,s="";for(r in t)if(void 0!==(a=t[r]))if(Array.isArray(a))for(o=0;o<a.length;o++)s&&(s+="&"),s+=encodeURIComponent(r)+"="+encodeURIComponent(a[o]);else s&&(s+="&"),s+=encodeURIComponent(r)+"="+encodeURIComponent(a);return(e||"")+s}function A(t){if(!t)return"";var e=decodeURIComponent(t);return"false"!==e&&("true"===e||("0"===e.charAt(0)?e:0*+e==0?+e:e))}function I(t){for(var e,r,o={},a=t.split("&");e=a.shift();)void 0!==o[r=(e=e.split("=")).shift()]?o[r]=[].concat(o[r],A(e.shift())):o[r]=A(e.shift());return o}function $(){return $=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(t[o]=r[o])}return t},$.apply(this,arguments)}
/**

@@ -22,3 +22,3 @@ * store

* @license MIT
*/class D{listeners=new Set;#t=!1;#e=0;constructor(t,e){this.state=t,this.options=e,this.options?.onUpdate&&this.subscribe(this.options?.onUpdate)}subscribe=t=>{this.listeners.add(t);const e=this.options?.onSubscribe?.(t,this);return()=>{this.listeners.delete(t),e?.()}};setState=t=>{const e=this.state;this.state=this.options?.updateFn?this.options.updateFn(e)(t):t(e),this.#r()};#r=()=>{if(this.#t)return;const t=++this.#e;this.listeners.forEach((e=>{this.#e===t&&e()}))};batch=t=>{if(this.#t)return t();this.#t=!0,t(),this.#t=!1,this.#r()}}
*/class D{listeners=new Set;_batching=!1;_flushing=0;constructor(t,e){this.state=t,this.options=e}subscribe=t=>{this.listeners.add(t);const e=this.options?.onSubscribe?.(t,this);return()=>{this.listeners.delete(t),e?.()}};setState=t=>{const e=this.state;this.state=this.options?.updateFn?this.options.updateFn(e)(t):t(e),this.options?.onUpdate?.(),this._flush()};_flush=()=>{if(this._batching)return;const t=++this._flushing;this.listeners.forEach((e=>{this._flushing===t&&e()}))};batch=t=>{if(this._batching)return t();this._batching=!0,t(),this._batching=!1,this._flush()}}
/**

@@ -33,3 +33,3 @@ * react-store

* @license MIT
*/function T(t,e=(t=>t)){return r.useSyncExternalStoreWithSelector(t.subscribe,(()=>t.state),(()=>t.state),e,N)}function N(t,e){if(Object.is(t,e))return!0;if("object"!=typeof t||null===t||"object"!=typeof e||null===e)return!1;const r=Object.keys(t);if(r.length!==Object.keys(e).length)return!1;for(let o=0;o<r.length;o++)if(!Object.prototype.hasOwnProperty.call(e,r[o])||!Object.is(t[r[o]],e[r[o]]))return!1;return!0}function H(t){const e=z(),{type:r,children:o,target:s,activeProps:n=(()=>({className:"active"})),inactiveProps:i=(()=>({})),activeOptions:c,disabled:h,hash:u,search:l,params:d,to:p=".",preload:f,preloadDelay:m,replace:y,style:v,className:w,onClick:_,onFocus:b,onMouseEnter:S,onMouseLeave:L,onTouchStart:E,...x}=t,P=e.buildLink(t);if("external"===P.type){const{href:t}=P;return{href:t}}const{handleClick:C,handleFocus:R,handleEnter:M,handleLeave:k,handleTouchStart:O,isActive:j,next:A}=P,I=t=>e=>{e.persist&&e.persist(),t.filter(Boolean).forEach((t=>{e.defaultPrevented||t(e)}))},$=j?g(n,{})??{}:{},D=j?{}:g(i,{})??{};return{...$,...D,...x,href:h?void 0:A.href,onClick:I([_,t=>{a.startTransition?a.startTransition((()=>{C(t)})):C(t)}]),onFocus:I([b,R]),onMouseEnter:I([S,M]),onMouseLeave:I([L,k]),onTouchStart:I([E,O]),target:s,style:{...v,...$.style,...D.style},className:[w,$.className,D.className].filter(Boolean).join(" ")||void 0,...h?{role:"link","aria-disabled":!0}:void 0,"data-status":j?"active":void 0}}const B=a.forwardRef(((t,e)=>{const r=H(t);return a.createElement("a",$({ref:e},r,{children:"function"==typeof t.children?t.children({isActive:"active"===r["data-status"]}):t.children}))}));const F=a.createContext(null),U=a.createContext(null);function z(){const t=a.useContext(U);return T(t.router.__store),t.router}function W(t){const e=z();return T(e.__store,t),e}function q(){return a.useContext(F)}function K(t){const e=z(),r=q()[0],o=t?.from?e.state.currentMatches.find((e=>e.route.id===t?.from)):r;return s(o,t?.from&&t.from),(t?.strict??1)&&s(r.route.id==o?.route.id,(o?.route.id,r.route.id,o?.route.id,o?.route.id)),T(o.__store,(e=>t?.track?.(o)??o)),o}function V(t){const{track:e,...r}=t,o=K(r);return T(o.__store,(e=>t?.track?.(e.loader)??e.loader)),o.state.loader}function J(t){const{track:e,...r}=t,o=K(r);return T(o.__store,(e=>t?.track?.(e.search)??e.search)),o.state.search}function G(){const t=z();return a.useCallback((e=>{const{pending:r,caseSensitive:o,...a}=e;return t.matchRoute(a,{pending:r,caseSensitive:o})}),[])}function Y(){const t=q().slice(1),e=t[0];return e?a.createElement(Q,{matches:t,match:e}):null}function Q({matches:t,match:e}){const r=z();T(e.__store,(t=>[t.status,t.error]));const o=a.useCallback((()=>null),[]),s=e.pendingComponent??r.options.defaultPendingComponent??o,n=e.errorComponent??r.options.defaultErrorComponent,i=e.route.options.wrapInSuspense??1?a.Suspense:Z,c=n?tt:Z;return a.createElement(F.Provider,{value:t},a.createElement(i,{fallback:a.createElement(s,null)},a.createElement(c,{key:e.route.id,errorComponent:n,onCatch:()=>{e.id}},a.createElement(X,{match:e}))))}function X(t){const e=z();if("error"===t.match.state.status)throw t.match.state.error;if("pending"===t.match.state.status)throw t.match.__loadPromise;if("success"===t.match.state.status)return a.createElement(t.match.component??e.options.defaultComponent??Y,{useLoader:t.match.route.useLoader,useMatch:t.match.route.useMatch,useContext:t.match.route.useContext,useSearch:t.match.route.useSearch});s(!1)}function Z(t){return a.createElement(a.Fragment,null,t.children)}class tt extends a.Component{state={error:!1,info:void 0};componentDidCatch(t,e){this.props.onCatch(t,e),console.error(t),this.setState({error:t,info:e})}render(){return a.createElement(et,$({},this.props,{errorState:this.state,reset:()=>this.setState({})}))}}function et(t){const[e,r]=a.useState(t.errorState),o=z(),s=t.errorComponent??rt,n=a.useRef("");return a.useEffect((()=>{e&&o.state.currentLocation.key!==n.current&&r({}),n.current=o.state.currentLocation.key}),[e,o.state.currentLocation.key]),a.useEffect((()=>{t.errorState.error&&r(t.errorState)}),[t.errorState.error]),t.errorState.error&&e.error?a.createElement(s,e):t.children}function rt({error:t}){return a.createElement("div",{style:{padding:".5rem",maxWidth:"100%"}},a.createElement("strong",{style:{fontSize:"1.2rem"}},"Something went wrong!"),a.createElement("div",{style:{height:".5rem"}}),a.createElement("div",null,a.createElement("pre",{style:{fontSize:".7em",border:"1px solid red",borderRadius:".25rem",padding:".5rem",color:"red",overflow:"auto"}},t.message?a.createElement("code",null,t.message):null)))}function ot(t,e=!0){const r=W();a.useEffect((()=>{if(!e)return;let o=r.history.block(((e,r)=>{window.confirm(t)?(o(),e()):r()}));return o}))}const at="__root__";class st{constructor(t){this.options=t||{},this.isRoot=!t?.getParentRoute}init=t=>{this.originalIndex=t.originalIndex,this.router=t.router;const e=this.options,r=!e?.path&&!e?.id;this.parentRoute=this.options?.getParentRoute?.(),r?this.path=at:s(this.parentRoute);let o=r?at:e.path;o&&"/"!==o&&(o=P(o));const a=e?.id||o;let n=r?at:S([this.parentRoute.id===at?"":this.parentRoute.id,a]);o===at&&(o="/"),n!==at&&(n=S(["/",n]));const i=n===at?"/":x(S([this.parentRoute.fullPath,o]));this.path=o,this.id=n,this.fullPath=i};addChildren=t=>(this.children=t,this);useMatch=t=>K({...t,from:this.id});useLoader=t=>V({...t,from:this.id});useContext=t=>K({...t,from:this.id}).context;useSearch=t=>J({...t,from:this.id})}class nt extends st{constructor(t){super(t)}static withRouterContext=()=>t=>new nt(t)}const it=ht(JSON.parse),ct=ut(JSON.stringify);function ht(t){return e=>{"?"===e.substring(0,1)&&(e=e.substring(1));let r=I(e);for(let e in r){const o=r[e];if("string"==typeof o)try{r[e]=t(o)}catch(t){}}return r}}function ut(t){return e=>{(e={...e})&&Object.keys(e).forEach((r=>{const o=e[r];if(void 0===o||void 0===o)delete e[r];else if(o&&"object"==typeof o&&null!==o)try{e[r]=t(o)}catch(t){}}));const r=j(e).toString();return r?`?${r}`:""}}const lt=async({router:t,routeMatch:e})=>{const r=t.buildNext({to:".",search:t=>({...t??{},__data:{matchId:e.id}})}),o=await fetch(r.href,{method:"GET",signal:e.abortController.signal});if(o.ok)return o.json();throw new Error("Failed to fetch match data")};const dt="undefined"==typeof window||!window.document.createElement;function pt(){return{status:"idle",latestLocation:null,currentLocation:null,currentMatches:[],lastUpdated:Date.now()}}function ft(t){return!!t?.isRedirect}const mt=["component","errorComponent","pendingComponent"];class yt{abortController=new AbortController;constructor(t,e,r){Object.assign(this,{route:e,router:t,id:r.id,pathname:r.pathname,params:r.params,__store:new D({updatedAt:0,routeSearch:{},search:{},status:"idle",loader:void 0},{onUpdate:()=>{this.state=this.__store.state}})}),this.state=this.__store.state,mt.map((async t=>{const e=this.route.options[t];this[t]=e})),"idle"!==this.state.status||this.#o()||this.__store.setState((t=>({...t,status:"success"})))}#o=()=>!(!this.route.options.loader&&!mt.some((t=>this.route.options[t]?.preload)));__commit=()=>{const{routeSearch:t,search:e,context:r,routeContext:o}=this.#a({location:this.router.state.currentLocation});this.context=r,this.routeContext=o,this.__store.setState((r=>({...r,routeSearch:v(r.routeSearch,t),search:v(r.search,e)})))};cancel=()=>{this.abortController?.abort()};#s=t=>{const e=this.parentMatch?this.parentMatch.#s(t):{search:t.location.search,routeSearch:t.location.search};try{const t=("object"==typeof this.route.options.validateSearch?this.route.options.validateSearch.parse:this.route.options.validateSearch)?.(e.search)??{};return{routeSearch:t,search:{...e.search,...t}}}catch(t){if(ft(t))throw t;(this.route.options.onValidateSearchError??this.route.options.onError)?.(t);const e=new Error("Invalid search params found",{cause:t});throw e.code="INVALID_SEARCH_PARAMS",e}};#a=t=>{const{search:e,routeSearch:r}=this.#s(t);try{const t=this.route.options.getContext?.({parentContext:this.parentMatch?.routeContext??{},context:this.parentMatch?.context??this.router?.options.context??{},params:this.params,search:e})||{};return{routeSearch:r,search:e,context:{...this.parentMatch?.context??this.router?.options.context,...t},routeContext:t}}catch(t){throw this.route.options.onError?.(t),t}};__load=async t=>{let e;this.parentMatch=t.parentMatch;try{e=this.#a(t)}catch(e){return ft(e)?void(t?.preload||this.router.navigate(e)):void this.__store.setState((t=>({...t,status:"error",error:e})))}const{routeSearch:r,search:o,context:a,routeContext:s}=e;if("pending"!==this.state.status)return this.__loadPromise=Promise.resolve().then((async()=>{const e=""+Date.now()+Math.random();this.#n=e;const n=()=>e!==this.#n?this.__loadPromise:void 0;let i;"idle"===this.state.status&&this.__store.setState((t=>({...t,status:"pending"})));const c=(async()=>{await Promise.all(mt.map((async t=>{const e=this.route.options[t];e?.preload&&await e.preload()})))})(),h=Promise.resolve().then((()=>{if(this.route.options.loader)return this.route.options.loader({params:this.params,routeSearch:r,search:o,signal:this.abortController.signal,preload:!!t?.preload,routeContext:s,context:a})}));try{const[t,e]=await Promise.all([c,h]);if(i=n())return await i;this.__store.setState((t=>({...t,error:void 0,status:"success",updatedAt:Date.now(),loader:e})))}catch(e){if(ft(e))return void(t?.preload||this.router.navigate(e));const r=this.route.options.onLoadError??this.route.options.onError;try{r?.(e)}catch(e){return ft(e)?void(t?.preload||this.router.navigate(e)):void this.__store.setState((t=>({...t,error:e,status:"error",updatedAt:Date.now()})))}this.__store.setState((t=>({...t,error:e,status:"error",updatedAt:Date.now()})))}finally{delete this.__loadPromise}})),this.__loadPromise};#n=""}t.Block=function({message:t,condition:e,children:r}){return ot(t,e),r??null},t.ErrorComponent=rt,t.Link=B,t.MatchRoute=function(t){const e=G()(t);return e?"function"==typeof t.children?t.children(e):e?t.children:null:null},t.Navigate=function(t){const e=z();return a.useLayoutEffect((()=>{e.navigate(t)}),[]),null},t.Outlet=Y,t.RootRoute=nt,t.Route=st,t.RouteMatch=yt,t.Router=class{#i;startedLoadingAt=Date.now();resolveNavigation=()=>{};constructor(t){this.options={defaultPreloadDelay:50,context:void 0,...t,stringifySearch:t?.stringifySearch??ct,parseSearch:t?.parseSearch??it,fetchServerDataFn:t?.fetchServerDataFn??lt},this.__store=new D(pt(),{onUpdate:()=>{this.state=this.__store.state}}),this.state=this.__store.state,this.update(t);const e=this.buildNext({hash:!0,fromCurrent:!0,search:!0,state:!0});this.state.latestLocation.href!==e.href&&this.#c({...e,replace:!0})}reset=()=>{this.__store.setState((t=>Object.assign(t,pt())))};mount=()=>(dt||this.state.currentMatches.length||this.safeLoad(),()=>{});hydrate=async t=>{let e=t;return"undefined"!=typeof document&&(e=window.__DEHYDRATED__,s(e)),this.options.hydrate?.(e),await this.load()};update=t=>{if(Object.assign(this.options,t),this.context=this.options.context,!this.history||this.options.history&&this.options.history!==this.history){this.#i&&this.#i(),this.history=this.options.history??(dt?p():d());const t=this.#h();this.__store.setState((e=>({...e,latestLocation:t,currentLocation:t}))),this.#i=this.history.listen((()=>{this.safeLoad({next:this.#h(this.state.latestLocation)})}))}const{basepath:e,routeTree:r}=this.options;return this.basepath=`/${P(e??"")??""}`,r&&(this.routesById={},this.routeTree=this.#u(r)),this};buildNext=t=>{const e=this.#l(t),r=this.matchRoutes(e.pathname);return this.#l({...t,__matches:r})};cancelMatches=()=>{[...this.state.currentMatches,...this.state.pendingMatches||[]].forEach((t=>{t.cancel()}))};safeLoad=t=>{this.load(t).catch((t=>{console.warn(t),s(!1)}))};load=async t=>{let e=Date.now();const r=e;let o;if(this.startedLoadingAt=r,this.cancelMatches(),this.__store.batch((()=>{t?.next&&this.__store.setState((e=>({...e,latestLocation:t.next}))),o=this.matchRoutes(this.state.latestLocation.pathname,{strictParseParams:!0}),this.__store.setState((t=>({...t,status:"pending",pendingMatches:o,pendingLocation:this.state.latestLocation})))})),await this.loadMatches(o,this.state.pendingLocation),this.startedLoadingAt!==r)return this.navigationPromise;const a=this.state.currentMatches,s=[],n=[];a.forEach((t=>{o.find((e=>e.id===t.id))?n.push(t):s.push(t)}));const i=o.filter((t=>!a.find((e=>e.id===t.id))));e=Date.now(),s.forEach((t=>{t.__onExit?.({params:t.params,search:t.state.routeSearch}),"error"===t.state.status&&this.__store.setState((t=>({...t,status:"idle",error:void 0})))})),n.forEach((t=>{t.route.options.onTransition?.({params:t.params,search:t.state.routeSearch})})),i.forEach((t=>{t.__onExit=t.route.options.onLoaded?.({params:t.params,search:t.state.search})}));const c=this.state.currentLocation;this.__store.setState((t=>({...t,status:"idle",currentLocation:this.state.latestLocation,currentMatches:o,pendingLocation:void 0,pendingMatches:void 0}))),o.forEach((t=>{t.__commit()})),c.href!==this.state.currentLocation.href&&this.options.onRouteChange?.(),this.resolveNavigation()};getRoute=t=>{const e=this.routesById[t];return s(e),e};loadRoute=async(t=this.state.latestLocation)=>{const e=this.buildNext(t),r=this.matchRoutes(e.pathname,{strictParseParams:!0});return await this.loadMatches(r,e),r};preloadRoute=async(t=this.state.latestLocation)=>{const e=this.buildNext(t),r=this.matchRoutes(e.pathname,{strictParseParams:!0});return await this.loadMatches(r,e,{preload:!0}),r};matchRoutes=(t,e)=>{const r=[];if(!this.routeTree)return r;const o=[...this.state.currentMatches,...this.state.pendingMatches??[]],a=async s=>{let n=y(r)?.params??{};const i=this.options.filterRoutes?.(s)??s;let c=[];const h=(r,o)=>(o.some((o=>{const a=o.children;if(!o.path&&a?.length)return h([...c,o],a);const s=!("/"===o.path&&!a?.length),i=k(this.basepath,t,{to:o.fullPath,fuzzy:s,caseSensitive:o.options.caseSensitive??this.options.caseSensitive});if(i){let t;try{t=o.options.parseParams?.(i)??i}catch(t){if(e?.strictParseParams)throw t}n={...n,...t}}return i&&(c=[...r,o]),!!c.length})),!!c.length);if(h([],i),!c.length)return;c.forEach((t=>{const e=M(t.path,n),a=M(t.id,n,!0),s=o.find((t=>t.id===a))||new yt(this,t,{id:a,params:n,pathname:S([this.basepath,e])});r.push(s)}));const u=y(c).children;u?.length&&a(u)};return a([this.routeTree]),r};loadMatches=async(t,e,r)=>{let o;try{await Promise.all(t.map((async(t,e)=>{try{await(t.route.options.beforeLoad?.({router:this,match:t}))}catch(r){if(ft(r))throw r;o=o??e;const a=t.route.options.onBeforeLoadError??t.route.options.onError;try{a?.(r)}catch(e){if(ft(e))throw e;return void t.__store.setState((t=>({...t,error:e,status:"error",updatedAt:Date.now()})))}t.__store.setState((t=>({...t,error:r,status:"error",updatedAt:Date.now()})))}})))}catch(t){if(ft(t))return void(r?.preload||this.navigate(t));throw t}const a=t.slice(0,o),s=a.map((async(t,o)=>{const s=a[o-1];t.__load({preload:r?.preload,location:e,parentMatch:s}),await t.__loadPromise,s&&await s.__loadPromise}));await Promise.all(s)};reload=()=>{this.navigate({fromCurrent:!0,replace:!0,search:!0})};resolvePath=(t,e)=>C(this.basepath,t,L(e));navigate=async({from:t,to:e="",search:r,hash:o,replace:a,params:n})=>{const i=String(e),c=void 0===t?t:String(t);let h;try{new URL(`${i}`),h=!0}catch(t){}return s(!h),this.#c({from:c,to:i,search:r,hash:o,replace:a,params:n})};matchRoute=(t,e)=>{t={...t,to:t.to?this.resolvePath(t.from??"",t.to):void 0};const r=this.buildNext(t),o=e?.pending?this.state.pendingLocation:this.state.currentLocation;if(!o)return!1;const a=k(this.basepath,o.pathname,{...e,to:r.pathname});return!!a&&(e?.includeSearch??1?!!b(o.search,r.search)&&a:a)};buildLink=({from:t,to:e=".",search:r,params:o,hash:a,target:s,replace:n,activeOptions:i,preload:c,preloadDelay:h,disabled:u})=>{try{return new URL(`${e}`),{type:"external",href:e}}catch(t){}const l={from:t,to:e,search:r,params:o,hash:a,replace:n},d=this.buildNext(l);c=c??this.options.defaultPreload;const p=h??this.options.defaultPreloadDelay??0,f=this.state.currentLocation.pathname.split("/"),m=d.pathname.split("/").every(((t,e)=>t===f[e])),y=i?.exact?this.state.currentLocation.pathname===d.pathname:m,g=!i?.includeHash||this.state.currentLocation.hash===d.hash,v=!(i?.includeSearch??1)||b(this.state.currentLocation.search,d.search);return{type:"internal",next:d,handleFocus:t=>{c&&this.preloadRoute(l).catch((t=>{console.warn(t),console.warn("Error preloading route! ☝️")}))},handleClick:t=>{u||function(t){return!!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)}(t)||t.defaultPrevented||s&&"_self"!==s||0!==t.button||(t.preventDefault(),this.#c(l))},handleEnter:t=>{const e=t.target||{};if(c){if(e.preloadTimeout)return;e.preloadTimeout=setTimeout((()=>{e.preloadTimeout=null,this.preloadRoute(l).catch((t=>{console.warn(t),console.warn("Error preloading route! ☝️")}))}),p)}},handleLeave:t=>{const e=t.target||{};e.preloadTimeout&&(clearTimeout(e.preloadTimeout),e.preloadTimeout=null)},handleTouchStart:t=>{this.preloadRoute(l).catch((t=>{console.warn(t),console.warn("Error preloading route! ☝️")}))},isActive:y&&g&&v,disabled:u}};#u=t=>{const e=(t,r)=>{t.forEach(((t,r)=>{t.init({originalIndex:r,router:this});s(!this.routesById[t.id],String(t.id)),this.routesById[t.id]=t;const o=t.children;o?.length&&(e(o),t.children=o.map(((t,e)=>{const r=R(E(L(t.path??"/")));for(;r.length>1&&"/"===r[0]?.value;)r.shift();let o=0;return r.forEach(((t,e)=>{let r=1;for(;e--;)r*=.001;"pathname"===t.type&&"/"!==t.value?o+=1*r:"param"===t.type?o+=2*r:"wildcard"===t.type&&(o+=3*r)})),{child:t,parsed:r,index:e,score:o}})).sort(((t,e)=>t.score!==e.score?t.score-e.score:t.index-e.index)).map((t=>t.child)))}))};e([t]);const r=(t,e)=>{t.forEach((t=>{t.isRoot?s(!e):s(!e||t.parentRoute===e,(t.path,t.parentRoute?.id,e?.id)),t.children&&r(t.children,t)}))};return r([t],void 0),t};#h=t=>{let{pathname:e,search:r,hash:o,state:a}=this.history.location;const s=this.options.parseSearch(r);return{pathname:e,searchStr:r,search:v(t?.search,s),hash:o.split("#").reverse()[0]??"",href:`${e}${r}${o}`,state:a,key:a?.key||"__init__"}};#l=(t={})=>{t.fromCurrent=t.fromCurrent??""===t.to;const e=t.fromCurrent?this.state.latestLocation.pathname:t.from??this.state.latestLocation.pathname;let r=C(this.basepath??"/",e,`${t.to??""}`);const o={...y(this.matchRoutes(this.state.latestLocation.pathname,{strictParseParams:!0}))?.params};let a=!0===(t.params??!0)?o:g(t.params,o);a&&t.__matches?.map((t=>t.route.options.stringifyParams)).filter(Boolean).forEach((t=>{a={...a,...t(a)}})),r=M(r,a??{});const s=t.__matches?.map((t=>t.route.options.preSearchFilters??[])).flat().filter(Boolean)??[],n=t.__matches?.map((t=>t.route.options.postSearchFilters??[])).flat().filter(Boolean)??[],i=s?.length?s?.reduce(((t,e)=>e(t)),this.state.latestLocation.search):this.state.latestLocation.search,c=!0===t.search?i:t.search?g(t.search,i)??{}:s?.length?i:{},h=n?.length?n.reduce(((t,e)=>e(t)),c):c,u=v(this.state.latestLocation.search,h),l=this.options.stringifySearch(u);let d=!0===t.hash?this.state.latestLocation.hash:g(t.hash,this.state.latestLocation.hash);d=d?`#${d}`:"";return{pathname:r,search:u,searchStr:l,state:!0===t.state?this.state.latestLocation.state:g(t.state,this.state.latestLocation.state),hash:d,href:this.history.createHref(`${r}${l}${d}`),key:t.key}};#c=async t=>{const e=this.buildNext(t),r=""+Date.now()+Math.random();this.navigateTimeout&&clearTimeout(this.navigateTimeout);let o="replace";t.replace||(o="push");this.state.latestLocation.href===e.href&&!e.key&&(o="replace");const a=`${e.pathname}${e.searchStr}${e.hash?`${e.hash}`:""}`;return this.history["push"===o?"push":"replace"](a,{id:r,...e.state}),this.navigationPromise=new Promise((t=>{const e=this.resolveNavigation;this.resolveNavigation=()=>{e(),t()}}))}},t.RouterProvider=function({router:t,...e}){t.update(e);const r=T(t.__store,(t=>t.currentMatches));return a.useEffect(t.mount,[t]),a.createElement(U.Provider,{value:{router:t}},a.createElement(F.Provider,{value:[void 0,...r]},a.createElement(tt,{errorComponent:rt,onCatch:()=>{}},a.createElement(Y,null))))},t.cleanPath=L,t.createBrowserHistory=d,t.createHashHistory=function(){return d({getHref:()=>window.location.hash.substring(1),createHref:t=>`#${t}`})},t.createMemoryHistory=p,t.decode=I,t.defaultFetchServerDataFn=lt,t.defaultParseSearch=it,t.defaultStringifySearch=ct,t.encode=j,t.functionalUpdate=g,t.interpolatePath=M,t.invariant=s,t.isPlainObject=w,t.isRedirect=ft,t.joinPaths=S,t.last=y,t.lazy=function(t){const e=a.lazy(t);return e.preload=async()=>{await t()},e},t.matchByPath=O,t.matchPathname=k,t.matchesContext=F,t.parsePathname=R,t.parseSearchWith=ht,t.partialDeepEqual=b,t.pick=function(t,e){return e.reduce(((e,r)=>(e[r]=t[r],e)),{})},t.redirect=function(t){return t.isRedirect=!0,t},t.replaceEqualDeep=v,t.resolvePath=C,t.rootRouteId=at,t.routerContext=U,t.stringifySearchWith=ut,t.trimPath=P,t.trimPathLeft=E,t.trimPathRight=x,t.useBlocker=ot,t.useLinkProps=H,t.useLoader=V,t.useMatch=K,t.useMatchRoute=G,t.useMatches=q,t.useNavigate=function(t){const e=z();return a.useCallback((r=>e.navigate({...t,...r})),[])},t.useParams=function(t){const e=z();return T(e.__store,(e=>{const r=y(e.currentMatches)?.params;return t?.track?.(r)??r})),y(e.state.currentMatches)?.params},t.useRouter=W,t.useRouterContext=z,t.useSearch=J,t.useStore=T,t.warning=n,Object.defineProperty(t,"__esModule",{value:!0})}));
*/function T(t,e=(t=>t)){return r.useSyncExternalStoreWithSelector(t.subscribe,(()=>t.state),(()=>t.state),e,N)}function N(t,e){if(Object.is(t,e))return!0;if("object"!=typeof t||null===t||"object"!=typeof e||null===e)return!1;const r=Object.keys(t);if(r.length!==Object.keys(e).length)return!1;for(let o=0;o<r.length;o++)if(!Object.prototype.hasOwnProperty.call(e,r[o])||!Object.is(t[r[o]],e[r[o]]))return!1;return!0}function H(t){const e=z(),{type:r,children:o,target:s,activeProps:n=(()=>({className:"active"})),inactiveProps:i=(()=>({})),activeOptions:c,disabled:h,hash:u,search:l,params:d,to:p=".",preload:f,preloadDelay:m,replace:y,style:v,className:_,onClick:w,onFocus:b,onMouseEnter:S,onMouseLeave:L,onTouchStart:E,...x}=t,P=e.buildLink(t);if("external"===P.type){const{href:t}=P;return{href:t}}const{handleClick:C,handleFocus:R,handleEnter:M,handleLeave:k,handleTouchStart:O,isActive:j,next:A}=P,I=t=>e=>{e.persist&&e.persist(),t.filter(Boolean).forEach((t=>{e.defaultPrevented||t(e)}))},$=j?g(n,{})??{}:{},D=j?{}:g(i,{})??{};return{...$,...D,...x,href:h?void 0:A.href,onClick:I([w,t=>{a.startTransition?a.startTransition((()=>{C(t)})):C(t)}]),onFocus:I([b,R]),onMouseEnter:I([S,M]),onMouseLeave:I([L,k]),onTouchStart:I([E,O]),target:s,style:{...v,...$.style,...D.style},className:[_,$.className,D.className].filter(Boolean).join(" ")||void 0,...h?{role:"link","aria-disabled":!0}:void 0,"data-status":j?"active":void 0}}const B=a.forwardRef(((t,e)=>{const r=H(t);return a.createElement("a",$({ref:e},r,{children:"function"==typeof t.children?t.children({isActive:"active"===r["data-status"]}):t.children}))}));const F=a.createContext(null),U=a.createContext(null);function z(){const t=a.useContext(U);return T(t.router.__store),t.router}function W(t){const e=z();return T(e.__store,t),e}function q(){return a.useContext(F)}function K(t){const e=z(),r=q()[0],o=t?.from?e.state.currentMatches.find((e=>e.route.id===t?.from)):r;return s(o,t?.from&&t.from),(t?.strict??1)&&s(r.route.id==o?.route.id,(o?.route.id,r.route.id,o?.route.id,o?.route.id)),T(o.__store,(e=>t?.track?.(o)??o)),o}function V(t){const{track:e,...r}=t,o=K(r);return T(o.__store,(e=>t?.track?.(e.loader)??e.loader)),o.state.loader}function J(t){const{track:e,...r}=t,o=K(r);return T(o.__store,(e=>t?.track?.(e.search)??e.search)),o.state.search}function G(){const t=z();return a.useCallback((e=>{const{pending:r,caseSensitive:o,...a}=e;return t.matchRoute(a,{pending:r,caseSensitive:o})}),[])}function Y(){const t=q().slice(1),e=t[0];return e?a.createElement(Q,{matches:t,match:e}):null}function Q({matches:t,match:e}){const r=z();T(e.__store,(t=>[t.status,t.error]));const o=a.useCallback((()=>null),[]),s=e.pendingComponent??r.options.defaultPendingComponent??o,n=e.errorComponent??r.options.defaultErrorComponent,i=e.route.options.wrapInSuspense??1?a.Suspense:Z,c=n?tt:Z;return a.createElement(F.Provider,{value:t},a.createElement(i,{fallback:a.createElement(s,null)},a.createElement(c,{key:e.route.id,errorComponent:n,onCatch:()=>{e.id}},a.createElement(X,{match:e}))))}function X(t){const e=z();if("error"===t.match.state.status)throw t.match.state.error;if("pending"===t.match.state.status)throw t.match.__loadPromise;if("success"===t.match.state.status)return a.createElement(t.match.component??e.options.defaultComponent??Y,{useLoader:t.match.route.useLoader,useMatch:t.match.route.useMatch,useContext:t.match.route.useContext,useSearch:t.match.route.useSearch});s(!1)}function Z(t){return a.createElement(a.Fragment,null,t.children)}class tt extends a.Component{state={error:!1,info:void 0};componentDidCatch(t,e){this.props.onCatch(t,e),console.error(t),this.setState({error:t,info:e})}render(){return a.createElement(et,$({},this.props,{errorState:this.state,reset:()=>this.setState({})}))}}function et(t){const[e,r]=a.useState(t.errorState),o=z(),s=t.errorComponent??rt,n=a.useRef("");return a.useEffect((()=>{e&&o.state.currentLocation.key!==n.current&&r({}),n.current=o.state.currentLocation.key}),[e,o.state.currentLocation.key]),a.useEffect((()=>{t.errorState.error&&r(t.errorState)}),[t.errorState.error]),t.errorState.error&&e.error?a.createElement(s,e):t.children}function rt({error:t}){return a.createElement("div",{style:{padding:".5rem",maxWidth:"100%"}},a.createElement("strong",{style:{fontSize:"1.2rem"}},"Something went wrong!"),a.createElement("div",{style:{height:".5rem"}}),a.createElement("div",null,a.createElement("pre",{style:{fontSize:".7em",border:"1px solid red",borderRadius:".25rem",padding:".5rem",color:"red",overflow:"auto"}},t.message?a.createElement("code",null,t.message):null)))}function ot(t,e=!0){const r=W();a.useEffect((()=>{if(!e)return;let o=r.history.block(((e,r)=>{window.confirm(t)?(o(),e()):r()}));return o}))}const at="__root__";class st{constructor(t){this.options=t||{},this.isRoot=!t?.getParentRoute}init=t=>{this.originalIndex=t.originalIndex,this.router=t.router;const e=this.options,r=!e?.path&&!e?.id;this.parentRoute=this.options?.getParentRoute?.(),r?this.path=at:s(this.parentRoute);let o=r?at:e.path;o&&"/"!==o&&(o=P(o));const a=e?.id||o;let n=r?at:S([this.parentRoute.id===at?"":this.parentRoute.id,a]);o===at&&(o="/"),n!==at&&(n=S(["/",n]));const i=n===at?"/":x(S([this.parentRoute.fullPath,o]));this.path=o,this.id=n,this.fullPath=i};addChildren=t=>(this.children=t,this);useMatch=t=>K({...t,from:this.id});useLoader=t=>V({...t,from:this.id});useContext=t=>K({...t,from:this.id}).context;useSearch=t=>J({...t,from:this.id})}class nt extends st{constructor(t){super(t)}static withRouterContext=()=>t=>new nt(t)}const it=ht(JSON.parse),ct=ut(JSON.stringify);function ht(t){return e=>{"?"===e.substring(0,1)&&(e=e.substring(1));let r=I(e);for(let e in r){const o=r[e];if("string"==typeof o)try{r[e]=t(o)}catch(t){}}return r}}function ut(t){return e=>{(e={...e})&&Object.keys(e).forEach((r=>{const o=e[r];if(void 0===o||void 0===o)delete e[r];else if(o&&"object"==typeof o&&null!==o)try{e[r]=t(o)}catch(t){}}));const r=j(e).toString();return r?`?${r}`:""}}const lt=async({router:t,routeMatch:e})=>{const r=t.buildNext({to:".",search:t=>({...t??{},__data:{matchId:e.id}})}),o=await fetch(r.href,{method:"GET",signal:e.abortController.signal});if(o.ok)return o.json();throw new Error("Failed to fetch match data")};const dt="undefined"==typeof window||!window.document.createElement;function pt(){return{status:"idle",latestLocation:null,currentLocation:null,currentMatches:[],lastUpdated:Date.now()}}function ft(t){return!!t?.isRedirect}const mt=["component","errorComponent","pendingComponent"];class yt{abortController=new AbortController;constructor(t,e,r){Object.assign(this,{route:e,router:t,id:r.id,pathname:r.pathname,params:r.params,__store:new D({updatedAt:0,routeSearch:{},search:{},status:"idle",loader:void 0},{onUpdate:()=>{this.state=this.__store.state}})}),this.state=this.__store.state,mt.map((async t=>{const e=this.route.options[t];this[t]=e})),"idle"!==this.state.status||this.#t()||this.__store.setState((t=>({...t,status:"success"})))}#t=()=>!(!this.route.options.loader&&!mt.some((t=>this.route.options[t]?.preload)));__commit=()=>{const{routeSearch:t,search:e,context:r,routeContext:o}=this.#e({location:this.router.state.currentLocation});this.context=r,this.routeContext=o,this.__store.setState((r=>({...r,routeSearch:v(r.routeSearch,t),search:v(r.search,e)})))};cancel=()=>{this.abortController?.abort()};#r=t=>{const e=this.parentMatch?this.parentMatch.#r(t):{search:t.location.search,routeSearch:t.location.search};try{const t=("object"==typeof this.route.options.validateSearch?this.route.options.validateSearch.parse:this.route.options.validateSearch)?.(e.search)??{};return{routeSearch:t,search:{...e.search,...t}}}catch(t){if(ft(t))throw t;(this.route.options.onValidateSearchError??this.route.options.onError)?.(t);const e=new Error("Invalid search params found",{cause:t});throw e.code="INVALID_SEARCH_PARAMS",e}};#e=t=>{const{search:e,routeSearch:r}=this.#r(t);try{const t=this.route.options.getContext?.({parentContext:this.parentMatch?.routeContext??{},context:this.parentMatch?.context??this.router?.options.context??{},params:this.params,search:e})||{};return{routeSearch:r,search:e,context:{...this.parentMatch?.context??this.router?.options.context,...t},routeContext:t}}catch(t){throw this.route.options.onError?.(t),t}};__load=async t=>{let e;this.parentMatch=t.parentMatch;try{e=this.#e(t)}catch(e){return ft(e)?void(t?.preload||this.router.navigate(e)):void this.__store.setState((t=>({...t,status:"error",error:e})))}const{routeSearch:r,search:o,context:a,routeContext:s}=e;if("pending"!==this.state.status)return this.__loadPromise=Promise.resolve().then((async()=>{const e=""+Date.now()+Math.random();this.#o=e;const n=()=>e!==this.#o?this.__loadPromise:void 0;let i;"idle"===this.state.status&&this.__store.setState((t=>({...t,status:"pending"})));const c=(async()=>{await Promise.all(mt.map((async t=>{const e=this.route.options[t];e?.preload&&await e.preload()})))})(),h=Promise.resolve().then((()=>{if(this.route.options.loader)return this.route.options.loader({params:this.params,routeSearch:r,search:o,signal:this.abortController.signal,preload:!!t?.preload,routeContext:s,context:a})}));try{const[t,e]=await Promise.all([c,h]);if(i=n())return await i;this.__store.setState((t=>({...t,error:void 0,status:"success",updatedAt:Date.now(),loader:e})))}catch(e){if(ft(e))return void(t?.preload||this.router.navigate(e));const r=this.route.options.onLoadError??this.route.options.onError;try{r?.(e)}catch(e){return ft(e)?void(t?.preload||this.router.navigate(e)):void this.__store.setState((t=>({...t,error:e,status:"error",updatedAt:Date.now()})))}this.__store.setState((t=>({...t,error:e,status:"error",updatedAt:Date.now()})))}finally{delete this.__loadPromise}})),this.__loadPromise};#o=""}t.Block=function({message:t,condition:e,children:r}){return ot(t,e),r??null},t.ErrorComponent=rt,t.Link=B,t.MatchRoute=function(t){const e=G()(t);return e?"function"==typeof t.children?t.children(e):e?t.children:null:null},t.Navigate=function(t){const e=z();return a.useLayoutEffect((()=>{e.navigate(t)}),[]),null},t.Outlet=Y,t.RootRoute=nt,t.Route=st,t.RouteMatch=yt,t.Router=class{#a;startedLoadingAt=Date.now();resolveNavigation=()=>{};constructor(t){this.options={defaultPreloadDelay:50,context:void 0,...t,stringifySearch:t?.stringifySearch??ct,parseSearch:t?.parseSearch??it,fetchServerDataFn:t?.fetchServerDataFn??lt},this.__store=new D(pt(),{onUpdate:()=>{this.state=this.__store.state}}),this.state=this.__store.state,this.update(t);const e=this.buildNext({hash:!0,fromCurrent:!0,search:!0,state:!0});this.state.latestLocation.href!==e.href&&this.#s({...e,replace:!0})}reset=()=>{this.__store.setState((t=>Object.assign(t,pt())))};mount=()=>(dt||this.state.currentMatches.length||this.safeLoad(),()=>{});hydrate=async t=>{let e=t;return"undefined"!=typeof document&&(e=window.__DEHYDRATED__,s(e)),this.options.hydrate?.(e),await this.load()};update=t=>{if(Object.assign(this.options,t),this.context=this.options.context,!this.history||this.options.history&&this.options.history!==this.history){this.#a&&this.#a(),this.history=this.options.history??(dt?p():d());const t=this.#n();this.__store.setState((e=>({...e,latestLocation:t,currentLocation:t}))),this.#a=this.history.listen((()=>{this.safeLoad({next:this.#n(this.state.latestLocation)})}))}const{basepath:e,routeTree:r}=this.options;return this.basepath=`/${P(e??"")??""}`,r&&(this.routesById={},this.routeTree=this.#i(r)),this};buildNext=t=>{const e=this.#c(t),r=this.matchRoutes(e.pathname);return this.#c({...t,__matches:r})};cancelMatches=()=>{[...this.state.currentMatches,...this.state.pendingMatches||[]].forEach((t=>{t.cancel()}))};safeLoad=t=>{this.load(t).catch((t=>{console.warn(t),s(!1)}))};load=async t=>{let e=Date.now();const r=e;let o;if(this.startedLoadingAt=r,this.cancelMatches(),this.__store.batch((()=>{t?.next&&this.__store.setState((e=>({...e,latestLocation:t.next}))),o=this.matchRoutes(this.state.latestLocation.pathname,{strictParseParams:!0}),this.__store.setState((t=>({...t,status:"pending",pendingMatches:o,pendingLocation:this.state.latestLocation})))})),await this.loadMatches(o,this.state.pendingLocation),this.startedLoadingAt!==r)return this.navigationPromise;const a=this.state.currentMatches,s=[],n=[];a.forEach((t=>{o.find((e=>e.id===t.id))?n.push(t):s.push(t)}));const i=o.filter((t=>!a.find((e=>e.id===t.id))));e=Date.now(),s.forEach((t=>{t.__onExit?.({params:t.params,search:t.state.routeSearch}),"error"===t.state.status&&this.__store.setState((t=>({...t,status:"idle",error:void 0})))})),n.forEach((t=>{t.route.options.onTransition?.({params:t.params,search:t.state.routeSearch})})),i.forEach((t=>{t.__onExit=t.route.options.onLoaded?.({params:t.params,search:t.state.search})}));const c=this.state.currentLocation;this.__store.setState((t=>({...t,status:"idle",currentLocation:this.state.latestLocation,currentMatches:o,pendingLocation:void 0,pendingMatches:void 0}))),o.forEach((t=>{t.__commit()})),c.href!==this.state.currentLocation.href&&this.options.onRouteChange?.(),this.resolveNavigation()};getRoute=t=>{const e=this.routesById[t];return s(e),e};loadRoute=async(t=this.state.latestLocation)=>{const e=this.buildNext(t),r=this.matchRoutes(e.pathname,{strictParseParams:!0});return await this.loadMatches(r,e),r};preloadRoute=async(t=this.state.latestLocation)=>{const e=this.buildNext(t),r=this.matchRoutes(e.pathname,{strictParseParams:!0});return await this.loadMatches(r,e,{preload:!0}),r};matchRoutes=(t,e)=>{if(!this.routeTree)return[];const r=[...this.state.currentMatches,...this.state.pendingMatches??[]];let o=[];const a=r=>{let s;if(r.some((r=>{const n=r.children;if(!r.path){if(n?.length){o.push({route:r});const t=a(n);return t?(s=t,!0):(o.pop(),!1)}return!1}const i="/"!==r.path||!!n?.length,c=k(this.basepath,t,{to:r.fullPath,fuzzy:i,caseSensitive:r.options.caseSensitive??this.options.caseSensitive});if(c){let t;try{t=r.options.parseParams?.(c)??c}catch(t){if(e?.strictParseParams)throw t}return o.push({route:r,params:t}),s=r,!0}return!1})),!s)return;const n=s.children;return n?.length?a(n):s};a([this.routeTree]);let s={};return o.map((({route:t,params:e})=>{Object.assign(s,e);const o=M(t.path,e),a=M(t.id,e,!0);return r.find((t=>t.id===a))||new yt(this,t,{id:a,params:s,pathname:S([this.basepath,o])})}))};loadMatches=async(t,e,r)=>{let o;try{await Promise.all(t.map((async(t,e)=>{try{await(t.route.options.beforeLoad?.({router:this,match:t}))}catch(r){if(ft(r))throw r;o=o??e;const a=t.route.options.onBeforeLoadError??t.route.options.onError;try{a?.(r)}catch(e){if(ft(e))throw e;return void t.__store.setState((t=>({...t,error:e,status:"error",updatedAt:Date.now()})))}t.__store.setState((t=>({...t,error:r,status:"error",updatedAt:Date.now()})))}})))}catch(t){if(ft(t))return void(r?.preload||this.navigate(t));throw t}const a=t.slice(0,o),s=a.map((async(t,o)=>{const s=a[o-1];t.__load({preload:r?.preload,location:e,parentMatch:s}),await t.__loadPromise,s&&await s.__loadPromise}));await Promise.all(s)};reload=()=>{this.navigate({fromCurrent:!0,replace:!0,search:!0})};resolvePath=(t,e)=>C(this.basepath,t,L(e));navigate=async({from:t,to:e="",search:r,hash:o,replace:a,params:n})=>{const i=String(e),c=void 0===t?t:String(t);let h;try{new URL(`${i}`),h=!0}catch(t){}return s(!h),this.#s({from:c,to:i,search:r,hash:o,replace:a,params:n})};matchRoute=(t,e)=>{t={...t,to:t.to?this.resolvePath(t.from??"",t.to):void 0};const r=this.buildNext(t),o=e?.pending?this.state.pendingLocation:this.state.currentLocation;if(!o)return!1;const a=k(this.basepath,o.pathname,{...e,to:r.pathname});return!!a&&(e?.includeSearch??1?!!b(o.search,r.search)&&a:a)};buildLink=({from:t,to:e=".",search:r,params:o,hash:a,target:s,replace:n,activeOptions:i,preload:c,preloadDelay:h,disabled:u})=>{try{return new URL(`${e}`),{type:"external",href:e}}catch(t){}const l={from:t,to:e,search:r,params:o,hash:a,replace:n},d=this.buildNext(l);c=c??this.options.defaultPreload;const p=h??this.options.defaultPreloadDelay??0,f=this.state.currentLocation.pathname.split("/"),m=d.pathname.split("/").every(((t,e)=>t===f[e])),y=i?.exact?this.state.currentLocation.pathname===d.pathname:m,g=!i?.includeHash||this.state.currentLocation.hash===d.hash,v=!(i?.includeSearch??1)||b(this.state.currentLocation.search,d.search);return{type:"internal",next:d,handleFocus:t=>{c&&this.preloadRoute(l).catch((t=>{console.warn(t),console.warn("Error preloading route! ☝️")}))},handleClick:t=>{u||function(t){return!!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)}(t)||t.defaultPrevented||s&&"_self"!==s||0!==t.button||(t.preventDefault(),this.#s(l))},handleEnter:t=>{const e=t.target||{};if(c){if(e.preloadTimeout)return;e.preloadTimeout=setTimeout((()=>{e.preloadTimeout=null,this.preloadRoute(l).catch((t=>{console.warn(t),console.warn("Error preloading route! ☝️")}))}),p)}},handleLeave:t=>{const e=t.target||{};e.preloadTimeout&&(clearTimeout(e.preloadTimeout),e.preloadTimeout=null)},handleTouchStart:t=>{this.preloadRoute(l).catch((t=>{console.warn(t),console.warn("Error preloading route! ☝️")}))},isActive:y&&g&&v,disabled:u}};#i=t=>{const e=(t,r)=>{t.forEach(((t,r)=>{t.init({originalIndex:r,router:this});s(!this.routesById[t.id],String(t.id)),this.routesById[t.id]=t;const o=t.children;o?.length&&(e(o),t.children=o.map(((t,e)=>{const r=R(E(L(t.path??"/")));for(;r.length>1&&"/"===r[0]?.value;)r.shift();let o=0;return r.forEach(((t,e)=>{let r=1;for(;e--;)r*=.001;"pathname"===t.type&&"/"!==t.value?o+=1*r:"param"===t.type?o+=2*r:"wildcard"===t.type&&(o+=3*r)})),{child:t,parsed:r,index:e,score:o}})).sort(((t,e)=>t.score!==e.score?t.score-e.score:t.index-e.index)).map((t=>t.child)))}))};e([t]);const r=(t,e)=>{t.forEach((t=>{t.isRoot?s(!e):s(!e||t.parentRoute===e,(t.path,t.parentRoute?.id,e?.id)),t.children&&r(t.children,t)}))};return r([t],void 0),t};#n=t=>{let{pathname:e,search:r,hash:o,state:a}=this.history.location;const s=this.options.parseSearch(r);return{pathname:e,searchStr:r,search:v(t?.search,s),hash:o.split("#").reverse()[0]??"",href:`${e}${r}${o}`,state:a,key:a?.key||"__init__"}};#c=(t={})=>{t.fromCurrent=t.fromCurrent??""===t.to;const e=t.fromCurrent?this.state.latestLocation.pathname:t.from??this.state.latestLocation.pathname;let r=C(this.basepath??"/",e,`${t.to??""}`);const o={...y(this.matchRoutes(this.state.latestLocation.pathname,{strictParseParams:!0}))?.params};let a=!0===(t.params??!0)?o:g(t.params,o);a&&t.__matches?.map((t=>t.route.options.stringifyParams)).filter(Boolean).forEach((t=>{a={...a,...t(a)}})),r=M(r,a??{});const s=t.__matches?.map((t=>t.route.options.preSearchFilters??[])).flat().filter(Boolean)??[],n=t.__matches?.map((t=>t.route.options.postSearchFilters??[])).flat().filter(Boolean)??[],i=s?.length?s?.reduce(((t,e)=>e(t)),this.state.latestLocation.search):this.state.latestLocation.search,c=!0===t.search?i:t.search?g(t.search,i)??{}:s?.length?i:{},h=n?.length?n.reduce(((t,e)=>e(t)),c):c,u=v(this.state.latestLocation.search,h),l=this.options.stringifySearch(u);let d=!0===t.hash?this.state.latestLocation.hash:g(t.hash,this.state.latestLocation.hash);d=d?`#${d}`:"";return{pathname:r,search:u,searchStr:l,state:!0===t.state?this.state.latestLocation.state:g(t.state,this.state.latestLocation.state),hash:d,href:this.history.createHref(`${r}${l}${d}`),key:t.key}};#s=async t=>{const e=this.buildNext(t),r=""+Date.now()+Math.random();this.navigateTimeout&&clearTimeout(this.navigateTimeout);let o="replace";t.replace||(o="push");this.state.latestLocation.href===e.href&&!e.key&&(o="replace");const a=`${e.pathname}${e.searchStr}${e.hash?`${e.hash}`:""}`;return this.history["push"===o?"push":"replace"](a,{id:r,...e.state}),this.navigationPromise=new Promise((t=>{const e=this.resolveNavigation;this.resolveNavigation=()=>{e(),t()}}))}},t.RouterProvider=function({router:t,...e}){t.update(e);const r=T(t.__store,(t=>t.currentMatches));return a.useEffect(t.mount,[t]),a.createElement(U.Provider,{value:{router:t}},a.createElement(F.Provider,{value:[void 0,...r]},a.createElement(tt,{errorComponent:rt,onCatch:()=>{}},a.createElement(Y,null))))},t.cleanPath=L,t.createBrowserHistory=d,t.createHashHistory=function(){return d({getHref:()=>window.location.hash.substring(1),createHref:t=>`#${t}`})},t.createMemoryHistory=p,t.decode=I,t.defaultFetchServerDataFn=lt,t.defaultParseSearch=it,t.defaultStringifySearch=ct,t.encode=j,t.functionalUpdate=g,t.interpolatePath=M,t.invariant=s,t.isPlainObject=_,t.isRedirect=ft,t.joinPaths=S,t.last=y,t.lazy=function(t){const e=a.lazy(t);return e.preload=async()=>{await t()},e},t.matchByPath=O,t.matchPathname=k,t.matchesContext=F,t.parsePathname=R,t.parseSearchWith=ht,t.partialDeepEqual=b,t.pick=function(t,e){return e.reduce(((e,r)=>(e[r]=t[r],e)),{})},t.redirect=function(t){return t.isRedirect=!0,t},t.replaceEqualDeep=v,t.resolvePath=C,t.rootRouteId=at,t.routerContext=U,t.stringifySearchWith=ut,t.trimPath=P,t.trimPathLeft=E,t.trimPathRight=x,t.useBlocker=ot,t.useLinkProps=H,t.useLoader=V,t.useMatch=K,t.useMatchRoute=G,t.useMatches=q,t.useNavigate=function(t){const e=z();return a.useCallback((r=>e.navigate({...t,...r})),[])},t.useParams=function(t){const e=z();return T(e.__store,(e=>{const r=y(e.currentMatches)?.params;return t?.track?.(r)??r})),y(e.state.currentMatches)?.params},t.useRouter=W,t.useRouterContext=z,t.useSearch=J,t.useStore=T,t.warning=n,Object.defineProperty(t,"__esModule",{value:!0})}));
//# sourceMappingURL=index.production.js.map
{
"name": "@tanstack/router",
"author": "Tanner Linsley",
"version": "0.0.1-beta.89",
"version": "0.0.1-beta.90",
"license": "MIT",

@@ -45,8 +45,9 @@ "repository": "tanstack/router",

"tiny-warning": "^1.0.3",
"@tanstack/react-store": "0.0.1-beta.89"
"@tanstack/react-store": "0.0.1-beta.90"
},
"scripts": {
"build": "rollup --config rollup.config.js",
"test": "vitest"
"test": "vitest",
"test:dev": "vitest --watch"
}
}

@@ -167,14 +167,24 @@ import { AnyPathParams } from './route'

): Record<string, string> | undefined {
if (!from.startsWith(basepath)) {
return undefined
}
// Remove the base path from the pathname
from = basepath != '/' ? from.substring(basepath.length) : from
// Default to to $ (wildcard)
const to = `${matchLocation.to ?? '$'}`
// Parse the from and to
const baseSegments = parsePathname(from)
const to = `${matchLocation.to ?? '$'}`
const routeSegments = parsePathname(to)
if (last(baseSegments)?.value === '/') {
baseSegments.pop()
if (!from.startsWith('/')) {
baseSegments.unshift({
type: 'pathname',
value: '/',
})
}
if (!to.startsWith('/')) {
routeSegments.unshift({
type: 'pathname',
value: '/',
})
}
const params: Record<string, string> = {}

@@ -191,4 +201,4 @@

const isLastRouteSegment = i === routeSegments.length - 1
const isLastBaseSegment = i === baseSegments.length - 1
const isLastBaseSegment = i >= baseSegments.length - 1
const isLastRouteSegment = i >= routeSegments.length - 1

@@ -237,6 +247,7 @@ if (routeSegment) {

if (isLastRouteSegment && !isLastBaseSegment) {
if (!isLastBaseSegment && isLastRouteSegment) {
return !!matchLocation.fuzzy
}
}
return true

@@ -243,0 +254,0 @@ })()

@@ -31,2 +31,3 @@ import { Store } from '@tanstack/react-store'

AnyRootRoute,
AnyPathParams,
} from './route'

@@ -104,5 +105,2 @@ import { RoutesInfo, AnyRoutesInfo, RoutesById } from './routeInfo'

export type SearchParser = (searchStr: string) => Record<string, any>
export type FilterRoutesFn = <TRoute extends AnyRoute>(
routes: TRoute[],
) => TRoute[]

@@ -125,3 +123,2 @@ type RouterContextOptions<TRouteTree extends AnyRoute> =

parseSearch?: SearchParser
filterRoutes?: FilterRoutesFn
defaultPreload?: false | 'intent'

@@ -575,9 +572,13 @@ defaultPreloadDelay?: number

matchRoutes = (pathname: string, opts?: { strictParseParams?: boolean }) => {
const matches: AnyRouteMatch[] = []
matchRoutes = (
pathname: string,
opts?: { strictParseParams?: boolean },
): RouteMatch[] => {
// If there's no route tree, we can't match anything
if (!this.routeTree) {
return matches
return []
}
// Existing matches are matches that are already loaded along with
// pending matches that are still loading
const existingMatches = [

@@ -588,91 +589,130 @@ ...this.state.currentMatches,

const findInRouteTree = async (
routes: Route<any, any>[],
): Promise<void> => {
const parentMatch = last(matches)
let params = parentMatch?.params ?? {}
// We need to "flatten" layout routes, but only process as many
// routes as we need to in order to find the best match
// This mean no looping over all of the routes (even though the
// user could technically do this in their own routes filter code,
// but that's their choice).
// Time to bust out the recursion... As we iterate over the routes,
// we'll keep track of the best match thus far by pushing or popping
// it onto the `matchingRoutes` array. In the case of a layout route,
// we'll assume that it matches and just recurse into its children.
// If we come up with nothing, we'll pop it off and try the next route.
// This way the user can have as many routes, including layout routes,
// as they want without worrying about performance.
// It does make one assumption though: that route branches are ordered from
// most specific to least specific. This is a good assumption to make IMO.
// Tools like Remix and React Router auto-rank routes, which is a neat trick
// that unfortunately requires looping over all of the routes.
// I'd rather err on the side of performance here
// and rely on the fact that to use TanStack Router, you already have to
// be thinking about your routes more intimately. We're smart enough
// to write switch statements, so we're smart enough to (keep) ordering
// our routes like we have been doing for years.
const filteredRoutes = this.options.filterRoutes?.(routes) ?? routes
let matchingRoutesAndParams: { route: Route; params?: AnyPathParams }[] = []
let matchingRoutes: Route[] = []
const findMatchInRoutes = (parentRoutes: Route[], routes: Route[]) => {
routes.some((route) => {
const children = route.children as undefined | Route[]
if (!route.path && children?.length) {
return findMatchInRoutes(
[...matchingRoutes, route],
children as any,
)
// For any given array of branching routes, find the best route match
// and push it onto the `matchingRoutes` array
const findRoutes = (routes: Route<any, any>[]): undefined | Route => {
let found: undefined | Route
// Given a list of routes, find the first route that matches
routes.some((route) => {
const children = route.children as undefined | Route[]
// If there is no path, but there are children,
// this is a layout route, so recurse again
if (!route.path) {
if (children?.length) {
// Preemptively push the route onto the matchingRoutes array
matchingRoutesAndParams.push({ route })
const childMatch = findRoutes(children)
// If we found a child match, mark it as found
// and return true to stop the loop
if (childMatch) {
found = childMatch
return true
}
// If there was no child match, pop our optimistic route off the array
// and return false to keep trying
matchingRoutesAndParams.pop()
return false
}
// It's a layout route, but for some reason it has no children
// so we'll just ignore it and keep matching
return false
}
const fuzzy = !!(route.path !== '/' || children?.length)
// If the route isn't an index route or it has children,
// fuzzy match the path
const fuzzy = route.path !== '/' || !!children?.length
const matchParams = matchPathname(this.basepath, pathname, {
to: route.fullPath,
fuzzy,
caseSensitive:
route.options.caseSensitive ?? this.options.caseSensitive,
})
const matchedParams = matchPathname(this.basepath, pathname, {
to: route.fullPath,
fuzzy,
caseSensitive:
route.options.caseSensitive ?? this.options.caseSensitive,
})
if (matchParams) {
let parsedParams
try {
parsedParams =
route.options.parseParams?.(matchParams!) ?? matchParams
} catch (err) {
if (opts?.strictParseParams) {
throw err
}
// This was a match!
if (matchedParams) {
// Let's parse the params using the route's `parseParams` function
let parsedParams
try {
parsedParams =
route.options.parseParams?.(matchedParams!) ?? matchedParams
} catch (err) {
if (opts?.strictParseParams) {
throw err
}
params = {
...params,
...parsedParams,
}
}
if (!!matchParams) {
matchingRoutes = [...parentRoutes, route]
}
matchingRoutesAndParams.push({ route, params: parsedParams })
return !!matchingRoutes.length
})
found = route
return true
}
return !!matchingRoutes.length
return false
})
// If we didn't find a match in this route branch
// return early.
if (!found) {
return undefined
}
findMatchInRoutes([], filteredRoutes)
if (!matchingRoutes.length) {
return
// If the found route has children, recurse again
const foundChildren = found.children as any
if (foundChildren?.length) {
return findRoutes(foundChildren)
}
matchingRoutes.forEach((foundRoute) => {
const interpolatedPath = interpolatePath(foundRoute.path, params)
const matchId = interpolatePath(foundRoute.id, params, true)
return found
}
const match =
existingMatches.find((d) => d.id === matchId) ||
new RouteMatch(this, foundRoute, {
id: matchId,
params,
pathname: joinPaths([this.basepath, interpolatedPath]),
})
findRoutes([this.routeTree as any])
matches.push(match)
})
// Alright, by now we should have all of our
// matching routes and their param pairs, let's
// Turn them into actual `Match` objects and
// accumulate the params into a single params bag
let allParams = {}
const foundRoute = last(matchingRoutes)!
const matches = matchingRoutesAndParams.map(({ route, params }) => {
// Add the parsed params to the accumulated params bag
Object.assign(allParams, params)
const foundChildren = foundRoute.children as any
const interpolatedPath = interpolatePath(route.path, params)
const matchId = interpolatePath(route.id, params, true)
if (foundChildren?.length) {
findInRouteTree(foundChildren)
}
}
// Waste not, want not. If we already have a match for this route,
// reuse it. This is important for layout routes, which might stick
// around between navigation actions that only change leaf routes.
return (existingMatches.find((d) => d.id === matchId) ||
new RouteMatch(this, route, {
id: matchId,
params: allParams,
pathname: joinPaths([this.basepath, interpolatedPath]),
})) as RouteMatch
})
findInRouteTree([this.routeTree as any])
return matches

@@ -679,0 +719,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc