@trpc/client 10.43.0 → 11.0.0-next.91

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.
@@ -1,4 +1,9 @@
1
- import { AnyRouter, inferRouterError, ProcedureType } from '@trpc/server';
1
+ import {
2
+ AnyRouter,
3
+ inferRouterError,
4
+ MaybePromise,
5
+ ProcedureType,
6
+ } from '@trpc/server';
2
7
  import { observable, Observer, UnsubscribeFn } from '@trpc/server/observable';
3
8
  import {
4
9
  TRPCClientIncomingMessage,
@@ -12,6 +17,8 @@ import { transformResult } from '../shared/transformResult';
12
17
  import { TRPCClientError } from '../TRPCClientError';
13
18
  import { Operation, TRPCLink } from './types';
14
19
 
20
+ const run = <TResult>(fn: () => TResult): TResult => fn();
21
+
15
22
  type WSCallbackResult<TRouter extends AnyRouter, TOutput> = TRPCResponseMessage<
16
23
  TOutput,
17
24
  inferRouterError<TRouter>
@@ -22,13 +29,13 @@ type WSCallbackObserver<TRouter extends AnyRouter, TOutput> = Observer<
22
29
  TRPCClientError<TRouter>
23
30
  >;
24
31
 
25
- export interface WebSocketClientOptions {
26
- url: string | (() => string);
32
+ export type WebSocketClientOptions = {
33
+ url: string | (() => MaybePromise<string>);
27
34
  WebSocket?: typeof WebSocket;
28
35
  retryDelayMs?: typeof retryDelay;
29
36
  onOpen?: () => void;
30
37
  onClose?: (cause?: { code?: number }) => void;
31
- }
38
+ };
32
39
 
33
40
  export function createWSClient(opts: WebSocketClientOptions) {
34
41
  const {
@@ -56,7 +63,7 @@ export function createWSClient(opts: WebSocketClientOptions) {
56
63
  /**
57
64
  * Reference to the WebSocket instance this request was made to
58
65
  */
59
- ws: WebSocket;
66
+ connection: Connection | null;
60
67
  type: ProcedureType;
61
68
  callbacks: TCallbacks;
62
69
  op: Operation;
@@ -64,70 +71,84 @@ export function createWSClient(opts: WebSocketClientOptions) {
64
71
  const pendingRequests: Record<number | string, TRequest> =
65
72
  Object.create(null);
66
73
  let connectAttempt = 0;
67
- let dispatchTimer: NodeJS.Timer | number | null = null;
68
- let connectTimer: NodeJS.Timer | number | null = null;
69
- let activeConnection = createWS();
70
- let state: 'closed' | 'connecting' | 'open' = 'connecting';
74
+ let connectTimer: ReturnType<typeof setTimeout> | undefined = undefined;
75
+ let connectionIndex = 0;
76
+ let activeConnection: null | Connection = createConnection();
77
+ /**
78
+ * Global connection has been killed
79
+ */
80
+ let killed = false;
81
+
82
+ type Connection = {
83
+ id: number;
84
+ } & (
85
+ | {
86
+ state: 'open';
87
+ ws: WebSocket;
88
+ }
89
+ | {
90
+ state: 'closed';
91
+ ws: WebSocket;
92
+ }
93
+ | {
94
+ state: 'connecting';
95
+ ws?: WebSocket;
96
+ }
97
+ );
98
+
71
99
  /**
72
100
  * tries to send the list of messages
73
101
  */
74
102
  function dispatch() {
75
- if (state !== 'open' || dispatchTimer) {
76
- return;
77
- }
78
- dispatchTimer = setTimeout(() => {
79
- dispatchTimer = null;
80
-
103
+ // using a timeout to batch messages
104
+ setTimeout(() => {
105
+ if (activeConnection?.state !== 'open') {
106
+ return;
107
+ }
108
+ for (const pending of Object.values(pendingRequests)) {
109
+ if (!pending.connection) {
110
+ pending.connection = activeConnection;
111
+ }
112
+ }
81
113
  if (outgoing.length === 1) {
82
114
  // single send
83
- activeConnection.send(JSON.stringify(outgoing.pop()));
115
+ activeConnection.ws.send(JSON.stringify(outgoing.pop()));
84
116
  } else {
85
117
  // batch send
86
- activeConnection.send(JSON.stringify(outgoing));
118
+ activeConnection.ws.send(JSON.stringify(outgoing));
87
119
  }
88
120
  // clear
89
121
  outgoing = [];
90
122
  });
91
123
  }
92
124
  function tryReconnect() {
93
- if (connectTimer !== null || state === 'closed') {
125
+ if (!!connectTimer || killed) {
94
126
  return;
95
127
  }
96
128
  const timeout = retryDelayFn(connectAttempt++);
97
129
  reconnectInMs(timeout);
98
130
  }
99
131
  function reconnect() {
100
- state = 'connecting';
101
132
  const oldConnection = activeConnection;
102
- activeConnection = createWS();
103
- closeIfNoPending(oldConnection);
133
+ activeConnection = createConnection();
134
+ oldConnection && closeIfNoPending(oldConnection);
104
135
  }
105
136
  function reconnectInMs(ms: number) {
106
137
  if (connectTimer) {
107
138
  return;
108
139
  }
109
- state = 'connecting';
110
140
  connectTimer = setTimeout(reconnect, ms);
111
141
  }
112
142
 
113
- function closeIfNoPending(conn: WebSocket) {
143
+ function closeIfNoPending(conn: Connection) {
114
144
  // disconnect as soon as there are are no pending result
115
145
  const hasPendingRequests = Object.values(pendingRequests).some(
116
- (p) => p.ws === conn,
146
+ (p) => p.connection === conn,
117
147
  );
118
148
  if (!hasPendingRequests) {
119
- conn.close();
149
+ conn.ws?.close();
120
150
  }
121
151
  }
122
-
123
- function closeActiveSubscriptions() {
124
- Object.values(pendingRequests).forEach((req) => {
125
- if (req.type === 'subscription') {
126
- req.callbacks.complete();
127
- }
128
- });
129
- }
130
-
131
152
  function resumeSubscriptionOnReconnect(req: TRequest) {
132
153
  if (outgoing.some((r) => r.id === req.op.id)) {
133
154
  return;
@@ -135,115 +156,128 @@ export function createWSClient(opts: WebSocketClientOptions) {
135
156
  request(req.op, req.callbacks);
136
157
  }
137
158
 
138
- function createWS() {
139
- const urlString = typeof url === 'function' ? url() : url;
140
- const conn = new WebSocketImpl(urlString);
141
- clearTimeout(connectTimer as any);
142
- connectTimer = null;
159
+ function createConnection(): Connection {
160
+ const self: Connection = {
161
+ id: ++connectionIndex,
162
+ state: 'connecting',
163
+ } as Connection;
143
164
 
144
- conn.addEventListener('open', () => {
145
- /* istanbul ignore next -- @preserve */
146
- if (conn !== activeConnection) {
147
- return;
148
- }
149
- connectAttempt = 0;
150
- state = 'open';
151
- onOpen?.();
152
- dispatch();
153
- });
154
- conn.addEventListener('error', () => {
155
- if (conn === activeConnection) {
165
+ const onError = () => {
166
+ self.state = 'closed';
167
+ if (self === activeConnection) {
156
168
  tryReconnect();
157
169
  }
158
- });
159
- const handleIncomingRequest = (req: TRPCClientIncomingRequest) => {
160
- if (req.method === 'reconnect' && conn === activeConnection) {
161
- if (state === 'open') {
162
- onClose?.();
163
- }
164
- reconnect();
165
- // notify subscribers
166
- for (const pendingReq of Object.values(pendingRequests)) {
167
- if (pendingReq.type === 'subscription') {
168
- resumeSubscriptionOnReconnect(pendingReq);
169
- }
170
- }
171
- }
172
170
  };
173
- const handleIncomingResponse = (data: TRPCResponseMessage) => {
174
- const req = data.id !== null && pendingRequests[data.id];
175
- if (!req) {
176
- // do something?
177
- return;
178
- }
171
+ run(async () => {
172
+ const urlString = typeof url === 'function' ? await url() : url;
173
+ const ws = new WebSocketImpl(urlString);
174
+ self.ws = ws;
179
175
 
180
- req.callbacks.next?.(data);
181
- if (req.ws !== activeConnection && conn === activeConnection) {
182
- const oldWs = req.ws;
183
- // gracefully replace old connection with this
184
- req.ws = activeConnection;
185
- closeIfNoPending(oldWs);
186
- }
176
+ clearTimeout(connectTimer);
177
+ connectTimer = undefined;
187
178
 
188
- if (
189
- 'result' in data &&
190
- data.result.type === 'stopped' &&
191
- conn === activeConnection
192
- ) {
193
- req.callbacks.complete();
194
- }
195
- };
196
- conn.addEventListener('message', ({ data }) => {
197
- const msg = JSON.parse(data) as TRPCClientIncomingMessage;
179
+ ws.addEventListener('open', () => {
180
+ /* istanbul ignore next -- @preserve */
181
+ if (activeConnection?.ws !== ws) {
182
+ return;
183
+ }
184
+ connectAttempt = 0;
185
+ self.state = 'open';
198
186
 
199
- if ('method' in msg) {
200
- handleIncomingRequest(msg);
201
- } else {
202
- handleIncomingResponse(msg);
203
- }
204
- if (conn !== activeConnection || state === 'closed') {
205
- // when receiving a message, we close old connection that has no pending requests
206
- closeIfNoPending(conn);
207
- }
208
- });
187
+ onOpen?.();
188
+ dispatch();
189
+ });
190
+ ws.addEventListener('error', onError);
191
+ const handleIncomingRequest = (req: TRPCClientIncomingRequest) => {
192
+ if (self !== activeConnection) {
193
+ return;
194
+ }
195
+ if (req.method === 'reconnect') {
196
+ reconnect();
197
+ // notify subscribers
198
+ for (const pendingReq of Object.values(pendingRequests)) {
199
+ if (pendingReq.type === 'subscription') {
200
+ resumeSubscriptionOnReconnect(pendingReq);
201
+ }
202
+ }
203
+ }
204
+ };
205
+ const handleIncomingResponse = (data: TRPCResponseMessage) => {
206
+ const req = data.id !== null && pendingRequests[data.id];
207
+ if (!req) {
208
+ // do something?
209
+ return;
210
+ }
209
211
 
210
- conn.addEventListener('close', ({ code }) => {
211
- if (state === 'open') {
212
- onClose?.({ code });
213
- }
212
+ req.callbacks.next?.(data);
213
+ if (self === activeConnection && req.connection !== activeConnection) {
214
+ // gracefully replace old connection with this
215
+ const oldConn = req.connection;
216
+ req.connection = self;
217
+ oldConn && closeIfNoPending(oldConn);
218
+ }
214
219
 
215
- if (activeConnection === conn) {
216
- // connection might have been replaced already
217
- tryReconnect();
218
- }
220
+ if (
221
+ 'result' in data &&
222
+ data.result.type === 'stopped' &&
223
+ activeConnection === self
224
+ ) {
225
+ req.callbacks.complete();
226
+ }
227
+ };
228
+ ws.addEventListener('message', ({ data }) => {
229
+ const msg = JSON.parse(data) as TRPCClientIncomingMessage;
219
230
 
220
- for (const [key, req] of Object.entries(pendingRequests)) {
221
- if (req.ws !== conn) {
222
- continue;
231
+ if ('method' in msg) {
232
+ handleIncomingRequest(msg);
233
+ } else {
234
+ handleIncomingResponse(msg);
223
235
  }
236
+ if (self !== activeConnection) {
237
+ // when receiving a message, we close old connection that has no pending requests
238
+ closeIfNoPending(self);
239
+ }
240
+ });
224
241
 
225
- if (state === 'closed') {
226
- // If the connection was closed, we just call `complete()` on the request
227
- delete pendingRequests[key];
228
- req.callbacks.complete?.();
229
- continue;
242
+ ws.addEventListener('close', ({ code }) => {
243
+ if (self.state === 'open') {
244
+ onClose?.({ code });
230
245
  }
231
- // The connection was closed either unexpectedly or because of a reconnect
232
- if (req.type === 'subscription') {
233
- // Subscriptions will resume after we've reconnected
234
- resumeSubscriptionOnReconnect(req);
235
- } else {
236
- // Queries and mutations will error if interrupted
237
- delete pendingRequests[key];
238
- req.callbacks.error?.(
239
- TRPCClientError.from(
240
- new TRPCWebSocketClosedError('WebSocket closed prematurely'),
241
- ),
242
- );
246
+ self.state = 'closed';
247
+
248
+ if (activeConnection === self) {
249
+ // connection might have been replaced already
250
+ tryReconnect();
243
251
  }
244
- }
245
- });
246
- return conn;
252
+
253
+ for (const [key, req] of Object.entries(pendingRequests)) {
254
+ if (req.connection !== self) {
255
+ continue;
256
+ }
257
+
258
+ if (self.state === 'closed') {
259
+ // If the connection was closed, we just call `complete()` on the request
260
+ delete pendingRequests[key];
261
+ req.callbacks.complete?.();
262
+ continue;
263
+ }
264
+ // The connection was closed either unexpectedly or because of a reconnect
265
+ if (req.type === 'subscription') {
266
+ // Subscriptions will resume after we've reconnected
267
+ resumeSubscriptionOnReconnect(req);
268
+ } else {
269
+ // Queries and mutations will error if interrupted
270
+ delete pendingRequests[key];
271
+ req.callbacks.error?.(
272
+ TRPCClientError.from(
273
+ new TRPCWebSocketClosedError('WebSocket closed prematurely'),
274
+ ),
275
+ );
276
+ }
277
+ }
278
+ });
279
+ }).catch(onError);
280
+ return self;
247
281
  }
248
282
 
249
283
  function request(op: Operation, callbacks: TCallbacks): UnsubscribeFn {
@@ -257,7 +291,7 @@ export function createWSClient(opts: WebSocketClientOptions) {
257
291
  },
258
292
  };
259
293
  pendingRequests[id] = {
260
- ws: activeConnection,
294
+ connection: null,
261
295
  type,
262
296
  callbacks,
263
297
  op,
@@ -273,10 +307,7 @@ export function createWSClient(opts: WebSocketClientOptions) {
273
307
  outgoing = outgoing.filter((msg) => msg.id !== id);
274
308
 
275
309
  callbacks?.complete?.();
276
- if (
277
- activeConnection.readyState === WebSocketImpl.OPEN &&
278
- op.type === 'subscription'
279
- ) {
310
+ if (activeConnection?.state === 'open' && op.type === 'subscription') {
280
311
  outgoing.push({
281
312
  id,
282
313
  method: 'subscription.stop',
@@ -287,12 +318,24 @@ export function createWSClient(opts: WebSocketClientOptions) {
287
318
  }
288
319
  return {
289
320
  close: () => {
290
- state = 'closed';
291
- onClose?.();
292
- closeActiveSubscriptions();
293
- closeIfNoPending(activeConnection);
294
- clearTimeout(connectTimer as any);
295
- connectTimer = null;
321
+ killed = true;
322
+
323
+ for (const req of Object.values(pendingRequests)) {
324
+ if (req.type === 'subscription') {
325
+ req.callbacks.complete();
326
+ } else if (!req.connection) {
327
+ // close pending requests that aren't attached to a connection yet
328
+ req.callbacks.error(
329
+ TRPCClientError.from(
330
+ new Error('Closed before connection was established'),
331
+ ),
332
+ );
333
+ }
334
+ }
335
+ activeConnection && closeIfNoPending(activeConnection);
336
+ clearTimeout(connectTimer);
337
+
338
+ connectTimer = undefined;
296
339
  },
297
340
  request,
298
341
  getConnection() {
@@ -1,49 +0,0 @@
1
- import type { AnyMutationProcedure, AnyProcedure, AnyQueryProcedure, AnyRouter, AnySubscriptionProcedure, IntersectionError, ProcedureArgs, ProcedureRouterRecord, ProcedureType } from '@trpc/server';
2
- import type { Unsubscribable } from '@trpc/server/observable';
3
- import { inferTransformedProcedureOutput, inferTransformedSubscriptionOutput } from '@trpc/server/shared';
4
- import { TRPCClient } from './createTRPCClient';
5
- import { CreateTRPCClientOptions } from './createTRPCUntypedClient';
6
- import { TRPCSubscriptionObserver, TRPCUntypedClient, UntypedClientProperties } from './internals/TRPCUntypedClient';
7
- import { TRPCClientError } from './TRPCClientError';
8
- /**
9
- * @public
10
- **/
11
- export type inferRouterProxyClient<TRouter extends AnyRouter> = DecoratedProcedureRecord<TRouter, TRouter['_def']['record']>;
12
- /** @internal */
13
- export type Resolver<TProcedure extends AnyProcedure> = (...args: ProcedureArgs<TProcedure['_def']>) => Promise<inferTransformedProcedureOutput<TProcedure>>;
14
- type SubscriptionResolver<TProcedure extends AnyProcedure> = (...args: [
15
- input: ProcedureArgs<TProcedure['_def']>[0],
16
- opts: Partial<TRPCSubscriptionObserver<inferTransformedSubscriptionOutput<TProcedure>, TRPCClientError<TProcedure>>> & ProcedureArgs<TProcedure['_def']>[1]
17
- ]) => Unsubscribable;
18
- type DecorateProcedure<TProcedure extends AnyProcedure> = TProcedure extends AnyQueryProcedure ? {
19
- query: Resolver<TProcedure>;
20
- } : TProcedure extends AnyMutationProcedure ? {
21
- mutate: Resolver<TProcedure>;
22
- } : TProcedure extends AnySubscriptionProcedure ? {
23
- subscribe: SubscriptionResolver<TProcedure>;
24
- } : never;
25
- /**
26
- * @internal
27
- */
28
- type DecoratedProcedureRecord<TRouter extends AnyRouter, TProcedures extends ProcedureRouterRecord> = {
29
- [TKey in keyof TProcedures]: TProcedures[TKey] extends AnyRouter ? DecoratedProcedureRecord<TRouter, TProcedures[TKey]['_def']['record']> : TProcedures[TKey] extends AnyProcedure ? DecorateProcedure<TProcedures[TKey]> : never;
30
- };
31
- /** @internal */
32
- export declare const clientCallTypeToProcedureType: (clientCallType: string) => ProcedureType;
33
- /**
34
- * Creates a proxy client and shows type errors if you have query names that collide with built-in properties
35
- */
36
- export type CreateTRPCProxyClient<TRouter extends AnyRouter> = inferRouterProxyClient<TRouter> extends infer $ProcedureRecord ? UntypedClientProperties & keyof $ProcedureRecord extends never ? inferRouterProxyClient<TRouter> : IntersectionError<UntypedClientProperties & keyof $ProcedureRecord> : never;
37
- /**
38
- * @deprecated use `createTRPCProxyClient` instead
39
- * @internal
40
- */
41
- export declare function createTRPCClientProxy<TRouter extends AnyRouter>(client: TRPCClient<TRouter>): CreateTRPCProxyClient<TRouter>;
42
- export declare function createTRPCProxyClient<TRouter extends AnyRouter>(opts: CreateTRPCClientOptions<TRouter>): CreateTRPCProxyClient<TRouter>;
43
- /**
44
- * Get an untyped client from a proxy client
45
- * @internal
46
- */
47
- export declare function getUntypedClient<TRouter extends AnyRouter>(client: inferRouterProxyClient<TRouter>): TRPCUntypedClient<TRouter>;
48
- export {};
49
- //# sourceMappingURL=createTRPCClientProxy.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createTRPCClientProxy.d.ts","sourceRoot":"","sources":["../src/createTRPCClientProxy.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- export * from '../../dist/links/formDataLink';
@@ -1 +0,0 @@
1
- module.exports = require('../../dist/links/formDataLink');
@@ -1 +0,0 @@
1
- export * from '../../dist/links/httpTuplesonLink';
@@ -1 +0,0 @@
1
- module.exports = require('../../dist/links/httpTuplesonLink');
@@ -1,146 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
- import type {
3
- AnyMutationProcedure,
4
- AnyProcedure,
5
- AnyQueryProcedure,
6
- AnyRouter,
7
- AnySubscriptionProcedure,
8
- IntersectionError,
9
- ProcedureArgs,
10
- ProcedureRouterRecord,
11
- ProcedureType,
12
- } from '@trpc/server';
13
- import type { Unsubscribable } from '@trpc/server/observable';
14
- import {
15
- createFlatProxy,
16
- createRecursiveProxy,
17
- inferTransformedProcedureOutput,
18
- inferTransformedSubscriptionOutput,
19
- } from '@trpc/server/shared';
20
- import { TRPCClient } from './createTRPCClient';
21
- import { CreateTRPCClientOptions } from './createTRPCUntypedClient';
22
- import {
23
- TRPCSubscriptionObserver,
24
- TRPCUntypedClient,
25
- UntypedClientProperties,
26
- } from './internals/TRPCUntypedClient';
27
- import { TRPCClientError } from './TRPCClientError';
28
-
29
- /**
30
- * @public
31
- **/
32
- export type inferRouterProxyClient<TRouter extends AnyRouter> =
33
- DecoratedProcedureRecord<TRouter, TRouter['_def']['record']>;
34
-
35
- /** @internal */
36
- export type Resolver<TProcedure extends AnyProcedure> = (
37
- ...args: ProcedureArgs<TProcedure['_def']>
38
- ) => Promise<inferTransformedProcedureOutput<TProcedure>>;
39
-
40
- type SubscriptionResolver<TProcedure extends AnyProcedure> = (
41
- ...args: [
42
- input: ProcedureArgs<TProcedure['_def']>[0],
43
- opts: Partial<
44
- TRPCSubscriptionObserver<
45
- inferTransformedSubscriptionOutput<TProcedure>,
46
- TRPCClientError<TProcedure>
47
- >
48
- > &
49
- ProcedureArgs<TProcedure['_def']>[1],
50
- ]
51
- ) => Unsubscribable;
52
-
53
- type DecorateProcedure<TProcedure extends AnyProcedure> =
54
- TProcedure extends AnyQueryProcedure
55
- ? {
56
- query: Resolver<TProcedure>;
57
- }
58
- : TProcedure extends AnyMutationProcedure
59
- ? {
60
- mutate: Resolver<TProcedure>;
61
- }
62
- : TProcedure extends AnySubscriptionProcedure
63
- ? {
64
- subscribe: SubscriptionResolver<TProcedure>;
65
- }
66
- : never;
67
-
68
- /**
69
- * @internal
70
- */
71
- type DecoratedProcedureRecord<
72
- TRouter extends AnyRouter,
73
- TProcedures extends ProcedureRouterRecord,
74
- > = {
75
- [TKey in keyof TProcedures]: TProcedures[TKey] extends AnyRouter
76
- ? DecoratedProcedureRecord<TRouter, TProcedures[TKey]['_def']['record']>
77
- : TProcedures[TKey] extends AnyProcedure
78
- ? DecorateProcedure<TProcedures[TKey]>
79
- : never;
80
- };
81
-
82
- const clientCallTypeMap: Record<keyof DecorateProcedure<any>, ProcedureType> = {
83
- query: 'query',
84
- mutate: 'mutation',
85
- subscribe: 'subscription',
86
- };
87
-
88
- /** @internal */
89
- export const clientCallTypeToProcedureType = (
90
- clientCallType: string,
91
- ): ProcedureType => {
92
- return clientCallTypeMap[clientCallType as keyof typeof clientCallTypeMap];
93
- };
94
-
95
- /**
96
- * Creates a proxy client and shows type errors if you have query names that collide with built-in properties
97
- */
98
- export type CreateTRPCProxyClient<TRouter extends AnyRouter> =
99
- inferRouterProxyClient<TRouter> extends infer $ProcedureRecord
100
- ? UntypedClientProperties & keyof $ProcedureRecord extends never
101
- ? inferRouterProxyClient<TRouter>
102
- : IntersectionError<UntypedClientProperties & keyof $ProcedureRecord>
103
- : never;
104
-
105
- /**
106
- * @deprecated use `createTRPCProxyClient` instead
107
- * @internal
108
- */
109
- export function createTRPCClientProxy<TRouter extends AnyRouter>(
110
- client: TRPCClient<TRouter>,
111
- ): CreateTRPCProxyClient<TRouter> {
112
- return createFlatProxy<CreateTRPCProxyClient<TRouter>>((key) => {
113
- if (client.hasOwnProperty(key)) {
114
- return (client as any)[key as any];
115
- }
116
- if (key === '__untypedClient') {
117
- return client;
118
- }
119
- return createRecursiveProxy(({ path, args }) => {
120
- const pathCopy = [key, ...path];
121
- const procedureType = clientCallTypeToProcedureType(pathCopy.pop()!);
122
-
123
- const fullPath = pathCopy.join('.');
124
-
125
- return (client as any)[procedureType](fullPath, ...args);
126
- });
127
- });
128
- }
129
-
130
- export function createTRPCProxyClient<TRouter extends AnyRouter>(
131
- opts: CreateTRPCClientOptions<TRouter>,
132
- ): CreateTRPCProxyClient<TRouter> {
133
- const client = new TRPCUntypedClient(opts);
134
- const proxy = createTRPCClientProxy(client as TRPCClient<TRouter>);
135
- return proxy;
136
- }
137
-
138
- /**
139
- * Get an untyped client from a proxy client
140
- * @internal
141
- */
142
- export function getUntypedClient<TRouter extends AnyRouter>(
143
- client: inferRouterProxyClient<TRouter>,
144
- ): TRPCUntypedClient<TRouter> {
145
- return (client as any).__untypedClient;
146
- }