@tanstack/router-core 1.167.0 → 1.167.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 (166) hide show
  1. package/dist/cjs/Matches.cjs +15 -12
  2. package/dist/cjs/Matches.cjs.map +1 -1
  3. package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
  4. package/dist/cjs/config.cjs +9 -8
  5. package/dist/cjs/config.cjs.map +1 -1
  6. package/dist/cjs/defer.cjs +37 -21
  7. package/dist/cjs/defer.cjs.map +1 -1
  8. package/dist/cjs/index.cjs +87 -89
  9. package/dist/cjs/isServer/client.cjs +5 -3
  10. package/dist/cjs/isServer/client.cjs.map +1 -1
  11. package/dist/cjs/isServer/development.cjs +5 -3
  12. package/dist/cjs/isServer/development.cjs.map +1 -1
  13. package/dist/cjs/isServer/server.cjs +5 -3
  14. package/dist/cjs/isServer/server.cjs.map +1 -1
  15. package/dist/cjs/link.cjs +5 -4
  16. package/dist/cjs/link.cjs.map +1 -1
  17. package/dist/cjs/load-matches.cjs +619 -766
  18. package/dist/cjs/load-matches.cjs.map +1 -1
  19. package/dist/cjs/lru-cache.cjs +67 -64
  20. package/dist/cjs/lru-cache.cjs.map +1 -1
  21. package/dist/cjs/new-process-route-tree.cjs +707 -792
  22. package/dist/cjs/new-process-route-tree.cjs.map +1 -1
  23. package/dist/cjs/not-found.cjs +20 -7
  24. package/dist/cjs/not-found.cjs.map +1 -1
  25. package/dist/cjs/path.cjs +221 -232
  26. package/dist/cjs/path.cjs.map +1 -1
  27. package/dist/cjs/qss.cjs +62 -28
  28. package/dist/cjs/qss.cjs.map +1 -1
  29. package/dist/cjs/redirect.cjs +44 -30
  30. package/dist/cjs/redirect.cjs.map +1 -1
  31. package/dist/cjs/rewrite.cjs +56 -56
  32. package/dist/cjs/rewrite.cjs.map +1 -1
  33. package/dist/cjs/root.cjs +6 -4
  34. package/dist/cjs/root.cjs.map +1 -1
  35. package/dist/cjs/route.cjs +96 -105
  36. package/dist/cjs/route.cjs.map +1 -1
  37. package/dist/cjs/router.cjs +1153 -1524
  38. package/dist/cjs/router.cjs.map +1 -1
  39. package/dist/cjs/router.d.cts +2 -0
  40. package/dist/cjs/scroll-restoration.cjs +189 -207
  41. package/dist/cjs/scroll-restoration.cjs.map +1 -1
  42. package/dist/cjs/searchMiddleware.cjs +48 -37
  43. package/dist/cjs/searchMiddleware.cjs.map +1 -1
  44. package/dist/cjs/searchParams.cjs +57 -45
  45. package/dist/cjs/searchParams.cjs.map +1 -1
  46. package/dist/cjs/ssr/client.cjs +6 -8
  47. package/dist/cjs/ssr/constants.cjs +6 -5
  48. package/dist/cjs/ssr/constants.cjs.map +1 -1
  49. package/dist/cjs/ssr/createRequestHandler.cjs +41 -59
  50. package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -1
  51. package/dist/cjs/ssr/handlerCallback.cjs +5 -4
  52. package/dist/cjs/ssr/handlerCallback.cjs.map +1 -1
  53. package/dist/cjs/ssr/headers.cjs +17 -26
  54. package/dist/cjs/ssr/headers.cjs.map +1 -1
  55. package/dist/cjs/ssr/json.cjs +8 -4
  56. package/dist/cjs/ssr/json.cjs.map +1 -1
  57. package/dist/cjs/ssr/serializer/RawStream.cjs +268 -268
  58. package/dist/cjs/ssr/serializer/RawStream.cjs.map +1 -1
  59. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs +31 -32
  60. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs.map +1 -1
  61. package/dist/cjs/ssr/serializer/seroval-plugins.cjs +12 -12
  62. package/dist/cjs/ssr/serializer/seroval-plugins.cjs.map +1 -1
  63. package/dist/cjs/ssr/serializer/transformer.cjs +45 -41
  64. package/dist/cjs/ssr/serializer/transformer.cjs.map +1 -1
  65. package/dist/cjs/ssr/server.cjs +12 -14
  66. package/dist/cjs/ssr/ssr-client.cjs +173 -211
  67. package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
  68. package/dist/cjs/ssr/ssr-match-id.cjs +6 -5
  69. package/dist/cjs/ssr/ssr-match-id.cjs.map +1 -1
  70. package/dist/cjs/ssr/ssr-server.cjs +266 -300
  71. package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
  72. package/dist/cjs/ssr/transformStreamWithRouter.cjs +317 -337
  73. package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -1
  74. package/dist/cjs/ssr/tsrScript.cjs +6 -4
  75. package/dist/cjs/ssr/tsrScript.cjs.map +1 -1
  76. package/dist/cjs/ssr/tsrScript.d.cts +1 -0
  77. package/dist/cjs/utils/batch.cjs +13 -13
  78. package/dist/cjs/utils/batch.cjs.map +1 -1
  79. package/dist/cjs/utils.cjs +274 -208
  80. package/dist/cjs/utils.cjs.map +1 -1
  81. package/dist/esm/Matches.js +16 -13
  82. package/dist/esm/Matches.js.map +1 -1
  83. package/dist/esm/config.js +10 -9
  84. package/dist/esm/config.js.map +1 -1
  85. package/dist/esm/defer.js +37 -22
  86. package/dist/esm/defer.js.map +1 -1
  87. package/dist/esm/index.js +12 -82
  88. package/dist/esm/isServer/client.js +6 -5
  89. package/dist/esm/isServer/client.js.map +1 -1
  90. package/dist/esm/isServer/development.js +6 -5
  91. package/dist/esm/isServer/development.js.map +1 -1
  92. package/dist/esm/isServer/server.js +6 -5
  93. package/dist/esm/isServer/server.js.map +1 -1
  94. package/dist/esm/link.js +6 -5
  95. package/dist/esm/link.js.map +1 -1
  96. package/dist/esm/load-matches.js +614 -765
  97. package/dist/esm/load-matches.js.map +1 -1
  98. package/dist/esm/lru-cache.js +68 -65
  99. package/dist/esm/lru-cache.js.map +1 -1
  100. package/dist/esm/new-process-route-tree.js +705 -797
  101. package/dist/esm/new-process-route-tree.js.map +1 -1
  102. package/dist/esm/not-found.js +21 -9
  103. package/dist/esm/not-found.js.map +1 -1
  104. package/dist/esm/path.js +220 -241
  105. package/dist/esm/path.js.map +1 -1
  106. package/dist/esm/qss.js +63 -30
  107. package/dist/esm/qss.js.map +1 -1
  108. package/dist/esm/redirect.js +45 -34
  109. package/dist/esm/redirect.js.map +1 -1
  110. package/dist/esm/rewrite.js +57 -60
  111. package/dist/esm/rewrite.js.map +1 -1
  112. package/dist/esm/root.js +7 -5
  113. package/dist/esm/root.js.map +1 -1
  114. package/dist/esm/route.js +92 -105
  115. package/dist/esm/route.js.map +1 -1
  116. package/dist/esm/router.d.ts +2 -0
  117. package/dist/esm/router.js +1147 -1527
  118. package/dist/esm/router.js.map +1 -1
  119. package/dist/esm/scroll-restoration.js +188 -213
  120. package/dist/esm/scroll-restoration.js.map +1 -1
  121. package/dist/esm/searchMiddleware.js +48 -38
  122. package/dist/esm/searchMiddleware.js.map +1 -1
  123. package/dist/esm/searchParams.js +57 -48
  124. package/dist/esm/searchParams.js.map +1 -1
  125. package/dist/esm/ssr/client.js +1 -6
  126. package/dist/esm/ssr/constants.js +7 -7
  127. package/dist/esm/ssr/constants.js.map +1 -1
  128. package/dist/esm/ssr/createRequestHandler.js +39 -58
  129. package/dist/esm/ssr/createRequestHandler.js.map +1 -1
  130. package/dist/esm/ssr/handlerCallback.js +6 -5
  131. package/dist/esm/ssr/handlerCallback.js.map +1 -1
  132. package/dist/esm/ssr/headers.js +16 -26
  133. package/dist/esm/ssr/headers.js.map +1 -1
  134. package/dist/esm/ssr/json.js +9 -5
  135. package/dist/esm/ssr/json.js.map +1 -1
  136. package/dist/esm/ssr/serializer/RawStream.js +267 -273
  137. package/dist/esm/ssr/serializer/RawStream.js.map +1 -1
  138. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js +31 -32
  139. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js.map +1 -1
  140. package/dist/esm/ssr/serializer/seroval-plugins.js +10 -11
  141. package/dist/esm/ssr/serializer/seroval-plugins.js.map +1 -1
  142. package/dist/esm/ssr/serializer/transformer.js +44 -43
  143. package/dist/esm/ssr/serializer/transformer.js.map +1 -1
  144. package/dist/esm/ssr/server.js +2 -12
  145. package/dist/esm/ssr/ssr-client.js +169 -209
  146. package/dist/esm/ssr/ssr-client.js.map +1 -1
  147. package/dist/esm/ssr/ssr-match-id.js +7 -7
  148. package/dist/esm/ssr/ssr-match-id.js.map +1 -1
  149. package/dist/esm/ssr/ssr-server.js +262 -300
  150. package/dist/esm/ssr/ssr-server.js.map +1 -1
  151. package/dist/esm/ssr/transformStreamWithRouter.js +315 -338
  152. package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -1
  153. package/dist/esm/ssr/tsrScript.js +6 -5
  154. package/dist/esm/ssr/tsrScript.js.map +1 -1
  155. package/dist/esm/utils/batch.js +13 -14
  156. package/dist/esm/utils/batch.js.map +1 -1
  157. package/dist/esm/utils.js +273 -224
  158. package/dist/esm/utils.js.map +1 -1
  159. package/package.json +2 -2
  160. package/src/router.ts +2 -0
  161. package/dist/cjs/index.cjs.map +0 -1
  162. package/dist/cjs/ssr/client.cjs.map +0 -1
  163. package/dist/cjs/ssr/server.cjs.map +0 -1
  164. package/dist/esm/index.js.map +0 -1
  165. package/dist/esm/ssr/client.js.map +0 -1
  166. package/dist/esm/ssr/server.js.map +0 -1
@@ -1,1550 +1,1178 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const store = require("@tanstack/store");
4
- const history = require("@tanstack/history");
5
- const isServer = require("@tanstack/router-core/isServer");
6
- const batch = require("./utils/batch.cjs");
7
- const utils = require("./utils.cjs");
8
- const newProcessRouteTree = require("./new-process-route-tree.cjs");
9
- const path = require("./path.cjs");
10
- const lruCache = require("./lru-cache.cjs");
11
- const notFound = require("./not-found.cjs");
12
- const scrollRestoration = require("./scroll-restoration.cjs");
13
- const searchParams = require("./searchParams.cjs");
14
- const root = require("./root.cjs");
15
- const redirect = require("./redirect.cjs");
16
- const loadMatches = require("./load-matches.cjs");
17
- const rewrite = require("./rewrite.cjs");
1
+ require("./_virtual/_rolldown/runtime.cjs");
2
+ const require_batch = require("./utils/batch.cjs");
3
+ const require_utils = require("./utils.cjs");
4
+ const require_lru_cache = require("./lru-cache.cjs");
5
+ const require_new_process_route_tree = require("./new-process-route-tree.cjs");
6
+ const require_path = require("./path.cjs");
7
+ const require_not_found = require("./not-found.cjs");
8
+ const require_scroll_restoration = require("./scroll-restoration.cjs");
9
+ const require_searchParams = require("./searchParams.cjs");
10
+ const require_root = require("./root.cjs");
11
+ const require_redirect = require("./redirect.cjs");
12
+ const require_load_matches = require("./load-matches.cjs");
13
+ const require_rewrite = require("./rewrite.cjs");
14
+ let _tanstack_store = require("@tanstack/store");
15
+ let _tanstack_history = require("@tanstack/history");
16
+ let _tanstack_router_core_isServer = require("@tanstack/router-core/isServer");
17
+ //#region src/router.ts
18
+ /**
19
+ * Convert an unknown error into a minimal, serializable object.
20
+ * Includes name and message (and stack in development).
21
+ */
18
22
  function defaultSerializeError(err) {
19
- if (err instanceof Error) {
20
- const obj = {
21
- name: err.name,
22
- message: err.message
23
- };
24
- if (process.env.NODE_ENV === "development") {
25
- obj.stack = err.stack;
26
- }
27
- return obj;
28
- }
29
- return {
30
- data: err
31
- };
23
+ if (err instanceof Error) {
24
+ const obj = {
25
+ name: err.name,
26
+ message: err.message
27
+ };
28
+ if (process.env.NODE_ENV === "development") obj.stack = err.stack;
29
+ return obj;
30
+ }
31
+ return { data: err };
32
32
  }
