@trpc/client 10.0.0-alpha.8 → 10.0.0-proxy-alpha.53

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 (180) 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 +260 -280
  13. package/dist/index.mjs +253 -271
  14. package/dist/internals/TRPCClient.d.ts +39 -21
  15. package/dist/internals/TRPCClient.d.ts.map +1 -1
  16. package/dist/internals/dataLoader.d.ts +7 -6
  17. package/dist/internals/dataLoader.d.ts.map +1 -1
  18. package/dist/internals/fetchHelpers.d.ts +1 -1
  19. package/dist/internals/fetchHelpers.d.ts.map +1 -1
  20. package/dist/internals/retryDelay.d.ts.map +1 -1
  21. package/dist/links/dedupeLink.d.ts.map +1 -1
  22. package/dist/links/httpBatchLink.d.ts +2 -2
  23. package/dist/links/httpBatchLink.d.ts.map +1 -1
  24. package/dist/links/httpBatchLink.js +189 -172
  25. package/dist/links/httpBatchLink.mjs +189 -172
  26. package/dist/links/httpLink.d.ts +1 -1
  27. package/dist/links/httpLink.d.ts.map +1 -1
  28. package/dist/links/httpLink.js +31 -35
  29. package/dist/links/httpLink.mjs +31 -35
  30. package/dist/links/index.d.ts +9 -0
  31. package/dist/links/index.d.ts.map +1 -0
  32. package/dist/links/internals/createChain.d.ts.map +1 -1
  33. package/dist/links/internals/httpUtils.d.ts +31 -0
  34. package/dist/links/internals/httpUtils.d.ts.map +1 -0
  35. package/dist/links/internals/transformResult.d.ts +28 -0
  36. package/dist/links/internals/transformResult.d.ts.map +1 -0
  37. package/dist/links/loggerLink.d.ts +3 -3
  38. package/dist/links/loggerLink.d.ts.map +1 -1
  39. package/dist/links/loggerLink.js +90 -96
  40. package/dist/links/loggerLink.mjs +90 -91
  41. package/dist/links/retryLink.d.ts.map +1 -1
  42. package/dist/links/splitLink.d.ts +1 -1
  43. package/dist/links/splitLink.d.ts.map +1 -1
  44. package/dist/links/splitLink.js +3 -25
  45. package/dist/links/splitLink.mjs +2 -28
  46. package/dist/links/types.d.ts +13 -12
  47. package/dist/links/types.d.ts.map +1 -1
  48. package/dist/links/wsLink.d.ts +12 -5
  49. package/dist/links/wsLink.d.ts.map +1 -1
  50. package/dist/links/wsLink.js +250 -358
  51. package/dist/links/wsLink.mjs +250 -348
  52. package/dist/splitLink-695ae288.js +48 -0
  53. package/dist/splitLink-ad44a55d.mjs +45 -0
  54. package/dist/transformResult-106791d7.mjs +62 -0
  55. package/dist/transformResult-e15ccdf6.js +65 -0
  56. package/links/httpBatchLink/dist/trpc-client-links-httpBatchLink.cjs.dev.js +15 -13
  57. package/links/httpBatchLink/dist/trpc-client-links-httpBatchLink.cjs.prod.js +15 -13
  58. package/links/httpBatchLink/dist/trpc-client-links-httpBatchLink.esm.js +12 -10
  59. package/links/httpLink/dist/trpc-client-links-httpLink.cjs.dev.js +4 -4
  60. package/links/httpLink/dist/trpc-client-links-httpLink.cjs.prod.js +4 -4
  61. package/links/httpLink/dist/trpc-client-links-httpLink.esm.js +1 -1
  62. package/links/wsLink/dist/trpc-client-links-wsLink.cjs.dev.js +3 -1
  63. package/links/wsLink/dist/trpc-client-links-wsLink.cjs.prod.js +3 -1
  64. package/links/wsLink/dist/trpc-client-links-wsLink.esm.js +3 -1
  65. package/package.json +23 -34
  66. package/src/TRPCClientError.ts +38 -28
  67. package/src/createTRPCClient.ts +8 -3
  68. package/src/createTRPCClientProxy.ts +113 -0
  69. package/src/index.ts +2 -1
  70. package/src/internals/TRPCClient.ts +118 -77
  71. package/src/internals/dataLoader.ts +116 -53
  72. package/src/internals/fetchHelpers.ts +2 -2
  73. package/src/links/dedupeLink.test.ts +9 -15
  74. package/src/links/dedupeLink.ts +6 -7
  75. package/src/links/httpBatchLink.ts +73 -36
  76. package/src/links/httpLink.ts +18 -6
  77. package/src/links/index.ts +8 -0
  78. package/src/links/internals/createChain.test.ts +23 -38
  79. package/src/links/internals/createChain.ts +8 -3
  80. package/src/links/internals/httpUtils.ts +117 -0
  81. package/src/links/internals/transformResult.ts +40 -0
  82. package/src/links/loggerLink.ts +6 -7
  83. package/src/links/retryLink.ts +2 -3
  84. package/src/links/splitLink.test.ts +3 -3
  85. package/src/links/splitLink.ts +5 -5
  86. package/src/links/types.ts +15 -12
  87. package/src/links/wsLink.ts +57 -23
  88. package/dist/TRPCClientError-17b117e1.mjs +0 -81
  89. package/dist/TRPCClientError-ec6bd2ca.js +0 -94
  90. package/dist/createChain-389cc116.mjs +0 -25
  91. package/dist/createChain-864dbb30.js +0 -27
  92. package/dist/httpUtils-1f9e4e3c.js +0 -97
  93. package/dist/httpUtils-c09d7b79.mjs +0 -91
  94. package/dist/index.ts.js +0 -1
  95. package/dist/internals/transformRPCResponse.d.ts +0 -15
  96. package/dist/internals/transformRPCResponse.d.ts.map +0 -1
  97. package/dist/links/httpBatchLink.ts.js +0 -1
  98. package/dist/links/httpLink.ts.js +0 -1
  99. package/dist/links/httpUtils.d.ts +0 -22
  100. package/dist/links/httpUtils.d.ts.map +0 -1
  101. package/dist/links/internals/transformOperationResult.d.ts +0 -16
  102. package/dist/links/internals/transformOperationResult.d.ts.map +0 -1
  103. package/dist/links/loggerLink.ts.js +0 -1
  104. package/dist/links/splitLink.ts.js +0 -1
  105. package/dist/links/transformerLink.d.ts +0 -4
  106. package/dist/links/transformerLink.d.ts.map +0 -1
  107. package/dist/links/transformerLink.js +0 -75
  108. package/dist/links/transformerLink.mjs +0 -67
  109. package/dist/links/transformerLink.ts.js +0 -1
  110. package/dist/links/wsLink.ts.js +0 -1
  111. package/dist/observable-7e66cb56.mjs +0 -102
  112. package/dist/observable-85669100.js +0 -104
  113. package/dist/rx/index.d.ts +0 -3
  114. package/dist/rx/index.d.ts.map +0 -1
  115. package/dist/rx/index.js +0 -9
  116. package/dist/rx/index.mjs +0 -1
  117. package/dist/rx/index.ts.js +0 -1
  118. package/dist/rx/observable.d.ts +0 -4
  119. package/dist/rx/observable.d.ts.map +0 -1
  120. package/dist/rx/operators/index.d.ts +0 -4
  121. package/dist/rx/operators/index.d.ts.map +0 -1
  122. package/dist/rx/operators/index.js +0 -38
  123. package/dist/rx/operators/index.mjs +0 -32
  124. package/dist/rx/operators/index.ts.js +0 -1
  125. package/dist/rx/operators/map.d.ts +0 -3
  126. package/dist/rx/operators/map.d.ts.map +0 -1
  127. package/dist/rx/operators/share.d.ts +0 -6
  128. package/dist/rx/operators/share.d.ts.map +0 -1
  129. package/dist/rx/operators/tap.d.ts +0 -3
  130. package/dist/rx/operators/tap.d.ts.map +0 -1
  131. package/dist/rx/types.d.ts +0 -29
  132. package/dist/rx/types.d.ts.map +0 -1
  133. package/dist/rx/util/identity.d.ts +0 -2
  134. package/dist/rx/util/identity.d.ts.map +0 -1
  135. package/dist/rx/util/observableToPromise.d.ts +0 -10
  136. package/dist/rx/util/observableToPromise.d.ts.map +0 -1
  137. package/dist/rx/util/pipe.d.ts +0 -4
  138. package/dist/rx/util/pipe.d.ts.map +0 -1
  139. package/dist/share-4d79dc49.js +0 -110
  140. package/dist/share-671b63fa.mjs +0 -108
  141. package/dist/tap-538fa07f.mjs +0 -30
  142. package/dist/tap-799a2d33.js +0 -32
  143. package/links/transformerLink/dist/trpc-client-links-transformerLink.cjs.d.ts +0 -1
  144. package/links/transformerLink/dist/trpc-client-links-transformerLink.cjs.dev.js +0 -67
  145. package/links/transformerLink/dist/trpc-client-links-transformerLink.cjs.js +0 -7
  146. package/links/transformerLink/dist/trpc-client-links-transformerLink.cjs.prod.js +0 -67
  147. package/links/transformerLink/dist/trpc-client-links-transformerLink.esm.js +0 -63
  148. package/links/transformerLink/index.d.ts +0 -1
  149. package/links/transformerLink/index.js +0 -1
  150. package/rx/dist/trpc-client-rx.cjs.d.ts +0 -1
  151. package/rx/dist/trpc-client-rx.cjs.dev.js +0 -9
  152. package/rx/dist/trpc-client-rx.cjs.js +0 -7
  153. package/rx/dist/trpc-client-rx.cjs.prod.js +0 -9
  154. package/rx/dist/trpc-client-rx.esm.js +0 -1
  155. package/rx/index.d.ts +0 -1
  156. package/rx/index.js +0 -1
  157. package/rx/operators/dist/trpc-client-rx-operators.cjs.d.ts +0 -1
  158. package/rx/operators/dist/trpc-client-rx-operators.cjs.dev.js +0 -39
  159. package/rx/operators/dist/trpc-client-rx-operators.cjs.js +0 -7
  160. package/rx/operators/dist/trpc-client-rx-operators.cjs.prod.js +0 -39
  161. package/rx/operators/dist/trpc-client-rx-operators.esm.js +0 -33
  162. package/rx/operators/index.d.ts +0 -1
  163. package/rx/operators/index.js +0 -1
  164. package/src/internals/transformRPCResponse.ts +0 -25
  165. package/src/links/httpUtils.ts +0 -94
  166. package/src/links/internals/transformOperationResult.ts +0 -25
  167. package/src/links/transformerLink.ts +0 -70
  168. package/src/rx/index.ts +0 -2
  169. package/src/rx/observable.test.ts +0 -83
  170. package/src/rx/observable.ts +0 -70
  171. package/src/rx/operators/index.ts +0 -3
  172. package/src/rx/operators/map.test.ts +0 -92
  173. package/src/rx/operators/map.ts +0 -25
  174. package/src/rx/operators/share.test.ts +0 -60
  175. package/src/rx/operators/share.ts +0 -67
  176. package/src/rx/operators/tap.ts +0 -26
  177. package/src/rx/types.ts +0 -69
  178. package/src/rx/util/identity.ts +0 -3
  179. package/src/rx/util/observableToPromise.ts +0 -49
  180. 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,32 @@
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';
9
- import { CancelFn } from '..';
10
+ import { ProcedureRecord } from '@trpc/server';
11
+ import {
12
+ Unsubscribable,
13
+ inferObservableValue,
14
+ observableToPromise,
15
+ share,
16
+ } from '@trpc/server/observable';
17
+ import { TRPCClientError } from '../TRPCClientError';
10
18
  import { getFetch } from '../getFetch';
