@tanstack/router-core 0.0.1-beta.174 → 0.0.1-beta.176
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/index.js +1 -0
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/route.js.map +1 -1
- package/build/cjs/router.js +57 -36
- package/build/cjs/router.js.map +1 -1
- package/build/esm/index.js +56 -36
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +158 -191
- package/build/types/defer.d.ts +19 -0
- package/build/types/fileRoute.d.ts +35 -0
- package/build/types/history.d.ts +31 -0
- package/build/types/index.d.ts +12 -780
- package/build/types/link.d.ts +92 -0
- package/build/types/path.d.ts +16 -0
- package/build/types/qss.d.ts +2 -0
- package/build/types/route.d.ts +234 -0
- package/build/types/routeInfo.d.ts +22 -0
- package/build/types/router.d.ts +251 -0
- package/build/types/scroll-restoration.d.ts +6 -0
- package/build/types/searchParams.d.ts +5 -0
- package/build/types/utils.d.ts +53 -0
- package/build/umd/index.development.js +57 -36
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +2 -2
- package/build/umd/index.production.js.map +1 -1
- package/package.json +3 -3
- package/src/route.ts +12 -16
- package/src/router.ts +100 -55
package/build/esm/index.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import invariant from 'tiny-invariant';
|
|
12
12
|
export { default as invariant } from 'tiny-invariant';
|
|
13
13
|
export { default as warning } from 'tiny-warning';
|
|
14
|
-
import { Store } from '@tanstack/
|
|
14
|
+
import { Store } from '@tanstack/store';
|
|
15
15
|
|
|
16
16
|
// While the public API was clearly inspired by the "history" npm package,
|
|
17
17
|
// This implementation attempts to be more lightweight by
|
|
@@ -709,6 +709,8 @@ function stringifySearchWith(stringify, parser) {
|
|
|
709
709
|
//
|
|
710
710
|
|
|
711
711
|
const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
|
|
712
|
+
const visibilityChangeEvent = 'visibilitychange';
|
|
713
|
+
const focusEvent = 'focus';
|
|
712
714
|
class Router {
|
|
713
715
|
#unsubHistory;
|
|
714
716
|
resetNextScroll = false;
|
|
@@ -785,12 +787,26 @@ class Router {
|
|
|
785
787
|
this.__store.setState(s => Object.assign(s, getInitialRouterState()));
|
|
786
788
|
};
|
|
787
789
|
mount = () => {
|
|
788
|
-
//
|
|
789
|
-
//
|
|
790
|
+
// addEventListener does not exist in React Native, but window does
|
|
791
|
+
// In the future, we might need to invert control here for more adapters
|
|
792
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
793
|
+
if (typeof window !== 'undefined' && window.addEventListener) {
|
|
794
|
+
window.addEventListener(visibilityChangeEvent, this.#onFocus, false);
|
|
795
|
+
window.addEventListener(focusEvent, this.#onFocus, false);
|
|
796
|
+
}
|
|
790
797
|
this.safeLoad();
|
|
791
|
-
|
|
798
|
+
return () => {
|
|
799
|
+
if (typeof window !== 'undefined' && window.removeEventListener) {
|
|
800
|
+
window.removeEventListener(visibilityChangeEvent, this.#onFocus);
|
|
801
|
+
window.removeEventListener(focusEvent, this.#onFocus);
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
};
|
|
805
|
+
#onFocus = () => {
|
|
806
|
+
if (this.options.refetchOnWindowFocus ?? true) {
|
|
807
|
+
this.reload();
|
|
808
|
+
}
|
|
792
809
|
};
|
|
793
|
-
|
|
794
810
|
update = opts => {
|
|
795
811
|
this.options = {
|
|
796
812
|
...this.options,
|
|
@@ -861,7 +877,6 @@ class Router {
|
|
|
861
877
|
};
|
|
862
878
|
|
|
863
879
|
// Cancel any pending matches
|
|
864
|
-
// this.cancelMatches()
|
|
865
880
|
|
|
866
881
|
let pendingMatches;
|
|
867
882
|
this.#emit({
|
|
@@ -904,6 +919,9 @@ class Router {
|
|
|
904
919
|
if (latestPromise = checkLatest()) {
|
|
905
920
|
return latestPromise;
|
|
906
921
|
}
|
|
922
|
+
const exitingMatchIds = this.state.matchIds.filter(id => !this.state.pendingMatchIds.includes(id));
|
|
923
|
+
const enteringMatchIds = this.state.pendingMatchIds.filter(id => !this.state.matchIds.includes(id));
|
|
924
|
+
const stayingMatchIds = this.state.matchIds.filter(id => this.state.pendingMatchIds.includes(id));
|
|
907
925
|
this.__store.setState(s => ({
|
|
908
926
|
...s,
|
|
909
927
|
status: 'idle',
|
|
@@ -911,6 +929,13 @@ class Router {
|
|
|
911
929
|
matchIds: s.pendingMatchIds,
|
|
912
930
|
pendingMatchIds: []
|
|
913
931
|
}));
|
|
932
|
+
[[exitingMatchIds, 'onLeave'], [enteringMatchIds, 'onEnter'], [stayingMatchIds, 'onTransition']].forEach(([matchIds, hook]) => {
|
|
933
|
+
matchIds.forEach(id => {
|
|
934
|
+
const match = this.getRouteMatch(id);
|
|
935
|
+
const route = this.getRoute(match.routeId);
|
|
936
|
+
route.options[hook]?.(match);
|
|
937
|
+
});
|
|
938
|
+
});
|
|
914
939
|
this.#emit({
|
|
915
940
|
type: 'onLoad',
|
|
916
941
|
from: prevLocation,
|
|
@@ -927,6 +952,9 @@ class Router {
|
|
|
927
952
|
}
|
|
928
953
|
});
|
|
929
954
|
this.latestLoadPromise = promise;
|
|
955
|
+
this.latestLoadPromise.then(() => {
|
|
956
|
+
this.cleanMatches();
|
|
957
|
+
});
|
|
930
958
|
return this.latestLoadPromise;
|
|
931
959
|
};
|
|
932
960
|
#mergeMatches = (prevMatchesById, nextMatches) => {
|
|
@@ -971,7 +999,7 @@ class Router {
|
|
|
971
999
|
const now = Date.now();
|
|
972
1000
|
const outdatedMatchIds = Object.values(this.state.matchesById).filter(match => {
|
|
973
1001
|
const route = this.getRoute(match.routeId);
|
|
974
|
-
return !this.state.matchIds.includes(match.id) && !this.state.pendingMatchIds.includes(match.id) && match.
|
|
1002
|
+
return !this.state.matchIds.includes(match.id) && !this.state.pendingMatchIds.includes(match.id) && (match.preloadMaxAge > -1 ? match.updatedAt + match.preloadMaxAge < now : true) && (route.options.gcMaxAge ? match.updatedAt + route.options.gcMaxAge < now : true);
|
|
975
1003
|
}).map(d => d.id);
|
|
976
1004
|
if (outdatedMatchIds.length) {
|
|
977
1005
|
this.__store.setState(s => {
|
|
@@ -1059,8 +1087,8 @@ class Router {
|
|
|
1059
1087
|
params: routeParams,
|
|
1060
1088
|
pathname: joinPaths([this.basepath, interpolatedPath]),
|
|
1061
1089
|
updatedAt: Date.now(),
|
|
1062
|
-
|
|
1063
|
-
|
|
1090
|
+
maxAge: -1,
|
|
1091
|
+
preloadMaxAge: -1,
|
|
1064
1092
|
routeSearch: {},
|
|
1065
1093
|
search: {},
|
|
1066
1094
|
status: hasLoaders ? 'pending' : 'success',
|
|
@@ -1156,11 +1184,10 @@ class Router {
|
|
|
1156
1184
|
paramsError: match.paramsError,
|
|
1157
1185
|
searchError: match.searchError,
|
|
1158
1186
|
params: match.params,
|
|
1159
|
-
|
|
1187
|
+
preloadMaxAge: 0
|
|
1160
1188
|
}));
|
|
1161
1189
|
});
|
|
1162
1190
|
}
|
|
1163
|
-
this.cleanMatches();
|
|
1164
1191
|
let firstBadMatchIndex;
|
|
1165
1192
|
|
|
1166
1193
|
// Check each match middleware to see if the route can be accessed
|
|
@@ -1222,8 +1249,7 @@ class Router {
|
|
|
1222
1249
|
matchPromises.push((async () => {
|
|
1223
1250
|
const parentMatchPromise = matchPromises[index - 1];
|
|
1224
1251
|
const route = this.getRoute(match.routeId);
|
|
1225
|
-
if (match.isFetching || match.status === 'success' && !
|
|
1226
|
-
matchId: match.id,
|
|
1252
|
+
if (match.isFetching || match.status === 'success' && !isMatchInvalid(match, {
|
|
1227
1253
|
preload: opts?.preload
|
|
1228
1254
|
})) {
|
|
1229
1255
|
return this.getRouteMatch(match.id)?.loadPromise;
|
|
@@ -1296,7 +1322,6 @@ class Router {
|
|
|
1296
1322
|
})());
|
|
1297
1323
|
});
|
|
1298
1324
|
await Promise.all(matchPromises);
|
|
1299
|
-
this.cleanMatches();
|
|
1300
1325
|
};
|
|
1301
1326
|
reload = () => {
|
|
1302
1327
|
return this.navigate({
|
|
@@ -1481,7 +1506,7 @@ class Router {
|
|
|
1481
1506
|
dehydrate = () => {
|
|
1482
1507
|
return {
|
|
1483
1508
|
state: {
|
|
1484
|
-
dehydratedMatches: this.state.matches.map(d => pick(d, ['fetchedAt', 'invalid', '
|
|
1509
|
+
dehydratedMatches: this.state.matches.map(d => pick(d, ['fetchedAt', 'invalid', 'preloadMaxAge', 'maxAge', 'id', 'loaderData', 'status', 'updatedAt']))
|
|
1485
1510
|
}
|
|
1486
1511
|
};
|
|
1487
1512
|
};
|
|
@@ -1720,7 +1745,6 @@ class Router {
|
|
|
1720
1745
|
...next.state
|
|
1721
1746
|
});
|
|
1722
1747
|
this.resetNextScroll = location.resetScroll ?? true;
|
|
1723
|
-
console.log('resetScroll', this.resetNextScroll);
|
|
1724
1748
|
return this.latestLoadPromise;
|
|
1725
1749
|
};
|
|
1726
1750
|
getRouteMatch = id => {
|
|
@@ -1745,17 +1769,17 @@ class Router {
|
|
|
1745
1769
|
if (!match) return;
|
|
1746
1770
|
const route = this.getRoute(match.routeId);
|
|
1747
1771
|
const updatedAt = opts?.updatedAt ?? Date.now();
|
|
1748
|
-
const
|
|
1749
|
-
const
|
|
1772
|
+
const preloadMaxAge = opts?.maxAge ?? route.options.preloadMaxAge ?? this.options.defaultPreloadMaxAge ?? 5000;
|
|
1773
|
+
const maxAge = opts?.maxAge ?? route.options.maxAge ?? this.options.defaultMaxAge ?? -1;
|
|
1750
1774
|
this.setRouteMatch(id, s => ({
|
|
1751
1775
|
...s,
|
|
1752
1776
|
error: undefined,
|
|
1753
1777
|
status: 'success',
|
|
1754
1778
|
isFetching: false,
|
|
1755
|
-
updatedAt:
|
|
1779
|
+
updatedAt: updatedAt,
|
|
1756
1780
|
loaderData: functionalUpdate(updater, s.loaderData),
|
|
1757
|
-
|
|
1758
|
-
|
|
1781
|
+
preloadMaxAge,
|
|
1782
|
+
maxAge
|
|
1759
1783
|
}));
|
|
1760
1784
|
};
|
|
1761
1785
|
invalidate = async opts => {
|
|
@@ -1786,20 +1810,6 @@ class Router {
|
|
|
1786
1810
|
return this.reload();
|
|
1787
1811
|
}
|
|
1788
1812
|
};
|
|
1789
|
-
getIsInvalid = opts => {
|
|
1790
|
-
if (!opts?.matchId) {
|
|
1791
|
-
return !!this.state.matches.find(d => this.getIsInvalid({
|
|
1792
|
-
matchId: d.id,
|
|
1793
|
-
preload: opts?.preload
|
|
1794
|
-
}));
|
|
1795
|
-
}
|
|
1796
|
-
const match = this.getRouteMatch(opts?.matchId);
|
|
1797
|
-
if (!match) {
|
|
1798
|
-
return false;
|
|
1799
|
-
}
|
|
1800
|
-
const now = Date.now();
|
|
1801
|
-
return match.invalid || (opts?.preload ? match.preloadInvalidAt : match.invalidAt) < now;
|
|
1802
|
-
};
|
|
1803
1813
|
}
|
|
1804
1814
|
|
|
1805
1815
|
// Detect if we're in the DOM
|
|
@@ -1845,6 +1855,16 @@ function lazyFn(fn, key) {
|
|
|
1845
1855
|
return imported[key || 'default'](...args);
|
|
1846
1856
|
};
|
|
1847
1857
|
}
|
|
1858
|
+
function isMatchInvalid(match, opts) {
|
|
1859
|
+
const now = Date.now();
|
|
1860
|
+
if (match.invalid) {
|
|
1861
|
+
return true;
|
|
1862
|
+
}
|
|
1863
|
+
if (opts?.preload) {
|
|
1864
|
+
return match.preloadMaxAge < 0 ? false : match.updatedAt + match.preloadMaxAge < now;
|
|
1865
|
+
}
|
|
1866
|
+
return match.maxAge < 0 ? false : match.updatedAt + match.maxAge < now;
|
|
1867
|
+
}
|
|
1848
1868
|
|
|
1849
1869
|
const windowKey = 'window';
|
|
1850
1870
|
const delimiter = '___';
|
|
@@ -1990,5 +2010,5 @@ function isDehydratedDeferred(obj) {
|
|
|
1990
2010
|
return typeof obj === 'object' && obj !== null && !(obj instanceof Promise) && !obj.then && '__deferredState' in obj;
|
|
1991
2011
|
}
|
|
1992
2012
|
|
|
1993
|
-
export { FileRoute, PathParamError, RootRoute, Route, Router, RouterContext, SearchParamError, cleanPath, componentTypes, createBrowserHistory, createHashHistory, createMemoryHistory, decode, defaultParseSearch, defaultStringifySearch, defer, encode, functionalUpdate, interpolatePath, isDehydratedDeferred, isPlainObject, isRedirect, joinPaths, last, lazyFn, matchByPath, matchPathname, parsePathname, parseSearchWith, partialDeepEqual, pick, redirect, replaceEqualDeep, resolvePath, restoreScrollPositions, rootRouteId, stringifySearchWith, trimPath, trimPathLeft, trimPathRight, watchScrollPositions };
|
|
2013
|
+
export { FileRoute, PathParamError, RootRoute, Route, Router, RouterContext, SearchParamError, cleanPath, componentTypes, createBrowserHistory, createHashHistory, createMemoryHistory, decode, defaultParseSearch, defaultStringifySearch, defer, encode, functionalUpdate, interpolatePath, isDehydratedDeferred, isMatchInvalid, isPlainObject, isRedirect, joinPaths, last, lazyFn, matchByPath, matchPathname, parsePathname, parseSearchWith, partialDeepEqual, pick, redirect, replaceEqualDeep, resolvePath, restoreScrollPositions, rootRouteId, stringifySearchWith, trimPath, trimPathLeft, trimPathRight, watchScrollPositions };
|
|
1994
2014
|
//# sourceMappingURL=index.js.map
|