@tanstack/router-core 1.132.0-alpha.4 → 1.132.0-alpha.8

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 (54) hide show
  1. package/dist/cjs/Matches.cjs.map +1 -1
  2. package/dist/cjs/Matches.d.cts +2 -2
  3. package/dist/cjs/config.cjs +10 -0
  4. package/dist/cjs/config.cjs.map +1 -0
  5. package/dist/cjs/config.d.cts +17 -0
  6. package/dist/cjs/fileRoute.d.cts +3 -2
  7. package/dist/cjs/index.cjs +2 -0
  8. package/dist/cjs/index.cjs.map +1 -1
  9. package/dist/cjs/index.d.cts +3 -2
  10. package/dist/cjs/load-matches.cjs.map +1 -1
  11. package/dist/cjs/route.cjs.map +1 -1
  12. package/dist/cjs/route.d.cts +42 -37
  13. package/dist/cjs/router.cjs +25 -26
  14. package/dist/cjs/router.cjs.map +1 -1
  15. package/dist/cjs/router.d.cts +19 -13
  16. package/dist/cjs/ssr/serializer/transformer.cjs +14 -12
  17. package/dist/cjs/ssr/serializer/transformer.cjs.map +1 -1
  18. package/dist/cjs/ssr/serializer/transformer.d.cts +53 -15
  19. package/dist/cjs/ssr/server.d.cts +5 -0
  20. package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
  21. package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
  22. package/dist/esm/Matches.d.ts +2 -2
  23. package/dist/esm/Matches.js.map +1 -1
  24. package/dist/esm/config.d.ts +17 -0
  25. package/dist/esm/config.js +10 -0
  26. package/dist/esm/config.js.map +1 -0
  27. package/dist/esm/fileRoute.d.ts +3 -2
  28. package/dist/esm/index.d.ts +3 -2
  29. package/dist/esm/index.js +2 -0
  30. package/dist/esm/index.js.map +1 -1
  31. package/dist/esm/load-matches.js.map +1 -1
  32. package/dist/esm/route.d.ts +42 -37
  33. package/dist/esm/route.js.map +1 -1
  34. package/dist/esm/router.d.ts +19 -13
  35. package/dist/esm/router.js +25 -26
  36. package/dist/esm/router.js.map +1 -1
  37. package/dist/esm/ssr/serializer/transformer.d.ts +53 -15
  38. package/dist/esm/ssr/serializer/transformer.js +14 -12
  39. package/dist/esm/ssr/serializer/transformer.js.map +1 -1
  40. package/dist/esm/ssr/server.d.ts +5 -0
  41. package/dist/esm/ssr/ssr-client.js.map +1 -1
  42. package/dist/esm/ssr/ssr-server.js.map +1 -1
  43. package/package.json +1 -1
  44. package/src/Matches.ts +2 -2
  45. package/src/config.ts +42 -0
  46. package/src/fileRoute.ts +15 -3
  47. package/src/index.ts +13 -1
  48. package/src/load-matches.ts +2 -2
  49. package/src/route.ts +136 -33
  50. package/src/router.ts +59 -64
  51. package/src/ssr/serializer/transformer.ts +168 -31
  52. package/src/ssr/server.ts +6 -0
  53. package/src/ssr/ssr-client.ts +2 -2
  54. package/src/ssr/ssr-server.ts +2 -2
package/src/router.ts CHANGED
@@ -84,6 +84,8 @@ import type { Manifest } from './manifest'
84
84
  import type { AnySchema, AnyValidator } from './validators'
85
85
  import type { NavigateOptions, ResolveRelativePath, ToOptions } from './link'
86
86
  import type { NotFoundError } from './not-found'
87
+ import type { AnySerializationAdapter } from './ssr/serializer/transformer'
88
+ import type { AnyRouterConfig } from './config'
87
89
 
