@remix-run/router 0.2.0-pre.7 → 0.2.0-pre.8
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 +9 -0
- package/dist/index.d.ts +1 -1
- package/dist/router.cjs.js +51 -25
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +15 -8
- package/dist/router.js +51 -25
- package/dist/router.js.map +1 -1
- package/dist/utils.d.ts +13 -15
- package/index.ts +4 -4
- package/package.json +1 -1
- package/router.ts +97 -62
- package/utils.ts +38 -26
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @remix-run/router
|
|
2
2
|
|
|
3
|
+
## 0.2.0-pre.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- fix: avoid uneccesary re-renders on `defer` resolution (#9155)
|
|
8
|
+
- fix: pass `useMatches` objects to `ScrollRestoration` `getKey` (#9157)
|
|
9
|
+
- fix: fetcher submission revalidating fetchers using wrong key (#9166)
|
|
10
|
+
- fix: use a push navigation on submission errors (#9162)
|
|
11
|
+
|
|
3
12
|
## 0.2.0-pre.7
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BrowserHistoryOptions, HashHistoryOptions, MemoryHistoryOptions } from "./history";
|
|
2
2
|
import type { Router, RouterInit } from "./router";
|
|
3
3
|
import { convertRoutesToDataRoutes } from "./utils";
|
|
4
|
-
export type { ActionFunction, ActionFunctionArgs,
|
|
4
|
+
export type { ActionFunction, ActionFunctionArgs, AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticRouteMatch, AgnosticRouteObject, TrackedPromise, FormEncType, FormMethod, JsonFunction, LoaderFunction, LoaderFunctionArgs, ParamParseKey, Params, PathMatch, PathPattern, RedirectFunction, ShouldRevalidateFunction, Submission, } from "./utils";
|
|
5
5
|
export { ErrorResponse, defer, generatePath, getToPathname, invariant, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, redirect, resolvePath, resolveTo, stripBasename, warning, } from "./utils";
|
|
6
6
|
export type { BrowserHistory, HashHistory, History, InitialEntry, Location, MemoryHistory, Path, To, } from "./history";
|
|
7
7
|
export { Action, createBrowserHistory, createPath, createHashHistory, createMemoryHistory, parsePath, } from "./history";
|
package/dist/router.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v0.2.0-pre.
|
|
2
|
+
* @remix-run/router v0.2.0-pre.8
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -890,10 +890,17 @@ function resolvePathname(relativePath, fromPathname) {
|
|
|
890
890
|
*/
|
|
891
891
|
|
|
892
892
|
|
|
893
|
-
function resolveTo(toArg, routePathnames, locationPathname) {
|
|
893
|
+
function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {
|
|
894
|
+
if (isPathRelative === void 0) {
|
|
895
|
+
isPathRelative = false;
|
|
896
|
+
}
|
|
897
|
+
|
|
894
898
|
let to = typeof toArg === "string" ? parsePath(toArg) : _extends({}, toArg);
|
|
895
899
|
let isEmptyPath = toArg === "" || to.pathname === "";
|
|
896
|
-
let toPathname = isEmptyPath ? "/" : to.pathname;
|
|
900
|
+
let toPathname = isEmptyPath ? "/" : to.pathname;
|
|
901
|
+
let from; // Routing is relative to the current pathname if explicitly requested.
|
|
902
|
+
//
|
|
903
|
+
// If a pathname is explicitly provided in `to`, it should be relative to the
|
|
897
904
|
// route context. This is explained in `Note on `<Link to>` values` in our
|
|
898
905
|
// migration guide from v5 as a means of disambiguation between `to` values
|
|
899
906
|
// that begin with `/` and those that do not. However, this is problematic for
|
|
@@ -901,9 +908,7 @@ function resolveTo(toArg, routePathnames, locationPathname) {
|
|
|
901
908
|
// hash string, in which case we should assume that the navigation is relative
|
|
902
909
|
// to the current location's pathname and *not* the route pathname.
|
|
903
910
|
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
if (toPathname == null) {
|
|
911
|
+
if (isPathRelative || toPathname == null) {
|
|
907
912
|
from = locationPathname;
|
|
908
913
|
} else {
|
|
909
914
|
let routePathnameIndex = routePathnames.length - 1;
|
|
@@ -1212,7 +1217,7 @@ function createRouter(init) {
|
|
|
1212
1217
|
|
|
1213
1218
|
if (initialMatches == null) {
|
|
1214
1219
|
// If we do not match a user-provided-route, fall back to the root
|
|
1215
|
-
// to allow the
|
|
1220
|
+
// to allow the error boundary to take over
|
|
1216
1221
|
let {
|
|
1217
1222
|
matches,
|
|
1218
1223
|
route,
|
|
@@ -1400,7 +1405,7 @@ function createRouter(init) {
|
|
|
1400
1405
|
return await startNavigation(historyAction, location, {
|
|
1401
1406
|
submission,
|
|
1402
1407
|
// Send through the formData serialization error if we have one so we can
|
|
1403
|
-
// render at the right
|
|
1408
|
+
// render at the right error boundary after we match routes
|
|
1404
1409
|
pendingError: error,
|
|
1405
1410
|
resetScroll,
|
|
1406
1411
|
replace: opts == null ? void 0 : opts.replace
|
|
@@ -1586,7 +1591,15 @@ function createRouter(init) {
|
|
|
1586
1591
|
if (isErrorResult(result)) {
|
|
1587
1592
|
// Store off the pending error - we use it to determine which loaders
|
|
1588
1593
|
// to call and will commit it when we complete the navigation
|
|
1589
|
-
let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);
|
|
1594
|
+
let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id); // By default, all submissions are REPLACE navigations, but if the
|
|
1595
|
+
// action threw an error that'll be rendered in an errorElement, we fall
|
|
1596
|
+
// back to PUSH so that the user can use the back button to get back to
|
|
1597
|
+
// the pre-submission form location to try again
|
|
1598
|
+
|
|
1599
|
+
if ((opts == null ? void 0 : opts.replace) !== true) {
|
|
1600
|
+
pendingAction = exports.Action.Push;
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1590
1603
|
return {
|
|
1591
1604
|
pendingActionError: {
|
|
1592
1605
|
[boundaryMatch.route.id]: result.error
|
|
@@ -1712,15 +1725,9 @@ function createRouter(init) {
|
|
|
1712
1725
|
|
|
1713
1726
|
activeDeferreds.forEach((deferredData, routeId) => {
|
|
1714
1727
|
deferredData.subscribe(aborted => {
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
[routeId]: deferredData.data
|
|
1719
|
-
})
|
|
1720
|
-
});
|
|
1721
|
-
} // Remove this instance if we were aborted or if promises have settled
|
|
1722
|
-
|
|
1723
|
-
|
|
1728
|
+
// Note: No need to updateState here since the TrackedPromise on
|
|
1729
|
+
// loaderData is stable across resolve/reject
|
|
1730
|
+
// Remove this instance if we were aborted or if promises have settled
|
|
1724
1731
|
if (aborted || deferredData.done) {
|
|
1725
1732
|
activeDeferreds.delete(routeId);
|
|
1726
1733
|
}
|
|
@@ -1879,7 +1886,7 @@ function createRouter(init) {
|
|
|
1879
1886
|
let [staleKey] = _ref6;
|
|
1880
1887
|
let revalidatingFetcher = {
|
|
1881
1888
|
state: "loading",
|
|
1882
|
-
data: (_state$fetchers$get3 = state.fetchers.get(
|
|
1889
|
+
data: (_state$fetchers$get3 = state.fetchers.get(staleKey)) == null ? void 0 : _state$fetchers$get3.data,
|
|
1883
1890
|
formMethod: undefined,
|
|
1884
1891
|
formAction: undefined,
|
|
1885
1892
|
formEncType: undefined,
|
|
@@ -2231,14 +2238,16 @@ function createRouter(init) {
|
|
|
2231
2238
|
|
|
2232
2239
|
function saveScrollPosition(location, matches) {
|
|
2233
2240
|
if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) {
|
|
2234
|
-
let
|
|
2241
|
+
let userMatches = matches.map(m => createUseMatchesMatch(m, state.loaderData));
|
|
2242
|
+
let key = getScrollRestorationKey(location, userMatches) || location.key;
|
|
2235
2243
|
savedScrollPositions[key] = getScrollPosition();
|
|
2236
2244
|
}
|
|
2237
2245
|
}
|
|
2238
2246
|
|
|
2239
2247
|
function getSavedScrollPosition(location, matches) {
|
|
2240
2248
|
if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) {
|
|
2241
|
-
let
|
|
2249
|
+
let userMatches = matches.map(m => createUseMatchesMatch(m, state.loaderData));
|
|
2250
|
+
let key = getScrollRestorationKey(location, userMatches) || location.key;
|
|
2242
2251
|
let y = savedScrollPositions[key];
|
|
2243
2252
|
|
|
2244
2253
|
if (typeof y === "number") {
|
|
@@ -2869,7 +2878,7 @@ function processRouteLoaderData(matches, matchesToLoad, results, pendingError, a
|
|
|
2869
2878
|
|
|
2870
2879
|
if (isErrorResult(result)) {
|
|
2871
2880
|
// Look upwards from the matched route for the closest ancestor
|
|
2872
|
-
//
|
|
2881
|
+
// error boundary, defaulting to the root match
|
|
2873
2882
|
let boundaryMatch = findNearestBoundary(matches, id);
|
|
2874
2883
|
let error = result.error; // If we have a pending action error, we report it at the highest-route
|
|
2875
2884
|
// that throws a loader error, and then clear it out to indicate that
|
|
@@ -2981,13 +2990,13 @@ function mergeLoaderData(loaderData, newLoaderData, matches) {
|
|
|
2981
2990
|
});
|
|
2982
2991
|
return mergedLoaderData;
|
|
2983
2992
|
} // Find the nearest error boundary, looking upwards from the leaf route (or the
|
|
2984
|
-
// route specified by routeId) for the closest ancestor
|
|
2985
|
-
// to the root match
|
|
2993
|
+
// route specified by routeId) for the closest ancestor error boundary,
|
|
2994
|
+
// defaulting to the root match
|
|
2986
2995
|
|
|
2987
2996
|
|
|
2988
2997
|
function findNearestBoundary(matches, routeId) {
|
|
2989
2998
|
let eligibleMatches = routeId ? matches.slice(0, matches.findIndex(m => m.route.id === routeId) + 1) : [...matches];
|
|
2990
|
-
return eligibleMatches.reverse().find(m => m.route.
|
|
2999
|
+
return eligibleMatches.reverse().find(m => m.route.hasErrorBoundary === true) || matches[0];
|
|
2991
3000
|
}
|
|
2992
3001
|
|
|
2993
3002
|
function getNotFoundMatches(routes) {
|
|
@@ -3100,6 +3109,23 @@ async function resolveDeferredData(result, signal, unwrap) {
|
|
|
3100
3109
|
|
|
3101
3110
|
function hasNakedIndexQuery(search) {
|
|
3102
3111
|
return new URLSearchParams(search).getAll("index").some(v => v === "");
|
|
3112
|
+
} // Note: This should match the format exported by useMatches, so if you change
|
|
3113
|
+
// this please also change that :) Eventually we'll DRY this up
|
|
3114
|
+
|
|
3115
|
+
|
|
3116
|
+
function createUseMatchesMatch(match, loaderData) {
|
|
3117
|
+
let {
|
|
3118
|
+
route,
|
|
3119
|
+
pathname,
|
|
3120
|
+
params
|
|
3121
|
+
} = match;
|
|
3122
|
+
return {
|
|
3123
|
+
id: route.id,
|
|
3124
|
+
pathname,
|
|
3125
|
+
params,
|
|
3126
|
+
data: loaderData[route.id],
|
|
3127
|
+
handle: route.handle
|
|
3128
|
+
};
|
|
3103
3129
|
}
|
|
3104
3130
|
|
|
3105
3131
|
function getTargetMatch(matches, location) {
|