@tanstack/react-router 1.97.8 → 1.97.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 (69) hide show
  1. package/dist/cjs/Match.cjs +8 -24
  2. package/dist/cjs/Match.cjs.map +1 -1
  3. package/dist/cjs/Matches.cjs +1 -1
  4. package/dist/cjs/Matches.cjs.map +1 -1
  5. package/dist/cjs/RouterProvider.cjs.map +1 -1
  6. package/dist/cjs/RouterProvider.d.cts +0 -1
  7. package/dist/cjs/ScriptOnce.cjs +19 -4
  8. package/dist/cjs/ScriptOnce.cjs.map +1 -1
  9. package/dist/cjs/ScriptOnce.d.cts +2 -1
  10. package/dist/cjs/Transitioner.cjs +1 -2
  11. package/dist/cjs/Transitioner.cjs.map +1 -1
  12. package/dist/cjs/awaited.cjs +1 -22
  13. package/dist/cjs/awaited.cjs.map +1 -1
  14. package/dist/cjs/index.cjs +2 -7
  15. package/dist/cjs/index.cjs.map +1 -1
  16. package/dist/cjs/index.d.cts +4 -6
  17. package/dist/cjs/router.cjs +11 -129
  18. package/dist/cjs/router.cjs.map +1 -1
  19. package/dist/cjs/router.d.cts +33 -93
  20. package/dist/cjs/routerContext.cjs.map +1 -1
  21. package/dist/cjs/routerContext.d.cts +7 -2
  22. package/dist/cjs/serializer.d.cts +15 -0
  23. package/dist/esm/Match.js +9 -25
  24. package/dist/esm/Match.js.map +1 -1
  25. package/dist/esm/Matches.js +1 -1
  26. package/dist/esm/Matches.js.map +1 -1
  27. package/dist/esm/RouterProvider.d.ts +0 -1
  28. package/dist/esm/RouterProvider.js.map +1 -1
  29. package/dist/esm/ScriptOnce.d.ts +2 -1
  30. package/dist/esm/ScriptOnce.js +19 -4
  31. package/dist/esm/ScriptOnce.js.map +1 -1
  32. package/dist/esm/Transitioner.js +1 -2
  33. package/dist/esm/Transitioner.js.map +1 -1
  34. package/dist/esm/awaited.js +1 -22
  35. package/dist/esm/awaited.js.map +1 -1
  36. package/dist/esm/index.d.ts +4 -6
  37. package/dist/esm/index.js +1 -6
  38. package/dist/esm/index.js.map +1 -1
  39. package/dist/esm/router.d.ts +33 -93
  40. package/dist/esm/router.js +11 -129
  41. package/dist/esm/router.js.map +1 -1
  42. package/dist/esm/routerContext.d.ts +7 -2
  43. package/dist/esm/routerContext.js.map +1 -1
  44. package/dist/esm/serializer.d.ts +15 -0
  45. package/package.json +1 -1
  46. package/src/Match.tsx +4 -29
  47. package/src/Matches.tsx +1 -1
  48. package/src/RouterProvider.tsx +3 -3
  49. package/src/ScriptOnce.tsx +22 -4
  50. package/src/Transitioner.tsx +1 -1
  51. package/src/awaited.tsx +3 -25
  52. package/src/index.tsx +12 -34
  53. package/src/router.ts +44 -271
  54. package/src/routerContext.tsx +7 -1
  55. package/src/serializer.ts +24 -0
  56. package/dist/cjs/isServerSideError.cjs +0 -22
  57. package/dist/cjs/isServerSideError.cjs.map +0 -1
  58. package/dist/cjs/isServerSideError.d.cts +0 -5
  59. package/dist/cjs/transformer.cjs +0 -137
  60. package/dist/cjs/transformer.cjs.map +0 -1
  61. package/dist/cjs/transformer.d.cts +0 -16
  62. package/dist/esm/isServerSideError.d.ts +0 -5
  63. package/dist/esm/isServerSideError.js +0 -22
  64. package/dist/esm/isServerSideError.js.map +0 -1
  65. package/dist/esm/transformer.d.ts +0 -16
  66. package/dist/esm/transformer.js +0 -137
  67. package/dist/esm/transformer.js.map +0 -1
  68. package/src/isServerSideError.tsx +0 -23
  69. package/src/transformer.ts +0 -192
