react-router 7.0.0-pre.1 → 7.0.0-pre.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/dom-export.mjs +10 -2
  3. package/dist/dom-export.mjs.map +1 -1
  4. package/dist/index.d.ts +2 -3
  5. package/dist/index.mjs +1375 -219
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/lib/components.d.ts +6 -6
  8. package/dist/lib/dom/lib.d.ts +3 -2
  9. package/dist/lib/dom/ssr/components.d.ts +0 -1
  10. package/dist/lib/dom/ssr/data.d.ts +0 -5
  11. package/dist/lib/dom/ssr/entry.d.ts +2 -1
  12. package/dist/lib/dom/ssr/routeModules.d.ts +64 -22
  13. package/dist/lib/dom/ssr/routes.d.ts +2 -5
  14. package/dist/lib/hooks.d.ts +4 -3
  15. package/dist/lib/router/router.d.ts +4 -0
  16. package/dist/lib/router/utils.d.ts +1 -9
  17. package/dist/lib/server-runtime/build.d.ts +1 -1
  18. package/dist/lib/server-runtime/cookies.d.ts +5 -5
  19. package/dist/lib/server-runtime/data.d.ts +1 -5
  20. package/dist/lib/server-runtime/routeModules.d.ts +3 -175
  21. package/dist/lib/server-runtime/routes.d.ts +2 -22
  22. package/dist/lib/server-runtime/sessions.d.ts +4 -4
  23. package/dist/lib/types.d.ts +17 -10
  24. package/dist/lib/types.mjs +1 -1
  25. package/dist/main-dom-export.js +1 -1
  26. package/dist/main.js +1 -1
  27. package/dist/react-router-dom.development.js +2 -2
  28. package/dist/react-router-dom.development.js.map +1 -1
  29. package/dist/react-router-dom.production.min.js +2 -2
  30. package/dist/react-router-dom.production.min.js.map +1 -1
  31. package/dist/react-router.development.js +196 -171
  32. package/dist/react-router.development.js.map +1 -1
  33. package/dist/react-router.production.min.js +2 -2
  34. package/dist/react-router.production.min.js.map +1 -1
  35. package/dist/umd/react-router-dom.development.js +2 -2
  36. package/dist/umd/react-router-dom.development.js.map +1 -1
  37. package/dist/umd/react-router-dom.production.min.js +2 -2
  38. package/dist/umd/react-router-dom.production.min.js.map +1 -1
  39. package/dist/umd/react-router.development.js +195 -179
  40. package/dist/umd/react-router.development.js.map +1 -1
  41. package/dist/umd/react-router.production.min.js +2 -2
  42. package/dist/umd/react-router.production.min.js.map +1 -1
  43. package/package.json +4 -4
  44. package/dist/lib/server-runtime/jsonify.d.ts +0 -33
  45. package/dist/lib/server-runtime/responses.d.ts +0 -37
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * React Router v7.0.0-pre.1
2
+ * React Router v7.0.0-pre.2
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -43,32 +43,69 @@ function _objectWithoutPropertiesLoose(source, excluded) {
43
43
  ////////////////////////////////////////////////////////////////////////////////
44
44
  //#region Types and Constants
45
45
  ////////////////////////////////////////////////////////////////////////////////
46
+
46
47
  /**
47
48
  * Actions represent the type of change to a location value.
48
49
  */
49
- var Action;
50
- (function (Action) {
51
- /**
52
- * A POP indicates a change to an arbitrary index in the history stack, such
53
- * as a back or forward navigation. It does not describe the direction of the
54
- * navigation, only that the current index changed.
55
- *
56
- * Note: This is the default action for newly created history objects.
57
- */
50
+ let Action = /*#__PURE__*/function (Action) {
58
51
  Action["Pop"] = "POP";
59
- /**
60
- * A PUSH indicates a new entry being added to the history stack, such as when
61
- * a link is clicked and a new page loads. When this happens, all subsequent
62
- * entries in the stack are lost.
63
- */
64
52
  Action["Push"] = "PUSH";
65
- /**
66
- * A REPLACE indicates the entry at the current index in the history stack
67
- * being replaced by a new one.
68
- */
69
53
  Action["Replace"] = "REPLACE";
70
- })(Action || (Action = {}));
54
+ return Action;
55
+ }({});
56
+
57
+ /**
58
+ * The pathname, search, and hash values of a URL.
59
+ */
60
+
61
+ // TODO: (v7) Change the Location generic default from `any` to `unknown` and
62
+ // remove Remix `useLocation` wrapper.
63
+
64
+ /**
65
+ * An entry in a history stack. A location contains information about the
66
+ * URL path, as well as possibly some arbitrary state and a key.
67
+ */
68
+
69
+ /**
70
+ * A change to the current location.
71
+ */
72
+
73
+ /**
74
+ * A function that receives notifications about location changes.
75
+ */
76
+
77
+ /**
78
+ * Describes a location that is the destination of some navigation used in
79
+ * {@link Link}, {@link useNavigate}, etc.
80
+ */
81
+
82
+ /**
83
+ * A history is an interface to the navigation stack. The history serves as the
84
+ * source of truth for the current location, as well as provides a set of
85
+ * methods that may be used to change it.
86
+ *
87
+ * It is similar to the DOM's `window.history` object, but with a smaller, more
88
+ * focused API.
89
+ */
90
+
71
91
  const PopStateEventType = "popstate";
92
+ //#endregion
93
+
94
+ ////////////////////////////////////////////////////////////////////////////////
95
+ //#region Memory History
96
+ ////////////////////////////////////////////////////////////////////////////////
97
+
98
+ /**
99
+ * A user-supplied object that describes a location. Used when providing
100
+ * entries to `createMemoryHistory` via its `initialEntries` option.
101
+ */
102
+
103
+ /**
104
+ * A memory history stores locations in memory. This is useful in stateful
105
+ * environments where there is no web browser, such as node tests or React
106
+ * Native.
107
+ */
108
+
72
109
  /**
73
110
  * Memory history stores the current location in memory. It is designed for use
74
111
  * in stateful non-browser environments like tests and React Native.
@@ -173,6 +210,20 @@ function createMemoryHistory(options) {
173
210
  };
174
211
  return history;
175
212
  }
213
+ //#endregion
214
+
215
+ ////////////////////////////////////////////////////////////////////////////////
216
+ //#region Browser History
217
+ ////////////////////////////////////////////////////////////////////////////////
218
+
219
+ /**
220
+ * A browser history stores the current location in regular URLs in a web
221
+ * browser environment. This is the standard for most web apps and provides the
222
+ * cleanest URLs the browser's address bar.
223
+ *
224
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#browserhistory
225
+ */
226
+
176
227
  /**
177
228
  * Browser history stores the location in regular URLs. This is the standard for
178
229
  * most web apps, but it requires some configuration on the server to ensure you
@@ -203,6 +254,24 @@ function createBrowserHistory(options) {
203
254
  }
204
255
  return getUrlBasedHistory(createBrowserLocation, createBrowserHref, null, options);
205
256
  }
257
+ //#endregion
258
+
259
+ ////////////////////////////////////////////////////////////////////////////////
260
+ //#region Hash History
261
+ ////////////////////////////////////////////////////////////////////////////////
262
+
263
+ /**
264
+ * A hash history stores the current location in the fragment identifier portion
265
+ * of the URL in a web browser environment.
266
+ *
267
+ * This is ideal for apps that do not control the server for some reason
268
+ * (because the fragment identifier is never sent to the server), including some
269
+ * shared hosting environments that do not provide fine-grained controls over
270
+ * which pages are served at which URLs.
271
+ *
272
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#hashhistory
273
+ */
274
+
206
275
  /**
207
276
  * Hash history stores the location in window.location.hash. This makes it ideal
208
277
  * for situations where you don't want to send the location to the server for
@@ -220,7 +289,8 @@ function createHashHistory(options) {
220
289
  pathname = "/",
221
290
  search = "",
222
291
  hash = ""
223
- } = parsePath(window.location.hash.substr(1));
292
+ } = parsePath(window.location.hash.substring(1));
293
+
224
294
  // Hash URL should always have a leading / just like window.location.pathname
225
295
  // does, so if an app ends up at a route like /#something then we add a
226
296
  // leading slash so all of our path-matching behaves the same as if it would
@@ -253,6 +323,16 @@ function createHashHistory(options) {
253
323
  }
254
324
  return getUrlBasedHistory(createHashLocation, createHashHref, validateHashLocation, options);
255
325
  }
326
+ //#endregion
327
+
328
+ ////////////////////////////////////////////////////////////////////////////////
329
+ //#region UTILS
330
+ ////////////////////////////////////////////////////////////////////////////////
331
+
332
+ /**
333
+ * @private
334
+ */
335
+
256
336
  function invariant$2(value, message) {
257
337
  if (value === false || value === null || typeof value === "undefined") {
258
338
  throw new Error(message);
@@ -272,8 +352,9 @@ function warning(cond, message) {
272
352
  }
273
353
  }
274
354
  function createKey$1() {
275
- return Math.random().toString(36).substr(2, 8);
355
+ return Math.random().toString(36).substring(2, 10);
276
356
  }
357
+
277
358
  /**
278
359
  * For browser-based histories, we combine the state and key into an object
279
360
  */
@@ -284,6 +365,7 @@ function getHistoryState(location, index) {
284
365
  idx: index
285
366
  };
286
367
  }
368
+
287
369
  /**
288
370
  * Creates a Location object with a unique key from the given Path
289
371
  */
@@ -305,6 +387,7 @@ function createLocation(current, to, state, key) {
305
387
  });
306
388
  return location;
307
389
  }
390
+
308
391
  /**
309
392
  * Creates a string URL path from the given pathname, search, and hash components.
310
393
  *
@@ -320,6 +403,7 @@ function createPath(_ref) {
320
403
  if (hash && hash !== "#") pathname += hash.charAt(0) === "#" ? hash : "#" + hash;
321
404
  return pathname;
322
405
  }
406
+
323
407
  /**
324
408
  * Parses a string URL path into its separate pathname, search, and hash components.
325
409
  *
@@ -330,13 +414,13 @@ function parsePath(path) {
330
414
  if (path) {
331
415
  let hashIndex = path.indexOf("#");
332
416
  if (hashIndex >= 0) {
333
- parsedPath.hash = path.substr(hashIndex);
334
- path = path.substr(0, hashIndex);
417
+ parsedPath.hash = path.substring(hashIndex);
418
+ path = path.substring(0, hashIndex);
335
419
  }
336
420
  let searchIndex = path.indexOf("?");
337
421
  if (searchIndex >= 0) {
338
- parsedPath.search = path.substr(searchIndex);
339
- path = path.substr(0, searchIndex);
422
+ parsedPath.search = path.substring(searchIndex);
423
+ path = path.substring(0, searchIndex);
340
424
  }
341
425
  if (path) {
342
426
  parsedPath.pathname = path;
@@ -391,6 +475,7 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
391
475
  index = getIndex() + 1;
392
476
  let historyState = getHistoryState(location, index);
393
477
  let url = history.createHref(location);
478
+
394
479
  // try...catch because iOS limits us to 100 pushState calls :/
395
480
  try {
396
481
  globalHistory.pushState(historyState, "", url);
@@ -482,18 +567,165 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
482
567
  };
483
568
  return history;
484
569
  }
570
+
485
571
  //#endregion
486
572
 
487
- var ResultType;
488
- (function (ResultType) {
573
+ /**
574
+ * Map of routeId -> data returned from a loader/action/error
575
+ */
576
+
577
+ let ResultType = /*#__PURE__*/function (ResultType) {
489
578
  ResultType["data"] = "data";
490
579
  ResultType["redirect"] = "redirect";
491
580
  ResultType["error"] = "error";
492
- })(ResultType || (ResultType = {}));
581
+ return ResultType;
582
+ }({});
583
+
584
+ /**
585
+ * Successful result from a loader or action
586
+ */
587
+
588
+ /**
589
+ * Redirect result from a loader or action
590
+ */
591
+
592
+ /**
593
+ * Unsuccessful result from a loader or action
594
+ */
595
+
596
+ /**
597
+ * Result from a loader or action - potentially successful or unsuccessful
598
+ */
599
+
600
+ /**
601
+ * Users can specify either lowercase or uppercase form methods on `<Form>`,
602
+ * useSubmit(), `<fetcher.Form>`, etc.
603
+ */
604
+
605
+ /**
606
+ * Active navigation/fetcher form methods are exposed in uppercase on the
607
+ * RouterState. This is to align with the normalization done via fetch().
608
+ */
609
+
610
+ // Thanks https://github.com/sindresorhus/type-fest!
611
+
612
+ /**
613
+ * @private
614
+ * Internal interface to pass around for action submissions, not intended for
615
+ * external consumption
616
+ */
617
+
618
+ /**
619
+ * @private
620
+ * Arguments passed to route loader/action functions. Same for now but we keep
621
+ * this as a private implementation detail in case they diverge in the future.
622
+ */
623
+
624
+ /**
625
+ * Arguments passed to loader functions
626
+ */
627
+
628
+ /**
629
+ * Arguments passed to action functions
630
+ */
631
+
632
+ /**
633
+ * Loaders and actions can return anything except `undefined` (`null` is a
634
+ * valid return value if there is no data to return). Responses are preferred
635
+ * and will ease any future migration to Remix
636
+ */
637
+
638
+ /**
639
+ * Route loader function signature
640
+ */
641
+
642
+ /**
643
+ * Route action function signature
644
+ */
645
+
646
+ /**
647
+ * Arguments passed to shouldRevalidate function
648
+ */
649
+
650
+ /**
651
+ * Route shouldRevalidate function signature. This runs after any submission
652
+ * (navigation or fetcher), so we flatten the navigation/fetcher submission
653
+ * onto the arguments. It shouldn't matter whether it came from a navigation
654
+ * or a fetcher, what really matters is the URLs and the formData since loaders
655
+ * have to re-run based on the data models that were potentially mutated.
656
+ */
657
+
658
+ /**
659
+ * Result from a loader or action called via dataStrategy
660
+ */
661
+
662
+ /**
663
+ * Function provided by the framework-aware layers to set any framework-specific
664
+ * properties from framework-agnostic properties
665
+ */
666
+
667
+ /**
668
+ * Keys we cannot change from within a lazy() function. We spread all other keys
669
+ * onto the route. Either they're meaningful to the router, or they'll get
670
+ * ignored.
671
+ */
672
+
493
673
  const immutableRouteKeys = new Set(["lazy", "caseSensitive", "path", "id", "index", "children"]);
674
+
675
+ /**
676
+ * lazy() function to load a route definition, which can add non-matching
677
+ * related properties to a route
678
+ */
679
+
680
+ /**
681
+ * Base RouteObject with common props shared by all types of routes
682
+ */
683
+
684
+ /**
685
+ * Index routes must not have children
686
+ */
687
+
688
+ /**
689
+ * Non-index routes may have children, but cannot have index
690
+ */
691
+
692
+ /**
693
+ * A route object represents a logical route, with (optionally) its child
694
+ * routes organized in a tree-like structure.
695
+ */
696
+
697
+ /**
698
+ * A data route object, which is just a RouteObject with a required unique ID
699
+ */
700
+
701
+ // Recursive helper for finding path parameters in the absence of wildcards
702
+
703
+ /**
704
+ * Examples:
705
+ * "/a/b/*" -> "*"
706
+ * ":a" -> "a"
707
+ * "/a/:b" -> "b"
708
+ * "/a/blahblahblah:b" -> "b"
709
+ * "/:a/:b" -> "a" | "b"
710
+ * "/:a/b/:c/*" -> "a" | "c" | "*"
711
+ */
712
+
713
+ // Attempt to parse the given string segment. If it fails, then just return the
714
+ // plain string type as a default fallback. Otherwise, return the union of the
715
+ // parsed string literals that were referenced as dynamic segments in the route.
716
+
717
+ /**
718
+ * The parameters that were parsed from the URL path.
719
+ */
720
+
721
+ /**
722
+ * A RouteMatch contains info about how a route matched a URL.
723
+ */
724
+
494
725
  function isIndexRoute(route) {
495
726
  return route.index === true;
496
727
  }
728
+
497
729
  // Walk the route tree generating unique IDs where necessary, so we are working
498
730
  // solely with AgnosticDataRouteObject's within the Router
499
731
  function convertRoutesToDataRoutes(routes, mapRouteProperties, parentPath, manifest) {
@@ -527,6 +759,7 @@ function convertRoutesToDataRoutes(routes, mapRouteProperties, parentPath, manif
527
759
  }
528
760
  });
529
761
  }
762
+
530
763
  /**
531
764
  * Matches the given routes to a location and returns the match data.
532
765
  *
@@ -596,6 +829,7 @@ function flattenRoutes(routes, branches, parentsMeta, parentPath) {
596
829
  }
597
830
  let path = joinPaths([parentPath, meta.relativePath]);
598
831
  let routesMeta = parentsMeta.concat(meta);
832
+
599
833
  // Add the children before adding this route to the array, so we traverse the
600
834
  // route tree depth-first and child routes appear before their parents in
601
835
  // the "flattened" version.
@@ -606,6 +840,7 @@ function flattenRoutes(routes, branches, parentsMeta, parentPath) {
606
840
  route.index !== true) ? process.env.NODE_ENV !== "production" ? invariant$2(false, "Index routes must not have child routes. Please remove " + ("all child routes from route path \"" + path + "\".")) : invariant$2(false) : void 0;
607
841
  flattenRoutes(route.children, branches, routesMeta, path);
608
842
  }
843
+
609
844
  // Routes without a path shouldn't ever match by themselves unless they are
610
845
  // index routes, so don't add them to the list of possible branches.
611
846
  if (route.path == null && !route.index) {
@@ -630,6 +865,7 @@ function flattenRoutes(routes, branches, parentsMeta, parentPath) {
630
865
  });
631
866
  return branches;
632
867
  }
868
+
633
869
  /**
634
870
  * Computes all combinations of optional path segments for a given path,
635
871
  * excluding combinations that are ambiguous and of lower priority.
@@ -648,6 +884,7 @@ function explodeOptionalSegments(path) {
648
884
  let segments = path.split("/");
649
885
  if (segments.length === 0) return [];
650
886
  let [first, ...rest] = segments;
887
+
651
888
  // Optional path segments are denoted by a trailing `?`
652
889
  let isOptional = first.endsWith("?");
653
890
  // Compute the corresponding required segment: `foo?` -> `foo`
@@ -659,6 +896,7 @@ function explodeOptionalSegments(path) {
659
896
  }
660
897
  let restExploded = explodeOptionalSegments(rest.join("/"));
661
898
  let result = [];
899
+
662
900
  // All child paths with the prefix. Do this for all children before the
663
901
  // optional version for all children, so we get consistent ordering where the
664
902
  // parent optional aspect is preferred as required. Otherwise, we can get
@@ -667,10 +905,12 @@ function explodeOptionalSegments(path) {
667
905
  // then /:one. By always including the parent as required _for all children_
668
906
  // first, we avoid this issue
669
907
  result.push(...restExploded.map(subpath => subpath === "" ? required : [required, subpath].join("/")));
908
+
670
909
  // Then, if this is an optional value, add all child versions without
671
910
  if (isOptional) {
672
911
  result.push(...restExploded);
673
912
  }
913
+
674
914
  // for absolute paths, ensure `/` instead of empty segment
675
915
  return result.map(exploded => path.startsWith("/") && exploded === "" ? "/" : exploded);
676
916
  }
@@ -752,6 +992,7 @@ function matchRouteBranch(branch, pathname, allowPartial) {
752
992
  }
753
993
  return matches;
754
994
  }
995
+
755
996
  /**
756
997
  * Returns a path with params interpolated.
757
998
  *
@@ -766,11 +1007,13 @@ function generatePath(originalPath, params) {
766
1007
  process.env.NODE_ENV !== "production" ? warning(false, "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(/\*$/, "/*") + "\".")) : void 0;
767
1008
  path = path.replace(/\*$/, "/*");
768
1009
  }
1010
+
769
1011
  // ensure `/` is added at the beginning if the path is absolute
770
1012
  const prefix = path.startsWith("/") ? "/" : "";
771
1013
  const stringify = p => p == null ? "" : typeof p === "string" ? p : String(p);
772
1014
  const segments = path.split(/\/+/).map((segment, index, array) => {
773
1015
  const isLastSegment = index === array.length - 1;
1016
+
774
1017
  // only apply the splat if it's the last segment
775
1018
  if (isLastSegment && segment === "*") {
776
1019
  const star = "*";
@@ -784,6 +1027,7 @@ function generatePath(originalPath, params) {
784
1027
  !(optional === "?" || param != null) ? process.env.NODE_ENV !== "production" ? invariant$2(false, "Missing \":" + key + "\" param") : invariant$2(false) : void 0;
785
1028
  return stringify(param);
786
1029
  }
1030
+
787
1031
  // Remove any optional markers from optional static segments
788
1032
  return segment.replace(/\?$/g, "");
789
1033
  })
@@ -791,6 +1035,15 @@ function generatePath(originalPath, params) {
791
1035
  .filter(segment => !!segment);
792
1036
  return prefix + segments.join("/");
793
1037
  }
1038
+
1039
+ /**
1040
+ * A PathPattern is used to match on some portion of a URL pathname.
1041
+ */
1042
+
1043
+ /**
1044
+ * A PathMatch contains info about how a PathPattern matched on a URL pathname.
1045
+ */
1046
+
794
1047
  /**
795
1048
  * Performs pattern matching on a URL pathname and returns information about
796
1049
  * the match.
@@ -886,6 +1139,7 @@ function decodePath(value) {
886
1139
  return value;
887
1140
  }
888
1141
  }
1142
+
889
1143
  /**
890
1144
  * @private
891
1145
  */
@@ -894,6 +1148,7 @@ function stripBasename(pathname, basename) {
894
1148
  if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
895
1149
  return null;
896
1150
  }
1151
+
897
1152
  // We want to leave trailing slash behavior in the user's control, so if they
898
1153
  // specify a basename with a trailing slash, we should support it
899
1154
  let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length;
@@ -904,6 +1159,7 @@ function stripBasename(pathname, basename) {
904
1159
  }
905
1160
  return pathname.slice(startIndex) || "/";
906
1161
  }
1162
+
907
1163
  /**
908
1164
  * Returns a resolved path object relative to the given pathname.
909
1165
  *
@@ -941,6 +1197,7 @@ function resolvePathname(relativePath, fromPathname) {
941
1197
  function getInvalidPathError(char, field, dest, path) {
942
1198
  return "Cannot include a '" + char + "' character in a manually specified " + ("`to." + field + "` field [" + JSON.stringify(path) + "]. 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.";
943
1199
  }
1200
+
944
1201
  /**
945
1202
  * @private
946
1203
  *
@@ -967,14 +1224,17 @@ function getInvalidPathError(char, field, dest, path) {
967
1224
  function getPathContributingMatches(matches) {
968
1225
  return matches.filter((match, index) => index === 0 || match.route.path && match.route.path.length > 0);
969
1226
  }
1227
+
970
1228
  // Return the array of pathnames for the current route matches - used to
971
1229
  // generate the routePathnames input for resolveTo()
972
1230
  function getResolveToMatches(matches) {
973
1231
  let pathMatches = getPathContributingMatches(matches);
1232
+
974
1233
  // Use the full pathname for the leaf match so we include splat values for "." links
975
1234
  // https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329
976
1235
  return pathMatches.map((match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase);
977
1236
  }
1237
+
978
1238
  /**
979
1239
  * @private
980
1240
  */
