@tanstack/react-router 1.45.0 → 1.45.3
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/CatchBoundary.cjs +1 -1
- package/dist/cjs/CatchBoundary.cjs.map +1 -1
- package/dist/cjs/CatchBoundary.d.cts +1 -1
- package/dist/cjs/Match.cjs +24 -34
- package/dist/cjs/Match.cjs.map +1 -1
- package/dist/cjs/Matches.cjs +1 -1
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +4 -2
- package/dist/cjs/RouterProvider.cjs +0 -8
- package/dist/cjs/RouterProvider.cjs.map +1 -1
- package/dist/cjs/RouterProvider.d.cts +1 -4
- package/dist/cjs/Transitioner.cjs +5 -1
- package/dist/cjs/Transitioner.cjs.map +1 -1
- package/dist/cjs/index.cjs +0 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/path.cjs +1 -1
- package/dist/cjs/path.cjs.map +1 -1
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +1 -0
- package/dist/cjs/router.cjs +459 -406
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +22 -10
- package/dist/esm/CatchBoundary.d.ts +1 -1
- package/dist/esm/CatchBoundary.js +1 -1
- package/dist/esm/CatchBoundary.js.map +1 -1
- package/dist/esm/Match.js +24 -34
- package/dist/esm/Match.js.map +1 -1
- package/dist/esm/Matches.d.ts +4 -2
- package/dist/esm/Matches.js +1 -1
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/RouterProvider.d.ts +1 -4
- package/dist/esm/RouterProvider.js +1 -9
- package/dist/esm/RouterProvider.js.map +1 -1
- package/dist/esm/Transitioner.js +5 -1
- package/dist/esm/Transitioner.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -2
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/path.js +1 -1
- package/dist/esm/path.js.map +1 -1
- package/dist/esm/route.d.ts +1 -0
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +22 -10
- package/dist/esm/router.js +461 -408
- package/dist/esm/router.js.map +1 -1
- package/package.json +2 -2
- package/src/CatchBoundary.tsx +7 -3
- package/src/Match.tsx +47 -38
- package/src/Matches.tsx +5 -3
- package/src/RouterProvider.tsx +0 -11
- package/src/Transitioner.tsx +5 -1
- package/src/index.tsx +0 -1
- package/src/link.tsx +2 -2
- package/src/path.ts +1 -1
- package/src/route.ts +1 -0
- package/src/router.ts +642 -566
package/dist/cjs/router.cjs
CHANGED
|
@@ -7,7 +7,6 @@ const warning = require("tiny-warning");
|
|
|
7
7
|
const root = require("./root.cjs");
|
|
8
8
|
const searchParams = require("./searchParams.cjs");
|
|
9
9
|
const utils = require("./utils.cjs");
|
|
10
|
-
const RouterProvider = require("./RouterProvider.cjs");
|
|
11
10
|
const path = require("./path.cjs");
|
|
12
11
|
const redirects = require("./redirects.cjs");
|
|
13
12
|
const notFound = require("./not-found.cjs");
|
|
@@ -30,9 +29,7 @@ class Router {
|
|
|
30
29
|
)}`;
|
|
31
30
|
this.resetNextScroll = true;
|
|
32
31
|
this.shouldViewTransition = void 0;
|
|
33
|
-
this.latestLoadPromise = Promise.resolve();
|
|
34
32
|
this.subscribers = /* @__PURE__ */ new Set();
|
|
35
|
-
this.isServer = typeof document === "undefined";
|
|
36
33
|
this.startReactTransition = (fn) => fn();
|
|
37
34
|
this.update = (newOptions) => {
|
|
38
35
|
if (newOptions.notFoundRoute) {
|
|
@@ -45,6 +42,7 @@ class Router {
|
|
|
45
42
|
...this.options,
|
|
46
43
|
...newOptions
|
|
47
44
|
};
|
|
45
|
+
this.isServer = this.options.isServer ?? typeof document === "undefined";
|
|
48
46
|
if (!this.basepath || newOptions.basepath && newOptions.basepath !== previousOptions.basepath) {
|
|
49
47
|
if (newOptions.basepath === void 0 || newOptions.basepath === "" || newOptions.basepath === "/") {
|
|
50
48
|
this.basepath = "/";
|
|
@@ -56,9 +54,9 @@ class Router {
|
|
|
56
54
|
// eslint-disable-next-line ts/no-unnecessary-condition
|
|
57
55
|
!this.history || this.options.history && this.options.history !== this.history
|
|
58
56
|
) {
|
|
59
|
-
this.history = this.options.history ?? (
|
|
60
|
-
initialEntries: [this.
|
|
61
|
-
}));
|
|
57
|
+
this.history = this.options.history ?? (this.isServer ? history.createMemoryHistory({
|
|
58
|
+
initialEntries: [this.basepath || "/"]
|
|
59
|
+
}) : history.createBrowserHistory());
|
|
62
60
|
this.latestLocation = this.parseLocation();
|
|
63
61
|
}
|
|
64
62
|
if (this.options.routeTree !== this.routeTree) {
|
|
@@ -172,11 +170,6 @@ class Router {
|
|
|
172
170
|
}
|
|
173
171
|
});
|
|
174
172
|
};
|
|
175
|
-
this.checkLatest = (promise) => {
|
|
176
|
-
if (this.latestLoadPromise !== promise) {
|
|
177
|
-
throw this.latestLoadPromise;
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
173
|
this.parseLocation = (previousLocation) => {
|
|
181
174
|
const parse = ({
|
|
182
175
|
pathname,
|
|
@@ -328,7 +321,7 @@ class Router {
|
|
|
328
321
|
params: routeParams,
|
|
329
322
|
leaveWildcards: true
|
|
330
323
|
}) + loaderDepsHash;
|
|
331
|
-
const existingMatch =
|
|
324
|
+
const existingMatch = this.getMatch(matchId);
|
|
332
325
|
const cause = this.state.matches.find((d) => d.id === matchId) ? "stay" : "enter";
|
|
333
326
|
let match;
|
|
334
327
|
if (existingMatch) {
|
|
@@ -338,11 +331,7 @@ class Router {
|
|
|
338
331
|
params: routeParams
|
|
339
332
|
};
|
|
340
333
|
} else {
|
|
341
|
-
const status = route.options.loader || route.options.beforeLoad ? "pending" : "success";
|
|
342
|
-
const loadPromise = utils.createControlledPromise();
|
|
343
|
-
if (status === "success") {
|
|
344
|
-
loadPromise.resolve();
|
|
345
|
-
}
|
|
334
|
+
const status = route.options.loader || route.options.beforeLoad || route.lazyFn ? "pending" : "success";
|
|
346
335
|
match = {
|
|
347
336
|
id: matchId,
|
|
348
337
|
index,
|
|
@@ -352,12 +341,10 @@ class Router {
|
|
|
352
341
|
updatedAt: Date.now(),
|
|
353
342
|
search: {},
|
|
354
343
|
searchError: void 0,
|
|
355
|
-
status
|
|
344
|
+
status,
|
|
356
345
|
isFetching: false,
|
|
357
346
|
error: void 0,
|
|
358
347
|
paramsError: parseErrors[index],
|
|
359
|
-
loaderPromise: Promise.resolve(),
|
|
360
|
-
loadPromise,
|
|
361
348
|
routeContext: void 0,
|
|
362
349
|
context: void 0,
|
|
363
350
|
abortController: new AbortController(),
|
|
@@ -368,7 +355,8 @@ class Router {
|
|
|
368
355
|
preload: false,
|
|
369
356
|
links: (_d = (_c = route.options).links) == null ? void 0 : _d.call(_c),
|
|
370
357
|
scripts: (_f = (_e = route.options).scripts) == null ? void 0 : _f.call(_e),
|
|
371
|
-
staticData: route.options.staticData || {}
|
|
358
|
+
staticData: route.options.staticData || {},
|
|
359
|
+
loadPromise: utils.createControlledPromise()
|
|
372
360
|
};
|
|
373
361
|
}
|
|
374
362
|
if (match.status === "success") {
|
|
@@ -393,7 +381,7 @@ class Router {
|
|
|
393
381
|
};
|
|
394
382
|
this.cancelMatch = (id) => {
|
|
395
383
|
var _a;
|
|
396
|
-
(_a =
|
|
384
|
+
(_a = this.getMatch(id)) == null ? void 0 : _a.abortController.abort();
|
|
397
385
|
};
|
|
398
386
|
this.cancelMatches = () => {
|
|
399
387
|
var _a;
|
|
@@ -517,8 +505,7 @@ class Router {
|
|
|
517
505
|
}
|
|
518
506
|
return buildWithMatches(opts);
|
|
519
507
|
};
|
|
520
|
-
this.commitLocation =
|
|
521
|
-
startTransition,
|
|
508
|
+
this.commitLocation = ({
|
|
522
509
|
viewTransition,
|
|
523
510
|
ignoreBlocker,
|
|
524
511
|
...next
|
|
@@ -530,6 +517,10 @@ class Router {
|
|
|
530
517
|
return isEqual;
|
|
531
518
|
};
|
|
532
519
|
const isSameUrl = this.latestLocation.href === next.href;
|
|
520
|
+
const previousCommitPromise = this.commitLocationPromise;
|
|
521
|
+
this.commitLocationPromise = utils.createControlledPromise(() => {
|
|
522
|
+
previousCommitPromise == null ? void 0 : previousCommitPromise.resolve();
|
|
523
|
+
});
|
|
533
524
|
if (isSameUrl && isSameState()) {
|
|
534
525
|
this.load();
|
|
535
526
|
} else {
|
|
@@ -564,12 +555,14 @@ class Router {
|
|
|
564
555
|
);
|
|
565
556
|
}
|
|
566
557
|
this.resetNextScroll = next.resetScroll ?? true;
|
|
567
|
-
|
|
558
|
+
if (!this.history.subscribers.size) {
|
|
559
|
+
this.load();
|
|
560
|
+
}
|
|
561
|
+
return this.commitLocationPromise;
|
|
568
562
|
};
|
|
569
563
|
this.buildAndCommitLocation = ({
|
|
570
564
|
replace,
|
|
571
565
|
resetScroll,
|
|
572
|
-
startTransition,
|
|
573
566
|
viewTransition,
|
|
574
567
|
ignoreBlocker,
|
|
575
568
|
...rest
|
|
@@ -577,7 +570,6 @@ class Router {
|
|
|
577
570
|
const location = this.buildLocation(rest);
|
|
578
571
|
return this.commitLocation({
|
|
579
572
|
...location,
|
|
580
|
-
startTransition,
|
|
581
573
|
viewTransition,
|
|
582
574
|
replace,
|
|
583
575
|
resetScroll,
|
|
@@ -594,7 +586,7 @@ class Router {
|
|
|
594
586
|
}
|
|
595
587
|
invariant(
|
|
596
588
|
!isExternal,
|
|
597
|
-
"Attempting to navigate to external url with
|
|
589
|
+
"Attempting to navigate to external url with router.navigate!"
|
|
598
590
|
);
|
|
599
591
|
return this.buildAndCommitLocation({
|
|
600
592
|
...rest,
|
|
@@ -605,127 +597,162 @@ class Router {
|
|
|
605
597
|
};
|
|
606
598
|
this.load = async () => {
|
|
607
599
|
this.latestLocation = this.parseLocation(this.latestLocation);
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
this.latestLoadPromise = promise;
|
|
600
|
+
this.__store.setState((s) => ({
|
|
601
|
+
...s,
|
|
602
|
+
loadedAt: Date.now()
|
|
603
|
+
}));
|
|
613
604
|
let redirect;
|
|
614
605
|
let notFound$1;
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
pendingMatches
|
|
624
|
-
this.__store.
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
606
|
+
const loadPromise = new Promise((resolve) => {
|
|
607
|
+
this.startReactTransition(async () => {
|
|
608
|
+
var _a;
|
|
609
|
+
try {
|
|
610
|
+
const next = this.latestLocation;
|
|
611
|
+
const prevLocation = this.state.resolvedLocation;
|
|
612
|
+
const pathDidChange = prevLocation.href !== next.href;
|
|
613
|
+
this.cancelMatches();
|
|
614
|
+
let pendingMatches;
|
|
615
|
+
this.__store.batch(() => {
|
|
616
|
+
pendingMatches = this.matchRoutes(next.pathname, next.search);
|
|
617
|
+
this.__store.setState((s) => ({
|
|
618
|
+
...s,
|
|
619
|
+
status: "pending",
|
|
620
|
+
isLoading: true,
|
|
621
|
+
location: next,
|
|
622
|
+
pendingMatches,
|
|
623
|
+
// If a cached moved to pendingMatches, remove it from cachedMatches
|
|
624
|
+
cachedMatches: s.cachedMatches.filter((d) => {
|
|
625
|
+
return !pendingMatches.find((e) => e.id === d.id);
|
|
626
|
+
})
|
|
627
|
+
}));
|
|
628
|
+
});
|
|
629
|
+
if (!this.state.redirect) {
|
|
630
|
+
this.emit({
|
|
631
|
+
type: "onBeforeNavigate",
|
|
632
|
+
fromLocation: prevLocation,
|
|
633
|
+
toLocation: next,
|
|
634
|
+
pathChanged: pathDidChange
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
637
|
this.emit({
|
|
638
|
-
type: "
|
|
638
|
+
type: "onBeforeLoad",
|
|
639
639
|
fromLocation: prevLocation,
|
|
640
640
|
toLocation: next,
|
|
641
641
|
pathChanged: pathDidChange
|
|
642
642
|
});
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
cachedMatches: [
|
|
678
|
-
...s.cachedMatches,
|
|
679
|
-
...exitingMatches.filter((d) => d.status !== "error")
|
|
680
|
-
]
|
|
681
|
-
};
|
|
643
|
+
await this.loadMatches({
|
|
644
|
+
matches: pendingMatches,
|
|
645
|
+
location: next,
|
|
646
|
+
// eslint-disable-next-line ts/require-await
|
|
647
|
+
onReady: async () => {
|
|
648
|
+
this.startViewTransition(async () => {
|
|
649
|
+
let exitingMatches;
|
|
650
|
+
let enteringMatches;
|
|
651
|
+
let stayingMatches;
|
|
652
|
+
this.__store.batch(() => {
|
|
653
|
+
this.__store.setState((s) => {
|
|
654
|
+
const previousMatches = s.matches;
|
|
655
|
+
const newMatches = s.pendingMatches || s.matches;
|
|
656
|
+
exitingMatches = previousMatches.filter(
|
|
657
|
+
(match) => !newMatches.find((d) => d.id === match.id)
|
|
658
|
+
);
|
|
659
|
+
enteringMatches = newMatches.filter(
|
|
660
|
+
(match) => !previousMatches.find((d) => d.id === match.id)
|
|
661
|
+
);
|
|
662
|
+
stayingMatches = previousMatches.filter(
|
|
663
|
+
(match) => newMatches.find((d) => d.id === match.id)
|
|
664
|
+
);
|
|
665
|
+
return {
|
|
666
|
+
...s,
|
|
667
|
+
isLoading: false,
|
|
668
|
+
matches: newMatches,
|
|
669
|
+
pendingMatches: void 0,
|
|
670
|
+
cachedMatches: [
|
|
671
|
+
...s.cachedMatches,
|
|
672
|
+
...exitingMatches.filter((d) => d.status !== "error")
|
|
673
|
+
]
|
|
674
|
+
};
|
|
675
|
+
});
|
|
676
|
+
this.cleanCache();
|
|
682
677
|
});
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
[
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
(_b = (_a = this.looseRoutesById[match.routeId].options)[hook]) == null ? void 0 : _b.call(_a, match);
|
|
678
|
+
[
|
|
679
|
+
[exitingMatches, "onLeave"],
|
|
680
|
+
[enteringMatches, "onEnter"],
|
|
681
|
+
[stayingMatches, "onStay"]
|
|
682
|
+
].forEach(([matches, hook]) => {
|
|
683
|
+
matches.forEach((match) => {
|
|
684
|
+
var _a2, _b;
|
|
685
|
+
(_b = (_a2 = this.looseRoutesById[match.routeId].options)[hook]) == null ? void 0 : _b.call(_a2, match);
|
|
686
|
+
});
|
|
693
687
|
});
|
|
694
688
|
});
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
})
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
} catch (err) {
|
|
692
|
+
if (redirects.isResolvedRedirect(err)) {
|
|
693
|
+
redirect = err;
|
|
694
|
+
if (!this.isServer) {
|
|
695
|
+
this.navigate({ ...err, replace: true, __isRedirect: true });
|
|
696
|
+
}
|
|
697
|
+
} else if (notFound.isNotFound(err)) {
|
|
698
|
+
notFound$1 = err;
|
|
703
699
|
}
|
|
704
|
-
|
|
705
|
-
|
|
700
|
+
this.__store.setState((s) => ({
|
|
701
|
+
...s,
|
|
702
|
+
statusCode: redirect ? redirect.statusCode : notFound$1 ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200,
|
|
703
|
+
redirect
|
|
704
|
+
}));
|
|
706
705
|
}
|
|
707
|
-
this.
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
|
|
706
|
+
if (this.latestLoadPromise === loadPromise) {
|
|
707
|
+
(_a = this.commitLocationPromise) == null ? void 0 : _a.resolve();
|
|
708
|
+
this.latestLoadPromise = void 0;
|
|
709
|
+
this.commitLocationPromise = void 0;
|
|
710
|
+
}
|
|
711
|
+
resolve();
|
|
712
|
+
});
|
|
714
713
|
});
|
|
715
|
-
|
|
714
|
+
this.latestLoadPromise = loadPromise;
|
|
715
|
+
await loadPromise;
|
|
716
|
+
while (this.latestLoadPromise && loadPromise !== this.latestLoadPromise) {
|
|
717
|
+
await this.latestLoadPromise;
|
|
718
|
+
}
|
|
716
719
|
};
|
|
717
|
-
this.startViewTransition =
|
|
720
|
+
this.startViewTransition = (fn) => {
|
|
718
721
|
var _a, _b;
|
|
719
722
|
const shouldViewTransition = this.shouldViewTransition ?? this.options.defaultViewTransition;
|
|
720
723
|
delete this.shouldViewTransition;
|
|
721
724
|
((_b = (_a = shouldViewTransition && typeof document !== "undefined" ? document : void 0) == null ? void 0 : _a.startViewTransition) == null ? void 0 : _b.call(_a, fn)) || fn();
|
|
722
725
|
};
|
|
726
|
+
this.updateMatch = (id, updater) => {
|
|
727
|
+
var _a;
|
|
728
|
+
let updated;
|
|
729
|
+
const isPending = (_a = this.state.pendingMatches) == null ? void 0 : _a.find((d) => d.id === id);
|
|
730
|
+
const isMatched = this.state.matches.find((d) => d.id === id);
|
|
731
|
+
const matchesKey = isPending ? "pendingMatches" : isMatched ? "matches" : "cachedMatches";
|
|
732
|
+
this.__store.setState((s) => {
|
|
733
|
+
var _a2;
|
|
734
|
+
return {
|
|
735
|
+
...s,
|
|
736
|
+
[matchesKey]: (_a2 = s[matchesKey]) == null ? void 0 : _a2.map(
|
|
737
|
+
(d) => d.id === id ? updated = updater(d) : d
|
|
738
|
+
)
|
|
739
|
+
};
|
|
740
|
+
});
|
|
741
|
+
return updated;
|
|
742
|
+
};
|
|
743
|
+
this.getMatch = (matchId) => {
|
|
744
|
+
return [
|
|
745
|
+
...this.state.cachedMatches,
|
|
746
|
+
...this.state.pendingMatches ?? [],
|
|
747
|
+
...this.state.matches
|
|
748
|
+
].find((d) => d.id === matchId);
|
|
749
|
+
};
|
|
723
750
|
this.loadMatches = async ({
|
|
724
|
-
checkLatest,
|
|
725
751
|
location,
|
|
726
752
|
matches,
|
|
727
753
|
preload,
|
|
728
|
-
onReady
|
|
754
|
+
onReady,
|
|
755
|
+
updateMatch = this.updateMatch
|
|
729
756
|
}) => {
|
|
730
757
|
let firstBadMatchIndex;
|
|
731
758
|
let rendered = false;
|
|
@@ -738,41 +765,32 @@ class Router {
|
|
|
738
765
|
if (!this.isServer && !this.state.matches.length) {
|
|
739
766
|
triggerOnReady();
|
|
740
767
|
}
|
|
741
|
-
const updateMatch = (id, updater, opts) => {
|
|
742
|
-
var _a;
|
|
743
|
-
let updated;
|
|
744
|
-
const isPending = (_a = this.state.pendingMatches) == null ? void 0 : _a.find((d) => d.id === id);
|
|
745
|
-
const isMatched = this.state.matches.find((d) => d.id === id);
|
|
746
|
-
const matchesKey = isPending ? "pendingMatches" : isMatched ? "matches" : "cachedMatches";
|
|
747
|
-
this.__store.setState((s) => {
|
|
748
|
-
var _a2;
|
|
749
|
-
return {
|
|
750
|
-
...s,
|
|
751
|
-
[matchesKey]: (_a2 = s[matchesKey]) == null ? void 0 : _a2.map(
|
|
752
|
-
(d) => d.id === id ? updated = updater(d) : d
|
|
753
|
-
)
|
|
754
|
-
};
|
|
755
|
-
});
|
|
756
|
-
return updated;
|
|
757
|
-
};
|
|
758
768
|
const handleRedirectAndNotFound = (match, err) => {
|
|
769
|
+
var _a, _b, _c;
|
|
759
770
|
if (redirects.isResolvedRedirect(err)) throw err;
|
|
760
771
|
if (redirects.isRedirect(err) || notFound.isNotFound(err)) {
|
|
761
772
|
updateMatch(match.id, (prev) => ({
|
|
762
773
|
...prev,
|
|
763
774
|
status: redirects.isRedirect(err) ? "redirected" : notFound.isNotFound(err) ? "notFound" : "error",
|
|
764
775
|
isFetching: false,
|
|
765
|
-
error: err
|
|
776
|
+
error: err,
|
|
777
|
+
beforeLoadPromise: void 0,
|
|
778
|
+
loaderPromise: void 0
|
|
766
779
|
}));
|
|
767
780
|
if (!err.routeId) {
|
|
768
781
|
err.routeId = match.routeId;
|
|
769
782
|
}
|
|
783
|
+
(_a = match.beforeLoadPromise) == null ? void 0 : _a.resolve();
|
|
784
|
+
(_b = match.loaderPromise) == null ? void 0 : _b.resolve();
|
|
785
|
+
(_c = match.loadPromise) == null ? void 0 : _c.resolve();
|
|
770
786
|
if (redirects.isRedirect(err)) {
|
|
771
787
|
rendered = true;
|
|
772
788
|
err = this.resolveRedirect({ ...err, _fromLocation: location });
|
|
773
789
|
throw err;
|
|
774
790
|
} else if (notFound.isNotFound(err)) {
|
|
775
|
-
this.
|
|
791
|
+
this._handleNotFound(matches, err, {
|
|
792
|
+
updateMatch
|
|
793
|
+
});
|
|
776
794
|
throw err;
|
|
777
795
|
}
|
|
778
796
|
}
|
|
@@ -781,268 +799,293 @@ class Router {
|
|
|
781
799
|
await new Promise((resolveAll, rejectAll) => {
|
|
782
800
|
;
|
|
783
801
|
(async () => {
|
|
802
|
+
var _a, _b, _c;
|
|
784
803
|
try {
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
const
|
|
788
|
-
const
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
const shouldPending = !!(onReady && !this.isServer && !preload && (route.options.loader || route.options.beforeLoad) && typeof pendingMs === "number" && pendingMs !== Infinity && (route.options.pendingComponent ?? this.options.defaultPendingComponent));
|
|
792
|
-
if (shouldPending) {
|
|
793
|
-
setTimeout(() => {
|
|
794
|
-
try {
|
|
795
|
-
checkLatest();
|
|
796
|
-
triggerOnReady();
|
|
797
|
-
} catch {
|
|
798
|
-
}
|
|
799
|
-
}, pendingMs);
|
|
804
|
+
const handleSerialError = (index, err, routerCode) => {
|
|
805
|
+
var _a2, _b2;
|
|
806
|
+
const { id: matchId, routeId } = matches[index];
|
|
807
|
+
const route = this.looseRoutesById[routeId];
|
|
808
|
+
if (err instanceof Promise) {
|
|
809
|
+
throw err;
|
|
800
810
|
}
|
|
801
|
-
|
|
802
|
-
|
|
811
|
+
err.routerCode = routerCode;
|
|
812
|
+
firstBadMatchIndex = firstBadMatchIndex ?? index;
|
|
813
|
+
handleRedirectAndNotFound(this.getMatch(matchId), err);
|
|
814
|
+
try {
|
|
815
|
+
(_b2 = (_a2 = route.options).onError) == null ? void 0 : _b2.call(_a2, err);
|
|
816
|
+
} catch (errorHandlerErr) {
|
|
817
|
+
err = errorHandlerErr;
|
|
818
|
+
handleRedirectAndNotFound(this.getMatch(matchId), err);
|
|
803
819
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
matches[index] = match = updateMatch(match.id, (prev) => ({
|
|
810
|
-
...prev,
|
|
811
|
-
isFetching: "beforeLoad",
|
|
812
|
-
loadPromise
|
|
813
|
-
}));
|
|
814
|
-
const handleSerialError = (err, routerCode) => {
|
|
815
|
-
var _a, _b;
|
|
816
|
-
if (err instanceof Promise) {
|
|
817
|
-
throw err;
|
|
818
|
-
}
|
|
819
|
-
err.routerCode = routerCode;
|
|
820
|
-
firstBadMatchIndex = firstBadMatchIndex ?? index;
|
|
821
|
-
handleRedirectAndNotFound(match, err);
|
|
822
|
-
try {
|
|
823
|
-
(_b = (_a = route.options).onError) == null ? void 0 : _b.call(_a, err);
|
|
824
|
-
} catch (errorHandlerErr) {
|
|
825
|
-
err = errorHandlerErr;
|
|
826
|
-
handleRedirectAndNotFound(match, err);
|
|
827
|
-
}
|
|
828
|
-
matches[index] = match = updateMatch(match.id, () => ({
|
|
829
|
-
...match,
|
|
820
|
+
updateMatch(matchId, (prev) => {
|
|
821
|
+
var _a3;
|
|
822
|
+
(_a3 = prev.beforeLoadPromise) == null ? void 0 : _a3.resolve();
|
|
823
|
+
return {
|
|
824
|
+
...prev,
|
|
830
825
|
error: err,
|
|
831
826
|
status: "error",
|
|
827
|
+
isFetching: false,
|
|
832
828
|
updatedAt: Date.now(),
|
|
833
|
-
abortController: new AbortController()
|
|
834
|
-
|
|
835
|
-
};
|
|
836
|
-
if (match.paramsError) {
|
|
837
|
-
handleSerialError(match.paramsError, "PARSE_PARAMS");
|
|
838
|
-
}
|
|
839
|
-
if (match.searchError) {
|
|
840
|
-
handleSerialError(match.searchError, "VALIDATE_SEARCH");
|
|
841
|
-
}
|
|
842
|
-
try {
|
|
843
|
-
const parentContext = (parentMatch == null ? void 0 : parentMatch.context) ?? this.options.context ?? {};
|
|
844
|
-
matches[index] = match = {
|
|
845
|
-
...match,
|
|
846
|
-
routeContext: utils.replaceEqualDeep(
|
|
847
|
-
match.routeContext,
|
|
848
|
-
parentContext
|
|
849
|
-
),
|
|
850
|
-
context: utils.replaceEqualDeep(match.context, parentContext),
|
|
851
|
-
abortController
|
|
829
|
+
abortController: new AbortController(),
|
|
830
|
+
beforeLoadPromise: void 0
|
|
852
831
|
};
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
832
|
+
});
|
|
833
|
+
};
|
|
834
|
+
for (const [index, { id: matchId, routeId }] of matches.entries()) {
|
|
835
|
+
const existingMatch = this.getMatch(matchId);
|
|
836
|
+
if (
|
|
837
|
+
// If we are in the middle of a load, either of these will be present
|
|
838
|
+
// (not to be confused with `loadPromise`, which is always defined)
|
|
839
|
+
existingMatch.beforeLoadPromise || existingMatch.loaderPromise
|
|
840
|
+
) {
|
|
841
|
+
await existingMatch.beforeLoadPromise;
|
|
842
|
+
} else {
|
|
843
|
+
try {
|
|
844
|
+
updateMatch(matchId, (prev) => ({
|
|
845
|
+
...prev,
|
|
846
|
+
loadPromise: utils.createControlledPromise(() => {
|
|
847
|
+
var _a2;
|
|
848
|
+
(_a2 = prev.loadPromise) == null ? void 0 : _a2.resolve();
|
|
849
|
+
}),
|
|
850
|
+
beforeLoadPromise: utils.createControlledPromise()
|
|
851
|
+
}));
|
|
852
|
+
const route = this.looseRoutesById[routeId];
|
|
853
|
+
const abortController = new AbortController();
|
|
854
|
+
const parentMatchId = (_a = matches[index - 1]) == null ? void 0 : _a.id;
|
|
855
|
+
const getParentContext = () => {
|
|
856
|
+
if (!parentMatchId) {
|
|
857
|
+
return this.options.context ?? {};
|
|
858
|
+
}
|
|
859
|
+
return this.getMatch(parentMatchId).context ?? this.options.context ?? {};
|
|
860
|
+
};
|
|
861
|
+
const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
|
|
862
|
+
const shouldPending = !!(onReady && !this.isServer && !preload && (route.options.loader || route.options.beforeLoad) && typeof pendingMs === "number" && pendingMs !== Infinity && (route.options.pendingComponent ?? this.options.defaultPendingComponent));
|
|
863
|
+
if (shouldPending) {
|
|
864
|
+
setTimeout(() => {
|
|
865
|
+
try {
|
|
866
|
+
triggerOnReady();
|
|
867
|
+
} catch {
|
|
868
|
+
}
|
|
869
|
+
}, pendingMs);
|
|
870
|
+
}
|
|
871
|
+
const { paramsError, searchError } = this.getMatch(matchId);
|
|
872
|
+
if (paramsError) {
|
|
873
|
+
handleSerialError(index, paramsError, "PARSE_PARAMS");
|
|
874
|
+
}
|
|
875
|
+
if (searchError) {
|
|
876
|
+
handleSerialError(index, searchError, "VALIDATE_SEARCH");
|
|
877
|
+
}
|
|
878
|
+
const parentContext = getParentContext();
|
|
879
|
+
updateMatch(matchId, (prev) => ({
|
|
880
|
+
...prev,
|
|
881
|
+
isFetching: "beforeLoad",
|
|
882
|
+
fetchCount: prev.fetchCount + 1,
|
|
883
|
+
routeContext: utils.replaceEqualDeep(
|
|
884
|
+
prev.routeContext,
|
|
885
|
+
parentContext
|
|
886
|
+
),
|
|
887
|
+
context: utils.replaceEqualDeep(prev.context, parentContext),
|
|
888
|
+
abortController
|
|
889
|
+
}));
|
|
890
|
+
const { search, params, routeContext, cause } = this.getMatch(matchId);
|
|
891
|
+
const beforeLoadFnContext = {
|
|
892
|
+
search,
|
|
893
|
+
abortController,
|
|
894
|
+
params,
|
|
895
|
+
preload: !!preload,
|
|
896
|
+
context: routeContext,
|
|
897
|
+
location,
|
|
898
|
+
navigate: (opts) => this.navigate({ ...opts, _fromLocation: location }),
|
|
899
|
+
buildLocation: this.buildLocation,
|
|
900
|
+
cause: preload ? "preload" : cause
|
|
901
|
+
};
|
|
902
|
+
const beforeLoadContext = await ((_c = (_b = route.options).beforeLoad) == null ? void 0 : _c.call(_b, beforeLoadFnContext)) ?? {};
|
|
903
|
+
if (redirects.isRedirect(beforeLoadContext) || notFound.isNotFound(beforeLoadContext)) {
|
|
904
|
+
handleSerialError(index, beforeLoadContext, "BEFORE_LOAD");
|
|
905
|
+
}
|
|
906
|
+
updateMatch(matchId, (prev) => {
|
|
907
|
+
const routeContext2 = {
|
|
908
|
+
...prev.routeContext,
|
|
909
|
+
...beforeLoadContext
|
|
910
|
+
};
|
|
911
|
+
return {
|
|
912
|
+
...prev,
|
|
913
|
+
routeContext: utils.replaceEqualDeep(
|
|
914
|
+
prev.routeContext,
|
|
915
|
+
routeContext2
|
|
916
|
+
),
|
|
917
|
+
context: utils.replaceEqualDeep(prev.context, routeContext2),
|
|
918
|
+
abortController
|
|
919
|
+
};
|
|
920
|
+
});
|
|
921
|
+
} catch (err) {
|
|
922
|
+
handleSerialError(index, err, "BEFORE_LOAD");
|
|
868
923
|
}
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
),
|
|
879
|
-
context: utils.replaceEqualDeep(match.context, context),
|
|
880
|
-
abortController
|
|
881
|
-
};
|
|
882
|
-
updateMatch(match.id, () => match);
|
|
883
|
-
} catch (err) {
|
|
884
|
-
handleSerialError(err, "BEFORE_LOAD");
|
|
885
|
-
break;
|
|
924
|
+
updateMatch(matchId, (prev) => {
|
|
925
|
+
var _a2;
|
|
926
|
+
(_a2 = prev.beforeLoadPromise) == null ? void 0 : _a2.resolve();
|
|
927
|
+
return {
|
|
928
|
+
...prev,
|
|
929
|
+
beforeLoadPromise: void 0,
|
|
930
|
+
isFetching: false
|
|
931
|
+
};
|
|
932
|
+
});
|
|
886
933
|
}
|
|
887
934
|
}
|
|
888
|
-
checkLatest();
|
|
889
935
|
const validResolvedMatches = matches.slice(0, firstBadMatchIndex);
|
|
890
936
|
const matchPromises = [];
|
|
891
|
-
validResolvedMatches.forEach((
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
matches[index] = match = updateMatch(
|
|
927
|
-
match.id,
|
|
928
|
-
(prev) => ({
|
|
929
|
-
...prev,
|
|
930
|
-
isFetching: "loader",
|
|
931
|
-
fetchCount: match.fetchCount + 1
|
|
932
|
-
})
|
|
933
|
-
);
|
|
934
|
-
lazyPromise = ((_a = route.lazyFn) == null ? void 0 : _a.call(route).then((lazyRoute) => {
|
|
935
|
-
Object.assign(route.options, lazyRoute.options);
|
|
936
|
-
})) || Promise.resolve();
|
|
937
|
-
componentsPromise = lazyPromise.then(
|
|
938
|
-
() => Promise.all(
|
|
939
|
-
componentTypes.map(async (type) => {
|
|
940
|
-
const component = route.options[type];
|
|
941
|
-
if (component == null ? void 0 : component.preload) {
|
|
942
|
-
await component.preload();
|
|
943
|
-
}
|
|
944
|
-
})
|
|
945
|
-
)
|
|
946
|
-
);
|
|
947
|
-
await lazyPromise;
|
|
948
|
-
checkLatest();
|
|
949
|
-
loaderPromise = (_c = (_b = route.options).loader) == null ? void 0 : _c.call(_b, loaderContext);
|
|
950
|
-
matches[index] = match = updateMatch(
|
|
951
|
-
match.id,
|
|
952
|
-
(prev) => ({
|
|
953
|
-
...prev,
|
|
954
|
-
loaderPromise
|
|
955
|
-
})
|
|
956
|
-
);
|
|
957
|
-
}
|
|
958
|
-
let loaderData = await loaderPromise;
|
|
959
|
-
if (this.serializeLoaderData) {
|
|
960
|
-
loaderData = this.serializeLoaderData(loaderData, {
|
|
961
|
-
router: this,
|
|
962
|
-
match
|
|
963
|
-
});
|
|
964
|
-
}
|
|
965
|
-
checkLatest();
|
|
966
|
-
handleRedirectAndNotFound(match, loaderData);
|
|
967
|
-
await potentialPendingMinPromise();
|
|
968
|
-
checkLatest();
|
|
969
|
-
const meta = (_e = (_d = route.options).meta) == null ? void 0 : _e.call(_d, {
|
|
970
|
-
matches,
|
|
971
|
-
match,
|
|
972
|
-
params: match.params,
|
|
973
|
-
loaderData
|
|
974
|
-
});
|
|
975
|
-
const headers = (_g = (_f = route.options).headers) == null ? void 0 : _g.call(_f, {
|
|
976
|
-
loaderData
|
|
977
|
-
});
|
|
978
|
-
matches[index] = match = updateMatch(match.id, (prev) => ({
|
|
937
|
+
validResolvedMatches.forEach(({ id: matchId, routeId }, index) => {
|
|
938
|
+
matchPromises.push(
|
|
939
|
+
(async () => {
|
|
940
|
+
const { loaderPromise: prevLoaderPromise } = this.getMatch(matchId);
|
|
941
|
+
if (prevLoaderPromise) {
|
|
942
|
+
await prevLoaderPromise;
|
|
943
|
+
} else {
|
|
944
|
+
const parentMatchPromise = matchPromises[index - 1];
|
|
945
|
+
const route = this.looseRoutesById[routeId];
|
|
946
|
+
const getLoaderContext = () => {
|
|
947
|
+
const {
|
|
948
|
+
params,
|
|
949
|
+
loaderDeps,
|
|
950
|
+
abortController,
|
|
951
|
+
context,
|
|
952
|
+
cause
|
|
953
|
+
} = this.getMatch(matchId);
|
|
954
|
+
return {
|
|
955
|
+
params,
|
|
956
|
+
deps: loaderDeps,
|
|
957
|
+
preload: !!preload,
|
|
958
|
+
parentMatchPromise,
|
|
959
|
+
abortController,
|
|
960
|
+
context,
|
|
961
|
+
location,
|
|
962
|
+
navigate: (opts) => this.navigate({ ...opts, _fromLocation: location }),
|
|
963
|
+
cause: preload ? "preload" : cause,
|
|
964
|
+
route
|
|
965
|
+
};
|
|
966
|
+
};
|
|
967
|
+
const age = Date.now() - this.getMatch(matchId).updatedAt;
|
|
968
|
+
const staleAge = preload ? route.options.preloadStaleTime ?? this.options.defaultPreloadStaleTime ?? 3e4 : route.options.staleTime ?? this.options.defaultStaleTime ?? 0;
|
|
969
|
+
const shouldReloadOption = route.options.shouldReload;
|
|
970
|
+
const shouldReload = typeof shouldReloadOption === "function" ? shouldReloadOption(getLoaderContext()) : shouldReloadOption;
|
|
971
|
+
updateMatch(matchId, (prev) => ({
|
|
979
972
|
...prev,
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
isFetching: false,
|
|
983
|
-
updatedAt: Date.now(),
|
|
984
|
-
loaderData,
|
|
985
|
-
meta,
|
|
986
|
-
headers
|
|
973
|
+
loaderPromise: utils.createControlledPromise(),
|
|
974
|
+
preload: !!preload && !this.state.matches.find((d) => d.id === matchId)
|
|
987
975
|
}));
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
976
|
+
const runLoader = async () => {
|
|
977
|
+
var _a2, _b2, _c2, _d, _e, _f, _g, _h;
|
|
978
|
+
try {
|
|
979
|
+
const potentialPendingMinPromise = async () => {
|
|
980
|
+
const latestMatch = this.getMatch(matchId);
|
|
981
|
+
if (latestMatch.minPendingPromise) {
|
|
982
|
+
await latestMatch.minPendingPromise;
|
|
983
|
+
}
|
|
984
|
+
};
|
|
985
|
+
try {
|
|
986
|
+
route._lazyPromise = route._lazyPromise || (route.lazyFn ? route.lazyFn().then((lazyRoute) => {
|
|
987
|
+
Object.assign(
|
|
988
|
+
route.options,
|
|
989
|
+
lazyRoute.options
|
|
990
|
+
);
|
|
991
|
+
}) : Promise.resolve());
|
|
992
|
+
const componentsPromise = this.getMatch(matchId).componentsPromise || route._lazyPromise.then(
|
|
993
|
+
() => Promise.all(
|
|
994
|
+
componentTypes.map(async (type) => {
|
|
995
|
+
const component = route.options[type];
|
|
996
|
+
if (component == null ? void 0 : component.preload) {
|
|
997
|
+
await component.preload();
|
|
998
|
+
}
|
|
999
|
+
})
|
|
1000
|
+
)
|
|
1001
|
+
);
|
|
1002
|
+
updateMatch(matchId, (prev) => ({
|
|
1003
|
+
...prev,
|
|
1004
|
+
isFetching: "loader",
|
|
1005
|
+
componentsPromise
|
|
1006
|
+
}));
|
|
1007
|
+
await route._lazyPromise;
|
|
1008
|
+
let loaderData = await ((_b2 = (_a2 = route.options).loader) == null ? void 0 : _b2.call(_a2, getLoaderContext()));
|
|
1009
|
+
if (this.serializeLoaderData) {
|
|
1010
|
+
loaderData = this.serializeLoaderData(loaderData, {
|
|
1011
|
+
router: this,
|
|
1012
|
+
match: this.getMatch(matchId)
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
handleRedirectAndNotFound(
|
|
1016
|
+
this.getMatch(matchId),
|
|
1017
|
+
loaderData
|
|
1018
|
+
);
|
|
1019
|
+
await potentialPendingMinPromise();
|
|
1020
|
+
const meta = (_d = (_c2 = route.options).meta) == null ? void 0 : _d.call(_c2, {
|
|
1021
|
+
matches,
|
|
1022
|
+
match: this.getMatch(matchId),
|
|
1023
|
+
params: this.getMatch(matchId).params,
|
|
1024
|
+
loaderData
|
|
1025
|
+
});
|
|
1026
|
+
const headers = (_f = (_e = route.options).headers) == null ? void 0 : _f.call(_e, {
|
|
1027
|
+
loaderData
|
|
1028
|
+
});
|
|
1029
|
+
updateMatch(matchId, (prev) => ({
|
|
1030
|
+
...prev,
|
|
1031
|
+
error: void 0,
|
|
1032
|
+
status: "success",
|
|
1033
|
+
isFetching: false,
|
|
1034
|
+
updatedAt: Date.now(),
|
|
1035
|
+
loaderData,
|
|
1036
|
+
meta,
|
|
1037
|
+
headers
|
|
1038
|
+
}));
|
|
1039
|
+
} catch (e) {
|
|
1040
|
+
let error = e;
|
|
1041
|
+
await potentialPendingMinPromise();
|
|
1042
|
+
handleRedirectAndNotFound(this.getMatch(matchId), e);
|
|
1043
|
+
try {
|
|
1044
|
+
(_h = (_g = route.options).onError) == null ? void 0 : _h.call(_g, e);
|
|
1045
|
+
} catch (onErrorError) {
|
|
1046
|
+
error = onErrorError;
|
|
1047
|
+
handleRedirectAndNotFound(
|
|
1048
|
+
this.getMatch(matchId),
|
|
1049
|
+
onErrorError
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
1052
|
+
updateMatch(matchId, (prev) => ({
|
|
1053
|
+
...prev,
|
|
1054
|
+
error,
|
|
1055
|
+
status: "error",
|
|
1056
|
+
isFetching: false
|
|
1057
|
+
}));
|
|
1058
|
+
}
|
|
1059
|
+
await this.getMatch(matchId).componentsPromise;
|
|
1060
|
+
} catch (err) {
|
|
1061
|
+
handleRedirectAndNotFound(this.getMatch(matchId), err);
|
|
1062
|
+
}
|
|
1063
|
+
};
|
|
1064
|
+
const { status, invalid } = this.getMatch(matchId);
|
|
1065
|
+
if (status === "success" && (invalid || (shouldReload ?? age > staleAge))) {
|
|
1066
|
+
;
|
|
1067
|
+
(async () => {
|
|
1068
|
+
try {
|
|
1069
|
+
await runLoader();
|
|
1070
|
+
} catch (err) {
|
|
1071
|
+
}
|
|
1072
|
+
})();
|
|
1073
|
+
} else if (status !== "success") {
|
|
1074
|
+
await runLoader();
|
|
999
1075
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
status: "error",
|
|
1004
|
-
isFetching: false
|
|
1005
|
-
}));
|
|
1076
|
+
const { loaderPromise, loadPromise } = this.getMatch(matchId);
|
|
1077
|
+
loaderPromise == null ? void 0 : loaderPromise.resolve();
|
|
1078
|
+
loadPromise == null ? void 0 : loadPromise.resolve();
|
|
1006
1079
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
const shouldReload = typeof shouldReloadOption === "function" ? shouldReloadOption(loaderContext) : shouldReloadOption;
|
|
1015
|
-
matches[index] = match = {
|
|
1016
|
-
...match,
|
|
1017
|
-
preload: !!preload && !this.state.matches.find((d) => d.id === match.id)
|
|
1018
|
-
};
|
|
1019
|
-
const fetchWithRedirectAndNotFound = async () => {
|
|
1020
|
-
try {
|
|
1021
|
-
await fetchAndResolveInLoaderLifetime();
|
|
1022
|
-
} catch (err) {
|
|
1023
|
-
checkLatest();
|
|
1024
|
-
handleRedirectAndNotFound(match, err);
|
|
1025
|
-
}
|
|
1026
|
-
};
|
|
1027
|
-
if (match.status === "success" && (match.invalid || (shouldReload ?? age > staleAge))) {
|
|
1028
|
-
;
|
|
1029
|
-
(async () => {
|
|
1030
|
-
try {
|
|
1031
|
-
await fetchWithRedirectAndNotFound();
|
|
1032
|
-
} catch (err) {
|
|
1033
|
-
}
|
|
1034
|
-
})();
|
|
1035
|
-
return;
|
|
1036
|
-
}
|
|
1037
|
-
if (match.status !== "success") {
|
|
1038
|
-
await fetchWithRedirectAndNotFound();
|
|
1039
|
-
}
|
|
1040
|
-
return;
|
|
1041
|
-
};
|
|
1042
|
-
matchPromises.push(createValidateResolvedMatchPromise());
|
|
1080
|
+
updateMatch(matchId, (prev) => ({
|
|
1081
|
+
...prev,
|
|
1082
|
+
isFetching: false,
|
|
1083
|
+
loaderPromise: void 0
|
|
1084
|
+
}));
|
|
1085
|
+
})()
|
|
1086
|
+
);
|
|
1043
1087
|
});
|
|
1044
1088
|
await Promise.all(matchPromises);
|
|
1045
|
-
checkLatest();
|
|
1046
1089
|
resolveAll();
|
|
1047
1090
|
} catch (err) {
|
|
1048
1091
|
rejectAll(err);
|
|
@@ -1064,7 +1107,7 @@ class Router {
|
|
|
1064
1107
|
const invalidate = (d) => ({
|
|
1065
1108
|
...d,
|
|
1066
1109
|
invalid: true,
|
|
1067
|
-
...d.status === "error" ? { status: "pending" } : {}
|
|
1110
|
+
...d.status === "error" ? { status: "pending", error: void 0 } : {}
|
|
1068
1111
|
});
|
|
1069
1112
|
this.__store.setState((s) => {
|
|
1070
1113
|
var _a;
|
|
@@ -1122,18 +1165,23 @@ class Router {
|
|
|
1122
1165
|
}
|
|
1123
1166
|
});
|
|
1124
1167
|
});
|
|
1125
|
-
const
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
}
|
|
1168
|
+
const activeMatchIds = new Set(
|
|
1169
|
+
[...this.state.matches, ...this.state.pendingMatches ?? []].map(
|
|
1170
|
+
(d) => d.id
|
|
1171
|
+
)
|
|
1172
|
+
);
|
|
1131
1173
|
try {
|
|
1132
1174
|
matches = await this.loadMatches({
|
|
1133
1175
|
matches,
|
|
1134
1176
|
location: next,
|
|
1135
1177
|
preload: true,
|
|
1136
|
-
|
|
1178
|
+
updateMatch: (id, updater) => {
|
|
1179
|
+
if (activeMatchIds.has(id)) {
|
|
1180
|
+
matches = matches.map((d) => d.id === id ? updater(d) : d);
|
|
1181
|
+
} else {
|
|
1182
|
+
this.updateMatch(id, updater);
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1137
1185
|
});
|
|
1138
1186
|
return matches;
|
|
1139
1187
|
} catch (err) {
|
|
@@ -1201,7 +1249,7 @@ class Router {
|
|
|
1201
1249
|
manifest: this.manifest
|
|
1202
1250
|
};
|
|
1203
1251
|
};
|
|
1204
|
-
this.hydrate =
|
|
1252
|
+
this.hydrate = () => {
|
|
1205
1253
|
var _a, _b, _c;
|
|
1206
1254
|
let ctx;
|
|
1207
1255
|
if (typeof document !== "undefined") {
|
|
@@ -1274,7 +1322,9 @@ class Router {
|
|
|
1274
1322
|
${children}\`)` : ""}; __TSR__.cleanScripts()<\/script>`
|
|
1275
1323
|
);
|
|
1276
1324
|
};
|
|
1277
|
-
this.
|
|
1325
|
+
this._handleNotFound = (matches, err, {
|
|
1326
|
+
updateMatch = this.updateMatch
|
|
1327
|
+
} = {}) => {
|
|
1278
1328
|
const matchesByRouteId = Object.fromEntries(
|
|
1279
1329
|
matches.map((match2) => [match2.routeId, match2])
|
|
1280
1330
|
);
|
|
@@ -1288,11 +1338,18 @@ class Router {
|
|
|
1288
1338
|
}
|
|
1289
1339
|
const match = matchesByRouteId[routeCursor.id];
|
|
1290
1340
|
invariant(match, "Could not find match for route: " + routeCursor.id);
|
|
1291
|
-
|
|
1341
|
+
updateMatch(match.id, (prev) => ({
|
|
1342
|
+
...prev,
|
|
1292
1343
|
status: "notFound",
|
|
1293
1344
|
error: err,
|
|
1294
1345
|
isFetching: false
|
|
1295
|
-
});
|
|
1346
|
+
}));
|
|
1347
|
+
if (err.routerCode === "BEFORE_LOAD" && routeCursor.parentRoute) {
|
|
1348
|
+
err.routeId = routeCursor.parentRoute.id;
|
|
1349
|
+
this._handleNotFound(matches, err, {
|
|
1350
|
+
updateMatch
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1296
1353
|
};
|
|
1297
1354
|
this.hasNotFoundMatch = () => {
|
|
1298
1355
|
return this.__store.state.matches.some(
|
|
@@ -1318,11 +1375,6 @@ class Router {
|
|
|
1318
1375
|
get looseRoutesById() {
|
|
1319
1376
|
return this.routesById;
|
|
1320
1377
|
}
|
|
1321
|
-
// resolveMatchPromise = (matchId: string, key: string, value: any) => {
|
|
1322
|
-
// state.matches
|
|
1323
|
-
// .find((d) => d.id === matchId)
|
|
1324
|
-
// ?.__promisesByKey[key]?.resolve(value)
|
|
1325
|
-
// }
|
|
1326
1378
|
}
|
|
1327
1379
|
function lazyFn(fn, key) {
|
|
1328
1380
|
return async (...args) => {
|
|
@@ -1336,6 +1388,7 @@ class PathParamError extends Error {
|
|
|
1336
1388
|
}
|
|
1337
1389
|
function getInitialRouterState(location) {
|
|
1338
1390
|
return {
|
|
1391
|
+
loadedAt: 0,
|
|
1339
1392
|
isLoading: false,
|
|
1340
1393
|
isTransitioning: false,
|
|
1341
1394
|
status: "idle",
|