@remix-run/router 0.0.0-experimental-bc2c864b → 0.0.0-experimental-a0888892
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 +12 -0
- package/dist/router.cjs.js +25 -24
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.js +25 -24
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +25 -24
- 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/dist/utils.d.ts +3 -3
- package/history.ts +4 -0
- package/package.json +1 -1
- package/router.ts +30 -17
- package/utils.ts +18 -32
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# `@remix-run/router`
|
|
2
2
|
|
|
3
|
+
## 1.15.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add a `createStaticHandler` `future.v7_throwAbortReason` flag to throw `request.signal.reason` (defaults to a `DOMException`) when a request is aborted instead of an `Error` such as `new Error("query() call aborted: GET /path")` ([#11104](https://github.com/remix-run/react-router/pull/11104))
|
|
8
|
+
|
|
9
|
+
- Please note that `DOMException` was added in Node v17 so you will not get a `DOMException` on Node 16 and below.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Respect the `ErrorResponse` status code if passed to `getStaticContextFormError` ([#11213](https://github.com/remix-run/react-router/pull/11213))
|
|
14
|
+
|
|
3
15
|
## 1.14.2
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/router.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v0.0.0-experimental-
|
|
2
|
+
* @remix-run/router v0.0.0-experimental-a0888892
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -496,6 +496,10 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
|
|
|
496
496
|
// See https://bugzilla.mozilla.org/show_bug.cgi?id=878297
|
|
497
497
|
let base = window.location.origin !== "null" ? window.location.origin : window.location.href;
|
|
498
498
|
let href = typeof to === "string" ? to : createPath(to);
|
|
499
|
+
// Treating this as a full URL will strip any trailing spaces so we need to
|
|
500
|
+
// pre-encode them since they might be part of a matching splat param from
|
|
501
|
+
// an ancestor route
|
|
502
|
+
href = href.replace(/ $/, "%20");
|
|
499
503
|
invariant(base, "No window.location.(origin|href) available to create URL for href: " + href);
|
|
500
504
|
return new URL(href, base);
|
|
501
505
|
}
|
|
@@ -756,14 +760,14 @@ function matchRoutes(routes, locationArg, basename) {
|
|
|
756
760
|
rankRouteBranches(branches);
|
|
757
761
|
let matches = null;
|
|
758
762
|
for (let i = 0; matches == null && i < branches.length; ++i) {
|
|
759
|
-
matches = matchRouteBranch(branches[i],
|
|
760
763
|
// Incoming pathnames are generally encoded from either window.location
|
|
761
764
|
// or from router.navigate, but we want to match against the unencoded
|
|
762
765
|
// paths in the route definitions. Memory router locations won't be
|
|
763
766
|
// encoded here but there also shouldn't be anything to decode so this
|
|
764
767
|
// should be a safe operation. This avoids needing matchRoutes to be
|
|
765
768
|
// history-aware.
|
|
766
|
-
|
|
769
|
+
let decoded = decodePath(pathname);
|
|
770
|
+
matches = matchRouteBranch(branches[i], decoded);
|
|
767
771
|
}
|
|
768
772
|
return matches;
|
|
769
773
|
}
|
|
@@ -1042,7 +1046,7 @@ function matchPath(pattern, pathname) {
|
|
|
1042
1046
|
if (isOptional && !value) {
|
|
1043
1047
|
memo[paramName] = undefined;
|
|
1044
1048
|
} else {
|
|
1045
|
-
memo[paramName] =
|
|
1049
|
+
memo[paramName] = (value || "").replace(/%2F/g, "/");
|
|
1046
1050
|
}
|
|
1047
1051
|
return memo;
|
|
1048
1052
|
}, {});
|
|
@@ -1094,22 +1098,14 @@ function compilePath(path, caseSensitive, end) {
|
|
|
1094
1098
|
let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i");
|
|
1095
1099
|
return [matcher, params];
|
|
1096
1100
|
}
|
|
1097
|
-
function
|
|
1101
|
+
function decodePath(value) {
|
|
1098
1102
|
try {
|
|
1099
|
-
return
|
|
1103
|
+
return value.split("/").map(v => decodeURIComponent(v).replace(/\//g, "%2F")).join("/");
|
|
1100
1104
|
} catch (error) {
|
|
1101
1105
|
warning(false, "The URL path \"" + value + "\" could not be decoded because it is is a " + "malformed URL segment. This is probably due to a bad percent " + ("encoding (" + error + ")."));
|
|
1102
1106
|
return value;
|
|
1103
1107
|
}
|
|
1104
1108
|
}
|
|
1105
|
-
function safelyDecodeURIComponent(value, paramName) {
|
|
1106
|
-
try {
|
|
1107
|
-
return decodeURIComponent(value);
|
|
1108
|
-
} catch (error) {
|
|
1109
|
-
warning(false, "The value for the URL param \"" + paramName + "\" will not be decoded because" + (" the string \"" + value + "\" is a malformed URL segment. This is probably") + (" due to a bad percent encoding (" + error + ")."));
|
|
1110
|
-
return value;
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
1109
|
|
|
1114
1110
|
/**
|
|
1115
1111
|
* @private
|
|
@@ -1731,7 +1727,7 @@ function createRouter(init) {
|
|
|
1731
1727
|
// were marked for explicit hydration
|
|
1732
1728
|
let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;
|
|
1733
1729
|
let errors = init.hydrationData ? init.hydrationData.errors : null;
|
|
1734
|
-
initialized = initialMatches.every(m => m.route.loader && m.route.loader.hydrate !== true && (loaderData && loaderData[m.route.id] !== undefined || errors && errors[m.route.id] !== undefined));
|
|
1730
|
+
initialized = initialMatches.every(m => m.route.loader && (typeof m.route.loader !== "function" || m.route.loader.hydrate !== true) && (loaderData && loaderData[m.route.id] !== undefined || errors && errors[m.route.id] !== undefined));
|
|
1735
1731
|
} else {
|
|
1736
1732
|
// Without partial hydration - we're initialized if we were provided any
|
|
1737
1733
|
// hydrationData - which is expected to be complete
|
|
@@ -3924,7 +3920,7 @@ function getMatchesToLoad(history, state, matches, submission, location, isIniti
|
|
|
3924
3920
|
return false;
|
|
3925
3921
|
}
|
|
3926
3922
|
if (isInitialLoad) {
|
|
3927
|
-
if (route.loader.hydrate) {
|
|
3923
|
+
if (typeof route.loader !== "function" || route.loader.hydrate) {
|
|
3928
3924
|
return true;
|
|
3929
3925
|
}
|
|
3930
3926
|
return state.loaderData[route.id] === undefined && (
|
|
@@ -4137,9 +4133,9 @@ async function callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLo
|
|
|
4137
4133
|
// loader/action, and mapping return values/thrown errors to a
|
|
4138
4134
|
// HandlerResult. Users can pass a callback to take fine-grained control
|
|
4139
4135
|
// over the execution of the loader/action
|
|
4140
|
-
let bikeshed_loadRoute =
|
|
4136
|
+
let bikeshed_loadRoute = handlerOverride => {
|
|
4141
4137
|
loadedMatches.add(match.route.id);
|
|
4142
|
-
return routeIdsToLoad.has(match.route.id) ? callLoaderOrAction(type, request, match, manifest, mapRouteProperties,
|
|
4138
|
+
return routeIdsToLoad.has(match.route.id) ? callLoaderOrAction(type, request, match, manifest, mapRouteProperties, handlerOverride, requestContext) :
|
|
4143
4139
|
// TODO: What's the best thing to do here - return an empty "success" result?
|
|
4144
4140
|
// Or return a success result with the current route loader/action data?
|
|
4145
4141
|
// We strip these results out if the route didn't need to be revalidated in
|
|
@@ -4169,7 +4165,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLo
|
|
|
4169
4165
|
}
|
|
4170
4166
|
|
|
4171
4167
|
// Default logic for calling a loader/action is the user has no specified a dataStrategy
|
|
4172
|
-
async function callLoaderOrAction(type, request, match, manifest, mapRouteProperties,
|
|
4168
|
+
async function callLoaderOrAction(type, request, match, manifest, mapRouteProperties, handlerOverride, staticContext) {
|
|
4173
4169
|
let result;
|
|
4174
4170
|
let onReject;
|
|
4175
4171
|
let runHandler = handler => {
|
|
@@ -4178,12 +4174,17 @@ async function callLoaderOrAction(type, request, match, manifest, mapRouteProper
|
|
|
4178
4174
|
let abortPromise = new Promise((_, r) => reject = r);
|
|
4179
4175
|
onReject = () => reject();
|
|
4180
4176
|
request.signal.addEventListener("abort", onReject);
|
|
4181
|
-
let
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4177
|
+
let runHandlerForReal = ctx => {
|
|
4178
|
+
if (typeof handler !== "function") {
|
|
4179
|
+
return Promise.reject(new Error("You cannot call the handler for a route which defines a boolean " + ("\"" + type + "\" [routeId: " + match.route.id + "]")));
|
|
4180
|
+
}
|
|
4181
|
+
return handler({
|
|
4182
|
+
request,
|
|
4183
|
+
params: match.params,
|
|
4184
|
+
context: staticContext
|
|
4185
|
+
}, ...(ctx !== undefined ? [ctx] : []));
|
|
4185
4186
|
};
|
|
4186
|
-
let handlerPromise =
|
|
4187
|
+
let handlerPromise = handlerOverride ? handlerOverride(async ctx => runHandlerForReal(ctx)) : runHandlerForReal();
|
|
4187
4188
|
return Promise.race([handlerPromise, abortPromise]);
|
|
4188
4189
|
};
|
|
4189
4190
|
try {
|