@tanstack/router-core 1.168.17 → 1.169.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/cjs/Matches.cjs +1 -1
  2. package/dist/cjs/Matches.cjs.map +1 -1
  3. package/dist/cjs/config.cjs +1 -1
  4. package/dist/cjs/config.cjs.map +1 -1
  5. package/dist/cjs/defer.cjs +1 -1
  6. package/dist/cjs/defer.cjs.map +1 -1
  7. package/dist/cjs/index.cjs +1 -0
  8. package/dist/cjs/index.d.cts +1 -1
  9. package/dist/cjs/isServer/client.cjs +1 -1
  10. package/dist/cjs/isServer/client.cjs.map +1 -1
  11. package/dist/cjs/isServer/development.cjs +1 -1
  12. package/dist/cjs/isServer/development.cjs.map +1 -1
  13. package/dist/cjs/isServer/server.cjs +1 -1
  14. package/dist/cjs/isServer/server.cjs.map +1 -1
  15. package/dist/cjs/link.cjs +1 -1
  16. package/dist/cjs/link.cjs.map +1 -1
  17. package/dist/cjs/load-matches.cjs +19 -19
  18. package/dist/cjs/load-matches.cjs.map +1 -1
  19. package/dist/cjs/new-process-route-tree.cjs +36 -48
  20. package/dist/cjs/new-process-route-tree.cjs.map +1 -1
  21. package/dist/cjs/new-process-route-tree.d.cts +4 -26
  22. package/dist/cjs/path.cjs +1 -22
  23. package/dist/cjs/path.cjs.map +1 -1
  24. package/dist/cjs/root.cjs +1 -1
  25. package/dist/cjs/root.cjs.map +1 -1
  26. package/dist/cjs/route.cjs.map +1 -1
  27. package/dist/cjs/route.d.cts +1 -32
  28. package/dist/cjs/router.cjs +36 -21
  29. package/dist/cjs/router.cjs.map +1 -1
  30. package/dist/cjs/router.d.cts +3 -4
  31. package/dist/cjs/scroll-restoration-script/server.cjs +1 -1
  32. package/dist/cjs/scroll-restoration-script/server.cjs.map +1 -1
  33. package/dist/cjs/scroll-restoration.cjs +6 -6
  34. package/dist/cjs/scroll-restoration.cjs.map +1 -1
  35. package/dist/cjs/searchParams.cjs +2 -2
  36. package/dist/cjs/searchParams.cjs.map +1 -1
  37. package/dist/cjs/ssr/constants.cjs +2 -2
  38. package/dist/cjs/ssr/constants.cjs.map +1 -1
  39. package/dist/cjs/ssr/serializer/RawStream.cjs +12 -12
  40. package/dist/cjs/ssr/serializer/RawStream.cjs.map +1 -1
  41. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs +1 -1
  42. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs.map +1 -1
  43. package/dist/cjs/ssr/serializer/seroval-plugins.cjs +1 -1
  44. package/dist/cjs/ssr/serializer/seroval-plugins.cjs.map +1 -1
  45. package/dist/cjs/ssr/ssr-server.cjs +9 -9
  46. package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
  47. package/dist/cjs/ssr/transformStreamWithRouter.cjs +6 -6
  48. package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -1
  49. package/dist/cjs/utils.cjs +12 -7
  50. package/dist/cjs/utils.cjs.map +1 -1
  51. package/dist/cjs/utils.d.cts +1 -0
  52. package/dist/esm/Matches.js +1 -1
  53. package/dist/esm/Matches.js.map +1 -1
  54. package/dist/esm/config.js +1 -1
  55. package/dist/esm/config.js.map +1 -1
  56. package/dist/esm/defer.js +1 -1
  57. package/dist/esm/defer.js.map +1 -1
  58. package/dist/esm/index.d.ts +1 -1
  59. package/dist/esm/index.js +2 -2
  60. package/dist/esm/isServer/client.js +1 -1
  61. package/dist/esm/isServer/client.js.map +1 -1
  62. package/dist/esm/isServer/development.js +1 -1
  63. package/dist/esm/isServer/development.js.map +1 -1
  64. package/dist/esm/isServer/server.js +1 -1
  65. package/dist/esm/isServer/server.js.map +1 -1
  66. package/dist/esm/link.js +1 -1
  67. package/dist/esm/link.js.map +1 -1
  68. package/dist/esm/load-matches.js +19 -19
  69. package/dist/esm/load-matches.js.map +1 -1
  70. package/dist/esm/new-process-route-tree.d.ts +4 -26
  71. package/dist/esm/new-process-route-tree.js +36 -49
  72. package/dist/esm/new-process-route-tree.js.map +1 -1
  73. package/dist/esm/path.js +1 -22
  74. package/dist/esm/path.js.map +1 -1
  75. package/dist/esm/root.js +1 -1
  76. package/dist/esm/root.js.map +1 -1
  77. package/dist/esm/route.d.ts +1 -32
  78. package/dist/esm/route.js.map +1 -1
  79. package/dist/esm/router.d.ts +3 -4
  80. package/dist/esm/router.js +38 -23
  81. package/dist/esm/router.js.map +1 -1
  82. package/dist/esm/scroll-restoration-script/server.js +1 -1
  83. package/dist/esm/scroll-restoration-script/server.js.map +1 -1
  84. package/dist/esm/scroll-restoration.js +6 -6
  85. package/dist/esm/scroll-restoration.js.map +1 -1
  86. package/dist/esm/searchParams.js +2 -2
  87. package/dist/esm/searchParams.js.map +1 -1
  88. package/dist/esm/ssr/constants.js +2 -2
  89. package/dist/esm/ssr/constants.js.map +1 -1
  90. package/dist/esm/ssr/serializer/RawStream.js +10 -10
  91. package/dist/esm/ssr/serializer/RawStream.js.map +1 -1
  92. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js +1 -1
  93. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js.map +1 -1
  94. package/dist/esm/ssr/serializer/seroval-plugins.js +1 -1
  95. package/dist/esm/ssr/serializer/seroval-plugins.js.map +1 -1
  96. package/dist/esm/ssr/ssr-server.js +9 -9
  97. package/dist/esm/ssr/ssr-server.js.map +1 -1
  98. package/dist/esm/ssr/transformStreamWithRouter.js +6 -6
  99. package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -1
  100. package/dist/esm/utils.d.ts +1 -0
  101. package/dist/esm/utils.js +12 -8
  102. package/dist/esm/utils.js.map +1 -1
  103. package/package.json +1 -1
  104. package/src/index.ts +1 -0
  105. package/src/new-process-route-tree.ts +42 -77
  106. package/src/path.ts +1 -27
  107. package/src/route.ts +5 -34
  108. package/src/router.ts +76 -54
  109. package/src/utils.ts +7 -0
