@tanstack/react-router 1.18.3 → 1.19.0
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 +75 -24
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +2 -3
- package/dist/cjs/RouterProvider.cjs +1 -10
- package/dist/cjs/RouterProvider.cjs.map +1 -1
- package/dist/cjs/awaited.cjs +2 -4
- package/dist/cjs/awaited.cjs.map +1 -1
- package/dist/cjs/fileRoute.cjs.map +1 -1
- package/dist/cjs/fileRoute.d.cts +6 -5
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/link.d.cts +2 -2
- package/dist/cjs/not-found.cjs.map +1 -1
- package/dist/cjs/not-found.d.cts +11 -1
- package/dist/cjs/redirects.cjs +1 -1
- package/dist/cjs/redirects.cjs.map +1 -1
- package/dist/cjs/route.cjs +3 -2
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +25 -24
- package/dist/cjs/router.cjs +172 -143
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +12 -8
- package/dist/esm/Matches.d.ts +2 -3
- package/dist/esm/Matches.js +67 -16
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/RouterProvider.js +1 -10
- package/dist/esm/RouterProvider.js.map +1 -1
- package/dist/esm/awaited.js +2 -4
- package/dist/esm/awaited.js.map +1 -1
- package/dist/esm/fileRoute.d.ts +6 -5
- package/dist/esm/fileRoute.js.map +1 -1
- package/dist/esm/link.d.ts +2 -2
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/not-found.d.ts +11 -1
- package/dist/esm/not-found.js.map +1 -1
- package/dist/esm/redirects.js +1 -1
- package/dist/esm/redirects.js.map +1 -1
- package/dist/esm/route.d.ts +25 -24
- package/dist/esm/route.js +3 -2
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +12 -8
- package/dist/esm/router.js +163 -134
- package/dist/esm/router.js.map +1 -1
- package/package.json +1 -1
- package/src/Matches.tsx +100 -27
- package/src/RouterProvider.tsx +1 -12
- package/src/awaited.tsx +3 -5
- package/src/fileRoute.ts +8 -3
- package/src/link.tsx +7 -5
- package/src/not-found.tsx +11 -1
- package/src/redirects.ts +2 -1
- package/src/route.ts +55 -114
- package/src/router.ts +267 -175
package/dist/esm/router.js
CHANGED
|
@@ -65,7 +65,10 @@ class Router {
|
|
|
65
65
|
onUpdate: () => {
|
|
66
66
|
this.__store.state = {
|
|
67
67
|
...this.state,
|
|
68
|
-
status: this.state.isTransitioning || this.state.isLoading ? "pending" : "idle"
|
|
68
|
+
status: this.state.isTransitioning || this.state.isLoading ? "pending" : "idle",
|
|
69
|
+
cachedMatches: this.state.cachedMatches.filter(
|
|
70
|
+
(d) => !["redirected"].includes(d.status)
|
|
71
|
+
)
|
|
69
72
|
};
|
|
70
73
|
}
|
|
71
74
|
});
|
|
@@ -219,7 +222,7 @@ class Router {
|
|
|
219
222
|
}
|
|
220
223
|
return false;
|
|
221
224
|
});
|
|
222
|
-
let routeCursor = foundRoute || this.routesById[
|
|
225
|
+
let routeCursor = foundRoute || this.routesById[rootRouteId];
|
|
223
226
|
let matchedRoutes = [routeCursor];
|
|
224
227
|
let isGlobalNotFound = false;
|
|
225
228
|
if (
|
|
@@ -240,6 +243,20 @@ class Router {
|
|
|
240
243
|
if (routeCursor)
|
|
241
244
|
matchedRoutes.unshift(routeCursor);
|
|
242
245
|
}
|
|
246
|
+
const globalNotFoundRouteId = (() => {
|
|
247
|
+
if (!isGlobalNotFound) {
|
|
248
|
+
return void 0;
|
|
249
|
+
}
|
|
250
|
+
if (this.options.notFoundMode !== "root") {
|
|
251
|
+
for (let i = matchedRoutes.length - 1; i >= 0; i--) {
|
|
252
|
+
const route = matchedRoutes[i];
|
|
253
|
+
if (route.children) {
|
|
254
|
+
return route.id;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return rootRouteId;
|
|
259
|
+
})();
|
|
243
260
|
const parseErrors = matchedRoutes.map((route) => {
|
|
244
261
|
let parsedParamsError;
|
|
245
262
|
if (route.options.parseParams) {
|
|
@@ -297,12 +314,11 @@ class Router {
|
|
|
297
314
|
params: routeParams,
|
|
298
315
|
leaveWildcards: true
|
|
299
316
|
}) + loaderDepsHash;
|
|
300
|
-
|
|
317
|
+
let existingMatch = getRouteMatch(this.state, matchId);
|
|
301
318
|
const cause = this.state.matches.find((d) => d.id === matchId) ? "stay" : "enter";
|
|
302
319
|
const match = existingMatch ? {
|
|
303
320
|
...existingMatch,
|
|
304
321
|
cause,
|
|
305
|
-
notFoundError: isGlobalNotFound && route.id === rootRouteId ? { global: true } : void 0,
|
|
306
322
|
params: routeParams
|
|
307
323
|
} : {
|
|
308
324
|
id: matchId,
|
|
@@ -326,11 +342,13 @@ class Router {
|
|
|
326
342
|
loaderDeps,
|
|
327
343
|
invalid: false,
|
|
328
344
|
preload: false,
|
|
329
|
-
notFoundError: isGlobalNotFound && route.id === rootRouteId ? { global: true } : void 0,
|
|
330
345
|
links: (_d = (_c = route.options).links) == null ? void 0 : _d.call(_c),
|
|
331
346
|
scripts: (_f = (_e = route.options).scripts) == null ? void 0 : _f.call(_e),
|
|
332
347
|
staticData: route.options.staticData || {}
|
|
333
348
|
};
|
|
349
|
+
if (!(opts == null ? void 0 : opts.preload)) {
|
|
350
|
+
match.globalNotFound = globalNotFoundRouteId === route.id;
|
|
351
|
+
}
|
|
334
352
|
match.search = replaceEqualDeep(match.search, preMatchSearch);
|
|
335
353
|
match.searchError = searchError;
|
|
336
354
|
matches.push(match);
|
|
@@ -338,8 +356,6 @@ class Router {
|
|
|
338
356
|
return matches;
|
|
339
357
|
};
|
|
340
358
|
this.cancelMatch = (id) => {
|
|
341
|
-
var _a, _b;
|
|
342
|
-
(_b = (_a = getRouteMatch(this.state, id)) == null ? void 0 : _a.abortController) == null ? void 0 : _b.abort();
|
|
343
359
|
};
|
|
344
360
|
this.cancelMatches = () => {
|
|
345
361
|
var _a;
|
|
@@ -349,13 +365,9 @@ class Router {
|
|
|
349
365
|
};
|
|
350
366
|
this.buildLocation = (opts) => {
|
|
351
367
|
const build = (dest = {}, matches) => {
|
|
352
|
-
var _a, _b;
|
|
368
|
+
var _a, _b, _c;
|
|
353
369
|
const relevantMatches = this.state.pendingMatches || this.state.matches;
|
|
354
370
|
const fromSearch = ((_a = relevantMatches[relevantMatches.length - 1]) == null ? void 0 : _a.search) || this.latestLocation.search;
|
|
355
|
-
let pathname = this.resolvePathWithBase(
|
|
356
|
-
dest.from ?? this.latestLocation.pathname,
|
|
357
|
-
`${dest.to ?? ""}`
|
|
358
|
-
);
|
|
359
371
|
const fromMatches = this.matchRoutes(
|
|
360
372
|
this.latestLocation.pathname,
|
|
361
373
|
fromSearch
|
|
@@ -363,7 +375,12 @@ class Router {
|
|
|
363
375
|
const stayingMatches = matches == null ? void 0 : matches.filter(
|
|
364
376
|
(d) => fromMatches == null ? void 0 : fromMatches.find((e) => e.routeId === d.routeId)
|
|
365
377
|
);
|
|
366
|
-
const
|
|
378
|
+
const fromRoute = this.looseRoutesById[(_b = last(fromMatches)) == null ? void 0 : _b.routeId];
|
|
379
|
+
let pathname = dest.to ? this.resolvePathWithBase(
|
|
380
|
+
dest.from ?? this.latestLocation.pathname,
|
|
381
|
+
`${dest.to}`
|
|
382
|
+
) : fromRoute == null ? void 0 : fromRoute.fullPath;
|
|
383
|
+
const prevParams = { ...(_c = last(fromMatches)) == null ? void 0 : _c.params };
|
|
367
384
|
let nextParams = (dest.params ?? true) === true ? prevParams : { ...prevParams, ...functionalUpdate(dest.params, prevParams) };
|
|
368
385
|
if (nextParams) {
|
|
369
386
|
matches == null ? void 0 : matches.map((d) => this.looseRoutesById[d.routeId].options.stringifyParams).filter(Boolean).forEach((fn) => {
|
|
@@ -455,7 +472,7 @@ class Router {
|
|
|
455
472
|
if (this.navigateTimeout)
|
|
456
473
|
clearTimeout(this.navigateTimeout);
|
|
457
474
|
const isSameUrl = this.latestLocation.href === next.href;
|
|
458
|
-
if (!isSameUrl
|
|
475
|
+
if (!isSameUrl) {
|
|
459
476
|
let { maskedLocation, ...nextHistory } = next;
|
|
460
477
|
if (maskedLocation) {
|
|
461
478
|
nextHistory = {
|
|
@@ -529,13 +546,14 @@ class Router {
|
|
|
529
546
|
};
|
|
530
547
|
this.loadMatches = async ({
|
|
531
548
|
checkLatest,
|
|
549
|
+
location,
|
|
532
550
|
matches,
|
|
533
551
|
preload
|
|
534
552
|
}) => {
|
|
535
553
|
var _a, _b;
|
|
536
554
|
let latestPromise;
|
|
537
555
|
let firstBadMatchIndex;
|
|
538
|
-
const updateMatch = (match) => {
|
|
556
|
+
const updateMatch = (match, opts) => {
|
|
539
557
|
var _a2;
|
|
540
558
|
const isPending = (_a2 = this.state.pendingMatches) == null ? void 0 : _a2.find(
|
|
541
559
|
(d) => d.id === match.id
|
|
@@ -543,36 +561,43 @@ class Router {
|
|
|
543
561
|
const isMatched = this.state.matches.find((d) => d.id === match.id);
|
|
544
562
|
const matchesKey = isPending ? "pendingMatches" : isMatched ? "matches" : "cachedMatches";
|
|
545
563
|
this.__store.setState((s) => {
|
|
546
|
-
var _a3;
|
|
564
|
+
var _a3, _b2;
|
|
547
565
|
return {
|
|
548
566
|
...s,
|
|
549
|
-
[matchesKey]: (_a3 = s[matchesKey]) == null ? void 0 : _a3.map(
|
|
550
|
-
(d) => d.id === match.id ? match : d
|
|
551
|
-
)
|
|
567
|
+
[matchesKey]: (opts == null ? void 0 : opts.remove) ? (_a3 = s[matchesKey]) == null ? void 0 : _a3.filter((d) => d.id !== match.id) : (_b2 = s[matchesKey]) == null ? void 0 : _b2.map((d) => d.id === match.id ? match : d)
|
|
552
568
|
};
|
|
553
569
|
});
|
|
554
570
|
};
|
|
571
|
+
const handleMatchSpecialError = (match, err) => {
|
|
572
|
+
match = {
|
|
573
|
+
...match,
|
|
574
|
+
status: isRedirect(err) ? "redirected" : isNotFound(err) ? "notFound" : "error",
|
|
575
|
+
isFetching: false,
|
|
576
|
+
error: err
|
|
577
|
+
};
|
|
578
|
+
updateMatch(match);
|
|
579
|
+
if (!err.routeId) {
|
|
580
|
+
err.routeId = match.routeId;
|
|
581
|
+
}
|
|
582
|
+
throw err;
|
|
583
|
+
};
|
|
555
584
|
for (let [index, match] of matches.entries()) {
|
|
556
585
|
const parentMatch = matches[index - 1];
|
|
557
586
|
const route = this.looseRoutesById[match.routeId];
|
|
558
587
|
const abortController = new AbortController();
|
|
559
|
-
const
|
|
588
|
+
const handleSerialError = (err, code) => {
|
|
560
589
|
var _a2, _b2;
|
|
561
590
|
err.routerCode = code;
|
|
562
591
|
firstBadMatchIndex = firstBadMatchIndex ?? index;
|
|
563
|
-
if (isRedirect(err)) {
|
|
564
|
-
|
|
565
|
-
}
|
|
566
|
-
if (isNotFound(err)) {
|
|
567
|
-
err.routeId = match.routeId;
|
|
568
|
-
throw err;
|
|
592
|
+
if (isRedirect(err) || isNotFound(err)) {
|
|
593
|
+
handleMatchSpecialError(match, err);
|
|
569
594
|
}
|
|
570
595
|
try {
|
|
571
596
|
(_b2 = (_a2 = route.options).onError) == null ? void 0 : _b2.call(_a2, err);
|
|
572
597
|
} catch (errorHandlerErr) {
|
|
573
598
|
err = errorHandlerErr;
|
|
574
|
-
if (isRedirect(
|
|
575
|
-
|
|
599
|
+
if (isRedirect(err) || isNotFound(err)) {
|
|
600
|
+
handleMatchSpecialError(match, errorHandlerErr);
|
|
576
601
|
}
|
|
577
602
|
}
|
|
578
603
|
matches[index] = match = {
|
|
@@ -583,13 +608,13 @@ class Router {
|
|
|
583
608
|
abortController: new AbortController()
|
|
584
609
|
};
|
|
585
610
|
};
|
|
611
|
+
if (match.paramsError) {
|
|
612
|
+
handleSerialError(match.paramsError, "PARSE_PARAMS");
|
|
613
|
+
}
|
|
614
|
+
if (match.searchError) {
|
|
615
|
+
handleSerialError(match.searchError, "VALIDATE_SEARCH");
|
|
616
|
+
}
|
|
586
617
|
try {
|
|
587
|
-
if (match.paramsError) {
|
|
588
|
-
handleError(match.paramsError, "PARSE_PARAMS");
|
|
589
|
-
}
|
|
590
|
-
if (match.searchError) {
|
|
591
|
-
handleError(match.searchError, "VALIDATE_SEARCH");
|
|
592
|
-
}
|
|
593
618
|
const parentContext = (parentMatch == null ? void 0 : parentMatch.context) ?? this.options.context ?? {};
|
|
594
619
|
const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
|
|
595
620
|
const pendingPromise = typeof pendingMs === "number" && pendingMs <= 0 ? Promise.resolve() : new Promise((r) => setTimeout(r, pendingMs));
|
|
@@ -599,14 +624,13 @@ class Router {
|
|
|
599
624
|
params: match.params,
|
|
600
625
|
preload: !!preload,
|
|
601
626
|
context: parentContext,
|
|
602
|
-
location
|
|
603
|
-
// TOOD: just expose state and router, etc
|
|
627
|
+
location,
|
|
604
628
|
navigate: (opts) => this.navigate({ ...opts, from: match.pathname }),
|
|
605
629
|
buildLocation: this.buildLocation,
|
|
606
630
|
cause: preload ? "preload" : match.cause
|
|
607
631
|
})) ?? {};
|
|
608
|
-
if (isRedirect(beforeLoadContext)) {
|
|
609
|
-
|
|
632
|
+
if (isRedirect(beforeLoadContext) || isNotFound(beforeLoadContext)) {
|
|
633
|
+
handleSerialError(beforeLoadContext, "BEFORE_LOAD");
|
|
610
634
|
}
|
|
611
635
|
const context = {
|
|
612
636
|
...parentContext,
|
|
@@ -620,7 +644,7 @@ class Router {
|
|
|
620
644
|
pendingPromise
|
|
621
645
|
};
|
|
622
646
|
} catch (err) {
|
|
623
|
-
|
|
647
|
+
handleSerialError(err, "BEFORE_LOAD");
|
|
624
648
|
break;
|
|
625
649
|
}
|
|
626
650
|
}
|
|
@@ -633,12 +657,8 @@ class Router {
|
|
|
633
657
|
const parentMatchPromise = matchPromises[index - 1];
|
|
634
658
|
const route = this.looseRoutesById[match.routeId];
|
|
635
659
|
const handleError = (err) => {
|
|
636
|
-
if (isRedirect(err)) {
|
|
637
|
-
|
|
638
|
-
}
|
|
639
|
-
if (isNotFound(err)) {
|
|
640
|
-
err.routeId = match.routeId;
|
|
641
|
-
throw err;
|
|
660
|
+
if (isRedirect(err) || isNotFound(err)) {
|
|
661
|
+
handleMatchSpecialError(match, err);
|
|
642
662
|
}
|
|
643
663
|
};
|
|
644
664
|
let loadPromise;
|
|
@@ -649,7 +669,6 @@ class Router {
|
|
|
649
669
|
let didShowPending = false;
|
|
650
670
|
const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
|
|
651
671
|
const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
|
|
652
|
-
const shouldPending = !preload && typeof pendingMs === "number" && (route.options.pendingComponent ?? this.options.defaultPendingComponent);
|
|
653
672
|
const loaderContext = {
|
|
654
673
|
params: match.params,
|
|
655
674
|
deps: match.loaderDeps,
|
|
@@ -657,53 +676,47 @@ class Router {
|
|
|
657
676
|
parentMatchPromise,
|
|
658
677
|
abortController: match.abortController,
|
|
659
678
|
context: match.context,
|
|
660
|
-
location
|
|
679
|
+
location,
|
|
661
680
|
navigate: (opts) => this.navigate({ ...opts, from: match.pathname }),
|
|
662
|
-
cause: preload ? "preload" : match.cause
|
|
681
|
+
cause: preload ? "preload" : match.cause,
|
|
682
|
+
route
|
|
663
683
|
};
|
|
664
684
|
const fetch = async () => {
|
|
665
|
-
var _a3, _b2, _c, _d, _e, _f, _g, _h;
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
685
|
+
var _a3, _b2, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
686
|
+
try {
|
|
687
|
+
if (match.isFetching) {
|
|
688
|
+
loadPromise = (_a3 = getRouteMatch(this.state, match.id)) == null ? void 0 : _a3.loadPromise;
|
|
689
|
+
} else {
|
|
690
|
+
matches[index] = match = {
|
|
691
|
+
...match,
|
|
692
|
+
isFetching: true,
|
|
693
|
+
fetchCount: match.fetchCount + 1
|
|
694
|
+
};
|
|
695
|
+
const lazyPromise = ((_b2 = route.lazyFn) == null ? void 0 : _b2.call(route).then((lazyRoute) => {
|
|
696
|
+
Object.assign(route.options, lazyRoute.options);
|
|
697
|
+
})) || Promise.resolve();
|
|
698
|
+
const componentsPromise = lazyPromise.then(
|
|
699
|
+
() => Promise.all(
|
|
700
|
+
componentTypes.map(async (type) => {
|
|
701
|
+
const component = route.options[type];
|
|
702
|
+
if (component == null ? void 0 : component.preload) {
|
|
703
|
+
await component.preload();
|
|
704
|
+
}
|
|
705
|
+
})
|
|
706
|
+
)
|
|
707
|
+
);
|
|
708
|
+
const loaderPromise = (_d = (_c = route.options).loader) == null ? void 0 : _d.call(_c, loaderContext);
|
|
709
|
+
loadPromise = Promise.all([
|
|
710
|
+
componentsPromise,
|
|
711
|
+
loaderPromise,
|
|
712
|
+
lazyPromise
|
|
713
|
+
]).then((d) => d[1]);
|
|
671
714
|
}
|
|
672
715
|
matches[index] = match = {
|
|
673
716
|
...match,
|
|
674
|
-
|
|
675
|
-
fetchCount: match.fetchCount + 1
|
|
717
|
+
loadPromise
|
|
676
718
|
};
|
|
677
|
-
|
|
678
|
-
Object.assign(route.options, lazyRoute.options);
|
|
679
|
-
})) || Promise.resolve();
|
|
680
|
-
const componentsPromise = lazyPromise.then(
|
|
681
|
-
() => Promise.all(
|
|
682
|
-
componentTypes.map(async (type) => {
|
|
683
|
-
const component = route.options[type];
|
|
684
|
-
if (component == null ? void 0 : component.preload) {
|
|
685
|
-
await component.preload();
|
|
686
|
-
}
|
|
687
|
-
})
|
|
688
|
-
)
|
|
689
|
-
);
|
|
690
|
-
async function loader() {
|
|
691
|
-
var _a4, _b3;
|
|
692
|
-
return await ((_b3 = (_a4 = route.options).loader) == null ? void 0 : _b3.call(_a4, loaderContext));
|
|
693
|
-
}
|
|
694
|
-
const loaderPromise = loader();
|
|
695
|
-
loadPromise = Promise.all([
|
|
696
|
-
componentsPromise,
|
|
697
|
-
loaderPromise,
|
|
698
|
-
lazyPromise
|
|
699
|
-
]).then((d) => d[1]);
|
|
700
|
-
}
|
|
701
|
-
matches[index] = match = {
|
|
702
|
-
...match,
|
|
703
|
-
loadPromise
|
|
704
|
-
};
|
|
705
|
-
updateMatch(match);
|
|
706
|
-
try {
|
|
719
|
+
updateMatch(match);
|
|
707
720
|
const loaderData = await loadPromise;
|
|
708
721
|
if (latestPromise = checkLatest())
|
|
709
722
|
return await latestPromise;
|
|
@@ -714,11 +727,11 @@ class Router {
|
|
|
714
727
|
if (latestPromise = checkLatest())
|
|
715
728
|
return await latestPromise;
|
|
716
729
|
const [meta, headers] = await Promise.all([
|
|
717
|
-
(
|
|
730
|
+
(_f = (_e = route.options).meta) == null ? void 0 : _f.call(_e, {
|
|
718
731
|
params: match.params,
|
|
719
732
|
loaderData
|
|
720
733
|
}),
|
|
721
|
-
(
|
|
734
|
+
(_h = (_g = route.options).headers) == null ? void 0 : _h.call(_g, {
|
|
722
735
|
loaderData
|
|
723
736
|
})
|
|
724
737
|
]);
|
|
@@ -738,7 +751,7 @@ class Router {
|
|
|
738
751
|
return await latestPromise;
|
|
739
752
|
handleError(error);
|
|
740
753
|
try {
|
|
741
|
-
(
|
|
754
|
+
(_j = (_i = route.options).onError) == null ? void 0 : _j.call(_i, error);
|
|
742
755
|
} catch (onErrorError) {
|
|
743
756
|
error = onErrorError;
|
|
744
757
|
handleError(onErrorError);
|
|
@@ -761,8 +774,26 @@ class Router {
|
|
|
761
774
|
...match,
|
|
762
775
|
preload: !!preload && !this.state.matches.find((d) => d.id === match.id)
|
|
763
776
|
};
|
|
764
|
-
|
|
765
|
-
|
|
777
|
+
if (match.status === "success" && (match.invalid || (shouldReload ?? age > staleAge))) {
|
|
778
|
+
(async () => {
|
|
779
|
+
try {
|
|
780
|
+
await fetch();
|
|
781
|
+
} catch (err) {
|
|
782
|
+
console.info("Background Fetching Error", err);
|
|
783
|
+
if (isRedirect(err)) {
|
|
784
|
+
const isActive = (this.state.pendingMatches || this.state.matches).find((d) => d.id === match.id);
|
|
785
|
+
handleError(err);
|
|
786
|
+
if (isActive) {
|
|
787
|
+
this.handleRedirect(err);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
})();
|
|
792
|
+
return resolve();
|
|
793
|
+
}
|
|
794
|
+
const shouldPending = !preload && typeof pendingMs === "number" && (route.options.pendingComponent ?? this.options.defaultPendingComponent);
|
|
795
|
+
if (match.status !== "success") {
|
|
796
|
+
try {
|
|
766
797
|
if (shouldPending) {
|
|
767
798
|
(_a2 = match.pendingPromise) == null ? void 0 : _a2.then(async () => {
|
|
768
799
|
if (latestPromise = checkLatest())
|
|
@@ -777,11 +808,9 @@ class Router {
|
|
|
777
808
|
});
|
|
778
809
|
}
|
|
779
810
|
await fetch();
|
|
780
|
-
}
|
|
781
|
-
|
|
811
|
+
} catch (err) {
|
|
812
|
+
reject(err);
|
|
782
813
|
}
|
|
783
|
-
} catch (err) {
|
|
784
|
-
reject(err);
|
|
785
814
|
}
|
|
786
815
|
resolve();
|
|
787
816
|
})
|
|
@@ -837,15 +866,20 @@ class Router {
|
|
|
837
866
|
}));
|
|
838
867
|
});
|
|
839
868
|
try {
|
|
869
|
+
let redirected;
|
|
870
|
+
let notFound;
|
|
840
871
|
try {
|
|
841
872
|
await this.loadMatches({
|
|
842
873
|
matches: pendingMatches,
|
|
874
|
+
location: next,
|
|
843
875
|
checkLatest: () => this.checkLatest(promise)
|
|
844
876
|
});
|
|
845
877
|
} catch (err) {
|
|
846
878
|
if (isRedirect(err)) {
|
|
879
|
+
redirected = err;
|
|
847
880
|
this.handleRedirect(err);
|
|
848
881
|
} else if (isNotFound(err)) {
|
|
882
|
+
notFound = err;
|
|
849
883
|
this.handleNotFound(pendingMatches, err);
|
|
850
884
|
}
|
|
851
885
|
}
|
|
@@ -870,7 +904,8 @@ class Router {
|
|
|
870
904
|
cachedMatches: [
|
|
871
905
|
...s.cachedMatches,
|
|
872
906
|
...exitingMatches.filter((d) => d.status !== "error")
|
|
873
|
-
]
|
|
907
|
+
],
|
|
908
|
+
statusCode: (redirected == null ? void 0 : redirected.code) || notFound ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200
|
|
874
909
|
}));
|
|
875
910
|
this.cleanCache();
|
|
876
911
|
});
|
|
@@ -895,6 +930,7 @@ class Router {
|
|
|
895
930
|
if (latestPromise = this.checkLatest(promise)) {
|
|
896
931
|
return latestPromise;
|
|
897
932
|
}
|
|
933
|
+
console.log("Load Error", err);
|
|
898
934
|
reject(err);
|
|
899
935
|
}
|
|
900
936
|
});
|
|
@@ -905,10 +941,9 @@ class Router {
|
|
|
905
941
|
if (!err.href) {
|
|
906
942
|
err.href = this.buildLocation(err).href;
|
|
907
943
|
}
|
|
908
|
-
if (isServer) {
|
|
909
|
-
|
|
944
|
+
if (!isServer) {
|
|
945
|
+
this.navigate({ ...err, replace: true });
|
|
910
946
|
}
|
|
911
|
-
this.navigate(err);
|
|
912
947
|
};
|
|
913
948
|
this.cleanCache = () => {
|
|
914
949
|
this.__store.setState((s) => {
|
|
@@ -925,11 +960,12 @@ class Router {
|
|
|
925
960
|
};
|
|
926
961
|
});
|
|
927
962
|
};
|
|
928
|
-
this.preloadRoute = async (
|
|
963
|
+
this.preloadRoute = async (opts) => {
|
|
929
964
|
var _a;
|
|
930
|
-
let next = this.buildLocation(
|
|
965
|
+
let next = this.buildLocation(opts);
|
|
931
966
|
let matches = this.matchRoutes(next.pathname, next.search, {
|
|
932
|
-
throwOnError: true
|
|
967
|
+
throwOnError: true,
|
|
968
|
+
preload: true
|
|
933
969
|
});
|
|
934
970
|
const loadedMatchIds = Object.fromEntries(
|
|
935
971
|
(_a = [
|
|
@@ -951,14 +987,16 @@ class Router {
|
|
|
951
987
|
try {
|
|
952
988
|
matches = await this.loadMatches({
|
|
953
989
|
matches,
|
|
990
|
+
location: next,
|
|
954
991
|
preload: true,
|
|
955
992
|
checkLatest: () => void 0
|
|
956
993
|
});
|
|
957
994
|
return matches;
|
|
958
995
|
} catch (err) {
|
|
959
|
-
if (
|
|
960
|
-
|
|
996
|
+
if (isRedirect(err)) {
|
|
997
|
+
return await this.preloadRoute(err);
|
|
961
998
|
}
|
|
999
|
+
console.error(err);
|
|
962
1000
|
return void 0;
|
|
963
1001
|
}
|
|
964
1002
|
};
|
|
@@ -1045,15 +1083,7 @@ class Router {
|
|
|
1045
1083
|
return {
|
|
1046
1084
|
state: {
|
|
1047
1085
|
dehydratedMatches: this.state.matches.map((d) => ({
|
|
1048
|
-
...pick(d, [
|
|
1049
|
-
"id",
|
|
1050
|
-
"status",
|
|
1051
|
-
"updatedAt",
|
|
1052
|
-
"loaderData",
|
|
1053
|
-
// Not-founds that occur during SSR don't require the client to load data before
|
|
1054
|
-
// triggering in order to prevent the flicker of the loading component
|
|
1055
|
-
"notFoundError"
|
|
1056
|
-
]),
|
|
1086
|
+
...pick(d, ["id", "status", "updatedAt", "loaderData"]),
|
|
1057
1087
|
// If an error occurs server-side during SSRing,
|
|
1058
1088
|
// send a small subset of the error to the client
|
|
1059
1089
|
error: d.error ? {
|
|
@@ -1115,30 +1145,28 @@ class Router {
|
|
|
1115
1145
|
};
|
|
1116
1146
|
this.handleNotFound = (matches, err) => {
|
|
1117
1147
|
const matchesByRouteId = Object.fromEntries(
|
|
1118
|
-
matches.map((
|
|
1148
|
+
matches.map((match2) => [match2.routeId, match2])
|
|
1119
1149
|
);
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
"Found invalid route tree while trying to find not-found handler."
|
|
1128
|
-
);
|
|
1129
|
-
if (currentRoute.id === rootRouteId)
|
|
1130
|
-
break;
|
|
1131
|
-
}
|
|
1132
|
-
const match = matchesByRouteId[currentRoute.id];
|
|
1133
|
-
invariant(match, "Could not find match for route: " + currentRoute.id);
|
|
1134
|
-
match.notFoundError = err;
|
|
1135
|
-
return;
|
|
1136
|
-
}
|
|
1150
|
+
let routeCursor = (err.global ? this.looseRoutesById[rootRouteId] : this.looseRoutesById[err.routeId]) || this.looseRoutesById[rootRouteId];
|
|
1151
|
+
while (!routeCursor.options.notFoundComponent && !this.options.defaultNotFoundComponent && routeCursor.id !== rootRouteId) {
|
|
1152
|
+
routeCursor = routeCursor == null ? void 0 : routeCursor.parentRoute;
|
|
1153
|
+
invariant(
|
|
1154
|
+
routeCursor,
|
|
1155
|
+
"Found invalid route tree while trying to find not-found handler."
|
|
1156
|
+
);
|
|
1137
1157
|
}
|
|
1138
|
-
matchesByRouteId[
|
|
1158
|
+
let match = matchesByRouteId[routeCursor.id];
|
|
1159
|
+
invariant(match, "Could not find match for route: " + routeCursor.id);
|
|
1160
|
+
Object.assign(match, {
|
|
1161
|
+
status: "notFound",
|
|
1162
|
+
error: err,
|
|
1163
|
+
isFetching: false
|
|
1164
|
+
});
|
|
1139
1165
|
};
|
|
1140
1166
|
this.hasNotFoundMatch = () => {
|
|
1141
|
-
return this.__store.state.matches.some(
|
|
1167
|
+
return this.__store.state.matches.some(
|
|
1168
|
+
(d) => d.status === "notFound" || d.globalNotFound
|
|
1169
|
+
);
|
|
1142
1170
|
};
|
|
1143
1171
|
this.update({
|
|
1144
1172
|
defaultPreloadDelay: 50,
|
|
@@ -1186,7 +1214,8 @@ function getInitialRouterState(location) {
|
|
|
1186
1214
|
matches: [],
|
|
1187
1215
|
pendingMatches: [],
|
|
1188
1216
|
cachedMatches: [],
|
|
1189
|
-
lastUpdated: 0
|
|
1217
|
+
lastUpdated: 0,
|
|
1218
|
+
statusCode: 200
|
|
1190
1219
|
};
|
|
1191
1220
|
}
|
|
1192
1221
|
function defaultSerializeError(err) {
|