33
- const trailingSlashOptions = {
34
- always: "always",
35
- never: "never",
36
- preserve: "preserve"
33
+ /** Options for configuring trailing-slash behavior. */
34
+ var trailingSlashOptions = {
35
+ always: "always",
36
+ never: "never",
37
+ preserve: "preserve"
37
38
  };
39
+ /**
40
+ * Compute whether path, href or hash changed between previous and current
41
+ * resolved locations in router state.
42
+ */
38
43
  function getLocationChangeInfo(routerState) {
39
- const fromLocation = routerState.resolvedLocation;
40
- const toLocation = routerState.location;
41
- const pathChanged = fromLocation?.pathname !== toLocation.pathname;
42
- const hrefChanged = fromLocation?.href !== toLocation.href;
43
- const hashChanged = fromLocation?.hash !== toLocation.hash;
44
- return { fromLocation, toLocation, pathChanged, hrefChanged, hashChanged };
44
+ const fromLocation = routerState.resolvedLocation;
45
+ const toLocation = routerState.location;
46
+ return {
47
+ fromLocation,
48
+ toLocation,
49
+ pathChanged: fromLocation?.pathname !== toLocation.pathname,
50
+ hrefChanged: fromLocation?.href !== toLocation.href,
51
+ hashChanged: fromLocation?.hash !== toLocation.hash
52
+ };
45
53
  }
46
54
  function filterRedirectedCachedMatches(matches) {
47
- const filtered = matches.filter((d) => d.status !== "redirected");
48
- return filtered.length === matches.length ? matches : filtered;
55
+ const filtered = matches.filter((d) => d.status !== "redirected");
56
+ return filtered.length === matches.length ? matches : filtered;
49
57
  }
50
58
  function createServerStore(initialState) {
51
- const store2 = {
52
- state: initialState,
53
- setState: (updater) => {
54
- store2.state = updater(store2.state);
55
- }
56
- };
57
- return store2;
59
+ const store = {
60
+ state: initialState,
61
+ setState: (updater) => {
62
+ store.state = updater(store.state);
63
+ }
64
+ };
65
+ return store;
58
66
  }
59
- class RouterCore {
60
- /**
61
- * @deprecated Use the `createRouter` function instead
62
- */
63
- constructor(options) {
64
- this.tempLocationKey = `${Math.round(
65
- Math.random() * 1e7
66
- )}`;
67
- this.resetNextScroll = true;
68
- this.shouldViewTransition = void 0;
69
- this.isViewTransitionTypesSupported = void 0;
70
- this.subscribers = /* @__PURE__ */ new Set();
71
- this.isScrollRestoring = false;
72
- this.isScrollRestorationSetup = false;
73
- this.startTransition = (fn) => fn();
74
- this.update = (newOptions) => {
75
- if (process.env.NODE_ENV !== "production") {
76
- if (newOptions.notFoundRoute) {
77
- console.warn(
78
- "The notFoundRoute API is deprecated and will be removed in the next major version. See https://tanstack.com/router/v1/docs/framework/react/guide/not-found-errors#migrating-from-notfoundroute for more info."
79
- );
80
- }
81
- }
82
- const prevOptions = this.options;
83
- const prevBasepath = this.basepath ?? prevOptions?.basepath ?? "/";
84
- const basepathWasUnset = this.basepath === void 0;
85
- const prevRewriteOption = prevOptions?.rewrite;
86
- this.options = {
87
- ...prevOptions,
88
- ...newOptions
89
- };
90
- this.isServer = this.options.isServer ?? typeof document === "undefined";
91
- this.protocolAllowlist = new Set(this.options.protocolAllowlist);
92
- if (this.options.pathParamsAllowedCharacters)
93
- this.pathParamsDecoder = path.compileDecodeCharMap(
94
- this.options.pathParamsAllowedCharacters
95
- );
96
- if (!this.history || this.options.history && this.options.history !== this.history) {
97
- if (!this.options.history) {
98
- if (!(isServer.isServer ?? this.isServer)) {
99
- this.history = history.createBrowserHistory();
100
- }
101
- } else {
102
- this.history = this.options.history;
103
- }
104
- }
105
- this.origin = this.options.origin;
106
- if (!this.origin) {
107
- if (!(isServer.isServer ?? this.isServer) && window?.origin && window.origin !== "null") {
108
- this.origin = window.origin;
109
- } else {
110
- this.origin = "http://localhost";
111
- }
112
- }
113
- if (this.history) {
114
- this.updateLatestLocation();
115
- }
116
- if (this.options.routeTree !== this.routeTree) {
117
- this.routeTree = this.options.routeTree;
118
- let processRouteTreeResult;
119
- if ((isServer.isServer ?? this.isServer) && process.env.NODE_ENV !== "development" && globalThis.__TSR_CACHE__ && globalThis.__TSR_CACHE__.routeTree === this.routeTree) {
120
- const cached = globalThis.__TSR_CACHE__;
121
- this.resolvePathCache = cached.resolvePathCache;
122
- processRouteTreeResult = cached.processRouteTreeResult;
123
- } else {
124
- this.resolvePathCache = lruCache.createLRUCache(1e3);
125
- processRouteTreeResult = this.buildRouteTree();
126
- if ((isServer.isServer ?? this.isServer) && process.env.NODE_ENV !== "development" && globalThis.__TSR_CACHE__ === void 0) {
127
- globalThis.__TSR_CACHE__ = {
128
- routeTree: this.routeTree,
129
- processRouteTreeResult,
130
- resolvePathCache: this.resolvePathCache
131
- };
132
- }
133
- }
134
- this.setRoutes(processRouteTreeResult);
135
- }
136
- if (!this.__store && this.latestLocation) {
137
- if (isServer.isServer ?? this.isServer) {
138
- this.__store = createServerStore(
139
- getInitialRouterState(this.latestLocation)
140
- );
141
- } else {
142
- this.__store = store.createStore(getInitialRouterState(this.latestLocation));
143
- scrollRestoration.setupScrollRestoration(this);
144
- }
145
- }
146
- let needsLocationUpdate = false;
147
- const nextBasepath = this.options.basepath ?? "/";
148
- const nextRewriteOption = this.options.rewrite;
149
- const basepathChanged = basepathWasUnset || prevBasepath !== nextBasepath;
150
- const rewriteChanged = prevRewriteOption !== nextRewriteOption;
151
- if (basepathChanged || rewriteChanged) {
152
- this.basepath = nextBasepath;
153
- const rewrites = [];
154
- const trimmed = path.trimPath(nextBasepath);
155
- if (trimmed && trimmed !== "/") {
156
- rewrites.push(
157
- rewrite.rewriteBasepath({
158
- basepath: nextBasepath
159
- })
160
- );
161
- }
162
- if (nextRewriteOption) {
163
- rewrites.push(nextRewriteOption);
164
- }
165
- this.rewrite = rewrites.length === 0 ? void 0 : rewrites.length === 1 ? rewrites[0] : rewrite.composeRewrites(rewrites);
166
- if (this.history) {
167
- this.updateLatestLocation();
168
- }
169
- needsLocationUpdate = true;
170
- }
171
- if (needsLocationUpdate && this.__store) {
172
- this.__store.setState((s) => ({
173
- ...s,
174
- location: this.latestLocation
175
- }));
176
- }
177
- if (typeof window !== "undefined" && "CSS" in window && typeof window.CSS?.supports === "function") {
178
- this.isViewTransitionTypesSupported = window.CSS.supports(
179
- "selector(:active-view-transition-type(a)"
180
- );
181
- }
182
- };
183
- this.updateLatestLocation = () => {
184
- this.latestLocation = this.parseLocation(
185
- this.history.location,
186
- this.latestLocation
187
- );
188
- };
189
- this.buildRouteTree = () => {
190
- const result = newProcessRouteTree.processRouteTree(
191
- this.routeTree,
192
- this.options.caseSensitive,
193
- (route, i) => {
194
- route.init({
195
- originalIndex: i
196
- });
197
- }
198
- );
199
- if (this.options.routeMasks) {
200
- newProcessRouteTree.processRouteMasks(this.options.routeMasks, result.processedTree);
201
- }
202
- return result;
203
- };
204
- this.subscribe = (eventType, fn) => {
205
- const listener = {
206
- eventType,
207
- fn
208
- };
209
- this.subscribers.add(listener);
210
- return () => {
211
- this.subscribers.delete(listener);
212
- };
213
- };
214
- this.emit = (routerEvent) => {
215
- this.subscribers.forEach((listener) => {
216
- if (listener.eventType === routerEvent.type) {
217
- listener.fn(routerEvent);
218
- }
219
- });
220
- };
221
- this.parseLocation = (locationToParse, previousLocation) => {
222
- const parse = ({
223
- pathname,
224
- search,
225
- hash,
226
- href,
227
- state
228
- }) => {
229
- if (!this.rewrite && !/[ \x00-\x1f\x7f\u0080-\uffff]/.test(pathname)) {
230
- const parsedSearch2 = this.options.parseSearch(search);
231
- const searchStr2 = this.options.stringifySearch(parsedSearch2);
232
- return {
233
- href: pathname + searchStr2 + hash,
234
- publicHref: href,
235
- pathname: utils.decodePath(pathname).path,
236
- external: false,
237
- searchStr: searchStr2,
238
- search: utils.nullReplaceEqualDeep(
239
- previousLocation?.search,
240
- parsedSearch2
241
- ),
242
- hash: utils.decodePath(hash.slice(1)).path,
243
- state: utils.replaceEqualDeep(previousLocation?.state, state)
244
- };
245
- }
246
- const fullUrl = new URL(href, this.origin);
247
- const url = rewrite.executeRewriteInput(this.rewrite, fullUrl);
248
- const parsedSearch = this.options.parseSearch(url.search);
249
- const searchStr = this.options.stringifySearch(parsedSearch);
250
- url.search = searchStr;
251
- const fullPath = url.href.replace(url.origin, "");
252
- return {
253
- href: fullPath,
254
- publicHref: href,
255
- pathname: utils.decodePath(url.pathname).path,
256
- external: !!this.rewrite && url.origin !== this.origin,
257
- searchStr,
258
- search: utils.nullReplaceEqualDeep(
259
- previousLocation?.search,
260
- parsedSearch
261
- ),
262
- hash: utils.decodePath(url.hash.slice(1)).path,
263
- state: utils.replaceEqualDeep(previousLocation?.state, state)
264
- };
265
- };
266
- const location = parse(locationToParse);
267
- const { __tempLocation, __tempKey } = location.state;
268
- if (__tempLocation && (!__tempKey || __tempKey === this.tempLocationKey)) {
269
- const parsedTempLocation = parse(__tempLocation);
270
- parsedTempLocation.state.key = location.state.key;
271
- parsedTempLocation.state.__TSR_key = location.state.__TSR_key;
272
- delete parsedTempLocation.state.__tempLocation;
273
- return {
274
- ...parsedTempLocation,
275
- maskedLocation: location
276
- };
277
- }
278
- return location;
279
- };
280
- this.resolvePathWithBase = (from, path$1) => {
281
- const resolvedPath = path.resolvePath({
282
- base: from,
283
- to: path.cleanPath(path$1),
284
- trailingSlash: this.options.trailingSlash,
285
- cache: this.resolvePathCache
286
- });
287
- return resolvedPath;
288
- };
289
- this.matchRoutes = (pathnameOrNext, locationSearchOrOpts, opts) => {
290
- if (typeof pathnameOrNext === "string") {
291
- return this.matchRoutesInternal(
292
- {
293
- pathname: pathnameOrNext,
294
- search: locationSearchOrOpts
295
- },
296
- opts
297
- );
298
- }
299
- return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts);
300
- };
301
- this.getMatchedRoutes = (pathname) => {
302
- return getMatchedRoutes({
303
- pathname,
304
- routesById: this.routesById,
305
- processedTree: this.processedTree
306
- });
307
- };
308
- this.cancelMatch = (id) => {
309
- const match = this.getMatch(id);
310
- if (!match) return;
311
- match.abortController.abort();
312
- clearTimeout(match._nonReactive.pendingTimeout);
313
- match._nonReactive.pendingTimeout = void 0;
314
- };
315
- this.cancelMatches = () => {
316
- const currentPendingMatches = this.state.matches.filter(
317
- (match) => match.status === "pending"
318
- );
319
- const currentLoadingMatches = this.state.matches.filter(
320
- (match) => match.isFetching === "loader"
321
- );
322
- const matchesToCancelArray = /* @__PURE__ */ new Set([
323
- ...this.state.pendingMatches ?? [],
324
- ...currentPendingMatches,
325
- ...currentLoadingMatches
326
- ]);
327
- matchesToCancelArray.forEach((match) => {
328
- this.cancelMatch(match.id);
329
- });
330
- };
331
- this.buildLocation = (opts) => {
332
- const build = (dest = {}) => {
333
- const currentLocation = dest._fromLocation || this.pendingBuiltLocation || this.latestLocation;
334
- const lightweightResult = this.matchRoutesLightweight(currentLocation);
335
- if (dest.from && process.env.NODE_ENV !== "production" && dest._isNavigate) {
336
- const allFromMatches = this.getMatchedRoutes(dest.from).matchedRoutes;
337
- const matchedFrom = utils.findLast(lightweightResult.matchedRoutes, (d) => {
338
- return comparePaths(d.fullPath, dest.from);
339
- });
340
- const matchedCurrent = utils.findLast(allFromMatches, (d) => {
341
- return comparePaths(d.fullPath, lightweightResult.fullPath);
342
- });
343
- if (!matchedFrom && !matchedCurrent) {
344
- console.warn(`Could not find match for from: ${dest.from}`);
345
- }
346
- }
347
- const defaultedFromPath = dest.unsafeRelative === "path" ? currentLocation.pathname : dest.from ?? lightweightResult.fullPath;
348
- const fromPath = this.resolvePathWithBase(defaultedFromPath, ".");
349
- const fromSearch = lightweightResult.search;
350
- const fromParams = Object.assign(
351
- /* @__PURE__ */ Object.create(null),
352
- lightweightResult.params
353
- );
354
- const nextTo = dest.to ? this.resolvePathWithBase(fromPath, `${dest.to}`) : this.resolvePathWithBase(fromPath, ".");
355
- const nextParams = dest.params === false || dest.params === null ? /* @__PURE__ */ Object.create(null) : (dest.params ?? true) === true ? fromParams : Object.assign(
356
- fromParams,
357
- utils.functionalUpdate(dest.params, fromParams)
358
- );
359
- const destMatchResult = this.getMatchedRoutes(nextTo);
360
- let destRoutes = destMatchResult.matchedRoutes;
361
- const isGlobalNotFound = !destMatchResult.foundRoute || destMatchResult.foundRoute.path !== "/" && destMatchResult.routeParams["**"];
362
- if (isGlobalNotFound && this.options.notFoundRoute) {
363
- destRoutes = [...destRoutes, this.options.notFoundRoute];
364
- }
365
- if (Object.keys(nextParams).length > 0) {
366
- for (const route of destRoutes) {
367
- const fn = route.options.params?.stringify ?? route.options.stringifyParams;
368
- if (fn) {
369
- try {
370
- Object.assign(nextParams, fn(nextParams));
371
- } catch {
372
- }
373
- }
374
- }
375
- }
376
- const nextPathname = opts.leaveParams ? (
377
- // Use the original template path for interpolation
378
- // This preserves the original parameter syntax including optional parameters
379
- nextTo
380
- ) : utils.decodePath(
381
- path.interpolatePath({
382
- path: nextTo,
383
- params: nextParams,
384
- decoder: this.pathParamsDecoder,
385
- server: this.isServer
386
- }).interpolatedPath
387
- ).path;
388
- let nextSearch = fromSearch;
389
- if (opts._includeValidateSearch && this.options.search?.strict) {
390
- const validatedSearch = {};
391
- destRoutes.forEach((route) => {
392
- if (route.options.validateSearch) {
393
- try {
394
- Object.assign(
395
- validatedSearch,
396
- validateSearch(route.options.validateSearch, {
397
- ...validatedSearch,
398
- ...nextSearch
399
- })
400
- );
401
- } catch {
402
- }
403
- }
404
- });
405
- nextSearch = validatedSearch;
406
- }
407
- nextSearch = applySearchMiddleware({
408
- search: nextSearch,
409
- dest,
410
- destRoutes,
411
- _includeValidateSearch: opts._includeValidateSearch
412
- });
413
- nextSearch = utils.nullReplaceEqualDeep(fromSearch, nextSearch);
414
- const searchStr = this.options.stringifySearch(nextSearch);
415
- const hash = dest.hash === true ? currentLocation.hash : dest.hash ? utils.functionalUpdate(dest.hash, currentLocation.hash) : void 0;
416
- const hashStr = hash ? `#${hash}` : "";
417
- let nextState = dest.state === true ? currentLocation.state : dest.state ? utils.functionalUpdate(dest.state, currentLocation.state) : {};
418
- nextState = utils.replaceEqualDeep(currentLocation.state, nextState);
419
- const fullPath = `${nextPathname}${searchStr}${hashStr}`;
420
- let href;
421
- let publicHref;
422
- let external = false;
423
- if (this.rewrite) {
424
- const url = new URL(fullPath, this.origin);
425
- const rewrittenUrl = rewrite.executeRewriteOutput(this.rewrite, url);
426
- href = url.href.replace(url.origin, "");
427
- if (rewrittenUrl.origin !== this.origin) {
428
- publicHref = rewrittenUrl.href;
429
- external = true;
430
- } else {
431
- publicHref = rewrittenUrl.pathname + rewrittenUrl.search + rewrittenUrl.hash;
432
- }
433
- } else {
434
- href = utils.encodePathLikeUrl(fullPath);
435
- publicHref = href;
436
- }
437
- return {
438
- publicHref,
439
- href,
440
- pathname: nextPathname,
441
- search: nextSearch,
442
- searchStr,
443
- state: nextState,
444
- hash: hash ?? "",
445
- external,
446
- unmaskOnReload: dest.unmaskOnReload
447
- };
448
- };
449
- const buildWithMatches = (dest = {}, maskedDest) => {
450
- const next = build(dest);
451
- let maskedNext = maskedDest ? build(maskedDest) : void 0;
452
- if (!maskedNext) {
453
- const params = /* @__PURE__ */ Object.create(null);
454
- if (this.options.routeMasks) {
455
- const match = newProcessRouteTree.findFlatMatch(
456
- next.pathname,
457
- this.processedTree
458
- );
459
- if (match) {
460
- Object.assign(params, match.rawParams);
461
- const {
462
- from: _from,
463
- params: maskParams,
464
- ...maskProps
465
- } = match.route;
466
- const nextParams = maskParams === false || maskParams === null ? /* @__PURE__ */ Object.create(null) : (maskParams ?? true) === true ? params : Object.assign(params, utils.functionalUpdate(maskParams, params));
467
- maskedDest = {
468
- from: opts.from,
469
- ...maskProps,
470
- params: nextParams
471
- };
472
- maskedNext = build(maskedDest);
473
- }
474
- }
475
- }
476
- if (maskedNext) {
477
- next.maskedLocation = maskedNext;
478
- }
479
- return next;
480
- };
481
- if (opts.mask) {
482
- return buildWithMatches(opts, {
483
- from: opts.from,
484
- ...opts.mask
485
- });
486
- }
487
- return buildWithMatches(opts);
488
- };
489
- this.commitLocation = async ({
490
- viewTransition,
491
- ignoreBlocker,
492
- ...next
493
- }) => {
494
- const isSameState = () => {
495
- const ignoredProps = [
496
- "key",
497
- // TODO: Remove in v2 - use __TSR_key instead
498
- "__TSR_key",
499
- "__TSR_index",
500
- "__hashScrollIntoViewOptions"
501
- ];
502
- ignoredProps.forEach((prop) => {
503
- next.state[prop] = this.latestLocation.state[prop];
504
- });
505
- const isEqual = utils.deepEqual(next.state, this.latestLocation.state);
506
- ignoredProps.forEach((prop) => {
507
- delete next.state[prop];
508
- });
509
- return isEqual;
510
- };
511
- const isSameUrl = path.trimPathRight(this.latestLocation.href) === path.trimPathRight(next.href);
512
- const previousCommitPromise = this.commitLocationPromise;
513
- this.commitLocationPromise = utils.createControlledPromise(() => {
514
- previousCommitPromise?.resolve();
515
- });
516
- if (isSameUrl && isSameState()) {
517
- this.load();
518
- } else {
519
- let {
520
- // eslint-disable-next-line prefer-const
521
- maskedLocation,
522
- // eslint-disable-next-line prefer-const
523
- hashScrollIntoView,
524
- ...nextHistory
525
- } = next;
526
- if (maskedLocation) {
527
- nextHistory = {
528
- ...maskedLocation,
529
- state: {
530
- ...maskedLocation.state,
531
- __tempKey: void 0,
532
- __tempLocation: {
533
- ...nextHistory,
534
- search: nextHistory.searchStr,
535
- state: {
536
- ...nextHistory.state,
537
- __tempKey: void 0,
538
- __tempLocation: void 0,
539
- __TSR_key: void 0,
540
- key: void 0
541
- // TODO: Remove in v2 - use __TSR_key instead
542
- }
543
- }
544
- }
545
- };
546
- if (nextHistory.unmaskOnReload ?? this.options.unmaskOnReload ?? false) {
547
- nextHistory.state.__tempKey = this.tempLocationKey;
548
- }
549
- }
550
- nextHistory.state.__hashScrollIntoViewOptions = hashScrollIntoView ?? this.options.defaultHashScrollIntoView ?? true;
551
- this.shouldViewTransition = viewTransition;
552
- this.history[next.replace ? "replace" : "push"](
553
- nextHistory.publicHref,
554
- nextHistory.state,
555
- { ignoreBlocker }
556
- );
557
- }
558
- this.resetNextScroll = next.resetScroll ?? true;
559
- if (!this.history.subscribers.size) {
560
- this.load();
561
- }
562
- return this.commitLocationPromise;
563
- };
564
- this.buildAndCommitLocation = ({
565
- replace,
566
- resetScroll,
567
- hashScrollIntoView,
568
- viewTransition,
569
- ignoreBlocker,
570
- href,
571
- ...rest
572
- } = {}) => {
573
- if (href) {
574
- const currentIndex = this.history.location.state.__TSR_index;
575
- const parsed = history.parseHref(href, {
576
- __TSR_index: replace ? currentIndex : currentIndex + 1
577
- });
578
- const hrefUrl = new URL(parsed.pathname, this.origin);
579
- const rewrittenUrl = rewrite.executeRewriteInput(this.rewrite, hrefUrl);
580
- rest.to = rewrittenUrl.pathname;
581
- rest.search = this.options.parseSearch(parsed.search);
582
- rest.hash = parsed.hash.slice(1);
583
- }
584
- const location = this.buildLocation({
585
- ...rest,
586
- _includeValidateSearch: true
587
- });
588
- this.pendingBuiltLocation = location;
589
- const commitPromise = this.commitLocation({
590
- ...location,
591
- viewTransition,
592
- replace,
593
- resetScroll,
594
- hashScrollIntoView,
595
- ignoreBlocker
596
- });
597
- Promise.resolve().then(() => {
598
- if (this.pendingBuiltLocation === location) {
599
- this.pendingBuiltLocation = void 0;
600
- }
601
- });
602
- return commitPromise;
603
- };
604
- this.navigate = async ({
605
- to,
606
- reloadDocument,
607
- href,
608
- publicHref,
609
- ...rest
610
- }) => {
611
- let hrefIsUrl = false;
612
- if (href) {
613
- try {
614
- new URL(`${href}`);
615
- hrefIsUrl = true;
616
- } catch {
617
- }
618
- }
619
- if (hrefIsUrl && !reloadDocument) {
620
- reloadDocument = true;
621
- }
622
- if (reloadDocument) {
623
- if (to !== void 0 || !href) {
624
- const location = this.buildLocation({ to, ...rest });
625
- href = href ?? location.publicHref;
626
- publicHref = publicHref ?? location.publicHref;
627
- }
628
- const reloadHref = !hrefIsUrl && publicHref ? publicHref : href;
629
- if (utils.isDangerousProtocol(reloadHref, this.protocolAllowlist)) {
630
- if (process.env.NODE_ENV !== "production") {
631
- console.warn(
632
- `Blocked navigation to dangerous protocol: ${reloadHref}`
633
- );
634
- }
635
- return Promise.resolve();
636
- }
637
- if (!rest.ignoreBlocker) {
638
- const historyWithBlockers = this.history;
639
- const blockers = historyWithBlockers.getBlockers?.() ?? [];
640
- for (const blocker of blockers) {
641
- if (blocker?.blockerFn) {
642
- const shouldBlock = await blocker.blockerFn({
643
- currentLocation: this.latestLocation,
644
- nextLocation: this.latestLocation,
645
- // External URLs don't have a next location in our router
646
- action: "PUSH"
647
- });
648
- if (shouldBlock) {
649
- return Promise.resolve();
650
- }
651
- }
652
- }
653
- }
654
- if (rest.replace) {
655
- window.location.replace(reloadHref);
656
- } else {
657
- window.location.href = reloadHref;
658
- }
659
- return Promise.resolve();
660
- }
661
- return this.buildAndCommitLocation({
662
- ...rest,
663
- href,
664
- to,
665
- _isNavigate: true
666
- });
667
- };
668
- this.beforeLoad = () => {
669
- this.cancelMatches();
670
- this.updateLatestLocation();
671
- if (isServer.isServer ?? this.isServer) {
672
- const nextLocation = this.buildLocation({
673
- to: this.latestLocation.pathname,
674
- search: true,
675
- params: true,
676
- hash: true,
677
- state: true,
678
- _includeValidateSearch: true
679
- });
680
- if (this.latestLocation.publicHref !== nextLocation.publicHref) {
681
- const href = this.getParsedLocationHref(nextLocation);
682
- if (nextLocation.external) {
683
- throw redirect.redirect({ href });
684
- } else {
685
- throw redirect.redirect({ href, _builtLocation: nextLocation });
686
- }
687
- }
688
- }
689
- const pendingMatches = this.matchRoutes(this.latestLocation);
690
- this.__store.setState((s) => ({
691
- ...s,
692
- status: "pending",
693
- statusCode: 200,
694
- isLoading: true,
695
- location: this.latestLocation,
696
- pendingMatches,
697
- // If a cached moved to pendingMatches, remove it from cachedMatches
698
- cachedMatches: s.cachedMatches.filter(
699
- (d) => !pendingMatches.some((e) => e.id === d.id)
700
- )
701
- }));
702
- };
703
- this.load = async (opts) => {
704
- let redirect2;
705
- let notFound$1;
706
- let loadPromise;
707
- const previousLocation = this.state.resolvedLocation ?? this.state.location;
708
- loadPromise = new Promise((resolve) => {
709
- this.startTransition(async () => {
710
- try {
711
- this.beforeLoad();
712
- const next = this.latestLocation;
713
- const prevLocation = this.state.resolvedLocation;
714
- if (!this.state.redirect) {
715
- this.emit({
716
- type: "onBeforeNavigate",
717
- ...getLocationChangeInfo({
718
- resolvedLocation: prevLocation,
719
- location: next
720
- })
721
- });
722
- }
723
- this.emit({
724
- type: "onBeforeLoad",
725
- ...getLocationChangeInfo({
726
- resolvedLocation: prevLocation,
727
- location: next
728
- })
729
- });
730
- await loadMatches.loadMatches({
731
- router: this,
732
- sync: opts?.sync,
733
- forceStaleReload: previousLocation.href === next.href,
734
- matches: this.state.pendingMatches,
735
- location: next,
736
- updateMatch: this.updateMatch,
737
- // eslint-disable-next-line @typescript-eslint/require-await
738
- onReady: async () => {
739
- this.startTransition(() => {
740
- this.startViewTransition(async () => {
741
- let exitingMatches = [];
742
- let hookExitingMatches = [];
743
- let hookEnteringMatches = [];
744
- let hookStayingMatches = [];
745
- batch.batch(() => {
746
- this.__store.setState((s) => {
747
- const previousMatches = s.matches;
748
- const newMatches = s.pendingMatches || s.matches;
749
- exitingMatches = previousMatches.filter(
750
- (match) => !newMatches.some((d) => d.id === match.id)
751
- );
752
- hookExitingMatches = previousMatches.filter(
753
- (match) => !newMatches.some((d) => d.routeId === match.routeId)
754
- );
755
- hookEnteringMatches = newMatches.filter(
756
- (match) => !previousMatches.some(
757
- (d) => d.routeId === match.routeId
758
- )
759
- );
760
- hookStayingMatches = newMatches.filter(
761
- (match) => previousMatches.some(
762
- (d) => d.routeId === match.routeId
763
- )
764
- );
765
- return {
766
- ...s,
767
- isLoading: false,
768
- loadedAt: Date.now(),
769
- matches: newMatches,
770
- pendingMatches: void 0,
771
- /**
772
- * When committing new matches, cache any exiting matches that are still usable.
773
- * Routes that resolved with `status: 'error'` or `status: 'notFound'` are
774
- * deliberately excluded from `cachedMatches` so that subsequent invalidations
775
- * or reloads re-run their loaders instead of reusing the failed/not-found data.
776
- */
777
- cachedMatches: [
778
- ...s.cachedMatches,
779
- ...exitingMatches.filter(
780
- (d) => d.status !== "error" && d.status !== "notFound" && d.status !== "redirected"
781
- )
782
- ]
783
- };
784
- });
785
- this.clearExpiredCache();
786
- });
787
- [
788
- [hookExitingMatches, "onLeave"],
789
- [hookEnteringMatches, "onEnter"],
790
- [hookStayingMatches, "onStay"]
791
- ].forEach(([matches, hook]) => {
792
- matches.forEach((match) => {
793
- this.looseRoutesById[match.routeId].options[hook]?.(
794
- match
795
- );
796
- });
797
- });
798
- });
799
- });
800
- }
801
- });
802
- } catch (err) {
803
- if (redirect.isRedirect(err)) {
804
- redirect2 = err;
805
- if (!(isServer.isServer ?? this.isServer)) {
806
- this.navigate({
807
- ...redirect2.options,
808
- replace: true,
809
- ignoreBlocker: true
810
- });
811
- }
812
- } else if (notFound.isNotFound(err)) {
813
- notFound$1 = err;
814
- }
815
- this.__store.setState((s) => ({
816
- ...s,
817
- statusCode: redirect2 ? redirect2.status : notFound$1 ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200,
818
- redirect: redirect2
819
- }));
820
- }
821
- if (this.latestLoadPromise === loadPromise) {
822
- this.commitLocationPromise?.resolve();
823
- this.latestLoadPromise = void 0;
824
- this.commitLocationPromise = void 0;
825
- }
826
- resolve();
827
- });
828
- });
829
- this.latestLoadPromise = loadPromise;
830
- await loadPromise;
831
- while (this.latestLoadPromise && loadPromise !== this.latestLoadPromise) {
832
- await this.latestLoadPromise;
833
- }
834
- let newStatusCode = void 0;
835
- if (this.hasNotFoundMatch()) {
836
- newStatusCode = 404;
837
- } else if (this.__store.state.matches.some((d) => d.status === "error")) {
838
- newStatusCode = 500;
839
- }
840
- if (newStatusCode !== void 0) {
841
- this.__store.setState((s) => ({
842
- ...s,
843
- statusCode: newStatusCode
844
- }));
845
- }
846
- };
847
- this.startViewTransition = (fn) => {
848
- const shouldViewTransition = this.shouldViewTransition ?? this.options.defaultViewTransition;
849
- this.shouldViewTransition = void 0;
850
- if (shouldViewTransition && typeof document !== "undefined" && "startViewTransition" in document && typeof document.startViewTransition === "function") {
851
- let startViewTransitionParams;
852
- if (typeof shouldViewTransition === "object" && this.isViewTransitionTypesSupported) {
853
- const next = this.latestLocation;
854
- const prevLocation = this.state.resolvedLocation;
855
- const resolvedViewTransitionTypes = typeof shouldViewTransition.types === "function" ? shouldViewTransition.types(
856
- getLocationChangeInfo({
857
- resolvedLocation: prevLocation,
858
- location: next
859
- })
860
- ) : shouldViewTransition.types;
861
- if (resolvedViewTransitionTypes === false) {
862
- fn();
863
- return;
864
- }
865
- startViewTransitionParams = {
866
- update: fn,
867
- types: resolvedViewTransitionTypes
868
- };
869
- } else {
870
- startViewTransitionParams = fn;
871
- }
872
- document.startViewTransition(startViewTransitionParams);
873
- } else {
874
- fn();
875
- }
876
- };
877
- this.updateMatch = (id, updater) => {
878
- this.startTransition(() => {
879
- const matchesKey = this.state.pendingMatches?.some((d) => d.id === id) ? "pendingMatches" : this.state.matches.some((d) => d.id === id) ? "matches" : this.state.cachedMatches.some((d) => d.id === id) ? "cachedMatches" : "";
880
- if (matchesKey) {
881
- if (matchesKey === "cachedMatches") {
882
- this.__store.setState((s) => ({
883
- ...s,
884
- cachedMatches: filterRedirectedCachedMatches(
885
- s.cachedMatches.map((d) => d.id === id ? updater(d) : d)
886
- )
887
- }));
888
- } else {
889
- this.__store.setState((s) => ({
890
- ...s,
891
- [matchesKey]: s[matchesKey]?.map(
892
- (d) => d.id === id ? updater(d) : d
893
- )
894
- }));
895
- }
896
- }
897
- });
898
- };
899
- this.getMatch = (matchId) => {
900
- const findFn = (d) => d.id === matchId;
901
- return this.state.cachedMatches.find(findFn) ?? this.state.pendingMatches?.find(findFn) ?? this.state.matches.find(findFn);
902
- };
903
- this.invalidate = (opts) => {
904
- const invalidate = (d) => {
905
- if (opts?.filter?.(d) ?? true) {
906
- return {
907
- ...d,
908
- invalid: true,
909
- ...opts?.forcePending || d.status === "error" || d.status === "notFound" ? { status: "pending", error: void 0 } : void 0
910
- };
911
- }
912
- return d;
913
- };
914
- this.__store.setState((s) => ({
915
- ...s,
916
- matches: s.matches.map(invalidate),
917
- cachedMatches: s.cachedMatches.map(invalidate),
918
- pendingMatches: s.pendingMatches?.map(invalidate)
919
- }));
920
- this.shouldViewTransition = false;
921
- return this.load({ sync: opts?.sync });
922
- };
923
- this.getParsedLocationHref = (location) => {
924
- return location.publicHref || "/";
925
- };
926
- this.resolveRedirect = (redirect2) => {
927
- const locationHeader = redirect2.headers.get("Location");
928
- if (!redirect2.options.href || redirect2.options._builtLocation) {
929
- const location = redirect2.options._builtLocation ?? this.buildLocation(redirect2.options);
930
- const href = this.getParsedLocationHref(location);
931
- redirect2.options.href = href;
932
- redirect2.headers.set("Location", href);
933
- } else if (locationHeader) {
934
- try {
935
- const url = new URL(locationHeader);
936
- if (this.origin && url.origin === this.origin) {
937
- const href = url.pathname + url.search + url.hash;
938
- redirect2.options.href = href;
939
- redirect2.headers.set("Location", href);
940
- }
941
- } catch {
942
- }
943
- }
944
- if (redirect2.options.href && !redirect2.options._builtLocation && // Check for dangerous protocols before processing the redirect
945
- utils.isDangerousProtocol(redirect2.options.href, this.protocolAllowlist)) {
946
- throw new Error(
947
- process.env.NODE_ENV !== "production" ? `Redirect blocked: unsafe protocol in href "${redirect2.options.href}". Allowed protocols: ${Array.from(this.protocolAllowlist).join(", ")}.` : "Redirect blocked: unsafe protocol"
948
- );
949
- }
950
- if (!redirect2.headers.get("Location")) {
951
- redirect2.headers.set("Location", redirect2.options.href);
952
- }
953
- return redirect2;
954
- };
955
- this.clearCache = (opts) => {
956
- const filter = opts?.filter;
957
- if (filter !== void 0) {
958
- this.__store.setState((s) => {
959
- return {
960
- ...s,
961
- cachedMatches: s.cachedMatches.filter(
962
- (m) => !filter(m)
963
- )
964
- };
965
- });
966
- } else {
967
- this.__store.setState((s) => {
968
- return {
969
- ...s,
970
- cachedMatches: []
971
- };
972
- });
973
- }
974
- };
975
- this.clearExpiredCache = () => {
976
- const filter = (d) => {
977
- const route = this.looseRoutesById[d.routeId];
978
- if (!route.options.loader) {
979
- return true;
980
- }
981
- const gcTime = (d.preload ? route.options.preloadGcTime ?? this.options.defaultPreloadGcTime : route.options.gcTime ?? this.options.defaultGcTime) ?? 5 * 60 * 1e3;
982
- const isError = d.status === "error";
983
- if (isError) return true;
984
- const gcEligible = Date.now() - d.updatedAt >= gcTime;
985
- return gcEligible;
986
- };
987
- this.clearCache({ filter });
988
- };
989
- this.loadRouteChunk = loadMatches.loadRouteChunk;
990
- this.preloadRoute = async (opts) => {
991
- const next = opts._builtLocation ?? this.buildLocation(opts);
992
- let matches = this.matchRoutes(next, {
993
- throwOnError: true,
994
- preload: true,
995
- dest: opts
996
- });
997
- const activeMatchIds = new Set(
998
- [...this.state.matches, ...this.state.pendingMatches ?? []].map(
999
- (d) => d.id
1000
- )
1001
- );
1002
- const loadedMatchIds = /* @__PURE__ */ new Set([
1003
- ...activeMatchIds,
1004
- ...this.state.cachedMatches.map((d) => d.id)
1005
- ]);
1006
- batch.batch(() => {
1007
- matches.forEach((match) => {
1008
- if (!loadedMatchIds.has(match.id)) {
1009
- this.__store.setState((s) => ({
1010
- ...s,
1011
- cachedMatches: [...s.cachedMatches, match]
1012
- }));
1013
- }
1014
- });
1015
- });
1016
- try {
1017
- matches = await loadMatches.loadMatches({
1018
- router: this,
1019
- matches,
1020
- location: next,
1021
- preload: true,
1022
- updateMatch: (id, updater) => {
1023
- if (activeMatchIds.has(id)) {
1024
- matches = matches.map((d) => d.id === id ? updater(d) : d);
1025
- } else {
1026
- this.updateMatch(id, updater);
1027
- }
1028
- }
1029
- });
1030
- return matches;
1031
- } catch (err) {
1032
- if (redirect.isRedirect(err)) {
1033
- if (err.options.reloadDocument) {
1034
- return void 0;
1035
- }
1036
- return await this.preloadRoute({
1037
- ...err.options,
1038
- _fromLocation: next
1039
- });
1040
- }
1041
- if (!notFound.isNotFound(err)) {
1042
- console.error(err);
1043
- }
1044
- return void 0;
1045
- }
1046
- };
1047
- this.matchRoute = (location, opts) => {
1048
- const matchLocation = {
1049
- ...location,
1050
- to: location.to ? this.resolvePathWithBase(location.from || "", location.to) : void 0,
1051
- params: location.params || {},
1052
- leaveParams: true
1053
- };
1054
- const next = this.buildLocation(matchLocation);
1055
- if (opts?.pending && this.state.status !== "pending") {
1056
- return false;
1057
- }
1058
- const pending = opts?.pending === void 0 ? !this.state.isLoading : opts.pending;
1059
- const baseLocation = pending ? this.latestLocation : this.state.resolvedLocation || this.state.location;
1060
- const match = newProcessRouteTree.findSingleMatch(
1061
- next.pathname,
1062
- opts?.caseSensitive ?? false,
1063
- opts?.fuzzy ?? false,
1064
- baseLocation.pathname,
1065
- this.processedTree
1066
- );
1067
- if (!match) {
1068
- return false;
1069
- }
1070
- if (location.params) {
1071
- if (!utils.deepEqual(match.rawParams, location.params, { partial: true })) {
1072
- return false;
1073
- }
1074
- }
1075
- if (opts?.includeSearch ?? true) {
1076
- return utils.deepEqual(baseLocation.search, next.search, { partial: true }) ? match.rawParams : false;
1077
- }
1078
- return match.rawParams;
1079
- };
1080
- this.hasNotFoundMatch = () => {
1081
- return this.__store.state.matches.some(
1082
- (d) => d.status === "notFound" || d.globalNotFound
1083
- );
1084
- };
1085
- this.update({
1086
- defaultPreloadDelay: 50,
1087
- defaultPendingMs: 1e3,
1088
- defaultPendingMinMs: 500,
1089
- context: void 0,
1090
- ...options,
1091
- caseSensitive: options.caseSensitive ?? false,
1092
- notFoundMode: options.notFoundMode ?? "fuzzy",
1093
- stringifySearch: options.stringifySearch ?? searchParams.defaultStringifySearch,
1094
- parseSearch: options.parseSearch ?? searchParams.defaultParseSearch,
1095
- protocolAllowlist: options.protocolAllowlist ?? utils.DEFAULT_PROTOCOL_ALLOWLIST
1096
- });
1097
- if (typeof document !== "undefined") {
1098
- self.__TSR_ROUTER__ = this;
1099
- }
1100
- }
1101
- isShell() {
1102
- return !!this.options.isShell;
1103
- }
1104
- isPrerendering() {
1105
- return !!this.options.isPrerendering;
1106
- }
1107
- get state() {
1108
- return this.__store.state;
1109
- }
1110
- setRoutes({
1111
- routesById,
1112
- routesByPath,
1113
- processedTree
1114
- }) {
1115
- this.routesById = routesById;
1116
- this.routesByPath = routesByPath;
1117
- this.processedTree = processedTree;
1118
- const notFoundRoute = this.options.notFoundRoute;
1119
- if (notFoundRoute) {
1120
- notFoundRoute.init({
1121
- originalIndex: 99999999999
1122
- });
1123
- this.routesById[notFoundRoute.id] = notFoundRoute;
1124
- }
1125
- }
1126
- get looseRoutesById() {
1127
- return this.routesById;
1128
- }
1129
- getParentContext(parentMatch) {
1130
- const parentMatchId = parentMatch?.id;
1131
- const parentContext = !parentMatchId ? this.options.context ?? void 0 : parentMatch.context ?? this.options.context ?? void 0;
1132
- return parentContext;
1133
- }
1134
- matchRoutesInternal(next, opts) {
1135
- const matchedRoutesResult = this.getMatchedRoutes(next.pathname);
1136
- const { foundRoute, routeParams, parsedParams } = matchedRoutesResult;
1137
- let { matchedRoutes } = matchedRoutesResult;
1138
- let isGlobalNotFound = false;
1139
- if (
1140
- // If we found a route, and it's not an index route and we have left over path
1141
- foundRoute ? foundRoute.path !== "/" && routeParams["**"] : (
1142
- // Or if we didn't find a route and we have left over path
1143
- path.trimPathRight(next.pathname)
1144
- )
1145
- ) {
1146
- if (this.options.notFoundRoute) {
1147
- matchedRoutes = [...matchedRoutes, this.options.notFoundRoute];
1148
- } else {
1149
- isGlobalNotFound = true;
1150
- }
1151
- }
1152
- const globalNotFoundRouteId = isGlobalNotFound ? findGlobalNotFoundRouteId(this.options.notFoundMode, matchedRoutes) : void 0;
1153
- const matches = new Array(matchedRoutes.length);
1154
- const previousMatchesByRouteId = new Map(
1155
- this.state.matches.map((match) => [match.routeId, match])
1156
- );
1157
- for (let index = 0; index < matchedRoutes.length; index++) {
1158
- const route = matchedRoutes[index];
1159
- const parentMatch = matches[index - 1];
1160
- let preMatchSearch;
1161
- let strictMatchSearch;
1162
- let searchError;
1163
- {
1164
- const parentSearch = parentMatch?.search ?? next.search;
1165
- const parentStrictSearch = parentMatch?._strictSearch ?? void 0;
1166
- try {
1167
- const strictSearch = validateSearch(route.options.validateSearch, { ...parentSearch }) ?? void 0;
1168
- preMatchSearch = {
1169
- ...parentSearch,
1170
- ...strictSearch
1171
- };
1172
- strictMatchSearch = { ...parentStrictSearch, ...strictSearch };
1173
- searchError = void 0;
1174
- } catch (err) {
1175
- let searchParamError = err;
1176
- if (!(err instanceof SearchParamError)) {
1177
- searchParamError = new SearchParamError(err.message, {
1178
- cause: err
1179
- });
1180
- }
1181
- if (opts?.throwOnError) {
1182
- throw searchParamError;
1183
- }
1184
- preMatchSearch = parentSearch;
1185
- strictMatchSearch = {};
1186
- searchError = searchParamError;
1187
- }
1188
- }
1189
- const loaderDeps = route.options.loaderDeps?.({
1190
- search: preMatchSearch
1191
- }) ?? "";
1192
- const loaderDepsHash = loaderDeps ? JSON.stringify(loaderDeps) : "";
1193
- const { interpolatedPath, usedParams } = path.interpolatePath({
1194
- path: route.fullPath,
1195
- params: routeParams,
1196
- decoder: this.pathParamsDecoder,
1197
- server: this.isServer
1198
- });
1199
- const matchId = (
1200
- // route.id for disambiguation
1201
- route.id + // interpolatedPath for param changes
1202
- interpolatedPath + // explicit deps
1203
- loaderDepsHash
1204
- );
1205
- const existingMatch = this.getMatch(matchId);
1206
- const previousMatch = previousMatchesByRouteId.get(route.id);
1207
- const strictParams = existingMatch?._strictParams ?? usedParams;
1208
- let paramsError = void 0;
1209
- if (!existingMatch) {
1210
- try {
1211
- extractStrictParams(route, usedParams, parsedParams, strictParams);
1212
- } catch (err) {
1213
- if (notFound.isNotFound(err) || redirect.isRedirect(err)) {
1214
- paramsError = err;
1215
- } else {
1216
- paramsError = new PathParamError(err.message, {
1217
- cause: err
1218
- });
1219
- }
1220
- if (opts?.throwOnError) {
1221
- throw paramsError;
1222
- }
1223
- }
1224
- }
1225
- Object.assign(routeParams, strictParams);
1226
- const cause = previousMatch ? "stay" : "enter";
1227
- let match;
1228
- if (existingMatch) {
1229
- match = {
1230
- ...existingMatch,
1231
- cause,
1232
- params: previousMatch?.params ?? routeParams,
1233
- _strictParams: strictParams,
1234
- search: previousMatch ? utils.nullReplaceEqualDeep(previousMatch.search, preMatchSearch) : utils.nullReplaceEqualDeep(existingMatch.search, preMatchSearch),
1235
- _strictSearch: strictMatchSearch
1236
- };
1237
- } else {
1238
- const status = route.options.loader || route.options.beforeLoad || route.lazyFn || loadMatches.routeNeedsPreload(route) ? "pending" : "success";
1239
- match = {
1240
- id: matchId,
1241
- ssr: isServer.isServer ?? this.isServer ? void 0 : route.options.ssr,
1242
- index,
1243
- routeId: route.id,
1244
- params: previousMatch?.params ?? routeParams,
1245
- _strictParams: strictParams,
1246
- pathname: interpolatedPath,
1247
- updatedAt: Date.now(),
1248
- search: previousMatch ? utils.nullReplaceEqualDeep(previousMatch.search, preMatchSearch) : preMatchSearch,
1249
- _strictSearch: strictMatchSearch,
1250
- searchError: void 0,
1251
- status,
1252
- isFetching: false,
1253
- error: void 0,
1254
- paramsError,
1255
- __routeContext: void 0,
1256
- _nonReactive: {
1257
- loadPromise: utils.createControlledPromise()
1258
- },
1259
- __beforeLoadContext: void 0,
1260
- context: {},
1261
- abortController: new AbortController(),
1262
- fetchCount: 0,
1263
- cause,
1264
- loaderDeps: previousMatch ? utils.replaceEqualDeep(previousMatch.loaderDeps, loaderDeps) : loaderDeps,
1265
- invalid: false,
1266
- preload: false,
1267
- links: void 0,
1268
- scripts: void 0,
1269
- headScripts: void 0,
1270
- meta: void 0,
1271
- staticData: route.options.staticData || {},
1272
- fullPath: route.fullPath
1273
- };
1274
- }
1275
- if (!opts?.preload) {
1276
- match.globalNotFound = globalNotFoundRouteId === route.id;
1277
- }
1278
- match.searchError = searchError;
1279
- const parentContext = this.getParentContext(parentMatch);
1280
- match.context = {
1281
- ...parentContext,
1282
- ...match.__routeContext,
1283
- ...match.__beforeLoadContext
1284
- };
1285
- matches[index] = match;
1286
- }
1287
- for (let index = 0; index < matches.length; index++) {
1288
- const match = matches[index];
1289
- const route = this.looseRoutesById[match.routeId];
1290
- const existingMatch = this.getMatch(match.id);
1291
- const previousMatch = previousMatchesByRouteId.get(match.routeId);
1292
- match.params = previousMatch ? utils.nullReplaceEqualDeep(previousMatch.params, routeParams) : routeParams;
1293
- if (!existingMatch) {
1294
- const parentMatch = matches[index - 1];
1295
- const parentContext = this.getParentContext(parentMatch);
1296
- if (route.options.context) {
1297
- const contextFnContext = {
1298
- deps: match.loaderDeps,
1299
- params: match.params,
1300
- context: parentContext ?? {},
1301
- location: next,
1302
- navigate: (opts2) => this.navigate({ ...opts2, _fromLocation: next }),
1303
- buildLocation: this.buildLocation,
1304
- cause: match.cause,
1305
- abortController: match.abortController,
1306
- preload: !!match.preload,
1307
- matches,
1308
- routeId: route.id
1309
- };
1310
- match.__routeContext = route.options.context(contextFnContext) ?? void 0;
1311
- }
1312
- match.context = {
1313
- ...parentContext,
1314
- ...match.__routeContext,
1315
- ...match.__beforeLoadContext
1316
- };
1317
- }
1318
- }
1319
- return matches;
1320
- }
1321
- /**
1322
- * Lightweight route matching for buildLocation.
1323
- * Only computes fullPath, accumulated search, and params - skipping expensive
1324
- * operations like AbortController, ControlledPromise, loaderDeps, and full match objects.
1325
- */
1326
- matchRoutesLightweight(location) {
1327
- const { matchedRoutes, routeParams, parsedParams } = this.getMatchedRoutes(
1328
- location.pathname
1329
- );
1330
- const lastRoute = utils.last(matchedRoutes);
1331
- const accumulatedSearch = { ...location.search };
1332
- for (const route of matchedRoutes) {
1333
- try {
1334
- Object.assign(
1335
- accumulatedSearch,
1336
- validateSearch(route.options.validateSearch, accumulatedSearch)
1337
- );
1338
- } catch {
1339
- }
1340
- }
1341
- const lastStateMatch = utils.last(this.state.matches);
1342
- const canReuseParams = lastStateMatch && lastStateMatch.routeId === lastRoute.id && location.pathname === this.state.location.pathname;
1343
- let params;
1344
- if (canReuseParams) {
1345
- params = lastStateMatch.params;
1346
- } else {
1347
- const strictParams = Object.assign(
1348
- /* @__PURE__ */ Object.create(null),
1349
- routeParams
1350
- );
1351
- for (const route of matchedRoutes) {
1352
- try {
1353
- extractStrictParams(
1354
- route,
1355
- routeParams,
1356
- parsedParams ?? {},
1357
- strictParams
1358
- );
1359
- } catch {
1360
- }
1361
- }
1362
- params = strictParams;
1363
- }
1364
- return {
1365
- matchedRoutes,
1366
- fullPath: lastRoute.fullPath,
1367
- search: accumulatedSearch,
1368
- params
1369
- };
1370
- }
1371
- }
1372
- class SearchParamError extends Error {
1373
- }
1374
- class PathParamError extends Error {
1375
- }
1376
- const normalize = (str) => str.endsWith("/") && str.length > 1 ? str.slice(0, -1) : str;
67
+ var RouterCore = class {
68
+ /**
69
+ * @deprecated Use the `createRouter` function instead
70
+ */
71
+ constructor(options) {
72
+ this.tempLocationKey = `${Math.round(Math.random() * 1e7)}`;
73
+ this.resetNextScroll = true;
74
+ this.shouldViewTransition = void 0;
75
+ this.isViewTransitionTypesSupported = void 0;
76
+ this.subscribers = /* @__PURE__ */ new Set();
77
+ this.isScrollRestoring = false;
78
+ this.isScrollRestorationSetup = false;
79
+ this.startTransition = (fn) => fn();
80
+ this.update = (newOptions) => {
81
+ if (process.env.NODE_ENV !== "production") {
82
+ if (newOptions.notFoundRoute) console.warn("The notFoundRoute API is deprecated and will be removed in the next major version. See https://tanstack.com/router/v1/docs/framework/react/guide/not-found-errors#migrating-from-notfoundroute for more info.");
83
+ }
84
+ const prevOptions = this.options;
85
+ const prevBasepath = this.basepath ?? prevOptions?.basepath ?? "/";
86
+ const basepathWasUnset = this.basepath === void 0;
87
+ const prevRewriteOption = prevOptions?.rewrite;
88
+ this.options = {
89
+ ...prevOptions,
90
+ ...newOptions
91
+ };
92
+ this.isServer = this.options.isServer ?? typeof document === "undefined";
93
+ this.protocolAllowlist = new Set(this.options.protocolAllowlist);
94
+ if (this.options.pathParamsAllowedCharacters) this.pathParamsDecoder = require_path.compileDecodeCharMap(this.options.pathParamsAllowedCharacters);
95
+ if (!this.history || this.options.history && this.options.history !== this.history) if (!this.options.history) {
96
+ if (!(_tanstack_router_core_isServer.isServer ?? this.isServer)) this.history = (0, _tanstack_history.createBrowserHistory)();
97
+ } else this.history = this.options.history;
98
+ this.origin = this.options.origin;
99
+ if (!this.origin) if (!(_tanstack_router_core_isServer.isServer ?? this.isServer) && window?.origin && window.origin !== "null") this.origin = window.origin;
100
+ else this.origin = "http://localhost";
101
+ if (this.history) this.updateLatestLocation();
102
+ if (this.options.routeTree !== this.routeTree) {
103
+ this.routeTree = this.options.routeTree;
104
+ let processRouteTreeResult;
105
+ if ((_tanstack_router_core_isServer.isServer ?? this.isServer) && process.env.NODE_ENV !== "development" && globalThis.__TSR_CACHE__ && globalThis.__TSR_CACHE__.routeTree === this.routeTree) {
106
+ const cached = globalThis.__TSR_CACHE__;
107
+ this.resolvePathCache = cached.resolvePathCache;
108
+ processRouteTreeResult = cached.processRouteTreeResult;
109
+ } else {
110
+ this.resolvePathCache = require_lru_cache.createLRUCache(1e3);
111
+ processRouteTreeResult = this.buildRouteTree();
112
+ if ((_tanstack_router_core_isServer.isServer ?? this.isServer) && process.env.NODE_ENV !== "development" && globalThis.__TSR_CACHE__ === void 0) globalThis.__TSR_CACHE__ = {
113
+ routeTree: this.routeTree,
114
+ processRouteTreeResult,
115
+ resolvePathCache: this.resolvePathCache
116
+ };
117
+ }
118
+ this.setRoutes(processRouteTreeResult);
119
+ }
120
+ if (!this.__store && this.latestLocation) if (_tanstack_router_core_isServer.isServer ?? this.isServer) this.__store = createServerStore(getInitialRouterState(this.latestLocation));
121
+ else {
122
+ this.__store = (0, _tanstack_store.createStore)(getInitialRouterState(this.latestLocation));
123
+ require_scroll_restoration.setupScrollRestoration(this);
124
+ }
125
+ let needsLocationUpdate = false;
126
+ const nextBasepath = this.options.basepath ?? "/";
127
+ const nextRewriteOption = this.options.rewrite;
128
+ if (basepathWasUnset || prevBasepath !== nextBasepath || prevRewriteOption !== nextRewriteOption) {
129
+ this.basepath = nextBasepath;
130
+ const rewrites = [];
131
+ const trimmed = require_path.trimPath(nextBasepath);
132
+ if (trimmed && trimmed !== "/") rewrites.push(require_rewrite.rewriteBasepath({ basepath: nextBasepath }));
133
+ if (nextRewriteOption) rewrites.push(nextRewriteOption);
134
+ this.rewrite = rewrites.length === 0 ? void 0 : rewrites.length === 1 ? rewrites[0] : require_rewrite.composeRewrites(rewrites);
135
+ if (this.history) this.updateLatestLocation();
136
+ needsLocationUpdate = true;
137
+ }
138
+ if (needsLocationUpdate && this.__store) this.__store.setState((s) => ({
139
+ ...s,
140
+ location: this.latestLocation
141
+ }));
142
+ if (typeof window !== "undefined" && "CSS" in window && typeof window.CSS?.supports === "function") this.isViewTransitionTypesSupported = window.CSS.supports("selector(:active-view-transition-type(a)");
143
+ };
144
+ this.updateLatestLocation = () => {
145
+ this.latestLocation = this.parseLocation(this.history.location, this.latestLocation);
146
+ };
147
+ this.buildRouteTree = () => {
148
+ const result = require_new_process_route_tree.processRouteTree(this.routeTree, this.options.caseSensitive, (route, i) => {
149
+ route.init({ originalIndex: i });
150
+ });
151
+ if (this.options.routeMasks) require_new_process_route_tree.processRouteMasks(this.options.routeMasks, result.processedTree);
152
+ return result;
153
+ };
154
+ this.subscribe = (eventType, fn) => {
155
+ const listener = {
156
+ eventType,
157
+ fn
158
+ };
159
+ this.subscribers.add(listener);
160
+ return () => {
161
+ this.subscribers.delete(listener);
162
+ };
163
+ };
164
+ this.emit = (routerEvent) => {
165
+ this.subscribers.forEach((listener) => {
166
+ if (listener.eventType === routerEvent.type) listener.fn(routerEvent);
167
+ });
168
+ };
169
+ this.parseLocation = (locationToParse, previousLocation) => {
170
+ const parse = ({ pathname, search, hash, href, state }) => {
171
+ if (!this.rewrite && !/[ \x00-\x1f\x7f\u0080-\uffff]/.test(pathname)) {
172
+ const parsedSearch = this.options.parseSearch(search);
173
+ const searchStr = this.options.stringifySearch(parsedSearch);
174
+ return {
175
+ href: pathname + searchStr + hash,
176
+ publicHref: href,
177
+ pathname: require_utils.decodePath(pathname).path,
178
+ external: false,
179
+ searchStr,
180
+ search: require_utils.nullReplaceEqualDeep(previousLocation?.search, parsedSearch),
181
+ hash: require_utils.decodePath(hash.slice(1)).path,
182
+ state: require_utils.replaceEqualDeep(previousLocation?.state, state)
183
+ };
184
+ }
185
+ const fullUrl = new URL(href, this.origin);
186
+ const url = require_rewrite.executeRewriteInput(this.rewrite, fullUrl);
187
+ const parsedSearch = this.options.parseSearch(url.search);
188
+ const searchStr = this.options.stringifySearch(parsedSearch);
189
+ url.search = searchStr;
190
+ return {
191
+ href: url.href.replace(url.origin, ""),
192
+ publicHref: href,
193
+ pathname: require_utils.decodePath(url.pathname).path,
194
+ external: !!this.rewrite && url.origin !== this.origin,
195
+ searchStr,
196
+ search: require_utils.nullReplaceEqualDeep(previousLocation?.search, parsedSearch),
197
+ hash: require_utils.decodePath(url.hash.slice(1)).path,
198
+ state: require_utils.replaceEqualDeep(previousLocation?.state, state)
199
+ };
200
+ };
201
+ const location = parse(locationToParse);
202
+ const { __tempLocation, __tempKey } = location.state;
203
+ if (__tempLocation && (!__tempKey || __tempKey === this.tempLocationKey)) {
204
+ const parsedTempLocation = parse(__tempLocation);
205
+ parsedTempLocation.state.key = location.state.key;
206
+ parsedTempLocation.state.__TSR_key = location.state.__TSR_key;
207
+ delete parsedTempLocation.state.__tempLocation;
208
+ return {
209
+ ...parsedTempLocation,
210
+ maskedLocation: location
211
+ };
212
+ }
213
+ return location;
214
+ };
215
+ this.resolvePathWithBase = (from, path) => {
216
+ return require_path.resolvePath({
217
+ base: from,
218
+ to: require_path.cleanPath(path),
219
+ trailingSlash: this.options.trailingSlash,
220
+ cache: this.resolvePathCache
221
+ });
222
+ };
223
+ this.matchRoutes = (pathnameOrNext, locationSearchOrOpts, opts) => {
224
+ if (typeof pathnameOrNext === "string") return this.matchRoutesInternal({
225
+ pathname: pathnameOrNext,
226
+ search: locationSearchOrOpts
227
+ }, opts);
228
+ return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts);
229
+ };
230
+ this.getMatchedRoutes = (pathname) => {
231
+ return getMatchedRoutes({
232
+ pathname,
233
+ routesById: this.routesById,
234
+ processedTree: this.processedTree
235
+ });
236
+ };
237
+ this.cancelMatch = (id) => {
238
+ const match = this.getMatch(id);
239
+ if (!match) return;
240
+ match.abortController.abort();
241
+ clearTimeout(match._nonReactive.pendingTimeout);
242
+ match._nonReactive.pendingTimeout = void 0;
243
+ };
244
+ this.cancelMatches = () => {
245
+ const currentPendingMatches = this.state.matches.filter((match) => match.status === "pending");
246
+ const currentLoadingMatches = this.state.matches.filter((match) => match.isFetching === "loader");
247
+ new Set([
248
+ ...this.state.pendingMatches ?? [],
249
+ ...currentPendingMatches,
250
+ ...currentLoadingMatches
251
+ ]).forEach((match) => {
252
+ this.cancelMatch(match.id);
253
+ });
254
+ };
255
+ this.buildLocation = (opts) => {
256
+ const build = (dest = {}) => {
257
+ const currentLocation = dest._fromLocation || this.pendingBuiltLocation || this.latestLocation;
258
+ const lightweightResult = this.matchRoutesLightweight(currentLocation);
259
+ if (dest.from && process.env.NODE_ENV !== "production" && dest._isNavigate) {
260
+ const allFromMatches = this.getMatchedRoutes(dest.from).matchedRoutes;
261
+ const matchedFrom = require_utils.findLast(lightweightResult.matchedRoutes, (d) => {
262
+ return comparePaths(d.fullPath, dest.from);
263
+ });
264
+ const matchedCurrent = require_utils.findLast(allFromMatches, (d) => {
265
+ return comparePaths(d.fullPath, lightweightResult.fullPath);
266
+ });
267
+ if (!matchedFrom && !matchedCurrent) console.warn(`Could not find match for from: ${dest.from}`);
268
+ }
269
+ const defaultedFromPath = dest.unsafeRelative === "path" ? currentLocation.pathname : dest.from ?? lightweightResult.fullPath;
270
+ const fromPath = this.resolvePathWithBase(defaultedFromPath, ".");
271
+ const fromSearch = lightweightResult.search;
272
+ const fromParams = Object.assign(Object.create(null), lightweightResult.params);
273
+ const nextTo = dest.to ? this.resolvePathWithBase(fromPath, `${dest.to}`) : this.resolvePathWithBase(fromPath, ".");
274
+ const nextParams = dest.params === false || dest.params === null ? Object.create(null) : (dest.params ?? true) === true ? fromParams : Object.assign(fromParams, require_utils.functionalUpdate(dest.params, fromParams));
275
+ const destMatchResult = this.getMatchedRoutes(nextTo);
276
+ let destRoutes = destMatchResult.matchedRoutes;
277
+ if ((!destMatchResult.foundRoute || destMatchResult.foundRoute.path !== "/" && destMatchResult.routeParams["**"]) && this.options.notFoundRoute) destRoutes = [...destRoutes, this.options.notFoundRoute];
278
+ if (Object.keys(nextParams).length > 0) for (const route of destRoutes) {
279
+ const fn = route.options.params?.stringify ?? route.options.stringifyParams;
280
+ if (fn) try {
281
+ Object.assign(nextParams, fn(nextParams));
282
+ } catch {}
283
+ }
284
+ const nextPathname = opts.leaveParams ? nextTo : require_utils.decodePath(require_path.interpolatePath({
285
+ path: nextTo,
286
+ params: nextParams,
287
+ decoder: this.pathParamsDecoder,
288
+ server: this.isServer
289
+ }).interpolatedPath).path;
290
+ let nextSearch = fromSearch;
291
+ if (opts._includeValidateSearch && this.options.search?.strict) {
292
+ const validatedSearch = {};
293
+ destRoutes.forEach((route) => {
294
+ if (route.options.validateSearch) try {
295
+ Object.assign(validatedSearch, validateSearch(route.options.validateSearch, {
296
+ ...validatedSearch,
297
+ ...nextSearch
298
+ }));
299
+ } catch {}
300
+ });
301
+ nextSearch = validatedSearch;
302
+ }
303
+ nextSearch = applySearchMiddleware({
304
+ search: nextSearch,
305
+ dest,
306
+ destRoutes,
307
+ _includeValidateSearch: opts._includeValidateSearch
308
+ });
309
+ nextSearch = require_utils.nullReplaceEqualDeep(fromSearch, nextSearch);
310
+ const searchStr = this.options.stringifySearch(nextSearch);
311
+ const hash = dest.hash === true ? currentLocation.hash : dest.hash ? require_utils.functionalUpdate(dest.hash, currentLocation.hash) : void 0;
312
+ const hashStr = hash ? `#${hash}` : "";
313
+ let nextState = dest.state === true ? currentLocation.state : dest.state ? require_utils.functionalUpdate(dest.state, currentLocation.state) : {};
314
+ nextState = require_utils.replaceEqualDeep(currentLocation.state, nextState);
315
+ const fullPath = `${nextPathname}${searchStr}${hashStr}`;
316
+ let href;
317
+ let publicHref;
318
+ let external = false;
319
+ if (this.rewrite) {
320
+ const url = new URL(fullPath, this.origin);
321
+ const rewrittenUrl = require_rewrite.executeRewriteOutput(this.rewrite, url);
322
+ href = url.href.replace(url.origin, "");
323
+ if (rewrittenUrl.origin !== this.origin) {
324
+ publicHref = rewrittenUrl.href;
325
+ external = true;
326
+ } else publicHref = rewrittenUrl.pathname + rewrittenUrl.search + rewrittenUrl.hash;
327
+ } else {
328
+ href = require_utils.encodePathLikeUrl(fullPath);
329
+ publicHref = href;
330
+ }
331
+ return {
332
+ publicHref,
333
+ href,
334
+ pathname: nextPathname,
335
+ search: nextSearch,
336
+ searchStr,
337
+ state: nextState,
338
+ hash: hash ?? "",
339
+ external,
340
+ unmaskOnReload: dest.unmaskOnReload
341
+ };
342
+ };
343
+ const buildWithMatches = (dest = {}, maskedDest) => {
344
+ const next = build(dest);
345
+ let maskedNext = maskedDest ? build(maskedDest) : void 0;
346
+ if (!maskedNext) {
347
+ const params = Object.create(null);
348
+ if (this.options.routeMasks) {
349
+ const match = require_new_process_route_tree.findFlatMatch(next.pathname, this.processedTree);
350
+ if (match) {
351
+ Object.assign(params, match.rawParams);
352
+ const { from: _from, params: maskParams, ...maskProps } = match.route;
353
+ const nextParams = maskParams === false || maskParams === null ? Object.create(null) : (maskParams ?? true) === true ? params : Object.assign(params, require_utils.functionalUpdate(maskParams, params));
354
+ maskedDest = {
355
+ from: opts.from,
356
+ ...maskProps,
357
+ params: nextParams
358
+ };
359
+ maskedNext = build(maskedDest);
360
+ }
361
+ }
362
+ }
363
+ if (maskedNext) next.maskedLocation = maskedNext;
364
+ return next;
365
+ };
366
+ if (opts.mask) return buildWithMatches(opts, {
367
+ from: opts.from,
368
+ ...opts.mask
369
+ });
370
+ return buildWithMatches(opts);
371
+ };
372
+ this.commitLocation = async ({ viewTransition, ignoreBlocker, ...next }) => {
373
+ const isSameState = () => {
374
+ const ignoredProps = [
375
+ "key",
376
+ "__TSR_key",
377
+ "__TSR_index",
378
+ "__hashScrollIntoViewOptions"
379
+ ];
380
+ ignoredProps.forEach((prop) => {
381
+ next.state[prop] = this.latestLocation.state[prop];
382
+ });
383
+ const isEqual = require_utils.deepEqual(next.state, this.latestLocation.state);
384
+ ignoredProps.forEach((prop) => {
385
+ delete next.state[prop];
386
+ });
387
+ return isEqual;
388
+ };
389
+ const isSameUrl = require_path.trimPathRight(this.latestLocation.href) === require_path.trimPathRight(next.href);
390
+ const previousCommitPromise = this.commitLocationPromise;
391
+ this.commitLocationPromise = require_utils.createControlledPromise(() => {
392
+ previousCommitPromise?.resolve();
393
+ });
394
+ if (isSameUrl && isSameState()) this.load();
395
+ else {
396
+ let { maskedLocation, hashScrollIntoView, ...nextHistory } = next;
397
+ if (maskedLocation) {
398
+ nextHistory = {
399
+ ...maskedLocation,
400
+ state: {
401
+ ...maskedLocation.state,
402
+ __tempKey: void 0,
403
+ __tempLocation: {
404
+ ...nextHistory,
405
+ search: nextHistory.searchStr,
406
+ state: {
407
+ ...nextHistory.state,
408
+ __tempKey: void 0,
409
+ __tempLocation: void 0,
410
+ __TSR_key: void 0,
411
+ key: void 0
412
+ }
413
+ }
414
+ }
415
+ };
416
+ if (nextHistory.unmaskOnReload ?? this.options.unmaskOnReload ?? false) nextHistory.state.__tempKey = this.tempLocationKey;
417
+ }
418
+ nextHistory.state.__hashScrollIntoViewOptions = hashScrollIntoView ?? this.options.defaultHashScrollIntoView ?? true;
419
+ this.shouldViewTransition = viewTransition;
420
+ this.history[next.replace ? "replace" : "push"](nextHistory.publicHref, nextHistory.state, { ignoreBlocker });
421
+ }
422
+ this.resetNextScroll = next.resetScroll ?? true;
423
+ if (!this.history.subscribers.size) this.load();
424
+ return this.commitLocationPromise;
425
+ };
426
+ this.buildAndCommitLocation = ({ replace, resetScroll, hashScrollIntoView, viewTransition, ignoreBlocker, href, ...rest } = {}) => {
427
+ if (href) {
428
+ const currentIndex = this.history.location.state.__TSR_index;
429
+ const parsed = (0, _tanstack_history.parseHref)(href, { __TSR_index: replace ? currentIndex : currentIndex + 1 });
430
+ const hrefUrl = new URL(parsed.pathname, this.origin);
431
+ rest.to = require_rewrite.executeRewriteInput(this.rewrite, hrefUrl).pathname;
432
+ rest.search = this.options.parseSearch(parsed.search);
433
+ rest.hash = parsed.hash.slice(1);
434
+ }
435
+ const location = this.buildLocation({
436
+ ...rest,
437
+ _includeValidateSearch: true
438
+ });
439
+ this.pendingBuiltLocation = location;
440
+ const commitPromise = this.commitLocation({
441
+ ...location,
442
+ viewTransition,
443
+ replace,
444
+ resetScroll,
445
+ hashScrollIntoView,
446
+ ignoreBlocker
447
+ });
448
+ Promise.resolve().then(() => {
449
+ if (this.pendingBuiltLocation === location) this.pendingBuiltLocation = void 0;
450
+ });
451
+ return commitPromise;
452
+ };
453
+ this.navigate = async ({ to, reloadDocument, href, publicHref, ...rest }) => {
454
+ let hrefIsUrl = false;
455
+ if (href) try {
456
+ new URL(`${href}`);
457
+ hrefIsUrl = true;
458
+ } catch {}
459
+ if (hrefIsUrl && !reloadDocument) reloadDocument = true;
460
+ if (reloadDocument) {
461
+ if (to !== void 0 || !href) {
462
+ const location = this.buildLocation({
463
+ to,
464
+ ...rest
465
+ });
466
+ href = href ?? location.publicHref;
467
+ publicHref = publicHref ?? location.publicHref;
468
+ }
469
+ const reloadHref = !hrefIsUrl && publicHref ? publicHref : href;
470
+ if (require_utils.isDangerousProtocol(reloadHref, this.protocolAllowlist)) {
471
+ if (process.env.NODE_ENV !== "production") console.warn(`Blocked navigation to dangerous protocol: ${reloadHref}`);
472
+ return Promise.resolve();
473
+ }
474
+ if (!rest.ignoreBlocker) {
475
+ const blockers = this.history.getBlockers?.() ?? [];
476
+ for (const blocker of blockers) if (blocker?.blockerFn) {
477
+ if (await blocker.blockerFn({
478
+ currentLocation: this.latestLocation,
479
+ nextLocation: this.latestLocation,
480
+ action: "PUSH"
481
+ })) return Promise.resolve();
482
+ }
483
+ }
484
+ if (rest.replace) window.location.replace(reloadHref);
485
+ else window.location.href = reloadHref;
486
+ return Promise.resolve();
487
+ }
488
+ return this.buildAndCommitLocation({
489
+ ...rest,
490
+ href,
491
+ to,
492
+ _isNavigate: true
493
+ });
494
+ };
495
+ this.beforeLoad = () => {
496
+ this.cancelMatches();
497
+ this.updateLatestLocation();
498
+ if (_tanstack_router_core_isServer.isServer ?? this.isServer) {
499
+ const nextLocation = this.buildLocation({
500
+ to: this.latestLocation.pathname,
501
+ search: true,
502
+ params: true,
503
+ hash: true,
504
+ state: true,
505
+ _includeValidateSearch: true
506
+ });
507
+ if (this.latestLocation.publicHref !== nextLocation.publicHref) {
508
+ const href = this.getParsedLocationHref(nextLocation);
509
+ if (nextLocation.external) throw require_redirect.redirect({ href });
510
+ else throw require_redirect.redirect({
511
+ href,
512
+ _builtLocation: nextLocation
513
+ });
514
+ }
515
+ }
516
+ const pendingMatches = this.matchRoutes(this.latestLocation);
517
+ this.__store.setState((s) => ({
518
+ ...s,
519
+ status: "pending",
520
+ statusCode: 200,
521
+ isLoading: true,
522
+ location: this.latestLocation,
523
+ pendingMatches,
524
+ cachedMatches: s.cachedMatches.filter((d) => !pendingMatches.some((e) => e.id === d.id))
525
+ }));
526
+ };
527
+ this.load = async (opts) => {
528
+ let redirect;
529
+ let notFound;
530
+ let loadPromise;
531
+ const previousLocation = this.state.resolvedLocation ?? this.state.location;
532
+ loadPromise = new Promise((resolve) => {
533
+ this.startTransition(async () => {
534
+ try {
535
+ this.beforeLoad();
536
+ const next = this.latestLocation;
537
+ const prevLocation = this.state.resolvedLocation;
538
+ if (!this.state.redirect) this.emit({
539
+ type: "onBeforeNavigate",
540
+ ...getLocationChangeInfo({
541
+ resolvedLocation: prevLocation,
542
+ location: next
543
+ })
544
+ });
545
+ this.emit({
546
+ type: "onBeforeLoad",
547
+ ...getLocationChangeInfo({
548
+ resolvedLocation: prevLocation,
549
+ location: next
550
+ })
551
+ });
552
+ await require_load_matches.loadMatches({
553
+ router: this,
554
+ sync: opts?.sync,
555
+ forceStaleReload: previousLocation.href === next.href,
556
+ matches: this.state.pendingMatches,
557
+ location: next,
558
+ updateMatch: this.updateMatch,
559
+ onReady: async () => {
560
+ this.startTransition(() => {
561
+ this.startViewTransition(async () => {
562
+ let exitingMatches = [];
563
+ let hookExitingMatches = [];
564
+ let hookEnteringMatches = [];
565
+ let hookStayingMatches = [];
566
+ require_batch.batch(() => {
567
+ this.__store.setState((s) => {
568
+ const previousMatches = s.matches;
569
+ const newMatches = s.pendingMatches || s.matches;
570
+ exitingMatches = previousMatches.filter((match) => !newMatches.some((d) => d.id === match.id));
571
+ hookExitingMatches = previousMatches.filter((match) => !newMatches.some((d) => d.routeId === match.routeId));
572
+ hookEnteringMatches = newMatches.filter((match) => !previousMatches.some((d) => d.routeId === match.routeId));
573
+ hookStayingMatches = newMatches.filter((match) => previousMatches.some((d) => d.routeId === match.routeId));
574
+ return {
575
+ ...s,
576
+ isLoading: false,
577
+ loadedAt: Date.now(),
578
+ matches: newMatches,
579
+ pendingMatches: void 0,
580
+ cachedMatches: [...s.cachedMatches, ...exitingMatches.filter((d) => d.status !== "error" && d.status !== "notFound" && d.status !== "redirected")]
581
+ };
582
+ });
583
+ this.clearExpiredCache();
584
+ });
585
+ [
586
+ [hookExitingMatches, "onLeave"],
587
+ [hookEnteringMatches, "onEnter"],
588
+ [hookStayingMatches, "onStay"]
589
+ ].forEach(([matches, hook]) => {
590
+ matches.forEach((match) => {
591
+ this.looseRoutesById[match.routeId].options[hook]?.(match);
592
+ });
593
+ });
594
+ });
595
+ });
596
+ }
597
+ });
598
+ } catch (err) {
599
+ if (require_redirect.isRedirect(err)) {
600
+ redirect = err;
601
+ if (!(_tanstack_router_core_isServer.isServer ?? this.isServer)) this.navigate({
602
+ ...redirect.options,
603
+ replace: true,
604
+ ignoreBlocker: true
605
+ });
606
+ } else if (require_not_found.isNotFound(err)) notFound = err;
607
+ this.__store.setState((s) => ({
608
+ ...s,
609
+ statusCode: redirect ? redirect.status : notFound ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200,
610
+ redirect
611
+ }));
612
+ }
613
+ if (this.latestLoadPromise === loadPromise) {
614
+ this.commitLocationPromise?.resolve();
615
+ this.latestLoadPromise = void 0;
616
+ this.commitLocationPromise = void 0;
617
+ }
618
+ resolve();
619
+ });
620
+ });
621
+ this.latestLoadPromise = loadPromise;
622
+ await loadPromise;
623
+ while (this.latestLoadPromise && loadPromise !== this.latestLoadPromise) await this.latestLoadPromise;
624
+ let newStatusCode = void 0;
625
+ if (this.hasNotFoundMatch()) newStatusCode = 404;
626
+ else if (this.__store.state.matches.some((d) => d.status === "error")) newStatusCode = 500;
627
+ if (newStatusCode !== void 0) this.__store.setState((s) => ({
628
+ ...s,
629
+ statusCode: newStatusCode
630
+ }));
631
+ };
632
+ this.startViewTransition = (fn) => {
633
+ const shouldViewTransition = this.shouldViewTransition ?? this.options.defaultViewTransition;
634
+ this.shouldViewTransition = void 0;
635
+ if (shouldViewTransition && typeof document !== "undefined" && "startViewTransition" in document && typeof document.startViewTransition === "function") {
636
+ let startViewTransitionParams;
637
+ if (typeof shouldViewTransition === "object" && this.isViewTransitionTypesSupported) {
638
+ const next = this.latestLocation;
639
+ const prevLocation = this.state.resolvedLocation;
640
+ const resolvedViewTransitionTypes = typeof shouldViewTransition.types === "function" ? shouldViewTransition.types(getLocationChangeInfo({
641
+ resolvedLocation: prevLocation,
642
+ location: next
643
+ })) : shouldViewTransition.types;
644
+ if (resolvedViewTransitionTypes === false) {
645
+ fn();
646
+ return;
647
+ }
648
+ startViewTransitionParams = {
649
+ update: fn,
650
+ types: resolvedViewTransitionTypes
651
+ };
652
+ } else startViewTransitionParams = fn;
653
+ document.startViewTransition(startViewTransitionParams);
654
+ } else fn();
655
+ };
656
+ this.updateMatch = (id, updater) => {
657
+ this.startTransition(() => {
658
+ const matchesKey = this.state.pendingMatches?.some((d) => d.id === id) ? "pendingMatches" : this.state.matches.some((d) => d.id === id) ? "matches" : this.state.cachedMatches.some((d) => d.id === id) ? "cachedMatches" : "";
659
+ if (matchesKey) if (matchesKey === "cachedMatches") this.__store.setState((s) => ({
660
+ ...s,
661
+ cachedMatches: filterRedirectedCachedMatches(s.cachedMatches.map((d) => d.id === id ? updater(d) : d))
662
+ }));
663
+ else this.__store.setState((s) => ({
664
+ ...s,
665
+ [matchesKey]: s[matchesKey]?.map((d) => d.id === id ? updater(d) : d)
666
+ }));
667
+ });
668
+ };
669
+ this.getMatch = (matchId) => {
670
+ const findFn = (d) => d.id === matchId;
671
+ return this.state.cachedMatches.find(findFn) ?? this.state.pendingMatches?.find(findFn) ?? this.state.matches.find(findFn);
672
+ };
673
+ this.invalidate = (opts) => {
674
+ const invalidate = (d) => {
675
+ if (opts?.filter?.(d) ?? true) return {
676
+ ...d,
677
+ invalid: true,
678
+ ...opts?.forcePending || d.status === "error" || d.status === "notFound" ? {
679
+ status: "pending",
680
+ error: void 0
681
+ } : void 0
682
+ };
683
+ return d;
684
+ };
685
+ this.__store.setState((s) => ({
686
+ ...s,
687
+ matches: s.matches.map(invalidate),
688
+ cachedMatches: s.cachedMatches.map(invalidate),
689
+ pendingMatches: s.pendingMatches?.map(invalidate)
690
+ }));
691
+ this.shouldViewTransition = false;
692
+ return this.load({ sync: opts?.sync });
693
+ };
694
+ this.getParsedLocationHref = (location) => {
695
+ return location.publicHref || "/";
696
+ };
697
+ this.resolveRedirect = (redirect) => {
698
+ const locationHeader = redirect.headers.get("Location");
699
+ if (!redirect.options.href || redirect.options._builtLocation) {
700
+ const location = redirect.options._builtLocation ?? this.buildLocation(redirect.options);
701
+ const href = this.getParsedLocationHref(location);
702
+ redirect.options.href = href;
703
+ redirect.headers.set("Location", href);
704
+ } else if (locationHeader) try {
705
+ const url = new URL(locationHeader);
706
+ if (this.origin && url.origin === this.origin) {
707
+ const href = url.pathname + url.search + url.hash;
708
+ redirect.options.href = href;
709
+ redirect.headers.set("Location", href);
710
+ }
711
+ } catch {}
712
+ if (redirect.options.href && !redirect.options._builtLocation && require_utils.isDangerousProtocol(redirect.options.href, this.protocolAllowlist)) throw new Error(process.env.NODE_ENV !== "production" ? `Redirect blocked: unsafe protocol in href "${redirect.options.href}". Allowed protocols: ${Array.from(this.protocolAllowlist).join(", ")}.` : "Redirect blocked: unsafe protocol");
713
+ if (!redirect.headers.get("Location")) redirect.headers.set("Location", redirect.options.href);
714
+ return redirect;
715
+ };
716
+ this.clearCache = (opts) => {
717
+ const filter = opts?.filter;
718
+ if (filter !== void 0) this.__store.setState((s) => {
719
+ return {
720
+ ...s,
721
+ cachedMatches: s.cachedMatches.filter((m) => !filter(m))
722
+ };
723
+ });
724
+ else this.__store.setState((s) => {
725
+ return {
726
+ ...s,
727
+ cachedMatches: []
728
+ };
729
+ });
730
+ };
731
+ this.clearExpiredCache = () => {
732
+ const filter = (d) => {
733
+ const route = this.looseRoutesById[d.routeId];
734
+ if (!route.options.loader) return true;
735
+ const gcTime = (d.preload ? route.options.preloadGcTime ?? this.options.defaultPreloadGcTime : route.options.gcTime ?? this.options.defaultGcTime) ?? 300 * 1e3;
736
+ if (d.status === "error") return true;
737
+ return Date.now() - d.updatedAt >= gcTime;
738
+ };
739
+ this.clearCache({ filter });
740
+ };
741
+ this.loadRouteChunk = require_load_matches.loadRouteChunk;
742
+ this.preloadRoute = async (opts) => {
743
+ const next = opts._builtLocation ?? this.buildLocation(opts);
744
+ let matches = this.matchRoutes(next, {
745
+ throwOnError: true,
746
+ preload: true,
747
+ dest: opts
748
+ });
749
+ const activeMatchIds = new Set([...this.state.matches, ...this.state.pendingMatches ?? []].map((d) => d.id));
750
+ const loadedMatchIds = new Set([...activeMatchIds, ...this.state.cachedMatches.map((d) => d.id)]);
751
+ require_batch.batch(() => {
752
+ matches.forEach((match) => {
753
+ if (!loadedMatchIds.has(match.id)) this.__store.setState((s) => ({
754
+ ...s,
755
+ cachedMatches: [...s.cachedMatches, match]
756
+ }));
757
+ });
758
+ });
759
+ try {
760
+ matches = await require_load_matches.loadMatches({
761
+ router: this,
762
+ matches,
763
+ location: next,
764
+ preload: true,
765
+ updateMatch: (id, updater) => {
766
+ if (activeMatchIds.has(id)) matches = matches.map((d) => d.id === id ? updater(d) : d);
767
+ else this.updateMatch(id, updater);
768
+ }
769
+ });
770
+ return matches;
771
+ } catch (err) {
772
+ if (require_redirect.isRedirect(err)) {
773
+ if (err.options.reloadDocument) return;
774
+ return await this.preloadRoute({
775
+ ...err.options,
776
+ _fromLocation: next
777
+ });
778
+ }
779
+ if (!require_not_found.isNotFound(err)) console.error(err);
780
+ return;
781
+ }
782
+ };
783
+ this.matchRoute = (location, opts) => {
784
+ const matchLocation = {
785
+ ...location,
786
+ to: location.to ? this.resolvePathWithBase(location.from || "", location.to) : void 0,
787
+ params: location.params || {},
788
+ leaveParams: true
789
+ };
790
+ const next = this.buildLocation(matchLocation);
791
+ if (opts?.pending && this.state.status !== "pending") return false;
792
+ const baseLocation = (opts?.pending === void 0 ? !this.state.isLoading : opts.pending) ? this.latestLocation : this.state.resolvedLocation || this.state.location;
793
+ const match = require_new_process_route_tree.findSingleMatch(next.pathname, opts?.caseSensitive ?? false, opts?.fuzzy ?? false, baseLocation.pathname, this.processedTree);
794
+ if (!match) return false;
795
+ if (location.params) {
796
+ if (!require_utils.deepEqual(match.rawParams, location.params, { partial: true })) return false;
797
+ }
798
+ if (opts?.includeSearch ?? true) return require_utils.deepEqual(baseLocation.search, next.search, { partial: true }) ? match.rawParams : false;
799
+ return match.rawParams;
800
+ };
801
+ this.hasNotFoundMatch = () => {
802
+ return this.__store.state.matches.some((d) => d.status === "notFound" || d.globalNotFound);
803
+ };
804
+ this.update({
805
+ defaultPreloadDelay: 50,
806
+ defaultPendingMs: 1e3,
807
+ defaultPendingMinMs: 500,
808
+ context: void 0,
809
+ ...options,
810
+ caseSensitive: options.caseSensitive ?? false,
811
+ notFoundMode: options.notFoundMode ?? "fuzzy",
812
+ stringifySearch: options.stringifySearch ?? require_searchParams.defaultStringifySearch,
813
+ parseSearch: options.parseSearch ?? require_searchParams.defaultParseSearch,
814
+ protocolAllowlist: options.protocolAllowlist ?? require_utils.DEFAULT_PROTOCOL_ALLOWLIST
815
+ });
816
+ if (typeof document !== "undefined") self.__TSR_ROUTER__ = this;
817
+ }
818
+ isShell() {
819
+ return !!this.options.isShell;
820
+ }
821
+ isPrerendering() {
822
+ return !!this.options.isPrerendering;
823
+ }
824
+ get state() {
825
+ return this.__store.state;
826
+ }
827
+ setRoutes({ routesById, routesByPath, processedTree }) {
828
+ this.routesById = routesById;
829
+ this.routesByPath = routesByPath;
830
+ this.processedTree = processedTree;
831
+ const notFoundRoute = this.options.notFoundRoute;
832
+ if (notFoundRoute) {
833
+ notFoundRoute.init({ originalIndex: 99999999999 });
834
+ this.routesById[notFoundRoute.id] = notFoundRoute;
835
+ }
836
+ }
837
+ get looseRoutesById() {
838
+ return this.routesById;
839
+ }
840
+ getParentContext(parentMatch) {
841
+ return !parentMatch?.id ? this.options.context ?? void 0 : parentMatch.context ?? this.options.context ?? void 0;
842
+ }
843
+ matchRoutesInternal(next, opts) {
844
+ const matchedRoutesResult = this.getMatchedRoutes(next.pathname);
845
+ const { foundRoute, routeParams, parsedParams } = matchedRoutesResult;
846
+ let { matchedRoutes } = matchedRoutesResult;
847
+ let isGlobalNotFound = false;
848
+ if (foundRoute ? foundRoute.path !== "/" && routeParams["**"] : require_path.trimPathRight(next.pathname)) if (this.options.notFoundRoute) matchedRoutes = [...matchedRoutes, this.options.notFoundRoute];
849
+ else isGlobalNotFound = true;
850
+ const globalNotFoundRouteId = isGlobalNotFound ? findGlobalNotFoundRouteId(this.options.notFoundMode, matchedRoutes) : void 0;
851
+ const matches = new Array(matchedRoutes.length);
852
+ const previousMatchesByRouteId = new Map(this.state.matches.map((match) => [match.routeId, match]));
853
+ for (let index = 0; index < matchedRoutes.length; index++) {
854
+ const route = matchedRoutes[index];
855
+ const parentMatch = matches[index - 1];
856
+ let preMatchSearch;
857
+ let strictMatchSearch;
858
+ let searchError;
859
+ {
860
+ const parentSearch = parentMatch?.search ?? next.search;
861
+ const parentStrictSearch = parentMatch?._strictSearch ?? void 0;
862
+ try {
863
+ const strictSearch = validateSearch(route.options.validateSearch, { ...parentSearch }) ?? void 0;
864
+ preMatchSearch = {
865
+ ...parentSearch,
866
+ ...strictSearch
867
+ };
868
+ strictMatchSearch = {
869
+ ...parentStrictSearch,
870
+ ...strictSearch
871
+ };
872
+ searchError = void 0;
873
+ } catch (err) {
874
+ let searchParamError = err;
875
+ if (!(err instanceof SearchParamError)) searchParamError = new SearchParamError(err.message, { cause: err });
876
+ if (opts?.throwOnError) throw searchParamError;
877
+ preMatchSearch = parentSearch;
878
+ strictMatchSearch = {};
879
+ searchError = searchParamError;
880
+ }
881
+ }
882
+ const loaderDeps = route.options.loaderDeps?.({ search: preMatchSearch }) ?? "";
883
+ const loaderDepsHash = loaderDeps ? JSON.stringify(loaderDeps) : "";
884
+ const { interpolatedPath, usedParams } = require_path.interpolatePath({
885
+ path: route.fullPath,
886
+ params: routeParams,
887
+ decoder: this.pathParamsDecoder,
888
+ server: this.isServer
889
+ });
890
+ const matchId = route.id + interpolatedPath + loaderDepsHash;
891
+ const existingMatch = this.getMatch(matchId);
892
+ const previousMatch = previousMatchesByRouteId.get(route.id);
893
+ const strictParams = existingMatch?._strictParams ?? usedParams;
894
+ let paramsError = void 0;
895
+ if (!existingMatch) try {
896
+ extractStrictParams(route, usedParams, parsedParams, strictParams);
897
+ } catch (err) {
898
+ if (require_not_found.isNotFound(err) || require_redirect.isRedirect(err)) paramsError = err;
899
+ else paramsError = new PathParamError(err.message, { cause: err });
900
+ if (opts?.throwOnError) throw paramsError;
901
+ }
902
+ Object.assign(routeParams, strictParams);
903
+ const cause = previousMatch ? "stay" : "enter";
904
+ let match;
905
+ if (existingMatch) match = {
906
+ ...existingMatch,
907
+ cause,
908
+ params: previousMatch?.params ?? routeParams,
909
+ _strictParams: strictParams,
910
+ search: previousMatch ? require_utils.nullReplaceEqualDeep(previousMatch.search, preMatchSearch) : require_utils.nullReplaceEqualDeep(existingMatch.search, preMatchSearch),
911
+ _strictSearch: strictMatchSearch
912
+ };
913
+ else {
914
+ const status = route.options.loader || route.options.beforeLoad || route.lazyFn || require_load_matches.routeNeedsPreload(route) ? "pending" : "success";
915
+ match = {
916
+ id: matchId,
917
+ ssr: _tanstack_router_core_isServer.isServer ?? this.isServer ? void 0 : route.options.ssr,
918
+ index,
919
+ routeId: route.id,
920
+ params: previousMatch?.params ?? routeParams,
921
+ _strictParams: strictParams,
922
+ pathname: interpolatedPath,
923
+ updatedAt: Date.now(),
924
+ search: previousMatch ? require_utils.nullReplaceEqualDeep(previousMatch.search, preMatchSearch) : preMatchSearch,
925
+ _strictSearch: strictMatchSearch,
926
+ searchError: void 0,
927
+ status,
928
+ isFetching: false,
929
+ error: void 0,
930
+ paramsError,
931
+ __routeContext: void 0,
932
+ _nonReactive: { loadPromise: require_utils.createControlledPromise() },
933
+ __beforeLoadContext: void 0,
934
+ context: {},
935
+ abortController: new AbortController(),
936
+ fetchCount: 0,
937
+ cause,
938
+ loaderDeps: previousMatch ? require_utils.replaceEqualDeep(previousMatch.loaderDeps, loaderDeps) : loaderDeps,
939
+ invalid: false,
940
+ preload: false,
941
+ links: void 0,
942
+ scripts: void 0,
943
+ headScripts: void 0,
944
+ meta: void 0,
945
+ staticData: route.options.staticData || {},
946
+ fullPath: route.fullPath
947
+ };
948
+ }
949
+ if (!opts?.preload) match.globalNotFound = globalNotFoundRouteId === route.id;
950
+ match.searchError = searchError;
951
+ const parentContext = this.getParentContext(parentMatch);
952
+ match.context = {
953
+ ...parentContext,
954
+ ...match.__routeContext,
955
+ ...match.__beforeLoadContext
956
+ };
957
+ matches[index] = match;
958
+ }
959
+ for (let index = 0; index < matches.length; index++) {
960
+ const match = matches[index];
961
+ const route = this.looseRoutesById[match.routeId];
962
+ const existingMatch = this.getMatch(match.id);
963
+ const previousMatch = previousMatchesByRouteId.get(match.routeId);
964
+ match.params = previousMatch ? require_utils.nullReplaceEqualDeep(previousMatch.params, routeParams) : routeParams;
965
+ if (!existingMatch) {
966
+ const parentMatch = matches[index - 1];
967
+ const parentContext = this.getParentContext(parentMatch);
968
+ if (route.options.context) {
969
+ const contextFnContext = {
970
+ deps: match.loaderDeps,
971
+ params: match.params,
972
+ context: parentContext ?? {},
973
+ location: next,
974
+ navigate: (opts) => this.navigate({
975
+ ...opts,
976
+ _fromLocation: next
977
+ }),
978
+ buildLocation: this.buildLocation,
979
+ cause: match.cause,
980
+ abortController: match.abortController,
981
+ preload: !!match.preload,
982
+ matches,
983
+ routeId: route.id
984
+ };
985
+ match.__routeContext = route.options.context(contextFnContext) ?? void 0;
986
+ }
987
+ match.context = {
988
+ ...parentContext,
989
+ ...match.__routeContext,
990
+ ...match.__beforeLoadContext
991
+ };
992
+ }
993
+ }
994
+ return matches;
995
+ }
996
+ /**
997
+ * Lightweight route matching for buildLocation.
998
+ * Only computes fullPath, accumulated search, and params - skipping expensive
999
+ * operations like AbortController, ControlledPromise, loaderDeps, and full match objects.
1000
+ */
1001
+ matchRoutesLightweight(location) {
1002
+ const { matchedRoutes, routeParams, parsedParams } = this.getMatchedRoutes(location.pathname);
1003
+ const lastRoute = require_utils.last(matchedRoutes);
1004
+ const accumulatedSearch = { ...location.search };
1005
+ for (const route of matchedRoutes) try {
1006
+ Object.assign(accumulatedSearch, validateSearch(route.options.validateSearch, accumulatedSearch));
1007
+ } catch {}
1008
+ const lastStateMatch = require_utils.last(this.state.matches);
1009
+ const canReuseParams = lastStateMatch && lastStateMatch.routeId === lastRoute.id && location.pathname === this.state.location.pathname;
1010
+ let params;
1011
+ if (canReuseParams) params = lastStateMatch.params;
1012
+ else {
1013
+ const strictParams = Object.assign(Object.create(null), routeParams);
1014
+ for (const route of matchedRoutes) try {
1015
+ extractStrictParams(route, routeParams, parsedParams ?? {}, strictParams);
1016
+ } catch {}
1017
+ params = strictParams;
1018
+ }
1019
+ return {
1020
+ matchedRoutes,
1021
+ fullPath: lastRoute.fullPath,
1022
+ search: accumulatedSearch,
1023
+ params
1024
+ };
1025
+ }
1026
+ };
1027
+ /** Error thrown when search parameter validation fails. */
1028
+ var SearchParamError = class extends Error {};
1029
+ /** Error thrown when path parameter parsing/validation fails. */
1030
+ var PathParamError = class extends Error {};
1031
+ var normalize = (str) => str.endsWith("/") && str.length > 1 ? str.slice(0, -1) : str;
1377
1032
  function comparePaths(a, b) {
1378
- return normalize(a) === normalize(b);
1033
+ return normalize(a) === normalize(b);
1379
1034
  }
