@remix-run/router 1.0.2 → 1.0.3-pre.1
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 +22 -2
- package/dist/history.d.ts +9 -0
- package/dist/index.d.ts +2 -2
- package/dist/router.cjs.js +340 -169
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.js +340 -170
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +3425 -0
- package/dist/router.umd.js.map +1 -0
- package/dist/router.umd.min.js +12 -0
- package/dist/router.umd.min.js.map +1 -0
- package/dist/utils.d.ts +24 -0
- package/history.ts +38 -2
- package/index.ts +5 -2
- package/package.json +2 -1
- package/router.ts +372 -171
- package/utils.ts +57 -1
package/dist/router.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.0.
|
|
2
|
+
* @remix-run/router v1.0.3-pre.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -116,6 +116,10 @@ function createMemoryHistory(options) {
|
|
|
116
116
|
return typeof to === "string" ? to : createPath(to);
|
|
117
117
|
},
|
|
118
118
|
|
|
119
|
+
encodeLocation(location) {
|
|
120
|
+
return location;
|
|
121
|
+
},
|
|
122
|
+
|
|
119
123
|
push(to, state) {
|
|
120
124
|
action = Action.Push;
|
|
121
125
|
let nextLocation = createMemoryLocation(to, state);
|
|
@@ -347,6 +351,14 @@ function parsePath(path) {
|
|
|
347
351
|
|
|
348
352
|
return parsedPath;
|
|
349
353
|
}
|
|
354
|
+
function createURL(location) {
|
|
355
|
+
// window.location.origin is "null" (the literal string value) in Firefox
|
|
356
|
+
// under certain conditions, notably when serving from a local HTML file
|
|
357
|
+
// See https://bugzilla.mozilla.org/show_bug.cgi?id=878297
|
|
358
|
+
let base = typeof window !== "undefined" && typeof window.location !== "undefined" && window.location.origin !== "null" ? window.location.origin : "unknown://unknown";
|
|
359
|
+
let href = typeof location === "string" ? location : createPath(location);
|
|
360
|
+
return new URL(href, base);
|
|
361
|
+
}
|
|
350
362
|
|
|
351
363
|
function getUrlBasedHistory(getLocation, createHref, validateLocation, options) {
|
|
352
364
|
if (options === void 0) {
|
|
@@ -390,7 +402,7 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
|
|
|
390
402
|
if (v5Compat && listener) {
|
|
391
403
|
listener({
|
|
392
404
|
action,
|
|
393
|
-
location
|
|
405
|
+
location: history.location
|
|
394
406
|
});
|
|
395
407
|
}
|
|
396
408
|
}
|
|
@@ -406,7 +418,7 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
|
|
|
406
418
|
if (v5Compat && listener) {
|
|
407
419
|
listener({
|
|
408
420
|
action,
|
|
409
|
-
location: location
|
|
421
|
+
location: history.location
|
|
410
422
|
});
|
|
411
423
|
}
|
|
412
424
|
}
|
|
@@ -437,6 +449,16 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
|
|
|
437
449
|
return createHref(window, to);
|
|
438
450
|
},
|
|
439
451
|
|
|
452
|
+
encodeLocation(location) {
|
|
453
|
+
// Encode a Location the same way window.location would
|
|
454
|
+
let url = createURL(createPath(location));
|
|
455
|
+
return _extends({}, location, {
|
|
456
|
+
pathname: url.pathname,
|
|
457
|
+
search: url.search,
|
|
458
|
+
hash: url.hash
|
|
459
|
+
});
|
|
460
|
+
},
|
|
461
|
+
|
|
440
462
|
push,
|
|
441
463
|
replace,
|
|
442
464
|
|
|
@@ -518,7 +540,13 @@ function matchRoutes(routes, locationArg, basename) {
|
|
|
518
540
|
let matches = null;
|
|
519
541
|
|
|
520
542
|
for (let i = 0; matches == null && i < branches.length; ++i) {
|
|
521
|
-
matches = matchRouteBranch(branches[i],
|
|
543
|
+
matches = matchRouteBranch(branches[i], // Incoming pathnames are generally encoded from either window.location
|
|
544
|
+
// or from router.navigate, but we want to match against the unencoded
|
|
545
|
+
// paths in the route definitions. Memory router locations won't be
|
|
546
|
+
// encoded here but there also shouldn't be anything to decode so this
|
|
547
|
+
// should be a safe operation. This avoids needing matchRoutes to be
|
|
548
|
+
// history-aware.
|
|
549
|
+
safelyDecodeURI(pathname));
|
|
522
550
|
}
|
|
523
551
|
|
|
524
552
|
return matches;
|
|
@@ -762,6 +790,15 @@ function compilePath(path, caseSensitive, end) {
|
|
|
762
790
|
return [matcher, paramNames];
|
|
763
791
|
}
|
|
764
792
|
|
|
793
|
+
function safelyDecodeURI(value) {
|
|
794
|
+
try {
|
|
795
|
+
return decodeURI(value);
|
|
796
|
+
} catch (error) {
|
|
797
|
+
warning(false, "The URL path \"" + value + "\" could not be decoded because it is is a " + "malformed URL segment. This is probably due to a bad percent " + ("encoding (" + error + ")."));
|
|
798
|
+
return value;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
765
802
|
function safelyDecodeURIComponent(value, paramName) {
|
|
766
803
|
try {
|
|
767
804
|
return decodeURIComponent(value);
|
|
@@ -861,9 +898,36 @@ function getInvalidPathError(char, field, dest, path) {
|
|
|
861
898
|
}
|
|
862
899
|
/**
|
|
863
900
|
* @private
|
|
901
|
+
*
|
|
902
|
+
* When processing relative navigation we want to ignore ancestor routes that
|
|
903
|
+
* do not contribute to the path, such that index/pathless layout routes don't
|
|
904
|
+
* interfere.
|
|
905
|
+
*
|
|
906
|
+
* For example, when moving a route element into an index route and/or a
|
|
907
|
+
* pathless layout route, relative link behavior contained within should stay
|
|
908
|
+
* the same. Both of the following examples should link back to the root:
|
|
909
|
+
*
|
|
910
|
+
* <Route path="/">
|
|
911
|
+
* <Route path="accounts" element={<Link to=".."}>
|
|
912
|
+
* </Route>
|
|
913
|
+
*
|
|
914
|
+
* <Route path="/">
|
|
915
|
+
* <Route path="accounts">
|
|
916
|
+
* <Route element={<AccountsLayout />}> // <-- Does not contribute
|
|
917
|
+
* <Route index element={<Link to=".."} /> // <-- Does not contribute
|
|
918
|
+
* </Route
|
|
919
|
+
* </Route>
|
|
920
|
+
* </Route>
|
|
864
921
|
*/
|
|
865
922
|
|
|
866
923
|
|
|
924
|
+
function getPathContributingMatches(matches) {
|
|
925
|
+
return matches.filter((match, index) => index === 0 || match.route.path && match.route.path.length > 0);
|
|
926
|
+
}
|
|
927
|
+
/**
|
|
928
|
+
* @private
|
|
929
|
+
*/
|
|
930
|
+
|
|
867
931
|
function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {
|
|
868
932
|
if (isPathRelative === void 0) {
|
|
869
933
|
isPathRelative = false;
|
|
@@ -1184,7 +1248,9 @@ const IDLE_FETCHER = {
|
|
|
1184
1248
|
formAction: undefined,
|
|
1185
1249
|
formEncType: undefined,
|
|
1186
1250
|
formData: undefined
|
|
1187
|
-
};
|
|
1251
|
+
};
|
|
1252
|
+
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
1253
|
+
const isServer = !isBrowser; //#endregion
|
|
1188
1254
|
////////////////////////////////////////////////////////////////////////////////
|
|
1189
1255
|
//#region createRouter
|
|
1190
1256
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -1391,7 +1457,13 @@ function createRouter(init) {
|
|
|
1391
1457
|
submission,
|
|
1392
1458
|
error
|
|
1393
1459
|
} = normalizeNavigateOptions(to, opts);
|
|
1394
|
-
let location = createLocation(state.location, path, opts && opts.state);
|
|
1460
|
+
let location = createLocation(state.location, path, opts && opts.state); // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded
|
|
1461
|
+
// URL from window.location, so we need to encode it here so the behavior
|
|
1462
|
+
// remains the same as POP and non-data-router usages. new URL() does all
|
|
1463
|
+
// the same encoding we'd get from a history.pushState/window.location read
|
|
1464
|
+
// without having to touch history
|
|
1465
|
+
|
|
1466
|
+
location = init.history.encodeLocation(location);
|
|
1395
1467
|
let historyAction = (opts && opts.replace) === true || submission != null ? Action.Replace : Action.Push;
|
|
1396
1468
|
let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined;
|
|
1397
1469
|
return await startNavigation(historyAction, location, {
|
|
@@ -1557,7 +1629,7 @@ function createRouter(init) {
|
|
|
1557
1629
|
if (!actionMatch.route.action) {
|
|
1558
1630
|
result = getMethodNotAllowedResult(location);
|
|
1559
1631
|
} else {
|
|
1560
|
-
result = await callLoaderOrAction("action", request, actionMatch);
|
|
1632
|
+
result = await callLoaderOrAction("action", request, actionMatch, matches, router.basename);
|
|
1561
1633
|
|
|
1562
1634
|
if (request.signal.aborted) {
|
|
1563
1635
|
return {
|
|
@@ -1652,7 +1724,7 @@ function createRouter(init) {
|
|
|
1652
1724
|
if (!isUninterruptedRevalidation) {
|
|
1653
1725
|
revalidatingFetchers.forEach(_ref2 => {
|
|
1654
1726
|
let [key] = _ref2;
|
|
1655
|
-
|
|
1727
|
+
let fetcher = state.fetchers.get(key);
|
|
1656
1728
|
let revalidatingFetcher = {
|
|
1657
1729
|
state: "loading",
|
|
1658
1730
|
data: fetcher && fetcher.data,
|
|
@@ -1680,7 +1752,7 @@ function createRouter(init) {
|
|
|
1680
1752
|
results,
|
|
1681
1753
|
loaderResults,
|
|
1682
1754
|
fetcherResults
|
|
1683
|
-
} = await callLoadersAndMaybeResolveData(state.matches, matchesToLoad, revalidatingFetchers, request);
|
|
1755
|
+
} = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, request);
|
|
1684
1756
|
|
|
1685
1757
|
if (request.signal.aborted) {
|
|
1686
1758
|
return {
|
|
@@ -1738,7 +1810,7 @@ function createRouter(init) {
|
|
|
1738
1810
|
|
|
1739
1811
|
|
|
1740
1812
|
function fetch(key, routeId, href, opts) {
|
|
1741
|
-
if (
|
|
1813
|
+
if (isServer) {
|
|
1742
1814
|
throw new Error("router.fetch() was called during the server render, but it shouldn't be. " + "You are likely calling a useFetcher() method in the body of your component. " + "Try moving it to a useEffect or a callback.");
|
|
1743
1815
|
}
|
|
1744
1816
|
|
|
@@ -1757,19 +1829,19 @@ function createRouter(init) {
|
|
|
1757
1829
|
let match = getTargetMatch(matches, path);
|
|
1758
1830
|
|
|
1759
1831
|
if (submission) {
|
|
1760
|
-
handleFetcherAction(key, routeId, path, match, submission);
|
|
1832
|
+
handleFetcherAction(key, routeId, path, match, matches, submission);
|
|
1761
1833
|
return;
|
|
1762
1834
|
} // Store off the match so we can call it's shouldRevalidate on subsequent
|
|
1763
1835
|
// revalidations
|
|
1764
1836
|
|
|
1765
1837
|
|
|
1766
|
-
fetchLoadMatches.set(key, [path, match]);
|
|
1767
|
-
handleFetcherLoader(key, routeId, path, match);
|
|
1838
|
+
fetchLoadMatches.set(key, [path, match, matches]);
|
|
1839
|
+
handleFetcherLoader(key, routeId, path, match, matches);
|
|
1768
1840
|
} // Call the action for the matched fetcher.submit(), and then handle redirects,
|
|
1769
1841
|
// errors, and revalidation
|
|
1770
1842
|
|
|
1771
1843
|
|
|
1772
|
-
async function handleFetcherAction(key, routeId, path, match, submission) {
|
|
1844
|
+
async function handleFetcherAction(key, routeId, path, match, requestMatches, submission) {
|
|
1773
1845
|
interruptActiveLoads();
|
|
1774
1846
|
fetchLoadMatches.delete(key);
|
|
1775
1847
|
|
|
@@ -1798,7 +1870,7 @@ function createRouter(init) {
|
|
|
1798
1870
|
let abortController = new AbortController();
|
|
1799
1871
|
let fetchRequest = createRequest(path, abortController.signal, submission);
|
|
1800
1872
|
fetchControllers.set(key, abortController);
|
|
1801
|
-
let actionResult = await callLoaderOrAction("action", fetchRequest, match);
|
|
1873
|
+
let actionResult = await callLoaderOrAction("action", fetchRequest, match, requestMatches, router.basename);
|
|
1802
1874
|
|
|
1803
1875
|
if (fetchRequest.signal.aborted) {
|
|
1804
1876
|
// We can delete this so long as we weren't aborted by ou our own fetcher
|
|
@@ -1890,7 +1962,7 @@ function createRouter(init) {
|
|
|
1890
1962
|
results,
|
|
1891
1963
|
loaderResults,
|
|
1892
1964
|
fetcherResults
|
|
1893
|
-
} = await callLoadersAndMaybeResolveData(state.matches, matchesToLoad, revalidatingFetchers, revalidationRequest);
|
|
1965
|
+
} = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, revalidationRequest);
|
|
1894
1966
|
|
|
1895
1967
|
if (abortController.signal.aborted) {
|
|
1896
1968
|
return;
|
|
@@ -1952,7 +2024,7 @@ function createRouter(init) {
|
|
|
1952
2024
|
} // Call the matched loader for fetcher.load(), handling redirects, errors, etc.
|
|
1953
2025
|
|
|
1954
2026
|
|
|
1955
|
-
async function handleFetcherLoader(key, routeId, path, match) {
|
|
2027
|
+
async function handleFetcherLoader(key, routeId, path, match, matches) {
|
|
1956
2028
|
let existingFetcher = state.fetchers.get(key); // Put this fetcher into it's loading state
|
|
1957
2029
|
|
|
1958
2030
|
let loadingFetcher = {
|
|
@@ -1971,7 +2043,7 @@ function createRouter(init) {
|
|
|
1971
2043
|
let abortController = new AbortController();
|
|
1972
2044
|
let fetchRequest = createRequest(path, abortController.signal);
|
|
1973
2045
|
fetchControllers.set(key, abortController);
|
|
1974
|
-
let result = await callLoaderOrAction("loader", fetchRequest, match); // Deferred isn't supported or fetcher loads, await everything and treat it
|
|
2046
|
+
let result = await callLoaderOrAction("loader", fetchRequest, match, matches, router.basename); // Deferred isn't supported or fetcher loads, await everything and treat it
|
|
1975
2047
|
// as a normal load. resolveDeferredData will return undefined if this
|
|
1976
2048
|
// fetcher gets aborted, so we just leave result untouched and short circuit
|
|
1977
2049
|
// below if that happens
|
|
@@ -2064,13 +2136,13 @@ function createRouter(init) {
|
|
|
2064
2136
|
});
|
|
2065
2137
|
}
|
|
2066
2138
|
|
|
2067
|
-
async function callLoadersAndMaybeResolveData(currentMatches, matchesToLoad, fetchersToLoad, request) {
|
|
2139
|
+
async function callLoadersAndMaybeResolveData(currentMatches, matches, matchesToLoad, fetchersToLoad, request) {
|
|
2068
2140
|
// Call all navigation loaders and revalidating fetcher loaders in parallel,
|
|
2069
2141
|
// then slice off the results into separate arrays so we can handle them
|
|
2070
2142
|
// accordingly
|
|
2071
|
-
let results = await Promise.all([...matchesToLoad.map(
|
|
2072
|
-
let [, href, match] = _ref8;
|
|
2073
|
-
return callLoaderOrAction("loader", createRequest(href, request.signal), match);
|
|
2143
|
+
let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(_ref8 => {
|
|
2144
|
+
let [, href, match, fetchMatches] = _ref8;
|
|
2145
|
+
return callLoaderOrAction("loader", createRequest(href, request.signal), match, fetchMatches, router.basename);
|
|
2074
2146
|
})]);
|
|
2075
2147
|
let loaderResults = results.slice(0, matchesToLoad.length);
|
|
2076
2148
|
let fetcherResults = results.slice(matchesToLoad.length);
|
|
@@ -2262,7 +2334,9 @@ function createRouter(init) {
|
|
|
2262
2334
|
navigate,
|
|
2263
2335
|
fetch,
|
|
2264
2336
|
revalidate,
|
|
2265
|
-
createHref
|
|
2337
|
+
// Passthrough to history-aware createHref used by useHref so we get proper
|
|
2338
|
+
// hash-aware URLs in DOM paths
|
|
2339
|
+
createHref: to => init.history.createHref(to),
|
|
2266
2340
|
getFetcher,
|
|
2267
2341
|
deleteFetcher,
|
|
2268
2342
|
dispose,
|
|
@@ -2275,15 +2349,75 @@ function createRouter(init) {
|
|
|
2275
2349
|
//#region createStaticHandler
|
|
2276
2350
|
////////////////////////////////////////////////////////////////////////////////
|
|
2277
2351
|
|
|
2352
|
+
const validActionMethods = new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
2353
|
+
const validRequestMethods = new Set(["GET", "HEAD", ...validActionMethods]);
|
|
2278
2354
|
function unstable_createStaticHandler(routes) {
|
|
2279
2355
|
invariant(routes.length > 0, "You must provide a non-empty routes array to unstable_createStaticHandler");
|
|
2280
2356
|
let dataRoutes = convertRoutesToDataRoutes(routes);
|
|
2357
|
+
/**
|
|
2358
|
+
* The query() method is intended for document requests, in which we want to
|
|
2359
|
+
* call an optional action and potentially multiple loaders for all nested
|
|
2360
|
+
* routes. It returns a StaticHandlerContext object, which is very similar
|
|
2361
|
+
* to the router state (location, loaderData, actionData, errors, etc.) and
|
|
2362
|
+
* also adds SSR-specific information such as the statusCode and headers
|
|
2363
|
+
* from action/loaders Responses.
|
|
2364
|
+
*
|
|
2365
|
+
* It _should_ never throw and should report all errors through the
|
|
2366
|
+
* returned context.errors object, properly associating errors to their error
|
|
2367
|
+
* boundary. Additionally, it tracks _deepestRenderedBoundaryId which can be
|
|
2368
|
+
* used to emulate React error boundaries during SSr by performing a second
|
|
2369
|
+
* pass only down to the boundaryId.
|
|
2370
|
+
*
|
|
2371
|
+
* The one exception where we do not return a StaticHandlerContext is when a
|
|
2372
|
+
* redirect response is returned or thrown from any action/loader. We
|
|
2373
|
+
* propagate that out and return the raw Response so the HTTP server can
|
|
2374
|
+
* return it directly.
|
|
2375
|
+
*/
|
|
2281
2376
|
|
|
2282
2377
|
async function query(request) {
|
|
2283
|
-
let
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2378
|
+
let url = new URL(request.url);
|
|
2379
|
+
let location = createLocation("", createPath(url), null, "default");
|
|
2380
|
+
let matches = matchRoutes(dataRoutes, location);
|
|
2381
|
+
|
|
2382
|
+
if (!validRequestMethods.has(request.method)) {
|
|
2383
|
+
let {
|
|
2384
|
+
matches: methodNotAllowedMatches,
|
|
2385
|
+
route,
|
|
2386
|
+
error
|
|
2387
|
+
} = getMethodNotAllowedMatches(dataRoutes);
|
|
2388
|
+
return {
|
|
2389
|
+
location,
|
|
2390
|
+
matches: methodNotAllowedMatches,
|
|
2391
|
+
loaderData: {},
|
|
2392
|
+
actionData: null,
|
|
2393
|
+
errors: {
|
|
2394
|
+
[route.id]: error
|
|
2395
|
+
},
|
|
2396
|
+
statusCode: error.status,
|
|
2397
|
+
loaderHeaders: {},
|
|
2398
|
+
actionHeaders: {}
|
|
2399
|
+
};
|
|
2400
|
+
} else if (!matches) {
|
|
2401
|
+
let {
|
|
2402
|
+
matches: notFoundMatches,
|
|
2403
|
+
route,
|
|
2404
|
+
error
|
|
2405
|
+
} = getNotFoundMatches(dataRoutes);
|
|
2406
|
+
return {
|
|
2407
|
+
location,
|
|
2408
|
+
matches: notFoundMatches,
|
|
2409
|
+
loaderData: {},
|
|
2410
|
+
actionData: null,
|
|
2411
|
+
errors: {
|
|
2412
|
+
[route.id]: error
|
|
2413
|
+
},
|
|
2414
|
+
statusCode: error.status,
|
|
2415
|
+
loaderHeaders: {},
|
|
2416
|
+
actionHeaders: {}
|
|
2417
|
+
};
|
|
2418
|
+
}
|
|
2419
|
+
|
|
2420
|
+
let result = await queryImpl(request, location, matches);
|
|
2287
2421
|
|
|
2288
2422
|
if (result instanceof Response) {
|
|
2289
2423
|
return result;
|
|
@@ -2296,11 +2430,52 @@ function unstable_createStaticHandler(routes) {
|
|
|
2296
2430
|
location
|
|
2297
2431
|
}, result);
|
|
2298
2432
|
}
|
|
2433
|
+
/**
|
|
2434
|
+
* The queryRoute() method is intended for targeted route requests, either
|
|
2435
|
+
* for fetch ?_data requests or resource route requests. In this case, we
|
|
2436
|
+
* are only ever calling a single action or loader, and we are returning the
|
|
2437
|
+
* returned value directly. In most cases, this will be a Response returned
|
|
2438
|
+
* from the action/loader, but it may be a primitive or other value as well -
|
|
2439
|
+
* and in such cases the calling context should handle that accordingly.
|
|
2440
|
+
*
|
|
2441
|
+
* We do respect the throw/return differentiation, so if an action/loader
|
|
2442
|
+
* throws, then this method will throw the value. This is important so we
|
|
2443
|
+
* can do proper boundary identification in Remix where a thrown Response
|
|
2444
|
+
* must go to the Catch Boundary but a returned Response is happy-path.
|
|
2445
|
+
*
|
|
2446
|
+
* One thing to note is that any Router-initiated thrown Response (such as a
|
|
2447
|
+
* 404 or 405) will have a custom X-Remix-Router-Error: "yes" header on it
|
|
2448
|
+
* in order to differentiate from responses thrown from user actions/loaders.
|
|
2449
|
+
*/
|
|
2450
|
+
|
|
2299
2451
|
|
|
2300
2452
|
async function queryRoute(request, routeId) {
|
|
2301
|
-
let
|
|
2302
|
-
|
|
2303
|
-
|
|
2453
|
+
let url = new URL(request.url);
|
|
2454
|
+
let location = createLocation("", createPath(url), null, "default");
|
|
2455
|
+
let matches = matchRoutes(dataRoutes, location);
|
|
2456
|
+
|
|
2457
|
+
if (!validRequestMethods.has(request.method)) {
|
|
2458
|
+
throw createRouterErrorResponse(null, {
|
|
2459
|
+
status: 405,
|
|
2460
|
+
statusText: "Method Not Allowed"
|
|
2461
|
+
});
|
|
2462
|
+
} else if (!matches) {
|
|
2463
|
+
throw createRouterErrorResponse(null, {
|
|
2464
|
+
status: 404,
|
|
2465
|
+
statusText: "Not Found"
|
|
2466
|
+
});
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
let match = routeId ? matches.find(m => m.route.id === routeId) : getTargetMatch(matches, location);
|
|
2470
|
+
|
|
2471
|
+
if (!match) {
|
|
2472
|
+
throw createRouterErrorResponse(null, {
|
|
2473
|
+
status: 404,
|
|
2474
|
+
statusText: "Not Found"
|
|
2475
|
+
});
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
let result = await queryImpl(request, location, matches, match);
|
|
2304
2479
|
|
|
2305
2480
|
if (result instanceof Response) {
|
|
2306
2481
|
return result;
|
|
@@ -2309,77 +2484,48 @@ function unstable_createStaticHandler(routes) {
|
|
|
2309
2484
|
let error = result.errors ? Object.values(result.errors)[0] : undefined;
|
|
2310
2485
|
|
|
2311
2486
|
if (error !== undefined) {
|
|
2312
|
-
//
|
|
2313
|
-
// directly for route requests and prevent the unwrapping into an
|
|
2314
|
-
// ErrorResponse, we still need this for error cases _prior_ the
|
|
2315
|
-
// execution of the loader/action, such as a 404/405 error.
|
|
2316
|
-
if (isRouteErrorResponse(error)) {
|
|
2317
|
-
return new Response(error.data, {
|
|
2318
|
-
status: error.status,
|
|
2319
|
-
statusText: error.statusText
|
|
2320
|
-
});
|
|
2321
|
-
} // If we got back result.errors, that means the loader/action threw
|
|
2487
|
+
// If we got back result.errors, that means the loader/action threw
|
|
2322
2488
|
// _something_ that wasn't a Response, but it's not guaranteed/required
|
|
2323
2489
|
// to be an `instanceof Error` either, so we have to use throw here to
|
|
2324
2490
|
// preserve the "error" state outside of queryImpl.
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
2491
|
throw error;
|
|
2328
2492
|
} // Pick off the right state value to return
|
|
2329
2493
|
|
|
2330
2494
|
|
|
2331
2495
|
let routeData = [result.actionData, result.loaderData].find(v => v);
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
if (isRouteErrorResponse(value)) {
|
|
2335
|
-
return new Response(value.data, {
|
|
2336
|
-
status: value.status,
|
|
2337
|
-
statusText: value.statusText
|
|
2338
|
-
});
|
|
2339
|
-
}
|
|
2340
|
-
|
|
2341
|
-
return value;
|
|
2496
|
+
return Object.values(routeData || {})[0];
|
|
2342
2497
|
}
|
|
2343
2498
|
|
|
2344
|
-
async function queryImpl(request,
|
|
2345
|
-
invariant(request.method !== "HEAD", "query()/queryRoute() do not support HEAD requests");
|
|
2499
|
+
async function queryImpl(request, location, matches, routeMatch) {
|
|
2346
2500
|
invariant(request.signal, "query()/queryRoute() requests must contain an AbortController signal");
|
|
2347
|
-
let {
|
|
2348
|
-
location,
|
|
2349
|
-
matches,
|
|
2350
|
-
shortCircuitState
|
|
2351
|
-
} = matchRequest(request, routeId);
|
|
2352
2501
|
|
|
2353
2502
|
try {
|
|
2354
|
-
if (
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
result: shortCircuitState
|
|
2358
|
-
};
|
|
2503
|
+
if (validActionMethods.has(request.method)) {
|
|
2504
|
+
let result = await submit(request, matches, routeMatch || getTargetMatch(matches, location), routeMatch != null);
|
|
2505
|
+
return result;
|
|
2359
2506
|
}
|
|
2360
2507
|
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
};
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2369
|
-
let result = await loadRouteData(request, matches, routeId != null);
|
|
2370
|
-
return {
|
|
2371
|
-
location,
|
|
2372
|
-
result: _extends({}, result, {
|
|
2373
|
-
actionData: null,
|
|
2374
|
-
actionHeaders: {}
|
|
2375
|
-
})
|
|
2376
|
-
};
|
|
2508
|
+
let result = await loadRouteData(request, matches, routeMatch);
|
|
2509
|
+
return result instanceof Response ? result : _extends({}, result, {
|
|
2510
|
+
actionData: null,
|
|
2511
|
+
actionHeaders: {}
|
|
2512
|
+
});
|
|
2377
2513
|
} catch (e) {
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2514
|
+
// If the user threw/returned a Response in callLoaderOrAction, we throw
|
|
2515
|
+
// it to bail out and then return or throw here based on whether the user
|
|
2516
|
+
// returned or threw
|
|
2517
|
+
if (isQueryRouteResponse(e)) {
|
|
2518
|
+
if (e.type === ResultType.error && !isRedirectResponse(e.response)) {
|
|
2519
|
+
throw e.response;
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2522
|
+
return e.response;
|
|
2523
|
+
} // Redirects are always returned since they don't propagate to catch
|
|
2524
|
+
// boundaries
|
|
2525
|
+
|
|
2526
|
+
|
|
2527
|
+
if (isRedirectResponse(e)) {
|
|
2528
|
+
return e;
|
|
2383
2529
|
}
|
|
2384
2530
|
|
|
2385
2531
|
throw e;
|
|
@@ -2390,10 +2536,17 @@ function unstable_createStaticHandler(routes) {
|
|
|
2390
2536
|
let result;
|
|
2391
2537
|
|
|
2392
2538
|
if (!actionMatch.route.action) {
|
|
2393
|
-
|
|
2394
|
-
|
|
2539
|
+
if (isRouteRequest) {
|
|
2540
|
+
throw createRouterErrorResponse(null, {
|
|
2541
|
+
status: 405,
|
|
2542
|
+
statusText: "Method Not Allowed"
|
|
2543
|
+
});
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
result = getMethodNotAllowedResult(request.url);
|
|
2395
2547
|
} else {
|
|
2396
|
-
result = await callLoaderOrAction("action", request, actionMatch,
|
|
2548
|
+
result = await callLoaderOrAction("action", request, actionMatch, matches, undefined, // Basename not currently supported in static handlers
|
|
2549
|
+
true, isRouteRequest);
|
|
2397
2550
|
|
|
2398
2551
|
if (request.signal.aborted) {
|
|
2399
2552
|
let method = isRouteRequest ? "queryRoute" : "query";
|
|
@@ -2403,7 +2556,7 @@ function unstable_createStaticHandler(routes) {
|
|
|
2403
2556
|
|
|
2404
2557
|
if (isRedirectResult(result)) {
|
|
2405
2558
|
// Uhhhh - this should never happen, we should always throw these from
|
|
2406
|
-
//
|
|
2559
|
+
// callLoaderOrAction, but the type narrowing here keeps TS happy and we
|
|
2407
2560
|
// can get back on the "throw all redirect responses" train here should
|
|
2408
2561
|
// this ever happen :/
|
|
2409
2562
|
throw new Response(null, {
|
|
@@ -2419,6 +2572,8 @@ function unstable_createStaticHandler(routes) {
|
|
|
2419
2572
|
}
|
|
2420
2573
|
|
|
2421
2574
|
if (isRouteRequest) {
|
|
2575
|
+
// Note: This should only be non-Response values if we get here, since
|
|
2576
|
+
// isRouteRequest should throw any Response received in callLoaderOrAction
|
|
2422
2577
|
if (isErrorResult(result)) {
|
|
2423
2578
|
let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);
|
|
2424
2579
|
return {
|
|
@@ -2455,7 +2610,7 @@ function unstable_createStaticHandler(routes) {
|
|
|
2455
2610
|
// Store off the pending error - we use it to determine which loaders
|
|
2456
2611
|
// to call and will commit it when we complete the navigation
|
|
2457
2612
|
let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);
|
|
2458
|
-
let context = await loadRouteData(request, matches,
|
|
2613
|
+
let context = await loadRouteData(request, matches, undefined, {
|
|
2459
2614
|
[boundaryMatch.route.id]: result.error
|
|
2460
2615
|
}); // action status codes take precedence over loader status codes
|
|
2461
2616
|
|
|
@@ -2468,7 +2623,7 @@ function unstable_createStaticHandler(routes) {
|
|
|
2468
2623
|
});
|
|
2469
2624
|
}
|
|
2470
2625
|
|
|
2471
|
-
let context = await loadRouteData(request, matches
|
|
2626
|
+
let context = await loadRouteData(request, matches);
|
|
2472
2627
|
return _extends({}, context, result.statusCode ? {
|
|
2473
2628
|
statusCode: result.statusCode
|
|
2474
2629
|
} : {}, {
|
|
@@ -2481,8 +2636,10 @@ function unstable_createStaticHandler(routes) {
|
|
|
2481
2636
|
});
|
|
2482
2637
|
}
|
|
2483
2638
|
|
|
2484
|
-
async function loadRouteData(request, matches,
|
|
2485
|
-
let
|
|
2639
|
+
async function loadRouteData(request, matches, routeMatch, pendingActionError) {
|
|
2640
|
+
let isRouteRequest = routeMatch != null;
|
|
2641
|
+
let requestMatches = routeMatch ? [routeMatch] : getLoaderMatchesUntilBoundary(matches, Object.keys(pendingActionError || {})[0]);
|
|
2642
|
+
let matchesToLoad = requestMatches.filter(m => m.route.loader); // Short circuit if we have no loaders to run
|
|
2486
2643
|
|
|
2487
2644
|
if (matchesToLoad.length === 0) {
|
|
2488
2645
|
return {
|
|
@@ -2494,7 +2651,8 @@ function unstable_createStaticHandler(routes) {
|
|
|
2494
2651
|
};
|
|
2495
2652
|
}
|
|
2496
2653
|
|
|
2497
|
-
let results = await Promise.all([...matchesToLoad.map(
|
|
2654
|
+
let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, undefined, // Basename not currently supported in static handlers
|
|
2655
|
+
true, isRouteRequest))]);
|
|
2498
2656
|
|
|
2499
2657
|
if (request.signal.aborted) {
|
|
2500
2658
|
let method = isRouteRequest ? "queryRoute" : "query";
|
|
@@ -2515,43 +2673,12 @@ function unstable_createStaticHandler(routes) {
|
|
|
2515
2673
|
});
|
|
2516
2674
|
}
|
|
2517
2675
|
|
|
2518
|
-
function
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
matches = matches.filter(m => m.route.id === routeId);
|
|
2525
|
-
} // Short circuit with a 404 if we match nothing
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
if (!matches) {
|
|
2529
|
-
let {
|
|
2530
|
-
matches: notFoundMatches,
|
|
2531
|
-
route,
|
|
2532
|
-
error
|
|
2533
|
-
} = getNotFoundMatches(dataRoutes);
|
|
2534
|
-
return {
|
|
2535
|
-
location,
|
|
2536
|
-
matches: notFoundMatches,
|
|
2537
|
-
shortCircuitState: {
|
|
2538
|
-
matches: notFoundMatches,
|
|
2539
|
-
loaderData: {},
|
|
2540
|
-
actionData: null,
|
|
2541
|
-
errors: {
|
|
2542
|
-
[route.id]: error
|
|
2543
|
-
},
|
|
2544
|
-
statusCode: 404,
|
|
2545
|
-
loaderHeaders: {},
|
|
2546
|
-
actionHeaders: {}
|
|
2547
|
-
}
|
|
2548
|
-
};
|
|
2549
|
-
}
|
|
2550
|
-
|
|
2551
|
-
return {
|
|
2552
|
-
location,
|
|
2553
|
-
matches
|
|
2554
|
-
};
|
|
2676
|
+
function createRouterErrorResponse(body, init) {
|
|
2677
|
+
return new Response(body, _extends({}, init, {
|
|
2678
|
+
headers: _extends({}, init.headers, {
|
|
2679
|
+
"X-Remix-Router-Error": "yes"
|
|
2680
|
+
})
|
|
2681
|
+
}));
|
|
2555
2682
|
}
|
|
2556
2683
|
|
|
2557
2684
|
return {
|
|
@@ -2600,7 +2727,7 @@ function normalizeNavigateOptions(to, opts, isFetcher) {
|
|
|
2600
2727
|
path,
|
|
2601
2728
|
submission: {
|
|
2602
2729
|
formMethod: opts.formMethod,
|
|
2603
|
-
formAction:
|
|
2730
|
+
formAction: stripHashFromPath(path),
|
|
2604
2731
|
formEncType: opts && opts.formEncType || "application/x-www-form-urlencoded",
|
|
2605
2732
|
formData: opts.formData
|
|
2606
2733
|
}
|
|
@@ -2683,16 +2810,16 @@ function getMatchesToLoad(state, matches, submission, location, isRevalidationRe
|
|
|
2683
2810
|
|
|
2684
2811
|
let revalidatingFetchers = [];
|
|
2685
2812
|
fetchLoadMatches && fetchLoadMatches.forEach((_ref10, key) => {
|
|
2686
|
-
let [href, match] = _ref10;
|
|
2813
|
+
let [href, match, fetchMatches] = _ref10;
|
|
2687
2814
|
|
|
2688
2815
|
// This fetcher was cancelled from a prior action submission - force reload
|
|
2689
2816
|
if (cancelledFetcherLoads.includes(key)) {
|
|
2690
|
-
revalidatingFetchers.push([key, href, match]);
|
|
2817
|
+
revalidatingFetchers.push([key, href, match, fetchMatches]);
|
|
2691
2818
|
} else if (isRevalidationRequired) {
|
|
2692
2819
|
let shouldRevalidate = shouldRevalidateLoader(href, match, submission, href, match, isRevalidationRequired, actionResult);
|
|
2693
2820
|
|
|
2694
2821
|
if (shouldRevalidate) {
|
|
2695
|
-
revalidatingFetchers.push([key, href, match]);
|
|
2822
|
+
revalidatingFetchers.push([key, href, match, fetchMatches]);
|
|
2696
2823
|
}
|
|
2697
2824
|
}
|
|
2698
2825
|
});
|
|
@@ -2754,9 +2881,9 @@ function shouldRevalidateLoader(currentLocation, currentMatch, submission, locat
|
|
|
2754
2881
|
return defaultShouldRevalidate;
|
|
2755
2882
|
}
|
|
2756
2883
|
|
|
2757
|
-
async function callLoaderOrAction(type, request, match,
|
|
2758
|
-
if (
|
|
2759
|
-
|
|
2884
|
+
async function callLoaderOrAction(type, request, match, matches, basename, isStaticRequest, isRouteRequest) {
|
|
2885
|
+
if (isStaticRequest === void 0) {
|
|
2886
|
+
isStaticRequest = false;
|
|
2760
2887
|
}
|
|
2761
2888
|
|
|
2762
2889
|
if (isRouteRequest === void 0) {
|
|
@@ -2788,20 +2915,30 @@ async function callLoaderOrAction(type, request, match, skipRedirects, isRouteRe
|
|
|
2788
2915
|
}
|
|
2789
2916
|
|
|
2790
2917
|
if (result instanceof Response) {
|
|
2791
|
-
// Process redirects
|
|
2792
|
-
let status = result.status;
|
|
2793
|
-
let location = result.headers.get("Location"); // For SSR single-route requests, we want to hand Responses back directly
|
|
2794
|
-
// without unwrapping
|
|
2918
|
+
let status = result.status; // Process redirects
|
|
2795
2919
|
|
|
2796
|
-
if (
|
|
2797
|
-
|
|
2798
|
-
|
|
2920
|
+
if (status >= 300 && status <= 399) {
|
|
2921
|
+
let location = result.headers.get("Location");
|
|
2922
|
+
invariant(location, "Redirects returned/thrown from loaders/actions must have a Location header"); // Support relative routing in redirects
|
|
2923
|
+
|
|
2924
|
+
let activeMatches = matches.slice(0, matches.indexOf(match) + 1);
|
|
2925
|
+
let routePathnames = getPathContributingMatches(activeMatches).map(match => match.pathnameBase);
|
|
2926
|
+
let requestPath = createURL(request.url).pathname;
|
|
2927
|
+
let resolvedLocation = resolveTo(location, routePathnames, requestPath);
|
|
2928
|
+
invariant(createPath(resolvedLocation), "Unable to resolve redirect location: " + result.headers.get("Location")); // Prepend the basename to the redirect location if we have one
|
|
2799
2929
|
|
|
2800
|
-
|
|
2801
|
-
|
|
2930
|
+
if (basename) {
|
|
2931
|
+
let path = resolvedLocation.pathname;
|
|
2932
|
+
resolvedLocation.pathname = path === "/" ? basename : joinPaths([basename, path]);
|
|
2933
|
+
}
|
|
2934
|
+
|
|
2935
|
+
location = createPath(resolvedLocation); // Don't process redirects in the router during static requests requests.
|
|
2802
2936
|
// Instead, throw the Response and let the server handle it with an HTTP
|
|
2803
|
-
// redirect
|
|
2804
|
-
|
|
2937
|
+
// redirect. We also update the Location header in place in this flow so
|
|
2938
|
+
// basename and relative routing is taken into account
|
|
2939
|
+
|
|
2940
|
+
if (isStaticRequest) {
|
|
2941
|
+
result.headers.set("Location", location);
|
|
2805
2942
|
throw result;
|
|
2806
2943
|
}
|
|
2807
2944
|
|
|
@@ -2811,6 +2948,17 @@ async function callLoaderOrAction(type, request, match, skipRedirects, isRouteRe
|
|
|
2811
2948
|
location,
|
|
2812
2949
|
revalidate: result.headers.get("X-Remix-Revalidate") !== null
|
|
2813
2950
|
};
|
|
2951
|
+
} // For SSR single-route requests, we want to hand Responses back directly
|
|
2952
|
+
// without unwrapping. We do this with the QueryRouteResponse wrapper
|
|
2953
|
+
// interface so we can know whether it was returned or thrown
|
|
2954
|
+
|
|
2955
|
+
|
|
2956
|
+
if (isRouteRequest) {
|
|
2957
|
+
// eslint-disable-next-line no-throw-literal
|
|
2958
|
+
throw {
|
|
2959
|
+
type: resultType || ResultType.data,
|
|
2960
|
+
response: result
|
|
2961
|
+
};
|
|
2814
2962
|
}
|
|
2815
2963
|
|
|
2816
2964
|
let data;
|
|
@@ -2859,7 +3007,7 @@ async function callLoaderOrAction(type, request, match, skipRedirects, isRouteRe
|
|
|
2859
3007
|
}
|
|
2860
3008
|
|
|
2861
3009
|
function createRequest(location, signal, submission) {
|
|
2862
|
-
let url = createURL(location).toString();
|
|
3010
|
+
let url = createURL(stripHashFromPath(location)).toString();
|
|
2863
3011
|
let init = {
|
|
2864
3012
|
signal
|
|
2865
3013
|
};
|
|
@@ -3026,10 +3174,10 @@ function findNearestBoundary(matches, routeId) {
|
|
|
3026
3174
|
return eligibleMatches.reverse().find(m => m.route.hasErrorBoundary === true) || matches[0];
|
|
3027
3175
|
}
|
|
3028
3176
|
|
|
3029
|
-
function
|
|
3177
|
+
function getShortCircuitMatches(routes, status, statusText) {
|
|
3030
3178
|
// Prefer a root layout route if present, otherwise shim in a route object
|
|
3031
|
-
let route = routes.find(r => r.index || r.path
|
|
3032
|
-
id: "__shim-
|
|
3179
|
+
let route = routes.find(r => r.index || !r.path || r.path === "/") || {
|
|
3180
|
+
id: "__shim-" + status + "-route__"
|
|
3033
3181
|
};
|
|
3034
3182
|
return {
|
|
3035
3183
|
matches: [{
|
|
@@ -3039,16 +3187,24 @@ function getNotFoundMatches(routes) {
|
|
|
3039
3187
|
route
|
|
3040
3188
|
}],
|
|
3041
3189
|
route,
|
|
3042
|
-
error: new ErrorResponse(
|
|
3190
|
+
error: new ErrorResponse(status, statusText, null)
|
|
3043
3191
|
};
|
|
3044
3192
|
}
|
|
3045
3193
|
|
|
3194
|
+
function getNotFoundMatches(routes) {
|
|
3195
|
+
return getShortCircuitMatches(routes, 404, "Not Found");
|
|
3196
|
+
}
|
|
3197
|
+
|
|
3198
|
+
function getMethodNotAllowedMatches(routes) {
|
|
3199
|
+
return getShortCircuitMatches(routes, 405, "Method Not Allowed");
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3046
3202
|
function getMethodNotAllowedResult(path) {
|
|
3047
|
-
let href = typeof path === "string" ? path :
|
|
3203
|
+
let href = typeof path === "string" ? path : createPath(path);
|
|
3048
3204
|
console.warn("You're trying to submit to a route that does not have an action. To " + "fix this, please add an `action` function to the route for " + ("[" + href + "]"));
|
|
3049
3205
|
return {
|
|
3050
3206
|
type: ResultType.error,
|
|
3051
|
-
error: new ErrorResponse(405, "Method Not Allowed", "
|
|
3207
|
+
error: new ErrorResponse(405, "Method Not Allowed", "")
|
|
3052
3208
|
};
|
|
3053
3209
|
} // Find any returned redirect errors, starting from the lowest match
|
|
3054
3210
|
|
|
@@ -3061,11 +3217,13 @@ function findRedirect(results) {
|
|
|
3061
3217
|
return result;
|
|
3062
3218
|
}
|
|
3063
3219
|
}
|
|
3064
|
-
}
|
|
3065
|
-
|
|
3220
|
+
}
|
|
3066
3221
|
|
|
3067
|
-
function
|
|
3068
|
-
|
|
3222
|
+
function stripHashFromPath(path) {
|
|
3223
|
+
let parsedPath = typeof path === "string" ? parsePath(path) : path;
|
|
3224
|
+
return createPath(_extends({}, parsedPath, {
|
|
3225
|
+
hash: ""
|
|
3226
|
+
}));
|
|
3069
3227
|
}
|
|
3070
3228
|
|
|
3071
3229
|
function isHashChangeOnly(a, b) {
|
|
@@ -3084,6 +3242,20 @@ function isRedirectResult(result) {
|
|
|
3084
3242
|
return (result && result.type) === ResultType.redirect;
|
|
3085
3243
|
}
|
|
3086
3244
|
|
|
3245
|
+
function isRedirectResponse(result) {
|
|
3246
|
+
if (!(result instanceof Response)) {
|
|
3247
|
+
return false;
|
|
3248
|
+
}
|
|
3249
|
+
|
|
3250
|
+
let status = result.status;
|
|
3251
|
+
let location = result.headers.get("Location");
|
|
3252
|
+
return status >= 300 && status <= 399 && location != null;
|
|
3253
|
+
}
|
|
3254
|
+
|
|
3255
|
+
function isQueryRouteResponse(obj) {
|
|
3256
|
+
return obj && obj.response instanceof Response && (obj.type === ResultType.data || ResultType.error);
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3087
3259
|
async function resolveDeferredResults(currentMatches, matchesToLoad, results, signal, isFetcher, currentLoaderData) {
|
|
3088
3260
|
for (let index = 0; index < results.length; index++) {
|
|
3089
3261
|
let result = results[index];
|
|
@@ -3160,18 +3332,16 @@ function createUseMatchesMatch(match, loaderData) {
|
|
|
3160
3332
|
function getTargetMatch(matches, location) {
|
|
3161
3333
|
let search = typeof location === "string" ? parsePath(location).search : location.search;
|
|
3162
3334
|
|
|
3163
|
-
if (matches[matches.length - 1].route.index &&
|
|
3164
|
-
|
|
3165
|
-
|
|
3335
|
+
if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || "")) {
|
|
3336
|
+
// Return the leaf index route when index is present
|
|
3337
|
+
return matches[matches.length - 1];
|
|
3338
|
+
} // Otherwise grab the deepest "path contributing" match (ignoring index and
|
|
3339
|
+
// pathless layout routes)
|
|
3166
3340
|
|
|
3167
|
-
return matches.slice(-1)[0];
|
|
3168
|
-
}
|
|
3169
3341
|
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
let href = typeof location === "string" ? location : createHref(location);
|
|
3173
|
-
return new URL(href, base);
|
|
3342
|
+
let pathMatches = getPathContributingMatches(matches);
|
|
3343
|
+
return pathMatches[pathMatches.length - 1];
|
|
3174
3344
|
} //#endregion
|
|
3175
3345
|
|
|
3176
|
-
export { AbortedDeferredError, Action, ErrorResponse, IDLE_FETCHER, IDLE_NAVIGATION, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, createRouter, defer, generatePath, getStaticContextFromError, getToPathname, invariant, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, parsePath, redirect, resolvePath, resolveTo, stripBasename, unstable_createStaticHandler, warning };
|
|
3346
|
+
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, unstable_createStaticHandler, warning };
|
|
3177
3347
|
//# sourceMappingURL=router.js.map
|