@tanstack/router-core 1.171.15 → 1.171.16

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 (149) hide show
  1. package/dist/cjs/Matches.cjs.map +1 -1
  2. package/dist/cjs/Matches.d.cts +3 -12
  3. package/dist/cjs/await-signal.cjs +21 -0
  4. package/dist/cjs/await-signal.cjs.map +1 -0
  5. package/dist/cjs/await-signal.d.cts +1 -0
  6. package/dist/cjs/index.cjs +3 -1
  7. package/dist/cjs/index.d.cts +3 -2
  8. package/dist/cjs/isServer/client.cjs +2 -0
  9. package/dist/cjs/isServer/client.cjs.map +1 -1
  10. package/dist/cjs/isServer/client.d.cts +1 -0
  11. package/dist/cjs/isServer/development.cjs +2 -0
  12. package/dist/cjs/isServer/development.cjs.map +1 -1
  13. package/dist/cjs/isServer/development.d.cts +1 -0
  14. package/dist/cjs/isServer/server.cjs +2 -0
  15. package/dist/cjs/isServer/server.cjs.map +1 -1
  16. package/dist/cjs/isServer/server.d.cts +1 -0
  17. package/dist/cjs/link.cjs.map +1 -1
  18. package/dist/cjs/link.d.cts +5 -3
  19. package/dist/cjs/load-client.cjs +1393 -0
  20. package/dist/cjs/load-client.cjs.map +1 -0
  21. package/dist/cjs/load-client.d.cts +118 -0
  22. package/dist/cjs/load-server.cjs +565 -0
  23. package/dist/cjs/load-server.cjs.map +1 -0
  24. package/dist/cjs/load-server.d.cts +16 -0
  25. package/dist/cjs/redirect.cjs.map +1 -1
  26. package/dist/cjs/redirect.d.cts +0 -1
  27. package/dist/cjs/route.cjs.map +1 -1
  28. package/dist/cjs/router.cjs +204 -439
  29. package/dist/cjs/router.cjs.map +1 -1
  30. package/dist/cjs/router.d.cts +68 -54
  31. package/dist/cjs/ssr/client.cjs +2 -2
  32. package/dist/cjs/ssr/createRequestHandler.cjs +60 -9
  33. package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -1
  34. package/dist/cjs/ssr/createRequestHandler.d.cts +1 -0
  35. package/dist/cjs/ssr/handlerCallback.cjs +49 -4
  36. package/dist/cjs/ssr/handlerCallback.cjs.map +1 -1
  37. package/dist/cjs/ssr/handlerCallback.d.cts +3 -0
  38. package/dist/cjs/ssr/server.cjs +4 -0
  39. package/dist/cjs/ssr/server.d.cts +2 -2
  40. package/dist/cjs/ssr/ssr-client.d.cts +1 -10
  41. package/dist/cjs/ssr/ssr-match-id.cjs +2 -2
  42. package/dist/cjs/ssr/ssr-match-id.cjs.map +1 -1
  43. package/dist/cjs/ssr/ssr-server.cjs +6 -6
  44. package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
  45. package/dist/cjs/ssr/transformStreamWithRouter.cjs +27 -1
  46. package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -1
  47. package/dist/cjs/ssr/transformStreamWithRouter.d.cts +2 -0
  48. package/dist/cjs/ssr/types.d.cts +0 -1
  49. package/dist/cjs/stores.cjs +30 -104
  50. package/dist/cjs/stores.cjs.map +1 -1
  51. package/dist/cjs/stores.d.cts +7 -32
  52. package/dist/cjs/utils.cjs +0 -4
  53. package/dist/cjs/utils.cjs.map +1 -1
  54. package/dist/esm/Matches.d.ts +3 -12
  55. package/dist/esm/Matches.js.map +1 -1
  56. package/dist/esm/await-signal.d.ts +1 -0
  57. package/dist/esm/await-signal.js +21 -0
  58. package/dist/esm/await-signal.js.map +1 -0
  59. package/dist/esm/index.d.ts +3 -2
  60. package/dist/esm/index.js +3 -2
  61. package/dist/esm/isServer/client.d.ts +1 -0
  62. package/dist/esm/isServer/client.js +2 -1
  63. package/dist/esm/isServer/client.js.map +1 -1
  64. package/dist/esm/isServer/development.d.ts +1 -0
  65. package/dist/esm/isServer/development.js +2 -1
  66. package/dist/esm/isServer/development.js.map +1 -1
  67. package/dist/esm/isServer/server.d.ts +1 -0
  68. package/dist/esm/isServer/server.js +2 -1
  69. package/dist/esm/isServer/server.js.map +1 -1
  70. package/dist/esm/link.d.ts +5 -3
  71. package/dist/esm/link.js.map +1 -1
  72. package/dist/esm/load-client.d.ts +118 -0
  73. package/dist/esm/load-client.js +1386 -0
  74. package/dist/esm/load-client.js.map +1 -0
  75. package/dist/esm/load-server.d.ts +16 -0
  76. package/dist/esm/load-server.js +565 -0
  77. package/dist/esm/load-server.js.map +1 -0
  78. package/dist/esm/redirect.d.ts +0 -1
  79. package/dist/esm/redirect.js.map +1 -1
  80. package/dist/esm/route.js.map +1 -1
  81. package/dist/esm/router.d.ts +68 -54
  82. package/dist/esm/router.js +207 -442
  83. package/dist/esm/router.js.map +1 -1
  84. package/dist/esm/ssr/client.js +1 -1
  85. package/dist/esm/ssr/createRequestHandler.d.ts +1 -0
  86. package/dist/esm/ssr/createRequestHandler.js +61 -11
  87. package/dist/esm/ssr/createRequestHandler.js.map +1 -1
  88. package/dist/esm/ssr/handlerCallback.d.ts +3 -0
  89. package/dist/esm/ssr/handlerCallback.js +47 -5
  90. package/dist/esm/ssr/handlerCallback.js.map +1 -1
  91. package/dist/esm/ssr/server.d.ts +2 -2
  92. package/dist/esm/ssr/server.js +3 -3
  93. package/dist/esm/ssr/ssr-client.d.ts +1 -10
  94. package/dist/esm/ssr/ssr-match-id.js +2 -2
  95. package/dist/esm/ssr/ssr-match-id.js.map +1 -1
  96. package/dist/esm/ssr/ssr-server.js +6 -6
  97. package/dist/esm/ssr/ssr-server.js.map +1 -1
  98. package/dist/esm/ssr/transformStreamWithRouter.d.ts +2 -0
  99. package/dist/esm/ssr/transformStreamWithRouter.js +27 -1
  100. package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -1
  101. package/dist/esm/ssr/types.d.ts +0 -1
  102. package/dist/esm/stores.d.ts +7 -32
  103. package/dist/esm/stores.js +30 -104
  104. package/dist/esm/stores.js.map +1 -1
  105. package/dist/esm/utils.js +1 -4
  106. package/dist/esm/utils.js.map +1 -1
  107. package/package.json +3 -3
  108. package/skills/router-core/SKILL.md +23 -4
  109. package/skills/router-core/auth-and-guards/SKILL.md +10 -10
  110. package/skills/router-core/code-splitting/SKILL.md +5 -4
  111. package/skills/router-core/data-loading/SKILL.md +30 -18
  112. package/skills/router-core/navigation/SKILL.md +5 -4
  113. package/skills/router-core/not-found-and-errors/SKILL.md +5 -4
  114. package/skills/router-core/path-params/SKILL.md +5 -4
  115. package/skills/router-core/search-params/SKILL.md +5 -4
  116. package/skills/router-core/ssr/SKILL.md +5 -4
  117. package/skills/router-core/type-safety/SKILL.md +11 -4
  118. package/src/Matches.ts +6 -21
  119. package/src/await-signal.ts +27 -0
  120. package/src/index.ts +1 -3
  121. package/src/isServer/client.ts +1 -0
  122. package/src/isServer/development.ts +1 -0
  123. package/src/isServer/server.ts +1 -0
  124. package/src/link.ts +5 -3
  125. package/src/load-client.ts +2651 -0
  126. package/src/load-server.ts +849 -0
  127. package/src/redirect.ts +0 -1
  128. package/src/route.ts +2 -11
  129. package/src/router.ts +426 -773
  130. package/src/ssr/createRequestHandler.ts +109 -16
  131. package/src/ssr/handlerCallback.ts +76 -10
  132. package/src/ssr/server.ts +4 -1
  133. package/src/ssr/ssr-client.ts +1 -310
  134. package/src/ssr/ssr-match-id.ts +11 -2
  135. package/src/ssr/ssr-server.ts +9 -8
  136. package/src/ssr/transformStreamWithRouter.ts +37 -1
  137. package/src/ssr/types.ts +0 -1
  138. package/src/stores.ts +46 -208
  139. package/dist/cjs/load-matches.cjs +0 -658
  140. package/dist/cjs/load-matches.cjs.map +0 -1
  141. package/dist/cjs/load-matches.d.cts +0 -18
  142. package/dist/cjs/ssr/ssr-client.cjs +0 -183
  143. package/dist/cjs/ssr/ssr-client.cjs.map +0 -1
  144. package/dist/esm/load-matches.d.ts +0 -18
  145. package/dist/esm/load-matches.js +0 -656
  146. package/dist/esm/load-matches.js.map +0 -1
  147. package/dist/esm/ssr/ssr-client.js +0 -183
  148. package/dist/esm/ssr/ssr-client.js.map +0 -1
  149. package/src/load-matches.ts +0 -1278