1035
+ /**
1036
+ * Lazily import a module function and forward arguments to it, retaining
1037
+ * parameter and return types for the selected export key.
1038
+ */
1380
1039
  function lazyFn(fn, key) {
1381
- return async (...args) => {
1382
- const imported = await fn();
1383
- return imported[key || "default"](...args);
1384
- };
1040
+ return async (...args) => {
1041
+ return (await fn())[key || "default"](...args);
1042
+ };
1385
1043
  }
1044
+ /** Create an initial RouterState from a parsed location. */
1386
1045
  function getInitialRouterState(location) {
1387
- return {
1388
- loadedAt: 0,
1389
- isLoading: false,
1390
- isTransitioning: false,
1391
- status: "idle",
1392
- resolvedLocation: void 0,
1393
- location,
1394
- matches: [],
1395
- pendingMatches: [],
1396
- cachedMatches: [],
1397
- statusCode: 200
1398
- };
1046
+ return {
1047
+ loadedAt: 0,
1048
+ isLoading: false,
1049
+ isTransitioning: false,
1050
+ status: "idle",
1051
+ resolvedLocation: void 0,
1052
+ location,
1053
+ matches: [],
1054
+ pendingMatches: [],
1055
+ cachedMatches: [],
1056
+ statusCode: 200
1057
+ };
1399
1058
  }
