react-router 8.3.0 → 8.4.0

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 (176) hide show
  1. package/CHANGELOG.md +46 -2
  2. package/dist/development/dom-export.js +1 -1
  3. package/dist/development/index-react-server-client.js +1 -1
  4. package/dist/development/index-react-server.d.ts +50 -48
  5. package/dist/development/index-react-server.js +96 -43
  6. package/dist/development/index.d.ts +2 -2
  7. package/dist/development/index.js +3 -3
  8. package/dist/development/lib/actions.js +10 -5
  9. package/dist/development/lib/components.js +50 -10
  10. package/dist/development/lib/context.d.ts +14 -5
  11. package/dist/development/lib/context.js +11 -3
  12. package/dist/development/lib/dom/dom.js +2 -2
  13. package/dist/development/lib/dom/lib.js +33 -36
  14. package/dist/development/lib/dom/server.d.ts +6 -1
  15. package/dist/development/lib/dom/server.js +40 -14
  16. package/dist/development/lib/dom/ssr/components.js +16 -24
  17. package/dist/development/lib/dom/ssr/data.js +1 -1
  18. package/dist/development/lib/dom/ssr/entry.d.ts +4 -0
  19. package/dist/development/lib/dom/ssr/errorBoundaries.js +1 -1
  20. package/dist/development/lib/dom/ssr/fallback.js +1 -1
  21. package/dist/development/lib/dom/ssr/fog-of-war.js +34 -12
  22. package/dist/development/lib/dom/ssr/hydration.d.ts +3 -1
  23. package/dist/development/lib/dom/ssr/hydration.js +6 -4
  24. package/dist/development/lib/dom/ssr/invariant.js +1 -1
  25. package/dist/development/lib/dom/ssr/links.js +1 -1
  26. package/dist/development/lib/dom/ssr/markup.js +5 -2
  27. package/dist/development/lib/dom/ssr/routeModules.js +1 -1
  28. package/dist/development/lib/dom/ssr/routes-test-stub.js +1 -1
  29. package/dist/development/lib/dom/ssr/routes.js +1 -1
  30. package/dist/development/lib/dom/ssr/server.js +2 -2
  31. package/dist/development/lib/dom/ssr/single-fetch.js +13 -22
  32. package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
  33. package/dist/development/lib/dom-export/hydrated-router.js +2 -1
  34. package/dist/development/lib/errors.js +1 -1
  35. package/dist/development/lib/hooks.js +54 -46
  36. package/dist/development/lib/href.js +1 -1
  37. package/dist/development/lib/router/history.js +2 -2
  38. package/dist/development/lib/router/instrumentation.js +1 -1
  39. package/dist/development/lib/router/matcher-route-pattern.d.ts +2 -0
  40. package/dist/development/lib/router/matcher-route-pattern.js +216 -0
  41. package/dist/development/lib/router/matcher-route-pattern.preload.d.ts +20 -0
  42. package/dist/development/lib/router/matcher-route-pattern.preload.js +36 -0
  43. package/dist/development/lib/router/matcher.d.ts +2 -0
  44. package/dist/development/lib/router/matcher.js +29 -0
  45. package/dist/development/lib/router/navigation.js +45 -0
  46. package/dist/development/lib/router/router.d.ts +21 -7
  47. package/dist/development/lib/router/router.js +111 -82
  48. package/dist/development/lib/router/url.js +1 -1
  49. package/dist/development/lib/router/utils.d.ts +6 -1
  50. package/dist/development/lib/router/utils.js +15 -9
  51. package/dist/development/lib/rsc/browser.js +5 -1
  52. package/dist/development/lib/rsc/errorBoundaries.js +1 -1
  53. package/dist/development/lib/rsc/html-stream/browser.js +1 -1
  54. package/dist/development/lib/rsc/html-stream/server.js +3 -5
  55. package/dist/development/lib/rsc/route-modules.js +1 -1
  56. package/dist/development/lib/rsc/server.rsc.d.ts +7 -0
  57. package/dist/development/lib/rsc/server.ssr.js +26 -22
  58. package/dist/development/lib/server-runtime/cookies.js +2 -2
  59. package/dist/development/lib/server-runtime/crypto.js +2 -2
  60. package/dist/development/lib/server-runtime/data.js +1 -1
  61. package/dist/development/lib/server-runtime/dev.js +2 -2
  62. package/dist/development/lib/server-runtime/entry.js +1 -1
  63. package/dist/development/lib/server-runtime/errors.js +1 -1
  64. package/dist/development/lib/server-runtime/headers.js +1 -1
  65. package/dist/development/lib/server-runtime/invariant.js +1 -1
  66. package/dist/development/lib/server-runtime/mode.js +1 -1
  67. package/dist/development/lib/server-runtime/routeMatching.js +3 -4
  68. package/dist/development/lib/server-runtime/routes.js +1 -1
  69. package/dist/development/lib/server-runtime/server.js +8 -7
  70. package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
  71. package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
  72. package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
  73. package/dist/development/lib/server-runtime/sessions.js +1 -1
  74. package/dist/development/lib/server-runtime/single-fetch.js +2 -2
  75. package/dist/development/lib/server-runtime/urls.js +1 -1
  76. package/dist/development/lib/server-runtime/warnings.js +1 -1
  77. package/dist/development/lib/types/internal.js +1 -1
  78. package/dist/development/route-pattern.d.ts +3 -0
  79. package/dist/development/route-pattern.js +12 -0
  80. package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
  81. package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +4 -4
  82. package/dist/development/vendor/turbo-stream-v2/unflatten.js +1 -1
  83. package/dist/development/vendor/turbo-stream-v2/utils.js +1 -1
  84. package/dist/production/dom-export.js +1 -1
  85. package/dist/production/index-react-server-client.js +1 -1
  86. package/dist/production/index-react-server.d.ts +50 -48
  87. package/dist/production/index-react-server.js +96 -43
  88. package/dist/production/index.d.ts +2 -2
  89. package/dist/production/index.js +3 -3
  90. package/dist/production/lib/actions.js +10 -5
  91. package/dist/production/lib/components.js +50 -10
  92. package/dist/production/lib/context.d.ts +14 -5
  93. package/dist/production/lib/context.js +11 -3
  94. package/dist/production/lib/dom/dom.js +2 -2
  95. package/dist/production/lib/dom/lib.js +33 -36
  96. package/dist/production/lib/dom/server.d.ts +6 -1
  97. package/dist/production/lib/dom/server.js +40 -14
  98. package/dist/production/lib/dom/ssr/components.js +16 -24
  99. package/dist/production/lib/dom/ssr/data.js +1 -1
  100. package/dist/production/lib/dom/ssr/entry.d.ts +4 -0
  101. package/dist/production/lib/dom/ssr/errorBoundaries.js +1 -1
  102. package/dist/production/lib/dom/ssr/fallback.js +1 -1
  103. package/dist/production/lib/dom/ssr/fog-of-war.js +34 -12
  104. package/dist/production/lib/dom/ssr/hydration.d.ts +3 -1
  105. package/dist/production/lib/dom/ssr/hydration.js +6 -4
  106. package/dist/production/lib/dom/ssr/invariant.js +1 -1
  107. package/dist/production/lib/dom/ssr/links.js +1 -1
  108. package/dist/production/lib/dom/ssr/markup.js +5 -2
  109. package/dist/production/lib/dom/ssr/routeModules.js +1 -1
  110. package/dist/production/lib/dom/ssr/routes-test-stub.js +1 -1
  111. package/dist/production/lib/dom/ssr/routes.js +1 -1
  112. package/dist/production/lib/dom/ssr/server.js +2 -2
  113. package/dist/production/lib/dom/ssr/single-fetch.js +13 -22
  114. package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
  115. package/dist/production/lib/dom-export/hydrated-router.js +2 -1
  116. package/dist/production/lib/errors.js +1 -1
  117. package/dist/production/lib/hooks.js +54 -46
  118. package/dist/production/lib/href.js +1 -1
  119. package/dist/production/lib/router/history.js +2 -2
  120. package/dist/production/lib/router/instrumentation.js +1 -1
  121. package/dist/production/lib/router/matcher-route-pattern.d.ts +2 -0
  122. package/dist/production/lib/router/matcher-route-pattern.js +216 -0
  123. package/dist/production/lib/router/matcher-route-pattern.preload.d.ts +20 -0
  124. package/dist/production/lib/router/matcher-route-pattern.preload.js +36 -0
  125. package/dist/production/lib/router/matcher.d.ts +2 -0
  126. package/dist/production/lib/router/matcher.js +29 -0
  127. package/dist/production/lib/router/navigation.js +45 -0
  128. package/dist/production/lib/router/router.d.ts +21 -7
  129. package/dist/production/lib/router/router.js +111 -82
  130. package/dist/production/lib/router/url.js +1 -1
  131. package/dist/production/lib/router/utils.d.ts +6 -1
  132. package/dist/production/lib/router/utils.js +15 -9
  133. package/dist/production/lib/rsc/browser.js +5 -1
  134. package/dist/production/lib/rsc/errorBoundaries.js +1 -1
  135. package/dist/production/lib/rsc/html-stream/browser.js +1 -1
  136. package/dist/production/lib/rsc/html-stream/server.js +3 -5
  137. package/dist/production/lib/rsc/route-modules.js +1 -1
  138. package/dist/production/lib/rsc/server.rsc.d.ts +7 -0
  139. package/dist/production/lib/rsc/server.ssr.js +26 -22
  140. package/dist/production/lib/server-runtime/cookies.js +2 -2
  141. package/dist/production/lib/server-runtime/crypto.js +2 -2
  142. package/dist/production/lib/server-runtime/data.js +1 -1
  143. package/dist/production/lib/server-runtime/dev.js +2 -2
  144. package/dist/production/lib/server-runtime/entry.js +1 -1
  145. package/dist/production/lib/server-runtime/errors.js +1 -1
  146. package/dist/production/lib/server-runtime/headers.js +1 -1
  147. package/dist/production/lib/server-runtime/invariant.js +1 -1
  148. package/dist/production/lib/server-runtime/mode.js +1 -1
  149. package/dist/production/lib/server-runtime/routeMatching.js +3 -4
  150. package/dist/production/lib/server-runtime/routes.js +1 -1
  151. package/dist/production/lib/server-runtime/server.js +8 -7
  152. package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
  153. package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
  154. package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
  155. package/dist/production/lib/server-runtime/sessions.js +1 -1
  156. package/dist/production/lib/server-runtime/single-fetch.js +2 -2
  157. package/dist/production/lib/server-runtime/urls.js +1 -1
  158. package/dist/production/lib/server-runtime/warnings.js +1 -1
  159. package/dist/production/lib/types/internal.js +1 -1
  160. package/dist/production/route-pattern.d.ts +3 -0
  161. package/dist/production/route-pattern.js +12 -0
  162. package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
  163. package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +4 -4
  164. package/dist/production/vendor/turbo-stream-v2/unflatten.js +1 -1
  165. package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
  166. package/docs/how-to/fetchers.md +6 -1
  167. package/docs/how-to/middleware.md +3 -1
  168. package/docs/how-to/optimize-revalidation.md +178 -5
  169. package/docs/how-to/react-server-components.md +26 -3
  170. package/docs/how-to/resource-routes.md +3 -0
  171. package/docs/start/data/actions.md +2 -1
  172. package/docs/start/data/route-object.md +21 -6
  173. package/docs/start/framework/actions.md +4 -2
  174. package/docs/start/framework/route-module.md +32 -5
  175. package/docs/upgrading/future.md +68 -0
  176. package/package.json +11 -1
