@tanstack/react-router 0.0.1-beta.272 → 0.0.1-beta.274
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/Matches.js.map +1 -1
- package/build/cjs/RouterProvider.js +14 -9
- package/build/cjs/RouterProvider.js.map +1 -1
- package/build/cjs/index.js +4 -1
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/route.js.map +1 -1
- package/build/cjs/router.js +150 -100
- package/build/cjs/router.js.map +1 -1
- package/build/esm/index.js +162 -106
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +353 -353
- package/build/types/Matches.d.ts +2 -2
- package/build/types/RouterProvider.d.ts +1 -1
- package/build/types/route.d.ts +2 -2
- package/build/types/router.d.ts +3 -1
- package/build/umd/index.development.js +164 -109
- 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 -2
- package/src/Matches.tsx +2 -2
- package/src/RouterProvider.tsx +18 -10
- package/src/route.ts +2 -2
- package/src/router.ts +197 -128
package/build/types/Matches.d.ts
CHANGED
|
@@ -22,10 +22,10 @@ export interface RouteMatch<TRouteTree extends AnyRoute = AnyRoute, TRouteId ext
|
|
|
22
22
|
routeContext: RouteById<TRouteTree, TRouteId>['types']['routeContext'];
|
|
23
23
|
context: RouteById<TRouteTree, TRouteId>['types']['allContext'];
|
|
24
24
|
search: FullSearchSchema<TRouteTree> & RouteById<TRouteTree, TRouteId>['types']['fullSearchSchema'];
|
|
25
|
-
|
|
25
|
+
fetchCount: number;
|
|
26
26
|
shouldReloadDeps: any;
|
|
27
27
|
abortController: AbortController;
|
|
28
|
-
cause: 'enter' | 'stay';
|
|
28
|
+
cause: 'preload' | 'enter' | 'stay';
|
|
29
29
|
}
|
|
30
30
|
export type AnyRouteMatch = RouteMatch<any>;
|
|
31
31
|
export declare function Matches(): React.JSX.Element;
|
|
@@ -22,7 +22,7 @@ export type NavigateFn<TRouteTree extends AnyRoute> = <TFrom extends RoutePaths<
|
|
|
22
22
|
export type MatchRouteFn<TRouteTree extends AnyRoute> = <TFrom extends RoutePaths<TRouteTree> = '/', TTo extends string = '', TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>>(location: ToOptions<TRouteTree, TFrom, TTo>, opts?: MatchRouteOptions) => false | RouteById<TRouteTree, TResolved>['types']['allParams'];
|
|
23
23
|
export type BuildLocationFn<TRouteTree extends AnyRoute> = (opts: BuildNextOptions) => ParsedLocation;
|
|
24
24
|
export type InjectedHtmlEntry = string | (() => Promise<string> | string);
|
|
25
|
-
export declare
|
|
25
|
+
export declare let routerContext: React.Context<Router<any, Record<string, any>>>;
|
|
26
26
|
export declare function RouterProvider<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TDehydrated extends Record<string, any> = Record<string, any>>({ router, ...rest }: RouterProps<TRouteTree, TDehydrated>): React.JSX.Element;
|
|
27
27
|
export declare function getRouteMatch<TRouteTree extends AnyRoute>(state: RouterState<TRouteTree>, id: string): undefined | RouteMatch<TRouteTree>;
|
|
28
28
|
export declare function useRouterState<TSelected = RouterState<RegisteredRouter['routeTree']>>(opts?: {
|
package/build/types/route.d.ts
CHANGED
|
@@ -61,7 +61,7 @@ type BeforeLoadFn<TFullSearchSchema extends Record<string, any>, TParentRoute ex
|
|
|
61
61
|
location: ParsedLocation;
|
|
62
62
|
navigate: NavigateFn<AnyRoute>;
|
|
63
63
|
buildLocation: BuildLocationFn<AnyRoute>;
|
|
64
|
-
cause: 'enter' | 'stay';
|
|
64
|
+
cause: 'preload' | 'enter' | 'stay';
|
|
65
65
|
}) => Promise<TRouteContext> | TRouteContext | void;
|
|
66
66
|
export type UpdatableRouteOptions<TFullSearchSchema extends Record<string, any>> = MetaOptions & {
|
|
67
67
|
caseSensitive?: boolean;
|
|
@@ -102,7 +102,7 @@ export interface LoaderFnContext<TAllParams = {}, TFullSearchSchema extends Reco
|
|
|
102
102
|
location: ParsedLocation<TFullSearchSchema>;
|
|
103
103
|
navigate: (opts: NavigateOptions<AnyRoute>) => Promise<void>;
|
|
104
104
|
parentMatchPromise?: Promise<void>;
|
|
105
|
-
cause: 'enter' | 'stay';
|
|
105
|
+
cause: 'preload' | 'enter' | 'stay';
|
|
106
106
|
}
|
|
107
107
|
export type SearchFilter<T, U = T> = (prev: T) => U;
|
|
108
108
|
export type ResolveId<TParentRoute, TCustomId extends string, TPath extends string> = TParentRoute extends {
|
package/build/types/router.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export interface RouterOptions<TRouteTree extends AnyRoute, TDehydrated extends
|
|
|
41
41
|
defaultPendingComponent?: RouteComponent;
|
|
42
42
|
defaultPendingMs?: number;
|
|
43
43
|
defaultPendingMinMs?: number;
|
|
44
|
+
defaultPreloadMaxAge?: number;
|
|
44
45
|
caseSensitive?: boolean;
|
|
45
46
|
routeTree?: TRouteTree;
|
|
46
47
|
basepath?: string;
|
|
@@ -63,6 +64,7 @@ export interface RouterState<TRouteTree extends AnyRoute = AnyRoute> {
|
|
|
63
64
|
isTransitioning: boolean;
|
|
64
65
|
matches: RouteMatch<TRouteTree>[];
|
|
65
66
|
pendingMatches?: RouteMatch<TRouteTree>[];
|
|
67
|
+
preloadMatches: RouteMatch<TRouteTree>[];
|
|
66
68
|
location: ParsedLocation<FullSearchSchema<TRouteTree>>;
|
|
67
69
|
resolvedLocation: ParsedLocation<FullSearchSchema<TRouteTree>>;
|
|
68
70
|
lastUpdated: number;
|
|
@@ -87,7 +89,7 @@ export interface BuildNextOptions {
|
|
|
87
89
|
export interface DehydratedRouterState {
|
|
88
90
|
dehydratedMatches: DehydratedRouteMatch[];
|
|
89
91
|
}
|
|
90
|
-
export type DehydratedRouteMatch = Pick<RouteMatch, '
|
|
92
|
+
export type DehydratedRouteMatch = Pick<RouteMatch, 'id' | 'status' | 'updatedAt'>;
|
|
91
93
|
export interface DehydratedRouter {
|
|
92
94
|
state: DehydratedRouterState;
|
|
93
95
|
}
|
|
@@ -1080,9 +1080,13 @@
|
|
|
1080
1080
|
});
|
|
1081
1081
|
}
|
|
1082
1082
|
|
|
1083
|
-
|
|
1083
|
+
exports.routerContext = /*#__PURE__*/React__namespace.createContext(null);
|
|
1084
1084
|
if (typeof document !== 'undefined') {
|
|
1085
|
-
window.__TSR_ROUTER_CONTEXT__
|
|
1085
|
+
if (window.__TSR_ROUTER_CONTEXT__) {
|
|
1086
|
+
exports.routerContext = window.__TSR_ROUTER_CONTEXT__;
|
|
1087
|
+
} else {
|
|
1088
|
+
window.__TSR_ROUTER_CONTEXT__ = exports.routerContext;
|
|
1089
|
+
}
|
|
1086
1090
|
}
|
|
1087
1091
|
function RouterProvider({
|
|
1088
1092
|
router,
|
|
@@ -1098,7 +1102,7 @@
|
|
|
1098
1102
|
}
|
|
1099
1103
|
});
|
|
1100
1104
|
const matches = router.options.InnerWrap ? /*#__PURE__*/React__namespace.createElement(router.options.InnerWrap, null, /*#__PURE__*/React__namespace.createElement(Matches, null)) : /*#__PURE__*/React__namespace.createElement(Matches, null);
|
|
1101
|
-
const provider = /*#__PURE__*/React__namespace.createElement(routerContext.Provider, {
|
|
1105
|
+
const provider = /*#__PURE__*/React__namespace.createElement(exports.routerContext.Provider, {
|
|
1102
1106
|
value: router
|
|
1103
1107
|
}, matches, /*#__PURE__*/React__namespace.createElement(Transitioner, null));
|
|
1104
1108
|
if (router.options.Wrap) {
|
|
@@ -1169,9 +1173,11 @@
|
|
|
1169
1173
|
pathChanged: routerState.location.href !== routerState.resolvedLocation?.href
|
|
1170
1174
|
});
|
|
1171
1175
|
if (document.querySelector) {
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
el
|
|
1176
|
+
if (routerState.location.hash !== '') {
|
|
1177
|
+
const el = document.getElementById(routerState.location.hash);
|
|
1178
|
+
if (el) {
|
|
1179
|
+
el.scrollIntoView();
|
|
1180
|
+
}
|
|
1175
1181
|
}
|
|
1176
1182
|
}
|
|
1177
1183
|
router.pendingMatches = [];
|
|
@@ -1190,14 +1196,14 @@
|
|
|
1190
1196
|
return null;
|
|
1191
1197
|
}
|
|
1192
1198
|
function getRouteMatch(state, id) {
|
|
1193
|
-
return [...(state.pendingMatches ?? []), ...state.matches].find(d => d.id === id);
|
|
1199
|
+
return [...state.preloadMatches, ...(state.pendingMatches ?? []), ...state.matches].find(d => d.id === id);
|
|
1194
1200
|
}
|
|
1195
1201
|
function useRouterState(opts) {
|
|
1196
1202
|
const router = useRouter();
|
|
1197
1203
|
return useStore(router.__store, opts?.select);
|
|
1198
1204
|
}
|
|
1199
1205
|
function useRouter() {
|
|
1200
|
-
const resolvedContext = typeof document !== 'undefined' ? window.__TSR_ROUTER_CONTEXT__ || routerContext : routerContext;
|
|
1206
|
+
const resolvedContext = typeof document !== 'undefined' ? window.__TSR_ROUTER_CONTEXT__ || exports.routerContext : exports.routerContext;
|
|
1201
1207
|
const value = React__namespace.useContext(resolvedContext);
|
|
1202
1208
|
warning(value, 'useRouter must be used inside a <RouterProvider> component!');
|
|
1203
1209
|
return value;
|
|
@@ -2294,7 +2300,7 @@
|
|
|
2294
2300
|
context: undefined,
|
|
2295
2301
|
abortController: new AbortController(),
|
|
2296
2302
|
shouldReloadDeps: undefined,
|
|
2297
|
-
|
|
2303
|
+
fetchCount: 0,
|
|
2298
2304
|
cause
|
|
2299
2305
|
};
|
|
2300
2306
|
|
|
@@ -2503,10 +2509,13 @@
|
|
|
2503
2509
|
}) => {
|
|
2504
2510
|
let latestPromise;
|
|
2505
2511
|
let firstBadMatchIndex;
|
|
2506
|
-
const
|
|
2512
|
+
const updateMatch = match => {
|
|
2513
|
+
const isPreload = this.state.preloadMatches.find(d => d.id === match.id);
|
|
2514
|
+
const isPending = this.state.pendingMatches?.find(d => d.id === match.id);
|
|
2515
|
+
const matchesKey = isPreload ? 'preloadMatches' : isPending ? 'pendingMatches' : 'matches';
|
|
2507
2516
|
this.__store.setState(s => ({
|
|
2508
2517
|
...s,
|
|
2509
|
-
|
|
2518
|
+
[matchesKey]: s[matchesKey]?.map(d => d.id === match.id ? match : d)
|
|
2510
2519
|
}));
|
|
2511
2520
|
};
|
|
2512
2521
|
|
|
@@ -2559,7 +2568,7 @@
|
|
|
2559
2568
|
from: match.pathname
|
|
2560
2569
|
}),
|
|
2561
2570
|
buildLocation: this.buildLocation,
|
|
2562
|
-
cause: match.cause
|
|
2571
|
+
cause: preload ? 'preload' : match.cause
|
|
2563
2572
|
})) ?? {};
|
|
2564
2573
|
if (isRedirect(beforeLoadContext)) {
|
|
2565
2574
|
throw beforeLoadContext;
|
|
@@ -2589,7 +2598,7 @@
|
|
|
2589
2598
|
const validResolvedMatches = matches.slice(0, firstBadMatchIndex);
|
|
2590
2599
|
const matchPromises = [];
|
|
2591
2600
|
validResolvedMatches.forEach((match, index) => {
|
|
2592
|
-
matchPromises.push((async
|
|
2601
|
+
matchPromises.push(new Promise(async resolve => {
|
|
2593
2602
|
const parentMatchPromise = matchPromises[index - 1];
|
|
2594
2603
|
const route = this.looseRoutesById[match.routeId];
|
|
2595
2604
|
const handleErrorAndRedirect = err => {
|
|
@@ -2604,92 +2613,95 @@
|
|
|
2604
2613
|
let loadPromise;
|
|
2605
2614
|
matches[index] = match = {
|
|
2606
2615
|
...match,
|
|
2607
|
-
fetchedAt: Date.now(),
|
|
2608
2616
|
showPending: false
|
|
2609
2617
|
};
|
|
2618
|
+
let didShowPending = false;
|
|
2610
2619
|
const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
};
|
|
2620
|
+
const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
|
|
2621
|
+
const shouldPending = !preload && pendingMs && (route.options.pendingComponent ?? this.options.defaultPendingComponent);
|
|
2622
|
+
const fetch = async () => {
|
|
2623
|
+
if (match.isFetching) {
|
|
2624
|
+
loadPromise = getRouteMatch(this.state, match.id)?.loadPromise;
|
|
2625
|
+
} else {
|
|
2626
|
+
const loaderContext = {
|
|
2627
|
+
params: match.params,
|
|
2628
|
+
search: match.search,
|
|
2629
|
+
preload: !!preload,
|
|
2630
|
+
parentMatchPromise,
|
|
2631
|
+
abortController: match.abortController,
|
|
2632
|
+
context: match.context,
|
|
2633
|
+
location: this.state.location,
|
|
2634
|
+
navigate: opts => this.navigate({
|
|
2635
|
+
...opts,
|
|
2636
|
+
from: match.pathname
|
|
2637
|
+
}),
|
|
2638
|
+
cause: preload ? 'preload' : match.cause
|
|
2639
|
+
};
|
|
2632
2640
|
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2641
|
+
// Default to reloading the route all the time
|
|
2642
|
+
let shouldLoad = true;
|
|
2643
|
+
const shouldReloadFn = route.options.shouldReload;
|
|
2644
|
+
let shouldReloadDeps = typeof shouldReloadFn === 'function' ? shouldReloadFn(loaderContext) : !!(shouldReloadFn ?? true);
|
|
2645
|
+
const compareDeps = () => {
|
|
2646
|
+
if (typeof shouldReloadDeps === 'object') {
|
|
2647
|
+
// compare the deps to see if they've changed
|
|
2648
|
+
shouldLoad = !deepEqual(shouldReloadDeps, match.shouldReloadDeps);
|
|
2649
|
+
} else {
|
|
2650
|
+
shouldLoad = !!shouldReloadDeps;
|
|
2651
|
+
}
|
|
2652
|
+
};
|
|
2653
|
+
|
|
2654
|
+
// If it's the first preload, or the route is entering, or we're
|
|
2655
|
+
// invalidating, we definitely need to load the route
|
|
2656
|
+
if (invalidate) ; else if (preload) {
|
|
2657
|
+
if (!match.fetchCount) ; else {
|
|
2658
|
+
compareDeps();
|
|
2659
|
+
}
|
|
2660
|
+
} else if (match.cause === 'enter') {
|
|
2661
|
+
if (!match.fetchCount) ; else {
|
|
2662
|
+
compareDeps();
|
|
2663
|
+
}
|
|
2643
2664
|
} else {
|
|
2644
|
-
|
|
2665
|
+
compareDeps();
|
|
2666
|
+
}
|
|
2667
|
+
if (typeof shouldReloadDeps === 'object') {
|
|
2668
|
+
matches[index] = match = {
|
|
2669
|
+
...match,
|
|
2670
|
+
shouldReloadDeps
|
|
2671
|
+
};
|
|
2645
2672
|
}
|
|
2646
|
-
}
|
|
2647
2673
|
|
|
2648
|
-
|
|
2649
|
-
|
|
2674
|
+
// If the user doesn't want the route to reload, just
|
|
2675
|
+
// resolve with the existing loader data
|
|
2650
2676
|
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
...match,
|
|
2657
|
-
isFetching: true
|
|
2658
|
-
};
|
|
2659
|
-
const componentsPromise = Promise.all(componentTypes.map(async type => {
|
|
2660
|
-
const component = route.options[type];
|
|
2661
|
-
if (component?.preload) {
|
|
2662
|
-
await component.preload();
|
|
2677
|
+
if (!shouldLoad) {
|
|
2678
|
+
loadPromise = Promise.resolve(match.loaderData);
|
|
2679
|
+
} else {
|
|
2680
|
+
if (match.fetchCount && match.status === 'success') {
|
|
2681
|
+
resolve();
|
|
2663
2682
|
}
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
loadPromise = Promise.all([componentsPromise, loaderPromise]).then(d => d[1]);
|
|
2667
|
-
}
|
|
2668
|
-
}
|
|
2669
|
-
matches[index] = match = {
|
|
2670
|
-
...match,
|
|
2671
|
-
loadPromise
|
|
2672
|
-
};
|
|
2673
|
-
if (!preload) {
|
|
2674
|
-
updatePendingMatch(match);
|
|
2675
|
-
}
|
|
2676
|
-
let didShowPending = false;
|
|
2677
|
-
const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
|
|
2678
|
-
await new Promise(async resolve => {
|
|
2679
|
-
// If the route has a pending component and a pendingMs option,
|
|
2680
|
-
// forcefully show the pending component
|
|
2681
|
-
if (pendingPromise) {
|
|
2682
|
-
pendingPromise.then(() => {
|
|
2683
|
-
if (latestPromise = checkLatest()) return;
|
|
2684
|
-
didShowPending = true;
|
|
2683
|
+
|
|
2684
|
+
// Otherwise, load the route
|
|
2685
2685
|
matches[index] = match = {
|
|
2686
2686
|
...match,
|
|
2687
|
-
|
|
2687
|
+
isFetching: true,
|
|
2688
|
+
fetchCount: match.fetchCount + 1
|
|
2688
2689
|
};
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2690
|
+
const componentsPromise = Promise.all(componentTypes.map(async type => {
|
|
2691
|
+
const component = route.options[type];
|
|
2692
|
+
if (component?.preload) {
|
|
2693
|
+
await component.preload();
|
|
2694
|
+
}
|
|
2695
|
+
}));
|
|
2696
|
+
const loaderPromise = route.options.loader?.(loaderContext);
|
|
2697
|
+
loadPromise = Promise.all([componentsPromise, loaderPromise]).then(d => d[1]);
|
|
2698
|
+
}
|
|
2692
2699
|
}
|
|
2700
|
+
matches[index] = match = {
|
|
2701
|
+
...match,
|
|
2702
|
+
loadPromise
|
|
2703
|
+
};
|
|
2704
|
+
updateMatch(match);
|
|
2693
2705
|
try {
|
|
2694
2706
|
const loaderData = await loadPromise;
|
|
2695
2707
|
if (latestPromise = checkLatest()) return await latestPromise;
|
|
@@ -2730,18 +2742,38 @@
|
|
|
2730
2742
|
// we already moved the pendingMatches to the matches
|
|
2731
2743
|
// state, so we need to update that specific match
|
|
2732
2744
|
if (didShowPending && pendingMinMs && match.showPending) {
|
|
2733
|
-
|
|
2734
|
-
...s,
|
|
2735
|
-
matches: s.matches?.map(d => d.id === match.id ? match : d)
|
|
2736
|
-
}));
|
|
2745
|
+
updateMatch(match);
|
|
2737
2746
|
}
|
|
2738
2747
|
}
|
|
2739
|
-
|
|
2740
|
-
|
|
2748
|
+
updateMatch(match);
|
|
2749
|
+
};
|
|
2750
|
+
if (match.fetchCount && match.status === 'success') {
|
|
2751
|
+
// Background Fetching
|
|
2752
|
+
fetch();
|
|
2753
|
+
} else {
|
|
2754
|
+
// Critical Fetching
|
|
2755
|
+
|
|
2756
|
+
// If we need to potentially show the pending component,
|
|
2757
|
+
// start a timer to show it after the pendingMs
|
|
2758
|
+
if (shouldPending) {
|
|
2759
|
+
new Promise(r => setTimeout(r, pendingMs)).then(async () => {
|
|
2760
|
+
if (latestPromise = checkLatest()) return latestPromise;
|
|
2761
|
+
didShowPending = true;
|
|
2762
|
+
matches[index] = match = {
|
|
2763
|
+
...match,
|
|
2764
|
+
showPending: true
|
|
2765
|
+
};
|
|
2766
|
+
updateMatch(match);
|
|
2767
|
+
resolve();
|
|
2768
|
+
});
|
|
2741
2769
|
}
|
|
2742
|
-
|
|
2743
|
-
}
|
|
2744
|
-
|
|
2770
|
+
await fetch();
|
|
2771
|
+
}
|
|
2772
|
+
resolve();
|
|
2773
|
+
// No Fetching
|
|
2774
|
+
|
|
2775
|
+
resolve();
|
|
2776
|
+
}));
|
|
2745
2777
|
});
|
|
2746
2778
|
await Promise.all(matchPromises);
|
|
2747
2779
|
return matches;
|
|
@@ -2764,20 +2796,32 @@
|
|
|
2764
2796
|
toLocation: next,
|
|
2765
2797
|
pathChanged: pathDidChange
|
|
2766
2798
|
});
|
|
2767
|
-
|
|
2768
|
-
// Match the routes
|
|
2769
|
-
let pendingMatches = this.matchRoutes(next.pathname, next.search, {
|
|
2770
|
-
debug: true
|
|
2771
|
-
});
|
|
2799
|
+
let pendingMatches;
|
|
2772
2800
|
const previousMatches = this.state.matches;
|
|
2801
|
+
this.__store.batch(() => {
|
|
2802
|
+
this.__store.setState(s => ({
|
|
2803
|
+
...s,
|
|
2804
|
+
preloadMatches: s.preloadMatches.filter(d => {
|
|
2805
|
+
return Date.now() - d.updatedAt < (this.options.defaultPreloadMaxAge ?? 3000);
|
|
2806
|
+
})
|
|
2807
|
+
}));
|
|
2773
2808
|
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2809
|
+
// Match the routes
|
|
2810
|
+
pendingMatches = this.matchRoutes(next.pathname, next.search, {
|
|
2811
|
+
debug: true
|
|
2812
|
+
});
|
|
2813
|
+
|
|
2814
|
+
// Ingest the new matches
|
|
2815
|
+
this.__store.setState(s => ({
|
|
2816
|
+
...s,
|
|
2817
|
+
isLoading: true,
|
|
2818
|
+
location: next,
|
|
2819
|
+
pendingMatches,
|
|
2820
|
+
preloadMatches: s.preloadMatches.filter(d => {
|
|
2821
|
+
return !pendingMatches.find(e => e.id === d.id);
|
|
2822
|
+
})
|
|
2823
|
+
}));
|
|
2824
|
+
});
|
|
2781
2825
|
try {
|
|
2782
2826
|
try {
|
|
2783
2827
|
// Load the matches
|
|
@@ -2835,6 +2879,17 @@
|
|
|
2835
2879
|
let matches = this.matchRoutes(next.pathname, next.search, {
|
|
2836
2880
|
throwOnError: true
|
|
2837
2881
|
});
|
|
2882
|
+
const loadedMatchIds = Object.fromEntries([...this.state.matches, ...(this.state.pendingMatches ?? []), ...this.state.preloadMatches]?.map(d => [d.id, true]));
|
|
2883
|
+
this.__store.batch(() => {
|
|
2884
|
+
matches.forEach(match => {
|
|
2885
|
+
if (!loadedMatchIds[match.id]) {
|
|
2886
|
+
this.__store.setState(s => ({
|
|
2887
|
+
...s,
|
|
2888
|
+
preloadMatches: [...s.preloadMatches, match]
|
|
2889
|
+
}));
|
|
2890
|
+
}
|
|
2891
|
+
});
|
|
2892
|
+
});
|
|
2838
2893
|
matches = await this.loadMatches({
|
|
2839
2894
|
matches,
|
|
2840
2895
|
preload: true,
|
|
@@ -2897,7 +2952,7 @@
|
|
|
2897
2952
|
dehydrate = () => {
|
|
2898
2953
|
return {
|
|
2899
2954
|
state: {
|
|
2900
|
-
dehydratedMatches: this.state.matches.map(d => pick(d, ['
|
|
2955
|
+
dehydratedMatches: this.state.matches.map(d => pick(d, ['id', 'status', 'updatedAt', 'loaderData']))
|
|
2901
2956
|
}
|
|
2902
2957
|
};
|
|
2903
2958
|
};
|
|
@@ -2960,6 +3015,7 @@
|
|
|
2960
3015
|
location,
|
|
2961
3016
|
matches: [],
|
|
2962
3017
|
pendingMatches: [],
|
|
3018
|
+
preloadMatches: [],
|
|
2963
3019
|
lastUpdated: Date.now()
|
|
2964
3020
|
};
|
|
2965
3021
|
}
|
|
@@ -3253,7 +3309,6 @@
|
|
|
3253
3309
|
exports.resolvePath = resolvePath;
|
|
3254
3310
|
exports.rootRouteId = rootRouteId;
|
|
3255
3311
|
exports.rootRouteWithContext = rootRouteWithContext;
|
|
3256
|
-
exports.routerContext = routerContext;
|
|
3257
3312
|
exports.shallow = shallow;
|
|
3258
3313
|
exports.stringifySearchWith = stringifySearchWith;
|
|
3259
3314
|
exports.trimPath = trimPath;
|