1400
- function validateSearch(validateSearch2, input) {
1401
- if (validateSearch2 == null) return {};
1402
- if ("~standard" in validateSearch2) {
1403
- const result = validateSearch2["~standard"].validate(input);
1404
- if (result instanceof Promise)
1405
- throw new SearchParamError("Async validation not supported");
1406
- if (result.issues)
1407
- throw new SearchParamError(JSON.stringify(result.issues, void 0, 2), {
1408
- cause: result
1409
- });
1410
- return result.value;
1411
- }
1412
- if ("parse" in validateSearch2) {
1413
- return validateSearch2.parse(input);
1414
- }
1415
- if (typeof validateSearch2 === "function") {
1416
- return validateSearch2(input);
1417
- }
1418
- return {};
1059
+ function validateSearch(validateSearch, input) {
1060
+ if (validateSearch == null) return {};
1061
+ if ("~standard" in validateSearch) {
1062
+ const result = validateSearch["~standard"].validate(input);
1063
+ if (result instanceof Promise) throw new SearchParamError("Async validation not supported");
1064
+ if (result.issues) throw new SearchParamError(JSON.stringify(result.issues, void 0, 2), { cause: result });
1065
+ return result.value;
1066
+ }
1067
+ if ("parse" in validateSearch) return validateSearch.parse(input);
1068
+ if (typeof validateSearch === "function") return validateSearch(input);
1069
+ return {};
1419
1070
  }
1420
- function getMatchedRoutes({
1421
- pathname,
1422
- routesById,
1423
- processedTree
1424
- }) {
1425
- const routeParams = /* @__PURE__ */ Object.create(null);
1426
- const trimmedPath = path.trimPathRight(pathname);
1427
- let foundRoute = void 0;
1428
- let parsedParams = void 0;
1429
- const match = newProcessRouteTree.findRouteMatch(trimmedPath, processedTree, true);
1430
- if (match) {
1431
- foundRoute = match.route;
1432
- Object.assign(routeParams, match.rawParams);
1433
- parsedParams = Object.assign(/* @__PURE__ */ Object.create(null), match.parsedParams);
1434
- }
1435
- const matchedRoutes = match?.branch || [routesById[root.rootRouteId]];
1436
- return { matchedRoutes, routeParams, foundRoute, parsedParams };
1071
+ /**
1072
+ * Build the matched route chain and extract params for a pathname.
1073
+ * Falls back to the root route if no specific route is found.
1074
+ */
1075
+ function getMatchedRoutes({ pathname, routesById, processedTree }) {
1076
+ const routeParams = Object.create(null);
1077
+ const trimmedPath = require_path.trimPathRight(pathname);
1078
+ let foundRoute = void 0;
1079
+ let parsedParams = void 0;
1080
+ const match = require_new_process_route_tree.findRouteMatch(trimmedPath, processedTree, true);
1081
+ if (match) {
1082
+ foundRoute = match.route;
1083
+ Object.assign(routeParams, match.rawParams);
1084
+ parsedParams = Object.assign(Object.create(null), match.parsedParams);
1085
+ }
1086
+ return {
1087
+ matchedRoutes: match?.branch || [routesById["__root__"]],
1088
+ routeParams,
1089
+ foundRoute,
1090
+ parsedParams
1091
+ };
1437
1092
  }
1438
- function applySearchMiddleware({
1439
- search,
1440
- dest,
1441
- destRoutes,
1442
- _includeValidateSearch
1443
- }) {
1444
- const middleware = buildMiddlewareChain(destRoutes);
1445
- return middleware(search, dest, _includeValidateSearch ?? false);
1093
+ /**
1094
+ * TODO: once caches are persisted across requests on the server,
1095
+ * we can cache the built middleware chain using `last(destRoutes)` as the key
1096
+ */
1097
+ function applySearchMiddleware({ search, dest, destRoutes, _includeValidateSearch }) {
1098
+ return buildMiddlewareChain(destRoutes)(search, dest, _includeValidateSearch ?? false);
1446
1099
  }
1447
1100
  function buildMiddlewareChain(destRoutes) {
1448
- const context = {
1449
- dest: null,
1450
- _includeValidateSearch: false,
1451
- middlewares: []
1452
- };
1453
- for (const route of destRoutes) {
1454
- if ("search" in route.options) {
1455
- if (route.options.search?.middlewares) {
1456
- context.middlewares.push(...route.options.search.middlewares);
1457
- }
1458
- } else if (route.options.preSearchFilters || route.options.postSearchFilters) {
1459
- const legacyMiddleware = ({ search, next }) => {
1460
- let nextSearch = search;
1461
- if ("preSearchFilters" in route.options && route.options.preSearchFilters) {
1462
- nextSearch = route.options.preSearchFilters.reduce(
1463
- (prev, next2) => next2(prev),
1464
- search
1465
- );
1466
- }
1467
- const result = next(nextSearch);
1468
- if ("postSearchFilters" in route.options && route.options.postSearchFilters) {
1469
- return route.options.postSearchFilters.reduce(
1470
- (prev, next2) => next2(prev),
1471
- result
1472
- );
1473
- }
1474
- return result;
1475
- };
1476
- context.middlewares.push(legacyMiddleware);
1477
- }
1478
- if (route.options.validateSearch) {
1479
- const validate = ({ search, next }) => {
1480
- const result = next(search);
1481
- if (!context._includeValidateSearch) return result;
1482
- try {
1483
- const validatedSearch = {
1484
- ...result,
1485
- ...validateSearch(route.options.validateSearch, result) ?? void 0
1486
- };
1487
- return validatedSearch;
1488
- } catch {
1489
- return result;
1490
- }
1491
- };
1492
- context.middlewares.push(validate);
1493
- }
1494
- }
1495
- const final = ({ search }) => {
1496
- const dest = context.dest;
1497
- if (!dest.search) {
1498
- return {};
1499
- }
1500
- if (dest.search === true) {
1501
- return search;
1502
- }
1503
- return utils.functionalUpdate(dest.search, search);
1504
- };
1505
- context.middlewares.push(final);
1506
- const applyNext = (index, currentSearch, middlewares) => {
1507
- if (index >= middlewares.length) {
1508
- return currentSearch;
1509
- }
1510
- const middleware = middlewares[index];
1511
- const next = (newSearch) => {
1512
- return applyNext(index + 1, newSearch, middlewares);
1513
- };
1514
- return middleware({ search: currentSearch, next });
1515
- };
1516
- return function middleware(search, dest, _includeValidateSearch) {
1517
- context.dest = dest;
1518
- context._includeValidateSearch = _includeValidateSearch;
1519
- return applyNext(0, search, context.middlewares);
1520
- };
1101
+ const context = {
1102
+ dest: null,
1103
+ _includeValidateSearch: false,
1104
+ middlewares: []
1105
+ };
1106
+ for (const route of destRoutes) {
1107
+ if ("search" in route.options) {
1108
+ if (route.options.search?.middlewares) context.middlewares.push(...route.options.search.middlewares);
1109
+ } else if (route.options.preSearchFilters || route.options.postSearchFilters) {
1110
+ const legacyMiddleware = ({ search, next }) => {
1111
+ let nextSearch = search;
1112
+ if ("preSearchFilters" in route.options && route.options.preSearchFilters) nextSearch = route.options.preSearchFilters.reduce((prev, next) => next(prev), search);
1113
+ const result = next(nextSearch);
1114
+ if ("postSearchFilters" in route.options && route.options.postSearchFilters) return route.options.postSearchFilters.reduce((prev, next) => next(prev), result);
1115
+ return result;
1116
+ };
1117
+ context.middlewares.push(legacyMiddleware);
1118
+ }
1119
+ if (route.options.validateSearch) {
1120
+ const validate = ({ search, next }) => {
1121
+ const result = next(search);
1122
+ if (!context._includeValidateSearch) return result;
1123
+ try {
1124
+ return {
1125
+ ...result,
1126
+ ...validateSearch(route.options.validateSearch, result) ?? void 0
1127
+ };
1128
+ } catch {
1129
+ return result;
1130
+ }
1131
+ };
1132
+ context.middlewares.push(validate);
1133
+ }
1134
+ }
1135
+ const final = ({ search }) => {
1136
+ const dest = context.dest;
1137
+ if (!dest.search) return {};
1138
+ if (dest.search === true) return search;
1139
+ return require_utils.functionalUpdate(dest.search, search);
1140
+ };
1141
+ context.middlewares.push(final);
1142
+ const applyNext = (index, currentSearch, middlewares) => {
1143
+ if (index >= middlewares.length) return currentSearch;
1144
+ const middleware = middlewares[index];
1145
+ const next = (newSearch) => {
1146
+ return applyNext(index + 1, newSearch, middlewares);
1147
+ };
1148
+ return middleware({
1149
+ search: currentSearch,
1150
+ next
1151
+ });
1152
+ };
1153
+ return function middleware(search, dest, _includeValidateSearch) {
1154
+ context.dest = dest;
1155
+ context._includeValidateSearch = _includeValidateSearch;
1156
+ return applyNext(0, search, context.middlewares);
1157
+ };
1521
1158
  }
1522
1159
  function findGlobalNotFoundRouteId(notFoundMode, routes) {
1523
- if (notFoundMode !== "root") {
1524
- for (let i = routes.length - 1; i >= 0; i--) {
1525
- const route = routes[i];
1526
- if (route.children) {
1527
- return route.id;
1528
- }
1529
- }
1530
- }
1531
- return root.rootRouteId;
1160
+ if (notFoundMode !== "root") for (let i = routes.length - 1; i >= 0; i--) {
1161
+ const route = routes[i];
1162
+ if (route.children) return route.id;
1163
+ }
1164
+ return require_root.rootRouteId;
1532
1165
  }
1533
1166
  function extractStrictParams(route, referenceParams, parsedParams, accumulatedParams) {
1534
- const parseParams = route.options.params?.parse ?? route.options.parseParams;
1535
- if (parseParams) {
1536
- if (route.options.skipRouteOnParseError) {
1537
- for (const key in referenceParams) {
1538
- if (key in parsedParams) {
1539
- accumulatedParams[key] = parsedParams[key];
1540
- }
1541
- }
1542
- } else {
1543
- const result = parseParams(accumulatedParams);
1544
- Object.assign(accumulatedParams, result);
1545
- }
1546
- }
1167
+ const parseParams = route.options.params?.parse ?? route.options.parseParams;
1168
+ if (parseParams) if (route.options.skipRouteOnParseError) {
1169
+ for (const key in referenceParams) if (key in parsedParams) accumulatedParams[key] = parsedParams[key];
1170
+ } else {
1171
+ const result = parseParams(accumulatedParams);
1172
+ Object.assign(accumulatedParams, result);
1173
+ }
1547
1174
  }
1175
+ //#endregion
1548
1176
  exports.PathParamError = PathParamError;
1549
1177
  exports.RouterCore = RouterCore;
1550
1178
  exports.SearchParamError = SearchParamError;
@@ -1554,4 +1182,5 @@ exports.getLocationChangeInfo = getLocationChangeInfo;
1554
1182
  exports.getMatchedRoutes = getMatchedRoutes;
1555
1183
  exports.lazyFn = lazyFn;
1556
1184
  exports.trailingSlashOptions = trailingSlashOptions;
1557
- //# sourceMappingURL=router.cjs.map
1185
+
1186
+ //# sourceMappingURL=router.cjs.map