@tanstack/router-core 1.121.0-alpha.3 → 1.121.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 (50) hide show
  1. package/dist/cjs/RouterProvider.d.cts +2 -2
  2. package/dist/cjs/index.d.cts +2 -2
  3. package/dist/cjs/link.cjs.map +1 -1
  4. package/dist/cjs/link.d.cts +1 -1
  5. package/dist/cjs/qss.cjs +2 -4
  6. package/dist/cjs/qss.cjs.map +1 -1
  7. package/dist/cjs/qss.d.cts +9 -0
  8. package/dist/cjs/redirect.cjs +7 -0
  9. package/dist/cjs/redirect.cjs.map +1 -1
  10. package/dist/cjs/route.cjs.map +1 -1
  11. package/dist/cjs/route.d.cts +11 -1
  12. package/dist/cjs/router.cjs +136 -148
  13. package/dist/cjs/router.cjs.map +1 -1
  14. package/dist/cjs/router.d.cts +3 -6
  15. package/dist/cjs/scroll-restoration.cjs +1 -1
  16. package/dist/cjs/scroll-restoration.cjs.map +1 -1
  17. package/dist/cjs/scroll-restoration.d.cts +1 -1
  18. package/dist/cjs/utils.cjs +13 -8
  19. package/dist/cjs/utils.cjs.map +1 -1
  20. package/dist/cjs/utils.d.cts +0 -12
  21. package/dist/esm/RouterProvider.d.ts +2 -2
  22. package/dist/esm/index.d.ts +2 -2
  23. package/dist/esm/link.d.ts +1 -1
  24. package/dist/esm/link.js.map +1 -1
  25. package/dist/esm/qss.d.ts +9 -0
  26. package/dist/esm/qss.js +2 -4
  27. package/dist/esm/qss.js.map +1 -1
  28. package/dist/esm/redirect.js +7 -0
  29. package/dist/esm/redirect.js.map +1 -1
  30. package/dist/esm/route.d.ts +11 -1
  31. package/dist/esm/route.js.map +1 -1
  32. package/dist/esm/router.d.ts +3 -6
  33. package/dist/esm/router.js +136 -148
  34. package/dist/esm/router.js.map +1 -1
  35. package/dist/esm/scroll-restoration.d.ts +1 -1
  36. package/dist/esm/scroll-restoration.js +1 -1
  37. package/dist/esm/scroll-restoration.js.map +1 -1
  38. package/dist/esm/utils.d.ts +0 -12
  39. package/dist/esm/utils.js +13 -8
  40. package/dist/esm/utils.js.map +1 -1
  41. package/package.json +2 -2
  42. package/src/RouterProvider.ts +2 -6
  43. package/src/index.ts +1 -1
  44. package/src/link.ts +1 -1
  45. package/src/qss.ts +2 -6
  46. package/src/redirect.ts +8 -0
  47. package/src/route.ts +27 -18
  48. package/src/router.ts +206 -193
  49. package/src/scroll-restoration.ts +8 -2
  50. package/src/utils.ts +24 -20
@@ -196,9 +196,8 @@ class RouterCore {
196
196
  },
197
197
  opts
198
198
  );
199
- } else {
200
- return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts);
201
199
  }
200
+ return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts);
202
201
  };