88
90
  export type ControllablePromise<T = any> = Promise<T> & {
89
91
  resolve: (value: T) => void
@@ -94,6 +96,8 @@ export type InjectedHtmlEntry = Promise<string>
94
96
 
95
97
  export interface DefaultRegister {
96
98
  router: AnyRouter
99
+ config: AnyRouterConfig
100
+ ssr: SSROption
97
101
  }
98
102
 
99
103
  export interface Register extends DefaultRegister {
@@ -111,13 +115,14 @@ export interface DefaultRouterOptionsExtensions {}
111
115
  export interface RouterOptionsExtensions
112
116
  extends DefaultRouterOptionsExtensions {}
113
117
 
118
+ export type SSROption = boolean | 'data-only'
119
+
114
120
  export interface RouterOptions<
115
121
  TRouteTree extends AnyRoute,
116
122
  TTrailingSlashOption extends TrailingSlashOption,
117
123
  TDefaultStructuralSharingOption extends boolean = false,
118
124
  TRouterHistory extends RouterHistory = RouterHistory,
119
125
  TDehydrated extends Record<string, any> = Record<string, any>,
120
- TTransformerConfig = any,
121
126
  > extends RouterOptionsExtensions {
122
127
  /**
123
128
  * The history object that will be used to manage the browser history.
@@ -355,7 +360,7 @@ export interface RouterOptions<
355
360
  *
356
361
  * @default true
357
362
  */
358
- defaultSsr?: boolean | 'data-only'
363
+ defaultSsr?: SSROption
359
364
 
360
365
  search?: {
361
366
  /**
@@ -425,7 +430,7 @@ export interface RouterOptions<
425
430
  */
426
431
  disableGlobalCatchBoundary?: boolean
427
432
 
428
- serializationAdapters?: TTransformerConfig
433
+ serializationAdapters?: ReadonlyArray<AnySerializationAdapter>
429
434
  }
430
435
 
431
436
  export interface RouterState<
@@ -534,15 +539,13 @@ export type RouterConstructorOptions<
534
539
  TDefaultStructuralSharingOption extends boolean,
535
540
  TRouterHistory extends RouterHistory,
536
541
  TDehydrated extends Record<string, any>,
537
- TTransformerConfig,
538
542
  > = Omit<
539
543
  RouterOptions<
540
544
  TRouteTree,
541
545
  TTrailingSlashOption,
542
546
  TDefaultStructuralSharingOption,
543
547
  TRouterHistory,
544
- TDehydrated,
545
- TTransformerConfig
548
+ TDehydrated
546
549
  >,
547
550
  'context'
548
551
  > &
@@ -602,15 +605,13 @@ export type UpdateFn<
602
605
  TDefaultStructuralSharingOption extends boolean,
603
606
  TRouterHistory extends RouterHistory,
604
607
  TDehydrated extends Record<string, any>,
605
- TTransformerConfig extends any,
606
608
  > = (
607
609
  newOptions: RouterConstructorOptions<
608
610
  TRouteTree,
609
611
  TTrailingSlashOption,
610
612
  TDefaultStructuralSharingOption,
611
613
  TRouterHistory,
612
- TDehydrated,
613
- TTransformerConfig
614
+ TDehydrated
614
615
  >,
615
616
  ) => void
616
617
 
@@ -621,8 +622,8 @@ export type InvalidateFn<TRouter extends AnyRouter> = (opts?: {
621
622
  }) => Promise<void>
622
623
 
623
624
  export type ParseLocationFn<TRouteTree extends AnyRoute> = (
625
+ locationToParse: HistoryLocation,
624
626
  previousLocation?: ParsedLocation<FullSearchSchema<TRouteTree>>,
625
- locationToParse?: HistoryLocation,
626
627
  ) => ParsedLocation<FullSearchSchema<TRouteTree>>
627
628
 
628
629
  export type GetMatchRoutesFn = (
@@ -695,11 +696,10 @@ export type AnyRouterWithContext<TContext> = RouterCore<
695
696
  any,
696
697
  any,
697
698
  any,
698
- any,
699
699
  any
700
700
  >
701
701
 
702
- export type AnyRouter = RouterCore<any, any, any, any, any, any>
702
+ export type AnyRouter = RouterCore<any, any, any, any, any>
703
703
 
704
704
  export interface ViewTransitionOptions {
705
705
  types:
@@ -753,7 +753,6 @@ export type CreateRouterFn = <
753
753
  TDefaultStructuralSharingOption extends boolean = false,
754
754
  TRouterHistory extends RouterHistory = RouterHistory,
755
755
  TDehydrated extends Record<string, any> = Record<string, any>,
756
- TTransformerConfig = any,
757
756
  >(
758
757
  options: undefined extends number
759
758
  ? 'strictNullChecks must be enabled in tsconfig.json'
@@ -762,16 +761,14 @@ export type CreateRouterFn = <
762
761
  TTrailingSlashOption,
763
762
  TDefaultStructuralSharingOption,
764
763
  TRouterHistory,
765
- TDehydrated,
766
- TTransformerConfig
764
+ TDehydrated
767
765
  >,
768
766
  ) => RouterCore<
769
767
  TRouteTree,
770
768
  TTrailingSlashOption,
771
769
  TDefaultStructuralSharingOption,
772
770
  TRouterHistory,
773
- TDehydrated,
774
- TTransformerConfig
771
+ TDehydrated
775
772
  >
776
773
 
777
774
  export class RouterCore<
@@ -780,7 +777,6 @@ export class RouterCore<
780
777
  in out TDefaultStructuralSharingOption extends boolean,
781
778
  in out TRouterHistory extends RouterHistory = RouterHistory,
782
779
  in out TDehydrated extends Record<string, any> = Record<string, any>,
783
- in out TTransformerConfig = any,
784
780
  > {
785
781
  // Option-independent properties
786
782
  tempLocationKey: string | undefined = `${Math.round(
@@ -802,8 +798,7 @@ export class RouterCore<
802
798
  TTrailingSlashOption,
803
799
  TDefaultStructuralSharingOption,
804
800
  TRouterHistory,
805
- TDehydrated,
806
- TTransformerConfig
801
+ TDehydrated
807
802
  >,
808
803
  'stringifySearch' | 'parseSearch' | 'context'
809
804
  >
@@ -826,8 +821,7 @@ export class RouterCore<
826
821
  TTrailingSlashOption,
827
822
  TDefaultStructuralSharingOption,
828
823
  TRouterHistory,
829
- TDehydrated,
830
- TTransformerConfig
824
+ TDehydrated
831
825
  >,
832
826
  ) {
833
827
  this.update({
@@ -865,8 +859,7 @@ export class RouterCore<
865
859
  TTrailingSlashOption,
866
860
  TDefaultStructuralSharingOption,
867
861
  TRouterHistory,
868
- TDehydrated,
869
- TTransformerConfig
862
+ TDehydrated
870
863
  > = (newOptions) => {
871
864
  if (newOptions.notFoundRoute) {
872
865
  console.warn(
@@ -917,7 +910,7 @@ export class RouterCore<
917
910
  initialEntries: [this.basepath || '/'],
918
911
  })
919
912
  : createBrowserHistory()) as TRouterHistory)
920
- this.latestLocation = this.parseLocation()
913
+ this.updateLatestLocation()
921
914
  }
922
915
 
923
916
  if (this.options.routeTree !== this.routeTree) {
@@ -955,6 +948,13 @@ export class RouterCore<
955
948
  return this.__store.state
956
949
  }
957
950
 
951
+ updateLatestLocation = () => {
952
+ this.latestLocation = this.parseLocation(
953
+ this.history.location,
954
+ this.latestLocation,
955
+ )
956
+ }
957
+
958
958
  buildRouteTree = () => {
959
959
  const { routesById, routesByPath, flatRoutes } = processRouteTree({
960
960
  routeTree: this.routeTree,
@@ -1001,8 +1001,8 @@ export class RouterCore<
1001
1001
  }
1002
1002
 
1003
1003
  parseLocation: ParseLocationFn<TRouteTree> = (
1004
- previousLocation,
1005
1004
  locationToParse,
1005
+ previousLocation,
1006
1006
  ) => {
1007
1007
  const parse = ({
1008
1008
  pathname,
@@ -1023,7 +1023,7 @@ export class RouterCore<
1023
1023
  }
1024
1024
  }
1025
1025
 
1026
- const location = parse(locationToParse ?? this.history.location)
1026
+ const location = parse(locationToParse)
1027
1027
 
1028
1028
  const { __tempLocation, __tempKey } = location.state
1029
1029
 
@@ -1425,50 +1425,44 @@ export class RouterCore<
1425
1425
  _buildLocation: true,
1426
1426
  })
1427
1427
 
1428
+ // Now let's find the starting pathname
1429
+ // This should default to the current location if no from is provided
1428
1430
  const lastMatch = last(allCurrentLocationMatches)!
1429
1431
 
1430
- // First let's find the starting pathname
1431
- // By default, start with the current location
1432
- let fromPath = this.resolvePathWithBase(lastMatch.fullPath, '.')
1433
- const toPath = dest.to
1434
- ? this.resolvePathWithBase(fromPath, `${dest.to}`)
1435
- : this.resolvePathWithBase(fromPath, '.')
1436
-
1437
- const routeIsChanging =
1438
- !!dest.to &&
1439
- !comparePaths(dest.to.toString(), fromPath) &&
1440
- !comparePaths(toPath, fromPath)
1441
-
1442
- // If the route is changing we need to find the relative fromPath
1443
- if (dest.unsafeRelative === 'path') {
1444
- fromPath = currentLocation.pathname
1445
- } else if (routeIsChanging && dest.from) {
1446
- fromPath = dest.from
1447
-
1448
- // do this check only on navigations during test or development
1449
- if (process.env.NODE_ENV !== 'production' && dest._isNavigate) {
1450
- const allFromMatches = this.getMatchedRoutes(
1451
- dest.from,
1452
- undefined,
1453
- ).matchedRoutes
1432
+ // check that from path exists in the current route tree
1433
+ // do this check only on navigations during test or development
1434
+ if (
1435
+ dest.from &&
1436
+ process.env.NODE_ENV !== 'production' &&
1437
+ dest._isNavigate
1438
+ ) {
1439
+ const allFromMatches = this.getMatchedRoutes(
1440
+ dest.from,
1441
+ undefined,
1442
+ ).matchedRoutes
1454
1443
 
1455
- const matchedFrom = findLast(allCurrentLocationMatches, (d) => {
1456
- return comparePaths(d.fullPath, fromPath)
1457
- })
1444
+ const matchedFrom = findLast(allCurrentLocationMatches, (d) => {
1445
+ return comparePaths(d.fullPath, dest.from!)
1446
+ })
1458
1447
 
1459
- const matchedCurrent = findLast(allFromMatches, (d) => {
1460
- return comparePaths(d.fullPath, currentLocation.pathname)
1461
- })
1448
+ const matchedCurrent = findLast(allFromMatches, (d) => {
1449
+ return comparePaths(d.fullPath, lastMatch.fullPath)
1450
+ })
1462
1451
 
1463
- // for from to be invalid it shouldn't just be unmatched to currentLocation
1464
- // but the currentLocation should also be unmatched to from
1465
- if (!matchedFrom && !matchedCurrent) {
1466
- console.warn(`Could not find match for from: ${fromPath}`)
1467
- }
1452
+ // for from to be invalid it shouldn't just be unmatched to currentLocation
1453
+ // but the currentLocation should also be unmatched to from
1454
+ if (!matchedFrom && !matchedCurrent) {
1455
+ console.warn(`Could not find match for from: ${dest.from}`)
1468
1456
  }
1469
1457
  }
1470
1458
 
1471
- fromPath = this.resolvePathWithBase(fromPath, '.')
1459
+ const defaultedFromPath =
1460
+ dest.unsafeRelative === 'path'
1461
+ ? currentLocation.pathname
1462
+ : (dest.from ?? lastMatch.fullPath)
1463
+
1464
+ // ensure this includes the basePath if set
1465
+ const fromPath = this.resolvePathWithBase(defaultedFromPath, '.')
1472
1466
 
1473
1467
  // From search should always use the current location
1474
1468
  const fromSearch = lastMatch.search
@@ -1476,6 +1470,7 @@ export class RouterCore<
1476
1470
  const fromParams = { ...lastMatch.params }
1477
1471
 
1478
1472
  // Resolve the next to
1473
+ // ensure this includes the basePath if set
1479
1474
  const nextTo = dest.to
1480
1475
  ? this.resolvePathWithBase(fromPath, `${dest.to}`)
1481
1476
  : this.resolvePathWithBase(fromPath, '.')
@@ -1814,7 +1809,7 @@ export class RouterCore<
1814
1809
  beforeLoad = () => {
1815
1810
  // Cancel any pending matches
1816
1811
  this.cancelMatches()
1817
- this.latestLocation = this.parseLocation(this.latestLocation)
1812
+ this.updateLatestLocation()
1818
1813
 
1819
1814
  if (this.isServer) {
1820
1815
  // for SPAs on the initial load, this is handled by the Transitioner
@@ -1,39 +1,111 @@
1
1
  import { createPlugin } from 'seroval'
2
2
  import { GLOBAL_TSR } from '../constants'
3
- import type { SerovalNode } from 'seroval'
3
+ import type { Plugin, SerovalNode } from 'seroval'
4
+ import type { Register, SSROption } from '../../router'
5
+ import type { LooseReturnType } from '../../utils'
6
+ import type { AnyRoute, ResolveAllSSR } from '../../route'
4
7
 
5
- export type Transformer<TInput, TTransformed> = {
8
+ export type Serializable =
9
+ | number
10
+ | string
11
+ | boolean
12
+ | null
13
+ | undefined
14
+ | bigint
15
+ | Date
16
+
17
+ export function createSerializationAdapter<
18
+ TInput = unknown,
19
+ TOutput = unknown /* we need to check that this type is actually serializable taking into account all seroval native types and any custom plugin WE=router/start add!!! */,
20
+ >(
21
+ opts: CreateSerializationAdapterOptions<TInput, TOutput>,
22
+ ): SerializationAdapter<TInput, TOutput> {
23
+ return opts as unknown as SerializationAdapter<TInput, TOutput>
24
+ }
25
+
26
+ export interface CreateSerializationAdapterOptions<TInput, TOutput> {
6
27
  key: string
7
- test: (value: any) => value is TInput
8
- toSerializable: (value: TInput) => TTransformed
9
- fromSerializable: (value: TTransformed) => TInput
28
+ test: (value: unknown) => value is TInput
29
+ toSerializable: (value: TInput) => ValidateSerializable<TOutput, Serializable>
30
+ fromSerializable: (value: TOutput) => TInput
10
31
  }
11
32
 
12
- export type AnyTransformer = Transformer<any, any>
33
+ export type ValidateSerializable<T, TSerializable> = T extends TSerializable
34
+ ? T
35
+ : T extends (...args: Array<any>) => any
36
+ ? 'Function is not serializable'
37
+ : T extends Promise<any>
38
+ ? ValidateSerializablePromise<T, TSerializable>
39
+ : T extends ReadableStream<any>
40
+ ? ValidateReadableStream<T, TSerializable>
41
+ : T extends Set<any>
42
+ ? ValidateSerializableSet<T, TSerializable>
43
+ : T extends Map<any, any>
44
+ ? ValidateSerializableMap<T, TSerializable>
45
+ : {
46
+ [K in keyof T]: ValidateSerializable<T[K], TSerializable>
47
+ }
13
48
 
14
- export function createSerializationAdapter<
15
- TKey extends string,
16
- TInput,
17
- TTransformed /* we need to check that this type is actually serializable taking into account all seroval native types and any custom plugin WE=router/start add!!! */,
18
- >(opts: {
19
- key: TKey
20
- test: (value: any) => value is TInput
21
- toSerializable: (value: TInput) => TTransformed
22
- fromSerializable: (value: TTransformed) => TInput
23
- }): Transformer<TInput, TTransformed> {
24
- return opts
49
+ export type ValidateSerializablePromise<T, TSerializable> =
50
+ T extends Promise<infer TAwaited>
51
+ ? Promise<ValidateSerializable<TAwaited, TSerializable>>
52
+ : never
53
+
54
+ export type ValidateReadableStream<T, TSerializable> =
55
+ T extends ReadableStream<infer TStreamed>
56
+ ? ReadableStream<ValidateSerializable<TStreamed, TSerializable>>
57
+ : never
58
+
59
+ export type ValidateSerializableSet<T, TSerializable> =
60
+ T extends Set<infer TItem>
61
+ ? Set<ValidateSerializable<TItem, TSerializable>>
62
+ : never
63
+
64
+ export type ValidateSerializableMap<T, TSerializable> =
65
+ T extends Map<infer TKey, infer TValue>
66
+ ? Map<
67
+ ValidateSerializable<TKey, TSerializable>,
68
+ ValidateSerializable<TValue, TSerializable>
69
+ >
70
+ : never
71
+
72
+ export type RegisteredReadableStream =
73
+ unknown extends SerializerExtensions['ReadableStream']
74
+ ? never
75
+ : SerializerExtensions['ReadableStream']
76
+
77
+ export interface DefaultSerializerExtensions {
78
+ ReadableStream: unknown
79
+ }
80
+
81
+ export interface SerializerExtensions extends DefaultSerializerExtensions {}
82
+
83
+ export interface SerializationAdapter<TInput, TOutput> {
84
+ '~types': SerializationAdapterTypes<TInput, TOutput>
85
+ key: string
86
+ test: (value: unknown) => value is TInput
87
+ toSerializable: (value: TInput) => TOutput
88
+ fromSerializable: (value: TOutput) => TInput
89
+ makePlugin: (options: { didRun: boolean }) => Plugin<TInput, SerovalNode>
90
+ }
91
+
92
+ export interface SerializationAdapterTypes<TInput, TOutput> {
93
+ input: TInput
94
+ output: TOutput
25
95
  }
26
96
 
27
- export function makeSsrSerovalPlugin<TInput, TTransformed>(
28
- transformer: Transformer<TInput, TTransformed>,
97
+ export type AnySerializationAdapter = SerializationAdapter<any, any>
98
+
99
+ export function makeSsrSerovalPlugin<TInput, TOutput>(
100
+ serializationAdapter: SerializationAdapter<TInput, TOutput>,
29
101
  options: { didRun: boolean },
30
102
  ) {
31
103
  return createPlugin<TInput, SerovalNode>({
32
- tag: '$TSR/t/' + transformer.key,
33
- test: transformer.test,
104
+ tag: '$TSR/t/' + serializationAdapter.key,
105
+ test: serializationAdapter.test,
34
106
  parse: {
35
107
  stream(value, ctx) {
36
- return ctx.parse(transformer.toSerializable(value))
108
+ return ctx.parse(serializationAdapter.toSerializable(value))
37
109
  },
38
110
  },
39
111
  serialize(node, ctx) {
@@ -41,7 +113,7 @@ export function makeSsrSerovalPlugin<TInput, TTransformed>(
41
113
  return (
42
114
  GLOBAL_TSR +
43
115
  '.t.get("' +
44
- transformer.key +
116
+ serializationAdapter.key +
45
117
  '")(' +
46
118
  ctx.serialize(node) +
47
119
  ')'
@@ -52,27 +124,92 @@ export function makeSsrSerovalPlugin<TInput, TTransformed>(
52
124
  })
53
125
  }
54
126
 
55
- export function makeSerovalPlugin<TInput, TTransformed>(
56
- transformer: Transformer<TInput, TTransformed>,
127
+ export function makeSerovalPlugin<TInput, TOutput>(
128
+ serializationAdapter: SerializationAdapter<TInput, TOutput>,
57
129
  ) {
58
130
  return createPlugin<TInput, SerovalNode>({
59
- tag: '$TSR/t/' + transformer.key,
60
- test: transformer.test,
131
+ tag: '$TSR/t/' + serializationAdapter.key,
132
+ test: serializationAdapter.test,
61
133
  parse: {
62
134
  sync(value, ctx) {
63
- return ctx.parse(transformer.toSerializable(value))
135
+ return ctx.parse(serializationAdapter.toSerializable(value))
64
136
  },
65
137
  async async(value, ctx) {
66
- return await ctx.parse(transformer.toSerializable(value))
138
+ return await ctx.parse(serializationAdapter.toSerializable(value))
67
139
  },
68
140
  stream(value, ctx) {
69
- return ctx.parse(transformer.toSerializable(value))
141
+ return ctx.parse(serializationAdapter.toSerializable(value))
70
142
  },
71
143
  },
72
144
  // we don't generate JS code outside of SSR (for now)
73
145
  serialize: undefined as never,
74
146
  deserialize(node, ctx) {
75
- return transformer.fromSerializable(ctx.deserialize(node) as TTransformed)
147
+ return serializationAdapter.fromSerializable(
148
+ ctx.deserialize(node) as TOutput,
149
+ )
76
150
  },
77
151
  })
78
152
  }
153
+
154
+ export type ValidateSerializableInput<
155
+ TRegister extends Register,
156
+ T,
157
+ > = ValidateSerializable<T, RegisteredSerializableInput<TRegister>>
158
+
159
+ export type RegisteredSerializableInput<TRegister extends Register> =
160
+ | (unknown extends RegisteredSerializationAdapters<TRegister>
161
+ ? never
162
+ : RegisteredSerializationAdapters<TRegister> extends ReadonlyArray<AnySerializationAdapter>
163
+ ? RegisteredSerializationAdapters<TRegister>[number]['~types']['input']
164
+ : never)
165
+ | Serializable
166
+
167
+ export type RegisteredSerializationAdapters<TRegister extends Register> =
168
+ TRegister['config']['~types']['serializationAdapters']
169
+
170
+ export type ValidateSerializableInputResult<
171
+ TRegister extends Register,
172
+ T,
173
+ > = ValidateSerializableResult<T, RegisteredSerializableInput<TRegister>>
174
+
175
+ export type ValidateSerializableResult<T, TSerializable> =
176
+ T extends TSerializable
177
+ ? T
178
+ : unknown extends SerializerExtensions['ReadableStream']
179
+ ? { [K in keyof T]: ValidateSerializableResult<T[K], TSerializable> }
180
+ : T extends SerializerExtensions['ReadableStream']
181
+ ? ReadableStream
182
+ : { [K in keyof T]: ValidateSerializableResult<T[K], TSerializable> }
183
+
184
+ export type RegisteredSSROption<TRegister extends Register> =
185
+ unknown extends TRegister['config']['~types']['defaultSsr']
186
+ ? SSROption
187
+ : TRegister['config']['~types']['defaultSsr']
188
+
189
+ export type ValidateSerializableLifecycleResult<
190
+ TRegister extends Register,
191
+ TParentRoute extends AnyRoute,
192
+ TSSR,
193
+ TFn,
194
+ > = false extends TRegister['ssr']
195
+ ? any
196
+ : ValidateSerializableLifecycleResultSSR<
197
+ TRegister,
198
+ TParentRoute,
199
+ TSSR,
200
+ TFn
201
+ > extends infer TInput
202
+ ? TInput
203
+ : never
204
+
205
+ export type ValidateSerializableLifecycleResultSSR<
206
+ TRegister extends Register,
207
+ TParentRoute extends AnyRoute,
208
+ TSSR,
209
+ TFn,
210
+ > =
211
+ ResolveAllSSR<TParentRoute, TSSR> extends false
212
+ ? any
213
+ : RegisteredSSROption<TRegister> extends false
214
+ ? any
215
+ : ValidateSerializableInput<TRegister, LooseReturnType<TFn>>
package/src/ssr/server.ts CHANGED
@@ -8,3 +8,9 @@ export {
8
8
  transformReadableStreamWithRouter,
9
9
  } from './transformStreamWithRouter'
10
10
  export { attachRouterServerSsrUtils } from './ssr-server'
11
+
12
+ declare module '../router' {
13
+ export interface Register {
14
+ ssr: true
15
+ }
16
+ }
@@ -5,7 +5,7 @@ import type { AnyRouteMatch, MakeRouteMatch } from '../Matches'
5
5
  import type { AnyRouter } from '../router'
6
6
  import type { Manifest } from '../manifest'
7
7
  import type { RouteContextOptions } from '../route'
8
- import type { AnyTransformer } from './serializer/transformer'
8
+ import type { AnySerializationAdapter } from './serializer/transformer'
9
9
  import type { GLOBAL_TSR } from './constants'
10
10
 
11
11
  declare global {
@@ -63,7 +63,7 @@ export async function hydrate(router: AnyRouter): Promise<any> {
63
63
  )
64
64
 
65
65
  const serializationAdapters = router.options.serializationAdapters as
66
- | Array<AnyTransformer>
66
+ | Array<AnySerializationAdapter>
67
67
  | undefined
68
68
 
69
69
  if (serializationAdapters?.length) {
@@ -10,7 +10,7 @@ import type { DehydratedMatch } from './ssr-client'
10
10
  import type { DehydratedRouter } from './client'
11
11
  import type { AnyRouteMatch } from '../Matches'
12
12
  import type { Manifest } from '../manifest'
13
- import type { AnyTransformer } from './serializer/transformer'
13
+ import type { AnySerializationAdapter } from './serializer/transformer'
14
14
 
15
15
  declare module '../router' {
16
16
  interface ServerSsr {
@@ -109,7 +109,7 @@ export function attachRouterServerSsrUtils(
109
109
  const plugins =
110
110
  (
111
111
  router.options.serializationAdapters as
112
- | Array<AnyTransformer>
112
+ | Array<AnySerializationAdapter>
113
113
  | undefined
114
114
  )?.map((t) => makeSsrSerovalPlugin(t, trackPlugins)) ?? []
115
115
  crossSerializeStream(dehydratedRouter, {