@@ -1,6 +1,6 @@
1
- import { DEFAULT_PROTOCOL_ALLOWLIST, createControlledPromise, decodePath, deepEqual, encodePathLikeUrl, findLast, functionalUpdate, isDangerousProtocol, last, nullReplaceEqualDeep, replaceEqualDeep } from "./utils.js";
1
+ import { DEFAULT_PROTOCOL_ALLOWLIST, createControlledPromise, decodePath, deepEqual, encodePathLikeUrl, findLast, functionalUpdate, hasKeys, isDangerousProtocol, last, nullReplaceEqualDeep, replaceEqualDeep } from "./utils.js";
2
2
  import { createLRUCache } from "./lru-cache.js";
3
- import { findFlatMatch, findRouteMatch, findSingleMatch, processRouteMasks, processRouteTree } from "./new-process-route-tree.js";
3
+ import { buildRouteBranch, findFlatMatch, findRouteMatch, findSingleMatch, processRouteMasks, processRouteTree } from "./new-process-route-tree.js";
4
4
  import { cleanPath, compileDecodeCharMap, interpolatePath, resolvePath, trimPath, trimPathRight } from "./path.js";
5
5
  import { isNotFound } from "./not-found.js";
6
6
  import { setupScrollRestoration } from "./scroll-restoration.js";
@@ -29,7 +29,7 @@ function defaultSerializeError(err) {
29
29
  return { data: err };
30
30
  }
31
31
  /** Options for configuring trailing-slash behavior. */
