@tanstack/router
Advanced tools
Comparing version 0.0.1-beta.140 to 0.0.1-beta.141
@@ -100,3 +100,5 @@ /** | ||
exports.useParams = react.useParams; | ||
exports.useRouteContext = react.useRouteContext; | ||
exports.useRouter = react.useRouter; | ||
exports.useRouterContext = react.useRouterContext; | ||
exports.useRouterState = react.useRouterState; | ||
@@ -103,0 +105,0 @@ exports.useSearch = react.useSearch; |
@@ -206,4 +206,4 @@ /** | ||
const matchIds = useRouterState({ | ||
select: d => { | ||
const hasPendingComponent = d.pendingMatches.some(d => { | ||
select: state => { | ||
const hasPendingComponent = state.pendingMatches.some(d => { | ||
const route = router.getRoute(d.routeId); | ||
@@ -213,5 +213,6 @@ return !!route?.options.pendingComponent; | ||
if (hasPendingComponent) { | ||
return d.pendingMatches.map(d => d.id); | ||
console.log('hasPending'); | ||
return state.pendingMatchIds; | ||
} | ||
return d.matches.map(d => d.id); | ||
return state.matchIds; | ||
} | ||
@@ -269,5 +270,17 @@ }); | ||
...opts, | ||
select: match => opts?.select?.(match.loader) ?? match.loader | ||
select: match => opts?.select?.(match.loaderData) ?? match.loaderData | ||
}); | ||
} | ||
function useRouterContext(opts) { | ||
return useMatch({ | ||
...opts, | ||
select: match => opts?.select?.(match.context) ?? match.context | ||
}); | ||
} | ||
function useRouteContext(opts) { | ||
return useMatch({ | ||
...opts, | ||
select: match => opts?.select?.(match.routeContext) ?? match.routeContext | ||
}); | ||
} | ||
function useSearch(opts) { | ||
@@ -348,2 +361,3 @@ return useMatch({ | ||
useContext: route.useContext, | ||
useRouteContext: route.useRouteContext, | ||
useSearch: route.useSearch, | ||
@@ -370,3 +384,3 @@ useParams: route.useParams | ||
select: d => { | ||
const match = d.pendingMatches.find(d => d.id === matchId) || d.matches.find(d => d.id === matchId); | ||
const match = d.matchesById[matchId]; | ||
return utils.pick(match, ['status', 'loadPromise', 'routeId', 'error']); | ||
@@ -384,2 +398,3 @@ } | ||
useContext: route.useContext, | ||
useRouteContext: route.useRouteContext, | ||
useSearch: route.useSearch, | ||
@@ -396,2 +411,3 @@ useParams: route.useParams | ||
useContext: route.useContext, | ||
useRouteContext: route.useRouteContext, | ||
useSearch: route.useSearch, | ||
@@ -586,5 +602,7 @@ useParams: route.useParams | ||
exports.useParams = useParams; | ||
exports.useRouteContext = useRouteContext; | ||
exports.useRouter = useRouter; | ||
exports.useRouterContext = useRouterContext; | ||
exports.useRouterState = useRouterState; | ||
exports.useSearch = useSearch; | ||
//# sourceMappingURL=react.js.map |
@@ -96,2 +96,9 @@ /** | ||
}; | ||
useRouteContext = opts => { | ||
return react.useMatch({ | ||
...opts, | ||
from: this.id, | ||
select: d => opts?.select?.(d.routeContext) ?? d.routeContext | ||
}); | ||
}; | ||
useSearch = opts => { | ||
@@ -115,32 +122,3 @@ return react.useSearch({ | ||
}; | ||
// 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 { | ||
@@ -147,0 +125,0 @@ constructor(options) { |
@@ -41,3 +41,22 @@ /** | ||
onUpdate: () => { | ||
const prev = this.state; | ||
this.state = this.__store.state; | ||
const matchesByIdChanged = prev.matchesById !== this.state.matchesById; | ||
let matchesChanged; | ||
let pendingMatchesChanged; | ||
if (!matchesByIdChanged) { | ||
matchesChanged = prev.matchIds.length !== this.state.matchIds.length || prev.matchIds.some((d, i) => d !== this.state.matchIds[i]); | ||
pendingMatchesChanged = prev.pendingMatchIds.length !== this.state.pendingMatchIds.length || prev.pendingMatchIds.some((d, i) => d !== this.state.pendingMatchIds[i]); | ||
} | ||
if (matchesByIdChanged || matchesChanged) { | ||
this.state.matches = this.state.matchIds.map(id => { | ||
return this.state.matchesById[id]; | ||
}); | ||
} | ||
if (matchesByIdChanged || pendingMatchesChanged) { | ||
this.state.pendingMatches = this.state.pendingMatchIds.map(id => { | ||
return this.state.matchesById[id]; | ||
}); | ||
} | ||
this.state.isFetching = [...this.state.matches, ...this.state.pendingMatches].some(d => d.isFetching); | ||
}, | ||
@@ -129,3 +148,3 @@ defaultPriority: 'low' | ||
}; | ||
latestLoadPromise = null; | ||
latestLoadPromise = Promise.resolve(); | ||
load = async opts => { | ||
@@ -139,3 +158,4 @@ const promise = new Promise(async (resolve, reject) => { | ||
// Cancel any pending matches | ||
this.cancelMatches(); | ||
// this.cancelMatches() | ||
let pendingMatches; | ||
@@ -153,3 +173,4 @@ this.__store.batch(() => { | ||
pendingMatches = this.matchRoutes(this.state.location.pathname, this.state.location.search, { | ||
throwOnError: opts?.throwOnError | ||
throwOnError: opts?.throwOnError, | ||
debug: true | ||
}); | ||
@@ -159,3 +180,4 @@ this.__store.setState(s => ({ | ||
status: 'pending', | ||
pendingMatches | ||
pendingMatchIds: pendingMatches.map(d => d.id), | ||
matchesById: this.#mergeMatches(s.matchesById, pendingMatches) | ||
})); | ||
@@ -176,4 +198,4 @@ }); | ||
resolvedLocation: s.location, | ||
matches: s.pendingMatches, | ||
pendingMatches: [] | ||
matchIds: s.pendingMatchIds, | ||
pendingMatchIds: [] | ||
})); | ||
@@ -195,2 +217,18 @@ if (prevLocation.href !== this.state.location.href) { | ||
}; | ||
#mergeMatches = (prevMatchesById, nextMatches) => { | ||
const nextMatchesById = { | ||
...prevMatchesById | ||
}; | ||
let hadNew = false; | ||
nextMatches.forEach(match => { | ||
if (!nextMatchesById[match.id]) { | ||
hadNew = true; | ||
nextMatchesById[match.id] = match; | ||
} | ||
}); | ||
if (!hadNew) { | ||
return prevMatchesById; | ||
} | ||
return nextMatchesById; | ||
}; | ||
getRoute = id => { | ||
@@ -206,22 +244,35 @@ const route = this.routesById[id]; | ||
}); | ||
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 | ||
} | ||
matchesById: this.#mergeMatches(s.matchesById, matches) | ||
}; | ||
}); | ||
await this.loadMatches(matches, { | ||
preload: true | ||
preload: true, | ||
maxAge: navigateOpts.maxAge | ||
}); | ||
return matches; | ||
}; | ||
cleanMatches = () => { | ||
const now = Date.now(); | ||
const outdatedMatchIds = Object.values(this.state.matchesById).filter(match => { | ||
const route = this.getRoute(match.routeId); | ||
return !this.state.matchIds.includes(match.id) && !this.state.pendingMatchIds.includes(match.id) && match.preloadInvalidAt < now && (route.options.gcMaxAge ? match.updatedAt + route.options.gcMaxAge < now : true); | ||
}).map(d => d.id); | ||
if (outdatedMatchIds.length) { | ||
this.__store.setState(s => { | ||
const matchesById = { | ||
...s.matchesById | ||
}; | ||
outdatedMatchIds.forEach(id => { | ||
delete matchesById[id]; | ||
}); | ||
return { | ||
...s, | ||
matchesById | ||
}; | ||
}); | ||
} | ||
}; | ||
matchRoutes = (pathname, locationSearch, opts) => { | ||
@@ -261,2 +312,6 @@ let routeParams = {}; | ||
parsedParams = route.options.parseParams?.(routeParams) ?? routeParams; | ||
// (typeof route.options.parseParams === 'object' && | ||
// route.options.parseParams.parse | ||
// ? route.options.parseParams.parse(routeParams) | ||
// : (route.options.parseParams as any)?.(routeParams!)) ?? routeParams | ||
} catch (err) { | ||
@@ -274,6 +329,8 @@ parsedParamsError = new PathParamError(err.message, { | ||
const interpolatedPath = path.interpolatePath(route.path, allParams); | ||
const matchId = path.interpolatePath(route.id, allParams, true) + (route.options.getKey?.({ | ||
const key = route.options.key ? route.options.key({ | ||
params: allParams, | ||
search: locationSearch | ||
}) ?? ''); | ||
}) ?? '' : ''; | ||
const stringifiedKey = key ? JSON.stringify(key) : ''; | ||
const matchId = path.interpolatePath(route.id, allParams, true) + stringifiedKey; | ||
@@ -285,3 +342,2 @@ // Waste not, want not. If we already have a match for this route, | ||
if (existingMatch) { | ||
// Return a copy, we don't want to mutate the existing match | ||
return { | ||
@@ -296,13 +352,18 @@ ...existingMatch | ||
id: matchId, | ||
key: stringifiedKey, | ||
routeId: route.id, | ||
params: allParams, | ||
pathname: path.joinPaths([this.basepath, interpolatedPath]), | ||
updatedAt: 0, | ||
updatedAt: Date.now(), | ||
invalidAt: Infinity, | ||
preloadInvalidAt: Infinity, | ||
routeSearch: {}, | ||
search: {}, | ||
status: hasLoaders ? 'pending' : 'success', | ||
status: hasLoaders ? 'idle' : 'success', | ||
isFetching: false, | ||
invalid: false, | ||
error: undefined, | ||
paramsError: parsedParamsError, | ||
searchError: undefined, | ||
loader: undefined, | ||
loaderData: undefined, | ||
loadPromise: Promise.resolve(), | ||
@@ -379,2 +440,3 @@ routeContext: undefined, | ||
loadMatches = async (resolvedMatches, opts) => { | ||
this.cleanMatches(); | ||
let firstBadMatchIndex; | ||
@@ -386,2 +448,16 @@ | ||
const route = this.getRoute(match.routeId); | ||
if (!opts?.preload) { | ||
// Update each match with its latest url data | ||
this.setRouteMatch(match.id, s => ({ | ||
...s, | ||
routeSearch: match.routeSearch, | ||
search: match.search, | ||
routeContext: match.routeContext, | ||
context: match.context, | ||
error: match.error, | ||
paramsError: match.paramsError, | ||
searchError: match.searchError, | ||
params: match.params | ||
})); | ||
} | ||
const handleError = (err, handler) => { | ||
@@ -432,11 +508,17 @@ firstBadMatchIndex = firstBadMatchIndex ?? index; | ||
validResolvedMatches.forEach((match, index) => { | ||
matchPromises.push(Promise.resolve().then(async () => { | ||
matchPromises.push((async () => { | ||
const parentMatchPromise = matchPromises[index - 1]; | ||
const route = this.getRoute(match.routeId); | ||
if (match.isFetching || match.status === 'success' && !this.getIsInvalid({ | ||
matchId: match.id, | ||
preload: opts?.preload | ||
})) { | ||
return this.getRouteMatch(match.id)?.loadPromise; | ||
} | ||
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; | ||
}; | ||
const checkLatest = () => { | ||
const latest = this.getRouteMatch(match.id); | ||
return latest && latest.fetchedAt !== fetchedAt ? latest.loadPromise : undefined; | ||
}; | ||
const loadPromise = (async () => { | ||
let latestPromise; | ||
@@ -449,30 +531,23 @@ const componentsPromise = Promise.all(componentTypes.map(async type => { | ||
})); | ||
const loaderPromise = Promise.resolve().then(() => { | ||
if (route.options.loader) { | ||
return route.options.loader({ | ||
...match, | ||
preload: !!opts?.preload, | ||
parentMatchPromise | ||
}); | ||
const loaderPromise = route.options.loader?.({ | ||
...match, | ||
preload: !!opts?.preload, | ||
parentMatchPromise | ||
}); | ||
const handleError = err => { | ||
if (isRedirect(err)) { | ||
if (!opts?.preload) { | ||
this.navigate(err); | ||
} | ||
return true; | ||
} | ||
return; | ||
}); | ||
return false; | ||
}; | ||
try { | ||
const [_, loader] = await Promise.all([componentsPromise, loaderPromise]); | ||
if (latestPromise = checkLatest()) return await latestPromise; | ||
if (!opts?.preload || !this.state.matches.find(d => d.id === match.id)) { | ||
this.setRouteMatch(match.id, s => ({ | ||
...s, | ||
error: undefined, | ||
status: 'success', | ||
updatedAt: Date.now(), | ||
loader | ||
})); | ||
} | ||
this.setRouteMatchData(match.id, () => loader, opts); | ||
} catch (err) { | ||
if (latestPromise = checkLatest()) return await latestPromise; | ||
if (isRedirect(err)) { | ||
if (!opts?.preload) { | ||
this.navigate(err); | ||
} | ||
if (handleError(err)) { | ||
return; | ||
@@ -486,6 +561,3 @@ } | ||
caughtError = errorHandlerErr; | ||
if (isRedirect(errorHandlerErr)) { | ||
if (!opts?.preload) { | ||
this.navigate(errorHandlerErr); | ||
} | ||
if (handleError(errorHandlerErr)) { | ||
return; | ||
@@ -498,27 +570,17 @@ } | ||
status: 'error', | ||
isFetching: false, | ||
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.setRouteMatch(match.id, s => ({ | ||
...s, | ||
status: s.status !== 'success' ? 'pending' : s.status, | ||
isFetching: true, | ||
loadPromise, | ||
fetchedAt | ||
fetchedAt, | ||
invalid: false | ||
})); | ||
await loadPromise; | ||
})); | ||
})()); | ||
}); | ||
@@ -528,3 +590,3 @@ await Promise.all(matchPromises); | ||
reload = () => { | ||
this.navigate({ | ||
return this.navigate({ | ||
fromCurrent: true, | ||
@@ -721,3 +783,2 @@ replace: true, | ||
...ctx.router.state, | ||
matches: s.matches, | ||
resolvedLocation: ctx.router.state.location | ||
@@ -934,46 +995,73 @@ }; | ||
getRouteMatch = id => { | ||
return this.state.matches.find(d => d.id === id) || this.state.pendingMatches.find(d => d.id === id) || this.state.preloadMatches[id]; | ||
return this.state.matchesById[id]; | ||
}; | ||
#setResolvedRouteMatch = (id, updater) => { | ||
setRouteMatch = (id, updater) => { | ||
this.__store.setState(prev => ({ | ||
...prev, | ||
matches: prev.matches.map(d => { | ||
if (d.id === id) { | ||
return updater(d); | ||
} | ||
return d; | ||
}) | ||
matchesById: { | ||
...prev.matchesById, | ||
[id]: updater(prev.matchesById[id]) | ||
} | ||
})); | ||
}; | ||
#setPendingRouteMatch = (id, updater) => { | ||
this.__store.setState(prev => ({ | ||
...prev, | ||
pendingMatches: prev.pendingMatches.map(d => { | ||
if (d.id === id) { | ||
return updater(d); | ||
} | ||
return d; | ||
}) | ||
setRouteMatchData = (id, updater, opts) => { | ||
const match = this.getRouteMatch(id); | ||
if (!match) return; | ||
const route = this.getRoute(match.routeId); | ||
const updatedAt = opts?.updatedAt ?? Date.now(); | ||
const preloadInvalidAt = updatedAt + (opts?.maxAge ?? route.options.preloadMaxAge ?? this.options.defaultPreloadMaxAge ?? 5000); | ||
const invalidAt = updatedAt + (opts?.maxAge ?? route.options.maxAge ?? this.options.defaultMaxAge ?? Infinity); | ||
this.setRouteMatch(id, s => ({ | ||
...s, | ||
error: undefined, | ||
status: 'success', | ||
isFetching: false, | ||
updatedAt: Date.now(), | ||
loaderData: utils.functionalUpdate(updater, s.loaderData), | ||
preloadInvalidAt, | ||
invalidAt | ||
})); | ||
if (this.state.matches.find(d => d.id === id)) ; | ||
}; | ||
#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]) | ||
invalidate = async opts => { | ||
if (opts?.matchId) { | ||
this.setRouteMatch(opts.matchId, s => ({ | ||
...s, | ||
invalid: true | ||
})); | ||
const matchIndex = this.state.matches.findIndex(d => d.id === opts.matchId); | ||
const childMatch = this.state.matches[matchIndex + 1]; | ||
if (childMatch) { | ||
return this.invalidate({ | ||
matchId: childMatch.id, | ||
reload: false | ||
}); | ||
} | ||
})); | ||
} else { | ||
this.__store.batch(() => { | ||
Object.values(this.state.matchesById).forEach(match => { | ||
this.setRouteMatch(match.id, s => ({ | ||
...s, | ||
invalid: true | ||
})); | ||
}); | ||
}); | ||
} | ||
if (opts?.reload ?? true) { | ||
return this.reload(); | ||
} | ||
}; | ||
setRouteMatch = (id, updater) => { | ||
if (this.state.matches.find(d => d.id === id)) { | ||
return this.#setResolvedRouteMatch(id, updater); | ||
getIsInvalid = opts => { | ||
if (!opts?.matchId) { | ||
return !!this.state.matches.find(d => this.getIsInvalid({ | ||
matchId: d.id, | ||
preload: opts?.preload | ||
})); | ||
} | ||
if (this.state.pendingMatches.find(d => d.id === id)) { | ||
return this.#setPendingRouteMatch(id, updater); | ||
const match = this.getRouteMatch(opts?.matchId); | ||
if (!match) { | ||
return false; | ||
} | ||
if (this.state.preloadMatches[id]) { | ||
return this.#setPreloadRouteMatch(id, updater); | ||
} | ||
const now = Date.now(); | ||
return match.invalid || (opts?.preload ? match.preloadInvalidAt : match.invalidAt) < now; | ||
}; | ||
@@ -987,7 +1075,10 @@ } | ||
status: 'idle', | ||
isFetching: false, | ||
resolvedLocation: null, | ||
location: null, | ||
matchesById: {}, | ||
matchIds: [], | ||
pendingMatchIds: [], | ||
matches: [], | ||
pendingMatches: [], | ||
preloadMatches: {}, | ||
lastUpdated: Date.now() | ||
@@ -994,0 +1085,0 @@ }; |
@@ -14,7 +14,7 @@ { | ||
"name": "tiny-invariant@1.3.1/node_modules/tiny-invariant/dist/esm/tiny-invariant.js", | ||
"uid": "8aaa-47" | ||
"uid": "742e-47" | ||
}, | ||
{ | ||
"name": "tiny-warning@1.0.3/node_modules/tiny-warning/dist/tiny-warning.esm.js", | ||
"uid": "8aaa-49" | ||
"uid": "742e-49" | ||
} | ||
@@ -30,35 +30,35 @@ ] | ||
{ | ||
"uid": "8aaa-51", | ||
"uid": "742e-51", | ||
"name": "history.ts" | ||
}, | ||
{ | ||
"uid": "8aaa-53", | ||
"uid": "742e-53", | ||
"name": "utils.ts" | ||
}, | ||
{ | ||
"uid": "8aaa-55", | ||
"uid": "742e-55", | ||
"name": "path.ts" | ||
}, | ||
{ | ||
"uid": "8aaa-57", | ||
"uid": "742e-57", | ||
"name": "qss.ts" | ||
}, | ||
{ | ||
"uid": "8aaa-65", | ||
"uid": "742e-65", | ||
"name": "react.tsx" | ||
}, | ||
{ | ||
"uid": "8aaa-67", | ||
"uid": "742e-67", | ||
"name": "route.ts" | ||
}, | ||
{ | ||
"uid": "8aaa-69", | ||
"uid": "742e-69", | ||
"name": "searchParams.ts" | ||
}, | ||
{ | ||
"uid": "8aaa-71", | ||
"uid": "742e-71", | ||
"name": "router.ts" | ||
}, | ||
{ | ||
"uid": "8aaa-73", | ||
"uid": "742e-73", | ||
"name": "index.ts" | ||
@@ -70,7 +70,7 @@ } | ||
"name": "store/build/esm/index.js", | ||
"uid": "8aaa-61" | ||
"uid": "742e-61" | ||
}, | ||
{ | ||
"name": "react-store/build/esm/index.js", | ||
"uid": "8aaa-63" | ||
"uid": "742e-63" | ||
} | ||
@@ -80,3 +80,3 @@ ] | ||
{ | ||
"uid": "8aaa-59", | ||
"uid": "742e-59", | ||
"name": "\u0000rollupPluginBabelHelpers.js" | ||
@@ -90,92 +90,92 @@ } | ||
"nodeParts": { | ||
"8aaa-47": { | ||
"742e-47": { | ||
"renderedLength": 199, | ||
"gzipLength": 134, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-46" | ||
"mainUid": "742e-46" | ||
}, | ||
"8aaa-49": { | ||
"742e-49": { | ||
"renderedLength": 48, | ||
"gzipLength": 65, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-48" | ||
"mainUid": "742e-48" | ||
}, | ||
"8aaa-51": { | ||
"742e-51": { | ||
"renderedLength": 6378, | ||
"gzipLength": 1522, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-50" | ||
"mainUid": "742e-50" | ||
}, | ||
"8aaa-53": { | ||
"742e-53": { | ||
"renderedLength": 2821, | ||
"gzipLength": 990, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-52" | ||
"mainUid": "742e-52" | ||
}, | ||
"8aaa-55": { | ||
"742e-55": { | ||
"renderedLength": 6028, | ||
"gzipLength": 1423, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-54" | ||
"mainUid": "742e-54" | ||
}, | ||
"8aaa-57": { | ||
"742e-57": { | ||
"renderedLength": 1371, | ||
"gzipLength": 552, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-56" | ||
"mainUid": "742e-56" | ||
}, | ||
"8aaa-59": { | ||
"742e-59": { | ||
"renderedLength": 457, | ||
"gzipLength": 241, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-58" | ||
"mainUid": "742e-58" | ||
}, | ||
"8aaa-61": { | ||
"742e-61": { | ||
"renderedLength": 1969, | ||
"gzipLength": 653, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-60" | ||
"mainUid": "742e-60" | ||
}, | ||
"8aaa-63": { | ||
"742e-63": { | ||
"renderedLength": 1070, | ||
"gzipLength": 485, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-62" | ||
"mainUid": "742e-62" | ||
}, | ||
"8aaa-65": { | ||
"renderedLength": 16689, | ||
"gzipLength": 3680, | ||
"742e-65": { | ||
"renderedLength": 17156, | ||
"gzipLength": 3732, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-64" | ||
"mainUid": "742e-64" | ||
}, | ||
"8aaa-67": { | ||
"renderedLength": 4568, | ||
"gzipLength": 1127, | ||
"742e-67": { | ||
"renderedLength": 3937, | ||
"gzipLength": 969, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-66" | ||
"mainUid": "742e-66" | ||
}, | ||
"8aaa-69": { | ||
"742e-69": { | ||
"renderedLength": 1387, | ||
"gzipLength": 483, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-68" | ||
"mainUid": "742e-68" | ||
}, | ||
"8aaa-71": { | ||
"renderedLength": 34332, | ||
"gzipLength": 7709, | ||
"742e-71": { | ||
"renderedLength": 38274, | ||
"gzipLength": 8514, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-70" | ||
"mainUid": "742e-70" | ||
}, | ||
"8aaa-73": { | ||
"742e-73": { | ||
"renderedLength": 0, | ||
"gzipLength": 0, | ||
"brotliLength": 0, | ||
"mainUid": "8aaa-72" | ||
"mainUid": "742e-72" | ||
} | ||
}, | ||
"nodeMetas": { | ||
"8aaa-46": { | ||
"742e-46": { | ||
"id": "/node_modules/.pnpm/tiny-invariant@1.3.1/node_modules/tiny-invariant/dist/esm/tiny-invariant.js", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-47" | ||
"index.production.js": "742e-47" | ||
}, | ||
@@ -185,19 +185,19 @@ "imported": [], | ||
{ | ||
"uid": "8aaa-72" | ||
"uid": "742e-72" | ||
}, | ||
{ | ||
"uid": "8aaa-66" | ||
"uid": "742e-66" | ||
}, | ||
{ | ||
"uid": "8aaa-70" | ||
"uid": "742e-70" | ||
}, | ||
{ | ||
"uid": "8aaa-64" | ||
"uid": "742e-64" | ||
} | ||
] | ||
}, | ||
"8aaa-48": { | ||
"742e-48": { | ||
"id": "/node_modules/.pnpm/tiny-warning@1.0.3/node_modules/tiny-warning/dist/tiny-warning.esm.js", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-49" | ||
"index.production.js": "742e-49" | ||
}, | ||
@@ -207,13 +207,13 @@ "imported": [], | ||
{ | ||
"uid": "8aaa-72" | ||
"uid": "742e-72" | ||
}, | ||
{ | ||
"uid": "8aaa-64" | ||
"uid": "742e-64" | ||
} | ||
] | ||
}, | ||
"8aaa-50": { | ||
"742e-50": { | ||
"id": "/packages/router/src/history.ts", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-51" | ||
"index.production.js": "742e-51" | ||
}, | ||
@@ -223,13 +223,13 @@ "imported": [], | ||
{ | ||
"uid": "8aaa-72" | ||
"uid": "742e-72" | ||
}, | ||
{ | ||
"uid": "8aaa-70" | ||
"uid": "742e-70" | ||
} | ||
] | ||
}, | ||
"8aaa-52": { | ||
"742e-52": { | ||
"id": "/packages/router/src/utils.ts", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-53" | ||
"index.production.js": "742e-53" | ||
}, | ||
@@ -239,23 +239,23 @@ "imported": [], | ||
{ | ||
"uid": "8aaa-72" | ||
"uid": "742e-72" | ||
}, | ||
{ | ||
"uid": "8aaa-54" | ||
"uid": "742e-54" | ||
}, | ||
{ | ||
"uid": "8aaa-70" | ||
"uid": "742e-70" | ||
}, | ||
{ | ||
"uid": "8aaa-64" | ||
"uid": "742e-64" | ||
} | ||
] | ||
}, | ||
"8aaa-54": { | ||
"742e-54": { | ||
"id": "/packages/router/src/path.ts", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-55" | ||
"index.production.js": "742e-55" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "8aaa-52" | ||
"uid": "742e-52" | ||
} | ||
@@ -265,16 +265,16 @@ ], | ||
{ | ||
"uid": "8aaa-72" | ||
"uid": "742e-72" | ||
}, | ||
{ | ||
"uid": "8aaa-66" | ||
"uid": "742e-66" | ||
}, | ||
{ | ||
"uid": "8aaa-70" | ||
"uid": "742e-70" | ||
} | ||
] | ||
}, | ||
"8aaa-56": { | ||
"742e-56": { | ||
"id": "/packages/router/src/qss.ts", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-57" | ||
"index.production.js": "742e-57" | ||
}, | ||
@@ -284,13 +284,13 @@ "imported": [], | ||
{ | ||
"uid": "8aaa-72" | ||
"uid": "742e-72" | ||
}, | ||
{ | ||
"uid": "8aaa-68" | ||
"uid": "742e-68" | ||
} | ||
] | ||
}, | ||
"8aaa-58": { | ||
"742e-58": { | ||
"id": "\u0000rollupPluginBabelHelpers.js", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-59" | ||
"index.production.js": "742e-59" | ||
}, | ||
@@ -300,10 +300,10 @@ "imported": [], | ||
{ | ||
"uid": "8aaa-64" | ||
"uid": "742e-64" | ||
} | ||
] | ||
}, | ||
"8aaa-60": { | ||
"742e-60": { | ||
"id": "/packages/store/build/esm/index.js", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-61" | ||
"index.production.js": "742e-61" | ||
}, | ||
@@ -313,17 +313,17 @@ "imported": [], | ||
{ | ||
"uid": "8aaa-62" | ||
"uid": "742e-62" | ||
} | ||
] | ||
}, | ||
"8aaa-62": { | ||
"742e-62": { | ||
"id": "/packages/react-store/build/esm/index.js", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-63" | ||
"index.production.js": "742e-63" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "8aaa-77" | ||
"uid": "742e-77" | ||
}, | ||
{ | ||
"uid": "8aaa-60" | ||
"uid": "742e-60" | ||
} | ||
@@ -333,32 +333,32 @@ ], | ||
{ | ||
"uid": "8aaa-70" | ||
"uid": "742e-70" | ||
}, | ||
{ | ||
"uid": "8aaa-64" | ||
"uid": "742e-64" | ||
} | ||
] | ||
}, | ||
"8aaa-64": { | ||
"742e-64": { | ||
"id": "/packages/router/src/react.tsx", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-65" | ||
"index.production.js": "742e-65" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "8aaa-58" | ||
"uid": "742e-58" | ||
}, | ||
{ | ||
"uid": "8aaa-76" | ||
"uid": "742e-76" | ||
}, | ||
{ | ||
"uid": "8aaa-62" | ||
"uid": "742e-62" | ||
}, | ||
{ | ||
"uid": "8aaa-46" | ||
"uid": "742e-46" | ||
}, | ||
{ | ||
"uid": "8aaa-48" | ||
"uid": "742e-48" | ||
}, | ||
{ | ||
"uid": "8aaa-52" | ||
"uid": "742e-52" | ||
} | ||
@@ -368,23 +368,23 @@ ], | ||
{ | ||
"uid": "8aaa-72" | ||
"uid": "742e-72" | ||
}, | ||
{ | ||
"uid": "8aaa-66" | ||
"uid": "742e-66" | ||
} | ||
] | ||
}, | ||
"8aaa-66": { | ||
"742e-66": { | ||
"id": "/packages/router/src/route.ts", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-67" | ||
"index.production.js": "742e-67" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "8aaa-46" | ||
"uid": "742e-46" | ||
}, | ||
{ | ||
"uid": "8aaa-54" | ||
"uid": "742e-54" | ||
}, | ||
{ | ||
"uid": "8aaa-64" | ||
"uid": "742e-64" | ||
} | ||
@@ -394,14 +394,14 @@ ], | ||
{ | ||
"uid": "8aaa-72" | ||
"uid": "742e-72" | ||
} | ||
] | ||
}, | ||
"8aaa-68": { | ||
"742e-68": { | ||
"id": "/packages/router/src/searchParams.ts", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-69" | ||
"index.production.js": "742e-69" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "8aaa-56" | ||
"uid": "742e-56" | ||
} | ||
@@ -411,32 +411,32 @@ ], | ||
{ | ||
"uid": "8aaa-72" | ||
"uid": "742e-72" | ||
}, | ||
{ | ||
"uid": "8aaa-70" | ||
"uid": "742e-70" | ||
} | ||
] | ||
}, | ||
"8aaa-70": { | ||
"742e-70": { | ||
"id": "/packages/router/src/router.ts", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-71" | ||
"index.production.js": "742e-71" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "8aaa-62" | ||
"uid": "742e-62" | ||
}, | ||
{ | ||
"uid": "8aaa-46" | ||
"uid": "742e-46" | ||
}, | ||
{ | ||
"uid": "8aaa-54" | ||
"uid": "742e-54" | ||
}, | ||
{ | ||
"uid": "8aaa-68" | ||
"uid": "742e-68" | ||
}, | ||
{ | ||
"uid": "8aaa-52" | ||
"uid": "742e-52" | ||
}, | ||
{ | ||
"uid": "8aaa-50" | ||
"uid": "742e-50" | ||
} | ||
@@ -446,47 +446,47 @@ ], | ||
{ | ||
"uid": "8aaa-72" | ||
"uid": "742e-72" | ||
} | ||
] | ||
}, | ||
"8aaa-72": { | ||
"742e-72": { | ||
"id": "/packages/router/src/index.ts", | ||
"moduleParts": { | ||
"index.production.js": "8aaa-73" | ||
"index.production.js": "742e-73" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "8aaa-46" | ||
"uid": "742e-46" | ||
}, | ||
{ | ||
"uid": "8aaa-48" | ||
"uid": "742e-48" | ||
}, | ||
{ | ||
"uid": "8aaa-50" | ||
"uid": "742e-50" | ||
}, | ||
{ | ||
"uid": "8aaa-74" | ||
"uid": "742e-74" | ||
}, | ||
{ | ||
"uid": "8aaa-54" | ||
"uid": "742e-54" | ||
}, | ||
{ | ||
"uid": "8aaa-56" | ||
"uid": "742e-56" | ||
}, | ||
{ | ||
"uid": "8aaa-66" | ||
"uid": "742e-66" | ||
}, | ||
{ | ||
"uid": "8aaa-75" | ||
"uid": "742e-75" | ||
}, | ||
{ | ||
"uid": "8aaa-70" | ||
"uid": "742e-70" | ||
}, | ||
{ | ||
"uid": "8aaa-68" | ||
"uid": "742e-68" | ||
}, | ||
{ | ||
"uid": "8aaa-52" | ||
"uid": "742e-52" | ||
}, | ||
{ | ||
"uid": "8aaa-64" | ||
"uid": "742e-64" | ||
} | ||
@@ -497,3 +497,3 @@ ], | ||
}, | ||
"8aaa-74": { | ||
"742e-74": { | ||
"id": "/packages/router/src/link.ts", | ||
@@ -504,7 +504,7 @@ "moduleParts": {}, | ||
{ | ||
"uid": "8aaa-72" | ||
"uid": "742e-72" | ||
} | ||
] | ||
}, | ||
"8aaa-75": { | ||
"742e-75": { | ||
"id": "/packages/router/src/routeInfo.ts", | ||
@@ -515,7 +515,7 @@ "moduleParts": {}, | ||
{ | ||
"uid": "8aaa-72" | ||
"uid": "742e-72" | ||
} | ||
] | ||
}, | ||
"8aaa-76": { | ||
"742e-76": { | ||
"id": "react", | ||
@@ -526,3 +526,3 @@ "moduleParts": {}, | ||
{ | ||
"uid": "8aaa-64" | ||
"uid": "742e-64" | ||
} | ||
@@ -532,3 +532,3 @@ ], | ||
}, | ||
"8aaa-77": { | ||
"742e-77": { | ||
"id": "use-sync-external-store/shim/with-selector", | ||
@@ -539,3 +539,3 @@ "moduleParts": {}, | ||
{ | ||
"uid": "8aaa-62" | ||
"uid": "742e-62" | ||
} | ||
@@ -542,0 +542,0 @@ ], |
@@ -74,2 +74,12 @@ import * as React from 'react'; | ||
}): TStrict extends true ? TSelected : TSelected | undefined; | ||
export declare function useRouterContext<TFrom extends keyof RegisteredRoutesInfo['routesById'], TStrict extends boolean = true, TContext = RegisteredRoutesInfo['routesById'][TFrom]['__types']['context'], TSelected = TContext>(opts?: { | ||
from: TFrom; | ||
strict?: TStrict; | ||
select?: (search: TContext) => TSelected; | ||
}): TStrict extends true ? TSelected : TSelected | undefined; | ||
export declare function useRouteContext<TFrom extends keyof RegisteredRoutesInfo['routesById'], TStrict extends boolean = true, TRouteContext = RegisteredRoutesInfo['routesById'][TFrom]['__types']['routeContext'], TSelected = TRouteContext>(opts?: { | ||
from: TFrom; | ||
strict?: TStrict; | ||
select?: (search: TRouteContext) => TSelected; | ||
}): TStrict extends true ? TSelected : TSelected | undefined; | ||
export declare function useSearch<TFrom extends keyof RegisteredRoutesInfo['routesById'], TStrict extends boolean = true, TSearch = RegisteredRoutesInfo['routesById'][TFrom]['__types']['fullSearchSchema'], TSelected = TSearch>(opts?: { | ||
@@ -86,3 +96,3 @@ from: TFrom; | ||
from?: TDefaultFrom; | ||
}): <TFrom extends unknown = TDefaultFrom, TTo extends string = "">(opts?: NavigateOptions<AnyRoutesInfo, TFrom, TTo> | undefined) => Promise<void | null>; | ||
}): <TFrom extends unknown = TDefaultFrom, TTo extends string = "">(opts?: NavigateOptions<AnyRoutesInfo, TFrom, TTo> | undefined) => Promise<void>; | ||
export declare function useMatchRoute(): <TFrom extends string = "/", TTo extends string = "">(opts: MakeUseMatchRouteOptions<TFrom, TTo>) => any; | ||
@@ -89,0 +99,0 @@ export declare function MatchRoute<TFrom extends string = '/', TTo extends string = ''>(props: MakeMatchRouteOptions<TFrom, TTo>): any; |
import { ParsePathParams } from './link'; | ||
import { AnyRouter, Router, RouteMatch } from './router'; | ||
import { IsAny, NoInfer, PickRequired, PickUnsafe, UnionToIntersection } from './utils'; | ||
import { IsAny, NoInfer, PickRequired, UnionToIntersection } from './utils'; | ||
import { AnyRoutesInfo, DefaultRoutesInfo } from './routeInfo'; | ||
@@ -26,7 +26,7 @@ import { RouteComponent, RouteErrorComponent } from './react'; | ||
}; | ||
export type AnyRouteProps = RouteProps<any, any, any, any>; | ||
export type ComponentPropsFromRoute<TRoute> = TRoute extends Route<infer TParentRoute, infer TPath, infer TFullPath, infer TCustomId, infer TId, infer TLoader, infer TSearchSchema, infer TFullSearchSchema, infer TParams, infer TAllParams, infer TParentContext, infer TAllParentContext, infer TRouteContext, infer TContext, infer TRouterContext, infer TChildren, infer TRoutesInfo> ? RouteProps<TLoader, TFullSearchSchema, TAllParams, TContext> : never; | ||
export type AnyRouteProps = RouteProps<any, any, any, any, any>; | ||
export type ComponentPropsFromRoute<TRoute> = TRoute extends Route<infer TParentRoute, infer TPath, infer TFullPath, infer TCustomId, infer TId, infer TLoader, infer TSearchSchema, infer TFullSearchSchema, infer TParams, infer TAllParams, infer TParentContext, infer TAllParentContext, infer TRouteContext, infer TContext, infer TRouterContext, infer TChildren, infer TRoutesInfo> ? RouteProps<TLoader, TFullSearchSchema, TAllParams, TRouteContext, TContext> : never; | ||
export type ComponentFromRoute<TRoute> = RouteComponent<ComponentPropsFromRoute<TRoute>>; | ||
export type RouteLoaderFromRoute<TRoute extends AnyRoute> = LoaderFn<TRoute['__types']['loader'], TRoute['__types']['searchSchema'], TRoute['__types']['fullSearchSchema'], TRoute['__types']['allParams'], TRoute['__types']['routeContext'], TRoute['__types']['context']>; | ||
export type RouteProps<TLoader = unknown, TFullSearchSchema extends AnySearchSchema = AnySearchSchema, TAllParams = AnyPathParams, TContext = AnyContext> = { | ||
export type RouteProps<TLoader = unknown, TFullSearchSchema extends AnySearchSchema = AnySearchSchema, TAllParams = AnyPathParams, TRouteContext = AnyContext, TContext = AnyContext> = { | ||
useMatch: () => RouteMatch<AnyRoutesInfo, AnyRoute>; | ||
@@ -44,11 +44,15 @@ useLoader: () => UseLoaderResult<TLoader>; | ||
}) => TSelected; | ||
useRouteContext: <TDefaultSelected = TRouteContext, TSelected = TDefaultSelected>(opts?: { | ||
select?: (context: TDefaultSelected) => TSelected; | ||
}) => TSelected; | ||
}; | ||
export type RouteOptions<TParentRoute extends AnyRoute = AnyRoute, TCustomId extends string = string, TPath extends string = string, TLoader = unknown, TParentSearchSchema extends AnySearchSchema = {}, TSearchSchema extends AnySearchSchema = {}, TFullSearchSchema extends AnySearchSchema = TSearchSchema, TParentParams extends AnyPathParams = AnyPathParams, TParams extends AnyPathParams = Record<ParsePathParams<TPath>, string>, TAllParams extends AnyPathParams = TParams, TParentContext extends AnyContext = AnyContext, TAllParentContext extends IsAny<TParentRoute['__types']['allParams'], TParentContext, TParentRoute['__types']['allParams'] & TParentContext> = IsAny<TParentRoute['__types']['allParams'], TParentContext, TParentRoute['__types']['allParams'] & TParentContext>, TRouteContext extends RouteContext = RouteContext, TContext extends MergeFromParent<TAllParentContext, TRouteContext> = MergeFromParent<TAllParentContext, TRouteContext>> = BaseRouteOptions<TParentRoute, TCustomId, TPath, TLoader, TParentSearchSchema, TSearchSchema, TFullSearchSchema, TParentParams, TParams, TAllParams, TParentContext, TAllParentContext, TRouteContext, TContext> & UpdatableRouteOptions<TLoader, TSearchSchema, TFullSearchSchema, TAllParams, TRouteContext, TContext>; | ||
export type BaseRouteOptions<TParentRoute extends AnyRoute = AnyRoute, TCustomId extends string = string, TPath extends string = string, TLoader = unknown, TParentSearchSchema extends AnySearchSchema = {}, TSearchSchema extends AnySearchSchema = {}, TFullSearchSchema extends AnySearchSchema = TSearchSchema, TParentParams extends AnyPathParams = AnyPathParams, TParams = Record<ParsePathParams<TPath>, string>, TAllParams = TParams, TParentContext extends AnyContext = AnyContext, TAllParentContext extends IsAny<TParentRoute['__types']['allParams'], TParentContext, TParentRoute['__types']['allParams'] & TParentContext> = IsAny<TParentRoute['__types']['allParams'], TParentContext, TParentRoute['__types']['allParams'] & TParentContext>, TRouteContext extends RouteContext = RouteContext, TContext extends MergeFromParent<TAllParentContext, TRouteContext> = MergeFromParent<TAllParentContext, TRouteContext>> = RoutePathOptions<TCustomId, TPath> & { | ||
export type ParamsFallback<TPath extends string, TParams> = unknown extends TParams ? Record<ParsePathParams<TPath>, string> : TParams; | ||
export type BaseRouteOptions<TParentRoute extends AnyRoute = AnyRoute, TCustomId extends string = string, TPath extends string = string, TLoader = unknown, TParentSearchSchema extends AnySearchSchema = {}, TSearchSchema extends AnySearchSchema = {}, TFullSearchSchema extends AnySearchSchema = TSearchSchema, TParentParams extends AnyPathParams = AnyPathParams, TParams = unknown, TAllParams = ParamsFallback<TPath, TParams>, TParentContext extends AnyContext = AnyContext, TAllParentContext extends IsAny<TParentRoute['__types']['allParams'], TParentContext, TParentRoute['__types']['allParams'] & TParentContext> = IsAny<TParentRoute['__types']['allParams'], TParentContext, TParentRoute['__types']['allParams'] & TParentContext>, TRouteContext extends RouteContext = RouteContext, TContext extends MergeFromParent<TAllParentContext, TRouteContext> = MergeFromParent<TAllParentContext, TRouteContext>> = RoutePathOptions<TCustomId, TPath> & { | ||
getParentRoute: () => TParentRoute; | ||
validateSearch?: SearchSchemaValidator<TSearchSchema, TParentSearchSchema>; | ||
loader?: LoaderFn<TLoader, TSearchSchema, TFullSearchSchema, TAllParams, NoInfer<TRouteContext>, TContext>; | ||
} & (PickUnsafe<TParentParams, ParsePathParams<TPath>> extends never ? {} : 'Cannot redefined path params in child routes!') & ({ | ||
} & ({ | ||
parseParams?: (rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>) => TParams extends Record<ParsePathParams<TPath>, any> ? TParams : 'parseParams must return an object'; | ||
stringifyParams?: (params: NoInfer<TParams>) => Record<ParsePathParams<TPath>, string>; | ||
stringifyParams?: (params: NoInfer<ParamsFallback<TPath, TParams>>) => Record<ParsePathParams<TPath>, string>; | ||
} | { | ||
@@ -73,10 +77,13 @@ stringifyParams?: never; | ||
export type UpdatableRouteOptions<TLoader, TSearchSchema extends AnySearchSchema, TFullSearchSchema extends AnySearchSchema, TAllParams extends AnyPathParams, TRouteContext extends AnyContext, TContext extends AnyContext> = MetaOptions & { | ||
getKey?: GetKeyFn<TFullSearchSchema, TAllParams>; | ||
key?: null | false | GetKeyFn<TFullSearchSchema, TAllParams>; | ||
caseSensitive?: boolean; | ||
wrapInSuspense?: boolean; | ||
component?: RouteComponent<RouteProps<TLoader, TFullSearchSchema, TAllParams, TContext>>; | ||
component?: RouteComponent<RouteProps<TLoader, TFullSearchSchema, TAllParams, TRouteContext, TContext>>; | ||
errorComponent?: RouteErrorComponent; | ||
pendingComponent?: RouteComponent<RouteProps<TLoader, TFullSearchSchema, TAllParams, TContext>>; | ||
pendingComponent?: RouteComponent<RouteProps<TLoader, TFullSearchSchema, TAllParams, TRouteContext, TContext>>; | ||
preSearchFilters?: SearchFilter<TFullSearchSchema>[]; | ||
postSearchFilters?: SearchFilter<TFullSearchSchema>[]; | ||
preloadMaxAge?: number; | ||
maxAge?: number; | ||
gcMaxAge?: number; | ||
beforeLoad?: (opts: LoaderContext<TSearchSchema, TFullSearchSchema, TAllParams, NoInfer<TRouteContext>, TContext>) => Promise<void> | void; | ||
@@ -100,2 +107,7 @@ onBeforeLoadError?: (err: any) => void; | ||
}; | ||
export type ParseParamsOption<TPath extends string, TParams> = ParseParamsFn<TPath, TParams>; | ||
export type ParseParamsFn<TPath extends string, TParams> = (rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>) => TParams extends Record<ParsePathParams<TPath>, any> ? TParams : 'parseParams must return an object'; | ||
export type ParseParamsObj<TPath extends string, TParams> = { | ||
parse?: ParseParamsFn<TPath, TParams>; | ||
}; | ||
export type SearchSchemaValidator<TReturn, TParentSchema> = SearchSchemaValidatorObj<TReturn, TParentSchema> | SearchSchemaValidatorFn<TReturn, TParentSchema>; | ||
@@ -210,2 +222,6 @@ export type SearchSchemaValidatorObj<TReturn, TParentSchema> = { | ||
} | undefined) => TStrict extends true ? TSelected : TSelected | undefined; | ||
useRouteContext: <TStrict extends boolean = true, TSelected = TRouteContext>(opts?: { | ||
strict?: TStrict | undefined; | ||
select?: ((search: TRouteContext) => TSelected) | undefined; | ||
} | undefined) => TStrict extends true ? TSelected : TSelected | undefined; | ||
useSearch: <TStrict extends boolean = true, TSelected = TFullSearchSchema>(opts?: { | ||
@@ -212,0 +228,0 @@ strict?: TStrict | undefined; |
@@ -55,6 +55,9 @@ /// <reference types="react" /> | ||
id: string; | ||
key?: string; | ||
routeId: string; | ||
pathname: string; | ||
params: TRoute['__types']['allParams']; | ||
status: 'pending' | 'success' | 'error'; | ||
status: 'idle' | 'pending' | 'success' | 'error'; | ||
isFetching: boolean; | ||
invalid: boolean; | ||
error: unknown; | ||
@@ -64,3 +67,5 @@ paramsError: unknown; | ||
updatedAt: number; | ||
loader: TRoute['__types']['loader']; | ||
invalidAt: number; | ||
preloadInvalidAt: number; | ||
loaderData: TRoute['__types']['loader']; | ||
loadPromise?: Promise<void>; | ||
@@ -87,7 +92,8 @@ __resolveLoadPromise?: () => void; | ||
defaultPreloadDelay?: number; | ||
defaultComponent?: RouteComponent<RouteProps<unknown, AnySearchSchema, AnyPathParams, AnyContext>>; | ||
defaultComponent?: RouteComponent<RouteProps<unknown, AnySearchSchema, AnyPathParams, AnyContext, AnyContext>>; | ||
defaultErrorComponent?: RouteErrorComponent; | ||
defaultPendingComponent?: RouteComponent<RouteProps<unknown, AnySearchSchema, AnyPathParams, AnyContext>>; | ||
defaultLoaderMaxAge?: number; | ||
defaultLoaderGcMaxAge?: number; | ||
defaultPendingComponent?: RouteComponent<RouteProps<unknown, AnySearchSchema, AnyPathParams, AnyContext, AnyContext>>; | ||
defaultMaxAge?: number; | ||
defaultGcMaxAge?: number; | ||
defaultPreloadMaxAge?: number; | ||
caseSensitive?: boolean; | ||
@@ -111,5 +117,8 @@ routeTree?: TRouteTree; | ||
status: 'idle' | 'pending'; | ||
isFetching: boolean; | ||
matchesById: Record<string, RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>>; | ||
matchIds: string[]; | ||
pendingMatchIds: string[]; | ||
matches: RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[]; | ||
pendingMatches: RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[]; | ||
preloadMatches: Record<string, RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>>; | ||
location: ParsedLocation<TRoutesInfo['fullSearchSchema'], TState>; | ||
@@ -180,3 +189,3 @@ resolvedLocation: ParsedLocation<TRoutesInfo['fullSearchSchema'], TState>; | ||
}) => Promise<void>; | ||
latestLoadPromise: Promise<void> | null; | ||
latestLoadPromise: Promise<void>; | ||
load: (opts?: { | ||
@@ -187,12 +196,17 @@ next?: ParsedLocation; | ||
getRoute: <TId extends keyof TRoutesInfo["routesById"]>(id: TId) => TRoutesInfo["routesById"][TId]; | ||
preloadRoute: (navigateOpts?: BuildNextOptions) => Promise<RouteMatch<TRoutesInfo, TRoutesInfo["routeIntersection"]>[]>; | ||
preloadRoute: (navigateOpts?: BuildNextOptions & { | ||
maxAge?: number; | ||
}) => Promise<RouteMatch<TRoutesInfo, TRoutesInfo["routeIntersection"]>[]>; | ||
cleanMatches: () => void; | ||
matchRoutes: (pathname: string, locationSearch: AnySearchSchema, opts?: { | ||
throwOnError?: boolean; | ||
debug?: boolean; | ||
}) => RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[]; | ||
loadMatches: (resolvedMatches: AnyRouteMatch[], opts?: { | ||
preload?: boolean; | ||
maxAge?: number; | ||
}) => Promise<void>; | ||
reload: () => void; | ||
reload: () => Promise<void>; | ||
resolvePath: (from: string, path: string) => string; | ||
navigate: <TFrom extends string = "/", TTo extends string = "">({ from, to, search, hash, replace, params, }: NavigateOptions<TRoutesInfo, TFrom, TTo>) => Promise<void | null>; | ||
navigate: <TFrom extends string = "/", TTo extends string = "">({ from, to, search, hash, replace, params, }: NavigateOptions<TRoutesInfo, TFrom, TTo>) => Promise<void>; | ||
matchRoute: <TFrom extends string = "/", TTo extends string = "", TResolved extends string = ResolveRelativePath<TFrom, NoInfer<TTo>>>(location: ToOptions<TRoutesInfo, TFrom, TTo, ResolveRelativePath<TFrom, NoInfer<TTo>>>, opts?: MatchRouteOptions) => false | TRoutesInfo["routesById"][TResolved]["__types"]["allParams"]; | ||
@@ -208,2 +222,14 @@ buildLink: <TFrom extends string = "/", TTo extends string = "">({ from, to, search, params, hash, target, replace, activeOptions, preload, preloadDelay: userPreloadDelay, disabled, }: LinkOptions<TRoutesInfo, TFrom, TTo>) => LinkInfo; | ||
setRouteMatch: (id: string, updater: (prev: RouteMatch<TRoutesInfo, AnyRoute>) => RouteMatch<TRoutesInfo, AnyRoute>) => void; | ||
setRouteMatchData: (id: string, updater: (prev: any) => any, opts?: { | ||
updatedAt?: number; | ||
maxAge?: number; | ||
}) => void; | ||
invalidate: (opts?: { | ||
matchId?: string; | ||
reload?: boolean; | ||
}) => Promise<void>; | ||
getIsInvalid: (opts?: { | ||
matchId: string; | ||
preload?: boolean; | ||
}) => boolean; | ||
} | ||
@@ -210,0 +236,0 @@ export type AnyRedirect = Redirect<any, any, any>; |
@@ -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 n=o(e);function s(t,e){if(!t)throw new Error("Invariant failed")}const a="pushstate",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,n=[],s=[];const a=()=>{if(n.length)n[0]?.(a,(()=>{n=[],u()}));else for(;s.length;)s.shift()?.()},i=t=>{s.push(t),a()},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=>(n.push(t),1===n.length&&addEventListener(c,h,{capture:!0}),()=>{n=n.filter((e=>e!==t)),n.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(a,t),window.addEventListener(i,t);var e=window.history.pushState;window.history.pushState=function(){let r=e.apply(history,arguments);return t(),r};var r=window.history.replaceState;return window.history.replaceState=function(){let e=r.apply(history,arguments);return t(),e},()=>{window.history.pushState=e,window.history.replaceState=r,window.removeEventListener(a,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,n)=>{o={...n,key:m()},e.push(t),r++},replaceState:(t,n)=>{o={...n,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 w(t,e){if(t===e)return t;const r=e,o=Array.isArray(t)&&Array.isArray(r);if(o||b(t)&&b(r)){const e=o?t.length:Object.keys(t).length,n=o?r:Object.keys(r),s=n.length,a=o?[]:{};let i=0;for(let e=0;e<s;e++){const s=o?e:n[e];a[s]=w(t[s],r[s]),a[s]===t[s]&&i++}return e===s&&i===e?t:a}return r}function b(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 E(t,e){return t===e||typeof t==typeof e&&(b(t)&&b(e)?!Object.keys(e).some((r=>!E(t[r],e[r]))):!(!Array.isArray(t)||!Array.isArray(e))&&(t.length===e.length&&t.every(((t,r)=>E(t,e[r])))))}function R(t){return P(t.filter(Boolean).join("/"))}function P(t){return t.replace(/\/{2,}/g,"/")}function _(t){return"/"===t?t:t.replace(/^\/{1,}/,"")}function x(t){return"/"===t?t:t.replace(/\/{1,}$/,"")}function M(t){return x(_(t))}function C(t,e,r){e=e.replace(new RegExp(`^${t}`),"/"),r=r.replace(new RegExp(`^${t}`),"/");let o=L(e);const n=L(r);n.forEach(((t,e)=>{if("/"===t.value)e?e===n.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 P(R([t,...o.map((t=>t.value))]))}function L(t){if(!t)return[];const e=[];if("/"===(t=P(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 O(t,e,r=!1){return R(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=k(t,e,r);if(!r.to||o)return o??{}}function k(t,e,r){e="/"!=t?e.substring(t.length):e;const o=`${r.to??"$"}`,n=L(e),s=L(o);e.startsWith("/")||n.unshift({type:"pathname",value:"/"}),o.startsWith("/")||s.unshift({type:"pathname",value:"/"});const a={};return(()=>{for(let t=0;t<Math.max(n.length,s.length);t++){const e=n[t],o=s[t],i=t>=n.length-1,c=t>=s.length-1;if(o){if("wildcard"===o.type)return!!e?.value&&(a["*"]=R(n.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)&&(a[o.value.substring(1)]=e.value)}}if(!i&&c)return!!r.fuzzy}return!0})()?a:void 0}function I(t,e){var r,o,n,s="";for(r in t)if(void 0!==(n=t[r]))if(Array.isArray(n))for(o=0;o<n.length;o++)s&&(s+="&"),s+=encodeURIComponent(r)+"="+encodeURIComponent(n[o]);else s&&(s+="&"),s+=encodeURIComponent(r)+"="+encodeURIComponent(n);return(e||"")+s}function $(t){if(!t)return"";var e=decodeURIComponent(t);return"false"!==e&&("true"===e||(0*+e==0&&+e+""===e?+e:e))}function D(t){for(var e,r,o={},n=t.split("&");e=n.shift();)void 0!==o[r=(e=e.split("=")).shift()]?o[r]=[].concat(o[r],$(e.shift())):o[r]=$(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 s(t){if(t&&t.__esModule)return t;var e=Object.create(null);return t&&Object.keys(t).forEach((function(r){if("default"!==r){var s=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,s.get?s:{enumerable:!0,get:function(){return t[r]}})}})),e.default=t,Object.freeze(e)}var o=s(e);function n(t,e){if(!t)throw new Error("Invariant failed")}const a="pushstate",i="popstate",c="beforeunload",h=t=>(t.preventDefault(),t.returnValue=""),u=()=>{removeEventListener(c,h,{capture:!0})};function l(t){let e=t.getLocation(),r=()=>{},s=new Set,o=[],n=[];const a=()=>{if(o.length)o[0]?.(a,(()=>{o=[],u()}));else for(;n.length;)n.shift()?.()},i=t=>{n.push(t),a()},l=()=>{e=t.getLocation(),s.forEach((t=>t()))};return{get location(){return e},listen:e=>(0===s.size&&(r=t.listener(l)),s.add(e),()=>{s.delete(e),0===s.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=>(o.push(t),1===o.length&&addEventListener(c,h,{capture:!0}),()=>{o=o.filter((e=>e!==t)),o.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(a,t),window.addEventListener(i,t);var e=window.history.pushState;window.history.pushState=function(){let r=e.apply(history,arguments);return t(),r};var r=window.history.replaceState;return window.history.replaceState=function(){let e=r.apply(history,arguments);return t(),e},()=>{window.history.pushState=e,window.history.replaceState=r,window.removeEventListener(a,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,s={};return l({getLocation:()=>f(e[r],s),listener:()=>()=>{},pushState:(t,o)=>{s={...o,key:m()},e.push(t),r++},replaceState:(t,o)=>{s={...o,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("#"),s=t.indexOf("?");return{href:t,pathname:t.substring(0,r>0?s>0?Math.min(r,s):r:s>0?s:t.length),hash:r>-1?t.substring(r):"",search:s>-1?t.slice(s,-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 w(t,e){if(t===e)return t;const r=e,s=Array.isArray(t)&&Array.isArray(r);if(s||b(t)&&b(r)){const e=s?t.length:Object.keys(t).length,o=s?r:Object.keys(r),n=o.length,a=s?[]:{};let i=0;for(let e=0;e<n;e++){const n=s?e:o[e];a[n]=w(t[n],r[n]),a[n]===t[n]&&i++}return e===n&&i===e?t:a}return r}function b(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 x(t,e){return t===e||typeof t==typeof e&&(b(t)&&b(e)?!Object.keys(e).some((r=>!x(t[r],e[r]))):!(!Array.isArray(t)||!Array.isArray(e))&&(t.length===e.length&&t.every(((t,r)=>x(t,e[r])))))}function E(t){return R(t.filter(Boolean).join("/"))}function R(t){return t.replace(/\/{2,}/g,"/")}function I(t){return"/"===t?t:t.replace(/^\/{1,}/,"")}function P(t){return"/"===t?t:t.replace(/\/{1,}$/,"")}function _(t){return P(I(t))}function C(t,e,r){e=e.replace(new RegExp(`^${t}`),"/"),r=r.replace(new RegExp(`^${t}`),"/");let s=M(e);const o=M(r);o.forEach(((t,e)=>{if("/"===t.value)e?e===o.length-1&&s.push(t):s=[t];else if(".."===t.value)s.length>1&&"/"===y(s)?.value&&s.pop(),s.pop();else{if("."===t.value)return;s.push(t)}}));return R(E([t,...s.map((t=>t.value))]))}function M(t){if(!t)return[];const e=[];if("/"===(t=R(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 L(t,e,r=!1){return E(M(t).map((t=>{if("wildcard"===t.type){const s=e[t.value];return r?`${t.value}${s??""}`:s}return"param"===t.type?e[t.value.substring(1)]??"":t.value})))}function O(t,e,r){const s=j(t,e,r);if(!r.to||s)return s??{}}function j(t,e,r){e="/"!=t?e.substring(t.length):e;const s=`${r.to??"$"}`,o=M(e),n=M(s);e.startsWith("/")||o.unshift({type:"pathname",value:"/"}),s.startsWith("/")||n.unshift({type:"pathname",value:"/"});const a={};return(()=>{for(let t=0;t<Math.max(o.length,n.length);t++){const e=o[t],s=n[t],i=t>=o.length-1,c=t>=n.length-1;if(s){if("wildcard"===s.type)return!!e?.value&&(a["*"]=E(o.slice(t).map((t=>t.value))),!0);if("pathname"===s.type){if("/"===s.value&&!e?.value)return!0;if(e)if(r.caseSensitive){if(s.value!==e.value)return!1}else if(s.value.toLowerCase()!==e.value.toLowerCase())return!1}if(!e)return!1;if("param"===s.type){if("/"===e?.value)return!1;"$"!==e.value.charAt(0)&&(a[s.value.substring(1)]=e.value)}}if(!i&&c)return!!r.fuzzy}return!0})()?a:void 0}function k(t,e){var r,s,o,n="";for(r in t)if(void 0!==(o=t[r]))if(Array.isArray(o))for(s=0;s<o.length;s++)n&&(n+="&"),n+=encodeURIComponent(r)+"="+encodeURIComponent(o[s]);else n&&(n+="&"),n+=encodeURIComponent(r)+"="+encodeURIComponent(o);return(e||"")+n}function A(t){if(!t)return"";var e=decodeURIComponent(t);return"false"!==e&&("true"===e||(0*+e==0&&+e+""===e?+e:e))}function D(t){for(var e,r,s={},o=t.split("&");e=o.shift();)void 0!==s[r=(e=e.split("=")).shift()]?s[r]=[].concat(s[r],A(e.shift())):s[r]=A(e.shift());return s}function B(){return B=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var s in r)Object.prototype.hasOwnProperty.call(r,s)&&(t[s]=r[s])}return t},B.apply(this,arguments)} | ||
/** | ||
@@ -22,3 +22,3 @@ * @tanstack/store/src/index.ts | ||
* @license MIT | ||
*/class H{listeners=new Set;_batching=!1;_flushing=0;_nextPriority=null;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,e)=>{const r=this.state;this.state=this.options?.updateFn?this.options.updateFn(r)(t):t(r);const o=e?.priority??this.options?.defaultPriority??"high";null===this._nextPriority||"high"===this._nextPriority?this._nextPriority=o:this._nextPriority=this.options?.defaultPriority??"high",this.options?.onUpdate?.({priority:this._nextPriority}),this._flush()};_flush=()=>{if(this._batching)return;const t=++this._flushing;this.listeners.forEach((e=>{this._flushing===t&&e({priority:this._nextPriority??"high"})}))};batch=t=>{if(this._batching)return t();this._batching=!0,t(),this._batching=!1,this._flush()}} | ||
*/class ${listeners=new Set;_batching=!1;_flushing=0;_nextPriority=null;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,e)=>{const r=this.state;this.state=this.options?.updateFn?this.options.updateFn(r)(t):t(r);const s=e?.priority??this.options?.defaultPriority??"high";null===this._nextPriority||"high"===this._nextPriority?this._nextPriority=s:this._nextPriority=this.options?.defaultPriority??"high",this.options?.onUpdate?.({priority:this._nextPriority}),this._flush()};_flush=()=>{if(this._batching)return;const t=++this._flushing;this.listeners.forEach((e=>{this._flushing===t&&e({priority:this._nextPriority??"high"})}))};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 A(t,e=(t=>t)){return r.useSyncExternalStoreWithSelector(t.subscribe,(()=>t.state),(()=>t.state),e,B)}function B(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=K(),{type:r,children:o,target:s,activeProps:a=(()=>({className:"active"})),inactiveProps:i=(()=>({})),activeOptions:c,disabled:h,hash:u,search:l,params:d,to:p=".",preload:f,preloadDelay:m,replace:y,style:v,className:w,onClick:b,onFocus:S,onMouseEnter:E,onMouseLeave:R,onTouchStart:P,..._}=t,x=e.buildLink(t);if("external"===x.type){const{href:t}=x;return{href:t}}const{handleClick:M,handleFocus:C,handleEnter:L,handleLeave:O,handleTouchStart:j,isActive:k,next:I}=x,$=t=>e=>{e.persist&&e.persist(),t.filter(Boolean).forEach((t=>{e.defaultPrevented||t(e)}))},D=k?g(a,{})??{}:{},T=k?{}:g(i,{})??{};return{...D,...T,..._,href:h?void 0:I.href,onClick:$([b,e=>{(t.startTransition??1)&&(n.startTransition||(t=>t))((()=>{M(e)}))}]),onFocus:$([S,C]),onMouseEnter:$([E,L]),onMouseLeave:$([R,O]),onTouchStart:$([P,j]),target:s,style:{...v,...D.style,...T.style},className:[w,D.className,T.className].filter(Boolean).join(" ")||void 0,...h?{role:"link","aria-disabled":!0}:void 0,"data-status":k?"active":void 0}}const U=n.forwardRef(((t,e)=>{const r=N(t);return n.createElement("a",T({ref:e},r,{children:"function"==typeof t.children?t.children({isActive:"active"===r["data-status"]}):t.children}))}));const z=n.createContext(null),F=n.createContext(null);function W(t){return A(K().__store,t?.select)}function J(){const t=K(),e=W({select:e=>e.pendingMatches.some((e=>!!t.getRoute(e.routeId)?.options.pendingComponent))?e.pendingMatches.map((t=>t.id)):e.matches.map((t=>t.id))});return n.createElement(z.Provider,{value:[void 0,...e]},n.createElement(ot,{errorComponent:st,onCatch:()=>{}},n.createElement(X,null)))}function K(){return n.useContext(F)}function q(t){const e=K(),r=n.useContext(z)[0],o=e.getRouteMatch(r)?.routeId,a=W({select:e=>{const o=e.matches;return(t?.from?o.find((e=>e.routeId===t?.from)):o.find((t=>t.id===r))).routeId}});(t?.strict??1)&&s(o==a);return W({select:e=>{const o=e.matches,n=t?.from?o.find((e=>e.routeId===t?.from)):o.find((t=>t.id===r));return s(n,t?.from&&t.from),t?.select?.(n)??n}})}function Y(t){return q({...t,select:e=>t?.select?.(e.loader)??e.loader})}function V(t){return q({...t,select:e=>t?.select?.(e.search)??e.search})}function G(t){return W({select:e=>{const r=y(e.matches)?.params;return t?.select?.(r)??r}})}function Q(){const t=K();return n.useCallback((e=>{const{pending:r,caseSensitive:o,...n}=e;return t.matchRoute(n,{pending:r,caseSensitive:o})}),[])}function X(){const t=n.useContext(z).slice(1);return t[0]?n.createElement(tt,{matchIds:t}):null}const Z=()=>null;function tt({matchIds:t}){const e=K(),r=t[0],o=e.getRouteMatch(r).routeId,s=e.getRoute(o),a=s.options.pendingComponent??e.options.defaultPendingComponent??Z,i=s.options.errorComponent??e.options.defaultErrorComponent??st,c=s.options.wrapInSuspense??!s.isRoot?n.Suspense:rt,h=i?ot:rt;return n.createElement(z.Provider,{value:t},n.createElement(c,{fallback:n.createElement(a,{useLoader:s.useLoader,useMatch:s.useMatch,useContext:s.useContext,useSearch:s.useSearch,useParams:s.useParams})},n.createElement(h,{key:s.id,errorComponent:i,onCatch:()=>{}},n.createElement(et,{matchId:r,PendingComponent:a}))))}function et({matchId:t,PendingComponent:e}){const r=K(),o=W({select:e=>v(e.pendingMatches.find((e=>e.id===t))||e.matches.find((e=>e.id===t)),["status","loadPromise","routeId","error"])}),a=r.getRoute(o.routeId);if("error"===o.status)throw o.error;if("pending"===o.status)return n.createElement(e,{useLoader:a.useLoader,useMatch:a.useMatch,useContext:a.useContext,useSearch:a.useSearch,useParams:a.useParams});if("success"===o.status){let t=a.options.component??r.options.defaultComponent;return t?n.createElement(t,{useLoader:a.useLoader,useMatch:a.useMatch,useContext:a.useContext,useSearch:a.useSearch,useParams:a.useParams}):n.createElement(X,null)}s(!1)}function rt(t){return n.createElement(n.Fragment,null,t.children)}class ot extends n.Component{state={error:!1,info:void 0};componentDidCatch(t,e){this.props.onCatch(t,e),this.setState({error:t,info:e})}render(){return n.createElement(nt,T({},this.props,{errorState:this.state,reset:()=>this.setState({})}))}}function nt(t){const e=W({select:t=>t.resolvedLocation.key}),[r,o]=n.useState(t.errorState),s=t.errorComponent??st,a=n.useRef("");return n.useEffect((()=>{r&&e!==a.current&&o({}),a.current=e}),[r,e]),n.useEffect((()=>{t.errorState.error&&o(t.errorState)}),[t.errorState.error]),t.errorState.error&&r.error?n.createElement(s,r):t.children}function st({error:t}){const[e,r]=n.useState(!1);return n.createElement("div",{style:{padding:".5rem",maxWidth:"100%"}},n.createElement("div",{style:{display:"flex",alignItems:"center",gap:".5rem"}},n.createElement("strong",{style:{fontSize:"1rem"}},"Something went wrong!"),n.createElement("button",{style:{appearance:"none",fontSize:".6em",border:"1px solid currentColor",padding:".1rem .2rem",fontWeight:"bold",borderRadius:".25rem"},onClick:()=>r((t=>!t))},e?"Hide Error":"Show Error")),n.createElement("div",{style:{height:".25rem"}}),e?n.createElement("div",null,n.createElement("pre",{style:{fontSize:".7em",border:"1px solid red",borderRadius:".25rem",padding:".3rem",color:"red",overflow:"auto"}},t.message?n.createElement("code",null,t.message):null)):null)}function at(t,e=!0){const r=K();n.useEffect((()=>{if(!e)return;let o=r.history.block(((e,r)=>{window.confirm(t)&&(o(),e())}));return o}))}const it="__root__";class ct{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=it:s(this.parentRoute);let o=r?it:e.path;o&&"/"!==o&&(o=M(o));const n=e?.id||o;let a=r?it:R([this.parentRoute.id===it?"":this.parentRoute.id,n]);o===it&&(o="/"),a!==it&&(a=R(["/",a]));const i=a===it?"/":R([this.parentRoute.fullPath,o]);this.path=o,this.id=a,this.fullPath=i,this.to=i};addChildren=t=>(this.children=t,this);update=t=>(Object.assign(this.options,t),this);useMatch=t=>q({...t,from:this.id});useLoader=t=>Y({...t,from:this.id});useContext=t=>q({...t,from:this.id,select:e=>t?.select?.(e.context)??e.context});useSearch=t=>V({...t,from:this.id});useParams=t=>G({...t,from:this.id})}class ht extends ct{constructor(t){super(t)}}const ut=dt(JSON.parse),lt=pt(JSON.stringify);function dt(t){return e=>{"?"===e.substring(0,1)&&(e=e.substring(1));let r=D(e);for(let e in r){const o=r[e];if("string"==typeof o)try{r[e]=t(o)}catch(t){}}return r}}function pt(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 ft=["component","errorComponent","pendingComponent"];const mt="undefined"==typeof window||!window.document.createElement;function yt(){return{status:"idle",resolvedLocation:null,location:null,matches:[],pendingMatches:[],preloadMatches:{},lastUpdated:Date.now()}}function gt(t){return!!t?.isRedirect}class vt extends Error{}class wt extends Error{}t.Block=function({message:t,condition:e,children:r}){return at(t,e),r??null},t.ErrorComponent=st,t.Link=U,t.MatchRoute=function(t){const e=Q()(t);return"function"==typeof t.children?t.children(e):e?t.children:null},t.Navigate=function(t){const e=K();return n.useLayoutEffect((()=>{e.navigate(t)}),[]),null},t.Outlet=X,t.PathParamError=wt,t.RootRoute=ht,t.Route=ct,t.Router=class{#t;constructor(t){this.options={defaultPreloadDelay:50,context:void 0,...t,stringifySearch:t?.stringifySearch??lt,parseSearch:t?.parseSearch??ut},this.__store=new H(yt(),{onUpdate:()=>{this.state=this.__store.state},defaultPriority:"low"}),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,yt())))};mount=()=>{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??(mt?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=`/${M(e??"")??""}`,r&&r!==this.routeTree&&this.#o(r),this};buildNext=t=>{const e=this.#n(t),r=this.matchRoutes(e.pathname,e.search);return this.#n({...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=>{}));latestLoadPromise=null;load=async t=>{const e=new Promise((async(r,o)=>{let n;const s=()=>this.latestLoadPromise!==e?this.latestLoadPromise:void 0;let a;this.cancelMatches(),this.__store.batch((()=>{t?.next&&this.__store.setState((e=>({...e,location:t.next}))),a=this.matchRoutes(this.state.location.pathname,this.state.location.search,{throwOnError:t?.throwOnError}),this.__store.setState((t=>({...t,status:"pending",pendingMatches:a})))}));try{if(await this.loadMatches(a),n=s())return await n;const t=this.state.resolvedLocation;this.__store.setState((t=>({...t,status:"idle",resolvedLocation:t.location,matches:t.pendingMatches,pendingMatches:[]}))),t.href!==this.state.location.href&&this.options.onRouteChange?.(),r()}catch(t){if(n=s())return await n;o(t)}}));return this.latestLoadPromise=e,this.latestLoadPromise};getRoute=t=>{const e=this.routesById[t];return s(e),e};preloadRoute=async(t=this.state.location)=>{const e=this.buildNext(t),r=this.matchRoutes(e.pathname,e.search,{throwOnError:!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={},n=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__,s=[n];for(;n?.parentRoute;)n=n.parentRoute,n&&s.unshift(n);let a={};const i=s.map((t=>{let n,s;try{n=t.options.parseParams?.(o)??o}catch(t){if(s=new wt(t.message,{cause:t}),r?.throwOnError)throw s}Object.assign(a,n);const i=O(t.path,a),c=O(t.id,a,!0)+(t.options.getKey?.({params:a,search:e})??""),h=this.getRouteMatch(c);if(h)return{...h};const u=!(!t.options.loader&&!ft.some((e=>t.options[e]?.preload)));return{id:c,routeId:t.id,params:a,pathname:R([this.basepath,i]),updatedAt:0,routeSearch:{},search:{},status:u?"pending":"success",error:void 0,paramsError:s,searchError:void 0,loader:void 0,loadPromise:Promise.resolve(),routeContext:void 0,context:void 0,abortController:new AbortController,fetchedAt:0}}));return i.forEach(((t,o)=>{const n=i[o-1],s=this.getRoute(t.routeId),a=(()=>{const o={search:n?.search??e,routeSearch:n?.routeSearch??e};try{const e=("object"==typeof s.options.validateSearch?s.options.validateSearch.parse:s.options.validateSearch)?.(o.search)??{},r={...o.search,...e};return{routeSearch:w(t.routeSearch,e),search:w(t.search,r)}}catch(e){if(t.searchError=new vt(e.message,{cause:e}),r?.throwOnError)throw t.searchError;return o}})(),c=(()=>{try{const e=s.options.getContext?.({parentContext:n?.routeContext??{},context:n?.context??this?.options.context??{},params:t.params,search:t.search})||{};return{context:{...n?.context??this?.options.context,...e},routeContext:e}}catch(t){throw s.options.onError?.(t),t}})();Object.assign(t,{...a,...c})})),i};loadMatches=async(t,e)=>{let r;try{await Promise.all(t.map((async(t,o)=>{const n=this.getRoute(t.routeId),s=(e,s)=>{if(r=r??o,s=s||n.options.onError,gt(e))throw e;try{s?.(e)}catch(t){if(e=t,gt(t))throw t}this.setRouteMatch(t.id,(t=>({...t,error:e,status:"error",updatedAt:Date.now()})))};t.paramsError&&s(t.paramsError,n.options.onParseParamsError),t.searchError&&s(t.searchError,n.options.onValidateSearchError);try{await(n.options.beforeLoad?.({...t,preload:!!e?.preload}))}catch(t){s(t,n.options.onBeforeLoadError)}})))}catch(t){throw e?.preload||this.navigate(t),t}const o=t.slice(0,r),n=[];o.forEach(((t,r)=>{n.push(Promise.resolve().then((async()=>{const o=n[r-1],s=this.getRoute(t.routeId),a=Date.now(),i=Promise.resolve().then((async()=>{const r=()=>{const e=this.getRouteMatch(t.id);return e&&e.fetchedAt!==a?e.loadPromise:void 0};let n;const i=Promise.all(ft.map((async t=>{const e=s.options[t];e?.preload&&await e.preload()}))),c=Promise.resolve().then((()=>{if(s.options.loader)return s.options.loader({...t,preload:!!e?.preload,parentMatchPromise:o})}));try{const[o,s]=await Promise.all([i,c]);if(n=r())return await n;e?.preload&&this.state.matches.find((e=>e.id===t.id))||this.setRouteMatch(t.id,(t=>({...t,error:void 0,status:"success",updatedAt:Date.now(),loader:s})))}catch(o){if(n=r())return await n;if(gt(o))return void(e?.preload||this.navigate(o));const a=s.options.onLoadError??s.options.onError;let i=o;try{a?.(o)}catch(t){if(i=t,gt(t))return void(e?.preload||this.navigate(t))}this.setRouteMatch(t.id,(t=>({...t,error:i,status:"error",updatedAt:Date.now()})))}finally{if(n=r())return await n;e?.preload&&this.__store.setState((e=>{const r={...e.preloadMatches};return delete r[t.id],{...e,preloadMatches:r}}))}}));this.setRouteMatch(t.id,(t=>({...t,loadPromise:i,fetchedAt:a}))),await i})))})),await Promise.all(n)};reload=()=>{this.navigate({fromCurrent:!0,replace:!0,search:!0})};resolvePath=(t,e)=>C(this.basepath,t,P(e));navigate=async({from:t,to:e="",search:r,hash:o,replace:n,params:a})=>{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.#e({from:c,to:i,search:r,hash:o,replace:n,params:a})};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 n=j(this.basepath,o.pathname,{...e,to:r.pathname});return!!n&&(e?.includeSearch??1?!!E(o.search,r.search)&&n:n)};buildLink=({from:t,to:e=".",search:r,params:o,hash:n,target:s,replace:a,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:n,replace:a},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)||E(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.#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__),s(e);const r=e;this.dehydratedData=r.payload,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__${n=r,n.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 n})),()=>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(s(!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=M(t.fullPath),o=L(r);for(;o.length>1&&"/"===o[0]?.value;)o.shift();const n=o.map((t=>"param"===t.type?.5:"wildcard"===t.type?.25:1));return{child:t,trimmed:r,parsed:o,index:e,score:n}})).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:n}=this.history.location;const s=this.options.parseSearch(r);return{pathname:e,searchStr:r,search:w(t?.search,s),hash:o.split("#").reverse()[0]??"",href:`${e}${r}${o}`,state:n,key:n?.key||"__init__"}};#n=(t={})=>{t.fromCurrent=t.fromCurrent??""===t.to;const e=t.fromCurrent?this.state.location.pathname:t.from??this.state.location.pathname;let r=C(this.basepath??"/",e,`${t.to??""}`);const o={...y(this.matchRoutes(this.state.location.pathname,this.state.location.search))?.params};let n=!0===(t.params??!0)?o:g(t.params,o);n&&t.__matches?.map((t=>this.getRoute(t.routeId).options.stringifyParams)).filter(Boolean).forEach((t=>{n={...n,...t(n)}})),r=O(r,n??{});const s=t.__matches?.map((t=>this.getRoute(t.routeId).options.preSearchFilters??[])).flat().filter(Boolean)??[],a=t.__matches?.map((t=>this.getRoute(t.routeId).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=a?.length?a.reduce(((t,e)=>e(t)),c):c,u=w(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 n=`${e.pathname}${e.searchStr}${e.hash?`#${e.hash}`:""}`;return this.history["push"===o?"push":"replace"](n,{id:r,...e.state}),this.latestLoadPromise};getRouteMatch=t=>this.state.matches.find((e=>e.id===t))||this.state.pendingMatches.find((e=>e.id===t))||this.state.preloadMatches[t];#s=(t,e)=>{this.__store.setState((r=>({...r,matches:r.matches.map((r=>r.id===t?e(r):r))})))};#a=(t,e)=>{this.__store.setState((r=>({...r,pendingMatches:r.pendingMatches.map((r=>r.id===t?e(r):r))})))};#i=(t,e)=>{s(this.state.preloadMatches[t]),this.__store.setState((r=>({...r,preloadMatches:{...r.preloadMatches,[t]:e(r.preloadMatches[t])}})))};setRouteMatch=(t,e)=>this.state.matches.find((e=>e.id===t))?this.#s(t,e):this.state.pendingMatches.find((e=>e.id===t))?this.#a(t,e):this.state.preloadMatches[t]?this.#i(t,e):void 0},t.RouterContext=class{constructor(){}createRootRoute=t=>new ht(t)},t.RouterProvider=function({router:t,...e}){t.update(e),n.useEffect((()=>{let e;return n.startTransition((()=>{e=t.mount()})),e}),[t]);const r=t.options.Wrap||n.Fragment;return n.createElement(n.Suspense,{fallback:null},n.createElement(r,null,n.createElement(F.Provider,{value:t},n.createElement(J,null))))},t.SearchParamError=vt,t.cleanPath=P,t.componentTypes=ft,t.createBrowserHistory=d,t.createHashHistory=function(){return d({getHref:()=>window.location.hash.substring(1),createHref:t=>`#${t}`})},t.createMemoryHistory=p,t.decode=D,t.defaultParseSearch=ut,t.defaultStringifySearch=lt,t.encode=I,t.functionalUpdate=g,t.interpolatePath=O,t.invariant=s,t.isPlainObject=b,t.isRedirect=gt,t.joinPaths=R,t.last=y,t.lazyFn=function(t,e){return async(...r)=>(await t())[e||"default"](...r)},t.lazyRouteComponent=function(t,e){let r;const o=()=>(r||(r=t()),r),s=n.lazy((async()=>({default:(await o())[e??"default"]})));return s.preload=o,s},t.matchByPath=k,t.matchIdsContext=z,t.matchPathname=j,t.parsePathname=L,t.parseSearchWith=dt,t.partialDeepEqual=E,t.pick=v,t.redirect=function(t){return t.isRedirect=!0,t},t.replaceEqualDeep=w,t.resolvePath=C,t.rootRouteId=it,t.routerContext=F,t.shallow=function(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},t.stringifySearchWith=pt,t.trimPath=M,t.trimPathLeft=_,t.trimPathRight=x,t.useBlocker=at,t.useDehydrate=function(){const t=K();return n.useCallback((function(e,r){return t.dehydrateData(e,r)}),[])},t.useHydrate=function(){const t=K();return function(e){return t.hydrateData(e)}},t.useInjectHtml=function(){const t=K();return n.useCallback((e=>{t.injectHtml(e)}),[])},t.useLinkProps=N,t.useLoader=Y,t.useMatch=q,t.useMatchRoute=Q,t.useMatches=function(t){const e=n.useContext(z);return W({select:r=>{const o=r.matches.slice(r.matches.findIndex((t=>t.id===e[0])));return t?.select?.(o)??o}})},t.useNavigate=function(t){const e=K();return n.useCallback((r=>e.navigate({...t,...r})),[])},t.useParams=G,t.useRouter=K,t.useRouterState=W,t.useSearch=V,t.useStore=A,t.warning=function(t,e){},Object.defineProperty(t,"__esModule",{value:!0})})); | ||
*/function T(t,e=(t=>t)){return r.useSyncExternalStoreWithSelector(t.subscribe,(()=>t.state),(()=>t.state),e,H)}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 s=0;s<r.length;s++)if(!Object.prototype.hasOwnProperty.call(e,r[s])||!Object.is(t[r[s]],e[r[s]]))return!1;return!0}function F(t){const e=q(),{type:r,children:s,target:n,activeProps:a=(()=>({className:"active"})),inactiveProps:i=(()=>({})),activeOptions:c,disabled:h,hash:u,search:l,params:d,to:p=".",preload:f,preloadDelay:m,replace:y,style:v,className:w,onClick:b,onFocus:S,onMouseEnter:x,onMouseLeave:E,onTouchStart:R,...I}=t,P=e.buildLink(t);if("external"===P.type){const{href:t}=P;return{href:t}}const{handleClick:_,handleFocus:C,handleEnter:M,handleLeave:L,handleTouchStart:O,isActive:j,next:k}=P,A=t=>e=>{e.persist&&e.persist(),t.filter(Boolean).forEach((t=>{e.defaultPrevented||t(e)}))},D=j?g(a,{})??{}:{},B=j?{}:g(i,{})??{};return{...D,...B,...I,href:h?void 0:k.href,onClick:A([b,e=>{(t.startTransition??1)&&(o.startTransition||(t=>t))((()=>{_(e)}))}]),onFocus:A([S,C]),onMouseEnter:A([x,M]),onMouseLeave:A([E,L]),onTouchStart:A([R,O]),target:n,style:{...v,...D.style,...B.style},className:[w,D.className,B.className].filter(Boolean).join(" ")||void 0,...h?{role:"link","aria-disabled":!0}:void 0,"data-status":j?"active":void 0}}const N=o.forwardRef(((t,e)=>{const r=F(t);return o.createElement("a",B({ref:e},r,{children:"function"==typeof t.children?t.children({isActive:"active"===r["data-status"]}):t.children}))}));const U=o.createContext(null),z=o.createContext(null);function W(t){return T(q().__store,t?.select)}function J(){const t=q(),e=W({select:e=>e.pendingMatches.some((e=>!!t.getRoute(e.routeId)?.options.pendingComponent))?(console.log("hasPending"),e.pendingMatchIds):e.matchIds});return o.createElement(U.Provider,{value:[void 0,...e]},o.createElement(st,{errorComponent:nt,onCatch:()=>{}},o.createElement(X,null)))}function q(){return o.useContext(z)}function K(t){const e=q(),r=o.useContext(U)[0],s=e.getRouteMatch(r)?.routeId,a=W({select:e=>{const s=e.matches;return(t?.from?s.find((e=>e.routeId===t?.from)):s.find((t=>t.id===r))).routeId}});(t?.strict??1)&&n(s==a);return W({select:e=>{const s=e.matches,o=t?.from?s.find((e=>e.routeId===t?.from)):s.find((t=>t.id===r));return n(o,t?.from&&t.from),t?.select?.(o)??o}})}function Y(t){return K({...t,select:e=>t?.select?.(e.loaderData)??e.loaderData})}function V(t){return K({...t,select:e=>t?.select?.(e.search)??e.search})}function G(t){return W({select:e=>{const r=y(e.matches)?.params;return t?.select?.(r)??r}})}function Q(){const t=q();return o.useCallback((e=>{const{pending:r,caseSensitive:s,...o}=e;return t.matchRoute(o,{pending:r,caseSensitive:s})}),[])}function X(){const t=o.useContext(U).slice(1);return t[0]?o.createElement(tt,{matchIds:t}):null}const Z=()=>null;function tt({matchIds:t}){const e=q(),r=t[0],s=e.getRouteMatch(r).routeId,n=e.getRoute(s),a=n.options.pendingComponent??e.options.defaultPendingComponent??Z,i=n.options.errorComponent??e.options.defaultErrorComponent??nt,c=n.options.wrapInSuspense??!n.isRoot?o.Suspense:rt,h=i?st:rt;return o.createElement(U.Provider,{value:t},o.createElement(c,{fallback:o.createElement(a,{useLoader:n.useLoader,useMatch:n.useMatch,useContext:n.useContext,useRouteContext:n.useRouteContext,useSearch:n.useSearch,useParams:n.useParams})},o.createElement(h,{key:n.id,errorComponent:i,onCatch:()=>{}},o.createElement(et,{matchId:r,PendingComponent:a}))))}function et({matchId:t,PendingComponent:e}){const r=q(),s=W({select:e=>v(e.matchesById[t],["status","loadPromise","routeId","error"])}),a=r.getRoute(s.routeId);if("error"===s.status)throw s.error;if("pending"===s.status)return o.createElement(e,{useLoader:a.useLoader,useMatch:a.useMatch,useContext:a.useContext,useRouteContext:a.useRouteContext,useSearch:a.useSearch,useParams:a.useParams});if("success"===s.status){let t=a.options.component??r.options.defaultComponent;return t?o.createElement(t,{useLoader:a.useLoader,useMatch:a.useMatch,useContext:a.useContext,useRouteContext:a.useRouteContext,useSearch:a.useSearch,useParams:a.useParams}):o.createElement(X,null)}n(!1)}function rt(t){return o.createElement(o.Fragment,null,t.children)}class st extends o.Component{state={error:!1,info:void 0};componentDidCatch(t,e){this.props.onCatch(t,e),this.setState({error:t,info:e})}render(){return o.createElement(ot,B({},this.props,{errorState:this.state,reset:()=>this.setState({})}))}}function ot(t){const e=W({select:t=>t.resolvedLocation.key}),[r,s]=o.useState(t.errorState),n=t.errorComponent??nt,a=o.useRef("");return o.useEffect((()=>{r&&e!==a.current&&s({}),a.current=e}),[r,e]),o.useEffect((()=>{t.errorState.error&&s(t.errorState)}),[t.errorState.error]),t.errorState.error&&r.error?o.createElement(n,r):t.children}function nt({error:t}){const[e,r]=o.useState(!1);return o.createElement("div",{style:{padding:".5rem",maxWidth:"100%"}},o.createElement("div",{style:{display:"flex",alignItems:"center",gap:".5rem"}},o.createElement("strong",{style:{fontSize:"1rem"}},"Something went wrong!"),o.createElement("button",{style:{appearance:"none",fontSize:".6em",border:"1px solid currentColor",padding:".1rem .2rem",fontWeight:"bold",borderRadius:".25rem"},onClick:()=>r((t=>!t))},e?"Hide Error":"Show Error")),o.createElement("div",{style:{height:".25rem"}}),e?o.createElement("div",null,o.createElement("pre",{style:{fontSize:".7em",border:"1px solid red",borderRadius:".25rem",padding:".3rem",color:"red",overflow:"auto"}},t.message?o.createElement("code",null,t.message):null)):null)}function at(t,e=!0){const r=q();o.useEffect((()=>{if(!e)return;let s=r.history.block(((e,r)=>{window.confirm(t)&&(s(),e())}));return s}))}const it="__root__";class ct{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=it:n(this.parentRoute);let s=r?it:e.path;s&&"/"!==s&&(s=_(s));const o=e?.id||s;let a=r?it:E([this.parentRoute.id===it?"":this.parentRoute.id,o]);s===it&&(s="/"),a!==it&&(a=E(["/",a]));const i=a===it?"/":E([this.parentRoute.fullPath,s]);this.path=s,this.id=a,this.fullPath=i,this.to=i};addChildren=t=>(this.children=t,this);update=t=>(Object.assign(this.options,t),this);useMatch=t=>K({...t,from:this.id});useLoader=t=>Y({...t,from:this.id});useContext=t=>K({...t,from:this.id,select:e=>t?.select?.(e.context)??e.context});useRouteContext=t=>K({...t,from:this.id,select:e=>t?.select?.(e.routeContext)??e.routeContext});useSearch=t=>V({...t,from:this.id});useParams=t=>G({...t,from:this.id})}class ht extends ct{constructor(t){super(t)}}const ut=dt(JSON.parse),lt=pt(JSON.stringify);function dt(t){return e=>{"?"===e.substring(0,1)&&(e=e.substring(1));let r=D(e);for(let e in r){const s=r[e];if("string"==typeof s)try{r[e]=t(s)}catch(t){}}return r}}function pt(t){return e=>{(e={...e})&&Object.keys(e).forEach((r=>{const s=e[r];if(void 0===s||void 0===s)delete e[r];else if(s&&"object"==typeof s&&null!==s)try{e[r]=t(s)}catch(t){}}));const r=k(e).toString();return r?`?${r}`:""}}const ft=["component","errorComponent","pendingComponent"];const mt="undefined"==typeof window||!window.document.createElement;function yt(){return{status:"idle",isFetching:!1,resolvedLocation:null,location:null,matchesById:{},matchIds:[],pendingMatchIds:[],matches:[],pendingMatches:[],lastUpdated:Date.now()}}function gt(t){return!!t?.isRedirect}class vt extends Error{}class wt extends Error{}t.Block=function({message:t,condition:e,children:r}){return at(t,e),r??null},t.ErrorComponent=nt,t.Link=N,t.MatchRoute=function(t){const e=Q()(t);return"function"==typeof t.children?t.children(e):e?t.children:null},t.Navigate=function(t){const e=q();return o.useLayoutEffect((()=>{e.navigate(t)}),[]),null},t.Outlet=X,t.PathParamError=wt,t.RootRoute=ht,t.Route=ct,t.Router=class{#t;constructor(t){this.options={defaultPreloadDelay:50,context:void 0,...t,stringifySearch:t?.stringifySearch??lt,parseSearch:t?.parseSearch??ut},this.__store=new $(yt(),{onUpdate:()=>{const t=this.state;this.state=this.__store.state;const e=t.matchesById!==this.state.matchesById;let r,s;e||(r=t.matchIds.length!==this.state.matchIds.length||t.matchIds.some(((t,e)=>t!==this.state.matchIds[e])),s=t.pendingMatchIds.length!==this.state.pendingMatchIds.length||t.pendingMatchIds.some(((t,e)=>t!==this.state.pendingMatchIds[e]))),(e||r)&&(this.state.matches=this.state.matchIds.map((t=>this.state.matchesById[t]))),(e||s)&&(this.state.pendingMatches=this.state.pendingMatchIds.map((t=>this.state.matchesById[t]))),this.state.isFetching=[...this.state.matches,...this.state.pendingMatches].some((t=>t.isFetching))},defaultPriority:"low"}),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,yt())))};mount=()=>{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??(mt?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=`/${_(e??"")??""}`,r&&r!==this.routeTree&&this.#s(r),this};buildNext=t=>{const e=this.#o(t),r=this.matchRoutes(e.pathname,e.search);return this.#o({...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=>{}));latestLoadPromise=Promise.resolve();load=async t=>{const e=new Promise((async(r,s)=>{let o;const n=()=>this.latestLoadPromise!==e?this.latestLoadPromise:void 0;let a;this.__store.batch((()=>{t?.next&&this.__store.setState((e=>({...e,location:t.next}))),a=this.matchRoutes(this.state.location.pathname,this.state.location.search,{throwOnError:t?.throwOnError,debug:!0}),this.__store.setState((t=>({...t,status:"pending",pendingMatchIds:a.map((t=>t.id)),matchesById:this.#n(t.matchesById,a)})))}));try{if(await this.loadMatches(a),o=n())return await o;const t=this.state.resolvedLocation;this.__store.setState((t=>({...t,status:"idle",resolvedLocation:t.location,matchIds:t.pendingMatchIds,pendingMatchIds:[]}))),t.href!==this.state.location.href&&this.options.onRouteChange?.(),r()}catch(t){if(o=n())return await o;s(t)}}));return this.latestLoadPromise=e,this.latestLoadPromise};#n=(t,e)=>{const r={...t};let s=!1;return e.forEach((t=>{r[t.id]||(s=!0,r[t.id]=t)})),s?r:t};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,{throwOnError:!0});return this.__store.setState((t=>({...t,matchesById:this.#n(t.matchesById,r)}))),await this.loadMatches(r,{preload:!0,maxAge:t.maxAge}),r};cleanMatches=()=>{const t=Date.now(),e=Object.values(this.state.matchesById).filter((e=>{const r=this.getRoute(e.routeId);return!this.state.matchIds.includes(e.id)&&!this.state.pendingMatchIds.includes(e.id)&&e.preloadInvalidAt<t&&(!r.options.gcMaxAge||e.updatedAt+r.options.gcMaxAge<t)})).map((t=>t.id));e.length&&this.__store.setState((t=>{const r={...t.matchesById};return e.forEach((t=>{delete r[t]})),{...t,matchesById:r}}))};matchRoutes=(t,e,r)=>{let s={},o=this.flatRoutes.find((e=>{const r=O(this.basepath,t,{to:e.fullPath,caseSensitive:e.options.caseSensitive??this.options.caseSensitive});return!!r&&(s=r,!0)}))||this.routesById.__root__,n=[o];for(;o?.parentRoute;)o=o.parentRoute,o&&n.unshift(o);let a={};const i=n.map((t=>{let o,n;try{o=t.options.parseParams?.(s)??s}catch(t){if(n=new wt(t.message,{cause:t}),r?.throwOnError)throw n}Object.assign(a,o);const i=L(t.path,a),c=t.options.key?t.options.key({params:a,search:e})??"":"",h=c?JSON.stringify(c):"",u=L(t.id,a,!0)+h,l=this.getRouteMatch(u);if(l)return{...l};const d=!(!t.options.loader&&!ft.some((e=>t.options[e]?.preload)));return{id:u,key:h,routeId:t.id,params:a,pathname:E([this.basepath,i]),updatedAt:Date.now(),invalidAt:1/0,preloadInvalidAt:1/0,routeSearch:{},search:{},status:d?"idle":"success",isFetching:!1,invalid:!1,error:void 0,paramsError:n,searchError:void 0,loaderData:void 0,loadPromise:Promise.resolve(),routeContext:void 0,context:void 0,abortController:new AbortController,fetchedAt:0}}));return i.forEach(((t,s)=>{const o=i[s-1],n=this.getRoute(t.routeId),a=(()=>{const s={search:o?.search??e,routeSearch:o?.routeSearch??e};try{const e=("object"==typeof n.options.validateSearch?n.options.validateSearch.parse:n.options.validateSearch)?.(s.search)??{},r={...s.search,...e};return{routeSearch:w(t.routeSearch,e),search:w(t.search,r)}}catch(e){if(t.searchError=new vt(e.message,{cause:e}),r?.throwOnError)throw t.searchError;return s}})(),c=(()=>{try{const e=n.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 n.options.onError?.(t),t}})();Object.assign(t,{...a,...c})})),i};loadMatches=async(t,e)=>{let r;this.cleanMatches();try{await Promise.all(t.map((async(t,s)=>{const o=this.getRoute(t.routeId);e?.preload||this.setRouteMatch(t.id,(e=>({...e,routeSearch:t.routeSearch,search:t.search,routeContext:t.routeContext,context:t.context,error:t.error,paramsError:t.paramsError,searchError:t.searchError,params:t.params})));const n=(e,n)=>{if(r=r??s,n=n||o.options.onError,gt(e))throw e;try{n?.(e)}catch(t){if(e=t,gt(t))throw t}this.setRouteMatch(t.id,(t=>({...t,error:e,status:"error",updatedAt:Date.now()})))};t.paramsError&&n(t.paramsError,o.options.onParseParamsError),t.searchError&&n(t.searchError,o.options.onValidateSearchError);try{await(o.options.beforeLoad?.({...t,preload:!!e?.preload}))}catch(t){n(t,o.options.onBeforeLoadError)}})))}catch(t){throw e?.preload||this.navigate(t),t}const s=t.slice(0,r),o=[];s.forEach(((t,r)=>{o.push((async()=>{const s=o[r-1],n=this.getRoute(t.routeId);if(t.isFetching||"success"===t.status&&!this.getIsInvalid({matchId:t.id,preload:e?.preload}))return this.getRouteMatch(t.id)?.loadPromise;const a=Date.now(),i=()=>{const e=this.getRouteMatch(t.id);return e&&e.fetchedAt!==a?e.loadPromise:void 0},c=(async()=>{let r;const o=Promise.all(ft.map((async t=>{const e=n.options[t];e?.preload&&await e.preload()}))),a=n.options.loader?.({...t,preload:!!e?.preload,parentMatchPromise:s}),c=t=>!!gt(t)&&(e?.preload||this.navigate(t),!0);try{const[s,n]=await Promise.all([o,a]);if(r=i())return await r;this.setRouteMatchData(t.id,(()=>n),e)}catch(e){if(r=i())return await r;if(c(e))return;const s=n.options.onLoadError??n.options.onError;let o=e;try{s?.(e)}catch(t){if(o=t,c(t))return}this.setRouteMatch(t.id,(t=>({...t,error:o,status:"error",isFetching:!1,updatedAt:Date.now()})))}})();this.setRouteMatch(t.id,(t=>({...t,status:"success"!==t.status?"pending":t.status,isFetching:!0,loadPromise:c,fetchedAt:a,invalid:!1}))),await c})())})),await Promise.all(o)};reload=()=>this.navigate({fromCurrent:!0,replace:!0,search:!0});resolvePath=(t,e)=>C(this.basepath,t,R(e));navigate=async({from:t,to:e="",search:r,hash:s,replace:o,params:a})=>{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:s,replace:o,params:a})};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 s=e?.pending?this.state.location:this.state.resolvedLocation;if(!s)return!1;const o=O(this.basepath,s.pathname,{...e,to:r.pathname});return!!o&&(e?.includeSearch??1?!!x(s.search,r.search)&&o:o)};buildLink=({from:t,to:e=".",search:r,params:s,hash:o,target:n,replace:a,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:s,hash:o,replace:a},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)||x(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.dehydratedData=r.payload,this.options.hydrate?.(r.payload),this.__store.setState((t=>({...t,...r.router.state,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}`,s="function"==typeof e?await e():e;return`<script id='${t}' suppressHydrationWarning>window["__TSR_DEHYDRATED__${o=r,o.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/"/g,'\\"')}"] = ${JSON.stringify(s)}\n ;(() => {\n var el = document.getElementById('${t}')\n el.parentElement.removeChild(el)\n })()\n <\/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_DEHYDRATED__${e}`]}};#s=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=P(t.fullPath);this.routesByPath[e]&&!t.fullPath.endsWith("/")||(this.routesByPath[e]=t)}const s=t.children;s?.length&&e(s)}))};e([t]),this.flatRoutes=Object.values(this.routesByPath).map(((t,e)=>{const r=_(t.fullPath),s=M(r);for(;s.length>1&&"/"===s[0]?.value;)s.shift();const o=s.map((t=>"param"===t.type?.5:"wildcard"===t.type?.25:1));return{child:t,trimmed:r,parsed:s,index:e,score:o}})).sort(((t,e)=>{let r="/"===t.trimmed?1:"/"===e.trimmed?-1:0;if(0!==r)return r;const s=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<s;r++)if(t.score[r]!==e.score[r])return e.score[r]-t.score[r];for(let r=0;r<s;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:s,state:o}=this.history.location;const n=this.options.parseSearch(r);return{pathname:e,searchStr:r,search:w(t?.search,n),hash:s.split("#").reverse()[0]??"",href:`${e}${r}${s}`,state:o,key:o?.key||"__init__"}};#o=(t={})=>{t.fromCurrent=t.fromCurrent??""===t.to;const e=t.fromCurrent?this.state.location.pathname:t.from??this.state.location.pathname;let r=C(this.basepath??"/",e,`${t.to??""}`);const s={...y(this.matchRoutes(this.state.location.pathname,this.state.location.search))?.params};let o=!0===(t.params??!0)?s:g(t.params,s);o&&t.__matches?.map((t=>this.getRoute(t.routeId).options.stringifyParams)).filter(Boolean).forEach((t=>{o={...o,...t(o)}})),r=L(r,o??{});const n=t.__matches?.map((t=>this.getRoute(t.routeId).options.preSearchFilters??[])).flat().filter(Boolean)??[],a=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=a?.length?a.reduce(((t,e)=>e(t)),c):c,u=w(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 s="replace";t.replace||(s="push");this.state.location.href===e.href&&!e.key&&(s="replace");const o=`${e.pathname}${e.searchStr}${e.hash?`#${e.hash}`:""}`;return this.history["push"===s?"push":"replace"](o,{id:r,...e.state}),this.latestLoadPromise};getRouteMatch=t=>this.state.matchesById[t];setRouteMatch=(t,e)=>{this.__store.setState((r=>({...r,matchesById:{...r.matchesById,[t]:e(r.matchesById[t])}})))};setRouteMatchData=(t,e,r)=>{const s=this.getRouteMatch(t);if(!s)return;const o=this.getRoute(s.routeId),n=r?.updatedAt??Date.now(),a=n+(r?.maxAge??o.options.preloadMaxAge??this.options.defaultPreloadMaxAge??5e3),i=n+(r?.maxAge??o.options.maxAge??this.options.defaultMaxAge??1/0);this.setRouteMatch(t,(t=>({...t,error:void 0,status:"success",isFetching:!1,updatedAt:Date.now(),loaderData:g(e,t.loaderData),preloadInvalidAt:a,invalidAt:i}))),this.state.matches.find((e=>e.id===t))};invalidate=async t=>{if(t?.matchId){this.setRouteMatch(t.matchId,(t=>({...t,invalid:!0})));const e=this.state.matches.findIndex((e=>e.id===t.matchId)),r=this.state.matches[e+1];if(r)return this.invalidate({matchId:r.id,reload:!1})}else this.__store.batch((()=>{Object.values(this.state.matchesById).forEach((t=>{this.setRouteMatch(t.id,(t=>({...t,invalid:!0})))}))}));if(t?.reload??1)return this.reload()};getIsInvalid=t=>{if(!t?.matchId)return!!this.state.matches.find((e=>this.getIsInvalid({matchId:e.id,preload:t?.preload})));const e=this.getRouteMatch(t?.matchId);if(!e)return!1;const r=Date.now();return e.invalid||(t?.preload?e.preloadInvalidAt:e.invalidAt)<r}},t.RouterContext=class{constructor(){}createRootRoute=t=>new ht(t)},t.RouterProvider=function({router:t,...e}){t.update(e),o.useEffect((()=>{let e;return o.startTransition((()=>{e=t.mount()})),e}),[t]);const r=t.options.Wrap||o.Fragment;return o.createElement(o.Suspense,{fallback:null},o.createElement(r,null,o.createElement(z.Provider,{value:t},o.createElement(J,null))))},t.SearchParamError=vt,t.cleanPath=R,t.componentTypes=ft,t.createBrowserHistory=d,t.createHashHistory=function(){return d({getHref:()=>window.location.hash.substring(1),createHref:t=>`#${t}`})},t.createMemoryHistory=p,t.decode=D,t.defaultParseSearch=ut,t.defaultStringifySearch=lt,t.encode=k,t.functionalUpdate=g,t.interpolatePath=L,t.invariant=n,t.isPlainObject=b,t.isRedirect=gt,t.joinPaths=E,t.last=y,t.lazyFn=function(t,e){return async(...r)=>(await t())[e||"default"](...r)},t.lazyRouteComponent=function(t,e){let r;const s=()=>(r||(r=t()),r),n=o.lazy((async()=>({default:(await s())[e??"default"]})));return n.preload=s,n},t.matchByPath=j,t.matchIdsContext=U,t.matchPathname=O,t.parsePathname=M,t.parseSearchWith=dt,t.partialDeepEqual=x,t.pick=v,t.redirect=function(t){return t.isRedirect=!0,t},t.replaceEqualDeep=w,t.resolvePath=C,t.rootRouteId=it,t.routerContext=z,t.shallow=function(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 s=0;s<r.length;s++)if(!Object.prototype.hasOwnProperty.call(e,r[s])||!Object.is(t[r[s]],e[r[s]]))return!1;return!0},t.stringifySearchWith=pt,t.trimPath=_,t.trimPathLeft=I,t.trimPathRight=P,t.useBlocker=at,t.useDehydrate=function(){const t=q();return o.useCallback((function(e,r){return t.dehydrateData(e,r)}),[])},t.useHydrate=function(){const t=q();return function(e){return t.hydrateData(e)}},t.useInjectHtml=function(){const t=q();return o.useCallback((e=>{t.injectHtml(e)}),[])},t.useLinkProps=F,t.useLoader=Y,t.useMatch=K,t.useMatchRoute=Q,t.useMatches=function(t){const e=o.useContext(U);return W({select:r=>{const s=r.matches.slice(r.matches.findIndex((t=>t.id===e[0])));return t?.select?.(s)??s}})},t.useNavigate=function(t){const e=q();return o.useCallback((r=>e.navigate({...t,...r})),[])},t.useParams=G,t.useRouteContext=function(t){return K({...t,select:e=>t?.select?.(e.routeContext)??e.routeContext})},t.useRouter=q,t.useRouterContext=function(t){return K({...t,select:e=>t?.select?.(e.context)??e.context})},t.useRouterState=W,t.useSearch=V,t.useStore=T,t.warning=function(t,e){},Object.defineProperty(t,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=index.production.js.map |
{ | ||
"name": "@tanstack/router", | ||
"author": "Tanner Linsley", | ||
"version": "0.0.1-beta.140", | ||
"version": "0.0.1-beta.141", | ||
"license": "MIT", | ||
@@ -6,0 +6,0 @@ "repository": "tanstack/router", |
109
src/route.ts
@@ -49,3 +49,3 @@ import { ParsePathParams } from './link' | ||
export type AnyRouteProps = RouteProps<any, any, any, any> | ||
export type AnyRouteProps = RouteProps<any, any, any, any, any> | ||
export type ComponentPropsFromRoute<TRoute> = TRoute extends Route< | ||
@@ -70,3 +70,3 @@ infer TParentRoute, | ||
> | ||
? RouteProps<TLoader, TFullSearchSchema, TAllParams, TContext> | ||
? RouteProps<TLoader, TFullSearchSchema, TAllParams, TRouteContext, TContext> | ||
: never | ||
@@ -91,2 +91,3 @@ | ||
TAllParams = AnyPathParams, | ||
TRouteContext = AnyContext, | ||
TContext = AnyContext, | ||
@@ -116,2 +117,8 @@ > = { | ||
}) => TSelected | ||
useRouteContext: < | ||
TDefaultSelected = TRouteContext, | ||
TSelected = TDefaultSelected, | ||
>(opts?: { | ||
select?: (context: TDefaultSelected) => TSelected | ||
}) => TSelected | ||
} | ||
@@ -170,2 +177,7 @@ | ||
export type ParamsFallback< | ||
TPath extends string, | ||
TParams, | ||
> = unknown extends TParams ? Record<ParsePathParams<TPath>, string> : TParams | ||
export type BaseRouteOptions< | ||
@@ -180,4 +192,4 @@ TParentRoute extends AnyRoute = AnyRoute, | ||
TParentParams extends AnyPathParams = AnyPathParams, | ||
TParams = Record<ParsePathParams<TPath>, string>, | ||
TAllParams = TParams, | ||
TParams = unknown, | ||
TAllParams = ParamsFallback<TPath, TParams>, | ||
TParentContext extends AnyContext = AnyContext, | ||
@@ -209,7 +221,3 @@ TAllParentContext extends IsAny< | ||
> | ||
} & (PickUnsafe<TParentParams, ParsePathParams<TPath>> extends never | ||
? // Detect if an existing path param is being redefined | ||
{} | ||
: 'Cannot redefined path params in child routes!') & | ||
( | ||
} & ( | ||
| { | ||
@@ -222,4 +230,15 @@ // Both or none | ||
: 'parseParams must return an object' | ||
// | { | ||
// parse: ( | ||
// rawParams: IsAny< | ||
// TPath, | ||
// any, | ||
// Record<ParsePathParams<TPath>, string> | ||
// >, | ||
// ) => TParams extends Record<ParsePathParams<TPath>, any> | ||
// ? TParams | ||
// : 'parseParams must return an object' | ||
// } | ||
stringifyParams?: ( | ||
params: NoInfer<TParams>, | ||
params: NoInfer<ParamsFallback<TPath, TParams>>, | ||
) => Record<ParsePathParams<TPath>, string> | ||
@@ -284,3 +303,3 @@ } | ||
> = MetaOptions & { | ||
getKey?: GetKeyFn<TFullSearchSchema, TAllParams> | ||
key?: null | false | GetKeyFn<TFullSearchSchema, TAllParams> | ||
// If true, this route will be matched as case-sensitive | ||
@@ -292,3 +311,3 @@ caseSensitive?: boolean | ||
component?: RouteComponent< | ||
RouteProps<TLoader, TFullSearchSchema, TAllParams, TContext> | ||
RouteProps<TLoader, TFullSearchSchema, TAllParams, TRouteContext, TContext> | ||
> | ||
@@ -299,3 +318,3 @@ // The content to be rendered when the route encounters an error | ||
pendingComponent?: RouteComponent< | ||
RouteProps<TLoader, TFullSearchSchema, TAllParams, TContext> | ||
RouteProps<TLoader, TFullSearchSchema, TAllParams, TRouteContext, TContext> | ||
> | ||
@@ -308,2 +327,8 @@ // Filter functions that can manipulate search params *before* they are passed to links and navigate | ||
postSearchFilters?: SearchFilter<TFullSearchSchema>[] | ||
// If set, preload matches of this route will be considered fresh for this many milliseconds. | ||
preloadMaxAge?: number | ||
// If set, a match of this route will be considered fresh for this many milliseconds. | ||
maxAge?: number | ||
// If set, a match of this route that becomes inactive (or unused) will be garbage collected after this many milliseconds | ||
gcMaxAge?: number | ||
// This async function is called before a route is loaded. | ||
@@ -349,2 +374,18 @@ // If an error is thrown here, the route's loader will not be called. | ||
export type ParseParamsOption<TPath extends string, TParams> = ParseParamsFn< | ||
TPath, | ||
TParams | ||
> | ||
// | ParseParamsObj<TPath, TParams> | ||
export type ParseParamsFn<TPath extends string, TParams> = ( | ||
rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>, | ||
) => TParams extends Record<ParsePathParams<TPath>, any> | ||
? TParams | ||
: 'parseParams must return an object' | ||
export type ParseParamsObj<TPath extends string, TParams> = { | ||
parse?: ParseParamsFn<TPath, TParams> | ||
} | ||
// The parse type here allows a zod schema to be passed directly to the validator | ||
@@ -771,2 +812,16 @@ export type SearchSchemaValidator<TReturn, TParentSchema> = | ||
useRouteContext = < | ||
TStrict extends boolean = true, | ||
TSelected = TRouteContext, | ||
>(opts?: { | ||
strict?: TStrict | ||
select?: (search: TRouteContext) => TSelected | ||
}): TStrict extends true ? TSelected : TSelected | undefined => { | ||
return useMatch({ | ||
...opts, | ||
from: this.id, | ||
select: (d: any) => opts?.select?.(d.routeContext) ?? d.routeContext, | ||
} as any) | ||
} | ||
useSearch = < | ||
@@ -814,30 +869,2 @@ TStrict extends boolean = true, | ||
} | ||
// 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, | ||
// ) | ||
// } | ||
} | ||
@@ -844,0 +871,0 @@ |
@@ -124,6 +124,9 @@ import { Store } from '@tanstack/react-store' | ||
id: string | ||
key?: string | ||
routeId: string | ||
pathname: string | ||
params: TRoute['__types']['allParams'] | ||
status: 'pending' | 'success' | 'error' | ||
status: 'idle' | 'pending' | 'success' | 'error' | ||
isFetching: boolean | ||
invalid: boolean | ||
error: unknown | ||
@@ -133,3 +136,5 @@ paramsError: unknown | ||
updatedAt: number | ||
loader: TRoute['__types']['loader'] | ||
invalidAt: number | ||
preloadInvalidAt: number | ||
loaderData: TRoute['__types']['loader'] | ||
loadPromise?: Promise<void> | ||
@@ -167,10 +172,11 @@ __resolveLoadPromise?: () => void | ||
defaultComponent?: RouteComponent< | ||
RouteProps<unknown, AnySearchSchema, AnyPathParams, AnyContext> | ||
RouteProps<unknown, AnySearchSchema, AnyPathParams, AnyContext, AnyContext> | ||
> | ||
defaultErrorComponent?: RouteErrorComponent | ||
defaultPendingComponent?: RouteComponent< | ||
RouteProps<unknown, AnySearchSchema, AnyPathParams, AnyContext> | ||
RouteProps<unknown, AnySearchSchema, AnyPathParams, AnyContext, AnyContext> | ||
> | ||
defaultLoaderMaxAge?: number | ||
defaultLoaderGcMaxAge?: number | ||
defaultMaxAge?: number | ||
defaultGcMaxAge?: number | ||
defaultPreloadMaxAge?: number | ||
caseSensitive?: boolean | ||
@@ -195,8 +201,11 @@ routeTree?: TRouteTree | ||
status: 'idle' | 'pending' | ||
matches: RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[] | ||
pendingMatches: RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[] | ||
preloadMatches: Record< | ||
isFetching: boolean | ||
matchesById: Record< | ||
string, | ||
RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']> | ||
> | ||
matchIds: string[] | ||
pendingMatchIds: string[] | ||
matches: RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[] | ||
pendingMatches: RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[] | ||
location: ParsedLocation<TRoutesInfo['fullSearchSchema'], TState> | ||
@@ -302,3 +311,39 @@ resolvedLocation: ParsedLocation<TRoutesInfo['fullSearchSchema'], TState> | ||
onUpdate: () => { | ||
const prev = this.state | ||
this.state = this.__store.state | ||
const matchesByIdChanged = prev.matchesById !== this.state.matchesById | ||
let matchesChanged | ||
let pendingMatchesChanged | ||
if (!matchesByIdChanged) { | ||
matchesChanged = | ||
prev.matchIds.length !== this.state.matchIds.length || | ||
prev.matchIds.some((d, i) => d !== this.state.matchIds[i]) | ||
pendingMatchesChanged = | ||
prev.pendingMatchIds.length !== | ||
this.state.pendingMatchIds.length || | ||
prev.pendingMatchIds.some( | ||
(d, i) => d !== this.state.pendingMatchIds[i], | ||
) | ||
} | ||
if (matchesByIdChanged || matchesChanged) { | ||
this.state.matches = this.state.matchIds.map((id) => { | ||
return this.state.matchesById[id] as any | ||
}) | ||
} | ||
if (matchesByIdChanged || pendingMatchesChanged) { | ||
this.state.pendingMatches = this.state.pendingMatchIds.map((id) => { | ||
return this.state.matchesById[id] as any | ||
}) | ||
} | ||
this.state.isFetching = [ | ||
...this.state.matches, | ||
...this.state.pendingMatches, | ||
].some((d) => d.isFetching) | ||
}, | ||
@@ -308,2 +353,3 @@ defaultPriority: 'low', | ||
) | ||
this.state = this.__store.state | ||
@@ -412,3 +458,3 @@ | ||
latestLoadPromise: Promise<void> | null = null | ||
latestLoadPromise: Promise<void> = Promise.resolve() | ||
@@ -425,6 +471,4 @@ load = async (opts?: { next?: ParsedLocation; throwOnError?: boolean }) => { | ||
let now = Date.now() | ||
// Cancel any pending matches | ||
this.cancelMatches() | ||
// this.cancelMatches() | ||
@@ -448,2 +492,3 @@ let pendingMatches!: RouteMatch<any, any>[] | ||
throwOnError: opts?.throwOnError, | ||
debug: true, | ||
}, | ||
@@ -455,3 +500,4 @@ ) | ||
status: 'pending', | ||
pendingMatches, | ||
pendingMatchIds: pendingMatches.map((d) => d.id), | ||
matchesById: this.#mergeMatches(s.matchesById, pendingMatches), | ||
})) | ||
@@ -475,4 +521,4 @@ }) | ||
resolvedLocation: s.location, | ||
matches: s.pendingMatches, | ||
pendingMatches: [], | ||
matchIds: s.pendingMatchIds, | ||
pendingMatchIds: [], | ||
})) | ||
@@ -500,2 +546,32 @@ | ||
#mergeMatches = ( | ||
prevMatchesById: Record< | ||
string, | ||
RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']> | ||
>, | ||
nextMatches: RouteMatch[], | ||
): Record< | ||
string, | ||
RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']> | ||
> => { | ||
const nextMatchesById: any = { | ||
...prevMatchesById, | ||
} | ||
let hadNew = false | ||
nextMatches.forEach((match) => { | ||
if (!nextMatchesById[match.id]) { | ||
hadNew = true | ||
nextMatchesById[match.id] = match | ||
} | ||
}) | ||
if (!hadNew) { | ||
return prevMatchesById | ||
} | ||
return nextMatchesById | ||
} | ||
getRoute = <TId extends keyof TRoutesInfo['routesById']>( | ||
@@ -512,3 +588,5 @@ id: TId, | ||
preloadRoute = async ( | ||
navigateOpts: BuildNextOptions = this.state.location, | ||
navigateOpts: BuildNextOptions & { | ||
maxAge?: number | ||
} = this.state.location, | ||
) => { | ||
@@ -520,17 +598,6 @@ const next = this.buildNext(navigateOpts) | ||
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, | ||
}, | ||
matchesById: this.#mergeMatches(s.matchesById, matches), | ||
} | ||
@@ -541,10 +608,43 @@ }) | ||
preload: true, | ||
maxAge: navigateOpts.maxAge, | ||
}) | ||
return matches | ||
} | ||
cleanMatches = () => { | ||
const now = Date.now() | ||
const outdatedMatchIds = Object.values(this.state.matchesById) | ||
.filter((match) => { | ||
const route = this.getRoute(match.routeId) | ||
return ( | ||
!this.state.matchIds.includes(match.id) && | ||
!this.state.pendingMatchIds.includes(match.id) && | ||
match.preloadInvalidAt < now && | ||
(route.options.gcMaxAge | ||
? match.updatedAt + route.options.gcMaxAge < now | ||
: true) | ||
) | ||
}) | ||
.map((d) => d.id) | ||
if (outdatedMatchIds.length) { | ||
this.__store.setState((s) => { | ||
const matchesById = { ...s.matchesById } | ||
outdatedMatchIds.forEach((id) => { | ||
delete matchesById[id] | ||
}) | ||
return { | ||
...s, | ||
matchesById, | ||
} | ||
}) | ||
} | ||
} | ||
matchRoutes = ( | ||
pathname: string, | ||
locationSearch: AnySearchSchema, | ||
opts?: { throwOnError?: boolean }, | ||
opts?: { throwOnError?: boolean; debug?: boolean }, | ||
): RouteMatch<TRoutesInfo, TRoutesInfo['routeIntersection']>[] => { | ||
@@ -591,3 +691,8 @@ let routeParams: AnyPathParams = {} | ||
try { | ||
parsedParams = route.options.parseParams?.(routeParams!) ?? routeParams | ||
parsedParams = | ||
(route.options.parseParams as any)?.(routeParams!) ?? routeParams | ||
// (typeof route.options.parseParams === 'object' && | ||
// route.options.parseParams.parse | ||
// ? route.options.parseParams.parse(routeParams) | ||
// : (route.options.parseParams as any)?.(routeParams!)) ?? routeParams | ||
} catch (err: any) { | ||
@@ -607,8 +712,13 @@ parsedParamsError = new PathParamError(err.message, { | ||
const interpolatedPath = interpolatePath(route.path, allParams) | ||
const key = route.options.key | ||
? route.options.key({ | ||
params: allParams, | ||
search: locationSearch, | ||
}) ?? '' | ||
: '' | ||
const stringifiedKey = key ? JSON.stringify(key) : '' | ||
const matchId = | ||
interpolatePath(route.id, allParams, true) + | ||
(route.options.getKey?.({ | ||
params: allParams, | ||
search: locationSearch, | ||
}) ?? '') | ||
interpolatePath(route.id, allParams, true) + stringifiedKey | ||
@@ -621,3 +731,2 @@ // Waste not, want not. If we already have a match for this route, | ||
if (existingMatch) { | ||
// Return a copy, we don't want to mutate the existing match | ||
return { ...existingMatch } | ||
@@ -634,13 +743,18 @@ } | ||
id: matchId, | ||
key: stringifiedKey, | ||
routeId: route.id, | ||
params: allParams, | ||
pathname: joinPaths([this.basepath, interpolatedPath]), | ||
updatedAt: 0, | ||
updatedAt: Date.now(), | ||
invalidAt: Infinity, | ||
preloadInvalidAt: Infinity, | ||
routeSearch: {}, | ||
search: {} as any, | ||
status: hasLoaders ? 'pending' : 'success', | ||
status: hasLoaders ? 'idle' : 'success', | ||
isFetching: false, | ||
invalid: false, | ||
error: undefined, | ||
paramsError: parsedParamsError, | ||
searchError: undefined, | ||
loader: undefined, | ||
loaderData: undefined, | ||
loadPromise: Promise.resolve(), | ||
@@ -731,3 +845,3 @@ routeContext: undefined!, | ||
return matches | ||
return matches as any | ||
} | ||
@@ -739,4 +853,7 @@ | ||
preload?: boolean | ||
maxAge?: number | ||
}, | ||
) => { | ||
this.cleanMatches() | ||
let firstBadMatchIndex: number | undefined | ||
@@ -750,2 +867,17 @@ | ||
if (!opts?.preload) { | ||
// Update each match with its latest url data | ||
this.setRouteMatch(match.id, (s) => ({ | ||
...s, | ||
routeSearch: match.routeSearch, | ||
search: match.search, | ||
routeContext: match.routeContext, | ||
context: match.context, | ||
error: match.error, | ||
paramsError: match.paramsError, | ||
searchError: match.searchError, | ||
params: match.params, | ||
})) | ||
} | ||
const handleError = ( | ||
@@ -811,14 +943,23 @@ err: any, | ||
matchPromises.push( | ||
Promise.resolve().then(async () => { | ||
(async () => { | ||
const parentMatchPromise = matchPromises[index - 1] | ||
const route = this.getRoute(match.routeId) | ||
if ( | ||
match.isFetching || | ||
(match.status === 'success' && | ||
!this.getIsInvalid({ matchId: match.id, preload: opts?.preload })) | ||
) { | ||
return this.getRouteMatch(match.id)?.loadPromise | ||
} | ||
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 | ||
} | ||
const checkLatest = () => { | ||
const latest = this.getRouteMatch(match.id) | ||
return latest && latest.fetchedAt !== fetchedAt | ||
? latest.loadPromise | ||
: undefined | ||
} | ||
const loadPromise = (async () => { | ||
let latestPromise | ||
@@ -836,13 +977,19 @@ | ||
const loaderPromise = Promise.resolve().then(() => { | ||
if (route.options.loader) { | ||
return route.options.loader({ | ||
...match, | ||
preload: !!opts?.preload, | ||
parentMatchPromise, | ||
}) | ||
} | ||
return | ||
const loaderPromise = route.options.loader?.({ | ||
...match, | ||
preload: !!opts?.preload, | ||
parentMatchPromise, | ||
}) | ||
const handleError = (err: any) => { | ||
if (isRedirect(err)) { | ||
if (!opts?.preload) { | ||
this.navigate(err as any) | ||
} | ||
return true | ||
} | ||
return false | ||
} | ||
try { | ||
@@ -855,21 +1002,7 @@ const [_, loader] = await Promise.all([ | ||
if ( | ||
!opts?.preload || | ||
!this.state.matches.find((d) => d.id === match.id) | ||
) { | ||
this.setRouteMatch(match.id, (s) => ({ | ||
...s, | ||
error: undefined, | ||
status: 'success', | ||
updatedAt: Date.now(), | ||
loader, | ||
})) | ||
} | ||
this.setRouteMatchData(match.id, () => loader, opts) | ||
} catch (err) { | ||
if ((latestPromise = checkLatest())) return await latestPromise | ||
if (isRedirect(err)) { | ||
if (!opts?.preload) { | ||
this.navigate(err as any) | ||
} | ||
if (handleError(err)) { | ||
return | ||
@@ -887,6 +1020,4 @@ } | ||
caughtError = errorHandlerErr | ||
if (isRedirect(errorHandlerErr)) { | ||
if (!opts?.preload) { | ||
this.navigate(errorHandlerErr as any) | ||
} | ||
if (handleError(errorHandlerErr)) { | ||
return | ||
@@ -900,27 +1031,19 @@ } | ||
status: 'error', | ||
isFetching: false, | ||
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.setRouteMatch(match.id, (s) => ({ | ||
...s, | ||
status: s.status !== 'success' ? 'pending' : s.status, | ||
isFetching: true, | ||
loadPromise, | ||
fetchedAt, | ||
invalid: false, | ||
})) | ||
await loadPromise | ||
}), | ||
})(), | ||
) | ||
@@ -933,3 +1056,3 @@ }) | ||
reload = () => { | ||
this.navigate({ | ||
return this.navigate({ | ||
fromCurrent: true, | ||
@@ -1188,3 +1311,2 @@ replace: true, | ||
...ctx.router.state, | ||
matches: s.matches, | ||
resolvedLocation: ctx.router.state.location, | ||
@@ -1504,10 +1626,6 @@ } | ||
): undefined | RouteMatch<TRoutesInfo, AnyRoute> => { | ||
return ( | ||
this.state.matches.find((d) => d.id === id) || | ||
this.state.pendingMatches.find((d) => d.id === id) || | ||
this.state.preloadMatches[id] | ||
) | ||
return this.state.matchesById[id] | ||
} | ||
#setResolvedRouteMatch = ( | ||
setRouteMatch = ( | ||
id: string, | ||
@@ -1520,63 +1638,106 @@ updater: ( | ||
...prev, | ||
matches: prev.matches.map((d) => { | ||
if (d.id === id) { | ||
return updater(d as any) | ||
} | ||
return d | ||
}), | ||
matchesById: { | ||
...prev.matchesById, | ||
[id]: updater(prev.matchesById[id] as any), | ||
}, | ||
})) | ||
} | ||
#setPendingRouteMatch = ( | ||
setRouteMatchData = ( | ||
id: string, | ||
updater: ( | ||
prev: RouteMatch<TRoutesInfo, AnyRoute>, | ||
) => RouteMatch<TRoutesInfo, AnyRoute>, | ||
updater: (prev: any) => any, | ||
opts?: { | ||
updatedAt?: number | ||
maxAge?: number | ||
}, | ||
) => { | ||
this.__store.setState((prev) => ({ | ||
...prev, | ||
pendingMatches: prev.pendingMatches.map((d) => { | ||
if (d.id === id) { | ||
return updater(d as any) | ||
} | ||
return d | ||
}), | ||
})) | ||
} | ||
const match = this.getRouteMatch(id) | ||
#setPreloadRouteMatch = ( | ||
id: string, | ||
updater: ( | ||
prev: RouteMatch<TRoutesInfo, AnyRoute>, | ||
) => RouteMatch<TRoutesInfo, AnyRoute>, | ||
) => { | ||
invariant(this.state.preloadMatches[id], 'Match not found') | ||
if (!match) return | ||
this.__store.setState((prev) => ({ | ||
...prev, | ||
preloadMatches: { | ||
...prev.preloadMatches, | ||
[id]: updater(prev.preloadMatches[id] as any), | ||
}, | ||
const route = this.getRoute(match.routeId) | ||
const updatedAt = opts?.updatedAt ?? Date.now() | ||
const preloadInvalidAt = | ||
updatedAt + | ||
(opts?.maxAge ?? | ||
route.options.preloadMaxAge ?? | ||
this.options.defaultPreloadMaxAge ?? | ||
5000) | ||
const invalidAt = | ||
updatedAt + | ||
(opts?.maxAge ?? | ||
route.options.maxAge ?? | ||
this.options.defaultMaxAge ?? | ||
Infinity) | ||
this.setRouteMatch(id, (s) => ({ | ||
...s, | ||
error: undefined, | ||
status: 'success', | ||
isFetching: false, | ||
updatedAt: Date.now(), | ||
loaderData: functionalUpdate(updater, s.loaderData), | ||
preloadInvalidAt, | ||
invalidAt, | ||
})) | ||
} | ||
setRouteMatch = ( | ||
id: string, | ||
updater: ( | ||
prev: RouteMatch<TRoutesInfo, AnyRoute>, | ||
) => RouteMatch<TRoutesInfo, AnyRoute>, | ||
) => { | ||
if (this.state.matches.find((d) => d.id === id)) { | ||
return this.#setResolvedRouteMatch(id, updater) | ||
} | ||
} | ||
if (this.state.pendingMatches.find((d) => d.id === id)) { | ||
return this.#setPendingRouteMatch(id, updater) | ||
invalidate = async (opts?: { | ||
matchId?: string | ||
reload?: boolean | ||
}): Promise<void> => { | ||
if (opts?.matchId) { | ||
this.setRouteMatch(opts.matchId, (s) => ({ | ||
...s, | ||
invalid: true, | ||
})) | ||
const matchIndex = this.state.matches.findIndex( | ||
(d) => d.id === opts.matchId, | ||
) | ||
const childMatch = this.state.matches[matchIndex + 1] | ||
if (childMatch) { | ||
return this.invalidate({ matchId: childMatch.id, reload: false }) | ||
} | ||
} else { | ||
this.__store.batch(() => { | ||
Object.values(this.state.matchesById).forEach((match) => { | ||
this.setRouteMatch(match.id, (s) => ({ | ||
...s, | ||
invalid: true, | ||
})) | ||
}) | ||
}) | ||
} | ||
if (this.state.preloadMatches[id]) { | ||
return this.#setPreloadRouteMatch(id, updater) | ||
if (opts?.reload ?? true) { | ||
return this.reload() | ||
} | ||
} | ||
getIsInvalid = (opts?: { matchId: string; preload?: boolean }): boolean => { | ||
if (!opts?.matchId) { | ||
return !!this.state.matches.find((d) => | ||
this.getIsInvalid({ matchId: d.id, preload: opts?.preload }), | ||
) | ||
} | ||
const match = this.getRouteMatch(opts?.matchId) | ||
if (!match) { | ||
return false | ||
} | ||
const now = Date.now() | ||
return ( | ||
match.invalid || | ||
(opts?.preload ? match.preloadInvalidAt : match.invalidAt) < now | ||
) | ||
} | ||
} | ||
@@ -1590,7 +1751,10 @@ | ||
status: 'idle', | ||
isFetching: false, | ||
resolvedLocation: null!, | ||
location: null!, | ||
matchesById: {}, | ||
matchIds: [], | ||
pendingMatchIds: [], | ||
matches: [], | ||
pendingMatches: [], | ||
preloadMatches: {}, | ||
lastUpdated: Date.now(), | ||
@@ -1597,0 +1761,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is 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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1439590
13320