@tanstack/router-core 1.154.13 → 1.154.14

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.
@@ -6,7 +6,7 @@ export type { IsRequiredParams, AddTrailingSlash, RemoveTrailingSlashes, AddLead
6
6
  export { componentTypes } from './load-matches.cjs';
7
7
  export type { RouteToPath, TrailingSlashOptionByRouter, ParseRoute, CodeRouteToPath, RouteIds, FullSearchSchema, FullSearchSchemaInput, AllParams, RouteById, AllContext, RoutePaths, RoutesById, RoutesByPath, AllLoaderData, RouteByPath, } from './routeInfo.cjs';
8
8
  export type { InferFileRouteTypes, FileRouteTypes, FileRoutesByPath, CreateFileRoute, LazyRoute, LazyRouteOptions, CreateLazyFileRoute, } from './fileRoute.cjs';
9
- export type { MatchSnapshot, ParsedLocation, ValidatedSearchEntry, } from './location.cjs';
9
+ export type { ParsedLocation } from './location.cjs';
10
10
  export type { Manifest, RouterManagedTag } from './manifest.cjs';
11
11
  export { isMatch } from './Matches.cjs';
12
12
  export type { AnyMatchAndValue, FindValueByIndex, FindValueByKey, CreateMatchAndValue, NextMatchAndValue, IsMatchKeyOf, IsMatchPath, IsMatchResult, IsMatchParse, IsMatch, RouteMatch, RouteMatchExtensions, MakeRouteMatchUnion, MakeRouteMatch, AnyRouteMatch, MakeRouteMatchFromRoute, MatchRouteOptions, } from './Matches.cjs';
@@ -1,32 +1,5 @@
1
1
  import { ParsedHistoryState } from '@tanstack/history';
2
2
  import { AnySchema } from './validators.cjs';
3
- /**
4
- * Per-route validated search result cached in snapshot.
5
- */
6
- export interface ValidatedSearchEntry {
7
- /** Merged search (parent + this route's validated) */
8
- search: Record<string, unknown>;
9
- /** Strict search (only this route's validated fields) */
10
- strictSearch: Record<string, unknown>;
11
- }
12
- /**
13
- * Match snapshot stored in history state for fast-path on back/forward navigation.
14
- * Allows skipping path matching by storing route IDs and params.
15
- */
16
- export interface MatchSnapshot {
17
- /** Ordered route IDs that matched */
18
- routeIds: Array<string>;
19
- /** Raw path params extracted from the URL */
20
- params: Record<string, string>;
21
- /** Parsed/validated path params */
22
- parsedParams: Record<string, unknown>;
23
- /** Route ID that should show global not found, if any */
24
- globalNotFoundRouteId?: string;
25
- /** Search string when snapshot was created (for cache invalidation) */
26
- searchStr?: string;
27
- /** Per-route validated search results (parallel to routeIds) */
28
- validatedSearches?: Array<ValidatedSearchEntry>;
29
- }
30
3
  export interface ParsedLocation<TSearchObj extends AnySchema = {}> {
31
4
  /**
32
5
  * The full path of the location, including pathname, search, and hash.
@@ -49,6 +49,7 @@ class RouterCore {
49
49
  this.tempLocationKey = `${Math.round(
50
50
  Math.random() * 1e7
51
51
  )}`;
52
+ this.resetNextScroll = true;
52
53
  this.shouldViewTransition = void 0;
53
54
  this.isViewTransitionTypesSupported = void 0;
54
55
  this.subscribers = /* @__PURE__ */ new Set();
@@ -250,9 +251,9 @@ class RouterCore {
250
251
  search: locationSearchOrOpts
251
252
  },
252
253
  opts
253
- ).matches;
254
+ );
254
255
  }
255
- return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts).matches;
256
+ return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts);
256
257
  };
