@trpc/client 10.0.0-alpha.5 → 10.0.0-alpha.50

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 (178) hide show
  1. package/README.md +58 -1
  2. package/dist/TRPCClientError.d.ts +16 -20
  3. package/dist/TRPCClientError.d.ts.map +1 -1
  4. package/dist/createTRPCClient.d.ts +2 -3
  5. package/dist/createTRPCClient.d.ts.map +1 -1
  6. package/dist/createTRPCClientProxy.d.ts +37 -0
  7. package/dist/createTRPCClientProxy.d.ts.map +1 -0
  8. package/dist/httpUtils-44781613.mjs +76 -0
  9. package/dist/httpUtils-801112a6.js +79 -0
  10. package/dist/index.d.ts +2 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +254 -280
  13. package/dist/index.mjs +247 -271
  14. package/dist/internals/TRPCClient.d.ts +38 -17
  15. package/dist/internals/TRPCClient.d.ts.map +1 -1
  16. package/dist/internals/dataLoader.d.ts +7 -4
  17. package/dist/internals/dataLoader.d.ts.map +1 -1
  18. package/dist/internals/fetchHelpers.d.ts.map +1 -1
  19. package/dist/internals/retryDelay.d.ts.map +1 -1
  20. package/dist/links/dedupeLink.d.ts.map +1 -1
  21. package/dist/links/httpBatchLink.d.ts +5 -2
  22. package/dist/links/httpBatchLink.d.ts.map +1 -1
  23. package/dist/links/httpBatchLink.js +189 -166
  24. package/dist/links/httpBatchLink.mjs +189 -166
  25. package/dist/links/httpLink.d.ts +1 -1
  26. package/dist/links/httpLink.d.ts.map +1 -1
  27. package/dist/links/httpLink.js +31 -35
  28. package/dist/links/httpLink.mjs +31 -35
  29. package/dist/links/index.d.ts +9 -0
  30. package/dist/links/index.d.ts.map +1 -0
  31. package/dist/links/internals/createChain.d.ts.map +1 -1
  32. package/dist/links/internals/httpUtils.d.ts +31 -0
  33. package/dist/links/internals/httpUtils.d.ts.map +1 -0
  34. package/dist/links/internals/transformResult.d.ts +28 -0
  35. package/dist/links/internals/transformResult.d.ts.map +1 -0
  36. package/dist/links/loggerLink.d.ts +3 -3
  37. package/dist/links/loggerLink.d.ts.map +1 -1
  38. package/dist/links/loggerLink.js +90 -96
  39. package/dist/links/loggerLink.mjs +90 -91
  40. package/dist/links/retryLink.d.ts.map +1 -1
  41. package/dist/links/splitLink.d.ts +1 -1
  42. package/dist/links/splitLink.d.ts.map +1 -1
  43. package/dist/links/splitLink.js +3 -25
  44. package/dist/links/splitLink.mjs +2 -28
  45. package/dist/links/types.d.ts +13 -12
  46. package/dist/links/types.d.ts.map +1 -1
  47. package/dist/links/wsLink.d.ts +12 -5
  48. package/dist/links/wsLink.d.ts.map +1 -1
  49. package/dist/links/wsLink.js +250 -357
  50. package/dist/links/wsLink.mjs +250 -348
  51. package/dist/splitLink-695ae288.js +48 -0
  52. package/dist/splitLink-ad44a55d.mjs +45 -0
  53. package/dist/transformResult-106791d7.mjs +62 -0
  54. package/dist/transformResult-e15ccdf6.js +65 -0
  55. package/links/httpBatchLink/dist/trpc-client-links-httpBatchLink.cjs.dev.js +15 -13
  56. package/links/httpBatchLink/dist/trpc-client-links-httpBatchLink.cjs.prod.js +15 -13
  57. package/links/httpBatchLink/dist/trpc-client-links-httpBatchLink.esm.js +12 -10
  58. package/links/httpLink/dist/trpc-client-links-httpLink.cjs.dev.js +4 -4
  59. package/links/httpLink/dist/trpc-client-links-httpLink.cjs.prod.js +4 -4
  60. package/links/httpLink/dist/trpc-client-links-httpLink.esm.js +1 -1
  61. package/links/wsLink/dist/trpc-client-links-wsLink.cjs.dev.js +3 -1
  62. package/links/wsLink/dist/trpc-client-links-wsLink.cjs.prod.js +3 -1
  63. package/links/wsLink/dist/trpc-client-links-wsLink.esm.js +3 -1
  64. package/package.json +23 -34
  65. package/src/TRPCClientError.ts +38 -28
  66. package/src/createTRPCClient.ts +8 -3
  67. package/src/createTRPCClientProxy.ts +113 -0
  68. package/src/index.ts +2 -1
  69. package/src/internals/TRPCClient.ts +96 -59
  70. package/src/internals/dataLoader.ts +120 -45
  71. package/src/links/dedupeLink.test.ts +9 -15
  72. package/src/links/dedupeLink.ts +6 -7
  73. package/src/links/httpBatchLink.ts +76 -33
  74. package/src/links/httpLink.ts +18 -6
  75. package/src/links/index.ts +8 -0
  76. package/src/links/internals/createChain.test.ts +23 -38
  77. package/src/links/internals/createChain.ts +8 -3
  78. package/src/links/internals/httpUtils.ts +117 -0
  79. package/src/links/internals/transformResult.ts +40 -0
  80. package/src/links/loggerLink.ts +6 -7
  81. package/src/links/retryLink.ts +2 -3
  82. package/src/links/splitLink.test.ts +3 -3
  83. package/src/links/splitLink.ts +5 -5
  84. package/src/links/types.ts +15 -12
  85. package/src/links/wsLink.ts +57 -23
  86. package/dist/TRPCClientError-17b117e1.mjs +0 -81
  87. package/dist/TRPCClientError-ec6bd2ca.js +0 -94
  88. package/dist/createChain-389cc116.mjs +0 -25
  89. package/dist/createChain-864dbb30.js +0 -27
  90. package/dist/httpUtils-1f9e4e3c.js +0 -97
  91. package/dist/httpUtils-c09d7b79.mjs +0 -91
  92. package/dist/index.ts.js +0 -1
  93. package/dist/internals/transformRPCResponse.d.ts +0 -15
  94. package/dist/internals/transformRPCResponse.d.ts.map +0 -1
  95. package/dist/links/httpBatchLink.ts.js +0 -1
  96. package/dist/links/httpLink.ts.js +0 -1
  97. package/dist/links/httpUtils.d.ts +0 -22
  98. package/dist/links/httpUtils.d.ts.map +0 -1
  99. package/dist/links/internals/transformOperationResult.d.ts +0 -16
  100. package/dist/links/internals/transformOperationResult.d.ts.map +0 -1
  101. package/dist/links/loggerLink.ts.js +0 -1
  102. package/dist/links/splitLink.ts.js +0 -1
  103. package/dist/links/transformerLink.d.ts +0 -4
  104. package/dist/links/transformerLink.d.ts.map +0 -1
  105. package/dist/links/transformerLink.js +0 -75
  106. package/dist/links/transformerLink.mjs +0 -67
  107. package/dist/links/transformerLink.ts.js +0 -1
  108. package/dist/links/wsLink.ts.js +0 -1
  109. package/dist/observable-7e66cb56.mjs +0 -102
  110. package/dist/observable-85669100.js +0 -104
  111. package/dist/rx/index.d.ts +0 -3
  112. package/dist/rx/index.d.ts.map +0 -1
  113. package/dist/rx/index.js +0 -9
  114. package/dist/rx/index.mjs +0 -1
  115. package/dist/rx/index.ts.js +0 -1
  116. package/dist/rx/observable.d.ts +0 -4
  117. package/dist/rx/observable.d.ts.map +0 -1
  118. package/dist/rx/operators/index.d.ts +0 -4
  119. package/dist/rx/operators/index.d.ts.map +0 -1
  120. package/dist/rx/operators/index.js +0 -38
  121. package/dist/rx/operators/index.mjs +0 -32
  122. package/dist/rx/operators/index.ts.js +0 -1
  123. package/dist/rx/operators/map.d.ts +0 -3
  124. package/dist/rx/operators/map.d.ts.map +0 -1
  125. package/dist/rx/operators/share.d.ts +0 -6
  126. package/dist/rx/operators/share.d.ts.map +0 -1
  127. package/dist/rx/operators/tap.d.ts +0 -3
  128. package/dist/rx/operators/tap.d.ts.map +0 -1
  129. package/dist/rx/types.d.ts +0 -29
  130. package/dist/rx/types.d.ts.map +0 -1
  131. package/dist/rx/util/identity.d.ts +0 -2
  132. package/dist/rx/util/identity.d.ts.map +0 -1
  133. package/dist/rx/util/observableToPromise.d.ts +0 -10
  134. package/dist/rx/util/observableToPromise.d.ts.map +0 -1
  135. package/dist/rx/util/pipe.d.ts +0 -4
  136. package/dist/rx/util/pipe.d.ts.map +0 -1
  137. package/dist/share-4d79dc49.js +0 -110
  138. package/dist/share-671b63fa.mjs +0 -108
  139. package/dist/tap-538fa07f.mjs +0 -30
  140. package/dist/tap-799a2d33.js +0 -32
  141. package/links/transformerLink/dist/trpc-client-links-transformerLink.cjs.d.ts +0 -1
  142. package/links/transformerLink/dist/trpc-client-links-transformerLink.cjs.dev.js +0 -67
  143. package/links/transformerLink/dist/trpc-client-links-transformerLink.cjs.js +0 -7
  144. package/links/transformerLink/dist/trpc-client-links-transformerLink.cjs.prod.js +0 -67
  145. package/links/transformerLink/dist/trpc-client-links-transformerLink.esm.js +0 -63
  146. package/links/transformerLink/index.d.ts +0 -1
  147. package/links/transformerLink/index.js +0 -1
  148. package/rx/dist/trpc-client-rx.cjs.d.ts +0 -1
  149. package/rx/dist/trpc-client-rx.cjs.dev.js +0 -9
  150. package/rx/dist/trpc-client-rx.cjs.js +0 -7
  151. package/rx/dist/trpc-client-rx.cjs.prod.js +0 -9
  152. package/rx/dist/trpc-client-rx.esm.js +0 -1
  153. package/rx/index.d.ts +0 -1
  154. package/rx/index.js +0 -1
  155. package/rx/operators/dist/trpc-client-rx-operators.cjs.d.ts +0 -1
  156. package/rx/operators/dist/trpc-client-rx-operators.cjs.dev.js +0 -39
  157. package/rx/operators/dist/trpc-client-rx-operators.cjs.js +0 -7
  158. package/rx/operators/dist/trpc-client-rx-operators.cjs.prod.js +0 -39
  159. package/rx/operators/dist/trpc-client-rx-operators.esm.js +0 -33
  160. package/rx/operators/index.d.ts +0 -1
  161. package/rx/operators/index.js +0 -1
  162. package/src/internals/transformRPCResponse.ts +0 -25
  163. package/src/links/httpUtils.ts +0 -94
  164. package/src/links/internals/transformOperationResult.ts +0 -25
  165. package/src/links/transformerLink.ts +0 -70
  166. package/src/rx/index.ts +0 -2
  167. package/src/rx/observable.test.ts +0 -83
  168. package/src/rx/observable.ts +0 -70
  169. package/src/rx/operators/index.ts +0 -3
  170. package/src/rx/operators/map.test.ts +0 -92
  171. package/src/rx/operators/map.ts +0 -25
  172. package/src/rx/operators/share.test.ts +0 -60
  173. package/src/rx/operators/share.ts +0 -67
  174. package/src/rx/operators/tap.ts +0 -26
  175. package/src/rx/types.ts +0 -69
  176. package/src/rx/util/identity.ts +0 -3
  177. package/src/rx/util/observableToPromise.ts +0 -49
  178. package/src/rx/util/pipe.ts +0 -22
