@remix-run/router 1.14.0-pre.1 → 1.14.1-pre.0
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/CHANGELOG.md +6 -4
- package/dist/router.cjs.js +53 -66
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.js +50 -62
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +53 -66
- package/dist/router.umd.js.map +1 -1
- package/dist/router.umd.min.js +2 -2
- package/dist/router.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/router.ts +45 -48
- package/utils.ts +5 -28
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# `@remix-run/router`
|
|
2
2
|
|
|
3
|
-
## 1.14.
|
|
3
|
+
## 1.14.1-pre.0
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- Fix bug with `route.lazy` not working correctly on initial SPA load when `v7_partialHydration` is specified ([#11121](https://github.com/remix-run/react-router/pull/11121))
|
|
8
|
+
- Fix bug preventing revalidation from occurring for persisted fetchers unmounted during the `submitting` phase ([#11102](https://github.com/remix-run/react-router/pull/11102))
|
|
9
|
+
- De-dup relative path logic in `resolveTo` ([#11097](https://github.com/remix-run/react-router/pull/11097))
|
|
8
10
|
|
|
9
|
-
## 1.14.0
|
|
11
|
+
## 1.14.0
|
|
10
12
|
|
|
11
13
|
### Minor Changes
|
|
12
14
|
|
|
@@ -155,7 +157,7 @@
|
|
|
155
157
|
<BrowserRouter>
|
|
156
158
|
<Routes>
|
|
157
159
|
<Route path="dashboard">
|
|
158
|
-
<Route path="*" element={<Dashboard />} />
|
|
160
|
+
<Route index path="*" element={<Dashboard />} />
|
|
159
161
|
</Route>
|
|
160
162
|
</Routes>
|
|
161
163
|
</BrowserRouter>
|
package/dist/router.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.14.
|
|
2
|
+
* @remix-run/router v1.14.1-pre.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -1237,37 +1237,21 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {
|
|
|
1237
1237
|
// to the current location's pathname and *not* the route pathname.
|
|
1238
1238
|
if (toPathname == null) {
|
|
1239
1239
|
from = locationPathname;
|
|
1240
|
-
} else if (isPathRelative) {
|
|
1241
|
-
let fromSegments = routePathnames.length === 0 ? [] : routePathnames[routePathnames.length - 1].replace(/^\//, "").split("/");
|
|
1242
|
-
if (toPathname.startsWith("..")) {
|
|
1243
|
-
let toSegments = toPathname.split("/");
|
|
1244
|
-
|
|
1245
|
-
// With relative="path", each leading .. segment means "go up one URL segment"
|
|
1246
|
-
while (toSegments[0] === "..") {
|
|
1247
|
-
toSegments.shift();
|
|
1248
|
-
fromSegments.pop();
|
|
1249
|
-
}
|
|
1250
|
-
to.pathname = toSegments.join("/");
|
|
1251
|
-
}
|
|
1252
|
-
from = "/" + fromSegments.join("/");
|
|
1253
1240
|
} else {
|
|
1254
1241
|
let routePathnameIndex = routePathnames.length - 1;
|
|
1255
|
-
if (toPathname.startsWith("..")) {
|
|
1256
|
-
let toSegments = toPathname.split("/");
|
|
1257
1242
|
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1243
|
+
// With relative="route" (the default), each leading .. segment means
|
|
1244
|
+
// "go up one route" instead of "go up one URL segment". This is a key
|
|
1245
|
+
// difference from how <a href> works and a major reason we call this a
|
|
1246
|
+
// "to" value instead of a "href".
|
|
1247
|
+
if (!isPathRelative && toPathname.startsWith("..")) {
|
|
1248
|
+
let toSegments = toPathname.split("/");
|
|
1262
1249
|
while (toSegments[0] === "..") {
|
|
1263
1250
|
toSegments.shift();
|
|
1264
1251
|
routePathnameIndex -= 1;
|
|
1265
1252
|
}
|
|
1266
1253
|
to.pathname = toSegments.join("/");
|
|
1267
1254
|
}
|
|
1268
|
-
|
|
1269
|
-
// If there are more ".." segments than parent routes, resolve relative to
|
|
1270
|
-
// the root / URL.
|
|
1271
1255
|
from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
|
|
1272
1256
|
}
|
|
1273
1257
|
let path = resolvePath(to, from);
|
|
@@ -2644,32 +2628,40 @@ function createRouter(init) {
|
|
|
2644
2628
|
}
|
|
2645
2629
|
return;
|
|
2646
2630
|
}
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
if (
|
|
2652
|
-
|
|
2653
|
-
if (pendingNavigationLoadId > originatingLoadId) {
|
|
2654
|
-
// A new navigation was kicked off after our action started, so that
|
|
2655
|
-
// should take precedence over this redirect navigation. We already
|
|
2656
|
-
// set isRevalidationRequired so all loaders for the new route should
|
|
2657
|
-
// fire unless opted out via shouldRevalidate
|
|
2631
|
+
|
|
2632
|
+
// When using v7_fetcherPersist, we don't want errors bubbling up to the UI
|
|
2633
|
+
// or redirects processed for unmounted fetchers so we just revert them to
|
|
2634
|
+
// idle
|
|
2635
|
+
if (future.v7_fetcherPersist && deletedFetchers.has(key)) {
|
|
2636
|
+
if (isRedirectResult(actionResult) || isErrorResult(actionResult)) {
|
|
2658
2637
|
updateFetcherState(key, getDoneFetcher(undefined));
|
|
2659
2638
|
return;
|
|
2660
|
-
} else {
|
|
2661
|
-
fetchRedirectIds.add(key);
|
|
2662
|
-
updateFetcherState(key, getLoadingFetcher(submission));
|
|
2663
|
-
return startRedirectNavigation(state, actionResult, {
|
|
2664
|
-
fetcherSubmission: submission
|
|
2665
|
-
});
|
|
2666
2639
|
}
|
|
2667
|
-
|
|
2640
|
+
// Let SuccessResult's fall through for revalidation
|
|
2641
|
+
} else {
|
|
2642
|
+
if (isRedirectResult(actionResult)) {
|
|
2643
|
+
fetchControllers.delete(key);
|
|
2644
|
+
if (pendingNavigationLoadId > originatingLoadId) {
|
|
2645
|
+
// A new navigation was kicked off after our action started, so that
|
|
2646
|
+
// should take precedence over this redirect navigation. We already
|
|
2647
|
+
// set isRevalidationRequired so all loaders for the new route should
|
|
2648
|
+
// fire unless opted out via shouldRevalidate
|
|
2649
|
+
updateFetcherState(key, getDoneFetcher(undefined));
|
|
2650
|
+
return;
|
|
2651
|
+
} else {
|
|
2652
|
+
fetchRedirectIds.add(key);
|
|
2653
|
+
updateFetcherState(key, getLoadingFetcher(submission));
|
|
2654
|
+
return startRedirectNavigation(state, actionResult, {
|
|
2655
|
+
fetcherSubmission: submission
|
|
2656
|
+
});
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2668
2659
|
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2660
|
+
// Process any non-redirect errors thrown
|
|
2661
|
+
if (isErrorResult(actionResult)) {
|
|
2662
|
+
setFetcherError(key, routeId, actionResult.error);
|
|
2663
|
+
return;
|
|
2664
|
+
}
|
|
2673
2665
|
}
|
|
2674
2666
|
if (isDeferredResult(actionResult)) {
|
|
2675
2667
|
throw getInternalRouterError(400, {
|
|
@@ -2806,6 +2798,9 @@ function createRouter(init) {
|
|
|
2806
2798
|
if (fetchRequest.signal.aborted) {
|
|
2807
2799
|
return;
|
|
2808
2800
|
}
|
|
2801
|
+
|
|
2802
|
+
// We don't want errors bubbling up or redirects followed for unmounted
|
|
2803
|
+
// fetchers, so short circuit here if it was removed from the UI
|
|
2809
2804
|
if (deletedFetchers.has(key)) {
|
|
2810
2805
|
updateFetcherState(key, getDoneFetcher(undefined));
|
|
2811
2806
|
return;
|
|
@@ -3864,18 +3859,24 @@ function getMatchesToLoad(history, state, matches, submission, location, isIniti
|
|
|
3864
3859
|
let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;
|
|
3865
3860
|
let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);
|
|
3866
3861
|
let navigationMatches = boundaryMatches.filter((match, index) => {
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
}
|
|
3872
|
-
if (match.route.lazy) {
|
|
3862
|
+
let {
|
|
3863
|
+
route
|
|
3864
|
+
} = match;
|
|
3865
|
+
if (route.lazy) {
|
|
3873
3866
|
// We haven't loaded this route yet so we don't know if it's got a loader!
|
|
3874
3867
|
return true;
|
|
3875
3868
|
}
|
|
3876
|
-
if (
|
|
3869
|
+
if (route.loader == null) {
|
|
3877
3870
|
return false;
|
|
3878
3871
|
}
|
|
3872
|
+
if (isInitialLoad) {
|
|
3873
|
+
if (route.loader.hydrate) {
|
|
3874
|
+
return true;
|
|
3875
|
+
}
|
|
3876
|
+
return state.loaderData[route.id] === undefined && (
|
|
3877
|
+
// Don't re-run if the loader ran and threw an error
|
|
3878
|
+
!state.errors || state.errors[route.id] === undefined);
|
|
3879
|
+
}
|
|
3879
3880
|
|
|
3880
3881
|
// Always call the loader on new route instances and pending defer cancellations
|
|
3881
3882
|
if (isNewLoader(state.loaderData, state.matches[index], match) || cancelledDeferredRoutes.some(id => id === match.route.id)) {
|
|
@@ -3977,20 +3978,6 @@ function getMatchesToLoad(history, state, matches, submission, location, isIniti
|
|
|
3977
3978
|
});
|
|
3978
3979
|
return [navigationMatches, revalidatingFetchers];
|
|
3979
3980
|
}
|
|
3980
|
-
|
|
3981
|
-
// Is this route unhydrated (when v7_partialHydration=true) such that we need
|
|
3982
|
-
// to call it's loader on the initial router creation
|
|
3983
|
-
function isUnhydratedRoute(state, route) {
|
|
3984
|
-
if (!route.loader) {
|
|
3985
|
-
return false;
|
|
3986
|
-
}
|
|
3987
|
-
if (route.loader.hydrate) {
|
|
3988
|
-
return true;
|
|
3989
|
-
}
|
|
3990
|
-
return state.loaderData[route.id] === undefined && (!state.errors ||
|
|
3991
|
-
// Loader ran but errored - don't re-run
|
|
3992
|
-
state.errors[route.id] === undefined);
|
|
3993
|
-
}
|
|
3994
3981
|
function isNewLoader(currentLoaderData, currentMatch, match) {
|
|
3995
3982
|
let isNew =
|
|
3996
3983
|
// [a] -> [a, b]
|