11
- import { httpBatchLink } from '../links/httpBatchLink';
19
+ import { httpBatchLink } from '../links';
12
20
  import { createChain } from '../links/internals/createChain';
13
- import { transformOperationResult } from '../links/internals/transformOperationResult';
14
21
  import {
15
22
  HTTPHeaders,
16
- LinkRuntime,
17
23
  OperationContext,
18
24
  OperationLink,
25
+ TRPCClientRuntime,
19
26
  TRPCLink,
20
27
  } 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
28
  import { getAbortController } from './fetchHelpers';
28
29
 
29
- type CancellablePromise<T = unknown> = Promise<T> & {
30
- cancel: CancelFn;
31
- };
32
-
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
30
  interface CreateTRPCClientBaseOptions {
45
31
  /**
46
32
  * Add ponyfill for fetch
@@ -54,6 +40,11 @@ interface CreateTRPCClientBaseOptions {
54
40
  * headers to be set on outgoing requests / callback that of said headers
55
41
  */
56
42
  headers?: HTTPHeaders | (() => HTTPHeaders | Promise<HTTPHeaders>);
43
+ /**
44
+ * Data transformer
45
+ * @link https://trpc.io/docs/data-transformers
46
+ **/
47
+ transformer?: ClientDataTransformerOptions;
57
48
  }