@@ -994,6 +1254,7 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {
994
1254
  let isEmptyPath = toArg === "" || to.pathname === "";
995
1255
  let toPathname = isEmptyPath ? "/" : to.pathname;
996
1256
  let from;
1257
+
997
1258
  // Routing is relative to the current pathname if explicitly requested.
998
1259
  //
999
1260
  // If a pathname is explicitly provided in `to`, it should be relative to the
@@ -1007,6 +1268,7 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {
1007
1268
  from = locationPathname;
1008
1269
  } else {
1009
1270
  let routePathnameIndex = routePathnames.length - 1;
1271
+
1010
1272
  // With relative="route" (the default), each leading .. segment means
1011
1273
  // "go up one route" instead of "go up one URL segment". This is a key
1012
1274
  // difference from how <a href> works and a major reason we call this a
@@ -1022,6 +1284,7 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {
1022
1284
  from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
1023
1285
  }
1024
1286
  let path = resolvePath(to, from);
1287
+
1025
1288
  // Ensure the pathname has a trailing slash if the original "to" had one
1026
1289
  let hasExplicitTrailingSlash = toPathname && toPathname !== "/" && toPathname.endsWith("/");
1027
1290
  // Or if this was a link to the current path which has a trailing slash
@@ -1031,43 +1294,26 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {
1031
1294
  }
1032
1295
  return path;
1033
1296
  }
1297
+
1034
1298
  /**
1035
1299
  * @private
1036
1300
  */
1037
1301
  const joinPaths = paths => paths.join("/").replace(/\/\/+/g, "/");
1302
+
1038
1303
  /**
1039
1304
  * @private
1040
1305
  */
1041
1306
  const normalizePathname = pathname => pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
1307
+
1042
1308
  /**
1043
1309
  * @private
1044
1310
  */
1045
1311
  const normalizeSearch = search => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
1312
+
1046
1313
  /**
1047
1314
  * @private
1048
1315
  */
1049
1316
  const normalizeHash = hash => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
1050
- /**
1051
- * This is a shortcut for creating `application/json` responses. Converts `data`
1052
- * to JSON and sets the `Content-Type` header.
1053
- *
1054
- * @category Utils
1055
- */
1056
- const json$1 = function json(data, init) {
1057
- if (init === void 0) {
1058
- init = {};
1059
- }
1060
- let responseInit = typeof init === "number" ? {
1061
- status: init
1062
- } : init;
1063
- let headers = new Headers(responseInit.headers);
1064
- if (!headers.has("Content-Type")) {
1065
- headers.set("Content-Type", "application/json; charset=utf-8");
1066
- }
1067
- return new Response(JSON.stringify(data), _extends({}, responseInit, {
1068
- headers
1069
- }));
1070
- };
1071
1317
  class DataWithResponseInit {
1072
1318
  constructor(data, init) {
1073
1319
  this.type = "DataWithResponseInit";
@@ -1075,6 +1321,7 @@ class DataWithResponseInit {
1075
1321
  this.init = init || null;
1076
1322
  }
1077
1323
  }
1324
+
1078
1325
  /**
1079
1326
  * Create "responses" that contain `status`/`headers` without forcing
1080
1327
  * serialization into an actual `Response` - used by Remix single fetch
@@ -1086,6 +1333,10 @@ function data(data, init) {
1086
1333
  status: init
1087
1334
  } : init);
1088
1335
  }
1336
+
1337
+ // This is now only used by the Await component and will eventually probably
1338
+ // go away in favor of the format used by `React.use`
1339
+
1089
1340
  /**
1090
1341
  * A redirect response. Sets the status code and the `Location` header.
1091
1342
  * Defaults to "302 Found".
@@ -1110,6 +1361,7 @@ const redirect = function redirect(url, init) {
1110
1361
  headers
1111
1362
  }));
1112
1363
  };
1364
+
1113
1365
  /**
1114
1366
  * A redirect response that will force a document reload to the new location.
1115
1367
  * Sets the status code and the `Location` header.
@@ -1122,6 +1374,7 @@ const redirectDocument = (url, init) => {
1122
1374
  response.headers.set("X-Remix-Reload-Document", "true");
1123
1375
  return response;
1124
1376
  };
1377
+
1125
1378
  /**
1126
1379
  * A redirect response that will perform a `history.replaceState` instead of a
1127
1380
  * `history.pushState` for client-side navigation redirects.
@@ -1159,6 +1412,7 @@ class ErrorResponseImpl {
1159
1412
  }
1160
1413
  }
1161
1414
  }
1415
+
1162
1416
  /**
1163
1417
  * Check if the given error is an ErrorResponse generated from a 4xx/5xx
1164
1418
  * Response thrown from an action/loader
@@ -1169,11 +1423,109 @@ function isRouteErrorResponse(error) {
1169
1423
  return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error;
1170
1424
  }
1171
1425
 
1426
+ ////////////////////////////////////////////////////////////////////////////////
1427
+ //#region Types and Constants
1428
+ ////////////////////////////////////////////////////////////////////////////////
1429
+
1430
+ /**
1431
+ * A Router instance manages all navigation and data loading/mutations
1432
+ */
1433
+
1434
+ /**
1435
+ * State maintained internally by the router. During a navigation, all states
1436
+ * reflect the the "old" location unless otherwise noted.
1437
+ */
1438
+
1439
+ /**
1440
+ * Data that can be passed into hydrate a Router from SSR
1441
+ */
1442
+
1443
+ /**
1444
+ * Future flags to toggle new feature behavior
1445
+ */
1446
+
1447
+ /**
1448
+ * Initialization options for createRouter
1449
+ */
1450
+
1451
+ /**
1452
+ * State returned from a server-side query() call
1453
+ */
1454
+
1455
+ /**
1456
+ * A StaticHandler instance manages a singular SSR navigation/fetch event
1457
+ */
1458
+
1459
+ /**
1460
+ * Subscriber function signature for changes to router state
1461
+ */
1462
+
1463
+ /**
1464
+ * Function signature for determining the key to be used in scroll restoration
1465
+ * for a given location
1466
+ */
1467
+
1468
+ /**
1469
+ * Function signature for determining the current scroll position
1470
+ */
1471
+
1472
+ /**
1473
+ - "route": relative to the route hierarchy so `..` means remove all segments of the current route even if it has many. For example, a `route("posts/:id")` would have both `:id` and `posts` removed from the url.
1474
+ - "path": relative to the pathname so `..` means remove one segment of the pathname. For example, a `route("posts/:id")` would have only `:id` removed from the url.
1475
+ */
1476
+
1477
+ // Allowed for any navigation or fetch
1478
+
1479
+ // Only allowed for navigations
1480
+
1481
+ // Only allowed for submission navigations
1482
+
1483
+ /**
1484
+ * Options for a navigate() call for a normal (non-submission) navigation
1485
+ */
1486
+
1487
+ /**
1488
+ * Options for a navigate() call for a submission navigation
1489
+ */
1490
+
1491
+ /**
1492
+ * Options to pass to navigate() for a navigation
1493
+ */
1494
+
1495
+ /**
1496
+ * Options for a fetch() load
1497
+ */
1498
+
1499
+ /**
1500
+ * Options for a fetch() submission
1501
+ */
1502
+
1503
+ /**
1504
+ * Options to pass to fetch()
1505
+ */
1506
+
1507
+ /**
1508
+ * Potential states for state.navigation
1509
+ */
1510
+
1511
+ /**
1512
+ * Potential states for fetchers
1513
+ */
1514
+
1515
+ /**
1516
+ * Cached info for active fetcher.load() instances so they can participate
1517
+ * in revalidation
1518
+ */
1519
+
1520
+ /**
1521
+ * Identified fetcher.load() calls that need to be revalidated
1522
+ */
1523
+
1172
1524
  const validMutationMethodsArr = ["POST", "PUT", "PATCH", "DELETE"];
1173
1525
  const validMutationMethods = new Set(validMutationMethodsArr);
1174
1526
  const validRequestMethodsArr = ["GET", ...validMutationMethodsArr];
1175
1527
  const validRequestMethods = new Set(validRequestMethodsArr);
1176
- const redirectStatusCodes$1 = new Set([301, 302, 303, 307, 308]);
1528
+ const redirectStatusCodes = new Set([301, 302, 303, 307, 308]);
1177
1529
  const redirectPreserveMethodStatusCodes = new Set([307, 308]);
1178
1530
  const IDLE_NAVIGATION = {
1179
1531
  state: "idle",
@@ -1206,13 +1558,17 @@ const defaultMapRouteProperties = route => ({
1206
1558
  hasErrorBoundary: Boolean(route.hasErrorBoundary)
1207
1559
  });
1208
1560
  const TRANSITIONS_STORAGE_KEY = "remix-router-transitions";
1561
+
1209
1562
  // Flag used on new `loaderData` to indicate that we do not want to preserve
1210
1563
  // any prior loader data from the throwing route in `mergeLoaderData`
1211
1564
  const ResetLoaderDataSymbol = Symbol("ResetLoaderData");
1565
+
1212
1566
  //#endregion
1567
+
1213
1568
  ////////////////////////////////////////////////////////////////////////////////
1214
1569
  //#region createRouter
1215
1570
  ////////////////////////////////////////////////////////////////////////////////
1571
+
1216
1572
  /**
1217
1573
  * Create a router and listen to history POP navigations
1218
1574
  */
@@ -1221,6 +1577,7 @@ function createRouter(init) {
1221
1577
  const isBrowser = typeof routerWindow !== "undefined" && typeof routerWindow.document !== "undefined" && typeof routerWindow.document.createElement !== "undefined";
1222
1578
  !(init.routes.length > 0) ? process.env.NODE_ENV !== "production" ? invariant$2(false, "You must provide a non-empty routes array to createRouter") : invariant$2(false) : void 0;
1223
1579
  let mapRouteProperties = init.mapRouteProperties || defaultMapRouteProperties;
1580
+
1224
1581
  // Routes keyed by ID
1225
1582
  let manifest = {};
1226
1583
  // Routes in tree format for matching
@@ -1229,6 +1586,7 @@ function createRouter(init) {
1229
1586
  let basename = init.basename || "/";
1230
1587
  let dataStrategyImpl = init.dataStrategy || defaultDataStrategy;
1231
1588
  let patchRoutesOnNavigationImpl = init.patchRoutesOnNavigation;
1589
+
1232
1590
  // Config driven behavior flags
1233
1591
  let future = _extends({}, init.future);
1234
1592
  // Cleanup function for history
@@ -1265,6 +1623,7 @@ function createRouter(init) {
1265
1623
  [route.id]: error
1266
1624
  };
1267
1625
  }
1626
+
1268
1627
  // In SPA apps, if the user provided a patchRoutesOnNavigation implementation and
1269
1628
  // our initial match is a splat route, clear them out so we run through lazy
1270
1629
  // discovery on hydration in case there's a more accurate lazy route match.
@@ -1281,6 +1640,7 @@ function createRouter(init) {
1281
1640
  if (!initialMatches) {
1282
1641
  initialized = false;
1283
1642
  initialMatches = [];
1643
+
1284
1644
  // If partial hydration and fog of war is enabled, we will be running
1285
1645
  // `patchRoutesOnNavigation` during hydration so include any partial matches as
1286
1646
  // the initial matches so we can properly render `HydrateFallback`'s
@@ -1326,57 +1686,77 @@ function createRouter(init) {
1326
1686
  fetchers: new Map(),
1327
1687
  blockers: new Map()
1328
1688
  };
1689
+
1329
1690
  // -- Stateful internal variables to manage navigations --
1330
1691
  // Current navigation in progress (to be committed in completeNavigation)
1331
1692
  let pendingAction = Action.Pop;
1693
+
1332
1694
  // Should the current navigation prevent the scroll reset if scroll cannot
1333
1695
  // be restored?
1334
1696
  let pendingPreventScrollReset = false;
1697
+
1335
1698
  // AbortController for the active navigation
1336
1699
  let pendingNavigationController;
1700
+
1337
1701
  // Should the current navigation enable document.startViewTransition?
1338
1702
  let pendingViewTransitionEnabled = false;
1703
+
1339
1704
  // Store applied view transitions so we can apply them on POP
1340
1705
  let appliedViewTransitions = new Map();
1706
+
1341
1707
  // Cleanup function for persisting applied transitions to sessionStorage
1342
1708
  let removePageHideEventListener = null;
1709
+
1343
1710
  // We use this to avoid touching history in completeNavigation if a
1344
1711
  // revalidation is entirely uninterrupted
1345
1712
  let isUninterruptedRevalidation = false;
1713
+
1346
1714
  // Use this internal flag to force revalidation of all loaders:
1347
1715
  // - submissions (completed or interrupted)
1348
1716
  // - useRevalidator()
1349
1717
  // - X-Remix-Revalidate (from redirect)
1350
1718
  let isRevalidationRequired = false;
1719
+
1351
1720
  // Use this internal array to capture fetcher loads that were cancelled by an
1352
1721
  // action navigation and require revalidation
1353
1722
  let cancelledFetcherLoads = new Set();
1723
+
1354
1724
  // AbortControllers for any in-flight fetchers
1355
1725
  let fetchControllers = new Map();
1726
+
1356
1727
  // Track loads based on the order in which they started
1357
1728
  let incrementingLoadId = 0;
1729
+
1358
1730
  // Track the outstanding pending navigation data load to be compared against
1359
1731
  // the globally incrementing load when a fetcher load lands after a completed
1360
1732
  // navigation
1361
1733
  let pendingNavigationLoadId = -1;
1734
+
1362
1735
  // Fetchers that triggered data reloads as a result of their actions
1363
1736
  let fetchReloadIds = new Map();
1737
+
1364
1738
  // Fetchers that triggered redirect navigations
1365
1739
  let fetchRedirectIds = new Set();
1740
+
1366
1741
  // Most recent href/match for fetcher.load calls for fetchers
1367
1742
  let fetchLoadMatches = new Map();
1743
+
1368
1744
  // Ref-count mounted fetchers so we know when it's ok to clean them up
1369
1745
  let activeFetchers = new Map();
1746
+
1370
1747
  // Fetchers queued for deletion because they've been removed from the UI.
1371
1748
  // These will be officially deleted after they return to idle
1372
1749
  let fetchersQueuedForDeletion = new Set();
1750
+
1373
1751
  // Store blocker functions in a separate Map outside of router state since
1374
1752
  // we don't need to update UI state if they change
1375
1753
  let blockerFunctions = new Map();
1754
+
1376
1755
  // Flag to ignore the next history update, so we can revert the URL change on
1377
1756
  // a POP navigation that was blocked by the user without touching router state
1378
1757
  let unblockBlockerHistoryUpdate = undefined;
1379
1758
  let pendingRevalidationDfd = null;
1759
+
1380
1760
  // Initialize the router, all side effects should be kicked off from here.
1381
1761
  // Implemented as a Fluent API for ease of:
1382
1762
  // let router = createRouter(init).initialize();
@@ -1408,6 +1788,7 @@ function createRouter(init) {
1408
1788
  unblockBlockerHistoryUpdate = resolve;
1409
1789
  });
1410
1790
  init.history.go(delta * -1);
1791
+
1411
1792
  // Put the blocker into a blocked state
1412
1793
  updateBlocker(blockerKey, {
1413
1794
  state: "blocked",
@@ -1444,6 +1825,7 @@ function createRouter(init) {
1444
1825
  routerWindow.addEventListener("pagehide", _saveAppliedTransitions);
1445
1826
  removePageHideEventListener = () => routerWindow.removeEventListener("pagehide", _saveAppliedTransitions);
1446
1827
  }
1828
+
1447
1829
  // Kick off initial data load if needed. Use Pop to avoid modifying history
1448
1830
  // Note we don't do any handling of lazy here. For SPA's it'll get handled
1449
1831
  // in the normal navigation flow. For SSR it's expected that lazy modules are
@@ -1456,6 +1838,7 @@ function createRouter(init) {
1456
1838
  }
1457
1839
  return router;
1458
1840
  }
1841
+
1459
1842
  // Clean up a router and it's side effects
1460
1843
  function dispose() {
1461
1844
  if (unlistenHistory) {
@@ -1469,17 +1852,20 @@ function createRouter(init) {
1469
1852
  state.fetchers.forEach((_, key) => deleteFetcher(key));
1470
1853
  state.blockers.forEach((_, key) => deleteBlocker(key));
1471
1854
  }
1855
+
1472
1856
  // Subscribe to state updates for the router
1473
1857
  function subscribe(fn) {
1474
1858
  subscribers.add(fn);
1475
1859
  return () => subscribers.delete(fn);
1476
1860
  }
1861
+
1477
1862
  // Update our state and notify the calling context of the change
1478
1863
  function updateState(newState, opts) {
1479
1864
  if (opts === void 0) {
1480
1865
  opts = {};
1481
1866
  }
1482
1867
  state = _extends({}, state, newState);
1868
+
1483
1869
  // Cleanup for all fetchers that have returned to idle since we only
1484
1870
  // care about in-flight fetchers
1485
1871
  // - If it's been unmounted then we can completely delete it
@@ -1497,6 +1883,7 @@ function createRouter(init) {
1497
1883
  }
1498
1884
  }
1499
1885
  });
1886
+
1500
1887
  // Iterate over a local copy so that if flushSync is used and we end up
1501
1888
  // removing and adding a new subscriber due to the useCallback dependencies,
1502
1889
  // we don't get ourselves into a loop calling the new subscriber immediately
@@ -1505,10 +1892,12 @@ function createRouter(init) {
1505
1892
  viewTransitionOpts: opts.viewTransitionOpts,
1506
1893
  flushSync: opts.flushSync === true
1507
1894
  }));
1895
+
1508
1896
  // Cleanup internally now that we've called our subscribers/updated state
1509
1897
  unmountedFetchers.forEach(key => deleteFetcher(key));
1510
1898
  mountedFetchers.forEach(key => state.fetchers.delete(key));
1511
1899
  }
1900
+
1512
1901
  // Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION
1513
1902
  // and setting state.[historyAction/location/matches] to the new route.
1514
1903
  // - Location is a required param
@@ -1540,8 +1929,10 @@ function createRouter(init) {
1540
1929
  // Clear actionData on any other completed navigations
1541
1930
  actionData = null;
1542
1931
  }
1932
+
1543
1933
  // Always preserve any existing loaderData from re-used routes
1544
1934
  let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData;
1935
+
1545
1936
  // On a successful navigation we can assume we got through all blockers
1546
1937
  // so we can start fresh
1547
1938
  let blockers = state.blockers;
@@ -1549,9 +1940,11 @@ function createRouter(init) {
1549
1940
  blockers = new Map(blockers);
1550
1941
  blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER));
1551
1942
  }
1943
+
1552
1944
  // Always respect the user flag. Otherwise don't reset on mutation
1553
1945
  // submission navigations unless they redirect
1554
1946
  let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && ((_location$state2 = location.state) == null ? void 0 : _location$state2._isRedirect) !== true;
1947
+
1555
1948
  // Commit any in-flight routes at the end of the HMR revalidation "navigation"
1556
1949
  if (inFlightDataRoutes) {
1557
1950
  dataRoutes = inFlightDataRoutes;
@@ -1563,6 +1956,7 @@ function createRouter(init) {
1563
1956
  init.history.replace(location, location.state);
1564
1957
  }
1565
1958
  let viewTransitionOpts;
1959
+
1566
1960
  // On POP, enable transitions if they were enabled on the original navigation
1567
1961
  if (pendingAction === Action.Pop) {
1568
1962
  // Forward takes precedence so they behave like the original navigation
@@ -1610,6 +2004,7 @@ function createRouter(init) {
1610
2004
  viewTransitionOpts,
1611
2005
  flushSync: flushSync === true
1612
2006
  });
2007
+
1613
2008
  // Reset stateful navigation vars
1614
2009
  pendingAction = Action.Pop;
1615
2010
  pendingPreventScrollReset = false;
@@ -1619,6 +2014,7 @@ function createRouter(init) {
1619
2014
  (_pendingRevalidationD = pendingRevalidationDfd) == null ? void 0 : _pendingRevalidationD.resolve();
1620
2015
  pendingRevalidationDfd = null;
1621
2016
  }
2017
+
1622
2018
  // Trigger a navigation event, which can either be a numerical POP or a PUSH
1623
2019
  // replace with an optional submission
1624
2020
  async function navigate(to, opts) {
@@ -1634,6 +2030,7 @@ function createRouter(init) {
1634
2030
  } = normalizeNavigateOptions(false, normalizedPath, opts);
1635
2031
  let currentLocation = state.location;
1636
2032
  let nextLocation = createLocation(state.location, path, opts && opts.state);
2033
+
1637
2034
  // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded
1638
2035
  // URL from window.location, so we need to encode it here so the behavior
1639
2036
  // remains the same as POP and non-data-router usages. new URL() does all
@@ -1694,6 +2091,7 @@ function createRouter(init) {
1694
2091
  flushSync
1695
2092
  });
1696
2093
  }
2094
+
1697
2095
  // Revalidate all current loaders. If a navigation is in progress or if this
1698
2096
  // is interrupted by a navigation, allow this to "succeed" by calling all
1699
2097
  // loaders during the next loader round
@@ -1713,15 +2111,18 @@ function createRouter(init) {
1713
2111
  updateState({
1714
2112
  revalidation: "loading"
1715
2113
  });
2114
+
1716
2115
  // Capture this here for the edge-case that we have a fully synchronous
1717
2116
  // startNavigation which would resolve and null out pendingRevalidationDfd
1718
2117
  // before we return from this function
1719
2118
  let promise = pendingRevalidationDfd.promise;
2119
+
1720
2120
  // If we're currently submitting an action, we don't need to start a new
1721
2121
  // navigation, we'll just let the follow up loader execution call all loaders
1722
2122
  if (state.navigation.state === "submitting") {
1723
2123
  return promise;
1724
2124
  }
2125
+
1725
2126
  // If we're currently in an idle state, start a new navigation for the current
1726
2127
  // action/location and mark it as uninterrupted, which will skip the history
1727
2128
  // update in completeNavigation
@@ -1731,6 +2132,7 @@ function createRouter(init) {
1731
2132
  });
1732
2133
  return promise;
1733
2134
  }
2135
+
1734
2136
  // Otherwise, if we're currently in a loading state, just start a new
1735
2137
  // navigation to the navigation.location but do not trigger an uninterrupted
1736
2138
  // revalidation so that history correctly updates once the navigation completes
@@ -1741,6 +2143,7 @@ function createRouter(init) {
1741
2143
  });
1742
2144
  return promise;
1743
2145
  }
2146
+
1744
2147
  // Start a navigation to the given action/location. Can optionally provide a
1745
2148
  // overrideNavigation which will override the normalLoad in the case of a redirect
1746
2149
  // navigation
@@ -1752,6 +2155,7 @@ function createRouter(init) {
1752
2155
  pendingNavigationController = null;
1753
2156
  pendingAction = historyAction;
1754
2157
  isUninterruptedRevalidation = (opts && opts.startUninterruptedRevalidation) === true;
2158
+
1755
2159
  // Save the current scroll position every time we start a new navigation,
1756
2160
  // and track whether we should reset scroll on completion
1757
2161
  saveScrollPosition(state.location, state.matches);
@@ -1765,6 +2169,7 @@ function createRouter(init) {
1765
2169
  if (fogOfWar.active && fogOfWar.matches) {
1766
2170
  matches = fogOfWar.matches;
1767
2171
  }
2172
+
1768
2173
  // Short circuit with a 404 on the root error boundary if we match nothing
1769
2174
  if (!matches) {
1770
2175
  let {
@@ -1783,6 +2188,7 @@ function createRouter(init) {
1783
2188
  });
1784
2189
  return;
1785
2190
  }
2191
+
1786
2192
  // Short circuit if it's only a hash change and not a revalidation or
1787
2193
  // mutation submission.
1788
2194
  //
@@ -1797,6 +2203,7 @@ function createRouter(init) {
1797
2203
  });
1798
2204
  return;
1799
2205
  }
2206
+
1800
2207
  // Create a controller/Request for this navigation
1801
2208
  pendingNavigationController = new AbortController();
1802
2209
  let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.submission);
@@ -1819,6 +2226,7 @@ function createRouter(init) {
1819
2226
  if (actionResult.shortCircuited) {
1820
2227
  return;
1821
2228
  }
2229
+
1822
2230
  // If we received a 404 from handleAction, it's because we couldn't lazily
1823
2231
  // discover the destination route so we don't want to call loaders
1824
2232
  if (actionResult.pendingActionResult) {
@@ -1841,9 +2249,11 @@ function createRouter(init) {
1841
2249
  flushSync = false;
1842
2250
  // No need to do fog of war matching again on loader execution
1843
2251
  fogOfWar.active = false;
2252
+
1844
2253
  // Create a GET request for the loaders
1845
2254
  request = createClientSideRequest(init.history, request.url, request.signal);
1846
2255
  }
2256
+
1847
2257
  // Call loaders
1848
2258
  let {
1849
2259
  shortCircuited,
@@ -1854,6 +2264,7 @@ function createRouter(init) {
1854
2264
  if (shortCircuited) {
1855
2265
  return;
1856
2266
  }
2267
+
1857
2268
  // Clean up now that the action/loaders have completed. Don't clean up if
1858
2269
  // we short circuited because pendingNavigationController will have already
1859
2270
  // been assigned to a new controller for the next navigation
@@ -1865,6 +2276,7 @@ function createRouter(init) {
1865
2276
  errors
1866
2277
  }));
1867
2278
  }
2279
+
1868
2280
  // Call the action matched by the leaf route for this navigation and handle
1869
2281
  // redirects/errors
1870
2282
  async function handleAction(request, location, submission, matches, isFogOfWar, opts) {
@@ -1872,6 +2284,7 @@ function createRouter(init) {
1872
2284
  opts = {};
1873
2285
  }
1874
2286
  interruptActiveLoads();
2287
+
1875
2288
  // Put us in a submitting state
1876
2289
  let navigation = getSubmittingNavigation(location, submission);
1877
2290
  updateState({
@@ -1911,6 +2324,7 @@ function createRouter(init) {
1911
2324
  matches = discoverResult.matches;
1912
2325
  }
1913
2326
  }
2327
+
1914
2328
  // Call our action and get the result
1915
2329
  let result;
1916
2330
  let actionMatch = getTargetMatch(matches, location);
@@ -1955,6 +2369,7 @@ function createRouter(init) {
1955
2369
  // Store off the pending error - we use it to determine which loaders
1956
2370
  // to call and will commit it when we complete the navigation
1957
2371
  let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);
2372
+
1958
2373
  // By default, all submissions to the current location are REPLACE
1959
2374
  // navigations, but if the action threw an error that'll be rendered in
1960
2375
  // an errorElement, we fall back to PUSH so that the user can use the
@@ -1973,14 +2388,17 @@ function createRouter(init) {
1973
2388
  pendingActionResult: [actionMatch.route.id, result]
1974
2389
  };
1975
2390
  }
2391
+
1976
2392
  // Call all applicable loaders for the given matches, handling redirects,
1977
2393
  // errors, etc.
1978
2394
  async function handleLoaders(request, location, matches, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace, initialHydration, flushSync, pendingActionResult) {
1979
2395
  // Figure out the right navigation we want to use for data loading
1980
2396
  let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission);
2397
+
1981
2398
  // If this was a redirect from an action we don't have a "submission" but
1982
2399
  // we have it on the loading navigation so use that if available
1983
2400
  let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation);
2401
+
1984
2402
  // If this is an uninterrupted revalidation, we remain in our current idle
1985
2403
  // state. If not, we need to switch to our loading state and load data,
1986
2404
  // preserving any new action data or existing action data (in the case of
@@ -1988,6 +2406,7 @@ function createRouter(init) {
1988
2406
  // Also (with "partial hydration"), don't update the state for the initial
1989
2407
  // data load since it's not a "navigation"
1990
2408
  let shouldUpdateNavigationState = !isUninterruptedRevalidation && !initialHydration;
2409
+
1991
2410
  // When fog of war is enabled, we enter our `loading` state earlier so we
1992
2411
  // can discover new routes during the `loading` state. We skip this if
1993
2412
  // we've already run actions since we would have done our matching already.
@@ -2038,6 +2457,7 @@ function createRouter(init) {
2038
2457
  let routesToUse = inFlightDataRoutes || dataRoutes;
2039
2458
  let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, initialHydration === true, isRevalidationRequired, cancelledFetcherLoads, fetchersQueuedForDeletion, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult);
2040
2459
  pendingNavigationLoadId = ++incrementingLoadId;
2460
+
2041
2461
  // Short circuit if we have no loaders to run
2042
2462
  if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {
2043
2463
  let updatedFetchers = markFetchRedirectsDone();
@@ -2083,6 +2503,7 @@ function createRouter(init) {
2083
2503
  fetchControllers.set(rf.key, rf.controller);
2084
2504
  }
2085
2505
  });
2506
+
2086
2507
  // Proxy navigation abort through to revalidation fetchers
2087
2508
  let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach(f => abortFetcher(f.key));
2088
2509
  if (pendingNavigationController) {
@@ -2097,6 +2518,7 @@ function createRouter(init) {
2097
2518
  shortCircuited: true
2098
2519
  };
2099
2520
  }
2521
+
2100
2522
  // Clean up _after_ loaders have completed. Don't clean up if we short
2101
2523
  // circuited because fetchControllers would have been aborted and
2102
2524
  // reassigned to new controllers for the next navigation
@@ -2104,6 +2526,7 @@ function createRouter(init) {
2104
2526
  pendingNavigationController.signal.removeEventListener("abort", abortPendingFetchRevalidations);
2105
2527
  }
2106
2528
  revalidatingFetchers.forEach(rf => fetchControllers.delete(rf.key));
2529
+
2107
2530
  // If any loaders returned a redirect Response, start a new REPLACE navigation
2108
2531
  let redirect = findRedirect(loaderResults);
2109
2532
  if (redirect) {
@@ -2127,11 +2550,13 @@ function createRouter(init) {
2127
2550
  shortCircuited: true
2128
2551
  };
2129
2552
  }
2553
+
2130
2554
  // Process and commit output from loaders
2131
2555
  let {
2132
2556
  loaderData,
2133
2557
  errors
2134
2558
  } = processLoaderData(state, matches, loaderResults, pendingActionResult, revalidatingFetchers, fetcherResults);
2559
+
2135
2560
  // Preserve SSR errors during partial hydration
2136
2561
  if (initialHydration && state.errors) {
2137
2562
  errors = _extends({}, state.errors, errors);
@@ -2171,6 +2596,7 @@ function createRouter(init) {
2171
2596
  });
2172
2597
  return new Map(state.fetchers);
2173
2598
  }
2599
+
2174
2600
  // Trigger a fetcher load/submit for the given fetcher key
2175
2601
  async function fetch(key, routeId, href, opts) {
2176
2602
  abortFetcher(key);
@@ -2207,6 +2633,7 @@ function createRouter(init) {
2207
2633
  await handleFetcherAction(key, routeId, path, match, matches, fogOfWar.active, flushSync, preventScrollReset, submission);
2208
2634
  return;
2209
2635
  }
2636
+
2210
2637
  // Store off the match so we can call it's shouldRevalidate on subsequent
2211
2638
  // revalidations
2212
2639
  fetchLoadMatches.set(key, {
@@ -2215,6 +2642,7 @@ function createRouter(init) {
2215
2642
  });
2216
2643
  await handleFetcherLoader(key, routeId, path, match, matches, fogOfWar.active, flushSync, preventScrollReset, submission);
2217
2644
  }
2645
+
2218
2646
  // Call the action for the matched fetcher.submit(), and then handle redirects,
2219
2647
  // errors, and revalidation
2220
2648
  async function handleFetcherAction(key, routeId, path, match, requestMatches, isFogOfWar, flushSync, preventScrollReset, submission) {
@@ -2237,6 +2665,7 @@ function createRouter(init) {
2237
2665
  if (!isFogOfWar && detectAndHandle405Error(match)) {
2238
2666
  return;
2239
2667
  }
2668
+
2240
2669
  // Put this fetcher into it's submitting state
2241
2670
  let existingFetcher = state.fetchers.get(key);
2242
2671
  updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), {
@@ -2268,6 +2697,7 @@ function createRouter(init) {
2268
2697
  }
2269
2698
  }
2270
2699
  }
2700
+
2271
2701
  // Call the action for the fetcher
2272
2702
  fetchControllers.set(key, abortController);
2273
2703
  let originatingLoadId = incrementingLoadId;
@@ -2281,6 +2711,7 @@ function createRouter(init) {
2281
2711
  }
2282
2712
  return;
2283
2713
  }
2714
+
2284
2715
  // We don't want errors bubbling up to the UI or redirects processed for
2285
2716
  // unmounted fetchers so we just revert them to idle
2286
2717
  if (fetchersQueuedForDeletion.has(key)) {
@@ -2308,12 +2739,14 @@ function createRouter(init) {
2308
2739
  });
2309
2740
  }
2310
2741
  }
2742
+
2311
2743
  // Process any non-redirect errors thrown
2312
2744
  if (isErrorResult(actionResult)) {
2313
2745
  setFetcherError(key, routeId, actionResult.error);
2314
2746
  return;
2315
2747
  }
2316
2748
  }
2749
+
2317
2750
  // Start the data load for current matches, or the next location if we're
2318
2751
  // in the middle of a navigation
2319
2752
  let nextLocation = state.navigation.location || state.location;
@@ -2326,6 +2759,7 @@ function createRouter(init) {
2326
2759
  let loadFetcher = getLoadingFetcher(submission, actionResult.data);
2327
2760
  state.fetchers.set(key, loadFetcher);
2328
2761
  let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, false, isRevalidationRequired, cancelledFetcherLoads, fetchersQueuedForDeletion, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, [match.route.id, actionResult]);
2762
+
2329
2763
  // Put all revalidating fetchers into the loading state, except for the
2330
2764
  // current fetcher which we want to keep in it's current loading state which
2331
2765
  // contains it's action submission info + action data
@@ -2371,11 +2805,13 @@ function createRouter(init) {
2371
2805
  preventScrollReset
2372
2806
  });
2373
2807
  }
2808
+
2374
2809
  // Process and commit output from loaders
2375
2810
  let {
2376
2811
  loaderData,
2377
2812
  errors
2378
2813
  } = processLoaderData(state, matches, loaderResults, undefined, revalidatingFetchers, fetcherResults);
2814
+
2379
2815
  // Since we let revalidations complete even if the submitting fetcher was
2380
2816
  // deleted, only put it back to idle if it hasn't been deleted
2381
2817
  if (state.fetchers.has(key)) {
@@ -2383,6 +2819,7 @@ function createRouter(init) {
2383
2819
  state.fetchers.set(key, doneFetcher);
2384
2820
  }
2385
2821
  abortStaleFetchLoads(loadId);
2822
+
2386
2823
  // If we are currently in a navigation loading state and this fetcher is
2387
2824
  // more recent than the navigation, we want the newer data so abort the
2388
2825
  // navigation and complete it with the fetcher data
@@ -2407,6 +2844,7 @@ function createRouter(init) {
2407
2844
  isRevalidationRequired = false;
2408
2845
  }
2409
2846
  }
2847
+
2410
2848
  // Call the matched loader for fetcher.load(), handling redirects, errors, etc.
2411
2849
  async function handleFetcherLoader(key, routeId, path, match, matches, isFogOfWar, flushSync, preventScrollReset, submission) {
2412
2850
  let existingFetcher = state.fetchers.get(key);
@@ -2436,11 +2874,13 @@ function createRouter(init) {
2436
2874
  match = getTargetMatch(matches, path);
2437
2875
  }
2438
2876
  }
2877
+
2439
2878
  // Call the loader for this fetcher route match
2440
2879
  fetchControllers.set(key, abortController);
2441
2880
  let originatingLoadId = incrementingLoadId;
2442
2881
  let results = await callDataStrategy("loader", state, fetchRequest, [match], matches, key);
2443
2882
  let result = results[match.route.id];
2883
+
2444
2884
  // We can delete this so long as we weren't aborted by our our own fetcher
2445
2885
  // re-load which would have put _new_ controller is in fetchControllers