32
- var trailingSlashOptions = {
32
+ const trailingSlashOptions = {
33
33
  always: "always",
34
34
  never: "never",
35
35
  preserve: "preserve"
@@ -70,6 +70,7 @@ var RouterCore = class {
70
70
  this.subscribers = /* @__PURE__ */ new Set();
71
71
  this.isScrollRestoring = false;
72
72
  this.isScrollRestorationSetup = false;
73
+ this.routeBranchCache = /* @__PURE__ */ new WeakMap();
73
74
  this.startTransition = (fn) => fn();
74
75
  this.update = (newOptions) => {
75
76
  if (process.env.NODE_ENV !== "production") {
@@ -207,7 +208,7 @@ var RouterCore = class {
207
208
  this.resolvePathWithBase = (from, path) => {
208
209
  return resolvePath({
209
210
  base: from,
210
- to: cleanPath(path),
211
+ to: path.includes("//") ? cleanPath(path) : path,
211
212
  trailingSlash: this.options.trailingSlash,
212
213
  cache: this.resolvePathCache
213
214
  });
@@ -259,15 +260,22 @@ var RouterCore = class {
259
260
  if (!matchedFrom && !matchedCurrent) console.warn(`Could not find match for from: ${dest.from}`);
260
261
  }
261
262
  const defaultedFromPath = dest.unsafeRelative === "path" ? currentLocation.pathname : dest.from ?? lightweightResult.fullPath;
262
- const fromPath = this.resolvePathWithBase(defaultedFromPath, ".");
263
+ const destTo = dest.to ? `${dest.to}` : void 0;
263
264
  const fromSearch = lightweightResult.search;
264
265
  const fromParams = Object.assign(Object.create(null), lightweightResult.params);
265
- const nextTo = dest.to ? this.resolvePathWithBase(fromPath, `${dest.to}`) : this.resolvePathWithBase(fromPath, ".");
266
+ const sourcePath = destTo?.charCodeAt(0) === 47 ? "/" : this.resolvePathWithBase(defaultedFromPath, ".");
267
+ const nextTo = destTo ? this.resolvePathWithBase(sourcePath, destTo) : sourcePath;
266
268
  const nextParams = dest.params === false || dest.params === null ? Object.create(null) : (dest.params ?? true) === true ? fromParams : Object.assign(fromParams, functionalUpdate(dest.params, fromParams));
267
- const destMatchResult = this.getMatchedRoutes(nextTo);
268
- let destRoutes = destMatchResult.matchedRoutes;
269
- if ((!destMatchResult.foundRoute || destMatchResult.foundRoute.path !== "/" && destMatchResult.routeParams["**"]) && this.options.notFoundRoute) destRoutes = [...destRoutes, this.options.notFoundRoute];
270
- if (Object.keys(nextParams).length > 0) for (const route of destRoutes) {
269
+ const destRoute = this.routesByPath[trimPathRight(nextTo)];
270
+ let destRoutes;
271
+ if (destRoute) destRoutes = this.getRouteBranch(destRoute);
272
+ else if (nextTo.includes("$")) destRoutes = [];
273
+ else {
274
+ const destMatchResult = this.getMatchedRoutes(nextTo);
275
+ destRoutes = destMatchResult.matchedRoutes;
276
+ if (this.options.notFoundRoute && (!destMatchResult.foundRoute || destMatchResult.foundRoute.path !== "/" && destMatchResult.routeParams["**"])) destRoutes = [...destRoutes, this.options.notFoundRoute];
277
+ }
278
+ if (destRoutes.length && hasKeys(nextParams)) for (const route of destRoutes) {
271
279
  const fn = route.options.params?.stringify ?? route.options.stringifyParams;
272
280
  if (fn) try {
273
281
  Object.assign(nextParams, fn(nextParams));
@@ -279,6 +287,9 @@ var RouterCore = class {
279
287
  decoder: this.pathParamsDecoder,
280
288
  server: this.isServer
281
289
  }).interpolatedPath).path;
290
+ if (process.env.NODE_ENV !== "production" && destRoute && !opts.leaveParams) try {
291
+ if (this.getMatchedRoutes(nextPathname).foundRoute?.id !== destRoute.id) console.warn(`Generated path "${nextPathname}" for route "${destRoute.id}" did not match the same route after params.stringify.`);
292
+ } catch {}
282
293
  let nextSearch = fromSearch;
283
294
  if (opts._includeValidateSearch && this.options.search?.strict) {
284
295
  const validatedSearch = {};
@@ -817,6 +828,14 @@ var RouterCore = class {
817
828
  this.routesById[notFoundRoute.id] = notFoundRoute;
818
829
  }
819
830
  }
831
+ getRouteBranch(route) {
832
+ let branch = this.routeBranchCache.get(route);
833
+ if (!branch) {
834
+ branch = buildRouteBranch(route);
835
+ this.routeBranchCache.set(route, branch);
836
+ }
837
+ return branch;
838
+ }
820
839
  get looseRoutesById() {
821
840
  return this.routesById;
822
841
  }
@@ -825,7 +844,7 @@ var RouterCore = class {
825
844
  }
826
845
  matchRoutesInternal(next, opts) {
827
846
  const matchedRoutesResult = this.getMatchedRoutes(next.pathname);
828
- const { foundRoute, routeParams, parsedParams } = matchedRoutesResult;
847
+ const { foundRoute, routeParams } = matchedRoutesResult;
829
848
  let { matchedRoutes } = matchedRoutesResult;
830
849
  let isGlobalNotFound = false;
831
850
  if (foundRoute ? foundRoute.path !== "/" && routeParams["**"] : trimPathRight(next.pathname)) if (this.options.notFoundRoute) matchedRoutes = [...matchedRoutes, this.options.notFoundRoute];
@@ -877,7 +896,7 @@ var RouterCore = class {
877
896
  const strictParams = existingMatch?._strictParams ?? usedParams;
878
897
  let paramsError = void 0;
879
898
  if (!existingMatch) try {
880
- extractStrictParams(route, usedParams, parsedParams, strictParams);
899
+ extractStrictParams(route, strictParams);
881
900
  } catch (err) {
882
901
  if (isNotFound(err) || isRedirect(err)) paramsError = err;
883
902
  else paramsError = new PathParamError(err.message, { cause: err });
@@ -983,7 +1002,7 @@ var RouterCore = class {
983
1002
  * operations like AbortController, ControlledPromise, loaderDeps, and full match objects.
984
1003
  */
985
1004
  matchRoutesLightweight(location) {
986
- const { matchedRoutes, routeParams, parsedParams } = this.getMatchedRoutes(location.pathname);
1005
+ const { matchedRoutes, routeParams } = this.getMatchedRoutes(location.pathname);
987
1006
  const lastRoute = last(matchedRoutes);
988
1007
  const accumulatedSearch = { ...location.search };
989
1008
  for (const route of matchedRoutes) try {
@@ -997,7 +1016,7 @@ var RouterCore = class {
997
1016
  else {
998
1017
  const strictParams = Object.assign(Object.create(null), routeParams);
999
1018
  for (const route of matchedRoutes) try {
1000
- extractStrictParams(route, routeParams, parsedParams ?? {}, strictParams);
1019
+ extractStrictParams(route, strictParams);
1001
1020
  } catch {}
1002
1021
  params = strictParams;
1003
1022
  }
@@ -1013,7 +1032,7 @@ var RouterCore = class {
1013
1032
  var SearchParamError = class extends Error {};
1014
1033
  /** Error thrown when path parameter parsing/validation fails. */
1015
1034
  var PathParamError = class extends Error {};
1016
- var normalize = (str) => str.endsWith("/") && str.length > 1 ? str.slice(0, -1) : str;
1035
+ const normalize = (str) => str.endsWith("/") && str.length > 1 ? str.slice(0, -1) : str;
1017
1036
  function comparePaths(a, b) {
1018
1037
  return normalize(a) === normalize(b);
1019
1038
  }
@@ -1059,18 +1078,15 @@ function getMatchedRoutes({ pathname, routesById, processedTree }) {
1059
1078
  const routeParams = Object.create(null);
1060
1079
  const trimmedPath = trimPathRight(pathname);
1061
1080
  let foundRoute = void 0;
1062
- let parsedParams = void 0;
1063
1081
  const match = findRouteMatch(trimmedPath, processedTree, true);
1064
1082
  if (match) {
1065
1083
  foundRoute = match.route;
1066
1084
  Object.assign(routeParams, match.rawParams);
1067
- parsedParams = Object.assign(Object.create(null), match.parsedParams);
1068
1085
  }
1069
1086
  return {
1070
1087
  matchedRoutes: match?.branch || [routesById["__root__"]],
1071
1088
  routeParams,
1072
- foundRoute,
1073
- parsedParams
1089
+ foundRoute
1074
1090
  };
1075
1091
  }
1076
1092
  /**
@@ -1146,12 +1162,11 @@ function findGlobalNotFoundRouteId(notFoundMode, routes) {
1146
1162
  }
1147
1163
  return rootRouteId;
1148
1164
  }
1149
- function extractStrictParams(route, referenceParams, parsedParams, accumulatedParams) {
1165
+ function extractStrictParams(route, accumulatedParams) {
1150
1166
  const parseParams = route.options.params?.parse ?? route.options.parseParams;
1151
- if (parseParams) if (route.options.skipRouteOnParseError) {
1152
- for (const key in referenceParams) if (key in parsedParams) accumulatedParams[key] = parsedParams[key];
1153
- } else {
1167
+ if (parseParams) {
1154
1168
  const result = parseParams(accumulatedParams);
1169
+ if (result === false) throw new Error("Route params.parse returned false for a matched route");
1155
1170
  Object.assign(accumulatedParams, result);
1156
1171
  }
1157
1172
  }