UNPKG

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