@tanstack/router-core 1.134.18 → 1.134.20

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.
package/src/Matches.ts CHANGED
@@ -148,6 +148,8 @@ export interface RouteMatch<
148
148
  displayPendingPromise?: Promise<void>
149
149
  minPendingPromise?: ControlledPromise<void>
150
150
  dehydrated?: boolean
151
+ /** @internal */
152
+ error?: unknown
151
153
  }
152
154
  loaderData?: TLoaderData
153
155
  /** @internal */
@@ -111,6 +111,8 @@ const handleRedirectAndNotFound = (
111
111
 
112
112
  const status = isRedirect(err) ? 'redirected' : 'notFound'
113
113
 
114
+ match._nonReactive.error = err
115
+
114
116
  inner.updateMatch(match.id, (prev) => ({
115
117
  ...prev,
116
118
  status,
@@ -560,9 +562,23 @@ const getLoaderContext = (
560
562
  route: AnyRoute,
561
563
  ): LoaderFnContext => {
562
564
  const parentMatchPromise = inner.matchPromises[index - 1] as any
563
- const { params, loaderDeps, abortController, context, cause } =
565
+ const { params, loaderDeps, abortController, cause } =
564
566
  inner.router.getMatch(matchId)!
565
567
 
568
+ let context = inner.router.options.context ?? {}
569
+
570
+ for (let i = 0; i <= index; i++) {
571
+ const innerMatch = inner.matches[i]
572
+ if (!innerMatch) continue
573
+ const m = inner.router.getMatch(innerMatch.id)
574
+ if (!m) continue
575
+ context = {
576
+ ...context,
577
+ ...(m.__routeContext ?? {}),
578
+ ...(m.__beforeLoadContext ?? {}),
579
+ }
580
+ }
581
+
566
582
  const preload = resolvePreload(inner, matchId)
567
583
 
568
584
  return {
@@ -750,8 +766,9 @@ const loadRouteMatch = async (
750
766
  }
751
767
  await prevMatch._nonReactive.loaderPromise
752
768
  const match = inner.router.getMatch(matchId)!
753
- if (match.error) {
754
- handleRedirectAndNotFound(inner, match, match.error)
769
+ const error = match._nonReactive.error || match.error
770
+ if (error) {
771
+ handleRedirectAndNotFound(inner, match, error)
755
772
  }
756
773
  } else {
757
774
  // This is where all of the stale-while-revalidate magic happens
package/src/router.ts CHANGED
@@ -2295,23 +2295,27 @@ export class RouterCore<
2295
2295
  }
2296
2296
 
2297
2297
  updateMatch: UpdateMatchFn = (id, updater) => {
2298
- const matchesKey = this.state.pendingMatches?.some((d) => d.id === id)
2299
- ? 'pendingMatches'
2300
- : this.state.matches.some((d) => d.id === id)
2301
- ? 'matches'
2302
- : this.state.cachedMatches.some((d) => d.id === id)
2303
- ? 'cachedMatches'
2304
- : ''
2305
-
2306
- if (matchesKey) {
2307
- this.__store.setState((s) => ({
2308
- ...s,
2309
- [matchesKey]: s[matchesKey]?.map((d) => (d.id === id ? updater(d) : d)),
2310
- }))
2311
- }
2298
+ this.startTransition(() => {
2299
+ const matchesKey = this.state.pendingMatches?.some((d) => d.id === id)
2300
+ ? 'pendingMatches'
2301
+ : this.state.matches.some((d) => d.id === id)
2302
+ ? 'matches'
2303
+ : this.state.cachedMatches.some((d) => d.id === id)
2304
+ ? 'cachedMatches'
2305
+ : ''
2306
+
2307
+ if (matchesKey) {
2308
+ this.__store.setState((s) => ({
2309
+ ...s,
2310
+ [matchesKey]: s[matchesKey]?.map((d) =>
2311
+ d.id === id ? updater(d) : d,
2312
+ ),
2313
+ }))
2314
+ }
2315
+ })
2312
2316
  }
2313
2317
 
2314
- getMatch: GetMatchFn = (matchId: string) => {
2318
+ getMatch: GetMatchFn = (matchId: string): AnyRouteMatch | undefined => {
2315
2319
  const findFn = (d: { id: string }) => d.id === matchId
2316
2320
  return (
2317
2321
  this.state.cachedMatches.find(findFn) ??