@remix-run/router 0.0.0-experimental-c9f8a7b2 → 0.0.0-experimental-e960cf1a
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 +8 -199
- package/dist/index.d.ts +2 -2
- package/dist/router.cjs.js +138 -90
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +3 -2
- package/dist/router.js +135 -91
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +138 -90
- 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 +13 -0
- package/index.ts +5 -0
- package/package.json +1 -1
- package/router.ts +243 -124
- package/utils.ts +25 -9
package/dist/router.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v0.0.0-experimental-
|
|
2
|
+
* @remix-run/router v0.0.0-experimental-e960cf1a
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -891,7 +891,7 @@
|
|
|
891
891
|
branches.sort((a, b) => a.score !== b.score ? b.score - a.score // Higher score first
|
|
892
892
|
: compareIndexes(a.routesMeta.map(meta => meta.childrenIndex), b.routesMeta.map(meta => meta.childrenIndex)));
|
|
893
893
|
}
|
|
894
|
-
const paramRe =
|
|
894
|
+
const paramRe = /^:\w+$/;
|
|
895
895
|
const dynamicSegmentValue = 3;
|
|
896
896
|
const indexRouteValue = 2;
|
|
897
897
|
const emptySegmentValue = 1;
|
|
@@ -981,7 +981,7 @@
|
|
|
981
981
|
// Apply the splat
|
|
982
982
|
return stringify(params[star]);
|
|
983
983
|
}
|
|
984
|
-
const keyMatch = segment.match(/^:(
|
|
984
|
+
const keyMatch = segment.match(/^:(\w+)(\??)$/);
|
|
985
985
|
if (keyMatch) {
|
|
986
986
|
const [, key, optional] = keyMatch;
|
|
987
987
|
let param = params[key];
|
|
@@ -1063,7 +1063,7 @@
|
|
|
1063
1063
|
let regexpSource = "^" + path.replace(/\/*\*?$/, "") // Ignore trailing / and /*, we'll handle it below
|
|
1064
1064
|
.replace(/^\/*/, "/") // Make sure it has a leading /
|
|
1065
1065
|
.replace(/[\\.*+^${}|()[\]]/g, "\\$&") // Escape special regex chars
|
|
1066
|
-
.replace(/\/:(
|
|
1066
|
+
.replace(/\/:(\w+)(\?)?/g, (_, paramName, isOptional) => {
|
|
1067
1067
|
params.push({
|
|
1068
1068
|
paramName,
|
|
1069
1069
|
isOptional: isOptional != null
|
|
@@ -1656,6 +1656,8 @@
|
|
|
1656
1656
|
const isBrowser = typeof routerWindow !== "undefined" && typeof routerWindow.document !== "undefined" && typeof routerWindow.document.createElement !== "undefined";
|
|
1657
1657
|
const isServer = !isBrowser;
|
|
1658
1658
|
invariant(init.routes.length > 0, "You must provide a non-empty routes array to createRouter");
|
|
1659
|
+
const dataStrategy = init.unstable_dataStrategy || defaultDataStrategy;
|
|
1660
|
+
const callLoaderOrAction = createCallLoaderOrAction(dataStrategy);
|
|
1659
1661
|
let mapRouteProperties;
|
|
1660
1662
|
if (init.mapRouteProperties) {
|
|
1661
1663
|
mapRouteProperties = init.mapRouteProperties;
|
|
@@ -1717,28 +1719,18 @@
|
|
|
1717
1719
|
[route.id]: error
|
|
1718
1720
|
};
|
|
1719
1721
|
}
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
// provided with hydrationData for every route with a loader, and no loaders
|
|
1733
|
-
// were marked for explicit hydration
|
|
1734
|
-
let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;
|
|
1735
|
-
let errors = init.hydrationData ? init.hydrationData.errors : null;
|
|
1736
|
-
initialized = initialMatches.every(m => m.route.loader && m.route.loader.hydrate !== true && (loaderData && loaderData[m.route.id] !== undefined || errors && errors[m.route.id] !== undefined));
|
|
1737
|
-
} else {
|
|
1738
|
-
// Without partial hydration - we're initialized if we were provided any
|
|
1739
|
-
// hydrationData - which is expected to be complete
|
|
1740
|
-
initialized = init.hydrationData != null;
|
|
1741
|
-
}
|
|
1722
|
+
|
|
1723
|
+
// "Initialized" here really means "Can `RouterProvider` render my route tree?"
|
|
1724
|
+
// Prior to `route.HydrateFallback`, we only had a root `fallbackElement` so we used
|
|
1725
|
+
// `state.initialized` to render that instead of `<DataRoutes>`. Now that we
|
|
1726
|
+
// support route level fallbacks we can always render and we'll just render
|
|
1727
|
+
// as deep as we have data for and detect the nearest ancestor HydrateFallback
|
|
1728
|
+
let initialized = future.v7_partialHydration ||
|
|
1729
|
+
// All initialMatches need to be loaded before we're ready. If we have lazy
|
|
1730
|
+
// functions around still then we'll need to run them in initialize()
|
|
1731
|
+
!initialMatches.some(m => m.route.lazy) && (
|
|
1732
|
+
// And we have to either have no loaders or have been provided hydrationData
|
|
1733
|
+
!initialMatches.some(m => m.route.loader) || init.hydrationData != null);
|
|
1742
1734
|
let router;
|
|
1743
1735
|
let state = {
|
|
1744
1736
|
historyAction: init.history.action,
|
|
@@ -1905,7 +1897,7 @@
|
|
|
1905
1897
|
// in the normal navigation flow. For SSR it's expected that lazy modules are
|
|
1906
1898
|
// resolved prior to router creation since we can't go into a fallbackElement
|
|
1907
1899
|
// UI for SSR'd apps
|
|
1908
|
-
if (!state.initialized) {
|
|
1900
|
+
if (!state.initialized || future.v7_partialHydration && state.matches.some(m => isUnhydratedRoute(state, m.route))) {
|
|
1909
1901
|
startNavigation(Action.Pop, state.location, {
|
|
1910
1902
|
initialHydration: true
|
|
1911
1903
|
});
|
|
@@ -2484,10 +2476,9 @@
|
|
|
2484
2476
|
pendingNavigationController.signal.addEventListener("abort", abortPendingFetchRevalidations);
|
|
2485
2477
|
}
|
|
2486
2478
|
let {
|
|
2487
|
-
results,
|
|
2488
2479
|
loaderResults,
|
|
2489
2480
|
fetcherResults
|
|
2490
|
-
} = await
|
|
2481
|
+
} = await loadDataAndMaybeResolveDeferred(state.matches, matches, matchesToLoad, revalidatingFetchers, request);
|
|
2491
2482
|
if (request.signal.aborted) {
|
|
2492
2483
|
return {
|
|
2493
2484
|
shortCircuited: true
|
|
@@ -2503,7 +2494,7 @@
|
|
|
2503
2494
|
revalidatingFetchers.forEach(rf => fetchControllers.delete(rf.key));
|
|
2504
2495
|
|
|
2505
2496
|
// If any loaders returned a redirect Response, start a new REPLACE navigation
|
|
2506
|
-
let redirect = findRedirect(
|
|
2497
|
+
let redirect = findRedirect([...loaderResults, ...fetcherResults]);
|
|
2507
2498
|
if (redirect) {
|
|
2508
2499
|
if (redirect.idx >= matchesToLoad.length) {
|
|
2509
2500
|
// If this redirect came from a fetcher make sure we mark it in
|
|
@@ -2708,10 +2699,9 @@
|
|
|
2708
2699
|
let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach(rf => abortFetcher(rf.key));
|
|
2709
2700
|
abortController.signal.addEventListener("abort", abortPendingFetchRevalidations);
|
|
2710
2701
|
let {
|
|
2711
|
-
results,
|
|
2712
2702
|
loaderResults,
|
|
2713
2703
|
fetcherResults
|
|
2714
|
-
} = await
|
|
2704
|
+
} = await loadDataAndMaybeResolveDeferred(state.matches, matches, matchesToLoad, revalidatingFetchers, revalidationRequest);
|
|
2715
2705
|
if (abortController.signal.aborted) {
|
|
2716
2706
|
return;
|
|
2717
2707
|
}
|
|
@@ -2719,7 +2709,7 @@
|
|
|
2719
2709
|
fetchReloadIds.delete(key);
|
|
2720
2710
|
fetchControllers.delete(key);
|
|
2721
2711
|
revalidatingFetchers.forEach(r => fetchControllers.delete(r.key));
|
|
2722
|
-
let redirect = findRedirect(
|
|
2712
|
+
let redirect = findRedirect([...loaderResults, ...fetcherResults]);
|
|
2723
2713
|
if (redirect) {
|
|
2724
2714
|
if (redirect.idx >= matchesToLoad.length) {
|
|
2725
2715
|
// If this redirect came from a fetcher make sure we mark it in
|
|
@@ -2929,28 +2919,36 @@
|
|
|
2929
2919
|
});
|
|
2930
2920
|
}
|
|
2931
2921
|
}
|
|
2932
|
-
async function
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
return
|
|
2939
|
-
}
|
|
2940
|
-
|
|
2922
|
+
async function loadDataAndMaybeResolveDeferred(currentMatches, matches, matchesToLoad, fetchersToLoad, request) {
|
|
2923
|
+
let [loaderResults, ...fetcherResults] = await Promise.all([matchesToLoad.length ? dataStrategy({
|
|
2924
|
+
matches: matchesToLoad.map(m => finesseToAgnosticDataStrategyMatch(m, mapRouteProperties, manifest)),
|
|
2925
|
+
request,
|
|
2926
|
+
type: "loader",
|
|
2927
|
+
defaultStrategy(match) {
|
|
2928
|
+
return callLoaderOrActionImplementation("loader", request, match, matches, basename, future.v7_relativeSplatPath);
|
|
2929
|
+
}
|
|
2930
|
+
}) : [], ...fetchersToLoad.map(f => {
|
|
2931
|
+
if (!f.matches || !f.match || !f.controller) {
|
|
2932
|
+
return Promise.resolve({
|
|
2941
2933
|
type: ResultType.error,
|
|
2942
2934
|
error: getInternalRouterError(404, {
|
|
2943
2935
|
pathname: f.path
|
|
2944
2936
|
})
|
|
2945
|
-
};
|
|
2946
|
-
return error;
|
|
2937
|
+
});
|
|
2947
2938
|
}
|
|
2939
|
+
return dataStrategy({
|
|
2940
|
+
matches: [finesseToAgnosticDataStrategyMatch(f.match, mapRouteProperties, manifest)],
|
|
2941
|
+
request,
|
|
2942
|
+
type: "loader",
|
|
2943
|
+
defaultStrategy(match) {
|
|
2944
|
+
invariant(f.controller, "Expected controller for fetcher in defaultStrategy");
|
|
2945
|
+
invariant(f.matches, "Expected matches for fetcher in defaultStrategy");
|
|
2946
|
+
return callLoaderOrActionImplementation("loader", createClientSideRequest(init.history, f.path, f.controller.signal), match, f.matches, basename, future.v7_relativeSplatPath);
|
|
2947
|
+
}
|
|
2948
|
+
}).then(r => r[0]);
|
|
2948
2949
|
})]);
|
|
2949
|
-
let loaderResults = results.slice(0, matchesToLoad.length);
|
|
2950
|
-
let fetcherResults = results.slice(matchesToLoad.length);
|
|
2951
2950
|
await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, loaderResults.map(() => request.signal), false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(f => f.match), fetcherResults, fetchersToLoad.map(f => f.controller ? f.controller.signal : null), true)]);
|
|
2952
2951
|
return {
|
|
2953
|
-
results,
|
|
2954
2952
|
loaderResults,
|
|
2955
2953
|
fetcherResults
|
|
2956
2954
|
};
|
|
@@ -3261,6 +3259,8 @@
|
|
|
3261
3259
|
|
|
3262
3260
|
function createStaticHandler(routes, opts) {
|
|
3263
3261
|
invariant(routes.length > 0, "You must provide a non-empty routes array to createStaticHandler");
|
|
3262
|
+
const dataStrategy = (opts == null ? void 0 : opts.dataStrategy) || defaultDataStrategy;
|
|
3263
|
+
const callLoaderOrAction = createCallLoaderOrAction(dataStrategy);
|
|
3264
3264
|
let manifest = {};
|
|
3265
3265
|
let basename = (opts ? opts.basename : null) || "/";
|
|
3266
3266
|
let mapRouteProperties;
|
|
@@ -3277,8 +3277,7 @@
|
|
|
3277
3277
|
}
|
|
3278
3278
|
// Config driven behavior flags
|
|
3279
3279
|
let future = _extends({
|
|
3280
|
-
v7_relativeSplatPath: false
|
|
3281
|
-
v7_throwAbortReason: false
|
|
3280
|
+
v7_relativeSplatPath: false
|
|
3282
3281
|
}, opts ? opts.future : null);
|
|
3283
3282
|
let dataRoutes = convertRoutesToDataRoutes(routes, mapRouteProperties, undefined, manifest);
|
|
3284
3283
|
|
|
@@ -3501,7 +3500,8 @@
|
|
|
3501
3500
|
requestContext
|
|
3502
3501
|
});
|
|
3503
3502
|
if (request.signal.aborted) {
|
|
3504
|
-
|
|
3503
|
+
let method = isRouteRequest ? "queryRoute" : "query";
|
|
3504
|
+
throw new Error(method + "() call aborted: " + request.method + " " + request.url);
|
|
3505
3505
|
}
|
|
3506
3506
|
}
|
|
3507
3507
|
if (isRedirectResult(result)) {
|
|
@@ -3613,13 +3613,21 @@
|
|
|
3613
3613
|
activeDeferreds: null
|
|
3614
3614
|
};
|
|
3615
3615
|
}
|
|
3616
|
-
let results = await
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3616
|
+
let results = await dataStrategy({
|
|
3617
|
+
matches: matchesToLoad.map(m => finesseToAgnosticDataStrategyMatch(m, mapRouteProperties, manifest)),
|
|
3618
|
+
request,
|
|
3619
|
+
type: "loader",
|
|
3620
|
+
defaultStrategy(match) {
|
|
3621
|
+
return callLoaderOrActionImplementation("loader", request, match, matches, basename, future.v7_relativeSplatPath, {
|
|
3622
|
+
isStaticRequest: true,
|
|
3623
|
+
isRouteRequest,
|
|
3624
|
+
requestContext
|
|
3625
|
+
});
|
|
3626
|
+
}
|
|
3627
|
+
});
|
|
3621
3628
|
if (request.signal.aborted) {
|
|
3622
|
-
|
|
3629
|
+
let method = isRouteRequest ? "queryRoute" : "query";
|
|
3630
|
+
throw new Error(method + "() call aborted: " + request.method + " " + request.url);
|
|
3623
3631
|
}
|
|
3624
3632
|
|
|
3625
3633
|
// Process and commit output from loaders
|
|
@@ -3651,6 +3659,14 @@
|
|
|
3651
3659
|
//#region Helpers
|
|
3652
3660
|
////////////////////////////////////////////////////////////////////////////////
|
|
3653
3661
|
|
|
3662
|
+
function defaultDataStrategy(_ref3) {
|
|
3663
|
+
let {
|
|
3664
|
+
defaultStrategy,
|
|
3665
|
+
matches
|
|
3666
|
+
} = _ref3;
|
|
3667
|
+
return Promise.all(matches.map(match => defaultStrategy(match)));
|
|
3668
|
+
}
|
|
3669
|
+
|
|
3654
3670
|
/**
|
|
3655
3671
|
* Given an existing StaticHandlerContext and an error thrown at render time,
|
|
3656
3672
|
* provide an updated StaticHandlerContext suitable for a second SSR render
|
|
@@ -3664,13 +3680,6 @@
|
|
|
3664
3680
|
});
|
|
3665
3681
|
return newContext;
|
|
3666
3682
|
}
|
|
3667
|
-
function throwStaticHandlerAbortedError(request, isRouteRequest, future) {
|
|
3668
|
-
if (future.v7_throwAbortReason && request.signal.reason !== undefined) {
|
|
3669
|
-
throw request.signal.reason;
|
|
3670
|
-
}
|
|
3671
|
-
let method = isRouteRequest ? "queryRoute" : "query";
|
|
3672
|
-
throw new Error(method + "() call aborted: " + request.method + " " + request.url);
|
|
3673
|
-
}
|
|
3674
3683
|
function isSubmissionNavigation(opts) {
|
|
3675
3684
|
return opts != null && ("formData" in opts && opts.formData != null || "body" in opts && opts.body !== undefined);
|
|
3676
3685
|
}
|
|
@@ -3755,8 +3764,8 @@
|
|
|
3755
3764
|
}
|
|
3756
3765
|
let text = typeof opts.body === "string" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ?
|
|
3757
3766
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data
|
|
3758
|
-
Array.from(opts.body.entries()).reduce((acc,
|
|
3759
|
-
let [name, value] =
|
|
3767
|
+
Array.from(opts.body.entries()).reduce((acc, _ref4) => {
|
|
3768
|
+
let [name, value] = _ref4;
|
|
3760
3769
|
return "" + acc + name + "=" + value + "\n";
|
|
3761
3770
|
}, "") : String(opts.body);
|
|
3762
3771
|
return {
|
|
@@ -3867,24 +3876,18 @@
|
|
|
3867
3876
|
let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;
|
|
3868
3877
|
let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);
|
|
3869
3878
|
let navigationMatches = boundaryMatches.filter((match, index) => {
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3879
|
+
if (isInitialLoad) {
|
|
3880
|
+
// On initial hydration we don't do any shouldRevalidate stuff - we just
|
|
3881
|
+
// call the unhydrated loaders
|
|
3882
|
+
return isUnhydratedRoute(state, match.route);
|
|
3883
|
+
}
|
|
3884
|
+
if (match.route.lazy) {
|
|
3874
3885
|
// We haven't loaded this route yet so we don't know if it's got a loader!
|
|
3875
3886
|
return true;
|
|
3876
3887
|
}
|
|
3877
|
-
if (route.loader == null) {
|
|
3888
|
+
if (match.route.loader == null) {
|
|
3878
3889
|
return false;
|
|
3879
3890
|
}
|
|
3880
|
-
if (isInitialLoad) {
|
|
3881
|
-
if (route.loader.hydrate) {
|
|
3882
|
-
return true;
|
|
3883
|
-
}
|
|
3884
|
-
return state.loaderData[route.id] === undefined && (
|
|
3885
|
-
// Don't re-run if the loader ran and threw an error
|
|
3886
|
-
!state.errors || state.errors[route.id] === undefined);
|
|
3887
|
-
}
|
|
3888
3891
|
|
|
3889
3892
|
// Always call the loader on new route instances and pending defer cancellations
|
|
3890
3893
|
if (isNewLoader(state.loaderData, state.matches[index], match) || cancelledDeferredRoutes.some(id => id === match.route.id)) {
|
|
@@ -3986,6 +3989,20 @@
|
|
|
3986
3989
|
});
|
|
3987
3990
|
return [navigationMatches, revalidatingFetchers];
|
|
3988
3991
|
}
|
|
3992
|
+
|
|
3993
|
+
// Is this route unhydrated (when v7_partialHydration=true) such that we need
|
|
3994
|
+
// to call it's loader on the initial router creation
|
|
3995
|
+
function isUnhydratedRoute(state, route) {
|
|
3996
|
+
if (!route.loader) {
|
|
3997
|
+
return false;
|
|
3998
|
+
}
|
|
3999
|
+
if (route.loader.hydrate) {
|
|
4000
|
+
return true;
|
|
4001
|
+
}
|
|
4002
|
+
return state.loaderData[route.id] === undefined && (!state.errors ||
|
|
4003
|
+
// Loader ran but errored - don't re-run
|
|
4004
|
+
state.errors[route.id] === undefined);
|
|
4005
|
+
}
|
|
3989
4006
|
function isNewLoader(currentLoaderData, currentMatch, match) {
|
|
3990
4007
|
let isNew =
|
|
3991
4008
|
// [a] -> [a, b]
|
|
@@ -4027,7 +4044,7 @@
|
|
|
4027
4044
|
*/
|
|
4028
4045
|
async function loadLazyRouteModule(route, mapRouteProperties, manifest) {
|
|
4029
4046
|
if (!route.lazy) {
|
|
4030
|
-
return;
|
|
4047
|
+
return route;
|
|
4031
4048
|
}
|
|
4032
4049
|
let lazyRoute = await route.lazy();
|
|
4033
4050
|
|
|
@@ -4035,7 +4052,7 @@
|
|
|
4035
4052
|
// call then we can return - first lazy() to finish wins because the return
|
|
4036
4053
|
// value of lazy is expected to be static
|
|
4037
4054
|
if (!route.lazy) {
|
|
4038
|
-
return;
|
|
4055
|
+
return route;
|
|
4039
4056
|
}
|
|
4040
4057
|
let routeToUpdate = manifest[route.id];
|
|
4041
4058
|
invariant(routeToUpdate, "No route found in manifest");
|
|
@@ -4071,8 +4088,42 @@
|
|
|
4071
4088
|
Object.assign(routeToUpdate, _extends({}, mapRouteProperties(routeToUpdate), {
|
|
4072
4089
|
lazy: undefined
|
|
4073
4090
|
}));
|
|
4091
|
+
return routeToUpdate;
|
|
4092
|
+
}
|
|
4093
|
+
function createCallLoaderOrAction(dataStrategy) {
|
|
4094
|
+
return async function (type, request, match, matches, manifest, mapRouteProperties, basename, v7_relativeSplatPath, opts) {
|
|
4095
|
+
if (opts === void 0) {
|
|
4096
|
+
opts = {};
|
|
4097
|
+
}
|
|
4098
|
+
let [result] = await dataStrategy({
|
|
4099
|
+
matches: [finesseToAgnosticDataStrategyMatch(match, mapRouteProperties, manifest)],
|
|
4100
|
+
request,
|
|
4101
|
+
type,
|
|
4102
|
+
defaultStrategy(match) {
|
|
4103
|
+
return callLoaderOrActionImplementation(type, request, match, matches, basename, v7_relativeSplatPath, opts);
|
|
4104
|
+
}
|
|
4105
|
+
});
|
|
4106
|
+
return result;
|
|
4107
|
+
};
|
|
4074
4108
|
}
|
|
4075
|
-
|
|
4109
|
+
function finesseToAgnosticDataStrategyMatch(match, mapRouteProperties, manifest) {
|
|
4110
|
+
let loadRoutePromise;
|
|
4111
|
+
if (match.route.lazy) {
|
|
4112
|
+
try {
|
|
4113
|
+
loadRoutePromise = loadLazyRouteModule(match.route, mapRouteProperties, manifest);
|
|
4114
|
+
} catch (error) {
|
|
4115
|
+
loadRoutePromise = Promise.reject(error);
|
|
4116
|
+
}
|
|
4117
|
+
}
|
|
4118
|
+
if (!loadRoutePromise) {
|
|
4119
|
+
loadRoutePromise = Promise.resolve(match.route);
|
|
4120
|
+
}
|
|
4121
|
+
loadRoutePromise.catch(() => {});
|
|
4122
|
+
return _extends({}, match, {
|
|
4123
|
+
route: Object.assign(loadRoutePromise, match.route)
|
|
4124
|
+
});
|
|
4125
|
+
}
|
|
4126
|
+
async function callLoaderOrActionImplementation(type, request, match, matches, basename, v7_relativeSplatPath, opts) {
|
|
4076
4127
|
if (opts === void 0) {
|
|
4077
4128
|
opts = {};
|
|
4078
4129
|
}
|
|
@@ -4103,15 +4154,15 @@
|
|
|
4103
4154
|
// route has a boundary that can handle the error
|
|
4104
4155
|
runHandler(handler).catch(e => {
|
|
4105
4156
|
handlerError = e;
|
|
4106
|
-
}),
|
|
4157
|
+
}), match.route]);
|
|
4107
4158
|
if (handlerError) {
|
|
4108
4159
|
throw handlerError;
|
|
4109
4160
|
}
|
|
4110
4161
|
result = values[0];
|
|
4111
4162
|
} else {
|
|
4112
4163
|
// Load lazy route module, then run any returned handler
|
|
4113
|
-
await
|
|
4114
|
-
handler =
|
|
4164
|
+
let route = await match.route;
|
|
4165
|
+
handler = route[type];
|
|
4115
4166
|
if (handler) {
|
|
4116
4167
|
// Handler still run even if we got interrupted to maintain consistency
|
|
4117
4168
|
// with un-abortable behavior of handler execution on non-lazy or
|
|
@@ -4162,7 +4213,7 @@
|
|
|
4162
4213
|
|
|
4163
4214
|
// Support relative routing in internal redirects
|
|
4164
4215
|
if (!ABSOLUTE_URL_REGEX.test(location)) {
|
|
4165
|
-
location = normalizeTo(new URL(request.url), matches.slice(0, matches.
|
|
4216
|
+
location = normalizeTo(new URL(request.url), matches.slice(0, matches.findIndex(m => m.route.id === match.route.id) + 1), basename, true, location, v7_relativeSplatPath);
|
|
4166
4217
|
} else if (!opts.isStaticRequest) {
|
|
4167
4218
|
// Strip off the protocol+origin for same-origin + same-basename absolute
|
|
4168
4219
|
// redirects. If this is a static request, we can let it go back to the
|
|
@@ -4208,11 +4259,7 @@
|
|
|
4208
4259
|
// Check between word boundaries instead of startsWith() due to the last
|
|
4209
4260
|
// paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type
|
|
4210
4261
|
if (contentType && /\bapplication\/json\b/.test(contentType)) {
|
|
4211
|
-
|
|
4212
|
-
data = null;
|
|
4213
|
-
} else {
|
|
4214
|
-
data = await result.json();
|
|
4215
|
-
}
|
|
4262
|
+
data = await result.json();
|
|
4216
4263
|
} else {
|
|
4217
4264
|
data = await result.text();
|
|
4218
4265
|
}
|
|
@@ -4814,6 +4861,7 @@
|
|
|
4814
4861
|
exports.IDLE_BLOCKER = IDLE_BLOCKER;
|
|
4815
4862
|
exports.IDLE_FETCHER = IDLE_FETCHER;
|
|
4816
4863
|
exports.IDLE_NAVIGATION = IDLE_NAVIGATION;
|
|
4864
|
+
exports.ResultType = ResultType;
|
|
4817
4865
|
exports.UNSAFE_DEFERRED_SYMBOL = UNSAFE_DEFERRED_SYMBOL;
|
|
4818
4866
|
exports.UNSAFE_DeferredData = DeferredData;
|
|
4819
4867
|
exports.UNSAFE_ErrorResponseImpl = ErrorResponseImpl;
|