@tanstack/router-core 1.171.24 → 1.171.26

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.
@@ -59,13 +59,13 @@ function _getUserHistoryState({ key: _key, __TSR_key: _tsrKey, __TSR_index: _tsr
59
59
  return state;
60
60
  }
61
61
  /** Run route lifecycle callbacks in leave/enter/stay phases. */
62
- function runRouteLifecycle(router, previous, matches, isCurrent) {
62
+ function runRouteLifecycle(router, previous, matches, owner) {
63
63
  for (const match of previous) {
64
- if (isCurrent?.() === false) return;
64
+ if (owner && router._tx !== owner) return;
65
65
  if (!matches.some((candidate) => candidate.routeId === match.routeId)) router.routesById[match.routeId].options.onLeave?.(match);
66
66
  }
67
67
  for (const match of matches) {
68
- if (isCurrent?.() === false) return;
68
+ if (owner && router._tx !== owner) return;
69
69
  router.routesById[match.routeId].options[previous.some((candidate) => candidate.routeId === match.routeId) ? "onStay" : "onEnter"]?.(match);
70
70
  }
71
71
  }
@@ -229,7 +229,7 @@ var RouterCore = class {
229
229
  this.resolvePathWithBase = (from, path) => {
230
230
  return require_path.resolvePath({
231
231
  base: from,
232
- to: path.includes("//") ? require_path.cleanPath(path) : path,
232
+ to: path,
233
233
  trailingSlash: this.options.trailingSlash,
234
234
  cache: this.resolvePathCache
235
235
  });
@@ -253,6 +253,15 @@ var RouterCore = class {
253
253
  };
254
254
  this.buildLocation = (opts) => {
255
255
  const build = (dest = {}) => {
256
+ if (dest.href) {
257
+ const parsed = (0, _tanstack_history.parseHref)(dest.href, {});
258
+ dest = {
259
+ ...dest,
260
+ to: require_rewrite.executeRewriteInput(this.rewrite, new URL(parsed.pathname, this.origin)).pathname,
261
+ search: this.options.parseSearch(parsed.search),
262
+ hash: parsed.hash.slice(1)
263
+ };
264
+ }
256
265
  const currentLocation = dest._fromLocation || this._pendingLocation || this.latestLocation;
257
266
  const lightweightResult = this.matchRoutesLightweight(currentLocation);
258
267
  if (dest.from && process.env.NODE_ENV !== "production" && dest._isNavigate) {
@@ -266,12 +275,10 @@ var RouterCore = class {
266
275
  if (!matchedFrom && !matchedCurrent) console.warn(`Could not find match for from: ${dest.from}`);
267
276
  }
268
277
  const defaultedFromPath = dest.unsafeRelative === "path" ? currentLocation.pathname : dest.from ?? lightweightResult[1];
269
- const destTo = dest.to ? `${dest.to}` : void 0;
270
278
  const fromSearch = lightweightResult[2];
271
- const fromParams = Object.assign(Object.create(null), lightweightResult[3]);
272
- const sourcePath = destTo?.charCodeAt(0) === 47 ? "/" : this.resolvePathWithBase(defaultedFromPath, ".");
273
- const nextTo = destTo ? this.resolvePathWithBase(sourcePath, destTo) : sourcePath;
274
- const nextParams = resolveNextParams(dest.params, fromParams);
279
+ const fromParams = lightweightResult[3];
280
+ const nextTo = this.resolvePathWithBase(defaultedFromPath, dest.to ? `${dest.to}` : ".");
281
+ let nextParams = resolveNextParams(dest.params, fromParams);
275
282
  const destRoute = this.routesByPath[require_path.trimPathRight(nextTo)];
276
283
  let destRoutes;
277
284
  if (destRoute) destRoutes = this.getRouteBranch(destRoute);
@@ -283,9 +290,12 @@ var RouterCore = class {
283
290
  }
284
291
  if (destRoutes.length && require_utils.hasKeys(nextParams)) for (const route of destRoutes) {
285
292
  const fn = route.options.params?.stringify ?? route.options.stringifyParams;
286
- if (fn) try {
287
- Object.assign(nextParams, fn(nextParams));
288
- } catch {}
293
+ if (fn) {
294
+ if (nextParams === fromParams) nextParams = Object.assign(Object.create(null), nextParams);
295
+ try {
296
+ Object.assign(nextParams, fn(nextParams));
297
+ } catch {}
298
+ }
289
299
  }
290
300
  const nextPathname = opts.leaveParams ? nextTo : require_utils.decodePath(require_path.interpolatePath({
291
301
  path: nextTo,
@@ -316,7 +326,7 @@ var RouterCore = class {
316
326
  const hash = dest.hash === true ? currentLocation.hash : dest.hash ? require_utils.functionalUpdate(dest.hash, currentLocation.hash) : void 0;
317
327
  const hashStr = hash ? `#${hash}` : "";
318
328
  let nextState = dest.state === true ? currentLocation.state : dest.state ? require_utils.functionalUpdate(dest.state, currentLocation.state) : {};
319
- nextState = require_utils.replaceEqualDeep(currentLocation.state, nextState);
329
+ if (dest.state) nextState = require_utils.replaceEqualDeep(currentLocation.state, nextState);
320
330
  const fullPath = `${nextPathname}${searchStr}${hashStr}`;
321
331
  let href;
322
332
  let publicHref;
@@ -411,20 +421,11 @@ var RouterCore = class {
411
421
  this._scroll.next = next.resetScroll ?? true;
412
422
  return this._commitPromise;
413
423
  };
414
- this.buildAndCommitLocation = ({ replace, resetScroll, hashScrollIntoView, viewTransition, ignoreBlocker, _redirects, href, ...rest } = {}) => {
415
- if (href) {
416
- const currentIndex = this.history.location.state.__TSR_index;
417
- const parsed = (0, _tanstack_history.parseHref)(href, { __TSR_index: replace ? currentIndex : currentIndex + 1 });
418
- const hrefUrl = new URL(parsed.pathname, this.origin);
419
- rest.to = require_rewrite.executeRewriteInput(this.rewrite, hrefUrl).pathname;
420
- rest.search = this.options.parseSearch(parsed.search);
421
- rest.hash = parsed.hash.slice(1);
422
- }
424
+ this.buildAndCommitLocation = ({ replace, resetScroll, hashScrollIntoView, viewTransition, ignoreBlocker, ...rest } = {}) => {
423
425
  const location = this.buildLocation({
424
426
  ...rest,
425
427
  _includeValidateSearch: true
426
428
  });
427
- if (_redirects) location._redirects = _redirects;
428
429
  this._pendingLocation = location;
429
430
  const commitPromise = this.commitLocation({
430
431
  ...location,
@@ -549,8 +550,8 @@ var RouterCore = class {
549
550
  };
550
551
  this.resolveRedirect = (redirect) => {
551
552
  const locationHeader = redirect.headers.get("Location");
552
- if (!redirect.options.href || redirect.options._builtLocation) {
553
- const href = (redirect.options._builtLocation ?? this.buildLocation(redirect.options)).publicHref || "/";
553
+ if (!redirect.options.href) {
554
+ const href = this.buildLocation(redirect.options).publicHref || "/";
554
555
  redirect.options.href = href;
555
556
  redirect.headers.set("Location", href);
556
557
  } else if (locationHeader) try {
@@ -561,7 +562,7 @@ var RouterCore = class {
561
562
  redirect.headers.set("Location", href);
562
563
  }
563
564
  } catch {}
564
- 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");
565
+ if (redirect.options.href && 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");
565
566
  if (!redirect.headers.get("Location")) redirect.headers.set("Location", redirect.options.href);
566
567
  return redirect;
567
568
  };
@@ -593,7 +594,7 @@ var RouterCore = class {
593
594
  for (const controller of abort) controller.abort();
594
595
  };
595
596
  this.loadRouteChunk = require_load_client.loadRouteChunk;
596
- this.preloadRoute = (opts) => require_load_client.preloadClientRoute(this, opts);
597
+ this.preloadRoute = (opts, builtLocation) => require_load_client.preloadClientRoute(this, opts, 0, builtLocation);
597
598
  this.matchRoute = (location, opts) => {
598
599
  const matchLocation = {
599
600
  ...location,
@@ -873,10 +874,10 @@ function applySearchMiddleware(search, dest, destRoutes, includeValidateSearch)
873
874
  middlewares.push(legacyMiddleware);
874
875
  }
875
876
  const routeValidateSearch = routeOptions.validateSearch;
876
- if (routeValidateSearch) {
877
+ if (includeValidateSearch && routeValidateSearch) {
877
878
  const validate = ({ search, next, meta }) => {
878
879
  const result = next(search);
879
- if (includeValidateSearch) try {
880
+ try {
880
881
  const validated = validateSearch(routeValidateSearch, result);
881
882
  if (meta && validated) {
882
883
  for (const key in validated) if (!(key in result)) (meta.defaulted ||= /* @__PURE__ */ new Map()).set(key, validated[key]);
@@ -930,7 +931,10 @@ function findGlobalNotFoundRouteId(notFoundMode, routes) {
930
931
  return require_root.rootRouteId;
931
932
  }
932
933
  function resolveNextParams(spec, base) {
933
- return spec === false || spec === null ? Object.create(null) : (spec ?? true) === true ? base : Object.assign(base, require_utils.functionalUpdate(spec, base));
934
+ if (spec === false || spec === null) return Object.create(null);
935
+ if ((spec ?? true) === true) return base;
936
+ const next = Object.assign(Object.create(null), base);
937
+ return Object.assign(next, require_utils.functionalUpdate(spec, next));
934
938
  }
935
939
  function extractStrictParams(route, accumulatedParams) {
936
940
  const parseParams = route.options.params?.parse ?? route.options.parseParams;