@remix-run/router 1.3.0-pre.3 → 1.3.1-pre.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 +12 -16
- package/dist/router.cjs.js +111 -102
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.js +111 -102
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +111 -102
- 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 -2
- package/history.ts +4 -8
- package/package.json +1 -1
- package/router.ts +121 -134
- package/utils.ts +14 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,35 +1,31 @@
|
|
|
1
1
|
# `@remix-run/router`
|
|
2
2
|
|
|
3
|
-
## 1.3.
|
|
3
|
+
## 1.3.1-pre.0
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
7
|
+
- Respect `preventScrollReset` on `fetcher.Form` ([#9963](https://github.com/remix-run/react-router/pull/9963))
|
|
8
|
+
- Fix revalidating fetcher `shouldRevalidate` params ([#9948](https://github.com/remix-run/react-router/pull/9948))
|
|
9
|
+
- Do not short circuit on hash change only mutation submissions ([#9944](https://github.com/remix-run/react-router/pull/9944))
|
|
10
|
+
- Remove `instanceof` check from `isRouteErrorResponse` to avoid bundling issues on the server ([#9930](https://github.com/remix-run/react-router/pull/9930))
|
|
11
|
+
- Detect no lazy data and remove abort controller for `defer` ([#9965](https://github.com/remix-run/react-router/pull/9965))
|
|
12
|
+
- Send the name as the value when url-encoding `File` `FormData` entries ([#9867](https://github.com/remix-run/react-router/pull/9867))
|
|
9
13
|
|
|
10
|
-
## 1.3.0
|
|
14
|
+
## 1.3.0
|
|
11
15
|
|
|
12
16
|
### Minor Changes
|
|
13
17
|
|
|
14
18
|
- Added support for navigation blocking APIs ([#9709](https://github.com/remix-run/react-router/pull/9709))
|
|
15
|
-
|
|
16
|
-
## 1.3.0-pre.1
|
|
17
|
-
|
|
18
|
-
### Patch Changes
|
|
19
|
-
|
|
20
|
-
- Fix scroll reset if a submission redirects ([#9886](https://github.com/remix-run/react-router/pull/9886))
|
|
21
|
-
|
|
22
|
-
## 1.3.0-pre.0
|
|
23
|
-
|
|
24
|
-
### Minor Changes
|
|
25
|
-
|
|
26
|
-
- Expose deferred information from createStaticHandler ([#9760](https://github.com/remix-run/react-router/pull/9760))
|
|
19
|
+
- Expose deferred information from `createStaticHandler` ([#9760](https://github.com/remix-run/react-router/pull/9760))
|
|
27
20
|
|
|
28
21
|
### Patch Changes
|
|
29
22
|
|
|
30
23
|
- Improved absolute redirect url detection in actions/loaders ([#9829](https://github.com/remix-run/react-router/pull/9829))
|
|
31
24
|
- Fix URL creation with memory histories ([#9814](https://github.com/remix-run/react-router/pull/9814))
|
|
32
25
|
- Fix `generatePath` when optional params are present ([#9764](https://github.com/remix-run/react-router/pull/9764))
|
|
26
|
+
- Fix scroll reset if a submission redirects ([#9886](https://github.com/remix-run/react-router/pull/9886))
|
|
27
|
+
- Fix 404 bug with same-origin absolute redirects ([#9913](https://github.com/remix-run/react-router/pull/9913))
|
|
28
|
+
- Support `OPTIONS` requests in `staticHandler.queryRoute` ([#9914](https://github.com/remix-run/react-router/pull/9914))
|
|
33
29
|
|
|
34
30
|
## 1.2.1
|
|
35
31
|
|
package/dist/router.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.3.
|
|
2
|
+
* @remix-run/router v1.3.1-pre.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -449,10 +449,7 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
|
|
|
449
449
|
});
|
|
450
450
|
}
|
|
451
451
|
} else {
|
|
452
|
-
warning$1(false,
|
|
453
|
-
// and link to it here so people can understand better what is going on
|
|
454
|
-
// and how to avoid it.
|
|
455
|
-
"You are trying to block a POP navigation to a location that was not " + "created by @remix-run/router. The block will fail silently in " + "production, but in general you should do all navigation with the " + "router (instead of using window.history.pushState directly) " + "to avoid this situation.");
|
|
452
|
+
warning$1(false, "You are trying to perform a POP navigation to a location that was not " + "created by @remix-run/router. This will fail silently in production. " + "You should navigate via the router to avoid this situation (instead of " + "using window.history.pushState/window.location.hash).");
|
|
456
453
|
}
|
|
457
454
|
}
|
|
458
455
|
|
|
@@ -1250,6 +1247,12 @@ class DeferredData {
|
|
|
1250
1247
|
[key]: this.trackPromise(key, value)
|
|
1251
1248
|
});
|
|
1252
1249
|
}, {});
|
|
1250
|
+
|
|
1251
|
+
if (this.done) {
|
|
1252
|
+
// All incoming values were resolved
|
|
1253
|
+
this.unlistenAbortSignal();
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1253
1256
|
this.init = responseInit;
|
|
1254
1257
|
}
|
|
1255
1258
|
|
|
@@ -1437,11 +1440,11 @@ class ErrorResponse {
|
|
|
1437
1440
|
}
|
|
1438
1441
|
/**
|
|
1439
1442
|
* Check if the given error is an ErrorResponse generated from a 4xx/5xx
|
|
1440
|
-
* Response
|
|
1443
|
+
* Response thrown from an action/loader
|
|
1441
1444
|
*/
|
|
1442
1445
|
|
|
1443
|
-
function isRouteErrorResponse(
|
|
1444
|
-
return
|
|
1446
|
+
function isRouteErrorResponse(error) {
|
|
1447
|
+
return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error;
|
|
1445
1448
|
}
|
|
1446
1449
|
|
|
1447
1450
|
//#region Types and Constants
|
|
@@ -1905,10 +1908,12 @@ function createRouter(init) {
|
|
|
1905
1908
|
}
|
|
1906
1909
|
});
|
|
1907
1910
|
return;
|
|
1908
|
-
} // Short circuit if it's only a hash change
|
|
1911
|
+
} // Short circuit if it's only a hash change and not a mutation submission
|
|
1912
|
+
// For example, on /page#hash and submit a <Form method="post"> which will
|
|
1913
|
+
// default to a navigation to /page
|
|
1909
1914
|
|
|
1910
1915
|
|
|
1911
|
-
if (isHashChangeOnly(state.location, location)) {
|
|
1916
|
+
if (isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) {
|
|
1912
1917
|
completeNavigation(location, {
|
|
1913
1918
|
matches
|
|
1914
1919
|
});
|
|
@@ -2122,9 +2127,8 @@ function createRouter(init) {
|
|
|
2122
2127
|
|
|
2123
2128
|
|
|
2124
2129
|
if (!isUninterruptedRevalidation) {
|
|
2125
|
-
revalidatingFetchers.forEach(
|
|
2126
|
-
let
|
|
2127
|
-
let fetcher = state.fetchers.get(key);
|
|
2130
|
+
revalidatingFetchers.forEach(rf => {
|
|
2131
|
+
let fetcher = state.fetchers.get(rf.key);
|
|
2128
2132
|
let revalidatingFetcher = {
|
|
2129
2133
|
state: "loading",
|
|
2130
2134
|
data: fetcher && fetcher.data,
|
|
@@ -2134,7 +2138,7 @@ function createRouter(init) {
|
|
|
2134
2138
|
formData: undefined,
|
|
2135
2139
|
" _hasFetcherDoneAnything ": true
|
|
2136
2140
|
};
|
|
2137
|
-
state.fetchers.set(key, revalidatingFetcher);
|
|
2141
|
+
state.fetchers.set(rf.key, revalidatingFetcher);
|
|
2138
2142
|
});
|
|
2139
2143
|
let actionData = pendingActionData || state.actionData;
|
|
2140
2144
|
updateState(_extends({
|
|
@@ -2149,10 +2153,7 @@ function createRouter(init) {
|
|
|
2149
2153
|
}
|
|
2150
2154
|
|
|
2151
2155
|
pendingNavigationLoadId = ++incrementingLoadId;
|
|
2152
|
-
revalidatingFetchers.forEach(
|
|
2153
|
-
let [key] = _ref3;
|
|
2154
|
-
return fetchControllers.set(key, pendingNavigationController);
|
|
2155
|
-
});
|
|
2156
|
+
revalidatingFetchers.forEach(rf => fetchControllers.set(rf.key, pendingNavigationController));
|
|
2156
2157
|
let {
|
|
2157
2158
|
results,
|
|
2158
2159
|
loaderResults,
|
|
@@ -2168,10 +2169,7 @@ function createRouter(init) {
|
|
|
2168
2169
|
// reassigned to new controllers for the next navigation
|
|
2169
2170
|
|
|
2170
2171
|
|
|
2171
|
-
revalidatingFetchers.forEach(
|
|
2172
|
-
let [key] = _ref4;
|
|
2173
|
-
return fetchControllers.delete(key);
|
|
2174
|
-
}); // If any loaders returned a redirect Response, start a new REPLACE navigation
|
|
2172
|
+
revalidatingFetchers.forEach(rf => fetchControllers.delete(rf.key)); // If any loaders returned a redirect Response, start a new REPLACE navigation
|
|
2175
2173
|
|
|
2176
2174
|
let redirect = findRedirect(results);
|
|
2177
2175
|
|
|
@@ -2235,6 +2233,7 @@ function createRouter(init) {
|
|
|
2235
2233
|
submission
|
|
2236
2234
|
} = normalizeNavigateOptions(href, opts, true);
|
|
2237
2235
|
let match = getTargetMatch(matches, path);
|
|
2236
|
+
pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;
|
|
2238
2237
|
|
|
2239
2238
|
if (submission && isMutationMethod(submission.formMethod)) {
|
|
2240
2239
|
handleFetcherAction(key, routeId, path, match, matches, submission);
|
|
@@ -2243,7 +2242,12 @@ function createRouter(init) {
|
|
|
2243
2242
|
// revalidations
|
|
2244
2243
|
|
|
2245
2244
|
|
|
2246
|
-
fetchLoadMatches.set(key,
|
|
2245
|
+
fetchLoadMatches.set(key, {
|
|
2246
|
+
routeId,
|
|
2247
|
+
path,
|
|
2248
|
+
match,
|
|
2249
|
+
matches
|
|
2250
|
+
});
|
|
2247
2251
|
handleFetcherLoader(key, routeId, path, match, matches, submission);
|
|
2248
2252
|
} // Call the action for the matched fetcher.submit(), and then handle redirects,
|
|
2249
2253
|
// errors, and revalidation
|
|
@@ -2349,11 +2353,8 @@ function createRouter(init) {
|
|
|
2349
2353
|
// current fetcher which we want to keep in it's current loading state which
|
|
2350
2354
|
// contains it's action submission info + action data
|
|
2351
2355
|
|
|
2352
|
-
revalidatingFetchers.filter(
|
|
2353
|
-
let
|
|
2354
|
-
return staleKey !== key;
|
|
2355
|
-
}).forEach(_ref6 => {
|
|
2356
|
-
let [staleKey] = _ref6;
|
|
2356
|
+
revalidatingFetchers.filter(rf => rf.key !== key).forEach(rf => {
|
|
2357
|
+
let staleKey = rf.key;
|
|
2357
2358
|
let existingFetcher = state.fetchers.get(staleKey);
|
|
2358
2359
|
let revalidatingFetcher = {
|
|
2359
2360
|
state: "loading",
|
|
@@ -2382,10 +2383,7 @@ function createRouter(init) {
|
|
|
2382
2383
|
|
|
2383
2384
|
fetchReloadIds.delete(key);
|
|
2384
2385
|
fetchControllers.delete(key);
|
|
2385
|
-
revalidatingFetchers.forEach(
|
|
2386
|
-
let [staleKey] = _ref7;
|
|
2387
|
-
return fetchControllers.delete(staleKey);
|
|
2388
|
-
});
|
|
2386
|
+
revalidatingFetchers.forEach(r => fetchControllers.delete(r.key));
|
|
2389
2387
|
let redirect = findRedirect(results);
|
|
2390
2388
|
|
|
2391
2389
|
if (redirect) {
|
|
@@ -2625,16 +2623,10 @@ function createRouter(init) {
|
|
|
2625
2623
|
// Call all navigation loaders and revalidating fetcher loaders in parallel,
|
|
2626
2624
|
// then slice off the results into separate arrays so we can handle them
|
|
2627
2625
|
// accordingly
|
|
2628
|
-
let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(
|
|
2629
|
-
let [, href, match, fetchMatches] = _ref8;
|
|
2630
|
-
return callLoaderOrAction("loader", createClientSideRequest(init.history, href, request.signal), match, fetchMatches, router.basename);
|
|
2631
|
-
})]);
|
|
2626
|
+
let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(f => callLoaderOrAction("loader", createClientSideRequest(init.history, f.path, request.signal), f.match, f.matches, router.basename))]);
|
|
2632
2627
|
let loaderResults = results.slice(0, matchesToLoad.length);
|
|
2633
2628
|
let fetcherResults = results.slice(matchesToLoad.length);
|
|
2634
|
-
await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, request.signal, false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(
|
|
2635
|
-
let [,, match] = _ref9;
|
|
2636
|
-
return match;
|
|
2637
|
-
}), fetcherResults, request.signal, true)]);
|
|
2629
|
+
await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, request.signal, false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(f => f.match), fetcherResults, request.signal, true)]);
|
|
2638
2630
|
return {
|
|
2639
2631
|
results,
|
|
2640
2632
|
loaderResults,
|
|
@@ -2773,12 +2765,12 @@ function createRouter(init) {
|
|
|
2773
2765
|
});
|
|
2774
2766
|
}
|
|
2775
2767
|
|
|
2776
|
-
function shouldBlockNavigation(
|
|
2768
|
+
function shouldBlockNavigation(_ref2) {
|
|
2777
2769
|
let {
|
|
2778
2770
|
currentLocation,
|
|
2779
2771
|
nextLocation,
|
|
2780
2772
|
historyAction
|
|
2781
|
-
} =
|
|
2773
|
+
} = _ref2;
|
|
2782
2774
|
|
|
2783
2775
|
if (activeBlocker == null) {
|
|
2784
2776
|
return;
|
|
@@ -3372,24 +3364,15 @@ function normalizeNavigateOptions(to, opts, isFetcher) {
|
|
|
3372
3364
|
|
|
3373
3365
|
|
|
3374
3366
|
let parsedPath = parsePath(path);
|
|
3367
|
+
let searchParams = convertFormDataToSearchParams(opts.formData); // Since fetcher GET submissions only run a single loader (as opposed to
|
|
3368
|
+
// navigation GET submissions which run all loaders), we need to preserve
|
|
3369
|
+
// any incoming ?index params
|
|
3375
3370
|
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
// navigation GET submissions which run all loaders), we need to preserve
|
|
3379
|
-
// any incoming ?index params
|
|
3380
|
-
|
|
3381
|
-
if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) {
|
|
3382
|
-
searchParams.append("index", "");
|
|
3383
|
-
}
|
|
3384
|
-
|
|
3385
|
-
parsedPath.search = "?" + searchParams;
|
|
3386
|
-
} catch (e) {
|
|
3387
|
-
return {
|
|
3388
|
-
path,
|
|
3389
|
-
error: getInternalRouterError(400)
|
|
3390
|
-
};
|
|
3371
|
+
if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) {
|
|
3372
|
+
searchParams.append("index", "");
|
|
3391
3373
|
}
|
|
3392
3374
|
|
|
3375
|
+
parsedPath.search = "?" + searchParams;
|
|
3393
3376
|
return {
|
|
3394
3377
|
path: createPath(parsedPath),
|
|
3395
3378
|
submission
|
|
@@ -3413,25 +3396,73 @@ function getLoaderMatchesUntilBoundary(matches, boundaryId) {
|
|
|
3413
3396
|
}
|
|
3414
3397
|
|
|
3415
3398
|
function getMatchesToLoad(history, state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches) {
|
|
3416
|
-
let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined;
|
|
3399
|
+
let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined;
|
|
3400
|
+
let currentUrl = history.createURL(state.location);
|
|
3401
|
+
let nextUrl = history.createURL(location);
|
|
3402
|
+
let defaultShouldRevalidate = // Forced revalidation due to submission, useRevalidate, or X-Remix-Revalidate
|
|
3403
|
+
isRevalidationRequired || // Clicked the same link, resubmitted a GET form
|
|
3404
|
+
currentUrl.toString() === nextUrl.toString() || // Search params affect all loaders
|
|
3405
|
+
currentUrl.search !== nextUrl.search; // Pick navigation matches that are net-new or qualify for revalidation
|
|
3417
3406
|
|
|
3418
3407
|
let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;
|
|
3419
3408
|
let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);
|
|
3420
|
-
let navigationMatches = boundaryMatches.filter((match, index) =>
|
|
3421
|
-
|
|
3409
|
+
let navigationMatches = boundaryMatches.filter((match, index) => {
|
|
3410
|
+
if (match.route.loader == null) {
|
|
3411
|
+
return false;
|
|
3412
|
+
} // Always call the loader on new route instances and pending defer cancellations
|
|
3422
3413
|
|
|
3423
|
-
let revalidatingFetchers = [];
|
|
3424
|
-
fetchLoadMatches && fetchLoadMatches.forEach((_ref11, key) => {
|
|
3425
|
-
let [href, match, fetchMatches] = _ref11;
|
|
3426
3414
|
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3415
|
+
if (isNewLoader(state.loaderData, state.matches[index], match) || cancelledDeferredRoutes.some(id => id === match.route.id)) {
|
|
3416
|
+
return true;
|
|
3417
|
+
} // This is the default implementation for when we revalidate. If the route
|
|
3418
|
+
// provides it's own implementation, then we give them full control but
|
|
3419
|
+
// provide this value so they can leverage it if needed after they check
|
|
3420
|
+
// their own specific use cases
|
|
3421
|
+
|
|
3422
|
+
|
|
3423
|
+
let currentRouteMatch = state.matches[index];
|
|
3424
|
+
let nextRouteMatch = match;
|
|
3425
|
+
return shouldRevalidateLoader(match, _extends({
|
|
3426
|
+
currentUrl,
|
|
3427
|
+
currentParams: currentRouteMatch.params,
|
|
3428
|
+
nextUrl,
|
|
3429
|
+
nextParams: nextRouteMatch.params
|
|
3430
|
+
}, submission, {
|
|
3431
|
+
actionResult,
|
|
3432
|
+
defaultShouldRevalidate: defaultShouldRevalidate || isNewRouteInstance(currentRouteMatch, nextRouteMatch)
|
|
3433
|
+
}));
|
|
3434
|
+
}); // Pick fetcher.loads that need to be revalidated
|
|
3435
|
+
|
|
3436
|
+
let revalidatingFetchers = [];
|
|
3437
|
+
fetchLoadMatches && fetchLoadMatches.forEach((f, key) => {
|
|
3438
|
+
if (!matches.some(m => m.route.id === f.routeId)) {
|
|
3439
|
+
// This fetcher is not going to be present in the subsequent render so
|
|
3440
|
+
// there's no need to revalidate it
|
|
3441
|
+
return;
|
|
3442
|
+
} else if (cancelledFetcherLoads.includes(key)) {
|
|
3443
|
+
// This fetcher was cancelled from a prior action submission - force reload
|
|
3444
|
+
revalidatingFetchers.push(_extends({
|
|
3445
|
+
key
|
|
3446
|
+
}, f));
|
|
3447
|
+
} else {
|
|
3448
|
+
// Revalidating fetchers are decoupled from the route matches since they
|
|
3449
|
+
// hit a static href, so they _always_ check shouldRevalidate and the
|
|
3450
|
+
// default is strictly if a revalidation is explicitly required (action
|
|
3451
|
+
// submissions, useRevalidator, X-Remix-Revalidate).
|
|
3452
|
+
let shouldRevalidate = shouldRevalidateLoader(f.match, _extends({
|
|
3453
|
+
currentUrl,
|
|
3454
|
+
currentParams: state.matches[state.matches.length - 1].params,
|
|
3455
|
+
nextUrl,
|
|
3456
|
+
nextParams: matches[matches.length - 1].params
|
|
3457
|
+
}, submission, {
|
|
3458
|
+
actionResult,
|
|
3459
|
+
defaultShouldRevalidate
|
|
3460
|
+
}));
|
|
3432
3461
|
|
|
3433
3462
|
if (shouldRevalidate) {
|
|
3434
|
-
revalidatingFetchers.push(
|
|
3463
|
+
revalidatingFetchers.push(_extends({
|
|
3464
|
+
key
|
|
3465
|
+
}, f));
|
|
3435
3466
|
}
|
|
3436
3467
|
}
|
|
3437
3468
|
});
|
|
@@ -3454,43 +3485,20 @@ function isNewRouteInstance(currentMatch, match) {
|
|
|
3454
3485
|
return (// param change for this match, /users/123 -> /users/456
|
|
3455
3486
|
currentMatch.pathname !== match.pathname || // splat param changed, which is not present in match.path
|
|
3456
3487
|
// e.g. /files/images/avatar.jpg -> files/finances.xls
|
|
3457
|
-
currentPath && currentPath.endsWith("*") && currentMatch.params["*"] !== match.params["*"]
|
|
3488
|
+
currentPath != null && currentPath.endsWith("*") && currentMatch.params["*"] !== match.params["*"]
|
|
3458
3489
|
);
|
|
3459
3490
|
}
|
|
3460
3491
|
|
|
3461
|
-
function shouldRevalidateLoader(
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
let nextUrl = history.createURL(location);
|
|
3465
|
-
let nextParams = match.params; // This is the default implementation as to when we revalidate. If the route
|
|
3466
|
-
// provides it's own implementation, then we give them full control but
|
|
3467
|
-
// provide this value so they can leverage it if needed after they check
|
|
3468
|
-
// their own specific use cases
|
|
3469
|
-
// Note that fetchers always provide the same current/next locations so the
|
|
3470
|
-
// URL-based checks here don't apply to fetcher shouldRevalidate calls
|
|
3471
|
-
|
|
3472
|
-
let defaultShouldRevalidate = isNewRouteInstance(currentMatch, match) || // Clicked the same link, resubmitted a GET form
|
|
3473
|
-
currentUrl.toString() === nextUrl.toString() || // Search params affect all loaders
|
|
3474
|
-
currentUrl.search !== nextUrl.search || // Forced revalidation due to submission, useRevalidate, or X-Remix-Revalidate
|
|
3475
|
-
isRevalidationRequired;
|
|
3476
|
-
|
|
3477
|
-
if (match.route.shouldRevalidate) {
|
|
3478
|
-
let routeChoice = match.route.shouldRevalidate(_extends({
|
|
3479
|
-
currentUrl,
|
|
3480
|
-
currentParams,
|
|
3481
|
-
nextUrl,
|
|
3482
|
-
nextParams
|
|
3483
|
-
}, submission, {
|
|
3484
|
-
actionResult,
|
|
3485
|
-
defaultShouldRevalidate
|
|
3486
|
-
}));
|
|
3492
|
+
function shouldRevalidateLoader(loaderMatch, arg) {
|
|
3493
|
+
if (loaderMatch.route.shouldRevalidate) {
|
|
3494
|
+
let routeChoice = loaderMatch.route.shouldRevalidate(arg);
|
|
3487
3495
|
|
|
3488
3496
|
if (typeof routeChoice === "boolean") {
|
|
3489
3497
|
return routeChoice;
|
|
3490
3498
|
}
|
|
3491
3499
|
}
|
|
3492
3500
|
|
|
3493
|
-
return defaultShouldRevalidate;
|
|
3501
|
+
return arg.defaultShouldRevalidate;
|
|
3494
3502
|
}
|
|
3495
3503
|
|
|
3496
3504
|
async function callLoaderOrAction(type, request, match, matches, basename, isStaticRequest, isRouteRequest, requestContext) {
|
|
@@ -3665,8 +3673,8 @@ function convertFormDataToSearchParams(formData) {
|
|
|
3665
3673
|
let searchParams = new URLSearchParams();
|
|
3666
3674
|
|
|
3667
3675
|
for (let [key, value] of formData.entries()) {
|
|
3668
|
-
|
|
3669
|
-
searchParams.append(key, value);
|
|
3676
|
+
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs
|
|
3677
|
+
searchParams.append(key, value instanceof File ? value.name : value);
|
|
3670
3678
|
}
|
|
3671
3679
|
|
|
3672
3680
|
return searchParams;
|
|
@@ -3757,7 +3765,10 @@ function processLoaderData(state, matches, matchesToLoad, results, pendingError,
|
|
|
3757
3765
|
} = processRouteLoaderData(matches, matchesToLoad, results, pendingError, activeDeferreds); // Process results from our revalidating fetchers
|
|
3758
3766
|
|
|
3759
3767
|
for (let index = 0; index < revalidatingFetchers.length; index++) {
|
|
3760
|
-
let
|
|
3768
|
+
let {
|
|
3769
|
+
key,
|
|
3770
|
+
match
|
|
3771
|
+
} = revalidatingFetchers[index];
|
|
3761
3772
|
invariant(fetcherResults !== undefined && fetcherResults[index] !== undefined, "Did not find corresponding fetcher result");
|
|
3762
3773
|
let result = fetcherResults[index]; // Process fetcher non-redirect errors
|
|
3763
3774
|
|
|
@@ -3863,8 +3874,6 @@ function getInternalRouterError(status, _temp4) {
|
|
|
3863
3874
|
errorMessage = "You made a " + method + " request to \"" + pathname + "\" but " + ("did not provide a `loader` for route \"" + routeId + "\", ") + "so there is no way to handle the request.";
|
|
3864
3875
|
} else if (type === "defer-action") {
|
|
3865
3876
|
errorMessage = "defer() is not supported in actions";
|
|
3866
|
-
} else {
|
|
3867
|
-
errorMessage = "Cannot submit binary form data using GET";
|
|
3868
3877
|
}
|
|
3869
3878
|
} else if (status === 403) {
|
|
3870
3879
|
statusText = "Forbidden";
|