@remix-run/router 1.1.0 → 1.2.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 -0
- package/dist/router.cjs.js +150 -56
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +4 -1
- package/dist/router.js +149 -56
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +150 -56
- 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 +152 -47
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# `@remix-run/router`
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Remove `unstable_` prefix from `createStaticHandler`/`createStaticRouter`/`StaticRouterProvider` ([#9738](https://github.com/remix-run/react-router/pull/9738))
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Fix explicit `replace` on submissions and `PUSH` on submission to new paths ([#9734](https://github.com/remix-run/react-router/pull/9734))
|
|
12
|
+
- Fix a few bugs where loader/action data wasn't properly cleared on errors ([#9735](https://github.com/remix-run/react-router/pull/9735))
|
|
13
|
+
- Prevent `useLoaderData` usage in `errorElement` ([#9735](https://github.com/remix-run/react-router/pull/9735))
|
|
14
|
+
- Skip initial scroll restoration for SSR apps with `hydrationData` ([#9664](https://github.com/remix-run/react-router/pull/9664))
|
|
15
|
+
|
|
3
16
|
## 1.1.0
|
|
4
17
|
|
|
5
18
|
This release introduces support for [Optional Route Segments](https://github.com/remix-run/react-router/issues/9546). Now, adding a `?` to the end of any path segment will make that entire segment optional. This works for both static segments and dynamic parameters.
|
package/dist/router.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.
|
|
2
|
+
* @remix-run/router v1.2.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -1415,8 +1415,10 @@ function createRouter(init) {
|
|
|
1415
1415
|
// we don't get the saved positions from <ScrollRestoration /> until _after_
|
|
1416
1416
|
// the initial render, we need to manually trigger a separate updateState to
|
|
1417
1417
|
// send along the restoreScrollPosition
|
|
1418
|
+
// Set to true if we have `hydrationData` since we assume we were SSR'd and that
|
|
1419
|
+
// SSR did the initial scroll restoration.
|
|
1418
1420
|
|
|
1419
|
-
let initialScrollRestored =
|
|
1421
|
+
let initialScrollRestored = init.hydrationData != null;
|
|
1420
1422
|
let initialMatches = matchRoutes(dataRoutes, init.history.location, init.basename);
|
|
1421
1423
|
let initialErrors = null;
|
|
1422
1424
|
|
|
@@ -1444,7 +1446,8 @@ function createRouter(init) {
|
|
|
1444
1446
|
matches: initialMatches,
|
|
1445
1447
|
initialized,
|
|
1446
1448
|
navigation: IDLE_NAVIGATION,
|
|
1447
|
-
|
|
1449
|
+
// Don't restore on initial updateState() if we were SSR'd
|
|
1450
|
+
restoreScrollPosition: init.hydrationData != null ? false : null,
|
|
1448
1451
|
preventScrollReset: false,
|
|
1449
1452
|
revalidation: "idle",
|
|
1450
1453
|
loaderData: init.hydrationData && init.hydrationData.loaderData || {},
|
|
@@ -1553,14 +1556,30 @@ function createRouter(init) {
|
|
|
1553
1556
|
// location, indicating we redirected from the action (avoids false
|
|
1554
1557
|
// positives for loading/submissionRedirect when actionData returned
|
|
1555
1558
|
// on a prior submission)
|
|
1556
|
-
let isActionReload = state.actionData != null && state.navigation.formMethod != null && state.navigation.state === "loading" && ((_state$navigation$for = state.navigation.formAction) == null ? void 0 : _state$navigation$for.split("?")[0]) === location.pathname;
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1559
|
+
let isActionReload = state.actionData != null && state.navigation.formMethod != null && state.navigation.state === "loading" && ((_state$navigation$for = state.navigation.formAction) == null ? void 0 : _state$navigation$for.split("?")[0]) === location.pathname;
|
|
1560
|
+
let actionData;
|
|
1561
|
+
|
|
1562
|
+
if (newState.actionData) {
|
|
1563
|
+
if (Object.keys(newState.actionData).length > 0) {
|
|
1564
|
+
actionData = newState.actionData;
|
|
1565
|
+
} else {
|
|
1566
|
+
// Empty actionData -> clear prior actionData due to an action error
|
|
1567
|
+
actionData = null;
|
|
1568
|
+
}
|
|
1569
|
+
} else if (isActionReload) {
|
|
1570
|
+
// Keep the current data if we're wrapping up the action reload
|
|
1571
|
+
actionData = state.actionData;
|
|
1572
|
+
} else {
|
|
1573
|
+
// Clear actionData on any other completed navigations
|
|
1574
|
+
actionData = null;
|
|
1575
|
+
} // Always preserve any existing loaderData from re-used routes
|
|
1576
|
+
|
|
1577
|
+
|
|
1578
|
+
let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData;
|
|
1579
|
+
updateState(_extends({}, newState, {
|
|
1580
|
+
// matches, errors, fetchers go through as-is
|
|
1581
|
+
actionData,
|
|
1582
|
+
loaderData,
|
|
1564
1583
|
historyAction: pendingAction,
|
|
1565
1584
|
location,
|
|
1566
1585
|
initialized: true,
|
|
@@ -1606,7 +1625,19 @@ function createRouter(init) {
|
|
|
1606
1625
|
// without having to touch history
|
|
1607
1626
|
|
|
1608
1627
|
location = _extends({}, location, init.history.encodeLocation(location));
|
|
1609
|
-
let
|
|
1628
|
+
let userReplace = opts && opts.replace != null ? opts.replace : undefined;
|
|
1629
|
+
let historyAction = exports.Action.Push;
|
|
1630
|
+
|
|
1631
|
+
if (userReplace === true) {
|
|
1632
|
+
historyAction = exports.Action.Replace;
|
|
1633
|
+
} else if (userReplace === false) ; else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) {
|
|
1634
|
+
// By default on submissions to the current location we REPLACE so that
|
|
1635
|
+
// users don't have to double-click the back button to get to the prior
|
|
1636
|
+
// location. If the user redirects to a different location from the
|
|
1637
|
+
// action/loader this will be ignored and the redirect will be a PUSH
|
|
1638
|
+
historyAction = exports.Action.Replace;
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1610
1641
|
let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined;
|
|
1611
1642
|
return await startNavigation(historyAction, location, {
|
|
1612
1643
|
submission,
|
|
@@ -1750,11 +1781,14 @@ function createRouter(init) {
|
|
|
1750
1781
|
|
|
1751
1782
|
|
|
1752
1783
|
pendingNavigationController = null;
|
|
1753
|
-
completeNavigation(location, {
|
|
1754
|
-
matches
|
|
1784
|
+
completeNavigation(location, _extends({
|
|
1785
|
+
matches
|
|
1786
|
+
}, pendingActionData ? {
|
|
1787
|
+
actionData: pendingActionData
|
|
1788
|
+
} : {}, {
|
|
1755
1789
|
loaderData,
|
|
1756
1790
|
errors
|
|
1757
|
-
});
|
|
1791
|
+
}));
|
|
1758
1792
|
} // Call the action matched by the leaf route for this navigation and handle
|
|
1759
1793
|
// redirects/errors
|
|
1760
1794
|
|
|
@@ -1794,7 +1828,18 @@ function createRouter(init) {
|
|
|
1794
1828
|
}
|
|
1795
1829
|
|
|
1796
1830
|
if (isRedirectResult(result)) {
|
|
1797
|
-
|
|
1831
|
+
let replace;
|
|
1832
|
+
|
|
1833
|
+
if (opts && opts.replace != null) {
|
|
1834
|
+
replace = opts.replace;
|
|
1835
|
+
} else {
|
|
1836
|
+
// If the user didn't explicity indicate replace behavior, replace if
|
|
1837
|
+
// we redirected to the exact same location we're currently at to avoid
|
|
1838
|
+
// double back-buttons
|
|
1839
|
+
replace = result.location === state.location.pathname + state.location.search;
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
await startRedirectNavigation(state, result, replace);
|
|
1798
1843
|
return {
|
|
1799
1844
|
shortCircuited: true
|
|
1800
1845
|
};
|
|
@@ -1813,6 +1858,8 @@ function createRouter(init) {
|
|
|
1813
1858
|
}
|
|
1814
1859
|
|
|
1815
1860
|
return {
|
|
1861
|
+
// Send back an empty object we can use to clear out any prior actionData
|
|
1862
|
+
pendingActionData: {},
|
|
1816
1863
|
pendingActionError: {
|
|
1817
1864
|
[boundaryMatch.route.id]: result.error
|
|
1818
1865
|
}
|
|
@@ -1856,13 +1903,14 @@ function createRouter(init) {
|
|
|
1856
1903
|
cancelActiveDeferreds(routeId => !(matches && matches.some(m => m.route.id === routeId)) || matchesToLoad && matchesToLoad.some(m => m.route.id === routeId)); // Short circuit if we have no loaders to run
|
|
1857
1904
|
|
|
1858
1905
|
if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {
|
|
1859
|
-
completeNavigation(location, {
|
|
1906
|
+
completeNavigation(location, _extends({
|
|
1860
1907
|
matches,
|
|
1861
|
-
loaderData:
|
|
1908
|
+
loaderData: {},
|
|
1862
1909
|
// Commit pending error if we're short circuiting
|
|
1863
|
-
errors: pendingError || null
|
|
1864
|
-
|
|
1865
|
-
|
|
1910
|
+
errors: pendingError || null
|
|
1911
|
+
}, pendingActionData ? {
|
|
1912
|
+
actionData: pendingActionData
|
|
1913
|
+
} : {}));
|
|
1866
1914
|
return {
|
|
1867
1915
|
shortCircuited: true
|
|
1868
1916
|
};
|
|
@@ -1882,14 +1930,19 @@ function createRouter(init) {
|
|
|
1882
1930
|
formMethod: undefined,
|
|
1883
1931
|
formAction: undefined,
|
|
1884
1932
|
formEncType: undefined,
|
|
1885
|
-
formData: undefined
|
|
1933
|
+
formData: undefined,
|
|
1934
|
+
" _hasFetcherDoneAnything ": true
|
|
1886
1935
|
};
|
|
1887
1936
|
state.fetchers.set(key, revalidatingFetcher);
|
|
1888
1937
|
});
|
|
1938
|
+
let actionData = pendingActionData || state.actionData;
|
|
1889
1939
|
updateState(_extends({
|
|
1890
|
-
navigation: loadingNavigation
|
|
1891
|
-
|
|
1892
|
-
|
|
1940
|
+
navigation: loadingNavigation
|
|
1941
|
+
}, actionData ? Object.keys(actionData).length === 0 ? {
|
|
1942
|
+
actionData: null
|
|
1943
|
+
} : {
|
|
1944
|
+
actionData
|
|
1945
|
+
} : {}, revalidatingFetchers.length > 0 ? {
|
|
1893
1946
|
fetchers: new Map(state.fetchers)
|
|
1894
1947
|
} : {}));
|
|
1895
1948
|
}
|
|
@@ -2013,7 +2066,8 @@ function createRouter(init) {
|
|
|
2013
2066
|
let fetcher = _extends({
|
|
2014
2067
|
state: "submitting"
|
|
2015
2068
|
}, submission, {
|
|
2016
|
-
data: existingFetcher && existingFetcher.data
|
|
2069
|
+
data: existingFetcher && existingFetcher.data,
|
|
2070
|
+
" _hasFetcherDoneAnything ": true
|
|
2017
2071
|
});
|
|
2018
2072
|
|
|
2019
2073
|
state.fetchers.set(key, fetcher);
|
|
@@ -2043,14 +2097,15 @@ function createRouter(init) {
|
|
|
2043
2097
|
let loadingFetcher = _extends({
|
|
2044
2098
|
state: "loading"
|
|
2045
2099
|
}, submission, {
|
|
2046
|
-
data: undefined
|
|
2100
|
+
data: undefined,
|
|
2101
|
+
" _hasFetcherDoneAnything ": true
|
|
2047
2102
|
});
|
|
2048
2103
|
|
|
2049
2104
|
state.fetchers.set(key, loadingFetcher);
|
|
2050
2105
|
updateState({
|
|
2051
2106
|
fetchers: new Map(state.fetchers)
|
|
2052
2107
|
});
|
|
2053
|
-
return startRedirectNavigation(state, actionResult);
|
|
2108
|
+
return startRedirectNavigation(state, actionResult, false, true);
|
|
2054
2109
|
} // Process any non-redirect errors thrown
|
|
2055
2110
|
|
|
2056
2111
|
|
|
@@ -2075,7 +2130,9 @@ function createRouter(init) {
|
|
|
2075
2130
|
let loadFetcher = _extends({
|
|
2076
2131
|
state: "loading",
|
|
2077
2132
|
data: actionResult.data
|
|
2078
|
-
}, submission
|
|
2133
|
+
}, submission, {
|
|
2134
|
+
" _hasFetcherDoneAnything ": true
|
|
2135
|
+
});
|
|
2079
2136
|
|
|
2080
2137
|
state.fetchers.set(key, loadFetcher);
|
|
2081
2138
|
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, {
|
|
@@ -2097,7 +2154,8 @@ function createRouter(init) {
|
|
|
2097
2154
|
formMethod: undefined,
|
|
2098
2155
|
formAction: undefined,
|
|
2099
2156
|
formEncType: undefined,
|
|
2100
|
-
formData: undefined
|
|
2157
|
+
formData: undefined,
|
|
2158
|
+
" _hasFetcherDoneAnything ": true
|
|
2101
2159
|
};
|
|
2102
2160
|
state.fetchers.set(staleKey, revalidatingFetcher);
|
|
2103
2161
|
fetchControllers.set(staleKey, abortController);
|
|
@@ -2138,7 +2196,8 @@ function createRouter(init) {
|
|
|
2138
2196
|
formMethod: undefined,
|
|
2139
2197
|
formAction: undefined,
|
|
2140
2198
|
formEncType: undefined,
|
|
2141
|
-
formData: undefined
|
|
2199
|
+
formData: undefined,
|
|
2200
|
+
" _hasFetcherDoneAnything ": true
|
|
2142
2201
|
};
|
|
2143
2202
|
state.fetchers.set(key, doneFetcher);
|
|
2144
2203
|
let didAbortFetchLoads = abortStaleFetchLoads(loadId); // If we are currently in a navigation loading state and this fetcher is
|
|
@@ -2160,7 +2219,7 @@ function createRouter(init) {
|
|
|
2160
2219
|
// manually merge here since we aren't going through completeNavigation
|
|
2161
2220
|
updateState(_extends({
|
|
2162
2221
|
errors,
|
|
2163
|
-
loaderData: mergeLoaderData(state.loaderData, loaderData, matches)
|
|
2222
|
+
loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors)
|
|
2164
2223
|
}, didAbortFetchLoads ? {
|
|
2165
2224
|
fetchers: new Map(state.fetchers)
|
|
2166
2225
|
} : {}));
|
|
@@ -2179,7 +2238,8 @@ function createRouter(init) {
|
|
|
2179
2238
|
formEncType: undefined,
|
|
2180
2239
|
formData: undefined
|
|
2181
2240
|
}, submission, {
|
|
2182
|
-
data: existingFetcher && existingFetcher.data
|
|
2241
|
+
data: existingFetcher && existingFetcher.data,
|
|
2242
|
+
" _hasFetcherDoneAnything ": true
|
|
2183
2243
|
});
|
|
2184
2244
|
|
|
2185
2245
|
state.fetchers.set(key, loadingFetcher);
|
|
@@ -2239,7 +2299,8 @@ function createRouter(init) {
|
|
|
2239
2299
|
formMethod: undefined,
|
|
2240
2300
|
formAction: undefined,
|
|
2241
2301
|
formEncType: undefined,
|
|
2242
|
-
formData: undefined
|
|
2302
|
+
formData: undefined,
|
|
2303
|
+
" _hasFetcherDoneAnything ": true
|
|
2243
2304
|
};
|
|
2244
2305
|
state.fetchers.set(key, doneFetcher);
|
|
2245
2306
|
updateState({
|
|
@@ -2267,14 +2328,19 @@ function createRouter(init) {
|
|
|
2267
2328
|
*/
|
|
2268
2329
|
|
|
2269
2330
|
|
|
2270
|
-
async function startRedirectNavigation(state, redirect, replace) {
|
|
2331
|
+
async function startRedirectNavigation(state, redirect, replace, isFetchActionRedirect) {
|
|
2271
2332
|
var _window;
|
|
2272
2333
|
|
|
2273
2334
|
if (redirect.revalidate) {
|
|
2274
2335
|
isRevalidationRequired = true;
|
|
2275
2336
|
}
|
|
2276
2337
|
|
|
2277
|
-
let redirectLocation = createLocation(state.location, redirect.location
|
|
2338
|
+
let redirectLocation = createLocation(state.location, redirect.location, // TODO: This can be removed once we get rid of useTransition in Remix v2
|
|
2339
|
+
_extends({
|
|
2340
|
+
_isRedirect: true
|
|
2341
|
+
}, isFetchActionRedirect ? {
|
|
2342
|
+
_isFetchActionRedirect: true
|
|
2343
|
+
} : {}));
|
|
2278
2344
|
invariant(redirectLocation, "Expected a location on the redirect navigation"); // Check if this an external redirect that goes to a new origin
|
|
2279
2345
|
|
|
2280
2346
|
if (typeof ((_window = window) == null ? void 0 : _window.location) !== "undefined") {
|
|
@@ -2400,7 +2466,8 @@ function createRouter(init) {
|
|
|
2400
2466
|
formMethod: undefined,
|
|
2401
2467
|
formAction: undefined,
|
|
2402
2468
|
formEncType: undefined,
|
|
2403
|
-
formData: undefined
|
|
2469
|
+
formData: undefined,
|
|
2470
|
+
" _hasFetcherDoneAnything ": true
|
|
2404
2471
|
};
|
|
2405
2472
|
state.fetchers.set(key, doneFetcher);
|
|
2406
2473
|
}
|
|
@@ -2543,8 +2610,8 @@ function createRouter(init) {
|
|
|
2543
2610
|
//#region createStaticHandler
|
|
2544
2611
|
////////////////////////////////////////////////////////////////////////////////
|
|
2545
2612
|
|
|
2546
|
-
function
|
|
2547
|
-
invariant(routes.length > 0, "You must provide a non-empty routes array to
|
|
2613
|
+
function createStaticHandler(routes, opts) {
|
|
2614
|
+
invariant(routes.length > 0, "You must provide a non-empty routes array to createStaticHandler");
|
|
2548
2615
|
let dataRoutes = convertRoutesToDataRoutes(routes);
|
|
2549
2616
|
let basename = (opts ? opts.basename : null) || "/";
|
|
2550
2617
|
/**
|
|
@@ -2866,7 +2933,10 @@ function unstable_createStaticHandler(routes, opts) {
|
|
|
2866
2933
|
if (matchesToLoad.length === 0) {
|
|
2867
2934
|
return {
|
|
2868
2935
|
matches,
|
|
2869
|
-
|
|
2936
|
+
// Add a null for all matched routes for proper revalidation on the client
|
|
2937
|
+
loaderData: matches.reduce((acc, m) => Object.assign(acc, {
|
|
2938
|
+
[m.route.id]: null
|
|
2939
|
+
}), {}),
|
|
2870
2940
|
errors: pendingActionError || null,
|
|
2871
2941
|
statusCode: 200,
|
|
2872
2942
|
loaderHeaders: {}
|
|
@@ -2878,17 +2948,25 @@ function unstable_createStaticHandler(routes, opts) {
|
|
|
2878
2948
|
if (request.signal.aborted) {
|
|
2879
2949
|
let method = isRouteRequest ? "queryRoute" : "query";
|
|
2880
2950
|
throw new Error(method + "() call aborted");
|
|
2881
|
-
}
|
|
2882
|
-
// cancel them for now
|
|
2951
|
+
}
|
|
2883
2952
|
|
|
2953
|
+
let executedLoaders = new Set();
|
|
2954
|
+
results.forEach((result, i) => {
|
|
2955
|
+
executedLoaders.add(matchesToLoad[i].route.id); // Can't do anything with these without the Remix side of things, so just
|
|
2956
|
+
// cancel them for now
|
|
2884
2957
|
|
|
2885
|
-
results.forEach(result => {
|
|
2886
2958
|
if (isDeferredResult(result)) {
|
|
2887
2959
|
result.deferredData.cancel();
|
|
2888
2960
|
}
|
|
2889
2961
|
}); // Process and commit output from loaders
|
|
2890
2962
|
|
|
2891
|
-
let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionError);
|
|
2963
|
+
let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionError); // Add a null for any non-loader matches for proper revalidation on the client
|
|
2964
|
+
|
|
2965
|
+
matches.forEach(match => {
|
|
2966
|
+
if (!executedLoaders.has(match.route.id)) {
|
|
2967
|
+
context.loaderData[match.route.id] = null;
|
|
2968
|
+
}
|
|
2969
|
+
});
|
|
2892
2970
|
return _extends({}, context, {
|
|
2893
2971
|
matches
|
|
2894
2972
|
});
|
|
@@ -3010,7 +3088,7 @@ function getLoaderMatchesUntilBoundary(matches, boundaryId) {
|
|
|
3010
3088
|
}
|
|
3011
3089
|
|
|
3012
3090
|
function getMatchesToLoad(state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches) {
|
|
3013
|
-
let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] :
|
|
3091
|
+
let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined; // Pick navigation matches that are net-new or qualify for revalidation
|
|
3014
3092
|
|
|
3015
3093
|
let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;
|
|
3016
3094
|
let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);
|
|
@@ -3180,9 +3258,10 @@ async function callLoaderOrAction(type, request, match, matches, basename, isSta
|
|
|
3180
3258
|
}
|
|
3181
3259
|
|
|
3182
3260
|
let data;
|
|
3183
|
-
let contentType = result.headers.get("Content-Type");
|
|
3261
|
+
let contentType = result.headers.get("Content-Type"); // Check between word boundaries instead of startsWith() due to the last
|
|
3262
|
+
// paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type
|
|
3184
3263
|
|
|
3185
|
-
if (contentType && contentType
|
|
3264
|
+
if (contentType && /\bapplication\/json\b/.test(contentType)) {
|
|
3186
3265
|
data = await result.json();
|
|
3187
3266
|
} else {
|
|
3188
3267
|
data = await result.text();
|
|
@@ -3287,9 +3366,11 @@ function processRouteLoaderData(matches, matchesToLoad, results, pendingError, a
|
|
|
3287
3366
|
|
|
3288
3367
|
if (errors[boundaryMatch.route.id] == null) {
|
|
3289
3368
|
errors[boundaryMatch.route.id] = error;
|
|
3290
|
-
} //
|
|
3291
|
-
|
|
3369
|
+
} // Clear our any prior loaderData for the throwing route
|
|
3370
|
+
|
|
3292
3371
|
|
|
3372
|
+
loaderData[id] = undefined; // Once we find our first (highest) error, we set the status code and
|
|
3373
|
+
// prevent deeper status codes from overriding
|
|
3293
3374
|
|
|
3294
3375
|
if (!foundError) {
|
|
3295
3376
|
foundError = true;
|
|
@@ -3315,10 +3396,12 @@ function processRouteLoaderData(matches, matchesToLoad, results, pendingError, a
|
|
|
3315
3396
|
}
|
|
3316
3397
|
}
|
|
3317
3398
|
}); // If we didn't consume the pending action error (i.e., all loaders
|
|
3318
|
-
// resolved), then consume it here
|
|
3399
|
+
// resolved), then consume it here. Also clear out any loaderData for the
|
|
3400
|
+
// throwing route
|
|
3319
3401
|
|
|
3320
3402
|
if (pendingError) {
|
|
3321
3403
|
errors = pendingError;
|
|
3404
|
+
loaderData[Object.keys(pendingError)[0]] = undefined;
|
|
3322
3405
|
}
|
|
3323
3406
|
|
|
3324
3407
|
return {
|
|
@@ -3365,7 +3448,8 @@ function processLoaderData(state, matches, matchesToLoad, results, pendingError,
|
|
|
3365
3448
|
formMethod: undefined,
|
|
3366
3449
|
formAction: undefined,
|
|
3367
3450
|
formEncType: undefined,
|
|
3368
|
-
formData: undefined
|
|
3451
|
+
formData: undefined,
|
|
3452
|
+
" _hasFetcherDoneAnything ": true
|
|
3369
3453
|
};
|
|
3370
3454
|
state.fetchers.set(key, doneFetcher);
|
|
3371
3455
|
}
|
|
@@ -3377,16 +3461,26 @@ function processLoaderData(state, matches, matchesToLoad, results, pendingError,
|
|
|
3377
3461
|
};
|
|
3378
3462
|
}
|
|
3379
3463
|
|
|
3380
|
-
function mergeLoaderData(loaderData, newLoaderData, matches) {
|
|
3464
|
+
function mergeLoaderData(loaderData, newLoaderData, matches, errors) {
|
|
3381
3465
|
let mergedLoaderData = _extends({}, newLoaderData);
|
|
3382
3466
|
|
|
3383
|
-
|
|
3467
|
+
for (let match of matches) {
|
|
3384
3468
|
let id = match.route.id;
|
|
3385
3469
|
|
|
3386
|
-
if (newLoaderData
|
|
3470
|
+
if (newLoaderData.hasOwnProperty(id)) {
|
|
3471
|
+
if (newLoaderData[id] !== undefined) {
|
|
3472
|
+
mergedLoaderData[id] = newLoaderData[id];
|
|
3473
|
+
}
|
|
3474
|
+
} else if (loaderData[id] !== undefined) {
|
|
3387
3475
|
mergedLoaderData[id] = loaderData[id];
|
|
3388
3476
|
}
|
|
3389
|
-
|
|
3477
|
+
|
|
3478
|
+
if (errors && errors.hasOwnProperty(id)) {
|
|
3479
|
+
// Don't keep any loader data below the boundary
|
|
3480
|
+
break;
|
|
3481
|
+
}
|
|
3482
|
+
}
|
|
3483
|
+
|
|
3390
3484
|
return mergedLoaderData;
|
|
3391
3485
|
} // Find the nearest error boundary, looking upwards from the leaf route (or the
|
|
3392
3486
|
// route specified by routeId) for the closest ancestor error boundary,
|
|
@@ -3608,6 +3702,7 @@ exports.createHashHistory = createHashHistory;
|
|
|
3608
3702
|
exports.createMemoryHistory = createMemoryHistory;
|
|
3609
3703
|
exports.createPath = createPath;
|
|
3610
3704
|
exports.createRouter = createRouter;
|
|
3705
|
+
exports.createStaticHandler = createStaticHandler;
|
|
3611
3706
|
exports.defer = defer;
|
|
3612
3707
|
exports.generatePath = generatePath;
|
|
3613
3708
|
exports.getStaticContextFromError = getStaticContextFromError;
|
|
@@ -3624,6 +3719,5 @@ exports.redirect = redirect;
|
|
|
3624
3719
|
exports.resolvePath = resolvePath;
|
|
3625
3720
|
exports.resolveTo = resolveTo;
|
|
3626
3721
|
exports.stripBasename = stripBasename;
|
|
3627
|
-
exports.unstable_createStaticHandler = unstable_createStaticHandler;
|
|
3628
3722
|
exports.warning = warning;
|
|
3629
3723
|
//# sourceMappingURL=router.cjs.js.map
|