2446
2886
  if (fetchControllers.get(key) === abortController) {
@@ -2449,12 +2889,14 @@ function createRouter(init) {
2449
2889
  if (fetchRequest.signal.aborted) {
2450
2890
  return;
2451
2891
  }
2892
+
2452
2893
  // We don't want errors bubbling up or redirects followed for unmounted
2453
2894
  // fetchers, so short circuit here if it was removed from the UI
2454
2895
  if (fetchersQueuedForDeletion.has(key)) {
2455
2896
  updateFetcherState(key, getDoneFetcher(undefined));
2456
2897
  return;
2457
2898
  }
2899
+
2458
2900
  // If the loader threw a redirect Response, start a new REPLACE navigation
2459
2901
  if (isRedirectResult(result)) {
2460
2902
  if (pendingNavigationLoadId > originatingLoadId) {
@@ -2470,14 +2912,17 @@ function createRouter(init) {
2470
2912
  return;
2471
2913
  }
2472
2914
  }
2915
+
2473
2916
  // Process any non-redirect errors thrown
2474
2917
  if (isErrorResult(result)) {
2475
2918
  setFetcherError(key, routeId, result.error);
2476
2919
  return;
2477
2920
  }
2921
+
2478
2922
  // Put the fetcher back into an idle state
2479
2923
  updateFetcherState(key, getDoneFetcher(result.data));
2480
2924
  }
2925
+
2481
2926
  /**
2482
2927
  * Utility function to handle redirects returned from an action or loader.
2483
2928
  * Normally, a redirect "replaces" the navigation that triggered it. So, for
@@ -2535,10 +2980,12 @@ function createRouter(init) {
2535
2980
  return;
2536
2981
  }
2537
2982
  }
2983
+
2538
2984
  // There's no need to abort on redirects, since we don't detect the
2539
2985
  // redirect until the action/loaders have settled
2540
2986
  pendingNavigationController = null;
2541
2987
  let redirectNavigationType = replace === true || redirect.response.headers.has("X-Remix-Replace") ? Action.Replace : Action.Push;
2988
+
2542
2989
  // Use the incoming submission if provided, fallback on the active one in
2543
2990
  // state.navigation
2544
2991
  let {
@@ -2549,6 +2996,7 @@ function createRouter(init) {
2549
2996
  if (!submission && !fetcherSubmission && formMethod && formAction && formEncType) {
2550
2997
  submission = getSubmissionFromNavigation(state.navigation);
2551
2998
  }
2999
+
2552
3000
  // If this was a 307/308 submission we want to preserve the HTTP method and
2553
3001
  // re-submit the GET/POST/PUT/PATCH/DELETE as a submission navigation to the
2554
3002
  // redirected location
@@ -2576,6 +3024,7 @@ function createRouter(init) {
2576
3024
  });
2577
3025
  }
2578
3026
  }
3027
+
2579
3028
  // Utility wrapper for calling dataStrategy client-side without having to
2580
3029
  // pass around the manifest, mapRouteProperties, etc.
2581
3030
  async function callDataStrategy(type, state, request, matchesToLoad, matches, fetcherKey) {
@@ -2595,7 +3044,7 @@ function createRouter(init) {
2595
3044
  return dataResults;
2596
3045
  }
2597
3046
  for (let [routeId, result] of Object.entries(results)) {
2598
- if (isRedirectDataStrategyResultResult(result)) {
3047
+ if (isRedirectDataStrategyResult(result)) {
2599
3048
  let response = result.result;
2600
3049
  dataResults[routeId] = {
2601
3050
  type: ResultType.redirect,
@@ -2608,7 +3057,6 @@ function createRouter(init) {
2608
3057
  return dataResults;
2609
3058
  }
2610
3059
  async function callLoadersAndMaybeResolveData(state, matches, matchesToLoad, fetchersToLoad, request) {
2611
- state.matches;
2612
3060
  // Kick off loaders and fetchers in parallel
2613
3061
  let loaderResultsPromise = callDataStrategy("loader", state, request, matchesToLoad, matches, null);
2614
3062
  let fetcherResultsPromise = Promise.all(fetchersToLoad.map(async f => {
@@ -2640,6 +3088,7 @@ function createRouter(init) {
2640
3088
  function interruptActiveLoads() {
2641
3089
  // Every interruption triggers a revalidation
2642
3090
  isRevalidationRequired = true;
3091
+
2643
3092
  // Abort in-flight fetcher loads
2644
3093
  fetchLoadMatches.forEach((_, key) => {
2645
3094
  if (fetchControllers.has(key)) {
@@ -2766,9 +3215,11 @@ function createRouter(init) {
2766
3215
  state.blockers.delete(key);
2767
3216
  blockerFunctions.delete(key);
2768
3217
  }
3218
+
2769
3219
  // Utility function to update blockers, ensuring valid state transitions
2770
3220
  function updateBlocker(key, newBlocker) {
2771
3221
  let blocker = state.blockers.get(key) || IDLE_BLOCKER;
3222
+
2772
3223
  // Poor mans state machine :)
2773
3224
  // https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM
2774
3225
  !(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") ? process.env.NODE_ENV !== "production" ? invariant$2(false, "Invalid blocker state transition: " + blocker.state + " -> " + newBlocker.state) : invariant$2(false) : void 0;
@@ -2787,6 +3238,7 @@ function createRouter(init) {
2787
3238
  if (blockerFunctions.size === 0) {
2788
3239
  return;
2789
3240
  }
3241
+
2790
3242
  // We ony support a single active blocker at the moment since we don't have
2791
3243
  // any compelling use cases for multi-blocker yet
2792
3244
  if (blockerFunctions.size > 1) {
@@ -2800,6 +3252,7 @@ function createRouter(init) {
2800
3252
  // it and can let this navigation continue
2801
3253
  return;
2802
3254
  }
3255
+
2803
3256
  // At this point, we know we're unblocked/blocked so we need to check the
2804
3257
  // user-provided blocker function
2805
3258
  if (blockerFunction({
@@ -2825,12 +3278,14 @@ function createRouter(init) {
2825
3278
  error
2826
3279
  };
2827
3280
  }
3281
+
2828
3282
  // Opt in to capturing and reporting scroll positions during navigations,
2829
3283
  // used by the <ScrollRestoration> component
2830
3284
  function enableScrollRestoration(positions, getPosition, getKey) {
2831
3285
  savedScrollPositions = positions;
2832
3286
  getScrollPosition = getPosition;
2833
3287
  getScrollRestorationKey = getKey || null;
3288
+
2834
3289
  // Perform initial hydration scroll restoration, since we miss the boat on
2835
3290
  // the initial updateState() because we've not yet rendered <ScrollRestoration/>
2836
3291
  // and therefore have no savedScrollPositions available
@@ -2949,6 +3404,7 @@ function createRouter(init) {
2949
3404
  };
2950
3405
  }
2951
3406
  let newPartialMatches = matchRoutesImpl(routesToUse, pathname, basename, true);
3407
+
2952
3408
  // Avoid loops if the second pass results in the same partial matches
2953
3409
  if (!newPartialMatches || partialMatches.length === newPartialMatches.length && partialMatches.every((m, i) => m.route.id === newPartialMatches[i].route.id)) {
2954
3410
  return {
@@ -2967,6 +3423,7 @@ function createRouter(init) {
2967
3423
  let isNonHMR = inFlightDataRoutes == null;
2968
3424
  let routesToUse = inFlightDataRoutes || dataRoutes;
2969
3425
  patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties);
3426
+
2970
3427
  // If we are not in the middle of an HMR revalidation and we changed the
2971
3428
  // routes, provide a new identity and trigger a reflow via `updateState`
2972
3429
  // to re-run memoized `router.routes` dependencies.
@@ -3016,12 +3473,19 @@ function createRouter(init) {
3016
3473
  };
3017
3474
  return router;
3018
3475
  }
3476
+ //#endregion
3477
+
3478
+ ////////////////////////////////////////////////////////////////////////////////
3479
+ //#region createStaticHandler
3480
+ ////////////////////////////////////////////////////////////////////////////////
3481
+
3019
3482
  function createStaticHandler$1(routes, opts) {
3020
3483
  !(routes.length > 0) ? process.env.NODE_ENV !== "production" ? invariant$2(false, "You must provide a non-empty routes array to createStaticHandler") : invariant$2(false) : void 0;
3021
3484
  let manifest = {};
3022
3485
  let basename = (opts ? opts.basename : null) || "/";
3023
3486
  let mapRouteProperties = (opts == null ? void 0 : opts.mapRouteProperties) || defaultMapRouteProperties;
3024
3487
  let dataRoutes = convertRoutesToDataRoutes(routes, mapRouteProperties, undefined, manifest);
3488
+
3025
3489
  /**
3026
3490
  * The query() method is intended for document requests, in which we want to
3027
3491
  * call an optional action and potentially multiple loaders for all nested
@@ -3058,6 +3522,7 @@ function createStaticHandler$1(routes, opts) {
3058
3522
  let method = request.method;
3059
3523
  let location = createLocation("", createPath(url), null, "default");
3060
3524
  let matches = matchRoutes(dataRoutes, location, basename);
3525
+
3061
3526
  // SSR supports HEAD requests while SPA doesn't
3062
3527
  if (!isValidMethod(method) && method !== "HEAD") {
3063
3528
  let error = getInternalRouterError(405, {
@@ -3103,9 +3568,10 @@ function createStaticHandler$1(routes, opts) {
3103
3568
  };
3104
3569
  }
3105
3570
  let result = await queryImpl(request, location, matches, requestContext, dataStrategy || null, skipLoaderErrorBubbling === true, null);
3106
- if (isResponse$2(result)) {
3571
+ if (isResponse(result)) {
3107
3572
  return result;
3108
3573
  }
3574
+
3109
3575
  // When returning StaticHandlerContext, we patch back in the location here
3110
3576
  // since we need it for React Context. But this helps keep our submit and
3111
3577
  // loadRouteData operating on a Request instead of a Location
@@ -3114,6 +3580,7 @@ function createStaticHandler$1(routes, opts) {
3114
3580
  basename
3115
3581
  }, result);
3116
3582
  }
3583
+
3117
3584
  /**
3118
3585
  * The queryRoute() method is intended for targeted route requests, either
3119
3586
  * for fetch ?_data requests or resource route requests. In this case, we
@@ -3150,6 +3617,7 @@ function createStaticHandler$1(routes, opts) {
3150
3617
  let method = request.method;
3151
3618
  let location = createLocation("", createPath(url), null, "default");
3152
3619
  let matches = matchRoutes(dataRoutes, location, basename);
3620
+
3153
3621
  // SSR supports HEAD requests while SPA doesn't
3154
3622
  if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") {
3155
3623
  throw getInternalRouterError(405, {
@@ -3173,7 +3641,7 @@ function createStaticHandler$1(routes, opts) {
3173
3641
  });
3174
3642
  }
3175
3643
  let result = await queryImpl(request, location, matches, requestContext, dataStrategy || null, false, match);
3176
- if (isResponse$2(result)) {
3644
+ if (isResponse(result)) {
3177
3645
  return result;
3178
3646
  }
3179
3647
  let error = result.errors ? Object.values(result.errors)[0] : undefined;
@@ -3184,6 +3652,7 @@ function createStaticHandler$1(routes, opts) {
3184
3652
  // preserve the "error" state outside of queryImpl.
3185
3653
  throw error;
3186
3654
  }
3655
+
3187
3656
  // Pick off the right state value to return
3188
3657
  if (result.actionData) {
3189
3658
  return Object.values(result.actionData)[0];
@@ -3201,7 +3670,7 @@ function createStaticHandler$1(routes, opts) {
3201
3670
  return result;
3202
3671
  }
3203
3672
  let result = await loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch);
3204
- return isResponse$2(result) ? result : _extends({}, result, {
3673
+ return isResponse(result) ? result : _extends({}, result, {
3205
3674
  actionData: null,
3206
3675
  actionHeaders: {}
3207
3676
  });
@@ -3209,7 +3678,7 @@ function createStaticHandler$1(routes, opts) {
3209
3678
  // If the user threw/returned a Response in callLoaderOrAction for a
3210
3679
  // `queryRoute` call, we throw the `DataStrategyResult` to bail out early
3211
3680
  // and then return or throw the raw Response here accordingly
3212
- if (isDataStrategyResult(e) && isResponse$2(e.result)) {
3681
+ if (isDataStrategyResult(e) && isResponse(e.result)) {
3213
3682
  if (e.type === ResultType.error) {
3214
3683
  throw e.result;
3215
3684
  }
@@ -3217,7 +3686,7 @@ function createStaticHandler$1(routes, opts) {
3217
3686
  }
3218
3687
  // Redirects are always returned since they don't propagate to catch
3219
3688
  // boundaries
3220
- if (isRedirectResponse$1(e)) {
3689
+ if (isRedirectResponse(e)) {
3221
3690
  return e;
3222
3691
  }
3223
3692
  throw e;
@@ -3277,6 +3746,7 @@ function createStaticHandler$1(routes, opts) {
3277
3746
  actionHeaders: {}
3278
3747
  };
3279
3748
  }
3749
+
3280
3750
  // Create a GET request for the loaders
3281
3751
  let loaderRequest = new Request(request.url, {
3282
3752
  headers: request.headers,
@@ -3288,6 +3758,7 @@ function createStaticHandler$1(routes, opts) {
3288
3758
  // to call and will commit it when we complete the navigation
3289
3759
  let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
3290
3760
  let context = await loadRouteData(loaderRequest, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, null, [boundaryMatch.route.id, result]);
3761
+
3291
3762
  // action status codes take precedence over loader status codes
3292
3763
  return _extends({}, context, {
3293
3764
  statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,
@@ -3312,6 +3783,7 @@ function createStaticHandler$1(routes, opts) {
3312
3783
  }
3313
3784
  async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, pendingActionResult) {
3314
3785
  let isRouteRequest = routeMatch != null;
3786
+
3315
3787
  // Short circuit if we have no loaders to run (queryRoute())
3316
3788
  if (isRouteRequest && !(routeMatch != null && routeMatch.route.loader) && !(routeMatch != null && routeMatch.route.lazy)) {
3317
3789
  throw getInternalRouterError(400, {
@@ -3322,6 +3794,7 @@ function createStaticHandler$1(routes, opts) {
3322
3794
  }
3323
3795
  let requestMatches = routeMatch ? [routeMatch] : pendingActionResult && isErrorResult(pendingActionResult[1]) ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]) : matches;
3324
3796
  let matchesToLoad = requestMatches.filter(m => m.route.loader || m.route.lazy);
3797
+
3325
3798
  // Short circuit if we have no loaders to run (query())
3326
3799
  if (matchesToLoad.length === 0) {
3327
3800
  return {
@@ -3341,8 +3814,10 @@ function createStaticHandler$1(routes, opts) {
3341
3814
  if (request.signal.aborted) {
3342
3815
  throwStaticHandlerAbortedError(request, isRouteRequest);
3343
3816
  }
3817
+
3344
3818
  // Process and commit output from loaders
3345
3819
  let context = processRouteLoaderData(matches, results, pendingActionResult, true, skipLoaderErrorBubbling);
3820
+
3346
3821
  // Add a null for any non-loader matches for proper revalidation on the client
3347
3822
  let executedLoaders = new Set(matchesToLoad.map(match => match.route.id));
3348
3823
  matches.forEach(match => {
@@ -3354,6 +3829,7 @@ function createStaticHandler$1(routes, opts) {
3354
3829
  matches
3355
3830
  });
3356
3831
  }
3832
+
3357
3833
  // Utility wrapper for calling dataStrategy server-side without having to
3358
3834
  // pass around the manifest, mapRouteProperties, etc.
3359
3835
  async function callDataStrategy(type, request, matchesToLoad, matches, isRouteRequest, requestContext, dataStrategy) {
@@ -3364,12 +3840,12 @@ function createStaticHandler$1(routes, opts) {
3364
3840
  return;
3365
3841
  }
3366
3842
  let result = results[match.route.id];
3367
- if (isRedirectDataStrategyResultResult(result)) {
3843
+ if (isRedirectDataStrategyResult(result)) {
3368
3844
  let response = result.result;
3369
3845
  // Throw redirects and let the server handle them with an HTTP redirect
3370
3846
  throw normalizeRelativeRoutingRedirectResponse(response, request, match.route.id, matches, basename);
3371
3847
  }
3372
- if (isResponse$2(result.result) && isRouteRequest) {
3848
+ if (isResponse(result.result) && isRouteRequest) {
3373
3849
  // For SSR single-route requests, we want to hand Responses back
3374
3850
  // directly without unwrapping
3375
3851
  throw result;
@@ -3384,10 +3860,13 @@ function createStaticHandler$1(routes, opts) {
3384
3860
  queryRoute
3385
3861
  };
3386
3862
  }
3863
+
3387
3864
  //#endregion
3865
+
3388
3866
  ////////////////////////////////////////////////////////////////////////////////
3389
3867
  //#region Helpers
3390
3868
  ////////////////////////////////////////////////////////////////////////////////
3869
+
3391
3870
  /**
3392
3871
  * Given an existing StaticHandlerContext and an error thrown at render time,
3393
3872
  * provide an updated StaticHandlerContext suitable for a second SSR render
@@ -3431,8 +3910,10 @@ function normalizeTo(location, matches, basename, to, fromRouteId, relative) {
3431
3910
  contextualMatches = matches;
3432
3911
  activeRouteMatch = matches[matches.length - 1];
3433
3912
  }
3913
+
3434
3914
  // Resolve the relative path
3435
3915
  let path = resolveTo(to ? to : ".", getResolveToMatches(contextualMatches), stripBasename(location.pathname, basename) || location.pathname, relative === "path");
3916
+
3436
3917
  // When `to` is not specified we inherit search/hash from the current
3437
3918
  // location, unlike when to="." and we just inherit the path.
3438
3919
  // See https://github.com/remix-run/remix/issues/927
@@ -3440,6 +3921,7 @@ function normalizeTo(location, matches, basename, to, fromRouteId, relative) {
3440
3921
  path.search = location.search;
3441
3922
  path.hash = location.hash;
3442
3923
  }
3924
+
3443
3925
  // Account for `?index` params when routing to the current location
3444
3926
  if ((to == null || to === "" || to === ".") && activeRouteMatch) {
3445
3927
  let nakedIndex = hasNakedIndexQuery(path.search);
@@ -3456,6 +3938,7 @@ function normalizeTo(location, matches, basename, to, fromRouteId, relative) {
3456
3938
  path.search = qs ? "?" + qs : "";
3457
3939
  }
3458
3940
  }
3941
+
3459
3942
  // If we're operating within a basename, prepend it to the pathname. If
3460
3943
  // this is a root navigation, then just use the raw basename which allows
3461
3944
  // the basename to have full control over the presence of a trailing slash
@@ -3465,6 +3948,7 @@ function normalizeTo(location, matches, basename, to, fromRouteId, relative) {
3465
3948
  }
3466
3949
  return createPath(path);
3467
3950
  }
3951
+
3468
3952
  // Normalize navigation options by converting formMethod=GET formData objects to
3469
3953
  // URLSearchParams so they behave identically to links with query params
3470
3954
  function normalizeNavigateOptions(isFetcher, path, opts) {
@@ -3488,6 +3972,7 @@ function normalizeNavigateOptions(isFetcher, path, opts) {
3488
3972
  type: "invalid-body"
3489
3973
  })
3490
3974
  });
3975
+
3491
3976
  // Create a Submission on non-GET navigations
3492
3977
  let rawFormMethod = opts.formMethod || "get";
3493
3978
  let formMethod = rawFormMethod.toUpperCase();
@@ -3575,6 +4060,7 @@ function normalizeNavigateOptions(isFetcher, path, opts) {
3575
4060
  submission
3576
4061
  };
3577
4062
  }
4063
+
3578
4064
  // Flatten submission onto URLSearchParams for GET submissions
3579
4065
  let parsedPath = parsePath(path);
3580
4066
  // On GET navigation submissions we can drop the ?index param from the
@@ -3589,6 +4075,7 @@ function normalizeNavigateOptions(isFetcher, path, opts) {
3589
4075
  submission
3590
4076
  };
3591
4077
  }
4078
+
3592
4079
  // Filter out all routes at/below any caught error as they aren't going to
3593
4080
  // render so we don't need to load them
3594
4081
  function getLoaderMatchesUntilBoundary(matches, boundaryId, includeBoundary) {
@@ -3605,6 +4092,7 @@ function getMatchesToLoad(history, state, matches, submission, location, initial
3605
4092
  let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : undefined;
3606
4093
  let currentUrl = history.createURL(state.location);
3607
4094
  let nextUrl = history.createURL(location);
4095
+
3608
4096
  // Pick navigation matches that are net-new or qualify for revalidation
3609
4097
  let boundaryMatches = matches;
3610
4098
  if (initialHydration && state.errors) {
@@ -3619,6 +4107,7 @@ function getMatchesToLoad(history, state, matches, submission, location, initial
3619
4107
  // boundary
3620
4108
  boundaryMatches = getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]);
3621
4109
  }
4110
+
3622
4111
  // Don't revalidate loaders by default after action 4xx/5xx responses
3623
4112
  // when the flag is enabled. They can still opt-into revalidation via
3624
4113
  // `shouldRevalidate` via `actionResult`
@@ -3638,10 +4127,12 @@ function getMatchesToLoad(history, state, matches, submission, location, initial
3638
4127
  if (initialHydration) {
3639
4128
  return shouldLoadRouteOnHydration(route, state.loaderData, state.errors);
3640
4129
  }
4130
+
3641
4131
  // Always call the loader on new route instances
3642
4132
  if (isNewLoader(state.loaderData, state.matches[index], match)) {
3643
4133
  return true;
3644
4134
  }
4135
+
3645
4136
  // This is the default implementation for when we revalidate. If the route
3646
4137
  // provides it's own implementation, then we give them full control but
3647
4138
  // provide this value so they can leverage it if needed after they check
@@ -3663,6 +4154,7 @@ function getMatchesToLoad(history, state, matches, submission, location, initial
3663
4154
  currentUrl.search !== nextUrl.search || isNewRouteInstance(currentRouteMatch, nextRouteMatch)
3664
4155
  }));
3665
4156
  });
4157
+
3666
4158
  // Pick fetcher.loads that need to be revalidated
3667
4159
  let revalidatingFetchers = [];
3668
4160
  fetchLoadMatches.forEach((f, key) => {
@@ -3675,6 +4167,7 @@ function getMatchesToLoad(history, state, matches, submission, location, initial
3675
4167
  return;
3676
4168
  }
3677
4169
  let fetcherMatches = matchRoutes(routesToUse, f.path, basename);
4170
+
3678
4171
  // If the fetcher path no longer matches, push it in with null matches so
3679
4172
  // we can trigger a 404 in callLoadersAndMaybeResolveData. Note this is
3680
4173
  // currently only a use-case for Remix HMR where the route tree can change
@@ -3690,6 +4183,7 @@ function getMatchesToLoad(history, state, matches, submission, location, initial
3690
4183
  });
3691
4184
  return;
3692
4185
  }
4186
+
3693
4187
  // Revalidating fetchers are decoupled from the route matches since they
3694
4188
  // load from a static href. They revalidate based on explicit revalidation
3695
4189
  // (submission, useRevalidator, or X-Remix-Revalidate)
@@ -3740,20 +4234,24 @@ function shouldLoadRouteOnHydration(route, loaderData, errors) {
3740
4234
  if (route.lazy) {
3741
4235
  return true;
3742
4236
  }
4237
+
3743
4238
  // No loader, nothing to initialize
3744
4239
  if (!route.loader) {
3745
4240
  return false;
3746
4241
  }
3747
4242
  let hasData = loaderData != null && loaderData[route.id] !== undefined;
3748
4243
  let hasError = errors != null && errors[route.id] !== undefined;
4244
+
3749
4245
  // Don't run if we error'd during SSR
3750
4246
  if (!hasData && hasError) {
3751
4247
  return false;
3752
4248
  }
4249
+
3753
4250
  // Explicitly opting-in to running on hydration
3754
4251
  if (typeof route.loader === "function" && route.loader.hydrate === true) {
3755
4252
  return true;
3756
4253
  }
4254
+
3757
4255
  // Otherwise, run if we're not yet initialized with anything
3758
4256
  return !hasData && !hasError;
3759
4257
  }
@@ -3763,9 +4261,11 @@ function isNewLoader(currentLoaderData, currentMatch, match) {
3763
4261
  !currentMatch ||
3764
4262
  // [a, b] -> [a, c]
3765
4263
  match.route.id !== currentMatch.route.id;
4264
+
3766
4265
  // Handle the case that we don't have data for a re-used route, potentially
3767
4266
  // from a prior error
3768
4267
  let isMissingData = !currentLoaderData.hasOwnProperty(match.route.id);
4268
+
3769
4269
  // Always load if this is a net-new route or we don't yet have data
3770
4270
  return isNew || isMissingData;
3771
4271
  }
@@ -3801,6 +4301,7 @@ function patchRoutesImpl(routeId, children, routesToUse, manifest, mapRoutePrope
3801
4301
  } else {
3802
4302
  childrenToPatch = routesToUse;
3803
4303
  }
4304
+
3804
4305
  // Don't patch in routes we already know about so that `patch` is idempotent
3805
4306
  // to simplify user-land code. This is useful because we re-call the
3806
4307
  // `patchRoutesOnNavigation` function for matched routes with params.
@@ -3813,15 +4314,18 @@ function isSameRoute(newRoute, existingRoute) {
3813
4314
  if ("id" in newRoute && "id" in existingRoute && newRoute.id === existingRoute.id) {
3814
4315
  return true;
3815
4316
  }
4317
+
3816
4318
  // Second is by pathing differences
3817
4319
  if (!(newRoute.index === existingRoute.index && newRoute.path === existingRoute.path && newRoute.caseSensitive === existingRoute.caseSensitive)) {
3818
4320
  return false;
3819
4321
  }
4322
+
3820
4323
  // Pathless layout routes are trickier since we need to check children.
3821
4324
  // If they have no children then they're the same as far as we can tell
3822
4325
  if ((!newRoute.children || newRoute.children.length === 0) && (!existingRoute.children || existingRoute.children.length === 0)) {
3823
4326
  return true;
3824
4327
  }
4328
+
3825
4329
  // Otherwise, we look to see if every child in the new route is already
3826
4330
  // represented in the existing route's children
3827
4331
  return newRoute.children.every((aChild, i) => {
@@ -3829,6 +4333,7 @@ function isSameRoute(newRoute, existingRoute) {
3829
4333
  return (_existingRoute$childr = existingRoute.children) == null ? void 0 : _existingRoute$childr.some(bChild => isSameRoute(aChild, bChild));
3830
4334
  });
3831
4335
  }
4336
+
3832
4337
  /**
3833
4338
  * Execute route.lazy() methods to lazily load route modules (loader, action,
3834
4339
  * shouldRevalidate) and update the routeManifest in place which shares objects
@@ -3839,6 +4344,7 @@ async function loadLazyRouteModule(route, mapRouteProperties, manifest) {
3839
4344
  return;
3840
4345
  }
3841
4346
  let lazyRoute = await route.lazy();
4347
+
3842
4348
  // If the lazy route function was executed and removed by another parallel
3843
4349
  // call then we can return - first lazy() to finish wins because the return
3844
4350
  // value of lazy is expected to be static
@@ -3847,6 +4353,7 @@ async function loadLazyRouteModule(route, mapRouteProperties, manifest) {
3847
4353
  }
3848
4354
  let routeToUpdate = manifest[route.id];
3849
4355
  !routeToUpdate ? process.env.NODE_ENV !== "production" ? invariant$2(false, "No route found in manifest") : invariant$2(false) : void 0;
4356
+
3850
4357
  // Update the route in place. This should be safe because there's no way
3851
4358
  // we could yet be sitting on this route as we can't get there without
3852
4359
  // resolving lazy() first.
@@ -3867,9 +4374,11 @@ async function loadLazyRouteModule(route, mapRouteProperties, manifest) {
3867
4374
  routeUpdates[lazyRouteProperty] = lazyRoute[lazyRouteProperty];
3868
4375
  }
3869
4376
  }
4377
+
3870
4378
  // Mutate the route with the provided updates. Do this first so we pass
3871
4379
  // the updated version to mapRouteProperties
3872
4380
  Object.assign(routeToUpdate, routeUpdates);
4381
+
3873
4382
  // Mutate the `hasErrorBoundary` property on the route based on the route
3874
4383
  // updates and remove the `lazy` function so we don't resolve the lazy
3875
4384
  // route again.
@@ -3877,6 +4386,7 @@ async function loadLazyRouteModule(route, mapRouteProperties, manifest) {
3877
4386
  lazy: undefined
3878
4387
  }));
3879
4388
  }
4389
+
3880
4390
  // Default implementation of `dataStrategy` which fetches all loaders in parallel
3881
4391
  async function defaultDataStrategy(_ref4) {
3882
4392
  let {
@@ -3911,6 +4421,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matc
3911
4421
  resolve
3912
4422
  });
3913
4423
  });
4424
+
3914
4425
  // Send all matches here to allow for a middleware-type implementation.
3915
4426
  // handler will be a no-op for unneeded routes and we filter those results
3916
4427
  // back out below.
@@ -3921,6 +4432,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matc
3921
4432
  fetcherKey,
3922
4433
  context: requestContext
3923
4434
  });
4435
+
3924
4436
  // Wait for all routes to load here but 'swallow the error since we want
3925
4437
  // it to bubble up from the `await loadRoutePromise` in `callLoaderOrAction` -
3926
4438
  // called from `match.resolve()`
@@ -3931,6 +4443,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matc
3931
4443
  }
3932
4444
  return results;
3933
4445
  }
4446
+
3934
4447
  // Default logic for calling a loader/action is the user has no specified a dataStrategy
3935
4448
  async function callLoaderOrAction(type, request, match, loadRoutePromise, handlerOverride, staticContext) {
3936
4449
  let result;
@@ -3971,6 +4484,7 @@ async function callLoaderOrAction(type, request, match, loadRoutePromise, handle
3971
4484
  };
3972
4485
  try {
3973
4486
  let handler = match.route[type];
4487
+
3974
4488
  // If we have a route.lazy promise, await that first
3975
4489
  if (loadRoutePromise) {
3976
4490
  if (handler) {
@@ -4042,7 +4556,7 @@ async function convertDataStrategyResultToDataResult(dataStrategyResult) {
4042
4556
  result,
4043
4557
  type
4044
4558
  } = dataStrategyResult;
4045
- if (isResponse$2(result)) {
4559
+ if (isResponse(result)) {
4046
4560
  let data;
4047
4561
  try {
4048
4562
  let contentType = result.headers.get("Content-Type");
@@ -4089,6 +4603,7 @@ async function convertDataStrategyResultToDataResult(dataStrategyResult) {
4089
4603
  statusCode: (_result$init = result.init) == null ? void 0 : _result$init.status
4090
4604
  };
4091
4605
  }
4606
+
4092
4607
  // Convert thrown data() to ErrorResponse instances
4093
4608
  result = new ErrorResponseImpl(((_result$init2 = result.init) == null ? void 0 : _result$init2.status) || 500, undefined, result.data);
4094
4609
  }
@@ -4112,6 +4627,7 @@ async function convertDataStrategyResultToDataResult(dataStrategyResult) {
4112
4627
  data: result
4113
4628
  };
4114
4629
  }
4630
+
4115
4631
  // Support relative routing in internal redirects
4116
4632
  function normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename) {
4117
4633
  let location = response.headers.get("Location");
@@ -4135,6 +4651,7 @@ function normalizeRedirectLocation(location, currentUrl, basename) {
4135
4651
  }
4136
4652
  return location;
4137
4653
  }
4654
+
4138
4655
  // Utility method for creating the Request instances for loaders/actions during
4139
4656
  // client-side navigations and fetches. During SSR we will always have a
4140
4657
  // Request instance from the static handler (query/queryRoute)
@@ -4199,6 +4716,7 @@ function processRouteLoaderData(matches, results, pendingActionResult, isStaticH
4199
4716
  let foundError = false;
4200
4717
  let loaderHeaders = {};
4201
4718
  let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : undefined;
4719
+
4202
4720
  // Process loader results into state.loaderData/state.errors
4203
4721
  matches.forEach(match => {
4204
4722
  if (!(match.route.id in results)) {
@@ -4228,10 +4746,12 @@ function processRouteLoaderData(matches, results, pendingActionResult, isStaticH
4228
4746
  errors[boundaryMatch.route.id] = error;
4229
4747
  }
4230
4748
  }
4749
+
4231
4750
  // Clear our any prior loaderData for the throwing route
4232
4751
  if (!isStaticHandler) {
4233
4752
  loaderData[id] = ResetLoaderDataSymbol;
4234
4753
  }
4754
+
4235
4755
  // Once we find our first (highest) error, we set the status code and
4236
4756
  // prevent deeper status codes from overriding
4237
4757
  if (!foundError) {
@@ -4253,6 +4773,7 @@ function processRouteLoaderData(matches, results, pendingActionResult, isStaticH
4253
4773
  }
4254
4774
  }
4255
4775
  });
4776
+
4256
4777
  // If we didn't consume the pending action error (i.e., all loaders
4257
4778
  // resolved), then consume it here. Also clear out any loaderData for the
4258
4779
  // throwing route
@@ -4274,6 +4795,7 @@ function processLoaderData(state, matches, results, pendingActionResult, revalid
4274
4795
  loaderData,
4275
4796
  errors
4276
4797
  } = processRouteLoaderData(matches, results, pendingActionResult);
4798
+
4277
4799
  // Process results from our revalidating fetchers
4278
4800
  revalidatingFetchers.forEach(rf => {
4279
4801
  let {
@@ -4283,6 +4805,7 @@ function processLoaderData(state, matches, results, pendingActionResult, revalid
4283
4805
  } = rf;
4284
4806
  let result = fetcherResults[key];
4285
4807
  !result ? process.env.NODE_ENV !== "production" ? invariant$2(false, "Did not find corresponding fetcher result") : invariant$2(false) : void 0;
4808
+
4286
4809
  // Process fetcher non-redirect errors
4287
4810
  if (controller && controller.signal.aborted) {
4288
4811
  // Nothing to do for aborted fetchers
@@ -4319,6 +4842,7 @@ function mergeLoaderData(loaderData, newLoaderData, matches, errors) {
4319
4842
  merged[k] = v;
4320
4843
  return merged;
4321
4844
  }, {});
4845
+
4322
4846
  // Preserve existing `loaderData` for routes not included in `newLoaderData` and
4323
4847
  // where a loader wasn't removed by HMR
4324
4848
  for (let match of matches) {
@@ -4346,6 +4870,7 @@ function getActionDataForCommit(pendingActionResult) {
4346
4870
  }
4347
4871
  };
4348
4872
  }
4873
+
4349
4874
  // Find the nearest error boundary, looking upwards from the leaf route (or the
4350
4875
  // route specified by routeId) for the closest ancestor error boundary,
4351
4876
  // defaulting to the root match
@@ -4401,6 +4926,7 @@ function getInternalRouterError(status, _temp5) {
4401
4926
  }
4402
4927
  return new ErrorResponseImpl(status || 500, statusText, new Error(errorMessage), true);
4403
4928
  }
4929
+
4404
4930
  // Find any returned redirect errors, starting from the lowest match
4405
4931
  function findRedirect(results) {
4406
4932
  let entries = Object.entries(results);
@@ -4434,6 +4960,7 @@ function isHashChangeOnly(a, b) {
4434
4960
  // /page#hash -> /page#other
4435
4961
  return true;
4436
4962
  }
4963
+
4437
4964
  // If the hash is removed the browser will re-perform a request to the server
4438
4965
  // /page#hash -> /page
4439
4966
  return false;
@@ -4441,8 +4968,8 @@ function isHashChangeOnly(a, b) {
4441
4968
  function isDataStrategyResult(result) {
4442
4969
  return result != null && typeof result === "object" && "type" in result && "result" in result && (result.type === ResultType.data || result.type === ResultType.error);
4443
4970
  }
4444
- function isRedirectDataStrategyResultResult(result) {
4445
- return isResponse$2(result.result) && redirectStatusCodes$1.has(result.result.status);
4971
+ function isRedirectDataStrategyResult(result) {
4972
+ return isResponse(result.result) && redirectStatusCodes.has(result.result.status);
4446
4973
  }
4447
4974
  function isErrorResult(result) {
4448
4975
  return result.type === ResultType.error;
@@ -4453,16 +4980,14 @@ function isRedirectResult(result) {
4453
4980
  function isDataWithResponseInit(value) {
4454
4981
  return typeof value === "object" && value != null && "type" in value && "data" in value && "init" in value && value.type === "DataWithResponseInit";
4455
4982
  }
4456
- function isResponse$2(value) {
4983
+ function isResponse(value) {
4457
4984
  return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
4458
4985
  }
4459
- function isRedirectResponse$1(result) {
4460
- if (!isResponse$2(result)) {
4461
- return false;
4462
- }
4463
- let status = result.status;
4464
- let location = result.headers.get("Location");
4465
- return status >= 300 && status <= 399 && location != null;
4986
+ function isRedirectStatusCode(statusCode) {
4987
+ return redirectStatusCodes.has(statusCode);
4988
+ }
4989
+ function isRedirectResponse(result) {
4990
+ return isResponse(result) && isRedirectStatusCode(result.status) && result.headers.has("Location");
4466
4991
  }
4467
4992
  function isValidMethod(method) {
4468
4993
  return validRequestMethods.has(method.toUpperCase());
@@ -4673,6 +5198,9 @@ function createDeferred$1() {
4673
5198
  }
4674
5199
  //#endregion
4675
5200
 
5201
+ // Create react-specific types from the agnostic types in @remix-run/router to
5202
+ // export from react-router
5203
+
4676
5204
  const DataRouterContext = /*#__PURE__*/React.createContext(null);
4677
5205
  DataRouterContext.displayName = "DataRouter";
4678
5206
  const DataRouterStateContext = /*#__PURE__*/React.createContext(null);
@@ -4681,10 +5209,24 @@ const ViewTransitionContext = /*#__PURE__*/React.createContext({
4681
5209
  isTransitioning: false
4682
5210
  });
4683
5211
  ViewTransitionContext.displayName = "ViewTransition";
5212
+
5213
+ // TODO: (v7) Change the useFetcher data from `any` to `unknown`
5214
+
4684
5215
  const FetchersContext = /*#__PURE__*/React.createContext(new Map());
4685
5216
  FetchersContext.displayName = "Fetchers";
4686
5217
  const AwaitContext = /*#__PURE__*/React.createContext(null);
4687
5218
  AwaitContext.displayName = "Await";
5219
+
5220
+ /**
5221
+ * A Navigator is a "location changer"; it's how you get to different locations.
5222
+ *
5223
+ * Every history instance conforms to the Navigator interface, but the
5224
+ * distinction is useful primarily when it comes to the low-level `<Router>` API
5225
+ * where both the location and a navigator must be provided separately in order
5226
+ * to avoid "tearing" that may occur in a suspense-enabled app if the action
5227
+ * and/or location were to be read directly from the history instance.
5228
+ */
5229
+
4688
5230
  const NavigationContext = /*#__PURE__*/React.createContext(null);
4689
5231
  NavigationContext.displayName = "Navigation";
4690
5232
  const LocationContext = /*#__PURE__*/React.createContext(null);
@@ -4731,6 +5273,7 @@ function useHref(to, _temp) {
4731
5273
  relative
4732
5274
  });
4733
5275
  let joinedPathname = pathname;
5276
+
4734
5277
  // If we're operating within a basename, prepend it to the pathname prior
4735
5278
  // to creating the href. If this is a root navigation, then just use the raw
4736
5279
  // basename which allows the basename to have full control over the presence
@@ -4744,6 +5287,7 @@ function useHref(to, _temp) {
4744
5287
  hash
4745
5288
  });