@@ -7,12 +7,15 @@ const require_scroll_restoration = require("./scroll-restoration.cjs");
7
7
  const require_searchParams = require("./searchParams.cjs");
8
8
  const require_root = require("./root.cjs");
9
9
  const require_redirect = require("./redirect.cjs");
10
- const require_load_matches = require("./load-matches.cjs");
10
+ const require_load_client = require("./load-client.cjs");
11
11
  const require_rewrite = require("./rewrite.cjs");
12
12
  const require_stores = require("./stores.cjs");
13
13
  let _tanstack_history = require("@tanstack/history");
14
14
  let _tanstack_router_core_isServer = require("@tanstack/router-core/isServer");
15
15
  //#region src/router.ts
16
+ function routeNeedsLoad(route) {
17
+ return route.options.loader || route.options.beforeLoad || route.lazyFn || route.options.component?.preload || route.options.pendingComponent?.preload;
18
+ }
16
19
  /**
17
20
  * Convert an unknown error into a minimal, serializable object.
18
21
  * Includes name and message (and stack in development).
@@ -39,17 +42,34 @@ const trailingSlashOptions = {
39
42
  * resolved locations.
40
43
  */
41
44
  function getLocationChangeInfo(location, resolvedLocation) {
42
- const fromLocation = resolvedLocation;
43
- const toLocation = location;
44
45
  return {
45
- fromLocation,
46
- toLocation,
47
- pathChanged: fromLocation?.pathname !== toLocation.pathname,
48
- hrefChanged: fromLocation?.href !== toLocation.href,
49
- hashChanged: fromLocation?.hash !== toLocation.hash
46
+ fromLocation: resolvedLocation,
47
+ toLocation: location,
48
+ pathChanged: resolvedLocation?.pathname !== location.pathname,
49
+ hrefChanged: resolvedLocation?.href !== location.href,
50
+ hashChanged: resolvedLocation?.hash !== location.hash
50
51
  };
51
52
  }
52
53
  /**
54
+ * Return only state owned by the application, excluding volatile history
55
+ * bookkeeping. Mask payloads (`__tempLocation`/`__tempKey`) are kept: they
56
+ * distinguish otherwise-identical locations.
57
+ */
58
+ function _getUserHistoryState({ key: _key, __TSR_key: _tsrKey, __TSR_index: _tsrIndex, __hashScrollIntoViewOptions: _hashScroll, ...state }) {
59
+ return state;
60
+ }
61
+ /** Run route lifecycle callbacks in leave/enter/stay phases. */
62
+ function runRouteLifecycle(router, previous, matches, isCurrent) {
63
+ for (const match of previous) {
64
+ if (isCurrent?.() === false) return;
65
+ if (!matches.some((candidate) => candidate.routeId === match.routeId)) router.routesById[match.routeId].options.onLeave?.(match);
66
+ }
67
+ for (const match of matches) {
68
+ if (isCurrent?.() === false) return;
69
+ router.routesById[match.routeId].options[previous.some((candidate) => candidate.routeId === match.routeId) ? "onStay" : "onEnter"]?.(match);
70
+ }
71
+ }
72
+ /**
53
73
  * Core, framework-agnostic router engine that powers TanStack Router.
54
74
  *
55
75
  * Provides navigation, matching, loading, preloading, caching and event APIs
@@ -65,12 +85,15 @@ var RouterCore = class {
65
85
  constructor(options, getStoreConfig) {
66
86
  this.tempLocationKey = `${Math.round(Math.random() * 1e7)}`;
67
87
  this._scroll = { next: true };
68
- this.shouldViewTransition = void 0;
69
- this.isViewTransitionTypesSupported = void 0;
70
88
  this.subscribers = /* @__PURE__ */ new Set();
89
+ this._cache = /* @__PURE__ */ new Map();
90
+ this._committed = [];
71
91
  this.routeBranchCache = /* @__PURE__ */ new WeakMap();
72
92
  this.lightweightCache = /* @__PURE__ */ new WeakMap();
