react-router 8.4.0 → 8.5.1

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 (233) hide show
  1. package/CHANGELOG.md +94 -1
  2. package/dist/development/dom-export.d.ts +2 -1
  3. package/dist/development/dom-export.js +1 -1
  4. package/dist/development/index-react-server-client.js +2 -2
  5. package/dist/development/index-react-server.d.ts +237 -165
  6. package/dist/development/index-react-server.js +69 -33
  7. package/dist/development/index.d.ts +9 -8
  8. package/dist/development/index.js +5 -4
  9. package/dist/development/lib/actions.js +1 -1
  10. package/dist/development/lib/await.js +58 -0
  11. package/dist/development/lib/components.d.ts +41 -5
  12. package/dist/development/lib/components.js +82 -5
  13. package/dist/development/lib/context.d.ts +8 -3
  14. package/dist/development/lib/context.js +1 -1
  15. package/dist/development/lib/dom/dom.d.ts +3 -0
  16. package/dist/development/lib/dom/dom.js +1 -1
  17. package/dist/development/lib/dom/lib.d.ts +34 -9
  18. package/dist/development/lib/dom/lib.js +17 -6
  19. package/dist/development/lib/dom/server.js +2 -2
  20. package/dist/development/lib/dom/ssr/components.js +12 -9
  21. package/dist/development/lib/dom/ssr/data.js +1 -1
  22. package/dist/development/lib/dom/ssr/entry.d.ts +9 -2
  23. package/dist/development/lib/dom/ssr/errorBoundaries.js +1 -1
  24. package/dist/development/lib/dom/ssr/fallback.js +1 -1
  25. package/dist/development/lib/dom/ssr/fog-of-war.d.ts +3 -2
  26. package/dist/development/lib/dom/ssr/fog-of-war.js +25 -13
  27. package/dist/development/lib/dom/ssr/hydration.js +1 -1
  28. package/dist/development/lib/dom/ssr/invariant.js +1 -1
  29. package/dist/development/lib/dom/ssr/links.js +1 -1
  30. package/dist/development/lib/dom/ssr/markup.js +1 -1
  31. package/dist/development/lib/dom/ssr/route-discovery.d.ts +120 -0
  32. package/dist/development/lib/dom/ssr/route-discovery.js +415 -0
  33. package/dist/development/lib/dom/ssr/routeModules.js +1 -1
  34. package/dist/development/lib/dom/ssr/routes-test-stub.js +2 -2
  35. package/dist/development/lib/dom/ssr/routes.d.ts +2 -2
  36. package/dist/development/lib/dom/ssr/routes.js +8 -8
  37. package/dist/development/lib/dom/ssr/server.js +3 -1
  38. package/dist/development/lib/dom/ssr/single-fetch.d.ts +28 -2
  39. package/dist/development/lib/dom/ssr/single-fetch.js +73 -55
  40. package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
  41. package/dist/development/lib/dom-export/hydrated-router.d.ts +28 -0
  42. package/dist/development/lib/dom-export/hydrated-router.js +32 -12
  43. package/dist/development/lib/errors.js +1 -1
  44. package/dist/development/lib/hooks.d.ts +3 -6
  45. package/dist/development/lib/hooks.js +8 -9
  46. package/dist/development/lib/href.js +1 -1
  47. package/dist/development/lib/router/history.js +1 -1
  48. package/dist/development/lib/router/instrumentation.js +1 -1
  49. package/dist/development/lib/router/matcher-route-pattern.js +1 -1
  50. package/dist/development/lib/router/matcher-route-pattern.preload.js +1 -1
  51. package/dist/development/lib/router/matcher.js +6 -1
  52. package/dist/development/lib/router/navigation.js +1 -1
  53. package/dist/development/lib/router/router.d.ts +8 -0
  54. package/dist/development/lib/router/router.js +213 -91
  55. package/dist/development/lib/router/url.js +1 -1
  56. package/dist/development/lib/router/utils.d.ts +31 -4
  57. package/dist/development/lib/router/utils.js +4 -3
  58. package/dist/development/lib/rsc/browser.js +4 -4
  59. package/dist/development/lib/rsc/errorBoundaries.js +1 -1
  60. package/dist/development/lib/rsc/html-stream/browser.js +1 -1
  61. package/dist/development/lib/rsc/html-stream/server.js +24 -12
  62. package/dist/development/lib/rsc/route-modules.js +1 -1
  63. package/dist/development/lib/rsc/server.rsc.d.ts +3 -2
  64. package/dist/development/lib/rsc/server.ssr.js +1 -1
  65. package/dist/development/lib/server-runtime/build.d.ts +14 -0
  66. package/dist/development/lib/server-runtime/cookies.js +1 -1
  67. package/dist/development/lib/server-runtime/crypto.js +1 -1
  68. package/dist/development/lib/server-runtime/data.js +1 -1
  69. package/dist/development/lib/server-runtime/dev.js +1 -1
  70. package/dist/development/lib/server-runtime/entry.js +1 -1
  71. package/dist/development/lib/server-runtime/errors.js +1 -1
  72. package/dist/development/lib/server-runtime/headers.js +1 -1
  73. package/dist/development/lib/server-runtime/invariant.js +1 -1
  74. package/dist/development/lib/server-runtime/mode.js +1 -1
  75. package/dist/development/lib/server-runtime/routeMatching.js +1 -1
  76. package/dist/development/lib/server-runtime/routes.d.ts +1 -1
  77. package/dist/development/lib/server-runtime/routes.js +1 -1
  78. package/dist/development/lib/server-runtime/server.js +24 -8
  79. package/dist/development/lib/server-runtime/serverHandoff.d.ts +17 -0
  80. package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
  81. package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
  82. package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
  83. package/dist/development/lib/server-runtime/sessions.js +2 -2
  84. package/dist/development/lib/server-runtime/single-fetch.js +1 -1
  85. package/dist/development/lib/server-runtime/urls.js +1 -1
  86. package/dist/development/lib/server-runtime/warnings.js +1 -1
  87. package/dist/development/lib/types/internal.js +1 -1
  88. package/dist/development/lib/types/route-data.d.ts +2 -2
  89. package/dist/development/lib/types/route-module-annotations.d.ts +1 -1
  90. package/dist/development/route-pattern.js +1 -1
  91. package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
  92. package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +1 -1
  93. package/dist/development/vendor/turbo-stream-v2/unflatten.js +23 -3
  94. package/dist/development/vendor/turbo-stream-v2/utils.js +1 -1
  95. package/dist/production/dom-export.d.ts +2 -1
  96. package/dist/production/dom-export.js +1 -1
  97. package/dist/production/index-react-server-client.js +2 -2
  98. package/dist/production/index-react-server.d.ts +237 -165
  99. package/dist/production/index-react-server.js +69 -33
  100. package/dist/production/index.d.ts +9 -8
  101. package/dist/production/index.js +5 -4
  102. package/dist/production/lib/actions.js +1 -1
  103. package/dist/production/lib/await.js +58 -0
  104. package/dist/production/lib/components.d.ts +41 -5
  105. package/dist/production/lib/components.js +82 -5
  106. package/dist/production/lib/context.d.ts +8 -3
  107. package/dist/production/lib/context.js +1 -1
  108. package/dist/production/lib/dom/dom.d.ts +3 -0
  109. package/dist/production/lib/dom/dom.js +1 -1
  110. package/dist/production/lib/dom/lib.d.ts +34 -9
  111. package/dist/production/lib/dom/lib.js +17 -6
  112. package/dist/production/lib/dom/server.js +2 -2
  113. package/dist/production/lib/dom/ssr/components.js +12 -9
  114. package/dist/production/lib/dom/ssr/data.js +1 -1
  115. package/dist/production/lib/dom/ssr/entry.d.ts +9 -2
  116. package/dist/production/lib/dom/ssr/errorBoundaries.js +1 -1
  117. package/dist/production/lib/dom/ssr/fallback.js +1 -1
  118. package/dist/production/lib/dom/ssr/fog-of-war.d.ts +3 -2
  119. package/dist/production/lib/dom/ssr/fog-of-war.js +25 -13
  120. package/dist/production/lib/dom/ssr/hydration.js +1 -1
  121. package/dist/production/lib/dom/ssr/invariant.js +1 -1
  122. package/dist/production/lib/dom/ssr/links.js +1 -1
  123. package/dist/production/lib/dom/ssr/markup.js +1 -1
  124. package/dist/production/lib/dom/ssr/route-discovery.d.ts +120 -0
  125. package/dist/production/lib/dom/ssr/route-discovery.js +415 -0
  126. package/dist/production/lib/dom/ssr/routeModules.js +1 -1
  127. package/dist/production/lib/dom/ssr/routes-test-stub.js +2 -2
  128. package/dist/production/lib/dom/ssr/routes.d.ts +2 -2
  129. package/dist/production/lib/dom/ssr/routes.js +8 -8
  130. package/dist/production/lib/dom/ssr/server.js +3 -1
  131. package/dist/production/lib/dom/ssr/single-fetch.d.ts +28 -2
  132. package/dist/production/lib/dom/ssr/single-fetch.js +73 -55
  133. package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
  134. package/dist/production/lib/dom-export/hydrated-router.d.ts +28 -0
  135. package/dist/production/lib/dom-export/hydrated-router.js +32 -12
  136. package/dist/production/lib/errors.js +1 -1
  137. package/dist/production/lib/hooks.d.ts +3 -6
  138. package/dist/production/lib/hooks.js +7 -8
  139. package/dist/production/lib/href.js +1 -1
  140. package/dist/production/lib/router/history.js +1 -1
  141. package/dist/production/lib/router/instrumentation.js +1 -1
  142. package/dist/production/lib/router/matcher-route-pattern.js +1 -1
  143. package/dist/production/lib/router/matcher-route-pattern.preload.js +1 -1
  144. package/dist/production/lib/router/matcher.js +6 -1
  145. package/dist/production/lib/router/navigation.js +1 -1
  146. package/dist/production/lib/router/router.d.ts +8 -0
  147. package/dist/production/lib/router/router.js +213 -91
  148. package/dist/production/lib/router/url.js +1 -1
  149. package/dist/production/lib/router/utils.d.ts +31 -4
  150. package/dist/production/lib/router/utils.js +4 -3
  151. package/dist/production/lib/rsc/browser.js +4 -4
  152. package/dist/production/lib/rsc/errorBoundaries.js +1 -1
  153. package/dist/production/lib/rsc/html-stream/browser.js +1 -1
  154. package/dist/production/lib/rsc/html-stream/server.js +24 -12
  155. package/dist/production/lib/rsc/route-modules.js +1 -1
  156. package/dist/production/lib/rsc/server.rsc.d.ts +3 -2
  157. package/dist/production/lib/rsc/server.ssr.js +1 -1
  158. package/dist/production/lib/server-runtime/build.d.ts +14 -0
  159. package/dist/production/lib/server-runtime/cookies.js +1 -1
  160. package/dist/production/lib/server-runtime/crypto.js +1 -1
  161. package/dist/production/lib/server-runtime/data.js +1 -1
  162. package/dist/production/lib/server-runtime/dev.js +1 -1
  163. package/dist/production/lib/server-runtime/entry.js +1 -1
  164. package/dist/production/lib/server-runtime/errors.js +1 -1
  165. package/dist/production/lib/server-runtime/headers.js +1 -1
  166. package/dist/production/lib/server-runtime/invariant.js +1 -1
  167. package/dist/production/lib/server-runtime/mode.js +1 -1
  168. package/dist/production/lib/server-runtime/routeMatching.js +1 -1
  169. package/dist/production/lib/server-runtime/routes.d.ts +1 -1
  170. package/dist/production/lib/server-runtime/routes.js +1 -1
  171. package/dist/production/lib/server-runtime/server.js +24 -8
  172. package/dist/production/lib/server-runtime/serverHandoff.d.ts +17 -0
  173. package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
  174. package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
  175. package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
  176. package/dist/production/lib/server-runtime/sessions.js +2 -2
  177. package/dist/production/lib/server-runtime/single-fetch.js +1 -1
  178. package/dist/production/lib/server-runtime/urls.js +1 -1
  179. package/dist/production/lib/server-runtime/warnings.js +1 -1
  180. package/dist/production/lib/types/internal.js +1 -1
  181. package/dist/production/lib/types/route-data.d.ts +2 -2
  182. package/dist/production/lib/types/route-module-annotations.d.ts +1 -1
  183. package/dist/production/route-pattern.js +1 -1
  184. package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
  185. package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +1 -1
  186. package/dist/production/vendor/turbo-stream-v2/unflatten.js +23 -3
  187. package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
  188. package/docs/explanation/backend-for-frontend.md +0 -3
  189. package/docs/explanation/code-splitting.md +0 -3
  190. package/docs/explanation/concurrency.md +0 -3
  191. package/docs/explanation/hot-module-replacement.md +0 -3
  192. package/docs/explanation/lazy-route-discovery.md +4 -3
  193. package/docs/explanation/progressive-enhancement.md +0 -3
  194. package/docs/explanation/race-conditions.md +0 -3
  195. package/docs/explanation/react-transitions.md +0 -3
  196. package/docs/explanation/sessions-and-cookies.md +109 -5
  197. package/docs/explanation/state-management.md +0 -3
  198. package/docs/explanation/styling.md +0 -3
  199. package/docs/explanation/type-safety.md +0 -3
  200. package/docs/how-to/accessibility.md +0 -6
  201. package/docs/how-to/client-data.md +0 -3
  202. package/docs/how-to/custom-fetch.md +218 -0
  203. package/docs/how-to/data-strategy.md +23 -4
  204. package/docs/how-to/error-boundary.md +0 -3
  205. package/docs/how-to/error-reporting.md +0 -3
  206. package/docs/how-to/fetchers.md +0 -3
  207. package/docs/how-to/file-route-conventions.md +0 -3
  208. package/docs/how-to/file-uploads.md +0 -3
  209. package/docs/how-to/form-validation.md +0 -3
  210. package/docs/how-to/headers.md +0 -3
  211. package/docs/how-to/instrumentation.md +0 -3
  212. package/docs/how-to/middleware.md +7 -3
  213. package/docs/how-to/navigation-blocking.md +0 -3
  214. package/docs/how-to/optimize-revalidation.md +2 -5
  215. package/docs/how-to/pre-rendering.md +23 -4
  216. package/docs/how-to/presets.md +0 -3
  217. package/docs/how-to/react-server-components.md +0 -3
  218. package/docs/how-to/resource-routes.md +0 -3
  219. package/docs/how-to/route-discovery.md +147 -0
  220. package/docs/how-to/route-module-type-safety.md +0 -3
  221. package/docs/how-to/security.md +0 -3
  222. package/docs/how-to/server-bundles.md +0 -3
  223. package/docs/how-to/spa.md +2 -3
  224. package/docs/how-to/status.md +0 -3
  225. package/docs/how-to/suspense.md +22 -6
  226. package/docs/how-to/using-handle.md +0 -3
  227. package/docs/how-to/view-transitions.md +79 -15
  228. package/docs/start/framework/data-loading.md +9 -0
  229. package/docs/start/framework/navigating.md +5 -9
  230. package/docs/start/framework/rendering.md +37 -0
  231. package/docs/upgrading/future.md +0 -12
  232. package/docs/upgrading/v7.md +3 -33
  233. package/package.json +9 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -27,7 +27,13 @@ function getPathsWithAncestors(paths) {
27
27
  return Array.from(result);
28
28
  }
