@tanstack/react-router 0.0.1-beta.205 → 0.0.1-beta.207
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/build/cjs/RouterProvider.js +59 -55
- package/build/cjs/RouterProvider.js.map +1 -1
- package/build/cjs/react.js +2 -1
- package/build/cjs/react.js.map +1 -1
- package/build/cjs/router.js.map +1 -1
- package/build/esm/index.js +61 -56
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +167 -167
- package/build/types/router.d.ts +3 -0
- package/build/umd/index.development.js +61 -56
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -4
- package/src/RouterProvider.tsx +73 -70
- package/src/react.tsx +2 -1
- package/src/router.ts +2 -0
|
@@ -46,6 +46,9 @@ var invariant__default = /*#__PURE__*/_interopDefaultLegacy(invariant);
|
|
|
46
46
|
|
|
47
47
|
const preloadWarning = 'Error preloading route! ☝️';
|
|
48
48
|
const routerContext = /*#__PURE__*/React__namespace.createContext(null);
|
|
49
|
+
if (typeof document !== 'undefined') {
|
|
50
|
+
window.__TSR_ROUTER_CONTEXT__ = routerContext;
|
|
51
|
+
}
|
|
49
52
|
function getInitialRouterState(location) {
|
|
50
53
|
return {
|
|
51
54
|
status: 'idle',
|
|
@@ -73,6 +76,10 @@ function RouterProvider({
|
|
|
73
76
|
const tempLocationKeyRef = React__namespace.useRef(`${Math.round(Math.random() * 10000000)}`);
|
|
74
77
|
const resetNextScrollRef = React__namespace.useRef(false);
|
|
75
78
|
const navigateTimeoutRef = React__namespace.useRef(null);
|
|
79
|
+
const latestLoadPromiseRef = React__namespace.useRef(Promise.resolve());
|
|
80
|
+
const checkLatest = promise => {
|
|
81
|
+
return latestLoadPromiseRef.current !== promise ? latestLoadPromiseRef.current : undefined;
|
|
82
|
+
};
|
|
76
83
|
const parseLocation = utils.useStableCallback(previousLocation => {
|
|
77
84
|
const parse = ({
|
|
78
85
|
pathname,
|
|
@@ -196,7 +203,6 @@ function RouterProvider({
|
|
|
196
203
|
d.child.rank = i;
|
|
197
204
|
return d.child;
|
|
198
205
|
}), [routesByPath]);
|
|
199
|
-
const latestLoadPromiseRef = React__namespace.useRef(Promise.resolve());
|
|
200
206
|
const matchRoutes = utils.useStableCallback((pathname, locationSearch, opts) => {
|
|
201
207
|
let routeParams = {};
|
|
202
208
|
let foundRoute = flatRoutes.find(route => {
|
|
@@ -329,7 +335,7 @@ function RouterProvider({
|
|
|
329
335
|
});
|
|
330
336
|
const buildLocation = utils.useStableCallback((opts = {}) => {
|
|
331
337
|
const build = (dest = {}, matches) => {
|
|
332
|
-
const from =
|
|
338
|
+
const from = latestLocationRef.current;
|
|
333
339
|
const fromPathname = dest.from ?? from.pathname;
|
|
334
340
|
let pathname = resolvePathWithBase(fromPathname, `${dest.to ?? ''}`);
|
|
335
341
|
const fromMatches = matchRoutes(fromPathname, from.search);
|
|
@@ -422,7 +428,7 @@ function RouterProvider({
|
|
|
422
428
|
});
|
|
423
429
|
const commitLocation = utils.useStableCallback(async next => {
|
|
424
430
|
if (navigateTimeoutRef.current) clearTimeout(navigateTimeoutRef.current);
|
|
425
|
-
const isSameUrl =
|
|
431
|
+
const isSameUrl = latestLocationRef.current.href === next.href;
|
|
426
432
|
|
|
427
433
|
// If the next urls are the same and we're not replacing,
|
|
428
434
|
// do nothing
|
|
@@ -495,9 +501,11 @@ function RouterProvider({
|
|
|
495
501
|
});
|
|
496
502
|
});
|
|
497
503
|
const loadMatches = utils.useStableCallback(async ({
|
|
504
|
+
checkLatest,
|
|
498
505
|
matches,
|
|
499
506
|
preload
|
|
500
507
|
}) => {
|
|
508
|
+
let latestPromise;
|
|
501
509
|
let firstBadMatchIndex;
|
|
502
510
|
|
|
503
511
|
// Check each match middleware to see if the route can be accessed
|
|
@@ -540,7 +548,7 @@ function RouterProvider({
|
|
|
540
548
|
params: match.params,
|
|
541
549
|
preload: !!preload,
|
|
542
550
|
meta: parentMeta,
|
|
543
|
-
location: state.location
|
|
551
|
+
location: state.location // TODO: This might need to be latestLocationRef.current...?
|
|
544
552
|
})) ?? {};
|
|
545
553
|
const meta = {
|
|
546
554
|
...parentMeta,
|
|
@@ -558,7 +566,7 @@ function RouterProvider({
|
|
|
558
566
|
} catch (err) {
|
|
559
567
|
if (redirects.isRedirect(err)) {
|
|
560
568
|
if (!preload) navigate(err);
|
|
561
|
-
return;
|
|
569
|
+
return matches;
|
|
562
570
|
}
|
|
563
571
|
throw err;
|
|
564
572
|
}
|
|
@@ -571,11 +579,6 @@ function RouterProvider({
|
|
|
571
579
|
if (match.isFetching) {
|
|
572
580
|
return getRouteMatch(state, match.id)?.loadPromise;
|
|
573
581
|
}
|
|
574
|
-
const fetchedAt = Date.now();
|
|
575
|
-
const checkLatest = () => {
|
|
576
|
-
const latest = getRouteMatch(state, match.id);
|
|
577
|
-
return latest && latest.fetchedAt !== fetchedAt ? latest.loadPromise : undefined;
|
|
578
|
-
};
|
|
579
582
|
const handleIfRedirect = err => {
|
|
580
583
|
if (redirects.isRedirect(err)) {
|
|
581
584
|
if (!preload) {
|
|
@@ -586,7 +589,6 @@ function RouterProvider({
|
|
|
586
589
|
return false;
|
|
587
590
|
};
|
|
588
591
|
const load = async () => {
|
|
589
|
-
let latestPromise;
|
|
590
592
|
try {
|
|
591
593
|
const componentsPromise = Promise.all(router.componentTypes.map(async type => {
|
|
592
594
|
const component = route.options[type];
|
|
@@ -628,12 +630,18 @@ function RouterProvider({
|
|
|
628
630
|
updatedAt: Date.now()
|
|
629
631
|
};
|
|
630
632
|
}
|
|
633
|
+
if (!preload) {
|
|
634
|
+
setState(s => ({
|
|
635
|
+
...s,
|
|
636
|
+
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
637
|
+
}));
|
|
638
|
+
}
|
|
631
639
|
};
|
|
632
640
|
let loadPromise;
|
|
633
641
|
matches[index] = match = {
|
|
634
642
|
...match,
|
|
635
643
|
isFetching: true,
|
|
636
|
-
fetchedAt,
|
|
644
|
+
fetchedAt: Date.now(),
|
|
637
645
|
invalid: false
|
|
638
646
|
};
|
|
639
647
|
loadPromise = load();
|
|
@@ -645,35 +653,32 @@ function RouterProvider({
|
|
|
645
653
|
})());
|
|
646
654
|
});
|
|
647
655
|
await Promise.all(matchPromises);
|
|
656
|
+
return matches;
|
|
648
657
|
});
|
|
649
|
-
const load = utils.useStableCallback(async
|
|
658
|
+
const load = utils.useStableCallback(async () => {
|
|
650
659
|
const promise = new Promise(async (resolve, reject) => {
|
|
660
|
+
const next = latestLocationRef.current;
|
|
651
661
|
const prevLocation = state.resolvedLocation;
|
|
652
|
-
const pathDidChange = !!(
|
|
662
|
+
const pathDidChange = !!(next && prevLocation.href !== next.href);
|
|
653
663
|
let latestPromise;
|
|
654
|
-
const checkLatest = () => {
|
|
655
|
-
return latestLoadPromiseRef.current !== promise ? latestLoadPromiseRef.current : undefined;
|
|
656
|
-
};
|
|
657
664
|
|
|
658
665
|
// Cancel any pending matches
|
|
659
666
|
cancelMatches(state);
|
|
660
667
|
router$1.emit({
|
|
661
668
|
type: 'onBeforeLoad',
|
|
662
669
|
from: prevLocation,
|
|
663
|
-
to:
|
|
670
|
+
to: next ?? state.location,
|
|
664
671
|
pathChanged: pathDidChange
|
|
665
672
|
});
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
}
|
|
673
|
+
|
|
674
|
+
// Ingest the new location
|
|
675
|
+
setState(s => ({
|
|
676
|
+
...s,
|
|
677
|
+
location: next
|
|
678
|
+
}));
|
|
673
679
|
|
|
674
680
|
// Match the routes
|
|
675
|
-
|
|
676
|
-
throwOnError: opts?.throwOnError,
|
|
681
|
+
let matches = matchRoutes(next.pathname, next.search, {
|
|
677
682
|
debug: true
|
|
678
683
|
});
|
|
679
684
|
setState(s => ({
|
|
@@ -682,10 +687,11 @@ function RouterProvider({
|
|
|
682
687
|
matches
|
|
683
688
|
}));
|
|
684
689
|
try {
|
|
685
|
-
// Load the matches
|
|
686
690
|
try {
|
|
691
|
+
// Load the matches
|
|
687
692
|
await loadMatches({
|
|
688
|
-
matches
|
|
693
|
+
matches,
|
|
694
|
+
checkLatest: () => checkLatest(promise)
|
|
689
695
|
});
|
|
690
696
|
} catch (err) {
|
|
691
697
|
// swallow this error, since we'll display the
|
|
@@ -693,7 +699,7 @@ function RouterProvider({
|
|
|
693
699
|
}
|
|
694
700
|
|
|
695
701
|
// Only apply the latest transition
|
|
696
|
-
if (latestPromise = checkLatest()) {
|
|
702
|
+
if (latestPromise = checkLatest(promise)) {
|
|
697
703
|
return latestPromise;
|
|
698
704
|
}
|
|
699
705
|
|
|
@@ -730,13 +736,13 @@ function RouterProvider({
|
|
|
730
736
|
router$1.emit({
|
|
731
737
|
type: 'onLoad',
|
|
732
738
|
from: prevLocation,
|
|
733
|
-
to:
|
|
739
|
+
to: next,
|
|
734
740
|
pathChanged: pathDidChange
|
|
735
741
|
});
|
|
736
742
|
resolve();
|
|
737
743
|
} catch (err) {
|
|
738
744
|
// Only apply the latest transition
|
|
739
|
-
if (latestPromise = checkLatest()) {
|
|
745
|
+
if (latestPromise = checkLatest(promise)) {
|
|
740
746
|
return latestPromise;
|
|
741
747
|
}
|
|
742
748
|
reject(err);
|
|
@@ -745,13 +751,6 @@ function RouterProvider({
|
|
|
745
751
|
latestLoadPromiseRef.current = promise;
|
|
746
752
|
return latestLoadPromiseRef.current;
|
|
747
753
|
});
|
|
748
|
-
const safeLoad = React__namespace.useCallback(async () => {
|
|
749
|
-
try {
|
|
750
|
-
return load();
|
|
751
|
-
} catch (err) {
|
|
752
|
-
// Don't do anything
|
|
753
|
-
}
|
|
754
|
-
}, []);
|
|
755
754
|
const preloadRoute = utils.useStableCallback(async (navigateOpts = state.location) => {
|
|
756
755
|
let next = buildLocation(navigateOpts);
|
|
757
756
|
let matches = matchRoutes(next.pathname, next.search, {
|
|
@@ -759,7 +758,8 @@ function RouterProvider({
|
|
|
759
758
|
});
|
|
760
759
|
await loadMatches({
|
|
761
760
|
matches,
|
|
762
|
-
preload: true
|
|
761
|
+
preload: true,
|
|
762
|
+
checkLatest: () => undefined
|
|
763
763
|
});
|
|
764
764
|
return [utils.last(matches), matches];
|
|
765
765
|
});
|
|
@@ -793,13 +793,13 @@ function RouterProvider({
|
|
|
793
793
|
const preloadDelay = userPreloadDelay ?? options.defaultPreloadDelay ?? 0;
|
|
794
794
|
|
|
795
795
|
// Compare path/hash for matches
|
|
796
|
-
const currentPathSplit =
|
|
796
|
+
const currentPathSplit = latestLocationRef.current.pathname.split('/');
|
|
797
797
|
const nextPathSplit = next.pathname.split('/');
|
|
798
798
|
const pathIsFuzzyEqual = nextPathSplit.every((d, i) => d === currentPathSplit[i]);
|
|
799
799
|
// Combine the matches based on user options
|
|
800
|
-
const pathTest = activeOptions?.exact ?
|
|
801
|
-
const hashTest = activeOptions?.includeHash ?
|
|
802
|
-
const searchTest = activeOptions?.includeSearch ?? true ? utils.partialDeepEqual(
|
|
800
|
+
const pathTest = activeOptions?.exact ? latestLocationRef.current.pathname === next.pathname : pathIsFuzzyEqual;
|
|
801
|
+
const hashTest = activeOptions?.includeHash ? latestLocationRef.current.hash === next.hash : true;
|
|
802
|
+
const searchTest = activeOptions?.includeSearch ?? true ? utils.partialDeepEqual(latestLocationRef.current.search, next.search) : true;
|
|
803
803
|
|
|
804
804
|
// The final "active" test
|
|
805
805
|
const isActive = pathTest && hashTest && searchTest;
|
|
@@ -867,13 +867,18 @@ function RouterProvider({
|
|
|
867
867
|
disabled
|
|
868
868
|
};
|
|
869
869
|
});
|
|
870
|
+
const latestLocationRef = React__namespace.useRef(state.location);
|
|
870
871
|
React__namespace.useLayoutEffect(() => {
|
|
871
872
|
const unsub = history$1.subscribe(() => {
|
|
873
|
+
latestLocationRef.current = parseLocation(latestLocationRef.current);
|
|
872
874
|
React__namespace.startTransition(() => {
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
875
|
+
if (state.location !== latestLocationRef.current) {
|
|
876
|
+
try {
|
|
877
|
+
load();
|
|
878
|
+
} catch (err) {
|
|
879
|
+
console.error(err);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
877
882
|
});
|
|
878
883
|
});
|
|
879
884
|
const nextLocation = buildLocation({
|
|
@@ -895,13 +900,12 @@ function RouterProvider({
|
|
|
895
900
|
const initialLoad = React__namespace.useRef(true);
|
|
896
901
|
if (initialLoad.current) {
|
|
897
902
|
initialLoad.current = false;
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
safeLoad();
|
|
903
|
+
try {
|
|
904
|
+
load();
|
|
905
|
+
} catch (err) {
|
|
906
|
+
console.error(err);
|
|
903
907
|
}
|
|
904
|
-
}
|
|
908
|
+
}
|
|
905
909
|
React__namespace.useMemo(() => [...state.matches, ...state.pendingMatches].some(d => d.isFetching), [state.matches, state.pendingMatches]);
|
|
906
910
|
const matchRoute = utils.useStableCallback((state, location, opts) => {
|
|
907
911
|
location = {
|
|
@@ -912,7 +916,7 @@ function RouterProvider({
|
|
|
912
916
|
if (opts?.pending && state.status !== 'pending') {
|
|
913
917
|
return false;
|
|
914
918
|
}
|
|
915
|
-
const baseLocation = opts?.pending ?
|
|
919
|
+
const baseLocation = opts?.pending ? latestLocationRef.current : state.resolvedLocation;
|
|
916
920
|
if (!baseLocation) {
|
|
917
921
|
return false;
|
|
918
922
|
}
|