react-router 8.5.0 → 8.5.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 +44 -1
- package/dist/development/dom-export.js +1 -1
- package/dist/development/index-react-server-client.js +1 -1
- package/dist/development/index-react-server.d.ts +50 -396
- package/dist/development/index-react-server.js +43 -15
- package/dist/development/index.js +1 -1
- package/dist/development/lib/actions.js +1 -1
- package/dist/development/lib/await.js +58 -0
- package/dist/development/lib/components.d.ts +41 -5
- package/dist/development/lib/components.js +62 -4
- package/dist/development/lib/context.d.ts +2 -2
- package/dist/development/lib/context.js +1 -1
- package/dist/development/lib/dom/dom.js +1 -1
- package/dist/development/lib/dom/lib.js +1 -1
- package/dist/development/lib/dom/server.js +1 -1
- package/dist/development/lib/dom/ssr/components.js +1 -1
- package/dist/development/lib/dom/ssr/data.js +1 -1
- package/dist/development/lib/dom/ssr/errorBoundaries.js +1 -1
- package/dist/development/lib/dom/ssr/fallback.js +1 -1
- package/dist/development/lib/dom/ssr/fog-of-war.js +12 -3
- package/dist/development/lib/dom/ssr/hydration.js +1 -1
- package/dist/development/lib/dom/ssr/invariant.js +1 -1
- package/dist/development/lib/dom/ssr/links.js +1 -1
- package/dist/development/lib/dom/ssr/markup.js +1 -1
- package/dist/development/lib/dom/ssr/route-discovery.d.ts +2 -2
- package/dist/development/lib/dom/ssr/route-discovery.js +3 -3
- package/dist/development/lib/dom/ssr/routeModules.js +1 -1
- package/dist/development/lib/dom/ssr/routes-test-stub.js +1 -1
- package/dist/development/lib/dom/ssr/routes.js +1 -1
- package/dist/development/lib/dom/ssr/server.js +1 -1
- package/dist/development/lib/dom/ssr/single-fetch.d.ts +1 -1
- package/dist/development/lib/dom/ssr/single-fetch.js +7 -7
- package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/development/lib/dom-export/hydrated-router.js +2 -2
- package/dist/development/lib/errors.js +1 -1
- package/dist/development/lib/hooks.d.ts +0 -3
- package/dist/development/lib/hooks.js +5 -6
- package/dist/development/lib/href.js +1 -1
- package/dist/development/lib/router/history.js +1 -1
- package/dist/development/lib/router/instrumentation.js +1 -1
- package/dist/development/lib/router/matcher-route-pattern.js +1 -1
- package/dist/development/lib/router/matcher-route-pattern.preload.js +1 -1
- package/dist/development/lib/router/matcher.js +6 -1
- package/dist/development/lib/router/navigation.js +1 -1
- package/dist/development/lib/router/router.d.ts +2 -0
- package/dist/development/lib/router/router.js +58 -28
- package/dist/development/lib/router/url.js +1 -1
- package/dist/development/lib/router/utils.d.ts +7 -0
- package/dist/development/lib/router/utils.js +1 -1
- package/dist/development/lib/rsc/browser.js +3 -3
- package/dist/development/lib/rsc/errorBoundaries.js +1 -1
- package/dist/development/lib/rsc/html-stream/browser.js +1 -1
- package/dist/development/lib/rsc/html-stream/server.js +1 -1
- package/dist/development/lib/rsc/route-modules.js +1 -1
- package/dist/development/lib/rsc/server.ssr.js +1 -1
- package/dist/development/lib/server-runtime/cookies.js +1 -1
- package/dist/development/lib/server-runtime/crypto.js +1 -1
- package/dist/development/lib/server-runtime/data.js +1 -1
- package/dist/development/lib/server-runtime/dev.js +1 -1
- package/dist/development/lib/server-runtime/entry.js +1 -1
- package/dist/development/lib/server-runtime/errors.js +1 -1
- package/dist/development/lib/server-runtime/headers.js +1 -1
- package/dist/development/lib/server-runtime/invariant.js +1 -1
- package/dist/development/lib/server-runtime/mode.js +1 -1
- package/dist/development/lib/server-runtime/routeMatching.js +1 -1
- package/dist/development/lib/server-runtime/routes.js +1 -1
- package/dist/development/lib/server-runtime/server.js +13 -5
- package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
- package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
- package/dist/development/lib/server-runtime/sessions.js +2 -2
- package/dist/development/lib/server-runtime/single-fetch.js +1 -1
- package/dist/development/lib/server-runtime/urls.js +1 -1
- package/dist/development/lib/server-runtime/warnings.js +1 -1
- package/dist/development/lib/types/internal.js +1 -1
- package/dist/development/route-pattern.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/unflatten.js +23 -3
- package/dist/development/vendor/turbo-stream-v2/utils.js +1 -1
- package/dist/production/dom-export.js +1 -1
- package/dist/production/index-react-server-client.js +1 -1
- package/dist/production/index-react-server.d.ts +50 -396
- package/dist/production/index-react-server.js +43 -15
- package/dist/production/index.js +1 -1
- package/dist/production/lib/actions.js +1 -1
- package/dist/production/lib/await.js +58 -0
- package/dist/production/lib/components.d.ts +41 -5
- package/dist/production/lib/components.js +62 -4
- package/dist/production/lib/context.d.ts +2 -2
- package/dist/production/lib/context.js +1 -1
- package/dist/production/lib/dom/dom.js +1 -1
- package/dist/production/lib/dom/lib.js +1 -1
- package/dist/production/lib/dom/server.js +1 -1
- package/dist/production/lib/dom/ssr/components.js +1 -1
- package/dist/production/lib/dom/ssr/data.js +1 -1
- package/dist/production/lib/dom/ssr/errorBoundaries.js +1 -1
- package/dist/production/lib/dom/ssr/fallback.js +1 -1
- package/dist/production/lib/dom/ssr/fog-of-war.js +12 -3
- package/dist/production/lib/dom/ssr/hydration.js +1 -1
- package/dist/production/lib/dom/ssr/invariant.js +1 -1
- package/dist/production/lib/dom/ssr/links.js +1 -1
- package/dist/production/lib/dom/ssr/markup.js +1 -1
- package/dist/production/lib/dom/ssr/route-discovery.d.ts +2 -2
- package/dist/production/lib/dom/ssr/route-discovery.js +3 -3
- package/dist/production/lib/dom/ssr/routeModules.js +1 -1
- package/dist/production/lib/dom/ssr/routes-test-stub.js +1 -1
- package/dist/production/lib/dom/ssr/routes.js +1 -1
- package/dist/production/lib/dom/ssr/server.js +1 -1
- package/dist/production/lib/dom/ssr/single-fetch.d.ts +1 -1
- package/dist/production/lib/dom/ssr/single-fetch.js +7 -7
- package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/production/lib/dom-export/hydrated-router.js +2 -2
- package/dist/production/lib/errors.js +1 -1
- package/dist/production/lib/hooks.d.ts +0 -3
- package/dist/production/lib/hooks.js +5 -6
- package/dist/production/lib/href.js +1 -1
- package/dist/production/lib/router/history.js +1 -1
- package/dist/production/lib/router/instrumentation.js +1 -1
- package/dist/production/lib/router/matcher-route-pattern.js +1 -1
- package/dist/production/lib/router/matcher-route-pattern.preload.js +1 -1
- package/dist/production/lib/router/matcher.js +6 -1
- package/dist/production/lib/router/navigation.js +1 -1
- package/dist/production/lib/router/router.d.ts +2 -0
- package/dist/production/lib/router/router.js +58 -28
- package/dist/production/lib/router/url.js +1 -1
- package/dist/production/lib/router/utils.d.ts +7 -0
- package/dist/production/lib/router/utils.js +1 -1
- package/dist/production/lib/rsc/browser.js +3 -3
- package/dist/production/lib/rsc/errorBoundaries.js +1 -1
- package/dist/production/lib/rsc/html-stream/browser.js +1 -1
- package/dist/production/lib/rsc/html-stream/server.js +1 -1
- package/dist/production/lib/rsc/route-modules.js +1 -1
- package/dist/production/lib/rsc/server.ssr.js +1 -1
- package/dist/production/lib/server-runtime/cookies.js +1 -1
- package/dist/production/lib/server-runtime/crypto.js +1 -1
- package/dist/production/lib/server-runtime/data.js +1 -1
- package/dist/production/lib/server-runtime/dev.js +1 -1
- package/dist/production/lib/server-runtime/entry.js +1 -1
- package/dist/production/lib/server-runtime/errors.js +1 -1
- package/dist/production/lib/server-runtime/headers.js +1 -1
- package/dist/production/lib/server-runtime/invariant.js +1 -1
- package/dist/production/lib/server-runtime/mode.js +1 -1
- package/dist/production/lib/server-runtime/routeMatching.js +1 -1
- package/dist/production/lib/server-runtime/routes.js +1 -1
- package/dist/production/lib/server-runtime/server.js +13 -5
- package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
- package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
- package/dist/production/lib/server-runtime/sessions.js +2 -2
- package/dist/production/lib/server-runtime/single-fetch.js +1 -1
- package/dist/production/lib/server-runtime/urls.js +1 -1
- package/dist/production/lib/server-runtime/warnings.js +1 -1
- package/dist/production/lib/types/internal.js +1 -1
- package/dist/production/route-pattern.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/unflatten.js +23 -3
- package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
- package/docs/explanation/backend-for-frontend.md +0 -3
- package/docs/explanation/code-splitting.md +0 -3
- package/docs/explanation/concurrency.md +0 -3
- package/docs/explanation/hot-module-replacement.md +0 -3
- package/docs/explanation/lazy-route-discovery.md +0 -3
- package/docs/explanation/progressive-enhancement.md +0 -3
- package/docs/explanation/race-conditions.md +0 -3
- package/docs/explanation/react-transitions.md +0 -3
- package/docs/explanation/sessions-and-cookies.md +1 -1
- package/docs/explanation/state-management.md +0 -3
- package/docs/explanation/styling.md +0 -3
- package/docs/explanation/type-safety.md +0 -3
- package/docs/how-to/accessibility.md +0 -6
- package/docs/how-to/client-data.md +0 -3
- package/docs/how-to/data-strategy.md +0 -3
- package/docs/how-to/error-boundary.md +0 -3
- package/docs/how-to/error-reporting.md +0 -3
- package/docs/how-to/fetchers.md +0 -3
- package/docs/how-to/file-route-conventions.md +0 -3
- package/docs/how-to/file-uploads.md +0 -3
- package/docs/how-to/form-validation.md +0 -3
- package/docs/how-to/headers.md +0 -3
- package/docs/how-to/instrumentation.md +0 -3
- package/docs/how-to/middleware.md +6 -3
- package/docs/how-to/navigation-blocking.md +0 -3
- package/docs/how-to/optimize-revalidation.md +0 -3
- package/docs/how-to/pre-rendering.md +0 -3
- package/docs/how-to/presets.md +0 -3
- package/docs/how-to/react-server-components.md +0 -3
- package/docs/how-to/resource-routes.md +0 -3
- package/docs/how-to/route-discovery.md +4 -2
- package/docs/how-to/route-module-type-safety.md +0 -3
- package/docs/how-to/security.md +0 -3
- package/docs/how-to/server-bundles.md +0 -3
- package/docs/how-to/spa.md +0 -3
- package/docs/how-to/status.md +0 -3
- package/docs/how-to/suspense.md +22 -6
- package/docs/how-to/using-handle.md +0 -3
- package/docs/how-to/view-transitions.md +0 -3
- package/docs/start/framework/data-loading.md +9 -0
- package/docs/upgrading/future.md +0 -12
- package/docs/upgrading/v7.md +3 -33
- package/package.json +1 -1
- package/dist/development/lib/dom/global.d.ts +0 -35
- package/dist/production/lib/dom/global.d.ts +0 -35
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.5.
|
|
2
|
+
* react-router v8.5.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -1047,12 +1047,17 @@ var V6RegExMatcher = class {
|
|
|
1047
1047
|
#routes = [];
|
|
1048
1048
|
#branches = [];
|
|
1049
1049
|
#basename;
|
|
1050
|
+
#matchCost = 0;
|
|
1050
1051
|
constructor(basename) {
|
|
1051
1052
|
this.#basename = basename;
|
|
1052
1053
|
}
|
|
1053
1054
|
update(routes) {
|
|
1054
1055
|
this.#routes = routes;
|
|
1055
1056
|
this.#branches = flattenAndRankRoutes(routes);
|
|
1057
|
+
this.#matchCost = this.#branches.reduce((total, branch) => total + branch.routesMeta.length, 0);
|
|
1058
|
+
}
|
|
1059
|
+
get matchCost() {
|
|
1060
|
+
return this.#matchCost;
|
|
1056
1061
|
}
|
|
1057
1062
|
match(locationArg, allowPartial = false) {
|
|
1058
1063
|
return matchRoutesImpl(this.#routes, locationArg, this.#basename, allowPartial, this.#branches);
|
|
@@ -1478,6 +1483,9 @@ function createStaticHandler(routes, opts) {
|
|
|
1478
1483
|
}
|
|
1479
1484
|
return {
|
|
1480
1485
|
dataRoutes,
|
|
1486
|
+
get _matchCost() {
|
|
1487
|
+
return dataRouteMatcher instanceof V6RegExMatcher ? dataRouteMatcher.matchCost : void 0;
|
|
1488
|
+
},
|
|
1481
1489
|
match,
|
|
1482
1490
|
query,
|
|
1483
1491
|
queryRoute
|
|
@@ -1589,6 +1597,9 @@ const loadLazyRouteProperty = ({ key, route, manifest, mapRouteProperties }) =>
|
|
|
1589
1597
|
}
|
|
1590
1598
|
})();
|
|
1591
1599
|
cache[key] = propertyPromise;
|
|
1600
|
+
propertyPromise.catch(() => {
|
|
1601
|
+
if (cache[key] === propertyPromise) delete cache[key];
|
|
1602
|
+
});
|
|
1592
1603
|
return propertyPromise;
|
|
1593
1604
|
};
|
|
1594
1605
|
const lazyRouteFunctionCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -1630,7 +1641,9 @@ function loadLazyRoute(route, type, manifest, mapRouteProperties, lazyRoutePrope
|
|
|
1630
1641
|
});
|
|
1631
1642
|
})();
|
|
1632
1643
|
lazyRouteFunctionCache.set(routeToUpdate, lazyRoutePromise);
|
|
1633
|
-
lazyRoutePromise.catch(() => {
|
|
1644
|
+
lazyRoutePromise.catch(() => {
|
|
1645
|
+
if (lazyRouteFunctionCache.get(routeToUpdate) === lazyRoutePromise) lazyRouteFunctionCache.delete(routeToUpdate);
|
|
1646
|
+
});
|
|
1634
1647
|
return {
|
|
1635
1648
|
lazyRoutePromise,
|
|
1636
1649
|
lazyHandlerPromise: lazyRoutePromise
|
|
@@ -1918,10 +1931,13 @@ async function callLoaderOrAction({ request, path, pattern, match, lazyHandlerPr
|
|
|
1918
1931
|
pathname,
|
|
1919
1932
|
routeId: match.route.id
|
|
1920
1933
|
});
|
|
1921
|
-
} else
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1934
|
+
} else {
|
|
1935
|
+
await lazyRoutePromise;
|
|
1936
|
+
return {
|
|
1937
|
+
type: "data",
|
|
1938
|
+
result: void 0
|
|
1939
|
+
};
|
|
1940
|
+
}
|
|
1925
1941
|
}
|
|
1926
1942
|
else if (!handler) {
|
|
1927
1943
|
let url = new URL(request.url);
|
|
@@ -2251,6 +2267,12 @@ function getPathsWithAncestors(paths) {
|
|
|
2251
2267
|
});
|
|
2252
2268
|
return Array.from(result);
|
|
2253
2269
|
}
|
|
2270
|
+
const MANIFEST_MATCH_COST_LIMIT = 5e4;
|
|
2271
|
+
const MANIFEST_MATCH_COST_SEGMENT_THRESHOLD = 10;
|
|
2272
|
+
function shouldUseInitialRouteDiscovery(pathname, matchCost = 0) {
|
|
2273
|
+
let segmentCount = pathname.split("/").length - 1;
|
|
2274
|
+
return Math.max(segmentCount - 1, 0) * pathname.length + 1 > 7680 || segmentCount > MANIFEST_MATCH_COST_SEGMENT_THRESHOLD && segmentCount * matchCost > MANIFEST_MATCH_COST_LIMIT;
|
|
2275
|
+
}
|
|
2254
2276
|
//#endregion
|
|
2255
2277
|
//#region lib/actions.ts
|
|
2256
2278
|
function throwIfPotentialCSRFAttack(request, allowedActionOrigins) {
|
|
@@ -2346,12 +2368,15 @@ const replace = (...args) => {
|
|
|
2346
2368
|
const cachedResolvePromise = React.cache(async (resolve) => {
|
|
2347
2369
|
return Promise.allSettled([resolve]).then((r) => r[0]);
|
|
2348
2370
|
});
|
|
2349
|
-
const Await = (async (
|
|
2350
|
-
|
|
2371
|
+
const Await = (async (props) => {
|
|
2372
|
+
invariant$1("resolve" in props !== "unstable_promise" in props, "<Await> requires exactly one of `resolve` or `unstable_promise`");
|
|
2373
|
+
let { children, errorElement } = props;
|
|
2374
|
+
let usePromise = "unstable_promise" in props;
|
|
2375
|
+
let resolved = await cachedResolvePromise(usePromise ? props.unstable_promise : props.resolve);
|
|
2351
2376
|
if (resolved.status === "rejected" && !errorElement) throw resolved.reason;
|
|
2352
2377
|
if (resolved.status === "rejected") return React.createElement(UNSAFE_AwaitContextProvider, {
|
|
2353
2378
|
children: React.createElement(React.Fragment, null, errorElement),
|
|
2354
|
-
value: {
|
|
2379
|
+
value: usePromise ? resolved : {
|
|
2355
2380
|
_tracked: true,
|
|
2356
2381
|
_error: resolved.reason
|
|
2357
2382
|
}
|
|
@@ -2359,7 +2384,7 @@ const Await = (async ({ children, resolve, errorElement }) => {
|
|
|
2359
2384
|
const toRender = typeof children === "function" ? children(resolved.value) : children;
|
|
2360
2385
|
return React.createElement(UNSAFE_AwaitContextProvider, {
|
|
2361
2386
|
children: toRender,
|
|
2362
|
-
value: {
|
|
2387
|
+
value: usePromise ? resolved : {
|
|
2363
2388
|
_tracked: true,
|
|
2364
2389
|
_data: resolved.value
|
|
2365
2390
|
}
|
|
@@ -2676,7 +2701,7 @@ async function generateRenderResponse(request, staticHandler, basename, isDataRe
|
|
|
2676
2701
|
let result = await processServerAction(request, basename, decodeReply, loadServerAction, decodeAction, decodeFormState, onError, temporaryReferences).finally(() => {
|
|
2677
2702
|
ctx.runningAction = false;
|
|
2678
2703
|
});
|
|
2679
|
-
if (isResponse(result)) return generateRedirectResponse(result, actionResult, basename, isDataRequest, generateResponse, temporaryReferences, ctx.redirect?.headers);
|
|
2704
|
+
if (isResponse(result)) return generateRedirectResponse(result, actionResult, basename, isDataRequest, generateResponse, temporaryReferences, result === ctx.redirect ? void 0 : ctx.redirect?.headers);
|
|
2680
2705
|
skipRevalidation = result?.skipRevalidation ?? false;
|
|
2681
2706
|
actionResult = result?.actionResult;
|
|
2682
2707
|
formState = result?.formState;
|
|
@@ -2710,7 +2735,7 @@ function generateRedirectResponse(response, actionResult, basename, isDataReques
|
|
|
2710
2735
|
status: response.status,
|
|
2711
2736
|
actionResult
|
|
2712
2737
|
};
|
|
2713
|
-
let headers = new Headers(sideEffectRedirectHeaders);
|
|
2738
|
+
let headers = new Headers(sideEffectRedirectHeaders === response.headers ? void 0 : sideEffectRedirectHeaders);
|
|
2714
2739
|
for (const [key, value] of response.headers.entries()) headers.append(key, value);
|
|
2715
2740
|
headers.delete("Location");
|
|
2716
2741
|
headers.delete("X-Remix-Reload-Document");
|
|
@@ -2788,11 +2813,14 @@ async function getRenderPayload(baseRenderPayload, staticHandler, basename, rout
|
|
|
2788
2813
|
parentId
|
|
2789
2814
|
});
|
|
2790
2815
|
}));
|
|
2816
|
+
let pathname = staticContext.location.pathname;
|
|
2817
|
+
let useInitialRouteDiscovery = routeDiscovery?.mode === "initial" && !isDataRequest || shouldUseInitialRouteDiscovery(pathname, staticHandler._matchCost);
|
|
2791
2818
|
let patches;
|
|
2792
|
-
if (
|
|
2793
|
-
else patches = getAdditionalRoutePatches(getPathsWithAncestors([
|
|
2819
|
+
if (useInitialRouteDiscovery) patches = getAllRoutePatches(routes, basename).then((patches) => patches.filter((patch) => !staticContext.matches.some((m) => m.route.id === patch.id)));
|
|
2820
|
+
else patches = getAdditionalRoutePatches(getPathsWithAncestors([pathname]).slice(0, -1), staticHandler, staticContext.matches.map((m) => m.route.id));
|
|
2794
2821
|
return {
|
|
2795
2822
|
...baseRenderPayload,
|
|
2823
|
+
routeDiscovery: useInitialRouteDiscovery ? { mode: "initial" } : baseRenderPayload.routeDiscovery,
|
|
2796
2824
|
matches: await matchesPromise,
|
|
2797
2825
|
patches
|
|
2798
2826
|
};
|
|
@@ -3251,7 +3279,7 @@ function createSessionStorage({ cookie: cookieArg, createData, readData, updateD
|
|
|
3251
3279
|
return cookie.serialize(id, options);
|
|
3252
3280
|
},
|
|
3253
3281
|
async destroySession(session, options) {
|
|
3254
|
-
await deleteData(session.id);
|
|
3282
|
+
if (session.id) await deleteData(session.id);
|
|
3255
3283
|
return cookie.serialize("", {
|
|
3256
3284
|
...options,
|
|
3257
3285
|
maxAge: void 0,
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* react-router v8.5.1
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Remix Software Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
* @license MIT
|
|
10
|
+
*/
|
|
11
|
+
//#region lib/await.ts
|
|
12
|
+
function getPromiseResult(promise) {
|
|
13
|
+
if (promise.status === "fulfilled") return {
|
|
14
|
+
status: "fulfilled",
|
|
15
|
+
value: promise.value
|
|
16
|
+
};
|
|
17
|
+
if (promise.status === "rejected") return {
|
|
18
|
+
status: "rejected",
|
|
19
|
+
reason: promise.reason
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
let awaitPromises = /* @__PURE__ */ new WeakMap();
|
|
23
|
+
function getAwaitPromise(source, onError) {
|
|
24
|
+
let cached = awaitPromises.get(source);
|
|
25
|
+
if (!cached) {
|
|
26
|
+
cached = {
|
|
27
|
+
promise: Promise.resolve(source).then((value) => settle({
|
|
28
|
+
status: "fulfilled",
|
|
29
|
+
value
|
|
30
|
+
}), (reason) => {
|
|
31
|
+
let result = settle({
|
|
32
|
+
status: "rejected",
|
|
33
|
+
reason
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
cached.onError(reason);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error("<Await> caught the following error in onError", error);
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}),
|
|
42
|
+
onError
|
|
43
|
+
};
|
|
44
|
+
awaitPromises.set(source, cached);
|
|
45
|
+
} else cached.onError = onError;
|
|
46
|
+
function settle(result) {
|
|
47
|
+
Object.assign(cached.promise, {
|
|
48
|
+
status: "fulfilled",
|
|
49
|
+
value: result
|
|
50
|
+
});
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
let result = getPromiseResult(source);
|
|
54
|
+
if (result) settle(result);
|
|
55
|
+
return cached.promise;
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
export { getAwaitPromise, getPromiseResult };
|
|
@@ -768,6 +768,8 @@ interface AwaitResolveRenderFunction<Resolve = any> {
|
|
|
768
768
|
* @category Types
|
|
769
769
|
*/
|
|
770
770
|
interface AwaitProps<Resolve> {
|
|
771
|
+
/** Use either `resolve` or `unstable_promise`, never both. */
|
|
772
|
+
unstable_promise?: never;
|
|
771
773
|
/**
|
|
772
774
|
* When using a function, the resolved value is provided as the parameter.
|
|
773
775
|
*
|
|
@@ -869,11 +871,46 @@ interface AwaitProps<Resolve> {
|
|
|
869
871
|
*/
|
|
870
872
|
resolve: Resolve;
|
|
871
873
|
}
|
|
874
|
+
interface AwaitPromiseProps<Resolve> extends Omit<AwaitProps<Resolve>, "resolve" | "unstable_promise"> {
|
|
875
|
+
resolve?: never;
|
|
876
|
+
/**
|
|
877
|
+
* A promise (or value) to read using React's `use()` API in client components.
|
|
878
|
+
* Unlike `resolve` in client components, this accepts promise-like values
|
|
879
|
+
* without modifying the source promise.
|
|
880
|
+
*
|
|
881
|
+
* `errorElement` handles promise rejections. Errors thrown while rendering
|
|
882
|
+
* children bubble to the nearest React error boundary.
|
|
883
|
+
*
|
|
884
|
+
* ```tsx
|
|
885
|
+
* <Await unstable_promise={reviewsPromise} errorElement={<ReviewsError />}>
|
|
886
|
+
* {(reviews) => <Reviews items={reviews} />}
|
|
887
|
+
* </Await>
|
|
888
|
+
* ```
|
|
889
|
+
*
|
|
890
|
+
* Pass exactly one of `unstable_promise` or `resolve`.
|
|
891
|
+
*/
|
|
892
|
+
unstable_promise: Resolve;
|
|
893
|
+
}
|
|
872
894
|
/**
|
|
873
895
|
* Used to render promise values with automatic error handling.
|
|
874
896
|
*
|
|
875
897
|
* **Note:** `<Await>` expects to be rendered inside a [`<React.Suspense>`](https://react.dev/reference/react/Suspense)
|
|
876
898
|
*
|
|
899
|
+
* Pass `unstable_promise` instead of `resolve` to opt into React's
|
|
900
|
+
* [`use()`](https://react.dev/reference/react/use) implementation. With
|
|
901
|
+
* `unstable_promise`, `errorElement` handles promise rejections, while errors
|
|
902
|
+
* thrown by children bubble to the nearest React error boundary.
|
|
903
|
+
*
|
|
904
|
+
* In React Server Components, `resolve` already has this error-handling behavior:
|
|
905
|
+
* `errorElement` handles only input rejections, while child render errors
|
|
906
|
+
* propagate to the surrounding error boundary. Both props accept promise-like
|
|
907
|
+
* values without modifying the source promise. Both props treat a falsy
|
|
908
|
+
* `errorElement` as absent and propagate the rejection. Pass an empty fragment
|
|
909
|
+
* to handle a rejection without rendering any content.
|
|
910
|
+
*
|
|
911
|
+
* <docs-warning>The `unstable_promise` prop is experimental and may change in
|
|
912
|
+
* minor or patch releases.</docs-warning>
|
|
913
|
+
*
|
|
877
914
|
* @example
|
|
878
915
|
* import { Await, useLoaderData } from "react-router";
|
|
879
916
|
*
|
|
@@ -914,13 +951,12 @@ interface AwaitProps<Resolve> {
|
|
|
914
951
|
* @param {AwaitProps.children} props.children n/a
|
|
915
952
|
* @param {AwaitProps.errorElement} props.errorElement n/a
|
|
916
953
|
* @param {AwaitProps.resolve} props.resolve n/a
|
|
954
|
+
* @param props.unstable_promise A promise (or value) to read using React's `use()`
|
|
955
|
+
* API in client components. Accepts promise-like values without modifying the
|
|
956
|
+
* source promise. Pass exactly one of `unstable_promise` or `resolve`.
|
|
917
957
|
* @returns React element for the rendered awaited value
|
|
918
958
|
*/
|
|
919
|
-
declare function Await<Resolve>(
|
|
920
|
-
children,
|
|
921
|
-
errorElement,
|
|
922
|
-
resolve
|
|
923
|
-
}: AwaitProps<Resolve>): React$1.JSX.Element;
|
|
959
|
+
declare function Await<Resolve>(props: AwaitProps<Resolve> | AwaitPromiseProps<Resolve>): React$1.JSX.Element;
|
|
924
960
|
/**
|
|
925
961
|
* Creates a route config from a React "children" object, which is usually
|
|
926
962
|
* either a `<Route>` element or an array of them. Used internally by
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.5.
|
|
2
|
+
* react-router v8.5.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -13,6 +13,7 @@ import { defaultMapRouteProperties, getResolveToMatches, getRoutePattern, resolv
|
|
|
13
13
|
import { getNavigatorCurrentUrl, validateNavigationTarget } from "./router/navigation.js";
|
|
14
14
|
import { clientErrors, createRouter } from "./router/router.js";
|
|
15
15
|
import { AwaitContext, DataRouterContext, DataRouterDataContext, DataRouterNavigationContext, DataRouterStateContext, FetchersContext, LocationContext, NavigationContext, RouteContext, ViewTransitionContext, useIsRSCRouterContext } from "./context.js";
|
|
16
|
+
import { getAwaitPromise, getPromiseResult } from "./await.js";
|
|
16
17
|
import { _renderMatches, useActionData, useAsyncValue, useInRouterContext, useLoaderData, useLocation, useMatches, useNavigate, useOutlet, useParams, useRouteError, useRoutes, useRoutesImpl } from "./hooks.js";
|
|
17
18
|
import { warnOnce } from "./server-runtime/warnings.js";
|
|
18
19
|
import { FrameworkContext } from "./dom/ssr/components.js";
|
|
@@ -85,6 +86,11 @@ var Deferred = class {
|
|
|
85
86
|
});
|
|
86
87
|
}
|
|
87
88
|
};
|
|
89
|
+
function handleSkippedViewTransition(transition, document) {
|
|
90
|
+
transition.ready.catch((reason) => {
|
|
91
|
+
if (!(document.visibilityState === "hidden" || typeof reason === "object" && reason !== null && "name" in reason && reason.name === "AbortError")) throw reason;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
88
94
|
/**
|
|
89
95
|
* Render the UI for the given {@link DataRouter}. This component should
|
|
90
96
|
* typically be at the top of an app's element tree. The router prop should
|
|
@@ -172,6 +178,7 @@ function RouterProvider({ router, flushSync: reactDomFlushSyncImpl, onError, use
|
|
|
172
178
|
let t = router.window.document.startViewTransition(() => {
|
|
173
179
|
reactDomFlushSyncImpl(() => setStateImpl(newState));
|
|
174
180
|
});
|
|
181
|
+
handleSkippedViewTransition(t, router.window.document);
|
|
175
182
|
t.finished.finally(() => {
|
|
176
183
|
reactDomFlushSyncImpl(() => {
|
|
177
184
|
setRenderDfd(void 0);
|
|
@@ -234,6 +241,7 @@ function RouterProvider({ router, flushSync: reactDomFlushSyncImpl, onError, use
|
|
|
234
241
|
});
|
|
235
242
|
await renderPromise;
|
|
236
243
|
});
|
|
244
|
+
handleSkippedViewTransition(transition, router.window.document);
|
|
237
245
|
transition.finished.finally(() => {
|
|
238
246
|
setRenderDfd(void 0);
|
|
239
247
|
setTransition(void 0);
|
|
@@ -643,6 +651,21 @@ function Routes({ children, location }) {
|
|
|
643
651
|
*
|
|
644
652
|
* **Note:** `<Await>` expects to be rendered inside a [`<React.Suspense>`](https://react.dev/reference/react/Suspense)
|
|
645
653
|
*
|
|
654
|
+
* Pass `unstable_promise` instead of `resolve` to opt into React's
|
|
655
|
+
* [`use()`](https://react.dev/reference/react/use) implementation. With
|
|
656
|
+
* `unstable_promise`, `errorElement` handles promise rejections, while errors
|
|
657
|
+
* thrown by children bubble to the nearest React error boundary.
|
|
658
|
+
*
|
|
659
|
+
* In React Server Components, `resolve` already has this error-handling behavior:
|
|
660
|
+
* `errorElement` handles only input rejections, while child render errors
|
|
661
|
+
* propagate to the surrounding error boundary. Both props accept promise-like
|
|
662
|
+
* values without modifying the source promise. Both props treat a falsy
|
|
663
|
+
* `errorElement` as absent and propagate the rejection. Pass an empty fragment
|
|
664
|
+
* to handle a rejection without rendering any content.
|
|
665
|
+
*
|
|
666
|
+
* <docs-warning>The `unstable_promise` prop is experimental and may change in
|
|
667
|
+
* minor or patch releases.</docs-warning>
|
|
668
|
+
*
|
|
646
669
|
* @example
|
|
647
670
|
* import { Await, useLoaderData } from "react-router";
|
|
648
671
|
*
|
|
@@ -683,9 +706,14 @@ function Routes({ children, location }) {
|
|
|
683
706
|
* @param {AwaitProps.children} props.children n/a
|
|
684
707
|
* @param {AwaitProps.errorElement} props.errorElement n/a
|
|
685
708
|
* @param {AwaitProps.resolve} props.resolve n/a
|
|
709
|
+
* @param props.unstable_promise A promise (or value) to read using React's `use()`
|
|
710
|
+
* API in client components. Accepts promise-like values without modifying the
|
|
711
|
+
* source promise. Pass exactly one of `unstable_promise` or `resolve`.
|
|
686
712
|
* @returns React element for the rendered awaited value
|
|
687
713
|
*/
|
|
688
|
-
function Await(
|
|
714
|
+
function Await(props) {
|
|
715
|
+
invariant("resolve" in props !== "unstable_promise" in props, "<Await> requires exactly one of `resolve` or `unstable_promise`");
|
|
716
|
+
let { children, errorElement } = props;
|
|
689
717
|
let dataRouterContext = React$1.useContext(DataRouterContext);
|
|
690
718
|
let dataRouterStateContext = React$1.useContext(DataRouterStateContext);
|
|
691
719
|
let onError = React$1.useCallback((error, errorInfo) => {
|
|
@@ -696,12 +724,25 @@ function Await({ children, errorElement, resolve }) {
|
|
|
696
724
|
errorInfo
|
|
697
725
|
});
|
|
698
726
|
}, [dataRouterContext, dataRouterStateContext]);
|
|
727
|
+
if ("unstable_promise" in props) return /* @__PURE__ */ React$1.createElement(AwaitPromise, {
|
|
728
|
+
value: props.unstable_promise,
|
|
729
|
+
errorElement,
|
|
730
|
+
onError
|
|
731
|
+
}, children);
|
|
699
732
|
return /* @__PURE__ */ React$1.createElement(AwaitErrorBoundary, {
|
|
700
|
-
resolve,
|
|
733
|
+
resolve: props.resolve,
|
|
701
734
|
errorElement,
|
|
702
735
|
onError
|
|
703
736
|
}, /* @__PURE__ */ React$1.createElement(ResolveAwait, null, children));
|
|
704
737
|
}
|
|
738
|
+
function AwaitPromise({ value, children, errorElement, onError }) {
|
|
739
|
+
let result = value != null && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function" ? React$1.use(getAwaitPromise(value, onError)) : {
|
|
740
|
+
status: "fulfilled",
|
|
741
|
+
value
|
|
742
|
+
};
|
|
743
|
+
if (result.status === "rejected" && !errorElement) throw result.reason;
|
|
744
|
+
return /* @__PURE__ */ React$1.createElement(AwaitContext.Provider, { value: result }, result.status === "rejected" ? errorElement : /* @__PURE__ */ React$1.createElement(ResolveAwait, null, children));
|
|
745
|
+
}
|
|
705
746
|
var AwaitErrorBoundary = class extends React$1.Component {
|
|
706
747
|
constructor(props) {
|
|
707
748
|
super(props);
|
|
@@ -735,7 +776,24 @@ var AwaitErrorBoundary = class extends React$1.Component {
|
|
|
735
776
|
} else {
|
|
736
777
|
status = 0;
|
|
737
778
|
Object.defineProperty(resolve, "_tracked", { get: () => true });
|
|
738
|
-
|
|
779
|
+
let result = getPromiseResult(resolve);
|
|
780
|
+
if (result) {
|
|
781
|
+
promise = resolve;
|
|
782
|
+
if (result.status === "fulfilled") {
|
|
783
|
+
status = 1;
|
|
784
|
+
Object.defineProperty(resolve, "_data", { get: () => result.value });
|
|
785
|
+
} else {
|
|
786
|
+
status = 2;
|
|
787
|
+
Object.defineProperty(resolve, "_error", { get: () => result.reason });
|
|
788
|
+
Promise.resolve(resolve).catch((reason) => {
|
|
789
|
+
try {
|
|
790
|
+
this.props.onError?.(reason);
|
|
791
|
+
} catch (error) {
|
|
792
|
+
console.error("<Await> caught the following error in onError", error);
|
|
793
|
+
}
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
} else promise = Promise.resolve(resolve).then((data) => Object.defineProperty(resolve, "_data", { get: () => data }), (error) => {
|
|
739
797
|
this.props.onError?.(error);
|
|
740
798
|
Object.defineProperty(resolve, "_error", { get: () => error });
|
|
741
799
|
});
|
|
@@ -32,8 +32,8 @@ type FetchersContextObject = {
|
|
|
32
32
|
fetcherData: Map<string, any>;
|
|
33
33
|
};
|
|
34
34
|
declare const FetchersContext: React$1.Context<FetchersContextObject | null>;
|
|
35
|
-
declare const AwaitContext: React$1.Context<TrackedPromise | null>;
|
|
36
|
-
declare const AwaitContextProvider: (props: React$1.ComponentProps<typeof AwaitContext.Provider>) => React$1.FunctionComponentElement<React$1.ProviderProps<TrackedPromise | null>>;
|
|
35
|
+
declare const AwaitContext: React$1.Context<TrackedPromise | PromiseSettledResult<unknown> | null>;
|
|
36
|
+
declare const AwaitContextProvider: (props: React$1.ComponentProps<typeof AwaitContext.Provider>) => React$1.FunctionComponentElement<React$1.ProviderProps<TrackedPromise | PromiseSettledResult<unknown> | null>>;
|
|
37
37
|
interface NavigateOptions {
|
|
38
38
|
/** Replace the current entry in the history stack instead of pushing a new one */
|
|
39
39
|
replace?: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.5.
|
|
2
|
+
* react-router v8.5.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -29,6 +29,12 @@ function getPathsWithAncestors(paths) {
|
|
|
29
29
|
function isFogOfWarEnabled(routeDiscovery, ssr) {
|
|
30
30
|
return routeDiscovery.mode === "lazy" && ssr;
|
|
31
31
|
}
|
|
32
|
+
const MANIFEST_MATCH_COST_LIMIT = 5e4;
|
|
33
|
+
const MANIFEST_MATCH_COST_SEGMENT_THRESHOLD = 10;
|
|
34
|
+
function shouldUseInitialRouteDiscovery(pathname, matchCost = 0) {
|
|
35
|
+
let segmentCount = pathname.split("/").length - 1;
|
|
36
|
+
return Math.max(segmentCount - 1, 0) * pathname.length + 1 > 7680 || segmentCount > MANIFEST_MATCH_COST_SEGMENT_THRESHOLD && segmentCount * matchCost > MANIFEST_MATCH_COST_LIMIT;
|
|
37
|
+
}
|
|
32
38
|
function getPartialManifest({ sri, ...manifest }, router) {
|
|
33
39
|
let routeIds = new Set(router.state.matches.map((m) => m.route.id));
|
|
34
40
|
let segments = router.state.location.pathname.split("/").filter(Boolean);
|
|
@@ -108,6 +114,9 @@ function useFogOFWarDiscovery(router, manifest, routeModules, ssr, routeDiscover
|
|
|
108
114
|
isApiOnly
|
|
109
115
|
]);
|
|
110
116
|
}
|
|
117
|
+
function getManifestPathsParam(paths) {
|
|
118
|
+
return paths.slice().sort().map((path) => path.replace(/,/g, "%2C")).join(",");
|
|
119
|
+
}
|
|
111
120
|
function getManifestPath(_manifestPath, basename) {
|
|
112
121
|
let manifestPath = _manifestPath || "/__manifest";
|
|
113
122
|
return basename == null ? manifestPath : joinPaths([basename, manifestPath]);
|
|
@@ -160,7 +169,7 @@ async function handleClientVersionMismatch(needsReload, version, errorReloadPath
|
|
|
160
169
|
async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal, fetchImplementation = (request) => fetch(request), serverOrigin, isApiOnly = false) {
|
|
161
170
|
paths = getPathsWithAncestors(paths);
|
|
162
171
|
const searchParams = new URLSearchParams();
|
|
163
|
-
searchParams.set("paths", paths
|
|
172
|
+
searchParams.set("paths", getManifestPathsParam(paths));
|
|
164
173
|
searchParams.set("version", manifest.version);
|
|
165
174
|
let url = new URL(getManifestPath(manifestPath, basename), serverOrigin ?? window.location.origin);
|
|
166
175
|
url.search = searchParams.toString();
|
|
@@ -207,4 +216,4 @@ function debounce(callback, wait) {
|
|
|
207
216
|
};
|
|
208
217
|
}
|
|
209
218
|
//#endregion
|
|
210
|
-
export { URL_LIMIT, getManifestPath, getPartialManifest, getPatchRoutesOnNavigationFunction, getPathsWithAncestors, handleClientVersionMismatch, isFogOfWarEnabled, useFogOFWarDiscovery };
|
|
219
|
+
export { URL_LIMIT, getManifestPath, getManifestPathsParam, getPartialManifest, getPatchRoutesOnNavigationFunction, getPathsWithAncestors, handleClientVersionMismatch, isFogOfWarEnabled, shouldUseInitialRouteDiscovery, useFogOFWarDiscovery };
|
|
@@ -4,7 +4,7 @@ import { Router } from "../../router/router.js";
|
|
|
4
4
|
import { ClientOnErrorFunction } from "../../components.js";
|
|
5
5
|
import { RouteModules } from "./routeModules.js";
|
|
6
6
|
import { RouterFetch } from "./single-fetch.js";
|
|
7
|
-
import {
|
|
7
|
+
import { ServerHandoff } from "../../server-runtime/serverHandoff.js";
|
|
8
8
|
import { AssetsManifest } from "./entry.js";
|
|
9
9
|
|
|
10
10
|
//#region lib/dom/ssr/route-discovery.d.ts
|
|
@@ -37,7 +37,7 @@ type RouteDiscoverySsrInfo = {
|
|
|
37
37
|
manifest: AssetsManifest;
|
|
38
38
|
routeModules: RouteModules;
|
|
39
39
|
router: Router | undefined;
|
|
40
|
-
context: Pick<
|
|
40
|
+
context: Pick<ServerHandoff, "ssr" | "routeDiscovery" | "isSpaMode" | "basename" | "unstable_apiServerOrigin" | "unstable_apiOnly">;
|
|
41
41
|
};
|
|
42
42
|
declare class RouteDiscoveryRuntime {
|
|
43
43
|
private ssrInfo;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.5.
|
|
2
|
+
* react-router v8.5.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { createPath, invariant } from "../../router/history.js";
|
|
12
12
|
import { DiscoveryCancelledError, getRoutePattern, prependBasename } from "../../router/utils.js";
|
|
13
13
|
import { createClientRoutes } from "./routes.js";
|
|
14
|
-
import { getManifestPath, getPathsWithAncestors, handleClientVersionMismatch, isFogOfWarEnabled } from "./fog-of-war.js";
|
|
14
|
+
import { getManifestPath, getManifestPathsParam, getPathsWithAncestors, handleClientVersionMismatch, isFogOfWarEnabled } from "./fog-of-war.js";
|
|
15
15
|
import { useFrameworkContext } from "./components.js";
|
|
16
16
|
import * as React$1 from "react";
|
|
17
17
|
//#region lib/dom/ssr/route-discovery.ts
|
|
@@ -158,7 +158,7 @@ var RouteDiscoveryRuntime = class {
|
|
|
158
158
|
requestUrl(paths) {
|
|
159
159
|
let { manifest, context } = this.ssrInfo;
|
|
160
160
|
let params = new URLSearchParams();
|
|
161
|
-
params.set("paths", paths
|
|
161
|
+
params.set("paths", getManifestPathsParam(paths));
|
|
162
162
|
params.set("version", manifest.version);
|
|
163
163
|
let url = new URL(getManifestPath(context.routeDiscovery.manifestPath, context.basename), context.unstable_apiServerOrigin ?? window.location.origin);
|
|
164
164
|
url.search = params.toString();
|