@remix-run/router 1.3.2 → 1.3.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 +14 -0
- package/dist/index.d.ts +2 -1
- package/dist/router.cjs.js +114 -51
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +8 -0
- package/dist/router.js +114 -51
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +114 -51
- 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/index.ts +2 -1
- package/package.json +1 -1
- package/router.ts +140 -61
package/dist/router.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.3.
|
|
2
|
+
* @remix-run/router v1.3.3-pre.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -1491,7 +1491,8 @@
|
|
|
1491
1491
|
|
|
1492
1492
|
function createRouter(init) {
|
|
1493
1493
|
invariant(init.routes.length > 0, "You must provide a non-empty routes array to createRouter");
|
|
1494
|
-
let dataRoutes = convertRoutesToDataRoutes(init.routes);
|
|
1494
|
+
let dataRoutes = convertRoutesToDataRoutes(init.routes);
|
|
1495
|
+
let inFlightDataRoutes; // Cleanup function for history
|
|
1495
1496
|
|
|
1496
1497
|
let unlistenHistory = null; // Externally-provided functions to call on all state changes
|
|
1497
1498
|
|
|
@@ -1727,6 +1728,12 @@
|
|
|
1727
1728
|
|
|
1728
1729
|
|
|
1729
1730
|
let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && ((_location$state2 = location.state) == null ? void 0 : _location$state2._isRedirect) !== true;
|
|
1731
|
+
|
|
1732
|
+
if (inFlightDataRoutes) {
|
|
1733
|
+
dataRoutes = inFlightDataRoutes;
|
|
1734
|
+
inFlightDataRoutes = undefined;
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1730
1737
|
updateState(_extends({}, newState, {
|
|
1731
1738
|
// matches, errors, fetchers go through as-is
|
|
1732
1739
|
actionData,
|
|
@@ -1882,8 +1889,9 @@
|
|
|
1882
1889
|
|
|
1883
1890
|
saveScrollPosition(state.location, state.matches);
|
|
1884
1891
|
pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;
|
|
1892
|
+
let routesToUse = inFlightDataRoutes || dataRoutes;
|
|
1885
1893
|
let loadingNavigation = opts && opts.overrideNavigation;
|
|
1886
|
-
let matches = matchRoutes(
|
|
1894
|
+
let matches = matchRoutes(routesToUse, location, init.basename); // Short circuit with a 404 on the root error boundary if we match nothing
|
|
1887
1895
|
|
|
1888
1896
|
if (!matches) {
|
|
1889
1897
|
let error = getInternalRouterError(404, {
|
|
@@ -1892,7 +1900,7 @@
|
|
|
1892
1900
|
let {
|
|
1893
1901
|
matches: notFoundMatches,
|
|
1894
1902
|
route
|
|
1895
|
-
} = getShortCircuitMatches(
|
|
1903
|
+
} = getShortCircuitMatches(routesToUse); // Cancel all pending deferred on 404s since we don't keep any routes
|
|
1896
1904
|
|
|
1897
1905
|
cancelActiveDeferreds();
|
|
1898
1906
|
completeNavigation(location, {
|
|
@@ -2097,7 +2105,8 @@
|
|
|
2097
2105
|
formData: loadingNavigation.formData,
|
|
2098
2106
|
formEncType: loadingNavigation.formEncType
|
|
2099
2107
|
} : undefined;
|
|
2100
|
-
let
|
|
2108
|
+
let routesToUse = inFlightDataRoutes || dataRoutes;
|
|
2109
|
+
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, routesToUse, init.basename, pendingActionData, pendingError); // Cancel pending deferreds for no-longer-matched routes or routes we're
|
|
2101
2110
|
// about to reload. Note that if this is an action reload we would have
|
|
2102
2111
|
// already cancelled all pending deferreds so this would be a no-op
|
|
2103
2112
|
|
|
@@ -2214,7 +2223,8 @@
|
|
|
2214
2223
|
}
|
|
2215
2224
|
|
|
2216
2225
|
if (fetchControllers.has(key)) abortFetcher(key);
|
|
2217
|
-
let
|
|
2226
|
+
let routesToUse = inFlightDataRoutes || dataRoutes;
|
|
2227
|
+
let matches = matchRoutes(routesToUse, href, init.basename);
|
|
2218
2228
|
|
|
2219
2229
|
if (!matches) {
|
|
2220
2230
|
setFetcherError(key, routeId, getInternalRouterError(404, {
|
|
@@ -2239,9 +2249,7 @@
|
|
|
2239
2249
|
|
|
2240
2250
|
fetchLoadMatches.set(key, {
|
|
2241
2251
|
routeId,
|
|
2242
|
-
path
|
|
2243
|
-
match,
|
|
2244
|
-
matches
|
|
2252
|
+
path
|
|
2245
2253
|
});
|
|
2246
2254
|
handleFetcherLoader(key, routeId, path, match, matches, submission);
|
|
2247
2255
|
} // Call the action for the matched fetcher.submit(), and then handle redirects,
|
|
@@ -2328,7 +2336,8 @@
|
|
|
2328
2336
|
|
|
2329
2337
|
let nextLocation = state.navigation.location || state.location;
|
|
2330
2338
|
let revalidationRequest = createClientSideRequest(init.history, nextLocation, abortController.signal);
|
|
2331
|
-
let
|
|
2339
|
+
let routesToUse = inFlightDataRoutes || dataRoutes;
|
|
2340
|
+
let matches = state.navigation.state !== "idle" ? matchRoutes(routesToUse, state.navigation.location, init.basename) : state.matches;
|
|
2332
2341
|
invariant(matches, "Didn't find any matches after fetcher action");
|
|
2333
2342
|
let loadId = ++incrementingLoadId;
|
|
2334
2343
|
fetchReloadIds.set(key, loadId);
|
|
@@ -2341,10 +2350,10 @@
|
|
|
2341
2350
|
});
|
|
2342
2351
|
|
|
2343
2352
|
state.fetchers.set(key, loadFetcher);
|
|
2344
|
-
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, {
|
|
2353
|
+
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, routesToUse, init.basename, {
|
|
2345
2354
|
[match.route.id]: actionResult.data
|
|
2346
|
-
}, undefined
|
|
2347
|
-
|
|
2355
|
+
}, undefined // No need to send through errors since we short circuit above
|
|
2356
|
+
); // Put all revalidating fetchers into the loading state, except for the
|
|
2348
2357
|
// current fetcher which we want to keep in it's current loading state which
|
|
2349
2358
|
// contains it's action submission info + action data
|
|
2350
2359
|
|
|
@@ -2550,9 +2559,10 @@
|
|
|
2550
2559
|
invariant(redirectLocation, "Expected a location on the redirect navigation"); // Check if this an absolute external redirect that goes to a new origin
|
|
2551
2560
|
|
|
2552
2561
|
if (ABSOLUTE_URL_REGEX.test(redirect.location) && isBrowser && typeof ((_window = window) == null ? void 0 : _window.location) !== "undefined") {
|
|
2553
|
-
let
|
|
2562
|
+
let url = init.history.createURL(redirect.location);
|
|
2563
|
+
let isDifferentBasename = stripBasename(url.pathname, init.basename || "/") == null;
|
|
2554
2564
|
|
|
2555
|
-
if (window.location.origin !==
|
|
2565
|
+
if (window.location.origin !== url.origin || isDifferentBasename) {
|
|
2556
2566
|
if (replace) {
|
|
2557
2567
|
window.location.replace(redirect.location);
|
|
2558
2568
|
} else {
|
|
@@ -2618,7 +2628,19 @@
|
|
|
2618
2628
|
// Call all navigation loaders and revalidating fetcher loaders in parallel,
|
|
2619
2629
|
// then slice off the results into separate arrays so we can handle them
|
|
2620
2630
|
// accordingly
|
|
2621
|
-
let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(f =>
|
|
2631
|
+
let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(f => {
|
|
2632
|
+
if (f.matches && f.match) {
|
|
2633
|
+
return callLoaderOrAction("loader", createClientSideRequest(init.history, f.path, request.signal), f.match, f.matches, router.basename);
|
|
2634
|
+
} else {
|
|
2635
|
+
let error = {
|
|
2636
|
+
type: ResultType.error,
|
|
2637
|
+
error: getInternalRouterError(404, {
|
|
2638
|
+
pathname: f.path
|
|
2639
|
+
})
|
|
2640
|
+
};
|
|
2641
|
+
return error;
|
|
2642
|
+
}
|
|
2643
|
+
})]);
|
|
2622
2644
|
let loaderResults = results.slice(0, matchesToLoad.length);
|
|
2623
2645
|
let fetcherResults = results.slice(matchesToLoad.length);
|
|
2624
2646
|
await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, request.signal, false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(f => f.match), fetcherResults, request.signal, true)]);
|
|
@@ -2853,6 +2875,10 @@
|
|
|
2853
2875
|
return null;
|
|
2854
2876
|
}
|
|
2855
2877
|
|
|
2878
|
+
function _internalSetRoutes(newRoutes) {
|
|
2879
|
+
inFlightDataRoutes = newRoutes;
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2856
2882
|
router = {
|
|
2857
2883
|
get basename() {
|
|
2858
2884
|
return init.basename;
|
|
@@ -2882,7 +2908,10 @@
|
|
|
2882
2908
|
getBlocker,
|
|
2883
2909
|
deleteBlocker,
|
|
2884
2910
|
_internalFetchControllers: fetchControllers,
|
|
2885
|
-
_internalActiveDeferreds: activeDeferreds
|
|
2911
|
+
_internalActiveDeferreds: activeDeferreds,
|
|
2912
|
+
// TODO: Remove setRoutes, it's temporary to avoid dealing with
|
|
2913
|
+
// updating the tree while validating the update algorithm.
|
|
2914
|
+
_internalSetRoutes
|
|
2886
2915
|
};
|
|
2887
2916
|
return router;
|
|
2888
2917
|
} //#endregion
|
|
@@ -3383,7 +3412,7 @@
|
|
|
3383
3412
|
return boundaryMatches;
|
|
3384
3413
|
}
|
|
3385
3414
|
|
|
3386
|
-
function getMatchesToLoad(history, state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError
|
|
3415
|
+
function getMatchesToLoad(history, state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, routesToUse, basename, pendingActionData, pendingError) {
|
|
3387
3416
|
let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined;
|
|
3388
3417
|
let currentUrl = history.createURL(state.location);
|
|
3389
3418
|
let nextUrl = history.createURL(location);
|
|
@@ -3422,36 +3451,56 @@
|
|
|
3422
3451
|
}); // Pick fetcher.loads that need to be revalidated
|
|
3423
3452
|
|
|
3424
3453
|
let revalidatingFetchers = [];
|
|
3425
|
-
fetchLoadMatches
|
|
3454
|
+
fetchLoadMatches.forEach((f, key) => {
|
|
3455
|
+
// Don't revalidate if fetcher won't be present in the subsequent render
|
|
3426
3456
|
if (!matches.some(m => m.route.id === f.routeId)) {
|
|
3427
|
-
// This fetcher is not going to be present in the subsequent render so
|
|
3428
|
-
// there's no need to revalidate it
|
|
3429
3457
|
return;
|
|
3430
|
-
}
|
|
3431
|
-
|
|
3458
|
+
}
|
|
3459
|
+
|
|
3460
|
+
let fetcherMatches = matchRoutes(routesToUse, f.path, basename); // If the fetcher path no longer matches, push it in with null matches so
|
|
3461
|
+
// we can trigger a 404 in callLoadersAndMaybeResolveData
|
|
3462
|
+
|
|
3463
|
+
if (!fetcherMatches) {
|
|
3432
3464
|
revalidatingFetchers.push(_extends({
|
|
3433
3465
|
key
|
|
3434
|
-
}, f
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
// hit a static href, so they _always_ check shouldRevalidate and the
|
|
3438
|
-
// default is strictly if a revalidation is explicitly required (action
|
|
3439
|
-
// submissions, useRevalidator, X-Remix-Revalidate).
|
|
3440
|
-
let shouldRevalidate = shouldRevalidateLoader(f.match, _extends({
|
|
3441
|
-
currentUrl,
|
|
3442
|
-
currentParams: state.matches[state.matches.length - 1].params,
|
|
3443
|
-
nextUrl,
|
|
3444
|
-
nextParams: matches[matches.length - 1].params
|
|
3445
|
-
}, submission, {
|
|
3446
|
-
actionResult,
|
|
3447
|
-
defaultShouldRevalidate
|
|
3466
|
+
}, f, {
|
|
3467
|
+
matches: null,
|
|
3468
|
+
match: null
|
|
3448
3469
|
}));
|
|
3470
|
+
return;
|
|
3471
|
+
}
|
|
3449
3472
|
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3473
|
+
let fetcherMatch = getTargetMatch(fetcherMatches, f.path);
|
|
3474
|
+
|
|
3475
|
+
if (cancelledFetcherLoads.includes(key)) {
|
|
3476
|
+
revalidatingFetchers.push(_extends({
|
|
3477
|
+
key,
|
|
3478
|
+
matches: fetcherMatches,
|
|
3479
|
+
match: fetcherMatch
|
|
3480
|
+
}, f));
|
|
3481
|
+
return;
|
|
3482
|
+
} // Revalidating fetchers are decoupled from the route matches since they
|
|
3483
|
+
// hit a static href, so they _always_ check shouldRevalidate and the
|
|
3484
|
+
// default is strictly if a revalidation is explicitly required (action
|
|
3485
|
+
// submissions, useRevalidator, X-Remix-Revalidate).
|
|
3486
|
+
|
|
3487
|
+
|
|
3488
|
+
let shouldRevalidate = shouldRevalidateLoader(fetcherMatch, _extends({
|
|
3489
|
+
currentUrl,
|
|
3490
|
+
currentParams: state.matches[state.matches.length - 1].params,
|
|
3491
|
+
nextUrl,
|
|
3492
|
+
nextParams: matches[matches.length - 1].params
|
|
3493
|
+
}, submission, {
|
|
3494
|
+
actionResult,
|
|
3495
|
+
defaultShouldRevalidate
|
|
3496
|
+
}));
|
|
3497
|
+
|
|
3498
|
+
if (shouldRevalidate) {
|
|
3499
|
+
revalidatingFetchers.push(_extends({
|
|
3500
|
+
key,
|
|
3501
|
+
matches: fetcherMatches,
|
|
3502
|
+
match: fetcherMatch
|
|
3503
|
+
}, f));
|
|
3455
3504
|
}
|
|
3456
3505
|
});
|
|
3457
3506
|
return [navigationMatches, revalidatingFetchers];
|
|
@@ -3548,13 +3597,14 @@
|
|
|
3548
3597
|
|
|
3549
3598
|
location = createPath(resolvedLocation);
|
|
3550
3599
|
} else if (!isStaticRequest) {
|
|
3551
|
-
// Strip off the protocol+origin for same-origin absolute
|
|
3552
|
-
// If this is a static
|
|
3553
|
-
// as-is
|
|
3600
|
+
// Strip off the protocol+origin for same-origin + same-basename absolute
|
|
3601
|
+
// redirects. If this is a static request, we can let it go back to the
|
|
3602
|
+
// browser as-is
|
|
3554
3603
|
let currentUrl = new URL(request.url);
|
|
3555
3604
|
let url = location.startsWith("//") ? new URL(currentUrl.protocol + location) : new URL(location);
|
|
3605
|
+
let isSameBasename = stripBasename(url.pathname, basename) != null;
|
|
3556
3606
|
|
|
3557
|
-
if (url.origin === currentUrl.origin) {
|
|
3607
|
+
if (url.origin === currentUrl.origin && isSameBasename) {
|
|
3558
3608
|
location = url.pathname + url.search + url.hash;
|
|
3559
3609
|
}
|
|
3560
3610
|
} // Don't process redirects in the router during static requests requests.
|
|
@@ -3621,9 +3671,13 @@
|
|
|
3621
3671
|
}
|
|
3622
3672
|
|
|
3623
3673
|
if (result instanceof DeferredData) {
|
|
3674
|
+
var _result$init, _result$init2;
|
|
3675
|
+
|
|
3624
3676
|
return {
|
|
3625
3677
|
type: ResultType.deferred,
|
|
3626
|
-
deferredData: result
|
|
3678
|
+
deferredData: result,
|
|
3679
|
+
statusCode: (_result$init = result.init) == null ? void 0 : _result$init.status,
|
|
3680
|
+
headers: ((_result$init2 = result.init) == null ? void 0 : _result$init2.headers) && new Headers(result.init.headers)
|
|
3627
3681
|
};
|
|
3628
3682
|
}
|
|
3629
3683
|
|
|
@@ -3760,7 +3814,7 @@
|
|
|
3760
3814
|
let result = fetcherResults[index]; // Process fetcher non-redirect errors
|
|
3761
3815
|
|
|
3762
3816
|
if (isErrorResult(result)) {
|
|
3763
|
-
let boundaryMatch = findNearestBoundary(state.matches, match.route.id);
|
|
3817
|
+
let boundaryMatch = findNearestBoundary(state.matches, match == null ? void 0 : match.route.id);
|
|
3764
3818
|
|
|
3765
3819
|
if (!(errors && errors[boundaryMatch.route.id])) {
|
|
3766
3820
|
errors = _extends({}, errors, {
|
|
@@ -3807,7 +3861,9 @@
|
|
|
3807
3861
|
if (newLoaderData[id] !== undefined) {
|
|
3808
3862
|
mergedLoaderData[id] = newLoaderData[id];
|
|
3809
3863
|
}
|
|
3810
|
-
} else if (loaderData[id] !== undefined) {
|
|
3864
|
+
} else if (loaderData[id] !== undefined && match.route.loader) {
|
|
3865
|
+
// Preserve existing keys not included in newLoaderData and where a loader
|
|
3866
|
+
// wasn't removed by HMR
|
|
3811
3867
|
mergedLoaderData[id] = loaderData[id];
|
|
3812
3868
|
}
|
|
3813
3869
|
|
|
@@ -3944,7 +4000,14 @@
|
|
|
3944
4000
|
async function resolveDeferredResults(currentMatches, matchesToLoad, results, signal, isFetcher, currentLoaderData) {
|
|
3945
4001
|
for (let index = 0; index < results.length; index++) {
|
|
3946
4002
|
let result = results[index];
|
|
3947
|
-
let match = matchesToLoad[index];
|
|
4003
|
+
let match = matchesToLoad[index]; // If we don't have a match, then we can have a deferred result to do
|
|
4004
|
+
// anything with. This is for revalidating fetchers where the route was
|
|
4005
|
+
// removed during HMR
|
|
4006
|
+
|
|
4007
|
+
if (!match) {
|
|
4008
|
+
continue;
|
|
4009
|
+
}
|
|
4010
|
+
|
|
3948
4011
|
let currentMatch = currentMatches.find(m => m.route.id === match.route.id);
|
|
3949
4012
|
let isRevalidatingLoader = currentMatch != null && !isNewRouteInstance(currentMatch, match) && (currentLoaderData && currentLoaderData[match.route.id]) !== undefined;
|
|
3950
4013
|
|
|
@@ -4037,6 +4100,7 @@
|
|
|
4037
4100
|
exports.UNSAFE_DeferredData = DeferredData;
|
|
4038
4101
|
exports.UNSAFE_convertRoutesToDataRoutes = convertRoutesToDataRoutes;
|
|
4039
4102
|
exports.UNSAFE_getPathContributingMatches = getPathContributingMatches;
|
|
4103
|
+
exports.UNSAFE_invariant = invariant;
|
|
4040
4104
|
exports.createBrowserHistory = createBrowserHistory;
|
|
4041
4105
|
exports.createHashHistory = createHashHistory;
|
|
4042
4106
|
exports.createMemoryHistory = createMemoryHistory;
|
|
@@ -4047,7 +4111,6 @@
|
|
|
4047
4111
|
exports.generatePath = generatePath;
|
|
4048
4112
|
exports.getStaticContextFromError = getStaticContextFromError;
|
|
4049
4113
|
exports.getToPathname = getToPathname;
|
|
4050
|
-
exports.invariant = invariant;
|
|
4051
4114
|
exports.isRouteErrorResponse = isRouteErrorResponse;
|
|
4052
4115
|
exports.joinPaths = joinPaths;
|
|
4053
4116
|
exports.json = json;
|