@@ -1,38 +1,45 @@
1
- import { AnyRouter, inferRouterError, Maybe } from '@trpc/server';
1
+ import {
2
+ AnyRouter,
3
+ DefaultErrorShape,
4
+ Maybe,
5
+ Procedure,
6
+ inferRouterError,
7
+ } from '@trpc/server';
2
8
  import { TRPCErrorResponse } from '@trpc/server/rpc';
3
9
 
4
- export interface TRPCClientErrorLike<TRouter extends AnyRouter> {
10
+ type RouterOrProcedure = AnyRouter | Procedure<any>;
11
+
12
+ type inferErrorShape<TRouterOrProcedure extends AnyRouter | Procedure<any>> =
13
+ TRouterOrProcedure extends AnyRouter
14
+ ? inferRouterError<TRouterOrProcedure>
15
+ : TRouterOrProcedure['_def']['_config']['errorShape'];
16
+
17
+ export interface TRPCClientErrorBase<TShape extends DefaultErrorShape> {
5
18
  readonly message: string;
6
- readonly shape: Maybe<inferRouterError<TRouter>>;
7
- readonly data: Maybe<inferRouterError<TRouter>['data']>;
19
+ readonly shape: Maybe<TShape>;
20
+ readonly data: Maybe<TShape['data']>;
8
21
  }
22
+ export type TRPCClientErrorLike<TRouterOrProcedure extends RouterOrProcedure> =
23
+ TRPCClientErrorBase<inferErrorShape<TRouterOrProcedure>>;
9
24
 
10
- export class TRPCClientError<TRouter extends AnyRouter>
25
+ export class TRPCClientError<TRouterOrProcedure extends RouterOrProcedure>
11
26
  extends Error
12
- implements TRPCClientErrorLike<TRouter>
27
+ implements TRPCClientErrorBase<inferErrorShape<TRouterOrProcedure>>
13
28
  {
14
- /**
15
- * @deprecated use `cause`
16
- */
17
- public readonly originalError;
18
29
  public readonly cause;
19
- public readonly shape: Maybe<inferRouterError<TRouter>>;
20
- public readonly data: Maybe<inferRouterError<TRouter>['data']>;
30
+ public readonly shape: Maybe<inferErrorShape<TRouterOrProcedure>>;
31
+ public readonly data: Maybe<inferErrorShape<TRouterOrProcedure>['data']>;
21
32
  public readonly meta;
22
33
 
23
34
  constructor(
24
35
  message: string,
25
36
  opts?: {
26
- result: Maybe<TRPCErrorResponse<inferRouterError<TRouter>>>;
27
- /**
28
- * @deprecated use `cause`
29
- **/
30
- originalError?: Maybe<Error>;
31
- cause?: Maybe<Error>;
37
+ result?: Maybe<inferErrorShape<TRouterOrProcedure>>;
38
+ cause?: Error;
32
39
  meta?: Record<string, unknown>;
33
40
  },
34
41
  ) {
35
- const cause = opts?.cause ?? opts?.originalError;
42
+ const cause = opts?.cause;
36
43
 
37
44
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
38
45
  // @ts-ignore https://github.com/tc39/proposal-error-cause
@@ -40,7 +47,7 @@ export class TRPCClientError<TRouter extends AnyRouter>
40
47
 
41
48
  this.meta = opts?.meta;
42
49
 
43
- this.cause = this.originalError = cause;
50
+ this.cause = cause;
44
51
  this.shape = opts?.result?.error;
45
52
  this.data = opts?.result?.error.data;
46
53
  this.name = 'TRPCClientError';
@@ -48,22 +55,25 @@ export class TRPCClientError<TRouter extends AnyRouter>
48
55
  Object.setPrototypeOf(this, TRPCClientError.prototype);
49
56
  }
50
57
 
51
- public static from<TRouter extends AnyRouter>(
58
+ public static from<TRouterOrProcedure extends RouterOrProcedure>(
52
59
  cause: Error | TRPCErrorResponse<any>,
53
60
  opts: { meta?: Record<string, unknown> } = {},
54
- ): TRPCClientError<TRouter> {
61
+ ): TRPCClientError<TRouterOrProcedure> {
55
62
  if (!(cause instanceof Error)) {
56
- return new TRPCClientError<TRouter>((cause.error as any).message ?? '', {
57
- ...opts,
58
- cause: null,
59
- result: cause,
60
- });
63
+ return new TRPCClientError<TRouterOrProcedure>(
64
+ (cause.error as any).message ?? '',
65
+ {
66
+ ...opts,
67
+ cause: undefined,
68
+ result: cause as any,
69
+ },
70
+ );
61
71
  }
62
72
  if (cause.name === 'TRPCClientError') {
63
73
  return cause as TRPCClientError<any>;
64
74
  }
65
75
 
66
- return new TRPCClientError<TRouter>(cause.message, {
76
+ return new TRPCClientError<TRouterOrProcedure>(cause.message, {
67
77
  ...opts,
68
78
  cause,
69
79
  result: null,
@@ -1,19 +1,24 @@
1
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
+
1
3
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
4
  import type { AnyRouter } from '@trpc/server';
3
5
  import {
4
- CreateTRPCClientOptions,
5
6
  TRPCClient as Client,
7
+ CreateTRPCClientOptions,
6
8
  } from './internals/TRPCClient';
7
9
 
8
10
  export function createTRPCClient<TRouter extends AnyRouter>(
9
11
  opts: CreateTRPCClientOptions<TRouter>,
10
12
  ) {
11
- return new Client<TRouter>(opts);
13
+ const client = new Client<TRouter>(opts);
14
+ return client;
12
15
  }
13
16
 
14
- export type TRPCClient<TRouter extends AnyRouter> = Client<TRouter>;
17
+ // Also the client created above needs to somehow be like `TRPCClient<Router> & Omit<Router, 'createCaller' | 'createProcedure' | '_def' | 'transformer' | 'errorFormatter' | 'getErrorShape>`
15
18
 
16
19
  export type {
17
20
  TRPCRequestOptions,
18
21
  CreateTRPCClientOptions,
22
+ TRPCClient,
23
+ AssertLegacyDef,
19
24
  } from './internals/TRPCClient';
@@ -0,0 +1,113 @@
1
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
+
3
+ /* eslint-disable @typescript-eslint/no-explicit-any */
4
+ import type {
5
+ AnyRouter,
6
+ OmitNeverKeys,
7
+ Procedure,
8
+ ProcedureArgs,
9
+ ProcedureRouterRecord,
10
+ ProcedureType,
11
+ inferProcedureOutput,
12
+ } from '@trpc/server';
13
+ import type {
14
+ Unsubscribable,
15
+ inferObservableValue,
16
+ } from '@trpc/server/observable';
17
+ import type { TRPCResultMessage } from '@trpc/server/rpc';
18
+ import { createProxy } from '@trpc/server/shared';
19
+ import { TRPCClientError } from './TRPCClientError';
20
+ import { CreateTRPCClientOptions, createTRPCClient } from './createTRPCClient';
21
+ import {
22
+ TRPCClient as Client,
23
+ TRPCSubscriptionObserver,
24
+ } from './internals/TRPCClient';
25
+
26
+ type Resolver<TProcedure extends Procedure<any>> = (
27
+ ...args: ProcedureArgs<TProcedure['_def']>
28
+ ) => Promise<inferProcedureOutput<TProcedure>>;
29
+
30
+ type SubscriptionResolver<
31
+ TProcedure extends Procedure<any>,
32
+ TRouter extends AnyRouter,
33
+ > = (
34
+ ...args: [
35
+ input: ProcedureArgs<TProcedure['_def']>[0],
36
+ opts: ProcedureArgs<TProcedure['_def']>[1] &
37
+ Partial<
38
+ TRPCSubscriptionObserver<
39
+ TRPCResultMessage<
40
+ inferObservableValue<inferProcedureOutput<TProcedure>>
41
+ >,
42
+ TRPCClientError<TRouter>
43
+ >
44
+ >,
45
+ ]
46
+ ) => Unsubscribable;
47
+
48
+ type DecorateProcedure<
49
+ TProcedure extends Procedure<any>,
50
+ TRouter extends AnyRouter,
51
+ > = OmitNeverKeys<{
52
+ query: TProcedure extends { _query: true } ? Resolver<TProcedure> : never;
53
+
54
+ mutate: TProcedure extends { _mutation: true } ? Resolver<TProcedure> : never;
55
+
56
+ subscribe: TProcedure extends { _subscription: true }
57
+ ? SubscriptionResolver<TProcedure, TRouter>
58
+ : never;
59
+ }>;
60
+
61
+ type assertProcedure<T> = T extends Procedure<any> ? T : never;
62
+
63
+ /**
64
+ * @internal
65
+ */
66
+ type DecoratedProcedureRecord<
67
+ TProcedures extends ProcedureRouterRecord,
68
+ TRouter extends AnyRouter,
69
+ > = OmitNeverKeys<{
70
+ [TKey in keyof TProcedures]: TProcedures[TKey] extends AnyRouter
71
+ ? DecoratedProcedureRecord<
72
+ TProcedures[TKey]['_def']['record'],
73
+ TProcedures[TKey]
74
+ >
75
+ : assertProcedure<TProcedures[TKey]>['_def']['_old'] extends true
76
+ ? never
77
+ : DecorateProcedure<assertProcedure<TProcedures[TKey]>, TRouter>;
78
+ }>;
79
+
80
+ const clientCallTypeMap: Record<
81
+ keyof DecorateProcedure<any, any>,
82
+ ProcedureType
83
+ > = {
84
+ query: 'query',
85
+ mutate: 'mutation',
86
+ subscribe: 'subscription',
87
+ };
88
+
89
+ /**
90
+ * @deprecated use createTRPCProxyClient instead
91
+ * @internal
92
+ */
93
+ export function createTRPCClientProxy<TRouter extends AnyRouter>(
94
+ client: Client<TRouter>,
95
+ ) {
96
+ const proxy = createProxy(({ path, args }) => {
97
+ const pathCopy = [...path];
98
+ const clientCallType = pathCopy.pop()! as keyof DecorateProcedure<any, any>;
99
+ const procedureType = clientCallTypeMap[clientCallType];
100
+
101
+ const fullPath = pathCopy.join('.');
102
+ return (client as any)[procedureType](fullPath, ...args);
103
+ });
104
+ return proxy as DecoratedProcedureRecord<TRouter['_def']['record'], TRouter>;
105
+ }
106
+
107
+ export function createTRPCProxyClient<TRouter extends AnyRouter>(
108
+ opts: CreateTRPCClientOptions<TRouter>,
109
+ ) {
110
+ const client = createTRPCClient<TRouter>(opts);
111
+ const proxy = createTRPCClientProxy(client);
112
+ return proxy;
113
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './createTRPCClient';
2
+ export * from './createTRPCClientProxy';
2
3
  export * from './getFetch';
3
- export * from './links/types';
4
4
  export * from './TRPCClientError';
5
+ export * from './links';
@@ -1,46 +1,37 @@
1
1
  import {
2
2
  AnyRouter,
3
+ ClientDataTransformerOptions,
4
+ DataTransformer,
3
5
  inferHandlerInput,
4
6
  inferProcedureInput,
5
7
  inferProcedureOutput,
6
8
  inferSubscriptionOutput,
7
9
  } from '@trpc/server';
8
- import { TRPCResult } from '@trpc/server/rpc';
10
+ import { ProcedureRecord } from '@trpc/server';
11
+ import {
12
+ Unsubscribable,
13
+ inferObservableValue,
14
+ observableToPromise,
15
+ share,
16
+ } from '@trpc/server/observable';
9
17
  import { CancelFn } from '..';
18
+ import { TRPCClientError } from '../TRPCClientError';
10
19
  import { getFetch } from '../getFetch';
11
- import { httpBatchLink } from '../links/httpBatchLink';
20
+ import { httpBatchLink } from '../links';
12
21
  import { createChain } from '../links/internals/createChain';
13
- import { transformOperationResult } from '../links/internals/transformOperationResult';
14
22
  import {
15
23
  HTTPHeaders,
16
- LinkRuntime,
17
24
  OperationContext,
18
25
  OperationLink,
26
+ TRPCClientRuntime,
19
27
  TRPCLink,
20
28
  } from '../links/types';
21
- import { UnsubscribeFn } from '../rx';
22
- import { inferObservableValue } from '../rx/observable';
23
- import { share } from '../rx/operators';
24
- import { Observer } from '../rx/types';
25
- import { observableToPromise } from '../rx/util/observableToPromise';
26
- import { TRPCClientError } from '../TRPCClientError';
27
29
  import { getAbortController } from './fetchHelpers';
28
30
 
29
31
  type CancellablePromise<T = unknown> = Promise<T> & {
30
32
  cancel: CancelFn;
31
33
  };
32
34
 
33
- /**
34
- * @deprecated no longer used
35
- */
36
- export interface FetchOptions {
37
- fetch?: typeof fetch;
38
- AbortController?: typeof AbortController;
39
- }
40
- let idCounter = 0;
41
- function getRequestId() {
42
- return ++idCounter;
43
- }
44
35
  interface CreateTRPCClientBaseOptions {
45
36
  /**
46
37
  * Add ponyfill for fetch
@@ -54,6 +45,11 @@ interface CreateTRPCClientBaseOptions {
54
45
  * headers to be set on outgoing requests / callback that of said headers
55
46
  */
56
47
  headers?: HTTPHeaders | (() => HTTPHeaders | Promise<HTTPHeaders>);
48
+ /**
49
+ * Data transformer
50
+ * @link https://trpc.io/docs/data-transformers
51
+ **/
52
+ transformer?: ClientDataTransformerOptions;
57
53
  }
58
54
 
59
55
  /** @internal */
@@ -69,7 +65,7 @@ export interface CreateTRPCClientWithURLOptions
69
65
  export interface CreateTRPCClientWithLinksOptions<TRouter extends AnyRouter>
70
66
  extends CreateTRPCClientBaseOptions {
71
67
  /**
72
- * @link http://localhost:3000/docs/links
68
+ * @link https://trpc.io/docs/links
73
69
  **/
74
70
  links: TRPCLink<TRouter>[];
75
71
  }
@@ -82,29 +78,73 @@ export interface TRPCRequestOptions {
82
78
  context?: OperationContext;
83
79
  }
84
80
 
81
+ export interface TRPCSubscriptionObserver<TValue, TError> {
82
+ onStarted: () => void;
83
+ onData: (value: TValue) => void;
84
+ onError: (err: TError) => void;
85
+ onStopped: () => void;
86
+ onComplete: () => void;
87
+ }
88
+
85
89
  /** @internal */
86
90
  export type CreateTRPCClientOptions<TRouter extends AnyRouter> =
87
91
  | CreateTRPCClientWithLinksOptions<TRouter>
88
92
  | CreateTRPCClientWithURLOptions;
93
+
94
+ export type AssertType<T, K> = T extends K ? T : never;
95
+ /**
96
+ * @deprecated
97
+ */
98
+ export type AssertLegacyDef<TRouter extends AnyRouter> =
99
+ TRouter['_def']['legacy'] extends Record<
100
+ 'subscriptions' | 'queries' | 'mutations',
101
+ ProcedureRecord
102
+ >
103
+ ? TRouter['_def']['legacy']
104
+ : {
105
+ subscriptions: {};
106
+ queries: {};
107
+ mutations: {};
108
+ };
109
+
89
110
  export class TRPCClient<TRouter extends AnyRouter> {
90
111
  private readonly links: OperationLink<TRouter>[];
91
- public readonly runtime: LinkRuntime;
112
+ public readonly runtime: TRPCClientRuntime;
113
+ private requestId: number;
114
+ private getRequestId() {
115
+ return ++this.requestId;
116
+ }
92
117
 
93
118
  constructor(opts: CreateTRPCClientOptions<TRouter>) {
94
119
  const _fetch = getFetch(opts?.fetch);
95
120
  const AC = getAbortController(opts?.AbortController);
121
+ this.requestId = 0;
96
122
 
97
- function getHeadersFn(): LinkRuntime['headers'] {
123
+ function getHeadersFn(): TRPCClientRuntime['headers'] {
98
124
  if (opts.headers) {
99
125
  const headers = opts.headers;
100
126
  return typeof headers === 'function' ? headers : () => headers;
101
127
  }
102
128
  return () => ({});
103
129
  }
130
+
131
+ const transformer: DataTransformer = opts.transformer
132
+ ? 'input' in opts.transformer
133
+ ? {
134
+ serialize: opts.transformer.input.serialize,
135
+ deserialize: opts.transformer.output.deserialize,
136
+ }
137
+ : opts.transformer
138
+ : {
139
+ serialize: (data) => data,
140
+ deserialize: (data) => data,
141
+ };
142
+
104
143
  this.runtime = {
105
144
  AbortController: AC as any,
106
145
  fetch: _fetch,
107
146
  headers: getHeadersFn(),
147
+ transformer,
108
148
  };
109
149
 
110
150
  if ('links' in opts) {
@@ -132,7 +172,7 @@ export class TRPCClient<TRouter extends AnyRouter> {
132
172
  const chain$ = createChain<TRouter, TInput, TOutput>({
133
173
  links: this.links as OperationLink<any, any, any>[],
134
174
  op: {
135
- id: getRequestId(),
175
+ id: this.getRequestId(),
136
176
  type,
137
177
  path,
138
178
  input,
@@ -154,13 +194,8 @@ export class TRPCClient<TRouter extends AnyRouter> {
154
194
  const cancellablePromise: CancellablePromise<any> = new Promise<TOutput>(
155
195
  (resolve, reject) => {
156
196
  promise
157
- .then((result) => {
158
- const transformed = transformOperationResult(result);
159
- if (transformed.ok) {
160
- resolve(transformed.data as any);
161
- return;
162
- }
163
- reject(transformed.error);
197
+ .then((envelope) => {
198
+ resolve((envelope.result as any).data);
164
199
  })
165
200
  .catch((err) => {
166
201
  reject(TRPCClientError.from(err));
@@ -172,15 +207,18 @@ export class TRPCClient<TRouter extends AnyRouter> {
172
207
  return cancellablePromise;
173
208
  }
174
209
  public query<
175
- TQueries extends TRouter['_def']['queries'],
210
+ TQueries extends AssertLegacyDef<TRouter>['queries'],
176
211
  TPath extends string & keyof TQueries,
177
212
  >(
178
213
  path: TPath,
179
- ...args: [...inferHandlerInput<TQueries[TPath]>, TRPCRequestOptions?]
214
+ ...args: [
215
+ ...inferHandlerInput<AssertType<TQueries, ProcedureRecord>[TPath]>,
216
+ TRPCRequestOptions?,
217
+ ]
180
218
  ) {
181
219
  const context = (args[1] as TRPCRequestOptions | undefined)?.context;
182
220
  return this.requestAsPromise<
183
- inferHandlerInput<TQueries[TPath]>,
221
+ inferHandlerInput<AssertType<TQueries, ProcedureRecord>[TPath]>,
184
222
  inferProcedureOutput<TQueries[TPath]>
185
223
  >({
186
224
  type: 'query',
@@ -189,17 +227,19 @@ export class TRPCClient<TRouter extends AnyRouter> {
189
227
  context,
190
228
  });
191
229
  }
192
-
193
230
  public mutation<
194
- TMutations extends TRouter['_def']['mutations'],
231
+ TMutations extends AssertLegacyDef<TRouter>['mutations'],
195
232
  TPath extends string & keyof TMutations,
196
233
  >(
197
234
  path: TPath,
198
- ...args: [...inferHandlerInput<TMutations[TPath]>, TRPCRequestOptions?]
235
+ ...args: [
236
+ ...inferHandlerInput<AssertType<TMutations, ProcedureRecord>[TPath]>,
237
+ TRPCRequestOptions?,
238
+ ]
199
239
  ) {
200
240
  const context = (args[1] as TRPCRequestOptions | undefined)?.context;
201
241
  return this.requestAsPromise<
202
- inferHandlerInput<TMutations[TPath]>,
242
+ inferHandlerInput<AssertType<TMutations, ProcedureRecord>[TPath]>,
203
243
  inferProcedureOutput<TMutations[TPath]>
204
244
  >({
205
245
  type: 'mutation',
@@ -209,43 +249,40 @@ export class TRPCClient<TRouter extends AnyRouter> {
209
249
  });
210
250
  }
211
251
  public subscription<
212
- TSubscriptions extends TRouter['_def']['subscriptions'],
252
+ TSubscriptions extends AssertLegacyDef<TRouter>['subscriptions'],
213
253
  TPath extends string & keyof TSubscriptions,
214
254
  TOutput extends inferSubscriptionOutput<TRouter, TPath>,
215
- TInput extends inferProcedureInput<TSubscriptions[TPath]>,
255
+ TInput extends inferProcedureInput<
256
+ AssertType<TSubscriptions, ProcedureRecord>[TPath]
257
+ >,
216
258
  >(
217
259
  path: TPath,
218
260
  input: TInput,
219
261
  opts: TRPCRequestOptions &
220
- Partial<Observer<TRPCResult<TOutput>, TRPCClientError<TRouter>>>,
221
- ): UnsubscribeFn {
262
+ Partial<TRPCSubscriptionObserver<TOutput, TRPCClientError<TRouter>>>,
263
+ ): Unsubscribable {
222
264
  const observable$ = this.$request<TInput, TOutput>({
223
265
  type: 'subscription',
224
266
  path,
225
267
  input,
226
- context: opts.context,
268
+ context: opts?.context,
227
269
  });
228
- const observer = observable$.subscribe({
229
- next(result) {
230
- if ('error' in result.data) {
231
- const err = TRPCClientError.from(result.data, {
232
- meta: result.context,
233
- });
234
-
235
- opts.error?.(err);
236
- return;
270
+ return observable$.subscribe({
271
+ next(envelope) {
272
+ if (envelope.result.type === 'started') {
273
+ opts.onStarted?.();
274
+ } else if (envelope.result.type === 'stopped') {
275
+ opts.onStopped?.();
276
+ } else {
277
+ opts.onData?.((envelope.result as any).data);
237
278
  }
238
- opts.next?.(result.data.result);
239
279
  },
240
280
  error(err) {
241
- opts.error?.(err);
281
+ opts.onError?.(err);
242
282
  },
243
283
  complete() {
244
- opts.complete?.();
284
+ opts.onComplete?.();
245
285
  },
246
286
  });
247
- return () => {
248
- observer.unsubscribe();
249
- };
250
287
  }
251
288
  }