@tanstack/router-core 1.132.0-alpha.0 → 1.132.0-alpha.2

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.
@@ -20,17 +20,16 @@ export interface TsrSsrGlobal {
20
20
  }
21
21
 
22
22
  function hydrateMatch(
23
+ match: AnyRouteMatch,
23
24
  deyhydratedMatch: DehydratedMatch,
24
- ): Partial<MakeRouteMatch> {
25
- return {
26
- id: deyhydratedMatch.i,
27
- __beforeLoadContext: deyhydratedMatch.b,
28
- loaderData: deyhydratedMatch.l,
29
- status: deyhydratedMatch.s,
30
- ssr: deyhydratedMatch.ssr,
31
- updatedAt: deyhydratedMatch.u,
32
- error: deyhydratedMatch.e,
33
- }
25
+ ): void {
26
+ match.id = deyhydratedMatch.i
27
+ match.__beforeLoadContext = deyhydratedMatch.b
28
+ match.loaderData = deyhydratedMatch.l
29
+ match.status = deyhydratedMatch.s
30
+ match.ssr = deyhydratedMatch.ssr
31
+ match.updatedAt = deyhydratedMatch.u
32
+ match.error = deyhydratedMatch.e
34
33
  }
35
34
  export interface DehydratedMatch {
36
35
  i: MakeRouteMatch['id']
@@ -80,17 +79,19 @@ export async function hydrate(router: AnyRouter): Promise<any> {
80
79
  route.options.pendingMinMs ?? router.options.defaultPendingMinMs
81
80
  if (pendingMinMs) {
82
81
  const minPendingPromise = createControlledPromise<void>()
83
- match.minPendingPromise = minPendingPromise
82
+ match._nonReactive.minPendingPromise = minPendingPromise
84
83
  match._forcePending = true
85
84
 
86
85
  setTimeout(() => {
87
86
  minPendingPromise.resolve()
88
87
  // We've handled the minPendingPromise, so we can delete it
89
- router.updateMatch(match.id, (prev) => ({
90
- ...prev,
91
- minPendingPromise: undefined,
92
- _forcePending: undefined,
93
- }))
88
+ router.updateMatch(match.id, (prev) => {
89
+ prev._nonReactive.minPendingPromise = undefined
90
+ return {
91
+ ...prev,
92
+ _forcePending: undefined,
93
+ }
94
+ })
94
95
  }, pendingMinMs)
95
96
  }
96
97
  }
@@ -103,17 +104,14 @@ export async function hydrate(router: AnyRouter): Promise<any> {
103
104
  (d) => d.i === match.id,
104
105
  )
105
106
  if (!dehydratedMatch) {
106
- Object.assign(match, { dehydrated: false, ssr: false })
107
+ match._nonReactive.dehydrated = false
108
+ match.ssr = false
107
109
  return
108
110
  }
109
111
 
110
- Object.assign(match, hydrateMatch(dehydratedMatch))
112
+ hydrateMatch(match, dehydratedMatch)
111
113
 
112
- if (match.ssr === false) {
113
- match._dehydrated = false
114
- } else {
115
- match._dehydrated = true
116
- }
114
+ match._nonReactive.dehydrated = match.ssr !== false
117
115
 
118
116
  if (match.ssr === 'data-only' || match.ssr === false) {
119
117
  if (firstNonSsrMatchIndex === undefined) {
@@ -141,24 +139,27 @@ export async function hydrate(router: AnyRouter): Promise<any> {
141
139
  const route = router.looseRoutesById[match.routeId]!
142
140
 
143
141
  const parentMatch = router.state.matches[match.index - 1]
144
- const parentContext = parentMatch?.context ?? router.options.context ?? {}
142
+ const parentContext = parentMatch?.context ?? router.options.context
145
143
 
146
144
  // `context()` was already executed by `matchRoutes`, however route context was not yet fully reconstructed
147
145
  // so run it again and merge route context
148
- const contextFnContext: RouteContextOptions<any, any, any, any> = {
149
- deps: match.loaderDeps,
150
- params: match.params,
151
- context: parentContext,
152
- location: router.state.location,
153
- navigate: (opts: any) =>
154
- router.navigate({ ...opts, _fromLocation: router.state.location }),
155
- buildLocation: router.buildLocation,
156
- cause: match.cause,
157
- abortController: match.abortController,
158
- preload: false,
159
- matches,
146
+ if (route.options.context) {
147
+ const contextFnContext: RouteContextOptions<any, any, any, any> = {
148
+ deps: match.loaderDeps,
149
+ params: match.params,
150
+ context: parentContext ?? {},
151
+ location: router.state.location,
152
+ navigate: (opts: any) =>
153
+ router.navigate({ ...opts, _fromLocation: router.state.location }),
154
+ buildLocation: router.buildLocation,
155
+ cause: match.cause,
156
+ abortController: match.abortController,
157
+ preload: false,
158
+ matches,
159
+ }
160
+ match.__routeContext =
161
+ route.options.context(contextFnContext) ?? undefined
160
162
  }
161
- match.__routeContext = route.options.context?.(contextFnContext) ?? {}
162
163
 
163
164
  match.context = {
164
165
  ...parentContext,
@@ -186,11 +187,11 @@ export async function hydrate(router: AnyRouter): Promise<any> {
186
187
 
187
188
  const isSpaMode = matches[matches.length - 1]!.id !== lastMatchId
188
189
  const hasSsrFalseMatches = matches.some((m) => m.ssr === false)
189
- // all matches have data from the server and we are not in SPA mode so we don't need to kick of router.load()
190
+ // all matches have data from the server and we are not in SPA mode so we don't need to kick of router.load()
190
191
  if (!hasSsrFalseMatches && !isSpaMode) {
191
192
  matches.forEach((match) => {
192
- // remove the _dehydrate flag since we won't run router.load() which would remove it
193
- match._dehydrated = undefined
193
+ // remove the dehydrated flag since we won't run router.load() which would remove it
194
+ match._nonReactive.dehydrated = undefined
194
195
  })
195
196
  return routeChunkPromise
196
197
  }
@@ -213,7 +214,7 @@ export async function hydrate(router: AnyRouter): Promise<any> {
213
214
  setMatchForcePending(match)
214
215
 
215
216
  match._displayPending = true
216
- match.displayPendingPromise = loadPromise
217
+ match._nonReactive.displayPendingPromise = loadPromise
217
218
 
218
219
  loadPromise.then(() => {
219
220
  batch(() => {
@@ -36,7 +36,7 @@ export type ValidateParams<
36
36
  > = PathParamOptions<TRouter, TFrom, TTo>
37
37
 
38
38
  /**
39
- * @internal
39
+ * @private
40
40
  */
41
41
  export type InferFrom<
42
42
  TOptions,
@@ -48,7 +48,7 @@ export type InferFrom<
48
48
  : TDefaultFrom
49
49
 
50
50
  /**
51
- * @internal
51
+ * @private
52
52
  */
53
53
  export type InferTo<TOptions> = TOptions extends {
54
54
  to: infer TTo extends string
@@ -57,7 +57,7 @@ export type InferTo<TOptions> = TOptions extends {
57
57
  : undefined
58
58
 
59
59
  /**
60
- * @internal
60
+ * @private
61
61
  */
62
62
  export type InferMaskTo<TOptions> = TOptions extends {
63
63
  mask: { to: infer TTo extends string }
@@ -131,7 +131,7 @@ export type ValidateId<
131
131
  > = ConstrainLiteral<TId, RouteIds<TRouter['routeTree']>>
132
132
 
133
133
  /**
134
- * @internal
134
+ * @private
135
135
  */
136
136
  export type InferStrict<TOptions> = TOptions extends {
137
137
  strict: infer TStrict extends boolean
@@ -140,7 +140,7 @@ export type InferStrict<TOptions> = TOptions extends {
140
140
  : true
141
141
 
142
142
  /**
143
- * @internal
143
+ * @private
144
144
  */
145
145
  export type InferShouldThrow<TOptions> = TOptions extends {
146
146
  shouldThrow: infer TShouldThrow extends boolean
@@ -149,7 +149,7 @@ export type InferShouldThrow<TOptions> = TOptions extends {
149
149
  : true
150
150
 
151
151
  /**
152
- * @internal
152
+ * @private
153
153
  */
154
154
  export type InferSelected<TOptions> = TOptions extends {
155
155
  select: (...args: Array<any>) => infer TSelected
package/src/utils.ts CHANGED
@@ -432,3 +432,13 @@ export function isModuleNotFoundError(error: any): boolean {
432
432
  error.message.startsWith('Importing a module script failed')
433
433
  )
434
434
  }
435
+
436
+ export function isPromise<T>(
437
+ value: Promise<Awaited<T>> | T,
438
+ ): value is Promise<Awaited<T>> {
439
+ return Boolean(
440
+ value &&
441
+ typeof value === 'object' &&
442
+ typeof (value as Promise<T>).then === 'function',
443
+ )
444
+ }