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