@tanstack/react-router 1.48.4 → 1.49.1
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/Matches.cjs +3 -1
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +5 -4
- package/dist/cjs/fileRoute.cjs.map +1 -1
- package/dist/cjs/fileRoute.d.cts +4 -5
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +3 -1
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/link.d.cts +1 -1
- package/dist/cjs/path.cjs +6 -9
- package/dist/cjs/path.cjs.map +1 -1
- package/dist/cjs/route.cjs +1 -1
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +80 -61
- package/dist/cjs/router.cjs +90 -57
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +22 -9
- package/dist/cjs/transformer.cjs +39 -0
- package/dist/cjs/transformer.cjs.map +1 -0
- package/dist/cjs/transformer.d.cts +5 -0
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +1 -0
- package/dist/esm/Matches.d.ts +5 -4
- package/dist/esm/Matches.js +3 -1
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/fileRoute.d.ts +4 -5
- package/dist/esm/fileRoute.js.map +1 -1
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/link.d.ts +1 -1
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/path.js +6 -9
- package/dist/esm/path.js.map +1 -1
- package/dist/esm/route.d.ts +80 -61
- package/dist/esm/route.js +1 -1
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +22 -9
- package/dist/esm/router.js +91 -58
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/transformer.d.ts +5 -0
- package/dist/esm/transformer.js +39 -0
- package/dist/esm/transformer.js.map +1 -0
- package/dist/esm/utils.d.ts +1 -0
- package/dist/esm/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/Matches.tsx +11 -7
- package/src/fileRoute.ts +28 -22
- package/src/index.tsx +5 -1
- package/src/link.tsx +10 -6
- package/src/path.ts +7 -10
- package/src/route.ts +375 -190
- package/src/router.ts +144 -75
- package/src/transformer.ts +49 -0
- package/src/utils.ts +5 -0
package/dist/cjs/router.cjs
CHANGED
|
@@ -10,6 +10,7 @@ const utils = require("./utils.cjs");
|
|
|
10
10
|
const path = require("./path.cjs");
|
|
11
11
|
const redirects = require("./redirects.cjs");
|
|
12
12
|
const notFound = require("./not-found.cjs");
|
|
13
|
+
const transformer = require("./transformer.cjs");
|
|
13
14
|
const componentTypes = [
|
|
14
15
|
"component",
|
|
15
16
|
"errorComponent",
|
|
@@ -210,12 +211,12 @@ class Router {
|
|
|
210
211
|
});
|
|
211
212
|
return resolvedPath;
|
|
212
213
|
};
|
|
213
|
-
this.matchRoutes = (
|
|
214
|
+
this.matchRoutes = (next, opts) => {
|
|
214
215
|
let routeParams = {};
|
|
215
216
|
const foundRoute = this.flatRoutes.find((route) => {
|
|
216
217
|
const matchedParams = path.matchPathname(
|
|
217
218
|
this.basepath,
|
|
218
|
-
path.trimPathRight(pathname),
|
|
219
|
+
path.trimPathRight(next.pathname),
|
|
219
220
|
{
|
|
220
221
|
to: route.fullPath,
|
|
221
222
|
caseSensitive: route.options.caseSensitive ?? this.options.caseSensitive,
|
|
@@ -235,7 +236,7 @@ class Router {
|
|
|
235
236
|
// If we found a route, and it's not an index route and we have left over path
|
|
236
237
|
foundRoute ? foundRoute.path !== "/" && routeParams["**"] : (
|
|
237
238
|
// Or if we didn't find a route and we have left over path
|
|
238
|
-
path.trimPathRight(pathname)
|
|
239
|
+
path.trimPathRight(next.pathname)
|
|
239
240
|
)
|
|
240
241
|
) {
|
|
241
242
|
if (this.options.notFoundRoute) {
|
|
@@ -284,10 +285,10 @@ class Router {
|
|
|
284
285
|
});
|
|
285
286
|
const matches = [];
|
|
286
287
|
matchedRoutes.forEach((route, index) => {
|
|
287
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
288
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
288
289
|
const parentMatch = matches[index - 1];
|
|
289
290
|
const [preMatchSearch, searchError] = (() => {
|
|
290
|
-
const parentSearch = (parentMatch == null ? void 0 : parentMatch.search) ??
|
|
291
|
+
const parentSearch = (parentMatch == null ? void 0 : parentMatch.search) ?? next.search;
|
|
291
292
|
try {
|
|
292
293
|
const validator = typeof route.options.validateSearch === "object" ? route.options.validateSearch.parse : route.options.validateSearch;
|
|
293
294
|
const search = (validator == null ? void 0 : validator(parentSearch)) ?? {};
|
|
@@ -345,8 +346,9 @@ class Router {
|
|
|
345
346
|
isFetching: false,
|
|
346
347
|
error: void 0,
|
|
347
348
|
paramsError: parseErrors[index],
|
|
348
|
-
|
|
349
|
-
|
|
349
|
+
__routeContext: {},
|
|
350
|
+
__beforeLoadContext: {},
|
|
351
|
+
context: {},
|
|
350
352
|
abortController: new AbortController(),
|
|
351
353
|
fetchCount: 0,
|
|
352
354
|
cause,
|
|
@@ -375,6 +377,30 @@ class Router {
|
|
|
375
377
|
}
|
|
376
378
|
match.search = utils.replaceEqualDeep(match.search, preMatchSearch);
|
|
377
379
|
match.searchError = searchError;
|
|
380
|
+
const parentMatchId = parentMatch == null ? void 0 : parentMatch.id;
|
|
381
|
+
const parentContext = !parentMatchId ? this.options.context ?? {} : parentMatch.context ?? this.options.context ?? {};
|
|
382
|
+
match.context = {
|
|
383
|
+
...parentContext,
|
|
384
|
+
...match.__routeContext,
|
|
385
|
+
...match.__beforeLoadContext
|
|
386
|
+
};
|
|
387
|
+
const contextFnContext = {
|
|
388
|
+
search: match.search,
|
|
389
|
+
params: match.params,
|
|
390
|
+
context: match.context,
|
|
391
|
+
location: next,
|
|
392
|
+
navigate: (opts2) => this.navigate({ ...opts2, _fromLocation: next }),
|
|
393
|
+
buildLocation: this.buildLocation,
|
|
394
|
+
cause: match.cause,
|
|
395
|
+
abortController: match.abortController,
|
|
396
|
+
preload: !!match.preload
|
|
397
|
+
};
|
|
398
|
+
match.__routeContext = ((_l = (_k = route.options).context) == null ? void 0 : _l.call(_k, contextFnContext)) ?? {};
|
|
399
|
+
match.context = {
|
|
400
|
+
...parentContext,
|
|
401
|
+
...match.__routeContext,
|
|
402
|
+
...match.__beforeLoadContext
|
|
403
|
+
};
|
|
378
404
|
matches.push(match);
|
|
379
405
|
});
|
|
380
406
|
return matches;
|
|
@@ -394,10 +420,10 @@ class Router {
|
|
|
394
420
|
this.buildLocation = (opts) => {
|
|
395
421
|
const build = (dest = {}, matches) => {
|
|
396
422
|
var _a, _b, _c;
|
|
397
|
-
const fromMatches = dest._fromLocation != null ? this.matchRoutes(
|
|
398
|
-
dest._fromLocation
|
|
399
|
-
dest.fromSearch || dest._fromLocation.search
|
|
400
|
-
) : this.state.matches;
|
|
423
|
+
const fromMatches = dest._fromLocation != null ? this.matchRoutes({
|
|
424
|
+
...dest._fromLocation,
|
|
425
|
+
search: dest.fromSearch || dest._fromLocation.search
|
|
426
|
+
}) : this.state.matches;
|
|
401
427
|
const fromMatch = dest.from != null ? fromMatches.find(
|
|
402
428
|
(d) => path.matchPathname(this.basepath, path.trimPathRight(d.pathname), {
|
|
403
429
|
to: dest.from,
|
|
@@ -489,8 +515,8 @@ class Router {
|
|
|
489
515
|
maskedNext = build(maskedDest);
|
|
490
516
|
}
|
|
491
517
|
}
|
|
492
|
-
const nextMatches = this.matchRoutes(next
|
|
493
|
-
const maskedMatches = maskedNext ? this.matchRoutes(maskedNext
|
|
518
|
+
const nextMatches = this.matchRoutes(next);
|
|
519
|
+
const maskedMatches = maskedNext ? this.matchRoutes(maskedNext) : void 0;
|
|
494
520
|
const maskedFinal = maskedNext ? build(maskedDest, maskedMatches) : void 0;
|
|
495
521
|
const final = build(dest, nextMatches);
|
|
496
522
|
if (maskedFinal) {
|
|
@@ -568,6 +594,13 @@ class Router {
|
|
|
568
594
|
ignoreBlocker,
|
|
569
595
|
...rest
|
|
570
596
|
} = {}) => {
|
|
597
|
+
const href = rest.href;
|
|
598
|
+
if (href) {
|
|
599
|
+
const parsed = history.parseHref(href, {});
|
|
600
|
+
rest.to = parsed.pathname;
|
|
601
|
+
rest.search = this.options.parseSearch(parsed.search);
|
|
602
|
+
rest.hash = parsed.hash;
|
|
603
|
+
}
|
|
571
604
|
const location = this.buildLocation(rest);
|
|
572
605
|
return this.commitLocation({
|
|
573
606
|
...location,
|
|
@@ -577,7 +610,7 @@ class Router {
|
|
|
577
610
|
ignoreBlocker
|
|
578
611
|
});
|
|
579
612
|
};
|
|
580
|
-
this.navigate = ({
|
|
613
|
+
this.navigate = ({ to, __isRedirect, ...rest }) => {
|
|
581
614
|
const toString = String(to);
|
|
582
615
|
let isExternal;
|
|
583
616
|
try {
|
|
@@ -591,7 +624,6 @@ class Router {
|
|
|
591
624
|
);
|
|
592
625
|
return this.buildAndCommitLocation({
|
|
593
626
|
...rest,
|
|
594
|
-
from,
|
|
595
627
|
to
|
|
596
628
|
// to: toString,
|
|
597
629
|
});
|
|
@@ -604,7 +636,8 @@ class Router {
|
|
|
604
636
|
}));
|
|
605
637
|
let redirect;
|
|
606
638
|
let notFound$1;
|
|
607
|
-
|
|
639
|
+
let loadPromise;
|
|
640
|
+
loadPromise = new Promise((resolve) => {
|
|
608
641
|
this.startReactTransition(async () => {
|
|
609
642
|
var _a;
|
|
610
643
|
try {
|
|
@@ -614,7 +647,7 @@ class Router {
|
|
|
614
647
|
this.cancelMatches();
|
|
615
648
|
let pendingMatches;
|
|
616
649
|
this.__store.batch(() => {
|
|
617
|
-
pendingMatches = this.matchRoutes(next
|
|
650
|
+
pendingMatches = this.matchRoutes(next);
|
|
618
651
|
this.__store.setState((s) => ({
|
|
619
652
|
...s,
|
|
620
653
|
status: "pending",
|
|
@@ -834,6 +867,7 @@ class Router {
|
|
|
834
867
|
};
|
|
835
868
|
for (const [index, { id: matchId, routeId }] of matches.entries()) {
|
|
836
869
|
const existingMatch = this.getMatch(matchId);
|
|
870
|
+
const parentMatchId = (_a = matches[index - 1]) == null ? void 0 : _a.id;
|
|
837
871
|
if (
|
|
838
872
|
// If we are in the middle of a load, either of these will be present
|
|
839
873
|
// (not to be confused with `loadPromise`, which is always defined)
|
|
@@ -852,13 +886,6 @@ class Router {
|
|
|
852
886
|
}));
|
|
853
887
|
const route = this.looseRoutesById[routeId];
|
|
854
888
|
const abortController = new AbortController();
|
|
855
|
-
const parentMatchId = (_a = matches[index - 1]) == null ? void 0 : _a.id;
|
|
856
|
-
const getParentContext = () => {
|
|
857
|
-
if (!parentMatchId) {
|
|
858
|
-
return this.options.context ?? {};
|
|
859
|
-
}
|
|
860
|
-
return this.getMatch(parentMatchId).context ?? this.options.context ?? {};
|
|
861
|
-
};
|
|
862
889
|
const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
|
|
863
890
|
const shouldPending = !!(onReady && !this.isServer && !preload && (route.options.loader || route.options.beforeLoad) && typeof pendingMs === "number" && pendingMs !== Infinity && (route.options.pendingComponent ?? this.options.defaultPendingComponent));
|
|
864
891
|
let pendingTimeout;
|
|
@@ -877,47 +904,54 @@ class Router {
|
|
|
877
904
|
if (searchError) {
|
|
878
905
|
handleSerialError(index, searchError, "VALIDATE_SEARCH");
|
|
879
906
|
}
|
|
880
|
-
const
|
|
907
|
+
const getParentMatchContext = () => parentMatchId ? this.getMatch(parentMatchId).context : this.options.context ?? {};
|
|
881
908
|
updateMatch(matchId, (prev) => ({
|
|
882
909
|
...prev,
|
|
883
910
|
isFetching: "beforeLoad",
|
|
884
911
|
fetchCount: prev.fetchCount + 1,
|
|
885
|
-
routeContext: utils.replaceEqualDeep(
|
|
886
|
-
prev.routeContext,
|
|
887
|
-
parentContext
|
|
888
|
-
),
|
|
889
|
-
context: utils.replaceEqualDeep(prev.context, parentContext),
|
|
890
912
|
abortController,
|
|
891
|
-
pendingTimeout
|
|
913
|
+
pendingTimeout,
|
|
914
|
+
context: {
|
|
915
|
+
...getParentMatchContext(),
|
|
916
|
+
...prev.__routeContext,
|
|
917
|
+
...prev.__beforeLoadContext
|
|
918
|
+
}
|
|
892
919
|
}));
|
|
893
|
-
const { search, params,
|
|
920
|
+
const { search, params, context, cause } = this.getMatch(matchId);
|
|
894
921
|
const beforeLoadFnContext = {
|
|
895
922
|
search,
|
|
896
923
|
abortController,
|
|
897
924
|
params,
|
|
898
925
|
preload: !!preload,
|
|
899
|
-
context
|
|
926
|
+
context,
|
|
900
927
|
location,
|
|
901
928
|
navigate: (opts) => this.navigate({ ...opts, _fromLocation: location }),
|
|
902
929
|
buildLocation: this.buildLocation,
|
|
903
930
|
cause: preload ? "preload" : cause
|
|
904
931
|
};
|
|
905
|
-
|
|
932
|
+
let beforeLoadContext = await ((_c = (_b = route.options).beforeLoad) == null ? void 0 : _c.call(_b, beforeLoadFnContext)) ?? {};
|
|
933
|
+
if (this.serializeLoaderData) {
|
|
934
|
+
beforeLoadContext = this.serializeLoaderData(
|
|
935
|
+
"__beforeLoadContext",
|
|
936
|
+
beforeLoadContext,
|
|
937
|
+
{
|
|
938
|
+
router: this,
|
|
939
|
+
match: this.getMatch(matchId)
|
|
940
|
+
}
|
|
941
|
+
);
|
|
942
|
+
}
|
|
906
943
|
if (redirects.isRedirect(beforeLoadContext) || notFound.isNotFound(beforeLoadContext)) {
|
|
907
944
|
handleSerialError(index, beforeLoadContext, "BEFORE_LOAD");
|
|
908
945
|
}
|
|
909
946
|
updateMatch(matchId, (prev) => {
|
|
910
|
-
const routeContext2 = {
|
|
911
|
-
...prev.routeContext,
|
|
912
|
-
...beforeLoadContext
|
|
913
|
-
};
|
|
914
947
|
return {
|
|
915
948
|
...prev,
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
949
|
+
__beforeLoadContext: beforeLoadContext,
|
|
950
|
+
context: {
|
|
951
|
+
...getParentMatchContext(),
|
|
952
|
+
...prev.__routeContext,
|
|
953
|
+
...beforeLoadContext
|
|
954
|
+
},
|
|
921
955
|
abortController
|
|
922
956
|
};
|
|
923
957
|
});
|
|
@@ -1010,10 +1044,14 @@ class Router {
|
|
|
1010
1044
|
await route._lazyPromise;
|
|
1011
1045
|
let loaderData = await ((_b2 = (_a2 = route.options).loader) == null ? void 0 : _b2.call(_a2, getLoaderContext()));
|
|
1012
1046
|
if (this.serializeLoaderData) {
|
|
1013
|
-
loaderData = this.serializeLoaderData(
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1047
|
+
loaderData = this.serializeLoaderData(
|
|
1048
|
+
"loaderData",
|
|
1049
|
+
loaderData,
|
|
1050
|
+
{
|
|
1051
|
+
router: this,
|
|
1052
|
+
match: this.getMatch(matchId)
|
|
1053
|
+
}
|
|
1054
|
+
);
|
|
1017
1055
|
}
|
|
1018
1056
|
handleRedirectAndNotFound(
|
|
1019
1057
|
this.getMatch(matchId),
|
|
@@ -1065,7 +1103,8 @@ class Router {
|
|
|
1065
1103
|
}
|
|
1066
1104
|
};
|
|
1067
1105
|
const { status, invalid } = this.getMatch(matchId);
|
|
1068
|
-
if (
|
|
1106
|
+
if (preload && route.options.preload === false) {
|
|
1107
|
+
} else if (status === "success" && (invalid || (shouldReload ?? age > staleAge))) {
|
|
1069
1108
|
;
|
|
1070
1109
|
(async () => {
|
|
1071
1110
|
try {
|
|
@@ -1147,7 +1186,7 @@ class Router {
|
|
|
1147
1186
|
};
|
|
1148
1187
|
this.preloadRoute = async (opts) => {
|
|
1149
1188
|
const next = this.buildLocation(opts);
|
|
1150
|
-
let matches = this.matchRoutes(next
|
|
1189
|
+
let matches = this.matchRoutes(next, {
|
|
1151
1190
|
throwOnError: true,
|
|
1152
1191
|
preload: true
|
|
1153
1192
|
});
|
|
@@ -1265,10 +1304,7 @@ class Router {
|
|
|
1265
1304
|
this.dehydratedData = ctx.payload;
|
|
1266
1305
|
(_c = (_b = this.options).hydrate) == null ? void 0 : _c.call(_b, ctx.payload);
|
|
1267
1306
|
const dehydratedState = ctx.router.state;
|
|
1268
|
-
const matches = this.matchRoutes(
|
|
1269
|
-
this.state.location.pathname,
|
|
1270
|
-
this.state.location.search
|
|
1271
|
-
).map((match) => {
|
|
1307
|
+
const matches = this.matchRoutes(this.state.location).map((match) => {
|
|
1272
1308
|
const dehydratedMatch = dehydratedState.dehydratedMatches.find(
|
|
1273
1309
|
(d) => d.id === match.id
|
|
1274
1310
|
);
|
|
@@ -1368,10 +1404,7 @@ class Router {
|
|
|
1368
1404
|
notFoundMode: options.notFoundMode ?? "fuzzy",
|
|
1369
1405
|
stringifySearch: options.stringifySearch ?? searchParams.defaultStringifySearch,
|
|
1370
1406
|
parseSearch: options.parseSearch ?? searchParams.defaultParseSearch,
|
|
1371
|
-
transformer: options.transformer ??
|
|
1372
|
-
parse: JSON.parse,
|
|
1373
|
-
stringify: JSON.stringify
|
|
1374
|
-
}
|
|
1407
|
+
transformer: options.transformer ?? transformer.defaultTransformer
|
|
1375
1408
|
});
|
|
1376
1409
|
if (typeof document !== "undefined") {
|
|
1377
1410
|
window.__TSR__ROUTER__ = this;
|