257
258
  this.getMatchedRoutes = (pathname) => {
258
259
  return getMatchedRoutes({
@@ -318,14 +319,12 @@ class RouterCore {
318
319
  }).interpolatedPath;
319
320
  const destMatchResult = this.getMatchedRoutes(interpolatedNextTo);
320
321
  let destRoutes = destMatchResult.matchedRoutes;
321
- const rawParams = destMatchResult.routeParams;
322
322
  const isGlobalNotFound = destMatchResult.foundRoute ? destMatchResult.foundRoute.path !== "/" && destMatchResult.routeParams["**"] : path.trimPathRight(interpolatedNextTo);
323
- let globalNotFoundRouteId;
324
323
  if (isGlobalNotFound) {
325
324
  if (this.options.notFoundRoute) {
326
325
  destRoutes = [...destRoutes, this.options.notFoundRoute];
327
326
  } else {
328
- globalNotFoundRouteId = findGlobalNotFoundRouteId(
327
+ findGlobalNotFoundRouteId(
329
328
  this.options.notFoundMode,
330
329
  destRoutes
331
330
  );
@@ -381,31 +380,19 @@ class RouterCore {
381
380
  const hashStr = hash ? `#${hash}` : "";
382
381
  let nextState = dest.state === true ? currentLocation.state : dest.state ? utils.functionalUpdate(dest.state, currentLocation.state) : {};
383
382
  nextState = utils.replaceEqualDeep(currentLocation.state, nextState);
384
- const snapshotParams = {
385
- ...rawParams,
386
- ...nextParams
387
- };
388
- const matchSnapshot = buildMatchSnapshotFromRoutes({
389
- routes: destRoutes,
390
- params: snapshotParams,
391
- searchStr,
392
- globalNotFoundRouteId
393
- });
394
383
  const fullPath = `${nextPathname}${searchStr}${hashStr}`;
395
384
  const url = new URL(fullPath, this.origin);
396
385
  const rewrittenUrl = rewrite.executeRewriteOutput(this.rewrite, url);
397
- const encodedHref = url.href.replace(url.origin, "");
398
386
  return {
399
387
  publicHref: rewrittenUrl.pathname + rewrittenUrl.search + rewrittenUrl.hash,
400
- href: encodedHref,
388
+ href: fullPath,
401
389
  url: rewrittenUrl,
402
390
  pathname: nextPathname,
403
391
  search: nextSearch,
404
392
  searchStr,
405
393
  state: nextState,
406
394
  hash: hash ?? "",
407
- unmaskOnReload: dest.unmaskOnReload,
408
- _matchSnapshot: matchSnapshot
395
+ unmaskOnReload: dest.unmaskOnReload
409
396
  };
410
397
  };
411
398
  const buildWithMatches = (dest = {}, maskedDest) => {
@@ -477,73 +464,53 @@ class RouterCore {
477
464
  });
478
465
  if (isSameUrl && isSameState()) {
479
466
  this.load();
480
- return this.commitLocationPromise;
481
- }
482
- let {
483
- // eslint-disable-next-line prefer-const
484
- maskedLocation,
485
- // eslint-disable-next-line prefer-const
486
- hashScrollIntoView,
487
- // don't pass url into history since it is a URL instance that cannot be serialized
488
- // eslint-disable-next-line prefer-const
489
- url: _url,
490
- ...nextHistory
491
- } = next;
492
- if (maskedLocation) {
493
- nextHistory = {
494
- ...maskedLocation,
495
- state: {
496
- ...maskedLocation.state,
497
- __tempKey: void 0,
498
- __tempLocation: {
499
- ...nextHistory,
500
- search: nextHistory.searchStr,
501
- state: {
502
- ...nextHistory.state,
503
- __tempKey: void 0,
504
- __tempLocation: void 0,
505
- __TSR_key: void 0,
506
- key: void 0
507
- // TODO: Remove in v2 - use __TSR_key instead
467
+ } else {
468
+ let {
469
+ // eslint-disable-next-line prefer-const
470
+ maskedLocation,
471
+ // eslint-disable-next-line prefer-const
472
+ hashScrollIntoView,
473
+ // don't pass url into history since it is a URL instance that cannot be serialized
474
+ // eslint-disable-next-line prefer-const
475
+ url: _url,
476
+ ...nextHistory
477
+ } = next;
478
+ if (maskedLocation) {
479
+ nextHistory = {
480
+ ...maskedLocation,
481
+ state: {
482
+ ...maskedLocation.state,
483
+ __tempKey: void 0,
484
+ __tempLocation: {
485
+ ...nextHistory,
486
+ search: nextHistory.searchStr,
487
+ state: {
488
+ ...nextHistory.state,
489
+ __tempKey: void 0,
490
+ __tempLocation: void 0,
491
+ __TSR_key: void 0,
492
+ key: void 0
493
+ // TODO: Remove in v2 - use __TSR_key instead
494
+ }
508
495
  }
509
496
  }
497
+ };
498
+ if (nextHistory.unmaskOnReload ?? this.options.unmaskOnReload ?? false) {
499
+ nextHistory.state.__tempKey = this.tempLocationKey;
510
500
  }
511
- };
512
- if (nextHistory.unmaskOnReload ?? this.options.unmaskOnReload ?? false) {
513
- nextHistory.state.__tempKey = this.tempLocationKey;
514
501
  }
502
+ nextHistory.state.__hashScrollIntoViewOptions = hashScrollIntoView ?? this.options.defaultHashScrollIntoView ?? true;
503
+ this.shouldViewTransition = viewTransition;
504
+ this.history[next.replace ? "replace" : "push"](
505
+ nextHistory.publicHref,
506
+ nextHistory.state,
507
+ { ignoreBlocker }
508
+ );
515
509
  }
516
- nextHistory.state.__hashScrollIntoViewOptions = hashScrollIntoView ?? this.options.defaultHashScrollIntoView ?? true;
517
- nextHistory.state.__TSR_resetScroll = next.resetScroll ?? true;
518
- this.shouldViewTransition = viewTransition;
519
- nextHistory.state.__TSR_sessionId = this.sessionId;
520
- nextHistory.state.__TSR_matches = next._matchSnapshot ?? buildMatchSnapshot({
521
- matchResult: this.getMatchedRoutes(next.pathname),
522
- pathname: next.pathname,
523
- searchStr: next.searchStr,
524
- notFoundRoute: this.options.notFoundRoute,
525
- notFoundMode: this.options.notFoundMode
526
- });
527
- const precomputedLocation = {
528
- ...next,
529
- publicHref: nextHistory.publicHref,
530
- state: nextHistory.state,
531
- maskedLocation
532
- };
533
- const result = await this.history[next.replace ? "replace" : "push"](
534
- nextHistory.publicHref,
535
- nextHistory.state,
536
- { ignoreBlocker, skipTransitionerLoad: true }
537
- );
538
- if (result.type === "BLOCKED") {
539
- this.commitLocationPromise?.resolve();
540
- return this.commitLocationPromise;
541
- }
542
- if (this.history.location.href !== nextHistory.publicHref) {
543
- return this.commitLocationPromise;
510
+ this.resetNextScroll = next.resetScroll ?? true;
511
+ if (!this.history.subscribers.size) {
512
+ this.load();
544
513
  }
545
- this.latestLocation = precomputedLocation;
546
- this.load({ _skipUpdateLatestLocation: true });
547
514
  return this.commitLocationPromise;
548
515
  };
549
516
  this.buildAndCommitLocation = ({
@@ -650,11 +617,9 @@ class RouterCore {
650
617
  _isNavigate: true
651
618
  });
652
619
  };
653
- this.beforeLoad = (opts) => {
620
+ this.beforeLoad = () => {
654
621
  this.cancelMatches();
655
- if (!opts?._skipUpdateLatestLocation) {
656
- this.updateLatestLocation();
657
- }
622
+ this.updateLatestLocation();
658
623
  if (this.isServer) {
659
624
  const nextLocation = this.buildLocation({
660
625
  to: this.latestLocation.pathname,
@@ -669,8 +634,7 @@ class RouterCore {
669
634
  throw redirect.redirect({ href });
670
635
  }
671
636
  }
672
- const snapshot = this.latestLocation.state.__TSR_sessionId === this.sessionId ? this.latestLocation.state.__TSR_matches : void 0;
673
- const pendingMatches = this.matchRoutes(this.latestLocation, { snapshot });
637
+ const pendingMatches = this.matchRoutes(this.latestLocation);
674
638
  this.__store.setState((s) => ({
675
639
  ...s,
676
640
  status: "pending",
@@ -691,9 +655,7 @@ class RouterCore {
691
655
  loadPromise = new Promise((resolve) => {
692
656
  this.startTransition(async () => {
693
657
  try {
694
- this.beforeLoad({
695
- _skipUpdateLatestLocation: opts?._skipUpdateLatestLocation
696
- });
658
+ this.beforeLoad();
697
659
  const next = this.latestLocation;
698
660
  const prevLocation = this.state.resolvedLocation;
699
661
  if (!this.state.redirect) {
@@ -1050,7 +1012,6 @@ class RouterCore {
1050
1012
  (d) => d.status === "notFound" || d.globalNotFound
1051
1013
  );
1052
1014
  };
1053
- this.sessionId = typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `${Date.now()}-${Math.random().toString(36).slice(2)}`;
1054
1015
  this.update({
1055
1016
  defaultPreloadDelay: 50,
1056
1017
  defaultPendingMs: 1e3,
@@ -1079,57 +1040,33 @@ class RouterCore {
1079
1040
  return this.routesById;
1080
1041
  }
1081
1042
  matchRoutesInternal(next, opts) {
1082
- const snapshot = opts?.snapshot;
1083
- const snapshotValid = snapshot && snapshot.routeIds.length > 0 && snapshot.routeIds.every((id) => this.routesById[id]);
1084
- let matchedRoutes;
1085
- let routeParams;
1086
- let rawParams;
1087
- let globalNotFoundRouteId;
1088
- let parsedParams;
1089
- if (snapshotValid) {
1090
- matchedRoutes = snapshot.routeIds.map((id) => this.routesById[id]);
1091
- routeParams = { ...snapshot.params };
1092
- rawParams = { ...snapshot.params };
1093
- globalNotFoundRouteId = snapshot.globalNotFoundRouteId;
1094
- parsedParams = snapshot.parsedParams;
1095
- } else {
1096
- const matchedRoutesResult = this.getMatchedRoutes(next.pathname);
1097
- const { foundRoute, routeParams: rp } = matchedRoutesResult;
1098
- routeParams = rp;
1099
- rawParams = { ...rp };
1100
- matchedRoutes = matchedRoutesResult.matchedRoutes;
1101
- parsedParams = matchedRoutesResult.parsedParams;
1102
- let isGlobalNotFound = false;
1103
- if (
1104
- // If we found a route, and it's not an index route and we have left over path
1105
- foundRoute ? foundRoute.path !== "/" && routeParams["**"] : (
1106
- // Or if we didn't find a route and we have left over path
1107
- path.trimPathRight(next.pathname)
1108
- )
1109
- ) {
1110
- if (this.options.notFoundRoute) {
1111
- matchedRoutes = [...matchedRoutes, this.options.notFoundRoute];
1112
- } else {
1113
- isGlobalNotFound = true;
1114
- }
1043
+ const matchedRoutesResult = this.getMatchedRoutes(next.pathname);
1044
+ const { foundRoute, routeParams, parsedParams } = matchedRoutesResult;
1045
+ let { matchedRoutes } = matchedRoutesResult;
1046
+ let isGlobalNotFound = false;
1047
+ if (
1048
+ // If we found a route, and it's not an index route and we have left over path
1049
+ foundRoute ? foundRoute.path !== "/" && routeParams["**"] : (
1050
+ // Or if we didn't find a route and we have left over path
1051
+ path.trimPathRight(next.pathname)
1052
+ )
1053
+ ) {
1054
+ if (this.options.notFoundRoute) {
1055
+ matchedRoutes = [...matchedRoutes, this.options.notFoundRoute];
1056
+ } else {
1057
+ isGlobalNotFound = true;
1115
1058
  }
1116
- globalNotFoundRouteId = isGlobalNotFound ? findGlobalNotFoundRouteId(this.options.notFoundMode, matchedRoutes) : void 0;
1117
1059
  }
1060
+ const globalNotFoundRouteId = isGlobalNotFound ? findGlobalNotFoundRouteId(this.options.notFoundMode, matchedRoutes) : void 0;
1118
1061
  const matches = [];
1119
1062
  const getParentContext = (parentMatch) => {
1120
1063
  const parentMatchId = parentMatch?.id;
1121
1064
  const parentContext = !parentMatchId ? this.options.context ?? void 0 : parentMatch.context ?? this.options.context ?? void 0;
1122
1065
  return parentContext;
1123
1066
  };
1124
- const canUseCachedSearch = snapshotValid && snapshot.searchStr === next.searchStr && snapshot.validatedSearches?.length === matchedRoutes.length;
1125
- const validatedSearchesToCache = [];
1126
1067
  matchedRoutes.forEach((route, index) => {
1127
1068
  const parentMatch = matches[index - 1];
1128
1069
  const [preMatchSearch, strictMatchSearch, searchError] = (() => {
1129
- if (canUseCachedSearch) {
1130
- const cached = snapshot.validatedSearches[index];
1131
- return [cached.search, cached.strictSearch, void 0];
1132
- }
1133
1070
  const parentSearch = parentMatch?.search ?? next.search;
1134
1071
  const parentStrictSearch = parentMatch?._strictSearch ?? void 0;
1135
1072
  try {
@@ -1155,12 +1092,6 @@ class RouterCore {
1155
1092
  return [parentSearch, {}, searchParamError];
1156
1093
  }
1157
1094
  })();
1158
- if (!canUseCachedSearch) {
1159
- validatedSearchesToCache.push({
1160
- search: preMatchSearch,
1161
- strictSearch: strictMatchSearch
1162
- });
1163
- }
1164
1095
  const loaderDeps = route.options.loaderDeps?.({
1165
1096
  search: preMatchSearch
1166
1097
  }) ?? "";
@@ -1274,13 +1205,6 @@ class RouterCore {
1274
1205
  };
1275
1206
  matches.push(match);
1276
1207
  });
1277
- if (!canUseCachedSearch && validatedSearchesToCache.length > 0) {
1278
- const existingSnapshot = next.state?.__TSR_matches;
1279
- if (existingSnapshot) {
1280
- existingSnapshot.searchStr = next.searchStr;
1281
- existingSnapshot.validatedSearches = validatedSearchesToCache;
1282
- }
1283
- }
1284
1208
  matches.forEach((match, index) => {
1285
1209
  const route = this.looseRoutesById[match.routeId];
1286
1210
  const existingMatch = this.getMatch(match.id);
@@ -1309,7 +1233,7 @@ class RouterCore {
1309
1233
  };
1310
1234
  }
1311
1235
  });
1312
- return { matches, rawParams };
1236
+ return matches;
1313
1237
  }
1314
1238
  }
1315
1239
  class SearchParamError extends Error {
@@ -1368,7 +1292,7 @@ function getMatchedRoutes({
1368
1292
  const routeParams = {};
1369
1293
  const trimmedPath = path.trimPathRight(pathname);
1370
1294
  let foundRoute = void 0;
1371
- let parsedParams = {};
1295
+ let parsedParams = void 0;
1372
1296
  const match = newProcessRouteTree.findRouteMatch(trimmedPath, processedTree, true);
1373
1297
  if (match) {
1374
1298
  foundRoute = match.route;
@@ -1378,64 +1302,6 @@ function getMatchedRoutes({
1378
1302
  const matchedRoutes = match?.branch || [routesById[root.rootRouteId]];
1379
1303
  return { matchedRoutes, routeParams, foundRoute, parsedParams };
1380
1304
  }
1381
- function buildMatchSnapshot({
1382
- matchResult,
1383
- pathname,
1384
- searchStr,
1385
- notFoundRoute,
1386
- notFoundMode
1387
- }) {
1388
- const snapshot = {
1389
- routeIds: matchResult.matchedRoutes.map((r) => r.id),
1390
- params: matchResult.routeParams,
1391
- parsedParams: matchResult.parsedParams,
1392
- searchStr
1393
- };
1394
- const isGlobalNotFound = matchResult.foundRoute ? matchResult.foundRoute.path !== "/" && matchResult.routeParams["**"] : path.trimPathRight(pathname);
1395
- if (isGlobalNotFound) {
1396
- if (notFoundRoute) {
1397
- snapshot.globalNotFoundRouteId = notFoundRoute.id;
1398
- } else {
1399
- if (notFoundMode !== "root") {
1400
- for (let i = matchResult.matchedRoutes.length - 1; i >= 0; i--) {
1401
- const route = matchResult.matchedRoutes[i];
1402
- if (route.children) {
1403
- snapshot.globalNotFoundRouteId = route.id;
1404
- break;
1405
- }
1406
- }
1407
- }
1408
- if (!snapshot.globalNotFoundRouteId) {
1409
- snapshot.globalNotFoundRouteId = root.rootRouteId;
1410
- }
1411
- }
1412
- }
1413
- return snapshot;
1414
- }
1415
- function buildMatchSnapshotFromRoutes({
1416
- routes,
1417
- params,
1418
- searchStr,
1419
- globalNotFoundRouteId
1420
- }) {
1421
- const stringParams = {};
1422
- for (const key in params) {
1423
- const value = params[key];
1424
- if (value != null) {
1425
- stringParams[key] = String(value);
1426
- }
1427
- }
1428
- const snapshot = {
1429
- routeIds: routes.map((r) => r.id),
1430
- params: stringParams,
1431
- parsedParams: params,
1432
- searchStr
1433
- };
1434
- if (globalNotFoundRouteId) {
1435
- snapshot.globalNotFoundRouteId = globalNotFoundRouteId;
1436
- }
1437
- return snapshot;
1438
- }
1439
1305
  function applySearchMiddleware({
1440
1306
  search,
1441
1307
  dest,
@@ -1534,8 +1400,6 @@ function findGlobalNotFoundRouteId(notFoundMode, routes) {
1534
1400
  exports.PathParamError = PathParamError;
1535
1401
  exports.RouterCore = RouterCore;
1536
1402
  exports.SearchParamError = SearchParamError;
1537
- exports.buildMatchSnapshot = buildMatchSnapshot;
1538
- exports.buildMatchSnapshotFromRoutes = buildMatchSnapshotFromRoutes;
1539
1403
  exports.defaultSerializeError = defaultSerializeError;
1540
1404
  exports.getInitialRouterState = getInitialRouterState;
1541
1405
  exports.getLocationChangeInfo = getLocationChangeInfo;