@remix-run/router 0.0.0-experimental-e192105b → 0.0.0-experimental-178bc9ee
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 +28 -0
- package/dist/index.d.ts +2 -2
- package/dist/router.cjs.js +118 -89
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +9 -1
- package/dist/router.js +115 -88
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +118 -89
- 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 +2 -1
- package/index.ts +2 -1
- package/package.json +1 -1
- package/router.ts +147 -77
- package/utils.ts +35 -5
package/dist/router.d.ts
CHANGED
|
@@ -12,6 +12,13 @@ export interface Router {
|
|
|
12
12
|
* Return the basename for the router
|
|
13
13
|
*/
|
|
14
14
|
get basename(): RouterInit["basename"];
|
|
15
|
+
/**
|
|
16
|
+
* @internal
|
|
17
|
+
* PRIVATE - DO NOT USE
|
|
18
|
+
*
|
|
19
|
+
* Return the future config for the router
|
|
20
|
+
*/
|
|
21
|
+
get future(): FutureConfig;
|
|
15
22
|
/**
|
|
16
23
|
* @internal
|
|
17
24
|
* PRIVATE - DO NOT USE
|
|
@@ -248,6 +255,7 @@ export type HydrationState = Partial<Pick<RouterState, "loaderData" | "actionDat
|
|
|
248
255
|
export interface FutureConfig {
|
|
249
256
|
v7_fetcherPersist: boolean;
|
|
250
257
|
v7_normalizeFormMethod: boolean;
|
|
258
|
+
v7_partialHydration: boolean;
|
|
251
259
|
v7_prependBasename: boolean;
|
|
252
260
|
}
|
|
253
261
|
/**
|
|
@@ -306,7 +314,7 @@ export interface RouterSubscriber {
|
|
|
306
314
|
(state: RouterState, opts: {
|
|
307
315
|
deletedFetchers: string[];
|
|
308
316
|
unstable_viewTransitionOpts?: ViewTransitionOpts;
|
|
309
|
-
unstable_flushSync
|
|
317
|
+
unstable_flushSync: boolean;
|
|
310
318
|
}): void;
|
|
311
319
|
}
|
|
312
320
|
/**
|
package/dist/router.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v0.0.0-experimental-
|
|
2
|
+
* @remix-run/router v0.0.0-experimental-178bc9ee
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -938,6 +938,12 @@ function getInvalidPathError(char, field, dest, path) {
|
|
|
938
938
|
function getPathContributingMatches(matches) {
|
|
939
939
|
return matches.filter((match, index) => index === 0 || match.route.path && match.route.path.length > 0);
|
|
940
940
|
}
|
|
941
|
+
// Return the array of pathnames for the current route matches - used to
|
|
942
|
+
// generate the routePathnames input for resolveTo()
|
|
943
|
+
function getResolveToMatches(matches) {
|
|
944
|
+
// Use the full pathname for the leaf match so we include splat values for "." links
|
|
945
|
+
return getPathContributingMatches(matches).map((match, idx) => idx === matches.length - 1 ? match.pathname : match.pathnameBase);
|
|
946
|
+
}
|
|
941
947
|
/**
|
|
942
948
|
* @private
|
|
943
949
|
*/
|
|
@@ -966,15 +972,28 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {
|
|
|
966
972
|
// `to` values that do not provide a pathname. `to` can simply be a search or
|
|
967
973
|
// hash string, in which case we should assume that the navigation is relative
|
|
968
974
|
// to the current location's pathname and *not* the route pathname.
|
|
969
|
-
if (
|
|
975
|
+
if (toPathname == null) {
|
|
970
976
|
from = locationPathname;
|
|
977
|
+
} else if (isPathRelative) {
|
|
978
|
+
let fromSegments = routePathnames[routePathnames.length - 1].replace(/^\//, "").split("/");
|
|
979
|
+
if (toPathname.startsWith("..")) {
|
|
980
|
+
let toSegments = toPathname.split("/");
|
|
981
|
+
// With relative="path", each leading .. segment means "go up one URL segment"
|
|
982
|
+
while (toSegments[0] === "..") {
|
|
983
|
+
toSegments.shift();
|
|
984
|
+
fromSegments.pop();
|
|
985
|
+
}
|
|
986
|
+
to.pathname = toSegments.join("/");
|
|
987
|
+
}
|
|
988
|
+
from = "/" + fromSegments.join("/");
|
|
971
989
|
} else {
|
|
972
990
|
let routePathnameIndex = routePathnames.length - 1;
|
|
973
991
|
if (toPathname.startsWith("..")) {
|
|
974
992
|
let toSegments = toPathname.split("/");
|
|
975
|
-
//
|
|
976
|
-
// URL segment". This is a key
|
|
977
|
-
//
|
|
993
|
+
// With relative="route" (the default), each leading .. segment means
|
|
994
|
+
// "go up one route" instead of "go up one URL segment". This is a key
|
|
995
|
+
// difference from how <a href> works and a major reason we call this a
|
|
996
|
+
// "to" value instead of a "href".
|
|
978
997
|
while (toSegments[0] === "..") {
|
|
979
998
|
toSegments.shift();
|
|
980
999
|
routePathnameIndex -= 1;
|
|
@@ -1317,6 +1336,7 @@ function createRouter(init) {
|
|
|
1317
1336
|
let future = _extends({
|
|
1318
1337
|
v7_fetcherPersist: false,
|
|
1319
1338
|
v7_normalizeFormMethod: false,
|
|
1339
|
+
v7_partialHydration: false,
|
|
1320
1340
|
v7_prependBasename: false
|
|
1321
1341
|
}, init.future);
|
|
1322
1342
|
// Cleanup function for history
|
|
@@ -1353,7 +1373,12 @@ function createRouter(init) {
|
|
|
1353
1373
|
[route.id]: error
|
|
1354
1374
|
};
|
|
1355
1375
|
}
|
|
1356
|
-
|
|
1376
|
+
// "Initialized" here really means "Can `RouterProvider` render my route tree?"
|
|
1377
|
+
// Prior to `route.Fallback`, we only had a root `fallbackElement` so we used
|
|
1378
|
+
// `state.initialized` to render that instead of `<DataRoutes>`. Now that we
|
|
1379
|
+
// support route level fallbacks we can always render and we'll just render
|
|
1380
|
+
// as deep as we have data for and detect the nearest ancestor Fallback
|
|
1381
|
+
let initialized = future.v7_partialHydration ||
|
|
1357
1382
|
// All initialMatches need to be loaded before we're ready. If we have lazy
|
|
1358
1383
|
// functions around still then we'll need to run them in initialize()
|
|
1359
1384
|
!initialMatches.some(m => m.route.lazy) && (
|
|
@@ -1386,8 +1411,6 @@ function createRouter(init) {
|
|
|
1386
1411
|
let pendingNavigationController;
|
|
1387
1412
|
// Should the current navigation enable document.startViewTransition?
|
|
1388
1413
|
let pendingViewTransitionEnabled = false;
|
|
1389
|
-
// Should the current navigation use flushSync for state updates?
|
|
1390
|
-
let pendingFlushSync = false;
|
|
1391
1414
|
// Store applied view transitions so we can apply them on POP
|
|
1392
1415
|
let appliedViewTransitions = new Map();
|
|
1393
1416
|
// Cleanup function for persisting applied transitions to sessionStorage
|
|
@@ -1483,8 +1506,6 @@ function createRouter(init) {
|
|
|
1483
1506
|
blockers.set(blockerKey, IDLE_BLOCKER);
|
|
1484
1507
|
updateState({
|
|
1485
1508
|
blockers
|
|
1486
|
-
}, {
|
|
1487
|
-
flushSync: false
|
|
1488
1509
|
});
|
|
1489
1510
|
}
|
|
1490
1511
|
});
|
|
@@ -1505,8 +1526,10 @@ function createRouter(init) {
|
|
|
1505
1526
|
// in the normal navigation flow. For SSR it's expected that lazy modules are
|
|
1506
1527
|
// resolved prior to router creation since we can't go into a fallbackElement
|
|
1507
1528
|
// UI for SSR'd apps
|
|
1508
|
-
if (!state.initialized) {
|
|
1509
|
-
startNavigation(Action.Pop, state.location
|
|
1529
|
+
if (!state.initialized || future.v7_partialHydration && state.matches.some(m => m.route.loader && state.loaderData[m.route.id] === undefined)) {
|
|
1530
|
+
startNavigation(Action.Pop, state.location, {
|
|
1531
|
+
initialHydration: true
|
|
1532
|
+
});
|
|
1510
1533
|
}
|
|
1511
1534
|
return router;
|
|
1512
1535
|
}
|
|
@@ -1530,6 +1553,9 @@ function createRouter(init) {
|
|
|
1530
1553
|
}
|
|
1531
1554
|
// Update our state and notify the calling context of the change
|
|
1532
1555
|
function updateState(newState, opts) {
|
|
1556
|
+
if (opts === void 0) {
|
|
1557
|
+
opts = {};
|
|
1558
|
+
}
|
|
1533
1559
|
state = _extends({}, state, newState);
|
|
1534
1560
|
// Prep fetcher cleanup so we can tell the UI which fetcher data entries
|
|
1535
1561
|
// can be removed
|
|
@@ -1555,7 +1581,7 @@ function createRouter(init) {
|
|
|
1555
1581
|
[...subscribers].forEach(subscriber => subscriber(state, {
|
|
1556
1582
|
deletedFetchers: deletedFetchersKeys,
|
|
1557
1583
|
unstable_viewTransitionOpts: opts.viewTransitionOpts,
|
|
1558
|
-
unstable_flushSync: opts.flushSync
|
|
1584
|
+
unstable_flushSync: opts.flushSync === true
|
|
1559
1585
|
}));
|
|
1560
1586
|
// Remove idle fetchers from state since we only care about in-flight fetchers.
|
|
1561
1587
|
if (future.v7_fetcherPersist) {
|
|
@@ -1568,8 +1594,11 @@ function createRouter(init) {
|
|
|
1568
1594
|
// - Location is a required param
|
|
1569
1595
|
// - Navigation will always be set to IDLE_NAVIGATION
|
|
1570
1596
|
// - Can pass any other state in newState
|
|
1571
|
-
function completeNavigation(location, newState) {
|
|
1597
|
+
function completeNavigation(location, newState, _temp) {
|
|
1572
1598
|
var _location$state, _location$state2;
|
|
1599
|
+
let {
|
|
1600
|
+
flushSync
|
|
1601
|
+
} = _temp === void 0 ? {} : _temp;
|
|
1573
1602
|
// Deduce if we're in a loading/actionReload state:
|
|
1574
1603
|
// - We have committed actionData in the store
|
|
1575
1604
|
// - The current navigation was a mutation submission
|
|
@@ -1657,13 +1686,12 @@ function createRouter(init) {
|
|
|
1657
1686
|
blockers
|
|
1658
1687
|
}), {
|
|
1659
1688
|
viewTransitionOpts,
|
|
1660
|
-
flushSync:
|
|
1689
|
+
flushSync: flushSync === true
|
|
1661
1690
|
});
|
|
1662
1691
|
// Reset stateful navigation vars
|
|
1663
1692
|
pendingAction = Action.Pop;
|
|
1664
1693
|
pendingPreventScrollReset = false;
|
|
1665
1694
|
pendingViewTransitionEnabled = false;
|
|
1666
|
-
pendingFlushSync = false;
|
|
1667
1695
|
isUninterruptedRevalidation = false;
|
|
1668
1696
|
isRevalidationRequired = false;
|
|
1669
1697
|
cancelledDeferredRoutes = [];
|
|
@@ -1728,8 +1756,6 @@ function createRouter(init) {
|
|
|
1728
1756
|
blockers.set(blockerKey, IDLE_BLOCKER);
|
|
1729
1757
|
updateState({
|
|
1730
1758
|
blockers
|
|
1731
|
-
}, {
|
|
1732
|
-
flushSync
|
|
1733
1759
|
});
|
|
1734
1760
|
}
|
|
1735
1761
|
});
|
|
@@ -1753,8 +1779,6 @@ function createRouter(init) {
|
|
|
1753
1779
|
interruptActiveLoads();
|
|
1754
1780
|
updateState({
|
|
1755
1781
|
revalidation: "loading"
|
|
1756
|
-
}, {
|
|
1757
|
-
flushSync: false
|
|
1758
1782
|
});
|
|
1759
1783
|
// If we're currently submitting an action, we don't need to start a new
|
|
1760
1784
|
// navigation, we'll just let the follow up loader execution call all loaders
|
|
@@ -1793,10 +1817,10 @@ function createRouter(init) {
|
|
|
1793
1817
|
saveScrollPosition(state.location, state.matches);
|
|
1794
1818
|
pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;
|
|
1795
1819
|
pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true;
|
|
1796
|
-
pendingFlushSync = (opts && opts.flushSync) === true;
|
|
1797
1820
|
let routesToUse = inFlightDataRoutes || dataRoutes;
|
|
1798
1821
|
let loadingNavigation = opts && opts.overrideNavigation;
|
|
1799
1822
|
let matches = matchRoutes(routesToUse, location, basename);
|
|
1823
|
+
let flushSync = (opts && opts.flushSync) === true;
|
|
1800
1824
|
// Short circuit with a 404 on the root error boundary if we match nothing
|
|
1801
1825
|
if (!matches) {
|
|
1802
1826
|
let error = getInternalRouterError(404, {
|
|
@@ -1814,6 +1838,8 @@ function createRouter(init) {
|
|
|
1814
1838
|
errors: {
|
|
1815
1839
|
[route.id]: error
|
|
1816
1840
|
}
|
|
1841
|
+
}, {
|
|
1842
|
+
flushSync
|
|
1817
1843
|
});
|
|
1818
1844
|
return;
|
|
1819
1845
|
}
|
|
@@ -1826,12 +1852,14 @@ function createRouter(init) {
|
|
|
1826
1852
|
if (state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) {
|
|
1827
1853
|
completeNavigation(location, {
|
|
1828
1854
|
matches
|
|
1855
|
+
}, {
|
|
1856
|
+
flushSync
|
|
1829
1857
|
});
|
|
1830
1858
|
return;
|
|
1831
1859
|
}
|
|
1832
1860
|
// Create a controller/Request for this navigation
|
|
1833
1861
|
pendingNavigationController = new AbortController();
|
|
1834
|
-
let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.submission);
|
|
1862
|
+
let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.initialHydration === true, opts && opts.submission);
|
|
1835
1863
|
let pendingActionData;
|
|
1836
1864
|
let pendingError;
|
|
1837
1865
|
if (opts && opts.pendingError) {
|
|
@@ -1845,7 +1873,8 @@ function createRouter(init) {
|
|
|
1845
1873
|
} else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) {
|
|
1846
1874
|
// Call action if we received an action submission
|
|
1847
1875
|
let actionOutput = await handleAction(request, location, opts.submission, matches, {
|
|
1848
|
-
replace: opts.replace
|
|
1876
|
+
replace: opts.replace,
|
|
1877
|
+
flushSync
|
|
1849
1878
|
});
|
|
1850
1879
|
if (actionOutput.shortCircuited) {
|
|
1851
1880
|
return;
|
|
@@ -1853,6 +1882,7 @@ function createRouter(init) {
|
|
|
1853
1882
|
pendingActionData = actionOutput.pendingActionData;
|
|
1854
1883
|
pendingError = actionOutput.pendingActionError;
|
|
1855
1884
|
loadingNavigation = getLoadingNavigation(location, opts.submission);
|
|
1885
|
+
flushSync = false;
|
|
1856
1886
|
// Create a GET request for the loaders
|
|
1857
1887
|
request = new Request(request.url, {
|
|
1858
1888
|
signal: request.signal
|
|
@@ -1863,7 +1893,7 @@ function createRouter(init) {
|
|
|
1863
1893
|
shortCircuited,
|
|
1864
1894
|
loaderData,
|
|
1865
1895
|
errors
|
|
1866
|
-
} = await handleLoaders(request, location, matches, loadingNavigation, opts && opts.submission, opts && opts.fetcherSubmission, opts && opts.replace, pendingActionData, pendingError);
|
|
1896
|
+
} = await handleLoaders(request, location, matches, loadingNavigation, opts && opts.submission, opts && opts.fetcherSubmission, opts && opts.replace, opts && opts.initialHydration === true, flushSync, pendingActionData, pendingError);
|
|
1867
1897
|
if (shortCircuited) {
|
|
1868
1898
|
return;
|
|
1869
1899
|
}
|
|
@@ -1892,7 +1922,7 @@ function createRouter(init) {
|
|
|
1892
1922
|
updateState({
|
|
1893
1923
|
navigation
|
|
1894
1924
|
}, {
|
|
1895
|
-
flushSync:
|
|
1925
|
+
flushSync: opts.flushSync === true
|
|
1896
1926
|
});
|
|
1897
1927
|
// Call our action and get the result
|
|
1898
1928
|
let result;
|
|
@@ -1964,14 +1994,14 @@ function createRouter(init) {
|
|
|
1964
1994
|
}
|
|
1965
1995
|
// Call all applicable loaders for the given matches, handling redirects,
|
|
1966
1996
|
// errors, etc.
|
|
1967
|
-
async function handleLoaders(request, location, matches, overrideNavigation, submission, fetcherSubmission, replace, pendingActionData, pendingError) {
|
|
1997
|
+
async function handleLoaders(request, location, matches, overrideNavigation, submission, fetcherSubmission, replace, initialHydration, flushSync, pendingActionData, pendingError) {
|
|
1968
1998
|
// Figure out the right navigation we want to use for data loading
|
|
1969
1999
|
let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission);
|
|
1970
2000
|
// If this was a redirect from an action we don't have a "submission" but
|
|
1971
2001
|
// we have it on the loading navigation so use that if available
|
|
1972
2002
|
let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation);
|
|
1973
2003
|
let routesToUse = inFlightDataRoutes || dataRoutes;
|
|
1974
|
-
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionData, pendingError);
|
|
2004
|
+
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, future.v7_partialHydration && initialHydration === true, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionData, pendingError);
|
|
1975
2005
|
// Cancel pending deferreds for no-longer-matched routes or routes we're
|
|
1976
2006
|
// about to reload. Note that if this is an action reload we would have
|
|
1977
2007
|
// already cancelled all pending deferreds so this would be a no-op
|
|
@@ -1989,7 +2019,9 @@ function createRouter(init) {
|
|
|
1989
2019
|
actionData: pendingActionData
|
|
1990
2020
|
} : {}, updatedFetchers ? {
|
|
1991
2021
|
fetchers: new Map(state.fetchers)
|
|
1992
|
-
} : {})
|
|
2022
|
+
} : {}), {
|
|
2023
|
+
flushSync
|
|
2024
|
+
});
|
|
1993
2025
|
return {
|
|
1994
2026
|
shortCircuited: true
|
|
1995
2027
|
};
|
|
@@ -2014,7 +2046,7 @@ function createRouter(init) {
|
|
|
2014
2046
|
} : {}, revalidatingFetchers.length > 0 ? {
|
|
2015
2047
|
fetchers: new Map(state.fetchers)
|
|
2016
2048
|
} : {}), {
|
|
2017
|
-
flushSync
|
|
2049
|
+
flushSync
|
|
2018
2050
|
});
|
|
2019
2051
|
}
|
|
2020
2052
|
revalidatingFetchers.forEach(rf => {
|
|
@@ -2159,7 +2191,7 @@ function createRouter(init) {
|
|
|
2159
2191
|
});
|
|
2160
2192
|
// Call the action for the fetcher
|
|
2161
2193
|
let abortController = new AbortController();
|
|
2162
|
-
let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, submission);
|
|
2194
|
+
let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, false, submission);
|
|
2163
2195
|
fetchControllers.set(key, abortController);
|
|
2164
2196
|
let originatingLoadId = incrementingLoadId;
|
|
2165
2197
|
let actionResult = await callLoaderOrAction("action", fetchRequest, match, requestMatches, manifest, mapRouteProperties, basename);
|
|
@@ -2172,9 +2204,7 @@ function createRouter(init) {
|
|
|
2172
2204
|
return;
|
|
2173
2205
|
}
|
|
2174
2206
|
if (deletedFetchers.has(key)) {
|
|
2175
|
-
updateFetcherState(key, getDoneFetcher(undefined)
|
|
2176
|
-
flushSync
|
|
2177
|
-
});
|
|
2207
|
+
updateFetcherState(key, getDoneFetcher(undefined));
|
|
2178
2208
|
return;
|
|
2179
2209
|
}
|
|
2180
2210
|
if (isRedirectResult(actionResult)) {
|
|
@@ -2184,15 +2214,11 @@ function createRouter(init) {
|
|
|
2184
2214
|
// should take precedence over this redirect navigation. We already
|
|
2185
2215
|
// set isRevalidationRequired so all loaders for the new route should
|
|
2186
2216
|
// fire unless opted out via shouldRevalidate
|
|
2187
|
-
updateFetcherState(key, getDoneFetcher(undefined)
|
|
2188
|
-
flushSync
|
|
2189
|
-
});
|
|
2217
|
+
updateFetcherState(key, getDoneFetcher(undefined));
|
|
2190
2218
|
return;
|
|
2191
2219
|
} else {
|
|
2192
2220
|
fetchRedirectIds.add(key);
|
|
2193
|
-
updateFetcherState(key, getLoadingFetcher(submission)
|
|
2194
|
-
flushSync
|
|
2195
|
-
});
|
|
2221
|
+
updateFetcherState(key, getLoadingFetcher(submission));
|
|
2196
2222
|
return startRedirectNavigation(state, actionResult, {
|
|
2197
2223
|
fetcherSubmission: submission
|
|
2198
2224
|
});
|
|
@@ -2200,9 +2226,7 @@ function createRouter(init) {
|
|
|
2200
2226
|
}
|
|
2201
2227
|
// Process any non-redirect errors thrown
|
|
2202
2228
|
if (isErrorResult(actionResult)) {
|
|
2203
|
-
setFetcherError(key, routeId, actionResult.error
|
|
2204
|
-
flushSync
|
|
2205
|
-
});
|
|
2229
|
+
setFetcherError(key, routeId, actionResult.error);
|
|
2206
2230
|
return;
|
|
2207
2231
|
}
|
|
2208
2232
|
if (isDeferredResult(actionResult)) {
|
|
@@ -2213,7 +2237,7 @@ function createRouter(init) {
|
|
|
2213
2237
|
// Start the data load for current matches, or the next location if we're
|
|
2214
2238
|
// in the middle of a navigation
|
|
2215
2239
|
let nextLocation = state.navigation.location || state.location;
|
|
2216
|
-
let revalidationRequest = createClientSideRequest(init.history, nextLocation, abortController.signal);
|
|
2240
|
+
let revalidationRequest = createClientSideRequest(init.history, nextLocation, abortController.signal, false);
|
|
2217
2241
|
let routesToUse = inFlightDataRoutes || dataRoutes;
|
|
2218
2242
|
let matches = state.navigation.state !== "idle" ? matchRoutes(routesToUse, state.navigation.location, basename) : state.matches;
|
|
2219
2243
|
invariant(matches, "Didn't find any matches after fetcher action");
|
|
@@ -2221,7 +2245,7 @@ function createRouter(init) {
|
|
|
2221
2245
|
fetchReloadIds.set(key, loadId);
|
|
2222
2246
|
let loadFetcher = getLoadingFetcher(submission, actionResult.data);
|
|
2223
2247
|
state.fetchers.set(key, loadFetcher);
|
|
2224
|
-
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, {
|
|
2248
|
+
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, false, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, {
|
|
2225
2249
|
[match.route.id]: actionResult.data
|
|
2226
2250
|
}, undefined // No need to send through errors since we short circuit above
|
|
2227
2251
|
);
|
|
@@ -2242,8 +2266,6 @@ function createRouter(init) {
|
|
|
2242
2266
|
});
|
|
2243
2267
|
updateState({
|
|
2244
2268
|
fetchers: new Map(state.fetchers)
|
|
2245
|
-
}, {
|
|
2246
|
-
flushSync
|
|
2247
2269
|
});
|
|
2248
2270
|
let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach(rf => abortFetcher(rf.key));
|
|
2249
2271
|
abortController.signal.addEventListener("abort", abortPendingFetchRevalidations);
|
|
@@ -2302,8 +2324,6 @@ function createRouter(init) {
|
|
|
2302
2324
|
errors,
|
|
2303
2325
|
loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors),
|
|
2304
2326
|
fetchers: new Map(state.fetchers)
|
|
2305
|
-
}, {
|
|
2306
|
-
flushSync
|
|
2307
2327
|
});
|
|
2308
2328
|
isRevalidationRequired = false;
|
|
2309
2329
|
}
|
|
@@ -2316,7 +2336,7 @@ function createRouter(init) {
|
|
|
2316
2336
|
});
|
|
2317
2337
|
// Call the loader for this fetcher route match
|
|
2318
2338
|
let abortController = new AbortController();
|
|
2319
|
-
let fetchRequest = createClientSideRequest(init.history, path, abortController.signal);
|
|
2339
|
+
let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, false);
|
|
2320
2340
|
fetchControllers.set(key, abortController);
|
|
2321
2341
|
let originatingLoadId = incrementingLoadId;
|
|
2322
2342
|
let result = await callLoaderOrAction("loader", fetchRequest, match, matches, manifest, mapRouteProperties, basename);
|
|
@@ -2336,9 +2356,7 @@ function createRouter(init) {
|
|
|
2336
2356
|
return;
|
|
2337
2357
|
}
|
|
2338
2358
|
if (deletedFetchers.has(key)) {
|
|
2339
|
-
updateFetcherState(key, getDoneFetcher(undefined)
|
|
2340
|
-
flushSync
|
|
2341
|
-
});
|
|
2359
|
+
updateFetcherState(key, getDoneFetcher(undefined));
|
|
2342
2360
|
return;
|
|
2343
2361
|
}
|
|
2344
2362
|
// If the loader threw a redirect Response, start a new REPLACE navigation
|
|
@@ -2346,9 +2364,7 @@ function createRouter(init) {
|
|
|
2346
2364
|
if (pendingNavigationLoadId > originatingLoadId) {
|
|
2347
2365
|
// A new navigation was kicked off after our loader started, so that
|
|
2348
2366
|
// should take precedence over this redirect navigation
|
|
2349
|
-
updateFetcherState(key, getDoneFetcher(undefined)
|
|
2350
|
-
flushSync
|
|
2351
|
-
});
|
|
2367
|
+
updateFetcherState(key, getDoneFetcher(undefined));
|
|
2352
2368
|
return;
|
|
2353
2369
|
} else {
|
|
2354
2370
|
fetchRedirectIds.add(key);
|
|
@@ -2358,16 +2374,12 @@ function createRouter(init) {
|
|
|
2358
2374
|
}
|
|
2359
2375
|
// Process any non-redirect errors thrown
|
|
2360
2376
|
if (isErrorResult(result)) {
|
|
2361
|
-
setFetcherError(key, routeId, result.error
|
|
2362
|
-
flushSync
|
|
2363
|
-
});
|
|
2377
|
+
setFetcherError(key, routeId, result.error);
|
|
2364
2378
|
return;
|
|
2365
2379
|
}
|
|
2366
2380
|
invariant(!isDeferredResult(result), "Unhandled fetcher deferred data");
|
|
2367
2381
|
// Put the fetcher back into an idle state
|
|
2368
|
-
updateFetcherState(key, getDoneFetcher(result.data)
|
|
2369
|
-
flushSync
|
|
2370
|
-
});
|
|
2382
|
+
updateFetcherState(key, getDoneFetcher(result.data));
|
|
2371
2383
|
}
|
|
2372
2384
|
/**
|
|
2373
2385
|
* Utility function to handle redirects returned from an action or loader.
|
|
@@ -2388,12 +2400,12 @@ function createRouter(init) {
|
|
|
2388
2400
|
* actually touch history until we've processed redirects, so we just use
|
|
2389
2401
|
* the history action from the original navigation (PUSH or REPLACE).
|
|
2390
2402
|
*/
|
|
2391
|
-
async function startRedirectNavigation(state, redirect,
|
|
2403
|
+
async function startRedirectNavigation(state, redirect, _temp2) {
|
|
2392
2404
|
let {
|
|
2393
2405
|
submission,
|
|
2394
2406
|
fetcherSubmission,
|
|
2395
2407
|
replace
|
|
2396
|
-
} =
|
|
2408
|
+
} = _temp2 === void 0 ? {} : _temp2;
|
|
2397
2409
|
if (redirect.revalidate) {
|
|
2398
2410
|
isRevalidationRequired = true;
|
|
2399
2411
|
}
|
|
@@ -2468,7 +2480,7 @@ function createRouter(init) {
|
|
|
2468
2480
|
// accordingly
|
|
2469
2481
|
let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, manifest, mapRouteProperties, basename)), ...fetchersToLoad.map(f => {
|
|
2470
2482
|
if (f.matches && f.match && f.controller) {
|
|
2471
|
-
return callLoaderOrAction("loader", createClientSideRequest(init.history, f.path, f.controller.signal), f.match, f.matches, manifest, mapRouteProperties, basename);
|
|
2483
|
+
return callLoaderOrAction("loader", createClientSideRequest(init.history, f.path, f.controller.signal, false), f.match, f.matches, manifest, mapRouteProperties, basename);
|
|
2472
2484
|
} else {
|
|
2473
2485
|
let error = {
|
|
2474
2486
|
type: ResultType.error,
|
|
@@ -2503,14 +2515,20 @@ function createRouter(init) {
|
|
|
2503
2515
|
});
|
|
2504
2516
|
}
|
|
2505
2517
|
function updateFetcherState(key, fetcher, opts) {
|
|
2518
|
+
if (opts === void 0) {
|
|
2519
|
+
opts = {};
|
|
2520
|
+
}
|
|
2506
2521
|
state.fetchers.set(key, fetcher);
|
|
2507
2522
|
updateState({
|
|
2508
2523
|
fetchers: new Map(state.fetchers)
|
|
2509
2524
|
}, {
|
|
2510
|
-
flushSync: opts.flushSync
|
|
2525
|
+
flushSync: (opts && opts.flushSync) === true
|
|
2511
2526
|
});
|
|
2512
2527
|
}
|
|
2513
2528
|
function setFetcherError(key, routeId, error, opts) {
|
|
2529
|
+
if (opts === void 0) {
|
|
2530
|
+
opts = {};
|
|
2531
|
+
}
|
|
2514
2532
|
let boundaryMatch = findNearestBoundary(state.matches, routeId);
|
|
2515
2533
|
deleteFetcher(key);
|
|
2516
2534
|
updateState({
|
|
@@ -2519,7 +2537,7 @@ function createRouter(init) {
|
|
|
2519
2537
|
},
|
|
2520
2538
|
fetchers: new Map(state.fetchers)
|
|
2521
2539
|
}, {
|
|
2522
|
-
flushSync: opts.flushSync
|
|
2540
|
+
flushSync: (opts && opts.flushSync) === true
|
|
2523
2541
|
});
|
|
2524
2542
|
}
|
|
2525
2543
|
function getFetcher(key) {
|
|
@@ -2561,8 +2579,6 @@ function createRouter(init) {
|
|
|
2561
2579
|
}
|
|
2562
2580
|
updateState({
|
|
2563
2581
|
fetchers: new Map(state.fetchers)
|
|
2564
|
-
}, {
|
|
2565
|
-
flushSync: false
|
|
2566
2582
|
});
|
|
2567
2583
|
}
|
|
2568
2584
|
function abortFetcher(key) {
|
|
@@ -2630,8 +2646,6 @@ function createRouter(init) {
|
|
|
2630
2646
|
blockers.set(key, newBlocker);
|
|
2631
2647
|
updateState({
|
|
2632
2648
|
blockers
|
|
2633
|
-
}, {
|
|
2634
|
-
flushSync: false
|
|
2635
2649
|
});
|
|
2636
2650
|
}
|
|
2637
2651
|
function shouldBlockNavigation(_ref2) {
|
|
@@ -2695,8 +2709,6 @@ function createRouter(init) {
|
|
|
2695
2709
|
if (y != null) {
|
|
2696
2710
|
updateState({
|
|
2697
2711
|
restoreScrollPosition: y
|
|
2698
|
-
}, {
|
|
2699
|
-
flushSync: false
|
|
2700
2712
|
});
|
|
2701
2713
|
}
|
|
2702
2714
|
}
|
|
@@ -2737,6 +2749,9 @@ function createRouter(init) {
|
|
|
2737
2749
|
get basename() {
|
|
2738
2750
|
return basename;
|
|
2739
2751
|
},
|
|
2752
|
+
get future() {
|
|
2753
|
+
return future;
|
|
2754
|
+
},
|
|
2740
2755
|
get state() {
|
|
2741
2756
|
return state;
|
|
2742
2757
|
},
|
|
@@ -2810,10 +2825,10 @@ function createStaticHandler(routes, opts) {
|
|
|
2810
2825
|
* propagate that out and return the raw Response so the HTTP server can
|
|
2811
2826
|
* return it directly.
|
|
2812
2827
|
*/
|
|
2813
|
-
async function query(request,
|
|
2828
|
+
async function query(request, _temp3) {
|
|
2814
2829
|
let {
|
|
2815
2830
|
requestContext
|
|
2816
|
-
} =
|
|
2831
|
+
} = _temp3 === void 0 ? {} : _temp3;
|
|
2817
2832
|
let url = new URL(request.url);
|
|
2818
2833
|
let method = request.method;
|
|
2819
2834
|
let location = createLocation("", createPath(url), null, "default");
|
|
@@ -2896,11 +2911,11 @@ function createStaticHandler(routes, opts) {
|
|
|
2896
2911
|
* code. Examples here are 404 and 405 errors that occur prior to reaching
|
|
2897
2912
|
* any user-defined loaders.
|
|
2898
2913
|
*/
|
|
2899
|
-
async function queryRoute(request,
|
|
2914
|
+
async function queryRoute(request, _temp4) {
|
|
2900
2915
|
let {
|
|
2901
2916
|
routeId,
|
|
2902
2917
|
requestContext
|
|
2903
|
-
} =
|
|
2918
|
+
} = _temp4 === void 0 ? {} : _temp4;
|
|
2904
2919
|
let url = new URL(request.url);
|
|
2905
2920
|
let method = request.method;
|
|
2906
2921
|
let location = createLocation("", createPath(url), null, "default");
|
|
@@ -3167,11 +3182,9 @@ function isSubmissionNavigation(opts) {
|
|
|
3167
3182
|
function normalizeTo(location, matches, basename, prependBasename, to, fromRouteId, relative) {
|
|
3168
3183
|
let contextualMatches;
|
|
3169
3184
|
let activeRouteMatch;
|
|
3170
|
-
if (fromRouteId
|
|
3185
|
+
if (fromRouteId) {
|
|
3171
3186
|
// Grab matches up to the calling route so our route-relative logic is
|
|
3172
|
-
// relative to the correct source route
|
|
3173
|
-
// fromRouteId is ignored since that is always relative to the current
|
|
3174
|
-
// location path
|
|
3187
|
+
// relative to the correct source route
|
|
3175
3188
|
contextualMatches = [];
|
|
3176
3189
|
for (let match of matches) {
|
|
3177
3190
|
contextualMatches.push(match);
|
|
@@ -3185,7 +3198,7 @@ function normalizeTo(location, matches, basename, prependBasename, to, fromRoute
|
|
|
3185
3198
|
activeRouteMatch = matches[matches.length - 1];
|
|
3186
3199
|
}
|
|
3187
3200
|
// Resolve the relative path
|
|
3188
|
-
let path = resolveTo(to ? to : ".",
|
|
3201
|
+
let path = resolveTo(to ? to : ".", getResolveToMatches(contextualMatches), stripBasename(location.pathname, basename) || location.pathname, relative === "path");
|
|
3189
3202
|
// When `to` is not specified we inherit search/hash from the current
|
|
3190
3203
|
// location, unlike when to="." and we just inherit the path.
|
|
3191
3204
|
// See https://github.com/remix-run/remix/issues/927
|
|
@@ -3342,7 +3355,7 @@ function getLoaderMatchesUntilBoundary(matches, boundaryId) {
|
|
|
3342
3355
|
}
|
|
3343
3356
|
return boundaryMatches;
|
|
3344
3357
|
}
|
|
3345
|
-
function getMatchesToLoad(history, state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionData, pendingError) {
|
|
3358
|
+
function getMatchesToLoad(history, state, matches, submission, location, isInitialLoad, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionData, pendingError) {
|
|
3346
3359
|
let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined;
|
|
3347
3360
|
let currentUrl = history.createURL(state.location);
|
|
3348
3361
|
let nextUrl = history.createURL(location);
|
|
@@ -3350,6 +3363,11 @@ function getMatchesToLoad(history, state, matches, submission, location, isReval
|
|
|
3350
3363
|
let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;
|
|
3351
3364
|
let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);
|
|
3352
3365
|
let navigationMatches = boundaryMatches.filter((match, index) => {
|
|
3366
|
+
if (isInitialLoad) {
|
|
3367
|
+
// On initial hydration we don't do any shouldRevalidate stuff - we just
|
|
3368
|
+
// call the loaders that don't have hydration data
|
|
3369
|
+
return match.route.loader && state.loaderData[match.route.id] === undefined;
|
|
3370
|
+
}
|
|
3353
3371
|
if (match.route.lazy) {
|
|
3354
3372
|
// We haven't loaded this route yet so we don't know if it's got a loader!
|
|
3355
3373
|
return true;
|
|
@@ -3386,8 +3404,12 @@ function getMatchesToLoad(history, state, matches, submission, location, isReval
|
|
|
3386
3404
|
// Pick fetcher.loads that need to be revalidated
|
|
3387
3405
|
let revalidatingFetchers = [];
|
|
3388
3406
|
fetchLoadMatches.forEach((f, key) => {
|
|
3389
|
-
// Don't revalidate
|
|
3390
|
-
|
|
3407
|
+
// Don't revalidate:
|
|
3408
|
+
// - on initial load (shouldn't be any fetchers then anyway)
|
|
3409
|
+
// - if fetcher won't be present in the subsequent render
|
|
3410
|
+
// - no longer matches the URL (v7_fetcherPersist=false)
|
|
3411
|
+
// - was unmounted but persisted due to v7_fetcherPersist=true
|
|
3412
|
+
if (isInitialLoad || !matches.some(m => m.route.id === f.routeId) || deletedFetchers.has(key)) {
|
|
3391
3413
|
return;
|
|
3392
3414
|
}
|
|
3393
3415
|
let fetcherMatches = matchRoutes(routesToUse, f.path, basename);
|
|
@@ -3700,11 +3722,16 @@ async function callLoaderOrAction(type, request, match, matches, manifest, mapRo
|
|
|
3700
3722
|
// Utility method for creating the Request instances for loaders/actions during
|
|
3701
3723
|
// client-side navigations and fetches. During SSR we will always have a
|
|
3702
3724
|
// Request instance from the static handler (query/queryRoute)
|
|
3703
|
-
function createClientSideRequest(history, location, signal, submission) {
|
|
3725
|
+
function createClientSideRequest(history, location, signal, initial, submission) {
|
|
3704
3726
|
let url = history.createURL(stripHashFromPath(location)).toString();
|
|
3705
3727
|
let init = {
|
|
3706
3728
|
signal
|
|
3707
3729
|
};
|
|
3730
|
+
if (initial) {
|
|
3731
|
+
init.headers = {
|
|
3732
|
+
"X-Remix-Initial-Load": "yes"
|
|
3733
|
+
};
|
|
3734
|
+
}
|
|
3708
3735
|
if (submission && isMutationMethod(submission.formMethod)) {
|
|
3709
3736
|
let {
|
|
3710
3737
|
formMethod,
|
|
@@ -3903,13 +3930,13 @@ function getShortCircuitMatches(routes) {
|
|
|
3903
3930
|
route
|
|
3904
3931
|
};
|
|
3905
3932
|
}
|
|
3906
|
-
function getInternalRouterError(status,
|
|
3933
|
+
function getInternalRouterError(status, _temp5) {
|
|
3907
3934
|
let {
|
|
3908
3935
|
pathname,
|
|
3909
3936
|
routeId,
|
|
3910
3937
|
method,
|
|
3911
3938
|
type
|
|
3912
|
-
} =
|
|
3939
|
+
} = _temp5 === void 0 ? {} : _temp5;
|
|
3913
3940
|
let statusText = "Unknown Server Error";
|
|
3914
3941
|
let errorMessage = "Unknown @remix-run/router error";
|
|
3915
3942
|
if (status === 400) {
|
|
@@ -4237,5 +4264,5 @@ function persistAppliedTransitions(_window, transitions) {
|
|
|
4237
4264
|
}
|
|
4238
4265
|
//#endregion
|
|
4239
4266
|
|
|
4240
|
-
export { AbortedDeferredError, Action, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, UNSAFE_DEFERRED_SYMBOL, DeferredData as UNSAFE_DeferredData, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, convertRouteMatchToUiMatch as UNSAFE_convertRouteMatchToUiMatch, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes,
|
|
4267
|
+
export { AbortedDeferredError, Action, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, UNSAFE_DEFERRED_SYMBOL, DeferredData as UNSAFE_DeferredData, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, convertRouteMatchToUiMatch as UNSAFE_convertRouteMatchToUiMatch, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, getResolveToMatches as UNSAFE_getResolveToMatches, invariant as UNSAFE_invariant, warning as UNSAFE_warning, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, createRouter, createStaticHandler, defer, generatePath, getStaticContextFromError, getToPathname, isDeferredData, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, parsePath, redirect, redirectDocument, resolvePath, resolveTo, stripBasename };
|
|
4241
4268
|
//# sourceMappingURL=router.js.map
|