INDIE UNPKG

8.62 kBJavaScriptView Raw
1/**
2 * react-router v8.5.0
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 */
11import { CRITICAL_CSS_DATA_ATTRIBUTE } from "../dom/ssr/components.js";
12import { RouterProvider as RouterProvider$1 } from "./dom-router-provider.js";
13import * as React$1 from "react";
14import { UNSAFE_FrameworkContext, UNSAFE_RemixErrorBoundary, UNSAFE_RouteDiscoveryRuntime, UNSAFE_createBrowserHistory, UNSAFE_createClientRoutes, UNSAFE_createClientRoutesWithHMRRevalidationOptOut, UNSAFE_createRouter, UNSAFE_decodeViaTurboStream, UNSAFE_defaultMapRouteProperties, UNSAFE_getCustomPatchRoutesOnNavigationFunction, UNSAFE_getHydrationData, UNSAFE_getPatchRoutesOnNavigationFunction, UNSAFE_getTurboStreamSingleFetchDataStrategy, UNSAFE_hydrationRouteProperties, UNSAFE_invariant, UNSAFE_useCustomRouteDiscovery, UNSAFE_useFogOFWarDiscovery } from "react-router";
15//#region lib/dom-export/hydrated-router.tsx
16let ssrInfo = null;
17let router = null;
18let fetchImplementation = (request) => window.fetch(request);
19function initSsrInfo() {
20 if (!ssrInfo && window.__reactRouterContext && window.__reactRouterManifest && window.__reactRouterRouteModules) {
21 if (window.__reactRouterManifest.sri === true) {
22 const importMap = document.querySelector("script[rr-importmap]");
23 if (importMap?.textContent) try {
24 window.__reactRouterManifest.sri = JSON.parse(importMap.textContent).integrity;
25 } catch (err) {
26 console.error("Failed to parse import map", err);
27 }
28 }
29 ssrInfo = {
30 context: window.__reactRouterContext,
31 manifest: window.__reactRouterManifest,
32 routeModules: window.__reactRouterRouteModules,
33 stateDecodingPromise: void 0,
34 router: void 0,
35 routeDiscoveryRuntime: void 0,
36 routerInitialized: false
37 };
38 }
39}
40function createHydratedRouter({ getContext, instrumentations, fetch: fetchImplementation }) {
41 initSsrInfo();
42 if (!ssrInfo) throw new Error("You must be using the SSR features of React Router in order to skip passing a `router` prop to `<RouterProvider>`");
43 let localSsrInfo = ssrInfo;
44 let isApiOnly = ssrInfo.context.unstable_apiOnly === true;
45 let ssr = ssrInfo.context.ssr;
46 if (!ssrInfo.stateDecodingPromise) {
47 let stream = ssrInfo.context.stream;
48 UNSAFE_invariant(stream, "No stream found for single fetch decoding");
49 ssrInfo.context.stream = void 0;
50 ssrInfo.stateDecodingPromise = UNSAFE_decodeViaTurboStream(stream, window).then((value) => {
51 ssrInfo.context.state = value.value;
52 localSsrInfo.stateDecodingPromise.value = true;
53 }).catch((e) => {
54 localSsrInfo.stateDecodingPromise.error = e;
55 });
56 }
57 if (ssrInfo.stateDecodingPromise.error) throw ssrInfo.stateDecodingPromise.error;
58 if (!ssrInfo.stateDecodingPromise.value) throw ssrInfo.stateDecodingPromise;
59 let routes = UNSAFE_createClientRoutes(ssrInfo.manifest.routes, ssrInfo.routeModules, ssrInfo.context.state, ssr, ssrInfo.context.isSpaMode, "", void 0, void 0, isApiOnly);
60 let hydrationData = void 0;
61 if (ssrInfo.context.isSpaMode) {
62 let { loaderData } = ssrInfo.context.state;
63 if (ssrInfo.manifest.routes.root?.hasLoader && loaderData && "root" in loaderData) hydrationData = { loaderData: { root: loaderData.root } };
64 } else hydrationData = UNSAFE_getHydrationData({
65 state: ssrInfo.context.state,
66 routes,
67 getRouteInfo: (routeId) => ({
68 clientLoader: ssrInfo.routeModules[routeId]?.clientLoader,
69 hasLoader: ssrInfo.manifest.routes[routeId]?.hasLoader === true,
70 hasHydrateFallback: ssrInfo.routeModules[routeId]?.HydrateFallback != null
71 }),
72 location: window.location,
73 basename: window.__reactRouterContext?.basename,
74 future: ssrInfo.context.future,
75 isSpaMode: ssrInfo.context.isSpaMode
76 });
77 if (window.history.state && window.history.state.masked) window.history.replaceState({
78 ...window.history.state,
79 masked: void 0
80 }, "");
81 let discoveryRuntime = ssrInfo.context.future.unstable_customRouteDiscovery ? new UNSAFE_RouteDiscoveryRuntime(ssrInfo, { fetch: fetchImplementation }) : void 0;
82 let router = UNSAFE_createRouter({
83 routes,
84 history: UNSAFE_createBrowserHistory(),
85 future: { unstable_customRouteDiscovery: ssrInfo.context.future.unstable_customRouteDiscovery },
86 basename: ssrInfo.context.basename,
87 getContext,
88 hydrationData,
89 mapRouteProperties: UNSAFE_defaultMapRouteProperties,
90 hydrationRouteProperties: UNSAFE_hydrationRouteProperties,
91 instrumentations,
92 dataStrategy: UNSAFE_getTurboStreamSingleFetchDataStrategy(() => router, ssrInfo.manifest, ssrInfo.routeModules, ssr, fetchImplementation, ssrInfo.context.unstable_apiOnly === true, ssrInfo.context.unstable_apiServerOrigin),
93 patchRoutesOnNavigation: discoveryRuntime ? UNSAFE_getCustomPatchRoutesOnNavigationFunction(() => router, discoveryRuntime) : UNSAFE_getPatchRoutesOnNavigationFunction(() => router, ssrInfo.manifest, ssrInfo.routeModules, ssr, ssrInfo.context.routeDiscovery, ssrInfo.context.isSpaMode, ssrInfo.context.basename, fetchImplementation, ssrInfo.context.unstable_apiServerOrigin, isApiOnly)
94 });
95 ssrInfo.router = router;
96 ssrInfo.routeDiscoveryRuntime = discoveryRuntime;
97 if (router.state.initialized) {
98 ssrInfo.routerInitialized = true;
99 router.initialize();
100 }
101 router.createRoutesForHMR = UNSAFE_createClientRoutesWithHMRRevalidationOptOut;
102 window.__reactRouterDataRouter = router;
103 return router;
104}
105/**
106* Framework-mode router component to be used to hydrate a router from a
107* {@link ServerRouter}. See [`entry.client.tsx`](../framework-conventions/entry.client.tsx).
108*
109* @public
110* @category Framework Routers
111* @mode framework
112* @param props Props
113* @param {dom.HydratedRouterProps.getContext} props.getContext n/a
114* @param {dom.HydratedRouterProps.onError} props.onError n/a
115* @param {dom.HydratedRouterProps.unstable_fetch} props.unstable_fetch n/a
116* @returns A React element that represents the hydrated application.
117*/
118function HydratedRouter(props) {
119 if (!router) {
120 router = createHydratedRouter({
121 getContext: props.getContext,
122 instrumentations: props.instrumentations,
123 fetch: props.unstable_fetch ?? fetchImplementation
124 });
125 if (props.unstable_fetch) fetchImplementation = props.unstable_fetch;
126 }
127 let [criticalCss, setCriticalCss] = React$1.useState(process.env.NODE_ENV === "development" ? ssrInfo?.context.criticalCss : void 0);
128 React$1.useEffect(() => {
129 if (process.env.NODE_ENV === "development") setCriticalCss(void 0);
130 }, []);
131 React$1.useEffect(() => {
132 if (process.env.NODE_ENV === "development" && criticalCss === void 0) document.querySelectorAll(`[${CRITICAL_CSS_DATA_ATTRIBUTE}]`).forEach((element) => element.remove());
133 }, [criticalCss]);
134 let [location, setLocation] = React$1.useState(router.state.location);
135 React$1.useLayoutEffect(() => {
136 if (ssrInfo && ssrInfo.router && !ssrInfo.routerInitialized) {
137 ssrInfo.routerInitialized = true;
138 ssrInfo.router.initialize();
139 }
140 }, []);
141 React$1.useLayoutEffect(() => {
142 if (ssrInfo && ssrInfo.router) return ssrInfo.router.subscribe((newState) => {
143 if (newState.location !== location) setLocation(newState.location);
144 });
145 }, [location]);
146 UNSAFE_invariant(ssrInfo, "ssrInfo unavailable for HydratedRouter");
147 let ssr = ssrInfo.context.ssr;
148 let discoveryRuntime = ssrInfo.routeDiscoveryRuntime;
149 let discoveryState;
150 if (discoveryRuntime) discoveryState = UNSAFE_useCustomRouteDiscovery(discoveryRuntime, props.onError);
151 else UNSAFE_useFogOFWarDiscovery(router, ssrInfo.manifest, ssrInfo.routeModules, ssr, ssrInfo.context.routeDiscovery, ssrInfo.context.isSpaMode, fetchImplementation, ssrInfo.context.unstable_apiServerOrigin, ssrInfo.context.unstable_apiOnly === true);
152 return /* @__PURE__ */ React$1.createElement(React$1.Fragment, null, /* @__PURE__ */ React$1.createElement(UNSAFE_FrameworkContext.Provider, { value: {
153 routeDiscoveryRuntime: discoveryRuntime,
154 routeDiscoveryState: discoveryState,
155 manifest: ssrInfo.manifest,
156 routeModules: ssrInfo.routeModules,
157 future: ssrInfo.context.future,
158 criticalCss,
159 ssr: ssrInfo.context.ssr,
160 isSpaMode: ssrInfo.context.isSpaMode,
161 unstable_apiOnly: ssrInfo.context.unstable_apiOnly,
162 routeDiscovery: ssrInfo.context.routeDiscovery,
163 unstable_apiServerOrigin: ssrInfo.context.unstable_apiServerOrigin
164 } }, /* @__PURE__ */ React$1.createElement(UNSAFE_RemixErrorBoundary, { location }, /* @__PURE__ */ React$1.createElement(RouterProvider$1, {
165 router,
166 useTransitions: props.useTransitions,
167 onError: props.onError
168 }))), /* @__PURE__ */ React$1.createElement(React$1.Fragment, null));
169}
170//#endregion
171export { HydratedRouter };