@tanstack/react-router 0.0.1-beta.206 → 0.0.1-beta.208
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 +61 -49
- package/build/cjs/RouterProvider.js.map +1 -1
- package/build/cjs/index.js +1 -0
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/react.js +6 -1
- package/build/cjs/react.js.map +1 -1
- package/build/cjs/route.js.map +1 -1
- package/build/cjs/router.js.map +1 -1
- package/build/esm/index.js +67 -51
- 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/react.d.ts +1 -0
- package/build/types/route.d.ts +4 -1
- package/build/types/router.d.ts +3 -0
- package/build/umd/index.development.js +67 -50
- 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 +62 -61
- package/src/react.tsx +16 -1
- package/src/route.ts +4 -1
- package/src/router.ts +2 -0
package/build/esm/index.js
CHANGED
|
@@ -671,6 +671,9 @@ function isRedirect(obj) {
|
|
|
671
671
|
|
|
672
672
|
const preloadWarning = 'Error preloading route! ☝️';
|
|
673
673
|
const routerContext = /*#__PURE__*/React.createContext(null);
|
|
674
|
+
if (typeof document !== 'undefined') {
|
|
675
|
+
window.__TSR_ROUTER_CONTEXT__ = routerContext;
|
|
676
|
+
}
|
|
674
677
|
function getInitialRouterState(location) {
|
|
675
678
|
return {
|
|
676
679
|
status: 'idle',
|
|
@@ -698,6 +701,10 @@ function RouterProvider({
|
|
|
698
701
|
const tempLocationKeyRef = React.useRef(`${Math.round(Math.random() * 10000000)}`);
|
|
699
702
|
const resetNextScrollRef = React.useRef(false);
|
|
700
703
|
const navigateTimeoutRef = React.useRef(null);
|
|
704
|
+
const latestLoadPromiseRef = React.useRef(Promise.resolve());
|
|
705
|
+
const checkLatest = promise => {
|
|
706
|
+
return latestLoadPromiseRef.current !== promise ? latestLoadPromiseRef.current : undefined;
|
|
707
|
+
};
|
|
701
708
|
const parseLocation = useStableCallback(previousLocation => {
|
|
702
709
|
const parse = ({
|
|
703
710
|
pathname,
|
|
@@ -821,7 +828,6 @@ function RouterProvider({
|
|
|
821
828
|
d.child.rank = i;
|
|
822
829
|
return d.child;
|
|
823
830
|
}), [routesByPath]);
|
|
824
|
-
const latestLoadPromiseRef = React.useRef(Promise.resolve());
|
|
825
831
|
const matchRoutes = useStableCallback((pathname, locationSearch, opts) => {
|
|
826
832
|
let routeParams = {};
|
|
827
833
|
let foundRoute = flatRoutes.find(route => {
|
|
@@ -1120,9 +1126,11 @@ function RouterProvider({
|
|
|
1120
1126
|
});
|
|
1121
1127
|
});
|
|
1122
1128
|
const loadMatches = useStableCallback(async ({
|
|
1129
|
+
checkLatest,
|
|
1123
1130
|
matches,
|
|
1124
1131
|
preload
|
|
1125
1132
|
}) => {
|
|
1133
|
+
let latestPromise;
|
|
1126
1134
|
let firstBadMatchIndex;
|
|
1127
1135
|
|
|
1128
1136
|
// Check each match middleware to see if the route can be accessed
|
|
@@ -1165,7 +1173,12 @@ function RouterProvider({
|
|
|
1165
1173
|
params: match.params,
|
|
1166
1174
|
preload: !!preload,
|
|
1167
1175
|
meta: parentMeta,
|
|
1168
|
-
location: state.location
|
|
1176
|
+
location: state.location,
|
|
1177
|
+
// TODO: This might need to be latestLocationRef.current...?
|
|
1178
|
+
navigate: opts => navigate({
|
|
1179
|
+
...opts,
|
|
1180
|
+
from: match.pathname
|
|
1181
|
+
})
|
|
1169
1182
|
})) ?? {};
|
|
1170
1183
|
const meta = {
|
|
1171
1184
|
...parentMeta,
|
|
@@ -1183,7 +1196,7 @@ function RouterProvider({
|
|
|
1183
1196
|
} catch (err) {
|
|
1184
1197
|
if (isRedirect(err)) {
|
|
1185
1198
|
if (!preload) navigate(err);
|
|
1186
|
-
return;
|
|
1199
|
+
return matches;
|
|
1187
1200
|
}
|
|
1188
1201
|
throw err;
|
|
1189
1202
|
}
|
|
@@ -1196,11 +1209,6 @@ function RouterProvider({
|
|
|
1196
1209
|
if (match.isFetching) {
|
|
1197
1210
|
return getRouteMatch(state, match.id)?.loadPromise;
|
|
1198
1211
|
}
|
|
1199
|
-
const fetchedAt = Date.now();
|
|
1200
|
-
const checkLatest = () => {
|
|
1201
|
-
const latest = getRouteMatch(state, match.id);
|
|
1202
|
-
return latest && latest.fetchedAt !== fetchedAt ? latest.loadPromise : undefined;
|
|
1203
|
-
};
|
|
1204
1212
|
const handleIfRedirect = err => {
|
|
1205
1213
|
if (isRedirect(err)) {
|
|
1206
1214
|
if (!preload) {
|
|
@@ -1211,7 +1219,6 @@ function RouterProvider({
|
|
|
1211
1219
|
return false;
|
|
1212
1220
|
};
|
|
1213
1221
|
const load = async () => {
|
|
1214
|
-
let latestPromise;
|
|
1215
1222
|
try {
|
|
1216
1223
|
const componentsPromise = Promise.all(componentTypes.map(async type => {
|
|
1217
1224
|
const component = route.options[type];
|
|
@@ -1225,7 +1232,12 @@ function RouterProvider({
|
|
|
1225
1232
|
preload: !!preload,
|
|
1226
1233
|
parentMatchPromise,
|
|
1227
1234
|
abortController: match.abortController,
|
|
1228
|
-
meta: match.meta
|
|
1235
|
+
meta: match.meta,
|
|
1236
|
+
location: state.location,
|
|
1237
|
+
navigate: opts => navigate({
|
|
1238
|
+
...opts,
|
|
1239
|
+
from: match.pathname
|
|
1240
|
+
})
|
|
1229
1241
|
});
|
|
1230
1242
|
await Promise.all([componentsPromise, loaderPromise]);
|
|
1231
1243
|
if (latestPromise = checkLatest()) return await latestPromise;
|
|
@@ -1253,12 +1265,18 @@ function RouterProvider({
|
|
|
1253
1265
|
updatedAt: Date.now()
|
|
1254
1266
|
};
|
|
1255
1267
|
}
|
|
1268
|
+
if (!preload) {
|
|
1269
|
+
setState(s => ({
|
|
1270
|
+
...s,
|
|
1271
|
+
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
1272
|
+
}));
|
|
1273
|
+
}
|
|
1256
1274
|
};
|
|
1257
1275
|
let loadPromise;
|
|
1258
1276
|
matches[index] = match = {
|
|
1259
1277
|
...match,
|
|
1260
1278
|
isFetching: true,
|
|
1261
|
-
fetchedAt,
|
|
1279
|
+
fetchedAt: Date.now(),
|
|
1262
1280
|
invalid: false
|
|
1263
1281
|
};
|
|
1264
1282
|
loadPromise = load();
|
|
@@ -1270,35 +1288,32 @@ function RouterProvider({
|
|
|
1270
1288
|
})());
|
|
1271
1289
|
});
|
|
1272
1290
|
await Promise.all(matchPromises);
|
|
1291
|
+
return matches;
|
|
1273
1292
|
});
|
|
1274
|
-
const load = useStableCallback(async
|
|
1293
|
+
const load = useStableCallback(async () => {
|
|
1275
1294
|
const promise = new Promise(async (resolve, reject) => {
|
|
1295
|
+
const next = latestLocationRef.current;
|
|
1276
1296
|
const prevLocation = state.resolvedLocation;
|
|
1277
|
-
const pathDidChange = !!(
|
|
1297
|
+
const pathDidChange = !!(next && prevLocation.href !== next.href);
|
|
1278
1298
|
let latestPromise;
|
|
1279
|
-
const checkLatest = () => {
|
|
1280
|
-
return latestLoadPromiseRef.current !== promise ? latestLoadPromiseRef.current : undefined;
|
|
1281
|
-
};
|
|
1282
1299
|
|
|
1283
1300
|
// Cancel any pending matches
|
|
1284
1301
|
cancelMatches(state);
|
|
1285
1302
|
router.emit({
|
|
1286
1303
|
type: 'onBeforeLoad',
|
|
1287
1304
|
from: prevLocation,
|
|
1288
|
-
to:
|
|
1305
|
+
to: next ?? state.location,
|
|
1289
1306
|
pathChanged: pathDidChange
|
|
1290
1307
|
});
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
}
|
|
1308
|
+
|
|
1309
|
+
// Ingest the new location
|
|
1310
|
+
setState(s => ({
|
|
1311
|
+
...s,
|
|
1312
|
+
location: next
|
|
1313
|
+
}));
|
|
1298
1314
|
|
|
1299
1315
|
// Match the routes
|
|
1300
|
-
|
|
1301
|
-
throwOnError: opts?.throwOnError,
|
|
1316
|
+
let matches = matchRoutes(next.pathname, next.search, {
|
|
1302
1317
|
debug: true
|
|
1303
1318
|
});
|
|
1304
1319
|
setState(s => ({
|
|
@@ -1307,10 +1322,11 @@ function RouterProvider({
|
|
|
1307
1322
|
matches
|
|
1308
1323
|
}));
|
|
1309
1324
|
try {
|
|
1310
|
-
// Load the matches
|
|
1311
1325
|
try {
|
|
1326
|
+
// Load the matches
|
|
1312
1327
|
await loadMatches({
|
|
1313
|
-
matches
|
|
1328
|
+
matches,
|
|
1329
|
+
checkLatest: () => checkLatest(promise)
|
|
1314
1330
|
});
|
|
1315
1331
|
} catch (err) {
|
|
1316
1332
|
// swallow this error, since we'll display the
|
|
@@ -1318,7 +1334,7 @@ function RouterProvider({
|
|
|
1318
1334
|
}
|
|
1319
1335
|
|
|
1320
1336
|
// Only apply the latest transition
|
|
1321
|
-
if (latestPromise = checkLatest()) {
|
|
1337
|
+
if (latestPromise = checkLatest(promise)) {
|
|
1322
1338
|
return latestPromise;
|
|
1323
1339
|
}
|
|
1324
1340
|
|
|
@@ -1355,13 +1371,13 @@ function RouterProvider({
|
|
|
1355
1371
|
router.emit({
|
|
1356
1372
|
type: 'onLoad',
|
|
1357
1373
|
from: prevLocation,
|
|
1358
|
-
to:
|
|
1374
|
+
to: next,
|
|
1359
1375
|
pathChanged: pathDidChange
|
|
1360
1376
|
});
|
|
1361
1377
|
resolve();
|
|
1362
1378
|
} catch (err) {
|
|
1363
1379
|
// Only apply the latest transition
|
|
1364
|
-
if (latestPromise = checkLatest()) {
|
|
1380
|
+
if (latestPromise = checkLatest(promise)) {
|
|
1365
1381
|
return latestPromise;
|
|
1366
1382
|
}
|
|
1367
1383
|
reject(err);
|
|
@@ -1370,13 +1386,6 @@ function RouterProvider({
|
|
|
1370
1386
|
latestLoadPromiseRef.current = promise;
|
|
1371
1387
|
return latestLoadPromiseRef.current;
|
|
1372
1388
|
});
|
|
1373
|
-
const safeLoad = React.useCallback(async () => {
|
|
1374
|
-
try {
|
|
1375
|
-
return load();
|
|
1376
|
-
} catch (err) {
|
|
1377
|
-
// Don't do anything
|
|
1378
|
-
}
|
|
1379
|
-
}, []);
|
|
1380
1389
|
const preloadRoute = useStableCallback(async (navigateOpts = state.location) => {
|
|
1381
1390
|
let next = buildLocation(navigateOpts);
|
|
1382
1391
|
let matches = matchRoutes(next.pathname, next.search, {
|
|
@@ -1384,7 +1393,8 @@ function RouterProvider({
|
|
|
1384
1393
|
});
|
|
1385
1394
|
await loadMatches({
|
|
1386
1395
|
matches,
|
|
1387
|
-
preload: true
|
|
1396
|
+
preload: true,
|
|
1397
|
+
checkLatest: () => undefined
|
|
1388
1398
|
});
|
|
1389
1399
|
return [last(matches), matches];
|
|
1390
1400
|
});
|
|
@@ -1497,10 +1507,13 @@ function RouterProvider({
|
|
|
1497
1507
|
const unsub = history.subscribe(() => {
|
|
1498
1508
|
latestLocationRef.current = parseLocation(latestLocationRef.current);
|
|
1499
1509
|
React.startTransition(() => {
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1510
|
+
if (state.location !== latestLocationRef.current) {
|
|
1511
|
+
try {
|
|
1512
|
+
load();
|
|
1513
|
+
} catch (err) {
|
|
1514
|
+
console.error(err);
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1504
1517
|
});
|
|
1505
1518
|
});
|
|
1506
1519
|
const nextLocation = buildLocation({
|
|
@@ -1522,13 +1535,12 @@ function RouterProvider({
|
|
|
1522
1535
|
const initialLoad = React.useRef(true);
|
|
1523
1536
|
if (initialLoad.current) {
|
|
1524
1537
|
initialLoad.current = false;
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
safeLoad();
|
|
1538
|
+
try {
|
|
1539
|
+
load();
|
|
1540
|
+
} catch (err) {
|
|
1541
|
+
console.error(err);
|
|
1530
1542
|
}
|
|
1531
|
-
}
|
|
1543
|
+
}
|
|
1532
1544
|
React.useMemo(() => [...state.matches, ...state.pendingMatches].some(d => d.isFetching), [state.matches, state.pendingMatches]);
|
|
1533
1545
|
const matchRoute = useStableCallback((state, location, opts) => {
|
|
1534
1546
|
location = {
|
|
@@ -1733,7 +1745,8 @@ function Navigate(props) {
|
|
|
1733
1745
|
}
|
|
1734
1746
|
const matchesContext = /*#__PURE__*/React.createContext(null);
|
|
1735
1747
|
function useRouter() {
|
|
1736
|
-
const
|
|
1748
|
+
const resolvedContext = window.__TSR_ROUTER_CONTEXT__ || routerContext;
|
|
1749
|
+
const value = React.useContext(resolvedContext);
|
|
1737
1750
|
warning(value, 'useRouter must be used inside a <RouterProvider> component!');
|
|
1738
1751
|
return value;
|
|
1739
1752
|
}
|
|
@@ -1811,6 +1824,9 @@ function useNavigate(defaultOpts) {
|
|
|
1811
1824
|
});
|
|
1812
1825
|
}, []);
|
|
1813
1826
|
}
|
|
1827
|
+
function typedNavigate(navigate) {
|
|
1828
|
+
return navigate;
|
|
1829
|
+
}
|
|
1814
1830
|
function useMatchRoute() {
|
|
1815
1831
|
const {
|
|
1816
1832
|
state,
|
|
@@ -2243,5 +2259,5 @@ class FileRoute {
|
|
|
2243
2259
|
};
|
|
2244
2260
|
}
|
|
2245
2261
|
|
|
2246
|
-
export { Block, CatchBoundary, CatchBoundaryImpl, ErrorComponent, FileRoute, Link, MatchRoute, Matches, Navigate, Outlet, PathParamError, RootRoute, Route, Router, RouterMeta, RouterProvider, SearchParamError, cleanPath, componentTypes, createRouteMask, decode, defaultParseSearch, defaultStringifySearch, encode, functionalUpdate, getInitialRouterState, getRouteMatch, interpolatePath, isPlainObject, isRedirect, isServer, joinPaths, last, lazyFn, lazyRouteComponent, matchByPath, matchPathname, matchesContext, parsePathname, parseSearchWith, partialDeepEqual, pick, redirect, replaceEqualDeep, resolvePath, rootRouteId, routerContext, shallow, stringifySearchWith, trimPath, trimPathLeft, trimPathRight, useBlocker, useLinkProps, useMatch, useMatchRoute, useMatches, useNavigate, useParams, useRouteMeta, useRouter, useRouterState, useSearch, useStableCallback };
|
|
2262
|
+
export { Block, CatchBoundary, CatchBoundaryImpl, ErrorComponent, FileRoute, Link, MatchRoute, Matches, Navigate, Outlet, PathParamError, RootRoute, Route, Router, RouterMeta, RouterProvider, SearchParamError, cleanPath, componentTypes, createRouteMask, decode, defaultParseSearch, defaultStringifySearch, encode, functionalUpdate, getInitialRouterState, getRouteMatch, interpolatePath, isPlainObject, isRedirect, isServer, joinPaths, last, lazyFn, lazyRouteComponent, matchByPath, matchPathname, matchesContext, parsePathname, parseSearchWith, partialDeepEqual, pick, redirect, replaceEqualDeep, resolvePath, rootRouteId, routerContext, shallow, stringifySearchWith, trimPath, trimPathLeft, trimPathRight, typedNavigate, useBlocker, useLinkProps, useMatch, useMatchRoute, useMatches, useNavigate, useParams, useRouteMeta, useRouter, useRouterState, useSearch, useStableCallback };
|
|
2247
2263
|
//# sourceMappingURL=index.js.map
|