@tanstack/react-router 1.45.0 → 1.45.3

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 (58) hide show
  1. package/dist/cjs/CatchBoundary.cjs +1 -1
  2. package/dist/cjs/CatchBoundary.cjs.map +1 -1
  3. package/dist/cjs/CatchBoundary.d.cts +1 -1
  4. package/dist/cjs/Match.cjs +24 -34
  5. package/dist/cjs/Match.cjs.map +1 -1
  6. package/dist/cjs/Matches.cjs +1 -1
  7. package/dist/cjs/Matches.cjs.map +1 -1
  8. package/dist/cjs/Matches.d.cts +4 -2
  9. package/dist/cjs/RouterProvider.cjs +0 -8
  10. package/dist/cjs/RouterProvider.cjs.map +1 -1
  11. package/dist/cjs/RouterProvider.d.cts +1 -4
  12. package/dist/cjs/Transitioner.cjs +5 -1
  13. package/dist/cjs/Transitioner.cjs.map +1 -1
  14. package/dist/cjs/index.cjs +0 -1
  15. package/dist/cjs/index.cjs.map +1 -1
  16. package/dist/cjs/index.d.cts +1 -1
  17. package/dist/cjs/link.cjs.map +1 -1
  18. package/dist/cjs/path.cjs +1 -1
  19. package/dist/cjs/path.cjs.map +1 -1
  20. package/dist/cjs/route.cjs.map +1 -1
  21. package/dist/cjs/route.d.cts +1 -0
  22. package/dist/cjs/router.cjs +459 -406
  23. package/dist/cjs/router.cjs.map +1 -1
  24. package/dist/cjs/router.d.cts +22 -10
  25. package/dist/esm/CatchBoundary.d.ts +1 -1
  26. package/dist/esm/CatchBoundary.js +1 -1
  27. package/dist/esm/CatchBoundary.js.map +1 -1
  28. package/dist/esm/Match.js +24 -34
  29. package/dist/esm/Match.js.map +1 -1
  30. package/dist/esm/Matches.d.ts +4 -2
  31. package/dist/esm/Matches.js +1 -1
  32. package/dist/esm/Matches.js.map +1 -1
  33. package/dist/esm/RouterProvider.d.ts +1 -4
  34. package/dist/esm/RouterProvider.js +1 -9
  35. package/dist/esm/RouterProvider.js.map +1 -1
  36. package/dist/esm/Transitioner.js +5 -1
  37. package/dist/esm/Transitioner.js.map +1 -1
  38. package/dist/esm/index.d.ts +1 -1
  39. package/dist/esm/index.js +1 -2
  40. package/dist/esm/link.js.map +1 -1
  41. package/dist/esm/path.js +1 -1
  42. package/dist/esm/path.js.map +1 -1
  43. package/dist/esm/route.d.ts +1 -0
  44. package/dist/esm/route.js.map +1 -1
  45. package/dist/esm/router.d.ts +22 -10
  46. package/dist/esm/router.js +461 -408
  47. package/dist/esm/router.js.map +1 -1
  48. package/package.json +2 -2
  49. package/src/CatchBoundary.tsx +7 -3
  50. package/src/Match.tsx +47 -38
  51. package/src/Matches.tsx +5 -3
  52. package/src/RouterProvider.tsx +0 -11
  53. package/src/Transitioner.tsx +5 -1
  54. package/src/index.tsx +0 -1
  55. package/src/link.tsx +2 -2
  56. package/src/path.ts +1 -1
  57. package/src/route.ts +1 -0
  58. package/src/router.ts +642 -566
@@ -3,7 +3,7 @@ import type { ErrorRouteComponent } from './route'
3
3
  import type { ErrorInfo } from 'react'
4
4
 