73
- this.startTransition = (fn) => fn();
93
+ this.startTransition = async (fn) => {
94
+ fn();
95
+ return false;
96
+ };
74
97
  this.update = (newOptions) => {
75
98
  if (process.env.NODE_ENV !== "production") {
76
99
  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,7 +106,7 @@ var RouterCore = class {
83
106
  ...prevOptions,
84
107
  ...newOptions
85
108
  };
86
- this.isServer = this.options.isServer ?? typeof document === "undefined";
109
+ this.isServer = this.options.isServer ?? _tanstack_router_core_isServer.isServer ?? typeof document === "undefined";
87
110
  this.protocolAllowlist = new Set(this.options.protocolAllowlist);
88
111
  if (this.options.pathParamsAllowedCharacters) this.pathParamsDecoder = require_path.compileDecodeCharMap(this.options.pathParamsAllowedCharacters);
89
112
  if (!this.history || this.options.history && this.options.history !== this.history) if (!this.options.history) {
@@ -114,10 +137,9 @@ var RouterCore = class {
114
137
  if (!this.stores && this.latestLocation) {
115
138
  const config = this.getStoreConfig(this);
116
139
  this.batch = config.batch;
117
- this.stores = require_stores.createRouterStores(getInitialRouterState(this.latestLocation), config);
140
+ this.stores = require_stores.createRouterStores(this.latestLocation, config);
118
141
  if (!(_tanstack_router_core_isServer.isServer ?? this.isServer)) require_scroll_restoration.setupScrollRestoration(this);
119
142
  }
120
- let needsLocationUpdate = false;
121
143
  const nextBasepath = this.options.basepath ?? "/";
122
144
  const nextRewriteOption = this.options.rewrite;
123
145
  if (basepathWasUnset || prevBasepath !== nextBasepath || prevRewriteOption !== nextRewriteOption) {
@@ -128,10 +150,8 @@ var RouterCore = class {
128
150
  if (nextRewriteOption) rewrites.push(nextRewriteOption);
129
151
  this.rewrite = rewrites.length === 0 ? void 0 : rewrites.length === 1 ? rewrites[0] : require_rewrite.composeRewrites(rewrites);
130
152
  if (this.history) this.updateLatestLocation();
131
- needsLocationUpdate = true;
153
+ if (this.stores) this.stores.location.set(this.latestLocation);
132
154
  }
133
- if (needsLocationUpdate && this.stores) this.stores.location.set(this.latestLocation);
134
- if (typeof window !== "undefined" && "CSS" in window && typeof window.CSS?.supports === "function") this.isViewTransitionTypesSupported = window.CSS.supports("selector(:active-view-transition-type(a))");
135
155
  };
136
156
  this.updateLatestLocation = () => {
137
157
  this.latestLocation = this.parseLocation(this.history.location, this.latestLocation);
@@ -154,9 +174,11 @@ var RouterCore = class {
154
174
  };
155
175
  };
156
176
  this.emit = (routerEvent) => {
157
- this.subscribers.forEach((listener) => {
158
- if (listener.eventType === routerEvent.type) listener.fn(routerEvent);
159
- });
177
+ for (const listener of this.subscribers) if (listener.eventType === routerEvent.type) try {
178
+ listener.fn(routerEvent);
179
+ } catch (e) {
180
+ console.error(e);
181
+ }
160
182
  };
161
183
  this.parseLocation = (locationToParse, previousLocation) => {
162
184
  const parse = ({ pathname, search, hash, href, state }) => {
@@ -220,33 +242,18 @@ var RouterCore = class {
220
242
  return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts);
221
243
  };
222
244
  this.getMatchedRoutes = (pathname) => {
223
- return getMatchedRoutes({
224
- pathname,
225
- routesById: this.routesById,
226
- processedTree: this.processedTree
227
- });
228
- };
229
- this.cancelMatch = (id) => {
230
- const match = this.getMatch(id);
231
- if (!match) return;
232
- match.abortController.abort();
233
- clearTimeout(match._nonReactive.pendingTimeout);
234
- match._nonReactive.pendingTimeout = void 0;
235
- };
236
- this.cancelMatches = () => {
237
- this.stores.pendingIds.get().forEach((matchId) => {
238
- this.cancelMatch(matchId);
239
- });
240
- this.stores.matchesId.get().forEach((matchId) => {
241
- if (this.stores.pendingMatchStores.has(matchId)) return;
242
- const match = this.stores.matchStores.get(matchId)?.get();
243
- if (!match) return;
244
- if (match.status === "pending" || match.isFetching === "loader") this.cancelMatch(matchId);
245
- });
245
+ const routeParams = Object.create(null);
246
+ const match = require_new_process_route_tree.findRouteMatch(require_path.trimPathRight(pathname), this.processedTree, true);
247
+ if (match) Object.assign(routeParams, match.rawParams);
248
+ return {
249
+ matchedRoutes: match?.branch || [this.routesById["__root__"]],
250
+ routeParams,
251
+ foundRoute: match?.route
252
+ };
246
253
  };
247
254
  this.buildLocation = (opts) => {
248
255
  const build = (dest = {}) => {
249
- const currentLocation = dest._fromLocation || this.pendingBuiltLocation || this.latestLocation;
256
+ const currentLocation = dest._fromLocation || this._pendingLocation || this.latestLocation;
250
257
  const lightweightResult = this.matchRoutesLightweight(currentLocation);
251
258
  if (dest.from && process.env.NODE_ENV !== "production" && dest._isNavigate) {
252
259
  const allFromMatches = this.getMatchedRoutes(dest.from).matchedRoutes;
@@ -264,7 +271,7 @@ var RouterCore = class {
264
271
  const fromParams = Object.assign(Object.create(null), lightweightResult.params);
265
272
  const sourcePath = destTo?.charCodeAt(0) === 47 ? "/" : this.resolvePathWithBase(defaultedFromPath, ".");
266
273
  const nextTo = destTo ? this.resolvePathWithBase(sourcePath, destTo) : sourcePath;
267
- 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));
274
+ const nextParams = resolveNextParams(dest.params, fromParams);
268
275
  const destRoute = this.routesByPath[require_path.trimPathRight(nextTo)];
269
276
  let destRoutes;
270
277
  if (destRoute) destRoutes = this.getRouteBranch(destRoute);
@@ -303,12 +310,7 @@ var RouterCore = class {
303
310
  });
304
311
  nextSearch = validatedSearch;
305
312
  }
306
- nextSearch = applySearchMiddleware({
307
- search: nextSearch,
308
- dest,
309
- destRoutes,
310
- _includeValidateSearch: opts._includeValidateSearch
311
- });
313
+ nextSearch = applySearchMiddleware(nextSearch, dest, destRoutes, opts._includeValidateSearch);
312
314
  nextSearch = require_utils.nullReplaceEqualDeep(fromSearch, nextSearch);
313
315
  const searchStr = this.options.stringifySearch(nextSearch);
314
316
  const hash = dest.hash === true ? currentLocation.hash : dest.hash ? require_utils.functionalUpdate(dest.hash, currentLocation.hash) : void 0;
@@ -353,7 +355,7 @@ var RouterCore = class {
353
355
  if (match) {
354
356
  Object.assign(params, match.rawParams);
355
357
  const { from: _from, params: maskParams, ...maskProps } = match.route;
356
- const nextParams = maskParams === false || maskParams === null ? Object.create(null) : (maskParams ?? true) === true ? params : Object.assign(params, require_utils.functionalUpdate(maskParams, params));
358
+ const nextParams = resolveNextParams(maskParams, params);
357
359
  maskedDest = {
358
360
  from: opts.from,
359
361
  ...maskProps,
@@ -374,29 +376,18 @@ var RouterCore = class {
374
376
  };
375
377
  this.commitLocation = async ({ viewTransition, ignoreBlocker, ...next }) => {
376
378
  let historyAction;
377
- const isSameState = () => {
378
- const ignoredProps = [
379
- "key",
380
- "__TSR_key",
381
- "__TSR_index",
382
- "__hashScrollIntoViewOptions"
383
- ];
384
- ignoredProps.forEach((prop) => {
385
- next.state[prop] = this.latestLocation.state[prop];
386
- });
387
- const isEqual = require_utils.deepEqual(next.state, this.latestLocation.state);
388
- ignoredProps.forEach((prop) => {
389
- delete next.state[prop];
390
- });
391
- return isEqual;
392
- };
393
- const isSameUrl = require_path.trimPathRight(this.latestLocation.href) === require_path.trimPathRight(next.href);
394
- let previousCommitPromise = this.commitLocationPromise;
395
- this.commitLocationPromise = require_utils.createControlledPromise(() => {
396
- previousCommitPromise?.resolve();
397
- previousCommitPromise = void 0;
379
+ const isSameLocation = require_path.trimPathRight(this.latestLocation.href) === require_path.trimPathRight(next.href) && require_utils.deepEqual(_getUserHistoryState(next.state), _getUserHistoryState(this.latestLocation.state));
380
+ const previousCommitPromise = this._commitPromise;
381
+ let resolve;
382
+ const commitPromise = new Promise((done) => {
383
+ resolve = done;
398
384
  });
399
- if (isSameUrl && isSameState()) this.load();
385
+ commitPromise.resolve = () => {
386
+ resolve();
387
+ previousCommitPromise?.resolve();
388
+ };
389
+ this._commitPromise = commitPromise;
390
+ if (isSameLocation) this.load();
400
391
  else {
401
392
  let { maskedLocation, hashScrollIntoView, ...nextHistory } = next;
402
393
  if (maskedLocation) {
@@ -424,12 +415,12 @@ var RouterCore = class {
424
415
  this.shouldViewTransition = viewTransition;
425
416
  historyAction = next.replace ? "REPLACE" : "PUSH";
426
417
  this.history[historyAction === "REPLACE" ? "replace" : "push"](nextHistory.publicHref, nextHistory.state, { ignoreBlocker });
418
+ if (!this.history.subscribers.size) this.load({ action: { type: historyAction } });
427
419
  }
428
420
  this._scroll.next = next.resetScroll ?? true;
429
- if (!this.history.subscribers.size) this.load(historyAction ? { action: { type: historyAction } } : void 0);
430
- return this.commitLocationPromise;
421
+ return this._commitPromise;
431
422
  };
432
- this.buildAndCommitLocation = ({ replace, resetScroll, hashScrollIntoView, viewTransition, ignoreBlocker, href, ...rest } = {}) => {
423
+ this.buildAndCommitLocation = ({ replace, resetScroll, hashScrollIntoView, viewTransition, ignoreBlocker, _redirects, href, ...rest } = {}) => {
433
424
  if (href) {
434
425
  const currentIndex = this.history.location.state.__TSR_index;
435
426
  const parsed = (0, _tanstack_history.parseHref)(href, { __TSR_index: replace ? currentIndex : currentIndex + 1 });
@@ -442,7 +433,8 @@ var RouterCore = class {
442
433
  ...rest,
443
434
  _includeValidateSearch: true
444
435
  });
445
- this.pendingBuiltLocation = location;
436
+ if (_redirects) location._redirects = _redirects;
437
+ this._pendingLocation = location;
446
438
  const commitPromise = this.commitLocation({
447
439
  ...location,
448
440
  viewTransition,
@@ -452,7 +444,7 @@ var RouterCore = class {
452
444
  ignoreBlocker
453
445
  });
454
446
  queueMicrotask(() => {
455
- if (this.pendingBuiltLocation === location) this.pendingBuiltLocation = void 0;
447
+ if (this._pendingLocation === location) this._pendingLocation = void 0;
456
448
  });
457
449
  return commitPromise;
458
450
  };
@@ -498,216 +490,76 @@ var RouterCore = class {
498
490
  _isNavigate: true
499
491
  });
500
492
  };
501
- this.beforeLoad = () => {
502
- this.cancelMatches();
503
- this.updateLatestLocation();
504
- if (_tanstack_router_core_isServer.isServer ?? this.isServer) {
505
- const nextLocation = this.buildLocation({
506
- to: this.latestLocation.pathname,
507
- search: true,
508
- params: true,
509
- hash: true,
510
- state: true,
511
- _includeValidateSearch: true
512
- });
513
- if (this.latestLocation.publicHref !== nextLocation.publicHref) {
514
- const href = this.getParsedLocationHref(nextLocation);
515
- if (nextLocation.external) throw require_redirect.redirect({ href });
516
- else throw require_redirect.redirect({
517
- href,
518
- _builtLocation: nextLocation
519
- });
520
- }
521
- }
522
- const pendingMatches = this.matchRoutes(this.latestLocation);
523
- const nextCachedMatches = this.stores.cachedMatches.get().filter((d) => !pendingMatches.some((e) => e.id === d.id));
524
- this.batch(() => {
525
- this.stores.status.set("pending");
526
- this.stores.statusCode.set(200);
527
- this.stores.isLoading.set(true);
528
- this.stores.location.set(this.latestLocation);
529
- this.stores.setPending(pendingMatches);
530
- this.stores.setCached(nextCachedMatches);
531
- });
532
- };
533
493
  this.load = async (opts) => {
534
- const historyAction = opts?.action?.type;
535
- let redirect;
536
- let notFound;
537
- let loadPromise;
538
- const previousLocation = this.stores.resolvedLocation.get() ?? this.stores.location.get();
539
- loadPromise = new Promise((resolve) => {
540
- this.startTransition(async () => {
541
- try {
542
- this.beforeLoad();
543
- if (historyAction) this._scroll.hash = historyAction === "PUSH" || historyAction === "REPLACE";
544
- const next = this.latestLocation;
545
- const locationChangeInfo = getLocationChangeInfo(next, this.stores.resolvedLocation.get());
546
- if (!this.stores.redirect.get()) this.emit({
547
- type: "onBeforeNavigate",
548
- ...locationChangeInfo
549
- });
550
- this.emit({
551
- type: "onBeforeLoad",
552
- ...locationChangeInfo
553
- });
554
- await require_load_matches.loadMatches({
555
- router: this,
556
- sync: opts?.sync,
557
- forceStaleReload: previousLocation.href === next.href,
558
- matches: this.stores.pendingMatches.get(),
559
- location: next,
560
- updateMatch: this.updateMatch,
561
- onReady: async () => {
562
- this.startTransition(() => {
563
- this.startViewTransition(async () => {
564
- let exitingMatches = null;
565
- let hookExitingMatches = null;
566
- let hookEnteringMatches = null;
567
- let hookStayingMatches = null;
568
- this.batch(() => {
569
- const pendingMatches = this.stores.pendingMatches.get();
570
- const mountPending = pendingMatches.length;
571
- const currentMatches = this.stores.matches.get();
572
- exitingMatches = mountPending ? currentMatches.filter((match) => !this.stores.pendingMatchStores.has(match.id)) : null;
573
- const pendingRouteIds = /* @__PURE__ */ new Set();
574
- for (const s of this.stores.pendingMatchStores.values()) if (s.routeId) pendingRouteIds.add(s.routeId);
575
- const activeRouteIds = /* @__PURE__ */ new Set();
576
- for (const s of this.stores.matchStores.values()) if (s.routeId) activeRouteIds.add(s.routeId);
577
- hookExitingMatches = mountPending ? currentMatches.filter((match) => !pendingRouteIds.has(match.routeId)) : null;
578
- hookEnteringMatches = mountPending ? pendingMatches.filter((match) => !activeRouteIds.has(match.routeId)) : null;
579
- hookStayingMatches = mountPending ? pendingMatches.filter((match) => activeRouteIds.has(match.routeId)) : currentMatches;
580
- this.stores.isLoading.set(false);
581
- this.stores.loadedAt.set(Date.now());
582
- /**
583
- * When committing new matches, cache any exiting matches that are still usable.
584
- * Routes that resolved with `status: 'error'` or `status: 'notFound'` are
585
- * deliberately excluded from `cachedMatches` so that subsequent invalidations
586
- * or reloads re-run their loaders instead of reusing the failed/not-found data.
587
- */
588
- if (mountPending) {
589
- this.stores.setMatches(pendingMatches);
590
- this.stores.setPending([]);
591
- this.stores.setCached([...this.stores.cachedMatches.get(), ...exitingMatches.filter((d) => d.status !== "error" && d.status !== "notFound" && d.status !== "redirected")]);
592
- this.clearExpiredCache();
593
- }
594
- });
595
- for (const [matches, hook] of [
596
- [hookExitingMatches, "onLeave"],
597
- [hookEnteringMatches, "onEnter"],
598
- [hookStayingMatches, "onStay"]
599
- ]) {
600
- if (!matches) continue;
601
- for (const match of matches) this.looseRoutesById[match.routeId].options[hook]?.(match);
602
- }
603
- });
604
- });
605
- }
606
- });
607
- } catch (err) {
608
- if (require_redirect.isRedirect(err)) {
609
- redirect = err;
610
- if (!(_tanstack_router_core_isServer.isServer ?? this.isServer)) this.navigate({
611
- ...redirect.options,
612
- replace: true,
613
- ignoreBlocker: true
614
- });
615
- } else if (require_not_found.isNotFound(err)) notFound = err;
616
- const nextStatusCode = redirect ? redirect.status : notFound ? 404 : this.stores.matches.get().some((d) => d.status === "error") ? 500 : 200;
617
- this.batch(() => {
618
- this.stores.statusCode.set(nextStatusCode);
619
- this.stores.redirect.set(redirect);
620
- });
621
- }
622
- if (this.latestLoadPromise === loadPromise) {
623
- this.commitLocationPromise?.resolve();
624
- this.latestLoadPromise = void 0;
625
- this.commitLocationPromise = void 0;
626
- }
627
- resolve();
628
- });
629
- });
630
- this.latestLoadPromise = loadPromise;
631
- await loadPromise;
632
- while (this.latestLoadPromise && loadPromise !== this.latestLoadPromise) await this.latestLoadPromise;
633
- let newStatusCode = void 0;
634
- if (this.hasNotFoundMatch()) newStatusCode = 404;
635
- else if (this.stores.matches.get().some((d) => d.status === "error")) newStatusCode = 500;
636
- if (newStatusCode !== void 0) this.stores.statusCode.set(newStatusCode);
494
+ if (_tanstack_router_core_isServer.isServer ?? this.isServer) return (0, _tanstack_router_core_isServer.loadServerRoute)(this, opts);
495
+ this.updateLatestLocation();
496
+ if (opts?.action) this._scroll.hash = opts.action.type === "PUSH" || opts.action.type === "REPLACE";
497
+ await require_load_client.loadClientRoute(this, opts);
637
498
  };
638
499
  this.startViewTransition = (fn) => {
639
500
  const shouldViewTransition = this.shouldViewTransition ?? this.options.defaultViewTransition;
640
501
  this.shouldViewTransition = void 0;
641
- if (shouldViewTransition && typeof document !== "undefined" && "startViewTransition" in document && typeof document.startViewTransition === "function") {
502
+ if (shouldViewTransition && !(_tanstack_router_core_isServer.isServer ?? typeof document === "undefined") && typeof document.startViewTransition === "function") {
642
503
  let startViewTransitionParams;
643
- if (typeof shouldViewTransition === "object" && this.isViewTransitionTypesSupported) {
504
+ if (typeof shouldViewTransition === "object" && window.CSS?.supports?.("selector(:active-view-transition-type(a))")) {
644
505
  const next = this.latestLocation;
645
506
  const prevLocation = this.stores.resolvedLocation.get();
646
507
  const resolvedViewTransitionTypes = typeof shouldViewTransition.types === "function" ? shouldViewTransition.types(getLocationChangeInfo(next, prevLocation)) : shouldViewTransition.types;
647
- if (resolvedViewTransitionTypes === false) {
648
- fn();
649
- return;
650
- }
508
+ if (resolvedViewTransitionTypes === false) return fn();
651
509
  startViewTransitionParams = {
652
510
  update: fn,
653
511
  types: resolvedViewTransitionTypes
654
512
  };
655
513
  } else startViewTransitionParams = fn;
656
- document.startViewTransition(startViewTransitionParams);
657
- } else fn();
658
- };
659
- this.updateMatch = (id, updater) => {
660
- this.startTransition(() => {
661
- const pendingMatch = this.stores.pendingMatchStores.get(id);
662
- if (pendingMatch) {
663
- pendingMatch.set(updater);
664
- return;
665
- }
666
- const activeMatch = this.stores.matchStores.get(id);
667
- if (activeMatch) {
668
- activeMatch.set(updater);
669
- return;
670
- }
671
- const cachedMatch = this.stores.cachedMatchStores.get(id);
672
- if (cachedMatch) {
673
- const next = updater(cachedMatch.get());
674
- if (next.status === "redirected") {
675
- if (this.stores.cachedMatchStores.delete(id)) this.stores.cachedIds.set((prev) => prev.filter((matchId) => matchId !== id));
676
- } else cachedMatch.set(next);
677
- }
678
- });
679
- };
680
- this.getMatch = (matchId) => {
681
- return this.stores.cachedMatchStores.get(matchId)?.get() ?? this.stores.pendingMatchStores.get(matchId)?.get() ?? this.stores.matchStores.get(matchId)?.get();
514
+ return document.startViewTransition(startViewTransitionParams).updateCallbackDone;
515
+ }
516
+ return fn();
682
517
  };
683
518
  this.invalidate = (opts) => {
519
+ const committedMatches = this._committed;
520
+ const filter = opts?.filter;
521
+ const preloads = this._preloads;
522
+ const invalidIds = new Set([
523
+ ...committedMatches,
524
+ ...this._cache.values(),
525
+ ...[...preloads?.values() ?? []].flat(),
526
+ ...this._tx?.[3] ?? []
527
+ ].filter((match) => !filter || filter(match)).map((match) => match.id));
528
+ const discardedPreloads = [];
529
+ for (const [controller, matches] of preloads ?? []) if (matches.some((match) => invalidIds.has(match.id))) {
530
+ preloads.delete(controller);
531
+ discardedPreloads.push(controller);
532
+ }
684
533
  const invalidate = (d) => {
685
- if (opts?.filter?.(d) ?? true) return {
686
- ...d,
687
- invalid: true,
688
- ...opts?.forcePending || d.status === "error" || d.status === "notFound" ? {
689
- status: "pending",
690
- error: void 0
691
- } : void 0
692
- };
534
+ if (invalidIds.has(d.id)) {
535
+ const route = this.routesById[d.routeId];
536
+ const next = {
537
+ ...d,
538
+ invalid: true,
539
+ ...(opts?.forcePending || d.status === "error" || d.status === "notFound") && routeNeedsLoad(route) ? {
540
+ status: "pending",
541
+ error: void 0
542
+ } : void 0
543
+ };
544
+ d._flight = void 0;
545
+ return next;
546
+ }
693
547
  return d;
694
548
  };
695
- this.batch(() => {
696
- this.stores.setMatches(this.stores.matches.get().map(invalidate));
697
- this.stores.setCached(this.stores.cachedMatches.get().map(invalidate));
698
- this.stores.setPending(this.stores.pendingMatches.get().map(invalidate));
699
- });
549
+ this._committed = committedMatches.map(invalidate);
550
+ for (const [id, match] of this._cache) if (invalidIds.has(id)) {
551
+ match.invalid = true;
552
+ if (opts?.forcePending) match.status = "pending";
553
+ }
554
+ for (const id of invalidIds) this._flights?.delete(id);
555
+ for (const controller of discardedPreloads) controller.abort();
700
556
  this.shouldViewTransition = false;
701
557
  return this.load({ sync: opts?.sync });
702
558
  };
703
- this.getParsedLocationHref = (location) => {
704
- return location.publicHref || "/";
705
- };
706
559
  this.resolveRedirect = (redirect) => {
707
560
  const locationHeader = redirect.headers.get("Location");
708
561
  if (!redirect.options.href || redirect.options._builtLocation) {
709
- const location = redirect.options._builtLocation ?? this.buildLocation(redirect.options);
710
- const href = this.getParsedLocationHref(location);
562
+ const href = (redirect.options._builtLocation ?? this.buildLocation(redirect.options)).publicHref || "/";
711
563
  redirect.options.href = href;
712
564
  redirect.headers.set("Location", href);
713
565
  } else if (locationHeader) try {
@@ -723,60 +575,34 @@ var RouterCore = class {
723
575
  return redirect;
724
576
  };
725
577
  this.clearCache = (opts) => {
578
+ const cached = this._cache;
579
+ const preloads = this._preloads;
726
580
  const filter = opts?.filter;
727
- if (filter !== void 0) this.stores.setCached(this.stores.cachedMatches.get().filter((m) => !filter(m)));
728
- else this.stores.setCached([]);
729
- };
730
- this.clearExpiredCache = () => {
731
- const now = Date.now();
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 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.stores.matchesId.get(), ...this.stores.pendingIds.get()]);
750
- const loadedMatchIds = new Set([...activeMatchIds, ...this.stores.cachedIds.get()]);
751
- const matchesToCache = matches.filter((match) => !loadedMatchIds.has(match.id));
752
- if (matchesToCache.length) {
753
- const cachedMatches = this.stores.cachedMatches.get();
754
- this.stores.setCached([...cachedMatches, ...matchesToCache]);
581
+ const discarded = [];
582
+ const discardedIds = [];
583
+ for (const [id, match] of cached) if (!filter || filter(match)) {
584
+ discardedIds.push(id);
585
+ discarded.push(match);
755
586
  }
756
- try {
757
- matches = await require_load_matches.loadMatches({
758
- router: this,
759
- matches,
760
- location: next,
761
- preload: true,
762
- updateMatch: (id, updater) => {
763
- if (activeMatchIds.has(id)) matches = matches.map((d) => d.id === id ? updater(d) : d);
764
- else this.updateMatch(id, updater);
765
- }
766
- });
767
- return matches;
768
- } catch (err) {
769
- if (require_redirect.isRedirect(err)) {
770
- if (err.options.reloadDocument) return;
771
- return await this.preloadRoute({
772
- ...err.options,
773
- _fromLocation: next
774
- });
587
+ const abort = [];
588
+ for (const [controller, matches] of preloads ?? []) if (!filter || matches.some(filter)) {
589
+ abort.push(controller);
590
+ discarded.push(...matches);
591
+ }
592
+ for (const id of discardedIds) cached.delete(id);
593
+ for (const controller of abort) preloads.delete(controller);
594
+ for (const match of discarded) {
595
+ const flight = match._flight;
596
+ match._flight = void 0;
597
+ if (flight && !--flight[2]) {
598
+ if (this._flights?.get(match.id) === flight) this._flights.delete(match.id);
599
+ abort.push(flight[1]);
775
600
  }
776
- if (!require_not_found.isNotFound(err)) console.error(err);
777
- return;
778
601
  }
602
+ for (const controller of abort) controller.abort();
779
603
  };
604
+ this.loadRouteChunk = require_load_client.loadRouteChunk;
605
+ this.preloadRoute = (opts) => require_load_client.preloadClientRoute(this, opts);
780
606
  this.matchRoute = (location, opts) => {
781
607
  const matchLocation = {
782
608
  ...location,
@@ -785,8 +611,9 @@ var RouterCore = class {
785
611
  leaveParams: true
786
612
  };
787
613
  const next = this.buildLocation(matchLocation);
788
- if (opts?.pending && this.stores.status.get() !== "pending") return false;
789
- const baseLocation = (opts?.pending === void 0 ? !this.stores.isLoading.get() : opts.pending) ? this.latestLocation : this.stores.resolvedLocation.get() || this.stores.location.get();
614
+ const isPending = this.stores.status.get() === "pending";
615
+ if (opts?.pending && !isPending) return false;
616
+ const baseLocation = opts?.pending ?? !isPending ? this.latestLocation : this.stores.resolvedLocation.get() || this.stores.location.get();
790
617
  const match = require_new_process_route_tree.findSingleMatch(next.pathname, opts?.caseSensitive ?? false, opts?.fuzzy ?? false, baseLocation.pathname, this.processedTree);
791
618
  if (!match) return false;
792
619
  if (location.params) {
@@ -795,9 +622,6 @@ var RouterCore = class {
795
622
  if (opts?.includeSearch ?? true) return require_utils.deepEqual(baseLocation.search, next.search, { partial: true }) ? match.rawParams : false;
796
623
  return match.rawParams;
797
624
  };
798
- this.hasNotFoundMatch = () => {
799
- return this.stores.matches.get().some((d) => d.status === "notFound" || d.globalNotFound);
800
- };
801
625
  this.getStoreConfig = getStoreConfig;
802
626
  this.update({
803
627
  defaultPreloadDelay: 50,
@@ -811,14 +635,11 @@ var RouterCore = class {
811
635
  parseSearch: options.parseSearch ?? require_searchParams.defaultParseSearch,
812
636
  protocolAllowlist: options.protocolAllowlist ?? require_utils.DEFAULT_PROTOCOL_ALLOWLIST
813
637
  });
814
- if (typeof document !== "undefined") self.__TSR_ROUTER__ = this;
638
+ if (!(_tanstack_router_core_isServer.isServer ?? typeof document === "undefined")) self.__TSR_ROUTER__ = this;
815
639
  }
816
640
  isShell() {
817
641
  return !!this.options.isShell;
818
642
  }
819
- isPrerendering() {
820
- return !!this.options.isPrerendering;
821
- }
822
643
  get state() {
823
644
  return this.stores.__store.get();
824
645
  }
@@ -840,12 +661,6 @@ var RouterCore = class {
840
661
  }
841
662
  return branch;
842
663
  }
843
- get looseRoutesById() {
844
- return this.routesById;
845
- }
846
- getParentContext(parentMatch) {
847
- return !parentMatch?.id ? this.options.context ?? void 0 : parentMatch.context ?? this.options.context ?? void 0;
848
- }
849
664
  matchRoutesInternal(next, opts) {
850
665
  const matchedRoutesResult = this.getMatchedRoutes(next.pathname);
851
666
  const { foundRoute, routeParams } = matchedRoutesResult;
@@ -853,10 +668,13 @@ var RouterCore = class {
853
668
  let isGlobalNotFound = false;
854
669
  if (foundRoute ? foundRoute.path !== "/" && routeParams["**"] : require_path.trimPathRight(next.pathname)) if (this.options.notFoundRoute) matchedRoutes = [...matchedRoutes, this.options.notFoundRoute];
855
670
  else isGlobalNotFound = true;
856
- const globalNotFoundRouteId = isGlobalNotFound ? findGlobalNotFoundRouteId(this.options.notFoundMode, matchedRoutes) : void 0;
671
+ const _notFoundRouteId = isGlobalNotFound ? findGlobalNotFoundRouteId(this.options.notFoundMode, matchedRoutes) : void 0;
857
672
  const matches = new Array(matchedRoutes.length);
858
- const previousActiveMatchesByRouteId = /* @__PURE__ */ new Map();
859
- for (const store of this.stores.matchStores.values()) if (store.routeId) previousActiveMatchesByRouteId.set(store.routeId, store.get());
673
+ const committed = this._committed;
674
+ const previousAt = (route, index) => {
675
+ const match = committed[index];
676
+ return match?.routeId === route.id ? match : route === this.options.notFoundRoute ? committed.find((candidate) => candidate.routeId === route.id) : void 0;
677
+ };
860
678
  for (let index = 0; index < matchedRoutes.length; index++) {
861
679
  const route = matchedRoutes[index];
862
680
  const parentMatch = matches[index - 1];
@@ -876,7 +694,6 @@ var RouterCore = class {
876
694
  ...parentStrictSearch,
877
695
  ...strictSearch
878
696
  };
879
- searchError = void 0;
880
697
  } catch (err) {
881
698
  let searchParamError = err;
882
699
  if (!(err instanceof SearchParamError)) searchParamError = new SearchParamError(err.message, { cause: err });
@@ -886,8 +703,15 @@ var RouterCore = class {
886
703
  searchError = searchParamError;
887
704
  }
888
705
  }
889
- const loaderDeps = route.options.loaderDeps?.({ search: preMatchSearch }) ?? "";
890
- const loaderDepsHash = loaderDeps ? JSON.stringify(loaderDeps) : "";
706
+ let loaderDeps = "";
707
+ let loaderDepsHash = "";
708
+ try {
709
+ loaderDeps = route.options.loaderDeps?.({ search: preMatchSearch }) ?? "";
710
+ loaderDepsHash = loaderDeps ? JSON.stringify(loaderDeps) || "" : "";
711
+ } catch (cause) {
712
+ if (opts?.throwOnError) throw cause;
713
+ searchError ??= cause;
714
+ }
891
715
  const { interpolatedPath, usedParams } = require_path.interpolatePath({
892
716
  path: route.fullPath,
893
717
  params: routeParams,
@@ -895,10 +719,10 @@ var RouterCore = class {
895
719
  server: this.isServer
896
720
  });
897
721
  const matchId = route.id + interpolatedPath + loaderDepsHash;
898
- const existingMatch = this.getMatch(matchId);
899
- const previousMatch = previousActiveMatchesByRouteId.get(route.id);
722
+ const previousMatch = previousAt(route, index);
723
+ const existingMatch = process.env.NODE_ENV !== "production" && opts?._rematerialize ? void 0 : this._cache.get(matchId) ?? (previousMatch?.id === matchId ? previousMatch : void 0);
900
724
  const strictParams = existingMatch?._strictParams ?? usedParams;
901
- let paramsError = void 0;
725
+ let paramsError;
902
726
  if (!existingMatch) try {
903
727
  extractStrictParams(route, strictParams);
904
728
  } catch (err) {
@@ -915,10 +739,11 @@ var RouterCore = class {
915
739
  params: previousMatch?.params ?? routeParams,
916
740
  _strictParams: strictParams,
917
741
  search: previousMatch ? require_utils.nullReplaceEqualDeep(previousMatch.search, preMatchSearch) : require_utils.nullReplaceEqualDeep(existingMatch.search, preMatchSearch),
918
- _strictSearch: strictMatchSearch
742
+ _strictSearch: strictMatchSearch,
743
+ searchError
919
744
  };
920
745
  else {
921
- const status = route.options.loader || route.options.beforeLoad || route.lazyFn || require_load_matches.routeNeedsPreload(route) ? "pending" : "success";
746
+ const status = routeNeedsLoad(route) ? "pending" : "success";
922
747
  match = {
923
748
  id: matchId,
924
749
  ssr: _tanstack_router_core_isServer.isServer ?? this.isServer ? void 0 : route.options.ssr,
@@ -930,83 +755,42 @@ var RouterCore = class {
930
755
  updatedAt: Date.now(),
931
756
  search: previousMatch ? require_utils.nullReplaceEqualDeep(previousMatch.search, preMatchSearch) : preMatchSearch,
932
757
  _strictSearch: strictMatchSearch,
933
- searchError: void 0,
758
+ searchError,
934
759
  status,
935
760
  isFetching: false,
936
761
  error: void 0,
937
762
  paramsError,
938
- __routeContext: void 0,
939
- _nonReactive: { loadPromise: require_utils.createControlledPromise() },
940
- __beforeLoadContext: void 0,
941
763
  context: {},
942
- abortController: new AbortController(),
943
- fetchCount: 0,
764
+ abortController: opts?._controller ?? new AbortController(),
944
765
  cause,
945
766
  loaderDeps: previousMatch ? require_utils.replaceEqualDeep(previousMatch.loaderDeps, loaderDeps) : loaderDeps,
946
767
  invalid: false,
947
768
  preload: false,
948
- links: void 0,
949
- scripts: void 0,
950
- headScripts: void 0,
951
- meta: void 0,
952
769
  staticData: route.options.staticData || {},
953
770
  fullPath: route.fullPath
954
771
  };
955
772
  }
956
- if (!opts?.preload) match.globalNotFound = globalNotFoundRouteId === route.id;
957
- match.searchError = searchError;
958
- const parentContext = this.getParentContext(parentMatch);
959
- match.context = {
960
- ...parentContext,
961
- ...match.__routeContext,
962
- ...match.__beforeLoadContext
963
- };
773
+ const _notFound = _notFoundRouteId === route.id;
774
+ if (match._notFound && !_notFound) match.error = void 0;
775
+ match._notFound = _notFound;
964
776
  matches[index] = match;
965
777
  }
966
778
  for (let index = 0; index < matches.length; index++) {
967
779
  const match = matches[index];
968
- const route = this.looseRoutesById[match.routeId];
969
- const existingMatch = this.getMatch(match.id);
970
- const previousMatch = previousActiveMatchesByRouteId.get(match.routeId);
971
- match.params = previousMatch ? require_utils.nullReplaceEqualDeep(previousMatch.params, routeParams) : routeParams;
972
- if (!existingMatch) {
973
- const parentMatch = matches[index - 1];
974
- const parentContext = this.getParentContext(parentMatch);
975
- if (route.options.context) {
976
- const contextFnContext = {
977
- deps: match.loaderDeps,
978
- params: match.params,
979
- context: parentContext ?? {},
980
- location: next,
981
- navigate: (opts) => this.navigate({
982
- ...opts,
983
- _fromLocation: next
984
- }),
985
- buildLocation: this.buildLocation,
986
- cause: match.cause,
987
- abortController: match.abortController,
988
- preload: !!match.preload,
989
- matches,
990
- routeId: route.id
991
- };
992
- match.__routeContext = route.options.context(contextFnContext) ?? void 0;
993
- }
994
- match.context = {
995
- ...parentContext,
996
- ...match.__routeContext,
997
- ...match.__beforeLoadContext
998
- };
999
- }
780
+ match.params = match.cause === "stay" ? require_utils.nullReplaceEqualDeep(match.params, routeParams) : routeParams;
781
+ if (opts?._controller) match.context = {};
1000
782
  }
1001
783
  return matches;
1002
784
  }
1003
785
  /**
1004
786
  * Lightweight route matching for buildLocation.
1005
787
  * Only computes fullPath, accumulated search, and params - skipping expensive
1006
- * operations like AbortController, ControlledPromise, loaderDeps, and full match objects.
788
+ * operations like AbortController, loaderDeps, and full match objects.
1007
789
  */
1008
790
  matchRoutesLightweight(location) {
1009
- const lastStateMatchId = require_utils.last(this.stores.matchesId.get());
791
+ const lastRouteId = require_utils.last(this.stores.ids.get());
792
+ const lastStateMatch = lastRouteId ? this.stores.byRoute.get(lastRouteId).get() : void 0;
793
+ const lastStateMatchId = lastStateMatch?.id;
1010
794
  const cached = this.lightweightCache.get(location);
1011
795
  if (cached && cached[0] === lastStateMatchId) return cached[1];
1012
796
  const { matchedRoutes, routeParams } = this.getMatchedRoutes(location.pathname);
@@ -1015,7 +799,6 @@ var RouterCore = class {
1015
799
  for (const route of matchedRoutes) try {
1016
800
  Object.assign(accumulatedSearch, validateSearch(route.options.validateSearch, accumulatedSearch));
1017
801
  } catch {}
1018
- const lastStateMatch = lastStateMatchId && this.stores.matchStores.get(lastStateMatchId)?.get();
1019
802
  const canReuseParams = lastStateMatch && lastStateMatch.routeId === lastRoute.id && lastStateMatch.pathname === location.pathname;
1020
803
  let params;
1021
804
  if (canReuseParams) params = lastStateMatch.params;
@@ -1036,6 +819,19 @@ var RouterCore = class {
1036
819
  return result;
1037
820
  }
1038
821
  };
822
+ /**
823
+ * In non-production environments,
824
+ * augment the RouterCore class with a `_refreshRoute` method
825
+ * dedicated to HMR.
826
+ */
827
+ if (process.env.NODE_ENV !== "production") {
828
+ RouterCore.prototype._replaceRouteChunk = require_load_client.replaceRouteChunk;
829
+ RouterCore.prototype._refreshRoute = async function() {
830
+ this._serverResult = void 0;
831
+ this.updateLatestLocation();
832
+ await require_load_client.refreshClientRoute(this);
833
+ };
834
+ }
1039
835
  /** Error thrown when search parameter validation fails. */
1040
836
  var SearchParamError = class extends Error {};
1041
837
  /** Error thrown when path parameter parsing/validation fails. */
@@ -1056,14 +852,11 @@ function lazyFn(fn, key) {
1056
852
  /** Create an initial RouterState from a parsed location. */
1057
853
  function getInitialRouterState(location) {
1058
854
  return {
1059
- loadedAt: 0,
1060
855
  isLoading: false,
1061
- isTransitioning: false,
1062
856
  status: "idle",
1063
857
  resolvedLocation: void 0,
1064
858
  location,
1065
- matches: [],
1066
- statusCode: 200
859
+ matches: []
1067
860
  };
1068
861
  }
1069
862
  function validateSearch(validateSearch, input) {
@@ -1078,35 +871,7 @@ function validateSearch(validateSearch, input) {
1078
871
  if (typeof validateSearch === "function") return validateSearch(input);
1079
872
  return {};
1080
873
  }
1081
- /**
1082
- * Build the matched route chain and extract params for a pathname.
1083
- * Falls back to the root route if no specific route is found.
1084
- */
1085
- function getMatchedRoutes({ pathname, routesById, processedTree }) {
1086
- const routeParams = Object.create(null);
1087
- const trimmedPath = require_path.trimPathRight(pathname);
1088
- let foundRoute = void 0;
1089
- const match = require_new_process_route_tree.findRouteMatch(trimmedPath, processedTree, true);
1090
- if (match) {
1091
- foundRoute = match.route;
1092
- Object.assign(routeParams, match.rawParams);
1093
- }
1094
- return {
1095
- matchedRoutes: match?.branch || [routesById["__root__"]],
1096
- routeParams,
1097
- foundRoute
1098
- };
1099
- }
1100
- /**
1101
- * TODO: once caches are persisted across requests on the server,
1102
- * we can cache the built middleware chain using `last(destRoutes)` as the key
1103
- */
1104
- function applySearchMiddleware({ search, dest, destRoutes, _includeValidateSearch }) {
1105
- return buildMiddlewareChain(destRoutes)(search, dest, _includeValidateSearch ?? false);
1106
- }
1107
- function buildMiddlewareChain(destRoutes) {
1108
- let dest;
1109
- let includeValidateSearch;
874
+ function applySearchMiddleware(search, dest, destRoutes, includeValidateSearch) {
1110
875
  const middlewares = [];
1111
876
  for (const route of destRoutes) {
1112
877
  const routeOptions = route.options;
@@ -1162,26 +927,26 @@ function buildMiddlewareChain(destRoutes) {
1162
927
  meta
1163
928
  });
1164
929
  };
1165
- return function middleware(search, nextDest, _includeValidateSearch) {
1166
- dest = nextDest;
1167
- includeValidateSearch = _includeValidateSearch;
1168
- return applyNext(0, search);
1169
- };
930
+ return applyNext(0, search);
1170
931
  }
1171
932
  function findGlobalNotFoundRouteId(notFoundMode, routes) {
1172
- if (notFoundMode !== "root") for (let i = routes.length - 1; i >= 0; i--) {
1173
- const route = routes[i];
1174
- if (route.children) return route.id;
933
+ if (notFoundMode !== "root") {
934
+ let fallback;
935
+ for (let i = routes.length - 1; i >= 0; i--) {
936
+ const route = routes[i];
937
+ if (route.options.notFoundComponent) return route.id;
938
+ fallback ||= route.children && route.id;
939
+ }
940
+ if (fallback) return fallback;
1175
941
  }
1176
942
  return require_root.rootRouteId;
1177
943
  }
944
+ function resolveNextParams(spec, base) {
945
+ return spec === false || spec === null ? Object.create(null) : (spec ?? true) === true ? base : Object.assign(base, require_utils.functionalUpdate(spec, base));
946
+ }
1178
947
  function extractStrictParams(route, accumulatedParams) {
1179
948
  const parseParams = route.options.params?.parse ?? route.options.parseParams;
1180
- if (parseParams) {
1181
- const result = parseParams(accumulatedParams);
1182
- if (result === false) throw new Error("Route params.parse returned false for a matched route");
1183
- Object.assign(accumulatedParams, result);
1184
- }
949
+ if (parseParams) Object.assign(accumulatedParams, parseParams(accumulatedParams));
1185
950
  }
1186
951
  //#endregion
1187
952
  exports.PathParamError = PathParamError;
@@ -1190,8 +955,8 @@ exports.SearchParamError = SearchParamError;
1190
955
  exports.defaultSerializeError = defaultSerializeError;
1191
956
  exports.getInitialRouterState = getInitialRouterState;
1192
957
  exports.getLocationChangeInfo = getLocationChangeInfo;
1193
- exports.getMatchedRoutes = getMatchedRoutes;
1194
958
  exports.lazyFn = lazyFn;
959
+ exports.runRouteLifecycle = runRouteLifecycle;
1195
960
  exports.trailingSlashOptions = trailingSlashOptions;
1196
961
 
1197
962
  //# sourceMappingURL=router.cjs.map