58
49
 
59
50
  /** @internal */
@@ -69,7 +60,7 @@ export interface CreateTRPCClientWithURLOptions
69
60
  export interface CreateTRPCClientWithLinksOptions<TRouter extends AnyRouter>
70
61
  extends CreateTRPCClientBaseOptions {
71
62
  /**
72
- * @link http://localhost:3000/docs/links
63
+ * @link https://trpc.io/docs/links
73
64
  **/
74
65
  links: TRPCLink<TRouter>[];
75
66
  }
@@ -80,31 +71,76 @@ export interface TRPCRequestOptions {
80
71
  * Pass additional context to links
81
72
  */
82
73
  context?: OperationContext;
74
+ signal?: AbortSignal;
75
+ }
76
+
77
+ export interface TRPCSubscriptionObserver<TValue, TError> {
78
+ onStarted: () => void;
79
+ onData: (value: TValue) => void;
80
+ onError: (err: TError) => void;
81
+ onStopped: () => void;
82
+ onComplete: () => void;
83
83
  }
84
84
 
85
85
  /** @internal */
86
86
  export type CreateTRPCClientOptions<TRouter extends AnyRouter> =
87
87
  | CreateTRPCClientWithLinksOptions<TRouter>
88
88
  | CreateTRPCClientWithURLOptions;
