UNPKG

32.1 kBJavaScriptView Raw
1/**
2 * react-router v7.10.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 */
11"use client";
12import {
13 RSCRouterGlobalErrorBoundary,
14 deserializeErrors,
15 getHydrationData,
16 populateRSCRouteModules
17} from "./chunk-MFC2CGJA.mjs";
18import {
19 CRITICAL_CSS_DATA_ATTRIBUTE,
20 ErrorResponseImpl,
21 FrameworkContext,
22 RSCRouterContext,
23 RemixErrorBoundary,
24 RouterProvider,
25 createBrowserHistory,
26 createClientRoutes,
27 createClientRoutesWithHMRRevalidationOptOut,
28 createContext,
29 createRequestInit,
30 createRouter,
31 decodeViaTurboStream,
32 getPatchRoutesOnNavigationFunction,
33 getSingleFetchDataStrategyImpl,
34 getTurboStreamSingleFetchDataStrategy,
35 hydrationRouteProperties,
36 invariant,
37 isMutationMethod,
38 mapRouteProperties,
39 noActionDefinedError,
40 setIsHydrated,
41 shouldHydrateRouteLoader,
42 singleFetchUrl,
43 stripIndexParam,
44 useFogOFWarDiscovery
45} from "./chunk-RNH4J7KQ.mjs";
46
47// lib/dom-export/dom-router-provider.tsx
48import * as React from "react";
49import * as ReactDOM from "react-dom";
50function RouterProvider2(props) {
51 return /* @__PURE__ */ React.createElement(RouterProvider, { flushSync: ReactDOM.flushSync, ...props });
52}
53
54// lib/dom-export/hydrated-router.tsx
55import * as React2 from "react";
56var ssrInfo = null;
57var router = null;
58function initSsrInfo() {
59 if (!ssrInfo && window.__reactRouterContext && window.__reactRouterManifest && window.__reactRouterRouteModules) {
60 if (window.__reactRouterManifest.sri === true) {
61 const importMap = document.querySelector("script[rr-importmap]");
62 if (importMap?.textContent) {
63 try {
64 window.__reactRouterManifest.sri = JSON.parse(
65 importMap.textContent
66 ).integrity;
67 } catch (err) {
68 console.error("Failed to parse import map", err);
69 }
70 }
71 }
72 ssrInfo = {
73 context: window.__reactRouterContext,
74 manifest: window.__reactRouterManifest,
75 routeModules: window.__reactRouterRouteModules,
76 stateDecodingPromise: void 0,
77 router: void 0,
78 routerInitialized: false
79 };
80 }
81}
82function createHydratedRouter({
83 getContext,
84 unstable_instrumentations
85}) {
86 initSsrInfo();
87 if (!ssrInfo) {
88 throw new Error(
89 "You must be using the SSR features of React Router in order to skip passing a `router` prop to `<RouterProvider>`"
90 );
91 }
92 let localSsrInfo = ssrInfo;
93 if (!ssrInfo.stateDecodingPromise) {
94 let stream = ssrInfo.context.stream;
95 invariant(stream, "No stream found for single fetch decoding");
96 ssrInfo.context.stream = void 0;
97 ssrInfo.stateDecodingPromise = decodeViaTurboStream(stream, window).then((value) => {
98 ssrInfo.context.state = value.value;
99 localSsrInfo.stateDecodingPromise.value = true;
100 }).catch((e) => {
101 localSsrInfo.stateDecodingPromise.error = e;
102 });
103 }
104 if (ssrInfo.stateDecodingPromise.error) {
105 throw ssrInfo.stateDecodingPromise.error;
106 }
107 if (!ssrInfo.stateDecodingPromise.value) {
108 throw ssrInfo.stateDecodingPromise;
109 }
110 let routes = createClientRoutes(
111 ssrInfo.manifest.routes,
112 ssrInfo.routeModules,
113 ssrInfo.context.state,
114 ssrInfo.context.ssr,
115 ssrInfo.context.isSpaMode
116 );
117 let hydrationData = void 0;
118 if (ssrInfo.context.isSpaMode) {
119 let { loaderData } = ssrInfo.context.state;
120 if (ssrInfo.manifest.routes.root?.hasLoader && loaderData && "root" in loaderData) {
121 hydrationData = {
122 loaderData: {
123 root: loaderData.root
124 }
125 };
126 }
127 } else {
128 hydrationData = getHydrationData({
129 state: ssrInfo.context.state,
130 routes,
131 getRouteInfo: (routeId) => ({
132 clientLoader: ssrInfo.routeModules[routeId]?.clientLoader,
133 hasLoader: ssrInfo.manifest.routes[routeId]?.hasLoader === true,
134 hasHydrateFallback: ssrInfo.routeModules[routeId]?.HydrateFallback != null
135 }),
136 location: window.location,
137 basename: window.__reactRouterContext?.basename,
138 isSpaMode: ssrInfo.context.isSpaMode
139 });
140 if (hydrationData && hydrationData.errors) {
141 hydrationData.errors = deserializeErrors(hydrationData.errors);
142 }
143 }
144 let router2 = createRouter({
145 routes,
146 history: createBrowserHistory(),
147 basename: ssrInfo.context.basename,
148 getContext,
149 hydrationData,
150 hydrationRouteProperties,
151 unstable_instrumentations,
152 mapRouteProperties,
153 future: {
154 middleware: ssrInfo.context.future.v8_middleware
155 },
156 dataStrategy: getTurboStreamSingleFetchDataStrategy(
157 () => router2,
158 ssrInfo.manifest,
159 ssrInfo.routeModules,
160 ssrInfo.context.ssr,
161 ssrInfo.context.basename
162 ),
163 patchRoutesOnNavigation: getPatchRoutesOnNavigationFunction(
164 ssrInfo.manifest,
165 ssrInfo.routeModules,
166 ssrInfo.context.ssr,
167 ssrInfo.context.routeDiscovery,
168 ssrInfo.context.isSpaMode,
169 ssrInfo.context.basename
170 )
171 });
172 ssrInfo.router = router2;
173 if (router2.state.initialized) {
174 ssrInfo.routerInitialized = true;
175 router2.initialize();
176 }
177 router2.createRoutesForHMR = /* spacer so ts-ignore does not affect the right hand of the assignment */
178 createClientRoutesWithHMRRevalidationOptOut;
179 window.__reactRouterDataRouter = router2;
180 return router2;
181}
182function HydratedRouter(props) {
183 if (!router) {
184 router = createHydratedRouter({
185 getContext: props.getContext,
186 unstable_instrumentations: props.unstable_instrumentations
187 });
188 }
189 let [criticalCss, setCriticalCss] = React2.useState(
190 process.env.NODE_ENV === "development" ? ssrInfo?.context.criticalCss : void 0
191 );
192 React2.useEffect(() => {
193 if (process.env.NODE_ENV === "development") {
194 setCriticalCss(void 0);
195 }
196 }, []);
197 React2.useEffect(() => {
198 if (process.env.NODE_ENV === "development" && criticalCss === void 0) {
199 document.querySelectorAll(`[${CRITICAL_CSS_DATA_ATTRIBUTE}]`).forEach((element) => element.remove());
200 }
201 }, [criticalCss]);
202 let [location2, setLocation] = React2.useState(router.state.location);
203 React2.useLayoutEffect(() => {
204 if (ssrInfo && ssrInfo.router && !ssrInfo.routerInitialized) {
205 ssrInfo.routerInitialized = true;
206 ssrInfo.router.initialize();
207 }
208 }, []);
209 React2.useLayoutEffect(() => {
210 if (ssrInfo && ssrInfo.router) {
211 return ssrInfo.router.subscribe((newState) => {
212 if (newState.location !== location2) {
213 setLocation(newState.location);
214 }
215 });
216 }
217 }, [location2]);
218 invariant(ssrInfo, "ssrInfo unavailable for HydratedRouter");
219 useFogOFWarDiscovery(
220 router,
221 ssrInfo.manifest,
222 ssrInfo.routeModules,
223 ssrInfo.context.ssr,
224 ssrInfo.context.routeDiscovery,
225 ssrInfo.context.isSpaMode
226 );
227 return (
228 // This fragment is important to ensure we match the <ServerRouter> JSX
229 // structure so that useId values hydrate correctly
230 /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
231 FrameworkContext.Provider,
232 {
233 value: {
234 manifest: ssrInfo.manifest,
235 routeModules: ssrInfo.routeModules,
236 future: ssrInfo.context.future,
237 criticalCss,
238 ssr: ssrInfo.context.ssr,
239 isSpaMode: ssrInfo.context.isSpaMode,
240 routeDiscovery: ssrInfo.context.routeDiscovery
241 }
242 },
243 /* @__PURE__ */ React2.createElement(RemixErrorBoundary, { location: location2 }, /* @__PURE__ */ React2.createElement(
244 RouterProvider2,
245 {
246 router,
247 unstable_useTransitions: props.unstable_useTransitions,
248 unstable_onError: props.unstable_onError
249 }
250 ))
251 ), /* @__PURE__ */ React2.createElement(React2.Fragment, null))
252 );
253}
254
255// lib/rsc/browser.tsx
256import * as React3 from "react";
257import * as ReactDOM2 from "react-dom";
258function createCallServer({
259 createFromReadableStream,
260 createTemporaryReferenceSet,
261 encodeReply,
262 fetch: fetchImplementation = fetch
263}) {
264 const globalVar = window;
265 let landedActionId = 0;
266 return async (id, args) => {
267 let actionId = globalVar.__routerActionID = (globalVar.__routerActionID ?? (globalVar.__routerActionID = 0)) + 1;
268 const temporaryReferences = createTemporaryReferenceSet();
269 const payloadPromise = fetchImplementation(
270 new Request(location.href, {
271 body: await encodeReply(args, { temporaryReferences }),
272 method: "POST",
273 headers: {
274 Accept: "text/x-component",
275 "rsc-action-id": id
276 }
277 })
278 ).then((response) => {
279 if (!response.body) {
280 throw new Error("No response body");
281 }
282 return createFromReadableStream(response.body, {
283 temporaryReferences
284 });
285 });
286 React3.startTransition(
287 () => (
288 // @ts-expect-error - Needs React 19 types
289 Promise.resolve(payloadPromise).then(async (payload) => {
290 if (payload.type === "redirect") {
291 if (payload.reload || isExternalLocation(payload.location)) {
292 window.location.href = payload.location;
293 return;
294 }
295 React3.startTransition(() => {
296 globalVar.__reactRouterDataRouter.navigate(payload.location, {
297 replace: payload.replace
298 });
299 });
300 return;
301 }
302 if (payload.type !== "action") {
303 throw new Error("Unexpected payload type");
304 }
305 const rerender = await payload.rerender;
306 if (rerender && landedActionId < actionId && globalVar.__routerActionID <= actionId) {
307 if (rerender.type === "redirect") {
308 if (rerender.reload || isExternalLocation(rerender.location)) {
309 window.location.href = rerender.location;
310 return;
311 }
312 React3.startTransition(() => {
313 globalVar.__reactRouterDataRouter.navigate(rerender.location, {
314 replace: rerender.replace
315 });
316 });
317 return;
318 }
319 React3.startTransition(() => {
320 let lastMatch;
321 for (const match of rerender.matches) {
322 globalVar.__reactRouterDataRouter.patchRoutes(
323 lastMatch?.id ?? null,
324 [createRouteFromServerManifest(match)],
325 true
326 );
327 lastMatch = match;
328 }
329 window.__reactRouterDataRouter._internalSetStateDoNotUseOrYouWillBreakYourApp(
330 {
331 loaderData: Object.assign(
332 {},
333 globalVar.__reactRouterDataRouter.state.loaderData,
334 rerender.loaderData
335 ),
336 errors: rerender.errors ? Object.assign(
337 {},
338 globalVar.__reactRouterDataRouter.state.errors,
339 rerender.errors
340 ) : null
341 }
342 );
343 });
344 }
345 }).catch(() => {
346 })
347 )
348 );
349 return payloadPromise.then((payload) => {
350 if (payload.type !== "action" && payload.type !== "redirect") {
351 throw new Error("Unexpected payload type");
352 }
353 return payload.actionResult;
354 });
355 };
356}
357function createRouterFromPayload({
358 fetchImplementation,
359 createFromReadableStream,
360 getContext,
361 payload
362}) {
363 const globalVar = window;
364 if (globalVar.__reactRouterDataRouter && globalVar.__reactRouterRouteModules)
365 return {
366 router: globalVar.__reactRouterDataRouter,
367 routeModules: globalVar.__reactRouterRouteModules
368 };
369 if (payload.type !== "render") throw new Error("Invalid payload type");
370 globalVar.__reactRouterRouteModules = globalVar.__reactRouterRouteModules ?? {};
371 populateRSCRouteModules(globalVar.__reactRouterRouteModules, payload.matches);
372 let patches = /* @__PURE__ */ new Map();
373 payload.patches?.forEach((patch) => {
374 invariant(patch.parentId, "Invalid patch parentId");
375 if (!patches.has(patch.parentId)) {
376 patches.set(patch.parentId, []);
377 }
378 patches.get(patch.parentId)?.push(patch);
379 });
380 let routes = payload.matches.reduceRight((previous, match) => {
381 const route = createRouteFromServerManifest(
382 match,
383 payload
384 );
385 if (previous.length > 0) {
386 route.children = previous;
387 let childrenToPatch = patches.get(match.id);
388 if (childrenToPatch) {
389 route.children.push(
390 ...childrenToPatch.map((r) => createRouteFromServerManifest(r))
391 );
392 }
393 }
394 return [route];
395 }, []);
396 globalVar.__reactRouterDataRouter = createRouter({
397 routes,
398 getContext,
399 basename: payload.basename,
400 history: createBrowserHistory(),
401 hydrationData: getHydrationData({
402 state: {
403 loaderData: payload.loaderData,
404 actionData: payload.actionData,
405 errors: payload.errors
406 },
407 routes,
408 getRouteInfo: (routeId) => {
409 let match = payload.matches.find((m) => m.id === routeId);
410 invariant(match, "Route not found in payload");
411 return {
412 clientLoader: match.clientLoader,
413 hasLoader: match.hasLoader,
414 hasHydrateFallback: match.hydrateFallbackElement != null
415 };
416 },
417 location: payload.location,
418 basename: payload.basename,
419 isSpaMode: false
420 }),
421 async patchRoutesOnNavigation({ path, signal }) {
422 if (discoveredPaths.has(path)) {
423 return;
424 }
425 await fetchAndApplyManifestPatches(
426 [path],
427 createFromReadableStream,
428 fetchImplementation,
429 signal
430 );
431 },
432 // FIXME: Pass `build.ssr` into this function
433 dataStrategy: getRSCSingleFetchDataStrategy(
434 () => globalVar.__reactRouterDataRouter,
435 true,
436 payload.basename,
437 createFromReadableStream,
438 fetchImplementation
439 )
440 });
441 if (globalVar.__reactRouterDataRouter.state.initialized) {
442 globalVar.__routerInitialized = true;
443 globalVar.__reactRouterDataRouter.initialize();
444 } else {
445 globalVar.__routerInitialized = false;
446 }
447 let lastLoaderData = void 0;
448 globalVar.__reactRouterDataRouter.subscribe(({ loaderData, actionData }) => {
449 if (lastLoaderData !== loaderData) {
450 globalVar.__routerActionID = (globalVar.__routerActionID ?? (globalVar.__routerActionID = 0)) + 1;
451 }
452 });
453 globalVar.__reactRouterDataRouter._updateRoutesForHMR = (routeUpdateByRouteId) => {
454 const oldRoutes = window.__reactRouterDataRouter.routes;
455 const newRoutes = [];
456 function walkRoutes(routes2, parentId) {
457 return routes2.map((route) => {
458 const routeUpdate = routeUpdateByRouteId.get(route.id);
459 if (routeUpdate) {
460 const {
461 routeModule,
462 hasAction,
463 hasComponent,
464 hasErrorBoundary,
465 hasLoader
466 } = routeUpdate;
467 const newRoute = createRouteFromServerManifest({
468 clientAction: routeModule.clientAction,
469 clientLoader: routeModule.clientLoader,
470 element: route.element,
471 errorElement: route.errorElement,
472 handle: route.handle,
473 hasAction,
474 hasComponent,
475 hasErrorBoundary,
476 hasLoader,
477 hydrateFallbackElement: route.hydrateFallbackElement,
478 id: route.id,
479 index: route.index,
480 links: routeModule.links,
481 meta: routeModule.meta,
482 parentId,
483 path: route.path,
484 shouldRevalidate: routeModule.shouldRevalidate
485 });
486 if (route.children) {
487 newRoute.children = walkRoutes(route.children, route.id);
488 }
489 return newRoute;
490 }
491 const updatedRoute = { ...route };
492 if (route.children) {
493 updatedRoute.children = walkRoutes(route.children, route.id);
494 }
495 return updatedRoute;
496 });
497 }
498 newRoutes.push(
499 ...walkRoutes(oldRoutes, void 0)
500 );
501 window.__reactRouterDataRouter._internalSetRoutes(newRoutes);
502 };
503 return {
504 router: globalVar.__reactRouterDataRouter,
505 routeModules: globalVar.__reactRouterRouteModules
506 };
507}
508var renderedRoutesContext = createContext();
509function getRSCSingleFetchDataStrategy(getRouter, ssr, basename, createFromReadableStream, fetchImplementation) {
510 let dataStrategy = getSingleFetchDataStrategyImpl(
511 getRouter,
512 (match) => {
513 let M = match;
514 return {
515 hasLoader: M.route.hasLoader,
516 hasClientLoader: M.route.hasClientLoader,
517 hasComponent: M.route.hasComponent,
518 hasAction: M.route.hasAction,
519 hasClientAction: M.route.hasClientAction,
520 hasShouldRevalidate: M.route.hasShouldRevalidate
521 };
522 },
523 // pass map into fetchAndDecode so it can add payloads
524 getFetchAndDecodeViaRSC(createFromReadableStream, fetchImplementation),
525 ssr,
526 basename,
527 // If the route has a component but we don't have an element, we need to hit
528 // the server loader flow regardless of whether the client loader calls
529 // `serverLoader` or not, otherwise we'll have nothing to render.
530 (match) => {
531 let M = match;
532 return M.route.hasComponent && !M.route.element;
533 }
534 );
535 return async (args) => args.runClientMiddleware(async () => {
536 let context = args.context;
537 context.set(renderedRoutesContext, []);
538 let results = await dataStrategy(args);
539 const renderedRoutesById = /* @__PURE__ */ new Map();
540 for (const route of context.get(renderedRoutesContext)) {
541 if (!renderedRoutesById.has(route.id)) {
542 renderedRoutesById.set(route.id, []);
543 }
544 renderedRoutesById.get(route.id).push(route);
545 }
546 React3.startTransition(() => {
547 for (const match of args.matches) {
548 const renderedRoutes = renderedRoutesById.get(match.route.id);
549 if (renderedRoutes) {
550 for (const rendered of renderedRoutes) {
551 window.__reactRouterDataRouter.patchRoutes(
552 rendered.parentId ?? null,
553 [createRouteFromServerManifest(rendered)],
554 true
555 );
556 }
557 }
558 }
559 });
560 return results;
561 });
562}
563function getFetchAndDecodeViaRSC(createFromReadableStream, fetchImplementation) {
564 return async (args, basename, targetRoutes) => {
565 let { request, context } = args;
566 let url = singleFetchUrl(request.url, basename, "rsc");
567 if (request.method === "GET") {
568 url = stripIndexParam(url);
569 if (targetRoutes) {
570 url.searchParams.set("_routes", targetRoutes.join(","));
571 }
572 }
573 let res = await fetchImplementation(
574 new Request(url, await createRequestInit(request))
575 );
576 if (res.status >= 400 && !res.headers.has("X-Remix-Response")) {
577 throw new ErrorResponseImpl(res.status, res.statusText, await res.text());
578 }
579 invariant(res.body, "No response body to decode");
580 try {
581 const payload = await createFromReadableStream(res.body, {
582 temporaryReferences: void 0
583 });
584 if (payload.type === "redirect") {
585 return {
586 status: res.status,
587 data: {
588 redirect: {
589 redirect: payload.location,
590 reload: payload.reload,
591 replace: payload.replace,
592 revalidate: false,
593 status: payload.status
594 }
595 }
596 };
597 }
598 if (payload.type !== "render") {
599 throw new Error("Unexpected payload type");
600 }
601 context.get(renderedRoutesContext).push(...payload.matches);
602 let results = { routes: {} };
603 const dataKey = isMutationMethod(request.method) ? "actionData" : "loaderData";
604 for (let [routeId, data] of Object.entries(payload[dataKey] || {})) {
605 results.routes[routeId] = { data };
606 }
607 if (payload.errors) {
608 for (let [routeId, error] of Object.entries(payload.errors)) {
609 results.routes[routeId] = { error };
610 }
611 }
612 return { status: res.status, data: results };
613 } catch (e) {
614 throw new Error("Unable to decode RSC response");
615 }
616 };
617}
618function RSCHydratedRouter({
619 createFromReadableStream,
620 fetch: fetchImplementation = fetch,
621 payload,
622 routeDiscovery = "eager",
623 getContext
624}) {
625 if (payload.type !== "render") throw new Error("Invalid payload type");
626 let { router: router2, routeModules } = React3.useMemo(
627 () => createRouterFromPayload({
628 payload,
629 fetchImplementation,
630 getContext,
631 createFromReadableStream
632 }),
633 [createFromReadableStream, payload, fetchImplementation, getContext]
634 );
635 React3.useEffect(() => {
636 setIsHydrated();
637 }, []);
638 React3.useLayoutEffect(() => {
639 const globalVar = window;
640 if (!globalVar.__routerInitialized) {
641 globalVar.__routerInitialized = true;
642 globalVar.__reactRouterDataRouter.initialize();
643 }
644 }, []);
645 let [{ routes, state }, setState] = React3.useState(() => ({
646 routes: cloneRoutes(router2.routes),
647 state: router2.state
648 }));
649 React3.useLayoutEffect(
650 () => router2.subscribe((newState) => {
651 if (diffRoutes(router2.routes, routes))
652 React3.startTransition(() => {
653 setState({
654 routes: cloneRoutes(router2.routes),
655 state: newState
656 });
657 });
658 }),
659 [router2.subscribe, routes, router2]
660 );
661 const transitionEnabledRouter = React3.useMemo(
662 () => ({
663 ...router2,
664 state,
665 routes
666 }),
667 [router2, routes, state]
668 );
669 React3.useEffect(() => {
670 if (routeDiscovery === "lazy" || // @ts-expect-error - TS doesn't know about this yet
671 window.navigator?.connection?.saveData === true) {
672 return;
673 }
674 function registerElement(el) {
675 let path = el.tagName === "FORM" ? el.getAttribute("action") : el.getAttribute("href");
676 if (!path) {
677 return;
678 }
679 let pathname = el.tagName === "A" ? el.pathname : new URL(path, window.location.origin).pathname;
680 if (!discoveredPaths.has(pathname)) {
681 nextPaths.add(pathname);
682 }
683 }
684 async function fetchPatches() {
685 document.querySelectorAll("a[data-discover], form[data-discover]").forEach(registerElement);
686 let paths = Array.from(nextPaths.keys()).filter((path) => {
687 if (discoveredPaths.has(path)) {
688 nextPaths.delete(path);
689 return false;
690 }
691 return true;
692 });
693 if (paths.length === 0) {
694 return;
695 }
696 try {
697 await fetchAndApplyManifestPatches(
698 paths,
699 createFromReadableStream,
700 fetchImplementation
701 );
702 } catch (e) {
703 console.error("Failed to fetch manifest patches", e);
704 }
705 }
706 let debouncedFetchPatches = debounce(fetchPatches, 100);
707 fetchPatches();
708 let observer = new MutationObserver(() => debouncedFetchPatches());
709 observer.observe(document.documentElement, {
710 subtree: true,
711 childList: true,
712 attributes: true,
713 attributeFilter: ["data-discover", "href", "action"]
714 });
715 }, [routeDiscovery, createFromReadableStream, fetchImplementation]);
716 const frameworkContext = {
717 future: {
718 // These flags have no runtime impact so can always be false. If we add
719 // flags that drive runtime behavior they'll need to be proxied through.
720 v8_middleware: false,
721 unstable_subResourceIntegrity: false
722 },
723 isSpaMode: false,
724 ssr: true,
725 criticalCss: "",
726 manifest: {
727 routes: {},
728 version: "1",
729 url: "",
730 entry: {
731 module: "",
732 imports: []
733 }
734 },
735 routeDiscovery: { mode: "lazy", manifestPath: "/__manifest" },
736 routeModules
737 };
738 return /* @__PURE__ */ React3.createElement(RSCRouterContext.Provider, { value: true }, /* @__PURE__ */ React3.createElement(RSCRouterGlobalErrorBoundary, { location: state.location }, /* @__PURE__ */ React3.createElement(FrameworkContext.Provider, { value: frameworkContext }, /* @__PURE__ */ React3.createElement(
739 RouterProvider,
740 {
741 router: transitionEnabledRouter,
742 flushSync: ReactDOM2.flushSync,
743 unstable_useTransitions: true
744 }
745 ))));
746}
747function createRouteFromServerManifest(match, payload) {
748 let hasInitialData = payload && match.id in payload.loaderData;
749 let initialData = payload?.loaderData[match.id];
750 let hasInitialError = payload?.errors && match.id in payload.errors;
751 let initialError = payload?.errors?.[match.id];
752 let isHydrationRequest = match.clientLoader?.hydrate === true || !match.hasLoader || // If the route has a component but we don't have an element, we need to hit
753 // the server loader flow regardless of whether the client loader calls
754 // `serverLoader` or not, otherwise we'll have nothing to render.
755 match.hasComponent && !match.element;
756 invariant(window.__reactRouterRouteModules);
757 populateRSCRouteModules(window.__reactRouterRouteModules, match);
758 let dataRoute = {
759 id: match.id,
760 element: match.element,
761 errorElement: match.errorElement,
762 handle: match.handle,
763 hasErrorBoundary: match.hasErrorBoundary,
764 hydrateFallbackElement: match.hydrateFallbackElement,
765 index: match.index,
766 loader: match.clientLoader ? async (args, singleFetch) => {
767 try {
768 let result = await match.clientLoader({
769 ...args,
770 serverLoader: () => {
771 preventInvalidServerHandlerCall(
772 "loader",
773 match.id,
774 match.hasLoader
775 );
776 if (isHydrationRequest) {
777 if (hasInitialData) {
778 return initialData;
779 }
780 if (hasInitialError) {
781 throw initialError;
782 }
783 }
784 return callSingleFetch(singleFetch);
785 }
786 });
787 return result;
788 } finally {
789 isHydrationRequest = false;
790 }
791 } : (
792 // We always make the call in this RSC world since even if we don't
793 // have a `loader` we may need to get the `element` implementation
794 (_, singleFetch) => callSingleFetch(singleFetch)
795 ),
796 action: match.clientAction ? (args, singleFetch) => match.clientAction({
797 ...args,
798 serverAction: async () => {
799 preventInvalidServerHandlerCall(
800 "action",
801 match.id,
802 match.hasLoader
803 );
804 return await callSingleFetch(singleFetch);
805 }
806 }) : match.hasAction ? (_, singleFetch) => callSingleFetch(singleFetch) : () => {
807 throw noActionDefinedError("action", match.id);
808 },
809 path: match.path,
810 shouldRevalidate: match.shouldRevalidate,
811 // We always have a "loader" in this RSC world since even if we don't
812 // have a `loader` we may need to get the `element` implementation
813 hasLoader: true,
814 hasClientLoader: match.clientLoader != null,
815 hasAction: match.hasAction,
816 hasClientAction: match.clientAction != null,
817 hasShouldRevalidate: match.shouldRevalidate != null
818 };
819 if (typeof dataRoute.loader === "function") {
820 dataRoute.loader.hydrate = shouldHydrateRouteLoader(
821 match.id,
822 match.clientLoader,
823 match.hasLoader,
824 false
825 );
826 }
827 return dataRoute;
828}
829function callSingleFetch(singleFetch) {
830 invariant(typeof singleFetch === "function", "Invalid singleFetch parameter");
831 return singleFetch();
832}
833function preventInvalidServerHandlerCall(type, routeId, hasHandler) {
834 if (!hasHandler) {
835 let fn = type === "action" ? "serverAction()" : "serverLoader()";
836 let msg = `You are trying to call ${fn} on a route that does not have a server ${type} (routeId: "${routeId}")`;
837 console.error(msg);
838 throw new ErrorResponseImpl(400, "Bad Request", new Error(msg), true);
839 }
840}
841var nextPaths = /* @__PURE__ */ new Set();
842var discoveredPathsMaxSize = 1e3;
843var discoveredPaths = /* @__PURE__ */ new Set();
844var URL_LIMIT = 7680;
845function getManifestUrl(paths) {
846 if (paths.length === 0) {
847 return null;
848 }
849 if (paths.length === 1) {
850 return new URL(`${paths[0]}.manifest`, window.location.origin);
851 }
852 const globalVar = window;
853 let basename = (globalVar.__reactRouterDataRouter.basename ?? "").replace(
854 /^\/|\/$/g,
855 ""
856 );
857 let url = new URL(`${basename}/.manifest`, window.location.origin);
858 url.searchParams.set("paths", paths.sort().join(","));
859 return url;
860}
861async function fetchAndApplyManifestPatches(paths, createFromReadableStream, fetchImplementation, signal) {
862 let url = getManifestUrl(paths);
863 if (url == null) {
864 return;
865 }
866 if (url.toString().length > URL_LIMIT) {
867 nextPaths.clear();
868 return;
869 }
870 let response = await fetchImplementation(new Request(url, { signal }));
871 if (!response.body || response.status < 200 || response.status >= 300) {
872 throw new Error("Unable to fetch new route matches from the server");
873 }
874 let payload = await createFromReadableStream(response.body, {
875 temporaryReferences: void 0
876 });
877 if (payload.type !== "manifest") {
878 throw new Error("Failed to patch routes");
879 }
880 paths.forEach((p) => addToFifoQueue(p, discoveredPaths));
881 React3.startTransition(() => {
882 payload.patches.forEach((p) => {
883 window.__reactRouterDataRouter.patchRoutes(
884 p.parentId ?? null,
885 [createRouteFromServerManifest(p)]
886 );
887 });
888 });
889}
890function addToFifoQueue(path, queue) {
891 if (queue.size >= discoveredPathsMaxSize) {
892 let first = queue.values().next().value;
893 queue.delete(first);
894 }
895 queue.add(path);
896}
897function debounce(callback, wait) {
898 let timeoutId;
899 return (...args) => {
900 window.clearTimeout(timeoutId);
901 timeoutId = window.setTimeout(() => callback(...args), wait);
902 };
903}
904function isExternalLocation(location2) {
905 const newLocation = new URL(location2, window.location.href);
906 return newLocation.origin !== window.location.origin;
907}
908function cloneRoutes(routes) {
909 if (!routes) return void 0;
910 return routes.map((route) => ({
911 ...route,
912 children: cloneRoutes(route.children)
913 }));
914}
915function diffRoutes(a, b) {
916 if (a.length !== b.length) return true;
917 return a.some((route, index) => {
918 if (route.element !== b[index].element) return true;
919 if (route.errorElement !== b[index].errorElement)
920 return true;
921 if (route.hydrateFallbackElement !== b[index].hydrateFallbackElement)
922 return true;
923 if (route.hasErrorBoundary !== b[index].hasErrorBoundary)
924 return true;
925 if (route.hasLoader !== b[index].hasLoader) return true;
926 if (route.hasClientLoader !== b[index].hasClientLoader)
927 return true;
928 if (route.hasAction !== b[index].hasAction) return true;
929 if (route.hasClientAction !== b[index].hasClientAction)
930 return true;
931 return diffRoutes(route.children || [], b[index].children || []);
932 });
933}
934
935// lib/rsc/html-stream/browser.ts
936function getRSCStream() {
937 let encoder = new TextEncoder();
938 let streamController = null;
939 let rscStream = new ReadableStream({
940 start(controller) {
941 if (typeof window === "undefined") {
942 return;
943 }
944 let handleChunk = (chunk) => {
945 if (typeof chunk === "string") {
946 controller.enqueue(encoder.encode(chunk));
947 } else {
948 controller.enqueue(chunk);
949 }
950 };
951 window.__FLIGHT_DATA || (window.__FLIGHT_DATA = []);
952 window.__FLIGHT_DATA.forEach(handleChunk);
953 window.__FLIGHT_DATA.push = (chunk) => {
954 handleChunk(chunk);
955 return 0;
956 };
957 streamController = controller;
958 }
959 });
960 if (typeof document !== "undefined" && document.readyState === "loading") {
961 document.addEventListener("DOMContentLoaded", () => {
962 streamController?.close();
963 });
964 } else {
965 streamController?.close();
966 }
967 return rscStream;
968}
969export {
970 HydratedRouter,
971 RouterProvider2 as RouterProvider,
972 RSCHydratedRouter as unstable_RSCHydratedRouter,
973 createCallServer as unstable_createCallServer,
974 getRSCStream as unstable_getRSCStream
975};