@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.d.ts
CHANGED
|
@@ -338,6 +338,7 @@ declare type FetcherStates<TData = any> = {
|
|
|
338
338
|
formEncType: undefined;
|
|
339
339
|
formData: undefined;
|
|
340
340
|
data: TData | undefined;
|
|
341
|
+
" _hasFetcherDoneAnything "?: boolean;
|
|
341
342
|
};
|
|
342
343
|
Loading: {
|
|
343
344
|
state: "loading";
|
|
@@ -346,6 +347,7 @@ declare type FetcherStates<TData = any> = {
|
|
|
346
347
|
formEncType: FormEncType | undefined;
|
|
347
348
|
formData: FormData | undefined;
|
|
348
349
|
data: TData | undefined;
|
|
350
|
+
" _hasFetcherDoneAnything "?: boolean;
|
|
349
351
|
};
|
|
350
352
|
Submitting: {
|
|
351
353
|
state: "submitting";
|
|
@@ -354,6 +356,7 @@ declare type FetcherStates<TData = any> = {
|
|
|
354
356
|
formEncType: FormEncType;
|
|
355
357
|
formData: FormData;
|
|
356
358
|
data: TData | undefined;
|
|
359
|
+
" _hasFetcherDoneAnything "?: boolean;
|
|
357
360
|
};
|
|
358
361
|
};
|
|
359
362
|
export declare type Fetcher<TData = any> = FetcherStates<TData>[keyof FetcherStates<TData>];
|
|
@@ -363,7 +366,7 @@ export declare const IDLE_FETCHER: FetcherStates["Idle"];
|
|
|
363
366
|
* Create a router and listen to history POP navigations
|
|
364
367
|
*/
|
|
365
368
|
export declare function createRouter(init: RouterInit): Router;
|
|
366
|
-
export declare function
|
|
369
|
+
export declare function createStaticHandler(routes: AgnosticRouteObject[], opts?: {
|
|
367
370
|
basename?: string;
|
|
368
371
|
}): StaticHandler;
|
|
369
372
|
/**
|
package/dist/router.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
|
*
|
|
@@ -1367,8 +1367,10 @@ function createRouter(init) {
|
|
|
1367
1367
|
// we don't get the saved positions from <ScrollRestoration /> until _after_
|
|
1368
1368
|
// the initial render, we need to manually trigger a separate updateState to
|
|
1369
1369
|
// send along the restoreScrollPosition
|
|
1370
|
+
// Set to true if we have `hydrationData` since we assume we were SSR'd and that
|
|
1371
|
+
// SSR did the initial scroll restoration.
|
|
1370
1372
|
|
|
1371
|
-
let initialScrollRestored =
|
|
1373
|
+
let initialScrollRestored = init.hydrationData != null;
|
|
1372
1374
|
let initialMatches = matchRoutes(dataRoutes, init.history.location, init.basename);
|
|
1373
1375
|
let initialErrors = null;
|
|
1374
1376
|
|
|
@@ -1396,7 +1398,8 @@ function createRouter(init) {
|
|
|
1396
1398
|
matches: initialMatches,
|
|
1397
1399
|
initialized,
|
|
1398
1400
|
navigation: IDLE_NAVIGATION,
|
|
1399
|
-
|
|
1401
|
+
// Don't restore on initial updateState() if we were SSR'd
|
|
1402
|
+
restoreScrollPosition: init.hydrationData != null ? false : null,
|
|
1400
1403
|
preventScrollReset: false,
|
|
1401
1404
|
revalidation: "idle",
|
|
1402
1405
|
loaderData: init.hydrationData && init.hydrationData.loaderData || {},
|
|
@@ -1505,14 +1508,29 @@ function createRouter(init) {
|
|
|
1505
1508
|
// location, indicating we redirected from the action (avoids false
|
|
1506
1509
|
// positives for loading/submissionRedirect when actionData returned
|
|
1507
1510
|
// on a prior submission)
|
|
1508
|
-
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;
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1511
|
+
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;
|
|
1512
|
+
let actionData;
|
|
1513
|
+
|
|
1514
|
+
if (newState.actionData) {
|
|
1515
|
+
if (Object.keys(newState.actionData).length > 0) {
|
|
1516
|
+
actionData = newState.actionData;
|
|
1517
|
+
} else {
|
|
1518
|
+
// Empty actionData -> clear prior actionData due to an action error
|
|
1519
|
+
actionData = null;
|
|
1520
|
+
}
|
|
1521
|
+
} else if (isActionReload) {
|
|
1522
|
+
// Keep the current data if we're wrapping up the action reload
|
|
1523
|
+
actionData = state.actionData;
|
|
1524
|
+
} else {
|
|
1525
|
+
// Clear actionData on any other completed navigations
|
|
1526
|
+
actionData = null;
|
|
1527
|
+
} // Always preserve any existing loaderData from re-used routes
|
|
1528
|
+
|
|
1529
|
+
|
|
1530
|
+
let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData;
|
|
1531
|
+
updateState(_extends({}, newState, {
|
|
1532
|
+
actionData,
|
|
1533
|
+
loaderData,
|
|
1516
1534
|
historyAction: pendingAction,
|
|
1517
1535
|
location,
|
|
1518
1536
|
initialized: true,
|
|
@@ -1558,7 +1576,19 @@ function createRouter(init) {
|
|
|
1558
1576
|
// without having to touch history
|
|
1559
1577
|
|
|
1560
1578
|
location = _extends({}, location, init.history.encodeLocation(location));
|
|
1561
|
-
let
|
|
1579
|
+
let userReplace = opts && opts.replace != null ? opts.replace : undefined;
|
|
1580
|
+
let historyAction = Action.Push;
|
|
1581
|
+
|
|
1582
|
+
if (userReplace === true) {
|
|
1583
|
+
historyAction = Action.Replace;
|
|
1584
|
+
} else if (userReplace === false) ; else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) {
|
|
1585
|
+
// By default on submissions to the current location we REPLACE so that
|
|
1586
|
+
// users don't have to double-click the back button to get to the prior
|
|
1587
|
+
// location. If the user redirects to a different location from the
|
|
1588
|
+
// action/loader this will be ignored and the redirect will be a PUSH
|
|
1589
|
+
historyAction = Action.Replace;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1562
1592
|
let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined;
|
|
1563
1593
|
return await startNavigation(historyAction, location, {
|
|
1564
1594
|
submission,
|
|
@@ -1702,11 +1732,14 @@ function createRouter(init) {
|
|
|
1702
1732
|
|
|
1703
1733
|
|
|
1704
1734
|
pendingNavigationController = null;
|
|
1705
|
-
completeNavigation(location, {
|
|
1706
|
-
matches
|
|
1735
|
+
completeNavigation(location, _extends({
|
|
1736
|
+
matches
|
|
1737
|
+
}, pendingActionData ? {
|
|
1738
|
+
actionData: pendingActionData
|
|
1739
|
+
} : {}, {
|
|
1707
1740
|
loaderData,
|
|
1708
1741
|
errors
|
|
1709
|
-
});
|
|
1742
|
+
}));
|
|
1710
1743
|
} // Call the action matched by the leaf route for this navigation and handle
|
|
1711
1744
|
// redirects/errors
|
|
1712
1745
|
|
|
@@ -1746,7 +1779,18 @@ function createRouter(init) {
|
|
|
1746
1779
|
}
|
|
1747
1780
|
|
|
1748
1781
|
if (isRedirectResult(result)) {
|
|
1749
|
-
|
|
1782
|
+
let replace;
|
|
1783
|
+
|
|
1784
|
+
if (opts && opts.replace != null) {
|
|
1785
|
+
replace = opts.replace;
|
|
1786
|
+
} else {
|
|
1787
|
+
// If the user didn't explicity indicate replace behavior, replace if
|
|
1788
|
+
// we redirected to the exact same location we're currently at to avoid
|
|
1789
|
+
// double back-buttons
|
|
1790
|
+
replace = result.location === state.location.pathname + state.location.search;
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
await startRedirectNavigation(state, result, replace);
|
|
1750
1794
|
return {
|
|
1751
1795
|
shortCircuited: true
|
|
1752
1796
|
};
|
|
@@ -1765,6 +1809,8 @@ function createRouter(init) {
|
|
|
1765
1809
|
}
|
|
1766
1810
|
|
|
1767
1811
|
return {
|
|
1812
|
+
// Send back an empty object we can use to clear out any prior actionData
|
|
1813
|
+
pendingActionData: {},
|
|
1768
1814
|
pendingActionError: {
|
|
1769
1815
|
[boundaryMatch.route.id]: result.error
|
|
1770
1816
|
}
|
|
@@ -1808,13 +1854,14 @@ function createRouter(init) {
|
|
|
1808
1854
|
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
|
|
1809
1855
|
|
|
1810
1856
|
if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {
|
|
1811
|
-
completeNavigation(location, {
|
|
1857
|
+
completeNavigation(location, _extends({
|
|
1812
1858
|
matches,
|
|
1813
|
-
loaderData:
|
|
1859
|
+
loaderData: {},
|
|
1814
1860
|
// Commit pending error if we're short circuiting
|
|
1815
|
-
errors: pendingError || null
|
|
1816
|
-
|
|
1817
|
-
|
|
1861
|
+
errors: pendingError || null
|
|
1862
|
+
}, pendingActionData ? {
|
|
1863
|
+
actionData: pendingActionData
|
|
1864
|
+
} : {}));
|
|
1818
1865
|
return {
|
|
1819
1866
|
shortCircuited: true
|
|
1820
1867
|
};
|
|
@@ -1834,14 +1881,19 @@ function createRouter(init) {
|
|
|
1834
1881
|
formMethod: undefined,
|
|
1835
1882
|
formAction: undefined,
|
|
1836
1883
|
formEncType: undefined,
|
|
1837
|
-
formData: undefined
|
|
1884
|
+
formData: undefined,
|
|
1885
|
+
" _hasFetcherDoneAnything ": true
|
|
1838
1886
|
};
|
|
1839
1887
|
state.fetchers.set(key, revalidatingFetcher);
|
|
1840
1888
|
});
|
|
1889
|
+
let actionData = pendingActionData || state.actionData;
|
|
1841
1890
|
updateState(_extends({
|
|
1842
|
-
navigation: loadingNavigation
|
|
1843
|
-
|
|
1844
|
-
|
|
1891
|
+
navigation: loadingNavigation
|
|
1892
|
+
}, actionData ? Object.keys(actionData).length === 0 ? {
|
|
1893
|
+
actionData: null
|
|
1894
|
+
} : {
|
|
1895
|
+
actionData
|
|
1896
|
+
} : {}, revalidatingFetchers.length > 0 ? {
|
|
1845
1897
|
fetchers: new Map(state.fetchers)
|
|
1846
1898
|
} : {}));
|
|
1847
1899
|
}
|
|
@@ -1965,7 +2017,8 @@ function createRouter(init) {
|
|
|
1965
2017
|
let fetcher = _extends({
|
|
1966
2018
|
state: "submitting"
|
|
1967
2019
|
}, submission, {
|
|
1968
|
-
data: existingFetcher && existingFetcher.data
|
|
2020
|
+
data: existingFetcher && existingFetcher.data,
|
|
2021
|
+
" _hasFetcherDoneAnything ": true
|
|
1969
2022
|
});
|
|
1970
2023
|
|
|
1971
2024
|
state.fetchers.set(key, fetcher);
|
|
@@ -1995,14 +2048,15 @@ function createRouter(init) {
|
|
|
1995
2048
|
let loadingFetcher = _extends({
|
|
1996
2049
|
state: "loading"
|
|
1997
2050
|
}, submission, {
|
|
1998
|
-
data: undefined
|
|
2051
|
+
data: undefined,
|
|
2052
|
+
" _hasFetcherDoneAnything ": true
|
|
1999
2053
|
});
|
|
2000
2054
|
|
|
2001
2055
|
state.fetchers.set(key, loadingFetcher);
|
|
2002
2056
|
updateState({
|
|
2003
2057
|
fetchers: new Map(state.fetchers)
|
|
2004
2058
|
});
|
|
2005
|
-
return startRedirectNavigation(state, actionResult);
|
|
2059
|
+
return startRedirectNavigation(state, actionResult, false, true);
|
|
2006
2060
|
} // Process any non-redirect errors thrown
|
|
2007
2061
|
|
|
2008
2062
|
|
|
@@ -2027,7 +2081,9 @@ function createRouter(init) {
|
|
|
2027
2081
|
let loadFetcher = _extends({
|
|
2028
2082
|
state: "loading",
|
|
2029
2083
|
data: actionResult.data
|
|
2030
|
-
}, submission
|
|
2084
|
+
}, submission, {
|
|
2085
|
+
" _hasFetcherDoneAnything ": true
|
|
2086
|
+
});
|
|
2031
2087
|
|
|
2032
2088
|
state.fetchers.set(key, loadFetcher);
|
|
2033
2089
|
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, {
|
|
@@ -2049,7 +2105,8 @@ function createRouter(init) {
|
|
|
2049
2105
|
formMethod: undefined,
|
|
2050
2106
|
formAction: undefined,
|
|
2051
2107
|
formEncType: undefined,
|
|
2052
|
-
formData: undefined
|
|
2108
|
+
formData: undefined,
|
|
2109
|
+
" _hasFetcherDoneAnything ": true
|
|
2053
2110
|
};
|
|
2054
2111
|
state.fetchers.set(staleKey, revalidatingFetcher);
|
|
2055
2112
|
fetchControllers.set(staleKey, abortController);
|
|
@@ -2090,7 +2147,8 @@ function createRouter(init) {
|
|
|
2090
2147
|
formMethod: undefined,
|
|
2091
2148
|
formAction: undefined,
|
|
2092
2149
|
formEncType: undefined,
|
|
2093
|
-
formData: undefined
|
|
2150
|
+
formData: undefined,
|
|
2151
|
+
" _hasFetcherDoneAnything ": true
|
|
2094
2152
|
};
|
|
2095
2153
|
state.fetchers.set(key, doneFetcher);
|
|
2096
2154
|
let didAbortFetchLoads = abortStaleFetchLoads(loadId); // If we are currently in a navigation loading state and this fetcher is
|
|
@@ -2112,7 +2170,7 @@ function createRouter(init) {
|
|
|
2112
2170
|
// manually merge here since we aren't going through completeNavigation
|
|
2113
2171
|
updateState(_extends({
|
|
2114
2172
|
errors,
|
|
2115
|
-
loaderData: mergeLoaderData(state.loaderData, loaderData, matches)
|
|
2173
|
+
loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors)
|
|
2116
2174
|
}, didAbortFetchLoads ? {
|
|
2117
2175
|
fetchers: new Map(state.fetchers)
|
|
2118
2176
|
} : {}));
|
|
@@ -2131,7 +2189,8 @@ function createRouter(init) {
|
|
|
2131
2189
|
formEncType: undefined,
|
|
2132
2190
|
formData: undefined
|
|
2133
2191
|
}, submission, {
|
|
2134
|
-
data: existingFetcher && existingFetcher.data
|
|
2192
|
+
data: existingFetcher && existingFetcher.data,
|
|
2193
|
+
" _hasFetcherDoneAnything ": true
|
|
2135
2194
|
});
|
|
2136
2195
|
|
|
2137
2196
|
state.fetchers.set(key, loadingFetcher);
|
|
@@ -2191,7 +2250,8 @@ function createRouter(init) {
|
|
|
2191
2250
|
formMethod: undefined,
|
|
2192
2251
|
formAction: undefined,
|
|
2193
2252
|
formEncType: undefined,
|
|
2194
|
-
formData: undefined
|
|
2253
|
+
formData: undefined,
|
|
2254
|
+
" _hasFetcherDoneAnything ": true
|
|
2195
2255
|
};
|
|
2196
2256
|
state.fetchers.set(key, doneFetcher);
|
|
2197
2257
|
updateState({
|
|
@@ -2219,14 +2279,19 @@ function createRouter(init) {
|
|
|
2219
2279
|
*/
|
|
2220
2280
|
|
|
2221
2281
|
|
|
2222
|
-
async function startRedirectNavigation(state, redirect, replace) {
|
|
2282
|
+
async function startRedirectNavigation(state, redirect, replace, isFetchActionRedirect) {
|
|
2223
2283
|
var _window;
|
|
2224
2284
|
|
|
2225
2285
|
if (redirect.revalidate) {
|
|
2226
2286
|
isRevalidationRequired = true;
|
|
2227
2287
|
}
|
|
2228
2288
|
|
|
2229
|
-
let redirectLocation = createLocation(state.location, redirect.location
|
|
2289
|
+
let redirectLocation = createLocation(state.location, redirect.location, // TODO: This can be removed once we get rid of useTransition in Remix v2
|
|
2290
|
+
_extends({
|
|
2291
|
+
_isRedirect: true
|
|
2292
|
+
}, isFetchActionRedirect ? {
|
|
2293
|
+
_isFetchActionRedirect: true
|
|
2294
|
+
} : {}));
|
|
2230
2295
|
invariant(redirectLocation, "Expected a location on the redirect navigation"); // Check if this an external redirect that goes to a new origin
|
|
2231
2296
|
|
|
2232
2297
|
if (typeof ((_window = window) == null ? void 0 : _window.location) !== "undefined") {
|
|
@@ -2352,7 +2417,8 @@ function createRouter(init) {
|
|
|
2352
2417
|
formMethod: undefined,
|
|
2353
2418
|
formAction: undefined,
|
|
2354
2419
|
formEncType: undefined,
|
|
2355
|
-
formData: undefined
|
|
2420
|
+
formData: undefined,
|
|
2421
|
+
" _hasFetcherDoneAnything ": true
|
|
2356
2422
|
};
|
|
2357
2423
|
state.fetchers.set(key, doneFetcher);
|
|
2358
2424
|
}
|
|
@@ -2495,8 +2561,8 @@ function createRouter(init) {
|
|
|
2495
2561
|
//#region createStaticHandler
|
|
2496
2562
|
////////////////////////////////////////////////////////////////////////////////
|
|
2497
2563
|
|
|
2498
|
-
function
|
|
2499
|
-
invariant(routes.length > 0, "You must provide a non-empty routes array to
|
|
2564
|
+
function createStaticHandler(routes, opts) {
|
|
2565
|
+
invariant(routes.length > 0, "You must provide a non-empty routes array to createStaticHandler");
|
|
2500
2566
|
let dataRoutes = convertRoutesToDataRoutes(routes);
|
|
2501
2567
|
let basename = (opts ? opts.basename : null) || "/";
|
|
2502
2568
|
/**
|
|
@@ -2818,7 +2884,10 @@ function unstable_createStaticHandler(routes, opts) {
|
|
|
2818
2884
|
if (matchesToLoad.length === 0) {
|
|
2819
2885
|
return {
|
|
2820
2886
|
matches,
|
|
2821
|
-
|
|
2887
|
+
// Add a null for all matched routes for proper revalidation on the client
|
|
2888
|
+
loaderData: matches.reduce((acc, m) => Object.assign(acc, {
|
|
2889
|
+
[m.route.id]: null
|
|
2890
|
+
}), {}),
|
|
2822
2891
|
errors: pendingActionError || null,
|
|
2823
2892
|
statusCode: 200,
|
|
2824
2893
|
loaderHeaders: {}
|
|
@@ -2830,17 +2899,25 @@ function unstable_createStaticHandler(routes, opts) {
|
|
|
2830
2899
|
if (request.signal.aborted) {
|
|
2831
2900
|
let method = isRouteRequest ? "queryRoute" : "query";
|
|
2832
2901
|
throw new Error(method + "() call aborted");
|
|
2833
|
-
}
|
|
2834
|
-
// cancel them for now
|
|
2902
|
+
}
|
|
2835
2903
|
|
|
2904
|
+
let executedLoaders = new Set();
|
|
2905
|
+
results.forEach((result, i) => {
|
|
2906
|
+
executedLoaders.add(matchesToLoad[i].route.id); // Can't do anything with these without the Remix side of things, so just
|
|
2907
|
+
// cancel them for now
|
|
2836
2908
|
|
|
2837
|
-
results.forEach(result => {
|
|
2838
2909
|
if (isDeferredResult(result)) {
|
|
2839
2910
|
result.deferredData.cancel();
|
|
2840
2911
|
}
|
|
2841
2912
|
}); // Process and commit output from loaders
|
|
2842
2913
|
|
|
2843
|
-
let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionError);
|
|
2914
|
+
let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionError); // Add a null for any non-loader matches for proper revalidation on the client
|
|
2915
|
+
|
|
2916
|
+
matches.forEach(match => {
|
|
2917
|
+
if (!executedLoaders.has(match.route.id)) {
|
|
2918
|
+
context.loaderData[match.route.id] = null;
|
|
2919
|
+
}
|
|
2920
|
+
});
|
|
2844
2921
|
return _extends({}, context, {
|
|
2845
2922
|
matches
|
|
2846
2923
|
});
|
|
@@ -2962,7 +3039,7 @@ function getLoaderMatchesUntilBoundary(matches, boundaryId) {
|
|
|
2962
3039
|
}
|
|
2963
3040
|
|
|
2964
3041
|
function getMatchesToLoad(state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches) {
|
|
2965
|
-
let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] :
|
|
3042
|
+
let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined; // Pick navigation matches that are net-new or qualify for revalidation
|
|
2966
3043
|
|
|
2967
3044
|
let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;
|
|
2968
3045
|
let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);
|
|
@@ -3132,9 +3209,10 @@ async function callLoaderOrAction(type, request, match, matches, basename, isSta
|
|
|
3132
3209
|
}
|
|
3133
3210
|
|
|
3134
3211
|
let data;
|
|
3135
|
-
let contentType = result.headers.get("Content-Type");
|
|
3212
|
+
let contentType = result.headers.get("Content-Type"); // Check between word boundaries instead of startsWith() due to the last
|
|
3213
|
+
// paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type
|
|
3136
3214
|
|
|
3137
|
-
if (contentType && contentType
|
|
3215
|
+
if (contentType && /\bapplication\/json\b/.test(contentType)) {
|
|
3138
3216
|
data = await result.json();
|
|
3139
3217
|
} else {
|
|
3140
3218
|
data = await result.text();
|
|
@@ -3239,9 +3317,11 @@ function processRouteLoaderData(matches, matchesToLoad, results, pendingError, a
|
|
|
3239
3317
|
|
|
3240
3318
|
if (errors[boundaryMatch.route.id] == null) {
|
|
3241
3319
|
errors[boundaryMatch.route.id] = error;
|
|
3242
|
-
} //
|
|
3243
|
-
|
|
3320
|
+
} // Clear our any prior loaderData for the throwing route
|
|
3321
|
+
|
|
3244
3322
|
|
|
3323
|
+
loaderData[id] = undefined; // Once we find our first (highest) error, we set the status code and
|
|
3324
|
+
// prevent deeper status codes from overriding
|
|
3245
3325
|
|
|
3246
3326
|
if (!foundError) {
|
|
3247
3327
|
foundError = true;
|
|
@@ -3267,10 +3347,12 @@ function processRouteLoaderData(matches, matchesToLoad, results, pendingError, a
|
|
|
3267
3347
|
}
|
|
3268
3348
|
}
|
|
3269
3349
|
}); // If we didn't consume the pending action error (i.e., all loaders
|
|
3270
|
-
// resolved), then consume it here
|
|
3350
|
+
// resolved), then consume it here. Also clear out any loaderData for the
|
|
3351
|
+
// throwing route
|
|
3271
3352
|
|
|
3272
3353
|
if (pendingError) {
|
|
3273
3354
|
errors = pendingError;
|
|
3355
|
+
loaderData[Object.keys(pendingError)[0]] = undefined;
|
|
3274
3356
|
}
|
|
3275
3357
|
|
|
3276
3358
|
return {
|
|
@@ -3317,7 +3399,8 @@ function processLoaderData(state, matches, matchesToLoad, results, pendingError,
|
|
|
3317
3399
|
formMethod: undefined,
|
|
3318
3400
|
formAction: undefined,
|
|
3319
3401
|
formEncType: undefined,
|
|
3320
|
-
formData: undefined
|
|
3402
|
+
formData: undefined,
|
|
3403
|
+
" _hasFetcherDoneAnything ": true
|
|
3321
3404
|
};
|
|
3322
3405
|
state.fetchers.set(key, doneFetcher);
|
|
3323
3406
|
}
|
|
@@ -3329,16 +3412,26 @@ function processLoaderData(state, matches, matchesToLoad, results, pendingError,
|
|
|
3329
3412
|
};
|
|
3330
3413
|
}
|
|
3331
3414
|
|
|
3332
|
-
function mergeLoaderData(loaderData, newLoaderData, matches) {
|
|
3415
|
+
function mergeLoaderData(loaderData, newLoaderData, matches, errors) {
|
|
3333
3416
|
let mergedLoaderData = _extends({}, newLoaderData);
|
|
3334
3417
|
|
|
3335
|
-
|
|
3418
|
+
for (let match of matches) {
|
|
3336
3419
|
let id = match.route.id;
|
|
3337
3420
|
|
|
3338
|
-
if (newLoaderData
|
|
3421
|
+
if (newLoaderData.hasOwnProperty(id)) {
|
|
3422
|
+
if (newLoaderData[id] !== undefined) {
|
|
3423
|
+
mergedLoaderData[id] = newLoaderData[id];
|
|
3424
|
+
}
|
|
3425
|
+
} else if (loaderData[id] !== undefined) {
|
|
3339
3426
|
mergedLoaderData[id] = loaderData[id];
|
|
3340
3427
|
}
|
|
3341
|
-
|
|
3428
|
+
|
|
3429
|
+
if (errors && errors.hasOwnProperty(id)) {
|
|
3430
|
+
// Don't keep any loader data below the boundary
|
|
3431
|
+
break;
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3434
|
+
|
|
3342
3435
|
return mergedLoaderData;
|
|
3343
3436
|
} // Find the nearest error boundary, looking upwards from the leaf route (or the
|
|
3344
3437
|
// route specified by routeId) for the closest ancestor error boundary,
|
|
@@ -3549,5 +3642,5 @@ function getTargetMatch(matches, location) {
|
|
|
3549
3642
|
return pathMatches[pathMatches.length - 1];
|
|
3550
3643
|
} //#endregion
|
|
3551
3644
|
|
|
3552
|
-
export { AbortedDeferredError, Action, ErrorResponse, IDLE_FETCHER, IDLE_NAVIGATION, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, getPathContributingMatches as UNSAFE_getPathContributingMatches, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, createRouter, defer, generatePath, getStaticContextFromError, getToPathname, invariant, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, parsePath, redirect, resolvePath, resolveTo, stripBasename,
|
|
3645
|
+
export { AbortedDeferredError, Action, ErrorResponse, IDLE_FETCHER, IDLE_NAVIGATION, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, getPathContributingMatches as UNSAFE_getPathContributingMatches, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, createRouter, createStaticHandler, defer, generatePath, getStaticContextFromError, getToPathname, invariant, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, parsePath, redirect, resolvePath, resolveTo, stripBasename, warning };
|
|
3553
3646
|
//# sourceMappingURL=router.js.map
|