@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/dist/router.umd.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
|
*
|
|
@@ -1417,8 +1417,10 @@
|
|
|
1417
1417
|
// we don't get the saved positions from <ScrollRestoration /> until _after_
|
|
1418
1418
|
// the initial render, we need to manually trigger a separate updateState to
|
|
1419
1419
|
// send along the restoreScrollPosition
|
|
1420
|
+
// Set to true if we have `hydrationData` since we assume we were SSR'd and that
|
|
1421
|
+
// SSR did the initial scroll restoration.
|
|
1420
1422
|
|
|
1421
|
-
let initialScrollRestored =
|
|
1423
|
+
let initialScrollRestored = init.hydrationData != null;
|
|
1422
1424
|
let initialMatches = matchRoutes(dataRoutes, init.history.location, init.basename);
|
|
1423
1425
|
let initialErrors = null;
|
|
1424
1426
|
|
|
@@ -1446,7 +1448,8 @@
|
|
|
1446
1448
|
matches: initialMatches,
|
|
1447
1449
|
initialized,
|
|
1448
1450
|
navigation: IDLE_NAVIGATION,
|
|
1449
|
-
|
|
1451
|
+
// Don't restore on initial updateState() if we were SSR'd
|
|
1452
|
+
restoreScrollPosition: init.hydrationData != null ? false : null,
|
|
1450
1453
|
preventScrollReset: false,
|
|
1451
1454
|
revalidation: "idle",
|
|
1452
1455
|
loaderData: init.hydrationData && init.hydrationData.loaderData || {},
|
|
@@ -1555,14 +1558,30 @@
|
|
|
1555
1558
|
// location, indicating we redirected from the action (avoids false
|
|
1556
1559
|
// positives for loading/submissionRedirect when actionData returned
|
|
1557
1560
|
// on a prior submission)
|
|
1558
|
-
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;
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1561
|
+
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;
|
|
1562
|
+
let actionData;
|
|
1563
|
+
|
|
1564
|
+
if (newState.actionData) {
|
|
1565
|
+
if (Object.keys(newState.actionData).length > 0) {
|
|
1566
|
+
actionData = newState.actionData;
|
|
1567
|
+
} else {
|
|
1568
|
+
// Empty actionData -> clear prior actionData due to an action error
|
|
1569
|
+
actionData = null;
|
|
1570
|
+
}
|
|
1571
|
+
} else if (isActionReload) {
|
|
1572
|
+
// Keep the current data if we're wrapping up the action reload
|
|
1573
|
+
actionData = state.actionData;
|
|
1574
|
+
} else {
|
|
1575
|
+
// Clear actionData on any other completed navigations
|
|
1576
|
+
actionData = null;
|
|
1577
|
+
} // Always preserve any existing loaderData from re-used routes
|
|
1578
|
+
|
|
1579
|
+
|
|
1580
|
+
let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData;
|
|
1581
|
+
updateState(_extends({}, newState, {
|
|
1582
|
+
// matches, errors, fetchers go through as-is
|
|
1583
|
+
actionData,
|
|
1584
|
+
loaderData,
|
|
1566
1585
|
historyAction: pendingAction,
|
|
1567
1586
|
location,
|
|
1568
1587
|
initialized: true,
|
|
@@ -1608,7 +1627,19 @@
|
|
|
1608
1627
|
// without having to touch history
|
|
1609
1628
|
|
|
1610
1629
|
location = _extends({}, location, init.history.encodeLocation(location));
|
|
1611
|
-
let
|
|
1630
|
+
let userReplace = opts && opts.replace != null ? opts.replace : undefined;
|
|
1631
|
+
let historyAction = exports.Action.Push;
|
|
1632
|
+
|
|
1633
|
+
if (userReplace === true) {
|
|
1634
|
+
historyAction = exports.Action.Replace;
|
|
1635
|
+
} else if (userReplace === false) ; else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) {
|
|
1636
|
+
// By default on submissions to the current location we REPLACE so that
|
|
1637
|
+
// users don't have to double-click the back button to get to the prior
|
|
1638
|
+
// location. If the user redirects to a different location from the
|
|
1639
|
+
// action/loader this will be ignored and the redirect will be a PUSH
|
|
1640
|
+
historyAction = exports.Action.Replace;
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1612
1643
|
let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined;
|
|
1613
1644
|
return await startNavigation(historyAction, location, {
|
|
1614
1645
|
submission,
|
|
@@ -1752,11 +1783,14 @@
|
|
|
1752
1783
|
|
|
1753
1784
|
|
|
1754
1785
|
pendingNavigationController = null;
|
|
1755
|
-
completeNavigation(location, {
|
|
1756
|
-
matches
|
|
1786
|
+
completeNavigation(location, _extends({
|
|
1787
|
+
matches
|
|
1788
|
+
}, pendingActionData ? {
|
|
1789
|
+
actionData: pendingActionData
|
|
1790
|
+
} : {}, {
|
|
1757
1791
|
loaderData,
|
|
1758
1792
|
errors
|
|
1759
|
-
});
|
|
1793
|
+
}));
|
|
1760
1794
|
} // Call the action matched by the leaf route for this navigation and handle
|
|
1761
1795
|
// redirects/errors
|
|
1762
1796
|
|
|
@@ -1796,7 +1830,18 @@
|
|
|
1796
1830
|
}
|
|
1797
1831
|
|
|
1798
1832
|
if (isRedirectResult(result)) {
|
|
1799
|
-
|
|
1833
|
+
let replace;
|
|
1834
|
+
|
|
1835
|
+
if (opts && opts.replace != null) {
|
|
1836
|
+
replace = opts.replace;
|
|
1837
|
+
} else {
|
|
1838
|
+
// If the user didn't explicity indicate replace behavior, replace if
|
|
1839
|
+
// we redirected to the exact same location we're currently at to avoid
|
|
1840
|
+
// double back-buttons
|
|
1841
|
+
replace = result.location === state.location.pathname + state.location.search;
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
await startRedirectNavigation(state, result, replace);
|
|
1800
1845
|
return {
|
|
1801
1846
|
shortCircuited: true
|
|
1802
1847
|
};
|
|
@@ -1815,6 +1860,8 @@
|
|
|
1815
1860
|
}
|
|
1816
1861
|
|
|
1817
1862
|
return {
|
|
1863
|
+
// Send back an empty object we can use to clear out any prior actionData
|
|
1864
|
+
pendingActionData: {},
|
|
1818
1865
|
pendingActionError: {
|
|
1819
1866
|
[boundaryMatch.route.id]: result.error
|
|
1820
1867
|
}
|
|
@@ -1858,13 +1905,14 @@
|
|
|
1858
1905
|
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
|
|
1859
1906
|
|
|
1860
1907
|
if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {
|
|
1861
|
-
completeNavigation(location, {
|
|
1908
|
+
completeNavigation(location, _extends({
|
|
1862
1909
|
matches,
|
|
1863
|
-
loaderData:
|
|
1910
|
+
loaderData: {},
|
|
1864
1911
|
// Commit pending error if we're short circuiting
|
|
1865
|
-
errors: pendingError || null
|
|
1866
|
-
|
|
1867
|
-
|
|
1912
|
+
errors: pendingError || null
|
|
1913
|
+
}, pendingActionData ? {
|
|
1914
|
+
actionData: pendingActionData
|
|
1915
|
+
} : {}));
|
|
1868
1916
|
return {
|
|
1869
1917
|
shortCircuited: true
|
|
1870
1918
|
};
|
|
@@ -1884,14 +1932,19 @@
|
|
|
1884
1932
|
formMethod: undefined,
|
|
1885
1933
|
formAction: undefined,
|
|
1886
1934
|
formEncType: undefined,
|
|
1887
|
-
formData: undefined
|
|
1935
|
+
formData: undefined,
|
|
1936
|
+
" _hasFetcherDoneAnything ": true
|
|
1888
1937
|
};
|
|
1889
1938
|
state.fetchers.set(key, revalidatingFetcher);
|
|
1890
1939
|
});
|
|
1940
|
+
let actionData = pendingActionData || state.actionData;
|
|
1891
1941
|
updateState(_extends({
|
|
1892
|
-
navigation: loadingNavigation
|
|
1893
|
-
|
|
1894
|
-
|
|
1942
|
+
navigation: loadingNavigation
|
|
1943
|
+
}, actionData ? Object.keys(actionData).length === 0 ? {
|
|
1944
|
+
actionData: null
|
|
1945
|
+
} : {
|
|
1946
|
+
actionData
|
|
1947
|
+
} : {}, revalidatingFetchers.length > 0 ? {
|
|
1895
1948
|
fetchers: new Map(state.fetchers)
|
|
1896
1949
|
} : {}));
|
|
1897
1950
|
}
|
|
@@ -2015,7 +2068,8 @@
|
|
|
2015
2068
|
let fetcher = _extends({
|
|
2016
2069
|
state: "submitting"
|
|
2017
2070
|
}, submission, {
|
|
2018
|
-
data: existingFetcher && existingFetcher.data
|
|
2071
|
+
data: existingFetcher && existingFetcher.data,
|
|
2072
|
+
" _hasFetcherDoneAnything ": true
|
|
2019
2073
|
});
|
|
2020
2074
|
|
|
2021
2075
|
state.fetchers.set(key, fetcher);
|
|
@@ -2045,14 +2099,15 @@
|
|
|
2045
2099
|
let loadingFetcher = _extends({
|
|
2046
2100
|
state: "loading"
|
|
2047
2101
|
}, submission, {
|
|
2048
|
-
data: undefined
|
|
2102
|
+
data: undefined,
|
|
2103
|
+
" _hasFetcherDoneAnything ": true
|
|
2049
2104
|
});
|
|
2050
2105
|
|
|
2051
2106
|
state.fetchers.set(key, loadingFetcher);
|
|
2052
2107
|
updateState({
|
|
2053
2108
|
fetchers: new Map(state.fetchers)
|
|
2054
2109
|
});
|
|
2055
|
-
return startRedirectNavigation(state, actionResult);
|
|
2110
|
+
return startRedirectNavigation(state, actionResult, false, true);
|
|
2056
2111
|
} // Process any non-redirect errors thrown
|
|
2057
2112
|
|
|
2058
2113
|
|
|
@@ -2077,7 +2132,9 @@
|
|
|
2077
2132
|
let loadFetcher = _extends({
|
|
2078
2133
|
state: "loading",
|
|
2079
2134
|
data: actionResult.data
|
|
2080
|
-
}, submission
|
|
2135
|
+
}, submission, {
|
|
2136
|
+
" _hasFetcherDoneAnything ": true
|
|
2137
|
+
});
|
|
2081
2138
|
|
|
2082
2139
|
state.fetchers.set(key, loadFetcher);
|
|
2083
2140
|
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, {
|
|
@@ -2099,7 +2156,8 @@
|
|
|
2099
2156
|
formMethod: undefined,
|
|
2100
2157
|
formAction: undefined,
|
|
2101
2158
|
formEncType: undefined,
|
|
2102
|
-
formData: undefined
|
|
2159
|
+
formData: undefined,
|
|
2160
|
+
" _hasFetcherDoneAnything ": true
|
|
2103
2161
|
};
|
|
2104
2162
|
state.fetchers.set(staleKey, revalidatingFetcher);
|
|
2105
2163
|
fetchControllers.set(staleKey, abortController);
|
|
@@ -2140,7 +2198,8 @@
|
|
|
2140
2198
|
formMethod: undefined,
|
|
2141
2199
|
formAction: undefined,
|
|
2142
2200
|
formEncType: undefined,
|
|
2143
|
-
formData: undefined
|
|
2201
|
+
formData: undefined,
|
|
2202
|
+
" _hasFetcherDoneAnything ": true
|
|
2144
2203
|
};
|
|
2145
2204
|
state.fetchers.set(key, doneFetcher);
|
|
2146
2205
|
let didAbortFetchLoads = abortStaleFetchLoads(loadId); // If we are currently in a navigation loading state and this fetcher is
|
|
@@ -2162,7 +2221,7 @@
|
|
|
2162
2221
|
// manually merge here since we aren't going through completeNavigation
|
|
2163
2222
|
updateState(_extends({
|
|
2164
2223
|
errors,
|
|
2165
|
-
loaderData: mergeLoaderData(state.loaderData, loaderData, matches)
|
|
2224
|
+
loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors)
|
|
2166
2225
|
}, didAbortFetchLoads ? {
|
|
2167
2226
|
fetchers: new Map(state.fetchers)
|
|
2168
2227
|
} : {}));
|
|
@@ -2181,7 +2240,8 @@
|
|
|
2181
2240
|
formEncType: undefined,
|
|
2182
2241
|
formData: undefined
|
|
2183
2242
|
}, submission, {
|
|
2184
|
-
data: existingFetcher && existingFetcher.data
|
|
2243
|
+
data: existingFetcher && existingFetcher.data,
|
|
2244
|
+
" _hasFetcherDoneAnything ": true
|
|
2185
2245
|
});
|
|
2186
2246
|
|
|
2187
2247
|
state.fetchers.set(key, loadingFetcher);
|
|
@@ -2241,7 +2301,8 @@
|
|
|
2241
2301
|
formMethod: undefined,
|
|
2242
2302
|
formAction: undefined,
|
|
2243
2303
|
formEncType: undefined,
|
|
2244
|
-
formData: undefined
|
|
2304
|
+
formData: undefined,
|
|
2305
|
+
" _hasFetcherDoneAnything ": true
|
|
2245
2306
|
};
|
|
2246
2307
|
state.fetchers.set(key, doneFetcher);
|
|
2247
2308
|
updateState({
|
|
@@ -2269,14 +2330,19 @@
|
|
|
2269
2330
|
*/
|
|
2270
2331
|
|
|
2271
2332
|
|
|
2272
|
-
async function startRedirectNavigation(state, redirect, replace) {
|
|
2333
|
+
async function startRedirectNavigation(state, redirect, replace, isFetchActionRedirect) {
|
|
2273
2334
|
var _window;
|
|
2274
2335
|
|
|
2275
2336
|
if (redirect.revalidate) {
|
|
2276
2337
|
isRevalidationRequired = true;
|
|
2277
2338
|
}
|
|
2278
2339
|
|
|
2279
|
-
let redirectLocation = createLocation(state.location, redirect.location
|
|
2340
|
+
let redirectLocation = createLocation(state.location, redirect.location, // TODO: This can be removed once we get rid of useTransition in Remix v2
|
|
2341
|
+
_extends({
|
|
2342
|
+
_isRedirect: true
|
|
2343
|
+
}, isFetchActionRedirect ? {
|
|
2344
|
+
_isFetchActionRedirect: true
|
|
2345
|
+
} : {}));
|
|
2280
2346
|
invariant(redirectLocation, "Expected a location on the redirect navigation"); // Check if this an external redirect that goes to a new origin
|
|
2281
2347
|
|
|
2282
2348
|
if (typeof ((_window = window) == null ? void 0 : _window.location) !== "undefined") {
|
|
@@ -2402,7 +2468,8 @@
|
|
|
2402
2468
|
formMethod: undefined,
|
|
2403
2469
|
formAction: undefined,
|
|
2404
2470
|
formEncType: undefined,
|
|
2405
|
-
formData: undefined
|
|
2471
|
+
formData: undefined,
|
|
2472
|
+
" _hasFetcherDoneAnything ": true
|
|
2406
2473
|
};
|
|
2407
2474
|
state.fetchers.set(key, doneFetcher);
|
|
2408
2475
|
}
|
|
@@ -2545,8 +2612,8 @@
|
|
|
2545
2612
|
//#region createStaticHandler
|
|
2546
2613
|
////////////////////////////////////////////////////////////////////////////////
|
|
2547
2614
|
|
|
2548
|
-
function
|
|
2549
|
-
invariant(routes.length > 0, "You must provide a non-empty routes array to
|
|
2615
|
+
function createStaticHandler(routes, opts) {
|
|
2616
|
+
invariant(routes.length > 0, "You must provide a non-empty routes array to createStaticHandler");
|
|
2550
2617
|
let dataRoutes = convertRoutesToDataRoutes(routes);
|
|
2551
2618
|
let basename = (opts ? opts.basename : null) || "/";
|
|
2552
2619
|
/**
|
|
@@ -2868,7 +2935,10 @@
|
|
|
2868
2935
|
if (matchesToLoad.length === 0) {
|
|
2869
2936
|
return {
|
|
2870
2937
|
matches,
|
|
2871
|
-
|
|
2938
|
+
// Add a null for all matched routes for proper revalidation on the client
|
|
2939
|
+
loaderData: matches.reduce((acc, m) => Object.assign(acc, {
|
|
2940
|
+
[m.route.id]: null
|
|
2941
|
+
}), {}),
|
|
2872
2942
|
errors: pendingActionError || null,
|
|
2873
2943
|
statusCode: 200,
|
|
2874
2944
|
loaderHeaders: {}
|
|
@@ -2880,17 +2950,25 @@
|
|
|
2880
2950
|
if (request.signal.aborted) {
|
|
2881
2951
|
let method = isRouteRequest ? "queryRoute" : "query";
|
|
2882
2952
|
throw new Error(method + "() call aborted");
|
|
2883
|
-
}
|
|
2884
|
-
// cancel them for now
|
|
2953
|
+
}
|
|
2885
2954
|
|
|
2955
|
+
let executedLoaders = new Set();
|
|
2956
|
+
results.forEach((result, i) => {
|
|
2957
|
+
executedLoaders.add(matchesToLoad[i].route.id); // Can't do anything with these without the Remix side of things, so just
|
|
2958
|
+
// cancel them for now
|
|
2886
2959
|
|
|
2887
|
-
results.forEach(result => {
|
|
2888
2960
|
if (isDeferredResult(result)) {
|
|
2889
2961
|
result.deferredData.cancel();
|
|
2890
2962
|
}
|
|
2891
2963
|
}); // Process and commit output from loaders
|
|
2892
2964
|
|
|
2893
|
-
let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionError);
|
|
2965
|
+
let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionError); // Add a null for any non-loader matches for proper revalidation on the client
|
|
2966
|
+
|
|
2967
|
+
matches.forEach(match => {
|
|
2968
|
+
if (!executedLoaders.has(match.route.id)) {
|
|
2969
|
+
context.loaderData[match.route.id] = null;
|
|
2970
|
+
}
|
|
2971
|
+
});
|
|
2894
2972
|
return _extends({}, context, {
|
|
2895
2973
|
matches
|
|
2896
2974
|
});
|
|
@@ -3012,7 +3090,7 @@
|
|
|
3012
3090
|
}
|
|
3013
3091
|
|
|
3014
3092
|
function getMatchesToLoad(state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches) {
|
|
3015
|
-
let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] :
|
|
3093
|
+
let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined; // Pick navigation matches that are net-new or qualify for revalidation
|
|
3016
3094
|
|
|
3017
3095
|
let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;
|
|
3018
3096
|
let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);
|
|
@@ -3182,9 +3260,10 @@
|
|
|
3182
3260
|
}
|
|
3183
3261
|
|
|
3184
3262
|
let data;
|
|
3185
|
-
let contentType = result.headers.get("Content-Type");
|
|
3263
|
+
let contentType = result.headers.get("Content-Type"); // Check between word boundaries instead of startsWith() due to the last
|
|
3264
|
+
// paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type
|
|
3186
3265
|
|
|
3187
|
-
if (contentType && contentType
|
|
3266
|
+
if (contentType && /\bapplication\/json\b/.test(contentType)) {
|
|
3188
3267
|
data = await result.json();
|
|
3189
3268
|
} else {
|
|
3190
3269
|
data = await result.text();
|
|
@@ -3289,9 +3368,11 @@
|
|
|
3289
3368
|
|
|
3290
3369
|
if (errors[boundaryMatch.route.id] == null) {
|
|
3291
3370
|
errors[boundaryMatch.route.id] = error;
|
|
3292
|
-
} //
|
|
3293
|
-
|
|
3371
|
+
} // Clear our any prior loaderData for the throwing route
|
|
3372
|
+
|
|
3294
3373
|
|
|
3374
|
+
loaderData[id] = undefined; // Once we find our first (highest) error, we set the status code and
|
|
3375
|
+
// prevent deeper status codes from overriding
|
|
3295
3376
|
|
|
3296
3377
|
if (!foundError) {
|
|
3297
3378
|
foundError = true;
|
|
@@ -3317,10 +3398,12 @@
|
|
|
3317
3398
|
}
|
|
3318
3399
|
}
|
|
3319
3400
|
}); // If we didn't consume the pending action error (i.e., all loaders
|
|
3320
|
-
// resolved), then consume it here
|
|
3401
|
+
// resolved), then consume it here. Also clear out any loaderData for the
|
|
3402
|
+
// throwing route
|
|
3321
3403
|
|
|
3322
3404
|
if (pendingError) {
|
|
3323
3405
|
errors = pendingError;
|
|
3406
|
+
loaderData[Object.keys(pendingError)[0]] = undefined;
|
|
3324
3407
|
}
|
|
3325
3408
|
|
|
3326
3409
|
return {
|
|
@@ -3367,7 +3450,8 @@
|
|
|
3367
3450
|
formMethod: undefined,
|
|
3368
3451
|
formAction: undefined,
|
|
3369
3452
|
formEncType: undefined,
|
|
3370
|
-
formData: undefined
|
|
3453
|
+
formData: undefined,
|
|
3454
|
+
" _hasFetcherDoneAnything ": true
|
|
3371
3455
|
};
|
|
3372
3456
|
state.fetchers.set(key, doneFetcher);
|
|
3373
3457
|
}
|
|
@@ -3379,16 +3463,26 @@
|
|
|
3379
3463
|
};
|
|
3380
3464
|
}
|
|
3381
3465
|
|
|
3382
|
-
function mergeLoaderData(loaderData, newLoaderData, matches) {
|
|
3466
|
+
function mergeLoaderData(loaderData, newLoaderData, matches, errors) {
|
|
3383
3467
|
let mergedLoaderData = _extends({}, newLoaderData);
|
|
3384
3468
|
|
|
3385
|
-
|
|
3469
|
+
for (let match of matches) {
|
|
3386
3470
|
let id = match.route.id;
|
|
3387
3471
|
|
|
3388
|
-
if (newLoaderData
|
|
3472
|
+
if (newLoaderData.hasOwnProperty(id)) {
|
|
3473
|
+
if (newLoaderData[id] !== undefined) {
|
|
3474
|
+
mergedLoaderData[id] = newLoaderData[id];
|
|
3475
|
+
}
|
|
3476
|
+
} else if (loaderData[id] !== undefined) {
|
|
3389
3477
|
mergedLoaderData[id] = loaderData[id];
|
|
3390
3478
|
}
|
|
3391
|
-
|
|
3479
|
+
|
|
3480
|
+
if (errors && errors.hasOwnProperty(id)) {
|
|
3481
|
+
// Don't keep any loader data below the boundary
|
|
3482
|
+
break;
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3485
|
+
|
|
3392
3486
|
return mergedLoaderData;
|
|
3393
3487
|
} // Find the nearest error boundary, looking upwards from the leaf route (or the
|
|
3394
3488
|
// route specified by routeId) for the closest ancestor error boundary,
|
|
@@ -3610,6 +3704,7 @@
|
|
|
3610
3704
|
exports.createMemoryHistory = createMemoryHistory;
|
|
3611
3705
|
exports.createPath = createPath;
|
|
3612
3706
|
exports.createRouter = createRouter;
|
|
3707
|
+
exports.createStaticHandler = createStaticHandler;
|
|
3613
3708
|
exports.defer = defer;
|
|
3614
3709
|
exports.generatePath = generatePath;
|
|
3615
3710
|
exports.getStaticContextFromError = getStaticContextFromError;
|
|
@@ -3626,7 +3721,6 @@
|
|
|
3626
3721
|
exports.resolvePath = resolvePath;
|
|
3627
3722
|
exports.resolveTo = resolveTo;
|
|
3628
3723
|
exports.stripBasename = stripBasename;
|
|
3629
|
-
exports.unstable_createStaticHandler = unstable_createStaticHandler;
|
|
3630
3724
|
exports.warning = warning;
|
|
3631
3725
|
|
|
3632
3726
|
Object.defineProperty(exports, '__esModule', { value: true });
|