@tanstack/react-router 1.15.14 → 1.15.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 (45) hide show
  1. package/dist/cjs/Matches.cjs.map +1 -1
  2. package/dist/cjs/Matches.d.cts +1 -0
  3. package/dist/cjs/awaited.cjs +41 -17
  4. package/dist/cjs/awaited.cjs.map +1 -1
  5. package/dist/cjs/createServerFn.cjs +16 -2
  6. package/dist/cjs/createServerFn.cjs.map +1 -1
  7. package/dist/cjs/createServerFn.d.cts +10 -3
  8. package/dist/cjs/defer.cjs.map +1 -1
  9. package/dist/cjs/defer.d.cts +3 -0
  10. package/dist/cjs/fileRoute.d.cts +6 -0
  11. package/dist/cjs/index.cjs +3 -1
  12. package/dist/cjs/index.cjs.map +1 -1
  13. package/dist/cjs/link.cjs +7 -12
  14. package/dist/cjs/link.cjs.map +1 -1
  15. package/dist/cjs/route.cjs.map +1 -1
  16. package/dist/cjs/route.d.cts +3 -0
  17. package/dist/cjs/router.cjs +34 -7
  18. package/dist/cjs/router.cjs.map +1 -1
  19. package/dist/cjs/router.d.cts +10 -0
  20. package/dist/esm/Matches.d.ts +1 -0
  21. package/dist/esm/Matches.js.map +1 -1
  22. package/dist/esm/awaited.js +41 -17
  23. package/dist/esm/awaited.js.map +1 -1
  24. package/dist/esm/createServerFn.d.ts +10 -3
  25. package/dist/esm/createServerFn.js +17 -3
  26. package/dist/esm/createServerFn.js.map +1 -1
  27. package/dist/esm/defer.d.ts +3 -0
  28. package/dist/esm/defer.js.map +1 -1
  29. package/dist/esm/fileRoute.d.ts +6 -0
  30. package/dist/esm/index.js +4 -2
  31. package/dist/esm/link.js +7 -12
  32. package/dist/esm/link.js.map +1 -1
  33. package/dist/esm/route.d.ts +3 -0
  34. package/dist/esm/route.js.map +1 -1
  35. package/dist/esm/router.d.ts +10 -0
  36. package/dist/esm/router.js +34 -7
  37. package/dist/esm/router.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/Matches.tsx +1 -0
  40. package/src/awaited.tsx +58 -25
  41. package/src/createServerFn.ts +32 -3
  42. package/src/defer.ts +6 -1
  43. package/src/link.tsx +9 -13
  44. package/src/route.ts +3 -0
  45. package/src/router.ts +54 -4
package/src/link.tsx CHANGED
@@ -448,25 +448,24 @@ export function useLinkProps<
448
448
  }
449
449
  }
450
450
 
451
- // The click handler
452
- const handleFocus = (e: MouseEvent) => {
453
- if (preload) {
451
+ const doPreload = () => {
452
+ React.startTransition(() => {
454
453
  router.preloadRoute(dest as any).catch((err) => {
455
454
  console.warn(err)
456
455
  console.warn(preloadWarning)
457
456
  })
458
- }
457
+ })
459
458
  }
460
459
 
461
- const handleTouchStart = (e: TouchEvent) => {
460
+ // The click handler
461
+ const handleFocus = (e: MouseEvent) => {
462
462
  if (preload) {
463
- router.preloadRoute(dest as any).catch((err) => {
464
- console.warn(err)
465
- console.warn(preloadWarning)
466
- })
463
+ doPreload()
467
464
  }
468
465
  }
469
466
 
467
+ const handleTouchStart = handleFocus
468
+
470
469
  const handleEnter = (e: MouseEvent) => {
471
470
  const target = (e.target || {}) as LinkCurrentTargetElement
472
471
 
@@ -477,10 +476,7 @@ export function useLinkProps<
477
476
 
478
477
  target.preloadTimeout = setTimeout(() => {
479
478
  target.preloadTimeout = null
480
- router.preloadRoute(dest as any).catch((err) => {
481
- console.warn(err)
482
- console.warn(preloadWarning)
483
- })
479
+ doPreload()
484
480
  }, preloadDelay)
485
481
  }
486
482
  }
package/src/route.ts CHANGED
@@ -220,6 +220,9 @@ export type UpdatableRouteOptions<
220
220
  | Promise<JSX.IntrinsicElements['meta'][]>
221
221
  links?: () => JSX.IntrinsicElements['link'][]
222
222
  scripts?: () => JSX.IntrinsicElements['script'][]
223
+ headers?: (ctx: {
224
+ loaderData: TLoaderData
225
+ }) => Promise<Record<string, string>> | Record<string, string>
223
226
  } & UpdatableStaticRouteOption