4746
5289
  }
5290
+
4747
5291
  /**
4748
5292
  * Returns true if this component is a descendant of a Router, useful to ensure
4749
5293
  * a component is used within a Router.
@@ -4753,6 +5297,7 @@ function useHref(to, _temp) {
4753
5297
  function useInRouterContext() {
4754
5298
  return React.useContext(LocationContext) != null;
4755
5299
  }
5300
+
4756
5301
  /**
4757
5302
  Returns the current {@link Location}. This can be useful if you'd like to perform some side effect whenever it changes.
4758
5303
 
@@ -4782,6 +5327,7 @@ function useLocation() {
4782
5327
  "useLocation() may be used only in the context of a <Router> component.") : invariant$2(false) : void 0;
4783
5328
  return React.useContext(LocationContext).location;
4784
5329
  }
5330
+
4785
5331
  /**
4786
5332
  * Returns the current navigation action which describes how the router came to
4787
5333
  * the current location, either by a pop, push, or replace on the history stack.
@@ -4791,6 +5337,7 @@ function useLocation() {
4791
5337
  function useNavigationType() {
4792
5338
  return React.useContext(LocationContext).navigationType;
4793
5339
  }
5340
+
4794
5341
  /**
4795
5342
  * Returns a PathMatch object if the given pattern matches the current URL.
4796
5343
  * This is useful for components that need to know "active" state, e.g.
@@ -4807,7 +5354,13 @@ function useMatch(pattern) {
4807
5354
  } = useLocation();
4808
5355
  return React.useMemo(() => matchPath(pattern, decodePath(pathname)), [pathname, pattern]);
4809
5356
  }
5357
+
5358
+ /**
5359
+ * The interface for the navigate() function returned from useNavigate().
5360
+ */
5361
+
4810
5362
  const navigateEffectWarning = "You should call navigate() in a React.useEffect(), not when " + "your component is first rendered.";
5363
+
4811
5364
  // Mute warnings for calls to useNavigate in SSR environments
4812
5365
  function useIsomorphicLayoutEffect(cb) {
4813
5366
  let isStatic = React.useContext(NavigationContext).static;
@@ -4818,6 +5371,7 @@ function useIsomorphicLayoutEffect(cb) {
4818
5371
  React.useLayoutEffect(cb);
4819
5372
  }
4820
5373
  }
5374
+
4821
5375
  /**
4822
5376
  Returns a function that lets you navigate programmatically in the browser in response to user interactions or effects.
4823
5377
 
@@ -4873,6 +5427,7 @@ function useNavigateUnstable() {
4873
5427
  options = {};
4874
5428
  }
4875
5429
  process.env.NODE_ENV !== "production" ? warning(activeRef.current, navigateEffectWarning) : void 0;
5430
+
4876
5431
  // Short circuit here since if this happens on first render the navigate
4877
5432
  // is useless because we haven't wired up our history listener yet
4878
5433
  if (!activeRef.current) return;
@@ -4881,6 +5436,7 @@ function useNavigateUnstable() {
4881
5436
  return;
4882
5437
  }
4883
5438
  let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, options.relative === "path");
5439
+
4884
5440
  // If we're operating within a basename, prepend it to the pathname prior
4885
5441
  // to handing off to history (but only if we're not in a data router,
4886
5442
  // otherwise it'll prepend the basename inside of the router).
@@ -4895,6 +5451,7 @@ function useNavigateUnstable() {
4895
5451
  return navigate;
4896
5452
  }
4897
5453
  const OutletContext = /*#__PURE__*/React.createContext(null);
5454
+
4898
5455
  /**
4899
5456
  * Returns the parent route {@link OutletProps.context | `<Outlet context>`}.
4900
5457
  *
@@ -4903,6 +5460,7 @@ const OutletContext = /*#__PURE__*/React.createContext(null);
4903
5460
  function useOutletContext() {
4904
5461
  return React.useContext(OutletContext);
4905
5462
  }
5463
+
4906
5464
  /**
4907
5465
  * Returns the element for the child route at this level of the route
4908
5466
  * hierarchy. Used internally by `<Outlet>` to render child routes.
@@ -4918,6 +5476,7 @@ function useOutlet(context) {
4918
5476
  }
4919
5477
  return outlet;
4920
5478
  }
5479
+
4921
5480
  /**
4922
5481
  Returns an object of key/value pairs of the dynamic params from the current URL that were matched by the routes. Child routes inherit all params from their parent routes.
4923
5482
 
@@ -4941,6 +5500,7 @@ function useParams() {
4941
5500
  let routeMatch = matches[matches.length - 1];
4942
5501
  return routeMatch ? routeMatch.params : {};
4943
5502
  }
5503
+
4944
5504
  /**
4945
5505
  Resolves the pathname of the given `to` value against the current location. Similar to {@link useHref}, but returns a {@link Path} instead of a string.
4946
5506
 
@@ -4971,6 +5531,7 @@ function useResolvedPath(to, _temp2) {
4971
5531
  let routePathnamesJson = JSON.stringify(getResolveToMatches(matches));
4972
5532
  return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === "path"), [to, routePathnamesJson, locationPathname, relative]);
4973
5533
  }
5534
+
4974
5535
  /**
4975
5536
  Hook version of {@link Routes | `<Routes>`} that uses objects instead of components. These objects have the same properties as the component props.
4976
5537
 
@@ -5005,6 +5566,7 @@ function useResolvedPath(to, _temp2) {
5005
5566
  function useRoutes(routes, locationArg) {
5006
5567
  return useRoutesImpl(routes, locationArg);
5007
5568
  }
5569
+
5008
5570
  /**
5009
5571
  * Internal implementation with accept optional param for RouterProvider usage
5010
5572
  *
@@ -5097,6 +5659,7 @@ function useRoutesImpl(routes, locationArg, dataRouterState, future) {
5097
5659
  // Re-encode pathnames that were decoded inside matchRoutes
5098
5660
  navigator.encodeLocation ? navigator.encodeLocation(match.pathnameBase).pathname : match.pathnameBase])
5099
5661
  })), parentMatches, dataRouterState);
5662
+
5100
5663
  // When a user passes in a `locationArg`, the associated routes need to
5101
5664
  // be wrapped in a new `LocationContext.Provider` in order for `useLocation`
5102
5665
  // to use the scoped location instead of the global location.
@@ -5177,6 +5740,7 @@ class RenderErrorBoundary extends React.Component {
5177
5740
  revalidation: props.revalidation
5178
5741
  };
5179
5742
  }
5743
+
5180
5744
  // If we're not changing locations, preserve the location but still surface
5181
5745
  // any new errors that may come through. We retain the existing error, we do
5182
5746
  // this because the error provided from the app state may be cleared without
@@ -5191,12 +5755,12 @@ class RenderErrorBoundary extends React.Component {
5191
5755
  console.error("React Router caught the following error during render", error, errorInfo);
5192
5756
  }
5193
5757
  render() {
5194
- return this.state.error !== undefined ? ( /*#__PURE__*/React.createElement(RouteContext.Provider, {
5758
+ return this.state.error !== undefined ? /*#__PURE__*/React.createElement(RouteContext.Provider, {
5195
5759
  value: this.props.routeContext
5196
5760
  }, /*#__PURE__*/React.createElement(RouteErrorContext.Provider, {
5197
5761
  value: this.state.error,
5198
5762
  children: this.props.component
5199
- }))) : this.props.children;
5763
+ })) : this.props.children;
5200
5764
  }
5201
5765
  }
5202
5766
  function RenderedRoute(_ref) {
@@ -5206,6 +5770,7 @@ function RenderedRoute(_ref) {
5206
5770
  children
5207
5771
  } = _ref;
5208
5772
  let dataRouterContext = React.useContext(DataRouterContext);
5773
+
5209
5774
  // Track how deep we got in our render pass to emulate SSR componentDidCatch
5210
5775
  // in a DataStaticRouter
5211
5776
  if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) {
@@ -5244,6 +5809,7 @@ function _renderMatches(matches, parentMatches, dataRouterState, future) {
5244
5809
  }
5245
5810
  }
5246
5811
  let renderedMatches = matches;
5812
+
5247
5813
  // If we have data errors, trim matches to the highest error boundary
5248
5814
  let errors = (_dataRouterState = dataRouterState) == null ? void 0 : _dataRouterState.errors;
5249
5815
  if (errors != null) {
@@ -5251,6 +5817,7 @@ function _renderMatches(matches, parentMatches, dataRouterState, future) {
5251
5817
  !(errorIndex >= 0) ? process.env.NODE_ENV !== "production" ? invariant$2(false, "Could not find a matching route for errors on route IDs: " + Object.keys(errors).join(",")) : invariant$2(false) : void 0;
5252
5818
  renderedMatches = renderedMatches.slice(0, Math.min(renderedMatches.length, errorIndex + 1));
5253
5819
  }
5820
+
5254
5821
  // If we're in a partial hydration mode, detect if we need to render down to
5255
5822
  // a given HydrateFallback while we load the rest of the hydration data
5256
5823
  let renderFallback = false;
@@ -5336,7 +5903,7 @@ function _renderMatches(matches, parentMatches, dataRouterState, future) {
5336
5903
  // Only wrap in an error boundary within data router usages when we have an
5337
5904
  // ErrorBoundary/errorElement on this route. Otherwise let it bubble up to
5338
5905
  // an ancestor ErrorBoundary/errorElement
5339
- return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? ( /*#__PURE__*/React.createElement(RenderErrorBoundary, {
5906
+ return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? /*#__PURE__*/React.createElement(RenderErrorBoundary, {
5340
5907
  location: dataRouterState.location,
5341
5908
  revalidation: dataRouterState.revalidation,
5342
5909
  component: errorElement,
@@ -5347,17 +5914,16 @@ function _renderMatches(matches, parentMatches, dataRouterState, future) {
5347
5914
  matches,
5348
5915
  isDataRoute: true
5349
5916
  }
5350
- })) : getChildren();
5917
+ }) : getChildren();
5351
5918
  }, null);
5352
5919
  }
5353
- var DataRouterHook$1;
5354
- (function (DataRouterHook) {
5920
+ var DataRouterHook$1 = /*#__PURE__*/function (DataRouterHook) {
5355
5921
  DataRouterHook["UseBlocker"] = "useBlocker";
5356
5922
  DataRouterHook["UseRevalidator"] = "useRevalidator";
5357
5923
  DataRouterHook["UseNavigateStable"] = "useNavigate";
5358
- })(DataRouterHook$1 || (DataRouterHook$1 = {}));
5359
- var DataRouterStateHook$1;
5360
- (function (DataRouterStateHook) {
5924
+ return DataRouterHook;
5925
+ }(DataRouterHook$1 || {});
5926
+ var DataRouterStateHook$1 = /*#__PURE__*/function (DataRouterStateHook) {
5361
5927
  DataRouterStateHook["UseBlocker"] = "useBlocker";
5362
5928
  DataRouterStateHook["UseLoaderData"] = "useLoaderData";
5363
5929
  DataRouterStateHook["UseActionData"] = "useActionData";
@@ -5368,7 +5934,8 @@ var DataRouterStateHook$1;
5368
5934
  DataRouterStateHook["UseRevalidator"] = "useRevalidator";
5369
5935
  DataRouterStateHook["UseNavigateStable"] = "useNavigate";
5370
5936
  DataRouterStateHook["UseRouteId"] = "useRouteId";
5371
- })(DataRouterStateHook$1 || (DataRouterStateHook$1 = {}));
5937
+ return DataRouterStateHook;
5938
+ }(DataRouterStateHook$1 || {});
5372
5939
  function getDataRouterConsoleError$1(hookName) {
5373
5940
  return hookName + " must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.";
5374
5941
  }
@@ -5387,6 +5954,7 @@ function useRouteContext(hookName) {
5387
5954
  !route ? process.env.NODE_ENV !== "production" ? invariant$2(false, getDataRouterConsoleError$1(hookName)) : invariant$2(false) : void 0;
5388
5955
  return route;
5389
5956
  }
5957
+
5390
5958
  // Internal version with hookName-aware debugging
5391
5959
  function useCurrentRouteId(hookName) {
5392
5960
  let route = useRouteContext(hookName);
@@ -5394,12 +5962,14 @@ function useCurrentRouteId(hookName) {
5394
5962
  !thisRoute.route.id ? process.env.NODE_ENV !== "production" ? invariant$2(false, hookName + " can only be used on routes that contain a unique \"id\"") : invariant$2(false) : void 0;
5395
5963
  return thisRoute.route.id;
5396
5964
  }
5965
+
5397
5966
  /**
5398
5967
  * Returns the ID for the nearest contextual route
5399
5968
  */
5400
5969
  function useRouteId() {
5401
5970
  return useCurrentRouteId(DataRouterStateHook$1.UseRouteId);
5402
5971
  }
5972
+
5403
5973
  /**
5404
5974
  Returns the current navigation, defaulting to an "idle" navigation when no navigation is in progress. You can use this to render pending UI (like a global spinner) or read FormData from a form navigation.
5405
5975
 
@@ -5420,6 +5990,7 @@ function useNavigation() {
5420
5990
  let state = useDataRouterState$1(DataRouterStateHook$1.UseNavigation);
5421
5991
  return state.navigation;
5422
5992
  }
5993
+
5423
5994
  /**
5424
5995
  Revalidate the data on the page for reasons outside of normal data mutations like window focus or polling on an interval.
5425
5996
 
@@ -5455,6 +6026,7 @@ function useRevalidator() {
5455
6026
  state: state.revalidation
5456
6027
  }), [dataRouterContext.router, state.revalidation]);
5457
6028
  }
6029
+
5458
6030
  /**
5459
6031
  * Returns the active route matches, useful for accessing loaderData for
5460
6032
  * parent/child routes or the route "handle" property
@@ -5468,6 +6040,7 @@ function useMatches() {
5468
6040
  } = useDataRouterState$1(DataRouterStateHook$1.UseMatches);
5469
6041
  return React.useMemo(() => matches.map(m => convertRouteMatchToUiMatch(m, loaderData)), [matches, loaderData]);
5470
6042
  }
6043
+
5471
6044
  /**
5472
6045
  Returns the data from the closest route {@link LoaderFunction | loader} or {@link ClientLoaderFunction | client loader}.
5473
6046
 
@@ -5491,6 +6064,7 @@ function useLoaderData() {
5491
6064
  let routeId = useCurrentRouteId(DataRouterStateHook$1.UseLoaderData);
5492
6065
  return state.loaderData[routeId];
5493
6066
  }
6067
+
5494
6068
  /**
5495
6069
  Returns the loader data for a given route by route ID.
5496
6070
 
@@ -5522,6 +6096,7 @@ function useRouteLoaderData(routeId) {
5522
6096
  let state = useDataRouterState$1(DataRouterStateHook$1.UseRouteLoaderData);
5523
6097
  return state.loaderData[routeId];
5524
6098
  }
6099
+
5525
6100
  /**
5526
6101
  Returns the action data from the most recent POST navigation form submission or `undefined` if there hasn't been one.
5527
6102
 
@@ -5552,6 +6127,7 @@ function useActionData() {
5552
6127
  let routeId = useCurrentRouteId(DataRouterStateHook$1.UseLoaderData);
5553
6128
  return state.actionData ? state.actionData[routeId] : undefined;
5554
6129
  }
6130
+
5555
6131
  /**
5556
6132
  Accesses the error thrown during an {@link ActionFunction | action}, {@link LoaderFunction | loader}, or component render to be used in a route module Error Boundary.
5557
6133
 
@@ -5569,14 +6145,17 @@ function useRouteError() {
5569
6145
  let error = React.useContext(RouteErrorContext);
5570
6146
  let state = useDataRouterState$1(DataRouterStateHook$1.UseRouteError);
5571
6147
  let routeId = useCurrentRouteId(DataRouterStateHook$1.UseRouteError);
6148
+
5572
6149
  // If this was a render error, we put it in a RouteError context inside
5573
6150
  // of RenderErrorBoundary
5574
6151
  if (error !== undefined) {
5575
6152
  return error;
5576
6153
  }
6154
+
5577
6155
  // Otherwise look for errors from our data router state
5578
6156
  return (_state$errors = state.errors) == null ? void 0 : _state$errors[routeId];
5579
6157
  }
6158
+
5580
6159
  /**
5581
6160
  Returns the resolved promise value from the closest {@link Await | `<Await>`}.
5582
6161
 
@@ -5598,6 +6177,7 @@ function useAsyncValue() {
5598
6177
  let value = React.useContext(AwaitContext);
5599
6178
  return value == null ? void 0 : value._data;
5600
6179
  }
6180
+
5601
6181
  /**
5602
6182
  Returns the rejection value from the closest {@link Await | `<Await>`}.
5603
6183
 
@@ -5625,6 +6205,7 @@ function useAsyncError() {
5625
6205
  return value == null ? void 0 : value._error;
5626
6206
  }
5627
6207
  let blockerId = 0;
6208
+
5628
6209
  /**
5629
6210
  * Allow the application to block navigations within the SPA and present the
5630
6211
  * user a confirmation dialog to confirm the navigation. Mostly used to avoid
@@ -5647,6 +6228,7 @@ function useBlocker(shouldBlock) {
5647
6228
  if (basename === "/") {
5648
6229
  return shouldBlock(arg);
5649
6230
  }
6231
+
5650
6232
  // If they provided us a function and we've got an active basename, strip
5651
6233
  // it from the locations we expose to the user to match the behavior of
5652
6234
  // useLocation
@@ -5665,6 +6247,7 @@ function useBlocker(shouldBlock) {
5665
6247
  historyAction
5666
6248
  });
5667
6249
  }, [basename, shouldBlock]);
6250
+
5668
6251
  // This effect is in charge of blocker key assignment and deletion (which is
5669
6252
  // tightly coupled to the key)
5670
6253
  React.useEffect(() => {
@@ -5672,6 +6255,7 @@ function useBlocker(shouldBlock) {
5672
6255
  setBlockerKey(key);
5673
6256
  return () => router.deleteBlocker(key);
5674
6257
  }, [router]);
6258
+
5675
6259
  // This effect handles assigning the blockerFunction. This is to handle
5676
6260
  // unstable blocker function identities, and happens only after the prior
5677
6261
  // effect so we don't get an orphaned blockerFunction in the router with a
@@ -5681,10 +6265,12 @@ function useBlocker(shouldBlock) {
5681
6265
  router.getBlocker(blockerKey, blockerFunction);
5682
6266
  }
5683
6267
  }, [router, blockerKey, blockerFunction]);
6268
+
5684
6269
  // Prefer the blocker from `state` not `router.state` since DataRouterContext
5685
6270
  // is memoized so this ensures we update on blocker state updates
5686
6271
  return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER;
5687
6272
  }
6273
+
5688
6274
  /**
5689
6275
  * Stable version of useNavigate that is used when we are in the context of
5690
6276
  * a RouterProvider.
@@ -5705,6 +6291,7 @@ function useNavigateStable() {
5705
6291
  options = {};
5706
6292
  }
5707
6293
  process.env.NODE_ENV !== "production" ? warning(activeRef.current, navigateEffectWarning) : void 0;
6294
+
5708
6295
  // Short circuit here since if this happens on first render the navigate
5709
6296
  // is useless because we haven't wired up our router subscriber yet
5710
6297
  if (!activeRef.current) return;
@@ -5778,6 +6365,7 @@ function mapRouteProperties(route) {
5778
6365
  }
5779
6366
  return updates;
5780
6367
  }
6368
+
5781
6369
  /**
5782
6370
  * @category Routers
5783
6371
  */
@@ -5797,6 +6385,10 @@ function createMemoryRouter(routes, opts) {
5797
6385
  }).initialize();
5798
6386
  }