203
202
  this.getMatchedRoutes = (pathname, routePathname) => {
204
203
  return getMatchedRoutes({
@@ -224,173 +223,92 @@ class RouterCore {
224
223
  });
225
224
  };
226
225
  this.buildLocation = (opts) => {
227
- const build = (dest = {}, matchedRoutesResult) => {
228
- var _a, _b, _c, _d, _e, _f, _g;
229
- const fromMatches = dest._fromLocation ? this.matchRoutes(dest._fromLocation, { _buildLocation: true }) : this.state.matches;
230
- const fromMatch = dest.from != null ? fromMatches.find(
231
- (d) => path.matchPathname(this.basepath, path.trimPathRight(d.pathname), {
232
- to: dest.from,
233
- caseSensitive: false,
234
- fuzzy: false
235
- })
236
- ) : void 0;
237
- const fromPath = (fromMatch == null ? void 0 : fromMatch.pathname) || this.latestLocation.pathname;
238
- invariant(
239
- dest.from == null || fromMatch != null,
240
- "Could not find match for from: " + dest.from
241
- );
242
- const fromSearch = ((_a = this.state.pendingMatches) == null ? void 0 : _a.length) ? (_b = utils.last(this.state.pendingMatches)) == null ? void 0 : _b.search : ((_c = utils.last(fromMatches)) == null ? void 0 : _c.search) || this.latestLocation.search;
243
- const stayingMatches = matchedRoutesResult == null ? void 0 : matchedRoutesResult.matchedRoutes.filter(
244
- (d) => fromMatches.find((e) => e.routeId === d.id)
245
- );
246
- let pathname;
247
- if (dest.to) {
248
- const resolvePathTo = (fromMatch == null ? void 0 : fromMatch.fullPath) || ((_d = utils.last(fromMatches)) == null ? void 0 : _d.fullPath) || this.latestLocation.pathname;
249
- pathname = this.resolvePathWithBase(resolvePathTo, `${dest.to}`);
250
- } else {
251
- const fromRouteByFromPathRouteId = this.routesById[(_e = stayingMatches == null ? void 0 : stayingMatches.find((route) => {
252
- const interpolatedPath = path.interpolatePath({
253
- path: route.fullPath,
254
- params: (matchedRoutesResult == null ? void 0 : matchedRoutesResult.routeParams) ?? {},
255
- decodeCharMap: this.pathParamsDecodeCharMap
256
- }).interpolatedPath;
257
- const pathname2 = path.joinPaths([this.basepath, interpolatedPath]);
258
- return pathname2 === fromPath;
259
- })) == null ? void 0 : _e.id];
260
- pathname = this.resolvePathWithBase(
261
- fromPath,
262
- (fromRouteByFromPathRouteId == null ? void 0 : fromRouteByFromPathRouteId.to) ?? fromPath
263
- );
226
+ const build = (dest = {}) => {
227
+ var _a;
228
+ const currentLocation = dest._fromLocation || this.latestLocation;
229
+ const allFromMatches = this.matchRoutes(currentLocation, {
230
+ _buildLocation: true
231
+ });
232
+ const lastMatch = utils.last(allFromMatches);
233
+ let fromPath = lastMatch.fullPath;
234
+ if (dest.unsafeRelative === "path") {
235
+ fromPath = currentLocation.pathname;
236
+ } else if (dest.to && dest.from) {
237
+ fromPath = dest.from;
238
+ const existingFrom = [...allFromMatches].reverse().find((d) => {
239
+ return d.fullPath === fromPath || d.fullPath === path.joinPaths([fromPath, "/"]);
240
+ });
241
+ if (!existingFrom) {
242
+ console.warn(`Could not find match for from: ${dest.from}`);
243
+ }
264
244
  }
265
- const prevParams = { ...(_f = utils.last(fromMatches)) == null ? void 0 : _f.params };
266
- let nextParams = (dest.params ?? true) === true ? prevParams : {
267
- ...prevParams,
268
- ...utils.functionalUpdate(dest.params, prevParams)
245
+ const fromSearch = lastMatch.search;
246
+ const fromParams = { ...lastMatch.params };
247
+ const nextTo = dest.to ? this.resolvePathWithBase(fromPath, `${dest.to}`) : fromPath;
248
+ let nextParams = (dest.params ?? true) === true ? fromParams : {
249
+ ...fromParams,
250
+ ...utils.functionalUpdate(dest.params, fromParams)
269
251
  };
252
+ const destRoutes = this.matchRoutes(
253
+ nextTo,
254
+ {},
255
+ {
256
+ _buildLocation: true
257
+ }
258
+ ).map((d) => this.looseRoutesById[d.routeId]);
270
259
  if (Object.keys(nextParams).length > 0) {
271
- matchedRoutesResult == null ? void 0 : matchedRoutesResult.matchedRoutes.map((route) => {
260
+ destRoutes.map((route) => {
272
261
  var _a2;
273
262
  return ((_a2 = route.options.params) == null ? void 0 : _a2.stringify) ?? route.options.stringifyParams;
274
263
  }).filter(Boolean).forEach((fn) => {
275
264
  nextParams = { ...nextParams, ...fn(nextParams) };
276
265
  });
277
266
  }
278
- pathname = path.interpolatePath({
279
- path: pathname,
267
+ const nextPathname = path.interpolatePath({
268
+ path: nextTo,
280
269
  params: nextParams ?? {},
281
270
  leaveWildcards: false,
282
271
  leaveParams: opts.leaveParams,
283
272
  decodeCharMap: this.pathParamsDecodeCharMap
284
273
  }).interpolatedPath;
285
- let search = fromSearch;
286
- if (opts._includeValidateSearch && ((_g = this.options.search) == null ? void 0 : _g.strict)) {
274
+ let nextSearch = fromSearch;
275
+ if (opts._includeValidateSearch && ((_a = this.options.search) == null ? void 0 : _a.strict)) {
287
276
  let validatedSearch = {};
288
- matchedRoutesResult == null ? void 0 : matchedRoutesResult.matchedRoutes.forEach((route) => {
277
+ destRoutes.forEach((route) => {
289
278
  try {
290
279
  if (route.options.validateSearch) {
291
280
  validatedSearch = {
292
281
  ...validatedSearch,
293
282
  ...validateSearch(route.options.validateSearch, {
294
283
  ...validatedSearch,
295
- ...search
284
+ ...nextSearch
296
285
  }) ?? {}
297
286
  };
298
287
  }
299
288
  } catch {
300
289
  }
301
290
  });
302
- search = validatedSearch;
291
+ nextSearch = validatedSearch;
303
292
  }
304
- const applyMiddlewares = (search2) => {
305
- const allMiddlewares = (matchedRoutesResult == null ? void 0 : matchedRoutesResult.matchedRoutes.reduce(
306
- (acc, route) => {
307
- var _a2;
308
- const middlewares = [];
309
- if ("search" in route.options) {
310
- if ((_a2 = route.options.search) == null ? void 0 : _a2.middlewares) {
311
- middlewares.push(...route.options.search.middlewares);
312
- }
313
- } else if (route.options.preSearchFilters || route.options.postSearchFilters) {
314
- const legacyMiddleware = ({
315
- search: search3,
316
- next
317
- }) => {
318
- let nextSearch = search3;
319
- if ("preSearchFilters" in route.options && route.options.preSearchFilters) {
320
- nextSearch = route.options.preSearchFilters.reduce(
321
- (prev, next2) => next2(prev),
322
- search3
323
- );
324
- }
325
- const result = next(nextSearch);
326
- if ("postSearchFilters" in route.options && route.options.postSearchFilters) {
327
- return route.options.postSearchFilters.reduce(
328
- (prev, next2) => next2(prev),
329
- result
330
- );
331
- }
332
- return result;
333
- };
334
- middlewares.push(legacyMiddleware);
335
- }
336
- if (opts._includeValidateSearch && route.options.validateSearch) {
337
- const validate = ({ search: search3, next }) => {
338
- const result = next(search3);
339
- try {
340
- const validatedSearch = {
341
- ...result,
342
- ...validateSearch(
343
- route.options.validateSearch,
344
- result
345
- ) ?? {}
346
- };
347
- return validatedSearch;
348
- } catch {
349
- return result;
350
- }
351
- };
352
- middlewares.push(validate);
353
- }
354
- return acc.concat(middlewares);
355
- },
356
- []
357
- )) ?? [];
358
- const final = ({ search: search3 }) => {
359
- if (!dest.search) {
360
- return {};
361
- }
362
- if (dest.search === true) {
363
- return search3;
364
- }
365
- return utils.functionalUpdate(dest.search, search3);
366
- };
367
- allMiddlewares.push(final);
368
- const applyNext = (index, currentSearch) => {
369
- if (index >= allMiddlewares.length) {
370
- return currentSearch;
371
- }
372
- const middleware = allMiddlewares[index];
373
- const next = (newSearch) => {
374
- return applyNext(index + 1, newSearch);
375
- };
376
- return middleware({ search: currentSearch, next });
377
- };
378
- return applyNext(0, search2);
379
- };
380
- search = applyMiddlewares(search);
381
- search = utils.replaceEqualDeep(fromSearch, search);
382
- const searchStr = this.options.stringifySearch(search);
383
- const hash = dest.hash === true ? this.latestLocation.hash : dest.hash ? utils.functionalUpdate(dest.hash, this.latestLocation.hash) : void 0;
293
+ nextSearch = applySearchMiddleware({
294
+ search: nextSearch,
295
+ dest,
296
+ destRoutes,
297
+ _includeValidateSearch: opts._includeValidateSearch
298
+ });
299
+ nextSearch = utils.replaceEqualDeep(fromSearch, nextSearch);
300
+ const searchStr = this.options.stringifySearch(nextSearch);
301
+ const hash = dest.hash === true ? currentLocation.hash : dest.hash ? utils.functionalUpdate(dest.hash, currentLocation.hash) : void 0;
384
302
  const hashStr = hash ? `#${hash}` : "";
385
- let nextState = dest.state === true ? this.latestLocation.state : dest.state ? utils.functionalUpdate(dest.state, this.latestLocation.state) : {};
386
- nextState = utils.replaceEqualDeep(this.latestLocation.state, nextState);
303
+ let nextState = dest.state === true ? currentLocation.state : dest.state ? utils.functionalUpdate(dest.state, currentLocation.state) : {};
304
+ nextState = utils.replaceEqualDeep(currentLocation.state, nextState);
387
305
  return {
388
- pathname,
389
- search,
306
+ pathname: nextPathname,
307
+ search: nextSearch,
390
308
  searchStr,
391
309
  state: nextState,
392
310
  hash: hash ?? "",
393
- href: `${pathname}${searchStr}${hashStr}`,
311
+ href: `${nextPathname}${searchStr}${hashStr}`,
394
312
  unmaskOnReload: dest.unmaskOnReload
395
313
  };
396
314
  };
@@ -422,20 +340,11 @@ class RouterCore {
422
340
  maskedNext = build(maskedDest);
423
341
  }
424
342
  }
425
- const nextMatches = this.getMatchedRoutes(
426
- next.pathname,
427
- dest.to
428
- );
429
- const final = build(dest, nextMatches);
430
343
  if (maskedNext) {
431
- const maskedMatches = this.getMatchedRoutes(
432
- maskedNext.pathname,
433
- maskedDest == null ? void 0 : maskedDest.to
434
- );
435
- const maskedFinal = build(maskedDest, maskedMatches);
436
- final.maskedLocation = maskedFinal;
344
+ const maskedFinal = build(maskedDest);
345
+ next.maskedLocation = maskedFinal;
437
346
  }
438
- return final;
347
+ return next;
439
348
  };
440
349
  if (opts.mask) {
441
350
  return buildWithMatches(opts, {
@@ -1184,6 +1093,7 @@ class RouterCore {
1184
1093
  pendingMatches: (_a = s.pendingMatches) == null ? void 0 : _a.map(invalidate)
1185
1094
  };
1186
1095
  });
1096
+ this.shouldViewTransition = false;
1187
1097
  return this.load({ sync: opts == null ? void 0 : opts.sync });
1188
1098
  };
1189
1099
  this.resolveRedirect = (redirect2) => {
@@ -1791,6 +1701,84 @@ function getMatchedRoutes({
1791
1701
  }
1792
1702
  return { matchedRoutes, routeParams, foundRoute };
1793
1703
  }
1704
+ function applySearchMiddleware({
1705
+ search,
1706
+ dest,
1707
+ destRoutes,
1708
+ _includeValidateSearch
1709
+ }) {
1710
+ const allMiddlewares = destRoutes.reduce(
1711
+ (acc, route) => {
1712
+ var _a;
1713
+ const middlewares = [];
1714
+ if ("search" in route.options) {
1715
+ if ((_a = route.options.search) == null ? void 0 : _a.middlewares) {
1716
+ middlewares.push(...route.options.search.middlewares);
1717
+ }
1718
+ } else if (route.options.preSearchFilters || route.options.postSearchFilters) {
1719
+ const legacyMiddleware = ({
1720
+ search: search2,
1721
+ next
1722
+ }) => {
1723
+ let nextSearch = search2;
1724
+ if ("preSearchFilters" in route.options && route.options.preSearchFilters) {
1725
+ nextSearch = route.options.preSearchFilters.reduce(
1726
+ (prev, next2) => next2(prev),
1727
+ search2
1728
+ );
1729
+ }
1730
+ const result = next(nextSearch);
1731
+ if ("postSearchFilters" in route.options && route.options.postSearchFilters) {
1732
+ return route.options.postSearchFilters.reduce(
1733
+ (prev, next2) => next2(prev),
1734
+ result
1735
+ );
1736
+ }
1737
+ return result;
1738
+ };
1739
+ middlewares.push(legacyMiddleware);
1740
+ }
1741
+ if (_includeValidateSearch && route.options.validateSearch) {
1742
+ const validate = ({ search: search2, next }) => {
1743
+ const result = next(search2);
1744
+ try {
1745
+ const validatedSearch = {
1746
+ ...result,
1747
+ ...validateSearch(route.options.validateSearch, result) ?? {}
1748
+ };
1749
+ return validatedSearch;
1750
+ } catch {
1751
+ return result;
1752
+ }
1753
+ };
1754
+ middlewares.push(validate);
1755
+ }
1756
+ return acc.concat(middlewares);
1757
+ },
1758
+ []
1759
+ ) ?? [];
1760
+ const final = ({ search: search2 }) => {
1761
+ if (!dest.search) {
1762
+ return {};
1763
+ }
1764
+ if (dest.search === true) {
1765
+ return search2;
1766
+ }
1767
+ return utils.functionalUpdate(dest.search, search2);
1768
+ };
1769
+ allMiddlewares.push(final);
1770
+ const applyNext = (index, currentSearch) => {
1771
+ if (index >= allMiddlewares.length) {
1772
+ return currentSearch;
1773
+ }
1774
+ const middleware = allMiddlewares[index];
1775
+ const next = (newSearch) => {
1776
+ return applyNext(index + 1, newSearch);
1777
+ };
1778
+ return middleware({ search: currentSearch, next });
1779
+ };
1780
+ return applyNext(0, search);
1781
+ }
1794
1782
  exports.PathParamError = PathParamError;
1795
1783
  exports.RouterCore = RouterCore;
1796
1784
  exports.SearchParamError = SearchParamError;