@tanstack/react-router 0.0.1-beta.280 → 0.0.1-beta.282
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/link.js.map +1 -1
- package/build/cjs/route.js.map +1 -1
- package/build/cjs/router.js +48 -30
- package/build/cjs/router.js.map +1 -1
- package/build/esm/index.js +48 -30
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +351 -351
- package/build/types/Matches.d.ts +1 -0
- package/build/types/link.d.ts +1 -1
- package/build/types/route.d.ts +1 -0
- package/build/types/router.d.ts +3 -6
- package/build/umd/index.development.js +48 -30
- 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 +1 -0
- package/src/link.tsx +1 -1
- package/src/route.ts +10 -0
- package/src/router.ts +47 -26
package/build/types/Matches.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export interface RouteMatch<TRouteTree extends AnyRoute = AnyRoute, TRouteId ext
|
|
|
26
26
|
abortController: AbortController;
|
|
27
27
|
cause: 'preload' | 'enter' | 'stay';
|
|
28
28
|
loaderDeps: RouteById<TRouteTree, TRouteId>['types']['loaderDeps'];
|
|
29
|
+
invalid: boolean;
|
|
29
30
|
}
|
|
30
31
|
export type AnyRouteMatch = RouteMatch<any, any>;
|
|
31
32
|
export declare function Matches(): React.JSX.Element;
|
package/build/types/link.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export type ToSubOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTr
|
|
|
43
43
|
state?: true | NonNullableUpdater<HistoryState>;
|
|
44
44
|
from?: TFrom;
|
|
45
45
|
} & CheckPath<TRouteTree, NoInfer<TResolved>, {}> & SearchParamOptions<TRouteTree, TFrom, TTo, TResolved> & PathParamOptions<TRouteTree, TFrom, TResolved>;
|
|
46
|
-
export type SearchParamOptions<TRouteTree extends AnyRoute, TFrom, TTo, TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>, TFromSearchEnsured = '/' extends TFrom ? FullSearchSchema<TRouteTree> : Expand<UnionToIntersection<PickRequired<RouteByPath<TRouteTree, TFrom>['types']['fullSearchSchema']>>>, TFromSearchOptional = Omit<
|
|
46
|
+
export type SearchParamOptions<TRouteTree extends AnyRoute, TFrom, TTo, TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>, TFromSearchEnsured = '/' extends TFrom ? FullSearchSchema<TRouteTree> : Expand<UnionToIntersection<PickRequired<RouteByPath<TRouteTree, TFrom>['types']['fullSearchSchema']>>>, TFromSearchOptional = Omit<FullSearchSchema<TRouteTree>, keyof TFromSearchEnsured>, TFromSearch = Expand<TFromSearchEnsured & TFromSearchOptional>, TToSearch = '' extends TTo ? FullSearchSchema<TRouteTree> : Expand<RouteByPath<TRouteTree, TResolved>['types']['fullSearchSchema']>> = keyof PickRequired<TToSearch> extends never ? {
|
|
47
47
|
search?: true | SearchReducer<TFromSearch, TToSearch>;
|
|
48
48
|
} : {
|
|
49
49
|
search: TFromSearchEnsured extends PickRequired<TToSearch> ? true | SearchReducer<TFromSearch, TToSearch> : SearchReducer<TFromSearch, TToSearch>;
|
package/build/types/route.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export type ParamsFallback<TPath extends string, TParams> = unknown extends TPar
|
|
|
34
34
|
export type BaseRouteOptions<TParentRoute extends AnyRoute = AnyRoute, TCustomId extends string = string, TPath extends string = string, TSearchSchema extends Record<string, any> = {}, TFullSearchSchema extends Record<string, any> = TSearchSchema, TParams extends AnyPathParams = {}, TAllParams = ParamsFallback<TPath, TParams>, TRouteContext extends RouteContext = RouteContext, TAllContext extends Record<string, any> = AnyContext, TLoaderDeps extends Record<string, any> = {}, TLoaderData extends any = unknown> = RoutePathOptions<TCustomId, TPath> & {
|
|
35
35
|
getParentRoute: () => TParentRoute;
|
|
36
36
|
validateSearch?: SearchSchemaValidator<TSearchSchema>;
|
|
37
|
+
shouldReload?: boolean | ((match: LoaderFnContext<TAllParams, TFullSearchSchema, TAllContext, TRouteContext>) => any);
|
|
37
38
|
} & (keyof PickRequired<RouteContext> extends never ? {
|
|
38
39
|
beforeLoad?: BeforeLoadFn<TFullSearchSchema, TParentRoute, TAllParams, TRouteContext>;
|
|
39
40
|
} : {
|
package/build/types/router.d.ts
CHANGED
|
@@ -162,16 +162,13 @@ export declare class Router<TRouteTree extends AnyRoute = AnyRoute, TDehydrated
|
|
|
162
162
|
commitLocation: ({ startTransition, ...next }: ParsedLocation & CommitLocationOptions) => Promise<void>;
|
|
163
163
|
buildAndCommitLocation: ({ replace, resetScroll, startTransition, ...rest }?: BuildNextOptions & CommitLocationOptions) => Promise<void>;
|
|
164
164
|
navigate: NavigateFn<TRouteTree>;
|
|
165
|
-
loadMatches: ({ checkLatest, matches, preload,
|
|
165
|
+
loadMatches: ({ checkLatest, matches, preload, }: {
|
|
166
166
|
checkLatest: () => Promise<void> | undefined;
|
|
167
167
|
matches: AnyRouteMatch[];
|
|
168
168
|
preload?: boolean | undefined;
|
|
169
|
-
invalidate?: boolean | undefined;
|
|
170
169
|
}) => Promise<RouteMatch[]>;
|
|
171
|
-
invalidate: () =>
|
|
172
|
-
load: (
|
|
173
|
-
invalidate?: boolean;
|
|
174
|
-
}) => Promise<void>;
|
|
170
|
+
invalidate: () => void;
|
|
171
|
+
load: () => Promise<void>;
|
|
175
172
|
preloadRoute: (navigateOpts?: ToOptions<TRouteTree>) => Promise<RouteMatch<AnyRoute, any>[]>;
|
|
176
173
|
matchRoute: MatchRouteFn<TRouteTree>;
|
|
177
174
|
injectHtml: (html: string | (() => Promise<string> | string)) => Promise<void>;
|
|
@@ -2326,7 +2326,8 @@
|
|
|
2326
2326
|
abortController: new AbortController(),
|
|
2327
2327
|
fetchCount: 0,
|
|
2328
2328
|
cause,
|
|
2329
|
-
loaderDeps
|
|
2329
|
+
loaderDeps,
|
|
2330
|
+
invalid: false
|
|
2330
2331
|
};
|
|
2331
2332
|
|
|
2332
2333
|
// Regardless of whether we're reusing an existing match or creating
|
|
@@ -2529,8 +2530,7 @@
|
|
|
2529
2530
|
loadMatches = async ({
|
|
2530
2531
|
checkLatest,
|
|
2531
2532
|
matches,
|
|
2532
|
-
preload
|
|
2533
|
-
invalidate
|
|
2533
|
+
preload
|
|
2534
2534
|
}) => {
|
|
2535
2535
|
let latestPromise;
|
|
2536
2536
|
let firstBadMatchIndex;
|
|
@@ -2645,24 +2645,27 @@
|
|
|
2645
2645
|
const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
|
|
2646
2646
|
const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
|
|
2647
2647
|
const shouldPending = !preload && pendingMs && (route.options.pendingComponent ?? this.options.defaultPendingComponent);
|
|
2648
|
+
const loaderContext = {
|
|
2649
|
+
params: match.params,
|
|
2650
|
+
deps: match.loaderDeps,
|
|
2651
|
+
preload: !!preload,
|
|
2652
|
+
parentMatchPromise,
|
|
2653
|
+
abortController: match.abortController,
|
|
2654
|
+
context: match.context,
|
|
2655
|
+
location: this.state.location,
|
|
2656
|
+
navigate: opts => this.navigate({
|
|
2657
|
+
...opts,
|
|
2658
|
+
from: match.pathname
|
|
2659
|
+
}),
|
|
2660
|
+
cause: preload ? 'preload' : match.cause
|
|
2661
|
+
};
|
|
2648
2662
|
const fetch = async () => {
|
|
2649
2663
|
if (match.isFetching) {
|
|
2650
2664
|
loadPromise = getRouteMatch(this.state, match.id)?.loadPromise;
|
|
2651
2665
|
} else {
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
preload: !!preload,
|
|
2656
|
-
parentMatchPromise,
|
|
2657
|
-
abortController: match.abortController,
|
|
2658
|
-
context: match.context,
|
|
2659
|
-
location: this.state.location,
|
|
2660
|
-
navigate: opts => this.navigate({
|
|
2661
|
-
...opts,
|
|
2662
|
-
from: match.pathname
|
|
2663
|
-
}),
|
|
2664
|
-
cause: preload ? 'preload' : match.cause
|
|
2665
|
-
};
|
|
2666
|
+
// If the user doesn't want the route to reload, just
|
|
2667
|
+
// resolve with the existing loader data
|
|
2668
|
+
|
|
2666
2669
|
if (match.fetchCount && match.status === 'success') {
|
|
2667
2670
|
resolve();
|
|
2668
2671
|
}
|
|
@@ -2729,14 +2732,15 @@
|
|
|
2729
2732
|
const age = Date.now() - match.updatedAt;
|
|
2730
2733
|
let staleAge = preload ? route.options.preloadStaleTime ?? this.options.defaultPreloadStaleTime ?? 30_000 // 30 seconds for preloads by default
|
|
2731
2734
|
: route.options.staleTime ?? this.options.defaultStaleTime ?? 0;
|
|
2732
|
-
if (match.status === 'success') {
|
|
2733
|
-
// Background Fetching, no need to wait
|
|
2734
|
-
if (age > staleAge) {
|
|
2735
|
-
fetch();
|
|
2736
|
-
}
|
|
2737
|
-
} else {
|
|
2738
|
-
// Critical Fetching, we need to await
|
|
2739
2735
|
|
|
2736
|
+
// Default to reloading the route all the time
|
|
2737
|
+
let shouldReload;
|
|
2738
|
+
const shouldReloadOption = route.options.shouldReload;
|
|
2739
|
+
|
|
2740
|
+
// Allow shouldReload to get the last say,
|
|
2741
|
+
// if provided.
|
|
2742
|
+
shouldReload = typeof shouldReloadOption === 'function' ? shouldReloadOption(loaderContext) : shouldReloadOption;
|
|
2743
|
+
if (match.status !== 'success') {
|
|
2740
2744
|
// If we need to potentially show the pending component,
|
|
2741
2745
|
// start a timer to show it after the pendingMs
|
|
2742
2746
|
if (shouldPending) {
|
|
@@ -2751,7 +2755,12 @@
|
|
|
2751
2755
|
resolve();
|
|
2752
2756
|
});
|
|
2753
2757
|
}
|
|
2758
|
+
|
|
2759
|
+
// Critical Fetching, we need to await
|
|
2754
2760
|
await fetch();
|
|
2761
|
+
} else if (match.invalid || (shouldReload ?? age > staleAge)) {
|
|
2762
|
+
// Background Fetching, no need to wait
|
|
2763
|
+
fetch();
|
|
2755
2764
|
}
|
|
2756
2765
|
resolve();
|
|
2757
2766
|
}));
|
|
@@ -2759,10 +2768,20 @@
|
|
|
2759
2768
|
await Promise.all(matchPromises);
|
|
2760
2769
|
return matches;
|
|
2761
2770
|
};
|
|
2762
|
-
invalidate = () =>
|
|
2763
|
-
invalidate
|
|
2764
|
-
|
|
2765
|
-
|
|
2771
|
+
invalidate = () => {
|
|
2772
|
+
const invalidate = d => ({
|
|
2773
|
+
...d,
|
|
2774
|
+
invalid: true
|
|
2775
|
+
});
|
|
2776
|
+
this.__store.setState(s => ({
|
|
2777
|
+
...s,
|
|
2778
|
+
matches: s.matches.map(invalidate),
|
|
2779
|
+
cachedMatches: s.cachedMatches.map(invalidate),
|
|
2780
|
+
pendingMatches: s.pendingMatches?.map(invalidate)
|
|
2781
|
+
}));
|
|
2782
|
+
this.load();
|
|
2783
|
+
};
|
|
2784
|
+
load = async () => {
|
|
2766
2785
|
const promise = new Promise(async (resolve, reject) => {
|
|
2767
2786
|
const next = this.latestLocation;
|
|
2768
2787
|
const prevLocation = this.state.resolvedLocation;
|
|
@@ -2813,8 +2832,7 @@
|
|
|
2813
2832
|
// Load the matches
|
|
2814
2833
|
await this.loadMatches({
|
|
2815
2834
|
matches: pendingMatches,
|
|
2816
|
-
checkLatest: () => this.checkLatest(promise)
|
|
2817
|
-
invalidate: opts?.invalidate
|
|
2835
|
+
checkLatest: () => this.checkLatest(promise)
|
|
2818
2836
|
});
|
|
2819
2837
|
} catch (err) {
|
|
2820
2838
|
// swallow this error, since we'll display the
|