5799
6387
  class Deferred {
6388
+ // @ts-expect-error - no initializer
6389
+
6390
+ // @ts-expect-error - no initializer
6391
+
5800
6392
  constructor() {
5801
6393
  this.status = "pending";
5802
6394
  this.promise = new Promise((resolve, reject) => {
@@ -5815,6 +6407,9 @@ class Deferred {
5815
6407
  });
5816
6408
  }
5817
6409
  }
6410
+
6411
+ // Copied from react-dom types
6412
+
5818
6413
  /**
5819
6414
  * Given a Remix Router instance, render the appropriate UI
5820
6415
  */
@@ -5835,8 +6430,8 @@ function RouterProvider(_ref) {
5835
6430
  let setState = React.useCallback((newState, _ref2) => {
5836
6431
  let {
5837
6432
  deletedFetchers,
5838
- flushSync: flushSync,
5839
- viewTransitionOpts: viewTransitionOpts
6433
+ flushSync,
6434
+ viewTransitionOpts
5840
6435
  } = _ref2;
5841
6436
  deletedFetchers.forEach(key => fetcherData.current.delete(key));
5842
6437
  newState.fetchers.forEach((fetcher, key) => {
@@ -5847,6 +6442,7 @@ function RouterProvider(_ref) {
5847
6442
  warnOnce(flushSync === false || reactDomFlushSyncImpl != null, "You provided the `flushSync` option to a router update, " + "but you are not using the `<RouterProvider>` from `react-router/dom` " + "so `ReactDOM.flushSync()` is unavailable. Please update your app " + 'to `import { RouterProvider } from "react-router/dom"` and ensure ' + "you have `react-dom` installed as a dependency to use the " + "`flushSync` option.");
5848
6443
  let isViewTransitionAvailable = router.window != null && router.window.document != null && typeof router.window.document.startViewTransition === "function";
5849
6444
  warnOnce(viewTransitionOpts == null || isViewTransitionAvailable, "You provided the `viewTransition` option to a router update, " + "but you do not appear to be running in a DOM environment as " + "`window.startViewTransition` is not available.");
6445
+
5850
6446
  // If this isn't a view transition or it's not available in this browser,
5851
6447
  // just update and be done with it
5852
6448
  if (!viewTransitionOpts || !isViewTransitionAvailable) {
@@ -5857,6 +6453,7 @@ function RouterProvider(_ref) {
5857
6453
  }
5858
6454
  return;
5859
6455
  }
6456
+
5860
6457
  // flushSync + startViewTransition
5861
6458
  if (reactDomFlushSyncImpl && flushSync) {
5862
6459
  // Flush through the context to mark DOM elements as transition=ing
@@ -5873,10 +6470,12 @@ function RouterProvider(_ref) {
5873
6470
  nextLocation: viewTransitionOpts.nextLocation
5874
6471
  });
5875
6472
  });
6473
+
5876
6474
  // Update the DOM
5877
6475
  let t = router.window.document.startViewTransition(() => {
5878
6476
  reactDomFlushSyncImpl(() => setStateImpl(newState));
5879
6477
  });
6478
+
5880
6479
  // Clean up after the animation completes
5881
6480
  t.finished.finally(() => {
5882
6481
  reactDomFlushSyncImpl(() => {
@@ -5891,6 +6490,7 @@ function RouterProvider(_ref) {
5891
6490
  reactDomFlushSyncImpl(() => setTransition(t));
5892
6491
  return;
5893
6492
  }
6493
+
5894
6494
  // startTransition + startViewTransition
5895
6495
  if (transition) {
5896
6496
  // Interrupting an in-progress transition, cancel and let everything flush
@@ -5913,9 +6513,11 @@ function RouterProvider(_ref) {
5913
6513
  });
5914
6514
  }
5915
6515
  }, [router.window, reactDomFlushSyncImpl, transition, renderDfd]);
6516
+
5916
6517
  // Need to use a layout effect here so we are subscribed early enough to
5917
6518
  // pick up on any render-driven redirects/navigations (useEffect/<Navigate>)
5918
6519
  React.useLayoutEffect(() => router.subscribe(setState), [router, setState]);
6520
+
5919
6521
  // When we start a view transition, create a Deferred we can use for the
5920
6522
  // eventual "completed" render
5921
6523
  React.useEffect(() => {
@@ -5923,6 +6525,7 @@ function RouterProvider(_ref) {
5923
6525
  setRenderDfd(new Deferred());
5924
6526
  }
5925
6527
  }, [vtContext]);
6528
+
5926
6529
  // Once the deferred is created, kick off startViewTransition() to update the
5927
6530
  // DOM and then wait on the Deferred to resolve (indicating the DOM update has
5928
6531
  // happened)
@@ -5945,6 +6548,7 @@ function RouterProvider(_ref) {
5945
6548
  setTransition(transition);
5946
6549
  }
5947
6550
  }, [pendingState, renderDfd, router.window]);
6551
+
5948
6552
  // When the new location finally renders and is committed to the DOM, this
5949
6553
  // effect will run to resolve the transition
5950
6554
  React.useEffect(() => {
@@ -5952,6 +6556,7 @@ function RouterProvider(_ref) {
5952
6556
  renderDfd.resolve();
5953
6557
  }
5954
6558
  }, [renderDfd, transition, state.location, pendingState]);
6559
+
5955
6560
  // If we get interrupted with a new navigation during a transition, we skip
5956
6561
  // the active transition, let it cleanup, then kick it off again here
5957
6562
  React.useEffect(() => {
@@ -5989,6 +6594,7 @@ function RouterProvider(_ref) {
5989
6594
  static: false,
5990
6595
  basename
5991
6596
  }), [router, navigator, basename]);
6597
+
5992
6598
  // The fragment and {null} here are important! We need them to keep React 18's
5993
6599
  // useId happy when we are server-rendering since we may have a <script> here
5994
6600
  // containing the hydrated server-side staticContext (from StaticRouterProvider).
@@ -6014,6 +6620,7 @@ function RouterProvider(_ref) {
6014
6620
  state: state
6015
6621
  })))))), null);
6016
6622
  }
6623
+
6017
6624
  // Memoize to avoid re-renders when updating `ViewTransitionContext`
6018
6625
  const MemoizedDataRoutes = /*#__PURE__*/React.memo(DataRoutes$1);
6019
6626
  function DataRoutes$1(_ref3) {
@@ -6024,6 +6631,11 @@ function DataRoutes$1(_ref3) {
6024
6631
  } = _ref3;
6025
6632
  return useRoutesImpl(routes, undefined, state);
6026
6633
  }
6634
+
6635
+ /**
6636
+ * @category Types
6637
+ */
6638
+
6027
6639
  /**
6028
6640
  * A `<Router>` that stores all entries in memory.
6029
6641
  *
@@ -6061,6 +6673,11 @@ function MemoryRouter(_ref4) {
6061
6673
  navigator: history
6062
6674
  });
6063
6675
  }
6676
+
6677
+ /**
6678
+ * @category Types
6679
+ */
6680
+
6064
6681
  /**
6065
6682
  * A component-based version of {@link useNavigate} to use in a [`React.Component
6066
6683
  * Class`](https://reactjs.org/docs/react-component.html) where hooks are not
@@ -6091,6 +6708,7 @@ function Navigate(_ref5) {
6091
6708
  pathname: locationPathname
6092
6709
  } = useLocation();
6093
6710
  let navigate = useNavigate();
6711
+
6094
6712
  // Resolve the path outside of the effect so that when effects run twice in
6095
6713
  // StrictMode they navigate to the same place
6096
6714
  let path = resolveTo(to, getResolveToMatches(matches), locationPathname, relative === "path");
@@ -6104,6 +6722,11 @@ function Navigate(_ref5) {
6104
6722
  }, [navigate, jsonPath, relative, replace, state]);
6105
6723
  return null;
6106
6724
  }
6725
+
6726
+ /**
6727
+ * @category Types
6728
+ */
6729
+
6107
6730
  /**
6108
6731
  Renders the matching child route of a parent route or nothing if no child route matches.
6109
6732
 
@@ -6125,6 +6748,19 @@ function Navigate(_ref5) {
6125
6748
  function Outlet(props) {
6126
6749
  return useOutlet(props.context);
6127
6750
  }
6751
+
6752
+ /**
6753
+ * @category Types
6754
+ */
6755
+
6756
+ /**
6757
+ * @category Types
6758
+ */
6759
+
6760
+ /**
6761
+ * @category Types
6762
+ */
6763
+
6128
6764
  /**
6129
6765
  * Configures an element to render when a pattern matches the current location.
6130
6766
  * It must be rendered within a {@link Routes} element. Note that these routes
@@ -6136,6 +6772,11 @@ function Outlet(props) {
6136
6772
  function Route(_props) {
6137
6773
  process.env.NODE_ENV !== "production" ? invariant$2(false, "A <Route> is only ever to be used as the child of <Routes> element, " + "never rendered directly. Please wrap your <Route> in a <Routes>.") : invariant$2(false) ;
6138
6774
  }
6775
+
6776
+ /**
6777
+ * @category Types
6778
+ */
6779
+
6139
6780
  /**
6140
6781
  * Provides location context for the rest of the app.
6141
6782
  *
@@ -6155,6 +6796,7 @@ function Router(_ref6) {
6155
6796
  static: staticProp = false
6156
6797
  } = _ref6;
6157
6798
  !!useInRouterContext() ? process.env.NODE_ENV !== "production" ? invariant$2(false, "You cannot render a <Router> inside another <Router>." + " You should never have more than one in your app.") : invariant$2(false) : void 0;
6799
+
6158
6800
  // Preserve trailing slashes on basename, so we can let the user control
6159
6801
  // the enforcement of trailing slashes throughout the app
6160
6802
  let basename = basenameProp.replace(/^\/*/, "/");
@@ -6201,6 +6843,11 @@ function Router(_ref6) {
6201
6843
  value: locationContext
6202
6844
  }));
6203
6845
  }
6846
+
6847
+ /**
6848
+ * @category Types
6849
+ */
6850
+
6204
6851
  /**
6205
6852
  Renders a branch of {@link Route | `<Routes>`} that best matches the current
6206
6853
  location. Note that these routes do not participate in data loading, actions,
@@ -6225,6 +6872,11 @@ function Routes(_ref7) {
6225
6872
  } = _ref7;
6226
6873
  return useRoutes(createRoutesFromChildren(children), location);
6227
6874
  }
6875
+
6876
+ /**
6877
+ * @category Types
6878
+ */
6879
+
6228
6880
  /**
6229
6881
  Used to render promise values with automatic error handling.
6230
6882
 
@@ -6277,12 +6929,12 @@ function Await(_ref8) {
6277
6929
  errorElement: errorElement
6278
6930
  }, /*#__PURE__*/React.createElement(ResolveAwait, null, children));
6279
6931
  }
6280
- var AwaitRenderStatus;
6281
- (function (AwaitRenderStatus) {
6932
+ var AwaitRenderStatus = /*#__PURE__*/function (AwaitRenderStatus) {
6282
6933
  AwaitRenderStatus[AwaitRenderStatus["pending"] = 0] = "pending";
6283
6934
  AwaitRenderStatus[AwaitRenderStatus["success"] = 1] = "success";
6284
6935
  AwaitRenderStatus[AwaitRenderStatus["error"] = 2] = "error";
6285
- })(AwaitRenderStatus || (AwaitRenderStatus = {}));
6936
+ return AwaitRenderStatus;
6937
+ }(AwaitRenderStatus || {});
6286
6938
  class AwaitErrorBoundary extends React.Component {
6287
6939
  constructor(props) {
6288
6940
  super(props);
@@ -6361,10 +7013,12 @@ class AwaitErrorBoundary extends React.Component {
6361
7013
  children: children
6362
7014
  });
6363
7015
  }
7016
+
6364
7017
  // Throw to the suspense boundary
6365
7018
  throw promise;
6366
7019
  }
6367
7020
  }
7021
+
6368
7022
  /**
6369
7023
  * @private
6370
7024
  * Indirection to leverage useAsyncValue for a render-prop API on `<Await>`
@@ -6377,9 +7031,11 @@ function ResolveAwait(_ref9) {
6377
7031
  let toRender = typeof children === "function" ? children(data) : children;
6378
7032
  return /*#__PURE__*/React.createElement(React.Fragment, null, toRender);
6379
7033
  }
7034
+
6380
7035
  ///////////////////////////////////////////////////////////////////////////////
6381
7036
  // UTILS
6382
7037
  ///////////////////////////////////////////////////////////////////////////////