29
29
  function isFogOfWarEnabled(routeDiscovery, ssr) {
30
- return routeDiscovery.mode === "lazy" && ssr === true;
30
+ return routeDiscovery.mode === "lazy" && ssr;
31
+ }
32
+ const MANIFEST_MATCH_COST_LIMIT = 5e4;
33
+ const MANIFEST_MATCH_COST_SEGMENT_THRESHOLD = 10;
34
+ function shouldUseInitialRouteDiscovery(pathname, matchCost = 0) {
35
+ let segmentCount = pathname.split("/").length - 1;
36
+ return Math.max(segmentCount - 1, 0) * pathname.length + 1 > 7680 || segmentCount > MANIFEST_MATCH_COST_SEGMENT_THRESHOLD && segmentCount * matchCost > MANIFEST_MATCH_COST_LIMIT;
31
37
  }
32
38
  function getPartialManifest({ sri, ...manifest }, router) {
33
39
  let routeIds = new Set(router.state.matches.map((m) => m.route.id));
@@ -49,15 +55,15 @@ function getPartialManifest({ sri, ...manifest }, router) {
49
55
  sri: sri ? true : void 0
50
56
  };
51
57
  }
52
- function getPatchRoutesOnNavigationFunction(getRouter, manifest, routeModules, ssr, routeDiscovery, isSpaMode, basename) {
58
+ function getPatchRoutesOnNavigationFunction(getRouter, manifest, routeModules, ssr, routeDiscovery, isSpaMode, basename, fetchImplementation = (request) => fetch(request), serverOrigin, isApiOnly = false) {
53
59
  if (!isFogOfWarEnabled(routeDiscovery, ssr)) return;
54
60
  return async ({ path, patch, signal, fetcherKey }) => {
55
61
  if (discoveredPaths.has(path)) return;
56
62
  let { state } = getRouter();
57
- await fetchAndApplyManifestPatches([path], fetcherKey ? window.location.href : createPath(state.navigation.location || state.location), manifest, routeModules, ssr, isSpaMode, basename, routeDiscovery.manifestPath, patch, signal);
63
+ await fetchAndApplyManifestPatches([path], fetcherKey ? window.location.href : createPath(state.navigation.location || state.location), manifest, routeModules, ssr, isSpaMode, basename, routeDiscovery.manifestPath, patch, signal, fetchImplementation, serverOrigin, isApiOnly);
58
64
  };
59
65
  }
60
- function useFogOFWarDiscovery(router, manifest, routeModules, ssr, routeDiscovery, isSpaMode) {
66
+ function useFogOFWarDiscovery(router, manifest, routeModules, ssr, routeDiscovery, isSpaMode, fetchImplementation = (request) => fetch(request), serverOrigin, isApiOnly = false) {
61
67
  React$1.useEffect(() => {
62
68
  if (!isFogOfWarEnabled(routeDiscovery, ssr) || window.navigator?.connection?.saveData === true) return;
63
69
  function registerElement(el) {
@@ -77,7 +83,7 @@ function useFogOFWarDiscovery(router, manifest, routeModules, ssr, routeDiscover
77
83
  });
78
84
  if (lazyPaths.length === 0) return;
79
85
  try {
80
- await fetchAndApplyManifestPatches(lazyPaths, null, manifest, routeModules, ssr, isSpaMode, router.basename, routeDiscovery.manifestPath, router.patchRoutes);
86
+ await fetchAndApplyManifestPatches(lazyPaths, null, manifest, routeModules, ssr, isSpaMode, router.basename, routeDiscovery.manifestPath, router.patchRoutes, void 0, fetchImplementation, serverOrigin, isApiOnly);
81
87
  } catch (e) {
82
88
  console.error("Failed to fetch manifest patches", e);
83
89
  }
@@ -102,9 +108,15 @@ function useFogOFWarDiscovery(router, manifest, routeModules, ssr, routeDiscover
102
108
  manifest,
103
109
  routeModules,
104
110
  router,
105
- routeDiscovery
111
+ routeDiscovery,
112
+ fetchImplementation,
113
+ serverOrigin,
114
+ isApiOnly
106
115
  ]);
107
116
  }
117
+ function getManifestPathsParam(paths) {
118
+ return paths.slice().sort().map((path) => path.replace(/,/g, "%2C")).join(",");
119
+ }
108
120
  function getManifestPath(_manifestPath, basename) {
109
121
  let manifestPath = _manifestPath || "/__manifest";
110
122
  return basename == null ? manifestPath : joinPaths([basename, manifestPath]);
@@ -154,12 +166,12 @@ async function handleClientVersionMismatch(needsReload, version, errorReloadPath
154
166
  }
155
167
  return reloadPromise;
156
168
  }
157
- async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal) {
169
+ async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal, fetchImplementation = (request) => fetch(request), serverOrigin, isApiOnly = false) {
158
170
  paths = getPathsWithAncestors(paths);
159
171
  const searchParams = new URLSearchParams();
160
- searchParams.set("paths", paths.sort().join(","));
172
+ searchParams.set("paths", getManifestPathsParam(paths));
161
173
  searchParams.set("version", manifest.version);
162
- let url = new URL(getManifestPath(manifestPath, basename), window.location.origin);
174
+ let url = new URL(getManifestPath(manifestPath, basename), serverOrigin ?? window.location.origin);
163
175
  url.search = searchParams.toString();
164
176
  if (url.toString().length > 7680) {
165
177
  nextPaths.clear();
@@ -167,7 +179,7 @@ async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, ro
167
179
  }
168
180
  let serverPatches;
169
181
  try {
170
- let res = await fetch(url, { signal });
182
+ let res = await fetchImplementation(new Request(url, { signal }), { type: "manifest" });
171
183
  if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
172
184
  if (await handleClientVersionMismatch(res.status === 204 && res.headers.has("X-Remix-Reload-Document"), manifest.version, errorReloadPath)) return;
173
185
  serverPatches = await res.json();
@@ -187,7 +199,7 @@ async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, ro
187
199
  Object.values(patches).forEach((patch) => {
188
200
  if (patch && (!patch.parentId || !patches[patch.parentId])) parentIds.add(patch.parentId);
189
201
  });
190
- parentIds.forEach((parentId) => patchRoutes(parentId || null, createClientRoutes(patches, routeModules, null, ssr, isSpaMode, parentId)));
202
+ parentIds.forEach((parentId) => patchRoutes(parentId || null, createClientRoutes(patches, routeModules, null, ssr, isSpaMode, parentId, void 0, void 0, isApiOnly)));
191
203
  }
192
204
  function addToFifoQueue(path, queue) {
193
205
  if (queue.size >= discoveredPathsMaxSize) {
@@ -204,4 +216,4 @@ function debounce(callback, wait) {
204
216
  };
205
217
  }
206
218
  //#endregion
207
- export { URL_LIMIT, getManifestPath, getPartialManifest, getPatchRoutesOnNavigationFunction, getPathsWithAncestors, handleClientVersionMismatch, isFogOfWarEnabled, useFogOFWarDiscovery };
219
+ export { URL_LIMIT, getManifestPath, getManifestPathsParam, getPartialManifest, getPatchRoutesOnNavigationFunction, getPathsWithAncestors, handleClientVersionMismatch, isFogOfWarEnabled, shouldUseInitialRouteDiscovery, useFogOFWarDiscovery };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -0,0 +1,120 @@
1
+
2
+ import { PatchRoutesOnNavigationFunction, RouteObject } from "../../router/utils.js";
3
+ import { Router } from "../../router/router.js";
4
+ import { ClientOnErrorFunction } from "../../components.js";
5
+ import { RouteModules } from "./routeModules.js";
6
+ import { RouterFetch } from "./single-fetch.js";
7
+ import { ServerHandoff } from "../../server-runtime/serverHandoff.js";
8
+ import { AssetsManifest } from "./entry.js";
9
+
10
+ //#region lib/dom/ssr/route-discovery.d.ts
11
+ /** A discovery response from a different build. */
12
+ type ManifestMismatchEvent = {
13
+ source: "eager" | "navigation" | "fetcher" | "imperative";
14
+ version: string;
15
+ reloadUrl: string | null;
16
+ loadAllRoutes(): Promise<void>;
17
+ stopPropagation(): void; /** Run built-in recovery for this source, at most once per mismatch event. */
18
+ defaultBehavior(): Promise<void>;
19
+ };
20
+ /** The result of imperative route discovery. */
21
+ type DiscoveryResult = {
22
+ type: "success";
23
+ } | {
24
+ type: "version-mismatch";
25
+ } | {
26
+ type: "aborted";
27
+ };
28
+ /** Options for {@link unstable_useRouteDiscovery}. */
29
+ type RouteDiscoveryOptions = {
30
+ onManifestMismatch?: (event: ManifestMismatchEvent) => void | Promise<void>;
31
+ };
32
+ type Registration = {
33
+ current: RouteDiscoveryOptions;
34
+ };
35
+ type DiscoveryState = "partial" | "loading" | "complete";
36
+ type RouteDiscoverySsrInfo = {
37
+ manifest: AssetsManifest;
38
+ routeModules: RouteModules;
39
+ router: Router | undefined;
40
+ context: Pick<ServerHandoff, "ssr" | "routeDiscovery" | "isSpaMode" | "basename" | "unstable_apiServerOrigin" | "unstable_apiOnly">;
41
+ };
42
+ declare class RouteDiscoveryRuntime {
43
+ private ssrInfo;
44
+ readonly enabled: boolean;
45
+ readonly discoveredPaths: Set<string>;
46
+ readonly nextPaths: Set<string>;
47
+ state: DiscoveryState;
48
+ ready: boolean;
49
+ private registrations;
50
+ private listeners;
51
+ private fullLoadErrorListeners;
52
+ private fullLoad?;
53
+ private loadedManifest?;
54
+ private mismatch?;
55
+ private fetchImplementation;
56
+ private loadManifest;
57
+ onError?: ClientOnErrorFunction;
58
+ constructor(ssrInfo: RouteDiscoverySsrInfo, {
59
+ fetch: fetchImplementation,
60
+ loadManifest
61
+ }?: {
62
+ fetch?: RouterFetch;
63
+ loadManifest?: () => Promise<AssetsManifest>;
64
+ });
65
+ private get router();
66
+ private loadManifestAsset;
67
+ subscribe: (listener: () => void) => () => void;
68
+ private update;
69
+ markReady: () => void;
70
+ register(registration: Registration): () => void;
71
+ private isComplete;
72
+ loadAllRoutes: () => Promise<void>;
73
+ reportError(error: unknown): void;
74
+ private dispatchMismatch;
75
+ private requestUrl;
76
+ discoverRoutes: (paths: string[], options?: {
77
+ signal?: AbortSignal;
78
+ }) => Promise<DiscoveryResult>;
79
+ discover(paths: string[], source: ManifestMismatchEvent["source"], reloadUrl: string | null, signal?: AbortSignal, patch?: (routeId: string | null, children: RouteObject[], unstable_allowElementMutations?: boolean) => void): Promise<DiscoveryResult>;
80
+ }
81
+ /**
82
+ * Control lazy route discovery in Framework Mode with `future.unstable_customRouteDiscovery`
83
+ * enabled. This allows you to imperatively discover routes as well as add custom behavior
84
+ * when a manifest version mismatch is detected. Calling `loadAllRoutes` will load the entire
85
+ * route manifest for the current (potentially stale) client version - this requires that prior
86
+ * client artifacts are still available on your CDN _and_ you have not made breaking changes to
87
+ * the API contracts of your loaders and actions.
88
+ *
89
+ * See the [Route Discovery guide](../../how-to/route-discovery) for more information and examples.
90
+ *
91
+ * @example
92
+ * let { state, discoverRoutes, loadAllRoutes } = unstable_useRouteDiscovery({
93
+ * onManifestMismatch: async (event) => {
94
+ * // Eagerly load the complete route tree for this client without requiring a hard reload
95
+ * await event.loadAllRoutes();
96
+ * },
97
+ * });
98
+ *
99
+ * // Eagerly discover specific routes
100
+ * discoverRoutes(["/a", "/b"]);
101
+ *
102
+ * @name unstable_useRouteDiscovery
103
+ * @public
104
+ * @category Hooks
105
+ * @mode framework
106
+ * @param options An awaited manifest-mismatch handler.
107
+ * @returns The client version, full-manifest loading state, and discovery operations.
108
+ */
109
+ declare function useRouteDiscovery(options?: RouteDiscoveryOptions): {
110
+ version: string;
111
+ state: DiscoveryState;
112
+ loadAllRoutes: () => Promise<void>;
113
+ discoverRoutes: (paths: string[], options?: {
114
+ signal?: AbortSignal;
115
+ }) => Promise<DiscoveryResult>;
116
+ };
117
+ declare function getCustomPatchRoutesOnNavigationFunction(getRouter: () => Router, runtime: RouteDiscoveryRuntime): PatchRoutesOnNavigationFunction | undefined;
118
+ declare function useCustomRouteDiscovery(runtime: RouteDiscoveryRuntime, onError?: ClientOnErrorFunction): "partial" | "loading" | "complete";
119
+ //#endregion
120
+ export { DiscoveryResult, DiscoveryState, ManifestMismatchEvent, RouteDiscoveryOptions, RouteDiscoveryRuntime, getCustomPatchRoutesOnNavigationFunction, useCustomRouteDiscovery, useRouteDiscovery };
@@ -0,0 +1,415 @@
1
+ /**
2
+ * react-router v8.5.1
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import { createPath, invariant } from "../../router/history.js";
12
+ import { DiscoveryCancelledError, getRoutePattern, prependBasename } from "../../router/utils.js";
13
+ import { createClientRoutes } from "./routes.js";
14
+ import { getManifestPath, getManifestPathsParam, getPathsWithAncestors, handleClientVersionMismatch, isFogOfWarEnabled } from "./fog-of-war.js";
15
+ import { useFrameworkContext } from "./components.js";
16
+ import * as React$1 from "react";
17
+ //#region lib/dom/ssr/route-discovery.ts
18
+ var RouteDiscoveryRuntime = class {
19
+ ssrInfo;
20
+ enabled;
21
+ discoveredPaths = /* @__PURE__ */ new Set();
22
+ nextPaths = /* @__PURE__ */ new Set();
23
+ state;
24
+ ready = false;
25
+ registrations = /* @__PURE__ */ new Set();
26
+ listeners = /* @__PURE__ */ new Set();
27
+ fullLoadErrorListeners = /* @__PURE__ */ new Set();
28
+ fullLoad;
29
+ loadedManifest;
30
+ mismatch;
31
+ fetchImplementation;
32
+ loadManifest;
33
+ onError;
34
+ constructor(ssrInfo, { fetch: fetchImplementation = (request) => fetch(request), loadManifest } = {}) {
35
+ this.ssrInfo = ssrInfo;
36
+ this.fetchImplementation = fetchImplementation;
37
+ this.loadManifest = loadManifest ?? (() => this.loadManifestAsset());
38
+ let { manifest, context } = ssrInfo;
39
+ this.enabled = isFogOfWarEnabled(context.routeDiscovery, context.ssr);
40
+ this.state = this.enabled && !manifest.hmr ? "partial" : "complete";
41
+ }
42
+ get router() {
43
+ invariant(this.ssrInfo.router, "Router unavailable for route discovery");
44
+ return this.ssrInfo.router;
45
+ }
46
+ async loadManifestAsset() {
47
+ let { manifest } = this.ssrInfo;
48
+ if (this.loadedManifest) return this.loadedManifest;
49
+ try {
50
+ await import(
51
+ /* @vite-ignore */
52
+ /* webpackIgnore: true */
53
+ manifest.url
54
+ );
55
+ invariant(window.__reactRouterManifest, "Unable to load the client manifest");
56
+ invariant(window.__reactRouterManifest !== manifest, "The full route manifest asset did not provide a manifest.");
57
+ this.loadedManifest = window.__reactRouterManifest;
58
+ return this.loadedManifest;
59
+ } finally {
60
+ window.__reactRouterManifest = manifest;
61
+ }
62
+ }
63
+ subscribe = (listener) => {
64
+ this.listeners.add(listener);
65
+ return () => {
66
+ this.listeners.delete(listener);
67
+ };
68
+ };
69
+ update(state, ready = this.ready) {
70
+ this.state = state;
71
+ this.ready = ready;
72
+ this.listeners.forEach((listener) => listener());
73
+ }
74
+ markReady = () => {
75
+ if (!this.ready) this.update(this.state, true);
76
+ };
77
+ register(registration) {
78
+ this.registrations.add(registration);
79
+ return () => {
80
+ this.registrations.delete(registration);
81
+ };
82
+ }
83
+ isComplete() {
84
+ return this.state === "complete";
85
+ }
86
+ loadAllRoutes = () => {
87
+ if (this.isComplete()) return Promise.resolve();
88
+ if (this.fullLoad) return this.fullLoad;
89
+ let { manifest, routeModules, context } = this.ssrInfo;
90
+ this.fullLoad = Promise.resolve().then(async () => {
91
+ try {
92
+ let fullManifest = await this.loadManifest();
93
+ invariant(fullManifest.version === manifest.version, "The full route manifest does not match the running client version.");
94
+ applyManifestPatches(fullManifest.routes, manifest, routeModules, context.ssr, context.isSpaMode, this.router.patchRoutes, context.unstable_apiOnly === true);
95
+ this.nextPaths.clear();
96
+ this.update("complete");
97
+ } catch (error) {
98
+ this.fullLoadErrorListeners.forEach((listener) => listener(error));
99
+ this.update("partial");
100
+ throw error;
101
+ } finally {
102
+ this.fullLoad = void 0;
103
+ }
104
+ });
105
+ this.update("loading");
106
+ return this.fullLoad;
107
+ };
108
+ reportError(error) {
109
+ if (this.onError) {
110
+ let { location, matches } = this.router.state;
111
+ this.onError(error, {
112
+ location,
113
+ params: matches[0]?.params || {},
114
+ pattern: getRoutePattern(matches)
115
+ });
116
+ } else console.error(error);
117
+ }
118
+ async dispatchMismatch(source, reloadUrl) {
119
+ let { version } = this.ssrInfo.manifest;
120
+ let stopped = false;
121
+ let defaultBehavior;
122
+ let event = {
123
+ source,
124
+ reloadUrl,
125
+ version,
126
+ stopPropagation() {
127
+ stopped = true;
128
+ },
129
+ loadAllRoutes: this.loadAllRoutes,
130
+ defaultBehavior: () => {
131
+ defaultBehavior ??= Promise.resolve().then(async () => {
132
+ if (source !== "imperative" && !this.isComplete()) await handleClientVersionMismatch(true, version, reloadUrl);
133
+ });
134
+ return defaultBehavior;
135
+ }
136
+ };
137
+ let registrations = [...this.registrations].reverse().filter((registration) => registration.current.onManifestMismatch);
138
+ if (registrations.length === 0) return event.defaultBehavior();
139
+ let loadErrors = /* @__PURE__ */ new Set();
140
+ let onLoadError = (error) => loadErrors.add(error);
141
+ this.fullLoadErrorListeners.add(onLoadError);
142
+ try {
143
+ for (let registration of registrations) {
144
+ if (!this.registrations.has(registration)) continue;
145
+ try {
146
+ await registration.current.onManifestMismatch?.(event);
147
+ } catch (error) {
148
+ if (!loadErrors.has(error)) throw error;
149
+ this.reportError(error);
150
+ break;
151
+ }
152
+ if (stopped) break;
153
+ }
154
+ } finally {
155
+ this.fullLoadErrorListeners.delete(onLoadError);
156
+ }
157
+ }
158
+ requestUrl(paths) {
159
+ let { manifest, context } = this.ssrInfo;
160
+ let params = new URLSearchParams();
161
+ params.set("paths", getManifestPathsParam(paths));
162
+ params.set("version", manifest.version);
163
+ let url = new URL(getManifestPath(context.routeDiscovery.manifestPath, context.basename), context.unstable_apiServerOrigin ?? window.location.origin);
164
+ url.search = params.toString();
165
+ return url;
166
+ }
167
+ discoverRoutes = async (paths, options = {}) => {
168
+ if (options.signal?.aborted) return { type: "aborted" };
169
+ if (this.isComplete()) return { type: "success" };
170
+ let pathnames = paths.map((path) => {
171
+ invariant(path.startsWith("/") && !path.startsWith("//") && !path.includes("\\"), "discoverRoutes expects application-root paths beginning with a single '/'.");
172
+ return prependBasename({
173
+ pathname: new URL(path, window.location.origin).pathname,
174
+ basename: this.ssrInfo.context.basename || "/"
175
+ });
176
+ });
177
+ return this.discover(pathnames, "imperative", null, options.signal);
178
+ };
179
+ async discover(paths, source, reloadUrl, signal, patch = this.router.patchRoutes) {
180
+ let { manifest, routeModules, context } = this.ssrInfo;
181
+ if (signal?.aborted) return { type: "aborted" };
182
+ if (this.isComplete()) return { type: "success" };
183
+ let pending = getPathsWithAncestors(paths.filter((path) => !this.discoveredPaths.has(path)));
184
+ if (!pending.length) return { type: "success" };
185
+ let batches = [];
186
+ if (source !== "imperative") {
187
+ if (this.requestUrl(pending).href.length > 7680) {
188
+ this.nextPaths.clear();
189
+ return { type: "success" };
190
+ }
191
+ batches.push(pending);
192
+ } else {
193
+ let batch = [];
194
+ for (let path of pending) {
195
+ if (this.discoveredPaths.has(path)) continue;
196
+ if (this.requestUrl([path]).href.length > 7680) {
197
+ console.warn(`Unable to discover path exceeding the manifest request URL limit: ${path}`);
198
+ continue;
199
+ }
200
+ if (this.requestUrl([...batch, path]).href.length > 7680) {
201
+ batches.push(batch);
202
+ batch = [];
203
+ }
204
+ batch.push(path);
205
+ }
206
+ if (batch.length) batches.push(batch);
207
+ }
208
+ for (let batch of batches) try {
209
+ if (signal?.aborted) return { type: "aborted" };
210
+ if (this.isComplete()) return { type: "success" };
211
+ let response;
212
+ try {
213
+ response = await this.fetchImplementation(new Request(this.requestUrl(batch), { signal }), { type: "manifest" });
214
+ } catch (error) {
215
+ if (signal?.aborted) return { type: "aborted" };
216
+ if (this.isComplete()) return { type: "success" };
217
+ throw error;
218
+ }
219
+ if (signal?.aborted) return { type: "aborted" };
220
+ if (this.isComplete()) return { type: "success" };
221
+ if (!response.ok) throw new Error(`${response.status} ${response.statusText}`);
222
+ if (response.status === 204 && response.headers.has("X-Remix-Reload-Document")) {
223
+ if (this.mismatch || [...this.registrations].some((r) => r.current.onManifestMismatch)) {
224
+ if (!this.mismatch) this.mismatch = Promise.resolve().then(() => this.dispatchMismatch(source, reloadUrl)).finally(() => {
225
+ this.mismatch = void 0;
226
+ });
227
+ await waitForDiscovery(this.mismatch, signal);
228
+ } else await waitForDiscovery(this.dispatchMismatch(source, reloadUrl), signal);
229
+ if (signal?.aborted) return { type: "aborted" };
230
+ return { type: this.isComplete() ? "success" : "version-mismatch" };
231
+ }
232
+ await handleClientVersionMismatch(false, manifest.version, reloadUrl);
233
+ let patches;
234
+ try {
235
+ patches = await response.json();
236
+ } catch (error) {
237
+ if (signal?.aborted) return { type: "aborted" };
238
+ if (this.isComplete()) return { type: "success" };
239
+ throw error;
240
+ }
241
+ if (signal?.aborted) return { type: "aborted" };
242
+ if (this.isComplete()) return { type: "success" };
243
+ applyManifestPatches(patches, manifest, routeModules, context.ssr, context.isSpaMode, patch, context.unstable_apiOnly === true);
244
+ batch.forEach((path) => {
245
+ if (this.discoveredPaths.size >= 1e3) this.discoveredPaths.delete(this.discoveredPaths.values().next().value);
246
+ this.discoveredPaths.add(path);
247
+ });
248
+ } catch (error) {
249
+ if (signal?.aborted) return { type: "aborted" };
250
+ throw error;
251
+ }
252
+ return { type: "success" };
253
+ }
254
+ };
255
+ function waitForDiscovery(promise, signal) {
256
+ return new Promise((resolve, reject) => {
257
+ let abort = () => resolve();
258
+ signal?.addEventListener("abort", abort, { once: true });
259
+ if (signal?.aborted) abort();
260
+ promise.then(() => resolve(), reject).finally(() => signal?.removeEventListener("abort", abort));
261
+ });
262
+ }
263
+ const serverLoad = () => Promise.resolve();
264
+ const serverDiscover = async () => ({ type: "success" });
265
+ /**
266
+ * Control lazy route discovery in Framework Mode with `future.unstable_customRouteDiscovery`
267
+ * enabled. This allows you to imperatively discover routes as well as add custom behavior
268
+ * when a manifest version mismatch is detected. Calling `loadAllRoutes` will load the entire
269
+ * route manifest for the current (potentially stale) client version - this requires that prior
270
+ * client artifacts are still available on your CDN _and_ you have not made breaking changes to
271
+ * the API contracts of your loaders and actions.
272
+ *
273
+ * See the [Route Discovery guide](../../how-to/route-discovery) for more information and examples.
274
+ *
275
+ * @example
276
+ * let { state, discoverRoutes, loadAllRoutes } = unstable_useRouteDiscovery({
277
+ * onManifestMismatch: async (event) => {
278
+ * // Eagerly load the complete route tree for this client without requiring a hard reload
279
+ * await event.loadAllRoutes();
280
+ * },
281
+ * });
282
+ *
283
+ * // Eagerly discover specific routes
284
+ * discoverRoutes(["/a", "/b"]);
285
+ *
286
+ * @name unstable_useRouteDiscovery
287
+ * @public
288
+ * @category Hooks
289
+ * @mode framework
290
+ * @param options An awaited manifest-mismatch handler.
291
+ * @returns The client version, full-manifest loading state, and discovery operations.
292
+ */
293
+ function useRouteDiscovery(options = {}) {
294
+ let context = useFrameworkContext();
295
+ invariant(context.future.unstable_customRouteDiscovery, "unstable_useRouteDiscovery requires future.unstable_customRouteDiscovery to be enabled in react-router.config.ts.");
296
+ invariant(context.manifest.url, "unstable_useRouteDiscovery is not supported in RSC mode.");
297
+ let runtime = context.routeDiscoveryRuntime;
298
+ let registration = React$1.useRef({ current: options });
299
+ let hasHandlers = Boolean(options.onManifestMismatch);
300
+ React$1.useLayoutEffect(() => {
301
+ registration.current.current = options;
302
+ });
303
+ React$1.useLayoutEffect(() => {
304
+ if (hasHandlers) return runtime?.register(registration.current);
305
+ }, [runtime, hasHandlers]);
306
+ let state = context.routeDiscoveryState ?? (isFogOfWarEnabled(context.routeDiscovery, context.ssr) && !context.manifest.hmr ? "partial" : "complete");
307
+ return {
308
+ version: context.manifest.version,
309
+ state,
310
+ loadAllRoutes: runtime?.loadAllRoutes || serverLoad,
311
+ discoverRoutes: runtime?.discoverRoutes || serverDiscover
312
+ };
313
+ }
314
+ function getCustomPatchRoutesOnNavigationFunction(getRouter, runtime) {
315
+ if (!runtime.enabled) return;
316
+ return async ({ path, patch, signal, fetcherKey }) => {
317
+ let { state } = getRouter();
318
+ if ((await runtime.discover([path], fetcherKey != null ? "fetcher" : "navigation", fetcherKey != null ? window.location.href : createPath(state.navigation.location || state.location), signal, patch)).type === "version-mismatch") throw new DiscoveryCancelledError();
319
+ };
320
+ }
321
+ function useCustomRouteDiscovery(runtime, onError) {
322
+ React$1.useLayoutEffect(() => {
323
+ runtime.onError = onError;
324
+ }, [runtime, onError]);
325
+ let [state, setState] = React$1.useState(runtime.state);
326
+ React$1.useLayoutEffect(() => {
327
+ let updateState = () => {
328
+ let nextState = runtime.state;
329
+ React$1.startTransition(() => setState(nextState));
330
+ };
331
+ let unsubscribe = runtime.subscribe(updateState);
332
+ updateState();
333
+ return unsubscribe;
334
+ }, [runtime]);
335
+ React$1.useEffect(() => {
336
+ if (!runtime.enabled || window.navigator?.connection?.saveData === true) return;
337
+ let { discoveredPaths, nextPaths } = runtime;
338
+ function registerElement(el) {
339
+ let path = el.tagName === "FORM" ? el.getAttribute("action") : el.getAttribute("href");
340
+ if (!path) return;
341
+ let pathname = el.tagName === "A" ? el.pathname : new URL(path, window.location.origin).pathname;
342
+ if (!discoveredPaths.has(pathname)) nextPaths.add(pathname);
343
+ }
344
+ let active = false;
345
+ async function fetchPatches() {
346
+ if (!active || runtime.state === "complete") return;
347
+ document.querySelectorAll("a[data-discover], form[data-discover]").forEach(registerElement);
348
+ let lazyPaths = Array.from(nextPaths.keys()).filter((path) => {
349
+ if (discoveredPaths.has(path)) {
350
+ nextPaths.delete(path);
351
+ return false;
352
+ }
353
+ return true;
354
+ });
355
+ if (lazyPaths.length === 0) return;
356
+ try {
357
+ await runtime.discover(lazyPaths, "eager", null);
358
+ } catch (e) {
359
+ runtime.reportError(e);
360
+ }
361
+ }
362
+ let debouncedFetchPatches = debounce(fetchPatches, 100);
363
+ let observer = new MutationObserver(() => debouncedFetchPatches());
364
+ function updateDiscovery() {
365
+ let { ready, state } = runtime;
366
+ if (!ready || state === "complete") {
367
+ active = false;
368
+ observer.disconnect();
369
+ } else if (!active) {
370
+ active = true;
371
+ observer.observe(document.documentElement, {
372
+ subtree: true,
373
+ childList: true,
374
+ attributes: true,
375
+ attributeFilter: [
376
+ "data-discover",
377
+ "href",
378
+ "action"
379
+ ]
380
+ });
381
+ fetchPatches();
382
+ }
383
+ }
384
+ let unsubscribe = runtime.subscribe(updateDiscovery);
385
+ updateDiscovery();
386
+ return () => {
387
+ active = false;
388
+ unsubscribe();
389
+ observer.disconnect();
390
+ };
391
+ }, [runtime]);
392
+ return state;
393
+ }
394
+ function applyManifestPatches(serverPatches, manifest, routeModules, ssr, isSpaMode, patchRoutes, isApiOnly) {
395
+ let knownRoutes = new Set(Object.keys(manifest.routes));
396
+ let patches = Object.values(serverPatches).reduce((acc, route) => {
397
+ if (route && !knownRoutes.has(route.id)) acc[route.id] = route;
398
+ return acc;
399
+ }, {});
400
+ let parentIds = /* @__PURE__ */ new Set();
401
+ Object.values(patches).forEach((patch) => {
402
+ if (patch && (!patch.parentId || !patches[patch.parentId])) parentIds.add(patch.parentId);
403
+ });
404
+ parentIds.forEach((parentId) => patchRoutes(parentId || null, createClientRoutes(patches, routeModules, null, ssr, isSpaMode, parentId, void 0, void 0, isApiOnly)));
405
+ Object.assign(manifest.routes, patches);
406
+ }
407
+ function debounce(callback, wait) {
408
+ let timeoutId;
409
+ return (...args) => {
410
+ window.clearTimeout(timeoutId);
411
+ timeoutId = window.setTimeout(() => callback(...args), wait);
412
+ };
413
+ }
414
+ //#endregion
415
+ export { RouteDiscoveryRuntime, getCustomPatchRoutesOnNavigationFunction, useCustomRouteDiscovery, useRouteDiscovery };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *