@remix-run/router 1.10.0-pre.0 → 1.11.0-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 +13 -34
- package/dist/router.cjs.js +68 -21
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +3 -2
- package/dist/router.js +66 -21
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +68 -21
- 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 +39 -7
- package/utils.ts +19 -15
package/dist/router.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.
|
|
2
|
+
* @remix-run/router v1.11.0-pre.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -1019,20 +1019,29 @@
|
|
|
1019
1019
|
end: true
|
|
1020
1020
|
};
|
|
1021
1021
|
}
|
|
1022
|
-
let [matcher,
|
|
1022
|
+
let [matcher, compiledParams] = compilePath(pattern.path, pattern.caseSensitive, pattern.end);
|
|
1023
1023
|
let match = pathname.match(matcher);
|
|
1024
1024
|
if (!match) return null;
|
|
1025
1025
|
let matchedPathname = match[0];
|
|
1026
1026
|
let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
|
|
1027
1027
|
let captureGroups = match.slice(1);
|
|
1028
|
-
let params =
|
|
1028
|
+
let params = compiledParams.reduce((memo, _ref, index) => {
|
|
1029
|
+
let {
|
|
1030
|
+
paramName,
|
|
1031
|
+
isOptional
|
|
1032
|
+
} = _ref;
|
|
1029
1033
|
// We need to compute the pathnameBase here using the raw splat value
|
|
1030
1034
|
// instead of using params["*"] later because it will be decoded then
|
|
1031
1035
|
if (paramName === "*") {
|
|
1032
1036
|
let splatValue = captureGroups[index] || "";
|
|
1033
1037
|
pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
|
|
1034
1038
|
}
|
|
1035
|
-
|
|
1039
|
+
const value = captureGroups[index];
|
|
1040
|
+
if (isOptional && !value) {
|
|
1041
|
+
memo[paramName] = undefined;
|
|
1042
|
+
} else {
|
|
1043
|
+
memo[paramName] = safelyDecodeURIComponent(value || "", paramName);
|
|
1044
|
+
}
|
|
1036
1045
|
return memo;
|
|
1037
1046
|
}, {});
|
|
1038
1047
|
return {
|
|
@@ -1050,16 +1059,21 @@
|
|
|
1050
1059
|
end = true;
|
|
1051
1060
|
}
|
|
1052
1061
|
warning(path === "*" || !path.endsWith("*") || path.endsWith("/*"), "Route path \"" + path + "\" will be treated as if it were " + ("\"" + path.replace(/\*$/, "/*") + "\" because the `*` character must ") + "always follow a `/` in the pattern. To get rid of this warning, " + ("please change the route path to \"" + path.replace(/\*$/, "/*") + "\"."));
|
|
1053
|
-
let
|
|
1062
|
+
let params = [];
|
|
1054
1063
|
let regexpSource = "^" + path.replace(/\/*\*?$/, "") // Ignore trailing / and /*, we'll handle it below
|
|
1055
1064
|
.replace(/^\/*/, "/") // Make sure it has a leading /
|
|
1056
|
-
.replace(/[
|
|
1057
|
-
.replace(/\/:(\w+)
|
|
1058
|
-
|
|
1059
|
-
|
|
1065
|
+
.replace(/[\\.*+^${}|()[\]]/g, "\\$&") // Escape special regex chars
|
|
1066
|
+
.replace(/\/:(\w+)(\?)?/g, (_, paramName, isOptional) => {
|
|
1067
|
+
params.push({
|
|
1068
|
+
paramName,
|
|
1069
|
+
isOptional: isOptional != null
|
|
1070
|
+
});
|
|
1071
|
+
return isOptional ? "/?([^\\/]+)?" : "/([^\\/]+)";
|
|
1060
1072
|
});
|
|
1061
1073
|
if (path.endsWith("*")) {
|
|
1062
|
-
|
|
1074
|
+
params.push({
|
|
1075
|
+
paramName: "*"
|
|
1076
|
+
});
|
|
1063
1077
|
regexpSource += path === "*" || path === "/*" ? "(.*)$" // Already matched the initial /, just match the rest
|
|
1064
1078
|
: "(?:\\/(.+)|\\/*)$"; // Don't include the / in params["*"]
|
|
1065
1079
|
} else if (end) {
|
|
@@ -1076,7 +1090,7 @@
|
|
|
1076
1090
|
regexpSource += "(?:(?=\\/|$))";
|
|
1077
1091
|
} else ;
|
|
1078
1092
|
let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i");
|
|
1079
|
-
return [matcher,
|
|
1093
|
+
return [matcher, params];
|
|
1080
1094
|
}
|
|
1081
1095
|
function safelyDecodeURI(value) {
|
|
1082
1096
|
try {
|
|
@@ -1304,8 +1318,8 @@
|
|
|
1304
1318
|
let onAbort = () => reject(new AbortedDeferredError("Deferred data aborted"));
|
|
1305
1319
|
this.unlistenAbortSignal = () => this.controller.signal.removeEventListener("abort", onAbort);
|
|
1306
1320
|
this.controller.signal.addEventListener("abort", onAbort);
|
|
1307
|
-
this.data = Object.entries(data).reduce((acc,
|
|
1308
|
-
let [key, value] =
|
|
1321
|
+
this.data = Object.entries(data).reduce((acc, _ref2) => {
|
|
1322
|
+
let [key, value] = _ref2;
|
|
1309
1323
|
return Object.assign(acc, {
|
|
1310
1324
|
[key]: this.trackPromise(key, value)
|
|
1311
1325
|
});
|
|
@@ -1405,8 +1419,8 @@
|
|
|
1405
1419
|
}
|
|
1406
1420
|
get unwrappedData() {
|
|
1407
1421
|
invariant(this.data !== null && this.done, "Can only unwrap data on initialized and settled deferreds");
|
|
1408
|
-
return Object.entries(this.data).reduce((acc,
|
|
1409
|
-
let [key, value] =
|
|
1422
|
+
return Object.entries(this.data).reduce((acc, _ref3) => {
|
|
1423
|
+
let [key, value] = _ref3;
|
|
1410
1424
|
return Object.assign(acc, {
|
|
1411
1425
|
[key]: unwrapTrackedPromise(value)
|
|
1412
1426
|
});
|
|
@@ -1651,6 +1665,7 @@
|
|
|
1651
1665
|
let basename = init.basename || "/";
|
|
1652
1666
|
// Config driven behavior flags
|
|
1653
1667
|
let future = _extends({
|
|
1668
|
+
v7_fetcherPersist: false,
|
|
1654
1669
|
v7_normalizeFormMethod: false,
|
|
1655
1670
|
v7_prependBasename: false
|
|
1656
1671
|
}, init.future);
|
|
@@ -1770,6 +1785,10 @@
|
|
|
1770
1785
|
// Most recent href/match for fetcher.load calls for fetchers
|
|
1771
1786
|
let fetchLoadMatches = new Map();
|
|
1772
1787
|
|
|
1788
|
+
// Fetchers that have requested a delete when using v7_fetcherPersist,
|
|
1789
|
+
// they'll be officially removed after they return to idle
|
|
1790
|
+
let deletedFetchers = new Set();
|
|
1791
|
+
|
|
1773
1792
|
// Store DeferredData instances for active route matches. When a
|
|
1774
1793
|
// route loader returns defer() we stick one in here. Then, when a nested
|
|
1775
1794
|
// promise resolves we update loaderData. If a new navigation starts we
|
|
@@ -1885,6 +1904,24 @@
|
|
|
1885
1904
|
subscribers.forEach(subscriber => subscriber(state, {
|
|
1886
1905
|
unstable_viewTransitionOpts: viewTransitionOpts
|
|
1887
1906
|
}));
|
|
1907
|
+
|
|
1908
|
+
// Remove idle fetchers from state since we only care about in-flight fetchers.
|
|
1909
|
+
if (future.v7_fetcherPersist) {
|
|
1910
|
+
state.fetchers.forEach((fetcher, key) => {
|
|
1911
|
+
if (fetcher.state === "idle") {
|
|
1912
|
+
if (deletedFetchers.has(key)) {
|
|
1913
|
+
// If the fetcher has unmounted and called router.deleteFetcher(),
|
|
1914
|
+
// we can totally delete the fetcher
|
|
1915
|
+
deleteFetcher(key);
|
|
1916
|
+
} else {
|
|
1917
|
+
// Otherwise, it must still be mounted in the UI so we just remove
|
|
1918
|
+
// it from state now that we've handed off the data to the React
|
|
1919
|
+
// layer. Things such as fetchLoadMatches remain for revalidation.
|
|
1920
|
+
state.fetchers.delete(key);
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
});
|
|
1924
|
+
}
|
|
1888
1925
|
}
|
|
1889
1926
|
|
|
1890
1927
|
// Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION
|
|
@@ -2626,7 +2663,7 @@
|
|
|
2626
2663
|
let doneFetcher = getDoneFetcher(actionResult.data);
|
|
2627
2664
|
state.fetchers.set(key, doneFetcher);
|
|
2628
2665
|
}
|
|
2629
|
-
|
|
2666
|
+
abortStaleFetchLoads(loadId);
|
|
2630
2667
|
|
|
2631
2668
|
// If we are currently in a navigation loading state and this fetcher is
|
|
2632
2669
|
// more recent than the navigation, we want the newer data so abort the
|
|
@@ -2644,12 +2681,11 @@
|
|
|
2644
2681
|
// otherwise just update with the fetcher data, preserving any existing
|
|
2645
2682
|
// loaderData for loaders that did not need to reload. We have to
|
|
2646
2683
|
// manually merge here since we aren't going through completeNavigation
|
|
2647
|
-
updateState(
|
|
2684
|
+
updateState({
|
|
2648
2685
|
errors,
|
|
2649
|
-
loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors)
|
|
2650
|
-
}, didAbortFetchLoads || revalidatingFetchers.length > 0 ? {
|
|
2686
|
+
loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors),
|
|
2651
2687
|
fetchers: new Map(state.fetchers)
|
|
2652
|
-
}
|
|
2688
|
+
});
|
|
2653
2689
|
isRevalidationRequired = false;
|
|
2654
2690
|
}
|
|
2655
2691
|
}
|
|
@@ -2890,8 +2926,19 @@
|
|
|
2890
2926
|
fetchLoadMatches.delete(key);
|
|
2891
2927
|
fetchReloadIds.delete(key);
|
|
2892
2928
|
fetchRedirectIds.delete(key);
|
|
2929
|
+
deletedFetchers.delete(key);
|
|
2893
2930
|
state.fetchers.delete(key);
|
|
2894
2931
|
}
|
|
2932
|
+
function deleteFetcherAndUpdateState(key) {
|
|
2933
|
+
if (future.v7_fetcherPersist) {
|
|
2934
|
+
deletedFetchers.add(key);
|
|
2935
|
+
} else {
|
|
2936
|
+
deleteFetcher(key);
|
|
2937
|
+
}
|
|
2938
|
+
updateState({
|
|
2939
|
+
fetchers: new Map(state.fetchers)
|
|
2940
|
+
});
|
|
2941
|
+
}
|
|
2895
2942
|
function abortFetcher(key) {
|
|
2896
2943
|
let controller = fetchControllers.get(key);
|
|
2897
2944
|
invariant(controller, "Expected fetch controller: " + key);
|
|
@@ -3086,7 +3133,7 @@
|
|
|
3086
3133
|
createHref: to => init.history.createHref(to),
|
|
3087
3134
|
encodeLocation: to => init.history.encodeLocation(to),
|
|
3088
3135
|
getFetcher,
|
|
3089
|
-
deleteFetcher,
|
|
3136
|
+
deleteFetcher: deleteFetcherAndUpdateState,
|
|
3090
3137
|
dispose,
|
|
3091
3138
|
getBlocker,
|
|
3092
3139
|
deleteBlocker,
|