89
+
90
+ export type AssertType<T, K> = T extends K ? T : never;
91
+ /**
92
+ * @deprecated
93
+ */
94
+ export type AssertLegacyDef<TRouter extends AnyRouter> =
95
+ TRouter['_def']['legacy'] extends Record<
96
+ 'subscriptions' | 'queries' | 'mutations',
97
+ ProcedureRecord
98
+ >
99
+ ? TRouter['_def']['legacy']
100
+ : {
101
+ subscriptions: {};
102
+ queries: {};
103
+ mutations: {};
104
+ };
105
+
89
106
  export class TRPCClient<TRouter extends AnyRouter> {
90
107
  private readonly links: OperationLink<TRouter>[];
91
- public readonly runtime: LinkRuntime;
108
+ public readonly runtime: TRPCClientRuntime;
109
+ private requestId: number;
110
+ private getRequestId() {
111
+ return ++this.requestId;
112
+ }
92
113
 
93
114
  constructor(opts: CreateTRPCClientOptions<TRouter>) {
94
115
  const _fetch = getFetch(opts?.fetch);
95
116
  const AC = getAbortController(opts?.AbortController);
117
+ this.requestId = 0;
96
118
 
97
- function getHeadersFn(): LinkRuntime['headers'] {
119
+ function getHeadersFn(): TRPCClientRuntime['headers'] {
98
120
  if (opts.headers) {
99
121
  const headers = opts.headers;
100
122
  return typeof headers === 'function' ? headers : () => headers;
101
123
  }
102
124
  return () => ({});
103
125
  }
126
+
127
+ const transformer: DataTransformer = opts.transformer
128
+ ? 'input' in opts.transformer
129
+ ? {
130
+ serialize: opts.transformer.input.serialize,
131
+ deserialize: opts.transformer.output.deserialize,
132
+ }
133
+ : opts.transformer
134
+ : {
135
+ serialize: (data) => data,
136
+ deserialize: (data) => data,
137
+ };
138
+
104
139
  this.runtime = {
105
- AbortController: AC as any,
140
+ AbortController: AC,
106
141
  fetch: _fetch,
107
142
  headers: getHeadersFn(),
143
+ transformer,
108
144
  };
109
145
 
110
146
  if ('links' in opts) {
@@ -132,7 +168,7 @@ export class TRPCClient<TRouter extends AnyRouter> {
132
168
  const chain$ = createChain<TRouter, TInput, TOutput>({
133
169
  links: this.links as OperationLink<any, any, any>[],
134
170
  op: {
135
- id: getRequestId(),
171
+ id: this.getRequestId(),
136
172
  type,
137
173
  path,
138
174
  input,
@@ -146,106 +182,111 @@ export class TRPCClient<TRouter extends AnyRouter> {
146
182
  input: TInput;
147
183
  path: string;
148
184
  context?: OperationContext;
149
- }): CancellablePromise<TOutput> {
185
+ signal?: AbortSignal;
186
+ }): Promise<TOutput> {
150
187
  const req$ = this.$request<TInput, TOutput>(opts);
151
188
  type TValue = inferObservableValue<typeof req$>;
152
189
  const { promise, abort } = observableToPromise<TValue>(req$);
153
190
 
154
- const cancellablePromise: CancellablePromise<any> = new Promise<TOutput>(
155
- (resolve, reject) => {
156
- 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);
164
- })
165
- .catch((err) => {
166
- reject(TRPCClientError.from(err));
167
- });
168
- },
169
- ) as any;
170
- cancellablePromise.cancel = abort;
191
+ const abortablePromise = new Promise<TOutput>((resolve, reject) => {
192
+ opts.signal?.addEventListener('abort', abort);
193
+
194
+ promise
195
+ .then((envelope) => {
196
+ resolve((envelope.result as any).data);
197
+ })
198
+ .catch((err) => {
199
+ reject(TRPCClientError.from(err));
200
+ });
201
+ });
171
202
 
172
- return cancellablePromise;
203
+ return abortablePromise;
173
204
  }
174
205
  public query<
175
- TQueries extends TRouter['_def']['queries'],
206
+ TQueries extends AssertLegacyDef<TRouter>['queries'],
176
207
  TPath extends string & keyof TQueries,
177
208
  >(
178
209
  path: TPath,
179
- ...args: [...inferHandlerInput<TQueries[TPath]>, TRPCRequestOptions?]
210
+ ...args: [
211
+ ...inferHandlerInput<AssertType<TQueries, ProcedureRecord>[TPath]>,
212
+ TRPCRequestOptions?,
213
+ ]
180
214
  ) {
215
+ // FIXME: Should be inferred from `args`
181
216
  const context = (args[1] as TRPCRequestOptions | undefined)?.context;
217
+ const signal = (args[1] as TRPCRequestOptions | undefined)?.signal;
218
+
182
219
  return this.requestAsPromise<
183
- inferHandlerInput<TQueries[TPath]>,
220
+ inferHandlerInput<AssertType<TQueries, ProcedureRecord>[TPath]>,
184
221
  inferProcedureOutput<TQueries[TPath]>
185
222
  >({
186
223
  type: 'query',
187
224
  path,
188
225
  input: args[0] as any,
189
226
  context,
227
+ signal,
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
  ) {
240
+ // FIXME: Should be inferred from `args`
200
241
  const context = (args[1] as TRPCRequestOptions | undefined)?.context;
242
+ const signal = (args[1] as TRPCRequestOptions | undefined)?.signal;
243
+
201
244
  return this.requestAsPromise<
202
- inferHandlerInput<TMutations[TPath]>,
245
+ inferHandlerInput<AssertType<TMutations, ProcedureRecord>[TPath]>,
203
246
  inferProcedureOutput<TMutations[TPath]>
204
247
  >({
205
248
  type: 'mutation',
206
249
  path,
207
250
  input: args[0] as any,
208
251
  context,
252
+ signal,
209
253
  });
210
254
  }
211
255
  public subscription<
212
- TSubscriptions extends TRouter['_def']['subscriptions'],
256
+ TSubscriptions extends AssertLegacyDef<TRouter>['subscriptions'],
213
257
  TPath extends string & keyof TSubscriptions,
214
258
  TOutput extends inferSubscriptionOutput<TRouter, TPath>,
215
- TInput extends inferProcedureInput<TSubscriptions[TPath]>,
259
+ TInput extends inferProcedureInput<
260
+ AssertType<TSubscriptions, ProcedureRecord>[TPath]
261
+ >,
216
262
  >(
217
263
  path: TPath,
218
264
  input: TInput,
219
265
  opts: TRPCRequestOptions &
220
- Partial<Observer<TRPCResult<TOutput>, TRPCClientError<TRouter>>>,
221
- ): UnsubscribeFn {
266
+ Partial<TRPCSubscriptionObserver<TOutput, TRPCClientError<TRouter>>>,
267
+ ): Unsubscribable {
222
268
  const observable$ = this.$request<TInput, TOutput>({
223
269
  type: 'subscription',
224
270
  path,
225
271
  input,
226
- context: opts.context,
272
+ context: opts?.context,
227
273
  });
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;
274
+ return observable$.subscribe({
275
+ next(envelope) {
276
+ if (envelope.result.type === 'started') {
277
+ opts.onStarted?.();
278
+ } else if (envelope.result.type === 'stopped') {
279
+ opts.onStopped?.();
280
+ } else {
281
+ opts.onData?.((envelope.result as any).data);
237
282
  }
238
- opts.next?.(result.data.result);
239
283
  },
240
284
  error(err) {
241
- opts.error?.(err);
285
+ opts.onError?.(err);
242
286
  },
243
287
  complete() {
244
- opts.complete?.();
288
+ opts.onComplete?.();
245
289
  },
246
290
  });
247
- return () => {
248
- observer.unsubscribe();
249
- };
250
291
  }
251
292
  }