You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 7-8.RSVP
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

Comparing version 0.0.1-beta.119 to 0.0.1-beta.120

11

build/cjs/index.js

@@ -21,3 +21,2 @@ /**

var route = require('./route.js');
var routeMatch = require('./routeMatch.js');
var router = require('./router.js');

@@ -61,6 +60,7 @@ var searchParams = require('./searchParams.js');

exports.Route = route.Route;
exports.RouterContext = route.RouterContext;
exports.rootRouteId = route.rootRouteId;
exports.RouteMatch = routeMatch.RouteMatch;
exports.Router = router.Router;
exports.defaultFetchServerDataFn = router.defaultFetchServerDataFn;
exports.componentTypes = router.componentTypes;
exports.createRouteMatch = router.createRouteMatch;
exports.isRedirect = router.isRedirect;

@@ -82,2 +82,3 @@ exports.redirect = router.redirect;

exports.MatchRoute = react.MatchRoute;
exports.MatchesProvider = react.MatchesProvider;
exports.Navigate = react.Navigate;

@@ -89,2 +90,4 @@ exports.Outlet = react.Outlet;

exports.routerContext = react.routerContext;
exports.routerStateContext = react.routerStateContext;
exports.shallow = react.shallow;
exports.useBlocker = react.useBlocker;

@@ -102,3 +105,3 @@ exports.useDehydrate = react.useDehydrate;

exports.useRouter = react.useRouter;
exports.useRouterContext = react.useRouterContext;
exports.useRouterState = react.useRouterState;
exports.useSearch = react.useSearch;

@@ -105,0 +108,0 @@ Object.defineProperty(exports, 'useStore', {

@@ -67,3 +67,3 @@ /**

function useLinkProps(options) {
const router = useRouterContext();
const router = useRouter();
const {

@@ -174,3 +174,3 @@ // custom props

function Navigate(props) {
const router = useRouterContext();
const router = useRouter();
React__namespace.useLayoutEffect(() => {

@@ -182,5 +182,13 @@ router.navigate(props);

const matchesContext = /*#__PURE__*/React__namespace.createContext(null);
const routerStateContext = /*#__PURE__*/React__namespace.createContext(null);
const routerContext = /*#__PURE__*/React__namespace.createContext(null);
// const useDeferredValue = React.useDeferredValue || ((d) => d)
const useDeferredValue = d => d;
function MatchesProvider({
matches,
children
}) {
return /*#__PURE__*/React__namespace.createElement(matchesContext.Provider, {
value: matches
}, children);
}
const useLayoutEffect = typeof document === 'undefined' ? React__namespace.useEffect : React__namespace.useLayoutEffect;
function RouterProvider({

@@ -191,10 +199,14 @@ router,

router.update(rest);
const matches = useDeferredValue(reactStore.useStore(router.__store, s => {
return s.matches;
}));
const [state, _setState] = React__namespace.useState(() => router.state);
const matches = state.matches;
useLayoutEffect(() => {
return router.__store.subscribe(() => {
(React__namespace.startTransition || (d => d()))(() => _setState(router.state));
});
});
React__namespace.useEffect(router.mount, [router]);
return /*#__PURE__*/React__namespace.createElement(routerContext.Provider, {
value: {
router: router
}
value: router
}, /*#__PURE__*/React__namespace.createElement(routerStateContext.Provider, {
value: state
}, /*#__PURE__*/React__namespace.createElement(matchesContext.Provider, {

@@ -207,14 +219,17 @@ value: [undefined, ...matches]

}
}, /*#__PURE__*/React__namespace.createElement(Outlet, null))));
}, /*#__PURE__*/React__namespace.createElement(Outlet, null)))));
}
function useRouterContext() {
function useRouter() {
const value = React__namespace.useContext(routerContext);
warning__default["default"](value, 'useRouter must be used inside a <Router> component!');
reactStore.useStore(value.router.__store);
return value.router;
return value;
}
function useRouter(track) {
const router = useRouterContext();
reactStore.useStore(router.__store, track);
return router;
function useRouterState(select) {
const state = React__namespace.useContext(routerStateContext);
const next = select?.(state) ?? state;
const valueRef = React__namespace.useRef(next);
if (!shallow(valueRef.current, next)) {
valueRef.current = next;
}
return valueRef.current;
}

@@ -225,11 +240,13 @@ function useMatches() {

function useMatch(opts) {
const router = useRouterContext();
const routerState = useRouterState();
const nearestMatch = useMatches()[0];
const matches = useDeferredValue(router.state.matches);
const match = opts?.from ? matches.find(d => d.route.id === opts?.from) : nearestMatch;
const matches = routerState.matches;
const match = opts?.from ? matches.find(d => d.routeId === opts?.from) : nearestMatch;
invariant__default["default"](match, `Could not find ${opts?.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`);
if (opts?.strict ?? true) {
invariant__default["default"](nearestMatch.route.id == match?.route.id, `useMatch("${match?.route.id}") is being called in a component that is meant to render the '${nearestMatch.route.id}' route. Did you mean to 'useMatch("${match?.route.id}", { strict: false })' or 'useRoute("${match?.route.id}")' instead?`);
invariant__default["default"](nearestMatch.routeId == match?.routeId, `useMatch("${match?.routeId}") is being called in a component that is meant to render the '${nearestMatch.routeId}' route. Did you mean to 'useMatch("${match?.routeId}", { strict: false })' or 'useRoute("${match?.routeId}")' instead?`);
}
reactStore.useStore(match.__store, d => opts?.track?.(match) ?? match);
// useStore(match!.__store as any, (d) => opts?.track?.(match as any) ?? match)
return match;

@@ -242,5 +259,3 @@ }

} = opts;
const match = useMatch(matchOpts);
reactStore.useStore(match.__store, d => opts?.track?.(d.loader) ?? d.loader);
return match.state.loader;
return useMatch(matchOpts).loader;
}

@@ -253,17 +268,14 @@ function useSearch(opts) {

const match = useMatch(matchOpts);
reactStore.useStore(match.__store, d => opts?.track?.(d.search) ?? d.search);
return match.state.search;
return match.search;
}
function useParams(opts) {
const router = useRouterContext();
return reactStore.useStore(router.__store, d => {
return useRouterState(d => {
const params = utils.last(d.matches)?.params;
return opts?.track?.(params) ?? params;
return params;
// return opts?.track?.(params) ?? params
});
// return last(router.state.matches)?.params as any
}
function useNavigate(defaultOpts) {
const router = useRouterContext();
const router = useRouter();
return React__namespace.useCallback(opts => {

@@ -277,3 +289,3 @@ return router.navigate({

function useMatchRoute() {
const router = useRouterContext();
const router = useRouter();
return React__namespace.useCallback(opts => {

@@ -317,28 +329,9 @@ const {

}) {
const router = useRouterContext();
reactStore.useStore(match.__store, store => [store.status, store.error]);
const router = useRouter();
const defaultPending = React__namespace.useCallback(() => null, []);
const PendingComponent = match.pendingComponent ?? router.options.defaultPendingComponent ?? defaultPending;
const errorComponent = match.errorComponent ?? router.options.defaultErrorComponent;
const ResolvedSuspenseBoundary = match.route.options.wrapInSuspense ?? !match.route.isRoot ? React__namespace.Suspense : SafeFragment;
const route = router.getRoute(match.routeId);
const PendingComponent = route.options.pendingComponent ?? router.options.defaultPendingComponent ?? defaultPending;
const errorComponent = route.options.errorComponent ?? router.options.defaultErrorComponent;
const ResolvedSuspenseBoundary = route.options.wrapInSuspense ?? !route.isRoot ? React__namespace.Suspense : SafeFragment;
const ResolvedCatchBoundary = errorComponent ? CatchBoundary : SafeFragment;
// if (typeof document === 'undefined') {
// if (match.state.loader) {
// Object.keys(match.state.loader).forEach((key) => {
// let value = match.state.loader[key]
// if (value instanceof Promise || value.then) {
// value = {
// __isPromise: true,
// key: key,
// }
// }
// dehydrated[key] = value
// })
// }
// } else {
// }
return /*#__PURE__*/React__namespace.createElement(matchesContext.Provider, {

@@ -349,3 +342,3 @@ value: matches

}, /*#__PURE__*/React__namespace.createElement(ResolvedCatchBoundary, {
key: match.route.id,
key: route.id,
errorComponent: errorComponent,

@@ -360,3 +353,3 @@ onCatch: () => {

function useInjectHtml() {
const router = useRouterContext();
const router = useRouter();
return React__namespace.useCallback(html => {

@@ -367,3 +360,3 @@ router.injectHtml(html);

function useDehydrate() {
const router = useRouterContext();
const router = useRouter();
return React__namespace.useCallback(function dehydrate(key, data) {

@@ -374,3 +367,3 @@ return router.dehydrateData(key, data);

function useHydrate() {
const router = useRouterContext();
const router = useRouter();
return function hydrate(key) {

@@ -381,18 +374,19 @@ return router.hydrateData(key);

function Inner(props) {
const router = useRouterContext();
if (props.match.state.status === 'error') {
throw props.match.state.error;
const router = useRouter();
const route = router.getRoute(props.match.routeId);
if (props.match.status === 'error') {
throw props.match.error;
}
if (props.match.state.status === 'pending') {
throw props.match.__loadPromise;
if (props.match.status === 'pending') {
throw props.match.loadPromise || invariant__default["default"](false, 'This should never happen');
}
if (props.match.state.status === 'success') {
let comp = props.match.component ?? router.options.defaultComponent;
if (props.match.status === 'success') {
let comp = route.options.component ?? router.options.defaultComponent;
if (comp) {
return /*#__PURE__*/React__namespace.createElement(comp, {
useLoader: props.match.route.useLoader,
useMatch: props.match.route.useMatch,
useContext: props.match.route.useContext,
useSearch: props.match.route.useSearch,
useParams: props.match.route.useParams
useLoader: route.useLoader,
useMatch: route.useMatch,
useContext: route.useContext,
useSearch: route.useSearch,
useParams: route.useParams
});

@@ -433,4 +427,4 @@ }

function CatchBoundaryInner(props) {
const routerState = useRouterState();
const [activeErrorState, setActiveErrorState] = React__namespace.useState(props.errorState);
const router = useRouterContext();
const errorComponent = props.errorComponent ?? ErrorComponent;

@@ -440,8 +434,12 @@ const prevKeyRef = React__namespace.useRef('');

if (activeErrorState) {
if (router.state.location.key !== prevKeyRef.current) ;
if (routerState.location.key !== prevKeyRef.current) {
setActiveErrorState({});
}
}
prevKeyRef.current = router.state.location.key;
}, [activeErrorState, router.state.location.key]);
prevKeyRef.current = routerState.location.key;
}, [activeErrorState, routerState.location.key]);
React__namespace.useEffect(() => {
if (props.errorState.error) ;
if (props.errorState.error) {
setActiveErrorState(props.errorState);
}
// props.reset()

@@ -502,2 +500,20 @@ }, [props.errorState.error]);

}
function shallow(objA, objB) {
if (Object.is(objA, objB)) {
return true;
}
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
return false;
}
const keysA = Object.keys(objA);
if (keysA.length !== Object.keys(objB).length) {
return false;
}
for (let i = 0; i < keysA.length; i++) {
if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) {
return false;
}
}
return true;
}

@@ -512,2 +528,3 @@ Object.defineProperty(exports, 'useStore', {

exports.MatchRoute = MatchRoute;
exports.MatchesProvider = MatchesProvider;
exports.Navigate = Navigate;

@@ -519,2 +536,4 @@ exports.Outlet = Outlet;

exports.routerContext = routerContext;
exports.routerStateContext = routerStateContext;
exports.shallow = shallow;
exports.useBlocker = useBlocker;

@@ -532,4 +551,4 @@ exports.useDehydrate = useDehydrate;

exports.useRouter = useRouter;
exports.useRouterContext = useRouterContext;
exports.useRouterState = useRouterState;
exports.useSearch = useSearch;
//# sourceMappingURL=react.js.map

@@ -104,2 +104,37 @@ /**

}
class RouterContext {
constructor() {}
createRootRoute = options => {
return new RootRoute(options);
};
// return <
// TLoader = unknown,
// TSearchSchema extends AnySearchSchema = {},
// TContext extends {} = {},
// >(
// options?: Omit<
// RouteOptions<
// AnyRoute,
// RootRouteId,
// '',
// TLoader,
// {},
// TSearchSchema,
// NoInfer<TSearchSchema>,
// {},
// TRouterContext,
// TRouterContext,
// TContext,
// TRouterContext & TContext
// >,
// 'path' | 'id' | 'getParentRoute' | 'caseSensitive'
// >,
// ) =>
// new RootRoute<TLoader, TSearchSchema, TContext, TRouterContext>(
// options as any,
// )
// }
}
class RootRoute extends Route {

@@ -109,5 +144,2 @@ constructor(options) {

}
static withRouterContext = () => {
return options => new RootRoute(options);
};
}

@@ -161,3 +193,4 @@

exports.Route = Route;
exports.RouterContext = RouterContext;
exports.rootRouteId = rootRouteId;
//# sourceMappingURL=route.js.map

@@ -18,3 +18,2 @@ /**

var path = require('./path.js');
var routeMatch = require('./routeMatch.js');
var searchParams = require('./searchParams.js');

@@ -28,24 +27,3 @@ var utils = require('./utils.js');

const defaultFetchServerDataFn = async ({
router,
routeMatch
}) => {
const next = router.buildNext({
to: '.',
search: d => ({
...(d ?? {}),
__data: {
matchId: routeMatch.id
}
})
});
const res = await fetch(next.href, {
method: 'GET',
signal: routeMatch.abortController.signal
});
if (res.ok) {
return res.json();
}
throw new Error('Failed to fetch match data');
};
const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
class Router {

@@ -61,5 +39,6 @@ #unsubHistory;

stringifySearch: options?.stringifySearch ?? searchParams.defaultStringifySearch,
parseSearch: options?.parseSearch ?? searchParams.defaultParseSearch,
fetchServerDataFn: options?.fetchServerDataFn ?? defaultFetchServerDataFn
parseSearch: options?.parseSearch ?? searchParams.defaultParseSearch
// fetchServerDataFn: options?.fetchServerDataFn ?? defaultFetchServerDataFn,
};
this.__store = new reactStore.Store(getInitialRouterState(), {

@@ -99,4 +78,10 @@ onUpdate: () => {

update = opts => {
Object.assign(this.options, opts);
this.context = this.options.context;
this.options = {
...this.options,
...opts,
context: {
...this.options.context,
...opts?.context
}
};
if (!this.history || this.options.history && this.options.history !== this.history) {

@@ -138,6 +123,9 @@ if (this.#unsubHistory) {

cancelMatches = () => {
[...this.state.matches].forEach(match => {
match.cancel();
this.state.matches.forEach(match => {
this.cancelMatch(match.id);
});
};
cancelMatch = id => {
this.getRouteMatch(id)?.abortController?.abort();
};
safeLoad = opts => {

@@ -178,8 +166,5 @@ this.load(opts).catch(err => {

});
matches.forEach(match => {
match.__commit();
});
// Load the matches
await this.loadMatches(matches, this.state.location);
await this.loadMatches(matches);
if (this.startedLoadingAt !== startedAt) {

@@ -189,50 +174,10 @@ // Ignore side-effects of outdated side-effects

}
const previousMatches = this.state.matches;
const exiting = [],
staying = [];
previousMatches.forEach(d => {
if (matches.find(dd => dd.id === d.id)) {
staying.push(d);
} else {
exiting.push(d);
}
});
const entering = matches.filter(d => {
return !previousMatches.find(dd => dd.id === d.id);
});
now = Date.now();
exiting.forEach(d => {
d.__onExit?.({
params: d.params,
search: d.state.routeSearch
});
// Clear non-loading error states when match leaves
if (d.state.status === 'error') {
this.__store.setState(s => ({
...s,
status: 'idle',
error: undefined
}));
}
});
staying.forEach(d => {
d.route.options.onTransition?.({
params: d.params,
search: d.state.routeSearch
});
});
entering.forEach(d => {
d.__onExit = d.route.options.onLoaded?.({
params: d.params,
search: d.state.search
});
});
const prevLocation = this.state.location;
const prevLocation = this.state.resolvedLocation;
this.__store.setState(s => ({
...s,
status: 'idle',
resolvedLocation: s.location,
matches
resolvedLocation: s.location
// matches,
}));
if (prevLocation.href !== this.state.location.href) {

@@ -248,10 +193,2 @@ this.options.onRouteChange?.();

};
loadRoute = async (navigateOpts = this.state.location) => {
const next = this.buildNext(navigateOpts);
const matches = this.matchRoutes(next.pathname, next.search, {
strictParseParams: true
});
await this.loadMatches(matches, next);
return matches;
};
preloadRoute = async (navigateOpts = this.state.location) => {

@@ -262,3 +199,18 @@ const next = this.buildNext(navigateOpts);

});
await this.loadMatches(matches, next, {
const matchesById = {};
matches.forEach(m => {
if (!this.state.matches.find(d => d.id === m.id)) {
matchesById[m.id] = m;
}
});
this.__store.setState(s => {
return {
...s,
preloadMatches: {
...s.preloadMatches,
...matchesById
}
};
});
await this.loadMatches(matches, {
preload: true

@@ -268,7 +220,3 @@ });

};
matchRoutes = (pathname, search, opts) => {
// If there's no route tree, we can't match anything
if (!this.flatRoutes.length) {
return [];
}
matchRoutes = (pathname, locationSearch, opts) => {
let routeParams = {};

@@ -286,10 +234,8 @@ let foundRoute = this.flatRoutes.find(route => {

});
if (!foundRoute) {
return [];
let routeCursor = foundRoute || this.routesById['__root__'];
let matchedRoutes = [routeCursor];
while (routeCursor?.parentRoute) {
routeCursor = routeCursor.parentRoute;
if (routeCursor) matchedRoutes.unshift(routeCursor);
}
let matchedRoutes = [foundRoute];
while (foundRoute?.parentRoute) {
foundRoute = foundRoute.parentRoute;
if (foundRoute) matchedRoutes.unshift(foundRoute);
}

@@ -304,3 +250,3 @@ // Alright, by now we should have all of our

// pending matches that are still loading
const existingMatches = [...this.state.matches];
const matches = matchedRoutes.map(route => {

@@ -321,3 +267,3 @@ let parsedParams;

params: allParams,
search
search: locationSearch
}) ?? '');

@@ -328,7 +274,13 @@

// around between navigation actions that only change leaf routes.
const existingMatch = existingMatches.find(d => d.id === matchId);
const existingMatch = this.getRouteMatch(matchId);
if (existingMatch) {
return existingMatch;
// Return a copy, we don't want to mutate the existing match
return {
...existingMatch
};
}
return new routeMatch.RouteMatch(this, route, {
// Create a fresh route match
return createRouteMatch({
route,
id: matchId,

@@ -338,12 +290,69 @@ params: allParams,

});
}).filter((d, i, all) => {
// Filter out any duplicate matches
// I honesty don't know why this is necessary, but it is and it's safe for now
// Someday someone will figure out why my logic is wrong and fix it to just
// not create duplicate matches in the first place
return all.findIndex(dd => dd.id === d.id) === i;
});
// Take each match and resolve its search params and context
// This has to happen after the matches are created or found
// so that we can use the parent match's search params and context
matches.forEach((match, i) => {
const parentMatch = matches[i - 1];
const route = this.getRoute(match.routeId);
const searchInfo = (() => {
// Validate the search params and stabilize them
const parentSearchInfo = {
search: parentMatch?.search ?? locationSearch,
routeSearch: parentMatch?.routeSearch ?? locationSearch
};
try {
const validator = typeof route.options.validateSearch === 'object' ? route.options.validateSearch.parse : route.options.validateSearch;
const routeSearch = validator?.(parentSearchInfo.search) ?? {};
const search = {
...parentSearchInfo.search,
...routeSearch
};
return {
routeSearch: utils.replaceEqualDeep(match.routeSearch, routeSearch),
search: utils.replaceEqualDeep(match.search, search)
};
} catch (err) {
if (isRedirect(err)) {
throw err;
}
const errorHandler = route.options.onValidateSearchError ?? route.options.onError;
errorHandler?.(err);
const error = new Error('Invalid search params found', {
cause: err
});
error.code = 'INVALID_SEARCH_PARAMS';
throw error;
}
})();
const contextInfo = (() => {
try {
const routeContext = route.options.getContext?.({
parentContext: parentMatch?.routeContext ?? {},
context: parentMatch?.context ?? this?.options.context ?? {},
params: match.params,
search: match.search
}) || {};
const context = {
...(parentMatch?.context ?? this?.options.context),
...routeContext
};
return {
context,
routeContext
};
} catch (err) {
route.options.onError?.(err);
throw err;
}
})();
Object.assign(match, {
...searchInfo,
...contextInfo
});
});
return matches;
};
loadMatches = async (resolvedMatches, location, opts) => {
loadMatches = async (resolvedMatches, opts) => {
let firstBadMatchIndex;

@@ -354,4 +363,5 @@

await Promise.all(resolvedMatches.map(async (match, index) => {
const route = this.getRoute(match.routeId);
try {
await match.route.options.beforeLoad?.({
await route.options.beforeLoad?.({
router: this,

@@ -365,20 +375,15 @@ match

firstBadMatchIndex = firstBadMatchIndex ?? index;
const errorHandler = match.route.options.onBeforeLoadError ?? match.route.options.onError;
const errorHandler = route.options.onBeforeLoadError ?? route.options.onError;
let caughtError = err;
try {
errorHandler?.(err);
} catch (errorHandlerErr) {
caughtError = errorHandlerErr;
if (isRedirect(errorHandlerErr)) {
throw errorHandlerErr;
}
match.__store.setState(s => ({
...s,
error: errorHandlerErr,
status: 'error',
updatedAt: Date.now()
}));
return;
}
match.__store.setState(s => ({
this.#setEitherRouteMatch(match.id, s => ({
...s,
error: err,
error: caughtError,
status: 'error',

@@ -400,13 +405,95 @@ updatedAt: Date.now()

const validResolvedMatches = resolvedMatches.slice(0, firstBadMatchIndex);
const matchPromises = validResolvedMatches.map(async (match, index) => {
const parentMatch = validResolvedMatches[index - 1];
match.__load({
preload: opts?.preload,
location,
parentMatch
});
await match.__loadPromise;
if (parentMatch) {
await parentMatch.__loadPromise;
}
const matchPromises = [];
validResolvedMatches.forEach((match, index) => {
matchPromises.push(Promise.resolve().then(async () => {
const parentMatchPromise = matchPromises[index - 1];
const route = this.getRoute(match.routeId);
const fetchedAt = Date.now();
const loadPromise = Promise.resolve().then(async () => {
const checkLatest = () => {
const latest = this.getRouteMatch(match.id);
return latest && latest.fetchedAt !== fetchedAt ? latest.loadPromise : undefined;
};
let latestPromise;
const componentsPromise = (async () => {
// then run all component and data loaders in parallel
// For each component type, potentially load it asynchronously
await Promise.all(componentTypes.map(async type => {
const component = route.options[type];
if (component?.preload) {
await component.preload();
}
}));
})();
const loaderPromise = Promise.resolve().then(() => {
if (route.options.loader) {
return route.options.loader({
...match,
preload: !!opts?.preload,
parentMatchPromise
});
}
return;
});
try {
const [_, loader] = await Promise.all([componentsPromise, loaderPromise]);
if (latestPromise = checkLatest()) return await latestPromise;
this.#setEitherRouteMatch(match.id, s => ({
...s,
error: undefined,
status: 'success',
updatedAt: Date.now(),
loader
}));
} catch (err) {
if (latestPromise = checkLatest()) return await latestPromise;
if (isRedirect(err)) {
if (!opts?.preload) {
this.navigate(err);
}
return;
}
const errorHandler = route.options.onLoadError ?? route.options.onError;
let caughtError = err;
try {
errorHandler?.(err);
} catch (errorHandlerErr) {
caughtError = errorHandlerErr;
if (isRedirect(errorHandlerErr)) {
if (!opts?.preload) {
this.navigate(errorHandlerErr);
}
return;
}
}
this.#setEitherRouteMatch(match.id, s => ({
...s,
error: caughtError,
status: 'error',
updatedAt: Date.now()
}));
} finally {
if (latestPromise = checkLatest()) return await latestPromise;
if (opts?.preload) {
this.__store.setState(s => {
const preloadMatches = {
...s.preloadMatches
};
delete preloadMatches[match.id];
return {
...s,
preloadMatches
};
});
}
}
});
this.#setEitherRouteMatch(match.id, s => ({
...s,
loadPromise,
fetchedAt
}));
await loadPromise;
}));
});

@@ -635,4 +722,10 @@ await Promise.all(matchPromises);

this.injectHtml(async () => {
const id = `__TSR_DEHYDRATED__${strKey}`;
const data = typeof getData === 'function' ? await getData() : getData;
return `<script>window["__TSR__DEHYRATED__${escapeJSON(strKey)}"] = ${JSON.stringify(data)}</script>`;
return `<script id='${id}' suppressHydrationWarning>window["__TSR_DEHYDRATED__${escapeJSON(strKey)}"] = ${JSON.stringify(data)}
;(() => {
var el = document.getElementById('${id}')
el.parentElement.removeChild(el)
})()
</script>`;
});

@@ -646,3 +739,3 @@ return () => this.hydrateData(key);

const strKey = typeof key === 'string' ? key : JSON.stringify(key);
return window[`__TSR__DEHYRATED__${strKey}`];
return window[`__TSR_DEHYDRATED__${strKey}`];
}

@@ -773,3 +866,3 @@ return undefined;

if (nextParams) {
dest.__matches?.map(d => d.route.options.stringifyParams).filter(Boolean).forEach(fn => {
dest.__matches?.map(d => this.getRoute(d.routeId).options.stringifyParams).filter(Boolean).forEach(fn => {
nextParams = {

@@ -782,4 +875,4 @@ ...nextParams,

pathname = path.interpolatePath(pathname, nextParams ?? {});
const preSearchFilters = dest.__matches?.map(match => match.route.options.preSearchFilters ?? []).flat().filter(Boolean) ?? [];
const postSearchFilters = dest.__matches?.map(match => match.route.options.postSearchFilters ?? []).flat().filter(Boolean) ?? [];
const preSearchFilters = dest.__matches?.map(match => this.getRoute(match.routeId).options.preSearchFilters ?? []).flat().filter(Boolean) ?? [];
const postSearchFilters = dest.__matches?.map(match => this.getRoute(match.routeId).options.postSearchFilters ?? []).flat().filter(Boolean) ?? [];

@@ -841,2 +934,32 @@ // Pre filters first

};
getRouteMatch = id => {
return this.state.matches.find(d => d.id === id) || this.state.preloadMatches[id];
};
setRouteMatch = (id, updater) => {
this.__store.setState(prev => ({
...prev,
matches: prev.matches.map(d => {
if (d.id === id) {
return updater(d);
}
return d;
})
}));
};
setPreloadRouteMatch = (id, updater) => {
invariant__default["default"](this.state.preloadMatches[id], 'Match not found');
this.__store.setState(prev => ({
...prev,
preloadMatches: {
...prev.preloadMatches,
[id]: updater(prev.preloadMatches[id])
}
}));
};
#setEitherRouteMatch = (id, updater) => {
if (this.state.matches.find(d => d.id === id)) {
return this.setRouteMatch(id, updater);
}
return this.setPreloadRouteMatch(id, updater);
};
}

@@ -852,2 +975,3 @@

matches: [],
preloadMatches: {},
lastUpdated: Date.now()

@@ -872,6 +996,34 @@ };

function createRouteMatch({
route,
id,
params,
pathname
}) {
const hasLoaders = !!(route.options.loader || componentTypes.some(d => route.options[d]?.preload));
const state = {
id: id,
routeId: route.id,
params: params,
pathname: pathname,
updatedAt: 0,
routeSearch: {},
search: {},
status: hasLoaders ? 'pending' : 'success',
error: undefined,
loader: undefined,
loadPromise: Promise.resolve(),
routeContext: undefined,
context: undefined,
abortController: new AbortController(),
fetchedAt: 0
};
return state;
}
exports.Router = Router;
exports.defaultFetchServerDataFn = defaultFetchServerDataFn;
exports.componentTypes = componentTypes;
exports.createRouteMatch = createRouteMatch;
exports.isRedirect = isRedirect;
exports.redirect = redirect;
//# sourceMappingURL=router.js.map

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

"name": "tiny-invariant@1.3.1/node_modules/tiny-invariant/dist/esm/tiny-invariant.js",
"uid": "8af4-49"
"uid": "a144-49"
},
{
"name": "tiny-warning@1.0.3/node_modules/tiny-warning/dist/tiny-warning.esm.js",
"uid": "8af4-51"
"uid": "a144-51"
}

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

{
"uid": "8af4-53",
"uid": "a144-53",
"name": "history.ts"
},
{
"uid": "8af4-55",
"uid": "a144-55",
"name": "utils.ts"
},
{
"uid": "8af4-57",
"uid": "a144-57",
"name": "path.ts"
},
{
"uid": "8af4-59",
"uid": "a144-59",
"name": "qss.ts"
},
{
"uid": "8af4-67",
"uid": "a144-67",
"name": "react.tsx"
},
{
"uid": "8af4-69",
"uid": "a144-69",
"name": "route.ts"
},
{
"uid": "8af4-71",
"uid": "a144-71",
"name": "searchParams.ts"
},
{
"uid": "8af4-73",
"uid": "a144-73",
"name": "router.ts"
},
{
"uid": "8af4-75",
"name": "routeMatch.ts"
},
{
"uid": "8af4-77",
"uid": "a144-75",
"name": "index.ts"

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

"name": "store/build/esm/index.js",
"uid": "8af4-63"
"uid": "a144-63"
},
{
"name": "react-store/build/esm/index.js",
"uid": "8af4-65"
"uid": "a144-65"
}

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

{
"uid": "8af4-61",
"uid": "a144-61",
"name": "\u0000rollupPluginBabelHelpers.js"

@@ -94,98 +90,92 @@ }

"nodeParts": {
"8af4-49": {
"a144-49": {
"renderedLength": 199,
"gzipLength": 134,
"brotliLength": 0,
"mainUid": "8af4-48"
"mainUid": "a144-48"
},
"8af4-51": {
"a144-51": {
"renderedLength": 48,
"gzipLength": 65,
"brotliLength": 0,
"mainUid": "8af4-50"
"mainUid": "a144-50"
},
"8af4-53": {
"a144-53": {
"renderedLength": 5643,
"gzipLength": 1404,
"brotliLength": 0,
"mainUid": "8af4-52"
"mainUid": "a144-52"
},
"8af4-55": {
"a144-55": {
"renderedLength": 2821,
"gzipLength": 990,
"brotliLength": 0,
"mainUid": "8af4-54"
"mainUid": "a144-54"
},
"8af4-57": {
"a144-57": {
"renderedLength": 6028,
"gzipLength": 1423,
"brotliLength": 0,
"mainUid": "8af4-56"
"mainUid": "a144-56"
},
"8af4-59": {
"a144-59": {
"renderedLength": 1395,
"gzipLength": 558,
"brotliLength": 0,
"mainUid": "8af4-58"
"mainUid": "a144-58"
},
"8af4-61": {
"a144-61": {
"renderedLength": 457,
"gzipLength": 241,
"brotliLength": 0,
"mainUid": "8af4-60"
"mainUid": "a144-60"
},
"8af4-63": {
"a144-63": {
"renderedLength": 1459,
"gzipLength": 543,
"brotliLength": 0,
"mainUid": "8af4-62"
"mainUid": "a144-62"
},
"8af4-65": {
"renderedLength": 1590,
"gzipLength": 640,
"a144-65": {
"renderedLength": 2158,
"gzipLength": 750,
"brotliLength": 0,
"mainUid": "8af4-64"
"mainUid": "a144-64"
},
"8af4-67": {
"renderedLength": 14408,
"gzipLength": 3414,
"a144-67": {
"renderedLength": 14965,
"gzipLength": 3557,
"brotliLength": 0,
"mainUid": "8af4-66"
"mainUid": "a144-66"
},
"8af4-69": {
"renderedLength": 3556,
"gzipLength": 903,
"a144-69": {
"renderedLength": 4424,
"gzipLength": 1083,
"brotliLength": 0,
"mainUid": "8af4-68"
"mainUid": "a144-68"
},
"8af4-71": {
"a144-71": {
"renderedLength": 1387,
"gzipLength": 483,
"brotliLength": 0,
"mainUid": "8af4-70"
"mainUid": "a144-70"
},
"8af4-73": {
"renderedLength": 27721,
"gzipLength": 6697,
"a144-73": {
"renderedLength": 33511,
"gzipLength": 7662,
"brotliLength": 0,
"mainUid": "8af4-72"
"mainUid": "a144-72"
},
"8af4-75": {
"renderedLength": 8914,
"gzipLength": 1932,
"brotliLength": 0,
"mainUid": "8af4-74"
},
"8af4-77": {
"a144-75": {
"renderedLength": 0,
"gzipLength": 0,
"brotliLength": 0,
"mainUid": "8af4-76"
"mainUid": "a144-74"
}
},
"nodeMetas": {
"8af4-48": {
"a144-48": {
"id": "/node_modules/.pnpm/tiny-invariant@1.3.1/node_modules/tiny-invariant/dist/esm/tiny-invariant.js",
"moduleParts": {
"index.production.js": "8af4-49"
"index.production.js": "a144-49"
},

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

{
"uid": "8af4-76"
"uid": "a144-74"
},
{
"uid": "8af4-68"
"uid": "a144-68"
},
{
"uid": "8af4-72"
"uid": "a144-72"
},
{
"uid": "8af4-66"
"uid": "a144-66"
}
]
},
"8af4-50": {
"a144-50": {
"id": "/node_modules/.pnpm/tiny-warning@1.0.3/node_modules/tiny-warning/dist/tiny-warning.esm.js",
"moduleParts": {
"index.production.js": "8af4-51"
"index.production.js": "a144-51"
},

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

{
"uid": "8af4-76"
"uid": "a144-74"
},
{
"uid": "8af4-66"
"uid": "a144-66"
}
]
},
"8af4-52": {
"a144-52": {
"id": "/packages/router/src/history.ts",
"moduleParts": {
"index.production.js": "8af4-53"
"index.production.js": "a144-53"
},

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

{
"uid": "8af4-76"
"uid": "a144-74"
},
{
"uid": "8af4-72"
"uid": "a144-72"
}
]
},
"8af4-54": {
"a144-54": {
"id": "/packages/router/src/utils.ts",
"moduleParts": {
"index.production.js": "8af4-55"
"index.production.js": "a144-55"
},

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

{
"uid": "8af4-76"
"uid": "a144-74"
},
{
"uid": "8af4-56"
"uid": "a144-56"
},
{
"uid": "8af4-74"
"uid": "a144-72"
},
{
"uid": "8af4-72"
},
{
"uid": "8af4-66"
"uid": "a144-66"
}
]
},
"8af4-56": {
"a144-56": {
"id": "/packages/router/src/path.ts",
"moduleParts": {
"index.production.js": "8af4-57"
"index.production.js": "a144-57"
},
"imported": [
{
"uid": "8af4-54"
"uid": "a144-54"
}

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

{
"uid": "8af4-76"
"uid": "a144-74"
},
{
"uid": "8af4-68"
"uid": "a144-68"
},
{
"uid": "8af4-72"
"uid": "a144-72"
}
]
},
"8af4-58": {
"a144-58": {
"id": "/packages/router/src/qss.ts",
"moduleParts": {
"index.production.js": "8af4-59"
"index.production.js": "a144-59"
},

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

{
"uid": "8af4-76"
"uid": "a144-74"
},
{
"uid": "8af4-70"
"uid": "a144-70"
}
]
},
"8af4-60": {
"a144-60": {
"id": "\u0000rollupPluginBabelHelpers.js",
"moduleParts": {
"index.production.js": "8af4-61"
"index.production.js": "a144-61"
},

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

{
"uid": "8af4-66"
"uid": "a144-66"
}
]
},
"8af4-62": {
"a144-62": {
"id": "/packages/store/build/esm/index.js",
"moduleParts": {
"index.production.js": "8af4-63"
"index.production.js": "a144-63"
},

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

{
"uid": "8af4-64"
"uid": "a144-64"
}
]
},
"8af4-64": {
"a144-64": {
"id": "/packages/react-store/build/esm/index.js",
"moduleParts": {
"index.production.js": "8af4-65"
"index.production.js": "a144-65"
},
"imported": [
{
"uid": "8af4-81"
"uid": "a144-78"
},
{
"uid": "8af4-62"
"uid": "a144-79"
},
{
"uid": "a144-62"
}

@@ -346,35 +336,32 @@ ],

{
"uid": "8af4-74"
"uid": "a144-72"
},
{
"uid": "8af4-72"
},
{
"uid": "8af4-66"
"uid": "a144-66"
}
]
},
"8af4-66": {
"a144-66": {
"id": "/packages/router/src/react.tsx",
"moduleParts": {
"index.production.js": "8af4-67"
"index.production.js": "a144-67"
},
"imported": [
{
"uid": "8af4-60"
"uid": "a144-60"
},
{
"uid": "8af4-80"
"uid": "a144-78"
},
{
"uid": "8af4-64"
"uid": "a144-64"
},
{
"uid": "8af4-48"
"uid": "a144-48"
},
{
"uid": "8af4-50"
"uid": "a144-50"
},
{
"uid": "8af4-54"
"uid": "a144-54"
}

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

{
"uid": "8af4-76"
"uid": "a144-74"
},
{
"uid": "8af4-68"
"uid": "a144-68"
}
]
},
"8af4-68": {
"a144-68": {
"id": "/packages/router/src/route.ts",
"moduleParts": {
"index.production.js": "8af4-69"
"index.production.js": "a144-69"
},
"imported": [
{
"uid": "8af4-48"
"uid": "a144-48"
},
{
"uid": "8af4-56"
"uid": "a144-56"
},
{
"uid": "8af4-66"
"uid": "a144-66"
}

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

{
"uid": "8af4-76"
"uid": "a144-74"
}
]
},
"8af4-70": {
"a144-70": {
"id": "/packages/router/src/searchParams.ts",
"moduleParts": {
"index.production.js": "8af4-71"
"index.production.js": "a144-71"
},
"imported": [
{
"uid": "8af4-58"
"uid": "a144-58"
}

@@ -427,35 +414,32 @@ ],

{
"uid": "8af4-76"
"uid": "a144-74"
},
{
"uid": "8af4-72"
"uid": "a144-72"
}
]
},
"8af4-72": {
"a144-72": {
"id": "/packages/router/src/router.ts",
"moduleParts": {
"index.production.js": "8af4-73"
"index.production.js": "a144-73"
},
"imported": [
{
"uid": "8af4-64"
"uid": "a144-64"
},
{
"uid": "8af4-48"
"uid": "a144-48"
},
{
"uid": "8af4-56"
"uid": "a144-56"
},
{
"uid": "8af4-74"
"uid": "a144-70"
},
{
"uid": "8af4-70"
"uid": "a144-54"
},
{
"uid": "8af4-54"
},
{
"uid": "8af4-52"
"uid": "a144-52"
}

@@ -465,78 +449,47 @@ ],

{
"uid": "8af4-76"
},
{
"uid": "8af4-74"
"uid": "a144-74"
}
]
},
"8af4-74": {
"id": "/packages/router/src/routeMatch.ts",
"moduleParts": {
"index.production.js": "8af4-75"
},
"imported": [
{
"uid": "8af4-64"
},
{
"uid": "8af4-72"
},
{
"uid": "8af4-54"
}
],
"importedBy": [
{
"uid": "8af4-76"
},
{
"uid": "8af4-72"
}
]
},
"8af4-76": {
"a144-74": {
"id": "/packages/router/src/index.ts",
"moduleParts": {
"index.production.js": "8af4-77"
"index.production.js": "a144-75"
},
"imported": [
{
"uid": "8af4-48"
"uid": "a144-48"
},
{
"uid": "8af4-50"
"uid": "a144-50"
},
{
"uid": "8af4-52"
"uid": "a144-52"
},
{
"uid": "8af4-78"
"uid": "a144-76"
},
{
"uid": "8af4-56"
"uid": "a144-56"
},
{
"uid": "8af4-58"
"uid": "a144-58"
},
{
"uid": "8af4-68"
"uid": "a144-68"
},
{
"uid": "8af4-79"
"uid": "a144-77"
},
{
"uid": "8af4-74"
"uid": "a144-72"
},
{
"uid": "8af4-72"
"uid": "a144-70"
},
{
"uid": "8af4-70"
"uid": "a144-54"
},
{
"uid": "8af4-54"
},
{
"uid": "8af4-66"
"uid": "a144-66"
}

@@ -547,3 +500,3 @@ ],

},
"8af4-78": {
"a144-76": {
"id": "/packages/router/src/link.ts",

@@ -554,7 +507,7 @@ "moduleParts": {},

{
"uid": "8af4-76"
"uid": "a144-74"
}
]
},
"8af4-79": {
"a144-77": {
"id": "/packages/router/src/routeInfo.ts",

@@ -565,7 +518,7 @@ "moduleParts": {},

{
"uid": "8af4-76"
"uid": "a144-74"
}
]
},
"8af4-80": {
"a144-78": {
"id": "react",

@@ -576,3 +529,6 @@ "moduleParts": {},

{
"uid": "8af4-66"
"uid": "a144-66"
},
{
"uid": "a144-64"
}

@@ -582,3 +538,3 @@ ],

},
"8af4-81": {
"a144-79": {
"id": "use-sync-external-store/shim/with-selector",

@@ -589,3 +545,3 @@ "moduleParts": {},

{
"uid": "8af4-64"
"uid": "a144-64"
}

@@ -592,0 +548,0 @@ ],

@@ -9,3 +9,2 @@ export { default as invariant } from 'tiny-invariant';

export * from './routeInfo';
export * from './routeMatch';
export * from './router';

@@ -12,0 +11,0 @@ export * from './searchParams';

@@ -6,4 +6,3 @@ import * as React from 'react';

import { RouteByPath, AnyRoutesInfo, DefaultRoutesInfo } from './routeInfo';
import { AnyRouteMatch, RouteMatch } from './routeMatch';
import { RegisteredRoutesInfo, MatchRouteOptions, RegisteredRouter, RouterOptions, RouterState, Router } from './router';
import { RegisteredRoutesInfo, MatchRouteOptions, RegisteredRouter, RouterOptions, Router, RouteMatch, RouterState } from './router';
export { useStore };

@@ -41,7 +40,6 @@ type ReactNode = any;

export declare function Navigate<TFrom extends RegisteredRoutesInfo['routePaths'] = '/', TTo extends string = ''>(props: NavigateOptions<RegisteredRoutesInfo, TFrom, TTo>): null;
type MatchesContextValue = AnyRouteMatch[];
type MatchesContextValue = RouteMatch[];
export declare const matchesContext: React.Context<MatchesContextValue>;
export declare const routerContext: React.Context<{
router: RegisteredRouter;
}>;
export declare const routerStateContext: React.Context<RouterState<import("./routeInfo").RoutesInfo<AnyRoute>, import("./router").LocationState>>;
export declare const routerContext: React.Context<Router<AnyRoute, import("./routeInfo").RoutesInfo<AnyRoute>, Record<string, any>>>;
export type MatchesProviderProps = {

@@ -51,14 +49,19 @@ value: MatchesContextValue;

};
export type RouterProps<TRouteConfig extends AnyRoute = AnyRoute, TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo, TDehydrated extends Record<string, any> = Record<string, any>> = RouterOptions<TRouteConfig, TDehydrated> & {
export type RouterProps<TRouteConfig extends AnyRoute = AnyRoute, TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo, TDehydrated extends Record<string, any> = Record<string, any>> = Omit<RouterOptions<TRouteConfig, TDehydrated>, 'context'> & {
router: Router<TRouteConfig, TRoutesInfo>;
context?: Partial<RouterOptions<TRouteConfig, TDehydrated>['context']>;
};
export declare function MatchesProvider({ matches, children, }: {
matches: RouteMatch[];
children: ReactNode;
}): JSX.Element;
export 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;
export declare function useRouterContext(): RegisteredRouter;
export declare function useRouter<T = RouterState>(track?: (state: Router['__store']['state']) => T): RegisteredRouter;
export declare function useRouter(): RegisteredRouter;
export declare function useRouterState<T = Router['state']>(select?: (state: Router['state']) => T): T;
export declare function useMatches(): RouteMatch[];
export declare function useMatch<TFrom extends keyof RegisteredRoutesInfo['routesById'], TStrict extends boolean = true, TRouteMatch = RouteMatch<RegisteredRoutesInfo, RegisteredRoutesInfo['routesById'][TFrom]>>(opts?: {
export declare function useMatch<TFrom extends keyof RegisteredRoutesInfo['routesById'], TStrict extends boolean = true, TRouteMatchState = RouteMatch<RegisteredRoutesInfo, RegisteredRoutesInfo['routesById'][TFrom]>>(opts?: {
from: TFrom;
strict?: TStrict;
track?: (match: TRouteMatch) => any;
}): TStrict extends true ? TRouteMatch : TRouteMatch | undefined;
track?: (match: TRouteMatchState) => any;
}): TStrict extends true ? TRouteMatchState : TRouteMatchState | undefined;
export type RouteFromIdOrRoute<T> = T extends RegisteredRoutesInfo['routeUnion'] ? T : T extends keyof RegisteredRoutesInfo['routesById'] ? RegisteredRoutesInfo['routesById'][T] : T extends string ? keyof RegisteredRoutesInfo['routesById'] : never;

@@ -68,3 +71,2 @@ export declare function useLoader<TFrom extends keyof RegisteredRoutesInfo['routesById'], TStrict extends boolean = true, TLoader = RegisteredRoutesInfo['routesById'][TFrom]['__types']['loader'], TSelected = TLoader>(opts?: {

strict?: TStrict;
track?: (search: TLoader) => TSelected;
}): TStrict extends true ? TSelected : TSelected | undefined;

@@ -74,7 +76,5 @@ export declare function useSearch<TFrom extends keyof RegisteredRoutesInfo['routesById'], TStrict extends boolean = true, TSearch = RegisteredRoutesInfo['routesById'][TFrom]['__types']['fullSearchSchema'], TSelected = TSearch>(opts?: {

strict?: TStrict;
track?: (search: TSearch) => TSelected;
}): TStrict extends true ? TSelected : TSelected | undefined;
export 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;

@@ -95,1 +95,2 @@ export declare function useNavigate<TDefaultFrom extends RegisteredRoutesInfo['routePaths'] = '/'>(defaultOpts?: {

export declare function Block({ message, condition, children }: PromptProps): any;
export declare function shallow<T>(objA: T, objB: T): boolean;
import { ParsePathParams } from './link';
import { RouteMatch } from './routeMatch';
import { AnyRouter, Router } from './router';
import { AnyRouter, Router, AnyRouteMatch, RouteMatch } from './router';
import { IsAny, NoInfer, PickRequired, PickUnsafe, UnionToIntersection } from './utils';

@@ -71,3 +70,3 @@ import { AnyRoutesInfo, DefaultRoutesInfo } from './routeInfo';

router: AnyRouter;
match: RouteMatch;
match: AnyRouteMatch;
}) => Promise<void> | void;

@@ -112,3 +111,5 @@ onBeforeLoadError?: (err: any) => void;

};
export 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;
export type OnLoadFn<TLoader = unknown, TSearchSchema extends AnySearchSchema = {}, TFullSearchSchema extends AnySearchSchema = {}, TAllParams = {}, TContext extends AnyContext = AnyContext, TAllContext extends AnyContext = AnyContext> = (match: LoaderContext<TSearchSchema, TFullSearchSchema, TAllParams, TContext, TAllContext> & {
parentMatchPromise?: Promise<void>;
}) => Promise<TLoader> | TLoader;
export type OnLoadFnKey<TSearchSchema extends AnySearchSchema = {}, TFullSearchSchema extends AnySearchSchema = {}, TAllParams = {}, TContext extends AnyContext = AnyContext, TAllContext extends AnyContext = AnyContext> = (loaderContext: {

@@ -122,3 +123,3 @@ params: TAllParams;

search: TFullSearchSchema;
signal?: AbortSignal;
abortController: AbortController;
preload: boolean;

@@ -146,2 +147,3 @@ routeContext: TContext;

}
export type AnyRouteWithRouterContext<TRouterContext extends AnyContext> = Route<any, any, any, any, any, any, any, any, any, any, any, any, any, any, TRouterContext, any, any>;
type MergeFromParent<T, U> = IsAny<T, U, T & U>;

@@ -218,5 +220,8 @@ export type UseLoaderResult<T> = T extends Record<PropertyKey, infer U> ? {

export type AnyRootRoute = RootRoute<any, any, any, any>;
export declare class RouterContext<TRouterContext extends {}> {
constructor();
createRootRoute: <TLoader = unknown, TSearchSchema extends AnySearchSchema = {}, TContext extends RouteContext = RouteContext>(options?: Omit<RouteOptions<AnyRoute, "__root__", "", TLoader, {}, TSearchSchema, NoInfer<TSearchSchema>, {}, TRouterContext, TRouterContext, TContext, NoInfer<TContext>, RouteContext, IsAny<NoInfer<TContext>, RouteContext, NoInfer<TContext> & RouteContext>>, "caseSensitive" | "id" | "path" | "getParentRoute" | "parseParams" | "stringifyParams"> | undefined) => RootRoute<TLoader, TSearchSchema, TContext, TRouterContext>;
}
export 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>;
}

@@ -223,0 +228,0 @@ type ResolveFullPath<TParentRoute extends AnyRoute, TPath extends string, TPrefixed extends RoutePrefix<TParentRoute['fullPath'], TPath> = RoutePrefix<TParentRoute['fullPath'], TPath>> = TPrefixed extends RootRouteId ? '/' : TPrefixed;

/// <reference types="react" />
import { Store } from '@tanstack/react-store';
import { LinkInfo, LinkOptions, NavigateOptions, ToOptions, ResolveRelativePath } from './link';
import { AnySearchSchema, AnyRoute, RootRoute, AnyContext } from './route';
import { RoutesInfo, AnyRoutesInfo, RoutesById, RoutesByPath } from './routeInfo';
import { RouteMatch } from './routeMatch';
import { Route, AnySearchSchema, AnyRoute, RootRoute, AnyContext, AnyPathParams } from './route';
import { RoutesInfo, AnyRoutesInfo, RoutesById, RoutesByPath, DefaultRoutesInfo } from './routeInfo';
import { NoInfer, PickAsRequired, Timeout, Updater } from './utils';

@@ -47,3 +46,22 @@ import { RouterHistory } from './history';

};
type RouterContextOptions<TRouteTree extends AnyRoute> = AnyContext extends TRouteTree['__types']['routerContext'] ? {
export interface RouteMatch<TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo, TRoute extends AnyRoute = Route> {
id: string;
routeId: string;
pathname: string;
params: TRoute['__types']['allParams'];
status: 'pending' | 'success' | 'error';
error: unknown;
updatedAt: number;
loader: TRoute['__types']['loader'];
loadPromise?: Promise<void>;
__resolveLoadPromise?: () => void;
routeContext: TRoute['__types']['routeContext'];
context: TRoute['__types']['context'];
routeSearch: TRoute['__types']['searchSchema'];
search: TRoutesInfo['fullSearchSchema'] & TRoute['__types']['fullSearchSchema'];
fetchedAt: number;
abortController: AbortController;
}
export type AnyRouteMatch = RouteMatch<AnyRoutesInfo, AnyRoute>;
export type RouterContextOptions<TRouteTree extends AnyRoute> = AnyContext extends TRouteTree['__types']['routerContext'] ? {
context?: TRouteTree['__types']['routerContext'];

@@ -77,3 +95,2 @@ } : {

onRouteChange?: () => void;
fetchServerDataFn?: FetchServerDataFn;
context?: TRouteTree['__types']['routerContext'];

@@ -86,9 +103,6 @@ Wrap?: React.ComponentType<{

}
type FetchServerDataFn = (ctx: {
router: AnyRouter;
routeMatch: RouteMatch;
}) => Promise<any>;
export interface RouterState<TRoutesInfo extends AnyRoutesInfo = AnyRoutesInfo, TState extends LocationState = LocationState> {
status: 'idle' | 'pending';
matches: RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[];
preloadMatches: Record<string, RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>>;
location: ParsedLocation<TRoutesInfo['fullSearchSchema'], TState>;

@@ -108,8 +122,4 @@ resolvedLocation: ParsedLocation<TRoutesInfo['fullSearchSchema'], TState>;

fromCurrent?: boolean;
__matches?: RouteMatch[];
__matches?: AnyRouteMatch[];
}
export type MatchCacheEntry = {
gc: number;
match: RouteMatch;
};
export interface MatchLocation {

@@ -133,5 +143,4 @@ to?: string | number | null;

}
export type MatchCache = Record<string, MatchCacheEntry>;
export declare const defaultFetchServerDataFn: FetchServerDataFn;
export type RouterConstructorOptions<TRouteTree extends AnyRoute, TDehydrated extends Record<string, any>> = Omit<RouterOptions<TRouteTree, TDehydrated>, 'context'> & RouterContextOptions<TRouteTree>;
export declare const componentTypes: readonly ["component", "errorComponent", "pendingComponent"];
export declare class Router<TRouteTree extends AnyRoute = AnyRoute, TRoutesInfo extends AnyRoutesInfo = RoutesInfo<TRouteTree>, TDehydrated extends Record<string, any> = Record<string, any>> {

@@ -144,3 +153,2 @@ #private;

options: PickAsRequired<RouterOptions<TRouteTree, TDehydrated>, 'stringifySearch' | 'parseSearch' | 'context'>;
context: NonNullable<TRouteTree['__types']['routerContext']>;
history: RouterHistory;

@@ -159,3 +167,3 @@ basepath: string;

resolveNavigation: () => void;
constructor(options?: RouterConstructorOptions<TRouteTree, TDehydrated>);
constructor(options: RouterConstructorOptions<TRouteTree, TDehydrated>);
reset: () => void;

@@ -166,2 +174,3 @@ mount: () => () => void;

cancelMatches: () => void;
cancelMatch: (id: string) => void;
safeLoad: (opts?: {

@@ -174,9 +183,8 @@ next?: ParsedLocation;

getRoute: <TId extends keyof TRoutesInfo["routesById"]>(id: TId) => TRoutesInfo["routesById"][TId];
loadRoute: (navigateOpts?: BuildNextOptions) => Promise<RouteMatch[]>;
preloadRoute: (navigateOpts?: BuildNextOptions) => Promise<RouteMatch<import("./routeInfo").DefaultRoutesInfo, AnyRoute>[]>;
matchRoutes: (pathname: string, search: AnySearchSchema, opts?: {
preloadRoute: (navigateOpts?: BuildNextOptions) => Promise<RouteMatch<TRoutesInfo, TRoutesInfo["routeIntersection"]>[]>;
matchRoutes: (pathname: string, locationSearch: AnySearchSchema, opts?: {
strictParseParams?: boolean;
debug?: boolean;
}) => RouteMatch[];
loadMatches: (resolvedMatches: RouteMatch[], location: ParsedLocation, opts?: {
}) => RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[];
loadMatches: (resolvedMatches: AnyRouteMatch[], opts?: {
preload?: boolean;

@@ -195,2 +203,5 @@ }) => Promise<void>;

hydrateData: <T = unknown>(key: any) => T | undefined;
getRouteMatch: (id: string) => undefined | RouteMatch<TRoutesInfo, AnyRoute>;
setRouteMatch: (id: string, updater: (prev: RouteMatch<TRoutesInfo, AnyRoute>) => RouteMatch<TRoutesInfo, AnyRoute>) => void;
setPreloadRouteMatch: (id: string, updater: (prev: RouteMatch<TRoutesInfo, AnyRoute>) => RouteMatch<TRoutesInfo, AnyRoute>) => void;
}

@@ -203,2 +214,7 @@ export type AnyRedirect = Redirect<any, any, any>;

export declare function isRedirect(obj: any): obj is AnyRedirect;
export {};
export declare function createRouteMatch({ route, id, params, pathname, }: {
route: AnyRoute;
id: string;
params: AnyPathParams;
pathname: string;
}): RouteMatch<DefaultRoutesInfo, Route<AnyRoute, "/", "/" | `/${any}/`, string, "/" | `/${any}/`, unknown, {}, any, Record<never, string>, Record<never, string>, any, any, import("./route").RouteContext, import("./route").RouteContext, AnyContext, unknown, DefaultRoutesInfo>>;

@@ -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.search}${window.location.hash}`),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):"",search:o>-1?t.slice(o,-1===r?void 0:r):"",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){return e.reduce(((e,r)=>(e[r]=t[r],e)),{})}function _(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]=_(t[s],r[s]),n[s]===t[s]&&i++}return e===s&&i===e?t:n}return r}function w(t){if(!b(t))return!1;const e=t.constructor;if(void 0===e)return!0;const r=e.prototype;return!!b(r)&&!!r.hasOwnProperty("isPrototypeOf")}function b(t){return"[object Object]"===Object.prototype.toString.call(t)}function S(t,e){return t===e||typeof t==typeof e&&(w(t)&&w(e)?!Object.keys(e).some((r=>!S(t[r],e[r]))):!(!Array.isArray(t)||!Array.isArray(e))&&(t.length===e.length&&t.every(((t,r)=>S(t,e[r])))))}function P(t){return E(t.filter(Boolean).join("/"))}function E(t){return t.replace(/\/{2,}/g,"/")}function x(t){return"/"===t?t:t.replace(/^\/{1,}/,"")}function R(t){return"/"===t?t:t.replace(/\/{1,}$/,"")}function C(t){return R(x(t))}function L(t,e,r){e=e.replace(new RegExp(`^${t}`),"/"),r=r.replace(new RegExp(`^${t}`),"/");let o=k(e);const a=k(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 E(P([t,...o.map((t=>t.value))]))}function k(t){if(!t)return[];const e=[];if("/"===(t=E(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 j(t,e,r=!1){return P(k(t).map((t=>{if("wildcard"===t.type){const o=e[t.value];return r?`${t.value}${o??""}`:o}return"param"===t.type?e[t.value.substring(1)]??"":t.value})))}function O(t,e,r){const o=D(t,e,r);if(!r.to||o)return o??{}}function D(t,e,r){e="/"!=t?e.substring(t.length):e;const o=`${r.to??"$"}`,a=k(e),s=k(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["*"]=P(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 M(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 $(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 T(){return T=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},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 n(t,e){if(!t)throw new Error("Invariant failed")}function s(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=[],n=[];const s=()=>{if(a.length)a[0]?.(s,(()=>{a=[],u()}));else{for(;n.length;)n.shift()?.();l()}},i=t=>{n.push(t),s()},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.search}${window.location.hash}`),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):"",search:o>-1?t.slice(o,-1===r?void 0:r):"",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){return e.reduce(((e,r)=>(e[r]=t[r],e)),{})}function b(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),n=a.length,s=o?[]:{};let i=0;for(let e=0;e<n;e++){const n=o?e:a[e];s[n]=b(t[n],r[n]),s[n]===t[n]&&i++}return e===n&&i===e?t:s}return r}function w(t){if(!S(t))return!1;const e=t.constructor;if(void 0===e)return!0;const r=e.prototype;return!!S(r)&&!!r.hasOwnProperty("isPrototypeOf")}function S(t){return"[object Object]"===Object.prototype.toString.call(t)}function R(t,e){return t===e||typeof t==typeof e&&(w(t)&&w(e)?!Object.keys(e).some((r=>!R(t[r],e[r]))):!(!Array.isArray(t)||!Array.isArray(e))&&(t.length===e.length&&t.every(((t,r)=>R(t,e[r])))))}function E(t){return _(t.filter(Boolean).join("/"))}function _(t){return t.replace(/\/{2,}/g,"/")}function P(t){return"/"===t?t:t.replace(/^\/{1,}/,"")}function x(t){return"/"===t?t:t.replace(/\/{1,}$/,"")}function C(t){return x(P(t))}function M(t,e,r){e=e.replace(new RegExp(`^${t}`),"/"),r=r.replace(new RegExp(`^${t}`),"/");let o=L(e);const a=L(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 _(E([t,...o.map((t=>t.value))]))}function L(t){if(!t)return[];const e=[];if("/"===(t=_(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 k(t,e,r=!1){return E(L(t).map((t=>{if("wildcard"===t.type){const o=e[t.value];return r?`${t.value}${o??""}`:o}return"param"===t.type?e[t.value.substring(1)]??"":t.value})))}function j(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=L(e),n=L(o);e.startsWith("/")||a.unshift({type:"pathname",value:"/"}),o.startsWith("/")||n.unshift({type:"pathname",value:"/"});const s={};return(()=>{for(let t=0;t<Math.max(a.length,n.length);t++){const e=a[t],o=n[t],i=t>=a.length-1,c=t>=n.length-1;if(o){if("wildcard"===o.type)return!!e?.value&&(s["*"]=E(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)&&(s[o.value.substring(1)]=e.value)}}if(!i&&c)return!!r.fuzzy}return!0})()?s:void 0}function I(t,e){var r,o,a,n="";for(r in t)if(void 0!==(a=t[r]))if(Array.isArray(a))for(o=0;o<a.length;o++)n&&(n+="&"),n+=encodeURIComponent(r)+"="+encodeURIComponent(a[o]);else n&&(n+="&"),n+=encodeURIComponent(r)+"="+encodeURIComponent(a);return(e||"")+n}function D(t){if(!t)return"";var e=decodeURIComponent(t);return"false"!==e&&("true"===e||("0"===e.charAt(0)?e:0*+e==0?+e:e))}function $(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],D(e.shift())):o[r]=D(e.shift());return o}function A(){return A=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},A.apply(this,arguments)}
/**

@@ -22,3 +22,3 @@ * @tanstack/store/src/index.ts

* @license MIT
*/class I{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()}}
*/class T{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 @@ * @tanstack/react-store/src/index.tsx

* @license MIT
*/function H(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 B(t){const e=W(),{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:P,onTouchStart:E,...x}=t,R=e.buildLink(t);if("external"===R.type){const{href:t}=R;return{href:t}}const{handleClick:C,handleFocus:L,handleEnter:k,handleLeave:j,handleTouchStart:O,isActive:D,next:M}=R,A=t=>e=>{e.persist&&e.persist(),t.filter(Boolean).forEach((t=>{e.defaultPrevented||t(e)}))},$=D?g(n,{})??{}:{},T=D?{}:g(i,{})??{};return{...$,...T,...x,href:h?void 0:M.href,onClick:A([w,t=>{a.startTransition?a.startTransition((()=>{C(t)})):C(t)}]),onFocus:A([b,L]),onMouseEnter:A([S,k]),onMouseLeave:A([P,j]),onTouchStart:A([E,O]),target:s,style:{...v,...$.style,...T.style},className:[_,$.className,T.className].filter(Boolean).join(" ")||void 0,...h?{role:"link","aria-disabled":!0}:void 0,"data-status":D?"active":void 0}}const F=a.forwardRef(((t,e)=>{const r=B(t);return a.createElement("a",T({ref:e},r,{children:"function"==typeof t.children?t.children({isActive:"active"===r["data-status"]}):t.children}))}));const U=a.createContext(null),z=a.createContext(null);function W(){const t=a.useContext(z);return H(t.router.__store),t.router}function J(t){const e=W();return H(e.__store,t),e}function K(){return a.useContext(U)}function q(t){const e=W(),r=K()[0],o=e.state.matches,a=t?.from?o.find((e=>e.route.id===t?.from)):r;return s(a,t?.from&&t.from),(t?.strict??1)&&s(r.route.id==a?.route.id,(a?.route.id,r.route.id,a?.route.id,a?.route.id)),H(a.__store,(e=>t?.track?.(a)??a)),a}function V(t){const{track:e,...r}=t,o=q(r);return H(o.__store,(e=>t?.track?.(e.loader)??e.loader)),o.state.loader}function Y(t){const{track:e,...r}=t??{},o=q(r);return H(o.__store,(e=>t?.track?.(e.search)??e.search)),o.state.search}function G(t){return H(W().__store,(e=>{const r=y(e.matches)?.params;return t?.track?.(r)??r}))}function Q(){const t=W();return a.useCallback((e=>{const{pending:r,caseSensitive:o,...a}=e;return t.matchRoute(a,{pending:r,caseSensitive:o})}),[])}function X(){const t=K().slice(1),e=t[0];return e?a.createElement(Z,{matches:t,match:e}):null}function Z({matches:t,match:e}){const r=W();H(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??!e.route.isRoot?a.Suspense:et,c=n?rt:et;return a.createElement(U.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(tt,{match:e}))))}function tt(t){const e=W();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){let r=t.match.component??e.options.defaultComponent;return r?a.createElement(r,{useLoader:t.match.route.useLoader,useMatch:t.match.route.useMatch,useContext:t.match.route.useContext,useSearch:t.match.route.useSearch,useParams:t.match.route.useParams}):a.createElement(X,null)}s(!1)}function et(t){return a.createElement(a.Fragment,null,t.children)}class rt 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(ot,T({},this.props,{errorState:this.state,reset:()=>this.setState({})}))}}function ot(t){const[e,r]=a.useState(t.errorState),o=W(),s=t.errorComponent??at,n=a.useRef("");return a.useEffect((()=>{e&&(o.state.location.key,n.current),n.current=o.state.location.key}),[e,o.state.location.key]),a.useEffect((()=>{t.errorState.error}),[t.errorState.error]),t.errorState.error&&e.error?a.createElement(s,e):t.children}function at({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 st(t,e=!0){const r=J();a.useEffect((()=>{if(!e)return;let o=r.history.block(((e,r)=>{window.confirm(t)&&(o(),e())}));return o}))}const nt="__root__";class it{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=nt:s(this.parentRoute);let o=r?nt:e.path;o&&"/"!==o&&(o=C(o));const a=e?.id||o;let n=r?nt:P([this.parentRoute.id===nt?"":this.parentRoute.id,a]);o===nt&&(o="/"),n!==nt&&(n=P(["/",n]));const i=n===nt?"/":P([this.parentRoute.fullPath,o]);this.path=o,this.id=n,this.fullPath=i,this.to=i};addChildren=t=>(this.children=t,this);useMatch=t=>q({...t,from:this.id});useLoader=t=>V({...t,from:this.id});useContext=t=>q({...t,from:this.id}).context;useSearch=t=>Y({...t,from:this.id});useParams=t=>G({...t,from:this.id})}class ct extends it{constructor(t){super(t)}static withRouterContext=()=>t=>new ct(t)}const ht=lt(JSON.parse),ut=dt(JSON.stringify);function lt(t){return e=>{"?"===e.substring(0,1)&&(e=e.substring(1));let r=$(e);for(let e in r){const o=r[e];if("string"==typeof o)try{r[e]=t(o)}catch(t){}}return r}}function dt(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=M(e).toString();return r?`?${r}`:""}}const pt=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 ft="undefined"==typeof window||!window.document.createElement;function mt(){return{status:"idle",resolvedLocation:null,location:null,matches:[],lastUpdated:Date.now()}}function yt(t){return!!t?.isRedirect}const gt=["component","errorComponent","pendingComponent"];class vt{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 I({updatedAt:0,routeSearch:{},search:{},status:"pending",loader:void 0},{onUpdate:()=>{this.state=this.__store.state}})}),this.state=this.__store.state,gt.map((async t=>{const e=this.route.options[t];this[t]=e})),this.__loadPromise=new Promise((t=>{this.__loadPromiseResolve=t})),"pending"!==this.state.status||this.#t()||(this.__store.setState((t=>({...t,status:"success"}))),this.__loadPromiseResolve?.())}#t=()=>!(!this.route.options.loader&&!gt.some((t=>this.route.options[t]?.preload)));__commit=()=>{const{routeSearch:t,search:e,context:r,routeContext:o}=this.#e({location:this.router.state.location});this.context=r,this.routeContext=o,this.__store.setState((r=>({...r,routeSearch:_(r.routeSearch,t),search:_(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(yt(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 yt(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,n={params:this.params,routeSearch:r,search:o,signal:this.abortController.signal,preload:!!t?.preload,routeContext:s,context:a};return this.__loadPromise=Promise.resolve().then((async()=>{const e=""+Date.now()+Math.random();this.#o=e;const r=()=>e!==this.#o?this.__loadPromise:void 0;let o;const a=(async()=>{await Promise.all(gt.map((async t=>{const e=this.route.options[t];e?.preload&&await e.preload()})))})(),s=Promise.resolve().then((()=>{if(this.route.options.loader)return this.route.options.loader(n)}));try{const[e,n]=await Promise.all([a,s]);if(o=r())return await o;t.preload||this.__store.setState((t=>({...t,error:void 0,status:"success",updatedAt:Date.now(),loader:n})))}catch(e){if(yt(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 yt(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{this.__loadPromiseResolve?.(),delete this.__loadPromise}})),this.__loadPromise};#o=""}t.Block=function({message:t,condition:e,children:r}){return st(t,e),r??null},t.ErrorComponent=at,t.Link=F,t.MatchRoute=function(t){const e=Q()(t);return e?"function"==typeof t.children?t.children(e):e?t.children:null:null},t.Navigate=function(t){const e=W();return a.useLayoutEffect((()=>{e.navigate(t)}),[]),null},t.Outlet=X,t.RootRoute=ct,t.Route=it,t.RouteMatch=vt,t.Router=class{#a;startedLoadingAt=Date.now();resolveNavigation=()=>{};constructor(t){this.options={defaultPreloadDelay:50,context:void 0,...t,stringifySearch:t?.stringifySearch??ut,parseSearch:t?.parseSearch??ht,fetchServerDataFn:t?.fetchServerDataFn??pt},this.__store=new I(mt(),{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.location.href!==e.href&&this.#s({...e,replace:!0})}reset=()=>{this.__store.setState((t=>Object.assign(t,mt())))};mount=()=>(ft||this.state.matches.length||this.safeLoad(),()=>{});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??(ft?p():d());const t=this.#n();this.__store.setState((e=>({...e,resolvedLocation:t,location:t}))),this.#a=this.history.listen((()=>{this.safeLoad({next:this.#n(this.state.location)})}))}const{basepath:e,routeTree:r}=this.options;return this.basepath=`/${C(e??"")??""}`,r&&r!==this.routeTree&&this.#i(r),this};buildNext=t=>{const e=this.#c(t),r=this.matchRoutes(e.pathname,e.search);return this.#c({...t,__matches:r})};cancelMatches=()=>{[...this.state.matches].forEach((t=>{t.cancel()}))};safeLoad=t=>{this.load(t).catch((t=>{console.warn(t),s(!1)}))};load=async t=>{this.#h();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,location:t.next}))),o=this.matchRoutes(this.state.location.pathname,this.state.location.search,{strictParseParams:!0,debug:!0}),this.__store.setState((t=>({...t,status:"pending",matches:o})))})),o.forEach((t=>{t.__commit()})),await this.loadMatches(o,this.state.location),this.startedLoadingAt!==r)return this.navigationPromise;const a=this.state.matches,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.location;this.__store.setState((t=>({...t,status:"idle",resolvedLocation:t.location,matches:o}))),c.href!==this.state.location.href&&this.options.onRouteChange?.(),this.resolveNavigation()};getRoute=t=>{const e=this.routesById[t];return s(e),e};loadRoute=async(t=this.state.location)=>{const e=this.buildNext(t),r=this.matchRoutes(e.pathname,e.search,{strictParseParams:!0});return await this.loadMatches(r,e),r};preloadRoute=async(t=this.state.location)=>{const e=this.buildNext(t),r=this.matchRoutes(e.pathname,e.search,{strictParseParams:!0});return await this.loadMatches(r,e,{preload:!0}),r};matchRoutes=(t,e,r)=>{if(!this.flatRoutes.length)return[];let o={},a=this.flatRoutes.find((e=>{const r=O(this.basepath,t,{to:e.fullPath,caseSensitive:e.options.caseSensitive??this.options.caseSensitive});return!!r&&(o=r,!0)}));if(!a)return[];let s=[a];for(;a?.parentRoute;)a=a.parentRoute,a&&s.unshift(a);let n={};const i=[...this.state.matches];return s.map((t=>{let a;try{a=t.options.parseParams?.(o)??o}catch(t){if(r?.strictParseParams)throw t}Object.assign(n,a);const s=j(t.path,n),c=j(t.id,n,!0)+(t.options.getKey?.({params:n,search:e})??""),h=i.find((t=>t.id===c));return h||new vt(this,t,{id:c,params:n,pathname:P([this.basepath,s])})})).filter(((t,e,r)=>r.findIndex((e=>e.id===t.id))===e))};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(yt(r))throw r;o=o??e;const a=t.route.options.onBeforeLoadError??t.route.options.onError;try{a?.(r)}catch(e){if(yt(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(yt(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)=>L(this.basepath,t,E(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);if(e?.pending&&"pending"!==this.state.status)return!1;const o=e?.pending?this.state.location:this.state.resolvedLocation;if(!o)return!1;const a=O(this.basepath,o.pathname,{...e,to:r.pathname});return!!a&&(e?.includeSearch??1?!!S(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.location.pathname.split("/"),m=d.pathname.split("/").every(((t,e)=>t===f[e])),y=i?.exact?this.state.location.pathname===d.pathname:m,g=!i?.includeHash||this.state.location.hash===d.hash,v=!(i?.includeSearch??1)||S(this.state.location.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}};dehydrate=()=>({state:{...v(this.state,["location","status","lastUpdated"])}});hydrate=async t=>{let e=t;"undefined"!=typeof document&&(e=window.__TSR_DEHYDRATED__),s(e);const r=e;this.options.hydrate?.(r.payload),this.__store.setState((t=>({...t,...r.router.state,matches:t.matches,resolvedLocation:r.router.state.location}))),await this.load()};injectedHtml=[];injectHtml=async t=>{this.injectedHtml.push(t)};dehydrateData=(t,e)=>{if("undefined"==typeof document){const r="string"==typeof t?t:JSON.stringify(t);return this.injectHtml((async()=>{const t="function"==typeof e?await e():e;return`<script>window["__TSR__DEHYRATED__${o=r,o.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/"/g,'\\"')}"] = ${JSON.stringify(t)}<\/script>`;var o})),()=>this.hydrateData(t)}return()=>{}};hydrateData=t=>{if("undefined"!=typeof document){const e="string"==typeof t?t:JSON.stringify(t);return window[`__TSR__DEHYRATED__${e}`]}};#i=t=>{this.routeTree=t,this.routesById={},this.routesByPath={},this.flatRoutes=[];const e=t=>{t.forEach(((t,r)=>{t.init({originalIndex:r,router:this});if(s(!this.routesById[t.id],String(t.id)),this.routesById[t.id]=t,!t.isRoot&&t.path){const e=R(t.fullPath);this.routesByPath[e]&&!t.fullPath.endsWith("/")||(this.routesByPath[e]=t)}const o=t.children;o?.length&&e(o)}))};e([t]),this.flatRoutes=Object.values(this.routesByPath).map(((t,e)=>{const r=C(t.fullPath),o=k(r);for(;o.length>1&&"/"===o[0]?.value;)o.shift();const a=o.map((t=>"param"===t.type?.5:"wildcard"===t.type?.25:1));return{child:t,trimmed:r,parsed:o,index:e,score:a}})).sort(((t,e)=>{let r="/"===t.trimmed?1:"/"===e.trimmed?-1:0;if(0!==r)return r;const o=Math.min(t.score.length,e.score.length);if(t.score.length!==e.score.length)return e.score.length-t.score.length;for(let r=0;r<o;r++)if(t.score[r]!==e.score[r])return e.score[r]-t.score[r];for(let r=0;r<o;r++)if(t.parsed[r].value!==e.parsed[r].value)return t.parsed[r].value>e.parsed[r].value?1:-1;return t.trimmed!==e.trimmed?t.trimmed>e.trimmed?1:-1:t.index-e.index})).map(((t,e)=>(t.child.rank=e,t.child)))};#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:_(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.location.pathname:t.from??this.state.location.pathname;let r=L(this.basepath??"/",e,`${t.to??""}`);const o={...y(this.matchRoutes(this.state.location.pathname,this.state.location.search,{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=j(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.location.search):this.state.location.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=_(this.state.location.search,h),l=this.options.stringifySearch(u),d=!0===t.hash?this.state.location.hash:g(t.hash,this.state.location.hash),p=d?`#${d}`:"";return{pathname:r,search:u,searchStr:l,state:!0===t.state?this.state.location.state:g(t.state,this.state.location.state),hash:d,href:this.history.createHref(`${r}${l}${p}`),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.location.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.#h()};#h=()=>{const t=this.resolveNavigation;return this.navigationPromise=new Promise((e=>{this.resolveNavigation=()=>{e(),t()}})),this.navigationPromise}},t.RouterProvider=function({router:t,...e}){t.update(e);const r=H(t.__store,(t=>t.matches));return a.useEffect(t.mount,[t]),a.createElement(z.Provider,{value:{router:t}},a.createElement(U.Provider,{value:[void 0,...r]},a.createElement(rt,{errorComponent:at,onCatch:()=>{}},a.createElement(X,null))))},t.cleanPath=E,t.createBrowserHistory=d,t.createHashHistory=function(){return d({getHref:()=>window.location.hash.substring(1),createHref:t=>`#${t}`})},t.createMemoryHistory=p,t.decode=$,t.defaultFetchServerDataFn=pt,t.defaultParseSearch=ht,t.defaultStringifySearch=ut,t.encode=M,t.functionalUpdate=g,t.interpolatePath=j,t.invariant=s,t.isPlainObject=w,t.isRedirect=yt,t.joinPaths=P,t.last=y,t.lazy=function(t,e="default"){const r=a.lazy((async()=>({default:(await t())[e]})));return r.preload=async()=>{await t()},r},t.matchByPath=D,t.matchPathname=O,t.matchesContext=U,t.parsePathname=k,t.parseSearchWith=lt,t.partialDeepEqual=S,t.pick=v,t.redirect=function(t){return t.isRedirect=!0,t},t.replaceEqualDeep=_,t.resolvePath=L,t.rootRouteId=nt,t.routerContext=z,t.stringifySearchWith=dt,t.trimPath=C,t.trimPathLeft=x,t.trimPathRight=R,t.useBlocker=st,t.useDehydrate=function(){const t=W();return a.useCallback((function(e,r){return t.dehydrateData(e,r)}),[])},t.useHydrate=function(){const t=W();return function(e){return t.hydrateData(e)}},t.useInjectHtml=function(){const t=W();return a.useCallback((e=>{t.injectHtml(e)}),[])},t.useLinkProps=B,t.useLoader=V,t.useMatch=q,t.useMatchRoute=Q,t.useMatches=K,t.useNavigate=function(t){const e=W();return a.useCallback((r=>e.navigate({...t,...r})),[])},t.useParams=G,t.useRouter=J,t.useRouterContext=W,t.useSearch=Y,t.useStore=H,t.warning=n,Object.defineProperty(t,"__esModule",{value:!0})}));
*/function H(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 N(t){const e=J(),{type:r,children:o,target:n,activeProps:s=(()=>({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:b,onClick:w,onFocus:S,onMouseEnter:R,onMouseLeave:E,onTouchStart:_,...P}=t,x=e.buildLink(t);if("external"===x.type){const{href:t}=x;return{href:t}}const{handleClick:C,handleFocus:M,handleEnter:L,handleLeave:k,handleTouchStart:j,isActive:O,next:I}=x,D=t=>e=>{e.persist&&e.persist(),t.filter(Boolean).forEach((t=>{e.defaultPrevented||t(e)}))},$=O?g(s,{})??{}:{},A=O?{}:g(i,{})??{};return{...$,...A,...P,href:h?void 0:I.href,onClick:D([w,t=>{a.startTransition?a.startTransition((()=>{C(t)})):C(t)}]),onFocus:D([S,M]),onMouseEnter:D([R,L]),onMouseLeave:D([E,k]),onTouchStart:D([_,j]),target:n,style:{...v,...$.style,...A.style},className:[b,$.className,A.className].filter(Boolean).join(" ")||void 0,...h?{role:"link","aria-disabled":!0}:void 0,"data-status":O?"active":void 0}}const B=a.forwardRef(((t,e)=>{const r=N(t);return a.createElement("a",A({ref:e},r,{children:"function"==typeof t.children?t.children({isActive:"active"===r["data-status"]}):t.children}))}));const U=a.createContext(null),z=a.createContext(null),F=a.createContext(null);const W="undefined"==typeof document?a.useEffect:a.useLayoutEffect;function J(){return a.useContext(F)}function K(t){const e=a.useContext(z),r=t?.(e)??e,o=a.useRef(r);return it(o.current,r)||(o.current=r),o.current}function q(){return a.useContext(U)}function Y(t){const e=K(),r=q()[0],o=e.matches,a=t?.from?o.find((e=>e.routeId===t?.from)):r;return n(a,t?.from&&t.from),(t?.strict??1)&&n(r.routeId==a?.routeId,(a?.routeId,r.routeId,a?.routeId,a?.routeId)),a}function V(t){const{track:e,...r}=t;return Y(r).loader}function G(t){const{track:e,...r}=t??{};return Y(r).search}function Q(t){return K((t=>{const e=y(t.matches)?.params;return e}))}function X(){const t=J();return a.useCallback((e=>{const{pending:r,caseSensitive:o,...a}=e;return t.matchRoute(a,{pending:r,caseSensitive:o})}),[])}function Z(){const t=q().slice(1),e=t[0];return e?a.createElement(tt,{matches:t,match:e}):null}function tt({matches:t,match:e}){const r=J(),o=a.useCallback((()=>null),[]),n=r.getRoute(e.routeId),s=n.options.pendingComponent??r.options.defaultPendingComponent??o,i=n.options.errorComponent??r.options.defaultErrorComponent,c=n.options.wrapInSuspense??!n.isRoot?a.Suspense:rt,h=i?ot:rt;return a.createElement(U.Provider,{value:t},a.createElement(c,{fallback:a.createElement(s,null)},a.createElement(h,{key:n.id,errorComponent:i,onCatch:()=>{e.id}},a.createElement(et,{match:e}))))}function et(t){const e=J(),r=e.getRoute(t.match.routeId);if("error"===t.match.status)throw t.match.error;if("pending"===t.match.status)throw t.match.loadPromise||n(!1);if("success"===t.match.status){let t=r.options.component??e.options.defaultComponent;return t?a.createElement(t,{useLoader:r.useLoader,useMatch:r.useMatch,useContext:r.useContext,useSearch:r.useSearch,useParams:r.useParams}):a.createElement(Z,null)}n(!1)}function rt(t){return a.createElement(a.Fragment,null,t.children)}class ot 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(at,A({},this.props,{errorState:this.state,reset:()=>this.setState({})}))}}function at(t){const e=K(),[r,o]=a.useState(t.errorState),n=t.errorComponent??nt,s=a.useRef("");return a.useEffect((()=>{r&&e.location.key!==s.current&&o({}),s.current=e.location.key}),[r,e.location.key]),a.useEffect((()=>{t.errorState.error&&o(t.errorState)}),[t.errorState.error]),t.errorState.error&&r.error?a.createElement(n,r):t.children}function nt({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 st(t,e=!0){const r=J();a.useEffect((()=>{if(!e)return;let o=r.history.block(((e,r)=>{window.confirm(t)&&(o(),e())}));return o}))}function it(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}const ct="__root__";class ht{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=ct:n(this.parentRoute);let o=r?ct:e.path;o&&"/"!==o&&(o=C(o));const a=e?.id||o;let s=r?ct:E([this.parentRoute.id===ct?"":this.parentRoute.id,a]);o===ct&&(o="/"),s!==ct&&(s=E(["/",s]));const i=s===ct?"/":E([this.parentRoute.fullPath,o]);this.path=o,this.id=s,this.fullPath=i,this.to=i};addChildren=t=>(this.children=t,this);useMatch=t=>Y({...t,from:this.id});useLoader=t=>V({...t,from:this.id});useContext=t=>Y({...t,from:this.id}).context;useSearch=t=>G({...t,from:this.id});useParams=t=>Q(this.id)}class ut extends ht{constructor(t){super(t)}}const lt=pt(JSON.parse),dt=ft(JSON.stringify);function pt(t){return e=>{"?"===e.substring(0,1)&&(e=e.substring(1));let r=$(e);for(let e in r){const o=r[e];if("string"==typeof o)try{r[e]=t(o)}catch(t){}}return r}}function ft(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=I(e).toString();return r?`?${r}`:""}}const mt=["component","errorComponent","pendingComponent"];const yt="undefined"==typeof window||!window.document.createElement;function gt(){return{status:"idle",resolvedLocation:null,location:null,matches:[],preloadMatches:{},lastUpdated:Date.now()}}function vt(t){return!!t?.isRedirect}function bt({route:t,id:e,params:r,pathname:o}){const a=!(!t.options.loader&&!mt.some((e=>t.options[e]?.preload)));return{id:e,routeId:t.id,params:r,pathname:o,updatedAt:0,routeSearch:{},search:{},status:a?"pending":"success",error:void 0,loader:void 0,loadPromise:Promise.resolve(),routeContext:void 0,context:void 0,abortController:new AbortController,fetchedAt:0}}t.Block=function({message:t,condition:e,children:r}){return st(t,e),r??null},t.ErrorComponent=nt,t.Link=B,t.MatchRoute=function(t){const e=X()(t);return e?"function"==typeof t.children?t.children(e):e?t.children:null:null},t.MatchesProvider=function({matches:t,children:e}){return a.createElement(U.Provider,{value:t},e)},t.Navigate=function(t){const e=J();return a.useLayoutEffect((()=>{e.navigate(t)}),[]),null},t.Outlet=Z,t.RootRoute=ut,t.Route=ht,t.Router=class{#t;startedLoadingAt=Date.now();resolveNavigation=()=>{};constructor(t){this.options={defaultPreloadDelay:50,context:void 0,...t,stringifySearch:t?.stringifySearch??dt,parseSearch:t?.parseSearch??lt},this.__store=new T(gt(),{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.location.href!==e.href&&this.#e({...e,replace:!0})}reset=()=>{this.__store.setState((t=>Object.assign(t,gt())))};mount=()=>(yt||this.state.matches.length||this.safeLoad(),()=>{});update=t=>{if(this.options={...this.options,...t,context:{...this.options.context,...t?.context}},!this.history||this.options.history&&this.options.history!==this.history){this.#t&&this.#t(),this.history=this.options.history??(yt?p():d());const t=this.#r();this.__store.setState((e=>({...e,resolvedLocation:t,location:t}))),this.#t=this.history.listen((()=>{this.safeLoad({next:this.#r(this.state.location)})}))}const{basepath:e,routeTree:r}=this.options;return this.basepath=`/${C(e??"")??""}`,r&&r!==this.routeTree&&this.#o(r),this};buildNext=t=>{const e=this.#a(t),r=this.matchRoutes(e.pathname,e.search);return this.#a({...t,__matches:r})};cancelMatches=()=>{this.state.matches.forEach((t=>{this.cancelMatch(t.id)}))};cancelMatch=t=>{this.getRouteMatch(t)?.abortController?.abort()};safeLoad=t=>{this.load(t).catch((t=>{console.warn(t),n(!1)}))};load=async t=>{this.#n();const e=Date.now();let r;if(this.startedLoadingAt=e,this.cancelMatches(),this.__store.batch((()=>{t?.next&&this.__store.setState((e=>({...e,location:t.next}))),r=this.matchRoutes(this.state.location.pathname,this.state.location.search,{strictParseParams:!0,debug:!0}),this.__store.setState((t=>({...t,status:"pending",matches:r})))})),await this.loadMatches(r),this.startedLoadingAt!==e)return this.navigationPromise;const o=this.state.resolvedLocation;this.__store.setState((t=>({...t,status:"idle",resolvedLocation:t.location}))),o.href!==this.state.location.href&&this.options.onRouteChange?.(),this.resolveNavigation()};getRoute=t=>{const e=this.routesById[t];return n(e),e};preloadRoute=async(t=this.state.location)=>{const e=this.buildNext(t),r=this.matchRoutes(e.pathname,e.search,{strictParseParams:!0}),o={};return r.forEach((t=>{this.state.matches.find((e=>e.id===t.id))||(o[t.id]=t)})),this.__store.setState((t=>({...t,preloadMatches:{...t.preloadMatches,...o}}))),await this.loadMatches(r,{preload:!0}),r};matchRoutes=(t,e,r)=>{let o={},a=this.flatRoutes.find((e=>{const r=j(this.basepath,t,{to:e.fullPath,caseSensitive:e.options.caseSensitive??this.options.caseSensitive});return!!r&&(o=r,!0)}))||this.routesById.__root__,n=[a];for(;a?.parentRoute;)a=a.parentRoute,a&&n.unshift(a);let s={};const i=n.map((t=>{let a;try{a=t.options.parseParams?.(o)??o}catch(t){if(r?.strictParseParams)throw t}Object.assign(s,a);const n=k(t.path,s),i=k(t.id,s,!0)+(t.options.getKey?.({params:s,search:e})??""),c=this.getRouteMatch(i);return c?{...c}:bt({route:t,id:i,params:s,pathname:E([this.basepath,n])})}));return i.forEach(((t,r)=>{const o=i[r-1],a=this.getRoute(t.routeId),n=(()=>{const r={search:o?.search??e,routeSearch:o?.routeSearch??e};try{const e=("object"==typeof a.options.validateSearch?a.options.validateSearch.parse:a.options.validateSearch)?.(r.search)??{},o={...r.search,...e};return{routeSearch:b(t.routeSearch,e),search:b(t.search,o)}}catch(t){if(vt(t))throw t;(a.options.onValidateSearchError??a.options.onError)?.(t);const e=new Error("Invalid search params found",{cause:t});throw e.code="INVALID_SEARCH_PARAMS",e}})(),s=(()=>{try{const e=a.options.getContext?.({parentContext:o?.routeContext??{},context:o?.context??this?.options.context??{},params:t.params,search:t.search})||{};return{context:{...o?.context??this?.options.context,...e},routeContext:e}}catch(t){throw a.options.onError?.(t),t}})();Object.assign(t,{...n,...s})})),i};loadMatches=async(t,e)=>{let r;try{await Promise.all(t.map((async(t,e)=>{const o=this.getRoute(t.routeId);try{await(o.options.beforeLoad?.({router:this,match:t}))}catch(a){if(vt(a))throw a;r=r??e;const n=o.options.onBeforeLoadError??o.options.onError;let s=a;try{n?.(a)}catch(t){if(s=t,vt(t))throw t}this.#s(t.id,(t=>({...t,error:s,status:"error",updatedAt:Date.now()})))}})))}catch(t){if(vt(t))return void(e?.preload||this.navigate(t));throw t}const o=t.slice(0,r),a=[];o.forEach(((t,r)=>{a.push(Promise.resolve().then((async()=>{const o=a[r-1],n=this.getRoute(t.routeId),s=Date.now(),i=Promise.resolve().then((async()=>{const r=()=>{const e=this.getRouteMatch(t.id);return e&&e.fetchedAt!==s?e.loadPromise:void 0};let a;const i=(async()=>{await Promise.all(mt.map((async t=>{const e=n.options[t];e?.preload&&await e.preload()})))})(),c=Promise.resolve().then((()=>{if(n.options.loader)return n.options.loader({...t,preload:!!e?.preload,parentMatchPromise:o})}));try{const[o,n]=await Promise.all([i,c]);if(a=r())return await a;this.#s(t.id,(t=>({...t,error:void 0,status:"success",updatedAt:Date.now(),loader:n})))}catch(o){if(a=r())return await a;if(vt(o))return void(e?.preload||this.navigate(o));const s=n.options.onLoadError??n.options.onError;let i=o;try{s?.(o)}catch(t){if(i=t,vt(t))return void(e?.preload||this.navigate(t))}this.#s(t.id,(t=>({...t,error:i,status:"error",updatedAt:Date.now()})))}finally{if(a=r())return await a;e?.preload&&this.__store.setState((e=>{const r={...e.preloadMatches};return delete r[t.id],{...e,preloadMatches:r}}))}}));this.#s(t.id,(t=>({...t,loadPromise:i,fetchedAt:s}))),await i})))})),await Promise.all(a)};reload=()=>{this.navigate({fromCurrent:!0,replace:!0,search:!0})};resolvePath=(t,e)=>M(this.basepath,t,_(e));navigate=async({from:t,to:e="",search:r,hash:o,replace:a,params:s})=>{const i=String(e),c=void 0===t?t:String(t);let h;try{new URL(`${i}`),h=!0}catch(t){}return n(!h),this.#e({from:c,to:i,search:r,hash:o,replace:a,params:s})};matchRoute=(t,e)=>{t={...t,to:t.to?this.resolvePath(t.from??"",t.to):void 0};const r=this.buildNext(t);if(e?.pending&&"pending"!==this.state.status)return!1;const o=e?.pending?this.state.location:this.state.resolvedLocation;if(!o)return!1;const a=j(this.basepath,o.pathname,{...e,to:r.pathname});return!!a&&(e?.includeSearch??1?!!R(o.search,r.search)&&a:a)};buildLink=({from:t,to:e=".",search:r,params:o,hash:a,target:n,replace:s,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:s},d=this.buildNext(l);c=c??this.options.defaultPreload;const p=h??this.options.defaultPreloadDelay??0,f=this.state.location.pathname.split("/"),m=d.pathname.split("/").every(((t,e)=>t===f[e])),y=i?.exact?this.state.location.pathname===d.pathname:m,g=!i?.includeHash||this.state.location.hash===d.hash,v=!(i?.includeSearch??1)||R(this.state.location.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||n&&"_self"!==n||0!==t.button||(t.preventDefault(),this.#e(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}};dehydrate=()=>({state:{...v(this.state,["location","status","lastUpdated"])}});hydrate=async t=>{let e=t;"undefined"!=typeof document&&(e=window.__TSR_DEHYDRATED__),n(e);const r=e;this.options.hydrate?.(r.payload),this.__store.setState((t=>({...t,...r.router.state,matches:t.matches,resolvedLocation:r.router.state.location}))),await this.load()};injectedHtml=[];injectHtml=async t=>{this.injectedHtml.push(t)};dehydrateData=(t,e)=>{if("undefined"==typeof document){const r="string"==typeof t?t:JSON.stringify(t);return this.injectHtml((async()=>{const t=`__TSR_DEHYDRATED__${r}`,o="function"==typeof e?await e():e;return`<script id='${t}' suppressHydrationWarning>window["__TSR_DEHYDRATED__${a=r,a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/"/g,'\\"')}"] = ${JSON.stringify(o)}\n ;(() => {\n var el = document.getElementById('${t}')\n el.parentElement.removeChild(el)\n })()\n <\/script>`;var a})),()=>this.hydrateData(t)}return()=>{}};hydrateData=t=>{if("undefined"!=typeof document){const e="string"==typeof t?t:JSON.stringify(t);return window[`__TSR_DEHYDRATED__${e}`]}};#o=t=>{this.routeTree=t,this.routesById={},this.routesByPath={},this.flatRoutes=[];const e=t=>{t.forEach(((t,r)=>{t.init({originalIndex:r,router:this});if(n(!this.routesById[t.id],String(t.id)),this.routesById[t.id]=t,!t.isRoot&&t.path){const e=x(t.fullPath);this.routesByPath[e]&&!t.fullPath.endsWith("/")||(this.routesByPath[e]=t)}const o=t.children;o?.length&&e(o)}))};e([t]),this.flatRoutes=Object.values(this.routesByPath).map(((t,e)=>{const r=C(t.fullPath),o=L(r);for(;o.length>1&&"/"===o[0]?.value;)o.shift();const a=o.map((t=>"param"===t.type?.5:"wildcard"===t.type?.25:1));return{child:t,trimmed:r,parsed:o,index:e,score:a}})).sort(((t,e)=>{let r="/"===t.trimmed?1:"/"===e.trimmed?-1:0;if(0!==r)return r;const o=Math.min(t.score.length,e.score.length);if(t.score.length!==e.score.length)return e.score.length-t.score.length;for(let r=0;r<o;r++)if(t.score[r]!==e.score[r])return e.score[r]-t.score[r];for(let r=0;r<o;r++)if(t.parsed[r].value!==e.parsed[r].value)return t.parsed[r].value>e.parsed[r].value?1:-1;return t.trimmed!==e.trimmed?t.trimmed>e.trimmed?1:-1:t.index-e.index})).map(((t,e)=>(t.child.rank=e,t.child)))};#r=t=>{let{pathname:e,search:r,hash:o,state:a}=this.history.location;const n=this.options.parseSearch(r);return{pathname:e,searchStr:r,search:b(t?.search,n),hash:o.split("#").reverse()[0]??"",href:`${e}${r}${o}`,state:a,key:a?.key||"__init__"}};#a=(t={})=>{t.fromCurrent=t.fromCurrent??""===t.to;const e=t.fromCurrent?this.state.location.pathname:t.from??this.state.location.pathname;let r=M(this.basepath??"/",e,`${t.to??""}`);const o={...y(this.matchRoutes(this.state.location.pathname,this.state.location.search,{strictParseParams:!0}))?.params};let a=!0===(t.params??!0)?o:g(t.params,o);a&&t.__matches?.map((t=>this.getRoute(t.routeId).options.stringifyParams)).filter(Boolean).forEach((t=>{a={...a,...t(a)}})),r=k(r,a??{});const n=t.__matches?.map((t=>this.getRoute(t.routeId).options.preSearchFilters??[])).flat().filter(Boolean)??[],s=t.__matches?.map((t=>this.getRoute(t.routeId).options.postSearchFilters??[])).flat().filter(Boolean)??[],i=n?.length?n?.reduce(((t,e)=>e(t)),this.state.location.search):this.state.location.search,c=!0===t.search?i:t.search?g(t.search,i)??{}:n?.length?i:{},h=s?.length?s.reduce(((t,e)=>e(t)),c):c,u=b(this.state.location.search,h),l=this.options.stringifySearch(u),d=!0===t.hash?this.state.location.hash:g(t.hash,this.state.location.hash),p=d?`#${d}`:"";return{pathname:r,search:u,searchStr:l,state:!0===t.state?this.state.location.state:g(t.state,this.state.location.state),hash:d,href:this.history.createHref(`${r}${l}${p}`),key:t.key}};#e=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.location.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.#n()};#n=()=>{const t=this.resolveNavigation;return this.navigationPromise=new Promise((e=>{this.resolveNavigation=()=>{e(),t()}})),this.navigationPromise};getRouteMatch=t=>this.state.matches.find((e=>e.id===t))||this.state.preloadMatches[t];setRouteMatch=(t,e)=>{this.__store.setState((r=>({...r,matches:r.matches.map((r=>r.id===t?e(r):r))})))};setPreloadRouteMatch=(t,e)=>{n(this.state.preloadMatches[t]),this.__store.setState((r=>({...r,preloadMatches:{...r.preloadMatches,[t]:e(r.preloadMatches[t])}})))};#s=(t,e)=>this.state.matches.find((e=>e.id===t))?this.setRouteMatch(t,e):this.setPreloadRouteMatch(t,e)},t.RouterContext=class{constructor(){}createRootRoute=t=>new ut(t)},t.RouterProvider=function({router:t,...e}){t.update(e);const[r,o]=a.useState((()=>t.state)),n=r.matches;return W((()=>t.__store.subscribe((()=>{(a.startTransition||(t=>t()))((()=>o(t.state)))})))),a.useEffect(t.mount,[t]),a.createElement(F.Provider,{value:t},a.createElement(z.Provider,{value:r},a.createElement(U.Provider,{value:[void 0,...n]},a.createElement(ot,{errorComponent:nt,onCatch:()=>{}},a.createElement(Z,null)))))},t.cleanPath=_,t.componentTypes=mt,t.createBrowserHistory=d,t.createHashHistory=function(){return d({getHref:()=>window.location.hash.substring(1),createHref:t=>`#${t}`})},t.createMemoryHistory=p,t.createRouteMatch=bt,t.decode=$,t.defaultParseSearch=lt,t.defaultStringifySearch=dt,t.encode=I,t.functionalUpdate=g,t.interpolatePath=k,t.invariant=n,t.isPlainObject=w,t.isRedirect=vt,t.joinPaths=E,t.last=y,t.lazy=function(t,e="default"){const r=a.lazy((async()=>({default:(await t())[e]})));return r.preload=async()=>{await t()},r},t.matchByPath=O,t.matchPathname=j,t.matchesContext=U,t.parsePathname=L,t.parseSearchWith=pt,t.partialDeepEqual=R,t.pick=v,t.redirect=function(t){return t.isRedirect=!0,t},t.replaceEqualDeep=b,t.resolvePath=M,t.rootRouteId=ct,t.routerContext=F,t.routerStateContext=z,t.shallow=it,t.stringifySearchWith=ft,t.trimPath=C,t.trimPathLeft=P,t.trimPathRight=x,t.useBlocker=st,t.useDehydrate=function(){const t=J();return a.useCallback((function(e,r){return t.dehydrateData(e,r)}),[])},t.useHydrate=function(){const t=J();return function(e){return t.hydrateData(e)}},t.useInjectHtml=function(){const t=J();return a.useCallback((e=>{t.injectHtml(e)}),[])},t.useLinkProps=N,t.useLoader=V,t.useMatch=Y,t.useMatchRoute=X,t.useMatches=q,t.useNavigate=function(t){const e=J();return a.useCallback((r=>e.navigate({...t,...r})),[])},t.useParams=Q,t.useRouter=J,t.useRouterState=K,t.useSearch=G,t.useStore=function(t,e=(t=>t)){return r.useSyncExternalStoreWithSelector(t.subscribe,(()=>t.state),(()=>t.state),e,H)},t.warning=s,Object.defineProperty(t,"__esModule",{value:!0})}));
//# sourceMappingURL=index.production.js.map
{
"name": "@tanstack/router",
"author": "Tanner Linsley",
"version": "0.0.1-beta.119",
"version": "0.0.1-beta.120",
"license": "MIT",

@@ -46,3 +46,3 @@ "repository": "tanstack/router",

"@gisatcz/cross-package-react-context": "^0.2.0",
"@tanstack/react-store": "0.0.1-beta.118"
"@tanstack/react-store": "0.0.1-beta.120"
},

@@ -49,0 +49,0 @@ "scripts": {

@@ -9,3 +9,2 @@ export { default as invariant } from 'tiny-invariant'

export * from './routeInfo'
export * from './routeMatch'
export * from './router'

@@ -12,0 +11,0 @@ export * from './searchParams'

@@ -1,10 +0,4 @@

import { AnyRoutesInfo, DefaultRoutesInfo, RouteByPath } from './routeInfo'
import { AnyRoutesInfo, RouteByPath } from './routeInfo'
import { ParsedLocation, LocationState, RegisteredRoutesInfo } from './router'
import {
Expand,
NoInfer,
PickRequired,
UnionToIntersection,
Updater,
} from './utils'
import { NoInfer, PickRequired, UnionToIntersection, Updater } from './utils'

@@ -11,0 +5,0 @@ export type LinkInfo =

import { ParsePathParams } from './link'
import { RouteMatch } from './routeMatch'
import { AnyRouter, RegisteredRoutesInfo, Router } from './router'
import {
AnyRouter,
Router,
AnyRouteMatch,
RouteMatch,
RouterConstructorOptions,
} from './router'
import {
IsAny,

@@ -12,6 +17,5 @@ NoInfer,

import invariant from 'tiny-invariant'
import { joinPaths, trimPath, trimPathRight } from './path'
import { AnyRoutesInfo, DefaultRoutesInfo } from './routeInfo'
import { joinPaths, trimPath } from './path'
import { AnyRoutesInfo, DefaultRoutesInfo, RoutesInfo } from './routeInfo'
import {
MakeLinkOptions,
RouteComponent,

@@ -264,3 +268,3 @@ useLoader,

router: AnyRouter
match: RouteMatch
match: AnyRouteMatch
}) => Promise<void> | void

@@ -368,3 +372,3 @@ // This function will be called if the route's loader throws an error **during an attempted navigation**.

> = (
loaderContext: LoaderContext<
match: LoaderContext<
TSearchSchema,

@@ -375,3 +379,5 @@ TFullSearchSchema,

TAllContext
>,
> & {
parentMatchPromise?: Promise<void>
},
) => Promise<TLoader> | TLoader

@@ -409,3 +415,3 @@

search: TFullSearchSchema
signal?: AbortSignal
abortController: AbortController
preload: boolean

@@ -477,2 +483,23 @@ routeContext: TContext

export type AnyRouteWithRouterContext<TRouterContext extends AnyContext> =
Route<
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
TRouterContext,
any,
any
>
type MergeFromParent<T, U> = IsAny<T, U, T & U>

@@ -749,2 +776,67 @@

export class RouterContext<TRouterContext extends {}> {
constructor() {}
createRootRoute = <
TLoader = unknown,
TSearchSchema extends AnySearchSchema = {},
TContext extends RouteContext = RouteContext,
>(
options?: Omit<
RouteOptions<
AnyRoute,
RootRouteId,
'',
TLoader,
{},
TSearchSchema,
NoInfer<TSearchSchema>,
{},
TRouterContext,
TRouterContext,
TContext,
NoInfer<TContext>
>,
| 'path'
| 'id'
| 'getParentRoute'
| 'caseSensitive'
| 'parseParams'
| 'stringifyParams'
>,
) => {
return new RootRoute<TLoader, TSearchSchema, TContext, TRouterContext>(
options,
)
}
// return <
// TLoader = unknown,
// TSearchSchema extends AnySearchSchema = {},
// TContext extends {} = {},
// >(
// options?: Omit<
// RouteOptions<
// AnyRoute,
// RootRouteId,
// '',
// TLoader,
// {},
// TSearchSchema,
// NoInfer<TSearchSchema>,
// {},
// TRouterContext,
// TRouterContext,
// TContext,
// TRouterContext & TContext
// >,
// 'path' | 'id' | 'getParentRoute' | 'caseSensitive'
// >,
// ) =>
// new RootRoute<TLoader, TSearchSchema, TContext, TRouterContext>(
// options as any,
// )
// }
}
export class RootRoute<

@@ -800,31 +892,2 @@ TLoader = unknown,

}
static withRouterContext = <TRouterContext extends {}>() => {
return <
TLoader = unknown,
TSearchSchema extends AnySearchSchema = {},
TContext extends {} = {},
>(
options?: Omit<
RouteOptions<
AnyRoute,
RootRouteId,
'',
TLoader,
{},
TSearchSchema,
NoInfer<TSearchSchema>,
{},
TRouterContext,
TRouterContext,
TContext,
TRouterContext & TContext
>,
'path' | 'id' | 'getParentRoute' | 'caseSensitive'
>,
) =>
new RootRoute<TLoader, TSearchSchema, TContext, TRouterContext>(
options as any,
)
}
}

@@ -831,0 +894,0 @@

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

trimPath,
trimPathLeft,
trimPathRight,

@@ -31,4 +30,5 @@ } from './path'

AnyContext,
AnyPathParams,
AnyRouteWithRouterContext,
AnyRootRoute,
AnyPathParams,
} from './route'

@@ -40,4 +40,4 @@ import {

RoutesByPath,
DefaultRoutesInfo,
} from './routeInfo'
import { AnyRouteMatch, RouteMatch, RouteMatchState } from './routeMatch'
import { defaultParseSearch, defaultStringifySearch } from './searchParams'

@@ -118,3 +118,28 @@ import {

type RouterContextOptions<TRouteTree extends AnyRoute> =
export interface RouteMatch<
TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo,
TRoute extends AnyRoute = Route,
> {
id: string
routeId: string
pathname: string
params: TRoute['__types']['allParams']
status: 'pending' | 'success' | 'error'
error: unknown
updatedAt: number
loader: TRoute['__types']['loader']
loadPromise?: Promise<void>
__resolveLoadPromise?: () => void
routeContext: TRoute['__types']['routeContext']
context: TRoute['__types']['context']
routeSearch: TRoute['__types']['searchSchema']
search: TRoutesInfo['fullSearchSchema'] &
TRoute['__types']['fullSearchSchema']
fetchedAt: number
abortController: AbortController
}
export type AnyRouteMatch = RouteMatch<AnyRoutesInfo, AnyRoute>
export type RouterContextOptions<TRouteTree extends AnyRoute> =
AnyContext extends TRouteTree['__types']['routerContext']

@@ -150,3 +175,3 @@ ? {

onRouteChange?: () => void
fetchServerDataFn?: FetchServerDataFn
// fetchServerDataFn?: FetchServerDataFn
context?: TRouteTree['__types']['routerContext']

@@ -158,7 +183,2 @@ Wrap?: React.ComponentType<{ children: React.ReactNode }>

type FetchServerDataFn = (ctx: {
router: AnyRouter
routeMatch: RouteMatch
}) => Promise<any>
export interface RouterState<

@@ -170,2 +190,6 @@ TRoutesInfo extends AnyRoutesInfo = AnyRoutesInfo,

matches: RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[]
preloadMatches: Record<
string,
RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>
>
location: ParsedLocation<TRoutesInfo['fullSearchSchema'], TState>

@@ -187,10 +211,5 @@ resolvedLocation: ParsedLocation<TRoutesInfo['fullSearchSchema'], TState>

fromCurrent?: boolean
__matches?: RouteMatch[]
__matches?: AnyRouteMatch[]
}
export type MatchCacheEntry = {
gc: number
match: RouteMatch
}
export interface MatchLocation {

@@ -216,5 +235,3 @@ to?: string | number | null

export interface DehydratedRouterState
extends Pick<RouterState, 'status' | 'location' | 'lastUpdated'> {
// matches: DehydratedRouteMatch[]
}
extends Pick<RouterState, 'status' | 'location' | 'lastUpdated'> {}

@@ -225,36 +242,2 @@ export interface DehydratedRouter {

export type MatchCache = Record<string, MatchCacheEntry>
interface DehydratedRouteMatch {
id: string
promiseKeys: string[]
// state: Pick<RouteMatchState<any, any>, 'status'>
}
export const defaultFetchServerDataFn: FetchServerDataFn = async ({
router,
routeMatch,
}) => {
const next = router.buildNext({
to: '.',
search: (d: any) => ({
...(d ?? {}),
__data: {
matchId: routeMatch.id,
},
}),
})
const res = await fetch(next.href, {
method: 'GET',
signal: routeMatch.abortController.signal,
})
if (res.ok) {
return res.json()
}
throw new Error('Failed to fetch match data')
}
export type RouterConstructorOptions<

@@ -266,2 +249,8 @@ TRouteTree extends AnyRoute,

export const componentTypes = [
'component',
'errorComponent',
'pendingComponent',
] as const
export class Router<

@@ -273,3 +262,2 @@ TRouteTree extends AnyRoute = AnyRoute,

types!: {
// Super secret internal stuff
RootRoute: TRouteTree

@@ -283,7 +271,5 @@ RoutesInfo: TRoutesInfo

>
context!: NonNullable<TRouteTree['__types']['routerContext']>
history!: RouterHistory
#unsubHistory?: () => void
basepath!: string
// __location: Location<TRoutesInfo['fullSearchSchema']>
routeTree!: RootRoute

@@ -302,3 +288,3 @@ routesById!: RoutesById<TRoutesInfo>

constructor(options?: RouterConstructorOptions<TRouteTree, TDehydrated>) {
constructor(options: RouterConstructorOptions<TRouteTree, TDehydrated>) {
this.options = {

@@ -310,3 +296,3 @@ defaultPreloadDelay: 50,

parseSearch: options?.parseSearch ?? defaultParseSearch,
fetchServerDataFn: options?.fetchServerDataFn ?? defaultFetchServerDataFn,
// fetchServerDataFn: options?.fetchServerDataFn ?? defaultFetchServerDataFn,
}

@@ -355,6 +341,11 @@

update = (opts?: RouterOptions<any, any>): this => {
Object.assign(this.options, opts)
this.options = {
...this.options,
...opts,
context: {
...this.options.context,
...opts?.context,
},
}
this.context = this.options.context
if (

@@ -410,7 +401,11 @@ !this.history ||

cancelMatches = () => {
;[...this.state.matches].forEach((match) => {
match.cancel()
this.state.matches.forEach((match) => {
this.cancelMatch(match.id)
})
}
cancelMatch = (id: string) => {
this.getRouteMatch(id)?.abortController?.abort()
}
safeLoad = (opts?: { next?: ParsedLocation }) => {

@@ -461,8 +456,4 @@ this.load(opts).catch((err) => {

matches.forEach((match) => {
match.__commit()
})
// Load the matches
await this.loadMatches(matches, this.state.location)
await this.loadMatches(matches)

@@ -474,53 +465,4 @@ if (this.startedLoadingAt !== startedAt) {

const previousMatches = this.state.matches
const prevLocation = this.state.resolvedLocation
const exiting: AnyRouteMatch[] = [],
staying: AnyRouteMatch[] = []
previousMatches.forEach((d) => {
if (matches.find((dd) => dd.id === d.id)) {
staying.push(d)
} else {
exiting.push(d)
}
})
const entering = matches.filter((d) => {
return !previousMatches.find((dd) => dd.id === d.id)
})
now = Date.now()
exiting.forEach((d) => {
d.__onExit?.({
params: d.params,
search: d.state.routeSearch,
})
// Clear non-loading error states when match leaves
if (d.state.status === 'error') {
this.__store.setState((s) => ({
...s,
status: 'idle',
error: undefined,
}))
}
})
staying.forEach((d) => {
d.route.options.onTransition?.({
params: d.params,
search: d.state.routeSearch,
})
})
entering.forEach((d) => {
d.__onExit = d.route.options.onLoaded?.({
params: d.params,
search: d.state.search,
})
})
const prevLocation = this.state.location
this.__store.setState((s) => ({

@@ -530,3 +472,3 @@ ...s,

resolvedLocation: s.location,
matches,
// matches,
}))

@@ -551,13 +493,2 @@

loadRoute = async (
navigateOpts: BuildNextOptions = this.state.location,
): Promise<RouteMatch[]> => {
const next = this.buildNext(navigateOpts)
const matches = this.matchRoutes(next.pathname, next.search, {
strictParseParams: true,
})
await this.loadMatches(matches, next)
return matches
}
preloadRoute = async (

@@ -571,3 +502,21 @@ navigateOpts: BuildNextOptions = this.state.location,

await this.loadMatches(matches, next, {
const matchesById: any = {}
matches.forEach((m) => {
if (!this.state.matches.find((d) => d.id === m.id)) {
matchesById[m.id] = m
}
})
this.__store.setState((s) => {
return {
...s,
preloadMatches: {
...s.preloadMatches,
...matchesById,
},
}
})
await this.loadMatches(matches, {
preload: true,

@@ -580,10 +529,5 @@ })

pathname: string,
search: AnySearchSchema,
locationSearch: AnySearchSchema,
opts?: { strictParseParams?: boolean; debug?: boolean },
): RouteMatch[] => {
// If there's no route tree, we can't match anything
if (!this.flatRoutes.length) {
return []
}
): RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[] => {
let routeParams: AnyPathParams = {}

@@ -606,11 +550,9 @@

if (!foundRoute) {
return []
}
let routeCursor = foundRoute || (this.routesById['__root__'] as any)
let matchedRoutes: AnyRoute[] = [foundRoute]
let matchedRoutes: AnyRoute[] = [routeCursor]
while (foundRoute?.parentRoute) {
foundRoute = foundRoute.parentRoute
if (foundRoute) matchedRoutes.unshift(foundRoute)
while (routeCursor?.parentRoute) {
routeCursor = routeCursor.parentRoute
if (routeCursor) matchedRoutes.unshift(routeCursor)
}

@@ -626,49 +568,121 @@

// pending matches that are still loading
const existingMatches = [...this.state.matches] as AnyRouteMatch[]
const matches = matchedRoutes
.map((route) => {
let parsedParams
const matches = matchedRoutes.map((route) => {
let parsedParams
try {
parsedParams = route.options.parseParams?.(routeParams!) ?? routeParams
} catch (err) {
if (opts?.strictParseParams) {
throw err
}
}
// Add the parsed params to the accumulated params bag
Object.assign(allParams, parsedParams)
const interpolatedPath = interpolatePath(route.path, allParams)
const matchId =
interpolatePath(route.id, allParams, true) +
(route.options.getKey?.({
params: allParams,
search: locationSearch,
}) ?? '')
// 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.
const existingMatch = this.getRouteMatch(matchId)
if (existingMatch) {
// Return a copy, we don't want to mutate the existing match
return { ...existingMatch }
}
// Create a fresh route match
return createRouteMatch({
route,
id: matchId,
params: allParams,
pathname: joinPaths([this.basepath, interpolatedPath]),
})
})
// Take each match and resolve its search params and context
// This has to happen after the matches are created or found
// so that we can use the parent match's search params and context
matches.forEach((match, i): any => {
const parentMatch = matches[i - 1]
const route = this.getRoute(match.routeId)
const searchInfo = (() => {
// Validate the search params and stabilize them
const parentSearchInfo = {
search: parentMatch?.search ?? locationSearch,
routeSearch: parentMatch?.routeSearch ?? locationSearch,
}
try {
parsedParams =
route.options.parseParams?.(routeParams!) ?? routeParams
} catch (err) {
if (opts?.strictParseParams) {
const validator =
typeof route.options.validateSearch === 'object'
? route.options.validateSearch.parse
: route.options.validateSearch
const routeSearch = validator?.(parentSearchInfo.search) ?? {}
const search = {
...parentSearchInfo.search,
...routeSearch,
}
return {
routeSearch: replaceEqualDeep(match.routeSearch, routeSearch),
search: replaceEqualDeep(match.search, search),
}
} catch (err: any) {
if (isRedirect(err)) {
throw err
}
const errorHandler =
route.options.onValidateSearchError ?? route.options.onError
errorHandler?.(err)
const error = new (Error as any)('Invalid search params found', {
cause: err,
})
error.code = 'INVALID_SEARCH_PARAMS'
throw error
}
})()
// Add the parsed params to the accumulated params bag
Object.assign(allParams, parsedParams)
const contextInfo = (() => {
try {
const routeContext =
route.options.getContext?.({
parentContext: parentMatch?.routeContext ?? {},
context: parentMatch?.context ?? this?.options.context ?? {},
params: match.params,
search: match.search,
}) || ({} as any)
const interpolatedPath = interpolatePath(route.path, allParams)
const matchId =
interpolatePath(route.id, allParams, true) +
(route.options.getKey?.({
params: allParams,
search,
}) ?? '')
const context = {
...(parentMatch?.context ?? this?.options.context),
...routeContext,
} as any
// 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.
const existingMatch = existingMatches.find((d) => d.id === matchId)
if (existingMatch) {
return existingMatch
return {
context,
routeContext,
}
} catch (err) {
route.options.onError?.(err)
throw err
}
})()
return new RouteMatch(this, route, {
id: matchId,
params: allParams,
pathname: joinPaths([this.basepath, interpolatedPath]),
}) as AnyRouteMatch
Object.assign(match, {
...searchInfo,
...contextInfo,
})
.filter((d, i, all) => {
// Filter out any duplicate matches
// I honesty don't know why this is necessary, but it is and it's safe for now
// Someday someone will figure out why my logic is wrong and fix it to just
// not create duplicate matches in the first place
return all.findIndex((dd) => dd.id === d.id) === i
})
})

@@ -679,7 +693,5 @@ return matches

loadMatches = async (
resolvedMatches: RouteMatch[],
location: ParsedLocation,
resolvedMatches: AnyRouteMatch[],
opts?: {
preload?: boolean
// filter?: (match: RouteMatch<any, any>) => any
},

@@ -693,4 +705,6 @@ ) => {

resolvedMatches.map(async (match, index) => {
const route = this.getRoute(match.routeId)
try {
await match.route.options.beforeLoad?.({
await route.options.beforeLoad?.({
router: this as any,

@@ -707,23 +721,19 @@ match,

const errorHandler =
match.route.options.onBeforeLoadError ??
match.route.options.onError
route.options.onBeforeLoadError ?? route.options.onError
let caughtError = err
try {
errorHandler?.(err)
} catch (errorHandlerErr) {
caughtError = errorHandlerErr
if (isRedirect(errorHandlerErr)) {
throw errorHandlerErr
}
match.__store.setState((s) => ({
...s,
error: errorHandlerErr,
status: 'error',
updatedAt: Date.now(),
}))
return
}
match.__store.setState((s) => ({
this.#setEitherRouteMatch(match.id, (s) => ({
...s,
error: err,
error: caughtError,
status: 'error',

@@ -747,12 +757,117 @@ updatedAt: Date.now(),

const validResolvedMatches = resolvedMatches.slice(0, firstBadMatchIndex)
const matchPromises = validResolvedMatches.map(async (match, index) => {
const parentMatch = validResolvedMatches[index - 1]
const matchPromises: Promise<any>[] = []
match.__load({ preload: opts?.preload, location, parentMatch })
validResolvedMatches.forEach((match, index) => {
matchPromises.push(
Promise.resolve().then(async () => {
const parentMatchPromise = matchPromises[index - 1]
const route = this.getRoute(match.routeId)
const fetchedAt = Date.now()
const loadPromise = Promise.resolve().then(async () => {
const checkLatest = () => {
const latest = this.getRouteMatch(match.id)
return latest && latest.fetchedAt !== fetchedAt
? latest.loadPromise
: undefined
}
await match.__loadPromise
let latestPromise
if (parentMatch) {
await parentMatch.__loadPromise
}
const componentsPromise = (async () => {
// then run all component and data loaders in parallel
// For each component type, potentially load it asynchronously
await Promise.all(
componentTypes.map(async (type) => {
const component = route.options[type]
if (component?.preload) {
await component.preload()
}
}),
)
})()
const loaderPromise = Promise.resolve().then(() => {
if (route.options.loader) {
return route.options.loader({
...match,
preload: !!opts?.preload,
parentMatchPromise,
})
}
return
})
try {
const [_, loader] = await Promise.all([
componentsPromise,
loaderPromise,
])
if ((latestPromise = checkLatest())) return await latestPromise
this.#setEitherRouteMatch(match.id, (s) => ({
...s,
error: undefined,
status: 'success',
updatedAt: Date.now(),
loader,
}))
} catch (err) {
if ((latestPromise = checkLatest())) return await latestPromise
if (isRedirect(err)) {
if (!opts?.preload) {
this.navigate(err as any)
}
return
}
const errorHandler =
route.options.onLoadError ?? route.options.onError
let caughtError = err
try {
errorHandler?.(err)
} catch (errorHandlerErr) {
caughtError = errorHandlerErr
if (isRedirect(errorHandlerErr)) {
if (!opts?.preload) {
this.navigate(errorHandlerErr as any)
}
return
}
}
this.#setEitherRouteMatch(match.id, (s) => ({
...s,
error: caughtError,
status: 'error',
updatedAt: Date.now(),
}))
} finally {
if ((latestPromise = checkLatest())) return await latestPromise
if (opts?.preload) {
this.__store.setState((s) => {
const preloadMatches = { ...s.preloadMatches }
delete preloadMatches[match.id]
return {
...s,
preloadMatches,
}
})
}
}
})
this.#setEitherRouteMatch(match.id, (s) => ({
...s,
loadPromise,
fetchedAt,
}))
await loadPromise
}),
)
})

@@ -1050,7 +1165,13 @@

this.injectHtml(async () => {
const id = `__TSR_DEHYDRATED__${strKey}`
const data =
typeof getData === 'function' ? await (getData as any)() : getData
return `<script>window["__TSR__DEHYRATED__${escapeJSON(
return `<script id='${id}' suppressHydrationWarning>window["__TSR_DEHYDRATED__${escapeJSON(
strKey,
)}"] = ${JSON.stringify(data)}</script>`
)}"] = ${JSON.stringify(data)}
;(() => {
var el = document.getElementById('${id}')
el.parentElement.removeChild(el)
})()
</script>`
})

@@ -1068,3 +1189,3 @@

return window[`__TSR__DEHYRATED__${strKey}` as any] as T
return window[`__TSR_DEHYDRATED__${strKey}` as any] as T
}

@@ -1228,3 +1349,3 @@

dest.__matches
?.map((d) => d.route.options.stringifyParams)
?.map((d) => this.getRoute(d.routeId).options.stringifyParams)
.filter(Boolean)

@@ -1240,3 +1361,6 @@ .forEach((fn) => {

dest.__matches
?.map((match) => match.route.options.preSearchFilters ?? [])
?.map(
(match) =>
this.getRoute(match.routeId).options.preSearchFilters ?? [],
)
.flat()

@@ -1247,3 +1371,6 @@ .filter(Boolean) ?? []

dest.__matches
?.map((match) => match.route.options.postSearchFilters ?? [])
?.map(
(match) =>
this.getRoute(match.routeId).options.postSearchFilters ?? [],
)
.flat()

@@ -1349,2 +1476,58 @@ .filter(Boolean) ?? []

}
getRouteMatch = (
id: string,
): undefined | RouteMatch<TRoutesInfo, AnyRoute> => {
return (
this.state.matches.find((d) => d.id === id) ||
this.state.preloadMatches[id]
)
}
setRouteMatch = (
id: string,
updater: (
prev: RouteMatch<TRoutesInfo, AnyRoute>,
) => RouteMatch<TRoutesInfo, AnyRoute>,
) => {
this.__store.setState((prev) => ({
...prev,
matches: prev.matches.map((d) => {
if (d.id === id) {
return updater(d as any)
}
return d
}),
}))
}
setPreloadRouteMatch = (
id: string,
updater: (
prev: RouteMatch<TRoutesInfo, AnyRoute>,
) => RouteMatch<TRoutesInfo, AnyRoute>,
) => {
invariant(this.state.preloadMatches[id], 'Match not found')
this.__store.setState((prev) => ({
...prev,
preloadMatches: {
...prev.preloadMatches,
[id]: updater(prev.preloadMatches[id] as any),
},
}))
}
#setEitherRouteMatch = (
id: string,
updater: (
prev: RouteMatch<TRoutesInfo, AnyRoute>,
) => RouteMatch<TRoutesInfo, AnyRoute>,
) => {
if (this.state.matches.find((d) => d.id === id)) {
return this.setRouteMatch(id, updater)
}
return this.setPreloadRouteMatch(id, updater)
}
}

@@ -1361,2 +1544,3 @@

matches: [],
preloadMatches: {},
lastUpdated: Date.now(),

@@ -1399,1 +1583,38 @@ }

}
export function createRouteMatch({
route,
id,
params,
pathname,
}: {
route: AnyRoute
id: string
params: AnyPathParams
pathname: string
}) {
const hasLoaders = !!(
route.options.loader ||
componentTypes.some((d) => route.options[d]?.preload)
)
const state: RouteMatch = {
id: id,
routeId: route.id,
params: params,
pathname: pathname,
updatedAt: 0,
routeSearch: {},
search: {} as any,
status: hasLoaders ? 'pending' : 'success',
error: undefined,
loader: undefined,
loadPromise: Promise.resolve(),
routeContext: undefined!,
context: undefined!,
abortController: new AbortController(),
fetchedAt: 0,
}
return state
}

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 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

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc