UNPKG

317 kBJavaScriptView Raw
1"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/**
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 */
11var __typeError = (msg) => {
12 throw TypeError(msg);
13};
14var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
15var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
16var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
17
18// lib/router/history.ts
19var Action = /* @__PURE__ */ ((Action2) => {
20 Action2["Pop"] = "POP";
21 Action2["Push"] = "PUSH";
22 Action2["Replace"] = "REPLACE";
23 return Action2;
24})(Action || {});
25var PopStateEventType = "popstate";
26function createMemoryHistory(options = {}) {
27 let { initialEntries = ["/"], initialIndex, v5Compat = false } = options;
28 let entries;
29 entries = initialEntries.map(
30 (entry, index2) => createMemoryLocation(
31 entry,
32 typeof entry === "string" ? null : entry.state,
33 index2 === 0 ? "default" : void 0
34 )
35 );
36 let index = clampIndex(
37 initialIndex == null ? entries.length - 1 : initialIndex
38 );
39 let action = "POP" /* Pop */;
40 let listener = null;
41 function clampIndex(n) {
42 return Math.min(Math.max(n, 0), entries.length - 1);
43 }
44 function getCurrentLocation() {
45 return entries[index];
46 }
47 function createMemoryLocation(to, state = null, key) {
48 let location = createLocation(
49 entries ? getCurrentLocation().pathname : "/",
50 to,
51 state,
52 key
53 );
54 warning(
55 location.pathname.charAt(0) === "/",
56 `relative pathnames are not supported in memory history: ${JSON.stringify(
57 to
58 )}`
59 );
60 return location;
61 }
62 function createHref(to) {
63 return typeof to === "string" ? to : createPath(to);
64 }
65 let history = {
66 get index() {
67 return index;
68 },
69 get action() {
70 return action;
71 },
72 get location() {
73 return getCurrentLocation();
74 },
75 createHref,
76 createURL(to) {
77 return new URL(createHref(to), "http://localhost");
78 },
79 encodeLocation(to) {
80 let path = typeof to === "string" ? parsePath(to) : to;
81 return {
82 pathname: path.pathname || "",
83 search: path.search || "",
84 hash: path.hash || ""
85 };
86 },
87 push(to, state) {
88 action = "PUSH" /* Push */;
89 let nextLocation = createMemoryLocation(to, state);
90 index += 1;
91 entries.splice(index, entries.length, nextLocation);
92 if (v5Compat && listener) {
93 listener({ action, location: nextLocation, delta: 1 });
94 }
95 },
96 replace(to, state) {
97 action = "REPLACE" /* Replace */;
98 let nextLocation = createMemoryLocation(to, state);
99 entries[index] = nextLocation;
100 if (v5Compat && listener) {
101 listener({ action, location: nextLocation, delta: 0 });
102 }
103 },
104 go(delta) {
105 action = "POP" /* Pop */;
106 let nextIndex = clampIndex(index + delta);
107 let nextLocation = entries[nextIndex];
108 index = nextIndex;
109 if (listener) {
110 listener({ action, location: nextLocation, delta });
111 }
112 },
113 listen(fn) {
114 listener = fn;
115 return () => {
116 listener = null;
117 };
118 }
119 };
120 return history;
121}
122function createBrowserHistory(options = {}) {
123 function createBrowserLocation(window2, globalHistory) {
124 let { pathname, search, hash } = window2.location;
125 return createLocation(
126 "",
127 { pathname, search, hash },
128 // state defaults to `null` because `window.history.state` does
129 globalHistory.state && globalHistory.state.usr || null,
130 globalHistory.state && globalHistory.state.key || "default"
131 );
132 }
133 function createBrowserHref(window2, to) {
134 return typeof to === "string" ? to : createPath(to);
135 }
136 return getUrlBasedHistory(
137 createBrowserLocation,
138 createBrowserHref,
139 null,
140 options
141 );
142}
143function createHashHistory(options = {}) {
144 function createHashLocation(window2, globalHistory) {
145 let {
146 pathname = "/",
147 search = "",
148 hash = ""
149 } = parsePath(window2.location.hash.substring(1));
150 if (!pathname.startsWith("/") && !pathname.startsWith(".")) {
151 pathname = "/" + pathname;
152 }
153 return createLocation(
154 "",
155 { pathname, search, hash },
156 // state defaults to `null` because `window.history.state` does
157 globalHistory.state && globalHistory.state.usr || null,
158 globalHistory.state && globalHistory.state.key || "default"
159 );
160 }
161 function createHashHref(window2, to) {
162 let base = window2.document.querySelector("base");
163 let href = "";
164 if (base && base.getAttribute("href")) {
165 let url = window2.location.href;
166 let hashIndex = url.indexOf("#");
167 href = hashIndex === -1 ? url : url.slice(0, hashIndex);
168 }
169 return href + "#" + (typeof to === "string" ? to : createPath(to));
170 }
171 function validateHashLocation(location, to) {
172 warning(
173 location.pathname.charAt(0) === "/",
174 `relative pathnames are not supported in hash history.push(${JSON.stringify(
175 to
176 )})`
177 );
178 }
179 return getUrlBasedHistory(
180 createHashLocation,
181 createHashHref,
182 validateHashLocation,
183 options
184 );
185}
186function invariant(value, message) {
187 if (value === false || value === null || typeof value === "undefined") {
188 throw new Error(message);
189 }
190}
191function warning(cond, message) {
192 if (!cond) {
193 if (typeof console !== "undefined") console.warn(message);
194 try {
195 throw new Error(message);
196 } catch (e) {
197 }
198 }
199}
200function createKey() {
201 return Math.random().toString(36).substring(2, 10);
202}
203function getHistoryState(location, index) {
204 return {
205 usr: location.state,
206 key: location.key,
207 idx: index
208 };
209}
210function createLocation(current, to, state = null, key) {
211 let location = {
212 pathname: typeof current === "string" ? current : current.pathname,
213 search: "",
214 hash: "",
215 ...typeof to === "string" ? parsePath(to) : to,
216 state,
217 // TODO: This could be cleaned up. push/replace should probably just take
218 // full Locations now and avoid the need to run through this flow at all
219 // But that's a pretty big refactor to the current test suite so going to
220 // keep as is for the time being and just let any incoming keys take precedence
221 key: to && to.key || key || createKey()
222 };
223 return location;
224}
225function createPath({
226 pathname = "/",
227 search = "",
228 hash = ""
229}) {
230 if (search && search !== "?")
231 pathname += search.charAt(0) === "?" ? search : "?" + search;
232 if (hash && hash !== "#")
233 pathname += hash.charAt(0) === "#" ? hash : "#" + hash;
234 return pathname;
235}
236function parsePath(path) {
237 let parsedPath = {};
238 if (path) {
239 let hashIndex = path.indexOf("#");
240 if (hashIndex >= 0) {
241 parsedPath.hash = path.substring(hashIndex);
242 path = path.substring(0, hashIndex);
243 }
244 let searchIndex = path.indexOf("?");
245 if (searchIndex >= 0) {
246 parsedPath.search = path.substring(searchIndex);
247 path = path.substring(0, searchIndex);
248 }
249 if (path) {
250 parsedPath.pathname = path;
251 }
252 }
253 return parsedPath;
254}
255function getUrlBasedHistory(getLocation, createHref, validateLocation, options = {}) {
256 let { window: window2 = document.defaultView, v5Compat = false } = options;
257 let globalHistory = window2.history;
258 let action = "POP" /* Pop */;
259 let listener = null;
260 let index = getIndex();
261 if (index == null) {
262 index = 0;
263 globalHistory.replaceState({ ...globalHistory.state, idx: index }, "");
264 }
265 function getIndex() {
266 let state = globalHistory.state || { idx: null };
267 return state.idx;
268 }
269 function handlePop() {
270 action = "POP" /* Pop */;
271 let nextIndex = getIndex();
272 let delta = nextIndex == null ? null : nextIndex - index;
273 index = nextIndex;
274 if (listener) {
275 listener({ action, location: history.location, delta });
276 }
277 }
278 function push(to, state) {
279 action = "PUSH" /* Push */;
280 let location = createLocation(history.location, to, state);
281 if (validateLocation) validateLocation(location, to);
282 index = getIndex() + 1;
283 let historyState = getHistoryState(location, index);
284 let url = history.createHref(location);
285 try {
286 globalHistory.pushState(historyState, "", url);
287 } catch (error) {
288 if (error instanceof DOMException && error.name === "DataCloneError") {
289 throw error;
290 }
291 window2.location.assign(url);
292 }
293 if (v5Compat && listener) {
294 listener({ action, location: history.location, delta: 1 });
295 }
296 }
297 function replace2(to, state) {
298 action = "REPLACE" /* Replace */;
299 let location = createLocation(history.location, to, state);
300 if (validateLocation) validateLocation(location, to);
301 index = getIndex();
302 let historyState = getHistoryState(location, index);
303 let url = history.createHref(location);
304 globalHistory.replaceState(historyState, "", url);
305 if (v5Compat && listener) {
306 listener({ action, location: history.location, delta: 0 });
307 }
308 }
309 function createURL(to) {
310 return createBrowserURLImpl(to);
311 }
312 let history = {
313 get action() {
314 return action;
315 },
316 get location() {
317 return getLocation(window2, globalHistory);
318 },
319 listen(fn) {
320 if (listener) {
321 throw new Error("A history only accepts one active listener");
322 }
323 window2.addEventListener(PopStateEventType, handlePop);
324 listener = fn;
325 return () => {
326 window2.removeEventListener(PopStateEventType, handlePop);
327 listener = null;
328 };
329 },
330 createHref(to) {
331 return createHref(window2, to);
332 },
333 createURL,
334 encodeLocation(to) {
335 let url = createURL(to);
336 return {
337 pathname: url.pathname,
338 search: url.search,
339 hash: url.hash
340 };
341 },
342 push,
343 replace: replace2,
344 go(n) {
345 return globalHistory.go(n);
346 }
347 };
348 return history;
349}
350function createBrowserURLImpl(to, isAbsolute = false) {
351 let base = "http://localhost";
352 if (typeof window !== "undefined") {
353 base = window.location.origin !== "null" ? window.location.origin : window.location.href;
354 }
355 invariant(base, "No window.location.(origin|href) available to create URL");
356 let href = typeof to === "string" ? to : createPath(to);
357 href = href.replace(/ $/, "%20");
358 if (!isAbsolute && href.startsWith("//")) {
359 href = base + href;
360 }
361 return new URL(href, base);
362}
363
364// lib/router/utils.ts
365function createContext(defaultValue) {
366 return { defaultValue };
367}
368var _map;
369var RouterContextProvider = class {
370 /**
371 * Create a new `RouterContextProvider` instance
372 * @param init An optional initial context map to populate the provider with
373 */
374 constructor(init) {
375 __privateAdd(this, _map, /* @__PURE__ */ new Map());
376 if (init) {
377 for (let [context, value] of init) {
378 this.set(context, value);
379 }
380 }
381 }
382 /**
383 * Access a value from the context. If no value has been set for the context,
384 * it will return the context's `defaultValue` if provided, or throw an error
385 * if no `defaultValue` was set.
386 * @param context The context to get the value for
387 * @returns The value for the context, or the context's `defaultValue` if no
388 * value was set
389 */
390 get(context) {
391 if (__privateGet(this, _map).has(context)) {
392 return __privateGet(this, _map).get(context);
393 }
394 if (context.defaultValue !== void 0) {
395 return context.defaultValue;
396 }
397 throw new Error("No value found for context");
398 }
399 /**
400 * Set a value for the context. If the context already has a value set, this
401 * will overwrite it.
402 *
403 * @param context The context to set the value for
404 * @param value The value to set for the context
405 * @returns {void}
406 */
407 set(context, value) {
408 __privateGet(this, _map).set(context, value);
409 }
410};
411_map = new WeakMap();
412var unsupportedLazyRouteObjectKeys = /* @__PURE__ */ new Set([
413 "lazy",
414 "caseSensitive",
415 "path",
416 "id",
417 "index",
418 "children"
419]);
420function isUnsupportedLazyRouteObjectKey(key) {
421 return unsupportedLazyRouteObjectKeys.has(
422 key
423 );
424}
425var unsupportedLazyRouteFunctionKeys = /* @__PURE__ */ new Set([
426 "lazy",
427 "caseSensitive",
428 "path",
429 "id",
430 "index",
431 "middleware",
432 "children"
433]);
434function isUnsupportedLazyRouteFunctionKey(key) {
435 return unsupportedLazyRouteFunctionKeys.has(
436 key
437 );
438}
439function isIndexRoute(route) {
440 return route.index === true;
441}
442function convertRoutesToDataRoutes(routes, mapRouteProperties2, parentPath = [], manifest = {}, allowInPlaceMutations = false) {
443 return routes.map((route, index) => {
444 let treePath = [...parentPath, String(index)];
445 let id = typeof route.id === "string" ? route.id : treePath.join("-");
446 invariant(
447 route.index !== true || !route.children,
448 `Cannot specify children on an index route`
449 );
450 invariant(
451 allowInPlaceMutations || !manifest[id],
452 `Found a route id collision on id "${id}". Route id's must be globally unique within Data Router usages`
453 );
454 if (isIndexRoute(route)) {
455 let indexRoute = {
456 ...route,
457 id
458 };
459 manifest[id] = mergeRouteUpdates(
460 indexRoute,
461 mapRouteProperties2(indexRoute)
462 );
463 return indexRoute;
464 } else {
465 let pathOrLayoutRoute = {
466 ...route,
467 id,
468 children: void 0
469 };
470 manifest[id] = mergeRouteUpdates(
471 pathOrLayoutRoute,
472 mapRouteProperties2(pathOrLayoutRoute)
473 );
474 if (route.children) {
475 pathOrLayoutRoute.children = convertRoutesToDataRoutes(
476 route.children,
477 mapRouteProperties2,
478 treePath,
479 manifest,
480 allowInPlaceMutations
481 );
482 }
483 return pathOrLayoutRoute;
484 }
485 });
486}
487function mergeRouteUpdates(route, updates) {
488 return Object.assign(route, {
489 ...updates,
490 ...typeof updates.lazy === "object" && updates.lazy != null ? {
491 lazy: {
492 ...route.lazy,
493 ...updates.lazy
494 }
495 } : {}
496 });
497}
498function matchRoutes(routes, locationArg, basename = "/") {
499 return matchRoutesImpl(routes, locationArg, basename, false);
500}
501function matchRoutesImpl(routes, locationArg, basename, allowPartial) {
502 let location = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
503 let pathname = stripBasename(location.pathname || "/", basename);
504 if (pathname == null) {
505 return null;
506 }
507 let branches = flattenRoutes(routes);
508 rankRouteBranches(branches);
509 let matches = null;
510 for (let i = 0; matches == null && i < branches.length; ++i) {
511 let decoded = decodePath(pathname);
512 matches = matchRouteBranch(
513 branches[i],
514 decoded,
515 allowPartial
516 );
517 }
518 return matches;
519}
520function convertRouteMatchToUiMatch(match, loaderData) {
521 let { route, pathname, params } = match;
522 return {
523 id: route.id,
524 pathname,
525 params,
526 data: loaderData[route.id],
527 loaderData: loaderData[route.id],
528 handle: route.handle
529 };
530}
531function flattenRoutes(routes, branches = [], parentsMeta = [], parentPath = "", _hasParentOptionalSegments = false) {
532 let flattenRoute = (route, index, hasParentOptionalSegments = _hasParentOptionalSegments, relativePath) => {
533 let meta = {
534 relativePath: relativePath === void 0 ? route.path || "" : relativePath,
535 caseSensitive: route.caseSensitive === true,
536 childrenIndex: index,
537 route
538 };
539 if (meta.relativePath.startsWith("/")) {
540 if (!meta.relativePath.startsWith(parentPath) && hasParentOptionalSegments) {
541 return;
542 }
543 invariant(
544 meta.relativePath.startsWith(parentPath),
545 `Absolute route path "${meta.relativePath}" nested under path "${parentPath}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`
546 );
547 meta.relativePath = meta.relativePath.slice(parentPath.length);
548 }
549 let path = joinPaths([parentPath, meta.relativePath]);
550 let routesMeta = parentsMeta.concat(meta);
551 if (route.children && route.children.length > 0) {
552 invariant(
553 // Our types know better, but runtime JS may not!
554 // @ts-expect-error
555 route.index !== true,
556 `Index routes must not have child routes. Please remove all child routes from route path "${path}".`
557 );
558 flattenRoutes(
559 route.children,
560 branches,
561 routesMeta,
562 path,
563 hasParentOptionalSegments
564 );
565 }
566 if (route.path == null && !route.index) {
567 return;
568 }
569 branches.push({
570 path,
571 score: computeScore(path, route.index),
572 routesMeta
573 });
574 };
575 routes.forEach((route, index) => {
576 if (route.path === "" || !_optionalChain([route, 'access', _2 => _2.path, 'optionalAccess', _3 => _3.includes, 'call', _4 => _4("?")])) {
577 flattenRoute(route, index);
578 } else {
579 for (let exploded of explodeOptionalSegments(route.path)) {
580 flattenRoute(route, index, true, exploded);
581 }
582 }
583 });
584 return branches;
585}
586function explodeOptionalSegments(path) {
587 let segments = path.split("/");
588 if (segments.length === 0) return [];
589 let [first, ...rest] = segments;
590 let isOptional = first.endsWith("?");
591 let required = first.replace(/\?$/, "");
592 if (rest.length === 0) {
593 return isOptional ? [required, ""] : [required];
594 }
595 let restExploded = explodeOptionalSegments(rest.join("/"));
596 let result = [];
597 result.push(
598 ...restExploded.map(
599 (subpath) => subpath === "" ? required : [required, subpath].join("/")
600 )
601 );
602 if (isOptional) {
603 result.push(...restExploded);
604 }
605 return result.map(
606 (exploded) => path.startsWith("/") && exploded === "" ? "/" : exploded
607 );
608}
609function rankRouteBranches(branches) {
610 branches.sort(
611 (a, b) => a.score !== b.score ? b.score - a.score : compareIndexes(
612 a.routesMeta.map((meta) => meta.childrenIndex),
613 b.routesMeta.map((meta) => meta.childrenIndex)
614 )
615 );
616}
617var paramRe = /^:[\w-]+$/;
618var dynamicSegmentValue = 3;
619var indexRouteValue = 2;
620var emptySegmentValue = 1;
621var staticSegmentValue = 10;
622var splatPenalty = -2;
623var isSplat = (s) => s === "*";
624function computeScore(path, index) {
625 let segments = path.split("/");
626 let initialScore = segments.length;
627 if (segments.some(isSplat)) {
628 initialScore += splatPenalty;
629 }
630 if (index) {
631 initialScore += indexRouteValue;
632 }
633 return segments.filter((s) => !isSplat(s)).reduce(
634 (score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue),
635 initialScore
636 );
637}
638function compareIndexes(a, b) {
639 let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);
640 return siblings ? (
641 // If two routes are siblings, we should try to match the earlier sibling
642 // first. This allows people to have fine-grained control over the matching
643 // behavior by simply putting routes with identical paths in the order they
644 // want them tried.
645 a[a.length - 1] - b[b.length - 1]
646 ) : (
647 // Otherwise, it doesn't really make sense to rank non-siblings by index,
648 // so they sort equally.
649 0
650 );
651}
652function matchRouteBranch(branch, pathname, allowPartial = false) {
653 let { routesMeta } = branch;
654 let matchedParams = {};
655 let matchedPathname = "/";
656 let matches = [];
657 for (let i = 0; i < routesMeta.length; ++i) {
658 let meta = routesMeta[i];
659 let end = i === routesMeta.length - 1;
660 let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/";
661 let match = matchPath(
662 { path: meta.relativePath, caseSensitive: meta.caseSensitive, end },
663 remainingPathname
664 );
665 let route = meta.route;
666 if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) {
667 match = matchPath(
668 {
669 path: meta.relativePath,
670 caseSensitive: meta.caseSensitive,
671 end: false
672 },
673 remainingPathname
674 );
675 }
676 if (!match) {
677 return null;
678 }
679 Object.assign(matchedParams, match.params);
680 matches.push({
681 // TODO: Can this as be avoided?
682 params: matchedParams,
683 pathname: joinPaths([matchedPathname, match.pathname]),
684 pathnameBase: normalizePathname(
685 joinPaths([matchedPathname, match.pathnameBase])
686 ),
687 route
688 });
689 if (match.pathnameBase !== "/") {
690 matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);
691 }
692 }
693 return matches;
694}
695function generatePath(originalPath, params = {}) {
696 let path = originalPath;
697 if (path.endsWith("*") && path !== "*" && !path.endsWith("/*")) {
698 warning(
699 false,
700 `Route path "${path}" will be treated as if it were "${path.replace(/\*$/, "/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${path.replace(/\*$/, "/*")}".`
701 );
702 path = path.replace(/\*$/, "/*");
703 }
704 const prefix = path.startsWith("/") ? "/" : "";
705 const stringify2 = (p) => p == null ? "" : typeof p === "string" ? p : String(p);
706 const segments = path.split(/\/+/).map((segment, index, array) => {
707 const isLastSegment = index === array.length - 1;
708 if (isLastSegment && segment === "*") {
709 const star = "*";
710 return stringify2(params[star]);
711 }
712 const keyMatch = segment.match(/^:([\w-]+)(\??)$/);
713 if (keyMatch) {
714 const [, key, optional] = keyMatch;
715 let param = params[key];
716 invariant(optional === "?" || param != null, `Missing ":${key}" param`);
717 return encodeURIComponent(stringify2(param));
718 }
719 return segment.replace(/\?$/g, "");
720 }).filter((segment) => !!segment);
721 return prefix + segments.join("/");
722}
723function matchPath(pattern, pathname) {
724 if (typeof pattern === "string") {
725 pattern = { path: pattern, caseSensitive: false, end: true };
726 }
727 let [matcher, compiledParams] = compilePath(
728 pattern.path,
729 pattern.caseSensitive,
730 pattern.end
731 );
732 let match = pathname.match(matcher);
733 if (!match) return null;
734 let matchedPathname = match[0];
735 let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
736 let captureGroups = match.slice(1);
737 let params = compiledParams.reduce(
738 (memo2, { paramName, isOptional }, index) => {
739 if (paramName === "*") {
740 let splatValue = captureGroups[index] || "";
741 pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
742 }
743 const value = captureGroups[index];
744 if (isOptional && !value) {
745 memo2[paramName] = void 0;
746 } else {
747 memo2[paramName] = (value || "").replace(/%2F/g, "/");
748 }
749 return memo2;
750 },
751 {}
752 );
753 return {
754 params,
755 pathname: matchedPathname,
756 pathnameBase,
757 pattern
758 };
759}
760function compilePath(path, caseSensitive = false, end = true) {
761 warning(
762 path === "*" || !path.endsWith("*") || path.endsWith("/*"),
763 `Route path "${path}" will be treated as if it were "${path.replace(/\*$/, "/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${path.replace(/\*$/, "/*")}".`
764 );
765 let params = [];
766 let regexpSource = "^" + path.replace(/\/*\*?$/, "").replace(/^\/*/, "/").replace(/[\\.*+^${}|()[\]]/g, "\\$&").replace(
767 /\/:([\w-]+)(\?)?/g,
768 (_, paramName, isOptional) => {
769 params.push({ paramName, isOptional: isOptional != null });
770 return isOptional ? "/?([^\\/]+)?" : "/([^\\/]+)";
771 }
772 ).replace(/\/([\w-]+)\?(\/|$)/g, "(/$1)?$2");
773 if (path.endsWith("*")) {
774 params.push({ paramName: "*" });
775 regexpSource += path === "*" || path === "/*" ? "(.*)$" : "(?:\\/(.+)|\\/*)$";
776 } else if (end) {
777 regexpSource += "\\/*$";
778 } else if (path !== "" && path !== "/") {
779 regexpSource += "(?:(?=\\/|$))";
780 } else {
781 }
782 let matcher = new RegExp(regexpSource, caseSensitive ? void 0 : "i");
783 return [matcher, params];
784}
785function decodePath(value) {
786 try {
787 return value.split("/").map((v) => decodeURIComponent(v).replace(/\//g, "%2F")).join("/");
788 } catch (error) {
789 warning(
790 false,
791 `The URL path "${value}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${error}).`
792 );
793 return value;
794 }
795}
796function stripBasename(pathname, basename) {
797 if (basename === "/") return pathname;
798 if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
799 return null;
800 }
801 let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length;
802 let nextChar = pathname.charAt(startIndex);
803 if (nextChar && nextChar !== "/") {
804 return null;
805 }
806 return pathname.slice(startIndex) || "/";
807}
808function prependBasename({
809 basename,
810 pathname
811}) {
812 return pathname === "/" ? basename : joinPaths([basename, pathname]);
813}
814var ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
815var isAbsoluteUrl = (url) => ABSOLUTE_URL_REGEX.test(url);
816function resolvePath(to, fromPathname = "/") {
817 let {
818 pathname: toPathname,
819 search = "",
820 hash = ""
821 } = typeof to === "string" ? parsePath(to) : to;
822 let pathname;
823 if (toPathname) {
824 if (isAbsoluteUrl(toPathname)) {
825 pathname = toPathname;
826 } else {
827 if (toPathname.includes("//")) {
828 let oldPathname = toPathname;
829 toPathname = toPathname.replace(/\/\/+/g, "/");
830 warning(
831 false,
832 `Pathnames cannot have embedded double slashes - normalizing ${oldPathname} -> ${toPathname}`
833 );
834 }
835 if (toPathname.startsWith("/")) {
836 pathname = resolvePathname(toPathname.substring(1), "/");
837 } else {
838 pathname = resolvePathname(toPathname, fromPathname);
839 }
840 }
841 } else {
842 pathname = fromPathname;
843 }
844 return {
845 pathname,
846 search: normalizeSearch(search),
847 hash: normalizeHash(hash)
848 };
849}
850function resolvePathname(relativePath, fromPathname) {
851 let segments = fromPathname.replace(/\/+$/, "").split("/");
852 let relativeSegments = relativePath.split("/");
853 relativeSegments.forEach((segment) => {
854 if (segment === "..") {
855 if (segments.length > 1) segments.pop();
856 } else if (segment !== ".") {
857 segments.push(segment);
858 }
859 });
860 return segments.length > 1 ? segments.join("/") : "/";
861}
862function getInvalidPathError(char, field, dest, path) {
863 return `Cannot include a '${char}' character in a manually specified \`to.${field}\` field [${JSON.stringify(
864 path
865 )}]. Please separate it out to the \`to.${dest}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`;
866}
867function getPathContributingMatches(matches) {
868 return matches.filter(
869 (match, index) => index === 0 || match.route.path && match.route.path.length > 0
870 );
871}
872function getResolveToMatches(matches) {
873 let pathMatches = getPathContributingMatches(matches);
874 return pathMatches.map(
875 (match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase
876 );
877}
878function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = false) {
879 let to;
880 if (typeof toArg === "string") {
881 to = parsePath(toArg);
882 } else {
883 to = { ...toArg };
884 invariant(
885 !to.pathname || !to.pathname.includes("?"),
886 getInvalidPathError("?", "pathname", "search", to)
887 );
888 invariant(
889 !to.pathname || !to.pathname.includes("#"),
890 getInvalidPathError("#", "pathname", "hash", to)
891 );
892 invariant(
893 !to.search || !to.search.includes("#"),
894 getInvalidPathError("#", "search", "hash", to)
895 );
896 }
897 let isEmptyPath = toArg === "" || to.pathname === "";
898 let toPathname = isEmptyPath ? "/" : to.pathname;
899 let from;
900 if (toPathname == null) {
901 from = locationPathname;
902 } else {
903 let routePathnameIndex = routePathnames.length - 1;
904 if (!isPathRelative && toPathname.startsWith("..")) {
905 let toSegments = toPathname.split("/");
906 while (toSegments[0] === "..") {
907 toSegments.shift();
908 routePathnameIndex -= 1;
909 }
910 to.pathname = toSegments.join("/");
911 }
912 from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
913 }
914 let path = resolvePath(to, from);
915 let hasExplicitTrailingSlash = toPathname && toPathname !== "/" && toPathname.endsWith("/");
916 let hasCurrentTrailingSlash = (isEmptyPath || toPathname === ".") && locationPathname.endsWith("/");
917 if (!path.pathname.endsWith("/") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) {
918 path.pathname += "/";
919 }
920 return path;
921}
922var joinPaths = (paths) => paths.join("/").replace(/\/\/+/g, "/");
923var normalizePathname = (pathname) => pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
924var normalizeSearch = (search) => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
925var normalizeHash = (hash) => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
926var DataWithResponseInit = class {
927 constructor(data2, init) {
928 this.type = "DataWithResponseInit";
929 this.data = data2;
930 this.init = init || null;
931 }
932};
933function data(data2, init) {
934 return new DataWithResponseInit(
935 data2,
936 typeof init === "number" ? { status: init } : init
937 );
938}
939var redirect = (url, init = 302) => {
940 let responseInit = init;
941 if (typeof responseInit === "number") {
942 responseInit = { status: responseInit };
943 } else if (typeof responseInit.status === "undefined") {
944 responseInit.status = 302;
945 }
946 let headers = new Headers(responseInit.headers);
947 headers.set("Location", url);
948 return new Response(null, { ...responseInit, headers });
949};
950var redirectDocument = (url, init) => {
951 let response = redirect(url, init);
952 response.headers.set("X-Remix-Reload-Document", "true");
953 return response;
954};
955var replace = (url, init) => {
956 let response = redirect(url, init);
957 response.headers.set("X-Remix-Replace", "true");
958 return response;
959};
960var ErrorResponseImpl = class {
961 constructor(status, statusText, data2, internal = false) {
962 this.status = status;
963 this.statusText = statusText || "";
964 this.internal = internal;
965 if (data2 instanceof Error) {
966 this.data = data2.toString();
967 this.error = data2;
968 } else {
969 this.data = data2;
970 }
971 }
972};
973function isRouteErrorResponse(error) {
974 return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error;
975}
976function getRoutePattern(matches) {
977 return matches.map((m) => m.route.path).filter(Boolean).join("/").replace(/\/\/*/g, "/") || "/";
978}
979
980// lib/router/instrumentation.ts
981var UninstrumentedSymbol = Symbol("Uninstrumented");
982function getRouteInstrumentationUpdates(fns, route) {
983 let aggregated = {
984 lazy: [],
985 "lazy.loader": [],
986 "lazy.action": [],
987 "lazy.middleware": [],
988 middleware: [],
989 loader: [],
990 action: []
991 };
992 fns.forEach(
993 (fn) => fn({
994 id: route.id,
995 index: route.index,
996 path: route.path,
997 instrument(i) {
998 let keys = Object.keys(aggregated);
999 for (let key of keys) {
1000 if (i[key]) {
1001 aggregated[key].push(i[key]);
1002 }
1003 }
1004 }
1005 })
1006 );
1007 let updates = {};
1008 if (typeof route.lazy === "function" && aggregated.lazy.length > 0) {
1009 let instrumented = wrapImpl(aggregated.lazy, route.lazy, () => void 0);
1010 if (instrumented) {
1011 updates.lazy = instrumented;
1012 }
1013 }
1014 if (typeof route.lazy === "object") {
1015 let lazyObject = route.lazy;
1016 ["middleware", "loader", "action"].forEach((key) => {
1017 let lazyFn = lazyObject[key];
1018 let instrumentations = aggregated[`lazy.${key}`];
1019 if (typeof lazyFn === "function" && instrumentations.length > 0) {
1020 let instrumented = wrapImpl(instrumentations, lazyFn, () => void 0);
1021 if (instrumented) {
1022 updates.lazy = Object.assign(updates.lazy || {}, {
1023 [key]: instrumented
1024 });
1025 }
1026 }
1027 });
1028 }
1029 ["loader", "action"].forEach((key) => {
1030 let handler = route[key];
1031 if (typeof handler === "function" && aggregated[key].length > 0) {
1032 let original = _nullishCoalesce(handler[UninstrumentedSymbol], () => ( handler));
1033 let instrumented = wrapImpl(
1034 aggregated[key],
1035 original,
1036 (...args) => getHandlerInfo(args[0])
1037 );
1038 if (instrumented) {
1039 instrumented[UninstrumentedSymbol] = original;
1040 updates[key] = instrumented;
1041 }
1042 }
1043 });
1044 if (route.middleware && route.middleware.length > 0 && aggregated.middleware.length > 0) {
1045 updates.middleware = route.middleware.map((middleware) => {
1046 let original = _nullishCoalesce(middleware[UninstrumentedSymbol], () => ( middleware));
1047 let instrumented = wrapImpl(
1048 aggregated.middleware,
1049 original,
1050 (...args) => getHandlerInfo(args[0])
1051 );
1052 if (instrumented) {
1053 instrumented[UninstrumentedSymbol] = original;
1054 return instrumented;
1055 }
1056 return middleware;
1057 });
1058 }
1059 return updates;
1060}
1061function instrumentClientSideRouter(router, fns) {
1062 let aggregated = {
1063 navigate: [],
1064 fetch: []
1065 };
1066 fns.forEach(
1067 (fn) => fn({
1068 instrument(i) {
1069 let keys = Object.keys(i);
1070 for (let key of keys) {
1071 if (i[key]) {
1072 aggregated[key].push(i[key]);
1073 }
1074 }
1075 }
1076 })
1077 );
1078 if (aggregated.navigate.length > 0) {
1079 let navigate = _nullishCoalesce(router.navigate[UninstrumentedSymbol], () => ( router.navigate));
1080 let instrumentedNavigate = wrapImpl(
1081 aggregated.navigate,
1082 navigate,
1083 (...args) => {
1084 let [to, opts] = args;
1085 return {
1086 to: typeof to === "number" || typeof to === "string" ? to : to ? createPath(to) : ".",
1087 ...getRouterInfo(router, _nullishCoalesce(opts, () => ( {})))
1088 };
1089 }
1090 );
1091 if (instrumentedNavigate) {
1092 instrumentedNavigate[UninstrumentedSymbol] = navigate;
1093 router.navigate = instrumentedNavigate;
1094 }
1095 }
1096 if (aggregated.fetch.length > 0) {
1097 let fetch2 = _nullishCoalesce(router.fetch[UninstrumentedSymbol], () => ( router.fetch));
1098 let instrumentedFetch = wrapImpl(aggregated.fetch, fetch2, (...args) => {
1099 let [key, , href, opts] = args;
1100 return {
1101 href: _nullishCoalesce(href, () => ( ".")),
1102 fetcherKey: key,
1103 ...getRouterInfo(router, _nullishCoalesce(opts, () => ( {})))
1104 };
1105 });
1106 if (instrumentedFetch) {
1107 instrumentedFetch[UninstrumentedSymbol] = fetch2;
1108 router.fetch = instrumentedFetch;
1109 }
1110 }
1111 return router;
1112}
1113function instrumentHandler(handler, fns) {
1114 let aggregated = {
1115 request: []
1116 };
1117 fns.forEach(
1118 (fn) => fn({
1119 instrument(i) {
1120 let keys = Object.keys(i);
1121 for (let key of keys) {
1122 if (i[key]) {
1123 aggregated[key].push(i[key]);
1124 }
1125 }
1126 }
1127 })
1128 );
1129 let instrumentedHandler = handler;
1130 if (aggregated.request.length > 0) {
1131 instrumentedHandler = wrapImpl(aggregated.request, handler, (...args) => {
1132 let [request, context] = args;
1133 return {
1134 request: getReadonlyRequest(request),
1135 context: context != null ? getReadonlyContext(context) : context
1136 };
1137 });
1138 }
1139 return instrumentedHandler;
1140}
1141function wrapImpl(impls, handler, getInfo) {
1142 if (impls.length === 0) {
1143 return null;
1144 }
1145 return async (...args) => {
1146 let result = await recurseRight(
1147 impls,
1148 getInfo(...args),
1149 () => handler(...args),
1150 impls.length - 1
1151 );
1152 if (result.type === "error") {
1153 throw result.value;
1154 }
1155 return result.value;
1156 };
1157}
1158async function recurseRight(impls, info, handler, index) {
1159 let impl = impls[index];
1160 let result;
1161 if (!impl) {
1162 try {
1163 let value = await handler();
1164 result = { type: "success", value };
1165 } catch (e) {
1166 result = { type: "error", value: e };
1167 }
1168 } else {
1169 let handlerPromise = void 0;
1170 let callHandler = async () => {
1171 if (handlerPromise) {
1172 console.error("You cannot call instrumented handlers more than once");
1173 } else {
1174 handlerPromise = recurseRight(impls, info, handler, index - 1);
1175 }
1176 result = await handlerPromise;
1177 invariant(result, "Expected a result");
1178 if (result.type === "error" && result.value instanceof Error) {
1179 return { status: "error", error: result.value };
1180 }
1181 return { status: "success", error: void 0 };
1182 };
1183 try {
1184 await impl(callHandler, info);
1185 } catch (e) {
1186 console.error("An instrumentation function threw an error:", e);
1187 }
1188 if (!handlerPromise) {
1189 await callHandler();
1190 }
1191 await handlerPromise;
1192 }
1193 if (result) {
1194 return result;
1195 }
1196 return {
1197 type: "error",
1198 value: new Error("No result assigned in instrumentation chain.")
1199 };
1200}
1201function getHandlerInfo(args) {
1202 let { request, context, params, unstable_pattern } = args;
1203 return {
1204 request: getReadonlyRequest(request),
1205 params: { ...params },
1206 unstable_pattern,
1207 context: getReadonlyContext(context)
1208 };
1209}
1210function getRouterInfo(router, opts) {
1211 return {
1212 currentUrl: createPath(router.state.location),
1213 ..."formMethod" in opts ? { formMethod: opts.formMethod } : {},
1214 ..."formEncType" in opts ? { formEncType: opts.formEncType } : {},
1215 ..."formData" in opts ? { formData: opts.formData } : {},
1216 ..."body" in opts ? { body: opts.body } : {}
1217 };
1218}
1219function getReadonlyRequest(request) {
1220 return {
1221 method: request.method,
1222 url: request.url,
1223 headers: {
1224 get: (...args) => request.headers.get(...args)
1225 }
1226 };
1227}
1228function getReadonlyContext(context) {
1229 if (isPlainObject(context)) {
1230 let frozen = { ...context };
1231 Object.freeze(frozen);
1232 return frozen;
1233 } else {
1234 return {
1235 get: (ctx) => context.get(ctx)
1236 };
1237 }
1238}
1239var objectProtoNames = Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
1240function isPlainObject(thing) {
1241 if (thing === null || typeof thing !== "object") {
1242 return false;
1243 }
1244 const proto = Object.getPrototypeOf(thing);
1245 return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames;
1246}
1247
1248// lib/router/router.ts
1249var validMutationMethodsArr = [
1250 "POST",
1251 "PUT",
1252 "PATCH",
1253 "DELETE"
1254];
1255var validMutationMethods = new Set(
1256 validMutationMethodsArr
1257);
1258var validRequestMethodsArr = [
1259 "GET",
1260 ...validMutationMethodsArr
1261];
1262var validRequestMethods = new Set(validRequestMethodsArr);
1263var redirectStatusCodes = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
1264var redirectPreserveMethodStatusCodes = /* @__PURE__ */ new Set([307, 308]);
1265var IDLE_NAVIGATION = {
1266 state: "idle",
1267 location: void 0,
1268 formMethod: void 0,
1269 formAction: void 0,
1270 formEncType: void 0,
1271 formData: void 0,
1272 json: void 0,
1273 text: void 0
1274};
1275var IDLE_FETCHER = {
1276 state: "idle",
1277 data: void 0,
1278 formMethod: void 0,
1279 formAction: void 0,
1280 formEncType: void 0,
1281 formData: void 0,
1282 json: void 0,
1283 text: void 0
1284};
1285var IDLE_BLOCKER = {
1286 state: "unblocked",
1287 proceed: void 0,
1288 reset: void 0,
1289 location: void 0
1290};
1291var defaultMapRouteProperties = (route) => ({
1292 hasErrorBoundary: Boolean(route.hasErrorBoundary)
1293});
1294var TRANSITIONS_STORAGE_KEY = "remix-router-transitions";
1295var ResetLoaderDataSymbol = Symbol("ResetLoaderData");
1296function createRouter(init) {
1297 const routerWindow = init.window ? init.window : typeof window !== "undefined" ? window : void 0;
1298 const isBrowser = typeof routerWindow !== "undefined" && typeof routerWindow.document !== "undefined" && typeof routerWindow.document.createElement !== "undefined";
1299 invariant(
1300 init.routes.length > 0,
1301 "You must provide a non-empty routes array to createRouter"
1302 );
1303 let hydrationRouteProperties2 = init.hydrationRouteProperties || [];
1304 let _mapRouteProperties = init.mapRouteProperties || defaultMapRouteProperties;
1305 let mapRouteProperties2 = _mapRouteProperties;
1306 if (init.unstable_instrumentations) {
1307 let instrumentations = init.unstable_instrumentations;
1308 mapRouteProperties2 = (route) => {
1309 return {
1310 ..._mapRouteProperties(route),
1311 ...getRouteInstrumentationUpdates(
1312 instrumentations.map((i) => i.route).filter(Boolean),
1313 route
1314 )
1315 };
1316 };
1317 }
1318 let manifest = {};
1319 let dataRoutes = convertRoutesToDataRoutes(
1320 init.routes,
1321 mapRouteProperties2,
1322 void 0,
1323 manifest
1324 );
1325 let inFlightDataRoutes;
1326 let basename = init.basename || "/";
1327 if (!basename.startsWith("/")) {
1328 basename = `/${basename}`;
1329 }
1330 let dataStrategyImpl = init.dataStrategy || defaultDataStrategyWithMiddleware;
1331 let future = {
1332 ...init.future
1333 };
1334 let unlistenHistory = null;
1335 let subscribers = /* @__PURE__ */ new Set();
1336 let savedScrollPositions = null;
1337 let getScrollRestorationKey = null;
1338 let getScrollPosition = null;
1339 let initialScrollRestored = init.hydrationData != null;
1340 let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);
1341 let initialMatchesIsFOW = false;
1342 let initialErrors = null;
1343 let initialized;
1344 if (initialMatches == null && !init.patchRoutesOnNavigation) {
1345 let error = getInternalRouterError(404, {
1346 pathname: init.history.location.pathname
1347 });
1348 let { matches, route } = getShortCircuitMatches(dataRoutes);
1349 initialized = true;
1350 initialMatches = matches;
1351 initialErrors = { [route.id]: error };
1352 } else {
1353 if (initialMatches && !init.hydrationData) {
1354 let fogOfWar = checkFogOfWar(
1355 initialMatches,
1356 dataRoutes,
1357 init.history.location.pathname
1358 );
1359 if (fogOfWar.active) {
1360 initialMatches = null;
1361 }
1362 }
1363 if (!initialMatches) {
1364 initialized = false;
1365 initialMatches = [];
1366 let fogOfWar = checkFogOfWar(
1367 null,
1368 dataRoutes,
1369 init.history.location.pathname
1370 );
1371 if (fogOfWar.active && fogOfWar.matches) {
1372 initialMatchesIsFOW = true;
1373 initialMatches = fogOfWar.matches;
1374 }
1375 } else if (initialMatches.some((m) => m.route.lazy)) {
1376 initialized = false;
1377 } else if (!initialMatches.some((m) => routeHasLoaderOrMiddleware(m.route))) {
1378 initialized = true;
1379 } else {
1380 let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;
1381 let errors = init.hydrationData ? init.hydrationData.errors : null;
1382 if (errors) {
1383 let idx = initialMatches.findIndex(
1384 (m) => errors[m.route.id] !== void 0
1385 );
1386 initialized = initialMatches.slice(0, idx + 1).every(
1387 (m) => !shouldLoadRouteOnHydration(m.route, loaderData, errors)
1388 );
1389 } else {
1390 initialized = initialMatches.every(
1391 (m) => !shouldLoadRouteOnHydration(m.route, loaderData, errors)
1392 );
1393 }
1394 }
1395 }
1396 let router;
1397 let state = {
1398 historyAction: init.history.action,
1399 location: init.history.location,
1400 matches: initialMatches,
1401 initialized,
1402 navigation: IDLE_NAVIGATION,
1403 // Don't restore on initial updateState() if we were SSR'd
1404 restoreScrollPosition: init.hydrationData != null ? false : null,
1405 preventScrollReset: false,
1406 revalidation: "idle",
1407 loaderData: init.hydrationData && init.hydrationData.loaderData || {},
1408 actionData: init.hydrationData && init.hydrationData.actionData || null,
1409 errors: init.hydrationData && init.hydrationData.errors || initialErrors,
1410 fetchers: /* @__PURE__ */ new Map(),
1411 blockers: /* @__PURE__ */ new Map()
1412 };
1413 let pendingAction = "POP" /* Pop */;
1414 let pendingPopstateNavigationDfd = null;
1415 let pendingPreventScrollReset = false;
1416 let pendingNavigationController;
1417 let pendingViewTransitionEnabled = false;
1418 let appliedViewTransitions = /* @__PURE__ */ new Map();
1419 let removePageHideEventListener = null;
1420 let isUninterruptedRevalidation = false;
1421 let isRevalidationRequired = false;
1422 let cancelledFetcherLoads = /* @__PURE__ */ new Set();
1423 let fetchControllers = /* @__PURE__ */ new Map();
1424 let incrementingLoadId = 0;
1425 let pendingNavigationLoadId = -1;
1426 let fetchReloadIds = /* @__PURE__ */ new Map();
1427 let fetchRedirectIds = /* @__PURE__ */ new Set();
1428 let fetchLoadMatches = /* @__PURE__ */ new Map();
1429 let activeFetchers = /* @__PURE__ */ new Map();
1430 let fetchersQueuedForDeletion = /* @__PURE__ */ new Set();
1431 let blockerFunctions = /* @__PURE__ */ new Map();
1432 let unblockBlockerHistoryUpdate = void 0;
1433 let pendingRevalidationDfd = null;
1434 function initialize() {
1435 unlistenHistory = init.history.listen(
1436 ({ action: historyAction, location, delta }) => {
1437 if (unblockBlockerHistoryUpdate) {
1438 unblockBlockerHistoryUpdate();
1439 unblockBlockerHistoryUpdate = void 0;
1440 return;
1441 }
1442 warning(
1443 blockerFunctions.size === 0 || delta != null,
1444 "You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs. This can also happen if you are using createHashRouter and the user manually changes the URL."
1445 );
1446 let blockerKey = shouldBlockNavigation({
1447 currentLocation: state.location,
1448 nextLocation: location,
1449 historyAction
1450 });
1451 if (blockerKey && delta != null) {
1452 let nextHistoryUpdatePromise = new Promise((resolve) => {
1453 unblockBlockerHistoryUpdate = resolve;
1454 });
1455 init.history.go(delta * -1);
1456 updateBlocker(blockerKey, {
1457 state: "blocked",
1458 location,
1459 proceed() {
1460 updateBlocker(blockerKey, {
1461 state: "proceeding",
1462 proceed: void 0,
1463 reset: void 0,
1464 location
1465 });
1466 nextHistoryUpdatePromise.then(() => init.history.go(delta));
1467 },
1468 reset() {
1469 let blockers = new Map(state.blockers);
1470 blockers.set(blockerKey, IDLE_BLOCKER);
1471 updateState({ blockers });
1472 }
1473 });
1474 _optionalChain([pendingPopstateNavigationDfd, 'optionalAccess', _5 => _5.resolve, 'call', _6 => _6()]);
1475 pendingPopstateNavigationDfd = null;
1476 return;
1477 }
1478 return startNavigation(historyAction, location);
1479 }
1480 );
1481 if (isBrowser) {
1482 restoreAppliedTransitions(routerWindow, appliedViewTransitions);
1483 let _saveAppliedTransitions = () => persistAppliedTransitions(routerWindow, appliedViewTransitions);
1484 routerWindow.addEventListener("pagehide", _saveAppliedTransitions);
1485 removePageHideEventListener = () => routerWindow.removeEventListener("pagehide", _saveAppliedTransitions);
1486 }
1487 if (!state.initialized) {
1488 startNavigation("POP" /* Pop */, state.location, {
1489 initialHydration: true
1490 });
1491 }
1492 return router;
1493 }
1494 function dispose() {
1495 if (unlistenHistory) {
1496 unlistenHistory();
1497 }
1498 if (removePageHideEventListener) {
1499 removePageHideEventListener();
1500 }
1501 subscribers.clear();
1502 pendingNavigationController && pendingNavigationController.abort();
1503 state.fetchers.forEach((_, key) => deleteFetcher(key));
1504 state.blockers.forEach((_, key) => deleteBlocker(key));
1505 }
1506 function subscribe(fn) {
1507 subscribers.add(fn);
1508 return () => subscribers.delete(fn);
1509 }
1510 function updateState(newState, opts = {}) {
1511 if (newState.matches) {
1512 newState.matches = newState.matches.map((m) => {
1513 let route = manifest[m.route.id];
1514 let matchRoute = m.route;
1515 if (matchRoute.element !== route.element || matchRoute.errorElement !== route.errorElement || matchRoute.hydrateFallbackElement !== route.hydrateFallbackElement) {
1516 return {
1517 ...m,
1518 route
1519 };
1520 }
1521 return m;
1522 });
1523 }
1524 state = {
1525 ...state,
1526 ...newState
1527 };
1528 let unmountedFetchers = [];
1529 let mountedFetchers = [];
1530 state.fetchers.forEach((fetcher, key) => {
1531 if (fetcher.state === "idle") {
1532 if (fetchersQueuedForDeletion.has(key)) {
1533 unmountedFetchers.push(key);
1534 } else {
1535 mountedFetchers.push(key);
1536 }
1537 }
1538 });
1539 fetchersQueuedForDeletion.forEach((key) => {
1540 if (!state.fetchers.has(key) && !fetchControllers.has(key)) {
1541 unmountedFetchers.push(key);
1542 }
1543 });
1544 [...subscribers].forEach(
1545 (subscriber) => subscriber(state, {
1546 deletedFetchers: unmountedFetchers,
1547 newErrors: _nullishCoalesce(newState.errors, () => ( null)),
1548 viewTransitionOpts: opts.viewTransitionOpts,
1549 flushSync: opts.flushSync === true
1550 })
1551 );
1552 unmountedFetchers.forEach((key) => deleteFetcher(key));
1553 mountedFetchers.forEach((key) => state.fetchers.delete(key));
1554 }
1555 function completeNavigation(location, newState, { flushSync } = {}) {
1556 let isActionReload = state.actionData != null && state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && state.navigation.state === "loading" && _optionalChain([location, 'access', _7 => _7.state, 'optionalAccess', _8 => _8._isRedirect]) !== true;
1557 let actionData;
1558 if (newState.actionData) {
1559 if (Object.keys(newState.actionData).length > 0) {
1560 actionData = newState.actionData;
1561 } else {
1562 actionData = null;
1563 }
1564 } else if (isActionReload) {
1565 actionData = state.actionData;
1566 } else {
1567 actionData = null;
1568 }
1569 let loaderData = newState.loaderData ? mergeLoaderData(
1570 state.loaderData,
1571 newState.loaderData,
1572 newState.matches || [],
1573 newState.errors
1574 ) : state.loaderData;
1575 let blockers = state.blockers;
1576 if (blockers.size > 0) {
1577 blockers = new Map(blockers);
1578 blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER));
1579 }
1580 let restoreScrollPosition = isUninterruptedRevalidation ? false : getSavedScrollPosition(location, newState.matches || state.matches);
1581 let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && _optionalChain([location, 'access', _9 => _9.state, 'optionalAccess', _10 => _10._isRedirect]) !== true;
1582 if (inFlightDataRoutes) {
1583 dataRoutes = inFlightDataRoutes;
1584 inFlightDataRoutes = void 0;
1585 }
1586 if (isUninterruptedRevalidation) {
1587 } else if (pendingAction === "POP" /* Pop */) {
1588 } else if (pendingAction === "PUSH" /* Push */) {
1589 init.history.push(location, location.state);
1590 } else if (pendingAction === "REPLACE" /* Replace */) {
1591 init.history.replace(location, location.state);
1592 }
1593 let viewTransitionOpts;
1594 if (pendingAction === "POP" /* Pop */) {
1595 let priorPaths = appliedViewTransitions.get(state.location.pathname);
1596 if (priorPaths && priorPaths.has(location.pathname)) {
1597 viewTransitionOpts = {
1598 currentLocation: state.location,
1599 nextLocation: location
1600 };
1601 } else if (appliedViewTransitions.has(location.pathname)) {
1602 viewTransitionOpts = {
1603 currentLocation: location,
1604 nextLocation: state.location
1605 };
1606 }
1607 } else if (pendingViewTransitionEnabled) {
1608 let toPaths = appliedViewTransitions.get(state.location.pathname);
1609 if (toPaths) {
1610 toPaths.add(location.pathname);
1611 } else {
1612 toPaths = /* @__PURE__ */ new Set([location.pathname]);
1613 appliedViewTransitions.set(state.location.pathname, toPaths);
1614 }
1615 viewTransitionOpts = {
1616 currentLocation: state.location,
1617 nextLocation: location
1618 };
1619 }
1620 updateState(
1621 {
1622 ...newState,
1623 // matches, errors, fetchers go through as-is
1624 actionData,
1625 loaderData,
1626 historyAction: pendingAction,
1627 location,
1628 initialized: true,
1629 navigation: IDLE_NAVIGATION,
1630 revalidation: "idle",
1631 restoreScrollPosition,
1632 preventScrollReset,
1633 blockers
1634 },
1635 {
1636 viewTransitionOpts,
1637 flushSync: flushSync === true
1638 }
1639 );
1640 pendingAction = "POP" /* Pop */;
1641 pendingPreventScrollReset = false;
1642 pendingViewTransitionEnabled = false;
1643 isUninterruptedRevalidation = false;
1644 isRevalidationRequired = false;
1645 _optionalChain([pendingPopstateNavigationDfd, 'optionalAccess', _11 => _11.resolve, 'call', _12 => _12()]);
1646 pendingPopstateNavigationDfd = null;
1647 _optionalChain([pendingRevalidationDfd, 'optionalAccess', _13 => _13.resolve, 'call', _14 => _14()]);
1648 pendingRevalidationDfd = null;
1649 }
1650 async function navigate(to, opts) {
1651 _optionalChain([pendingPopstateNavigationDfd, 'optionalAccess', _15 => _15.resolve, 'call', _16 => _16()]);
1652 pendingPopstateNavigationDfd = null;
1653 if (typeof to === "number") {
1654 if (!pendingPopstateNavigationDfd) {
1655 pendingPopstateNavigationDfd = createDeferred();
1656 }
1657 let promise = pendingPopstateNavigationDfd.promise;
1658 init.history.go(to);
1659 return promise;
1660 }
1661 let normalizedPath = normalizeTo(
1662 state.location,
1663 state.matches,
1664 basename,
1665 to,
1666 _optionalChain([opts, 'optionalAccess', _17 => _17.fromRouteId]),
1667 _optionalChain([opts, 'optionalAccess', _18 => _18.relative])
1668 );
1669 let { path, submission, error } = normalizeNavigateOptions(
1670 false,
1671 normalizedPath,
1672 opts
1673 );
1674 let currentLocation = state.location;
1675 let nextLocation = createLocation(state.location, path, opts && opts.state);
1676 nextLocation = {
1677 ...nextLocation,
1678 ...init.history.encodeLocation(nextLocation)
1679 };
1680 let userReplace = opts && opts.replace != null ? opts.replace : void 0;
1681 let historyAction = "PUSH" /* Push */;
1682 if (userReplace === true) {
1683 historyAction = "REPLACE" /* Replace */;
1684 } else if (userReplace === false) {
1685 } else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) {
1686 historyAction = "REPLACE" /* Replace */;
1687 }
1688 let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : void 0;
1689 let flushSync = (opts && opts.flushSync) === true;
1690 let blockerKey = shouldBlockNavigation({
1691 currentLocation,
1692 nextLocation,
1693 historyAction
1694 });
1695 if (blockerKey) {
1696 updateBlocker(blockerKey, {
1697 state: "blocked",
1698 location: nextLocation,
1699 proceed() {
1700 updateBlocker(blockerKey, {
1701 state: "proceeding",
1702 proceed: void 0,
1703 reset: void 0,
1704 location: nextLocation
1705 });
1706 navigate(to, opts);
1707 },
1708 reset() {
1709 let blockers = new Map(state.blockers);
1710 blockers.set(blockerKey, IDLE_BLOCKER);
1711 updateState({ blockers });
1712 }
1713 });
1714 return;
1715 }
1716 await startNavigation(historyAction, nextLocation, {
1717 submission,
1718 // Send through the formData serialization error if we have one so we can
1719 // render at the right error boundary after we match routes
1720 pendingError: error,
1721 preventScrollReset,
1722 replace: opts && opts.replace,
1723 enableViewTransition: opts && opts.viewTransition,
1724 flushSync
1725 });
1726 }
1727 function revalidate() {
1728 if (!pendingRevalidationDfd) {
1729 pendingRevalidationDfd = createDeferred();
1730 }
1731 interruptActiveLoads();
1732 updateState({ revalidation: "loading" });
1733 let promise = pendingRevalidationDfd.promise;
1734 if (state.navigation.state === "submitting") {
1735 return promise;
1736 }
1737 if (state.navigation.state === "idle") {
1738 startNavigation(state.historyAction, state.location, {
1739 startUninterruptedRevalidation: true
1740 });
1741 return promise;
1742 }
1743 startNavigation(
1744 pendingAction || state.historyAction,
1745 state.navigation.location,
1746 {
1747 overrideNavigation: state.navigation,
1748 // Proxy through any rending view transition
1749 enableViewTransition: pendingViewTransitionEnabled === true
1750 }
1751 );
1752 return promise;
1753 }
1754 async function startNavigation(historyAction, location, opts) {
1755 pendingNavigationController && pendingNavigationController.abort();
1756 pendingNavigationController = null;
1757 pendingAction = historyAction;
1758 isUninterruptedRevalidation = (opts && opts.startUninterruptedRevalidation) === true;
1759 saveScrollPosition(state.location, state.matches);
1760 pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;
1761 pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true;
1762 let routesToUse = inFlightDataRoutes || dataRoutes;
1763 let loadingNavigation = opts && opts.overrideNavigation;
1764 let matches = _optionalChain([opts, 'optionalAccess', _19 => _19.initialHydration]) && state.matches && state.matches.length > 0 && !initialMatchesIsFOW ? (
1765 // `matchRoutes()` has already been called if we're in here via `router.initialize()`
1766 state.matches
1767 ) : matchRoutes(routesToUse, location, basename);
1768 let flushSync = (opts && opts.flushSync) === true;
1769 if (matches && state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) {
1770 completeNavigation(location, { matches }, { flushSync });
1771 return;
1772 }
1773 let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname);
1774 if (fogOfWar.active && fogOfWar.matches) {
1775 matches = fogOfWar.matches;
1776 }
1777 if (!matches) {
1778 let { error, notFoundMatches, route } = handleNavigational404(
1779 location.pathname
1780 );
1781 completeNavigation(
1782 location,
1783 {
1784 matches: notFoundMatches,
1785 loaderData: {},
1786 errors: {
1787 [route.id]: error
1788 }
1789 },
1790 { flushSync }
1791 );
1792 return;
1793 }
1794 pendingNavigationController = new AbortController();
1795 let request = createClientSideRequest(
1796 init.history,
1797 location,
1798 pendingNavigationController.signal,
1799 opts && opts.submission
1800 );
1801 let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider();
1802 let pendingActionResult;
1803 if (opts && opts.pendingError) {
1804 pendingActionResult = [
1805 findNearestBoundary(matches).route.id,
1806 { type: "error" /* error */, error: opts.pendingError }
1807 ];
1808 } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) {
1809 let actionResult = await handleAction(
1810 request,
1811 location,
1812 opts.submission,
1813 matches,
1814 scopedContext,
1815 fogOfWar.active,
1816 opts && opts.initialHydration === true,
1817 { replace: opts.replace, flushSync }
1818 );
1819 if (actionResult.shortCircuited) {
1820 return;
1821 }
1822 if (actionResult.pendingActionResult) {
1823 let [routeId, result] = actionResult.pendingActionResult;
1824 if (isErrorResult(result) && isRouteErrorResponse(result.error) && result.error.status === 404) {
1825 pendingNavigationController = null;
1826 completeNavigation(location, {
1827 matches: actionResult.matches,
1828 loaderData: {},
1829 errors: {
1830 [routeId]: result.error
1831 }
1832 });
1833 return;
1834 }
1835 }
1836 matches = actionResult.matches || matches;
1837 pendingActionResult = actionResult.pendingActionResult;
1838 loadingNavigation = getLoadingNavigation(location, opts.submission);
1839 flushSync = false;
1840 fogOfWar.active = false;
1841 request = createClientSideRequest(
1842 init.history,
1843 request.url,
1844 request.signal
1845 );
1846 }
1847 let {
1848 shortCircuited,
1849 matches: updatedMatches,
1850 loaderData,
1851 errors
1852 } = await handleLoaders(
1853 request,
1854 location,
1855 matches,
1856 scopedContext,
1857 fogOfWar.active,
1858 loadingNavigation,
1859 opts && opts.submission,
1860 opts && opts.fetcherSubmission,
1861 opts && opts.replace,
1862 opts && opts.initialHydration === true,
1863 flushSync,
1864 pendingActionResult
1865 );
1866 if (shortCircuited) {
1867 return;
1868 }
1869 pendingNavigationController = null;
1870 completeNavigation(location, {
1871 matches: updatedMatches || matches,
1872 ...getActionDataForCommit(pendingActionResult),
1873 loaderData,
1874 errors
1875 });
1876 }
1877 async function handleAction(request, location, submission, matches, scopedContext, isFogOfWar, initialHydration, opts = {}) {
1878 interruptActiveLoads();
1879 let navigation = getSubmittingNavigation(location, submission);
1880 updateState({ navigation }, { flushSync: opts.flushSync === true });
1881 if (isFogOfWar) {
1882 let discoverResult = await discoverRoutes(
1883 matches,
1884 location.pathname,
1885 request.signal
1886 );
1887 if (discoverResult.type === "aborted") {
1888 return { shortCircuited: true };
1889 } else if (discoverResult.type === "error") {
1890 if (discoverResult.partialMatches.length === 0) {
1891 let { matches: matches2, route } = getShortCircuitMatches(dataRoutes);
1892 return {
1893 matches: matches2,
1894 pendingActionResult: [
1895 route.id,
1896 {
1897 type: "error" /* error */,
1898 error: discoverResult.error
1899 }
1900 ]
1901 };
1902 }
1903 let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;
1904 return {
1905 matches: discoverResult.partialMatches,
1906 pendingActionResult: [
1907 boundaryId,
1908 {
1909 type: "error" /* error */,
1910 error: discoverResult.error
1911 }
1912 ]
1913 };
1914 } else if (!discoverResult.matches) {
1915 let { notFoundMatches, error, route } = handleNavigational404(
1916 location.pathname
1917 );
1918 return {
1919 matches: notFoundMatches,
1920 pendingActionResult: [
1921 route.id,
1922 {
1923 type: "error" /* error */,
1924 error
1925 }
1926 ]
1927 };
1928 } else {
1929 matches = discoverResult.matches;
1930 }
1931 }
1932 let result;
1933 let actionMatch = getTargetMatch(matches, location);
1934 if (!actionMatch.route.action && !actionMatch.route.lazy) {
1935 result = {
1936 type: "error" /* error */,
1937 error: getInternalRouterError(405, {
1938 method: request.method,
1939 pathname: location.pathname,
1940 routeId: actionMatch.route.id
1941 })
1942 };
1943 } else {
1944 let dsMatches = getTargetedDataStrategyMatches(
1945 mapRouteProperties2,
1946 manifest,
1947 request,
1948 matches,
1949 actionMatch,
1950 initialHydration ? [] : hydrationRouteProperties2,
1951 scopedContext
1952 );
1953 let results = await callDataStrategy(
1954 request,
1955 dsMatches,
1956 scopedContext,
1957 null
1958 );
1959 result = results[actionMatch.route.id];
1960 if (!result) {
1961 for (let match of matches) {
1962 if (results[match.route.id]) {
1963 result = results[match.route.id];
1964 break;
1965 }
1966 }
1967 }
1968 if (request.signal.aborted) {
1969 return { shortCircuited: true };
1970 }
1971 }
1972 if (isRedirectResult(result)) {
1973 let replace2;
1974 if (opts && opts.replace != null) {
1975 replace2 = opts.replace;
1976 } else {
1977 let location2 = normalizeRedirectLocation(
1978 result.response.headers.get("Location"),
1979 new URL(request.url),
1980 basename
1981 );
1982 replace2 = location2 === state.location.pathname + state.location.search;
1983 }
1984 await startRedirectNavigation(request, result, true, {
1985 submission,
1986 replace: replace2
1987 });
1988 return { shortCircuited: true };
1989 }
1990 if (isErrorResult(result)) {
1991 let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);
1992 if ((opts && opts.replace) !== true) {
1993 pendingAction = "PUSH" /* Push */;
1994 }
1995 return {
1996 matches,
1997 pendingActionResult: [
1998 boundaryMatch.route.id,
1999 result,
2000 actionMatch.route.id
2001 ]
2002 };
2003 }
2004 return {
2005 matches,
2006 pendingActionResult: [actionMatch.route.id, result]
2007 };
2008 }
2009 async function handleLoaders(request, location, matches, scopedContext, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace2, initialHydration, flushSync, pendingActionResult) {
2010 let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission);
2011 let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation);
2012 let shouldUpdateNavigationState = !isUninterruptedRevalidation && !initialHydration;
2013 if (isFogOfWar) {
2014 if (shouldUpdateNavigationState) {
2015 let actionData = getUpdatedActionData(pendingActionResult);
2016 updateState(
2017 {
2018 navigation: loadingNavigation,
2019 ...actionData !== void 0 ? { actionData } : {}
2020 },
2021 {
2022 flushSync
2023 }
2024 );
2025 }
2026 let discoverResult = await discoverRoutes(
2027 matches,
2028 location.pathname,
2029 request.signal
2030 );
2031 if (discoverResult.type === "aborted") {
2032 return { shortCircuited: true };
2033 } else if (discoverResult.type === "error") {
2034 if (discoverResult.partialMatches.length === 0) {
2035 let { matches: matches2, route } = getShortCircuitMatches(dataRoutes);
2036 return {
2037 matches: matches2,
2038 loaderData: {},
2039 errors: {
2040 [route.id]: discoverResult.error
2041 }
2042 };
2043 }
2044 let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;
2045 return {
2046 matches: discoverResult.partialMatches,
2047 loaderData: {},
2048 errors: {
2049 [boundaryId]: discoverResult.error
2050 }
2051 };
2052 } else if (!discoverResult.matches) {
2053 let { error, notFoundMatches, route } = handleNavigational404(
2054 location.pathname
2055 );
2056 return {
2057 matches: notFoundMatches,
2058 loaderData: {},
2059 errors: {
2060 [route.id]: error
2061 }
2062 };
2063 } else {
2064 matches = discoverResult.matches;
2065 }
2066 }
2067 let routesToUse = inFlightDataRoutes || dataRoutes;
2068 let { dsMatches, revalidatingFetchers } = getMatchesToLoad(
2069 request,
2070 scopedContext,
2071 mapRouteProperties2,
2072 manifest,
2073 init.history,
2074 state,
2075 matches,
2076 activeSubmission,
2077 location,
2078 initialHydration ? [] : hydrationRouteProperties2,
2079 initialHydration === true,
2080 isRevalidationRequired,
2081 cancelledFetcherLoads,
2082 fetchersQueuedForDeletion,
2083 fetchLoadMatches,
2084 fetchRedirectIds,
2085 routesToUse,
2086 basename,
2087 init.patchRoutesOnNavigation != null,
2088 pendingActionResult
2089 );
2090 pendingNavigationLoadId = ++incrementingLoadId;
2091 if (!init.dataStrategy && !dsMatches.some((m) => m.shouldLoad) && !dsMatches.some(
2092 (m) => m.route.middleware && m.route.middleware.length > 0
2093 ) && revalidatingFetchers.length === 0) {
2094 let updatedFetchers2 = markFetchRedirectsDone();
2095 completeNavigation(
2096 location,
2097 {
2098 matches,
2099 loaderData: {},
2100 // Commit pending error if we're short circuiting
2101 errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { [pendingActionResult[0]]: pendingActionResult[1].error } : null,
2102 ...getActionDataForCommit(pendingActionResult),
2103 ...updatedFetchers2 ? { fetchers: new Map(state.fetchers) } : {}
2104 },
2105 { flushSync }
2106 );
2107 return { shortCircuited: true };
2108 }
2109 if (shouldUpdateNavigationState) {
2110 let updates = {};
2111 if (!isFogOfWar) {
2112 updates.navigation = loadingNavigation;
2113 let actionData = getUpdatedActionData(pendingActionResult);
2114 if (actionData !== void 0) {
2115 updates.actionData = actionData;
2116 }
2117 }
2118 if (revalidatingFetchers.length > 0) {
2119 updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers);
2120 }
2121 updateState(updates, { flushSync });
2122 }
2123 revalidatingFetchers.forEach((rf) => {
2124 abortFetcher(rf.key);
2125 if (rf.controller) {
2126 fetchControllers.set(rf.key, rf.controller);
2127 }
2128 });
2129 let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((f) => abortFetcher(f.key));
2130 if (pendingNavigationController) {
2131 pendingNavigationController.signal.addEventListener(
2132 "abort",
2133 abortPendingFetchRevalidations
2134 );
2135 }
2136 let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(
2137 dsMatches,
2138 revalidatingFetchers,
2139 request,
2140 scopedContext
2141 );
2142 if (request.signal.aborted) {
2143 return { shortCircuited: true };
2144 }
2145 if (pendingNavigationController) {
2146 pendingNavigationController.signal.removeEventListener(
2147 "abort",
2148 abortPendingFetchRevalidations
2149 );
2150 }
2151 revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key));
2152 let redirect2 = findRedirect(loaderResults);
2153 if (redirect2) {
2154 await startRedirectNavigation(request, redirect2.result, true, {
2155 replace: replace2
2156 });
2157 return { shortCircuited: true };
2158 }
2159 redirect2 = findRedirect(fetcherResults);
2160 if (redirect2) {
2161 fetchRedirectIds.add(redirect2.key);
2162 await startRedirectNavigation(request, redirect2.result, true, {
2163 replace: replace2
2164 });
2165 return { shortCircuited: true };
2166 }
2167 let { loaderData, errors } = processLoaderData(
2168 state,
2169 matches,
2170 loaderResults,
2171 pendingActionResult,
2172 revalidatingFetchers,
2173 fetcherResults
2174 );
2175 if (initialHydration && state.errors) {
2176 errors = { ...state.errors, ...errors };
2177 }
2178 let updatedFetchers = markFetchRedirectsDone();
2179 let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);
2180 let shouldUpdateFetchers = updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0;
2181 return {
2182 matches,
2183 loaderData,
2184 errors,
2185 ...shouldUpdateFetchers ? { fetchers: new Map(state.fetchers) } : {}
2186 };
2187 }
2188 function getUpdatedActionData(pendingActionResult) {
2189 if (pendingActionResult && !isErrorResult(pendingActionResult[1])) {
2190 return {
2191 [pendingActionResult[0]]: pendingActionResult[1].data
2192 };
2193 } else if (state.actionData) {
2194 if (Object.keys(state.actionData).length === 0) {
2195 return null;
2196 } else {
2197 return state.actionData;
2198 }
2199 }
2200 }
2201 function getUpdatedRevalidatingFetchers(revalidatingFetchers) {
2202 revalidatingFetchers.forEach((rf) => {
2203 let fetcher = state.fetchers.get(rf.key);
2204 let revalidatingFetcher = getLoadingFetcher(
2205 void 0,
2206 fetcher ? fetcher.data : void 0
2207 );
2208 state.fetchers.set(rf.key, revalidatingFetcher);
2209 });
2210 return new Map(state.fetchers);
2211 }
2212 async function fetch2(key, routeId, href, opts) {
2213 abortFetcher(key);
2214 let flushSync = (opts && opts.flushSync) === true;
2215 let routesToUse = inFlightDataRoutes || dataRoutes;
2216 let normalizedPath = normalizeTo(
2217 state.location,
2218 state.matches,
2219 basename,
2220 href,
2221 routeId,
2222 _optionalChain([opts, 'optionalAccess', _20 => _20.relative])
2223 );
2224 let matches = matchRoutes(routesToUse, normalizedPath, basename);
2225 let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath);
2226 if (fogOfWar.active && fogOfWar.matches) {
2227 matches = fogOfWar.matches;
2228 }
2229 if (!matches) {
2230 setFetcherError(
2231 key,
2232 routeId,
2233 getInternalRouterError(404, { pathname: normalizedPath }),
2234 { flushSync }
2235 );
2236 return;
2237 }
2238 let { path, submission, error } = normalizeNavigateOptions(
2239 true,
2240 normalizedPath,
2241 opts
2242 );
2243 if (error) {
2244 setFetcherError(key, routeId, error, { flushSync });
2245 return;
2246 }
2247 let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider();
2248 let preventScrollReset = (opts && opts.preventScrollReset) === true;
2249 if (submission && isMutationMethod(submission.formMethod)) {
2250 await handleFetcherAction(
2251 key,
2252 routeId,
2253 path,
2254 matches,
2255 scopedContext,
2256 fogOfWar.active,
2257 flushSync,
2258 preventScrollReset,
2259 submission
2260 );
2261 return;
2262 }
2263 fetchLoadMatches.set(key, { routeId, path });
2264 await handleFetcherLoader(
2265 key,
2266 routeId,
2267 path,
2268 matches,
2269 scopedContext,
2270 fogOfWar.active,
2271 flushSync,
2272 preventScrollReset,
2273 submission
2274 );
2275 }
2276 async function handleFetcherAction(key, routeId, path, requestMatches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission) {
2277 interruptActiveLoads();
2278 fetchLoadMatches.delete(key);
2279 let existingFetcher = state.fetchers.get(key);
2280 updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), {
2281 flushSync
2282 });
2283 let abortController = new AbortController();
2284 let fetchRequest = createClientSideRequest(
2285 init.history,
2286 path,
2287 abortController.signal,
2288 submission
2289 );
2290 if (isFogOfWar) {
2291 let discoverResult = await discoverRoutes(
2292 requestMatches,
2293 new URL(fetchRequest.url).pathname,
2294 fetchRequest.signal,
2295 key
2296 );
2297 if (discoverResult.type === "aborted") {
2298 return;
2299 } else if (discoverResult.type === "error") {
2300 setFetcherError(key, routeId, discoverResult.error, { flushSync });
2301 return;
2302 } else if (!discoverResult.matches) {
2303 setFetcherError(
2304 key,
2305 routeId,
2306 getInternalRouterError(404, { pathname: path }),
2307 { flushSync }
2308 );
2309 return;
2310 } else {
2311 requestMatches = discoverResult.matches;
2312 }
2313 }
2314 let match = getTargetMatch(requestMatches, path);
2315 if (!match.route.action && !match.route.lazy) {
2316 let error = getInternalRouterError(405, {
2317 method: submission.formMethod,
2318 pathname: path,
2319 routeId
2320 });
2321 setFetcherError(key, routeId, error, { flushSync });
2322 return;
2323 }
2324 fetchControllers.set(key, abortController);
2325 let originatingLoadId = incrementingLoadId;
2326 let fetchMatches = getTargetedDataStrategyMatches(
2327 mapRouteProperties2,
2328 manifest,
2329 fetchRequest,
2330 requestMatches,
2331 match,
2332 hydrationRouteProperties2,
2333 scopedContext
2334 );
2335 let actionResults = await callDataStrategy(
2336 fetchRequest,
2337 fetchMatches,
2338 scopedContext,
2339 key
2340 );
2341 let actionResult = actionResults[match.route.id];
2342 if (!actionResult) {
2343 for (let match2 of fetchMatches) {
2344 if (actionResults[match2.route.id]) {
2345 actionResult = actionResults[match2.route.id];
2346 break;
2347 }
2348 }
2349 }
2350 if (fetchRequest.signal.aborted) {
2351 if (fetchControllers.get(key) === abortController) {
2352 fetchControllers.delete(key);
2353 }
2354 return;
2355 }
2356 if (fetchersQueuedForDeletion.has(key)) {
2357 if (isRedirectResult(actionResult) || isErrorResult(actionResult)) {
2358 updateFetcherState(key, getDoneFetcher(void 0));
2359 return;
2360 }
2361 } else {
2362 if (isRedirectResult(actionResult)) {
2363 fetchControllers.delete(key);
2364 if (pendingNavigationLoadId > originatingLoadId) {
2365 updateFetcherState(key, getDoneFetcher(void 0));
2366 return;
2367 } else {
2368 fetchRedirectIds.add(key);
2369 updateFetcherState(key, getLoadingFetcher(submission));
2370 return startRedirectNavigation(fetchRequest, actionResult, false, {
2371 fetcherSubmission: submission,
2372 preventScrollReset
2373 });
2374 }
2375 }
2376 if (isErrorResult(actionResult)) {
2377 setFetcherError(key, routeId, actionResult.error);
2378 return;
2379 }
2380 }
2381 let nextLocation = state.navigation.location || state.location;
2382 let revalidationRequest = createClientSideRequest(
2383 init.history,
2384 nextLocation,
2385 abortController.signal
2386 );
2387 let routesToUse = inFlightDataRoutes || dataRoutes;
2388 let matches = state.navigation.state !== "idle" ? matchRoutes(routesToUse, state.navigation.location, basename) : state.matches;
2389 invariant(matches, "Didn't find any matches after fetcher action");
2390 let loadId = ++incrementingLoadId;
2391 fetchReloadIds.set(key, loadId);
2392 let loadFetcher = getLoadingFetcher(submission, actionResult.data);
2393 state.fetchers.set(key, loadFetcher);
2394 let { dsMatches, revalidatingFetchers } = getMatchesToLoad(
2395 revalidationRequest,
2396 scopedContext,
2397 mapRouteProperties2,
2398 manifest,
2399 init.history,
2400 state,
2401 matches,
2402 submission,
2403 nextLocation,
2404 hydrationRouteProperties2,
2405 false,
2406 isRevalidationRequired,
2407 cancelledFetcherLoads,
2408 fetchersQueuedForDeletion,
2409 fetchLoadMatches,
2410 fetchRedirectIds,
2411 routesToUse,
2412 basename,
2413 init.patchRoutesOnNavigation != null,
2414 [match.route.id, actionResult]
2415 );
2416 revalidatingFetchers.filter((rf) => rf.key !== key).forEach((rf) => {
2417 let staleKey = rf.key;
2418 let existingFetcher2 = state.fetchers.get(staleKey);
2419 let revalidatingFetcher = getLoadingFetcher(
2420 void 0,
2421 existingFetcher2 ? existingFetcher2.data : void 0
2422 );
2423 state.fetchers.set(staleKey, revalidatingFetcher);
2424 abortFetcher(staleKey);
2425 if (rf.controller) {
2426 fetchControllers.set(staleKey, rf.controller);
2427 }
2428 });
2429 updateState({ fetchers: new Map(state.fetchers) });
2430 let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((rf) => abortFetcher(rf.key));
2431 abortController.signal.addEventListener(
2432 "abort",
2433 abortPendingFetchRevalidations
2434 );
2435 let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(
2436 dsMatches,
2437 revalidatingFetchers,
2438 revalidationRequest,
2439 scopedContext
2440 );
2441 if (abortController.signal.aborted) {
2442 return;
2443 }
2444 abortController.signal.removeEventListener(
2445 "abort",
2446 abortPendingFetchRevalidations
2447 );
2448 fetchReloadIds.delete(key);
2449 fetchControllers.delete(key);
2450 revalidatingFetchers.forEach((r) => fetchControllers.delete(r.key));
2451 if (state.fetchers.has(key)) {
2452 let doneFetcher = getDoneFetcher(actionResult.data);
2453 state.fetchers.set(key, doneFetcher);
2454 }
2455 let redirect2 = findRedirect(loaderResults);
2456 if (redirect2) {
2457 return startRedirectNavigation(
2458 revalidationRequest,
2459 redirect2.result,
2460 false,
2461 { preventScrollReset }
2462 );
2463 }
2464 redirect2 = findRedirect(fetcherResults);
2465 if (redirect2) {
2466 fetchRedirectIds.add(redirect2.key);
2467 return startRedirectNavigation(
2468 revalidationRequest,
2469 redirect2.result,
2470 false,
2471 { preventScrollReset }
2472 );
2473 }
2474 let { loaderData, errors } = processLoaderData(
2475 state,
2476 matches,
2477 loaderResults,
2478 void 0,
2479 revalidatingFetchers,
2480 fetcherResults
2481 );
2482 abortStaleFetchLoads(loadId);
2483 if (state.navigation.state === "loading" && loadId > pendingNavigationLoadId) {
2484 invariant(pendingAction, "Expected pending action");
2485 pendingNavigationController && pendingNavigationController.abort();
2486 completeNavigation(state.navigation.location, {
2487 matches,
2488 loaderData,
2489 errors,
2490 fetchers: new Map(state.fetchers)
2491 });
2492 } else {
2493 updateState({
2494 errors,
2495 loaderData: mergeLoaderData(
2496 state.loaderData,
2497 loaderData,
2498 matches,
2499 errors
2500 ),
2501 fetchers: new Map(state.fetchers)
2502 });
2503 isRevalidationRequired = false;
2504 }
2505 }
2506 async function handleFetcherLoader(key, routeId, path, matches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission) {
2507 let existingFetcher = state.fetchers.get(key);
2508 updateFetcherState(
2509 key,
2510 getLoadingFetcher(
2511 submission,
2512 existingFetcher ? existingFetcher.data : void 0
2513 ),
2514 { flushSync }
2515 );
2516 let abortController = new AbortController();
2517 let fetchRequest = createClientSideRequest(
2518 init.history,
2519 path,
2520 abortController.signal
2521 );
2522 if (isFogOfWar) {
2523 let discoverResult = await discoverRoutes(
2524 matches,
2525 new URL(fetchRequest.url).pathname,
2526 fetchRequest.signal,
2527 key
2528 );
2529 if (discoverResult.type === "aborted") {
2530 return;
2531 } else if (discoverResult.type === "error") {
2532 setFetcherError(key, routeId, discoverResult.error, { flushSync });
2533 return;
2534 } else if (!discoverResult.matches) {
2535 setFetcherError(
2536 key,
2537 routeId,
2538 getInternalRouterError(404, { pathname: path }),
2539 { flushSync }
2540 );
2541 return;
2542 } else {
2543 matches = discoverResult.matches;
2544 }
2545 }
2546 let match = getTargetMatch(matches, path);
2547 fetchControllers.set(key, abortController);
2548 let originatingLoadId = incrementingLoadId;
2549 let dsMatches = getTargetedDataStrategyMatches(
2550 mapRouteProperties2,
2551 manifest,
2552 fetchRequest,
2553 matches,
2554 match,
2555 hydrationRouteProperties2,
2556 scopedContext
2557 );
2558 let results = await callDataStrategy(
2559 fetchRequest,
2560 dsMatches,
2561 scopedContext,
2562 key
2563 );
2564 let result = results[match.route.id];
2565 if (fetchControllers.get(key) === abortController) {
2566 fetchControllers.delete(key);
2567 }
2568 if (fetchRequest.signal.aborted) {
2569 return;
2570 }
2571 if (fetchersQueuedForDeletion.has(key)) {
2572 updateFetcherState(key, getDoneFetcher(void 0));
2573 return;
2574 }
2575 if (isRedirectResult(result)) {
2576 if (pendingNavigationLoadId > originatingLoadId) {
2577 updateFetcherState(key, getDoneFetcher(void 0));
2578 return;
2579 } else {
2580 fetchRedirectIds.add(key);
2581 await startRedirectNavigation(fetchRequest, result, false, {
2582 preventScrollReset
2583 });
2584 return;
2585 }
2586 }
2587 if (isErrorResult(result)) {
2588 setFetcherError(key, routeId, result.error);
2589 return;
2590 }
2591 updateFetcherState(key, getDoneFetcher(result.data));
2592 }
2593 async function startRedirectNavigation(request, redirect2, isNavigation, {
2594 submission,
2595 fetcherSubmission,
2596 preventScrollReset,
2597 replace: replace2
2598 } = {}) {
2599 if (!isNavigation) {
2600 _optionalChain([pendingPopstateNavigationDfd, 'optionalAccess', _21 => _21.resolve, 'call', _22 => _22()]);
2601 pendingPopstateNavigationDfd = null;
2602 }
2603 if (redirect2.response.headers.has("X-Remix-Revalidate")) {
2604 isRevalidationRequired = true;
2605 }
2606 let location = redirect2.response.headers.get("Location");
2607 invariant(location, "Expected a Location header on the redirect Response");
2608 location = normalizeRedirectLocation(
2609 location,
2610 new URL(request.url),
2611 basename
2612 );
2613 let redirectLocation = createLocation(state.location, location, {
2614 _isRedirect: true
2615 });
2616 if (isBrowser) {
2617 let isDocumentReload = false;
2618 if (redirect2.response.headers.has("X-Remix-Reload-Document")) {
2619 isDocumentReload = true;
2620 } else if (isAbsoluteUrl(location)) {
2621 const url = createBrowserURLImpl(location, true);
2622 isDocumentReload = // Hard reload if it's an absolute URL to a new origin
2623 url.origin !== routerWindow.location.origin || // Hard reload if it's an absolute URL that does not match our basename
2624 stripBasename(url.pathname, basename) == null;
2625 }
2626 if (isDocumentReload) {
2627 if (replace2) {
2628 routerWindow.location.replace(location);
2629 } else {
2630 routerWindow.location.assign(location);
2631 }
2632 return;
2633 }
2634 }
2635 pendingNavigationController = null;
2636 let redirectNavigationType = replace2 === true || redirect2.response.headers.has("X-Remix-Replace") ? "REPLACE" /* Replace */ : "PUSH" /* Push */;
2637 let { formMethod, formAction, formEncType } = state.navigation;
2638 if (!submission && !fetcherSubmission && formMethod && formAction && formEncType) {
2639 submission = getSubmissionFromNavigation(state.navigation);
2640 }
2641 let activeSubmission = submission || fetcherSubmission;
2642 if (redirectPreserveMethodStatusCodes.has(redirect2.response.status) && activeSubmission && isMutationMethod(activeSubmission.formMethod)) {
2643 await startNavigation(redirectNavigationType, redirectLocation, {
2644 submission: {
2645 ...activeSubmission,
2646 formAction: location
2647 },
2648 // Preserve these flags across redirects
2649 preventScrollReset: preventScrollReset || pendingPreventScrollReset,
2650 enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0
2651 });
2652 } else {
2653 let overrideNavigation = getLoadingNavigation(
2654 redirectLocation,
2655 submission
2656 );
2657 await startNavigation(redirectNavigationType, redirectLocation, {
2658 overrideNavigation,
2659 // Send fetcher submissions through for shouldRevalidate
2660 fetcherSubmission,
2661 // Preserve these flags across redirects
2662 preventScrollReset: preventScrollReset || pendingPreventScrollReset,
2663 enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0
2664 });
2665 }
2666 }
2667 async function callDataStrategy(request, matches, scopedContext, fetcherKey) {
2668 let results;
2669 let dataResults = {};
2670 try {
2671 results = await callDataStrategyImpl(
2672 dataStrategyImpl,
2673 request,
2674 matches,
2675 fetcherKey,
2676 scopedContext,
2677 false
2678 );
2679 } catch (e) {
2680 matches.filter((m) => m.shouldLoad).forEach((m) => {
2681 dataResults[m.route.id] = {
2682 type: "error" /* error */,
2683 error: e
2684 };
2685 });
2686 return dataResults;
2687 }
2688 if (request.signal.aborted) {
2689 return dataResults;
2690 }
2691 for (let [routeId, result] of Object.entries(results)) {
2692 if (isRedirectDataStrategyResult(result)) {
2693 let response = result.result;
2694 dataResults[routeId] = {
2695 type: "redirect" /* redirect */,
2696 response: normalizeRelativeRoutingRedirectResponse(
2697 response,
2698 request,
2699 routeId,
2700 matches,
2701 basename
2702 )
2703 };
2704 } else {
2705 dataResults[routeId] = await convertDataStrategyResultToDataResult(result);
2706 }
2707 }
2708 return dataResults;
2709 }
2710 async function callLoadersAndMaybeResolveData(matches, fetchersToLoad, request, scopedContext) {
2711 let loaderResultsPromise = callDataStrategy(
2712 request,
2713 matches,
2714 scopedContext,
2715 null
2716 );
2717 let fetcherResultsPromise = Promise.all(
2718 fetchersToLoad.map(async (f) => {
2719 if (f.matches && f.match && f.request && f.controller) {
2720 let results = await callDataStrategy(
2721 f.request,
2722 f.matches,
2723 scopedContext,
2724 f.key
2725 );
2726 let result = results[f.match.route.id];
2727 return { [f.key]: result };
2728 } else {
2729 return Promise.resolve({
2730 [f.key]: {
2731 type: "error" /* error */,
2732 error: getInternalRouterError(404, {
2733 pathname: f.path
2734 })
2735 }
2736 });
2737 }
2738 })
2739 );
2740 let loaderResults = await loaderResultsPromise;
2741 let fetcherResults = (await fetcherResultsPromise).reduce(
2742 (acc, r) => Object.assign(acc, r),
2743 {}
2744 );
2745 return {
2746 loaderResults,
2747 fetcherResults
2748 };
2749 }
2750 function interruptActiveLoads() {
2751 isRevalidationRequired = true;
2752 fetchLoadMatches.forEach((_, key) => {
2753 if (fetchControllers.has(key)) {
2754 cancelledFetcherLoads.add(key);
2755 }
2756 abortFetcher(key);
2757 });
2758 }
2759 function updateFetcherState(key, fetcher, opts = {}) {
2760 state.fetchers.set(key, fetcher);
2761 updateState(
2762 { fetchers: new Map(state.fetchers) },
2763 { flushSync: (opts && opts.flushSync) === true }
2764 );
2765 }
2766 function setFetcherError(key, routeId, error, opts = {}) {
2767 let boundaryMatch = findNearestBoundary(state.matches, routeId);
2768 deleteFetcher(key);
2769 updateState(
2770 {
2771 errors: {
2772 [boundaryMatch.route.id]: error
2773 },
2774 fetchers: new Map(state.fetchers)
2775 },
2776 { flushSync: (opts && opts.flushSync) === true }
2777 );
2778 }
2779 function getFetcher(key) {
2780 activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1);
2781 if (fetchersQueuedForDeletion.has(key)) {
2782 fetchersQueuedForDeletion.delete(key);
2783 }
2784 return state.fetchers.get(key) || IDLE_FETCHER;
2785 }
2786 function resetFetcher(key, opts) {
2787 abortFetcher(key, _optionalChain([opts, 'optionalAccess', _23 => _23.reason]));
2788 updateFetcherState(key, getDoneFetcher(null));
2789 }
2790 function deleteFetcher(key) {
2791 let fetcher = state.fetchers.get(key);
2792 if (fetchControllers.has(key) && !(fetcher && fetcher.state === "loading" && fetchReloadIds.has(key))) {
2793 abortFetcher(key);
2794 }
2795 fetchLoadMatches.delete(key);
2796 fetchReloadIds.delete(key);
2797 fetchRedirectIds.delete(key);
2798 fetchersQueuedForDeletion.delete(key);
2799 cancelledFetcherLoads.delete(key);
2800 state.fetchers.delete(key);
2801 }
2802 function queueFetcherForDeletion(key) {
2803 let count = (activeFetchers.get(key) || 0) - 1;
2804 if (count <= 0) {
2805 activeFetchers.delete(key);
2806 fetchersQueuedForDeletion.add(key);
2807 } else {
2808 activeFetchers.set(key, count);
2809 }
2810 updateState({ fetchers: new Map(state.fetchers) });
2811 }
2812 function abortFetcher(key, reason) {
2813 let controller = fetchControllers.get(key);
2814 if (controller) {
2815 controller.abort(reason);
2816 fetchControllers.delete(key);
2817 }
2818 }
2819 function markFetchersDone(keys) {
2820 for (let key of keys) {
2821 let fetcher = getFetcher(key);
2822 let doneFetcher = getDoneFetcher(fetcher.data);
2823 state.fetchers.set(key, doneFetcher);
2824 }
2825 }
2826 function markFetchRedirectsDone() {
2827 let doneKeys = [];
2828 let updatedFetchers = false;
2829 for (let key of fetchRedirectIds) {
2830 let fetcher = state.fetchers.get(key);
2831 invariant(fetcher, `Expected fetcher: ${key}`);
2832 if (fetcher.state === "loading") {
2833 fetchRedirectIds.delete(key);
2834 doneKeys.push(key);
2835 updatedFetchers = true;
2836 }
2837 }
2838 markFetchersDone(doneKeys);
2839 return updatedFetchers;
2840 }
2841 function abortStaleFetchLoads(landedId) {
2842 let yeetedKeys = [];
2843 for (let [key, id] of fetchReloadIds) {
2844 if (id < landedId) {
2845 let fetcher = state.fetchers.get(key);
2846 invariant(fetcher, `Expected fetcher: ${key}`);
2847 if (fetcher.state === "loading") {
2848 abortFetcher(key);
2849 fetchReloadIds.delete(key);
2850 yeetedKeys.push(key);
2851 }
2852 }
2853 }
2854 markFetchersDone(yeetedKeys);
2855 return yeetedKeys.length > 0;
2856 }
2857 function getBlocker(key, fn) {
2858 let blocker = state.blockers.get(key) || IDLE_BLOCKER;
2859 if (blockerFunctions.get(key) !== fn) {
2860 blockerFunctions.set(key, fn);
2861 }
2862 return blocker;
2863 }
2864 function deleteBlocker(key) {
2865 state.blockers.delete(key);
2866 blockerFunctions.delete(key);
2867 }
2868 function updateBlocker(key, newBlocker) {
2869 let blocker = state.blockers.get(key) || IDLE_BLOCKER;
2870 invariant(
2871 blocker.state === "unblocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "proceeding" || blocker.state === "blocked" && newBlocker.state === "unblocked" || blocker.state === "proceeding" && newBlocker.state === "unblocked",
2872 `Invalid blocker state transition: ${blocker.state} -> ${newBlocker.state}`
2873 );
2874 let blockers = new Map(state.blockers);
2875 blockers.set(key, newBlocker);
2876 updateState({ blockers });
2877 }
2878 function shouldBlockNavigation({
2879 currentLocation,
2880 nextLocation,
2881 historyAction
2882 }) {
2883 if (blockerFunctions.size === 0) {
2884 return;
2885 }
2886 if (blockerFunctions.size > 1) {
2887 warning(false, "A router only supports one blocker at a time");
2888 }
2889 let entries = Array.from(blockerFunctions.entries());
2890 let [blockerKey, blockerFunction] = entries[entries.length - 1];
2891 let blocker = state.blockers.get(blockerKey);
2892 if (blocker && blocker.state === "proceeding") {
2893 return;
2894 }
2895 if (blockerFunction({ currentLocation, nextLocation, historyAction })) {
2896 return blockerKey;
2897 }
2898 }
2899 function handleNavigational404(pathname) {
2900 let error = getInternalRouterError(404, { pathname });
2901 let routesToUse = inFlightDataRoutes || dataRoutes;
2902 let { matches, route } = getShortCircuitMatches(routesToUse);
2903 return { notFoundMatches: matches, route, error };
2904 }
2905 function enableScrollRestoration(positions, getPosition, getKey) {
2906 savedScrollPositions = positions;
2907 getScrollPosition = getPosition;
2908 getScrollRestorationKey = getKey || null;
2909 if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) {
2910 initialScrollRestored = true;
2911 let y = getSavedScrollPosition(state.location, state.matches);
2912 if (y != null) {
2913 updateState({ restoreScrollPosition: y });
2914 }
2915 }
2916 return () => {
2917 savedScrollPositions = null;
2918 getScrollPosition = null;
2919 getScrollRestorationKey = null;
2920 };
2921 }
2922 function getScrollKey(location, matches) {
2923 if (getScrollRestorationKey) {
2924 let key = getScrollRestorationKey(
2925 location,
2926 matches.map((m) => convertRouteMatchToUiMatch(m, state.loaderData))
2927 );
2928 return key || location.key;
2929 }
2930 return location.key;
2931 }
2932 function saveScrollPosition(location, matches) {
2933 if (savedScrollPositions && getScrollPosition) {
2934 let key = getScrollKey(location, matches);
2935 savedScrollPositions[key] = getScrollPosition();
2936 }
2937 }
2938 function getSavedScrollPosition(location, matches) {
2939 if (savedScrollPositions) {
2940 let key = getScrollKey(location, matches);
2941 let y = savedScrollPositions[key];
2942 if (typeof y === "number") {
2943 return y;
2944 }
2945 }
2946 return null;
2947 }
2948 function checkFogOfWar(matches, routesToUse, pathname) {
2949 if (init.patchRoutesOnNavigation) {
2950 if (!matches) {
2951 let fogMatches = matchRoutesImpl(
2952 routesToUse,
2953 pathname,
2954 basename,
2955 true
2956 );
2957 return { active: true, matches: fogMatches || [] };
2958 } else {
2959 if (Object.keys(matches[0].params).length > 0) {
2960 let partialMatches = matchRoutesImpl(
2961 routesToUse,
2962 pathname,
2963 basename,
2964 true
2965 );
2966 return { active: true, matches: partialMatches };
2967 }
2968 }
2969 }
2970 return { active: false, matches: null };
2971 }
2972 async function discoverRoutes(matches, pathname, signal, fetcherKey) {
2973 if (!init.patchRoutesOnNavigation) {
2974 return { type: "success", matches };
2975 }
2976 let partialMatches = matches;
2977 while (true) {
2978 let isNonHMR = inFlightDataRoutes == null;
2979 let routesToUse = inFlightDataRoutes || dataRoutes;
2980 let localManifest = manifest;
2981 try {
2982 await init.patchRoutesOnNavigation({
2983 signal,
2984 path: pathname,
2985 matches: partialMatches,
2986 fetcherKey,
2987 patch: (routeId, children) => {
2988 if (signal.aborted) return;
2989 patchRoutesImpl(
2990 routeId,
2991 children,
2992 routesToUse,
2993 localManifest,
2994 mapRouteProperties2,
2995 false
2996 );
2997 }
2998 });
2999 } catch (e) {
3000 return { type: "error", error: e, partialMatches };
3001 } finally {
3002 if (isNonHMR && !signal.aborted) {
3003 dataRoutes = [...dataRoutes];
3004 }
3005 }
3006 if (signal.aborted) {
3007 return { type: "aborted" };
3008 }
3009 let newMatches = matchRoutes(routesToUse, pathname, basename);
3010 let newPartialMatches = null;
3011 if (newMatches) {
3012 if (Object.keys(newMatches[0].params).length === 0) {
3013 return { type: "success", matches: newMatches };
3014 } else {
3015 newPartialMatches = matchRoutesImpl(
3016 routesToUse,
3017 pathname,
3018 basename,
3019 true
3020 );
3021 let matchedDeeper = newPartialMatches && partialMatches.length < newPartialMatches.length && compareMatches(
3022 partialMatches,
3023 newPartialMatches.slice(0, partialMatches.length)
3024 );
3025 if (!matchedDeeper) {
3026 return { type: "success", matches: newMatches };
3027 }
3028 }
3029 }
3030 if (!newPartialMatches) {
3031 newPartialMatches = matchRoutesImpl(
3032 routesToUse,
3033 pathname,
3034 basename,
3035 true
3036 );
3037 }
3038 if (!newPartialMatches || compareMatches(partialMatches, newPartialMatches)) {
3039 return { type: "success", matches: null };
3040 }
3041 partialMatches = newPartialMatches;
3042 }
3043 }
3044 function compareMatches(a, b) {
3045 return a.length === b.length && a.every((m, i) => m.route.id === b[i].route.id);
3046 }
3047 function _internalSetRoutes(newRoutes) {
3048 manifest = {};
3049 inFlightDataRoutes = convertRoutesToDataRoutes(
3050 newRoutes,
3051 mapRouteProperties2,
3052 void 0,
3053 manifest
3054 );
3055 }
3056 function patchRoutes(routeId, children, unstable_allowElementMutations = false) {
3057 let isNonHMR = inFlightDataRoutes == null;
3058 let routesToUse = inFlightDataRoutes || dataRoutes;
3059 patchRoutesImpl(
3060 routeId,
3061 children,
3062 routesToUse,
3063 manifest,
3064 mapRouteProperties2,
3065 unstable_allowElementMutations
3066 );
3067 if (isNonHMR) {
3068 dataRoutes = [...dataRoutes];
3069 updateState({});
3070 }
3071 }
3072 router = {
3073 get basename() {
3074 return basename;
3075 },
3076 get future() {
3077 return future;
3078 },
3079 get state() {
3080 return state;
3081 },
3082 get routes() {
3083 return dataRoutes;
3084 },
3085 get window() {
3086 return routerWindow;
3087 },
3088 initialize,
3089 subscribe,
3090 enableScrollRestoration,
3091 navigate,
3092 fetch: fetch2,
3093 revalidate,
3094 // Passthrough to history-aware createHref used by useHref so we get proper
3095 // hash-aware URLs in DOM paths
3096 createHref: (to) => init.history.createHref(to),
3097 encodeLocation: (to) => init.history.encodeLocation(to),
3098 getFetcher,
3099 resetFetcher,
3100 deleteFetcher: queueFetcherForDeletion,
3101 dispose,
3102 getBlocker,
3103 deleteBlocker,
3104 patchRoutes,
3105 _internalFetchControllers: fetchControllers,
3106 // TODO: Remove setRoutes, it's temporary to avoid dealing with
3107 // updating the tree while validating the update algorithm.
3108 _internalSetRoutes,
3109 _internalSetStateDoNotUseOrYouWillBreakYourApp(newState) {
3110 updateState(newState);
3111 }
3112 };
3113 if (init.unstable_instrumentations) {
3114 router = instrumentClientSideRouter(
3115 router,
3116 init.unstable_instrumentations.map((i) => i.router).filter(Boolean)
3117 );
3118 }
3119 return router;
3120}
3121function createStaticHandler(routes, opts) {
3122 invariant(
3123 routes.length > 0,
3124 "You must provide a non-empty routes array to createStaticHandler"
3125 );
3126 let manifest = {};
3127 let basename = (opts ? opts.basename : null) || "/";
3128 let _mapRouteProperties = _optionalChain([opts, 'optionalAccess', _24 => _24.mapRouteProperties]) || defaultMapRouteProperties;
3129 let mapRouteProperties2 = _mapRouteProperties;
3130 if (_optionalChain([opts, 'optionalAccess', _25 => _25.unstable_instrumentations])) {
3131 let instrumentations = opts.unstable_instrumentations;
3132 mapRouteProperties2 = (route) => {
3133 return {
3134 ..._mapRouteProperties(route),
3135 ...getRouteInstrumentationUpdates(
3136 instrumentations.map((i) => i.route).filter(Boolean),
3137 route
3138 )
3139 };
3140 };
3141 }
3142 let dataRoutes = convertRoutesToDataRoutes(
3143 routes,
3144 mapRouteProperties2,
3145 void 0,
3146 manifest
3147 );
3148 async function query(request, {
3149 requestContext,
3150 filterMatchesToLoad,
3151 skipLoaderErrorBubbling,
3152 skipRevalidation,
3153 dataStrategy,
3154 generateMiddlewareResponse
3155 } = {}) {
3156 let url = new URL(request.url);
3157 let method = request.method;
3158 let location = createLocation("", createPath(url), null, "default");
3159 let matches = matchRoutes(dataRoutes, location, basename);
3160 requestContext = requestContext != null ? requestContext : new RouterContextProvider();
3161 if (!isValidMethod(method) && method !== "HEAD") {
3162 let error = getInternalRouterError(405, { method });
3163 let { matches: methodNotAllowedMatches, route } = getShortCircuitMatches(dataRoutes);
3164 let staticContext = {
3165 basename,
3166 location,
3167 matches: methodNotAllowedMatches,
3168 loaderData: {},
3169 actionData: null,
3170 errors: {
3171 [route.id]: error
3172 },
3173 statusCode: error.status,
3174 loaderHeaders: {},
3175 actionHeaders: {}
3176 };
3177 return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext;
3178 } else if (!matches) {
3179 let error = getInternalRouterError(404, { pathname: location.pathname });
3180 let { matches: notFoundMatches, route } = getShortCircuitMatches(dataRoutes);
3181 let staticContext = {
3182 basename,
3183 location,
3184 matches: notFoundMatches,
3185 loaderData: {},
3186 actionData: null,
3187 errors: {
3188 [route.id]: error
3189 },
3190 statusCode: error.status,
3191 loaderHeaders: {},
3192 actionHeaders: {}
3193 };
3194 return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext;
3195 }
3196 if (generateMiddlewareResponse) {
3197 invariant(
3198 requestContext instanceof RouterContextProvider,
3199 "When using middleware in `staticHandler.query()`, any provided `requestContext` must be an instance of `RouterContextProvider`"
3200 );
3201 try {
3202 await loadLazyMiddlewareForMatches(
3203 matches,
3204 manifest,
3205 mapRouteProperties2
3206 );
3207 let renderedStaticContext;
3208 let response = await runServerMiddlewarePipeline(
3209 {
3210 request,
3211 unstable_pattern: getRoutePattern(matches),
3212 matches,
3213 params: matches[0].params,
3214 // If we're calling middleware then it must be enabled so we can cast
3215 // this to the proper type knowing it's not an `AppLoadContext`
3216 context: requestContext
3217 },
3218 async () => {
3219 let res = await generateMiddlewareResponse(
3220 async (revalidationRequest, opts2 = {}) => {
3221 let result2 = await queryImpl(
3222 revalidationRequest,
3223 location,
3224 matches,
3225 requestContext,
3226 dataStrategy || null,
3227 skipLoaderErrorBubbling === true,
3228 null,
3229 "filterMatchesToLoad" in opts2 ? _nullishCoalesce(opts2.filterMatchesToLoad, () => ( null)) : _nullishCoalesce(filterMatchesToLoad, () => ( null)),
3230 skipRevalidation === true
3231 );
3232 if (isResponse(result2)) {
3233 return result2;
3234 }
3235 renderedStaticContext = { location, basename, ...result2 };
3236 return renderedStaticContext;
3237 }
3238 );
3239 return res;
3240 },
3241 async (error, routeId) => {
3242 if (isRedirectResponse(error)) {
3243 return error;
3244 }
3245 if (isResponse(error)) {
3246 try {
3247 error = new ErrorResponseImpl(
3248 error.status,
3249 error.statusText,
3250 await parseResponseBody(error)
3251 );
3252 } catch (e) {
3253 error = e;
3254 }
3255 }
3256 if (isDataWithResponseInit(error)) {
3257 error = dataWithResponseInitToErrorResponse(error);
3258 }
3259 if (renderedStaticContext) {
3260 if (routeId in renderedStaticContext.loaderData) {
3261 renderedStaticContext.loaderData[routeId] = void 0;
3262 }
3263 let staticContext = getStaticContextFromError(
3264 dataRoutes,
3265 renderedStaticContext,
3266 error,
3267 skipLoaderErrorBubbling ? routeId : findNearestBoundary(matches, routeId).route.id
3268 );
3269 return generateMiddlewareResponse(
3270 () => Promise.resolve(staticContext)
3271 );
3272 } else {
3273 let boundaryRouteId = skipLoaderErrorBubbling ? routeId : findNearestBoundary(
3274 matches,
3275 _optionalChain([matches, 'access', _26 => _26.find, 'call', _27 => _27(
3276 (m) => m.route.id === routeId || m.route.loader
3277 ), 'optionalAccess', _28 => _28.route, 'access', _29 => _29.id]) || routeId
3278 ).route.id;
3279 let staticContext = {
3280 matches,
3281 location,
3282 basename,
3283 loaderData: {},
3284 actionData: null,
3285 errors: {
3286 [boundaryRouteId]: error
3287 },
3288 statusCode: isRouteErrorResponse(error) ? error.status : 500,
3289 actionHeaders: {},
3290 loaderHeaders: {}
3291 };
3292 return generateMiddlewareResponse(
3293 () => Promise.resolve(staticContext)
3294 );
3295 }
3296 }
3297 );
3298 invariant(isResponse(response), "Expected a response in query()");
3299 return response;
3300 } catch (e) {
3301 if (isResponse(e)) {
3302 return e;
3303 }
3304 throw e;
3305 }
3306 }
3307 let result = await queryImpl(
3308 request,
3309 location,
3310 matches,
3311 requestContext,
3312 dataStrategy || null,
3313 skipLoaderErrorBubbling === true,
3314 null,
3315 filterMatchesToLoad || null,
3316 skipRevalidation === true
3317 );
3318 if (isResponse(result)) {
3319 return result;
3320 }
3321 return { location, basename, ...result };
3322 }
3323 async function queryRoute(request, {
3324 routeId,
3325 requestContext,
3326 dataStrategy,
3327 generateMiddlewareResponse
3328 } = {}) {
3329 let url = new URL(request.url);
3330 let method = request.method;
3331 let location = createLocation("", createPath(url), null, "default");
3332 let matches = matchRoutes(dataRoutes, location, basename);
3333 requestContext = requestContext != null ? requestContext : new RouterContextProvider();
3334 if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") {
3335 throw getInternalRouterError(405, { method });
3336 } else if (!matches) {
3337 throw getInternalRouterError(404, { pathname: location.pathname });
3338 }
3339 let match = routeId ? matches.find((m) => m.route.id === routeId) : getTargetMatch(matches, location);
3340 if (routeId && !match) {
3341 throw getInternalRouterError(403, {
3342 pathname: location.pathname,
3343 routeId
3344 });
3345 } else if (!match) {
3346 throw getInternalRouterError(404, { pathname: location.pathname });
3347 }
3348 if (generateMiddlewareResponse) {
3349 invariant(
3350 requestContext instanceof RouterContextProvider,
3351 "When using middleware in `staticHandler.queryRoute()`, any provided `requestContext` must be an instance of `RouterContextProvider`"
3352 );
3353 await loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties2);
3354 let response = await runServerMiddlewarePipeline(
3355 {
3356 request,
3357 unstable_pattern: getRoutePattern(matches),
3358 matches,
3359 params: matches[0].params,
3360 // If we're calling middleware then it must be enabled so we can cast
3361 // this to the proper type knowing it's not an `AppLoadContext`
3362 context: requestContext
3363 },
3364 async () => {
3365 let res = await generateMiddlewareResponse(
3366 async (innerRequest) => {
3367 let result2 = await queryImpl(
3368 innerRequest,
3369 location,
3370 matches,
3371 requestContext,
3372 dataStrategy || null,
3373 false,
3374 match,
3375 null,
3376 false
3377 );
3378 let processed = handleQueryResult(result2);
3379 return isResponse(processed) ? processed : typeof processed === "string" ? new Response(processed) : Response.json(processed);
3380 }
3381 );
3382 return res;
3383 },
3384 (error) => {
3385 if (isDataWithResponseInit(error)) {
3386 return Promise.resolve(dataWithResponseInitToResponse(error));
3387 }
3388 if (isResponse(error)) {
3389 return Promise.resolve(error);
3390 }
3391 throw error;
3392 }
3393 );
3394 return response;
3395 }
3396 let result = await queryImpl(
3397 request,
3398 location,
3399 matches,
3400 requestContext,
3401 dataStrategy || null,
3402 false,
3403 match,
3404 null,
3405 false
3406 );
3407 return handleQueryResult(result);
3408 function handleQueryResult(result2) {
3409 if (isResponse(result2)) {
3410 return result2;
3411 }
3412 let error = result2.errors ? Object.values(result2.errors)[0] : void 0;
3413 if (error !== void 0) {
3414 throw error;
3415 }
3416 if (result2.actionData) {
3417 return Object.values(result2.actionData)[0];
3418 }
3419 if (result2.loaderData) {
3420 return Object.values(result2.loaderData)[0];
3421 }
3422 return void 0;
3423 }
3424 }
3425 async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, skipRevalidation) {
3426 invariant(
3427 request.signal,
3428 "query()/queryRoute() requests must contain an AbortController signal"
3429 );
3430 try {
3431 if (isMutationMethod(request.method)) {
3432 let result2 = await submit(
3433 request,
3434 matches,
3435 routeMatch || getTargetMatch(matches, location),
3436 requestContext,
3437 dataStrategy,
3438 skipLoaderErrorBubbling,
3439 routeMatch != null,
3440 filterMatchesToLoad,
3441 skipRevalidation
3442 );
3443 return result2;
3444 }
3445 let result = await loadRouteData(
3446 request,
3447 matches,
3448 requestContext,
3449 dataStrategy,
3450 skipLoaderErrorBubbling,
3451 routeMatch,
3452 filterMatchesToLoad
3453 );
3454 return isResponse(result) ? result : {
3455 ...result,
3456 actionData: null,
3457 actionHeaders: {}
3458 };
3459 } catch (e) {
3460 if (isDataStrategyResult(e) && isResponse(e.result)) {
3461 if (e.type === "error" /* error */) {
3462 throw e.result;
3463 }
3464 return e.result;
3465 }
3466 if (isRedirectResponse(e)) {
3467 return e;
3468 }
3469 throw e;
3470 }
3471 }
3472 async function submit(request, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest, filterMatchesToLoad, skipRevalidation) {
3473 let result;
3474 if (!actionMatch.route.action && !actionMatch.route.lazy) {
3475 let error = getInternalRouterError(405, {
3476 method: request.method,
3477 pathname: new URL(request.url).pathname,
3478 routeId: actionMatch.route.id
3479 });
3480 if (isRouteRequest) {
3481 throw error;
3482 }
3483 result = {
3484 type: "error" /* error */,
3485 error
3486 };
3487 } else {
3488 let dsMatches = getTargetedDataStrategyMatches(
3489 mapRouteProperties2,
3490 manifest,
3491 request,
3492 matches,
3493 actionMatch,
3494 [],
3495 requestContext
3496 );
3497 let results = await callDataStrategy(
3498 request,
3499 dsMatches,
3500 isRouteRequest,
3501 requestContext,
3502 dataStrategy
3503 );
3504 result = results[actionMatch.route.id];
3505 if (request.signal.aborted) {
3506 throwStaticHandlerAbortedError(request, isRouteRequest);
3507 }
3508 }
3509 if (isRedirectResult(result)) {
3510 throw new Response(null, {
3511 status: result.response.status,
3512 headers: {
3513 Location: result.response.headers.get("Location")
3514 }
3515 });
3516 }
3517 if (isRouteRequest) {
3518 if (isErrorResult(result)) {
3519 throw result.error;
3520 }
3521 return {
3522 matches: [actionMatch],
3523 loaderData: {},
3524 actionData: { [actionMatch.route.id]: result.data },
3525 errors: null,
3526 // Note: statusCode + headers are unused here since queryRoute will
3527 // return the raw Response or value
3528 statusCode: 200,
3529 loaderHeaders: {},
3530 actionHeaders: {}
3531 };
3532 }
3533 if (skipRevalidation) {
3534 if (isErrorResult(result)) {
3535 let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
3536 return {
3537 statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,
3538 actionData: null,
3539 actionHeaders: {
3540 ...result.headers ? { [actionMatch.route.id]: result.headers } : {}
3541 },
3542 matches,
3543 loaderData: {},
3544 errors: {
3545 [boundaryMatch.route.id]: result.error
3546 },
3547 loaderHeaders: {}
3548 };
3549 } else {
3550 return {
3551 actionData: {
3552 [actionMatch.route.id]: result.data
3553 },
3554 actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {},
3555 matches,
3556 loaderData: {},
3557 errors: null,
3558 statusCode: result.statusCode || 200,
3559 loaderHeaders: {}
3560 };
3561 }
3562 }
3563 let loaderRequest = new Request(request.url, {
3564 headers: request.headers,
3565 redirect: request.redirect,
3566 signal: request.signal
3567 });
3568 if (isErrorResult(result)) {
3569 let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
3570 let handlerContext2 = await loadRouteData(
3571 loaderRequest,
3572 matches,
3573 requestContext,
3574 dataStrategy,
3575 skipLoaderErrorBubbling,
3576 null,
3577 filterMatchesToLoad,
3578 [boundaryMatch.route.id, result]
3579 );
3580 return {
3581 ...handlerContext2,
3582 statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,
3583 actionData: null,
3584 actionHeaders: {
3585 ...result.headers ? { [actionMatch.route.id]: result.headers } : {}
3586 }
3587 };
3588 }
3589 let handlerContext = await loadRouteData(
3590 loaderRequest,
3591 matches,
3592 requestContext,
3593 dataStrategy,
3594 skipLoaderErrorBubbling,
3595 null,
3596 filterMatchesToLoad
3597 );
3598 return {
3599 ...handlerContext,
3600 actionData: {
3601 [actionMatch.route.id]: result.data
3602 },
3603 // action status codes take precedence over loader status codes
3604 ...result.statusCode ? { statusCode: result.statusCode } : {},
3605 actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {}
3606 };
3607 }
3608 async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, pendingActionResult) {
3609 let isRouteRequest = routeMatch != null;
3610 if (isRouteRequest && !_optionalChain([routeMatch, 'optionalAccess', _30 => _30.route, 'access', _31 => _31.loader]) && !_optionalChain([routeMatch, 'optionalAccess', _32 => _32.route, 'access', _33 => _33.lazy])) {
3611 throw getInternalRouterError(400, {
3612 method: request.method,
3613 pathname: new URL(request.url).pathname,
3614 routeId: _optionalChain([routeMatch, 'optionalAccess', _34 => _34.route, 'access', _35 => _35.id])
3615 });
3616 }
3617 let dsMatches;
3618 if (routeMatch) {
3619 dsMatches = getTargetedDataStrategyMatches(
3620 mapRouteProperties2,
3621 manifest,
3622 request,
3623 matches,
3624 routeMatch,
3625 [],
3626 requestContext
3627 );
3628 } else {
3629 let maxIdx = pendingActionResult && isErrorResult(pendingActionResult[1]) ? (
3630 // Up to but not including the boundary
3631 matches.findIndex((m) => m.route.id === pendingActionResult[0]) - 1
3632 ) : void 0;
3633 let pattern = getRoutePattern(matches);
3634 dsMatches = matches.map((match, index) => {
3635 if (maxIdx != null && index > maxIdx) {
3636 return getDataStrategyMatch(
3637 mapRouteProperties2,
3638 manifest,
3639 request,
3640 pattern,
3641 match,
3642 [],
3643 requestContext,
3644 false
3645 );
3646 }
3647 return getDataStrategyMatch(
3648 mapRouteProperties2,
3649 manifest,
3650 request,
3651 pattern,
3652 match,
3653 [],
3654 requestContext,
3655 (match.route.loader || match.route.lazy) != null && (!filterMatchesToLoad || filterMatchesToLoad(match))
3656 );
3657 });
3658 }
3659 if (!dataStrategy && !dsMatches.some((m) => m.shouldLoad)) {
3660 return {
3661 matches,
3662 loaderData: {},
3663 errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? {
3664 [pendingActionResult[0]]: pendingActionResult[1].error
3665 } : null,
3666 statusCode: 200,
3667 loaderHeaders: {}
3668 };
3669 }
3670 let results = await callDataStrategy(
3671 request,
3672 dsMatches,
3673 isRouteRequest,
3674 requestContext,
3675 dataStrategy
3676 );
3677 if (request.signal.aborted) {
3678 throwStaticHandlerAbortedError(request, isRouteRequest);
3679 }
3680 let handlerContext = processRouteLoaderData(
3681 matches,
3682 results,
3683 pendingActionResult,
3684 true,
3685 skipLoaderErrorBubbling
3686 );
3687 return {
3688 ...handlerContext,
3689 matches
3690 };
3691 }
3692 async function callDataStrategy(request, matches, isRouteRequest, requestContext, dataStrategy) {
3693 let results = await callDataStrategyImpl(
3694 dataStrategy || defaultDataStrategy,
3695 request,
3696 matches,
3697 null,
3698 requestContext,
3699 true
3700 );
3701 let dataResults = {};
3702 await Promise.all(
3703 matches.map(async (match) => {
3704 if (!(match.route.id in results)) {
3705 return;
3706 }
3707 let result = results[match.route.id];
3708 if (isRedirectDataStrategyResult(result)) {
3709 let response = result.result;
3710 throw normalizeRelativeRoutingRedirectResponse(
3711 response,
3712 request,
3713 match.route.id,
3714 matches,
3715 basename
3716 );
3717 }
3718 if (isRouteRequest) {
3719 if (isResponse(result.result)) {
3720 throw result;
3721 } else if (isDataWithResponseInit(result.result)) {
3722 throw dataWithResponseInitToResponse(result.result);
3723 }
3724 }
3725 dataResults[match.route.id] = await convertDataStrategyResultToDataResult(result);
3726 })
3727 );
3728 return dataResults;
3729 }
3730 return {
3731 dataRoutes,
3732 query,
3733 queryRoute
3734 };
3735}
3736function getStaticContextFromError(routes, handlerContext, error, boundaryId) {
3737 let errorBoundaryId = boundaryId || handlerContext._deepestRenderedBoundaryId || routes[0].id;
3738 return {
3739 ...handlerContext,
3740 statusCode: isRouteErrorResponse(error) ? error.status : 500,
3741 errors: {
3742 [errorBoundaryId]: error
3743 }
3744 };
3745}
3746function throwStaticHandlerAbortedError(request, isRouteRequest) {
3747 if (request.signal.reason !== void 0) {
3748 throw request.signal.reason;
3749 }
3750 let method = isRouteRequest ? "queryRoute" : "query";
3751 throw new Error(
3752 `${method}() call aborted without an \`AbortSignal.reason\`: ${request.method} ${request.url}`
3753 );
3754}
3755function isSubmissionNavigation(opts) {
3756 return opts != null && ("formData" in opts && opts.formData != null || "body" in opts && opts.body !== void 0);
3757}
3758function normalizeTo(location, matches, basename, to, fromRouteId, relative) {
3759 let contextualMatches;
3760 let activeRouteMatch;
3761 if (fromRouteId) {
3762 contextualMatches = [];
3763 for (let match of matches) {
3764 contextualMatches.push(match);
3765 if (match.route.id === fromRouteId) {
3766 activeRouteMatch = match;
3767 break;
3768 }
3769 }
3770 } else {
3771 contextualMatches = matches;
3772 activeRouteMatch = matches[matches.length - 1];
3773 }
3774 let path = resolveTo(
3775 to ? to : ".",
3776 getResolveToMatches(contextualMatches),
3777 stripBasename(location.pathname, basename) || location.pathname,
3778 relative === "path"
3779 );
3780 if (to == null) {
3781 path.search = location.search;
3782 path.hash = location.hash;
3783 }
3784 if ((to == null || to === "" || to === ".") && activeRouteMatch) {
3785 let nakedIndex = hasNakedIndexQuery(path.search);
3786 if (activeRouteMatch.route.index && !nakedIndex) {
3787 path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
3788 } else if (!activeRouteMatch.route.index && nakedIndex) {
3789 let params = new URLSearchParams(path.search);
3790 let indexValues = params.getAll("index");
3791 params.delete("index");
3792 indexValues.filter((v) => v).forEach((v) => params.append("index", v));
3793 let qs = params.toString();
3794 path.search = qs ? `?${qs}` : "";
3795 }
3796 }
3797 if (basename !== "/") {
3798 path.pathname = prependBasename({ basename, pathname: path.pathname });
3799 }
3800 return createPath(path);
3801}
3802function normalizeNavigateOptions(isFetcher, path, opts) {
3803 if (!opts || !isSubmissionNavigation(opts)) {
3804 return { path };
3805 }
3806 if (opts.formMethod && !isValidMethod(opts.formMethod)) {
3807 return {
3808 path,
3809 error: getInternalRouterError(405, { method: opts.formMethod })
3810 };
3811 }
3812 let getInvalidBodyError = () => ({
3813 path,
3814 error: getInternalRouterError(400, { type: "invalid-body" })
3815 });
3816 let rawFormMethod = opts.formMethod || "get";
3817 let formMethod = rawFormMethod.toUpperCase();
3818 let formAction = stripHashFromPath(path);
3819 if (opts.body !== void 0) {
3820 if (opts.formEncType === "text/plain") {
3821 if (!isMutationMethod(formMethod)) {
3822 return getInvalidBodyError();
3823 }
3824 let text = typeof opts.body === "string" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ? (
3825 // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data
3826 Array.from(opts.body.entries()).reduce(
3827 (acc, [name, value]) => `${acc}${name}=${value}
3828`,
3829 ""
3830 )
3831 ) : String(opts.body);
3832 return {
3833 path,
3834 submission: {
3835 formMethod,
3836 formAction,
3837 formEncType: opts.formEncType,
3838 formData: void 0,
3839 json: void 0,
3840 text
3841 }
3842 };
3843 } else if (opts.formEncType === "application/json") {
3844 if (!isMutationMethod(formMethod)) {
3845 return getInvalidBodyError();
3846 }
3847 try {
3848 let json = typeof opts.body === "string" ? JSON.parse(opts.body) : opts.body;
3849 return {
3850 path,
3851 submission: {
3852 formMethod,
3853 formAction,
3854 formEncType: opts.formEncType,
3855 formData: void 0,
3856 json,
3857 text: void 0
3858 }
3859 };
3860 } catch (e) {
3861 return getInvalidBodyError();
3862 }
3863 }
3864 }
3865 invariant(
3866 typeof FormData === "function",
3867 "FormData is not available in this environment"
3868 );
3869 let searchParams;
3870 let formData;
3871 if (opts.formData) {
3872 searchParams = convertFormDataToSearchParams(opts.formData);
3873 formData = opts.formData;
3874 } else if (opts.body instanceof FormData) {
3875 searchParams = convertFormDataToSearchParams(opts.body);
3876 formData = opts.body;
3877 } else if (opts.body instanceof URLSearchParams) {
3878 searchParams = opts.body;
3879 formData = convertSearchParamsToFormData(searchParams);
3880 } else if (opts.body == null) {
3881 searchParams = new URLSearchParams();
3882 formData = new FormData();
3883 } else {
3884 try {
3885 searchParams = new URLSearchParams(opts.body);
3886 formData = convertSearchParamsToFormData(searchParams);
3887 } catch (e) {
3888 return getInvalidBodyError();
3889 }
3890 }
3891 let submission = {
3892 formMethod,
3893 formAction,
3894 formEncType: opts && opts.formEncType || "application/x-www-form-urlencoded",
3895 formData,
3896 json: void 0,
3897 text: void 0
3898 };
3899 if (isMutationMethod(submission.formMethod)) {
3900 return { path, submission };
3901 }
3902 let parsedPath = parsePath(path);
3903 if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) {
3904 searchParams.append("index", "");
3905 }
3906 parsedPath.search = `?${searchParams}`;
3907 return { path: createPath(parsedPath), submission };
3908}
3909function getMatchesToLoad(request, scopedContext, mapRouteProperties2, manifest, history, state, matches, submission, location, lazyRoutePropertiesToSkip, initialHydration, isRevalidationRequired, cancelledFetcherLoads, fetchersQueuedForDeletion, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, hasPatchRoutesOnNavigation, pendingActionResult) {
3910 let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : void 0;
3911 let currentUrl = history.createURL(state.location);
3912 let nextUrl = history.createURL(location);
3913 let maxIdx;
3914 if (initialHydration && state.errors) {
3915 let boundaryId = Object.keys(state.errors)[0];
3916 maxIdx = matches.findIndex((m) => m.route.id === boundaryId);
3917 } else if (pendingActionResult && isErrorResult(pendingActionResult[1])) {
3918 let boundaryId = pendingActionResult[0];
3919 maxIdx = matches.findIndex((m) => m.route.id === boundaryId) - 1;
3920 }
3921 let actionStatus = pendingActionResult ? pendingActionResult[1].statusCode : void 0;
3922 let shouldSkipRevalidation = actionStatus && actionStatus >= 400;
3923 let baseShouldRevalidateArgs = {
3924 currentUrl,
3925 currentParams: _optionalChain([state, 'access', _36 => _36.matches, 'access', _37 => _37[0], 'optionalAccess', _38 => _38.params]) || {},
3926 nextUrl,
3927 nextParams: matches[0].params,
3928 ...submission,
3929 actionResult,
3930 actionStatus
3931 };
3932 let pattern = getRoutePattern(matches);
3933 let dsMatches = matches.map((match, index) => {
3934 let { route } = match;
3935 let forceShouldLoad = null;
3936 if (maxIdx != null && index > maxIdx) {
3937 forceShouldLoad = false;
3938 } else if (route.lazy) {
3939 forceShouldLoad = true;
3940 } else if (!routeHasLoaderOrMiddleware(route)) {
3941 forceShouldLoad = false;
3942 } else if (initialHydration) {
3943 forceShouldLoad = shouldLoadRouteOnHydration(
3944 route,
3945 state.loaderData,
3946 state.errors
3947 );
3948 } else if (isNewLoader(state.loaderData, state.matches[index], match)) {
3949 forceShouldLoad = true;
3950 }
3951 if (forceShouldLoad !== null) {
3952 return getDataStrategyMatch(
3953 mapRouteProperties2,
3954 manifest,
3955 request,
3956 pattern,
3957 match,
3958 lazyRoutePropertiesToSkip,
3959 scopedContext,
3960 forceShouldLoad
3961 );
3962 }
3963 let defaultShouldRevalidate = shouldSkipRevalidation ? false : (
3964 // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate
3965 isRevalidationRequired || currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search || // Search params affect all loaders
3966 currentUrl.search !== nextUrl.search || isNewRouteInstance(state.matches[index], match)
3967 );
3968 let shouldRevalidateArgs = {
3969 ...baseShouldRevalidateArgs,
3970 defaultShouldRevalidate
3971 };
3972 let shouldLoad = shouldRevalidateLoader(match, shouldRevalidateArgs);
3973 return getDataStrategyMatch(
3974 mapRouteProperties2,
3975 manifest,
3976 request,
3977 pattern,
3978 match,
3979 lazyRoutePropertiesToSkip,
3980 scopedContext,
3981 shouldLoad,
3982 shouldRevalidateArgs
3983 );
3984 });
3985 let revalidatingFetchers = [];
3986 fetchLoadMatches.forEach((f, key) => {
3987 if (initialHydration || !matches.some((m) => m.route.id === f.routeId) || fetchersQueuedForDeletion.has(key)) {
3988 return;
3989 }
3990 let fetcher = state.fetchers.get(key);
3991 let isMidInitialLoad = fetcher && fetcher.state !== "idle" && fetcher.data === void 0;
3992 let fetcherMatches = matchRoutes(routesToUse, f.path, basename);
3993 if (!fetcherMatches) {
3994 if (hasPatchRoutesOnNavigation && isMidInitialLoad) {
3995 return;
3996 }
3997 revalidatingFetchers.push({
3998 key,
3999 routeId: f.routeId,
4000 path: f.path,
4001 matches: null,
4002 match: null,
4003 request: null,
4004 controller: null
4005 });
4006 return;
4007 }
4008 if (fetchRedirectIds.has(key)) {
4009 return;
4010 }
4011 let fetcherMatch = getTargetMatch(fetcherMatches, f.path);
4012 let fetchController = new AbortController();
4013 let fetchRequest = createClientSideRequest(
4014 history,
4015 f.path,
4016 fetchController.signal
4017 );
4018 let fetcherDsMatches = null;
4019 if (cancelledFetcherLoads.has(key)) {
4020 cancelledFetcherLoads.delete(key);
4021 fetcherDsMatches = getTargetedDataStrategyMatches(
4022 mapRouteProperties2,
4023 manifest,
4024 fetchRequest,
4025 fetcherMatches,
4026 fetcherMatch,
4027 lazyRoutePropertiesToSkip,
4028 scopedContext
4029 );
4030 } else if (isMidInitialLoad) {
4031 if (isRevalidationRequired) {
4032 fetcherDsMatches = getTargetedDataStrategyMatches(
4033 mapRouteProperties2,
4034 manifest,
4035 fetchRequest,
4036 fetcherMatches,
4037 fetcherMatch,
4038 lazyRoutePropertiesToSkip,
4039 scopedContext
4040 );
4041 }
4042 } else {
4043 let shouldRevalidateArgs = {
4044 ...baseShouldRevalidateArgs,
4045 defaultShouldRevalidate: shouldSkipRevalidation ? false : isRevalidationRequired
4046 };
4047 if (shouldRevalidateLoader(fetcherMatch, shouldRevalidateArgs)) {
4048 fetcherDsMatches = getTargetedDataStrategyMatches(
4049 mapRouteProperties2,
4050 manifest,
4051 fetchRequest,
4052 fetcherMatches,
4053 fetcherMatch,
4054 lazyRoutePropertiesToSkip,
4055 scopedContext,
4056 shouldRevalidateArgs
4057 );
4058 }
4059 }
4060 if (fetcherDsMatches) {
4061 revalidatingFetchers.push({
4062 key,
4063 routeId: f.routeId,
4064 path: f.path,
4065 matches: fetcherDsMatches,
4066 match: fetcherMatch,
4067 request: fetchRequest,
4068 controller: fetchController
4069 });
4070 }
4071 });
4072 return { dsMatches, revalidatingFetchers };
4073}
4074function routeHasLoaderOrMiddleware(route) {
4075 return route.loader != null || route.middleware != null && route.middleware.length > 0;
4076}
4077function shouldLoadRouteOnHydration(route, loaderData, errors) {
4078 if (route.lazy) {
4079 return true;
4080 }
4081 if (!routeHasLoaderOrMiddleware(route)) {
4082 return false;
4083 }
4084 let hasData = loaderData != null && route.id in loaderData;
4085 let hasError = errors != null && errors[route.id] !== void 0;
4086 if (!hasData && hasError) {
4087 return false;
4088 }
4089 if (typeof route.loader === "function" && route.loader.hydrate === true) {
4090 return true;
4091 }
4092 return !hasData && !hasError;
4093}
4094function isNewLoader(currentLoaderData, currentMatch, match) {
4095 let isNew = (
4096 // [a] -> [a, b]
4097 !currentMatch || // [a, b] -> [a, c]
4098 match.route.id !== currentMatch.route.id
4099 );
4100 let isMissingData = !currentLoaderData.hasOwnProperty(match.route.id);
4101 return isNew || isMissingData;
4102}
4103function isNewRouteInstance(currentMatch, match) {
4104 let currentPath = currentMatch.route.path;
4105 return (
4106 // param change for this match, /users/123 -> /users/456
4107 currentMatch.pathname !== match.pathname || // splat param changed, which is not present in match.path
4108 // e.g. /files/images/avatar.jpg -> files/finances.xls
4109 currentPath != null && currentPath.endsWith("*") && currentMatch.params["*"] !== match.params["*"]
4110 );
4111}
4112function shouldRevalidateLoader(loaderMatch, arg) {
4113 if (loaderMatch.route.shouldRevalidate) {
4114 let routeChoice = loaderMatch.route.shouldRevalidate(arg);
4115 if (typeof routeChoice === "boolean") {
4116 return routeChoice;
4117 }
4118 }
4119 return arg.defaultShouldRevalidate;
4120}
4121function patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties2, allowElementMutations) {
4122 let childrenToPatch;
4123 if (routeId) {
4124 let route = manifest[routeId];
4125 invariant(
4126 route,
4127 `No route found to patch children into: routeId = ${routeId}`
4128 );
4129 if (!route.children) {
4130 route.children = [];
4131 }
4132 childrenToPatch = route.children;
4133 } else {
4134 childrenToPatch = routesToUse;
4135 }
4136 let uniqueChildren = [];
4137 let existingChildren = [];
4138 children.forEach((newRoute) => {
4139 let existingRoute = childrenToPatch.find(
4140 (existingRoute2) => isSameRoute(newRoute, existingRoute2)
4141 );
4142 if (existingRoute) {
4143 existingChildren.push({ existingRoute, newRoute });
4144 } else {
4145 uniqueChildren.push(newRoute);
4146 }
4147 });
4148 if (uniqueChildren.length > 0) {
4149 let newRoutes = convertRoutesToDataRoutes(
4150 uniqueChildren,
4151 mapRouteProperties2,
4152 [routeId || "_", "patch", String(_optionalChain([childrenToPatch, 'optionalAccess', _39 => _39.length]) || "0")],
4153 manifest
4154 );
4155 childrenToPatch.push(...newRoutes);
4156 }
4157 if (allowElementMutations && existingChildren.length > 0) {
4158 for (let i = 0; i < existingChildren.length; i++) {
4159 let { existingRoute, newRoute } = existingChildren[i];
4160 let existingRouteTyped = existingRoute;
4161 let [newRouteTyped] = convertRoutesToDataRoutes(
4162 [newRoute],
4163 mapRouteProperties2,
4164 [],
4165 // Doesn't matter for mutated routes since they already have an id
4166 {},
4167 // Don't touch the manifest here since we're updating in place
4168 true
4169 );
4170 Object.assign(existingRouteTyped, {
4171 element: newRouteTyped.element ? newRouteTyped.element : existingRouteTyped.element,
4172 errorElement: newRouteTyped.errorElement ? newRouteTyped.errorElement : existingRouteTyped.errorElement,
4173 hydrateFallbackElement: newRouteTyped.hydrateFallbackElement ? newRouteTyped.hydrateFallbackElement : existingRouteTyped.hydrateFallbackElement
4174 });
4175 }
4176 }
4177}
4178function isSameRoute(newRoute, existingRoute) {
4179 if ("id" in newRoute && "id" in existingRoute && newRoute.id === existingRoute.id) {
4180 return true;
4181 }
4182 if (!(newRoute.index === existingRoute.index && newRoute.path === existingRoute.path && newRoute.caseSensitive === existingRoute.caseSensitive)) {
4183 return false;
4184 }
4185 if ((!newRoute.children || newRoute.children.length === 0) && (!existingRoute.children || existingRoute.children.length === 0)) {
4186 return true;
4187 }
4188 return newRoute.children.every(
4189 (aChild, i) => _optionalChain([existingRoute, 'access', _40 => _40.children, 'optionalAccess', _41 => _41.some, 'call', _42 => _42((bChild) => isSameRoute(aChild, bChild))])
4190 );
4191}
4192var lazyRoutePropertyCache = /* @__PURE__ */ new WeakMap();
4193var loadLazyRouteProperty = ({
4194 key,
4195 route,
4196 manifest,
4197 mapRouteProperties: mapRouteProperties2
4198}) => {
4199 let routeToUpdate = manifest[route.id];
4200 invariant(routeToUpdate, "No route found in manifest");
4201 if (!routeToUpdate.lazy || typeof routeToUpdate.lazy !== "object") {
4202 return;
4203 }
4204 let lazyFn = routeToUpdate.lazy[key];
4205 if (!lazyFn) {
4206 return;
4207 }
4208 let cache = lazyRoutePropertyCache.get(routeToUpdate);
4209 if (!cache) {
4210 cache = {};
4211 lazyRoutePropertyCache.set(routeToUpdate, cache);
4212 }
4213 let cachedPromise = cache[key];
4214 if (cachedPromise) {
4215 return cachedPromise;
4216 }
4217 let propertyPromise = (async () => {
4218 let isUnsupported = isUnsupportedLazyRouteObjectKey(key);
4219 let staticRouteValue = routeToUpdate[key];
4220 let isStaticallyDefined = staticRouteValue !== void 0 && key !== "hasErrorBoundary";
4221 if (isUnsupported) {
4222 warning(
4223 !isUnsupported,
4224 "Route property " + key + " is not a supported lazy route property. This property will be ignored."
4225 );
4226 cache[key] = Promise.resolve();
4227 } else if (isStaticallyDefined) {
4228 warning(
4229 false,
4230 `Route "${routeToUpdate.id}" has a static property "${key}" defined. The lazy property will be ignored.`
4231 );
4232 } else {
4233 let value = await lazyFn();
4234 if (value != null) {
4235 Object.assign(routeToUpdate, { [key]: value });
4236 Object.assign(routeToUpdate, mapRouteProperties2(routeToUpdate));
4237 }
4238 }
4239 if (typeof routeToUpdate.lazy === "object") {
4240 routeToUpdate.lazy[key] = void 0;
4241 if (Object.values(routeToUpdate.lazy).every((value) => value === void 0)) {
4242 routeToUpdate.lazy = void 0;
4243 }
4244 }
4245 })();
4246 cache[key] = propertyPromise;
4247 return propertyPromise;
4248};
4249var lazyRouteFunctionCache = /* @__PURE__ */ new WeakMap();
4250function loadLazyRoute(route, type, manifest, mapRouteProperties2, lazyRoutePropertiesToSkip) {
4251 let routeToUpdate = manifest[route.id];
4252 invariant(routeToUpdate, "No route found in manifest");
4253 if (!route.lazy) {
4254 return {
4255 lazyRoutePromise: void 0,
4256 lazyHandlerPromise: void 0
4257 };
4258 }
4259 if (typeof route.lazy === "function") {
4260 let cachedPromise = lazyRouteFunctionCache.get(routeToUpdate);
4261 if (cachedPromise) {
4262 return {
4263 lazyRoutePromise: cachedPromise,
4264 lazyHandlerPromise: cachedPromise
4265 };
4266 }
4267 let lazyRoutePromise2 = (async () => {
4268 invariant(
4269 typeof route.lazy === "function",
4270 "No lazy route function found"
4271 );
4272 let lazyRoute = await route.lazy();
4273 let routeUpdates = {};
4274 for (let lazyRouteProperty in lazyRoute) {
4275 let lazyValue = lazyRoute[lazyRouteProperty];
4276 if (lazyValue === void 0) {
4277 continue;
4278 }
4279 let isUnsupported = isUnsupportedLazyRouteFunctionKey(lazyRouteProperty);
4280 let staticRouteValue = routeToUpdate[lazyRouteProperty];
4281 let isStaticallyDefined = staticRouteValue !== void 0 && // This property isn't static since it should always be updated based
4282 // on the route updates
4283 lazyRouteProperty !== "hasErrorBoundary";
4284 if (isUnsupported) {
4285 warning(
4286 !isUnsupported,
4287 "Route property " + lazyRouteProperty + " is not a supported property to be returned from a lazy route function. This property will be ignored."
4288 );
4289 } else if (isStaticallyDefined) {
4290 warning(
4291 !isStaticallyDefined,
4292 `Route "${routeToUpdate.id}" has a static property "${lazyRouteProperty}" defined but its lazy function is also returning a value for this property. The lazy route property "${lazyRouteProperty}" will be ignored.`
4293 );
4294 } else {
4295 routeUpdates[lazyRouteProperty] = lazyValue;
4296 }
4297 }
4298 Object.assign(routeToUpdate, routeUpdates);
4299 Object.assign(routeToUpdate, {
4300 // To keep things framework agnostic, we use the provided `mapRouteProperties`
4301 // function to set the framework-aware properties (`element`/`hasErrorBoundary`)
4302 // since the logic will differ between frameworks.
4303 ...mapRouteProperties2(routeToUpdate),
4304 lazy: void 0
4305 });
4306 })();
4307 lazyRouteFunctionCache.set(routeToUpdate, lazyRoutePromise2);
4308 lazyRoutePromise2.catch(() => {
4309 });
4310 return {
4311 lazyRoutePromise: lazyRoutePromise2,
4312 lazyHandlerPromise: lazyRoutePromise2
4313 };
4314 }
4315 let lazyKeys = Object.keys(route.lazy);
4316 let lazyPropertyPromises = [];
4317 let lazyHandlerPromise = void 0;
4318 for (let key of lazyKeys) {
4319 if (lazyRoutePropertiesToSkip && lazyRoutePropertiesToSkip.includes(key)) {
4320 continue;
4321 }
4322 let promise = loadLazyRouteProperty({
4323 key,
4324 route,
4325 manifest,
4326 mapRouteProperties: mapRouteProperties2
4327 });
4328 if (promise) {
4329 lazyPropertyPromises.push(promise);
4330 if (key === type) {
4331 lazyHandlerPromise = promise;
4332 }
4333 }
4334 }
4335 let lazyRoutePromise = lazyPropertyPromises.length > 0 ? Promise.all(lazyPropertyPromises).then(() => {
4336 }) : void 0;
4337 _optionalChain([lazyRoutePromise, 'optionalAccess', _43 => _43.catch, 'call', _44 => _44(() => {
4338 })]);
4339 _optionalChain([lazyHandlerPromise, 'optionalAccess', _45 => _45.catch, 'call', _46 => _46(() => {
4340 })]);
4341 return {
4342 lazyRoutePromise,
4343 lazyHandlerPromise
4344 };
4345}
4346function isNonNullable(value) {
4347 return value !== void 0;
4348}
4349function loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties2) {
4350 let promises = matches.map(({ route }) => {
4351 if (typeof route.lazy !== "object" || !route.lazy.middleware) {
4352 return void 0;
4353 }
4354 return loadLazyRouteProperty({
4355 key: "middleware",
4356 route,
4357 manifest,
4358 mapRouteProperties: mapRouteProperties2
4359 });
4360 }).filter(isNonNullable);
4361 return promises.length > 0 ? Promise.all(promises) : void 0;
4362}
4363async function defaultDataStrategy(args) {
4364 let matchesToLoad = args.matches.filter((m) => m.shouldLoad);
4365 let keyedResults = {};
4366 let results = await Promise.all(matchesToLoad.map((m) => m.resolve()));
4367 results.forEach((result, i) => {
4368 keyedResults[matchesToLoad[i].route.id] = result;
4369 });
4370 return keyedResults;
4371}
4372async function defaultDataStrategyWithMiddleware(args) {
4373 if (!args.matches.some((m) => m.route.middleware)) {
4374 return defaultDataStrategy(args);
4375 }
4376 return runClientMiddlewarePipeline(args, () => defaultDataStrategy(args));
4377}
4378function runServerMiddlewarePipeline(args, handler, errorHandler) {
4379 return runMiddlewarePipeline(
4380 args,
4381 handler,
4382 processResult,
4383 isResponse,
4384 errorHandler
4385 );
4386 function processResult(result) {
4387 return isDataWithResponseInit(result) ? dataWithResponseInitToResponse(result) : result;
4388 }
4389}
4390function runClientMiddlewarePipeline(args, handler) {
4391 return runMiddlewarePipeline(
4392 args,
4393 handler,
4394 (r) => r,
4395 // No post-processing needed on the client
4396 isDataStrategyResults,
4397 errorHandler
4398 );
4399 function errorHandler(error, routeId, nextResult) {
4400 if (nextResult) {
4401 return Promise.resolve(
4402 Object.assign(nextResult.value, {
4403 [routeId]: { type: "error", result: error }
4404 })
4405 );
4406 } else {
4407 let { matches } = args;
4408 let maxBoundaryIdx = Math.min(
4409 // Throwing route
4410 Math.max(
4411 matches.findIndex((m) => m.route.id === routeId),
4412 0
4413 ),
4414 // or the shallowest route that needs to load data
4415 Math.max(
4416 matches.findIndex((m) => m.shouldCallHandler()),
4417 0
4418 )
4419 );
4420 let boundaryRouteId = findNearestBoundary(
4421 matches,
4422 matches[maxBoundaryIdx].route.id
4423 ).route.id;
4424 return Promise.resolve({
4425 [boundaryRouteId]: { type: "error", result: error }
4426 });
4427 }
4428 }
4429}
4430async function runMiddlewarePipeline(args, handler, processResult, isResult, errorHandler) {
4431 let { matches, request, params, context, unstable_pattern } = args;
4432 let tuples = matches.flatMap(
4433 (m) => m.route.middleware ? m.route.middleware.map((fn) => [m.route.id, fn]) : []
4434 );
4435 let result = await callRouteMiddleware(
4436 {
4437 request,
4438 params,
4439 context,
4440 unstable_pattern
4441 },
4442 tuples,
4443 handler,
4444 processResult,
4445 isResult,
4446 errorHandler
4447 );
4448 return result;
4449}
4450async function callRouteMiddleware(args, middlewares, handler, processResult, isResult, errorHandler, idx = 0) {
4451 let { request } = args;
4452 if (request.signal.aborted) {
4453 throw _nullishCoalesce(request.signal.reason, () => ( new Error(`Request aborted: ${request.method} ${request.url}`)));
4454 }
4455 let tuple = middlewares[idx];
4456 if (!tuple) {
4457 let result = await handler();
4458 return result;
4459 }
4460 let [routeId, middleware] = tuple;
4461 let nextResult;
4462 let next = async () => {
4463 if (nextResult) {
4464 throw new Error("You may only call `next()` once per middleware");
4465 }
4466 try {
4467 let result = await callRouteMiddleware(
4468 args,
4469 middlewares,
4470 handler,
4471 processResult,
4472 isResult,
4473 errorHandler,
4474 idx + 1
4475 );
4476 nextResult = { value: result };
4477 return nextResult.value;
4478 } catch (error) {
4479 nextResult = { value: await errorHandler(error, routeId, nextResult) };
4480 return nextResult.value;
4481 }
4482 };
4483 try {
4484 let value = await middleware(args, next);
4485 let result = value != null ? processResult(value) : void 0;
4486 if (isResult(result)) {
4487 return result;
4488 } else if (nextResult) {
4489 return _nullishCoalesce(result, () => ( nextResult.value));
4490 } else {
4491 nextResult = { value: await next() };
4492 return nextResult.value;
4493 }
4494 } catch (error) {
4495 let response = await errorHandler(error, routeId, nextResult);
4496 return response;
4497 }
4498}
4499function getDataStrategyMatchLazyPromises(mapRouteProperties2, manifest, request, match, lazyRoutePropertiesToSkip) {
4500 let lazyMiddlewarePromise = loadLazyRouteProperty({
4501 key: "middleware",
4502 route: match.route,
4503 manifest,
4504 mapRouteProperties: mapRouteProperties2
4505 });
4506 let lazyRoutePromises = loadLazyRoute(
4507 match.route,
4508 isMutationMethod(request.method) ? "action" : "loader",
4509 manifest,
4510 mapRouteProperties2,
4511 lazyRoutePropertiesToSkip
4512 );
4513 return {
4514 middleware: lazyMiddlewarePromise,
4515 route: lazyRoutePromises.lazyRoutePromise,
4516 handler: lazyRoutePromises.lazyHandlerPromise
4517 };
4518}
4519function getDataStrategyMatch(mapRouteProperties2, manifest, request, unstable_pattern, match, lazyRoutePropertiesToSkip, scopedContext, shouldLoad, shouldRevalidateArgs = null) {
4520 let isUsingNewApi = false;
4521 let _lazyPromises = getDataStrategyMatchLazyPromises(
4522 mapRouteProperties2,
4523 manifest,
4524 request,
4525 match,
4526 lazyRoutePropertiesToSkip
4527 );
4528 return {
4529 ...match,
4530 _lazyPromises,
4531 shouldLoad,
4532 shouldRevalidateArgs,
4533 shouldCallHandler(defaultShouldRevalidate) {
4534 isUsingNewApi = true;
4535 if (!shouldRevalidateArgs) {
4536 return shouldLoad;
4537 }
4538 if (typeof defaultShouldRevalidate === "boolean") {
4539 return shouldRevalidateLoader(match, {
4540 ...shouldRevalidateArgs,
4541 defaultShouldRevalidate
4542 });
4543 }
4544 return shouldRevalidateLoader(match, shouldRevalidateArgs);
4545 },
4546 resolve(handlerOverride) {
4547 let { lazy, loader, middleware } = match.route;
4548 let callHandler = isUsingNewApi || shouldLoad || handlerOverride && !isMutationMethod(request.method) && (lazy || loader);
4549 let isMiddlewareOnlyRoute = middleware && middleware.length > 0 && !loader && !lazy;
4550 if (callHandler && (isMutationMethod(request.method) || !isMiddlewareOnlyRoute)) {
4551 return callLoaderOrAction({
4552 request,
4553 unstable_pattern,
4554 match,
4555 lazyHandlerPromise: _optionalChain([_lazyPromises, 'optionalAccess', _47 => _47.handler]),
4556 lazyRoutePromise: _optionalChain([_lazyPromises, 'optionalAccess', _48 => _48.route]),
4557 handlerOverride,
4558 scopedContext
4559 });
4560 }
4561 return Promise.resolve({ type: "data" /* data */, result: void 0 });
4562 }
4563 };
4564}
4565function getTargetedDataStrategyMatches(mapRouteProperties2, manifest, request, matches, targetMatch, lazyRoutePropertiesToSkip, scopedContext, shouldRevalidateArgs = null) {
4566 return matches.map((match) => {
4567 if (match.route.id !== targetMatch.route.id) {
4568 return {
4569 ...match,
4570 shouldLoad: false,
4571 shouldRevalidateArgs,
4572 shouldCallHandler: () => false,
4573 _lazyPromises: getDataStrategyMatchLazyPromises(
4574 mapRouteProperties2,
4575 manifest,
4576 request,
4577 match,
4578 lazyRoutePropertiesToSkip
4579 ),
4580 resolve: () => Promise.resolve({ type: "data", result: void 0 })
4581 };
4582 }
4583 return getDataStrategyMatch(
4584 mapRouteProperties2,
4585 manifest,
4586 request,
4587 getRoutePattern(matches),
4588 match,
4589 lazyRoutePropertiesToSkip,
4590 scopedContext,
4591 true,
4592 shouldRevalidateArgs
4593 );
4594 });
4595}
4596async function callDataStrategyImpl(dataStrategyImpl, request, matches, fetcherKey, scopedContext, isStaticHandler) {
4597 if (matches.some((m) => _optionalChain([m, 'access', _49 => _49._lazyPromises, 'optionalAccess', _50 => _50.middleware]))) {
4598 await Promise.all(matches.map((m) => _optionalChain([m, 'access', _51 => _51._lazyPromises, 'optionalAccess', _52 => _52.middleware])));
4599 }
4600 let dataStrategyArgs = {
4601 request,
4602 unstable_pattern: getRoutePattern(matches),
4603 params: matches[0].params,
4604 context: scopedContext,
4605 matches
4606 };
4607 let runClientMiddleware = isStaticHandler ? () => {
4608 throw new Error(
4609 "You cannot call `runClientMiddleware()` from a static handler `dataStrategy`. Middleware is run outside of `dataStrategy` during SSR in order to bubble up the Response. You can enable middleware via the `respond` API in `query`/`queryRoute`"
4610 );
4611 } : (cb) => {
4612 let typedDataStrategyArgs = dataStrategyArgs;
4613 return runClientMiddlewarePipeline(typedDataStrategyArgs, () => {
4614 return cb({
4615 ...typedDataStrategyArgs,
4616 fetcherKey,
4617 runClientMiddleware: () => {
4618 throw new Error(
4619 "Cannot call `runClientMiddleware()` from within an `runClientMiddleware` handler"
4620 );
4621 }
4622 });
4623 });
4624 };
4625 let results = await dataStrategyImpl({
4626 ...dataStrategyArgs,
4627 fetcherKey,
4628 runClientMiddleware
4629 });
4630 try {
4631 await Promise.all(
4632 matches.flatMap((m) => [
4633 _optionalChain([m, 'access', _53 => _53._lazyPromises, 'optionalAccess', _54 => _54.handler]),
4634 _optionalChain([m, 'access', _55 => _55._lazyPromises, 'optionalAccess', _56 => _56.route])
4635 ])
4636 );
4637 } catch (e) {
4638 }
4639 return results;
4640}
4641async function callLoaderOrAction({
4642 request,
4643 unstable_pattern,
4644 match,
4645 lazyHandlerPromise,
4646 lazyRoutePromise,
4647 handlerOverride,
4648 scopedContext
4649}) {
4650 let result;
4651 let onReject;
4652 let isAction = isMutationMethod(request.method);
4653 let type = isAction ? "action" : "loader";
4654 let runHandler = (handler) => {
4655 let reject;
4656 let abortPromise = new Promise((_, r) => reject = r);
4657 onReject = () => reject();
4658 request.signal.addEventListener("abort", onReject);
4659 let actualHandler = (ctx) => {
4660 if (typeof handler !== "function") {
4661 return Promise.reject(
4662 new Error(
4663 `You cannot call the handler for a route which defines a boolean "${type}" [routeId: ${match.route.id}]`
4664 )
4665 );
4666 }
4667 return handler(
4668 {
4669 request,
4670 unstable_pattern,
4671 params: match.params,
4672 context: scopedContext
4673 },
4674 ...ctx !== void 0 ? [ctx] : []
4675 );
4676 };
4677 let handlerPromise = (async () => {
4678 try {
4679 let val = await (handlerOverride ? handlerOverride((ctx) => actualHandler(ctx)) : actualHandler());
4680 return { type: "data", result: val };
4681 } catch (e) {
4682 return { type: "error", result: e };
4683 }
4684 })();
4685 return Promise.race([handlerPromise, abortPromise]);
4686 };
4687 try {
4688 let handler = isAction ? match.route.action : match.route.loader;
4689 if (lazyHandlerPromise || lazyRoutePromise) {
4690 if (handler) {
4691 let handlerError;
4692 let [value] = await Promise.all([
4693 // If the handler throws, don't let it immediately bubble out,
4694 // since we need to let the lazy() execution finish so we know if this
4695 // route has a boundary that can handle the error
4696 runHandler(handler).catch((e) => {
4697 handlerError = e;
4698 }),
4699 // Ensure all lazy route promises are resolved before continuing
4700 lazyHandlerPromise,
4701 lazyRoutePromise
4702 ]);
4703 if (handlerError !== void 0) {
4704 throw handlerError;
4705 }
4706 result = value;
4707 } else {
4708 await lazyHandlerPromise;
4709 let handler2 = isAction ? match.route.action : match.route.loader;
4710 if (handler2) {
4711 [result] = await Promise.all([runHandler(handler2), lazyRoutePromise]);
4712 } else if (type === "action") {
4713 let url = new URL(request.url);
4714 let pathname = url.pathname + url.search;
4715 throw getInternalRouterError(405, {
4716 method: request.method,
4717 pathname,
4718 routeId: match.route.id
4719 });
4720 } else {
4721 return { type: "data" /* data */, result: void 0 };
4722 }
4723 }
4724 } else if (!handler) {
4725 let url = new URL(request.url);
4726 let pathname = url.pathname + url.search;
4727 throw getInternalRouterError(404, {
4728 pathname
4729 });
4730 } else {
4731 result = await runHandler(handler);
4732 }
4733 } catch (e) {
4734 return { type: "error" /* error */, result: e };
4735 } finally {
4736 if (onReject) {
4737 request.signal.removeEventListener("abort", onReject);
4738 }
4739 }
4740 return result;
4741}
4742async function parseResponseBody(response) {
4743 let contentType = response.headers.get("Content-Type");
4744 if (contentType && /\bapplication\/json\b/.test(contentType)) {
4745 return response.body == null ? null : response.json();
4746 }
4747 return response.text();
4748}
4749async function convertDataStrategyResultToDataResult(dataStrategyResult) {
4750 let { result, type } = dataStrategyResult;
4751 if (isResponse(result)) {
4752 let data2;
4753 try {
4754 data2 = await parseResponseBody(result);
4755 } catch (e) {
4756 return { type: "error" /* error */, error: e };
4757 }
4758 if (type === "error" /* error */) {
4759 return {
4760 type: "error" /* error */,
4761 error: new ErrorResponseImpl(result.status, result.statusText, data2),
4762 statusCode: result.status,
4763 headers: result.headers
4764 };
4765 }
4766 return {
4767 type: "data" /* data */,
4768 data: data2,
4769 statusCode: result.status,
4770 headers: result.headers
4771 };
4772 }
4773 if (type === "error" /* error */) {
4774 if (isDataWithResponseInit(result)) {
4775 if (result.data instanceof Error) {
4776 return {
4777 type: "error" /* error */,
4778 error: result.data,
4779 statusCode: _optionalChain([result, 'access', _57 => _57.init, 'optionalAccess', _58 => _58.status]),
4780 headers: _optionalChain([result, 'access', _59 => _59.init, 'optionalAccess', _60 => _60.headers]) ? new Headers(result.init.headers) : void 0
4781 };
4782 }
4783 return {
4784 type: "error" /* error */,
4785 error: dataWithResponseInitToErrorResponse(result),
4786 statusCode: isRouteErrorResponse(result) ? result.status : void 0,
4787 headers: _optionalChain([result, 'access', _61 => _61.init, 'optionalAccess', _62 => _62.headers]) ? new Headers(result.init.headers) : void 0
4788 };
4789 }
4790 return {
4791 type: "error" /* error */,
4792 error: result,
4793 statusCode: isRouteErrorResponse(result) ? result.status : void 0
4794 };
4795 }
4796 if (isDataWithResponseInit(result)) {
4797 return {
4798 type: "data" /* data */,
4799 data: result.data,
4800 statusCode: _optionalChain([result, 'access', _63 => _63.init, 'optionalAccess', _64 => _64.status]),
4801 headers: _optionalChain([result, 'access', _65 => _65.init, 'optionalAccess', _66 => _66.headers]) ? new Headers(result.init.headers) : void 0
4802 };
4803 }
4804 return { type: "data" /* data */, data: result };
4805}
4806function normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename) {
4807 let location = response.headers.get("Location");
4808 invariant(
4809 location,
4810 "Redirects returned/thrown from loaders/actions must have a Location header"
4811 );
4812 if (!isAbsoluteUrl(location)) {
4813 let trimmedMatches = matches.slice(
4814 0,
4815 matches.findIndex((m) => m.route.id === routeId) + 1
4816 );
4817 location = normalizeTo(
4818 new URL(request.url),
4819 trimmedMatches,
4820 basename,
4821 location
4822 );
4823 response.headers.set("Location", location);
4824 }
4825 return response;
4826}
4827function normalizeRedirectLocation(location, currentUrl, basename) {
4828 if (isAbsoluteUrl(location)) {
4829 let normalizedLocation = location;
4830 let url = normalizedLocation.startsWith("//") ? new URL(currentUrl.protocol + normalizedLocation) : new URL(normalizedLocation);
4831 let isSameBasename = stripBasename(url.pathname, basename) != null;
4832 if (url.origin === currentUrl.origin && isSameBasename) {
4833 return url.pathname + url.search + url.hash;
4834 }
4835 }
4836 return location;
4837}
4838function createClientSideRequest(history, location, signal, submission) {
4839 let url = history.createURL(stripHashFromPath(location)).toString();
4840 let init = { signal };
4841 if (submission && isMutationMethod(submission.formMethod)) {
4842 let { formMethod, formEncType } = submission;
4843 init.method = formMethod.toUpperCase();
4844 if (formEncType === "application/json") {
4845 init.headers = new Headers({ "Content-Type": formEncType });
4846 init.body = JSON.stringify(submission.json);
4847 } else if (formEncType === "text/plain") {
4848 init.body = submission.text;
4849 } else if (formEncType === "application/x-www-form-urlencoded" && submission.formData) {
4850 init.body = convertFormDataToSearchParams(submission.formData);
4851 } else {
4852 init.body = submission.formData;
4853 }
4854 }
4855 return new Request(url, init);
4856}
4857function convertFormDataToSearchParams(formData) {
4858 let searchParams = new URLSearchParams();
4859 for (let [key, value] of formData.entries()) {
4860 searchParams.append(key, typeof value === "string" ? value : value.name);
4861 }
4862 return searchParams;
4863}
4864function convertSearchParamsToFormData(searchParams) {
4865 let formData = new FormData();
4866 for (let [key, value] of searchParams.entries()) {
4867 formData.append(key, value);
4868 }
4869 return formData;
4870}
4871function processRouteLoaderData(matches, results, pendingActionResult, isStaticHandler = false, skipLoaderErrorBubbling = false) {
4872 let loaderData = {};
4873 let errors = null;
4874 let statusCode;
4875 let foundError = false;
4876 let loaderHeaders = {};
4877 let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : void 0;
4878 matches.forEach((match) => {
4879 if (!(match.route.id in results)) {
4880 return;
4881 }
4882 let id = match.route.id;
4883 let result = results[id];
4884 invariant(
4885 !isRedirectResult(result),
4886 "Cannot handle redirect results in processLoaderData"
4887 );
4888 if (isErrorResult(result)) {
4889 let error = result.error;
4890 if (pendingError !== void 0) {
4891 error = pendingError;
4892 pendingError = void 0;
4893 }
4894 errors = errors || {};
4895 if (skipLoaderErrorBubbling) {
4896 errors[id] = error;
4897 } else {
4898 let boundaryMatch = findNearestBoundary(matches, id);
4899 if (errors[boundaryMatch.route.id] == null) {
4900 errors[boundaryMatch.route.id] = error;
4901 }
4902 }
4903 if (!isStaticHandler) {
4904 loaderData[id] = ResetLoaderDataSymbol;
4905 }
4906 if (!foundError) {
4907 foundError = true;
4908 statusCode = isRouteErrorResponse(result.error) ? result.error.status : 500;
4909 }
4910 if (result.headers) {
4911 loaderHeaders[id] = result.headers;
4912 }
4913 } else {
4914 loaderData[id] = result.data;
4915 if (result.statusCode && result.statusCode !== 200 && !foundError) {
4916 statusCode = result.statusCode;
4917 }
4918 if (result.headers) {
4919 loaderHeaders[id] = result.headers;
4920 }
4921 }
4922 });
4923 if (pendingError !== void 0 && pendingActionResult) {
4924 errors = { [pendingActionResult[0]]: pendingError };
4925 if (pendingActionResult[2]) {
4926 loaderData[pendingActionResult[2]] = void 0;
4927 }
4928 }
4929 return {
4930 loaderData,
4931 errors,
4932 statusCode: statusCode || 200,
4933 loaderHeaders
4934 };
4935}
4936function processLoaderData(state, matches, results, pendingActionResult, revalidatingFetchers, fetcherResults) {
4937 let { loaderData, errors } = processRouteLoaderData(
4938 matches,
4939 results,
4940 pendingActionResult
4941 );
4942 revalidatingFetchers.filter((f) => !f.matches || f.matches.some((m) => m.shouldLoad)).forEach((rf) => {
4943 let { key, match, controller } = rf;
4944 if (controller && controller.signal.aborted) {
4945 return;
4946 }
4947 let result = fetcherResults[key];
4948 invariant(result, "Did not find corresponding fetcher result");
4949 if (isErrorResult(result)) {
4950 let boundaryMatch = findNearestBoundary(state.matches, _optionalChain([match, 'optionalAccess', _67 => _67.route, 'access', _68 => _68.id]));
4951 if (!(errors && errors[boundaryMatch.route.id])) {
4952 errors = {
4953 ...errors,
4954 [boundaryMatch.route.id]: result.error
4955 };
4956 }
4957 state.fetchers.delete(key);
4958 } else if (isRedirectResult(result)) {
4959 invariant(false, "Unhandled fetcher revalidation redirect");
4960 } else {
4961 let doneFetcher = getDoneFetcher(result.data);
4962 state.fetchers.set(key, doneFetcher);
4963 }
4964 });
4965 return { loaderData, errors };
4966}
4967function mergeLoaderData(loaderData, newLoaderData, matches, errors) {
4968 let mergedLoaderData = Object.entries(newLoaderData).filter(([, v]) => v !== ResetLoaderDataSymbol).reduce((merged, [k, v]) => {
4969 merged[k] = v;
4970 return merged;
4971 }, {});
4972 for (let match of matches) {
4973 let id = match.route.id;
4974 if (!newLoaderData.hasOwnProperty(id) && loaderData.hasOwnProperty(id) && match.route.loader) {
4975 mergedLoaderData[id] = loaderData[id];
4976 }
4977 if (errors && errors.hasOwnProperty(id)) {
4978 break;
4979 }
4980 }
4981 return mergedLoaderData;
4982}
4983function getActionDataForCommit(pendingActionResult) {
4984 if (!pendingActionResult) {
4985 return {};
4986 }
4987 return isErrorResult(pendingActionResult[1]) ? {
4988 // Clear out prior actionData on errors
4989 actionData: {}
4990 } : {
4991 actionData: {
4992 [pendingActionResult[0]]: pendingActionResult[1].data
4993 }
4994 };
4995}
4996function findNearestBoundary(matches, routeId) {
4997 let eligibleMatches = routeId ? matches.slice(0, matches.findIndex((m) => m.route.id === routeId) + 1) : [...matches];
4998 return eligibleMatches.reverse().find((m) => m.route.hasErrorBoundary === true) || matches[0];
4999}
5000function getShortCircuitMatches(routes) {
5001 let route = routes.length === 1 ? routes[0] : routes.find((r) => r.index || !r.path || r.path === "/") || {
5002 id: `__shim-error-route__`
5003 };
5004 return {
5005 matches: [
5006 {
5007 params: {},
5008 pathname: "",
5009 pathnameBase: "",
5010 route
5011 }
5012 ],
5013 route
5014 };
5015}
5016function getInternalRouterError(status, {
5017 pathname,
5018 routeId,
5019 method,
5020 type,
5021 message
5022} = {}) {
5023 let statusText = "Unknown Server Error";
5024 let errorMessage = "Unknown @remix-run/router error";
5025 if (status === 400) {
5026 statusText = "Bad Request";
5027 if (method && pathname && routeId) {
5028 errorMessage = `You made a ${method} request to "${pathname}" but did not provide a \`loader\` for route "${routeId}", so there is no way to handle the request.`;
5029 } else if (type === "invalid-body") {
5030 errorMessage = "Unable to encode submission body";
5031 }
5032 } else if (status === 403) {
5033 statusText = "Forbidden";
5034 errorMessage = `Route "${routeId}" does not match URL "${pathname}"`;
5035 } else if (status === 404) {
5036 statusText = "Not Found";
5037 errorMessage = `No route matches URL "${pathname}"`;
5038 } else if (status === 405) {
5039 statusText = "Method Not Allowed";
5040 if (method && pathname && routeId) {
5041 errorMessage = `You made a ${method.toUpperCase()} request to "${pathname}" but did not provide an \`action\` for route "${routeId}", so there is no way to handle the request.`;
5042 } else if (method) {
5043 errorMessage = `Invalid request method "${method.toUpperCase()}"`;
5044 }
5045 }
5046 return new ErrorResponseImpl(
5047 status || 500,
5048 statusText,
5049 new Error(errorMessage),
5050 true
5051 );
5052}
5053function findRedirect(results) {
5054 let entries = Object.entries(results);
5055 for (let i = entries.length - 1; i >= 0; i--) {
5056 let [key, result] = entries[i];
5057 if (isRedirectResult(result)) {
5058 return { key, result };
5059 }
5060 }
5061}
5062function stripHashFromPath(path) {
5063 let parsedPath = typeof path === "string" ? parsePath(path) : path;
5064 return createPath({ ...parsedPath, hash: "" });
5065}
5066function isHashChangeOnly(a, b) {
5067 if (a.pathname !== b.pathname || a.search !== b.search) {
5068 return false;
5069 }
5070 if (a.hash === "") {
5071 return b.hash !== "";
5072 } else if (a.hash === b.hash) {
5073 return true;
5074 } else if (b.hash !== "") {
5075 return true;
5076 }
5077 return false;
5078}
5079function dataWithResponseInitToResponse(data2) {
5080 return Response.json(data2.data, _nullishCoalesce(data2.init, () => ( void 0)));
5081}
5082function dataWithResponseInitToErrorResponse(data2) {
5083 return new ErrorResponseImpl(
5084 _nullishCoalesce(_optionalChain([data2, 'access', _69 => _69.init, 'optionalAccess', _70 => _70.status]), () => ( 500)),
5085 _nullishCoalesce(_optionalChain([data2, 'access', _71 => _71.init, 'optionalAccess', _72 => _72.statusText]), () => ( "Internal Server Error")),
5086 data2.data
5087 );
5088}
5089function isDataStrategyResults(result) {
5090 return result != null && typeof result === "object" && Object.entries(result).every(
5091 ([key, value]) => typeof key === "string" && isDataStrategyResult(value)
5092 );
5093}
5094function isDataStrategyResult(result) {
5095 return result != null && typeof result === "object" && "type" in result && "result" in result && (result.type === "data" /* data */ || result.type === "error" /* error */);
5096}
5097function isRedirectDataStrategyResult(result) {
5098 return isResponse(result.result) && redirectStatusCodes.has(result.result.status);
5099}
5100function isErrorResult(result) {
5101 return result.type === "error" /* error */;
5102}
5103function isRedirectResult(result) {
5104 return (result && result.type) === "redirect" /* redirect */;
5105}
5106function isDataWithResponseInit(value) {
5107 return typeof value === "object" && value != null && "type" in value && "data" in value && "init" in value && value.type === "DataWithResponseInit";
5108}
5109function isResponse(value) {
5110 return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
5111}
5112function isRedirectStatusCode(statusCode) {
5113 return redirectStatusCodes.has(statusCode);
5114}
5115function isRedirectResponse(result) {
5116 return isResponse(result) && isRedirectStatusCode(result.status) && result.headers.has("Location");
5117}
5118function isValidMethod(method) {
5119 return validRequestMethods.has(method.toUpperCase());
5120}
5121function isMutationMethod(method) {
5122 return validMutationMethods.has(method.toUpperCase());
5123}
5124function hasNakedIndexQuery(search) {
5125 return new URLSearchParams(search).getAll("index").some((v) => v === "");
5126}
5127function getTargetMatch(matches, location) {
5128 let search = typeof location === "string" ? parsePath(location).search : location.search;
5129 if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || "")) {
5130 return matches[matches.length - 1];
5131 }
5132 let pathMatches = getPathContributingMatches(matches);
5133 return pathMatches[pathMatches.length - 1];
5134}
5135function getSubmissionFromNavigation(navigation) {
5136 let { formMethod, formAction, formEncType, text, formData, json } = navigation;
5137 if (!formMethod || !formAction || !formEncType) {
5138 return;
5139 }
5140 if (text != null) {
5141 return {
5142 formMethod,
5143 formAction,
5144 formEncType,
5145 formData: void 0,
5146 json: void 0,
5147 text
5148 };
5149 } else if (formData != null) {
5150 return {
5151 formMethod,
5152 formAction,
5153 formEncType,
5154 formData,
5155 json: void 0,
5156 text: void 0
5157 };
5158 } else if (json !== void 0) {
5159 return {
5160 formMethod,
5161 formAction,
5162 formEncType,
5163 formData: void 0,
5164 json,
5165 text: void 0
5166 };
5167 }
5168}
5169function getLoadingNavigation(location, submission) {
5170 if (submission) {
5171 let navigation = {
5172 state: "loading",
5173 location,
5174 formMethod: submission.formMethod,
5175 formAction: submission.formAction,
5176 formEncType: submission.formEncType,
5177 formData: submission.formData,
5178 json: submission.json,
5179 text: submission.text
5180 };
5181 return navigation;
5182 } else {
5183 let navigation = {
5184 state: "loading",
5185 location,
5186 formMethod: void 0,
5187 formAction: void 0,
5188 formEncType: void 0,
5189 formData: void 0,
5190 json: void 0,
5191 text: void 0
5192 };
5193 return navigation;
5194 }
5195}
5196function getSubmittingNavigation(location, submission) {
5197 let navigation = {
5198 state: "submitting",
5199 location,
5200 formMethod: submission.formMethod,
5201 formAction: submission.formAction,
5202 formEncType: submission.formEncType,
5203 formData: submission.formData,
5204 json: submission.json,
5205 text: submission.text
5206 };
5207 return navigation;
5208}
5209function getLoadingFetcher(submission, data2) {
5210 if (submission) {
5211 let fetcher = {
5212 state: "loading",
5213 formMethod: submission.formMethod,
5214 formAction: submission.formAction,
5215 formEncType: submission.formEncType,
5216 formData: submission.formData,
5217 json: submission.json,
5218 text: submission.text,
5219 data: data2
5220 };
5221 return fetcher;
5222 } else {
5223 let fetcher = {
5224 state: "loading",
5225 formMethod: void 0,
5226 formAction: void 0,
5227 formEncType: void 0,
5228 formData: void 0,
5229 json: void 0,
5230 text: void 0,
5231 data: data2
5232 };
5233 return fetcher;
5234 }
5235}
5236function getSubmittingFetcher(submission, existingFetcher) {
5237 let fetcher = {
5238 state: "submitting",
5239 formMethod: submission.formMethod,
5240 formAction: submission.formAction,
5241 formEncType: submission.formEncType,
5242 formData: submission.formData,
5243 json: submission.json,
5244 text: submission.text,
5245 data: existingFetcher ? existingFetcher.data : void 0
5246 };
5247 return fetcher;
5248}
5249function getDoneFetcher(data2) {
5250 let fetcher = {
5251 state: "idle",
5252 formMethod: void 0,
5253 formAction: void 0,
5254 formEncType: void 0,
5255 formData: void 0,
5256 json: void 0,
5257 text: void 0,
5258 data: data2
5259 };
5260 return fetcher;
5261}
5262function restoreAppliedTransitions(_window, transitions) {
5263 try {
5264 let sessionPositions = _window.sessionStorage.getItem(
5265 TRANSITIONS_STORAGE_KEY
5266 );
5267 if (sessionPositions) {
5268 let json = JSON.parse(sessionPositions);
5269 for (let [k, v] of Object.entries(json || {})) {
5270 if (v && Array.isArray(v)) {
5271 transitions.set(k, new Set(v || []));
5272 }
5273 }
5274 }
5275 } catch (e) {
5276 }
5277}
5278function persistAppliedTransitions(_window, transitions) {
5279 if (transitions.size > 0) {
5280 let json = {};
5281 for (let [k, v] of transitions) {
5282 json[k] = [...v];
5283 }
5284 try {
5285 _window.sessionStorage.setItem(
5286 TRANSITIONS_STORAGE_KEY,
5287 JSON.stringify(json)
5288 );
5289 } catch (error) {
5290 warning(
5291 false,
5292 `Failed to save applied view transitions in sessionStorage (${error}).`
5293 );
5294 }
5295 }
5296}
5297function createDeferred() {
5298 let resolve;
5299 let reject;
5300 let promise = new Promise((res, rej) => {
5301 resolve = async (val) => {
5302 res(val);
5303 try {
5304 await promise;
5305 } catch (e) {
5306 }
5307 };
5308 reject = async (error) => {
5309 rej(error);
5310 try {
5311 await promise;
5312 } catch (e) {
5313 }
5314 };
5315 });
5316 return {
5317 promise,
5318 //@ts-ignore
5319 resolve,
5320 //@ts-ignore
5321 reject
5322 };
5323}
5324
5325// lib/dom/ssr/single-fetch.tsx
5326var _react = require('react'); var React = _interopRequireWildcard(_react); var React2 = _interopRequireWildcard(_react); var React3 = _interopRequireWildcard(_react); var React8 = _interopRequireWildcard(_react); var React7 = _interopRequireWildcard(_react); var React6 = _interopRequireWildcard(_react); var React5 = _interopRequireWildcard(_react); var React4 = _interopRequireWildcard(_react); var React9 = _interopRequireWildcard(_react);
5327
5328// vendor/turbo-stream-v2/utils.ts
5329var HOLE = -1;
5330var NAN = -2;
5331var NEGATIVE_INFINITY = -3;
5332var NEGATIVE_ZERO = -4;
5333var NULL = -5;
5334var POSITIVE_INFINITY = -6;
5335var UNDEFINED = -7;
5336var TYPE_BIGINT = "B";
5337var TYPE_DATE = "D";
5338var TYPE_ERROR = "E";
5339var TYPE_MAP = "M";
5340var TYPE_NULL_OBJECT = "N";
5341var TYPE_PROMISE = "P";
5342var TYPE_REGEXP = "R";
5343var TYPE_SET = "S";
5344var TYPE_SYMBOL = "Y";
5345var TYPE_URL = "U";
5346var TYPE_PREVIOUS_RESOLVED = "Z";
5347var Deferred = class {
5348 constructor() {
5349 this.promise = new Promise((resolve, reject) => {
5350 this.resolve = resolve;
5351 this.reject = reject;
5352 });
5353 }
5354};
5355function createLineSplittingTransform() {
5356 const decoder = new TextDecoder();
5357 let leftover = "";
5358 return new TransformStream({
5359 transform(chunk, controller) {
5360 const str = decoder.decode(chunk, { stream: true });
5361 const parts = (leftover + str).split("\n");
5362 leftover = parts.pop() || "";
5363 for (const part of parts) {
5364 controller.enqueue(part);
5365 }
5366 },
5367 flush(controller) {
5368 if (leftover) {
5369 controller.enqueue(leftover);
5370 }
5371 }
5372 });
5373}
5374
5375// vendor/turbo-stream-v2/flatten.ts
5376function flatten(input) {
5377 const { indices } = this;
5378 const existing = indices.get(input);
5379 if (existing) return [existing];
5380 if (input === void 0) return UNDEFINED;
5381 if (input === null) return NULL;
5382 if (Number.isNaN(input)) return NAN;
5383 if (input === Number.POSITIVE_INFINITY) return POSITIVE_INFINITY;
5384 if (input === Number.NEGATIVE_INFINITY) return NEGATIVE_INFINITY;
5385 if (input === 0 && 1 / input < 0) return NEGATIVE_ZERO;
5386 const index = this.index++;
5387 indices.set(input, index);
5388 stringify.call(this, input, index);
5389 return index;
5390}
5391function stringify(input, index) {
5392 const { deferred, plugins, postPlugins } = this;
5393 const str = this.stringified;
5394 const stack = [[input, index]];
5395 while (stack.length > 0) {
5396 const [input2, index2] = stack.pop();
5397 const partsForObj = (obj) => Object.keys(obj).map((k) => `"_${flatten.call(this, k)}":${flatten.call(this, obj[k])}`).join(",");
5398 let error = null;
5399 switch (typeof input2) {
5400 case "boolean":
5401 case "number":
5402 case "string":
5403 str[index2] = JSON.stringify(input2);
5404 break;
5405 case "bigint":
5406 str[index2] = `["${TYPE_BIGINT}","${input2}"]`;
5407 break;
5408 case "symbol": {
5409 const keyFor = Symbol.keyFor(input2);
5410 if (!keyFor) {
5411 error = new Error(
5412 "Cannot encode symbol unless created with Symbol.for()"
5413 );
5414 } else {
5415 str[index2] = `["${TYPE_SYMBOL}",${JSON.stringify(keyFor)}]`;
5416 }
5417 break;
5418 }
5419 case "object": {
5420 if (!input2) {
5421 str[index2] = `${NULL}`;
5422 break;
5423 }
5424 const isArray = Array.isArray(input2);
5425 let pluginHandled = false;
5426 if (!isArray && plugins) {
5427 for (const plugin of plugins) {
5428 const pluginResult = plugin(input2);
5429 if (Array.isArray(pluginResult)) {
5430 pluginHandled = true;
5431 const [pluginIdentifier, ...rest] = pluginResult;
5432 str[index2] = `[${JSON.stringify(pluginIdentifier)}`;
5433 if (rest.length > 0) {
5434 str[index2] += `,${rest.map((v) => flatten.call(this, v)).join(",")}`;
5435 }
5436 str[index2] += "]";
5437 break;
5438 }
5439 }
5440 }
5441 if (!pluginHandled) {
5442 let result = isArray ? "[" : "{";
5443 if (isArray) {
5444 for (let i = 0; i < input2.length; i++)
5445 result += (i ? "," : "") + (i in input2 ? flatten.call(this, input2[i]) : HOLE);
5446 str[index2] = `${result}]`;
5447 } else if (input2 instanceof Date) {
5448 const dateTime = input2.getTime();
5449 str[index2] = `["${TYPE_DATE}",${Number.isNaN(dateTime) ? JSON.stringify("invalid") : dateTime}]`;
5450 } else if (input2 instanceof URL) {
5451 str[index2] = `["${TYPE_URL}",${JSON.stringify(input2.href)}]`;
5452 } else if (input2 instanceof RegExp) {
5453 str[index2] = `["${TYPE_REGEXP}",${JSON.stringify(
5454 input2.source
5455 )},${JSON.stringify(input2.flags)}]`;
5456 } else if (input2 instanceof Set) {
5457 if (input2.size > 0) {
5458 str[index2] = `["${TYPE_SET}",${[...input2].map((val) => flatten.call(this, val)).join(",")}]`;
5459 } else {
5460 str[index2] = `["${TYPE_SET}"]`;
5461 }
5462 } else if (input2 instanceof Map) {
5463 if (input2.size > 0) {
5464 str[index2] = `["${TYPE_MAP}",${[...input2].flatMap(([k, v]) => [
5465 flatten.call(this, k),
5466 flatten.call(this, v)
5467 ]).join(",")}]`;
5468 } else {
5469 str[index2] = `["${TYPE_MAP}"]`;
5470 }
5471 } else if (input2 instanceof Promise) {
5472 str[index2] = `["${TYPE_PROMISE}",${index2}]`;
5473 deferred[index2] = input2;
5474 } else if (input2 instanceof Error) {
5475 str[index2] = `["${TYPE_ERROR}",${JSON.stringify(input2.message)}`;
5476 if (input2.name !== "Error") {
5477 str[index2] += `,${JSON.stringify(input2.name)}`;
5478 }
5479 str[index2] += "]";
5480 } else if (Object.getPrototypeOf(input2) === null) {
5481 str[index2] = `["${TYPE_NULL_OBJECT}",{${partsForObj(input2)}}]`;
5482 } else if (isPlainObject2(input2)) {
5483 str[index2] = `{${partsForObj(input2)}}`;
5484 } else {
5485 error = new Error("Cannot encode object with prototype");
5486 }
5487 }
5488 break;
5489 }
5490 default: {
5491 const isArray = Array.isArray(input2);
5492 let pluginHandled = false;
5493 if (!isArray && plugins) {
5494 for (const plugin of plugins) {
5495 const pluginResult = plugin(input2);
5496 if (Array.isArray(pluginResult)) {
5497 pluginHandled = true;
5498 const [pluginIdentifier, ...rest] = pluginResult;
5499 str[index2] = `[${JSON.stringify(pluginIdentifier)}`;
5500 if (rest.length > 0) {
5501 str[index2] += `,${rest.map((v) => flatten.call(this, v)).join(",")}`;
5502 }
5503 str[index2] += "]";
5504 break;
5505 }
5506 }
5507 }
5508 if (!pluginHandled) {
5509 error = new Error("Cannot encode function or unexpected type");
5510 }
5511 }
5512 }
5513 if (error) {
5514 let pluginHandled = false;
5515 if (postPlugins) {
5516 for (const plugin of postPlugins) {
5517 const pluginResult = plugin(input2);
5518 if (Array.isArray(pluginResult)) {
5519 pluginHandled = true;
5520 const [pluginIdentifier, ...rest] = pluginResult;
5521 str[index2] = `[${JSON.stringify(pluginIdentifier)}`;
5522 if (rest.length > 0) {
5523 str[index2] += `,${rest.map((v) => flatten.call(this, v)).join(",")}`;
5524 }
5525 str[index2] += "]";
5526 break;
5527 }
5528 }
5529 }
5530 if (!pluginHandled) {
5531 throw error;
5532 }
5533 }
5534 }
5535}
5536var objectProtoNames2 = Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
5537function isPlainObject2(thing) {
5538 const proto = Object.getPrototypeOf(thing);
5539 return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames2;
5540}
5541
5542// vendor/turbo-stream-v2/unflatten.ts
5543var globalObj = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : void 0;
5544function unflatten(parsed) {
5545 const { hydrated, values } = this;
5546 if (typeof parsed === "number") return hydrate.call(this, parsed);
5547 if (!Array.isArray(parsed) || !parsed.length) throw new SyntaxError();
5548 const startIndex = values.length;
5549 for (const value of parsed) {
5550 values.push(value);
5551 }
5552 hydrated.length = values.length;
5553 return hydrate.call(this, startIndex);
5554}
5555function hydrate(index) {
5556 const { hydrated, values, deferred, plugins } = this;
5557 let result;
5558 const stack = [
5559 [
5560 index,
5561 (v) => {
5562 result = v;
5563 }
5564 ]
5565 ];
5566 let postRun = [];
5567 while (stack.length > 0) {
5568 const [index2, set] = stack.pop();
5569 switch (index2) {
5570 case UNDEFINED:
5571 set(void 0);
5572 continue;
5573 case NULL:
5574 set(null);
5575 continue;
5576 case NAN:
5577 set(NaN);
5578 continue;
5579 case POSITIVE_INFINITY:
5580 set(Infinity);
5581 continue;
5582 case NEGATIVE_INFINITY:
5583 set(-Infinity);
5584 continue;
5585 case NEGATIVE_ZERO:
5586 set(-0);
5587 continue;
5588 }
5589 if (hydrated[index2]) {
5590 set(hydrated[index2]);
5591 continue;
5592 }
5593 const value = values[index2];
5594 if (!value || typeof value !== "object") {
5595 hydrated[index2] = value;
5596 set(value);
5597 continue;
5598 }
5599 if (Array.isArray(value)) {
5600 if (typeof value[0] === "string") {
5601 const [type, b, c] = value;
5602 switch (type) {
5603 case TYPE_DATE:
5604 set(hydrated[index2] = new Date(b));
5605 continue;
5606 case TYPE_URL:
5607 set(hydrated[index2] = new URL(b));
5608 continue;
5609 case TYPE_BIGINT:
5610 set(hydrated[index2] = BigInt(b));
5611 continue;
5612 case TYPE_REGEXP:
5613 set(hydrated[index2] = new RegExp(b, c));
5614 continue;
5615 case TYPE_SYMBOL:
5616 set(hydrated[index2] = Symbol.for(b));
5617 continue;
5618 case TYPE_SET:
5619 const newSet = /* @__PURE__ */ new Set();
5620 hydrated[index2] = newSet;
5621 for (let i = value.length - 1; i > 0; i--)
5622 stack.push([
5623 value[i],
5624 (v) => {
5625 newSet.add(v);
5626 }
5627 ]);
5628 set(newSet);
5629 continue;
5630 case TYPE_MAP:
5631 const map = /* @__PURE__ */ new Map();
5632 hydrated[index2] = map;
5633 for (let i = value.length - 2; i > 0; i -= 2) {
5634 const r = [];
5635 stack.push([
5636 value[i + 1],
5637 (v) => {
5638 r[1] = v;
5639 }
5640 ]);
5641 stack.push([
5642 value[i],
5643 (k) => {
5644 r[0] = k;
5645 }
5646 ]);
5647 postRun.push(() => {
5648 map.set(r[0], r[1]);
5649 });
5650 }
5651 set(map);
5652 continue;
5653 case TYPE_NULL_OBJECT:
5654 const obj = /* @__PURE__ */ Object.create(null);
5655 hydrated[index2] = obj;
5656 for (const key of Object.keys(b).reverse()) {
5657 const r = [];
5658 stack.push([
5659 b[key],
5660 (v) => {
5661 r[1] = v;
5662 }
5663 ]);
5664 stack.push([
5665 Number(key.slice(1)),
5666 (k) => {
5667 r[0] = k;
5668 }
5669 ]);
5670 postRun.push(() => {
5671 obj[r[0]] = r[1];
5672 });
5673 }
5674 set(obj);
5675 continue;
5676 case TYPE_PROMISE:
5677 if (hydrated[b]) {
5678 set(hydrated[index2] = hydrated[b]);
5679 } else {
5680 const d = new Deferred();
5681 deferred[b] = d;
5682 set(hydrated[index2] = d.promise);
5683 }
5684 continue;
5685 case TYPE_ERROR:
5686 const [, message, errorType] = value;
5687 let error = errorType && globalObj && globalObj[errorType] ? new globalObj[errorType](message) : new Error(message);
5688 hydrated[index2] = error;
5689 set(error);
5690 continue;
5691 case TYPE_PREVIOUS_RESOLVED:
5692 set(hydrated[index2] = hydrated[b]);
5693 continue;
5694 default:
5695 if (Array.isArray(plugins)) {
5696 const r = [];
5697 const vals = value.slice(1);
5698 for (let i = 0; i < vals.length; i++) {
5699 const v = vals[i];
5700 stack.push([
5701 v,
5702 (v2) => {
5703 r[i] = v2;
5704 }
5705 ]);
5706 }
5707 postRun.push(() => {
5708 for (const plugin of plugins) {
5709 const result2 = plugin(value[0], ...r);
5710 if (result2) {
5711 set(hydrated[index2] = result2.value);
5712 return;
5713 }
5714 }
5715 throw new SyntaxError();
5716 });
5717 continue;
5718 }
5719 throw new SyntaxError();
5720 }
5721 } else {
5722 const array = [];
5723 hydrated[index2] = array;
5724 for (let i = 0; i < value.length; i++) {
5725 const n = value[i];
5726 if (n !== HOLE) {
5727 stack.push([
5728 n,
5729 (v) => {
5730 array[i] = v;
5731 }
5732 ]);
5733 }
5734 }
5735 set(array);
5736 continue;
5737 }
5738 } else {
5739 const object = {};
5740 hydrated[index2] = object;
5741 for (const key of Object.keys(value).reverse()) {
5742 const r = [];
5743 stack.push([
5744 value[key],
5745 (v) => {
5746 r[1] = v;
5747 }
5748 ]);
5749 stack.push([
5750 Number(key.slice(1)),
5751 (k) => {
5752 r[0] = k;
5753 }
5754 ]);
5755 postRun.push(() => {
5756 object[r[0]] = r[1];
5757 });
5758 }
5759 set(object);
5760 continue;
5761 }
5762 }
5763 while (postRun.length > 0) {
5764 postRun.pop()();
5765 }
5766 return result;
5767}
5768
5769// vendor/turbo-stream-v2/turbo-stream.ts
5770async function decode(readable, options) {
5771 const { plugins } = _nullishCoalesce(options, () => ( {}));
5772 const done = new Deferred();
5773 const reader = readable.pipeThrough(createLineSplittingTransform()).getReader();
5774 const decoder = {
5775 values: [],
5776 hydrated: [],
5777 deferred: {},
5778 plugins
5779 };
5780 const decoded = await decodeInitial.call(decoder, reader);
5781 let donePromise = done.promise;
5782 if (decoded.done) {
5783 done.resolve();
5784 } else {
5785 donePromise = decodeDeferred.call(decoder, reader).then(done.resolve).catch((reason) => {
5786 for (const deferred of Object.values(decoder.deferred)) {
5787 deferred.reject(reason);
5788 }
5789 done.reject(reason);
5790 });
5791 }
5792 return {
5793 done: donePromise.then(() => reader.closed),
5794 value: decoded.value
5795 };
5796}
5797async function decodeInitial(reader) {
5798 const read = await reader.read();
5799 if (!read.value) {
5800 throw new SyntaxError();
5801 }
5802 let line;
5803 try {
5804 line = JSON.parse(read.value);
5805 } catch (reason) {
5806 throw new SyntaxError();
5807 }
5808 return {
5809 done: read.done,
5810 value: unflatten.call(this, line)
5811 };
5812}
5813async function decodeDeferred(reader) {
5814 let read = await reader.read();
5815 while (!read.done) {
5816 if (!read.value) continue;
5817 const line = read.value;
5818 switch (line[0]) {
5819 case TYPE_PROMISE: {
5820 const colonIndex = line.indexOf(":");
5821 const deferredId = Number(line.slice(1, colonIndex));
5822 const deferred = this.deferred[deferredId];
5823 if (!deferred) {
5824 throw new Error(`Deferred ID ${deferredId} not found in stream`);
5825 }
5826 const lineData = line.slice(colonIndex + 1);
5827 let jsonLine;
5828 try {
5829 jsonLine = JSON.parse(lineData);
5830 } catch (reason) {
5831 throw new SyntaxError();
5832 }
5833 const value = unflatten.call(this, jsonLine);
5834 deferred.resolve(value);
5835 break;
5836 }
5837 case TYPE_ERROR: {
5838 const colonIndex = line.indexOf(":");
5839 const deferredId = Number(line.slice(1, colonIndex));
5840 const deferred = this.deferred[deferredId];
5841 if (!deferred) {
5842 throw new Error(`Deferred ID ${deferredId} not found in stream`);
5843 }
5844 const lineData = line.slice(colonIndex + 1);
5845 let jsonLine;
5846 try {
5847 jsonLine = JSON.parse(lineData);
5848 } catch (reason) {
5849 throw new SyntaxError();
5850 }
5851 const value = unflatten.call(this, jsonLine);
5852 deferred.reject(value);
5853 break;
5854 }
5855 default:
5856 throw new SyntaxError();
5857 }
5858 read = await reader.read();
5859 }
5860}
5861function encode(input, options) {
5862 const { plugins, postPlugins, signal } = _nullishCoalesce(options, () => ( {}));
5863 const encoder = {
5864 deferred: {},
5865 index: 0,
5866 indices: /* @__PURE__ */ new Map(),
5867 stringified: [],
5868 plugins,
5869 postPlugins,
5870 signal
5871 };
5872 const textEncoder = new TextEncoder();
5873 let lastSentIndex = 0;
5874 const readable = new ReadableStream({
5875 async start(controller) {
5876 const id = flatten.call(encoder, input);
5877 if (Array.isArray(id)) {
5878 throw new Error("This should never happen");
5879 }
5880 if (id < 0) {
5881 controller.enqueue(textEncoder.encode(`${id}
5882`));
5883 } else {
5884 controller.enqueue(
5885 textEncoder.encode(`[${encoder.stringified.join(",")}]
5886`)
5887 );
5888 lastSentIndex = encoder.stringified.length - 1;
5889 }
5890 const seenPromises = /* @__PURE__ */ new WeakSet();
5891 if (Object.keys(encoder.deferred).length) {
5892 let raceDone;
5893 const racePromise = new Promise((resolve, reject) => {
5894 raceDone = resolve;
5895 if (signal) {
5896 const rejectPromise = () => reject(signal.reason || new Error("Signal was aborted."));
5897 if (signal.aborted) {
5898 rejectPromise();
5899 } else {
5900 signal.addEventListener("abort", (event) => {
5901 rejectPromise();
5902 });
5903 }
5904 }
5905 });
5906 while (Object.keys(encoder.deferred).length > 0) {
5907 for (const [deferredId, deferred] of Object.entries(
5908 encoder.deferred
5909 )) {
5910 if (seenPromises.has(deferred)) continue;
5911 seenPromises.add(
5912 // biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
5913 encoder.deferred[Number(deferredId)] = Promise.race([
5914 racePromise,
5915 deferred
5916 ]).then(
5917 (resolved) => {
5918 const id2 = flatten.call(encoder, resolved);
5919 if (Array.isArray(id2)) {
5920 controller.enqueue(
5921 textEncoder.encode(
5922 `${TYPE_PROMISE}${deferredId}:[["${TYPE_PREVIOUS_RESOLVED}",${id2[0]}]]
5923`
5924 )
5925 );
5926 encoder.index++;
5927 lastSentIndex++;
5928 } else if (id2 < 0) {
5929 controller.enqueue(
5930 textEncoder.encode(
5931 `${TYPE_PROMISE}${deferredId}:${id2}
5932`
5933 )
5934 );
5935 } else {
5936 const values = encoder.stringified.slice(lastSentIndex + 1).join(",");
5937 controller.enqueue(
5938 textEncoder.encode(
5939 `${TYPE_PROMISE}${deferredId}:[${values}]
5940`
5941 )
5942 );
5943 lastSentIndex = encoder.stringified.length - 1;
5944 }
5945 },
5946 (reason) => {
5947 if (!reason || typeof reason !== "object" || !(reason instanceof Error)) {
5948 reason = new Error("An unknown error occurred");
5949 }
5950 const id2 = flatten.call(encoder, reason);
5951 if (Array.isArray(id2)) {
5952 controller.enqueue(
5953 textEncoder.encode(
5954 `${TYPE_ERROR}${deferredId}:[["${TYPE_PREVIOUS_RESOLVED}",${id2[0]}]]
5955`
5956 )
5957 );
5958 encoder.index++;
5959 lastSentIndex++;
5960 } else if (id2 < 0) {
5961 controller.enqueue(
5962 textEncoder.encode(
5963 `${TYPE_ERROR}${deferredId}:${id2}
5964`
5965 )
5966 );
5967 } else {
5968 const values = encoder.stringified.slice(lastSentIndex + 1).join(",");
5969 controller.enqueue(
5970 textEncoder.encode(
5971 `${TYPE_ERROR}${deferredId}:[${values}]
5972`
5973 )
5974 );
5975 lastSentIndex = encoder.stringified.length - 1;
5976 }
5977 }
5978 ).finally(() => {
5979 delete encoder.deferred[Number(deferredId)];
5980 })
5981 );
5982 }
5983 await Promise.race(Object.values(encoder.deferred));
5984 }
5985 raceDone();
5986 }
5987 await Promise.all(Object.values(encoder.deferred));
5988 controller.close();
5989 }
5990 });
5991 return readable;
5992}
5993
5994// lib/dom/ssr/data.ts
5995async function createRequestInit(request) {
5996 let init = { signal: request.signal };
5997 if (request.method !== "GET") {
5998 init.method = request.method;
5999 let contentType = request.headers.get("Content-Type");
6000 if (contentType && /\bapplication\/json\b/.test(contentType)) {
6001 init.headers = { "Content-Type": contentType };
6002 init.body = JSON.stringify(await request.json());
6003 } else if (contentType && /\btext\/plain\b/.test(contentType)) {
6004 init.headers = { "Content-Type": contentType };
6005 init.body = await request.text();
6006 } else if (contentType && /\bapplication\/x-www-form-urlencoded\b/.test(contentType)) {
6007 init.body = new URLSearchParams(await request.text());
6008 } else {
6009 init.body = await request.formData();
6010 }
6011 }
6012 return init;
6013}
6014
6015// lib/dom/ssr/markup.ts
6016var ESCAPE_LOOKUP = {
6017 "&": "\\u0026",
6018 ">": "\\u003e",
6019 "<": "\\u003c",
6020 "\u2028": "\\u2028",
6021 "\u2029": "\\u2029"
6022};
6023var ESCAPE_REGEX = /[&><\u2028\u2029]/g;
6024function escapeHtml(html) {
6025 return html.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
6026}
6027
6028// lib/dom/ssr/invariant.ts
6029function invariant2(value, message) {
6030 if (value === false || value === null || typeof value === "undefined") {
6031 throw new Error(message);
6032 }
6033}
6034
6035// lib/dom/ssr/single-fetch.tsx
6036var SingleFetchRedirectSymbol = Symbol("SingleFetchRedirect");
6037var SingleFetchNoResultError = class extends Error {
6038};
6039var SINGLE_FETCH_REDIRECT_STATUS = 202;
6040var NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([100, 101, 204, 205]);
6041function StreamTransfer({
6042 context,
6043 identifier,
6044 reader,
6045 textDecoder,
6046 nonce
6047}) {
6048 if (!context.renderMeta || !context.renderMeta.didRenderScripts) {
6049 return null;
6050 }
6051 if (!context.renderMeta.streamCache) {
6052 context.renderMeta.streamCache = {};
6053 }
6054 let { streamCache } = context.renderMeta;
6055 let promise = streamCache[identifier];
6056 if (!promise) {
6057 promise = streamCache[identifier] = reader.read().then((result) => {
6058 streamCache[identifier].result = {
6059 done: result.done,
6060 value: textDecoder.decode(result.value, { stream: true })
6061 };
6062 }).catch((e) => {
6063 streamCache[identifier].error = e;
6064 });
6065 }
6066 if (promise.error) {
6067 throw promise.error;
6068 }
6069 if (promise.result === void 0) {
6070 throw promise;
6071 }
6072 let { done, value } = promise.result;
6073 let scriptTag = value ? /* @__PURE__ */ React.createElement(
6074 "script",
6075 {
6076 nonce,
6077 dangerouslySetInnerHTML: {
6078 __html: `window.__reactRouterContext.streamController.enqueue(${escapeHtml(
6079 JSON.stringify(value)
6080 )});`
6081 }
6082 }
6083 ) : null;
6084 if (done) {
6085 return /* @__PURE__ */ React.createElement(React.Fragment, null, scriptTag, /* @__PURE__ */ React.createElement(
6086 "script",
6087 {
6088 nonce,
6089 dangerouslySetInnerHTML: {
6090 __html: `window.__reactRouterContext.streamController.close();`
6091 }
6092 }
6093 ));
6094 } else {
6095 return /* @__PURE__ */ React.createElement(React.Fragment, null, scriptTag, /* @__PURE__ */ React.createElement(React.Suspense, null, /* @__PURE__ */ React.createElement(
6096 StreamTransfer,
6097 {
6098 context,
6099 identifier: identifier + 1,
6100 reader,
6101 textDecoder,
6102 nonce
6103 }
6104 )));
6105 }
6106}
6107function getTurboStreamSingleFetchDataStrategy(getRouter, manifest, routeModules, ssr, basename) {
6108 let dataStrategy = getSingleFetchDataStrategyImpl(
6109 getRouter,
6110 (match) => {
6111 let manifestRoute = manifest.routes[match.route.id];
6112 invariant2(manifestRoute, "Route not found in manifest");
6113 let routeModule = routeModules[match.route.id];
6114 return {
6115 hasLoader: manifestRoute.hasLoader,
6116 hasClientLoader: manifestRoute.hasClientLoader,
6117 hasShouldRevalidate: Boolean(_optionalChain([routeModule, 'optionalAccess', _73 => _73.shouldRevalidate]))
6118 };
6119 },
6120 fetchAndDecodeViaTurboStream,
6121 ssr,
6122 basename
6123 );
6124 return async (args) => args.runClientMiddleware(dataStrategy);
6125}
6126function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode, ssr, basename, shouldAllowOptOut = () => true) {
6127 return async (args) => {
6128 let { request, matches, fetcherKey } = args;
6129 let router = getRouter();
6130 if (request.method !== "GET") {
6131 return singleFetchActionStrategy(args, fetchAndDecode, basename);
6132 }
6133 let foundRevalidatingServerLoader = matches.some((m) => {
6134 let { hasLoader, hasClientLoader } = getRouteInfo(m);
6135 return m.shouldCallHandler() && hasLoader && !hasClientLoader;
6136 });
6137 if (!ssr && !foundRevalidatingServerLoader) {
6138 return nonSsrStrategy(args, getRouteInfo, fetchAndDecode, basename);
6139 }
6140 if (fetcherKey) {
6141 return singleFetchLoaderFetcherStrategy(args, fetchAndDecode, basename);
6142 }
6143 return singleFetchLoaderNavigationStrategy(
6144 args,
6145 router,
6146 getRouteInfo,
6147 fetchAndDecode,
6148 ssr,
6149 basename,
6150 shouldAllowOptOut
6151 );
6152 };
6153}
6154async function singleFetchActionStrategy(args, fetchAndDecode, basename) {
6155 let actionMatch = args.matches.find((m) => m.shouldCallHandler());
6156 invariant2(actionMatch, "No action match found");
6157 let actionStatus = void 0;
6158 let result = await actionMatch.resolve(async (handler) => {
6159 let result2 = await handler(async () => {
6160 let { data: data2, status } = await fetchAndDecode(args, basename, [
6161 actionMatch.route.id
6162 ]);
6163 actionStatus = status;
6164 return unwrapSingleFetchResult(data2, actionMatch.route.id);
6165 });
6166 return result2;
6167 });
6168 if (isResponse(result.result) || isRouteErrorResponse(result.result) || isDataWithResponseInit(result.result)) {
6169 return { [actionMatch.route.id]: result };
6170 }
6171 return {
6172 [actionMatch.route.id]: {
6173 type: result.type,
6174 result: data(result.result, actionStatus)
6175 }
6176 };
6177}
6178async function nonSsrStrategy(args, getRouteInfo, fetchAndDecode, basename) {
6179 let matchesToLoad = args.matches.filter((m) => m.shouldCallHandler());
6180 let results = {};
6181 await Promise.all(
6182 matchesToLoad.map(
6183 (m) => m.resolve(async (handler) => {
6184 try {
6185 let { hasClientLoader } = getRouteInfo(m);
6186 let routeId = m.route.id;
6187 let result = hasClientLoader ? await handler(async () => {
6188 let { data: data2 } = await fetchAndDecode(args, basename, [routeId]);
6189 return unwrapSingleFetchResult(data2, routeId);
6190 }) : await handler();
6191 results[m.route.id] = { type: "data", result };
6192 } catch (e) {
6193 results[m.route.id] = { type: "error", result: e };
6194 }
6195 })
6196 )
6197 );
6198 return results;
6199}
6200async function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, basename, shouldAllowOptOut = () => true) {
6201 let routesParams = /* @__PURE__ */ new Set();
6202 let foundOptOutRoute = false;
6203 let routeDfds = args.matches.map(() => createDeferred2());
6204 let singleFetchDfd = createDeferred2();
6205 let results = {};
6206 let resolvePromise = Promise.all(
6207 args.matches.map(
6208 async (m, i) => m.resolve(async (handler) => {
6209 routeDfds[i].resolve();
6210 let routeId = m.route.id;
6211 let { hasLoader, hasClientLoader, hasShouldRevalidate } = getRouteInfo(m);
6212 let defaultShouldRevalidate = !m.shouldRevalidateArgs || m.shouldRevalidateArgs.actionStatus == null || m.shouldRevalidateArgs.actionStatus < 400;
6213 let shouldCall = m.shouldCallHandler(defaultShouldRevalidate);
6214 if (!shouldCall) {
6215 foundOptOutRoute || (foundOptOutRoute = m.shouldRevalidateArgs != null && // This is a revalidation,
6216 hasLoader && // for a route with a server loader,
6217 hasShouldRevalidate === true);
6218 return;
6219 }
6220 if (shouldAllowOptOut(m) && hasClientLoader) {
6221 if (hasLoader) {
6222 foundOptOutRoute = true;
6223 }
6224 try {
6225 let result = await handler(async () => {
6226 let { data: data2 } = await fetchAndDecode(args, basename, [routeId]);
6227 return unwrapSingleFetchResult(data2, routeId);
6228 });
6229 results[routeId] = { type: "data", result };
6230 } catch (e) {
6231 results[routeId] = { type: "error", result: e };
6232 }
6233 return;
6234 }
6235 if (hasLoader) {
6236 routesParams.add(routeId);
6237 }
6238 try {
6239 let result = await handler(async () => {
6240 let data2 = await singleFetchDfd.promise;
6241 return unwrapSingleFetchResult(data2, routeId);
6242 });
6243 results[routeId] = { type: "data", result };
6244 } catch (e) {
6245 results[routeId] = { type: "error", result: e };
6246 }
6247 })
6248 )
6249 );
6250 await Promise.all(routeDfds.map((d) => d.promise));
6251 let isInitialLoad = !router.state.initialized && router.state.navigation.state === "idle";
6252 if ((isInitialLoad || routesParams.size === 0) && !window.__reactRouterHdrActive) {
6253 singleFetchDfd.resolve({ routes: {} });
6254 } else {
6255 let targetRoutes = ssr && foundOptOutRoute && routesParams.size > 0 ? [...routesParams.keys()] : void 0;
6256 try {
6257 let data2 = await fetchAndDecode(args, basename, targetRoutes);
6258 singleFetchDfd.resolve(data2.data);
6259 } catch (e) {
6260 singleFetchDfd.reject(e);
6261 }
6262 }
6263 await resolvePromise;
6264 await bubbleMiddlewareErrors(
6265 singleFetchDfd.promise,
6266 args.matches,
6267 routesParams,
6268 results
6269 );
6270 return results;
6271}
6272async function bubbleMiddlewareErrors(singleFetchPromise, matches, routesParams, results) {
6273 try {
6274 let middlewareError;
6275 let fetchedData = await singleFetchPromise;
6276 if ("routes" in fetchedData) {
6277 for (let match of matches) {
6278 if (match.route.id in fetchedData.routes) {
6279 let routeResult = fetchedData.routes[match.route.id];
6280 if ("error" in routeResult) {
6281 middlewareError = routeResult.error;
6282 if (_optionalChain([results, 'access', _74 => _74[match.route.id], 'optionalAccess', _75 => _75.result]) == null) {
6283 results[match.route.id] = {
6284 type: "error",
6285 result: middlewareError
6286 };
6287 }
6288 break;
6289 }
6290 }
6291 }
6292 }
6293 if (middlewareError !== void 0) {
6294 Array.from(routesParams.values()).forEach((routeId) => {
6295 if (results[routeId].result instanceof SingleFetchNoResultError) {
6296 results[routeId].result = middlewareError;
6297 }
6298 });
6299 }
6300 } catch (e) {
6301 }
6302}
6303async function singleFetchLoaderFetcherStrategy(args, fetchAndDecode, basename) {
6304 let fetcherMatch = args.matches.find((m) => m.shouldCallHandler());
6305 invariant2(fetcherMatch, "No fetcher match found");
6306 let routeId = fetcherMatch.route.id;
6307 let result = await fetcherMatch.resolve(
6308 async (handler) => handler(async () => {
6309 let { data: data2 } = await fetchAndDecode(args, basename, [routeId]);
6310 return unwrapSingleFetchResult(data2, routeId);
6311 })
6312 );
6313 return { [fetcherMatch.route.id]: result };
6314}
6315function stripIndexParam(url) {
6316 let indexValues = url.searchParams.getAll("index");
6317 url.searchParams.delete("index");
6318 let indexValuesToKeep = [];
6319 for (let indexValue of indexValues) {
6320 if (indexValue) {
6321 indexValuesToKeep.push(indexValue);
6322 }
6323 }
6324 for (let toKeep of indexValuesToKeep) {
6325 url.searchParams.append("index", toKeep);
6326 }
6327 return url;
6328}
6329function singleFetchUrl(reqUrl, basename, extension) {
6330 let url = typeof reqUrl === "string" ? new URL(
6331 reqUrl,
6332 // This can be called during the SSR flow via PrefetchPageLinksImpl so
6333 // don't assume window is available
6334 typeof window === "undefined" ? "server://singlefetch/" : window.location.origin
6335 ) : reqUrl;
6336 if (url.pathname === "/") {
6337 url.pathname = `_root.${extension}`;
6338 } else if (basename && stripBasename(url.pathname, basename) === "/") {
6339 url.pathname = `${basename.replace(/\/$/, "")}/_root.${extension}`;
6340 } else {
6341 url.pathname = `${url.pathname.replace(/\/$/, "")}.${extension}`;
6342 }
6343 return url;
6344}
6345async function fetchAndDecodeViaTurboStream(args, basename, targetRoutes) {
6346 let { request } = args;
6347 let url = singleFetchUrl(request.url, basename, "data");
6348 if (request.method === "GET") {
6349 url = stripIndexParam(url);
6350 if (targetRoutes) {
6351 url.searchParams.set("_routes", targetRoutes.join(","));
6352 }
6353 }
6354 let res = await fetch(url, await createRequestInit(request));
6355 if (res.status >= 400 && !res.headers.has("X-Remix-Response")) {
6356 throw new ErrorResponseImpl(res.status, res.statusText, await res.text());
6357 }
6358 if (res.status === 204 && res.headers.has("X-Remix-Redirect")) {
6359 return {
6360 status: SINGLE_FETCH_REDIRECT_STATUS,
6361 data: {
6362 redirect: {
6363 redirect: res.headers.get("X-Remix-Redirect"),
6364 status: Number(res.headers.get("X-Remix-Status") || "302"),
6365 revalidate: res.headers.get("X-Remix-Revalidate") === "true",
6366 reload: res.headers.get("X-Remix-Reload-Document") === "true",
6367 replace: res.headers.get("X-Remix-Replace") === "true"
6368 }
6369 }
6370 };
6371 }
6372 if (NO_BODY_STATUS_CODES.has(res.status)) {
6373 let routes = {};
6374 if (targetRoutes && request.method !== "GET") {
6375 routes[targetRoutes[0]] = { data: void 0 };
6376 }
6377 return {
6378 status: res.status,
6379 data: { routes }
6380 };
6381 }
6382 invariant2(res.body, "No response body to decode");
6383 try {
6384 let decoded = await decodeViaTurboStream(res.body, window);
6385 let data2;
6386 if (request.method === "GET") {
6387 let typed = decoded.value;
6388 if (SingleFetchRedirectSymbol in typed) {
6389 data2 = { redirect: typed[SingleFetchRedirectSymbol] };
6390 } else {
6391 data2 = { routes: typed };
6392 }
6393 } else {
6394 let typed = decoded.value;
6395 let routeId = _optionalChain([targetRoutes, 'optionalAccess', _76 => _76[0]]);
6396 invariant2(routeId, "No routeId found for single fetch call decoding");
6397 if ("redirect" in typed) {
6398 data2 = { redirect: typed };
6399 } else {
6400 data2 = { routes: { [routeId]: typed } };
6401 }
6402 }
6403 return { status: res.status, data: data2 };
6404 } catch (e) {
6405 throw new Error("Unable to decode turbo-stream response");
6406 }
6407}
6408function decodeViaTurboStream(body, global) {
6409 return decode(body, {
6410 plugins: [
6411 (type, ...rest) => {
6412 if (type === "SanitizedError") {
6413 let [name, message, stack] = rest;
6414 let Constructor = Error;
6415 if (name && name in global && typeof global[name] === "function") {
6416 Constructor = global[name];
6417 }
6418 let error = new Constructor(message);
6419 error.stack = stack;
6420 return { value: error };
6421 }
6422 if (type === "ErrorResponse") {
6423 let [data2, status, statusText] = rest;
6424 return {
6425 value: new ErrorResponseImpl(status, statusText, data2)
6426 };
6427 }
6428 if (type === "SingleFetchRedirect") {
6429 return { value: { [SingleFetchRedirectSymbol]: rest[0] } };
6430 }
6431 if (type === "SingleFetchClassInstance") {
6432 return { value: rest[0] };
6433 }
6434 if (type === "SingleFetchFallback") {
6435 return { value: void 0 };
6436 }
6437 }
6438 ]
6439 });
6440}
6441function unwrapSingleFetchResult(result, routeId) {
6442 if ("redirect" in result) {
6443 let {
6444 redirect: location,
6445 revalidate,
6446 reload,
6447 replace: replace2,
6448 status
6449 } = result.redirect;
6450 throw redirect(location, {
6451 status,
6452 headers: {
6453 // Three R's of redirecting (lol Veep)
6454 ...revalidate ? { "X-Remix-Revalidate": "yes" } : null,
6455 ...reload ? { "X-Remix-Reload-Document": "yes" } : null,
6456 ...replace2 ? { "X-Remix-Replace": "yes" } : null
6457 }
6458 });
6459 }
6460 let routeResult = result.routes[routeId];
6461 if (routeResult == null) {
6462 throw new SingleFetchNoResultError(
6463 `No result found for routeId "${routeId}"`
6464 );
6465 } else if ("error" in routeResult) {
6466 throw routeResult.error;
6467 } else if ("data" in routeResult) {
6468 return routeResult.data;
6469 } else {
6470 throw new Error(`Invalid response found for routeId "${routeId}"`);
6471 }
6472}
6473function createDeferred2() {
6474 let resolve;
6475 let reject;
6476 let promise = new Promise((res, rej) => {
6477 resolve = async (val) => {
6478 res(val);
6479 try {
6480 await promise;
6481 } catch (e) {
6482 }
6483 };
6484 reject = async (error) => {
6485 rej(error);
6486 try {
6487 await promise;
6488 } catch (e) {
6489 }
6490 };
6491 });
6492 return {
6493 promise,
6494 //@ts-ignore
6495 resolve,
6496 //@ts-ignore
6497 reject
6498 };
6499}
6500
6501// lib/context.ts
6502
6503var DataRouterContext = React2.createContext(null);
6504DataRouterContext.displayName = "DataRouter";
6505var DataRouterStateContext = React2.createContext(null);
6506DataRouterStateContext.displayName = "DataRouterState";
6507var RSCRouterContext = React2.createContext(false);
6508function useIsRSCRouterContext() {
6509 return React2.useContext(RSCRouterContext);
6510}
6511var ViewTransitionContext = React2.createContext({
6512 isTransitioning: false
6513});
6514ViewTransitionContext.displayName = "ViewTransition";
6515var FetchersContext = React2.createContext(
6516 /* @__PURE__ */ new Map()
6517);
6518FetchersContext.displayName = "Fetchers";
6519var AwaitContext = React2.createContext(null);
6520AwaitContext.displayName = "Await";
6521var AwaitContextProvider = (props) => React2.createElement(AwaitContext.Provider, props);
6522var NavigationContext = React2.createContext(
6523 null
6524);
6525NavigationContext.displayName = "Navigation";
6526var LocationContext = React2.createContext(
6527 null
6528);
6529LocationContext.displayName = "Location";
6530var RouteContext = React2.createContext({
6531 outlet: null,
6532 matches: [],
6533 isDataRoute: false
6534});
6535RouteContext.displayName = "Route";
6536var RouteErrorContext = React2.createContext(null);
6537RouteErrorContext.displayName = "RouteError";
6538var ENABLE_DEV_WARNINGS = true;
6539
6540// lib/hooks.tsx
6541
6542function useHref(to, { relative } = {}) {
6543 invariant(
6544 useInRouterContext(),
6545 // TODO: This error is probably because they somehow have 2 versions of the
6546 // router loaded. We can help them understand how to avoid that.
6547 `useHref() may be used only in the context of a <Router> component.`
6548 );
6549 let { basename, navigator } = React3.useContext(NavigationContext);
6550 let { hash, pathname, search } = useResolvedPath(to, { relative });
6551 let joinedPathname = pathname;
6552 if (basename !== "/") {
6553 joinedPathname = pathname === "/" ? basename : joinPaths([basename, pathname]);
6554 }
6555 return navigator.createHref({ pathname: joinedPathname, search, hash });
6556}
6557function useInRouterContext() {
6558 return React3.useContext(LocationContext) != null;
6559}
6560function useLocation() {
6561 invariant(
6562 useInRouterContext(),
6563 // TODO: This error is probably because they somehow have 2 versions of the
6564 // router loaded. We can help them understand how to avoid that.
6565 `useLocation() may be used only in the context of a <Router> component.`
6566 );
6567 return React3.useContext(LocationContext).location;
6568}
6569function useNavigationType() {
6570 return React3.useContext(LocationContext).navigationType;
6571}
6572function useMatch(pattern) {
6573 invariant(
6574 useInRouterContext(),
6575 // TODO: This error is probably because they somehow have 2 versions of the
6576 // router loaded. We can help them understand how to avoid that.
6577 `useMatch() may be used only in the context of a <Router> component.`
6578 );
6579 let { pathname } = useLocation();
6580 return React3.useMemo(
6581 () => matchPath(pattern, decodePath(pathname)),
6582 [pathname, pattern]
6583 );
6584}
6585var navigateEffectWarning = `You should call navigate() in a React.useEffect(), not when your component is first rendered.`;
6586function useIsomorphicLayoutEffect(cb) {
6587 let isStatic = React3.useContext(NavigationContext).static;
6588 if (!isStatic) {
6589 React3.useLayoutEffect(cb);
6590 }
6591}
6592function useNavigate() {
6593 let { isDataRoute } = React3.useContext(RouteContext);
6594 return isDataRoute ? useNavigateStable() : useNavigateUnstable();
6595}
6596function useNavigateUnstable() {
6597 invariant(
6598 useInRouterContext(),
6599 // TODO: This error is probably because they somehow have 2 versions of the
6600 // router loaded. We can help them understand how to avoid that.
6601 `useNavigate() may be used only in the context of a <Router> component.`
6602 );
6603 let dataRouterContext = React3.useContext(DataRouterContext);
6604 let { basename, navigator } = React3.useContext(NavigationContext);
6605 let { matches } = React3.useContext(RouteContext);
6606 let { pathname: locationPathname } = useLocation();
6607 let routePathnamesJson = JSON.stringify(getResolveToMatches(matches));
6608 let activeRef = React3.useRef(false);
6609 useIsomorphicLayoutEffect(() => {
6610 activeRef.current = true;
6611 });
6612 let navigate = React3.useCallback(
6613 (to, options = {}) => {
6614 warning(activeRef.current, navigateEffectWarning);
6615 if (!activeRef.current) return;
6616 if (typeof to === "number") {
6617 navigator.go(to);
6618 return;
6619 }
6620 let path = resolveTo(
6621 to,
6622 JSON.parse(routePathnamesJson),
6623 locationPathname,
6624 options.relative === "path"
6625 );
6626 if (dataRouterContext == null && basename !== "/") {
6627 path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
6628 }
6629 (!!options.replace ? navigator.replace : navigator.push)(
6630 path,
6631 options.state,
6632 options
6633 );
6634 },
6635 [
6636 basename,
6637 navigator,
6638 routePathnamesJson,
6639 locationPathname,
6640 dataRouterContext
6641 ]
6642 );
6643 return navigate;
6644}
6645var OutletContext = React3.createContext(null);
6646function useOutletContext() {
6647 return React3.useContext(OutletContext);
6648}
6649function useOutlet(context) {
6650 let outlet = React3.useContext(RouteContext).outlet;
6651 return React3.useMemo(
6652 () => outlet && /* @__PURE__ */ React3.createElement(OutletContext.Provider, { value: context }, outlet),
6653 [outlet, context]
6654 );
6655}
6656function useParams() {
6657 let { matches } = React3.useContext(RouteContext);
6658 let routeMatch = matches[matches.length - 1];
6659 return routeMatch ? routeMatch.params : {};
6660}
6661function useResolvedPath(to, { relative } = {}) {
6662 let { matches } = React3.useContext(RouteContext);
6663 let { pathname: locationPathname } = useLocation();
6664 let routePathnamesJson = JSON.stringify(getResolveToMatches(matches));
6665 return React3.useMemo(
6666 () => resolveTo(
6667 to,
6668 JSON.parse(routePathnamesJson),
6669 locationPathname,
6670 relative === "path"
6671 ),
6672 [to, routePathnamesJson, locationPathname, relative]
6673 );
6674}
6675function useRoutes(routes, locationArg) {
6676 return useRoutesImpl(routes, locationArg);
6677}
6678function useRoutesImpl(routes, locationArg, dataRouterState, unstable_onError, future) {
6679 invariant(
6680 useInRouterContext(),
6681 // TODO: This error is probably because they somehow have 2 versions of the
6682 // router loaded. We can help them understand how to avoid that.
6683 `useRoutes() may be used only in the context of a <Router> component.`
6684 );
6685 let { navigator } = React3.useContext(NavigationContext);
6686 let { matches: parentMatches } = React3.useContext(RouteContext);
6687 let routeMatch = parentMatches[parentMatches.length - 1];
6688 let parentParams = routeMatch ? routeMatch.params : {};
6689 let parentPathname = routeMatch ? routeMatch.pathname : "/";
6690 let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/";
6691 let parentRoute = routeMatch && routeMatch.route;
6692 if (ENABLE_DEV_WARNINGS) {
6693 let parentPath = parentRoute && parentRoute.path || "";
6694 warningOnce(
6695 parentPathname,
6696 !parentRoute || parentPath.endsWith("*") || parentPath.endsWith("*?"),
6697 `You rendered descendant <Routes> (or called \`useRoutes()\`) at "${parentPathname}" (under <Route path="${parentPath}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
6698
6699Please change the parent <Route path="${parentPath}"> to <Route path="${parentPath === "/" ? "*" : `${parentPath}/*`}">.`
6700 );
6701 }
6702 let locationFromContext = useLocation();
6703 let location;
6704 if (locationArg) {
6705 let parsedLocationArg = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
6706 invariant(
6707 parentPathnameBase === "/" || _optionalChain([parsedLocationArg, 'access', _77 => _77.pathname, 'optionalAccess', _78 => _78.startsWith, 'call', _79 => _79(parentPathnameBase)]),
6708 `When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${parentPathnameBase}" but pathname "${parsedLocationArg.pathname}" was given in the \`location\` prop.`
6709 );
6710 location = parsedLocationArg;
6711 } else {
6712 location = locationFromContext;
6713 }
6714 let pathname = location.pathname || "/";
6715 let remainingPathname = pathname;
6716 if (parentPathnameBase !== "/") {
6717 let parentSegments = parentPathnameBase.replace(/^\//, "").split("/");
6718 let segments = pathname.replace(/^\//, "").split("/");
6719 remainingPathname = "/" + segments.slice(parentSegments.length).join("/");
6720 }
6721 let matches = matchRoutes(routes, { pathname: remainingPathname });
6722 if (ENABLE_DEV_WARNINGS) {
6723 warning(
6724 parentRoute || matches != null,
6725 `No routes matched location "${location.pathname}${location.search}${location.hash}" `
6726 );
6727 warning(
6728 matches == null || matches[matches.length - 1].route.element !== void 0 || matches[matches.length - 1].route.Component !== void 0 || matches[matches.length - 1].route.lazy !== void 0,
6729 `Matched leaf route at location "${location.pathname}${location.search}${location.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`
6730 );
6731 }
6732 let renderedMatches = _renderMatches(
6733 matches && matches.map(
6734 (match) => Object.assign({}, match, {
6735 params: Object.assign({}, parentParams, match.params),
6736 pathname: joinPaths([
6737 parentPathnameBase,
6738 // Re-encode pathnames that were decoded inside matchRoutes.
6739 // Pre-encode `?` and `#` ahead of `encodeLocation` because it uses
6740 // `new URL()` internally and we need to prevent it from treating
6741 // them as separators
6742 navigator.encodeLocation ? navigator.encodeLocation(
6743 match.pathname.replace(/\?/g, "%3F").replace(/#/g, "%23")
6744 ).pathname : match.pathname
6745 ]),
6746 pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([
6747 parentPathnameBase,
6748 // Re-encode pathnames that were decoded inside matchRoutes
6749 // Pre-encode `?` and `#` ahead of `encodeLocation` because it uses
6750 // `new URL()` internally and we need to prevent it from treating
6751 // them as separators
6752 navigator.encodeLocation ? navigator.encodeLocation(
6753 match.pathnameBase.replace(/\?/g, "%3F").replace(/#/g, "%23")
6754 ).pathname : match.pathnameBase
6755 ])
6756 })
6757 ),
6758 parentMatches,
6759 dataRouterState,
6760 unstable_onError,
6761 future
6762 );
6763 if (locationArg && renderedMatches) {
6764 return /* @__PURE__ */ React3.createElement(
6765 LocationContext.Provider,
6766 {
6767 value: {
6768 location: {
6769 pathname: "/",
6770 search: "",
6771 hash: "",
6772 state: null,
6773 key: "default",
6774 ...location
6775 },
6776 navigationType: "POP" /* Pop */
6777 }
6778 },
6779 renderedMatches
6780 );
6781 }
6782 return renderedMatches;
6783}
6784function DefaultErrorComponent() {
6785 let error = useRouteError();
6786 let message = isRouteErrorResponse(error) ? `${error.status} ${error.statusText}` : error instanceof Error ? error.message : JSON.stringify(error);
6787 let stack = error instanceof Error ? error.stack : null;
6788 let lightgrey = "rgba(200,200,200, 0.5)";
6789 let preStyles = { padding: "0.5rem", backgroundColor: lightgrey };
6790 let codeStyles = { padding: "2px 4px", backgroundColor: lightgrey };
6791 let devInfo = null;
6792 if (ENABLE_DEV_WARNINGS) {
6793 console.error(
6794 "Error handled by React Router default ErrorBoundary:",
6795 error
6796 );
6797 devInfo = /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("p", null, "\u{1F4BF} Hey developer \u{1F44B}"), /* @__PURE__ */ React3.createElement("p", null, "You can provide a way better UX than this when your app throws errors by providing your own ", /* @__PURE__ */ React3.createElement("code", { style: codeStyles }, "ErrorBoundary"), " or", " ", /* @__PURE__ */ React3.createElement("code", { style: codeStyles }, "errorElement"), " prop on your route."));
6798 }
6799 return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("h2", null, "Unexpected Application Error!"), /* @__PURE__ */ React3.createElement("h3", { style: { fontStyle: "italic" } }, message), stack ? /* @__PURE__ */ React3.createElement("pre", { style: preStyles }, stack) : null, devInfo);
6800}
6801var defaultErrorElement = /* @__PURE__ */ React3.createElement(DefaultErrorComponent, null);
6802var RenderErrorBoundary = class extends React3.Component {
6803 constructor(props) {
6804 super(props);
6805 this.state = {
6806 location: props.location,
6807 revalidation: props.revalidation,
6808 error: props.error
6809 };
6810 }
6811 static getDerivedStateFromError(error) {
6812 return { error };
6813 }
6814 static getDerivedStateFromProps(props, state) {
6815 if (state.location !== props.location || state.revalidation !== "idle" && props.revalidation === "idle") {
6816 return {
6817 error: props.error,
6818 location: props.location,
6819 revalidation: props.revalidation
6820 };
6821 }
6822 return {
6823 error: props.error !== void 0 ? props.error : state.error,
6824 location: state.location,
6825 revalidation: props.revalidation || state.revalidation
6826 };
6827 }
6828 componentDidCatch(error, errorInfo) {
6829 if (this.props.onError) {
6830 this.props.onError(error, errorInfo);
6831 } else {
6832 console.error(
6833 "React Router caught the following error during render",
6834 error
6835 );
6836 }
6837 }
6838 render() {
6839 return this.state.error !== void 0 ? /* @__PURE__ */ React3.createElement(RouteContext.Provider, { value: this.props.routeContext }, /* @__PURE__ */ React3.createElement(
6840 RouteErrorContext.Provider,
6841 {
6842 value: this.state.error,
6843 children: this.props.component
6844 }
6845 )) : this.props.children;
6846 }
6847};
6848function RenderedRoute({ routeContext, match, children }) {
6849 let dataRouterContext = React3.useContext(DataRouterContext);
6850 if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) {
6851 dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id;
6852 }
6853 return /* @__PURE__ */ React3.createElement(RouteContext.Provider, { value: routeContext }, children);
6854}
6855function _renderMatches(matches, parentMatches = [], dataRouterState = null, unstable_onError = null, future = null) {
6856 if (matches == null) {
6857 if (!dataRouterState) {
6858 return null;
6859 }
6860 if (dataRouterState.errors) {
6861 matches = dataRouterState.matches;
6862 } else if (parentMatches.length === 0 && !dataRouterState.initialized && dataRouterState.matches.length > 0) {
6863 matches = dataRouterState.matches;
6864 } else {
6865 return null;
6866 }
6867 }
6868 let renderedMatches = matches;
6869 let errors = _optionalChain([dataRouterState, 'optionalAccess', _80 => _80.errors]);
6870 if (errors != null) {
6871 let errorIndex = renderedMatches.findIndex(
6872 (m) => m.route.id && _optionalChain([errors, 'optionalAccess', _81 => _81[m.route.id]]) !== void 0
6873 );
6874 invariant(
6875 errorIndex >= 0,
6876 `Could not find a matching route for errors on route IDs: ${Object.keys(
6877 errors
6878 ).join(",")}`
6879 );
6880 renderedMatches = renderedMatches.slice(
6881 0,
6882 Math.min(renderedMatches.length, errorIndex + 1)
6883 );
6884 }
6885 let renderFallback = false;
6886 let fallbackIndex = -1;
6887 if (dataRouterState) {
6888 for (let i = 0; i < renderedMatches.length; i++) {
6889 let match = renderedMatches[i];
6890 if (match.route.HydrateFallback || match.route.hydrateFallbackElement) {
6891 fallbackIndex = i;
6892 }
6893 if (match.route.id) {
6894 let { loaderData, errors: errors2 } = dataRouterState;
6895 let needsToRunLoader = match.route.loader && !loaderData.hasOwnProperty(match.route.id) && (!errors2 || errors2[match.route.id] === void 0);
6896 if (match.route.lazy || needsToRunLoader) {
6897 renderFallback = true;
6898 if (fallbackIndex >= 0) {
6899 renderedMatches = renderedMatches.slice(0, fallbackIndex + 1);
6900 } else {
6901 renderedMatches = [renderedMatches[0]];
6902 }
6903 break;
6904 }
6905 }
6906 }
6907 }
6908 let onError = dataRouterState && unstable_onError ? (error, errorInfo) => {
6909 unstable_onError(error, {
6910 location: dataRouterState.location,
6911 params: _nullishCoalesce(_optionalChain([dataRouterState, 'access', _82 => _82.matches, 'optionalAccess', _83 => _83[0], 'optionalAccess', _84 => _84.params]), () => ( {})),
6912 unstable_pattern: getRoutePattern(dataRouterState.matches),
6913 errorInfo
6914 });
6915 } : void 0;
6916 return renderedMatches.reduceRight(
6917 (outlet, match, index) => {
6918 let error;
6919 let shouldRenderHydrateFallback = false;
6920 let errorElement = null;
6921 let hydrateFallbackElement = null;
6922 if (dataRouterState) {
6923 error = errors && match.route.id ? errors[match.route.id] : void 0;
6924 errorElement = match.route.errorElement || defaultErrorElement;
6925 if (renderFallback) {
6926 if (fallbackIndex < 0 && index === 0) {
6927 warningOnce(
6928 "route-fallback",
6929 false,
6930 "No `HydrateFallback` element provided to render during initial hydration"
6931 );
6932 shouldRenderHydrateFallback = true;
6933 hydrateFallbackElement = null;
6934 } else if (fallbackIndex === index) {
6935 shouldRenderHydrateFallback = true;
6936 hydrateFallbackElement = match.route.hydrateFallbackElement || null;
6937 }
6938 }
6939 }
6940 let matches2 = parentMatches.concat(renderedMatches.slice(0, index + 1));
6941 let getChildren = () => {
6942 let children;
6943 if (error) {
6944 children = errorElement;
6945 } else if (shouldRenderHydrateFallback) {
6946 children = hydrateFallbackElement;
6947 } else if (match.route.Component) {
6948 children = /* @__PURE__ */ React3.createElement(match.route.Component, null);
6949 } else if (match.route.element) {
6950 children = match.route.element;
6951 } else {
6952 children = outlet;
6953 }
6954 return /* @__PURE__ */ React3.createElement(
6955 RenderedRoute,
6956 {
6957 match,
6958 routeContext: {
6959 outlet,
6960 matches: matches2,
6961 isDataRoute: dataRouterState != null
6962 },
6963 children
6964 }
6965 );
6966 };
6967 return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? /* @__PURE__ */ React3.createElement(
6968 RenderErrorBoundary,
6969 {
6970 location: dataRouterState.location,
6971 revalidation: dataRouterState.revalidation,
6972 component: errorElement,
6973 error,
6974 children: getChildren(),
6975 routeContext: { outlet: null, matches: matches2, isDataRoute: true },
6976 onError
6977 }
6978 ) : getChildren();
6979 },
6980 null
6981 );
6982}
6983function getDataRouterConsoleError(hookName) {
6984 return `${hookName} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`;
6985}
6986function useDataRouterContext(hookName) {
6987 let ctx = React3.useContext(DataRouterContext);
6988 invariant(ctx, getDataRouterConsoleError(hookName));
6989 return ctx;
6990}
6991function useDataRouterState(hookName) {
6992 let state = React3.useContext(DataRouterStateContext);
6993 invariant(state, getDataRouterConsoleError(hookName));
6994 return state;
6995}
6996function useRouteContext(hookName) {
6997 let route = React3.useContext(RouteContext);
6998 invariant(route, getDataRouterConsoleError(hookName));
6999 return route;
7000}
7001function useCurrentRouteId(hookName) {
7002 let route = useRouteContext(hookName);
7003 let thisRoute = route.matches[route.matches.length - 1];
7004 invariant(
7005 thisRoute.route.id,
7006 `${hookName} can only be used on routes that contain a unique "id"`
7007 );
7008 return thisRoute.route.id;
7009}
7010function useRouteId() {
7011 return useCurrentRouteId("useRouteId" /* UseRouteId */);
7012}
7013function useNavigation() {
7014 let state = useDataRouterState("useNavigation" /* UseNavigation */);
7015 return state.navigation;
7016}
7017function useRevalidator() {
7018 let dataRouterContext = useDataRouterContext("useRevalidator" /* UseRevalidator */);
7019 let state = useDataRouterState("useRevalidator" /* UseRevalidator */);
7020 let revalidate = React3.useCallback(async () => {
7021 await dataRouterContext.router.revalidate();
7022 }, [dataRouterContext.router]);
7023 return React3.useMemo(
7024 () => ({ revalidate, state: state.revalidation }),
7025 [revalidate, state.revalidation]
7026 );
7027}
7028function useMatches() {
7029 let { matches, loaderData } = useDataRouterState(
7030 "useMatches" /* UseMatches */
7031 );
7032 return React3.useMemo(
7033 () => matches.map((m) => convertRouteMatchToUiMatch(m, loaderData)),
7034 [matches, loaderData]
7035 );
7036}
7037function useLoaderData() {
7038 let state = useDataRouterState("useLoaderData" /* UseLoaderData */);
7039 let routeId = useCurrentRouteId("useLoaderData" /* UseLoaderData */);
7040 return state.loaderData[routeId];
7041}
7042function useRouteLoaderData(routeId) {
7043 let state = useDataRouterState("useRouteLoaderData" /* UseRouteLoaderData */);
7044 return state.loaderData[routeId];
7045}
7046function useActionData() {
7047 let state = useDataRouterState("useActionData" /* UseActionData */);
7048 let routeId = useCurrentRouteId("useLoaderData" /* UseLoaderData */);
7049 return state.actionData ? state.actionData[routeId] : void 0;
7050}
7051function useRouteError() {
7052 let error = React3.useContext(RouteErrorContext);
7053 let state = useDataRouterState("useRouteError" /* UseRouteError */);
7054 let routeId = useCurrentRouteId("useRouteError" /* UseRouteError */);
7055 if (error !== void 0) {
7056 return error;
7057 }
7058 return _optionalChain([state, 'access', _85 => _85.errors, 'optionalAccess', _86 => _86[routeId]]);
7059}
7060function useAsyncValue() {
7061 let value = React3.useContext(AwaitContext);
7062 return _optionalChain([value, 'optionalAccess', _87 => _87._data]);
7063}
7064function useAsyncError() {
7065 let value = React3.useContext(AwaitContext);
7066 return _optionalChain([value, 'optionalAccess', _88 => _88._error]);
7067}
7068var blockerId = 0;
7069function useBlocker(shouldBlock) {
7070 let { router, basename } = useDataRouterContext("useBlocker" /* UseBlocker */);
7071 let state = useDataRouterState("useBlocker" /* UseBlocker */);
7072 let [blockerKey, setBlockerKey] = React3.useState("");
7073 let blockerFunction = React3.useCallback(
7074 (arg) => {
7075 if (typeof shouldBlock !== "function") {
7076 return !!shouldBlock;
7077 }
7078 if (basename === "/") {
7079 return shouldBlock(arg);
7080 }
7081 let { currentLocation, nextLocation, historyAction } = arg;
7082 return shouldBlock({
7083 currentLocation: {
7084 ...currentLocation,
7085 pathname: stripBasename(currentLocation.pathname, basename) || currentLocation.pathname
7086 },
7087 nextLocation: {
7088 ...nextLocation,
7089 pathname: stripBasename(nextLocation.pathname, basename) || nextLocation.pathname
7090 },
7091 historyAction
7092 });
7093 },
7094 [basename, shouldBlock]
7095 );
7096 React3.useEffect(() => {
7097 let key = String(++blockerId);
7098 setBlockerKey(key);
7099 return () => router.deleteBlocker(key);
7100 }, [router]);
7101 React3.useEffect(() => {
7102 if (blockerKey !== "") {
7103 router.getBlocker(blockerKey, blockerFunction);
7104 }
7105 }, [router, blockerKey, blockerFunction]);
7106 return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER;
7107}
7108function useNavigateStable() {
7109 let { router } = useDataRouterContext("useNavigate" /* UseNavigateStable */);
7110 let id = useCurrentRouteId("useNavigate" /* UseNavigateStable */);
7111 let activeRef = React3.useRef(false);
7112 useIsomorphicLayoutEffect(() => {
7113 activeRef.current = true;
7114 });
7115 let navigate = React3.useCallback(
7116 async (to, options = {}) => {
7117 warning(activeRef.current, navigateEffectWarning);
7118 if (!activeRef.current) return;
7119 if (typeof to === "number") {
7120 await router.navigate(to);
7121 } else {
7122 await router.navigate(to, { fromRouteId: id, ...options });
7123 }
7124 },
7125 [router, id]
7126 );
7127 return navigate;
7128}
7129var alreadyWarned = {};
7130function warningOnce(key, cond, message) {
7131 if (!cond && !alreadyWarned[key]) {
7132 alreadyWarned[key] = true;
7133 warning(false, message);
7134 }
7135}
7136function useRoute(...args) {
7137 const currentRouteId = useCurrentRouteId(
7138 "useRoute" /* UseRoute */
7139 );
7140 const id = _nullishCoalesce(args[0], () => ( currentRouteId));
7141 const state = useDataRouterState("useRoute" /* UseRoute */);
7142 const route = state.matches.find(({ route: route2 }) => route2.id === id);
7143 if (route === void 0) return void 0;
7144 return {
7145 handle: route.route.handle,
7146 loaderData: state.loaderData[id],
7147 actionData: _optionalChain([state, 'access', _89 => _89.actionData, 'optionalAccess', _90 => _90[id]])
7148 };
7149}
7150
7151// lib/dom/ssr/errorBoundaries.tsx
7152
7153
7154// lib/dom/ssr/components.tsx
7155
7156
7157// lib/dom/ssr/routeModules.ts
7158async function loadRouteModule(route, routeModulesCache) {
7159 if (route.id in routeModulesCache) {
7160 return routeModulesCache[route.id];
7161 }
7162 try {
7163 let routeModule = await Promise.resolve().then(() => _interopRequireWildcard(require(
7164 /* @vite-ignore */
7165 /* webpackIgnore: true */
7166 route.module
7167 )));
7168 routeModulesCache[route.id] = routeModule;
7169 return routeModule;
7170 } catch (error) {
7171 console.error(
7172 `Error loading route module \`${route.module}\`, reloading page...`
7173 );
7174 console.error(error);
7175 if (window.__reactRouterContext && window.__reactRouterContext.isSpaMode && // @ts-expect-error
7176 void 0) {
7177 throw error;
7178 }
7179 window.location.reload();
7180 return new Promise(() => {
7181 });
7182 }
7183}
7184
7185// lib/dom/ssr/links.ts
7186function getKeyedLinksForMatches(matches, routeModules, manifest) {
7187 let descriptors = matches.map((match) => {
7188 let module = routeModules[match.route.id];
7189 let route = manifest.routes[match.route.id];
7190 return [
7191 route && route.css ? route.css.map((href) => ({ rel: "stylesheet", href })) : [],
7192 _optionalChain([module, 'optionalAccess', _91 => _91.links, 'optionalCall', _92 => _92()]) || []
7193 ];
7194 }).flat(2);
7195 let preloads = getModuleLinkHrefs(matches, manifest);
7196 return dedupeLinkDescriptors(descriptors, preloads);
7197}
7198function getRouteCssDescriptors(route) {
7199 if (!route.css) return [];
7200 return route.css.map((href) => ({ rel: "stylesheet", href }));
7201}
7202async function prefetchRouteCss(route) {
7203 if (!route.css) return;
7204 let descriptors = getRouteCssDescriptors(route);
7205 await Promise.all(descriptors.map(prefetchStyleLink));
7206}
7207async function prefetchStyleLinks(route, routeModule) {
7208 if (!route.css && !routeModule.links || !isPreloadSupported()) return;
7209 let descriptors = [];
7210 if (route.css) {
7211 descriptors.push(...getRouteCssDescriptors(route));
7212 }
7213 if (routeModule.links) {
7214 descriptors.push(...routeModule.links());
7215 }
7216 if (descriptors.length === 0) return;
7217 let styleLinks = [];
7218 for (let descriptor of descriptors) {
7219 if (!isPageLinkDescriptor(descriptor) && descriptor.rel === "stylesheet") {
7220 styleLinks.push({
7221 ...descriptor,
7222 rel: "preload",
7223 as: "style"
7224 });
7225 }
7226 }
7227 await Promise.all(styleLinks.map(prefetchStyleLink));
7228}
7229async function prefetchStyleLink(descriptor) {
7230 return new Promise((resolve) => {
7231 if (descriptor.media && !window.matchMedia(descriptor.media).matches || document.querySelector(
7232 `link[rel="stylesheet"][href="${descriptor.href}"]`
7233 )) {
7234 return resolve();
7235 }
7236 let link = document.createElement("link");
7237 Object.assign(link, descriptor);
7238 function removeLink() {
7239 if (document.head.contains(link)) {
7240 document.head.removeChild(link);
7241 }
7242 }
7243 link.onload = () => {
7244 removeLink();
7245 resolve();
7246 };
7247 link.onerror = () => {
7248 removeLink();
7249 resolve();
7250 };
7251 document.head.appendChild(link);
7252 });
7253}
7254function isPageLinkDescriptor(object) {
7255 return object != null && typeof object.page === "string";
7256}
7257function isHtmlLinkDescriptor(object) {
7258 if (object == null) {
7259 return false;
7260 }
7261 if (object.href == null) {
7262 return object.rel === "preload" && typeof object.imageSrcSet === "string" && typeof object.imageSizes === "string";
7263 }
7264 return typeof object.rel === "string" && typeof object.href === "string";
7265}
7266async function getKeyedPrefetchLinks(matches, manifest, routeModules) {
7267 let links = await Promise.all(
7268 matches.map(async (match) => {
7269 let route = manifest.routes[match.route.id];
7270 if (route) {
7271 let mod = await loadRouteModule(route, routeModules);
7272 return mod.links ? mod.links() : [];
7273 }
7274 return [];
7275 })
7276 );
7277 return dedupeLinkDescriptors(
7278 links.flat(1).filter(isHtmlLinkDescriptor).filter((link) => link.rel === "stylesheet" || link.rel === "preload").map(
7279 (link) => link.rel === "stylesheet" ? { ...link, rel: "prefetch", as: "style" } : { ...link, rel: "prefetch" }
7280 )
7281 );
7282}
7283function getNewMatchesForLinks(page, nextMatches, currentMatches, manifest, location, mode) {
7284 let isNew = (match, index) => {
7285 if (!currentMatches[index]) return true;
7286 return match.route.id !== currentMatches[index].route.id;
7287 };
7288 let matchPathChanged = (match, index) => {
7289 return (
7290 // param change, /users/123 -> /users/456
7291 currentMatches[index].pathname !== match.pathname || // splat param changed, which is not present in match.path
7292 // e.g. /files/images/avatar.jpg -> files/finances.xls
7293 _optionalChain([currentMatches, 'access', _93 => _93[index], 'access', _94 => _94.route, 'access', _95 => _95.path, 'optionalAccess', _96 => _96.endsWith, 'call', _97 => _97("*")]) && currentMatches[index].params["*"] !== match.params["*"]
7294 );
7295 };
7296 if (mode === "assets") {
7297 return nextMatches.filter(
7298 (match, index) => isNew(match, index) || matchPathChanged(match, index)
7299 );
7300 }
7301 if (mode === "data") {
7302 return nextMatches.filter((match, index) => {
7303 let manifestRoute = manifest.routes[match.route.id];
7304 if (!manifestRoute || !manifestRoute.hasLoader) {
7305 return false;
7306 }
7307 if (isNew(match, index) || matchPathChanged(match, index)) {
7308 return true;
7309 }
7310 if (match.route.shouldRevalidate) {
7311 let routeChoice = match.route.shouldRevalidate({
7312 currentUrl: new URL(
7313 location.pathname + location.search + location.hash,
7314 window.origin
7315 ),
7316 currentParams: _optionalChain([currentMatches, 'access', _98 => _98[0], 'optionalAccess', _99 => _99.params]) || {},
7317 nextUrl: new URL(page, window.origin),
7318 nextParams: match.params,
7319 defaultShouldRevalidate: true
7320 });
7321 if (typeof routeChoice === "boolean") {
7322 return routeChoice;
7323 }
7324 }
7325 return true;
7326 });
7327 }
7328 return [];
7329}
7330function getModuleLinkHrefs(matches, manifest, { includeHydrateFallback } = {}) {
7331 return dedupeHrefs(
7332 matches.map((match) => {
7333 let route = manifest.routes[match.route.id];
7334 if (!route) return [];
7335 let hrefs = [route.module];
7336 if (route.clientActionModule) {
7337 hrefs = hrefs.concat(route.clientActionModule);
7338 }
7339 if (route.clientLoaderModule) {
7340 hrefs = hrefs.concat(route.clientLoaderModule);
7341 }
7342 if (includeHydrateFallback && route.hydrateFallbackModule) {
7343 hrefs = hrefs.concat(route.hydrateFallbackModule);
7344 }
7345 if (route.imports) {
7346 hrefs = hrefs.concat(route.imports);
7347 }
7348 return hrefs;
7349 }).flat(1)
7350 );
7351}
7352function dedupeHrefs(hrefs) {
7353 return [...new Set(hrefs)];
7354}
7355function sortKeys(obj) {
7356 let sorted = {};
7357 let keys = Object.keys(obj).sort();
7358 for (let key of keys) {
7359 sorted[key] = obj[key];
7360 }
7361 return sorted;
7362}
7363function dedupeLinkDescriptors(descriptors, preloads) {
7364 let set = /* @__PURE__ */ new Set();
7365 let preloadsSet = new Set(preloads);
7366 return descriptors.reduce((deduped, descriptor) => {
7367 let alreadyModulePreload = preloads && !isPageLinkDescriptor(descriptor) && descriptor.as === "script" && descriptor.href && preloadsSet.has(descriptor.href);
7368 if (alreadyModulePreload) {
7369 return deduped;
7370 }
7371 let key = JSON.stringify(sortKeys(descriptor));
7372 if (!set.has(key)) {
7373 set.add(key);
7374 deduped.push({ key, link: descriptor });
7375 }
7376 return deduped;
7377 }, []);
7378}
7379var _isPreloadSupported;
7380function isPreloadSupported() {
7381 if (_isPreloadSupported !== void 0) {
7382 return _isPreloadSupported;
7383 }
7384 let el = document.createElement("link");
7385 _isPreloadSupported = el.relList.supports("preload");
7386 el = null;
7387 return _isPreloadSupported;
7388}
7389
7390// lib/server-runtime/warnings.ts
7391var alreadyWarned2 = {};
7392function warnOnce(condition, message) {
7393 if (!condition && !alreadyWarned2[message]) {
7394 alreadyWarned2[message] = true;
7395 console.warn(message);
7396 }
7397}
7398
7399// lib/dom/ssr/fog-of-war.ts
7400
7401
7402// lib/dom/ssr/routes.tsx
7403
7404
7405// lib/dom/ssr/fallback.tsx
7406
7407function RemixRootDefaultHydrateFallback() {
7408 return /* @__PURE__ */ React4.createElement(BoundaryShell, { title: "Loading...", renderScripts: true }, ENABLE_DEV_WARNINGS ? /* @__PURE__ */ React4.createElement(
7409 "script",
7410 {
7411 dangerouslySetInnerHTML: {
7412 __html: `
7413 console.log(
7414 "\u{1F4BF} Hey developer \u{1F44B}. You can provide a way better UX than this " +
7415 "when your app is loading JS modules and/or running \`clientLoader\` " +
7416 "functions. Check out https://reactrouter.com/start/framework/route-module#hydratefallback " +
7417 "for more information."
7418 );
7419 `
7420 }
7421 }
7422 ) : null);
7423}
7424
7425// lib/dom/ssr/routes.tsx
7426function groupRoutesByParentId(manifest) {
7427 let routes = {};
7428 Object.values(manifest).forEach((route) => {
7429 if (route) {
7430 let parentId = route.parentId || "";
7431 if (!routes[parentId]) {
7432 routes[parentId] = [];
7433 }
7434 routes[parentId].push(route);
7435 }
7436 });
7437 return routes;
7438}
7439function getRouteComponents(route, routeModule, isSpaMode) {
7440 let Component4 = getRouteModuleComponent(routeModule);
7441 let HydrateFallback = routeModule.HydrateFallback && (!isSpaMode || route.id === "root") ? routeModule.HydrateFallback : route.id === "root" ? RemixRootDefaultHydrateFallback : void 0;
7442 let ErrorBoundary = routeModule.ErrorBoundary ? routeModule.ErrorBoundary : route.id === "root" ? () => /* @__PURE__ */ React5.createElement(RemixRootDefaultErrorBoundary, { error: useRouteError() }) : void 0;
7443 if (route.id === "root" && routeModule.Layout) {
7444 return {
7445 ...Component4 ? {
7446 element: /* @__PURE__ */ React5.createElement(routeModule.Layout, null, /* @__PURE__ */ React5.createElement(Component4, null))
7447 } : { Component: Component4 },
7448 ...ErrorBoundary ? {
7449 errorElement: /* @__PURE__ */ React5.createElement(routeModule.Layout, null, /* @__PURE__ */ React5.createElement(ErrorBoundary, null))
7450 } : { ErrorBoundary },
7451 ...HydrateFallback ? {
7452 hydrateFallbackElement: /* @__PURE__ */ React5.createElement(routeModule.Layout, null, /* @__PURE__ */ React5.createElement(HydrateFallback, null))
7453 } : { HydrateFallback }
7454 };
7455 }
7456 return { Component: Component4, ErrorBoundary, HydrateFallback };
7457}
7458function createServerRoutes(manifest, routeModules, future, isSpaMode, parentId = "", routesByParentId = groupRoutesByParentId(manifest), spaModeLazyPromise = Promise.resolve({ Component: () => null })) {
7459 return (routesByParentId[parentId] || []).map((route) => {
7460 let routeModule = routeModules[route.id];
7461 invariant2(
7462 routeModule,
7463 "No `routeModule` available to create server routes"
7464 );
7465 let dataRoute = {
7466 ...getRouteComponents(route, routeModule, isSpaMode),
7467 caseSensitive: route.caseSensitive,
7468 id: route.id,
7469 index: route.index,
7470 path: route.path,
7471 handle: routeModule.handle,
7472 // For SPA Mode, all routes are lazy except root. However we tell the
7473 // router root is also lazy here too since we don't need a full
7474 // implementation - we just need a `lazy` prop to tell the RR rendering
7475 // where to stop which is always at the root route in SPA mode
7476 lazy: isSpaMode ? () => spaModeLazyPromise : void 0,
7477 // For partial hydration rendering, we need to indicate when the route
7478 // has a loader/clientLoader, but it won't ever be called during the static
7479 // render, so just give it a no-op function so we can render down to the
7480 // proper fallback
7481 loader: route.hasLoader || route.hasClientLoader ? () => null : void 0
7482 // We don't need middleware/action/shouldRevalidate on these routes since
7483 // they're for a static render
7484 };
7485 let children = createServerRoutes(
7486 manifest,
7487 routeModules,
7488 future,
7489 isSpaMode,
7490 route.id,
7491 routesByParentId,
7492 spaModeLazyPromise
7493 );
7494 if (children.length > 0) dataRoute.children = children;
7495 return dataRoute;
7496 });
7497}
7498function createClientRoutesWithHMRRevalidationOptOut(needsRevalidation, manifest, routeModulesCache, initialState, ssr, isSpaMode) {
7499 return createClientRoutes(
7500 manifest,
7501 routeModulesCache,
7502 initialState,
7503 ssr,
7504 isSpaMode,
7505 "",
7506 groupRoutesByParentId(manifest),
7507 needsRevalidation
7508 );
7509}
7510function preventInvalidServerHandlerCall(type, route) {
7511 if (type === "loader" && !route.hasLoader || type === "action" && !route.hasAction) {
7512 let fn = type === "action" ? "serverAction()" : "serverLoader()";
7513 let msg = `You are trying to call ${fn} on a route that does not have a server ${type} (routeId: "${route.id}")`;
7514 console.error(msg);
7515 throw new ErrorResponseImpl(400, "Bad Request", new Error(msg), true);
7516 }
7517}
7518function noActionDefinedError(type, routeId) {
7519 let article = type === "clientAction" ? "a" : "an";
7520 let msg = `Route "${routeId}" does not have ${article} ${type}, but you are trying to submit to it. To fix this, please add ${article} \`${type}\` function to the route`;
7521 console.error(msg);
7522 throw new ErrorResponseImpl(405, "Method Not Allowed", new Error(msg), true);
7523}
7524function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSpaMode, parentId = "", routesByParentId = groupRoutesByParentId(manifest), needsRevalidation) {
7525 return (routesByParentId[parentId] || []).map((route) => {
7526 let routeModule = routeModulesCache[route.id];
7527 function fetchServerHandler(singleFetch) {
7528 invariant2(
7529 typeof singleFetch === "function",
7530 "No single fetch function available for route handler"
7531 );
7532 return singleFetch();
7533 }
7534 function fetchServerLoader(singleFetch) {
7535 if (!route.hasLoader) return Promise.resolve(null);
7536 return fetchServerHandler(singleFetch);
7537 }
7538 function fetchServerAction(singleFetch) {
7539 if (!route.hasAction) {
7540 throw noActionDefinedError("action", route.id);
7541 }
7542 return fetchServerHandler(singleFetch);
7543 }
7544 function prefetchModule(modulePath) {
7545 Promise.resolve().then(() => _interopRequireWildcard(require(
7546 /* @vite-ignore */
7547 /* webpackIgnore: true */
7548 modulePath
7549 )));
7550 }
7551 function prefetchRouteModuleChunks(route2) {
7552 if (route2.clientActionModule) {
7553 prefetchModule(route2.clientActionModule);
7554 }
7555 if (route2.clientLoaderModule) {
7556 prefetchModule(route2.clientLoaderModule);
7557 }
7558 }
7559 async function prefetchStylesAndCallHandler(handler) {
7560 let cachedModule = routeModulesCache[route.id];
7561 let linkPrefetchPromise = cachedModule ? prefetchStyleLinks(route, cachedModule) : Promise.resolve();
7562 try {
7563 return handler();
7564 } finally {
7565 await linkPrefetchPromise;
7566 }
7567 }
7568 let dataRoute = {
7569 id: route.id,
7570 index: route.index,
7571 path: route.path
7572 };
7573 if (routeModule) {
7574 Object.assign(dataRoute, {
7575 ...dataRoute,
7576 ...getRouteComponents(route, routeModule, isSpaMode),
7577 middleware: routeModule.clientMiddleware,
7578 handle: routeModule.handle,
7579 shouldRevalidate: getShouldRevalidateFunction(
7580 dataRoute.path,
7581 routeModule,
7582 route,
7583 ssr,
7584 needsRevalidation
7585 )
7586 });
7587 let hasInitialData = initialState && initialState.loaderData && route.id in initialState.loaderData;
7588 let initialData = hasInitialData ? _optionalChain([initialState, 'optionalAccess', _100 => _100.loaderData, 'optionalAccess', _101 => _101[route.id]]) : void 0;
7589 let hasInitialError = initialState && initialState.errors && route.id in initialState.errors;
7590 let initialError = hasInitialError ? _optionalChain([initialState, 'optionalAccess', _102 => _102.errors, 'optionalAccess', _103 => _103[route.id]]) : void 0;
7591 let isHydrationRequest = needsRevalidation == null && (_optionalChain([routeModule, 'access', _104 => _104.clientLoader, 'optionalAccess', _105 => _105.hydrate]) === true || !route.hasLoader);
7592 dataRoute.loader = async ({ request, params, context, unstable_pattern }, singleFetch) => {
7593 try {
7594 let result = await prefetchStylesAndCallHandler(async () => {
7595 invariant2(
7596 routeModule,
7597 "No `routeModule` available for critical-route loader"
7598 );
7599 if (!routeModule.clientLoader) {
7600 return fetchServerLoader(singleFetch);
7601 }
7602 return routeModule.clientLoader({
7603 request,
7604 params,
7605 context,
7606 unstable_pattern,
7607 async serverLoader() {
7608 preventInvalidServerHandlerCall("loader", route);
7609 if (isHydrationRequest) {
7610 if (hasInitialData) {
7611 return initialData;
7612 }
7613 if (hasInitialError) {
7614 throw initialError;
7615 }
7616 }
7617 return fetchServerLoader(singleFetch);
7618 }
7619 });
7620 });
7621 return result;
7622 } finally {
7623 isHydrationRequest = false;
7624 }
7625 };
7626 dataRoute.loader.hydrate = shouldHydrateRouteLoader(
7627 route.id,
7628 routeModule.clientLoader,
7629 route.hasLoader,
7630 isSpaMode
7631 );
7632 dataRoute.action = ({ request, params, context, unstable_pattern }, singleFetch) => {
7633 return prefetchStylesAndCallHandler(async () => {
7634 invariant2(
7635 routeModule,
7636 "No `routeModule` available for critical-route action"
7637 );
7638 if (!routeModule.clientAction) {
7639 if (isSpaMode) {
7640 throw noActionDefinedError("clientAction", route.id);
7641 }
7642 return fetchServerAction(singleFetch);
7643 }
7644 return routeModule.clientAction({
7645 request,
7646 params,
7647 context,
7648 unstable_pattern,
7649 async serverAction() {
7650 preventInvalidServerHandlerCall("action", route);
7651 return fetchServerAction(singleFetch);
7652 }
7653 });
7654 });
7655 };
7656 } else {
7657 if (!route.hasClientLoader) {
7658 dataRoute.loader = (_, singleFetch) => prefetchStylesAndCallHandler(() => {
7659 return fetchServerLoader(singleFetch);
7660 });
7661 }
7662 if (!route.hasClientAction) {
7663 dataRoute.action = (_, singleFetch) => prefetchStylesAndCallHandler(() => {
7664 if (isSpaMode) {
7665 throw noActionDefinedError("clientAction", route.id);
7666 }
7667 return fetchServerAction(singleFetch);
7668 });
7669 }
7670 let lazyRoutePromise;
7671 async function getLazyRoute() {
7672 if (lazyRoutePromise) {
7673 return await lazyRoutePromise;
7674 }
7675 lazyRoutePromise = (async () => {
7676 if (route.clientLoaderModule || route.clientActionModule) {
7677 await new Promise((resolve) => setTimeout(resolve, 0));
7678 }
7679 let routeModulePromise = loadRouteModuleWithBlockingLinks(
7680 route,
7681 routeModulesCache
7682 );
7683 prefetchRouteModuleChunks(route);
7684 return await routeModulePromise;
7685 })();
7686 return await lazyRoutePromise;
7687 }
7688 dataRoute.lazy = {
7689 loader: route.hasClientLoader ? async () => {
7690 let { clientLoader } = route.clientLoaderModule ? await Promise.resolve().then(() => _interopRequireWildcard(require(
7691 /* @vite-ignore */
7692 /* webpackIgnore: true */
7693 route.clientLoaderModule
7694 ))) : await getLazyRoute();
7695 invariant2(clientLoader, "No `clientLoader` export found");
7696 return (args, singleFetch) => clientLoader({
7697 ...args,
7698 async serverLoader() {
7699 preventInvalidServerHandlerCall("loader", route);
7700 return fetchServerLoader(singleFetch);
7701 }
7702 });
7703 } : void 0,
7704 action: route.hasClientAction ? async () => {
7705 let clientActionPromise = route.clientActionModule ? Promise.resolve().then(() => _interopRequireWildcard(require(
7706 /* @vite-ignore */
7707 /* webpackIgnore: true */
7708 route.clientActionModule
7709 ))) : getLazyRoute();
7710 prefetchRouteModuleChunks(route);
7711 let { clientAction } = await clientActionPromise;
7712 invariant2(clientAction, "No `clientAction` export found");
7713 return (args, singleFetch) => clientAction({
7714 ...args,
7715 async serverAction() {
7716 preventInvalidServerHandlerCall("action", route);
7717 return fetchServerAction(singleFetch);
7718 }
7719 });
7720 } : void 0,
7721 middleware: route.hasClientMiddleware ? async () => {
7722 let { clientMiddleware } = route.clientMiddlewareModule ? await Promise.resolve().then(() => _interopRequireWildcard(require(
7723 /* @vite-ignore */
7724 /* webpackIgnore: true */
7725 route.clientMiddlewareModule
7726 ))) : await getLazyRoute();
7727 invariant2(clientMiddleware, "No `clientMiddleware` export found");
7728 return clientMiddleware;
7729 } : void 0,
7730 shouldRevalidate: async () => {
7731 let lazyRoute = await getLazyRoute();
7732 return getShouldRevalidateFunction(
7733 dataRoute.path,
7734 lazyRoute,
7735 route,
7736 ssr,
7737 needsRevalidation
7738 );
7739 },
7740 handle: async () => (await getLazyRoute()).handle,
7741 // No need to wrap these in layout since the root route is never
7742 // loaded via route.lazy()
7743 Component: async () => (await getLazyRoute()).Component,
7744 ErrorBoundary: route.hasErrorBoundary ? async () => (await getLazyRoute()).ErrorBoundary : void 0
7745 };
7746 }
7747 let children = createClientRoutes(
7748 manifest,
7749 routeModulesCache,
7750 initialState,
7751 ssr,
7752 isSpaMode,
7753 route.id,
7754 routesByParentId,
7755 needsRevalidation
7756 );
7757 if (children.length > 0) dataRoute.children = children;
7758 return dataRoute;
7759 });
7760}
7761function getShouldRevalidateFunction(path, route, manifestRoute, ssr, needsRevalidation) {
7762 if (needsRevalidation) {
7763 return wrapShouldRevalidateForHdr(
7764 manifestRoute.id,
7765 route.shouldRevalidate,
7766 needsRevalidation
7767 );
7768 }
7769 if (!ssr && manifestRoute.hasLoader && !manifestRoute.hasClientLoader) {
7770 let myParams = path ? compilePath(path)[1].map((p) => p.paramName) : [];
7771 const didParamsChange = (opts) => myParams.some((p) => opts.currentParams[p] !== opts.nextParams[p]);
7772 if (route.shouldRevalidate) {
7773 let fn = route.shouldRevalidate;
7774 return (opts) => fn({
7775 ...opts,
7776 defaultShouldRevalidate: didParamsChange(opts)
7777 });
7778 } else {
7779 return (opts) => didParamsChange(opts);
7780 }
7781 }
7782 return route.shouldRevalidate;
7783}
7784function wrapShouldRevalidateForHdr(routeId, routeShouldRevalidate, needsRevalidation) {
7785 let handledRevalidation = false;
7786 return (arg) => {
7787 if (!handledRevalidation) {
7788 handledRevalidation = true;
7789 return needsRevalidation.has(routeId);
7790 }
7791 return routeShouldRevalidate ? routeShouldRevalidate(arg) : arg.defaultShouldRevalidate;
7792 };
7793}
7794async function loadRouteModuleWithBlockingLinks(route, routeModules) {
7795 let routeModulePromise = loadRouteModule(route, routeModules);
7796 let prefetchRouteCssPromise = prefetchRouteCss(route);
7797 let routeModule = await routeModulePromise;
7798 await Promise.all([
7799 prefetchRouteCssPromise,
7800 prefetchStyleLinks(route, routeModule)
7801 ]);
7802 return {
7803 Component: getRouteModuleComponent(routeModule),
7804 ErrorBoundary: routeModule.ErrorBoundary,
7805 clientMiddleware: routeModule.clientMiddleware,
7806 clientAction: routeModule.clientAction,
7807 clientLoader: routeModule.clientLoader,
7808 handle: routeModule.handle,
7809 links: routeModule.links,
7810 meta: routeModule.meta,
7811 shouldRevalidate: routeModule.shouldRevalidate
7812 };
7813}
7814function getRouteModuleComponent(routeModule) {
7815 if (routeModule.default == null) return void 0;
7816 let isEmptyObject = typeof routeModule.default === "object" && Object.keys(routeModule.default).length === 0;
7817 if (!isEmptyObject) {
7818 return routeModule.default;
7819 }
7820}
7821function shouldHydrateRouteLoader(routeId, clientLoader, hasLoader, isSpaMode) {
7822 return isSpaMode && routeId !== "root" || clientLoader != null && (clientLoader.hydrate === true || hasLoader !== true);
7823}
7824
7825// lib/dom/ssr/fog-of-war.ts
7826var nextPaths = /* @__PURE__ */ new Set();
7827var discoveredPathsMaxSize = 1e3;
7828var discoveredPaths = /* @__PURE__ */ new Set();
7829var URL_LIMIT = 7680;
7830function isFogOfWarEnabled(routeDiscovery, ssr) {
7831 return routeDiscovery.mode === "lazy" && ssr === true;
7832}
7833function getPartialManifest({ sri, ...manifest }, router) {
7834 let routeIds = new Set(router.state.matches.map((m) => m.route.id));
7835 let segments = router.state.location.pathname.split("/").filter(Boolean);
7836 let paths = ["/"];
7837 segments.pop();
7838 while (segments.length > 0) {
7839 paths.push(`/${segments.join("/")}`);
7840 segments.pop();
7841 }
7842 paths.forEach((path) => {
7843 let matches = matchRoutes(router.routes, path, router.basename);
7844 if (matches) {
7845 matches.forEach((m) => routeIds.add(m.route.id));
7846 }
7847 });
7848 let initialRoutes = [...routeIds].reduce(
7849 (acc, id) => Object.assign(acc, { [id]: manifest.routes[id] }),
7850 {}
7851 );
7852 return {
7853 ...manifest,
7854 routes: initialRoutes,
7855 sri: sri ? true : void 0
7856 };
7857}
7858function getPatchRoutesOnNavigationFunction(manifest, routeModules, ssr, routeDiscovery, isSpaMode, basename) {
7859 if (!isFogOfWarEnabled(routeDiscovery, ssr)) {
7860 return void 0;
7861 }
7862 return async ({ path, patch, signal, fetcherKey }) => {
7863 if (discoveredPaths.has(path)) {
7864 return;
7865 }
7866 await fetchAndApplyManifestPatches(
7867 [path],
7868 fetcherKey ? window.location.href : path,
7869 manifest,
7870 routeModules,
7871 ssr,
7872 isSpaMode,
7873 basename,
7874 routeDiscovery.manifestPath,
7875 patch,
7876 signal
7877 );
7878 };
7879}
7880function useFogOFWarDiscovery(router, manifest, routeModules, ssr, routeDiscovery, isSpaMode) {
7881 React6.useEffect(() => {
7882 if (!isFogOfWarEnabled(routeDiscovery, ssr) || // @ts-expect-error - TS doesn't know about this yet
7883 _optionalChain([window, 'access', _106 => _106.navigator, 'optionalAccess', _107 => _107.connection, 'optionalAccess', _108 => _108.saveData]) === true) {
7884 return;
7885 }
7886 function registerElement(el) {
7887 let path = el.tagName === "FORM" ? el.getAttribute("action") : el.getAttribute("href");
7888 if (!path) {
7889 return;
7890 }
7891 let pathname = el.tagName === "A" ? el.pathname : new URL(path, window.location.origin).pathname;
7892 if (!discoveredPaths.has(pathname)) {
7893 nextPaths.add(pathname);
7894 }
7895 }
7896 async function fetchPatches() {
7897 document.querySelectorAll("a[data-discover], form[data-discover]").forEach(registerElement);
7898 let lazyPaths = Array.from(nextPaths.keys()).filter((path) => {
7899 if (discoveredPaths.has(path)) {
7900 nextPaths.delete(path);
7901 return false;
7902 }
7903 return true;
7904 });
7905 if (lazyPaths.length === 0) {
7906 return;
7907 }
7908 try {
7909 await fetchAndApplyManifestPatches(
7910 lazyPaths,
7911 null,
7912 manifest,
7913 routeModules,
7914 ssr,
7915 isSpaMode,
7916 router.basename,
7917 routeDiscovery.manifestPath,
7918 router.patchRoutes
7919 );
7920 } catch (e) {
7921 console.error("Failed to fetch manifest patches", e);
7922 }
7923 }
7924 let debouncedFetchPatches = debounce(fetchPatches, 100);
7925 fetchPatches();
7926 let observer = new MutationObserver(() => debouncedFetchPatches());
7927 observer.observe(document.documentElement, {
7928 subtree: true,
7929 childList: true,
7930 attributes: true,
7931 attributeFilter: ["data-discover", "href", "action"]
7932 });
7933 return () => observer.disconnect();
7934 }, [ssr, isSpaMode, manifest, routeModules, router, routeDiscovery]);
7935}
7936function getManifestPath(_manifestPath, basename) {
7937 let manifestPath = _manifestPath || "/__manifest";
7938 if (basename == null) {
7939 return manifestPath;
7940 }
7941 return `${basename}${manifestPath}`.replace(/\/+/g, "/");
7942}
7943var MANIFEST_VERSION_STORAGE_KEY = "react-router-manifest-version";
7944async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal) {
7945 const searchParams = new URLSearchParams();
7946 searchParams.set("paths", paths.sort().join(","));
7947 searchParams.set("version", manifest.version);
7948 let url = new URL(
7949 getManifestPath(manifestPath, basename),
7950 window.location.origin
7951 );
7952 url.search = searchParams.toString();
7953 if (url.toString().length > URL_LIMIT) {
7954 nextPaths.clear();
7955 return;
7956 }
7957 let serverPatches;
7958 try {
7959 let res = await fetch(url, { signal });
7960 if (!res.ok) {
7961 throw new Error(`${res.status} ${res.statusText}`);
7962 } else if (res.status === 204 && res.headers.has("X-Remix-Reload-Document")) {
7963 if (!errorReloadPath) {
7964 console.warn(
7965 "Detected a manifest version mismatch during eager route discovery. The next navigation/fetch to an undiscovered route will result in a new document navigation to sync up with the latest manifest."
7966 );
7967 return;
7968 }
7969 try {
7970 if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === manifest.version) {
7971 console.error(
7972 "Unable to discover routes due to manifest version mismatch."
7973 );
7974 return;
7975 }
7976 sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, manifest.version);
7977 } catch (e2) {
7978 }
7979 window.location.href = errorReloadPath;
7980 console.warn("Detected manifest version mismatch, reloading...");
7981 await new Promise(() => {
7982 });
7983 } else if (res.status >= 400) {
7984 throw new Error(await res.text());
7985 }
7986 try {
7987 sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY);
7988 } catch (e3) {
7989 }
7990 serverPatches = await res.json();
7991 } catch (e) {
7992 if (_optionalChain([signal, 'optionalAccess', _109 => _109.aborted])) return;
7993 throw e;
7994 }
7995 let knownRoutes = new Set(Object.keys(manifest.routes));
7996 let patches = Object.values(serverPatches).reduce((acc, route) => {
7997 if (route && !knownRoutes.has(route.id)) {
7998 acc[route.id] = route;
7999 }
8000 return acc;
8001 }, {});
8002 Object.assign(manifest.routes, patches);
8003 paths.forEach((p) => addToFifoQueue(p, discoveredPaths));
8004 let parentIds = /* @__PURE__ */ new Set();
8005 Object.values(patches).forEach((patch) => {
8006 if (patch && (!patch.parentId || !patches[patch.parentId])) {
8007 parentIds.add(patch.parentId);
8008 }
8009 });
8010 parentIds.forEach(
8011 (parentId) => patchRoutes(
8012 parentId || null,
8013 createClientRoutes(patches, routeModules, null, ssr, isSpaMode, parentId)
8014 )
8015 );
8016}
8017function addToFifoQueue(path, queue) {
8018 if (queue.size >= discoveredPathsMaxSize) {
8019 let first = queue.values().next().value;
8020 queue.delete(first);
8021 }
8022 queue.add(path);
8023}
8024function debounce(callback, wait) {
8025 let timeoutId;
8026 return (...args) => {
8027 window.clearTimeout(timeoutId);
8028 timeoutId = window.setTimeout(() => callback(...args), wait);
8029 };
8030}
8031
8032// lib/dom/ssr/components.tsx
8033function useDataRouterContext2() {
8034 let context = React7.useContext(DataRouterContext);
8035 invariant2(
8036 context,
8037 "You must render this element inside a <DataRouterContext.Provider> element"
8038 );
8039 return context;
8040}
8041function useDataRouterStateContext() {
8042 let context = React7.useContext(DataRouterStateContext);
8043 invariant2(
8044 context,
8045 "You must render this element inside a <DataRouterStateContext.Provider> element"
8046 );
8047 return context;
8048}
8049var FrameworkContext = React7.createContext(void 0);
8050FrameworkContext.displayName = "FrameworkContext";
8051function useFrameworkContext() {
8052 let context = React7.useContext(FrameworkContext);
8053 invariant2(
8054 context,
8055 "You must render this element inside a <HydratedRouter> element"
8056 );
8057 return context;
8058}
8059function usePrefetchBehavior(prefetch, theirElementProps) {
8060 let frameworkContext = React7.useContext(FrameworkContext);
8061 let [maybePrefetch, setMaybePrefetch] = React7.useState(false);
8062 let [shouldPrefetch, setShouldPrefetch] = React7.useState(false);
8063 let { onFocus, onBlur, onMouseEnter, onMouseLeave, onTouchStart } = theirElementProps;
8064 let ref = React7.useRef(null);
8065 React7.useEffect(() => {
8066 if (prefetch === "render") {
8067 setShouldPrefetch(true);
8068 }
8069 if (prefetch === "viewport") {
8070 let callback = (entries) => {
8071 entries.forEach((entry) => {
8072 setShouldPrefetch(entry.isIntersecting);
8073 });
8074 };
8075 let observer = new IntersectionObserver(callback, { threshold: 0.5 });
8076 if (ref.current) observer.observe(ref.current);
8077 return () => {
8078 observer.disconnect();
8079 };
8080 }
8081 }, [prefetch]);
8082 React7.useEffect(() => {
8083 if (maybePrefetch) {
8084 let id = setTimeout(() => {
8085 setShouldPrefetch(true);
8086 }, 100);
8087 return () => {
8088 clearTimeout(id);
8089 };
8090 }
8091 }, [maybePrefetch]);
8092 let setIntent = () => {
8093 setMaybePrefetch(true);
8094 };
8095 let cancelIntent = () => {
8096 setMaybePrefetch(false);
8097 setShouldPrefetch(false);
8098 };
8099 if (!frameworkContext) {
8100 return [false, ref, {}];
8101 }
8102 if (prefetch !== "intent") {
8103 return [shouldPrefetch, ref, {}];
8104 }
8105 return [
8106 shouldPrefetch,
8107 ref,
8108 {
8109 onFocus: composeEventHandlers(onFocus, setIntent),
8110 onBlur: composeEventHandlers(onBlur, cancelIntent),
8111 onMouseEnter: composeEventHandlers(onMouseEnter, setIntent),
8112 onMouseLeave: composeEventHandlers(onMouseLeave, cancelIntent),
8113 onTouchStart: composeEventHandlers(onTouchStart, setIntent)
8114 }
8115 ];
8116}
8117function composeEventHandlers(theirHandler, ourHandler) {
8118 return (event) => {
8119 theirHandler && theirHandler(event);
8120 if (!event.defaultPrevented) {
8121 ourHandler(event);
8122 }
8123 };
8124}
8125function getActiveMatches(matches, errors, isSpaMode) {
8126 if (isSpaMode && !isHydrated) {
8127 return [matches[0]];
8128 }
8129 if (errors) {
8130 let errorIdx = matches.findIndex((m) => errors[m.route.id] !== void 0);
8131 return matches.slice(0, errorIdx + 1);
8132 }
8133 return matches;
8134}
8135var CRITICAL_CSS_DATA_ATTRIBUTE = "data-react-router-critical-css";
8136function Links({ nonce }) {
8137 let { isSpaMode, manifest, routeModules, criticalCss } = useFrameworkContext();
8138 let { errors, matches: routerMatches } = useDataRouterStateContext();
8139 let matches = getActiveMatches(routerMatches, errors, isSpaMode);
8140 let keyedLinks = React7.useMemo(
8141 () => getKeyedLinksForMatches(matches, routeModules, manifest),
8142 [matches, routeModules, manifest]
8143 );
8144 return /* @__PURE__ */ React7.createElement(React7.Fragment, null, typeof criticalCss === "string" ? /* @__PURE__ */ React7.createElement(
8145 "style",
8146 {
8147 ...{ [CRITICAL_CSS_DATA_ATTRIBUTE]: "" },
8148 dangerouslySetInnerHTML: { __html: criticalCss }
8149 }
8150 ) : null, typeof criticalCss === "object" ? /* @__PURE__ */ React7.createElement(
8151 "link",
8152 {
8153 ...{ [CRITICAL_CSS_DATA_ATTRIBUTE]: "" },
8154 rel: "stylesheet",
8155 href: criticalCss.href,
8156 nonce
8157 }
8158 ) : null, keyedLinks.map(
8159 ({ key, link }) => isPageLinkDescriptor(link) ? /* @__PURE__ */ React7.createElement(PrefetchPageLinks, { key, nonce, ...link }) : /* @__PURE__ */ React7.createElement("link", { key, nonce, ...link })
8160 ));
8161}
8162function PrefetchPageLinks({ page, ...linkProps }) {
8163 let { router } = useDataRouterContext2();
8164 let matches = React7.useMemo(
8165 () => matchRoutes(router.routes, page, router.basename),
8166 [router.routes, page, router.basename]
8167 );
8168 if (!matches) {
8169 return null;
8170 }
8171 return /* @__PURE__ */ React7.createElement(PrefetchPageLinksImpl, { page, matches, ...linkProps });
8172}
8173function useKeyedPrefetchLinks(matches) {
8174 let { manifest, routeModules } = useFrameworkContext();
8175 let [keyedPrefetchLinks, setKeyedPrefetchLinks] = React7.useState([]);
8176 React7.useEffect(() => {
8177 let interrupted = false;
8178 void getKeyedPrefetchLinks(matches, manifest, routeModules).then(
8179 (links) => {
8180 if (!interrupted) {
8181 setKeyedPrefetchLinks(links);
8182 }
8183 }
8184 );
8185 return () => {
8186 interrupted = true;
8187 };
8188 }, [matches, manifest, routeModules]);
8189 return keyedPrefetchLinks;
8190}
8191function PrefetchPageLinksImpl({
8192 page,
8193 matches: nextMatches,
8194 ...linkProps
8195}) {
8196 let location = useLocation();
8197 let { manifest, routeModules } = useFrameworkContext();
8198 let { basename } = useDataRouterContext2();
8199 let { loaderData, matches } = useDataRouterStateContext();
8200 let newMatchesForData = React7.useMemo(
8201 () => getNewMatchesForLinks(
8202 page,
8203 nextMatches,
8204 matches,
8205 manifest,
8206 location,
8207 "data"
8208 ),
8209 [page, nextMatches, matches, manifest, location]
8210 );
8211 let newMatchesForAssets = React7.useMemo(
8212 () => getNewMatchesForLinks(
8213 page,
8214 nextMatches,
8215 matches,
8216 manifest,
8217 location,
8218 "assets"
8219 ),
8220 [page, nextMatches, matches, manifest, location]
8221 );
8222 let dataHrefs = React7.useMemo(() => {
8223 if (page === location.pathname + location.search + location.hash) {
8224 return [];
8225 }
8226 let routesParams = /* @__PURE__ */ new Set();
8227 let foundOptOutRoute = false;
8228 nextMatches.forEach((m) => {
8229 let manifestRoute = manifest.routes[m.route.id];
8230 if (!manifestRoute || !manifestRoute.hasLoader) {
8231 return;
8232 }
8233 if (!newMatchesForData.some((m2) => m2.route.id === m.route.id) && m.route.id in loaderData && _optionalChain([routeModules, 'access', _110 => _110[m.route.id], 'optionalAccess', _111 => _111.shouldRevalidate])) {
8234 foundOptOutRoute = true;
8235 } else if (manifestRoute.hasClientLoader) {
8236 foundOptOutRoute = true;
8237 } else {
8238 routesParams.add(m.route.id);
8239 }
8240 });
8241 if (routesParams.size === 0) {
8242 return [];
8243 }
8244 let url = singleFetchUrl(page, basename, "data");
8245 if (foundOptOutRoute && routesParams.size > 0) {
8246 url.searchParams.set(
8247 "_routes",
8248 nextMatches.filter((m) => routesParams.has(m.route.id)).map((m) => m.route.id).join(",")
8249 );
8250 }
8251 return [url.pathname + url.search];
8252 }, [
8253 basename,
8254 loaderData,
8255 location,
8256 manifest,
8257 newMatchesForData,
8258 nextMatches,
8259 page,
8260 routeModules
8261 ]);
8262 let moduleHrefs = React7.useMemo(
8263 () => getModuleLinkHrefs(newMatchesForAssets, manifest),
8264 [newMatchesForAssets, manifest]
8265 );
8266 let keyedPrefetchLinks = useKeyedPrefetchLinks(newMatchesForAssets);
8267 return /* @__PURE__ */ React7.createElement(React7.Fragment, null, dataHrefs.map((href) => /* @__PURE__ */ React7.createElement("link", { key: href, rel: "prefetch", as: "fetch", href, ...linkProps })), moduleHrefs.map((href) => /* @__PURE__ */ React7.createElement("link", { key: href, rel: "modulepreload", href, ...linkProps })), keyedPrefetchLinks.map(({ key, link }) => (
8268 // these don't spread `linkProps` because they are full link descriptors
8269 // already with their own props
8270 /* @__PURE__ */ React7.createElement("link", { key, nonce: linkProps.nonce, ...link })
8271 )));
8272}
8273function Meta() {
8274 let { isSpaMode, routeModules } = useFrameworkContext();
8275 let {
8276 errors,
8277 matches: routerMatches,
8278 loaderData
8279 } = useDataRouterStateContext();
8280 let location = useLocation();
8281 let _matches = getActiveMatches(routerMatches, errors, isSpaMode);
8282 let error = null;
8283 if (errors) {
8284 error = errors[_matches[_matches.length - 1].route.id];
8285 }
8286 let meta = [];
8287 let leafMeta = null;
8288 let matches = [];
8289 for (let i = 0; i < _matches.length; i++) {
8290 let _match = _matches[i];
8291 let routeId = _match.route.id;
8292 let data2 = loaderData[routeId];
8293 let params = _match.params;
8294 let routeModule = routeModules[routeId];
8295 let routeMeta = [];
8296 let match = {
8297 id: routeId,
8298 data: data2,
8299 loaderData: data2,
8300 meta: [],
8301 params: _match.params,
8302 pathname: _match.pathname,
8303 handle: _match.route.handle,
8304 error
8305 };
8306 matches[i] = match;
8307 if (_optionalChain([routeModule, 'optionalAccess', _112 => _112.meta])) {
8308 routeMeta = typeof routeModule.meta === "function" ? routeModule.meta({
8309 data: data2,
8310 loaderData: data2,
8311 params,
8312 location,
8313 matches,
8314 error
8315 }) : Array.isArray(routeModule.meta) ? [...routeModule.meta] : routeModule.meta;
8316 } else if (leafMeta) {
8317 routeMeta = [...leafMeta];
8318 }
8319 routeMeta = routeMeta || [];
8320 if (!Array.isArray(routeMeta)) {
8321 throw new Error(
8322 "The route at " + _match.route.path + " returns an invalid value. All route meta functions must return an array of meta objects.\n\nTo reference the meta function API, see https://remix.run/route/meta"
8323 );
8324 }
8325 match.meta = routeMeta;
8326 matches[i] = match;
8327 meta = [...routeMeta];
8328 leafMeta = meta;
8329 }
8330 return /* @__PURE__ */ React7.createElement(React7.Fragment, null, meta.flat().map((metaProps) => {
8331 if (!metaProps) {
8332 return null;
8333 }
8334 if ("tagName" in metaProps) {
8335 let { tagName, ...rest } = metaProps;
8336 if (!isValidMetaTag(tagName)) {
8337 console.warn(
8338 `A meta object uses an invalid tagName: ${tagName}. Expected either 'link' or 'meta'`
8339 );
8340 return null;
8341 }
8342 let Comp = tagName;
8343 return /* @__PURE__ */ React7.createElement(Comp, { key: JSON.stringify(rest), ...rest });
8344 }
8345 if ("title" in metaProps) {
8346 return /* @__PURE__ */ React7.createElement("title", { key: "title" }, String(metaProps.title));
8347 }
8348 if ("charset" in metaProps) {
8349 _nullishCoalesce(metaProps.charSet, () => ( (metaProps.charSet = metaProps.charset)));
8350 delete metaProps.charset;
8351 }
8352 if ("charSet" in metaProps && metaProps.charSet != null) {
8353 return typeof metaProps.charSet === "string" ? /* @__PURE__ */ React7.createElement("meta", { key: "charSet", charSet: metaProps.charSet }) : null;
8354 }
8355 if ("script:ld+json" in metaProps) {
8356 try {
8357 let json = JSON.stringify(metaProps["script:ld+json"]);
8358 return /* @__PURE__ */ React7.createElement(
8359 "script",
8360 {
8361 key: `script:ld+json:${json}`,
8362 type: "application/ld+json",
8363 dangerouslySetInnerHTML: { __html: escapeHtml(json) }
8364 }
8365 );
8366 } catch (err) {
8367 return null;
8368 }
8369 }
8370 return /* @__PURE__ */ React7.createElement("meta", { key: JSON.stringify(metaProps), ...metaProps });
8371 }));
8372}
8373function isValidMetaTag(tagName) {
8374 return typeof tagName === "string" && /^(meta|link)$/.test(tagName);
8375}
8376var isHydrated = false;
8377function setIsHydrated() {
8378 isHydrated = true;
8379}
8380function Scripts(scriptProps) {
8381 let {
8382 manifest,
8383 serverHandoffString,
8384 isSpaMode,
8385 renderMeta,
8386 routeDiscovery,
8387 ssr
8388 } = useFrameworkContext();
8389 let { router, static: isStatic, staticContext } = useDataRouterContext2();
8390 let { matches: routerMatches } = useDataRouterStateContext();
8391 let isRSCRouterContext = useIsRSCRouterContext();
8392 let enableFogOfWar = isFogOfWarEnabled(routeDiscovery, ssr);
8393 if (renderMeta) {
8394 renderMeta.didRenderScripts = true;
8395 }
8396 let matches = getActiveMatches(routerMatches, null, isSpaMode);
8397 React7.useEffect(() => {
8398 setIsHydrated();
8399 }, []);
8400 let initialScripts = React7.useMemo(() => {
8401 if (isRSCRouterContext) {
8402 return null;
8403 }
8404 let streamScript = "window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());";
8405 let contextScript = staticContext ? `window.__reactRouterContext = ${serverHandoffString};${streamScript}` : " ";
8406 let routeModulesScript = !isStatic ? " " : `${_optionalChain([manifest, 'access', _113 => _113.hmr, 'optionalAccess', _114 => _114.runtime]) ? `import ${JSON.stringify(manifest.hmr.runtime)};` : ""}${!enableFogOfWar ? `import ${JSON.stringify(manifest.url)}` : ""};
8407${matches.map((match, routeIndex) => {
8408 let routeVarName = `route${routeIndex}`;
8409 let manifestEntry = manifest.routes[match.route.id];
8410 invariant2(manifestEntry, `Route ${match.route.id} not found in manifest`);
8411 let {
8412 clientActionModule,
8413 clientLoaderModule,
8414 clientMiddlewareModule,
8415 hydrateFallbackModule,
8416 module
8417 } = manifestEntry;
8418 let chunks = [
8419 ...clientActionModule ? [
8420 {
8421 module: clientActionModule,
8422 varName: `${routeVarName}_clientAction`
8423 }
8424 ] : [],
8425 ...clientLoaderModule ? [
8426 {
8427 module: clientLoaderModule,
8428 varName: `${routeVarName}_clientLoader`
8429 }
8430 ] : [],
8431 ...clientMiddlewareModule ? [
8432 {
8433 module: clientMiddlewareModule,
8434 varName: `${routeVarName}_clientMiddleware`
8435 }
8436 ] : [],
8437 ...hydrateFallbackModule ? [
8438 {
8439 module: hydrateFallbackModule,
8440 varName: `${routeVarName}_HydrateFallback`
8441 }
8442 ] : [],
8443 { module, varName: `${routeVarName}_main` }
8444 ];
8445 if (chunks.length === 1) {
8446 return `import * as ${routeVarName} from ${JSON.stringify(module)};`;
8447 }
8448 let chunkImportsSnippet = chunks.map((chunk) => `import * as ${chunk.varName} from "${chunk.module}";`).join("\n");
8449 let mergedChunksSnippet = `const ${routeVarName} = {${chunks.map((chunk) => `...${chunk.varName}`).join(",")}};`;
8450 return [chunkImportsSnippet, mergedChunksSnippet].join("\n");
8451 }).join("\n")}
8452 ${enableFogOfWar ? (
8453 // Inline a minimal manifest with the SSR matches
8454 `window.__reactRouterManifest = ${JSON.stringify(
8455 getPartialManifest(manifest, router),
8456 null,
8457 2
8458 )};`
8459 ) : ""}
8460 window.__reactRouterRouteModules = {${matches.map((match, index) => `${JSON.stringify(match.route.id)}:route${index}`).join(",")}};
8461
8462import(${JSON.stringify(manifest.entry.module)});`;
8463 return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(
8464 "script",
8465 {
8466 ...scriptProps,
8467 suppressHydrationWarning: true,
8468 dangerouslySetInnerHTML: { __html: contextScript },
8469 type: void 0
8470 }
8471 ), /* @__PURE__ */ React7.createElement(
8472 "script",
8473 {
8474 ...scriptProps,
8475 suppressHydrationWarning: true,
8476 dangerouslySetInnerHTML: { __html: routeModulesScript },
8477 type: "module",
8478 async: true
8479 }
8480 ));
8481 }, []);
8482 let preloads = isHydrated || isRSCRouterContext ? [] : dedupe(
8483 manifest.entry.imports.concat(
8484 getModuleLinkHrefs(matches, manifest, {
8485 includeHydrateFallback: true
8486 })
8487 )
8488 );
8489 let sri = typeof manifest.sri === "object" ? manifest.sri : {};
8490 warnOnce(
8491 !isRSCRouterContext,
8492 "The <Scripts /> element is a no-op when using RSC and can be safely removed."
8493 );
8494 return isHydrated || isRSCRouterContext ? null : /* @__PURE__ */ React7.createElement(React7.Fragment, null, typeof manifest.sri === "object" ? /* @__PURE__ */ React7.createElement(
8495 "script",
8496 {
8497 "rr-importmap": "",
8498 type: "importmap",
8499 suppressHydrationWarning: true,
8500 dangerouslySetInnerHTML: {
8501 __html: JSON.stringify({
8502 integrity: sri
8503 })
8504 }
8505 }
8506 ) : null, !enableFogOfWar ? /* @__PURE__ */ React7.createElement(
8507 "link",
8508 {
8509 rel: "modulepreload",
8510 href: manifest.url,
8511 crossOrigin: scriptProps.crossOrigin,
8512 integrity: sri[manifest.url],
8513 suppressHydrationWarning: true
8514 }
8515 ) : null, /* @__PURE__ */ React7.createElement(
8516 "link",
8517 {
8518 rel: "modulepreload",
8519 href: manifest.entry.module,
8520 crossOrigin: scriptProps.crossOrigin,
8521 integrity: sri[manifest.entry.module],
8522 suppressHydrationWarning: true
8523 }
8524 ), preloads.map((path) => /* @__PURE__ */ React7.createElement(
8525 "link",
8526 {
8527 key: path,
8528 rel: "modulepreload",
8529 href: path,
8530 crossOrigin: scriptProps.crossOrigin,
8531 integrity: sri[path],
8532 suppressHydrationWarning: true
8533 }
8534 )), initialScripts);
8535}
8536function dedupe(array) {
8537 return [...new Set(array)];
8538}
8539function mergeRefs(...refs) {
8540 return (value) => {
8541 refs.forEach((ref) => {
8542 if (typeof ref === "function") {
8543 ref(value);
8544 } else if (ref != null) {
8545 ref.current = value;
8546 }
8547 });
8548 };
8549}
8550
8551// lib/dom/ssr/errorBoundaries.tsx
8552var RemixErrorBoundary = class extends React8.Component {
8553 constructor(props) {
8554 super(props);
8555 this.state = { error: props.error || null, location: props.location };
8556 }
8557 static getDerivedStateFromError(error) {
8558 return { error };
8559 }
8560 static getDerivedStateFromProps(props, state) {
8561 if (state.location !== props.location) {
8562 return { error: props.error || null, location: props.location };
8563 }
8564 return { error: props.error || state.error, location: state.location };
8565 }
8566 render() {
8567 if (this.state.error) {
8568 return /* @__PURE__ */ React8.createElement(
8569 RemixRootDefaultErrorBoundary,
8570 {
8571 error: this.state.error,
8572 isOutsideRemixApp: true
8573 }
8574 );
8575 } else {
8576 return this.props.children;
8577 }
8578 }
8579};
8580function RemixRootDefaultErrorBoundary({
8581 error,
8582 isOutsideRemixApp
8583}) {
8584 console.error(error);
8585 let heyDeveloper = /* @__PURE__ */ React8.createElement(
8586 "script",
8587 {
8588 dangerouslySetInnerHTML: {
8589 __html: `
8590 console.log(
8591 "\u{1F4BF} Hey developer \u{1F44B}. You can provide a way better UX than this when your app throws errors. Check out https://reactrouter.com/how-to/error-boundary for more information."
8592 );
8593 `
8594 }
8595 }
8596 );
8597 if (isRouteErrorResponse(error)) {
8598 return /* @__PURE__ */ React8.createElement(BoundaryShell, { title: "Unhandled Thrown Response!" }, /* @__PURE__ */ React8.createElement("h1", { style: { fontSize: "24px" } }, error.status, " ", error.statusText), ENABLE_DEV_WARNINGS ? heyDeveloper : null);
8599 }
8600 let errorInstance;
8601 if (error instanceof Error) {
8602 errorInstance = error;
8603 } else {
8604 let errorString = error == null ? "Unknown Error" : typeof error === "object" && "toString" in error ? error.toString() : JSON.stringify(error);
8605 errorInstance = new Error(errorString);
8606 }
8607 return /* @__PURE__ */ React8.createElement(
8608 BoundaryShell,
8609 {
8610 title: "Application Error!",
8611 isOutsideRemixApp
8612 },
8613 /* @__PURE__ */ React8.createElement("h1", { style: { fontSize: "24px" } }, "Application Error"),
8614 /* @__PURE__ */ React8.createElement(
8615 "pre",
8616 {
8617 style: {
8618 padding: "2rem",
8619 background: "hsla(10, 50%, 50%, 0.1)",
8620 color: "red",
8621 overflow: "auto"
8622 }
8623 },
8624 errorInstance.stack
8625 ),
8626 heyDeveloper
8627 );
8628}
8629function BoundaryShell({
8630 title,
8631 renderScripts,
8632 isOutsideRemixApp,
8633 children
8634}) {
8635 let { routeModules } = useFrameworkContext();
8636 if (_optionalChain([routeModules, 'access', _115 => _115.root, 'optionalAccess', _116 => _116.Layout]) && !isOutsideRemixApp) {
8637 return children;
8638 }
8639 return /* @__PURE__ */ React8.createElement("html", { lang: "en" }, /* @__PURE__ */ React8.createElement("head", null, /* @__PURE__ */ React8.createElement("meta", { charSet: "utf-8" }), /* @__PURE__ */ React8.createElement(
8640 "meta",
8641 {
8642 name: "viewport",
8643 content: "width=device-width,initial-scale=1,viewport-fit=cover"
8644 }
8645 ), /* @__PURE__ */ React8.createElement("title", null, title)), /* @__PURE__ */ React8.createElement("body", null, /* @__PURE__ */ React8.createElement("main", { style: { fontFamily: "system-ui, sans-serif", padding: "2rem" } }, children, renderScripts ? /* @__PURE__ */ React8.createElement(Scripts, null) : null)));
8646}
8647
8648// lib/components.tsx
8649
8650var USE_OPTIMISTIC = "useOptimistic";
8651var useOptimisticImpl = React9[USE_OPTIMISTIC];
8652function useOptimisticSafe(val) {
8653 if (useOptimisticImpl) {
8654 return useOptimisticImpl(val);
8655 } else {
8656 return [val, () => void 0];
8657 }
8658}
8659function mapRouteProperties(route) {
8660 let updates = {
8661 // Note: this check also occurs in createRoutesFromChildren so update
8662 // there if you change this -- please and thank you!
8663 hasErrorBoundary: route.hasErrorBoundary || route.ErrorBoundary != null || route.errorElement != null
8664 };
8665 if (route.Component) {
8666 if (ENABLE_DEV_WARNINGS) {
8667 if (route.element) {
8668 warning(
8669 false,
8670 "You should not include both `Component` and `element` on your route - `Component` will be used."
8671 );
8672 }
8673 }
8674 Object.assign(updates, {
8675 element: React9.createElement(route.Component),
8676 Component: void 0
8677 });
8678 }
8679 if (route.HydrateFallback) {
8680 if (ENABLE_DEV_WARNINGS) {
8681 if (route.hydrateFallbackElement) {
8682 warning(
8683 false,
8684 "You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - `HydrateFallback` will be used."
8685 );
8686 }
8687 }
8688 Object.assign(updates, {
8689 hydrateFallbackElement: React9.createElement(route.HydrateFallback),
8690 HydrateFallback: void 0
8691 });
8692 }
8693 if (route.ErrorBoundary) {
8694 if (ENABLE_DEV_WARNINGS) {
8695 if (route.errorElement) {
8696 warning(
8697 false,
8698 "You should not include both `ErrorBoundary` and `errorElement` on your route - `ErrorBoundary` will be used."
8699 );
8700 }
8701 }
8702 Object.assign(updates, {
8703 errorElement: React9.createElement(route.ErrorBoundary),
8704 ErrorBoundary: void 0
8705 });
8706 }
8707 return updates;
8708}
8709var hydrationRouteProperties = [
8710 "HydrateFallback",
8711 "hydrateFallbackElement"
8712];
8713function createMemoryRouter(routes, opts) {
8714 return createRouter({
8715 basename: _optionalChain([opts, 'optionalAccess', _117 => _117.basename]),
8716 getContext: _optionalChain([opts, 'optionalAccess', _118 => _118.getContext]),
8717 future: _optionalChain([opts, 'optionalAccess', _119 => _119.future]),
8718 history: createMemoryHistory({
8719 initialEntries: _optionalChain([opts, 'optionalAccess', _120 => _120.initialEntries]),
8720 initialIndex: _optionalChain([opts, 'optionalAccess', _121 => _121.initialIndex])
8721 }),
8722 hydrationData: _optionalChain([opts, 'optionalAccess', _122 => _122.hydrationData]),
8723 routes,
8724 hydrationRouteProperties,
8725 mapRouteProperties,
8726 dataStrategy: _optionalChain([opts, 'optionalAccess', _123 => _123.dataStrategy]),
8727 patchRoutesOnNavigation: _optionalChain([opts, 'optionalAccess', _124 => _124.patchRoutesOnNavigation]),
8728 unstable_instrumentations: _optionalChain([opts, 'optionalAccess', _125 => _125.unstable_instrumentations])
8729 }).initialize();
8730}
8731var Deferred2 = class {
8732 constructor() {
8733 this.status = "pending";
8734 this.promise = new Promise((resolve, reject) => {
8735 this.resolve = (value) => {
8736 if (this.status === "pending") {
8737 this.status = "resolved";
8738 resolve(value);
8739 }
8740 };
8741 this.reject = (reason) => {
8742 if (this.status === "pending") {
8743 this.status = "rejected";
8744 reject(reason);
8745 }
8746 };
8747 });
8748 }
8749};
8750function RouterProvider({
8751 router,
8752 flushSync: reactDomFlushSyncImpl,
8753 unstable_onError,
8754 unstable_useTransitions
8755}) {
8756 let [_state, setStateImpl] = React9.useState(router.state);
8757 let [state, setOptimisticState] = useOptimisticSafe(_state);
8758 let [pendingState, setPendingState] = React9.useState();
8759 let [vtContext, setVtContext] = React9.useState({
8760 isTransitioning: false
8761 });
8762 let [renderDfd, setRenderDfd] = React9.useState();
8763 let [transition, setTransition] = React9.useState();
8764 let [interruption, setInterruption] = React9.useState();
8765 let fetcherData = React9.useRef(/* @__PURE__ */ new Map());
8766 let setState = React9.useCallback(
8767 (newState, { deletedFetchers, newErrors, flushSync, viewTransitionOpts }) => {
8768 if (newErrors && unstable_onError) {
8769 Object.values(newErrors).forEach(
8770 (error) => unstable_onError(error, {
8771 location: newState.location,
8772 params: _nullishCoalesce(_optionalChain([newState, 'access', _126 => _126.matches, 'access', _127 => _127[0], 'optionalAccess', _128 => _128.params]), () => ( {})),
8773 unstable_pattern: getRoutePattern(newState.matches)
8774 })
8775 );
8776 }
8777 newState.fetchers.forEach((fetcher, key) => {
8778 if (fetcher.data !== void 0) {
8779 fetcherData.current.set(key, fetcher.data);
8780 }
8781 });
8782 deletedFetchers.forEach((key) => fetcherData.current.delete(key));
8783 warnOnce(
8784 flushSync === false || reactDomFlushSyncImpl != null,
8785 'You provided the `flushSync` option to a router update, but you are not using the `<RouterProvider>` from `react-router/dom` so `ReactDOM.flushSync()` is unavailable. Please update your app to `import { RouterProvider } from "react-router/dom"` and ensure you have `react-dom` installed as a dependency to use the `flushSync` option.'
8786 );
8787 let isViewTransitionAvailable = router.window != null && router.window.document != null && typeof router.window.document.startViewTransition === "function";
8788 warnOnce(
8789 viewTransitionOpts == null || isViewTransitionAvailable,
8790 "You provided the `viewTransition` option to a router update, but you do not appear to be running in a DOM environment as `window.startViewTransition` is not available."
8791 );
8792 if (!viewTransitionOpts || !isViewTransitionAvailable) {
8793 if (reactDomFlushSyncImpl && flushSync) {
8794 reactDomFlushSyncImpl(() => setStateImpl(newState));
8795 } else if (unstable_useTransitions === false) {
8796 setStateImpl(newState);
8797 } else {
8798 React9.startTransition(() => {
8799 if (unstable_useTransitions === true) {
8800 setOptimisticState((s) => getOptimisticRouterState(s, newState));
8801 }
8802 setStateImpl(newState);
8803 });
8804 }
8805 return;
8806 }
8807 if (reactDomFlushSyncImpl && flushSync) {
8808 reactDomFlushSyncImpl(() => {
8809 if (transition) {
8810 _optionalChain([renderDfd, 'optionalAccess', _129 => _129.resolve, 'call', _130 => _130()]);
8811 transition.skipTransition();
8812 }
8813 setVtContext({
8814 isTransitioning: true,
8815 flushSync: true,
8816 currentLocation: viewTransitionOpts.currentLocation,
8817 nextLocation: viewTransitionOpts.nextLocation
8818 });
8819 });
8820 let t = router.window.document.startViewTransition(() => {
8821 reactDomFlushSyncImpl(() => setStateImpl(newState));
8822 });
8823 t.finished.finally(() => {
8824 reactDomFlushSyncImpl(() => {
8825 setRenderDfd(void 0);
8826 setTransition(void 0);
8827 setPendingState(void 0);
8828 setVtContext({ isTransitioning: false });
8829 });
8830 });
8831 reactDomFlushSyncImpl(() => setTransition(t));
8832 return;
8833 }
8834 if (transition) {
8835 _optionalChain([renderDfd, 'optionalAccess', _131 => _131.resolve, 'call', _132 => _132()]);
8836 transition.skipTransition();
8837 setInterruption({
8838 state: newState,
8839 currentLocation: viewTransitionOpts.currentLocation,
8840 nextLocation: viewTransitionOpts.nextLocation
8841 });
8842 } else {
8843 setPendingState(newState);
8844 setVtContext({
8845 isTransitioning: true,
8846 flushSync: false,
8847 currentLocation: viewTransitionOpts.currentLocation,
8848 nextLocation: viewTransitionOpts.nextLocation
8849 });
8850 }
8851 },
8852 [
8853 router.window,
8854 reactDomFlushSyncImpl,
8855 transition,
8856 renderDfd,
8857 unstable_useTransitions,
8858 setOptimisticState,
8859 unstable_onError
8860 ]
8861 );
8862 React9.useLayoutEffect(() => router.subscribe(setState), [router, setState]);
8863 React9.useEffect(() => {
8864 if (vtContext.isTransitioning && !vtContext.flushSync) {
8865 setRenderDfd(new Deferred2());
8866 }
8867 }, [vtContext]);
8868 React9.useEffect(() => {
8869 if (renderDfd && pendingState && router.window) {
8870 let newState = pendingState;
8871 let renderPromise = renderDfd.promise;
8872 let transition2 = router.window.document.startViewTransition(async () => {
8873 if (unstable_useTransitions === false) {
8874 setStateImpl(newState);
8875 } else {
8876 React9.startTransition(() => {
8877 if (unstable_useTransitions === true) {
8878 setOptimisticState((s) => getOptimisticRouterState(s, newState));
8879 }
8880 setStateImpl(newState);
8881 });
8882 }
8883 await renderPromise;
8884 });
8885 transition2.finished.finally(() => {
8886 setRenderDfd(void 0);
8887 setTransition(void 0);
8888 setPendingState(void 0);
8889 setVtContext({ isTransitioning: false });
8890 });
8891 setTransition(transition2);
8892 }
8893 }, [
8894 pendingState,
8895 renderDfd,
8896 router.window,
8897 unstable_useTransitions,
8898 setOptimisticState
8899 ]);
8900 React9.useEffect(() => {
8901 if (renderDfd && pendingState && state.location.key === pendingState.location.key) {
8902 renderDfd.resolve();
8903 }
8904 }, [renderDfd, transition, state.location, pendingState]);
8905 React9.useEffect(() => {
8906 if (!vtContext.isTransitioning && interruption) {
8907 setPendingState(interruption.state);
8908 setVtContext({
8909 isTransitioning: true,
8910 flushSync: false,
8911 currentLocation: interruption.currentLocation,
8912 nextLocation: interruption.nextLocation
8913 });
8914 setInterruption(void 0);
8915 }
8916 }, [vtContext.isTransitioning, interruption]);
8917 let navigator = React9.useMemo(() => {
8918 return {
8919 createHref: router.createHref,
8920 encodeLocation: router.encodeLocation,
8921 go: (n) => router.navigate(n),
8922 push: (to, state2, opts) => router.navigate(to, {
8923 state: state2,
8924 preventScrollReset: _optionalChain([opts, 'optionalAccess', _133 => _133.preventScrollReset])
8925 }),
8926 replace: (to, state2, opts) => router.navigate(to, {
8927 replace: true,
8928 state: state2,
8929 preventScrollReset: _optionalChain([opts, 'optionalAccess', _134 => _134.preventScrollReset])
8930 })
8931 };
8932 }, [router]);
8933 let basename = router.basename || "/";
8934 let dataRouterContext = React9.useMemo(
8935 () => ({
8936 router,
8937 navigator,
8938 static: false,
8939 basename,
8940 unstable_onError
8941 }),
8942 [router, navigator, basename, unstable_onError]
8943 );
8944 return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(DataRouterContext.Provider, { value: dataRouterContext }, /* @__PURE__ */ React9.createElement(DataRouterStateContext.Provider, { value: state }, /* @__PURE__ */ React9.createElement(FetchersContext.Provider, { value: fetcherData.current }, /* @__PURE__ */ React9.createElement(ViewTransitionContext.Provider, { value: vtContext }, /* @__PURE__ */ React9.createElement(
8945 Router,
8946 {
8947 basename,
8948 location: state.location,
8949 navigationType: state.historyAction,
8950 navigator,
8951 unstable_useTransitions: unstable_useTransitions === true
8952 },
8953 /* @__PURE__ */ React9.createElement(
8954 MemoizedDataRoutes,
8955 {
8956 routes: router.routes,
8957 future: router.future,
8958 state,
8959 unstable_onError
8960 }
8961 )
8962 ))))), null);
8963}
8964function getOptimisticRouterState(currentState, newState) {
8965 return {
8966 // Don't surface "current location specific" stuff mid-navigation
8967 // (historyAction, location, matches, loaderData, errors, initialized,
8968 // restoreScroll, preventScrollReset, blockers, etc.)
8969 ...currentState,
8970 // Only surface "pending/in-flight stuff"
8971 // (navigation, revalidation, actionData, fetchers, )
8972 navigation: newState.navigation.state !== "idle" ? newState.navigation : currentState.navigation,
8973 revalidation: newState.revalidation !== "idle" ? newState.revalidation : currentState.revalidation,
8974 actionData: newState.navigation.state !== "submitting" ? newState.actionData : currentState.actionData,
8975 fetchers: newState.fetchers
8976 };
8977}
8978var MemoizedDataRoutes = React9.memo(DataRoutes);
8979function DataRoutes({
8980 routes,
8981 future,
8982 state,
8983 unstable_onError
8984}) {
8985 return useRoutesImpl(routes, void 0, state, unstable_onError, future);
8986}
8987function MemoryRouter({
8988 basename,
8989 children,
8990 initialEntries,
8991 initialIndex,
8992 unstable_useTransitions
8993}) {
8994 let historyRef = React9.useRef();
8995 if (historyRef.current == null) {
8996 historyRef.current = createMemoryHistory({
8997 initialEntries,
8998 initialIndex,
8999 v5Compat: true
9000 });
9001 }
9002 let history = historyRef.current;
9003 let [state, setStateImpl] = React9.useState({
9004 action: history.action,
9005 location: history.location
9006 });
9007 let setState = React9.useCallback(
9008 (newState) => {
9009 if (unstable_useTransitions === false) {
9010 setStateImpl(newState);
9011 } else {
9012 React9.startTransition(() => setStateImpl(newState));
9013 }
9014 },
9015 [unstable_useTransitions]
9016 );
9017 React9.useLayoutEffect(() => history.listen(setState), [history, setState]);
9018 return /* @__PURE__ */ React9.createElement(
9019 Router,
9020 {
9021 basename,
9022 children,
9023 location: state.location,
9024 navigationType: state.action,
9025 navigator: history,
9026 unstable_useTransitions: unstable_useTransitions === true
9027 }
9028 );
9029}
9030function Navigate({
9031 to,
9032 replace: replace2,
9033 state,
9034 relative
9035}) {
9036 invariant(
9037 useInRouterContext(),
9038 // TODO: This error is probably because they somehow have 2 versions of
9039 // the router loaded. We can help them understand how to avoid that.
9040 `<Navigate> may be used only in the context of a <Router> component.`
9041 );
9042 let { static: isStatic } = React9.useContext(NavigationContext);
9043 warning(
9044 !isStatic,
9045 `<Navigate> must not be used on the initial render in a <StaticRouter>. This is a no-op, but you should modify your code so the <Navigate> is only ever rendered in response to some user interaction or state change.`
9046 );
9047 let { matches } = React9.useContext(RouteContext);
9048 let { pathname: locationPathname } = useLocation();
9049 let navigate = useNavigate();
9050 let path = resolveTo(
9051 to,
9052 getResolveToMatches(matches),
9053 locationPathname,
9054 relative === "path"
9055 );
9056 let jsonPath = JSON.stringify(path);
9057 React9.useEffect(() => {
9058 navigate(JSON.parse(jsonPath), { replace: replace2, state, relative });
9059 }, [navigate, jsonPath, relative, replace2, state]);
9060 return null;
9061}
9062function Outlet(props) {
9063 return useOutlet(props.context);
9064}
9065function Route(props) {
9066 invariant(
9067 false,
9068 `A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.`
9069 );
9070}
9071function Router({
9072 basename: basenameProp = "/",
9073 children = null,
9074 location: locationProp,
9075 navigationType = "POP" /* Pop */,
9076 navigator,
9077 static: staticProp = false,
9078 unstable_useTransitions
9079}) {
9080 invariant(
9081 !useInRouterContext(),
9082 `You cannot render a <Router> inside another <Router>. You should never have more than one in your app.`
9083 );
9084 let basename = basenameProp.replace(/^\/*/, "/");
9085 let navigationContext = React9.useMemo(
9086 () => ({
9087 basename,
9088 navigator,
9089 static: staticProp,
9090 unstable_useTransitions,
9091 future: {}
9092 }),
9093 [basename, navigator, staticProp, unstable_useTransitions]
9094 );
9095 if (typeof locationProp === "string") {
9096 locationProp = parsePath(locationProp);
9097 }
9098 let {
9099 pathname = "/",
9100 search = "",
9101 hash = "",
9102 state = null,
9103 key = "default"
9104 } = locationProp;
9105 let locationContext = React9.useMemo(() => {
9106 let trailingPathname = stripBasename(pathname, basename);
9107 if (trailingPathname == null) {
9108 return null;
9109 }
9110 return {
9111 location: {
9112 pathname: trailingPathname,
9113 search,
9114 hash,
9115 state,
9116 key
9117 },
9118 navigationType
9119 };
9120 }, [basename, pathname, search, hash, state, key, navigationType]);
9121 warning(
9122 locationContext != null,
9123 `<Router basename="${basename}"> is not able to match the URL "${pathname}${search}${hash}" because it does not start with the basename, so the <Router> won't render anything.`
9124 );
9125 if (locationContext == null) {
9126 return null;
9127 }
9128 return /* @__PURE__ */ React9.createElement(NavigationContext.Provider, { value: navigationContext }, /* @__PURE__ */ React9.createElement(LocationContext.Provider, { children, value: locationContext }));
9129}
9130function Routes({
9131 children,
9132 location
9133}) {
9134 return useRoutes(createRoutesFromChildren(children), location);
9135}
9136function Await({
9137 children,
9138 errorElement,
9139 resolve
9140}) {
9141 let dataRouterContext = React9.useContext(DataRouterContext);
9142 let dataRouterStateContext = React9.useContext(DataRouterStateContext);
9143 let onError = React9.useCallback(
9144 (error, errorInfo) => {
9145 if (dataRouterContext && dataRouterContext.unstable_onError && dataRouterStateContext) {
9146 dataRouterContext.unstable_onError(error, {
9147 location: dataRouterStateContext.location,
9148 params: _optionalChain([dataRouterStateContext, 'access', _135 => _135.matches, 'access', _136 => _136[0], 'optionalAccess', _137 => _137.params]) || {},
9149 unstable_pattern: getRoutePattern(dataRouterStateContext.matches),
9150 errorInfo
9151 });
9152 }
9153 },
9154 [dataRouterContext, dataRouterStateContext]
9155 );
9156 return /* @__PURE__ */ React9.createElement(
9157 AwaitErrorBoundary,
9158 {
9159 resolve,
9160 errorElement,
9161 onError
9162 },
9163 /* @__PURE__ */ React9.createElement(ResolveAwait, null, children)
9164 );
9165}
9166var AwaitErrorBoundary = class extends React9.Component {
9167 constructor(props) {
9168 super(props);
9169 this.state = { error: null };
9170 }
9171 static getDerivedStateFromError(error) {
9172 return { error };
9173 }
9174 componentDidCatch(error, errorInfo) {
9175 if (this.props.onError) {
9176 this.props.onError(error, errorInfo);
9177 } else {
9178 console.error(
9179 "<Await> caught the following error during render",
9180 error,
9181 errorInfo
9182 );
9183 }
9184 }
9185 render() {
9186 let { children, errorElement, resolve } = this.props;
9187 let promise = null;
9188 let status = 0 /* pending */;
9189 if (!(resolve instanceof Promise)) {
9190 status = 1 /* success */;
9191 promise = Promise.resolve();
9192 Object.defineProperty(promise, "_tracked", { get: () => true });
9193 Object.defineProperty(promise, "_data", { get: () => resolve });
9194 } else if (this.state.error) {
9195 status = 2 /* error */;
9196 let renderError = this.state.error;
9197 promise = Promise.reject().catch(() => {
9198 });
9199 Object.defineProperty(promise, "_tracked", { get: () => true });
9200 Object.defineProperty(promise, "_error", { get: () => renderError });
9201 } else if (resolve._tracked) {
9202 promise = resolve;
9203 status = "_error" in promise ? 2 /* error */ : "_data" in promise ? 1 /* success */ : 0 /* pending */;
9204 } else {
9205 status = 0 /* pending */;
9206 Object.defineProperty(resolve, "_tracked", { get: () => true });
9207 promise = resolve.then(
9208 (data2) => Object.defineProperty(resolve, "_data", { get: () => data2 }),
9209 (error) => {
9210 _optionalChain([this, 'access', _138 => _138.props, 'access', _139 => _139.onError, 'optionalCall', _140 => _140(error)]);
9211 Object.defineProperty(resolve, "_error", { get: () => error });
9212 }
9213 );
9214 }
9215 if (status === 2 /* error */ && !errorElement) {
9216 throw promise._error;
9217 }
9218 if (status === 2 /* error */) {
9219 return /* @__PURE__ */ React9.createElement(AwaitContext.Provider, { value: promise, children: errorElement });
9220 }
9221 if (status === 1 /* success */) {
9222 return /* @__PURE__ */ React9.createElement(AwaitContext.Provider, { value: promise, children });
9223 }
9224 throw promise;
9225 }
9226};
9227function ResolveAwait({
9228 children
9229}) {
9230 let data2 = useAsyncValue();
9231 let toRender = typeof children === "function" ? children(data2) : children;
9232 return /* @__PURE__ */ React9.createElement(React9.Fragment, null, toRender);
9233}
9234function createRoutesFromChildren(children, parentPath = []) {
9235 let routes = [];
9236 React9.Children.forEach(children, (element, index) => {
9237 if (!React9.isValidElement(element)) {
9238 return;
9239 }
9240 let treePath = [...parentPath, index];
9241 if (element.type === React9.Fragment) {
9242 routes.push.apply(
9243 routes,
9244 createRoutesFromChildren(element.props.children, treePath)
9245 );
9246 return;
9247 }
9248 invariant(
9249 element.type === Route,
9250 `[${typeof element.type === "string" ? element.type : element.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`
9251 );
9252 invariant(
9253 !element.props.index || !element.props.children,
9254 "An index route cannot have child routes."
9255 );
9256 let route = {
9257 id: element.props.id || treePath.join("-"),
9258 caseSensitive: element.props.caseSensitive,
9259 element: element.props.element,
9260 Component: element.props.Component,
9261 index: element.props.index,
9262 path: element.props.path,
9263 middleware: element.props.middleware,
9264 loader: element.props.loader,
9265 action: element.props.action,
9266 hydrateFallbackElement: element.props.hydrateFallbackElement,
9267 HydrateFallback: element.props.HydrateFallback,
9268 errorElement: element.props.errorElement,
9269 ErrorBoundary: element.props.ErrorBoundary,
9270 hasErrorBoundary: element.props.hasErrorBoundary === true || element.props.ErrorBoundary != null || element.props.errorElement != null,
9271 shouldRevalidate: element.props.shouldRevalidate,
9272 handle: element.props.handle,
9273 lazy: element.props.lazy
9274 };
9275 if (element.props.children) {
9276 route.children = createRoutesFromChildren(
9277 element.props.children,
9278 treePath
9279 );
9280 }
9281 routes.push(route);
9282 });
9283 return routes;
9284}
9285var createRoutesFromElements = createRoutesFromChildren;
9286function renderMatches(matches) {
9287 return _renderMatches(matches);
9288}
9289function useRouteComponentProps() {
9290 return {
9291 params: useParams(),
9292 loaderData: useLoaderData(),
9293 actionData: useActionData(),
9294 matches: useMatches()
9295 };
9296}
9297function WithComponentProps({
9298 children
9299}) {
9300 const props = useRouteComponentProps();
9301 return React9.cloneElement(children, props);
9302}
9303function withComponentProps(Component4) {
9304 return function WithComponentProps2() {
9305 const props = useRouteComponentProps();
9306 return React9.createElement(Component4, props);
9307 };
9308}
9309function useHydrateFallbackProps() {
9310 return {
9311 params: useParams(),
9312 loaderData: useLoaderData(),
9313 actionData: useActionData()
9314 };
9315}
9316function WithHydrateFallbackProps({
9317 children
9318}) {
9319 const props = useHydrateFallbackProps();
9320 return React9.cloneElement(children, props);
9321}
9322function withHydrateFallbackProps(HydrateFallback) {
9323 return function WithHydrateFallbackProps2() {
9324 const props = useHydrateFallbackProps();
9325 return React9.createElement(HydrateFallback, props);
9326 };
9327}
9328function useErrorBoundaryProps() {
9329 return {
9330 params: useParams(),
9331 loaderData: useLoaderData(),
9332 actionData: useActionData(),
9333 error: useRouteError()
9334 };
9335}
9336function WithErrorBoundaryProps({
9337 children
9338}) {
9339 const props = useErrorBoundaryProps();
9340 return React9.cloneElement(children, props);
9341}
9342function withErrorBoundaryProps(ErrorBoundary) {
9343 return function WithErrorBoundaryProps2() {
9344 const props = useErrorBoundaryProps();
9345 return React9.createElement(ErrorBoundary, props);
9346 };
9347}
9348
9349
9350
9351
9352
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
9364
9365
9366
9367
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440
9441
9442
9443
9444
9445
9446
9447
9448
9449
9450
9451
9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463
9464
9465
9466
9467
9468
9469exports.Action = Action; exports.createBrowserHistory = createBrowserHistory; exports.createHashHistory = createHashHistory; exports.invariant = invariant; exports.warning = warning; exports.createPath = createPath; exports.parsePath = parsePath; exports.createContext = createContext; exports.RouterContextProvider = RouterContextProvider; exports.convertRoutesToDataRoutes = convertRoutesToDataRoutes; exports.matchRoutes = matchRoutes; exports.generatePath = generatePath; exports.matchPath = matchPath; exports.stripBasename = stripBasename; exports.resolvePath = resolvePath; exports.joinPaths = joinPaths; exports.data = data; exports.redirect = redirect; exports.redirectDocument = redirectDocument; exports.replace = replace; exports.ErrorResponseImpl = ErrorResponseImpl; exports.isRouteErrorResponse = isRouteErrorResponse; exports.escapeHtml = escapeHtml; exports.encode = encode; exports.instrumentHandler = instrumentHandler; exports.IDLE_NAVIGATION = IDLE_NAVIGATION; exports.IDLE_FETCHER = IDLE_FETCHER; exports.IDLE_BLOCKER = IDLE_BLOCKER; exports.createRouter = createRouter; exports.createStaticHandler = createStaticHandler; exports.getStaticContextFromError = getStaticContextFromError; exports.isDataWithResponseInit = isDataWithResponseInit; exports.isResponse = isResponse; exports.isRedirectStatusCode = isRedirectStatusCode; exports.isRedirectResponse = isRedirectResponse; exports.isMutationMethod = isMutationMethod; exports.createRequestInit = createRequestInit; exports.SingleFetchRedirectSymbol = SingleFetchRedirectSymbol; exports.SINGLE_FETCH_REDIRECT_STATUS = SINGLE_FETCH_REDIRECT_STATUS; exports.NO_BODY_STATUS_CODES = NO_BODY_STATUS_CODES; exports.StreamTransfer = StreamTransfer; exports.getTurboStreamSingleFetchDataStrategy = getTurboStreamSingleFetchDataStrategy; exports.getSingleFetchDataStrategyImpl = getSingleFetchDataStrategyImpl; exports.stripIndexParam = stripIndexParam; exports.singleFetchUrl = singleFetchUrl; exports.decodeViaTurboStream = decodeViaTurboStream; exports.DataRouterContext = DataRouterContext; exports.DataRouterStateContext = DataRouterStateContext; exports.RSCRouterContext = RSCRouterContext; exports.ViewTransitionContext = ViewTransitionContext; exports.FetchersContext = FetchersContext; exports.AwaitContextProvider = AwaitContextProvider; exports.NavigationContext = NavigationContext; exports.LocationContext = LocationContext; exports.RouteContext = RouteContext; exports.ENABLE_DEV_WARNINGS = ENABLE_DEV_WARNINGS; exports.warnOnce = warnOnce; exports.useHref = useHref; exports.useInRouterContext = useInRouterContext; exports.useLocation = useLocation; exports.useNavigationType = useNavigationType; exports.useMatch = useMatch; exports.useNavigate = useNavigate; exports.useOutletContext = useOutletContext; exports.useOutlet = useOutlet; exports.useParams = useParams; exports.useResolvedPath = useResolvedPath; exports.useRoutes = useRoutes; exports.useRoutesImpl = useRoutesImpl; exports.useRouteId = useRouteId; exports.useNavigation = useNavigation; exports.useRevalidator = useRevalidator; exports.useMatches = useMatches; exports.useLoaderData = useLoaderData; exports.useRouteLoaderData = useRouteLoaderData; exports.useActionData = useActionData; exports.useRouteError = useRouteError; exports.useAsyncValue = useAsyncValue; exports.useAsyncError = useAsyncError; exports.useBlocker = useBlocker; exports.useRoute = useRoute; exports.RemixErrorBoundary = RemixErrorBoundary; exports.createServerRoutes = createServerRoutes; exports.createClientRoutesWithHMRRevalidationOptOut = createClientRoutesWithHMRRevalidationOptOut; exports.noActionDefinedError = noActionDefinedError; exports.createClientRoutes = createClientRoutes; exports.shouldHydrateRouteLoader = shouldHydrateRouteLoader; exports.getPatchRoutesOnNavigationFunction = getPatchRoutesOnNavigationFunction; exports.useFogOFWarDiscovery = useFogOFWarDiscovery; exports.getManifestPath = getManifestPath; exports.FrameworkContext = FrameworkContext; exports.usePrefetchBehavior = usePrefetchBehavior; exports.CRITICAL_CSS_DATA_ATTRIBUTE = CRITICAL_CSS_DATA_ATTRIBUTE; exports.Links = Links; exports.PrefetchPageLinks = PrefetchPageLinks; exports.Meta = Meta; exports.setIsHydrated = setIsHydrated; exports.Scripts = Scripts; exports.mergeRefs = mergeRefs; exports.mapRouteProperties = mapRouteProperties; exports.hydrationRouteProperties = hydrationRouteProperties; exports.createMemoryRouter = createMemoryRouter; exports.RouterProvider = RouterProvider; exports.MemoryRouter = MemoryRouter; exports.Navigate = Navigate; exports.Outlet = Outlet; exports.Route = Route; exports.Router = Router; exports.Routes = Routes; exports.Await = Await; exports.createRoutesFromChildren = createRoutesFromChildren; exports.createRoutesFromElements = createRoutesFromElements; exports.renderMatches = renderMatches; exports.WithComponentProps = WithComponentProps; exports.withComponentProps = withComponentProps; exports.WithHydrateFallbackProps = WithHydrateFallbackProps; exports.withHydrateFallbackProps = withHydrateFallbackProps; exports.WithErrorBoundaryProps = WithErrorBoundaryProps; exports.withErrorBoundaryProps = withErrorBoundaryProps;