@@ -1,3 +1,8 @@
1
- import { Router } from './router.js';
1
+ import { AnyRouter, Router } from './router.js';
2
2
  import * as React from 'react';
3
- export declare function getRouterContext(): React.Context<Router<any, any, any, import('@tanstack/history').RouterHistory, Record<string, any>, Record<string, any>>>;
3
+ declare global {
4
+ interface Window {
5
+ __TSR_ROUTER_CONTEXT__?: React.Context<AnyRouter>;
6
+ }
7
+ }
8
+ export declare function getRouterContext(): React.Context<AnyRouter> | React.Context<Router<any, any, any, import('@tanstack/history').RouterHistory, Record<string, any>, Record<string, any>>>;
@@ -1 +1 @@
1
- {"version":3,"file":"routerContext.js","sources":["../../src/routerContext.tsx"],"sourcesContent":["import * as React from 'react'\nimport type { Router } from './router'\n\nconst routerContext = React.createContext<Router<any, any, any>>(null!)\n\nexport function getRouterContext() {\n if (typeof document === 'undefined') {\n return routerContext\n }\n\n if (window.__TSR_ROUTER_CONTEXT__) {\n return window.__TSR_ROUTER_CONTEXT__\n }\n\n window.__TSR_ROUTER_CONTEXT__ = routerContext as any\n\n return routerContext\n}\n"],"names":[],"mappings":";AAGA,MAAM,gBAAgB,MAAM,cAAqC,IAAK;AAE/D,SAAS,mBAAmB;AAC7B,MAAA,OAAO,aAAa,aAAa;AAC5B,WAAA;AAAA,EAAA;AAGT,MAAI,OAAO,wBAAwB;AACjC,WAAO,OAAO;AAAA,EAAA;AAGhB,SAAO,yBAAyB;AAEzB,SAAA;AACT;"}
1
+ {"version":3,"file":"routerContext.js","sources":["../../src/routerContext.tsx"],"sourcesContent":["import * as React from 'react'\nimport type { AnyRouter, Router } from './router'\n\ndeclare global {\n interface Window {\n __TSR_ROUTER_CONTEXT__?: React.Context<AnyRouter>\n }\n}\n\nconst routerContext = React.createContext<Router<any, any, any>>(null!)\n\nexport function getRouterContext() {\n if (typeof document === 'undefined') {\n return routerContext\n }\n\n if (window.__TSR_ROUTER_CONTEXT__) {\n return window.__TSR_ROUTER_CONTEXT__\n }\n\n window.__TSR_ROUTER_CONTEXT__ = routerContext as any\n\n return routerContext\n}\n"],"names":[],"mappings":";AASA,MAAM,gBAAgB,MAAM,cAAqC,IAAK;AAE/D,SAAS,mBAAmB;AAC7B,MAAA,OAAO,aAAa,aAAa;AAC5B,WAAA;AAAA,EAAA;AAGT,MAAI,OAAO,wBAAwB;AACjC,WAAO,OAAO;AAAA,EAAA;AAGhB,SAAO,yBAAyB;AAEzB,SAAA;AACT;"}
@@ -0,0 +1,15 @@
1
+ export interface StartSerializer {
2
+ stringify: (obj: unknown) => string;
3
+ parse: (str: string) => unknown;
4
+ encode: <T>(value: T) => T;
5
+ decode: <T>(value: T) => T;
6
+ }
7
+ export type SerializerStringifyBy<T, TSerializable> = T extends TSerializable ? T : T extends (...args: Array<any>) => any ? 'Function is not serializable' : {
8
+ [K in keyof T]: SerializerStringifyBy<T[K], TSerializable>;
9
+ };
10
+ export type SerializerParseBy<T, TSerializable> = T extends TSerializable ? T : T extends React.JSX.Element ? ReadableStream : {
11
+ [K in keyof T]: SerializerParseBy<T[K], TSerializable>;
12
+ };
13
+ export type Serializable = Date | undefined | Error | FormData;
14
+ export type SerializerStringify<T> = SerializerStringifyBy<T, Serializable>;
15
+ export type SerializerParse<T> = SerializerParseBy<T, Serializable>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-router",
3
- "version": "1.97.8",
3
+ "version": "1.97.16",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
package/src/Match.tsx CHANGED
@@ -10,7 +10,6 @@ import { createControlledPromise, pick } from './utils'
10
10
  import { CatchNotFound, isNotFound } from './not-found'
