@tanstack/router-core 1.153.1 → 1.153.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/location.d.cts +27 -0
- package/dist/cjs/router.cjs +211 -80
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +32 -5
- package/dist/cjs/scroll-restoration.cjs +2 -2
- package/dist/cjs/scroll-restoration.cjs.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/location.d.ts +27 -0
- package/dist/esm/router.d.ts +32 -5
- package/dist/esm/router.js +211 -80
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/scroll-restoration.js +2 -2
- package/dist/esm/scroll-restoration.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +5 -1
- package/src/location.ts +35 -0
- package/src/router.ts +330 -92
- package/src/scroll-restoration.ts +2 -2
package/dist/cjs/index.d.cts
CHANGED
|
@@ -6,7 +6,7 @@ export type { IsRequiredParams, AddTrailingSlash, RemoveTrailingSlashes, AddLead
|
|
|
6
6
|
export { componentTypes } from './load-matches.cjs';
|
|
7
7
|
export type { RouteToPath, TrailingSlashOptionByRouter, ParseRoute, CodeRouteToPath, RouteIds, FullSearchSchema, FullSearchSchemaInput, AllParams, RouteById, AllContext, RoutePaths, RoutesById, RoutesByPath, AllLoaderData, RouteByPath, } from './routeInfo.cjs';
|
|
8
8
|
export type { InferFileRouteTypes, FileRouteTypes, FileRoutesByPath, CreateFileRoute, LazyRoute, LazyRouteOptions, CreateLazyFileRoute, } from './fileRoute.cjs';
|
|
9
|
-
export type { ParsedLocation } from './location.cjs';
|
|
9
|
+
export type { MatchSnapshot, ParsedLocation, ValidatedSearchEntry, } from './location.cjs';
|
|
10
10
|
export type { Manifest, RouterManagedTag } from './manifest.cjs';
|
|
11
11
|
export { isMatch } from './Matches.cjs';
|
|
12
12
|
export type { AnyMatchAndValue, FindValueByIndex, FindValueByKey, CreateMatchAndValue, NextMatchAndValue, IsMatchKeyOf, IsMatchPath, IsMatchResult, IsMatchParse, IsMatch, RouteMatch, RouteMatchExtensions, MakeRouteMatchUnion, MakeRouteMatch, AnyRouteMatch, MakeRouteMatchFromRoute, MatchRouteOptions, } from './Matches.cjs';
|
package/dist/cjs/location.d.cts
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
import { ParsedHistoryState } from '@tanstack/history';
|
|
2
2
|
import { AnySchema } from './validators.cjs';
|
|
3
|
+
/**
|
|
4
|
+
* Per-route validated search result cached in snapshot.
|
|
5
|
+
*/
|
|
6
|
+
export interface ValidatedSearchEntry {
|
|
7
|
+
/** Merged search (parent + this route's validated) */
|
|
8
|
+
search: Record<string, unknown>;
|
|
9
|
+
/** Strict search (only this route's validated fields) */
|
|
10
|
+
strictSearch: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Match snapshot stored in history state for fast-path on back/forward navigation.
|
|
14
|
+
* Allows skipping path matching by storing route IDs and params.
|
|
15
|
+
*/
|
|
16
|
+
export interface MatchSnapshot {
|
|
17
|
+
/** Ordered route IDs that matched */
|
|
18
|
+
routeIds: Array<string>;
|
|
19
|
+
/** Raw path params extracted from the URL */
|
|
20
|
+
params: Record<string, string>;
|
|
21
|
+
/** Parsed/validated path params */
|
|
22
|
+
parsedParams: Record<string, unknown>;
|
|
23
|
+
/** Route ID that should show global not found, if any */
|
|
24
|
+
globalNotFoundRouteId?: string;
|
|
25
|
+
/** Search string when snapshot was created (for cache invalidation) */
|
|
26
|
+
searchStr?: string;
|
|
27
|
+
/** Per-route validated search results (parallel to routeIds) */
|
|
28
|
+
validatedSearches?: Array<ValidatedSearchEntry>;
|
|
29
|
+
}
|
|
3
30
|
export interface ParsedLocation<TSearchObj extends AnySchema = {}> {
|
|
4
31
|
/**
|
|
5
32
|
* The full path of the location, including pathname, search, and hash.
|
package/dist/cjs/router.cjs
CHANGED
|
@@ -49,7 +49,6 @@ class RouterCore {
|
|
|
49
49
|
this.tempLocationKey = `${Math.round(
|
|
50
50
|
Math.random() * 1e7
|
|
51
51
|
)}`;
|
|
52
|
-
this.resetNextScroll = true;
|
|
53
52
|
this.shouldViewTransition = void 0;
|
|
54
53
|
this.isViewTransitionTypesSupported = void 0;
|
|
55
54
|
this.subscribers = /* @__PURE__ */ new Set();
|
|
@@ -317,9 +316,13 @@ class RouterCore {
|
|
|
317
316
|
path: nextTo,
|
|
318
317
|
params: nextParams
|
|
319
318
|
}).interpolatedPath;
|
|
320
|
-
const
|
|
319
|
+
const destMatches = this.matchRoutes(interpolatedNextTo, void 0, {
|
|
321
320
|
_buildLocation: true
|
|
322
|
-
})
|
|
321
|
+
});
|
|
322
|
+
const destRoutes = destMatches.map(
|
|
323
|
+
(d) => this.looseRoutesById[d.routeId]
|
|
324
|
+
);
|
|
325
|
+
const globalNotFoundMatch = destMatches.find((m) => m.globalNotFound);
|
|
323
326
|
if (Object.keys(nextParams).length > 0) {
|
|
324
327
|
for (const route of destRoutes) {
|
|
325
328
|
const fn = route.options.params?.stringify ?? route.options.stringifyParams;
|
|
@@ -370,19 +373,27 @@ class RouterCore {
|
|
|
370
373
|
const hashStr = hash ? `#${hash}` : "";
|
|
371
374
|
let nextState = dest.state === true ? currentLocation.state : dest.state ? utils.functionalUpdate(dest.state, currentLocation.state) : {};
|
|
372
375
|
nextState = utils.replaceEqualDeep(currentLocation.state, nextState);
|
|
376
|
+
const matchSnapshot = buildMatchSnapshotFromRoutes({
|
|
377
|
+
routes: destRoutes,
|
|
378
|
+
params: nextParams,
|
|
379
|
+
searchStr,
|
|
380
|
+
globalNotFoundRouteId: globalNotFoundMatch?.routeId
|
|
381
|
+
});
|
|
373
382
|
const fullPath = `${nextPathname}${searchStr}${hashStr}`;
|
|
374
383
|
const url = new URL(fullPath, this.origin);
|
|
375
384
|
const rewrittenUrl = rewrite.executeRewriteOutput(this.rewrite, url);
|
|
385
|
+
const encodedHref = url.href.replace(url.origin, "");
|
|
376
386
|
return {
|
|
377
387
|
publicHref: rewrittenUrl.pathname + rewrittenUrl.search + rewrittenUrl.hash,
|
|
378
|
-
href:
|
|
388
|
+
href: encodedHref,
|
|
379
389
|
url: rewrittenUrl,
|
|
380
390
|
pathname: nextPathname,
|
|
381
391
|
search: nextSearch,
|
|
382
392
|
searchStr,
|
|
383
393
|
state: nextState,
|
|
384
394
|
hash: hash ?? "",
|
|
385
|
-
unmaskOnReload: dest.unmaskOnReload
|
|
395
|
+
unmaskOnReload: dest.unmaskOnReload,
|
|
396
|
+
_matchSnapshot: matchSnapshot
|
|
386
397
|
};
|
|
387
398
|
};
|
|
388
399
|
const buildWithMatches = (dest = {}, maskedDest) => {
|
|
@@ -425,7 +436,7 @@ class RouterCore {
|
|
|
425
436
|
}
|
|
426
437
|
return buildWithMatches(opts);
|
|
427
438
|
};
|
|
428
|
-
this.commitLocation = ({
|
|
439
|
+
this.commitLocation = async ({
|
|
429
440
|
viewTransition,
|
|
430
441
|
ignoreBlocker,
|
|
431
442
|
...next
|
|
@@ -454,53 +465,73 @@ class RouterCore {
|
|
|
454
465
|
});
|
|
455
466
|
if (isSameUrl && isSameState()) {
|
|
456
467
|
this.load();
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
468
|
+
return this.commitLocationPromise;
|
|
469
|
+
}
|
|
470
|
+
let {
|
|
471
|
+
// eslint-disable-next-line prefer-const
|
|
472
|
+
maskedLocation,
|
|
473
|
+
// eslint-disable-next-line prefer-const
|
|
474
|
+
hashScrollIntoView,
|
|
475
|
+
// don't pass url into history since it is a URL instance that cannot be serialized
|
|
476
|
+
// eslint-disable-next-line prefer-const
|
|
477
|
+
url: _url,
|
|
478
|
+
...nextHistory
|
|
479
|
+
} = next;
|
|
480
|
+
if (maskedLocation) {
|
|
481
|
+
nextHistory = {
|
|
482
|
+
...maskedLocation,
|
|
483
|
+
state: {
|
|
484
|
+
...maskedLocation.state,
|
|
485
|
+
__tempKey: void 0,
|
|
486
|
+
__tempLocation: {
|
|
487
|
+
...nextHistory,
|
|
488
|
+
search: nextHistory.searchStr,
|
|
489
|
+
state: {
|
|
490
|
+
...nextHistory.state,
|
|
491
|
+
__tempKey: void 0,
|
|
492
|
+
__tempLocation: void 0,
|
|
493
|
+
__TSR_key: void 0,
|
|
494
|
+
key: void 0
|
|
495
|
+
// TODO: Remove in v2 - use __TSR_key instead
|
|
485
496
|
}
|
|
486
497
|
}
|
|
487
|
-
};
|
|
488
|
-
if (nextHistory.unmaskOnReload ?? this.options.unmaskOnReload ?? false) {
|
|
489
|
-
nextHistory.state.__tempKey = this.tempLocationKey;
|
|
490
498
|
}
|
|
499
|
+
};
|
|
500
|
+
if (nextHistory.unmaskOnReload ?? this.options.unmaskOnReload ?? false) {
|
|
501
|
+
nextHistory.state.__tempKey = this.tempLocationKey;
|
|
491
502
|
}
|
|
492
|
-
nextHistory.state.__hashScrollIntoViewOptions = hashScrollIntoView ?? this.options.defaultHashScrollIntoView ?? true;
|
|
493
|
-
this.shouldViewTransition = viewTransition;
|
|
494
|
-
this.history[next.replace ? "replace" : "push"](
|
|
495
|
-
nextHistory.publicHref,
|
|
496
|
-
nextHistory.state,
|
|
497
|
-
{ ignoreBlocker }
|
|
498
|
-
);
|
|
499
503
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
504
|
+
nextHistory.state.__hashScrollIntoViewOptions = hashScrollIntoView ?? this.options.defaultHashScrollIntoView ?? true;
|
|
505
|
+
nextHistory.state.__TSR_resetScroll = next.resetScroll ?? true;
|
|
506
|
+
this.shouldViewTransition = viewTransition;
|
|
507
|
+
nextHistory.state.__TSR_sessionId = this.sessionId;
|
|
508
|
+
nextHistory.state.__TSR_matches = next._matchSnapshot ?? buildMatchSnapshot({
|
|
509
|
+
matchResult: this.getMatchedRoutes(next.pathname),
|
|
510
|
+
pathname: next.pathname,
|
|
511
|
+
searchStr: next.searchStr,
|
|
512
|
+
notFoundRoute: this.options.notFoundRoute,
|
|
513
|
+
notFoundMode: this.options.notFoundMode
|
|
514
|
+
});
|
|
515
|
+
const precomputedLocation = {
|
|
516
|
+
...next,
|
|
517
|
+
publicHref: nextHistory.publicHref,
|
|
518
|
+
state: nextHistory.state,
|
|
519
|
+
maskedLocation
|
|
520
|
+
};
|
|
521
|
+
const result = await this.history[next.replace ? "replace" : "push"](
|
|
522
|
+
nextHistory.publicHref,
|
|
523
|
+
nextHistory.state,
|
|
524
|
+
{ ignoreBlocker, skipTransitionerLoad: true }
|
|
525
|
+
);
|
|
526
|
+
if (result.type === "BLOCKED") {
|
|
527
|
+
this.commitLocationPromise?.resolve();
|
|
528
|
+
return this.commitLocationPromise;
|
|
529
|
+
}
|
|
530
|
+
if (this.history.location.href !== nextHistory.publicHref) {
|
|
531
|
+
return this.commitLocationPromise;
|
|
503
532
|
}
|
|
533
|
+
this.latestLocation = precomputedLocation;
|
|
534
|
+
this.load({ _skipUpdateLatestLocation: true });
|
|
504
535
|
return this.commitLocationPromise;
|
|
505
536
|
};
|
|
506
537
|
this.buildAndCommitLocation = ({
|
|
@@ -607,9 +638,11 @@ class RouterCore {
|
|
|
607
638
|
_isNavigate: true
|
|
608
639
|
});
|
|
609
640
|
};
|
|
610
|
-
this.beforeLoad = () => {
|
|
641
|
+
this.beforeLoad = (opts) => {
|
|
611
642
|
this.cancelMatches();
|
|
612
|
-
|
|
643
|
+
if (!opts?._skipUpdateLatestLocation) {
|
|
644
|
+
this.updateLatestLocation();
|
|
645
|
+
}
|
|
613
646
|
if (this.isServer) {
|
|
614
647
|
const nextLocation = this.buildLocation({
|
|
615
648
|
to: this.latestLocation.pathname,
|
|
@@ -624,7 +657,8 @@ class RouterCore {
|
|
|
624
657
|
throw redirect.redirect({ href });
|
|
625
658
|
}
|
|
626
659
|
}
|
|
627
|
-
const
|
|
660
|
+
const snapshot = this.latestLocation.state.__TSR_sessionId === this.sessionId ? this.latestLocation.state.__TSR_matches : void 0;
|
|
661
|
+
const pendingMatches = this.matchRoutes(this.latestLocation, { snapshot });
|
|
628
662
|
this.__store.setState((s) => ({
|
|
629
663
|
...s,
|
|
630
664
|
status: "pending",
|
|
@@ -645,7 +679,9 @@ class RouterCore {
|
|
|
645
679
|
loadPromise = new Promise((resolve) => {
|
|
646
680
|
this.startTransition(async () => {
|
|
647
681
|
try {
|
|
648
|
-
this.beforeLoad(
|
|
682
|
+
this.beforeLoad({
|
|
683
|
+
_skipUpdateLatestLocation: opts?._skipUpdateLatestLocation
|
|
684
|
+
});
|
|
649
685
|
const next = this.latestLocation;
|
|
650
686
|
const prevLocation = this.state.resolvedLocation;
|
|
651
687
|
if (!this.state.redirect) {
|
|
@@ -1002,6 +1038,7 @@ class RouterCore {
|
|
|
1002
1038
|
(d) => d.status === "notFound" || d.globalNotFound
|
|
1003
1039
|
);
|
|
1004
1040
|
};
|
|
1041
|
+
this.sessionId = typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
1005
1042
|
this.update({
|
|
1006
1043
|
defaultPreloadDelay: 50,
|
|
1007
1044
|
defaultPendingMs: 1e3,
|
|
@@ -1030,46 +1067,67 @@ class RouterCore {
|
|
|
1030
1067
|
return this.routesById;
|
|
1031
1068
|
}
|
|
1032
1069
|
matchRoutesInternal(next, opts) {
|
|
1033
|
-
const
|
|
1034
|
-
const
|
|
1035
|
-
let
|
|
1036
|
-
let
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
if (
|
|
1052
|
-
|
|
1070
|
+
const snapshot = opts?.snapshot;
|
|
1071
|
+
const snapshotValid = snapshot && snapshot.routeIds.length > 0 && snapshot.routeIds.every((id) => this.routesById[id]);
|
|
1072
|
+
let matchedRoutes;
|
|
1073
|
+
let routeParams;
|
|
1074
|
+
let globalNotFoundRouteId;
|
|
1075
|
+
let parsedParams;
|
|
1076
|
+
if (snapshotValid) {
|
|
1077
|
+
matchedRoutes = snapshot.routeIds.map((id) => this.routesById[id]);
|
|
1078
|
+
routeParams = { ...snapshot.params };
|
|
1079
|
+
globalNotFoundRouteId = snapshot.globalNotFoundRouteId;
|
|
1080
|
+
parsedParams = snapshot.parsedParams;
|
|
1081
|
+
} else {
|
|
1082
|
+
const matchedRoutesResult = this.getMatchedRoutes(next.pathname);
|
|
1083
|
+
const { foundRoute, routeParams: rp } = matchedRoutesResult;
|
|
1084
|
+
routeParams = rp;
|
|
1085
|
+
matchedRoutes = matchedRoutesResult.matchedRoutes;
|
|
1086
|
+
parsedParams = matchedRoutesResult.parsedParams;
|
|
1087
|
+
let isGlobalNotFound = false;
|
|
1088
|
+
if (
|
|
1089
|
+
// If we found a route, and it's not an index route and we have left over path
|
|
1090
|
+
foundRoute ? foundRoute.path !== "/" && routeParams["**"] : (
|
|
1091
|
+
// Or if we didn't find a route and we have left over path
|
|
1092
|
+
path.trimPathRight(next.pathname)
|
|
1093
|
+
)
|
|
1094
|
+
) {
|
|
1095
|
+
if (this.options.notFoundRoute) {
|
|
1096
|
+
matchedRoutes = [...matchedRoutes, this.options.notFoundRoute];
|
|
1097
|
+
} else {
|
|
1098
|
+
isGlobalNotFound = true;
|
|
1099
|
+
}
|
|
1053
1100
|
}
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1101
|
+
globalNotFoundRouteId = (() => {
|
|
1102
|
+
if (!isGlobalNotFound) {
|
|
1103
|
+
return void 0;
|
|
1104
|
+
}
|
|
1105
|
+
if (this.options.notFoundMode !== "root") {
|
|
1106
|
+
for (let i = matchedRoutes.length - 1; i >= 0; i--) {
|
|
1107
|
+
const route = matchedRoutes[i];
|
|
1108
|
+
if (route.children) {
|
|
1109
|
+
return route.id;
|
|
1110
|
+
}
|
|
1059
1111
|
}
|
|
1060
1112
|
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
}
|
|
1113
|
+
return root.rootRouteId;
|
|
1114
|
+
})();
|
|
1115
|
+
}
|
|
1064
1116
|
const matches = [];
|
|
1065
1117
|
const getParentContext = (parentMatch) => {
|
|
1066
1118
|
const parentMatchId = parentMatch?.id;
|
|
1067
1119
|
const parentContext = !parentMatchId ? this.options.context ?? void 0 : parentMatch.context ?? this.options.context ?? void 0;
|
|
1068
1120
|
return parentContext;
|
|
1069
1121
|
};
|
|
1122
|
+
const canUseCachedSearch = snapshotValid && snapshot.searchStr === next.searchStr && snapshot.validatedSearches?.length === matchedRoutes.length;
|
|
1123
|
+
const validatedSearchesToCache = [];
|
|
1070
1124
|
matchedRoutes.forEach((route, index) => {
|
|
1071
1125
|
const parentMatch = matches[index - 1];
|
|
1072
1126
|
const [preMatchSearch, strictMatchSearch, searchError] = (() => {
|
|
1127
|
+
if (canUseCachedSearch) {
|
|
1128
|
+
const cached = snapshot.validatedSearches[index];
|
|
1129
|
+
return [cached.search, cached.strictSearch, void 0];
|
|
1130
|
+
}
|
|
1073
1131
|
const parentSearch = parentMatch?.search ?? next.search;
|
|
1074
1132
|
const parentStrictSearch = parentMatch?._strictSearch ?? void 0;
|
|
1075
1133
|
try {
|
|
@@ -1095,6 +1153,12 @@ class RouterCore {
|
|
|
1095
1153
|
return [parentSearch, {}, searchParamError];
|
|
1096
1154
|
}
|
|
1097
1155
|
})();
|
|
1156
|
+
if (!canUseCachedSearch) {
|
|
1157
|
+
validatedSearchesToCache.push({
|
|
1158
|
+
search: preMatchSearch,
|
|
1159
|
+
strictSearch: strictMatchSearch
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1098
1162
|
const loaderDeps = route.options.loaderDeps?.({
|
|
1099
1163
|
search: preMatchSearch
|
|
1100
1164
|
}) ?? "";
|
|
@@ -1208,6 +1272,13 @@ class RouterCore {
|
|
|
1208
1272
|
};
|
|
1209
1273
|
matches.push(match);
|
|
1210
1274
|
});
|
|
1275
|
+
if (!canUseCachedSearch && validatedSearchesToCache.length > 0) {
|
|
1276
|
+
const existingSnapshot = next.state?.__TSR_matches;
|
|
1277
|
+
if (existingSnapshot) {
|
|
1278
|
+
existingSnapshot.searchStr = next.searchStr;
|
|
1279
|
+
existingSnapshot.validatedSearches = validatedSearchesToCache;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1211
1282
|
matches.forEach((match, index) => {
|
|
1212
1283
|
const route = this.looseRoutesById[match.routeId];
|
|
1213
1284
|
const existingMatch = this.getMatch(match.id);
|
|
@@ -1295,7 +1366,7 @@ function getMatchedRoutes({
|
|
|
1295
1366
|
const routeParams = {};
|
|
1296
1367
|
const trimmedPath = path.trimPathRight(pathname);
|
|
1297
1368
|
let foundRoute = void 0;
|
|
1298
|
-
let parsedParams =
|
|
1369
|
+
let parsedParams = {};
|
|
1299
1370
|
const match = newProcessRouteTree.findRouteMatch(trimmedPath, processedTree, true);
|
|
1300
1371
|
if (match) {
|
|
1301
1372
|
foundRoute = match.route;
|
|
@@ -1305,6 +1376,64 @@ function getMatchedRoutes({
|
|
|
1305
1376
|
const matchedRoutes = match?.branch || [routesById[root.rootRouteId]];
|
|
1306
1377
|
return { matchedRoutes, routeParams, foundRoute, parsedParams };
|
|
1307
1378
|
}
|
|
1379
|
+
function buildMatchSnapshot({
|
|
1380
|
+
matchResult,
|
|
1381
|
+
pathname,
|
|
1382
|
+
searchStr,
|
|
1383
|
+
notFoundRoute,
|
|
1384
|
+
notFoundMode
|
|
1385
|
+
}) {
|
|
1386
|
+
const snapshot = {
|
|
1387
|
+
routeIds: matchResult.matchedRoutes.map((r) => r.id),
|
|
1388
|
+
params: matchResult.routeParams,
|
|
1389
|
+
parsedParams: matchResult.parsedParams,
|
|
1390
|
+
searchStr
|
|
1391
|
+
};
|
|
1392
|
+
const isGlobalNotFound = matchResult.foundRoute ? matchResult.foundRoute.path !== "/" && matchResult.routeParams["**"] : path.trimPathRight(pathname);
|
|
1393
|
+
if (isGlobalNotFound) {
|
|
1394
|
+
if (notFoundRoute) {
|
|
1395
|
+
snapshot.globalNotFoundRouteId = notFoundRoute.id;
|
|
1396
|
+
} else {
|
|
1397
|
+
if (notFoundMode !== "root") {
|
|
1398
|
+
for (let i = matchResult.matchedRoutes.length - 1; i >= 0; i--) {
|
|
1399
|
+
const route = matchResult.matchedRoutes[i];
|
|
1400
|
+
if (route.children) {
|
|
1401
|
+
snapshot.globalNotFoundRouteId = route.id;
|
|
1402
|
+
break;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
if (!snapshot.globalNotFoundRouteId) {
|
|
1407
|
+
snapshot.globalNotFoundRouteId = root.rootRouteId;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
return snapshot;
|
|
1412
|
+
}
|
|
1413
|
+
function buildMatchSnapshotFromRoutes({
|
|
1414
|
+
routes,
|
|
1415
|
+
params,
|
|
1416
|
+
searchStr,
|
|
1417
|
+
globalNotFoundRouteId
|
|
1418
|
+
}) {
|
|
1419
|
+
const stringParams = {};
|
|
1420
|
+
for (const key in params) {
|
|
1421
|
+
const value = params[key];
|
|
1422
|
+
if (value != null) {
|
|
1423
|
+
stringParams[key] = String(value);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
const snapshot = {
|
|
1427
|
+
routeIds: routes.map((r) => r.id),
|
|
1428
|
+
params: stringParams,
|
|
1429
|
+
parsedParams: params,
|
|
1430
|
+
searchStr
|
|
1431
|
+
};
|
|
1432
|
+
if (globalNotFoundRouteId) {
|
|
1433
|
+
snapshot.globalNotFoundRouteId = globalNotFoundRouteId;
|
|
1434
|
+
}
|
|
1435
|
+
return snapshot;
|
|
1436
|
+
}
|
|
1308
1437
|
function applySearchMiddleware({
|
|
1309
1438
|
search,
|
|
1310
1439
|
dest,
|
|
@@ -1385,6 +1514,8 @@ function applySearchMiddleware({
|
|
|
1385
1514
|
exports.PathParamError = PathParamError;
|
|
1386
1515
|
exports.RouterCore = RouterCore;
|
|
1387
1516
|
exports.SearchParamError = SearchParamError;
|
|
1517
|
+
exports.buildMatchSnapshot = buildMatchSnapshot;
|
|
1518
|
+
exports.buildMatchSnapshotFromRoutes = buildMatchSnapshotFromRoutes;
|
|
1388
1519
|
exports.defaultSerializeError = defaultSerializeError;
|
|
1389
1520
|
exports.getInitialRouterState = getInitialRouterState;
|
|
1390
1521
|
exports.getLocationChangeInfo = getLocationChangeInfo;
|