5
5
  export function CatchBoundary(props: {
6
- getResetKey: () => string
6
+ getResetKey: () => number | string
7
7
  children: React.ReactNode
8
8
  errorComponent?: ErrorRouteComponent
9
9
  onCatch?: (error: Error, errorInfo: ErrorInfo) => void
@@ -29,7 +29,7 @@ export function CatchBoundary(props: {
29
29
  }
30
30
 
31
31
  class CatchBoundaryImpl extends React.Component<{
32
- getResetKey: () => string
32
+ getResetKey: () => number | string
33
33
  children: (props: {
34
34
  error: Error | null
35
35
  reset: () => void
@@ -64,8 +64,12 @@ class CatchBoundaryImpl extends React.Component<{
64
64
  }
65
65
  }
66
66
  render() {
67
+ // If the resetKey has changed, don't render the error
67
68
  return this.props.children({
68
- error: this.state.error,
69
+ error:
70
+ this.state.resetKey !== this.props.getResetKey()
71
+ ? null
72
+ : this.state.error,
69
73
  reset: () => {
70
74
  this.reset()
71
75
  },
package/src/Match.tsx CHANGED
@@ -41,8 +41,8 @@ export function Match({ matchId }: { matchId: string }) {
41
41
 
42
42
  const routeNotFoundComponent = route.isRoot
43
43
  ? // If it's the root route, use the globalNotFound option, with fallback to the notFoundRoute's component
44
- route.options.notFoundComponent ??
45
- router.options.notFoundRoute?.options.component
44
+ (route.options.notFoundComponent ??
45
+ router.options.notFoundRoute?.options.component)
46
46
  : route.options.notFoundComponent
47
47
 
48
48
  const ResolvedSuspenseBoundary =
@@ -63,7 +63,7 @@ export function Match({ matchId }: { matchId: string }) {
63
63
  : SafeFragment
64
64
 
65
65
  const resetKey = useRouterState({
66
- select: (s) => s.resolvedLocation.state.key!,
66
+ select: (s) => s.loadedAt,
67
67
  })
68
68
 
69
69
  return (
@@ -108,23 +108,44 @@ function MatchInner({ matchId }: { matchId: string }): any {
108
108
 
109
109
  const route = router.routesById[routeId]!
110
110
 
111
- const [match, matchIndex] = useRouterState({
111
+ const matchIndex = useRouterState({
112
+ select: (s) => {
113
+ return s.matches.findIndex((d) => d.id === matchId)
114
+ },
115
+ })
116
+
117
+ const match = useRouterState({
112
118
  select: (s) => {
113
- const matchIndex = s.matches.findIndex((d) => d.id === matchId)
114
119
  const match = s.matches[matchIndex]!
115
- return [
116
- pick(match, [
117
- 'id',
118
- 'status',
119
- 'error',
120
- 'loadPromise',
121
- 'minPendingPromise',
122
- ]),
123
- matchIndex,
124
- ] as const
120
+ return pick(match, [
121
+ 'id',
122
+ 'status',
123
+ 'error',
124
+ 'loadPromise',
125
+ 'minPendingPromise',
126
+ ])
125
127
  },
126
128
  })
127
129
 
130
+ // function useChangedDiff(value: any) {
131
+ // const ref = React.useRef(value)
132
+ // const changed = ref.current !== value
133
+ // if (changed) {
134
+ // console.log(
135
+ // 'Changed:',
136
+ // value,
137
+ // Object.fromEntries(
138
+ // Object.entries(value).filter(
139
+ // ([key, val]) => val !== ref.current[key],
140
+ // ),
141
+ // ),
142
+ // )
143
+ // }
144
+ // ref.current = value
145
+ // }
146
+
147
+ // useChangedDiff(match)
148
+
128
149
  const RouteErrorComponent =
129
150
  (route.options.errorComponent ?? router.options.defaultErrorComponent) ||
130
151
  ErrorComponent
@@ -190,36 +211,24 @@ function MatchInner({ matchId }: { matchId: string }): any {
190
211
 
191
212
  if (pendingMinMs && !match.minPendingPromise) {
192
213
  // Create a promise that will resolve after the minPendingMs
193
- match.minPendingPromise = createControlledPromise()
194
-
195
214
  if (!router.isServer) {
215
+ const minPendingPromise = createControlledPromise<void>()
216
+
196
217
  Promise.resolve().then(() => {
197
- router.__store.setState((s) => ({
198
- ...s,
199
- matches: s.matches.map((d) =>
200
- d.id === match.id
201
- ? { ...d, minPendingPromise: createControlledPromise() }
202
- : d,
203
- ),
218
+ router.updateMatch(match.id, (prev) => ({
219
+ ...prev,
220
+ minPendingPromise,
204
221
  }))
205
222
  })
206
223
 
207
224
  setTimeout(() => {
225
+ minPendingPromise.resolve()
226
+
208
227
  // We've handled the minPendingPromise, so we can delete it
209
- router.__store.setState((s) => {
210
- return {
211
- ...s,
212
- matches: s.matches.map((d) =>
213
- d.id === match.id
214
- ? {
215
- ...d,
216
- minPendingPromise:
217
- (d.minPendingPromise?.resolve(), undefined),
218
- }
219
- : d,
220
- ),
221
- }
222
- })
228
+ router.updateMatch(match.id, (prev) => ({
229
+ ...prev,
230
+ minPendingPromise: undefined,
231
+ }))
223
232
  }, pendingMinMs)
224
233
  }
225
234
  }
package/src/Matches.tsx CHANGED
@@ -47,8 +47,10 @@ export interface RouteMatch<
47
47
  paramsError: unknown
48
48
  searchError: unknown
49
49
  updatedAt: number
50
- loadPromise: ControlledPromise<void>
51
- loaderPromise: Promise<TLoaderData>
50
+ componentsPromise?: Promise<Array<void>>
51
+ loadPromise?: ControlledPromise<void>
52
+ beforeLoadPromise?: ControlledPromise<void>
53
+ loaderPromise?: ControlledPromise<void>
52
54
  loaderData?: TLoaderData
53
55
  routeContext: TRouteContext
54
56
  context: TAllContext
@@ -132,7 +134,7 @@ function MatchesInner() {
132
134
  })
133
135
 
134
136
  const resetKey = useRouterState({
135
- select: (s) => s.resolvedLocation.state.key!,
137
+ select: (s) => s.loadedAt,
136
138
  })
137
139
 
138
140
  return (
@@ -104,17 +104,6 @@ export function RouterProvider<
104
104
  )
105
105
  }
106
106
 
107
- export function getRouteMatch<TRouteTree extends AnyRoute>(
108
- state: RouterState<TRouteTree>,
109
- id: string,
110
- ): undefined | MakeRouteMatch<TRouteTree> {
111
- return [
112
- ...state.cachedMatches,
113
- ...(state.pendingMatches ?? []),
114
- ...state.matches,
115
- ].find((d) => d.id === id)
116
- }
117
-
118
107
  export type RouterProps<
119
108
  TRouter extends AnyRouter = RegisteredRouter,
120
109
  TDehydrated extends Record<string, any> = Record<string, any>,
@@ -2,6 +2,7 @@ import * as React from 'react'
2
2
  import { pick, useLayoutEffect, usePrevious } from './utils'
3
3
  import { useRouter } from './useRouter'
4
4
  import { useRouterState } from './useRouterState'
5
+ import { trimPathRight } from '.'
5
6
 
6
7
  export function Transitioner() {
7
8
  const router = useRouter()
@@ -40,7 +41,10 @@ export function Transitioner() {
40
41
  state: true,
41
42
  })
42
43
 
43
- if (router.state.location.href !== nextLocation.href) {
44
+ if (
45
+ trimPathRight(router.latestLocation.href) !==
46
+ trimPathRight(nextLocation.href)
47
+ ) {
44
48
  router.commitLocation({ ...nextLocation, replace: true })
45
49
  }
46
50
 
package/src/index.tsx CHANGED
@@ -207,7 +207,6 @@ export {
207
207
  export {
208
208
  RouterProvider,
209
209
  RouterContextProvider,
210
- getRouteMatch,
211
210
  type RouterProps,
212
211
  type CommitLocationOptions,
213
212
  type MatchLocation,
package/src/link.tsx CHANGED
@@ -619,7 +619,7 @@ export function useLinkProps<
619
619
  ? s.location.hash === next.hash
620
620
  : true
621
621
  const searchTest =
622
- activeOptions?.includeSearch ?? true
622
+ (activeOptions?.includeSearch ?? true)
623
623
  ? deepEqual(s.location.search, next.search, !activeOptions?.exact)
624
624
  : true
625
625
 
@@ -733,7 +733,7 @@ export function useLinkProps<
733
733
 
734
734
  // Get the active props
735
735
  const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive
736
- ? functionalUpdate(activeProps as any, {}) ?? {}
736
+ ? (functionalUpdate(activeProps as any, {}) ?? {})
737
737
  : {}
738
738
 
739
739
  // Get the inactive props
package/src/path.ts CHANGED
@@ -175,7 +175,7 @@ export function parsePathname(pathname?: string): Array<Segment> {
175
175
 
176
176
  return {
177
177
  type: 'pathname',
178
- value: part,
178
+ value: decodeURIComponent(part),
179
179
  }
180
180
  }),
181
181
  )
package/src/route.ts CHANGED
@@ -638,6 +638,7 @@ export class Route<
638
638
  router?: AnyRouter
639
639
  rank!: number
640
640
  lazyFn?: () => Promise<LazyRoute<any>>
641
+ _lazyPromise?: Promise<void>
641
642
 
642
643
  /**
643
644
  * @deprecated Use the `createRoute` function instead.