11
11
  import { isRedirect } from './redirects'
12
12
  import { matchContext } from './matchContext'
13
- import { defaultDeserializeError, isServerSideError } from './isServerSideError'
14
13
  import { SafeFragment } from './SafeFragment'
15
14
  import { renderRouteNotFound } from './renderRouteNotFound'
16
15
  import { rootRouteId } from './root'
@@ -157,19 +156,8 @@ export const MatchInner = React.memo(function MatchInnerImpl({
157
156
  ErrorComponent
158
157
 
159
158
  if (match.status === 'notFound') {
160
- let error: unknown
161
- if (isServerSideError(match.error)) {
162
- const deserializeError =
163
- router.options.errorSerializer?.deserialize ?? defaultDeserializeError
164
-
165
- error = deserializeError(match.error.data)
166
- } else {
167
- error = match.error
168
- }
169
-
170
- invariant(isNotFound(error), 'Expected a notFound error')
171
-
172
- return renderRouteNotFound(router, route, error)
159
+ invariant(isNotFound(match.error), 'Expected a notFound error')
160
+ return renderRouteNotFound(router, route, match.error)
173
161
  }
174
162
 
175
163
  if (match.status === 'redirected') {
@@ -201,13 +189,7 @@ export const MatchInner = React.memo(function MatchInnerImpl({
201
189
  )
202
190
  }
203
191
 
204
- if (isServerSideError(match.error)) {
205
- const deserializeError =
206
- router.options.errorSerializer?.deserialize ?? defaultDeserializeError
207
- throw deserializeError(match.error.data)
208
- } else {
209
- throw match.error
210
- }
192
+ throw match.error
211
193
  }
212
194
 
213
195
  if (match.status === 'pending') {
@@ -241,14 +223,7 @@ export const MatchInner = React.memo(function MatchInnerImpl({
241
223
  throw router.getMatch(match.id)?.loadPromise
242
224
  }
243
225
 
244
- return (
245
- <>
246
- {out}
247
- {router.AfterEachMatch ? (
248
- <router.AfterEachMatch match={match} matchIndex={matchIndex} />
249
- ) : null}
250
- </>
251
- )
226
+ return out
252
227
  })
253
228
 
254
229
  export const Outlet = React.memo(function OutletImpl() {
package/src/Matches.tsx CHANGED
@@ -219,7 +219,7 @@ export function Matches() {
219
219
 
220
220
  // Do not render a root Suspense during SSR or hydrating from SSR
221
221
  const ResolvedSuspense =
222
- router.isServer || (typeof document !== 'undefined' && window.__TSR__)
222
+ router.isServer || (typeof document !== 'undefined' && router.clientSsr)
223
223
  ? SafeFragment
224
224
  : React.Suspense
225
225
 
@@ -54,8 +54,6 @@ export type BuildLocationFn = <
54
54
  },
55
55
  ) => ParsedLocation
56
56
 
57
- export type InjectedHtmlEntry = string | (() => Promise<string> | string)
58
-
59
57
  export function RouterContextProvider<
60
58
  TRouter extends AnyRouter = RegisteredRouter,
61
59
  TDehydrated extends Record<string, any> = Record<string, any>,
@@ -79,7 +77,9 @@ export function RouterContextProvider<
79
77
  const routerContext = getRouterContext()
80
78
 
81
79
  const provider = (
82
- <routerContext.Provider value={router}>{children}</routerContext.Provider>
80
+ <routerContext.Provider value={router as AnyRouter}>
81
+ {children}
82
+ </routerContext.Provider>
83
83
  )
84
84
 
85
85
  if (router.options.Wrap) {
@@ -1,4 +1,4 @@
1
- import { useRouter } from './useRouter'
1
+ import jsesc from 'jsesc'
2
2
 
3
3
  export function ScriptOnce({
4
4
  children,
@@ -6,9 +6,27 @@ export function ScriptOnce({
6
6
  }: {
7
7
  children: string
8
8
  log?: boolean
9
+ sync?: boolean
9
10
  }) {
10
- const router = useRouter()
11
+ if (typeof document !== 'undefined') {
12
+ return null
13
+ }
11
14
 
12
- router.injectScript(children, { logScript: log })
13
- return null
15
+ return (
16
+ <script
17
+ className="tsr-once"
18
+ dangerouslySetInnerHTML={{
19
+ __html: [
20
+ children,
21
+ (log ?? true) && process.env.NODE_ENV === 'development'
22
+ ? `console.info(\`Injected From Server:
23
+ ${jsesc(children.toString(), { quotes: 'backtick' })}\`)`
24
+ : '',
25
+ 'if (typeof __TSR__ !== "undefined") __TSR__.cleanScripts()',
26
+ ]
27
+ .filter(Boolean)
28
+ .join('\n'),
29
+ }}
30
+ />
31
+ )
14
32
  }
@@ -65,7 +65,7 @@ export function Transitioner() {
65
65
  // Try to load the initial location
66
66
  useLayoutEffect(() => {
67
67
  if (
68
- (typeof window !== 'undefined' && window.__TSR__?.dehydrated) ||
68
+ (typeof window !== 'undefined' && router.clientSsr) ||
69
69
  (mountLoadForRouter.current.router === router &&
70
70
  mountLoadForRouter.current.mounted)
71
71
  ) {
package/src/awaited.tsx CHANGED
@@ -1,9 +1,6 @@
1
1
  import * as React from 'react'
2
- import warning from 'tiny-warning'
3
- import { useRouter } from './useRouter'
4
- import { defaultSerializeError } from './router'
2
+
5
3
  import { TSR_DEFERRED_PROMISE, defer } from './defer'
6
- import { defaultDeserializeError, isServerSideError } from './isServerSideError'
7
4
  import type { DeferredPromise } from './defer'
8
5
 
9
6
  export type AwaitOptions<T> = {
@@ -13,7 +10,6 @@ export type AwaitOptions<T> = {
13
10
  export function useAwaited<T>({
14
11
  promise: _promise,
15
12
  }: AwaitOptions<T>): [T, DeferredPromise<T>] {
16
- const router = useRouter()
17
13
  const promise = defer(_promise)
18
14
 
19
15
  if (promise[TSR_DEFERRED_PROMISE].status === 'pending') {
@@ -21,27 +17,9 @@ export function useAwaited<T>({
21
17
  }
22
18
 
23
19
  if (promise[TSR_DEFERRED_PROMISE].status === 'error') {
24
- if (typeof document !== 'undefined') {
25
- if (isServerSideError(promise[TSR_DEFERRED_PROMISE].error)) {
26
- throw (
27
- router.options.errorSerializer?.deserialize ?? defaultDeserializeError
28
- )(promise[TSR_DEFERRED_PROMISE].error.data as any)
29
- } else {
30
- warning(
31
- false,
32
- "Encountered a server-side error that doesn't fit the expected shape",
33
- )
34
- throw promise[TSR_DEFERRED_PROMISE].error
35
- }
36
- } else {
37
- throw {
38
- data: (
39
- router.options.errorSerializer?.serialize ?? defaultSerializeError
40
- )(promise[TSR_DEFERRED_PROMISE].error),
41
- __isServerError: true,
42
- }
43
- }
20
+ throw promise[TSR_DEFERRED_PROMISE].error
44
21
  }
22
+
45
23
  return [promise[TSR_DEFERRED_PROMISE].data, promise]
46
24
  }
47
25
 
package/src/index.tsx CHANGED
@@ -17,8 +17,6 @@ export { default as warning } from 'tiny-warning'
17
17
  export { useAwaited, Await } from './awaited'
18
18
  export type { AwaitOptions } from './awaited'
19
19
 
20
- export { ScriptOnce } from './ScriptOnce'
21
-
22
20
  export { defer, TSR_DEFERRED_PROMISE } from './defer'
23
21
  export type { DeferredPromiseState, DeferredPromise } from './defer'
24
22
 
@@ -95,15 +93,9 @@ export type {
95
93
  } from './Matches'
96
94
 
97
95
  export { matchContext } from './matchContext'
98
-
99
96
  export { Match, Outlet } from './Match'
100
-
101
- export { isServerSideError, defaultDeserializeError } from './isServerSideError'
102
-
103
97
  export { useMatch } from './useMatch'
104
-
105
98
  export { useLoaderDeps } from './useLoaderDeps'
106
-
107
99
  export { useLoaderData } from './useLoaderData'
108
100
 
109
101
  export {
@@ -239,7 +231,6 @@ export type {
239
231
  Register,
240
232
  AnyRouter,
241
233
  RegisteredRouter,
242
- HydrationCtx,
243
234
  RouterContextOptions,
244
235
  TrailingSlashOption,
245
236
  RouterOptions,
@@ -247,23 +238,24 @@ export type {
247
238
  RouterState,
248
239
  ListenerFn,
249
240
  BuildNextOptions,
250
- DehydratedRouterState,
251
- DehydratedRouteMatch,
252
- DehydratedRouter,
253
241
  RouterConstructorOptions,
254
242
  RouterEvents,
255
243
  RouterEvent,
256
244
  RouterListener,
257
245
  AnyRouterWithContext,
258
- ClientExtractedBaseEntry,
259
- ClientExtractedEntry,
260
- ClientExtractedPromise,
261
246
  ControllablePromise,
262
- StreamState,
263
- TSRGlobal,
264
- TSRGlobalMatch,
247
+ InjectedHtmlEntry,
265
248
  } from './router'
266
249
 
250
+ export type {
251
+ StartSerializer,
252
+ Serializable,
253
+ SerializerParse,
254
+ SerializerParseBy,
255
+ SerializerStringify,
256
+ SerializerStringifyBy,
257
+ } from './serializer'
258
+
267
259
  export { RouterProvider, RouterContextProvider } from './RouterProvider'
268
260
  export type {
269
261
  RouterProps,
@@ -271,7 +263,6 @@ export type {
271
263
  MatchLocation,
272
264
  NavigateFn,
273
265
  BuildLocationFn,
274
- InjectedHtmlEntry,
275
266
  } from './RouterProvider'
276
267
 
277
268
  export {
@@ -289,16 +280,6 @@ export {
289
280
  } from './searchParams'
290
281
  export type { SearchSerializer, SearchParser } from './searchParams'
291
282
 
292
- export { defaultTransformer } from './transformer'
293
- export type {
294
- RouterTransformer,
295
- TransformerParse,
296
- TransformerStringify,
297
- DefaultSerializable,
298
- DefaultTransformerParse,
299
- DefaultTransformerStringify,
300
- } from './transformer'
301
-
302
283
  export type { UseBlockerOpts, ShouldBlockFn } from './useBlocker'
303
284
  export { useBlocker, Block } from './useBlocker'
304
285
 
@@ -306,7 +287,6 @@ export { useNavigate, Navigate } from './useNavigate'
306
287
  export type { UseNavigateResult } from './useNavigate'
307
288
 
308
289
  export { useParams } from './useParams'
309
-
310
290
  export { useSearch } from './useSearch'
311
291
 
312
292
  export {
@@ -314,13 +294,9 @@ export {
314
294
  } from './routerContext'
315
295
 
316
296
  export { useRouteContext } from './useRouteContext'
317
-
318
297
  export { useRouter } from './useRouter'
319
-
320
298
  export { useRouterState } from './useRouterState'
321
-
322
299
  export { useLocation } from './useLocation'
323
-
324
300
  export { useCanGoBack } from './useCanGoBack'
325
301
 
326
302
  export {
@@ -377,3 +353,5 @@ export type {
377
353
  export { retainSearchParams, stripSearchParams } from './searchMiddleware'
378
354
 
379
355
  export * from './typePrimitives'
356
+
357
+ export { ScriptOnce } from './ScriptOnce'