224
227
 
225
228
  export type UpdatableStaticRouteOption =
package/src/router.ts CHANGED
@@ -67,6 +67,14 @@ import { isRedirect } from './redirects'
67
67
  import { NotFoundError, isNotFound } from './not-found'
68
68
  import { ResolveRelativePath, ToOptions } from './link'
69
69
  import { NoInfer } from '@tanstack/react-store'
70
+ import warning from 'tiny-warning'
71
+ import {
72
+ DeferredPromise,
73
+ DeferredPromiseState,
74
+ defaultDeserializeError,
75
+ isDehydratedDeferred,
76
+ isServerSideError,
77
+ } from '.'
70
78
  // import warning from 'tiny-warning'
71
79
 
72
80
  //
@@ -304,6 +312,10 @@ export class Router<
304
312
  parseSearch: options?.parseSearch ?? defaultParseSearch,
305
313
  transformer: options?.transformer ?? JSON,
306
314
  })
315
+
316
+ if (typeof document !== 'undefined') {
317
+ ;(window as any).__TSR__ROUTER__ = this
318
+ }
307
319
  }
308
320
 
309
321
  // These are default implementations that can optionally be overridden
@@ -719,6 +731,7 @@ export class Router<
719
731
  path: route.fullPath,
720
732
  params: routeParams,
721
733
  })
734
+
722
735
  const matchId =
723
736
  interpolatePath({
724
737
  path: route.id,
@@ -743,7 +756,7 @@ export class Router<
743
756
  isGlobalNotFound && route.id === rootRouteId
744
757
  ? { global: true }
745
758
  : undefined,
746
- params: replaceEqualDeep(existingMatch.params, routeParams),
759
+ params: routeParams,
747
760
  }
748
761
  : {
749
762
  id: matchId,
@@ -1357,9 +1370,14 @@ export class Router<
1357
1370
 
1358
1371
  if ((latestPromise = checkLatest())) return await latestPromise
1359
1372
 
1360
- const meta = await route.options.meta?.({
1361
- loaderData,
1362
- })
1373
+ const [meta, headers] = await Promise.all([
1374
+ route.options.meta?.({
1375
+ loaderData,
1376
+ }),
1377
+ route.options.headers?.({
1378
+ loaderData,
1379
+ }),
1380
+ ])
1363
1381
 
1364
1382
  matches[index] = match = {
1365
1383
  ...match,
@@ -1370,6 +1388,7 @@ export class Router<
1370
1388
  loaderData,
1371
1389
  loadPromise: undefined,
1372
1390
  meta,
1391
+ headers,
1373
1392
  }
1374
1393
  } catch (error) {
1375
1394
  if ((latestPromise = checkLatest())) return await latestPromise
@@ -1707,7 +1726,30 @@ export class Router<
1707
1726
  this.injectedHtml.push(html)
1708
1727
  }
1709
1728
 
1729
+ // We use a token -> weak map to keep track of deferred promises
1730
+ // that are registered on the server and need to be resolved
1731
+ registeredDeferredsIds = new Map<string, {}>()
1732
+ registeredDeferreds = new WeakMap<{}, DeferredPromiseState<any>>()
1733
+
1734
+ getDeferred = (uid: string) => {
1735
+ const token = this.registeredDeferredsIds.get(uid)
1736
+
1737
+ if (!token) {
1738
+ return undefined
1739
+ }
1740
+
1741
+ return this.registeredDeferreds.get(token)
1742
+ }
1743
+
1744
+ /**
1745
+ * @deprecated Please inject your own html using the `injectHtml` method
1746
+ */
1710
1747
  dehydrateData = <T>(key: any, getData: T | (() => Promise<T> | T)) => {
1748
+ warning(
1749
+ false,
1750
+ `The dehydrateData method is deprecated. Please use the injectHtml method to inject your own data.`,
1751
+ )
1752
+
1711
1753
  if (typeof document === 'undefined') {
1712
1754
  const strKey = typeof key === 'string' ? key : JSON.stringify(key)
1713
1755
 
@@ -1728,7 +1770,15 @@ export class Router<
1728
1770
  return () => undefined
1729
1771
  }
1730
1772
 
1773
+ /**
1774
+ * @deprecated Please extract your own data from scripts injected using the `injectHtml` method
1775
+ */
1731
1776
  hydrateData = <T extends any = unknown>(key: any) => {
1777
+ warning(
1778
+ false,
1779
+ `The hydrateData method is deprecated. Please use the extractHtml method to extract your own data.`,
1780
+ )
1781
+
1732
1782
  if (typeof document !== 'undefined') {
1733
1783
  const strKey = typeof key === 'string' ? key : JSON.stringify(key)
1734
1784