7038
+
6383
7039
  /**
6384
7040
  * Creates a route config from a React "children" object, which is usually
6385
7041
  * either a `<Route>` element or an array of them. Used internally by
@@ -6431,6 +7087,7 @@ function createRoutesFromChildren(children, parentPath) {
6431
7087
  });
6432
7088
  return routes;
6433
7089
  }
7090
+
6434
7091
  /**
6435
7092
  * Renders the result of `matchRoutes()` into a React element.
6436
7093
  *
@@ -6518,6 +7175,9 @@ function getSearchParamsForLocation(locationSearch, defaultSearchParams) {
6518
7175
  }
6519
7176
  return searchParams;
6520
7177
  }
7178
+
7179
+ // Thanks https://github.com/sindresorhus/type-fest!
7180
+
6521
7181
  // One-time check for submitter support
6522
7182
  let _formDataSupportsSubmitter = null;
6523
7183
  function isFormDataSubmitterSupported() {
@@ -6533,6 +7193,19 @@ function isFormDataSubmitterSupported() {
6533
7193
  }
6534
7194
  return _formDataSupportsSubmitter;
6535
7195
  }
7196
+
7197
+ /**
7198
+ * Submit options shared by both navigations and fetchers
7199
+ */
7200
+
7201
+ /**
7202
+ * Submit options available to fetchers
7203
+ */
7204
+
7205
+ /**
7206
+ * Submit options available to navigations
7207
+ */
7208
+
6536
7209
  const supportedFormEncTypes = new Set(["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]);
6537
7210
  function getFormEncType(encType) {
6538
7211
  if (encType != null && !supportedFormEncTypes.has(encType)) {
@@ -6561,7 +7234,9 @@ function getFormSubmissionInfo(target, basename) {
6561
7234
  if (form == null) {
6562
7235
  throw new Error("Cannot submit a <button> or <input type=\"submit\"> without a <form>");
6563
7236
  }
7237
+
6564
7238
  // <button>/<input type="submit"> may override attributes of <form>
7239
+
6565
7240
  // When grabbing the action from the element, it will have had the basename
6566
7241
  // prefixed to ensure non-JS scenarios work, so strip it since we'll
6567
7242
  // re-prefix in the router
@@ -6569,8 +7244,10 @@ function getFormSubmissionInfo(target, basename) {
6569
7244
  action = attr ? stripBasename(attr, basename) : null;
6570
7245
  method = target.getAttribute("formmethod") || form.getAttribute("method") || defaultMethod;
6571
7246
  encType = getFormEncType(target.getAttribute("formenctype")) || getFormEncType(form.getAttribute("enctype")) || defaultEncType;
7247
+
6572
7248
  // Build a FormData object populated from a form and submitter
6573
7249
  formData = new FormData(form, target);
7250
+
6574
7251
  // If this browser doesn't support the `FormData(el, submitter)` format,
6575
7252
  // then tack on the submitter value at the end. This is a lightweight
6576
7253
  // solution that is not 100% spec compliant. For complete support in older
@@ -6597,6 +7274,7 @@ function getFormSubmissionInfo(target, basename) {
6597
7274
  encType = defaultEncType;
6598
7275
  body = target;
6599
7276
  }
7277
+
6600
7278
  // Send body for <Form encType="text/plain" so we encode it into text
6601
7279
  if (formData && encType === "text/plain") {
6602
7280
  body = formData;
@@ -6617,6 +7295,105 @@ function invariant$1(value, message) {
6617
7295
  }
6618
7296
  }
6619
7297
 
7298
+ /**
7299
+ * A function that handles data mutations for a route on the client
7300
+ */
7301
+
7302
+ /**
7303
+ * Arguments passed to a route `clientAction` function
7304
+ */
7305
+
7306
+ /**
7307
+ * A function that loads data for a route on the client
7308
+ */
7309
+
7310
+ /**
7311
+ * Arguments passed to a route `clientLoader` function
7312
+ */
7313
+
7314
+ /**
7315
+ * ErrorBoundary to display for this route
7316
+ */
7317
+
7318
+ /**
7319
+ * `<Route HydrateFallback>` component to render on initial loads
7320
+ * when client loaders are present
7321
+ */
7322
+
7323
+ /**
7324
+ * Optional, root-only `<Route Layout>` component to wrap the root content in.
7325
+ * Useful for defining the <html>/<head>/<body> document shell shared by the
7326
+ * Component, HydrateFallback, and ErrorBoundary
7327
+ */
7328
+
7329
+ /**
7330
+ * A function that defines `<link>` tags to be inserted into the `<head>` of
7331
+ * the document on route transitions.
7332
+ *
7333
+ * @see https://remix.run/route/meta
7334
+ */
7335
+
7336
+ /**
7337
+ * A function that returns an array of data objects to use for rendering
7338
+ * metadata HTML tags in a route. These tags are not rendered on descendant
7339
+ * routes in the route hierarchy. In other words, they will only be rendered on
7340
+ * the route in which they are exported.
7341
+ *
7342
+ * @param Loader - The type of the current route's loader function
7343
+ * @param MatchLoaders - Mapping from a parent route's filepath to its loader
7344
+ * function type
7345
+ *
7346
+ * Note that parent route filepaths are relative to the `app/` directory.
7347
+ *
7348
+ * For example, if this meta function is for `/sales/customers/$customerId`:
7349
+ *
7350
+ * ```ts
7351
+ * // app/root.tsx
7352
+ * const loader = () => ({ hello: "world" })
7353
+ * export type Loader = typeof loader
7354
+ *
7355
+ * // app/routes/sales.tsx
7356
+ * const loader = () => ({ salesCount: 1074 })
7357
+ * export type Loader = typeof loader
7358
+ *
7359
+ * // app/routes/sales/customers.tsx
7360
+ * const loader = () => ({ customerCount: 74 })
7361
+ * export type Loader = typeof loader
7362
+ *
7363
+ * // app/routes/sales/customers/$customersId.tsx
7364
+ * import type { Loader as RootLoader } from "../../../root"
7365
+ * import type { Loader as SalesLoader } from "../../sales"
7366
+ * import type { Loader as CustomersLoader } from "../../sales/customers"
7367
+ *
7368
+ * const loader = () => ({ name: "Customer name" })
7369
+ *
7370
+ * const meta: MetaFunction<typeof loader, {
7371
+ * "root": RootLoader,
7372
+ * "routes/sales": SalesLoader,
7373
+ * "routes/sales/customers": CustomersLoader,
7374
+ * }> = ({ data, matches }) => {
7375
+ * const { name } = data
7376
+ * // ^? string
7377
+ * const { customerCount } = matches.find((match) => match.id === "routes/sales/customers").data
7378
+ * // ^? number
7379
+ * const { salesCount } = matches.find((match) => match.id === "routes/sales").data
7380
+ * // ^? number
7381
+ * const { hello } = matches.find((match) => match.id === "root").data
7382
+ * // ^? "world"
7383
+ * }
7384
+ * ```
7385
+ */
7386
+
7387
+ /**
7388
+ * A React component that is rendered for a route.
7389
+ */
7390
+
7391
+ /**
7392
+ * An arbitrary object that is associated with a route.
7393
+ *
7394
+ * @see https://remix.run/route/handle
7395
+ */
7396
+
6620
7397
  async function loadRouteModule(route, routeModulesCache) {
6621
7398
  if (route.id in routeModulesCache) {
6622
7399
  return routeModulesCache[route.id];
@@ -6634,6 +7411,7 @@ async function loadRouteModule(route, routeModulesCache) {
6634
7411
  // - Or, the asset trying to be imported has an error (usually in vite dev
6635
7412
  // mode), so the best we can do here is log the error for visibility
6636
7413
  // (via `Preserve log`) and reload
7414
+
6637
7415
  // Log the error so it can be accessed via the `Preserve Log` setting
6638
7416
  console.error("Error loading route module `" + route.module + "`, reloading page...");
6639
7417
  console.error(error);
@@ -6661,7 +7439,7 @@ function getKeyedLinksForMatches(matches, routeModules, manifest) {
6661
7439
  let descriptors = matches.map(match => {
6662
7440
  let module = routeModules[match.route.id];
6663
7441
  let route = manifest.routes[match.route.id];
6664
- return [route.css ? route.css.map(href => ({
7442
+ return [route && route.css ? route.css.map(href => ({
6665
7443
  rel: "stylesheet",
6666
7444
  href
6667
7445
  })) : [], (module == null || module.links == null ? void 0 : module.links()) || []];
@@ -6691,6 +7469,7 @@ async function prefetchStyleLinks(route, routeModule) {
6691
7469
  }));
6692
7470
  }
6693
7471
  }
7472
+
6694
7473
  // don't block for non-matching media queries, or for stylesheets that are
6695
7474
  // already in the DOM (active route revalidations)
6696
7475
  let matchingLinks = styleLinks.filter(link => (!link.media || window.matchMedia(link.media).matches) && !document.querySelector("link[rel=\"stylesheet\"][href=\"" + link.href + "\"]"));
@@ -6719,6 +7498,7 @@ async function prefetchStyleLink(descriptor) {
6719
7498
  document.head.appendChild(link);
6720
7499
  });
6721
7500
  }
7501
+
6722
7502
  ////////////////////////////////////////////////////////////////////////////////
6723
7503
  function isPageLinkDescriptor(object) {
6724
7504
  return object != null && typeof object.page === "string";
@@ -6727,6 +7507,7 @@ function isHtmlLinkDescriptor(object) {
6727
7507
  if (object == null) {
6728
7508
  return false;
6729
7509
  }
7510
+
6730
7511
  // <link> may not have an href if <link rel="preload"> is used with imageSrcSet + imageSizes
6731
7512
  // https://github.com/remix-run/remix/issues/184
6732
7513
  // https://html.spec.whatwg.org/commit-snapshots/cb4f5ff75de5f4cbd7013c4abad02f21c77d4d1c/#attr-link-imagesrcset
@@ -6737,8 +7518,12 @@ function isHtmlLinkDescriptor(object) {
6737
7518
  }
6738
7519
  async function getKeyedPrefetchLinks(matches, manifest, routeModules) {
6739
7520
  let links = await Promise.all(matches.map(async match => {
6740
- let mod = await loadRouteModule(manifest.routes[match.route.id], routeModules);
6741
- return mod.links ? mod.links() : [];
7521
+ let route = manifest.routes[match.route.id];
7522
+ if (route) {
7523
+ let mod = await loadRouteModule(route, routeModules);
7524
+ return mod.links ? mod.links() : [];
7525
+ }
7526
+ return [];
6742
7527
  }));
6743
7528
  return dedupeLinkDescriptors(links.flat(1).filter(isHtmlLinkDescriptor).filter(link => link.rel === "stylesheet" || link.rel === "preload").map(link => link.rel === "stylesheet" ? _extends({}, link, {
6744
7529
  rel: "prefetch",
@@ -6747,9 +7532,9 @@ async function getKeyedPrefetchLinks(matches, manifest, routeModules) {
6747
7532
  rel: "prefetch"
6748
7533
  })));
6749
7534
  }
7535
+
6750
7536
  // This is ridiculously identical to transition.ts `filterMatchesToLoad`
6751
7537
  function getNewMatchesForLinks(page, nextMatches, currentMatches, manifest, location, mode) {
6752
- let path = parsePathPatch(page);
6753
7538
  let isNew = (match, index) => {
6754
7539
  if (!currentMatches[index]) return true;
6755
7540
  return match.route.id !== currentMatches[index].route.id;
@@ -6764,42 +7549,45 @@ function getNewMatchesForLinks(page, nextMatches, currentMatches, manifest, loca
6764
7549
  ((_currentMatches$index = currentMatches[index].route.path) == null ? void 0 : _currentMatches$index.endsWith("*")) && currentMatches[index].params["*"] !== match.params["*"]
6765
7550
  );
6766
7551
  };
6767
- // NOTE: keep this mostly up-to-date w/ the transition data diff, but this
7552
+ if (mode === "assets") {
7553
+ return nextMatches.filter((match, index) => isNew(match, index) || matchPathChanged(match, index));
7554
+ }
7555
+
7556
+ // NOTE: keep this mostly up-to-date w/ the router data diff, but this
6768
7557
  // version doesn't care about submissions
6769
- let newMatches = mode === "data" && location.search !== path.search ?
6770
- // this is really similar to stuff in transition.ts, maybe somebody smarter
7558
+ // TODO: this is really similar to stuff in router.ts, maybe somebody smarter
6771
7559
  // than me (or in less of a hurry) can share some of it. You're the best.
6772
- nextMatches.filter((match, index) => {
6773
- let manifestRoute = manifest.routes[match.route.id];
6774
- if (!manifestRoute.hasLoader) {
6775
- return false;
6776
- }
6777
- if (isNew(match, index) || matchPathChanged(match, index)) {
6778
- return true;
6779
- }
6780
- if (match.route.shouldRevalidate) {
6781
- var _currentMatches$;
6782
- let routeChoice = match.route.shouldRevalidate({
6783
- currentUrl: new URL(location.pathname + location.search + location.hash, window.origin),
6784
- currentParams: ((_currentMatches$ = currentMatches[0]) == null ? void 0 : _currentMatches$.params) || {},
6785
- nextUrl: new URL(page, window.origin),
6786
- nextParams: match.params,
6787
- defaultShouldRevalidate: true
6788
- });
6789
- if (typeof routeChoice === "boolean") {
6790
- return routeChoice;
7560
+ if (mode === "data") {
7561
+ return nextMatches.filter((match, index) => {
7562
+ let manifestRoute = manifest.routes[match.route.id];
7563
+ if (!manifestRoute || !manifestRoute.hasLoader) {
7564
+ return false;
6791
7565
  }
6792
- }
6793
- return true;
6794
- }) : nextMatches.filter((match, index) => {
6795
- let manifestRoute = manifest.routes[match.route.id];
6796
- return (mode === "assets" || manifestRoute.hasLoader) && (isNew(match, index) || matchPathChanged(match, index));
6797
- });
6798
- return newMatches;
7566
+ if (isNew(match, index) || matchPathChanged(match, index)) {
7567
+ return true;
7568
+ }
7569
+ if (match.route.shouldRevalidate) {
7570
+ var _currentMatches$;
7571
+ let routeChoice = match.route.shouldRevalidate({
7572
+ currentUrl: new URL(location.pathname + location.search + location.hash, window.origin),
7573
+ currentParams: ((_currentMatches$ = currentMatches[0]) == null ? void 0 : _currentMatches$.params) || {},
7574
+ nextUrl: new URL(page, window.origin),
7575
+ nextParams: match.params,
7576
+ defaultShouldRevalidate: true
7577
+ });
7578
+ if (typeof routeChoice === "boolean") {
7579
+ return routeChoice;
7580
+ }
7581
+ }
7582
+ return true;
7583
+ });
7584
+ }
7585
+ return [];
6799
7586
  }
6800
7587
  function getModuleLinkHrefs(matches, manifestPatch) {
6801
7588
  return dedupeHrefs(matches.map(match => {
6802
7589
  let route = manifestPatch.routes[match.route.id];
7590
+ if (!route) return [];
6803
7591
  let hrefs = [route.module];
6804
7592
  if (route.imports) {
6805
7593
  hrefs = hrefs.concat(route.imports);
@@ -6807,12 +7595,14 @@ function getModuleLinkHrefs(matches, manifestPatch) {
6807
7595
  return hrefs;
6808
7596
  }).flat(1));
6809
7597
  }
7598
+
6810
7599
  // The `<Script>` will render rel=modulepreload for the current page, we don't
6811
7600
  // need to include them in a page prefetch, this gives us the list to remove
6812
7601
  // while deduping.
6813
7602
  function getCurrentPageModulePreloadHrefs(matches, manifest) {
6814
7603
  return dedupeHrefs(matches.map(match => {
6815
7604
  let route = manifest.routes[match.route.id];
7605
+ if (!route) return [];
6816
7606
  let hrefs = [route.module];
6817
7607
  if (route.imports) {
6818
7608
  hrefs = hrefs.concat(route.imports);
@@ -6850,12 +7640,7 @@ function dedupeLinkDescriptors(descriptors, preloads) {
6850
7640
  return deduped;
6851
7641
  }, []);
6852
7642
  }
6853
- // https://github.com/remix-run/history/issues/897
6854
- function parsePathPatch(href) {
6855
- let path = parsePath(href);
6856
- if (path.search === undefined) path.search = "";
6857
- return path;
6858
- }
7643
+
6859
7644
  // Detect if this browser supports <link rel="preload"> (or has it enabled).
6860
7645
  // Originally added to handle the firefox `network.preload` config:
6861
7646
  // https://bugzilla.mozilla.org/show_bug.cgi?id=1847811
@@ -6872,8 +7657,10 @@ function isPreloadSupported() {
6872
7657
 
6873
7658
  // This escapeHtml utility is based on https://github.com/zertosh/htmlescape
6874
7659
  // License: https://github.com/zertosh/htmlescape/blob/0527ca7156a524d256101bb310a9f970f63078ad/LICENSE
7660
+
6875
7661
  // We've chosen to inline the utility here to reduce the number of npm dependencies we have,
6876
7662
  // slightly decrease the code size compared the original package and make it esm compatible.
7663
+
6877
7664
  const ESCAPE_LOOKUP$2 = {
6878
7665
  "&": "\\u0026",
6879
7666
  ">": "\\u003e",
@@ -6891,9 +7678,6 @@ function createHtml(html) {
6891
7678
  };
6892
7679
  }
6893
7680
 
6894
- function isResponse$1(value) {
6895
- return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
6896
- }
6897
7681
  async function createRequestInit(request) {
6898
7682
  let init = {
6899
7683
  signal: request.signal
@@ -6901,6 +7685,7 @@ async function createRequestInit(request) {
6901
7685
  if (request.method !== "GET") {
6902
7686
  init.method = request.method;
6903
7687
  let contentType = request.headers.get("Content-Type");
7688
+
6904
7689
  // Check between word boundaries instead of startsWith() due to the last
6905
7690
  // paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type
6906
7691
  if (contentType && /\bapplication\/json\b/.test(contentType)) {
@@ -6967,12 +7752,12 @@ function StreamTransfer(_ref) {
6967
7752
  done,
6968
7753
  value
6969
7754
  } = promise.result;
6970
- let scriptTag = value ? ( /*#__PURE__*/React.createElement("script", {
7755
+ let scriptTag = value ? /*#__PURE__*/React.createElement("script", {
6971
7756
  nonce: nonce,
6972
7757
  dangerouslySetInnerHTML: {
6973
7758
  __html: "window.__reactRouterContext.streamController.enqueue(" + escapeHtml$1(JSON.stringify(value)) + ");"
6974
7759
  }
6975
- })) : null;
7760
+ }) : null;
6976
7761
  if (done) {
6977
7762
  return /*#__PURE__*/React.createElement(React.Fragment, null, scriptTag, /*#__PURE__*/React.createElement("script", {
6978
7763
  nonce: nonce,
@@ -7001,14 +7786,17 @@ function getSingleFetchDataStrategy$1(manifest, routeModules, getRouter) {
7001
7786
  if (request.method !== "GET") {
7002
7787
  return singleFetchActionStrategy(request, matches);
7003
7788
  }
7789
+
7004
7790
  // Fetcher loads are singular calls to one loader
7005
7791
  if (fetcherKey) {
7006
7792
  return singleFetchLoaderFetcherStrategy(request, matches);
7007
7793
  }
7794
+
7008
7795
  // Navigational loads are more complex...
7009
7796
  return singleFetchLoaderNavigationStrategy(manifest, routeModules, getRouter(), request, matches);
7010
7797
  };
7011
7798
  }
7799
+
7012
7800
  // Actions are simple since they're singular calls to the server for both
7013
7801
  // navigations and fetchers)
7014
7802
  async function singleFetchActionStrategy(request, matches) {
@@ -7028,11 +7816,12 @@ async function singleFetchActionStrategy(request, matches) {
7028
7816
  });
7029
7817
  return result;
7030
7818
  });
7031
- if (isResponse$1(result.result) || isRouteErrorResponse(result.result)) {
7819
+ if (isResponse(result.result) || isRouteErrorResponse(result.result)) {
7032
7820
  return {
7033
7821
  [actionMatch.route.id]: result
7034
7822
  };
7035
7823
  }
7824
+
7036
7825
  // For non-responses, proxy along the statusCode via data()
7037
7826
  // (most notably for skipping action error revalidation)
7038
7827
  return {
@@ -7042,30 +7831,37 @@ async function singleFetchActionStrategy(request, matches) {
7042
7831
  }
7043
7832
  };
7044
7833
  }
7834
+
7045
7835
  // Loaders are trickier since we only want to hit the server once, so we
7046
7836
  // create a singular promise for all server-loader routes to latch onto.
7047
7837
  async function singleFetchLoaderNavigationStrategy(manifest, routeModules, router, request, matches) {
7048
7838
  // Track which routes need a server load - in case we need to tack on a
7049
7839
  // `_routes` param
7050
7840
  let routesParams = new Set();
7841
+
7051
7842
  // We only add `_routes` when one or more routes opts out of a load via
7052
7843
  // `shouldRevalidate` or `clientLoader`
7053
7844
  let foundOptOutRoute = false;
7845
+
7054
7846
  // Deferreds for each route so we can be sure they've all loaded via
7055
7847
  // `match.resolve()`, and a singular promise that can tell us all routes
7056
7848
  // have been resolved
7057
7849
  let routeDfds = matches.map(() => createDeferred());
7058
7850
  let routesLoadedPromise = Promise.all(routeDfds.map(d => d.promise));
7851
+
7059
7852
  // Deferred that we'll use for the call to the server that each match can
7060
7853
  // await and parse out it's specific result
7061
7854
  let singleFetchDfd = createDeferred();
7855
+
7062
7856
  // Base URL and RequestInit for calls to the server
7063
7857
  let url = stripIndexParam$1(singleFetchUrl(request.url));
7064
7858
  let init = await createRequestInit(request);
7859
+
7065
7860
  // We'll build up this results object as we loop through matches
7066
7861
  let results = {};
7067
7862
  let resolvePromise = Promise.all(matches.map(async (m, i) => m.resolve(async handler => {
7068
7863
  routeDfds[i].resolve();
7864
+ let manifestRoute = manifest.routes[m.route.id];
7069
7865
  if (!m.shouldLoad) {
7070
7866
  var _routeModules$m$route;
7071
7867
  // If we're not yet initialized and this is the initial load, respect
@@ -7074,18 +7870,20 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, route
7074
7870
  if (!router.state.initialized) {
7075
7871
  return;
7076
7872
  }
7873
+
7077
7874
  // Otherwise, we opt out if we currently have data, a `loader`, and a
7078
7875
  // `shouldRevalidate` function. This implies that the user opted out
7079
7876
  // via `shouldRevalidate`
7080
- if (m.route.id in router.state.loaderData && manifest.routes[m.route.id].hasLoader && (_routeModules$m$route = routeModules[m.route.id]) != null && _routeModules$m$route.shouldRevalidate) {
7877
+ if (m.route.id in router.state.loaderData && manifestRoute && manifestRoute.hasLoader && (_routeModules$m$route = routeModules[m.route.id]) != null && _routeModules$m$route.shouldRevalidate) {
7081
7878
  foundOptOutRoute = true;
7082
7879
  return;
7083
7880
  }
7084
7881
  }
7882
+
7085
7883
  // When a route has a client loader, it opts out of the singular call and
7086
7884
  // calls it's server loader via `serverLoader()` using a `?_routes` param
7087
- if (manifest.routes[m.route.id].hasClientLoader) {
7088
- if (manifest.routes[m.route.id].hasLoader) {
7885
+ if (manifestRoute && manifestRoute.hasClientLoader) {
7886
+ if (manifestRoute.hasLoader) {
7089
7887
  foundOptOutRoute = true;
7090
7888
  }
7091
7889
  try {
@@ -7102,10 +7900,12 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, route
7102
7900
  }
7103
7901
  return;
7104
7902
  }
7903
+
7105
7904
  // Load this route on the server if it has a loader
7106
- if (manifest.routes[m.route.id].hasLoader) {
7905
+ if (manifestRoute && manifestRoute.hasLoader) {
7107
7906
  routesParams.add(m.route.id);
7108
7907
  }
7908
+
7109
7909
  // Lump this match in with the others on a singular promise
7110
7910
  try {
7111
7911
  let result = await handler(async () => {
@@ -7123,8 +7923,10 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, route
7123
7923
  };
7124
7924
  }
7125
7925
  })));
7926
+
7126
7927
  // Wait for all routes to resolve above before we make the HTTP call
7127
7928
  await routesLoadedPromise;
7929
+
7128
7930
  // We can skip the server call:
7129
7931
  // - On initial hydration - only clientLoaders can pass through via `clientLoader.hydrate`
7130
7932
  // - If there are no routes to fetch from the server
@@ -7151,6 +7953,7 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, route
7151
7953
  await resolvePromise;
7152
7954
  return results;
7153
7955
  }
7956
+
7154
7957
  // Fetcher loader calls are much simpler than navigational loader calls
7155
7958
  async function singleFetchLoaderFetcherStrategy(request, matches) {
7156
7959
  let fetcherMatch = matches.find(m => m.shouldLoad);
@@ -7202,6 +8005,7 @@ function singleFetchUrl(reqUrl) {
7202
8005
  }
7203
8006
  async function fetchAndDecode(url, init) {
7204
8007
  let res = await fetch(url, init);
8008
+
7205
8009
  // If this 404'd without hitting the running server (most likely in a
7206
8010
  // pre-rendered app using a CDN), then bubble a standard 404 ErrorResponse
7207
8011
  if (res.status === 404 && !res.headers.has("X-Remix-Response")) {
@@ -7224,6 +8028,7 @@ async function fetchAndDecode(url, init) {
7224
8028
  throw new Error("Unable to decode turbo-stream response");
7225
8029
  }
7226
8030
  }
8031
+
7227
8032
  // Note: If you change this function please change the corresponding
7228
8033
  // encodeViaTurboStream function in server-runtime
7229
8034
  function decodeViaTurboStream(body, global) {
@@ -7360,6 +8165,7 @@ class RemixErrorBoundary extends React.Component {
7360
8165
  location: props.location
7361
8166
  };
7362
8167
  }
8168
+
7363
8169
  // If we're not changing locations, preserve the location but still surface
7364
8170
  // any new errors that may come through. We retain the existing error, we do
7365
8171
  // this because the error provided from the app state may be cleared without
@@ -7380,6 +8186,7 @@ class RemixErrorBoundary extends React.Component {
7380
8186
  }
7381
8187
  }
7382
8188
  }
8189
+
7383
8190
  /**
7384
8191
  * When app's don't provide a root level ErrorBoundary, we default to this.
7385
8192
  */
@@ -7437,16 +8244,19 @@ function BoundaryShell(_ref2) {
7437
8244
  let {
7438
8245
  routeModules
7439
8246
  } = useFrameworkContext();
8247
+
7440
8248
  // Generally speaking, when the root route has a Layout we want to use that
7441
8249
  // as the app shell instead of the default `BoundaryShell` wrapper markup below.
7442
8250
  // This is true for `loader`/`action` errors, most render errors, and
7443
8251
  // `HydrateFallback` scenarios.
8252
+
7444
8253
  // However, render errors thrown from the `Layout` present a bit of an issue
7445
8254
  // because if the `Layout` itself throws during the `ErrorBoundary` pass and
7446
8255
  // we bubble outside the `RouterProvider` to the wrapping `RemixErrorBoundary`,
7447
8256
  // by returning only `children` here we'll be trying to append a `<div>` to
7448
8257
  // the `document` and the DOM will throw, putting React into an error/hydration
7449
8258
  // loop.
8259
+
7450
8260
  // Instead, if we're ever rendering from the outermost `RemixErrorBoundary`
7451
8261
  // during hydration that wraps `RouterProvider`, then we can't trust the
7452
8262
  // `Layout` and should fallback to the default app shell so we're always
@@ -7489,11 +8299,13 @@ function RemixRootDefaultHydrateFallback() {
7489
8299
  function groupRoutesByParentId$1(manifest) {
7490
8300
  let routes = {};
7491
8301
  Object.values(manifest).forEach(route => {
7492
- let parentId = route.parentId || "";
7493
- if (!routes[parentId]) {
7494
- routes[parentId] = [];
8302
+ if (route) {
8303
+ let parentId = route.parentId || "";
8304
+ if (!routes[parentId]) {
8305
+ routes[parentId] = [];
8306
+ }
8307
+ routes[parentId].push(route);
7495
8308
  }
7496
- routes[parentId].push(route);
7497
8309
  });
7498
8310
  return routes;
7499
8311
  }
@@ -7506,15 +8318,15 @@ function getRouteComponents(route, routeModule, isSpaMode) {
7506
8318
  }) : undefined;
7507
8319
  if (route.id === "root" && routeModule.Layout) {
7508
8320
  return _extends({}, Component ? {
7509
- element: ( /*#__PURE__*/React.createElement(routeModule.Layout, null, /*#__PURE__*/React.createElement(Component, null)))
8321
+ element: /*#__PURE__*/React.createElement(routeModule.Layout, null, /*#__PURE__*/React.createElement(Component, null))
7510
8322
  } : {
7511
8323
  Component
7512
8324
  }, ErrorBoundary ? {
7513
- errorElement: ( /*#__PURE__*/React.createElement(routeModule.Layout, null, /*#__PURE__*/React.createElement(ErrorBoundary, null)))
8325
+ errorElement: /*#__PURE__*/React.createElement(routeModule.Layout, null, /*#__PURE__*/React.createElement(ErrorBoundary, null))
7514
8326
  } : {
7515
8327
  ErrorBoundary
7516
8328
  }, HydrateFallback ? {
7517
- hydrateFallbackElement: ( /*#__PURE__*/React.createElement(routeModule.Layout, null, /*#__PURE__*/React.createElement(HydrateFallback, null)))
8329
+ hydrateFallbackElement: /*#__PURE__*/React.createElement(routeModule.Layout, null, /*#__PURE__*/React.createElement(HydrateFallback, null))
7518
8330
  } : {
7519
8331
  HydrateFallback
7520
8332
  });
@@ -7633,7 +8445,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, isSpaMode
7633
8445
  // Use critical path modules directly
7634
8446
  Object.assign(dataRoute, _extends({}, dataRoute, getRouteComponents(route, routeModule, isSpaMode), {
7635
8447
  handle: routeModule.handle,
7636
- shouldRevalidate: needsRevalidation ? wrapShouldRevalidateForHdr(route.id, routeModule.shouldRevalidate, needsRevalidation) : routeModule.shouldRevalidate
8448
+ shouldRevalidate: getShouldRevalidateFunction(routeModule, route.id, needsRevalidation)
7637
8449
  }));
7638
8450
  let hasInitialData = initialState && initialState.loaderData && route.id in initialState.loaderData;
7639
8451
  let initialData = hasInitialData ? initialState == null || (_initialState$loaderD = initialState.loaderData) == null ? void 0 : _initialState$loaderD[route.id] : undefined;
@@ -7658,6 +8470,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, isSpaMode
7658
8470
  params,
7659
8471
  async serverLoader() {
7660
8472
  preventInvalidServerHandlerCall("loader", route, isSpaMode);
8473
+
7661
8474
  // On the first call, resolve with the server result
7662
8475
  if (isHydrationRequest) {
7663
8476
  if (hasInitialData) {
@@ -7667,6 +8480,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, isSpaMode
7667
8480
  throw initialError;
7668
8481
  }
7669
8482
  }
8483
+
7670
8484
  // Call the server loader for client-side navigations
7671
8485
  return fetchServerLoader(singleFetch);
7672
8486
  }
@@ -7679,6 +8493,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, isSpaMode
7679
8493
  isHydrationRequest = false;
7680
8494
  }
7681
8495
  };
8496
+
7682
8497
  // Let React Router know whether to run this on hydration
7683
8498
  dataRoute.loader.hydrate = shouldHydrateRouteLoader(route, routeModule, isSpaMode);
7684
8499
  dataRoute.action = (_ref2, singleFetch) => {
@@ -7726,6 +8541,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, isSpaMode
7726
8541
  });
7727
8542
  };
7728
8543
  }
8544
+
7729
8545
  // Load all other modules via route.lazy()
7730
8546
  dataRoute.lazy = async () => {
7731
8547
  let mod = await loadRouteModuleWithBlockingLinks(route, routeModulesCache);
@@ -7748,16 +8564,13 @@ function createClientRoutes(manifest, routeModulesCache, initialState, isSpaMode
7748
8564
  }
7749
8565
  }));
7750
8566
  }
7751
- if (needsRevalidation) {
7752
- lazyRoute.shouldRevalidate = wrapShouldRevalidateForHdr(route.id, mod.shouldRevalidate, needsRevalidation);
7753
- }
7754
8567
  return _extends({}, lazyRoute.loader ? {
7755
8568
  loader: lazyRoute.loader
7756
8569
  } : {}, lazyRoute.action ? {
7757
8570
  action: lazyRoute.action
7758
8571
  } : {}, {
7759
8572
  hasErrorBoundary: lazyRoute.hasErrorBoundary,
7760
- shouldRevalidate: lazyRoute.shouldRevalidate,
8573
+ shouldRevalidate: getShouldRevalidateFunction(lazyRoute, route.id, needsRevalidation),
7761
8574
  handle: lazyRoute.handle,
7762
8575
  // No need to wrap these in layout since the root route is never
7763
8576
  // loaded via route.lazy()
@@ -7771,6 +8584,23 @@ function createClientRoutes(manifest, routeModulesCache, initialState, isSpaMode
7771
8584
  return dataRoute;
7772
8585
  });
7773
8586
  }
8587
+ function getShouldRevalidateFunction(route, routeId, needsRevalidation) {
8588
+ // During HDR we force revalidation for updated routes
8589
+ if (needsRevalidation) {
8590
+ return wrapShouldRevalidateForHdr(routeId, route.shouldRevalidate, needsRevalidation);
8591
+ }
8592
+
8593
+ // Single fetch revalidates by default, so override the RR default value which
8594
+ // matches the multi-fetch behavior with `true`
8595
+ if (route.shouldRevalidate) {
8596
+ let fn = route.shouldRevalidate;
8597
+ return opts => fn(_extends({}, opts, {
8598
+ defaultShouldRevalidate: true
8599
+ }));
8600
+ }
8601
+ return route.shouldRevalidate;
8602
+ }
8603
+
7774
8604
  // When an HMR / HDR update happens we opt out of all user-defined
7775
8605
  // revalidation logic and force a revalidation on the first call
7776
8606
  function wrapShouldRevalidateForHdr(routeId, routeShouldRevalidate, needsRevalidation) {
@@ -7786,6 +8616,7 @@ function wrapShouldRevalidateForHdr(routeId, routeShouldRevalidate, needsRevalid
7786
8616
  async function loadRouteModuleWithBlockingLinks(route, routeModules) {
7787
8617
  let routeModule = await loadRouteModule(route, routeModules);
7788
8618
  await prefetchStyleLinks(route, routeModule);
8619
+
7789
8620
  // Include all `browserSafeRouteExports` fields, except `HydrateFallback`
7790
8621
  // since those aren't used on lazily loaded routes
7791
8622
  return {
@@ -7799,6 +8630,7 @@ async function loadRouteModuleWithBlockingLinks(route, routeModules) {
7799
8630
  shouldRevalidate: routeModule.shouldRevalidate
7800
8631
  };
7801
8632
  }
8633
+
7802
8634
  // Our compiler generates the default export as `{}` when no default is provided,
7803
8635
  // which can lead us to trying to use that as a Component in RR and calling
7804
8636
  // createElement on it. Patching here as a quick fix and hoping it's no longer
@@ -7816,10 +8648,12 @@ function shouldHydrateRouteLoader(route, routeModule, isSpaMode) {
7816
8648
 
7817
8649
  // Currently rendered links that may need prefetching
7818
8650
  const nextPaths = new Set();
8651
+
7819
8652
  // FIFO queue of previously discovered routes to prevent re-calling on
7820
8653
  // subsequent navigations to the same path
7821
8654
  const discoveredPathsMaxSize = 1000;
7822
8655
  const discoveredPaths = new Set();
8656
+
7823
8657
  // 7.5k to come in under the ~8k limit for most browsers
7824
8658
  // https://stackoverflow.com/a/417184
7825
8659
  const URL_LIMIT = 7680;
@@ -7831,8 +8665,10 @@ function getPartialManifest(manifest, router) {
7831
8665
  let routeIds = new Set(router.state.matches.map(m => m.route.id));
7832
8666
  let segments = router.state.location.pathname.split("/").filter(Boolean);
7833
8667
  let paths = ["/"];
8668
+
7834
8669
  // We've already matched to the last segment
7835
8670
  segments.pop();
8671
+
7836
8672
  // Traverse each path for our parents and match in case they have pathless/index
7837
8673
  // children we need to include in the initial manifest
7838
8674
  while (segments.length > 0) {
@@ -7874,6 +8710,7 @@ function useFogOFWarDiscovery(router, manifest, routeModules, isSpaMode) {
7874
8710
  if (!isFogOfWarEnabled(isSpaMode) || ((_navigator$connection = navigator.connection) == null ? void 0 : _navigator$connection.saveData) === true) {
7875
8711
  return;
7876
8712
  }
8713
+
7877
8714
  // Register a link href for patching
7878
8715
  function registerElement(el) {
7879
8716
  let path = el.tagName === "FORM" ? el.getAttribute("action") : el.getAttribute("href");
@@ -7885,6 +8722,7 @@ function useFogOFWarDiscovery(router, manifest, routeModules, isSpaMode) {
7885
8722
  nextPaths.add(url.pathname);
7886
8723
  }
7887
8724
  }
8725
+
7888
8726
  // Register and fetch patches for all initially-rendered links/forms
7889
8727
  async function fetchPatches() {
7890
8728
  let lazyPaths = Array.from(nextPaths.keys()).filter(path => {
@@ -7903,9 +8741,11 @@ function useFogOFWarDiscovery(router, manifest, routeModules, isSpaMode) {
7903
8741
  console.error("Failed to fetch manifest patches", e);
7904
8742
  }
7905
8743
  }
8744
+
7906
8745
  // Register and fetch patches for all initially-rendered links
7907
8746
  document.body.querySelectorAll("a[data-discover], form[data-discover]").forEach(el => registerElement(el));
7908
8747
  fetchPatches();
8748
+
7909
8749
  // Setup a MutationObserver to fetch all subsequently rendered links/form
7910
8750
  let debouncedFetchPatches = debounce(fetchPatches, 100);
7911
8751
  function isElement(node) {
@@ -7943,6 +8783,7 @@ async function fetchAndApplyManifestPatches(paths, manifest, routeModules, isSpa
7943
8783
  let url = new URL(manifestPath, window.location.origin);
7944
8784
  paths.sort().forEach(path => url.searchParams.append("p", path));
7945
8785
  url.searchParams.set("version", manifest.version);
8786
+
7946
8787
  // If the URL is nearing the ~8k limit on GET requests, skip this optimization
7947
8788
  // step and just let discovery happen on link click. We also wipe out the
7948
8789
  // nextPaths Set here so we can start filling it with fresh links
@@ -7957,19 +8798,25 @@ async function fetchAndApplyManifestPatches(paths, manifest, routeModules, isSpa
7957
8798
  throw new Error(await res.text());
7958
8799
  }
7959
8800
  let serverPatches = await res.json();
8801
+
7960
8802
  // Patch routes we don't know about yet into the manifest
7961
8803
  let knownRoutes = new Set(Object.keys(manifest.routes));
7962
- let patches = Object.values(serverPatches).reduce((acc, route) => !knownRoutes.has(route.id) ? Object.assign(acc, {
7963
- [route.id]: route
7964
- }) : acc, {});
8804
+ let patches = Object.values(serverPatches).reduce((acc, route) => {
8805
+ if (route && !knownRoutes.has(route.id)) {
8806
+ acc[route.id] = route;
8807
+ }
8808
+ return acc;
8809
+ }, {});
7965
8810
  Object.assign(manifest.routes, patches);
8811
+
7966
8812
  // Track discovered paths so we don't have to fetch them again
7967
8813
  paths.forEach(p => addToFifoQueue(p, discoveredPaths));
8814
+
7968
8815
  // Identify all parentIds for which we have new children to add and patch
7969
8816
  // in their new children
7970
8817
  let parentIds = new Set();
7971
8818
  Object.values(patches).forEach(patch => {
7972
- if (!patch.parentId || !patches[patch.parentId]) {
8819
+ if (patch && (!patch.parentId || !patches[patch.parentId])) {
7973
8820
  parentIds.add(patch.parentId);
7974
8821
  }
7975
8822
  });
@@ -7982,6 +8829,7 @@ function addToFifoQueue(path, queue) {
7982
8829
  }
7983
8830
  queue.add(path);
7984
8831
  }
8832
+
7985
8833
  // Thanks Josh!
7986
8834
  // https://www.joshwcomeau.com/snippets/javascript/debounce/
7987
8835
  function debounce(callback, wait) {
@@ -8008,8 +8856,10 @@ function useDataRouterStateContext() {
8008
8856
  !context ? process.env.NODE_ENV !== "production" ? invariant$1(false, "You must render this element inside a <DataRouterStateContext.Provider> element") : invariant$1(false) : void 0;
8009
8857
  return context;
8010
8858
  }
8859
+
8011
8860
  ////////////////////////////////////////////////////////////////////////////////
8012
8861
  // FrameworkContext
8862
+
8013
8863
  const FrameworkContext = /*#__PURE__*/React.createContext(undefined);
8014
8864
  FrameworkContext.displayName = "FrameworkContext";
8015
8865
  function useFrameworkContext() {
@@ -8017,6 +8867,26 @@ function useFrameworkContext() {
8017
8867
  !context ? process.env.NODE_ENV !== "production" ? invariant$1(false, "You must render this element inside a <HydratedRouter> element") : invariant$1(false) : void 0;
8018
8868
  return context;
8019
8869
  }
8870
+
8871
+ ////////////////////////////////////////////////////////////////////////////////
8872
+ // Public API
8873
+
8874
+ /**
8875
+ * Defines the discovery behavior of the link:
8876
+ *
8877
+ * - "render" - default, discover the route when the link renders
8878
+ * - "none" - don't eagerly discover, only discover if the link is clicked
8879
+ */
8880
+
8881
+ /**
8882
+ * Defines the prefetching behavior of the link:
8883
+ *
8884
+ * - "none": Never fetched
8885
+ * - "intent": Fetched when the user focuses or hovers the link
8886
+ * - "render": Fetched when the link is rendered
8887
+ * - "viewport": Fetched when the link is in the viewport
8888
+ */
8889
+
8020
8890
  function usePrefetchBehavior(prefetch, theirElementProps) {
8021
8891
  let frameworkContext = React.useContext(FrameworkContext);
8022
8892
  let [maybePrefetch, setMaybePrefetch] = React.useState(false);
@@ -8065,6 +8935,7 @@ function usePrefetchBehavior(prefetch, theirElementProps) {
8065
8935
  setMaybePrefetch(false);
8066
8936
  setShouldPrefetch(false);
8067
8937
  };
8938
+
8068
8939
  // No prefetching if not using SSR
8069
8940
  if (!frameworkContext) {
8070
8941
  return [false, ref, {}];
@@ -8072,6 +8943,7 @@ function usePrefetchBehavior(prefetch, theirElementProps) {
8072
8943
  if (prefetch !== "intent") {
8073
8944
  return [shouldPrefetch, ref, {}];
8074
8945
  }
8946
+
8075
8947
  // When using prefetch="intent" we need to attach focus/hover listeners
8076
8948
  return [shouldPrefetch, ref, {
8077
8949
  onFocus: composeEventHandlers(onFocus, setIntent),
@@ -8089,6 +8961,7 @@ function composeEventHandlers(theirHandler, ourHandler) {
8089
8961
  }
8090
8962
  };
8091
8963
  }
8964
+
8092
8965
  // Return the matches actively being displayed:
8093
8966
  // - In SPA Mode we only SSR/hydrate the root match, and include all matches
8094
8967
  // after hydration. This lets the router handle initial match loads via lazy().
@@ -8104,6 +8977,7 @@ function getActiveMatches(matches, errors, isSpaMode) {
8104
8977
  }
8105
8978
  return matches;
8106
8979
  }
8980
+
8107
8981
  /**
8108
8982
  Renders all of the `<link>` tags created by route module {@link LinksFunction} export. You should render it inside the `<head>` of your document.
8109
8983
 
@@ -8137,22 +9011,23 @@ function Links() {
8137
9011
  } = useDataRouterStateContext();
8138
9012
  let matches = getActiveMatches(routerMatches, errors, isSpaMode);
8139
9013
  let keyedLinks = React.useMemo(() => getKeyedLinksForMatches(matches, routeModules, manifest), [matches, routeModules, manifest]);
8140
- return /*#__PURE__*/React.createElement(React.Fragment, null, criticalCss ? ( /*#__PURE__*/React.createElement("style", {
9014
+ return /*#__PURE__*/React.createElement(React.Fragment, null, criticalCss ? /*#__PURE__*/React.createElement("style", {
8141
9015
  dangerouslySetInnerHTML: {
8142
9016
  __html: criticalCss
8143
9017
  }
8144
- })) : null, keyedLinks.map(_ref => {
9018
+ }) : null, keyedLinks.map(_ref => {
8145
9019
  let {
8146
9020
  key,
8147
9021
  link
8148
9022
  } = _ref;
8149
- return isPageLinkDescriptor(link) ? ( /*#__PURE__*/React.createElement(PrefetchPageLinks, _extends({
9023
+ return isPageLinkDescriptor(link) ? /*#__PURE__*/React.createElement(PrefetchPageLinks, _extends({
8150
9024
  key: key
8151
- }, link))) : ( /*#__PURE__*/React.createElement("link", _extends({
9025
+ }, link)) : /*#__PURE__*/React.createElement("link", _extends({
8152
9026
  key: key
8153
- }, link)));
9027
+ }, link));
8154
9028
  }));
8155
9029
  }
9030
+
8156
9031
  /**
8157
9032
  Renders `<link rel=prefetch|modulepreload>` tags for modules and data of another page to enable an instant navigation to that page. {@link LinkProps.prefetch | `<Link prefetch>`} uses this internally, but you can render it to prefetch a page for any other reason.
8158
9033
 
@@ -8226,18 +9101,20 @@ function PrefetchPageLinksImpl(_ref3) {
8226
9101
  // since it would always trigger a prefetch of the existing loaders
8227
9102
  return [];
8228
9103
  }
9104
+
8229
9105
  // Single-fetch is harder :)
8230
9106
  // This parallels the logic in the single fetch data strategy
8231
9107
  let routesParams = new Set();
8232
9108
  let foundOptOutRoute = false;
8233
9109
  nextMatches.forEach(m => {
8234
9110
  var _routeModules$m$route;
8235
- if (!manifest.routes[m.route.id].hasLoader) {
9111
+ let manifestRoute = manifest.routes[m.route.id];
9112
+ if (!manifestRoute || !manifestRoute.hasLoader) {
8236
9113
  return;
8237
9114
  }
8238
9115
  if (!newMatchesForData.some(m2 => m2.route.id === m.route.id) && m.route.id in loaderData && (_routeModules$m$route = routeModules[m.route.id]) != null && _routeModules$m$route.shouldRevalidate) {
8239
9116
  foundOptOutRoute = true;
8240
- } else if (manifest.routes[m.route.id].hasClientLoader) {
9117
+ } else if (manifestRoute.hasClientLoader) {
8241
9118
  foundOptOutRoute = true;
8242
9119
  } else {
8243
9120
  routesParams.add(m.route.id);
@@ -8256,19 +9133,20 @@ function PrefetchPageLinksImpl(_ref3) {
8256
9133
  return [url.pathname + url.search];
8257
9134
  }, [loaderData, location, manifest, newMatchesForData, nextMatches, page, routeModules]);
8258
9135
  let moduleHrefs = React.useMemo(() => getModuleLinkHrefs(newMatchesForAssets, manifest), [newMatchesForAssets, manifest]);
9136
+
8259
9137
  // needs to be a hook with async behavior because we need the modules, not
8260
9138
  // just the manifest like the other links in here.
8261
9139
  let keyedPrefetchLinks = useKeyedPrefetchLinks(newMatchesForAssets);
8262
- return /*#__PURE__*/React.createElement(React.Fragment, null, dataHrefs.map(href => ( /*#__PURE__*/React.createElement("link", _extends({
9140
+ return /*#__PURE__*/React.createElement(React.Fragment, null, dataHrefs.map(href => /*#__PURE__*/React.createElement("link", _extends({
8263
9141
  key: href,
8264
9142
  rel: "prefetch",
8265
9143
  as: "fetch",
8266
9144
  href: href
8267
- }, linkProps)))), moduleHrefs.map(href => ( /*#__PURE__*/React.createElement("link", _extends({
9145
+ }, linkProps))), moduleHrefs.map(href => /*#__PURE__*/React.createElement("link", _extends({
8268
9146
  key: href,
8269
9147
  rel: "modulepreload",
8270
9148
  href: href
8271
- }, linkProps)))), keyedPrefetchLinks.map(_ref4 => {
9149
+ }, linkProps))), keyedPrefetchLinks.map(_ref4 => {
8272
9150
  let {
8273
9151
  key,
8274
9152
  link
@@ -8283,6 +9161,7 @@ function PrefetchPageLinksImpl(_ref3) {
8283
9161
  );
8284
9162
  }));
8285
9163
  }
9164
+
8286
9165
  /**
8287
9166
  Renders all the `<meta>` tags created by route module {@link MetaFunction} exports. You should render it inside the `<head>` of your HTML.
8288
9167
 
@@ -8390,10 +9269,10 @@ function Meta() {
8390
9269
  delete metaProps.charset;
8391
9270
  }
8392
9271
  if ("charSet" in metaProps && metaProps.charSet != null) {
8393
- return typeof metaProps.charSet === "string" ? ( /*#__PURE__*/React.createElement("meta", {
9272
+ return typeof metaProps.charSet === "string" ? /*#__PURE__*/React.createElement("meta", {
8394
9273
  key: "charSet",
8395
9274
  charSet: metaProps.charSet
8396
- })) : null;
9275
+ }) : null;
8397
9276
  }
8398
9277
  if ("script:ld+json" in metaProps) {
8399
9278
  try {
@@ -8417,11 +9296,24 @@ function Meta() {
8417
9296
  function isValidMetaTag(tagName) {
8418
9297
  return typeof tagName === "string" && /^(meta|link)$/.test(tagName);
8419
9298
  }
9299
+
8420
9300
  /**
8421
9301
  * Tracks whether hydration is finished, so scripts can be skipped
8422
9302
  * during client-side updates.
8423
9303
  */
8424
9304
  let isHydrated = false;
9305
+
9306
+ /**
9307
+ A couple common attributes:
9308
+
9309
+ - `<Scripts crossOrigin>` for hosting your static assets on a different server than your app.
9310
+ - `<Scripts nonce>` to support a [content security policy for scripts](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src) with [nonce-sources](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources) for your `<script>` tags.
9311
+
9312
+ You cannot pass through attributes such as `async`, `defer`, `src`, `type`, `noModule` because they are managed by React Router internally.
9313
+
9314
+ @category Types
9315
+ */
9316
+
8425
9317
  /**
8426
9318
  Renders the client runtime of your app. It should be rendered inside the `<body>` of the document.
8427
9319
 
@@ -8460,6 +9352,7 @@ function Scripts(props) {
8460
9352
  matches: routerMatches
8461
9353
  } = useDataRouterStateContext();
8462
9354
  let enableFogOfWar = isFogOfWarEnabled(isSpaMode);
9355
+
8463
9356
  // Let <ServerRouter> know that we hydrated and we should render the single
8464
9357
  // fetch streaming scripts
8465
9358
  if (renderMeta) {
@@ -8492,23 +9385,23 @@ function Scripts(props) {
8492
9385
  }, []);
8493
9386
  let routePreloads = matches.map(match => {
8494
9387
  let route = manifest.routes[match.route.id];
8495
- return (route.imports || []).concat([route.module]);
9388
+ return route ? (route.imports || []).concat([route.module]) : [];
8496
9389
  }).flat(1);
8497
9390
  let preloads = isHydrated ? [] : manifest.entry.imports.concat(routePreloads);
8498
- return isHydrated ? null : ( /*#__PURE__*/React.createElement(React.Fragment, null, !enableFogOfWar ? ( /*#__PURE__*/React.createElement("link", {
9391
+ return isHydrated ? null : /*#__PURE__*/React.createElement(React.Fragment, null, !enableFogOfWar ? /*#__PURE__*/React.createElement("link", {
8499
9392
  rel: "modulepreload",
8500
9393
  href: manifest.url,
8501
9394
  crossOrigin: props.crossOrigin
8502
- })) : null, /*#__PURE__*/React.createElement("link", {
9395
+ }) : null, /*#__PURE__*/React.createElement("link", {
8503
9396
  rel: "modulepreload",
8504
9397
  href: manifest.entry.module,
8505
9398
  crossOrigin: props.crossOrigin
8506
- }), dedupe(preloads).map(path => ( /*#__PURE__*/React.createElement("link", {
9399
+ }), dedupe(preloads).map(path => /*#__PURE__*/React.createElement("link", {
8507
9400
  key: path,
8508
9401
  rel: "modulepreload",
8509
9402
  href: path,
8510
9403
  crossOrigin: props.crossOrigin
8511
- }))), initialScripts));
9404
+ })), initialScripts);
8512
9405
  }
8513
9406
  function dedupe(array) {
8514
9407
  return [...new Set(array)];
@@ -8535,7 +9428,9 @@ const _excluded$1 = ["onClick", "discover", "prefetch", "relative", "reloadDocum
8535
9428
  ////////////////////////////////////////////////////////////////////////////////
8536
9429
  //#region Global Stuff
8537
9430
  ////////////////////////////////////////////////////////////////////////////////
9431
+
8538
9432
  const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
9433
+
8539
9434
  // HEY YOU! DON'T TOUCH THIS VARIABLE!
8540
9435
  //
8541
9436
  // It is replaced with the proper version at build time via a babel plugin in
@@ -8553,6 +9448,12 @@ try {
8553
9448
  } catch (e) {
8554
9449
  // no-op
8555
9450
  }
9451
+ //#endregion
9452
+
9453
+ ////////////////////////////////////////////////////////////////////////////////
9454
+ //#region Routers
9455
+ ////////////////////////////////////////////////////////////////////////////////
9456
+
8556
9457
  /**
8557
9458
  * @category Routers
8558
9459
  */
@@ -8571,6 +9472,7 @@ function createBrowserRouter(routes, opts) {
8571
9472
  window: opts == null ? void 0 : opts.window
8572
9473
  }).initialize();
8573
9474
  }
9475
+
8574
9476
  /**
8575
9477
  * @category Routers
8576
9478
  */
@@ -8638,6 +9540,17 @@ function deserializeErrors$1(errors) {
8638
9540
  }
8639
9541
  return serialized;
8640
9542
  }
9543
+
9544
+ //#endregion
9545
+
9546
+ ////////////////////////////////////////////////////////////////////////////////
9547
+ //#region Components
9548
+ ////////////////////////////////////////////////////////////////////////////////
9549
+
9550
+ /**
9551
+ * @category Types
9552
+ */
9553
+
8641
9554
  /**
8642
9555
  * A `<Router>` for use in web browsers. Provides the cleanest URLs.
8643
9556
  *
@@ -8673,6 +9586,11 @@ function BrowserRouter(_ref) {
8673
9586
  navigator: history
8674
9587
  });
8675
9588
  }
9589
+
9590
+ /**
9591
+ * @category Types
9592
+ */
9593
+
8676
9594
  /**
8677
9595
  * A `<Router>` for use in web browsers. Stores the location in the hash
8678
9596
  * portion of the URL so it is not sent to the server.
@@ -8709,6 +9627,11 @@ function HashRouter(_ref2) {
8709
9627
  navigator: history
8710
9628
  });
8711
9629
  }
9630
+
9631
+ /**
9632
+ * @category Types
9633
+ */
9634
+
8712
9635
  /**
8713
9636
  * A `<Router>` that accepts a pre-instantiated history object. It's important
8714
9637
  * to note that using your own history object is highly discouraged and may add
@@ -8741,7 +9664,13 @@ function HistoryRouter(_ref3) {
8741
9664
  });
8742
9665
  }
8743
9666
  HistoryRouter.displayName = "unstable_HistoryRouter";
9667
+
9668
+ /**
9669
+ * @category Types
9670
+ */
9671
+
8744
9672
  const ABSOLUTE_URL_REGEX$1 = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
9673
+
8745
9674
  /**
8746
9675
  A progressively enhanced `<a href>` wrapper to enable navigation with client-side routing.
8747
9676
 
@@ -8780,12 +9709,14 @@ const Link = /*#__PURE__*/React.forwardRef(function LinkWithRef(_ref4, forwarded
8780
9709
  basename
8781
9710
  } = React.useContext(NavigationContext);
8782
9711
  let isAbsolute = typeof to === "string" && ABSOLUTE_URL_REGEX$1.test(to);
9712
+
8783
9713
  // Rendered into <a href> for absolute URLs
8784
9714
  let absoluteHref;
8785
9715
  let isExternal = false;
8786
9716
  if (typeof to === "string" && isAbsolute) {
8787
9717
  // Render the absolute href server- and client-side
8788
9718
  absoluteHref = to;
9719
+
8789
9720
  // Only check for external origins client-side
8790
9721
  if (isBrowser) {
8791
9722
  try {
@@ -8804,6 +9735,7 @@ const Link = /*#__PURE__*/React.forwardRef(function LinkWithRef(_ref4, forwarded
8804
9735
  }
8805
9736
  }
8806
9737
  }
9738
+
8807
9739
  // Rendered into <a href> for relative URLs
8808
9740
  let href = useHref(to, {
8809
9741
  relative
@@ -8833,11 +9765,51 @@ const Link = /*#__PURE__*/React.forwardRef(function LinkWithRef(_ref4, forwarded
8833
9765
  target: target,
8834
9766
  "data-discover": !isAbsolute && discover === "render" ? "true" : undefined
8835
9767
  }));
8836
- return shouldPrefetch && !isAbsolute ? ( /*#__PURE__*/React.createElement(React.Fragment, null, link, /*#__PURE__*/React.createElement(PrefetchPageLinks, {
9768
+ return shouldPrefetch && !isAbsolute ? /*#__PURE__*/React.createElement(React.Fragment, null, link, /*#__PURE__*/React.createElement(PrefetchPageLinks, {
8837
9769
  page: href
8838
- }))) : link;
9770
+ })) : link;
8839
9771
  });
8840
9772
  Link.displayName = "Link";
9773
+
9774
+ /**
9775
+ The object passed to {@link NavLink} `children`, `className`, and `style` prop callbacks to render and style the link based on its state.
9776
+
9777
+ ```
9778
+ // className
9779
+ <NavLink
9780
+ to="/messages"
9781
+ className={({ isActive, isPending }) =>
9782
+ isPending ? "pending" : isActive ? "active" : ""
9783
+ }
9784
+ >
9785
+ Messages
9786
+ </NavLink>
9787
+
9788
+ // style
9789
+ <NavLink
9790
+ to="/messages"
9791
+ style={({ isActive, isPending }) => {
9792
+ return {
9793
+ fontWeight: isActive ? "bold" : "",
9794
+ color: isPending ? "red" : "black",
9795
+ }
9796
+ )}
9797
+ />
9798
+
9799
+ // children
9800
+ <NavLink to="/tasks">
9801
+ {({ isActive, isPending }) => (
9802
+ <span className={isActive ? "active" : ""}>Tasks</span>
9803
+ )}
9804
+ </NavLink>
9805
+ ```
9806
+
9807
+ */
9808
+
9809
+ /**
9810
+ * @category Types
9811
+ */
9812
+
8841
9813
  /**
8842
9814
  Wraps {@link Link | `<Link>`} with additional props for styling active and pending states.
8843
9815
 
@@ -8900,6 +9872,7 @@ const NavLink = /*#__PURE__*/React.forwardRef(function NavLinkWithRef(_ref5, ref
8900
9872
  if (nextLocationPathname && basename) {
8901
9873
  nextLocationPathname = stripBasename(nextLocationPathname, basename) || nextLocationPathname;
8902
9874
  }
9875
+
8903
9876
  // If the `to` has a trailing slash, look at that exact spot. Otherwise,
8904
9877
  // we're looking for a slash _after_ what's in `to`. For example:
8905
9878
  //
@@ -8936,6 +9909,21 @@ const NavLink = /*#__PURE__*/React.forwardRef(function NavLinkWithRef(_ref5, ref
8936
9909
  }), typeof children === "function" ? children(renderProps) : children);
8937
9910
  });
8938
9911
  NavLink.displayName = "NavLink";
9912
+
9913
+ /**
9914
+ * Form props shared by navigations and fetchers
9915
+ */
9916
+
9917
+ /**
9918
+ * Form props available to fetchers
9919
+ * @category Types
9920
+ */
9921
+
9922
+ /**
9923
+ * Form props available to navigations
9924
+ * @category Types
9925
+ */
9926
+
8939
9927
  /**
8940
9928
 
8941
9929
  A progressively enhanced HTML [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) that submits data to actions via `fetch`, activating pending states in `useNavigation` which enables advanced user interfaces beyond a basic HTML form. After a form's action completes, all data on the page is automatically revalidated to keep the UI in sync with the data.
@@ -9050,6 +10038,7 @@ function ScrollRestoration(_ref7) {
9050
10038
  getKey,
9051
10039
  storageKey
9052
10040
  });
10041
+
9053
10042
  // In order to support `getKey`, we need to compute a "key" here so we can
9054
10043
  // hydrate that up so that SSR scroll restoration isn't waiting on React to
9055
10044
  // hydrate. *However*, our key on the server is not the same as our key on
@@ -9064,6 +10053,7 @@ function ScrollRestoration(_ref7) {
9064
10053
  // Nah, we only need this the first time for the SSR render
9065
10054
  // eslint-disable-next-line react-hooks/exhaustive-deps
9066
10055
  []);
10056
+
9067
10057
  // In SPA Mode, there's nothing to restore on initial render since we didn't
9068
10058
  // render anything on the server
9069
10059
  if (!remixContext || remixContext.isSpaMode) {
@@ -9096,24 +10086,24 @@ function ScrollRestoration(_ref7) {
9096
10086
  }
9097
10087
  ScrollRestoration.displayName = "ScrollRestoration";
9098
10088
  //#endregion
10089
+
9099
10090
  ////////////////////////////////////////////////////////////////////////////////
9100
10091
  //#region Hooks
9101
10092
  ////////////////////////////////////////////////////////////////////////////////
9102
- var DataRouterHook;
9103
- (function (DataRouterHook) {
10093
+ var DataRouterHook = /*#__PURE__*/function (DataRouterHook) {
9104
10094
  DataRouterHook["UseScrollRestoration"] = "useScrollRestoration";
9105
10095
  DataRouterHook["UseSubmit"] = "useSubmit";
9106
10096
  DataRouterHook["UseSubmitFetcher"] = "useSubmitFetcher";
9107
10097
  DataRouterHook["UseFetcher"] = "useFetcher";
9108
10098
  DataRouterHook["useViewTransitionState"] = "useViewTransitionState";
9109
- })(DataRouterHook || (DataRouterHook = {}));
9110
- var DataRouterStateHook;
9111
- (function (DataRouterStateHook) {
10099
+ return DataRouterHook;
10100
+ }(DataRouterHook || {});
10101
+ var DataRouterStateHook = /*#__PURE__*/function (DataRouterStateHook) {
9112
10102
  DataRouterStateHook["UseFetcher"] = "useFetcher";
9113
10103
  DataRouterStateHook["UseFetchers"] = "useFetchers";
9114
10104
  DataRouterStateHook["UseScrollRestoration"] = "useScrollRestoration";
9115
- })(DataRouterStateHook || (DataRouterStateHook = {}));
9116
- // Internal hooks
10105
+ return DataRouterStateHook;
10106
+ }(DataRouterStateHook || {}); // Internal hooks
9117
10107
  function getDataRouterConsoleError(hookName) {
9118
10108
  return hookName + " must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.";
9119
10109
  }
@@ -9127,7 +10117,9 @@ function useDataRouterState(hookName) {
9127
10117
  !state ? process.env.NODE_ENV !== "production" ? invariant$2(false, getDataRouterConsoleError(hookName)) : invariant$2(false) : void 0;
9128
10118
  return state;
9129
10119
  }
10120
+
9130
10121
  // External hooks
10122
+
9131
10123
  /**
9132
10124
  * Handles the click behavior for router `<Link>` components. This is useful if
9133
10125
  * you need to create custom `<Link>` components with the same click behavior we
@@ -9152,6 +10144,7 @@ function useLinkClickHandler(to, _temp) {
9152
10144
  return React.useCallback(event => {
9153
10145
  if (shouldProcessLinkClick(event, target)) {
9154
10146
  event.preventDefault();
10147
+
9155
10148
  // If the URL hasn't changed, a regular <a> will do a replace instead of
9156
10149
  // a push, so do the same here unless the replace prop is explicitly set
9157
10150
  let replace = replaceProp !== undefined ? replaceProp : createPath(location) === createPath(path);
@@ -9165,6 +10158,7 @@ function useLinkClickHandler(to, _temp) {
9165
10158
  }
9166
10159
  }, [location, navigate, path, replaceProp, state, target, to, preventScrollReset, relative, viewTransition]);
9167
10160
  }
10161
+
9168
10162
  /**
9169
10163
  Returns a tuple of the current URL's {@link URLSearchParams} and a function to update them. Setting the search params causes a navigation.
9170
10164
 
@@ -9197,8 +10191,47 @@ function useSearchParams(defaultInit) {
9197
10191
  }, [navigate, searchParams]);
9198
10192
  return [searchParams, setSearchParams];
9199
10193
  }
10194
+
10195
+ /**
10196
+ Sets new search params and causes a navigation when called.
10197
+
10198
+ ```tsx
10199
+ <button
10200
+ onClick={() => {
10201
+ const params = new URLSearchParams();
10202
+ params.set("someKey", "someValue");
10203
+ setSearchParams(params, {
10204
+ preventScrollReset: true,
10205
+ });
10206
+ }}
10207
+ />
10208
+ ```
10209
+
10210
+ It also supports a function for setting new search params.
10211
+
10212
+ ```tsx
10213
+ <button
10214
+ onClick={() => {
10215
+ setSearchParams((prev) => {
10216
+ prev.set("someKey", "someValue");
10217
+ return prev;
10218
+ });
10219
+ }}
10220
+ />
10221
+ ```
10222
+ */
10223
+
10224
+ /**
10225
+ * Submits a HTML `<form>` to the server without reloading the page.
10226
+ */
10227
+
10228
+ /**
10229
+ * Submits a fetcher `<form>` to the server without reloading the page.
10230
+ */
10231
+
9200
10232
  let fetcherId = 0;
9201
10233
  let getUniqueFetcherId = () => "__" + String(++fetcherId) + "__";
10234
+
9202
10235
  /**
9203
10236
  The imperative version of {@link Form | `<Form>`} that lets you submit a form from code instead of a user interaction.
9204
10237
 
@@ -9264,6 +10297,7 @@ function useSubmit() {
9264
10297
  }
9265
10298
  }, [router, basename, currentRouteId]);
9266
10299
  }
10300
+
9267
10301
  // v7: Eventually we should deprecate this entirely in favor of using the
9268
10302
  // router method directly?
9269
10303
  /**
@@ -9304,6 +10338,7 @@ action, _temp2) {
9304
10338
  let path = _extends({}, useResolvedPath(action ? action : ".", {
9305
10339
  relative
9306
10340
  }));
10341
+
9307
10342
  // If no action was specified, browsers will persist current search params
9308
10343
  // when determining the path, so match that behavior
9309
10344
  // https://github.com/remix-run/remix/issues/927
@@ -9312,6 +10347,7 @@ action, _temp2) {
9312
10347
  // Safe to write to this directly here since if action was undefined, we
9313
10348
  // would have called useResolvedPath(".") which will never include a search
9314
10349
  path.search = location.search;
10350
+
9315
10351
  // When grabbing search params from the URL, remove any included ?index param
9316
10352
  // since it might not apply to our contextual route. We add it back based
9317
10353
  // on match.route.index below
@@ -9328,6 +10364,7 @@ action, _temp2) {
9328
10364
  if ((!action || action === ".") && match.route.index) {
9329
10365
  path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
9330
10366
  }
10367
+
9331
10368
  // If we're operating within a basename, prepend it to the pathname prior
9332
10369
  // to creating the form action. If this is a root navigation, then just use
9333
10370
  // the raw basename which allows the basename to have full control over the
@@ -9337,7 +10374,17 @@ action, _temp2) {
9337
10374
  }
9338
10375
  return createPath(path);
9339
10376
  }
10377
+
10378
+ /**
10379
+ The return value of `useFetcher` that keeps track of the state of a fetcher.
10380
+
10381
+ ```tsx
10382
+ let fetcher = useFetcher();
10383
+ ```
10384
+ */
10385
+
9340
10386
  // TODO: (v7) Change the useFetcher generic default from `any` to `unknown`
10387
+
9341
10388
  /**
9342
10389
  Useful for creating complex, dynamic user interfaces that require multiple, concurrent data interactions without causing a navigation.
9343
10390
 
@@ -9385,17 +10432,20 @@ function useFetcher(_temp3) {
9385
10432
  !fetcherData ? process.env.NODE_ENV !== "production" ? invariant$2(false, "useFetcher must be used inside a FetchersContext") : invariant$2(false) : void 0;
9386
10433
  !route ? process.env.NODE_ENV !== "production" ? invariant$2(false, "useFetcher must be used inside a RouteContext") : invariant$2(false) : void 0;
9387
10434
  !(routeId != null) ? process.env.NODE_ENV !== "production" ? invariant$2(false, "useFetcher can only be used on routes that contain a unique \"id\"") : invariant$2(false) : void 0;
10435
+
9388
10436
  // Fetcher key handling
9389
10437
  let defaultKey = React.useId();
9390
10438
  let [fetcherKey, setFetcherKey] = React.useState(key || defaultKey);
9391
10439
  if (key && key !== fetcherKey) {
9392
10440
  setFetcherKey(key);
9393
10441
  }
10442
+
9394
10443
  // Registration/cleanup
9395
10444
  React.useEffect(() => {
9396
10445
  router.getFetcher(fetcherKey);
9397
10446
  return () => router.deleteFetcher(fetcherKey);
9398
10447
  }, [router, fetcherKey]);
10448
+
9399
10449
  // Fetcher additions
9400
10450
  let load = React.useCallback(async (href, opts) => {
9401
10451
  !routeId ? process.env.NODE_ENV !== "production" ? invariant$2(false, "No routeId available for fetcher.load()") : invariant$2(false) : void 0;
@@ -9419,6 +10469,7 @@ function useFetcher(_temp3) {
9419
10469
  FetcherForm.displayName = "fetcher.Form";
9420
10470
  return FetcherForm;
9421
10471
  }, [fetcherKey]);
10472
+
9422
10473
  // Exposed FetcherWithComponents
9423
10474
  let fetcher = state.fetchers.get(fetcherKey) || IDLE_FETCHER;
9424
10475
  let data = fetcherData.get(fetcherKey);
@@ -9431,6 +10482,7 @@ function useFetcher(_temp3) {
9431
10482
  }), [FetcherForm, submit, load, fetcher, data]);
9432
10483
  return fetcherWithComponents;
9433
10484
  }
10485
+
9434
10486
  /**
9435
10487
  Returns an array of all in-flight fetchers. This is useful for components throughout the app that didn't create the fetchers but want to use their submissions to participate in optimistic UI.
9436
10488
 
@@ -9474,6 +10526,7 @@ function getScrollRestorationKey(location, matches, basename, getKey) {
9474
10526
  }
9475
10527
  return key;
9476
10528
  }
10529
+
9477
10530
  /**
9478
10531
  * When rendered inside a RouterProvider, will restore scroll positions on navigations
9479
10532
  */
@@ -9495,6 +10548,7 @@ function useScrollRestoration(_temp4) {
9495
10548
  let location = useLocation();
9496
10549
  let matches = useMatches();
9497
10550
  let navigation = useNavigation();
10551
+
9498
10552
  // Trigger manual scroll restoration while we're active
9499
10553
  React.useEffect(() => {
9500
10554
  window.history.scrollRestoration = "manual";
@@ -9502,6 +10556,7 @@ function useScrollRestoration(_temp4) {
9502
10556
  window.history.scrollRestoration = "auto";
9503
10557
  };
9504
10558
  }, []);
10559
+
9505
10560
  // Save positions on pagehide
9506
10561
  usePageHide(React.useCallback(() => {
9507
10562
  if (navigation.state === "idle") {
@@ -9515,6 +10570,7 @@ function useScrollRestoration(_temp4) {
9515
10570
  }
9516
10571
  window.history.scrollRestoration = "auto";
9517
10572
  }, [navigation.state, getKey, basename, location, matches, storageKey]));
10573
+
9518
10574
  // Read in any saved scroll locations
9519
10575
  if (typeof document !== "undefined") {
9520
10576
  // eslint-disable-next-line react-hooks/rules-of-hooks
@@ -9528,12 +10584,14 @@ function useScrollRestoration(_temp4) {
9528
10584
  // no-op, use default empty object
9529
10585
  }
9530
10586
  }, [storageKey]);
10587
+
9531
10588
  // Enable scroll restoration in the router
9532
10589
  // eslint-disable-next-line react-hooks/rules-of-hooks
9533
10590
  React.useLayoutEffect(() => {
9534
10591
  let disableScrollRestoration = router == null ? void 0 : router.enableScrollRestoration(savedScrollPositions, () => window.scrollY, getKey ? (location, matches) => getScrollRestorationKey(location, matches, basename, getKey) : undefined);
9535
10592
  return () => disableScrollRestoration && disableScrollRestoration();
9536
10593
  }, [router, basename, getKey]);
10594
+
9537
10595
  // Restore scrolling when state.restoreScrollPosition changes
9538
10596
  // eslint-disable-next-line react-hooks/rules-of-hooks
9539
10597
  React.useLayoutEffect(() => {
@@ -9541,11 +10599,13 @@ function useScrollRestoration(_temp4) {
9541
10599
  if (restoreScrollPosition === false) {
9542
10600
  return;
9543
10601
  }
10602
+
9544
10603
  // been here before, scroll to it
9545
10604
  if (typeof restoreScrollPosition === "number") {
9546
10605
  window.scrollTo(0, restoreScrollPosition);
9547
10606
  return;
9548
10607
  }
10608
+
9549
10609
  // try to scroll to the hash
9550
10610
  if (location.hash) {
9551
10611
  let el = document.getElementById(decodeURIComponent(location.hash.slice(1)));
@@ -9554,15 +10614,18 @@ function useScrollRestoration(_temp4) {
9554
10614
  return;
9555
10615
  }
9556
10616
  }
10617
+
9557
10618
  // Don't reset if this navigation opted out
9558
10619
  if (preventScrollReset === true) {
9559
10620
  return;
9560
10621
  }
10622
+
9561
10623
  // otherwise go to the top on new locations
9562
10624
  window.scrollTo(0, 0);
9563
10625
  }, [location, restoreScrollPosition, preventScrollReset]);
9564
10626
  }
9565
10627
  }
10628
+
9566
10629
  /**
9567
10630
  * Setup a callback to be fired on the window's `beforeunload` event.
9568
10631
  *
@@ -9582,6 +10645,7 @@ function useBeforeUnload(callback, options) {
9582
10645
  };
9583
10646
  }, [callback, capture]);
9584
10647
  }
10648
+
9585
10649
  /**
9586
10650
  * Setup a callback to be fired on the window's `pagehide` event. This is
9587
10651
  * useful for saving some data to `window.localStorage` just before the page
@@ -9604,6 +10668,7 @@ function usePageHide(callback, options) {
9604
10668
  };
9605
10669
  }, [callback, capture]);
9606
10670
  }
10671
+
9607
10672
  /**
9608
10673
  Wrapper around useBlocker to show a window.confirm prompt to users instead of building a custom UI with {@link useBlocker}.
9609
10674
 
@@ -9665,6 +10730,7 @@ function usePrompt(_ref9) {
9665
10730
  }
9666
10731
  }, [blocker, when]);
9667
10732
  }
10733
+
9668
10734
  /**
9669
10735
  This hook returns `true` when there is an active [View Transition](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API) to the specified location. This can be used to apply finer-grained styles to elements to further customize the view transition. This requires that view transitions have been enabled for the given navigation via {@link LinkProps.viewTransition} (or the `Form`, `submit`, or `navigate` call)
9670
10736
 
@@ -9688,6 +10754,7 @@ function useViewTransitionState(to, opts) {
9688
10754
  }
9689
10755
  let currentPath = stripBasename(vtContext.currentLocation.pathname, basename) || vtContext.currentLocation.pathname;
9690
10756
  let nextPath = stripBasename(vtContext.nextLocation.pathname, basename) || vtContext.nextLocation.pathname;
10757
+
9691
10758
  // Transition is active if we're going to or coming from the indicated
9692
10759
  // destination. This ensures that other PUSH navigations that reverse
9693
10760
  // an indicated transition apply. I.e., on the list view you have:
@@ -9703,6 +10770,7 @@ function useViewTransitionState(to, opts) {
9703
10770
  // (even though this isn't strictly a POP reverse)
9704
10771
  return matchPath(path.pathname, nextPath) != null || matchPath(path.pathname, currentPath) != null;
9705
10772
  }
10773
+
9706
10774
  //#endregion
9707
10775
 
9708
10776
  /**
@@ -9797,13 +10865,13 @@ function StaticRouterProvider(_ref2) {
9797
10865
  routes: router.routes,
9798
10866
  future: router.future,
9799
10867
  state: state
9800
- })))))), hydrateScript ? ( /*#__PURE__*/React.createElement("script", {
10868
+ })))))), hydrateScript ? /*#__PURE__*/React.createElement("script", {
9801
10869
  suppressHydrationWarning: true,
9802
10870
  nonce: nonce,
9803
10871
  dangerouslySetInnerHTML: {
9804
10872
  __html: hydrateScript
9805
10873
  }
9806
- })) : null);
10874
+ }) : null);
9807
10875
  }
9808
10876
  function DataRoutes(_ref3) {
9809
10877
  let {
@@ -9867,6 +10935,7 @@ function createStaticHandler(routes, opts) {
9867
10935
  mapRouteProperties
9868
10936
  }));
9869
10937
  }
10938
+
9870
10939
  /**
9871
10940
  * @category Routers
9872
10941
  */
@@ -9876,6 +10945,7 @@ function createStaticRouter(routes, context, opts) {
9876
10945
  }
9877
10946
  let manifest = {};
9878
10947
  let dataRoutes = convertRoutesToDataRoutes(routes, mapRouteProperties, undefined, manifest);
10948
+
9879
10949
  // Because our context matches may be from a framework-agnostic set of
9880
10950
  // routes passed to createStaticHandler(), we update them here with our
9881
10951
  // newly created/enhanced data routes
@@ -9978,6 +11048,7 @@ function encodeLocation(to) {
9978
11048
  };
9979
11049
  }
9980
11050
  const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
11051
+
9981
11052
  // This utility is based on https://github.com/zertosh/htmlescape
9982
11053
  // License: https://github.com/zertosh/htmlescape/blob/0527ca7156a524d256101bb310a9f970f63078ad/LICENSE
9983
11054
  const ESCAPE_LOOKUP$1 = {
@@ -10016,6 +11087,7 @@ function ServerRouter(_ref) {
10016
11087
  serverHandoffString
10017
11088
  } = context;
10018
11089
  let routes = createServerRoutes(manifest.routes, routeModules, context.future, context.isSpaMode);
11090
+
10019
11091
  // Create a shallow clone of `loaderData` we can mutate for partial hydration.
10020
11092
  // When a route exports a `clientLoader` and a `HydrateFallback`, we want to
10021
11093
  // render the fallback on the server so we clear our the `loaderData` during SSR.
@@ -10030,7 +11102,7 @@ function ServerRouter(_ref) {
10030
11102
  // route opted into clientLoader hydration and either:
10031
11103
  // * gave us a HydrateFallback
10032
11104
  // * or doesn't have a server loader and we have no data to render
10033
- if (route && shouldHydrateRouteLoader(manifestRoute, route, context.isSpaMode) && (route.HydrateFallback || !manifestRoute.hasLoader)) {
11105
+ if (route && manifestRoute && shouldHydrateRouteLoader(manifestRoute, route, context.isSpaMode) && (route.HydrateFallback || !manifestRoute.hasLoader)) {
10034
11106
  delete context.staticHandlerContext.loaderData[routeId];
10035
11107
  }
10036
11108
  }
@@ -10053,13 +11125,13 @@ function ServerRouter(_ref) {
10053
11125
  router: router,
10054
11126
  context: context.staticHandlerContext,
10055
11127
  hydrate: false
10056
- }))), context.serverHandoffStream ? ( /*#__PURE__*/React.createElement(React.Suspense, null, /*#__PURE__*/React.createElement(StreamTransfer, {
11128
+ }))), context.serverHandoffStream ? /*#__PURE__*/React.createElement(React.Suspense, null, /*#__PURE__*/React.createElement(StreamTransfer, {
10057
11129
  context: context,
10058
11130
  identifier: 0,
10059
11131
  reader: context.serverHandoffStream.getReader(),
10060
11132
  textDecoder: new TextDecoder(),
10061
11133
  nonce: nonce
10062
- }))) : null);
11134
+ })) : null);
10063
11135
  }
10064
11136
 
10065
11137
  /**
@@ -10093,6 +11165,7 @@ function createRoutesStub(routes, context) {
10093
11165
  routeModules: {},
10094
11166
  isSpaMode: false
10095
11167
  };
11168
+
10096
11169
  // Update the routes to include context in the loader/action and populate
10097
11170
  // the manifest and routeModules during the walk
10098
11171
  let patched = processRoutes(
@@ -10116,6 +11189,7 @@ function processRoutes(routes, context, manifest, routeModules, parentId) {
10116
11189
  if (!route.id) {
10117
11190
  throw new Error("Expected a route.id in @remix-run/testing processRoutes() function");
10118
11191
  }
11192
+
10119
11193
  // Patch in the Remix context to loaders/actions
10120
11194
  let {
10121
11195
  loader,
@@ -10137,6 +11211,7 @@ function processRoutes(routes, context, manifest, routeModules, parentId) {
10137
11211
  handle: route.handle,
10138
11212
  shouldRevalidate: route.shouldRevalidate
10139
11213
  };
11214
+
10140
11215
  // Add the EntryRoute to the manifest
10141
11216
  let entryRoute = {
10142
11217
  id: route.id,
@@ -10154,6 +11229,7 @@ function processRoutes(routes, context, manifest, routeModules, parentId) {
10154
11229
  module: "build/stub-path-to-module.js" // any need for this?
10155
11230
  };
10156
11231
  manifest.routes[newRoute.id] = entryRoute;
11232
+
10157
11233
  // Add the route to routeModules
10158
11234
  routeModules[route.id] = {
10159
11235
  default: route.Component || Outlet,
@@ -10201,6 +11277,18 @@ function byteStringToUint8Array(byteString) {
10201
11277
  }
10202
11278
 
10203
11279
  const _excluded = ["secrets"];
11280
+
11281
+ /**
11282
+ * A HTTP cookie.
11283
+ *
11284
+ * A Cookie is a logical container for metadata about a HTTP cookie; its name
11285
+ * and options. But it doesn't contain a value. Instead, it has `parse()` and
11286
+ * `serialize()` methods that allow a single instance to be reused for
11287
+ * parsing/encoding multiple different values.
11288
+ *
11289
+ * @see https://remix.run/utils/cookies#cookie-api
11290
+ */
11291
+
10204
11292
  /**
10205
11293
  * Creates a logical container for managing a browser cookie from the server.
10206
11294
  */
@@ -10231,7 +11319,17 @@ const createCookie = function createCookie(name, cookieOptions) {
10231
11319
  async parse(cookieHeader, parseOptions) {
10232
11320
  if (!cookieHeader) return null;
10233
11321
  let cookies = parse(cookieHeader, _extends({}, options, parseOptions));
10234
- return name in cookies ? cookies[name] === "" ? "" : await decodeCookieValue(cookies[name], secrets) : null;
11322
+ if (name in cookies) {
11323
+ let value = cookies[name];
11324
+ if (typeof value === "string" && value !== "") {
11325
+ let decoded = await decodeCookieValue(value, secrets);
11326
+ return decoded;
11327
+ } else {
11328
+ return "";
11329
+ }
11330
+ } else {
11331
+ return null;
11332
+ }
10235
11333
  },
10236
11334
  async serialize(value, serializeOptions) {
10237
11335
  return serialize(name, value === "" ? "" : await encodeCookieValue(value, secrets), _extends({}, options, serializeOptions));
@@ -10275,6 +11373,7 @@ function decodeData(value) {
10275
11373
  return {};
10276
11374
  }
10277
11375
  }
11376
+
10278
11377
  // See: https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.escape.js
10279
11378
  function myEscape(value) {
10280
11379
  let str = value.toString();
@@ -10301,6 +11400,7 @@ function hex(code, length) {
10301
11400
  while (result.length < length) result = "0" + result;
10302
11401
  return result;
10303
11402
  }
11403
+
10304
11404
  // See: https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.unescape.js
10305
11405
  function myUnescape(value) {
10306
11406
  let str = value.toString();
@@ -10336,7 +11436,10 @@ function warnOnceAboutExpiresCookie(name, expires) {
10336
11436
 
10337
11437
  function createEntryRouteModules(manifest) {
10338
11438
  return Object.keys(manifest).reduce((memo, routeId) => {
10339
- memo[routeId] = manifest[routeId].module;
11439
+ let route = manifest[routeId];
11440
+ if (route) {
11441
+ memo[routeId] = route.module;
11442
+ }
10340
11443
  return memo;
10341
11444
  }, {});
10342
11445
  }
@@ -10344,12 +11447,12 @@ function createEntryRouteModules(manifest) {
10344
11447
  /**
10345
11448
  * The mode to use when running the server.
10346
11449
  */
10347
- var ServerMode;
10348
- (function (ServerMode) {
11450
+ let ServerMode = /*#__PURE__*/function (ServerMode) {
10349
11451
  ServerMode["Development"] = "development";
10350
11452
  ServerMode["Production"] = "production";
10351
11453
  ServerMode["Test"] = "test";
10352
- })(ServerMode || (ServerMode = {}));
11454
+ return ServerMode;
11455
+ }({});
10353
11456
  function isServerMode(value) {
10354
11457
  return value === ServerMode.Development || value === ServerMode.Production || value === ServerMode.Test;
10355
11458
  }
@@ -10395,6 +11498,7 @@ function isServerMode(value) {
10395
11498
  * because it came first, and that just wouldn't be fair to let errors cut in
10396
11499
  * line.
10397
11500
  */
11501
+
10398
11502
  function sanitizeError(error, serverMode) {
10399
11503
  if (error instanceof Error && serverMode !== ServerMode.Development) {
10400
11504
  let sanitized = new Error("Unexpected Server Error");
@@ -10411,6 +11515,10 @@ function sanitizeErrors(errors, serverMode) {
10411
11515
  });
10412
11516
  }, {});
10413
11517
  }
11518
+
11519
+ // must be type alias due to inference issues on interfaces
11520
+ // https://github.com/microsoft/TypeScript/issues/15300
11521
+
10414
11522
  function serializeError(error, serverMode) {
10415
11523
  let sanitized = sanitizeError(error, serverMode);
10416
11524
  return {
@@ -10456,27 +11564,11 @@ function matchServerRoutes(routes, pathname, basename) {
10456
11564
  }
10457
11565
 
10458
11566
  /**
10459
- * This is a shortcut for creating `application/json` responses. Converts `data`
10460
- * to JSON and sets the `Content-Type` header.
10461
- *
10462
- * @see https://remix.run/utils/json
11567
+ * An object of unknown type for route loaders and actions provided by the
11568
+ * server's `getLoadContext()` function. This is defined as an empty interface
11569
+ * specifically so apps can leverage declaration merging to augment this type
11570
+ * globally: https://www.typescriptlang.org/docs/handbook/declaration-merging.html
10463
11571
  */
10464
- const json = function json(data, init) {
10465
- if (init === void 0) {
10466
- init = {};
10467
- }
10468
- return json$1(data, init);
10469
- };
10470
- function isResponse(value) {
10471
- return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
10472
- }
10473
- const redirectStatusCodes = new Set([301, 302, 303, 307, 308]);
10474
- function isRedirectStatusCode(statusCode) {
10475
- return redirectStatusCodes.has(statusCode);
10476
- }
10477
- function isRedirectResponse(response) {
10478
- return isRedirectStatusCode(response.status);
10479
- }
10480
11572
 
10481
11573
  // Need to use RR's version here to permit the optional context even
10482
11574
  // though we know it'll always be provided in remix
@@ -10486,12 +11578,14 @@ async function callRouteHandler(handler, args) {
10486
11578
  params: args.params,
10487
11579
  context: args.context
10488
11580
  });
11581
+
10489
11582
  // If they returned a redirect via data(), re-throw it as a Response
10490
11583
  if (isDataWithResponseInit(result) && result.init && result.init.status && isRedirectStatusCode(result.init.status)) {
10491
11584
  throw new Response(null, result.init);
10492
11585
  }
10493
11586
  return result;
10494
11587
  }
11588
+
10495
11589
  // TODO: Document these search params better
10496
11590
  // and stop stripping these in V2. These break
10497
11591
  // support for running in a SW and also expose
@@ -10538,7 +11632,7 @@ function stripRoutesParam(request) {
10538
11632
 
10539
11633
  function invariant(value, message) {
10540
11634
  if (value === false || value === null || typeof value === "undefined") {
10541
- console.error("The following error is a bug in Remix; please open an issue! https://github.com/remix-run/remix/issues/new");
11635
+ console.error("The following error is a bug in React Router; please open an issue! https://github.com/remix-run/react-router/issues/new/choose");
10542
11636
  throw new Error(message);
10543
11637
  }
10544
11638
  }
@@ -10546,14 +11640,17 @@ function invariant(value, message) {
10546
11640
  function groupRoutesByParentId(manifest) {
10547
11641
  let routes = {};
10548
11642
  Object.values(manifest).forEach(route => {
10549
- let parentId = route.parentId || "";
10550
- if (!routes[parentId]) {
10551
- routes[parentId] = [];
11643
+ if (route) {
11644
+ let parentId = route.parentId || "";
11645
+ if (!routes[parentId]) {
11646
+ routes[parentId] = [];
11647
+ }
11648
+ routes[parentId].push(route);
10552
11649
  }
10553
- routes[parentId].push(route);
10554
11650
  });
10555
11651
  return routes;
10556
11652
  }
11653
+
10557
11654
  // Create a map of routes by parentId to use recursively instead of
10558
11655
  // repeatedly filtering the manifest.
10559
11656
  function createRoutes(manifest, parentId, routesByParentId) {
@@ -10567,6 +11664,7 @@ function createRoutes(manifest, parentId, routesByParentId) {
10567
11664
  children: createRoutes(manifest, route.id, routesByParentId)
10568
11665
  }));
10569
11666
  }
11667
+
10570
11668
  // Convert the Remix ServerManifest into DataRouteObject's for use with
10571
11669
  // createStaticHandler
10572
11670
  function createStaticHandlerDataRoutes(manifest, future, parentId, routesByParentId) {
@@ -10621,8 +11719,10 @@ function createStaticHandlerDataRoutes(manifest, future, parentId, routesByParen
10621
11719
 
10622
11720
  // This escapeHtml utility is based on https://github.com/zertosh/htmlescape
10623
11721
  // License: https://github.com/zertosh/htmlescape/blob/0527ca7156a524d256101bb310a9f970f63078ad/LICENSE
11722
+
10624
11723
  // We've chosen to inline the utility here to reduce the number of npm dependencies we have,
10625
11724
  // slightly decrease the code size compared the original package and make it esm compatible.
11725
+
10626
11726
  const ESCAPE_LOOKUP = {
10627
11727
  "&": "\\u0026",
10628
11728
  ">": "\\u003e",
@@ -10679,16 +11779,20 @@ function getDocumentHeaders(build, context) {
10679
11779
  let {
10680
11780
  id
10681
11781
  } = match.route;
10682
- let routeModule = build.routes[id].module;
11782
+ let route = build.routes[id];
11783
+ !route ? process.env.NODE_ENV !== "production" ? invariant(false, "Route with id \"" + id + "\" not found in build") : invariant(false) : void 0;
11784
+ let routeModule = route.module;
10683
11785
  let loaderHeaders = context.loaderHeaders[id] || new Headers();
10684
11786
  let actionHeaders = context.actionHeaders[id] || new Headers();
11787
+
10685
11788
  // Only expose errorHeaders to the leaf headers() function to
10686
11789
  // avoid duplication via parentHeaders
10687
- let includeErrorHeaders = errorHeaders != undefined && idx === matches.length - 1;
11790
+ let includeErrorHeaders = errorHeaders != null && idx === matches.length - 1;
10688
11791
  // Only prepend cookies from errorHeaders at the leaf renderable route
10689
11792
  // when it's not the same as loaderHeaders/actionHeaders to avoid
10690
11793
  // duplicate cookies
10691
11794
  let includeErrorCookies = includeErrorHeaders && errorHeaders !== loaderHeaders && errorHeaders !== actionHeaders;
11795
+
10692
11796
  // Use the parent headers for any route without a `headers` export
10693
11797
  if (routeModule.headers == null) {
10694
11798
  let headers = new Headers(parentHeaders);
@@ -10705,6 +11809,7 @@ function getDocumentHeaders(build, context) {
10705
11809
  actionHeaders,
10706
11810
  errorHeaders: includeErrorHeaders ? errorHeaders : undefined
10707
11811
  }) : routeModule.headers : undefined);
11812
+
10708
11813
  // Automatically preserve Set-Cookie headers from bubbled responses,
10709
11814
  // loaders, errors, and parent routes
10710
11815
  if (includeErrorCookies) {
@@ -10746,6 +11851,7 @@ function getSingleFetchDataStrategy(_temp) {
10746
11851
  if (isActionDataRequest && request.method === "GET") {
10747
11852
  return {};
10748
11853
  }
11854
+
10749
11855
  // Only run opt-in loaders when fine-grained revalidation is enabled
10750
11856
  let matchesToLoad = loadRouteIds ? matches.filter(m => loadRouteIds.includes(m.route.id)) : matches;
10751
11857
  let results = await Promise.all(matchesToLoad.map(match => match.resolve()));
@@ -10771,6 +11877,7 @@ async function singleFetchAction(build, serverMode, staticHandler, request, hand
10771
11877
  isActionDataRequest: true
10772
11878
  })
10773
11879
  });
11880
+
10774
11881
  // Unlike `handleDataRequest`, when singleFetch is enabled, query does
10775
11882
  // let non-Response return values through
10776
11883
  if (isResponse(result)) {
@@ -10789,6 +11896,7 @@ async function singleFetchAction(build, serverMode, staticHandler, request, hand
10789
11896
  status: SINGLE_FETCH_REDIRECT_STATUS
10790
11897
  };
10791
11898
  }
11899
+
10792
11900
  // Sanitize errors outside of development environments
10793
11901
  if (context.errors) {
10794
11902
  Object.values(context.errors).forEach(err => {
@@ -10861,6 +11969,7 @@ async function singleFetchLoaders(build, serverMode, staticHandler, request, han
10861
11969
  status: SINGLE_FETCH_REDIRECT_STATUS
10862
11970
  };
10863
11971
  }
11972
+
10864
11973
  // Sanitize errors outside of development environments
10865
11974
  if (context.errors) {
10866
11975
  Object.values(context.errors).forEach(err => {
@@ -10871,6 +11980,7 @@ async function singleFetchLoaders(build, serverMode, staticHandler, request, han
10871
11980
  });
10872
11981
  context.errors = sanitizeErrors(context.errors, serverMode);
10873
11982
  }
11983
+
10874
11984
  // Aggregate results based on the matches we intended to load since we get
10875
11985
  // `null` values back in `context.loaderData` for routes we didn't load
10876
11986
  let results = {};
@@ -10929,6 +12039,7 @@ function getSingleFetchRedirect(status, headers, basename) {
10929
12039
  replace: headers.has("X-Remix-Replace")
10930
12040
  };
10931
12041
  }
12042
+
10932
12043
  // Note: If you change this function please change the corresponding
10933
12044
  // decodeViaTurboStream function in server-runtime
10934
12045
  function encodeViaTurboStream(data, requestSignal, streamTimeout, serverMode) {
@@ -11038,6 +12149,7 @@ const createRequestHandler = (build, mode) => {
11038
12149
  request
11039
12150
  });
11040
12151
  };
12152
+
11041
12153
  // Manifest request for fog of war
11042
12154
  let manifestUrl = (((_build$basename = _build.basename) != null ? _build$basename : "/") + "/__manifest").replace(/\/+/g, "/");
11043
12155
  if (url.pathname === manifestUrl) {
@@ -11107,15 +12219,18 @@ async function handleManifestRequest(build, routes, url) {
11107
12219
  if (matches) {
11108
12220
  for (let match of matches) {
11109
12221
  let routeId = match.route.id;
11110
- patches[routeId] = build.assets.routes[routeId];
12222
+ let route = build.assets.routes[routeId];
12223
+ if (route) {
12224
+ patches[routeId] = route;
12225
+ }
11111
12226
  }
11112
12227
  }
11113
12228
  }
11114
- return json(patches, {
12229
+ return Response.json(patches, {
11115
12230
  headers: {
11116
12231
  "Cache-Control": "public, max-age=31536000, immutable"
11117
12232
  }
11118
- }); // Override the TypedResponse stuff from json()
12233
+ });
11119
12234
  }
11120
12235
  return new Response("Invalid Request", {
11121
12236
  status: 400
@@ -11127,10 +12242,12 @@ async function handleSingleFetchRequest(serverMode, build, staticHandler, reques
11127
12242
  headers,
11128
12243
  status
11129
12244
  } = request.method !== "GET" ? await singleFetchAction(build, serverMode, staticHandler, request, handlerUrl, loadContext, handleError) : await singleFetchLoaders(build, serverMode, staticHandler, request, handlerUrl, loadContext, handleError);
12245
+
11130
12246
  // Mark all successful responses with a header so we can identify in-flight
11131
12247
  // network errors that are missing this header
11132
12248
  let resultHeaders = new Headers(headers);
11133
12249
  resultHeaders.set("X-Remix-Response", "yes");
12250
+
11134
12251
  // 304 responses should not have a body
11135
12252
  if (status === 304) {
11136
12253
  return new Response(null, {
@@ -11138,6 +12255,7 @@ async function handleSingleFetchRequest(serverMode, build, staticHandler, reques
11138
12255
  headers: resultHeaders
11139
12256
  });
11140
12257
  }
12258
+
11141
12259
  // We use a less-descriptive `text/x-script` here instead of something like
11142
12260
  // `text/x-turbo` to enable compression when deployed via Cloudflare. See:
11143
12261
  // - https://github.com/remix-run/remix/issues/9884
@@ -11164,6 +12282,7 @@ async function handleDocumentRequest(serverMode, build, staticHandler, request,
11164
12282
  return context;
11165
12283
  }
11166
12284
  let headers = getDocumentHeaders(build, context);
12285
+
11167
12286
  // 304 responses should not have a body or a content-type
11168
12287
  if (context.statusCode === 304) {
11169
12288
  return new Response(null, {
@@ -11171,6 +12290,7 @@ async function handleDocumentRequest(serverMode, build, staticHandler, request,
11171
12290
  headers
11172
12291
  });
11173
12292
  }
12293
+
11174
12294
  // Sanitize errors outside of development environments
11175
12295
  if (context.errors) {
11176
12296
  Object.values(context.errors).forEach(err => {
@@ -11181,6 +12301,7 @@ async function handleDocumentRequest(serverMode, build, staticHandler, request,
11181
12301
  });
11182
12302
  context.errors = sanitizeErrors(context.errors, serverMode);
11183
12303
  }
12304
+
11184
12305
  // Server UI state to send to the client.
11185
12306
  // - When single fetch is enabled, this is streamed down via `serverHandoffStream`
11186
12307
  // - Otherwise it's stringified into `serverHandoffString`
@@ -11212,6 +12333,7 @@ async function handleDocumentRequest(serverMode, build, staticHandler, request,
11212
12333
  } catch (error) {
11213
12334
  handleError(error);
11214
12335
  let errorForSecondRender = error;
12336
+
11215
12337
  // If they threw a response, unwrap it into an ErrorResponse like we would
11216
12338
  // have for a loader/action
11217
12339
  if (isResponse(error)) {
@@ -11222,12 +12344,15 @@ async function handleDocumentRequest(serverMode, build, staticHandler, request,
11222
12344
  // If we can't unwrap the response - just leave it as-is
11223
12345
  }
11224
12346
  }
12347
+
11225
12348
  // Get a new StaticHandlerContext that contains the error at the right boundary
11226
12349
  context = getStaticContextFromError(staticHandler.dataRoutes, context, errorForSecondRender);
12350
+
11227
12351
  // Sanitize errors outside of development environments
11228
12352
  if (context.errors) {
11229
12353
  context.errors = sanitizeErrors(context.errors, serverMode);
11230
12354
  }
12355
+
11231
12356
  // Get a new entryContext for the second render pass
11232
12357
  // Server UI state to send to the client.
11233
12358
  // - When single fetch is enabled, this is streamed down via `serverHandoffStream`
@@ -11284,7 +12409,7 @@ async function handleResourceRequest(serverMode, build, staticHandler, routeId,
11284
12409
  }
11285
12410
  }
11286
12411
  function errorResponseToJson(errorResponse, serverMode) {
11287
- return json$1(serializeError(
12412
+ return Response.json(serializeError(
11288
12413
  // @ts-expect-error This is "private" from users but intended for internal use
11289
12414
  errorResponse.error || new Error("Unexpected Server Error"), serverMode), {
11290
12415
  status: errorResponse.status,
@@ -11299,6 +12424,7 @@ function returnLastResortErrorResponse(error, serverMode) {
11299
12424
  if (serverMode !== ServerMode.Production) {
11300
12425
  message += "\n\n" + String(error);
11301
12426
  }
12427
+
11302
12428
  // Good grief folks, get your act together 😂!
11303
12429
  return new Response(message, {
11304
12430
  status: 500,
@@ -11314,6 +12440,16 @@ function unwrapResponse(response) {
11314
12440
  return contentType && /\bapplication\/json\b/.test(contentType) ? response.body == null ? null : response.json() : response.text();
11315
12441
  }
11316
12442
 
12443
+ /**
12444
+ * An object of name/value pairs to be used in the session.
12445
+ */
12446
+
12447
+ /**
12448
+ * Session persists data across HTTP requests.
12449
+ *
12450
+ * @see https://remix.run/utils/sessions#session-api
12451
+ */
12452
+
11317
12453
  function flash(name) {
11318
12454
  return "__flash_" + name + "__";
11319
12455
  }
@@ -11372,6 +12508,25 @@ const createSession = function createSession(initialData, id) {
11372
12508
  const isSession = object => {
11373
12509
  return object != null && typeof object.id === "string" && typeof object.data !== "undefined" && typeof object.has === "function" && typeof object.get === "function" && typeof object.set === "function" && typeof object.flash === "function" && typeof object.unset === "function";
11374
12510
  };
12511
+
12512
+ /**
12513
+ * SessionStorage stores session data between HTTP requests and knows how to
12514
+ * parse and create cookies.
12515
+ *
12516
+ * A SessionStorage creates Session objects using a `Cookie` header as input.
12517
+ * Then, later it generates the `Set-Cookie` header to be used in the response.
12518
+ */
12519
+
12520
+ /**
12521
+ * SessionIdStorageStrategy is designed to allow anyone to easily build their
12522
+ * own SessionStorage using `createSessionStorage(strategy)`.
12523
+ *
12524
+ * This strategy describes a common scenario where the session id is stored in
12525
+ * a cookie but the actual session data is stored elsewhere, usually in a
12526
+ * database or on disk. A set of create, read, update, and delete operations
12527
+ * are provided for managing the session data.
12528
+ */
12529
+
11375
12530
  /**
11376
12531
  * Creates a SessionStorage object using a SessionIdStorageStrategy.
11377
12532
  *
@@ -11486,6 +12641,7 @@ function createMemorySessionStorage(_temp) {
11486
12641
  if (!expires || expires > new Date()) {
11487
12642
  return data;
11488
12643
  }
12644
+
11489
12645
  // Remove expired session data.
11490
12646
  if (expires) map.delete(id);
11491
12647
  }
@@ -11539,5 +12695,5 @@ function deserializeErrors(errors) {
11539
12695
  return serialized;
11540
12696
  }
11541
12697
 
11542
- export { Await, BrowserRouter, Form, HashRouter, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, Link, Links, MemoryRouter, Meta, NavLink, Navigate, Action as NavigationType, Outlet, PrefetchPageLinks, Route, Router, RouterProvider, Routes, Scripts, ScrollRestoration, ServerRouter, StaticRouter, StaticRouterProvider, DataRouterContext as UNSAFE_DataRouterContext, DataRouterStateContext as UNSAFE_DataRouterStateContext, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, FetchersContext as UNSAFE_FetchersContext, FrameworkContext as UNSAFE_FrameworkContext, LocationContext as UNSAFE_LocationContext, NavigationContext as UNSAFE_NavigationContext, RemixErrorBoundary as UNSAFE_RemixErrorBoundary, RouteContext as UNSAFE_RouteContext, ServerMode as UNSAFE_ServerMode, SingleFetchRedirectSymbol as UNSAFE_SingleFetchRedirectSymbol, ViewTransitionContext as UNSAFE_ViewTransitionContext, createBrowserHistory as UNSAFE_createBrowserHistory, createClientRoutes as UNSAFE_createClientRoutes, createClientRoutesWithHMRRevalidationOptOut as UNSAFE_createClientRoutesWithHMRRevalidationOptOut, createRouter as UNSAFE_createRouter, decodeViaTurboStream as UNSAFE_decodeViaTurboStream, deserializeErrors as UNSAFE_deserializeErrors, getPatchRoutesOnNavigationFunction as UNSAFE_getPatchRoutesOnNavigationFunction, getSingleFetchDataStrategy$1 as UNSAFE_getSingleFetchDataStrategy, invariant$2 as UNSAFE_invariant, mapRouteProperties as UNSAFE_mapRouteProperties, shouldHydrateRouteLoader as UNSAFE_shouldHydrateRouteLoader, useFogOFWarDiscovery as UNSAFE_useFogOFWarDiscovery, useScrollRestoration as UNSAFE_useScrollRestoration, createBrowserRouter, createCookie, createCookieSessionStorage, createHashRouter, createMemoryRouter, createMemorySessionStorage, createPath, createRequestHandler, createRoutesFromChildren, createRoutesFromChildren as createRoutesFromElements, createRoutesStub, createSearchParams, createSession, createSessionStorage, createStaticHandler, createStaticRouter, data, generatePath, isCookie, isRouteErrorResponse, isSession, json$1 as json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, renderMatches, replace, resolvePath, HistoryRouter as unstable_HistoryRouter, setDevServerHooks as unstable_setDevServerHooks, usePrompt as unstable_usePrompt, useActionData, useAsyncError, useAsyncValue, useBeforeUnload, useBlocker, useFetcher, useFetchers, useFormAction, useHref, useInRouterContext, useLinkClickHandler, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes, useSearchParams, useSubmit, useViewTransitionState };
12698
+ export { Await, BrowserRouter, Form, HashRouter, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, Link, Links, MemoryRouter, Meta, NavLink, Navigate, Action as NavigationType, Outlet, PrefetchPageLinks, Route, Router, RouterProvider, Routes, Scripts, ScrollRestoration, ServerRouter, StaticRouter, StaticRouterProvider, DataRouterContext as UNSAFE_DataRouterContext, DataRouterStateContext as UNSAFE_DataRouterStateContext, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, FetchersContext as UNSAFE_FetchersContext, FrameworkContext as UNSAFE_FrameworkContext, LocationContext as UNSAFE_LocationContext, NavigationContext as UNSAFE_NavigationContext, RemixErrorBoundary as UNSAFE_RemixErrorBoundary, RouteContext as UNSAFE_RouteContext, ServerMode as UNSAFE_ServerMode, SingleFetchRedirectSymbol as UNSAFE_SingleFetchRedirectSymbol, ViewTransitionContext as UNSAFE_ViewTransitionContext, createBrowserHistory as UNSAFE_createBrowserHistory, createClientRoutes as UNSAFE_createClientRoutes, createClientRoutesWithHMRRevalidationOptOut as UNSAFE_createClientRoutesWithHMRRevalidationOptOut, createRouter as UNSAFE_createRouter, decodeViaTurboStream as UNSAFE_decodeViaTurboStream, deserializeErrors as UNSAFE_deserializeErrors, getPatchRoutesOnNavigationFunction as UNSAFE_getPatchRoutesOnNavigationFunction, getSingleFetchDataStrategy$1 as UNSAFE_getSingleFetchDataStrategy, invariant$2 as UNSAFE_invariant, mapRouteProperties as UNSAFE_mapRouteProperties, shouldHydrateRouteLoader as UNSAFE_shouldHydrateRouteLoader, useFogOFWarDiscovery as UNSAFE_useFogOFWarDiscovery, useScrollRestoration as UNSAFE_useScrollRestoration, createBrowserRouter, createCookie, createCookieSessionStorage, createHashRouter, createMemoryRouter, createMemorySessionStorage, createPath, createRequestHandler, createRoutesFromChildren, createRoutesFromChildren as createRoutesFromElements, createRoutesStub, createSearchParams, createSession, createSessionStorage, createStaticHandler, createStaticRouter, data, generatePath, isCookie, isRouteErrorResponse, isSession, matchPath, matchRoutes, parsePath, redirect, redirectDocument, renderMatches, replace, resolvePath, HistoryRouter as unstable_HistoryRouter, setDevServerHooks as unstable_setDevServerHooks, usePrompt as unstable_usePrompt, useActionData, useAsyncError, useAsyncValue, useBeforeUnload, useBlocker, useFetcher, useFetchers, useFormAction, useHref, useInRouterContext, useLinkClickHandler, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes, useSearchParams, useSubmit, useViewTransitionState };
11543
12699
  //# sourceMappingURL=index.mjs.map