UNPKG

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