@@ -0,0 +1,216 @@
1
+ /**
2
+ * react-router v8.4.0
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import { invariant, parsePath, warning } from "./history.js";
12
+ import { decodePath, explodeOptionalSegments, joinPaths, matchPath, normalizePathname, stripBasename } from "./utils.js";
13
+ import { createMultiMatcher } from "@remix-run/route-pattern/match";
14
+ import { descending } from "@remix-run/route-pattern/specificity";
15
+ //#region lib/router/matcher-route-pattern.ts
16
+ var RoutePatternDataRouteMatcher = class {
17
+ #state;
18
+ #basename;
19
+ constructor(basename) {
20
+ this.#basename = basename;
21
+ }
22
+ update(routes) {
23
+ let branches = flattenRoutes(routes);
24
+ let matcher = createMultiMatcher({ ignoreCase: true });
25
+ let partialMatcher = createMultiMatcher({ ignoreCase: true });
26
+ for (let branch of branches) {
27
+ let routePattern = convertReactRouterPathToRoutePattern(branch.path);
28
+ validateRoutePatternSplat(branch.path, routePattern);
29
+ routePattern = addOptionalTrailingSlash(routePattern);
30
+ matcher.add(routePattern, branch);
31
+ if (!branch.routesMeta[branch.routesMeta.length - 1].route.index) partialMatcher.add(routePattern === "/" ? `/*__rr_partial` : `${routePattern}(/*__rr_partial)`, branch);
32
+ }
33
+ this.#state = {
34
+ branches,
35
+ matcher,
36
+ partialMatcher
37
+ };
38
+ return branches;
39
+ }
40
+ match(locationArg, allowPartial = false) {
41
+ let pathname = stripBasename((typeof locationArg === "string" ? parsePath(locationArg) : locationArg).pathname || "/", this.#basename);
42
+ if (pathname == null) return null;
43
+ let decoded = decodePath(pathname);
44
+ let url = new URL("http://reactrouter.local");
45
+ url.pathname = pathname.endsWith("/") ? pathname : `${pathname}/`;
46
+ invariant(this.#state, "Route pattern routes must be initialized before matching.");
47
+ let matches = this.#state.matcher.matchAll(url);
48
+ if (allowPartial) matches.push(...this.#state.partialMatcher.matchAll(url));
49
+ for (let match of prioritizeValidatedMatches(matches)) {
50
+ let routeMatches = convertRoutePatternMatchToRouteMatches(match, decoded, allowPartial);
51
+ if (routeMatches && validateRouteMatchParams(routeMatches)) return routeMatches;
52
+ }
53
+ return null;
54
+ }
55
+ };
56
+ function validateRoutePatternSplat(routePath, routePattern) {
57
+ invariant(getRoutePatternSplatIndexes(routePattern).length <= 1 && isTerminalRoutePatternSplat(routePattern), `Route path "${routePath}" is not supported with \`future.unstable_routePatternMatching\` because React Router only supports a single splat at the end of a route path.`);
58
+ }
59
+ function getRoutePatternSplatIndexes(routePattern) {
60
+ let splatIndexes = [];
61
+ for (let i = 0; i < routePattern.length; i++) {
62
+ let char = routePattern[i];
63
+ if (char === "\\") {
64
+ i++;
65
+ continue;
66
+ }
67
+ if (char === "*") splatIndexes.push(i);
68
+ }
69
+ return splatIndexes;
70
+ }
71
+ function isTerminalRoutePatternSplat(routePattern) {
72
+ for (let i = 0; i < routePattern.length; i++) {
73
+ let char = routePattern[i];
74
+ if (char === "\\") {
75
+ i++;
76
+ continue;
77
+ }
78
+ if (char !== "*") continue;
79
+ let suffix = routePattern.slice(i + 1);
80
+ return /^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(suffix) || suffix === "";
81
+ }
82
+ return true;
83
+ }
84
+ function addOptionalTrailingSlash(routePattern) {
85
+ return routePattern === "/" ? routePattern : `${routePattern.replace(/\/+$/, "")}(/)`;
86
+ }
87
+ function flattenRoutes(routes, branches = [], parentsMeta = [], parentPath = "") {
88
+ routes.forEach((route, index) => {
89
+ invariant(route.caseSensitive !== true, "`caseSensitive` routes are not supported with `future.unstable_routePatternMatching`.");
90
+ let meta = {
91
+ relativePath: route.path || "",
92
+ caseSensitive: false,
93
+ childrenIndex: index,
94
+ route
95
+ };
96
+ let absolutePath;
97
+ if (meta.relativePath.startsWith("/")) {
98
+ absolutePath = meta.relativePath;
99
+ let parentPathMatch = explodeOptionalSegments(parentPath).find((path) => meta.relativePath.startsWith(path));
100
+ invariant(parentPathMatch != null, `Absolute route path "${meta.relativePath}" nested under path "${parentPath}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`);
101
+ meta.relativePath = meta.relativePath.slice(parentPathMatch.length);
102
+ }
103
+ let routesMeta = parentsMeta.concat(meta);
104
+ let path = absolutePath ?? (meta.relativePath ? joinPaths([parentPath, meta.relativePath]) : parentPath);
105
+ if (route.children && route.children.length > 0) {
106
+ invariant(route.index !== true, `Index routes must not have child routes. Please remove all child routes from route path "${path}".`);
107
+ flattenRoutes(route.children, branches, routesMeta, path);
108
+ if (route.children?.some((child) => child.index)) return;
109
+ }
110
+ if (route.path != null || route.index) branches.push({
111
+ path,
112
+ score: 0,
113
+ routesMeta
114
+ });
115
+ });
116
+ return branches;
117
+ }
118
+ function convertReactRouterPathToRoutePattern(path) {
119
+ warning(path === "*" || !path.endsWith("*") || path.endsWith("/*"), `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(/\*$/, "/*")}".`);
120
+ if (path.endsWith("*") && path !== "*" && !path.endsWith("/*")) path = path.replace(/\*$/, "/*");
121
+ path = path.replace(/^\/*/, "/");
122
+ if (path === "") return "/";
123
+ let segments = path.split("/");
124
+ let pattern = segments.shift() || "";
125
+ for (let i = 0; i < segments.length;) {
126
+ let optionalRun = [];
127
+ while (i < segments.length && isOptionalRouteSegment(segments[i])) {
128
+ optionalRun.push(convertRouteSegment(segments[i].slice(0, -1)));
129
+ i++;
130
+ }
131
+ if (optionalRun.length > 0) {
132
+ let nested = optionalRun.reduceRight((child, segment) => `/${segment}${child ? `(${child})` : ""}`, "");
133
+ pattern += `(${nested})`;
134
+ continue;
135
+ }
136
+ pattern += `/${convertRouteSegment(segments[i])}`;
137
+ i++;
138
+ }
139
+ return pattern || "/";
140
+ }
141
+ function isOptionalRouteSegment(segment) {
142
+ return segment.endsWith("?");
143
+ }
144
+ function convertRouteSegment(segment) {
145
+ if (segment === "*") return "*__rr_splat";
146
+ let paramMatch = segment.match(/^:([\w-]+)(\?)?(.*)$/);
147
+ if (paramMatch) {
148
+ let [, paramName, optional, suffix] = paramMatch;
149
+ let converted = `:${paramName}${escapeRoutePatternLiteral(suffix)}`;
150
+ return optional ? `(:${paramName})${escapeRoutePatternLiteral(suffix)}` : converted;
151
+ }
152
+ return escapeRoutePatternLiteral(segment);
153
+ }
154
+ function escapeRoutePatternLiteral(value) {
155
+ return value.replace(/[\\():*]/g, "\\$&");
156
+ }
157
+ function validateRouteMatchParams(matches) {
158
+ return matches.every(({ route, params }) => route.unstable_validateParams == null || Object.keys(route.unstable_validateParams).length === 0 || Object.entries(route.unstable_validateParams).every(([param, re]) => params[param] != null ? new RegExp(re.source, re.flags).test(params[param]) : true));
159
+ }
160
+ function prioritizeValidatedMatches(matches) {
161
+ return matches.sort((a, b) => {
162
+ let specificity = descending(a, b);
163
+ if (specificity !== 0) return specificity;
164
+ return Number(hasParamValidators(b)) - Number(hasParamValidators(a));
165
+ });
166
+ }
167
+ function hasParamValidators(match) {
168
+ return match.data.routesMeta.some((meta) => meta.route.unstable_validateParams != null && Object.keys(meta.route.unstable_validateParams).length > 0);
169
+ }
170
+ function convertRoutePatternMatchToRouteMatches(match, pathname, allowPartial) {
171
+ let result = matchRoutePatternBranch(match.data, pathname, allowPartial, 0, "/", {});
172
+ if (result == null) return null;
173
+ for (let routeMatch of result.matches) routeMatch.params = result.params;
174
+ return result.matches;
175
+ }
176
+ function matchRoutePatternBranch(branch, pathname, allowPartial, metaIndex, matchedPathname, matchedParams) {
177
+ let meta = branch.routesMeta[metaIndex];
178
+ let end = metaIndex === branch.routesMeta.length - 1;
179
+ let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/";
180
+ for (let relativePath of explodeOptionalSegments(meta.relativePath)) {
181
+ let pattern = {
182
+ path: relativePath,
183
+ caseSensitive: false,
184
+ end
185
+ };
186
+ let pathMatch = matchPath(pattern, remainingPathname);
187
+ if (!pathMatch && end && allowPartial && !meta.route.index) pathMatch = matchPath({
188
+ ...pattern,
189
+ end: false
190
+ }, remainingPathname);
191
+ if (!pathMatch) continue;
192
+ let params = {
193
+ ...matchedParams,
194
+ ...pathMatch.params
195
+ };
196
+ let routeMatch = {
197
+ params,
198
+ pathname: joinPaths([matchedPathname, pathMatch.pathname]),
199
+ pathnameBase: normalizePathname(joinPaths([matchedPathname, pathMatch.pathnameBase])),
200
+ route: meta.route
201
+ };
202
+ let nextMatchedPathname = pathMatch.pathnameBase === "/" ? matchedPathname : joinPaths([matchedPathname, pathMatch.pathnameBase]);
203
+ if (end) return {
204
+ matches: [routeMatch],
205
+ params
206
+ };
207
+ let childResult = matchRoutePatternBranch(branch, pathname, allowPartial, metaIndex + 1, nextMatchedPathname, params);
208
+ if (childResult) return {
209
+ matches: [routeMatch, ...childResult.matches],
210
+ params: childResult.params
211
+ };
212
+ }
213
+ return null;
214
+ }
215
+ //#endregion
216
+ export { RoutePatternDataRouteMatcher };
@@ -0,0 +1,20 @@
1
+
2
+ //#region lib/router/matcher-route-pattern.preload.d.ts
3
+ /**
4
+ * Initialize the route-pattern matcher before creating a Data Router or static
5
+ * handler with `future.unstable_routePatternMatching` enabled. Import from
6
+ * `react-router/route-pattern` and call this once during application startup.
7
+ * Server and browser applications must each preload their own matcher.
8
+ *
9
+ * The matcher is statically imported by this module. Tree-shaking bundlers can
10
+ * remove it from applications that do not use this function. Initialization is
11
+ * synchronous, and repeated calls are safe.
12
+ *
13
+ * @public
14
+ * @category Data Routers
15
+ * @mode data
16
+ * @returns {void}
17
+ */
18
+ declare function unstable_preloadRoutePattern(): void;
19
+ //#endregion
20
+ export { unstable_preloadRoutePattern };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * react-router v8.4.0
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import { RoutePatternDataRouteMatcher } from "./matcher-route-pattern.js";
12
+ //#region lib/router/matcher-route-pattern.preload.ts
13
+ let RoutePatternMatcher;
14
+ function getRoutePatternMatcher() {
15
+ return RoutePatternMatcher;
16
+ }
17
+ /**
18
+ * Initialize the route-pattern matcher before creating a Data Router or static
19
+ * handler with `future.unstable_routePatternMatching` enabled. Import from
20
+ * `react-router/route-pattern` and call this once during application startup.
21
+ * Server and browser applications must each preload their own matcher.
22
+ *
23
+ * The matcher is statically imported by this module. Tree-shaking bundlers can
24
+ * remove it from applications that do not use this function. Initialization is
25
+ * synchronous, and repeated calls are safe.
26
+ *
27
+ * @public
28
+ * @category Data Routers
29
+ * @mode data
30
+ * @returns {void}
31
+ */
32
+ function unstable_preloadRoutePattern() {
33
+ RoutePatternMatcher = RoutePatternDataRouteMatcher;
34
+ }
35
+ //#endregion
36
+ export { getRoutePatternMatcher, unstable_preloadRoutePattern };
@@ -0,0 +1,2 @@
1
+
2
+ export { };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * react-router v8.4.0
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import { flattenAndRankRoutes, matchRoutesImpl } from "./utils.js";
12
+ //#region lib/router/matcher.ts
13
+ var V6RegExMatcher = class {
14
+ #routes = [];
15
+ #branches = [];
16
+ #basename;
17
+ constructor(basename) {
18
+ this.#basename = basename;
19
+ }
20
+ update(routes) {
21
+ this.#routes = routes;
22
+ this.#branches = flattenAndRankRoutes(routes);
23
+ }
24
+ match(locationArg, allowPartial = false) {
25
+ return matchRoutesImpl(this.#routes, locationArg, this.#basename, allowPartial, this.#branches);
26
+ }
27
+ };
28
+ //#endregion
29
+ export { V6RegExMatcher };
@@ -0,0 +1,45 @@
1
+ /**
2
+ * react-router v8.4.0
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ //#region lib/router/navigation.ts
12
+ const DEFAULT_NAVIGATION_URL = new URL("http://localhost");
13
+ function getNavigatorCurrentUrl(navigator) {
14
+ if (navigator.createURL) return navigator.createURL("/");
15
+ try {
16
+ return new URL(navigator.createHref("/"), DEFAULT_NAVIGATION_URL);
17
+ } catch {
18
+ return DEFAULT_NAVIGATION_URL;
19
+ }
20
+ }
21
+ function isSameOrigin(a, b) {
22
+ return a.origin === b.origin && (a.origin !== "null" || a.protocol === b.protocol && a.host === b.host);
23
+ }
24
+ function isExplicitUrl(destination, target) {
25
+ if (destination.startsWith("//")) return true;
26
+ let protocol = target.protocol.toLowerCase();
27
+ if (!destination.toLowerCase().startsWith(protocol)) return false;
28
+ return target.host === "" || destination.slice(protocol.length).startsWith("//");
29
+ }
30
+ function validateNavigationTarget(original, resolved, currentUrl, externalPolicy) {
31
+ let originalUrl = null;
32
+ try {
33
+ originalUrl = original == null ? null : new URL(original, currentUrl);
34
+ } catch {}
35
+ let resolvedUrl = new URL(resolved, currentUrl);
36
+ let originalIsExternal = originalUrl != null && !isSameOrigin(originalUrl, currentUrl);
37
+ let resolvedIsExternal = !isSameOrigin(resolvedUrl, currentUrl);
38
+ if (externalPolicy === "reject") {
39
+ if (originalIsExternal || resolvedIsExternal) throw new Error("External navigation is not allowed");
40
+ } else if (resolvedIsExternal) {
41
+ if (originalUrl == null || !isExplicitUrl(original, originalUrl) || !isSameOrigin(originalUrl, resolvedUrl)) throw new Error("External navigation is not allowed");
42
+ }
43
+ }
44
+ //#endregion
45
+ export { getNavigatorCurrentUrl, validateNavigationTarget };
@@ -1,6 +1,6 @@
1
1
 
2
2
  import { Action, History, Location, Path, To } from "./history.js";
3
- import { DataRouteMatch, DataRouteObject, DataStrategyFunction, FormEncType, HTMLFormMethod, MapRoutePropertiesFunction, MaybePromise, PatchRoutesOnNavigationFunction, RouteBranch, RouteData, RouteManifest, RouteObject, RouterContextProvider, Submission, UIMatch } from "./utils.js";
3
+ import { DataRouteMatch, DataRouteObject, DataStrategyFunction, FormEncType, HTMLFormMethod, MapRoutePropertiesFunction, MaybePromise, PatchRoutesOnNavigationFunction, RouteData, RouteManifest, RouteObject, RouterContextProvider, Submission, UIMatch } from "./utils.js";
4
4
  import { ClientInstrumentation, ServerInstrumentation } from "./instrumentation.js";
5
5
 
6
6
  //#region lib/router/router.d.ts
@@ -40,9 +40,10 @@ interface Router {
40
40
  * @private
41
41
  * PRIVATE - DO NOT USE
42
42
  *
43
- * Return the route branches for this router instance
43
+ * Match routes against a location using the router's configured route
44
+ * matching implementation.
44
45
  */
45
- get branches(): RouteBranch<DataRouteObject>[] | undefined;
46
+ match(locationArg: Partial<Location> | string): DataRouteMatch[] | null;
46
47
  /**
47
48
  * @private
48
49
  * PRIVATE - DO NOT USE
@@ -128,6 +129,14 @@ interface Router {
128
129
  * @param location
129
130
  */
130
131
  createHref(location: Location | URL): string;
132
+ /**
133
+ * @private
134
+ * PRIVATE - DO NOT USE
135
+ *
136
+ * Utility function to create a URL for the given location
137
+ * @param location
138
+ */
139
+ createURL?(to: To): URL;
131
140
  /**
132
141
  * @private
133
142
  * PRIVATE - DO NOT USE
@@ -296,7 +305,10 @@ type HydrationState = Partial<Pick<RouterState, "loaderData" | "actionData" | "e
296
305
  /**
297
306
  * Future flags to toggle new feature behavior
298
307
  */
299
- interface FutureConfig {}
308
+ interface FutureConfig {
309
+ /** Enables route-pattern matching after calling `unstable_preloadRoutePattern()`. */
310
+ unstable_routePatternMatching?: boolean;
311
+ }
300
312
  /**
301
313
  * Initialization options for createRouter
302
314
  */
@@ -328,6 +340,8 @@ interface StaticHandlerContext {
328
340
  loaderHeaders: Record<string, Headers>;
329
341
  actionHeaders: Record<string, Headers>;
330
342
  _deepestRenderedBoundaryId?: string | null;
343
+ /** @private */
344
+ _match: StaticHandler["match"];
331
345
  }
332
346
  /**
333
347
  * A StaticHandler instance manages a singular SSR navigation/fetch event
@@ -341,10 +355,10 @@ interface StaticHandler {
341
355
  * @private
342
356
  * PRIVATE - DO NOT USE
343
357
  *
344
- * The route branches derived from the data routes, used for internal route
345
- * matching in Framework Mode
358
+ * Match routes against a location using the handler's configured route
359
+ * matching implementation.
346
360
  */
347
- _internalRouteBranches: RouteBranch<DataRouteObject>[];
361
+ match(locationArg: Partial<Location> | string): DataRouteMatch[] | null;
348
362
  /**
349
363
  * Perform a query for a given request - executing all matched route
350
364
  * loaders/actions. Used for document requests.