@tanstack/react-router 0.0.1-beta.215 → 0.0.1-beta.217
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 +41 -16
- package/build/cjs/RouterProvider.js.map +1 -1
- package/build/cjs/index.js +1 -1
- package/build/cjs/route.js.map +1 -1
- package/build/cjs/utils.js +9 -4
- package/build/cjs/utils.js.map +1 -1
- package/build/esm/index.js +50 -20
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +263 -263
- package/build/types/RouterProvider.d.ts +1 -0
- package/build/types/route.d.ts +4 -3
- package/build/types/utils.d.ts +1 -1
- package/build/umd/index.development.js +50 -20
- 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/RouterProvider.tsx +71 -26
- package/src/route.ts +13 -3
- package/src/utils.ts +12 -6
|
@@ -76,6 +76,7 @@ export interface RouteMatch<TRouteTree extends AnyRoute = AnyRoute, TRouteId ext
|
|
|
76
76
|
routeSearch: RouteById<TRouteTree, TRouteId>['types']['searchSchema'];
|
|
77
77
|
search: FullSearchSchema<TRouteTree> & RouteById<TRouteTree, TRouteId>['types']['fullSearchSchema'];
|
|
78
78
|
fetchedAt: number;
|
|
79
|
+
shouldReloadDeps: any;
|
|
79
80
|
abortController: AbortController;
|
|
80
81
|
}
|
|
81
82
|
export type AnyRouteMatch = RouteMatch<any>;
|
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, 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
|
} : {
|
|
@@ -85,9 +86,7 @@ export type DefinedPathParamWarning = 'Path params cannot be redefined by child
|
|
|
85
86
|
export type ParentParams<TParentParams> = AnyPathParams extends TParentParams ? {} : {
|
|
86
87
|
[Key in keyof TParentParams]?: DefinedPathParamWarning;
|
|
87
88
|
};
|
|
88
|
-
export type RouteLoadFn<TAllParams = {}, TFullSearchSchema extends Record<string, any> = {}, TAllContext extends Record<string, any> = AnyContext, TRouteContext extends Record<string, any> = AnyContext, TLoaderData extends any = unknown> = (match: LoaderFnContext<TAllParams, TFullSearchSchema, TAllContext, TRouteContext>
|
|
89
|
-
parentMatchPromise?: Promise<void>;
|
|
90
|
-
}) => Promise<TLoaderData> | TLoaderData;
|
|
89
|
+
export type RouteLoadFn<TAllParams = {}, TFullSearchSchema extends Record<string, any> = {}, TAllContext extends Record<string, any> = AnyContext, TRouteContext extends Record<string, any> = AnyContext, TLoaderData extends any = unknown> = (match: LoaderFnContext<TAllParams, TFullSearchSchema, TAllContext, TRouteContext>) => Promise<TLoaderData> | TLoaderData;
|
|
91
90
|
export interface LoaderFnContext<TAllParams = {}, TFullSearchSchema extends Record<string, any> = {}, TAllContext extends Record<string, any> = AnyContext, TRouteContext extends Record<string, any> = AnyContext> {
|
|
92
91
|
abortController: AbortController;
|
|
93
92
|
preload: boolean;
|
|
@@ -96,6 +95,8 @@ export interface LoaderFnContext<TAllParams = {}, TFullSearchSchema extends Reco
|
|
|
96
95
|
context: Expand<Assign<TAllContext, TRouteContext>>;
|
|
97
96
|
location: ParsedLocation<TFullSearchSchema>;
|
|
98
97
|
navigate: (opts: NavigateOptions<AnyRoute>) => Promise<void>;
|
|
98
|
+
parentMatchPromise?: Promise<void>;
|
|
99
|
+
cause: 'enter' | 'stay';
|
|
99
100
|
}
|
|
100
101
|
export type SearchFilter<T, U = T> = (prev: T) => U;
|
|
101
102
|
export type ResolveId<TParentRoute, TCustomId extends string, TPath extends string> = TParentRoute extends {
|
package/build/types/utils.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ export declare function pick<T, K extends keyof T>(parent: T, keys: K[]): Pick<T
|
|
|
48
48
|
*/
|
|
49
49
|
export declare function replaceEqualDeep<T>(prev: any, _next: T): T;
|
|
50
50
|
export declare function isPlainObject(o: any): boolean;
|
|
51
|
-
export declare function
|
|
51
|
+
export declare function deepEqual(a: any, b: any, partial?: boolean): boolean;
|
|
52
52
|
export declare function useStableCallback<T extends (...args: any[]) => any>(fn: T): T;
|
|
53
53
|
export declare function shallow<T>(objA: T, objB: T): boolean;
|
|
54
54
|
export type StrictOrFrom<TFrom> = {
|
|
@@ -558,7 +558,7 @@
|
|
|
558
558
|
function hasObjectPrototype(o) {
|
|
559
559
|
return Object.prototype.toString.call(o) === '[object Object]';
|
|
560
560
|
}
|
|
561
|
-
function
|
|
561
|
+
function deepEqual(a, b, partial = false) {
|
|
562
562
|
if (a === b) {
|
|
563
563
|
return true;
|
|
564
564
|
}
|
|
@@ -566,10 +566,15 @@
|
|
|
566
566
|
return false;
|
|
567
567
|
}
|
|
568
568
|
if (isPlainObject(a) && isPlainObject(b)) {
|
|
569
|
-
|
|
569
|
+
const aKeys = Object.keys(a);
|
|
570
|
+
const bKeys = Object.keys(b);
|
|
571
|
+
if (!partial && aKeys.length !== bKeys.length) {
|
|
572
|
+
return false;
|
|
573
|
+
}
|
|
574
|
+
return !bKeys.some(key => !(key in a) || !deepEqual(a[key], b[key], partial));
|
|
570
575
|
}
|
|
571
576
|
if (Array.isArray(a) && Array.isArray(b)) {
|
|
572
|
-
return !
|
|
577
|
+
return !a.some((item, index) => !deepEqual(item, b[index], partial));
|
|
573
578
|
}
|
|
574
579
|
return false;
|
|
575
580
|
}
|
|
@@ -1356,6 +1361,7 @@
|
|
|
1356
1361
|
loadPromise: Promise.resolve(),
|
|
1357
1362
|
context: undefined,
|
|
1358
1363
|
abortController: new AbortController(),
|
|
1364
|
+
shouldReloadDeps: undefined,
|
|
1359
1365
|
fetchedAt: 0
|
|
1360
1366
|
};
|
|
1361
1367
|
return routeMatch;
|
|
@@ -1687,17 +1693,8 @@
|
|
|
1687
1693
|
if (match.isFetching) {
|
|
1688
1694
|
loadPromise = getRouteMatch(state, match.id)?.loadPromise;
|
|
1689
1695
|
} else {
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
isFetching: true
|
|
1693
|
-
};
|
|
1694
|
-
const componentsPromise = Promise.all(componentTypes.map(async type => {
|
|
1695
|
-
const component = route.options[type];
|
|
1696
|
-
if (component?.preload) {
|
|
1697
|
-
await component.preload();
|
|
1698
|
-
}
|
|
1699
|
-
}));
|
|
1700
|
-
const loaderPromise = route.options.loader?.({
|
|
1696
|
+
const cause = state.matches.find(d => d.id === match.id) ? 'stay' : 'enter';
|
|
1697
|
+
const loaderContext = {
|
|
1701
1698
|
params: match.params,
|
|
1702
1699
|
search: match.search,
|
|
1703
1700
|
preload: !!preload,
|
|
@@ -1708,9 +1705,42 @@
|
|
|
1708
1705
|
navigate: opts => navigate({
|
|
1709
1706
|
...opts,
|
|
1710
1707
|
from: match.pathname
|
|
1711
|
-
})
|
|
1712
|
-
|
|
1713
|
-
|
|
1708
|
+
}),
|
|
1709
|
+
cause
|
|
1710
|
+
};
|
|
1711
|
+
|
|
1712
|
+
// Default to reloading the route all the time
|
|
1713
|
+
let shouldReload = true;
|
|
1714
|
+
let shouldReloadDeps = typeof route.options.shouldReload === 'function' ? route.options.shouldReload?.(loaderContext) : !!route.options.shouldReload;
|
|
1715
|
+
if (typeof shouldReloadDeps === 'object') {
|
|
1716
|
+
// compare the deps to see if they've changed
|
|
1717
|
+
shouldReload = !deepEqual(shouldReloadDeps, match.shouldReloadDeps);
|
|
1718
|
+
console.log(shouldReloadDeps, match.shouldReloadDeps, shouldReload);
|
|
1719
|
+
match.shouldReloadDeps = shouldReloadDeps;
|
|
1720
|
+
} else {
|
|
1721
|
+
shouldReload = !!shouldReloadDeps;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
// If the user doesn't want the route to reload, just
|
|
1725
|
+
// resolve with the existing loader data
|
|
1726
|
+
|
|
1727
|
+
if (!shouldReload) {
|
|
1728
|
+
loadPromise = Promise.resolve(match.loaderData);
|
|
1729
|
+
} else {
|
|
1730
|
+
// Otherwise, load the route
|
|
1731
|
+
matches[index] = match = {
|
|
1732
|
+
...match,
|
|
1733
|
+
isFetching: true
|
|
1734
|
+
};
|
|
1735
|
+
const componentsPromise = Promise.all(componentTypes.map(async type => {
|
|
1736
|
+
const component = route.options[type];
|
|
1737
|
+
if (component?.preload) {
|
|
1738
|
+
await component.preload();
|
|
1739
|
+
}
|
|
1740
|
+
}));
|
|
1741
|
+
const loaderPromise = route.options.loader?.(loaderContext);
|
|
1742
|
+
loadPromise = Promise.all([componentsPromise, loaderPromise]).then(d => d[1]);
|
|
1743
|
+
}
|
|
1714
1744
|
}
|
|
1715
1745
|
matches[index] = match = {
|
|
1716
1746
|
...match,
|
|
@@ -1892,7 +1922,7 @@
|
|
|
1892
1922
|
// Combine the matches based on user options
|
|
1893
1923
|
const pathTest = activeOptions?.exact ? latestLocationRef.current.pathname === next.pathname : pathIsFuzzyEqual;
|
|
1894
1924
|
const hashTest = activeOptions?.includeHash ? latestLocationRef.current.hash === next.hash : true;
|
|
1895
|
-
const searchTest = activeOptions?.includeSearch ?? true ?
|
|
1925
|
+
const searchTest = activeOptions?.includeSearch ?? true ? deepEqual(latestLocationRef.current.search, next.search, true) : true;
|
|
1896
1926
|
|
|
1897
1927
|
// The final "active" test
|
|
1898
1928
|
const isActive = pathTest && hashTest && searchTest;
|
|
@@ -2023,7 +2053,7 @@
|
|
|
2023
2053
|
return false;
|
|
2024
2054
|
}
|
|
2025
2055
|
if (match && (opts?.includeSearch ?? true)) {
|
|
2026
|
-
return
|
|
2056
|
+
return deepEqual(baseLocation.search, next.search, true) ? match : false;
|
|
2027
2057
|
}
|
|
2028
2058
|
return match;
|
|
2029
2059
|
});
|
|
@@ -2749,6 +2779,7 @@
|
|
|
2749
2779
|
exports.createMemoryHistory = createMemoryHistory;
|
|
2750
2780
|
exports.createRouteMask = createRouteMask;
|
|
2751
2781
|
exports.decode = decode;
|
|
2782
|
+
exports.deepEqual = deepEqual;
|
|
2752
2783
|
exports.defaultParseSearch = defaultParseSearch;
|
|
2753
2784
|
exports.defaultStringifySearch = defaultStringifySearch;
|
|
2754
2785
|
exports.encode = encode;
|
|
@@ -2769,7 +2800,6 @@
|
|
|
2769
2800
|
exports.matchesContext = matchesContext;
|
|
2770
2801
|
exports.parsePathname = parsePathname;
|
|
2771
2802
|
exports.parseSearchWith = parseSearchWith;
|
|
2772
|
-
exports.partialDeepEqual = partialDeepEqual;
|
|
2773
2803
|
exports.pick = pick;
|
|
2774
2804
|
exports.redirect = redirect;
|
|
2775
2805
|
exports.replaceEqualDeep = replaceEqualDeep;
|