@trpc/client 11.0.0-next.92 → 11.0.0-rc.330

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 (159) hide show
  1. package/README.md +4 -4
  2. package/dist/TRPCClientError.d.ts +8 -7
  3. package/dist/TRPCClientError.d.ts.map +1 -1
  4. package/dist/{TRPCClientError-e224e397.js → TRPCClientError.js} +3 -3
  5. package/dist/{TRPCClientError-0de4d231.mjs → TRPCClientError.mjs} +4 -4
  6. package/dist/bundle-analysis.json +126 -155
  7. package/dist/createTRPCClient.d.ts +27 -19
  8. package/dist/createTRPCClient.d.ts.map +1 -1
  9. package/dist/createTRPCClient.js +50 -0
  10. package/dist/createTRPCClient.mjs +45 -0
  11. package/dist/createTRPCUntypedClient.d.ts +3 -2
  12. package/dist/createTRPCUntypedClient.d.ts.map +1 -1
  13. package/dist/createTRPCUntypedClient.js +10 -0
  14. package/dist/createTRPCUntypedClient.mjs +7 -0
  15. package/dist/getFetch.d.ts +1 -1
  16. package/dist/getFetch.d.ts.map +1 -1
  17. package/dist/getFetch.js +17 -0
  18. package/dist/getFetch.mjs +15 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +32 -370
  21. package/dist/index.mjs +9 -354
  22. package/dist/internals/TRPCUntypedClient.d.ts +5 -30
  23. package/dist/internals/TRPCUntypedClient.d.ts.map +1 -1
  24. package/dist/internals/TRPCUntypedClient.js +85 -0
  25. package/dist/internals/TRPCUntypedClient.mjs +83 -0
  26. package/dist/internals/dataLoader.d.ts +1 -1
  27. package/dist/internals/dataLoader.d.ts.map +1 -1
  28. package/dist/{httpBatchLink-204206a5.mjs → internals/dataLoader.js} +2 -117
  29. package/dist/internals/dataLoader.mjs +131 -0
  30. package/dist/internals/getAbortController.d.ts +2 -2
  31. package/dist/internals/getAbortController.d.ts.map +1 -1
  32. package/dist/internals/getAbortController.js +18 -0
  33. package/dist/internals/getAbortController.mjs +16 -0
  34. package/dist/internals/transformer.d.ts +42 -0
  35. package/dist/internals/transformer.d.ts.map +1 -0
  36. package/dist/internals/transformer.js +30 -0
  37. package/dist/internals/transformer.mjs +28 -0
  38. package/dist/internals/types.d.ts +4 -2
  39. package/dist/internals/types.d.ts.map +1 -1
  40. package/dist/links/HTTPBatchLinkOptions.d.ts +6 -5
  41. package/dist/links/HTTPBatchLinkOptions.d.ts.map +1 -1
  42. package/dist/links/httpBatchLink.d.ts +2 -2
  43. package/dist/links/httpBatchLink.d.ts.map +1 -1
  44. package/dist/links/httpBatchLink.js +37 -9
  45. package/dist/links/httpBatchLink.mjs +39 -5
  46. package/dist/links/httpBatchStreamLink.d.ts +6 -5
  47. package/dist/links/httpBatchStreamLink.d.ts.map +1 -1
  48. package/dist/links/httpBatchStreamLink.js +43 -0
  49. package/dist/links/httpBatchStreamLink.mjs +41 -0
  50. package/dist/links/httpFormDataLink.d.ts +1 -1
  51. package/dist/links/httpFormDataLink.d.ts.map +1 -1
  52. package/dist/links/httpFormDataLink.js +31 -0
  53. package/dist/links/httpFormDataLink.mjs +29 -0
  54. package/dist/links/httpLink.d.ts +8 -8
  55. package/dist/links/httpLink.d.ts.map +1 -1
  56. package/dist/links/httpLink.js +6 -9
  57. package/dist/links/httpLink.mjs +6 -7
  58. package/dist/links/internals/createChain.d.ts +2 -2
  59. package/dist/links/internals/createChain.d.ts.map +1 -1
  60. package/dist/{splitLink-f29e84be.js → links/internals/createChain.js} +0 -22
  61. package/dist/{splitLink-4c75f7be.mjs → links/internals/createChain.mjs} +1 -22
  62. package/dist/links/internals/createHTTPBatchLink.d.ts +6 -6
  63. package/dist/links/internals/createHTTPBatchLink.d.ts.map +1 -1
  64. package/dist/links/internals/createHTTPBatchLink.js +85 -0
  65. package/dist/links/internals/createHTTPBatchLink.mjs +83 -0
  66. package/dist/links/internals/dedupeLink.d.ts +2 -2
  67. package/dist/links/internals/dedupeLink.d.ts.map +1 -1
  68. package/dist/links/internals/getTextDecoder.d.ts +1 -1
  69. package/dist/links/internals/getTextDecoder.d.ts.map +1 -1
  70. package/dist/links/internals/getTextDecoder.js +18 -0
  71. package/dist/links/internals/getTextDecoder.mjs +16 -0
  72. package/dist/links/internals/httpUtils.d.ts +19 -11
  73. package/dist/links/internals/httpUtils.d.ts.map +1 -1
  74. package/dist/{httpUtils-c0e7bf5a.js → links/internals/httpUtils.js} +20 -39
  75. package/dist/{httpUtils-f58ceda1.mjs → links/internals/httpUtils.mjs} +20 -38
  76. package/dist/links/internals/parseJSONStream.d.ts +5 -6
  77. package/dist/links/internals/parseJSONStream.d.ts.map +1 -1
  78. package/dist/links/internals/parseJSONStream.js +118 -0
  79. package/dist/links/internals/parseJSONStream.mjs +115 -0
  80. package/dist/links/internals/retryLink.d.ts +2 -2
  81. package/dist/links/internals/retryLink.d.ts.map +1 -1
  82. package/dist/links/loggerLink.d.ts +4 -4
  83. package/dist/links/loggerLink.d.ts.map +1 -1
  84. package/dist/links/loggerLink.js +6 -4
  85. package/dist/links/loggerLink.mjs +6 -2
  86. package/dist/links/splitLink.d.ts +2 -2
  87. package/dist/links/splitLink.d.ts.map +1 -1
  88. package/dist/links/splitLink.js +23 -6
  89. package/dist/links/splitLink.mjs +25 -2
  90. package/dist/links/types.d.ts +15 -14
  91. package/dist/links/types.d.ts.map +1 -1
  92. package/dist/links/wsLink.d.ts +44 -13
  93. package/dist/links/wsLink.d.ts.map +1 -1
  94. package/dist/links/wsLink.js +64 -24
  95. package/dist/links/wsLink.mjs +64 -22
  96. package/dist/links.d.ts +10 -0
  97. package/dist/links.d.ts.map +1 -0
  98. package/dist/unstable-internals.d.ts +2 -0
  99. package/dist/unstable-internals.d.ts.map +1 -0
  100. package/dist/unstable-internals.js +7 -0
  101. package/dist/unstable-internals.mjs +1 -0
  102. package/package.json +26 -28
  103. package/src/TRPCClientError.ts +24 -13
  104. package/src/createTRPCClient.ts +58 -51
  105. package/src/createTRPCUntypedClient.ts +3 -5
  106. package/src/getFetch.ts +1 -1
  107. package/src/index.ts +2 -0
  108. package/src/internals/TRPCUntypedClient.ts +14 -84
  109. package/src/internals/dataLoader.ts +1 -1
  110. package/src/internals/getAbortController.ts +2 -2
  111. package/src/internals/transformer.ts +76 -0
  112. package/src/internals/types.ts +8 -1
  113. package/src/links/HTTPBatchLinkOptions.ts +17 -15
  114. package/src/links/httpBatchLink.ts +9 -8
  115. package/src/links/httpBatchStreamLink.ts +17 -17
  116. package/src/links/httpFormDataLink.ts +11 -12
  117. package/src/links/httpLink.ts +27 -19
  118. package/src/links/internals/createChain.ts +6 -2
  119. package/src/links/internals/createHTTPBatchLink.ts +24 -16
  120. package/src/links/internals/dedupeLink.ts +4 -3
  121. package/src/links/internals/getTextDecoder.ts +1 -1
  122. package/src/links/internals/httpUtils.ts +42 -21
  123. package/src/links/internals/parseJSONStream.ts +12 -14
  124. package/src/links/internals/retryLink.ts +4 -3
  125. package/src/links/loggerLink.ts +5 -5
  126. package/src/links/splitLink.ts +2 -2
  127. package/src/links/types.ts +27 -22
  128. package/src/links/wsLink.ts +124 -36
  129. package/src/links.ts +14 -0
  130. package/src/unstable-internals.ts +1 -0
  131. package/unstable-internals/index.d.ts +1 -0
  132. package/unstable-internals/index.js +1 -0
  133. package/dist/TRPCClientError-23c8aa93.js +0 -61
  134. package/dist/httpBatchLink-64fceaac.js +0 -251
  135. package/dist/httpBatchLink-92dab48e.js +0 -247
  136. package/dist/httpUtils-35e50476.js +0 -145
  137. package/dist/internals/isObject.d.ts +0 -2
  138. package/dist/internals/isObject.d.ts.map +0 -1
  139. package/dist/internals/retryDelay.d.ts +0 -2
  140. package/dist/internals/retryDelay.d.ts.map +0 -1
  141. package/dist/links/index.d.ts +0 -10
  142. package/dist/links/index.d.ts.map +0 -1
  143. package/dist/shared/index.d.ts +0 -2
  144. package/dist/shared/index.d.ts.map +0 -1
  145. package/dist/shared/index.js +0 -9
  146. package/dist/shared/index.mjs +0 -1
  147. package/dist/shared/transformResult.d.ts +0 -34
  148. package/dist/shared/transformResult.d.ts.map +0 -1
  149. package/dist/splitLink-0df96fdc.js +0 -41
  150. package/dist/transformResult-ace864b8.mjs +0 -58
  151. package/dist/transformResult-c1422cb5.js +0 -60
  152. package/dist/transformResult-dfce8f15.js +0 -61
  153. package/shared/index.d.ts +0 -1
  154. package/shared/index.js +0 -1
  155. package/src/internals/isObject.ts +0 -4
  156. package/src/internals/retryDelay.ts +0 -3
  157. package/src/links/index.ts +0 -14
  158. package/src/shared/index.ts +0 -1
  159. package/src/shared/transformResult.ts +0 -79
@@ -1,21 +1,22 @@
1
- import {
1
+ import type { Observer, UnsubscribeFn } from '@trpc/server/observable';
2
+ import { observable } from '@trpc/server/observable';
3
+ import type {
2
4
  AnyRouter,
5
+ inferClientTypes,
3
6
  inferRouterError,
4
7
  MaybePromise,
5
8
  ProcedureType,
6
- } from '@trpc/server';
7
- import { observable, Observer, UnsubscribeFn } from '@trpc/server/observable';
8
- import {
9
9
  TRPCClientIncomingMessage,
10
10
  TRPCClientIncomingRequest,
11
11
  TRPCClientOutgoingMessage,
12
12
  TRPCRequestMessage,
13
13
  TRPCResponseMessage,
14
- } from '@trpc/server/rpc';
15
- import { retryDelay } from '../internals/retryDelay';
16
- import { transformResult } from '../shared/transformResult';
14
+ } from '@trpc/server/unstable-core-do-not-import';
15
+ import { transformResult } from '@trpc/server/unstable-core-do-not-import';
17
16
  import { TRPCClientError } from '../TRPCClientError';
18
- import { Operation, TRPCLink } from './types';
17
+ import type { TransformerOptions } from '../unstable-internals';
18
+ import { getTransformer } from '../unstable-internals';
19
+ import type { Operation, TRPCLink } from './types';
19
20
 
20
21
  const run = <TResult>(fn: () => TResult): TResult => fn();
21
22
 
@@ -29,22 +30,66 @@ type WSCallbackObserver<TRouter extends AnyRouter, TOutput> = Observer<
29
30
  TRPCClientError<TRouter>
30
31
  >;
31
32
 
32
- export type WebSocketClientOptions = {
33
+ const exponentialBackoff = (attemptIndex: number) =>
34
+ attemptIndex === 0 ? 0 : Math.min(1000 * 2 ** attemptIndex, 30000);
35
+
36
+ export interface WebSocketClientOptions {
37
+ /**
38
+ * The URL to connect to (can be a function that returns a URL)
39
+ */
33
40
  url: string | (() => MaybePromise<string>);
41
+ /**
42
+ * Ponyfill which WebSocket implementation to use
43
+ */
34
44
  WebSocket?: typeof WebSocket;
35
- retryDelayMs?: typeof retryDelay;
45
+ /**
46
+ * The number of milliseconds before a reconnect is attempted.
47
+ * @default {@link exponentialBackoff}
48
+ */
49
+ retryDelayMs?: typeof exponentialBackoff;
50
+ /**
51
+ * Triggered when a WebSocket connection is established
52
+ */
36
53
  onOpen?: () => void;
54
+ /**
55
+ * Triggered when a WebSocket connection is closed
56
+ */
37
57
  onClose?: (cause?: { code?: number }) => void;
38
- };
58
+ /**
59
+ * Lazy mode will close the WebSocket automatically after a period of inactivity (no messages sent or received and no pending requests)
60
+ */
61
+ lazy?: {
62
+ /**
63
+ * Enable lazy mode
64
+ * @default false
65
+ */
66
+ enabled: boolean;
67
+ /**
68
+ * Close the WebSocket after this many milliseconds
69
+ * @default 0
70
+ */
71
+ closeMs: number;
72
+ };
73
+ }
39
74
 
75
+ type LazyOptions = Required<NonNullable<WebSocketClientOptions['lazy']>>;
76
+ const lazyDefaults: LazyOptions = {
77
+ enabled: false,
78
+ closeMs: 0,
79
+ };
40
80
  export function createWSClient(opts: WebSocketClientOptions) {
41
81
  const {
42
82
  url,
43
83
  WebSocket: WebSocketImpl = WebSocket,
44
- retryDelayMs: retryDelayFn = retryDelay,
84
+ retryDelayMs: retryDelayFn = exponentialBackoff,
45
85
  onOpen,
46
86
  onClose,
47
87
  } = opts;
88
+ const lazyOpts: LazyOptions = {
89
+ ...lazyDefaults,
90
+ ...opts.lazy,
91
+ };
92
+
48
93
  /* istanbul ignore next -- @preserve */
49
94
  if (!WebSocketImpl) {
50
95
  throw new Error(
@@ -73,11 +118,11 @@ export function createWSClient(opts: WebSocketClientOptions) {
73
118
  let connectAttempt = 0;
74
119
  let connectTimer: ReturnType<typeof setTimeout> | undefined = undefined;
75
120
  let connectionIndex = 0;
76
- let activeConnection: null | Connection = createConnection();
77
- /**
78
- * Global connection has been killed
79
- */
80
- let killed = false;
121
+ let lazyDisconnectTimer: ReturnType<typeof setTimeout> | undefined =
122
+ undefined;
123
+ let activeConnection: null | Connection = lazyOpts.enabled
124
+ ? null
125
+ : createConnection();
81
126
 
82
127
  type Connection = {
83
128
  id: number;
@@ -100,6 +145,10 @@ export function createWSClient(opts: WebSocketClientOptions) {
100
145
  * tries to send the list of messages
101
146
  */
102
147
  function dispatch() {
148
+ if (!activeConnection) {
149
+ activeConnection = createConnection();
150
+ return;
151
+ }
103
152
  // using a timeout to batch messages
104
153
  setTimeout(() => {
105
154
  if (activeConnection?.state !== 'open') {
@@ -119,16 +168,32 @@ export function createWSClient(opts: WebSocketClientOptions) {
119
168
  }
120
169
  // clear
121
170
  outgoing = [];
171
+
172
+ startLazyDisconnectTimer();
122
173
  });
123
174
  }
124
- function tryReconnect() {
125
- if (!!connectTimer || killed) {
175
+ function tryReconnect(conn: Connection) {
176
+ if (!!connectTimer) {
126
177
  return;
127
178
  }
179
+
180
+ conn.state = 'connecting';
128
181
  const timeout = retryDelayFn(connectAttempt++);
129
182
  reconnectInMs(timeout);
130
183
  }
184
+ function hasPendingRequests(conn?: Connection) {
185
+ const requests = Object.values(pendingRequests);
186
+ if (!conn) {
187
+ return requests.length > 0;
188
+ }
189
+ return requests.some((req) => req.connection === conn);
190
+ }
191
+
131
192
  function reconnect() {
193
+ if (lazyOpts.enabled && !hasPendingRequests()) {
194
+ // Skip reconnecting if there are pending requests and we're in lazy mode
195
+ return;
196
+ }
132
197
  const oldConnection = activeConnection;
133
198
  activeConnection = createConnection();
134
199
  oldConnection && closeIfNoPending(oldConnection);
@@ -141,11 +206,8 @@ export function createWSClient(opts: WebSocketClientOptions) {
141
206
  }
142
207
 
143
208
  function closeIfNoPending(conn: Connection) {
144
- // disconnect as soon as there are are no pending result
145
- const hasPendingRequests = Object.values(pendingRequests).some(
146
- (p) => p.connection === conn,
147
- );
148
- if (!hasPendingRequests) {
209
+ // disconnect as soon as there are are no pending requests
210
+ if (!hasPendingRequests(conn)) {
149
211
  conn.ws?.close();
150
212
  }
151
213
  }
@@ -156,16 +218,36 @@ export function createWSClient(opts: WebSocketClientOptions) {
156
218
  request(req.op, req.callbacks);
157
219
  }
158
220
 
221
+ const startLazyDisconnectTimer = () => {
222
+ if (!lazyOpts.enabled) {
223
+ return;
224
+ }
225
+
226
+ clearTimeout(lazyDisconnectTimer);
227
+ lazyDisconnectTimer = setTimeout(() => {
228
+ if (!activeConnection) {
229
+ return;
230
+ }
231
+
232
+ if (!hasPendingRequests(activeConnection)) {
233
+ activeConnection.ws?.close();
234
+ activeConnection = null;
235
+ }
236
+ }, lazyOpts.closeMs);
237
+ };
238
+
159
239
  function createConnection(): Connection {
160
240
  const self: Connection = {
161
241
  id: ++connectionIndex,
162
242
  state: 'connecting',
163
243
  } as Connection;
164
244
 
245
+ clearTimeout(lazyDisconnectTimer);
246
+
165
247
  const onError = () => {
166
248
  self.state = 'closed';
167
249
  if (self === activeConnection) {
168
- tryReconnect();
250
+ tryReconnect(self);
169
251
  }
170
252
  };
171
253
  run(async () => {
@@ -192,6 +274,7 @@ export function createWSClient(opts: WebSocketClientOptions) {
192
274
  if (self !== activeConnection) {
193
275
  return;
194
276
  }
277
+
195
278
  if (req.method === 'reconnect') {
196
279
  reconnect();
197
280
  // notify subscribers
@@ -226,6 +309,8 @@ export function createWSClient(opts: WebSocketClientOptions) {
226
309
  }
227
310
  };
228
311
  ws.addEventListener('message', ({ data }) => {
312
+ startLazyDisconnectTimer();
313
+
229
314
  const msg = JSON.parse(data) as TRPCClientIncomingMessage;
230
315
 
231
316
  if ('method' in msg) {
@@ -247,7 +332,7 @@ export function createWSClient(opts: WebSocketClientOptions) {
247
332
 
248
333
  if (activeConnection === self) {
249
334
  // connection might have been replaced already
250
- tryReconnect();
335
+ tryReconnect(self);
251
336
  }
252
337
 
253
338
  for (const [key, req] of Object.entries(pendingRequests)) {
@@ -299,6 +384,7 @@ export function createWSClient(opts: WebSocketClientOptions) {
299
384
 
300
385
  // enqueue message
301
386
  outgoing.push(envelope);
387
+
302
388
  dispatch();
303
389
 
304
390
  return () => {
@@ -314,11 +400,12 @@ export function createWSClient(opts: WebSocketClientOptions) {
314
400
  });
315
401
  dispatch();
316
402
  }
403
+ startLazyDisconnectTimer();
317
404
  };
318
405
  }
319
406
  return {
320
407
  close: () => {
321
- killed = true;
408
+ connectAttempt = 0;
322
409
 
323
410
  for (const req of Object.values(pendingRequests)) {
324
411
  if (req.type === 'subscription') {
@@ -334,20 +421,20 @@ export function createWSClient(opts: WebSocketClientOptions) {
334
421
  }
335
422
  activeConnection && closeIfNoPending(activeConnection);
336
423
  clearTimeout(connectTimer);
337
-
338
424
  connectTimer = undefined;
425
+ activeConnection = null;
339
426
  },
340
427
  request,
341
- getConnection() {
428
+ get connection() {
342
429
  return activeConnection;
343
430
  },
344
431
  };
345
432
  }
346
433
  export type TRPCWebSocketClient = ReturnType<typeof createWSClient>;
347
434
 
348
- export interface WebSocketLinkOptions {
435
+ export type WebSocketLinkOptions<TRouter extends AnyRouter> = {
349
436
  client: TRPCWebSocketClient;
350
- }
437
+ } & TransformerOptions<inferClientTypes<TRouter>>;
351
438
  class TRPCWebSocketClosedError extends Error {
352
439
  constructor(message: string) {
353
440
  super(message);
@@ -357,18 +444,19 @@ class TRPCWebSocketClosedError extends Error {
357
444
  }
358
445
 
359
446
  /**
360
- * @see https://trpc.io/docs/client/links/wsLink
447
+ * @link https://trpc.io/docs/v11/client/links/wsLink
361
448
  */
362
449
  export function wsLink<TRouter extends AnyRouter>(
363
- opts: WebSocketLinkOptions,
450
+ opts: WebSocketLinkOptions<TRouter>,
364
451
  ): TRPCLink<TRouter> {
365
- return (runtime) => {
452
+ const transformer = getTransformer(opts.transformer);
453
+ return () => {
366
454
  const { client } = opts;
367
455
  return ({ op }) => {
368
456
  return observable((observer) => {
369
457
  const { type, path, id, context } = op;
370
458
 
371
- const input = runtime.transformer.serialize(op.input);
459
+ const input = transformer.input.serialize(op.input);
372
460
 
373
461
  const unsub = client.request(
374
462
  { type, path, input, id, context },
@@ -381,7 +469,7 @@ export function wsLink<TRouter extends AnyRouter>(
381
469
  observer.complete();
382
470
  },
383
471
  next(message) {
384
- const transformed = transformResult(message, runtime);
472
+ const transformed = transformResult(message, transformer.output);
385
473
 
386
474
  if (!transformed.ok) {
387
475
  observer.error(TRPCClientError.from(transformed.error));
package/src/links.ts ADDED
@@ -0,0 +1,14 @@
1
+ export * from './links/types';
2
+
3
+ export * from './links/HTTPBatchLinkOptions';
4
+ export * from './links/httpBatchLink';
5
+ export * from './links/httpBatchStreamLink';
6
+ export * from './links/httpLink';
7
+ export * from './links/loggerLink';
8
+ export * from './links/splitLink';
9
+ export * from './links/wsLink';
10
+ export * from './links/httpFormDataLink';
11
+
12
+ // These are not public (yet) as we get this functionality from tanstack query
13
+ // export * from './links/internals/retryLink';
14
+ // export * from './links/internals/dedupeLink';
@@ -0,0 +1 @@
1
+ export * from './internals/transformer';
@@ -0,0 +1 @@
1
+ export * from '../dist/unstable-internals';
@@ -0,0 +1 @@
1
+ module.exports = require('../dist/unstable-internals');
@@ -1,61 +0,0 @@
1
- import { i as isObject } from './transformResult-c1422cb5.js';
2
-
3
- function isTRPCClientError(cause) {
4
- return (cause instanceof TRPCClientError ||
5
- /**
6
- * @deprecated
7
- * Delete in next major
8
- */
9
- (cause instanceof Error && cause.name === 'TRPCClientError'));
10
- }
11
- function isTRPCErrorResponse(obj) {
12
- return (isObject(obj) &&
13
- isObject(obj.error) &&
14
- typeof obj.error.code === 'number' &&
15
- typeof obj.error.message === 'string');
16
- }
17
- class TRPCClientError extends Error {
18
- constructor(message, opts) {
19
- const cause = opts?.cause;
20
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
21
- // @ts-ignore https://github.com/tc39/proposal-error-cause
22
- super(message, { cause });
23
- this.meta = opts?.meta;
24
- this.cause = cause;
25
- this.shape = opts?.result?.error;
26
- this.data = opts?.result?.error.data;
27
- this.name = 'TRPCClientError';
28
- Object.setPrototypeOf(this, TRPCClientError.prototype);
29
- }
30
- static from(_cause, opts = {}) {
31
- const cause = _cause;
32
- if (isTRPCClientError(cause)) {
33
- if (opts.meta) {
34
- // Decorate with meta error data
35
- cause.meta = {
36
- ...cause.meta,
37
- ...opts.meta,
38
- };
39
- }
40
- return cause;
41
- }
42
- if (isTRPCErrorResponse(cause)) {
43
- return new TRPCClientError(cause.error.message, {
44
- ...opts,
45
- result: cause,
46
- });
47
- }
48
- if (!(cause instanceof Error)) {
49
- return new TRPCClientError('Unknown error', {
50
- ...opts,
51
- cause: cause,
52
- });
53
- }
54
- return new TRPCClientError(cause.message, {
55
- ...opts,
56
- cause,
57
- });
58
- }
59
- }
60
-
61
- export { TRPCClientError as T };
@@ -1,251 +0,0 @@
1
- 'use strict';
2
-
3
- var observable = require('@trpc/server/observable');
4
- var transformResult = require('./transformResult-dfce8f15.js');
5
- var TRPCClientError = require('./TRPCClientError-e224e397.js');
6
- var httpUtils = require('./httpUtils-c0e7bf5a.js');
7
-
8
- /* eslint-disable @typescript-eslint/no-non-null-assertion */ /**
9
- * A function that should never be called unless we messed something up.
10
- */ const throwFatalError = ()=>{
11
- throw new Error('Something went wrong. Please submit an issue at https://github.com/trpc/trpc/issues/new');
12
- };
13
- /**
14
- * Dataloader that's very inspired by https://github.com/graphql/dataloader
15
- * Less configuration, no caching, and allows you to cancel requests
16
- * When cancelling a single fetch the whole batch will be cancelled only when _all_ items are cancelled
17
- */ function dataLoader(batchLoader) {
18
- let pendingItems = null;
19
- let dispatchTimer = null;
20
- const destroyTimerAndPendingItems = ()=>{
21
- clearTimeout(dispatchTimer);
22
- dispatchTimer = null;
23
- pendingItems = null;
24
- };
25
- /**
26
- * Iterate through the items and split them into groups based on the `batchLoader`'s validate function
27
- */ function groupItems(items) {
28
- const groupedItems = [
29
- []
30
- ];
31
- let index = 0;
32
- while(true){
33
- const item = items[index];
34
- if (!item) {
35
- break;
36
- }
37
- const lastGroup = groupedItems[groupedItems.length - 1];
38
- if (item.aborted) {
39
- // Item was aborted before it was dispatched
40
- item.reject?.(new Error('Aborted'));
41
- index++;
42
- continue;
43
- }
44
- const isValid = batchLoader.validate(lastGroup.concat(item).map((it)=>it.key));
45
- if (isValid) {
46
- lastGroup.push(item);
47
- index++;
48
- continue;
49
- }
50
- if (lastGroup.length === 0) {
51
- item.reject?.(new Error('Input is too big for a single dispatch'));
52
- index++;
53
- continue;
54
- }
55
- // Create new group, next iteration will try to add the item to that
56
- groupedItems.push([]);
57
- }
58
- return groupedItems;
59
- }
60
- function dispatch() {
61
- const groupedItems = groupItems(pendingItems);
62
- destroyTimerAndPendingItems();
63
- // Create batches for each group of items
64
- for (const items of groupedItems){
65
- if (!items.length) {
66
- continue;
67
- }
68
- const batch = {
69
- items,
70
- cancel: throwFatalError
71
- };
72
- for (const item of items){
73
- item.batch = batch;
74
- }
75
- const unitResolver = (index, value)=>{
76
- const item = batch.items[index];
77
- item.resolve?.(value);
78
- item.batch = null;
79
- item.reject = null;
80
- item.resolve = null;
81
- };
82
- const { promise , cancel } = batchLoader.fetch(batch.items.map((_item)=>_item.key), unitResolver);
83
- batch.cancel = cancel;
84
- promise.then((result)=>{
85
- for(let i = 0; i < result.length; i++){
86
- const value = result[i];
87
- unitResolver(i, value);
88
- }
89
- for (const item of batch.items){
90
- item.reject?.(new Error('Missing result'));
91
- item.batch = null;
92
- }
93
- }).catch((cause)=>{
94
- for (const item of batch.items){
95
- item.reject?.(cause);
96
- item.batch = null;
97
- }
98
- });
99
- }
100
- }
101
- function load(key) {
102
- const item = {
103
- aborted: false,
104
- key,
105
- batch: null,
106
- resolve: throwFatalError,
107
- reject: throwFatalError
108
- };
109
- const promise = new Promise((resolve, reject)=>{
110
- item.reject = reject;
111
- item.resolve = resolve;
112
- if (!pendingItems) {
113
- pendingItems = [];
114
- }
115
- pendingItems.push(item);
116
- });
117
- if (!dispatchTimer) {
118
- dispatchTimer = setTimeout(dispatch);
119
- }
120
- const cancel = ()=>{
121
- item.aborted = true;
122
- if (item.batch?.items.every((item)=>item.aborted)) {
123
- // All items in the batch have been cancelled
124
- item.batch.cancel();
125
- item.batch = null;
126
- }
127
- };
128
- return {
129
- promise,
130
- cancel
131
- };
132
- }
133
- return {
134
- load
135
- };
136
- }
137
-
138
- /**
139
- * @internal
140
- */ function createHTTPBatchLink(requester) {
141
- return function httpBatchLink(opts) {
142
- const resolvedOpts = httpUtils.resolveHTTPLinkOptions(opts);
143
- const maxURLLength = opts.maxURLLength ?? Infinity;
144
- // initialized config
145
- return (runtime)=>{
146
- const batchLoader = (type)=>{
147
- const validate = (batchOps)=>{
148
- if (maxURLLength === Infinity) {
149
- // escape hatch for quick calcs
150
- return true;
151
- }
152
- const path = batchOps.map((op)=>op.path).join(',');
153
- const inputs = batchOps.map((op)=>op.input);
154
- const url = httpUtils.getUrl({
155
- ...resolvedOpts,
156
- runtime,
157
- type,
158
- path,
159
- inputs
160
- });
161
- return url.length <= maxURLLength;
162
- };
163
- const fetch = requester({
164
- ...resolvedOpts,
165
- runtime,
166
- type,
167
- opts
168
- });
169
- return {
170
- validate,
171
- fetch
172
- };
173
- };
174
- const query = dataLoader(batchLoader('query'));
175
- const mutation = dataLoader(batchLoader('mutation'));
176
- const subscription = dataLoader(batchLoader('subscription'));
177
- const loaders = {
178
- query,
179
- subscription,
180
- mutation
181
- };
182
- return ({ op })=>{
183
- return observable.observable((observer)=>{
184
- const loader = loaders[op.type];
185
- const { promise , cancel } = loader.load(op);
186
- let _res = undefined;
187
- promise.then((res)=>{
188
- _res = res;
189
- const transformed = transformResult.transformResult(res.json, runtime);
190
- if (!transformed.ok) {
191
- observer.error(TRPCClientError.TRPCClientError.from(transformed.error, {
192
- meta: res.meta
193
- }));
194
- return;
195
- }
196
- observer.next({
197
- context: res.meta,
198
- result: transformed.result
199
- });
200
- observer.complete();
201
- }).catch((err)=>{
202
- observer.error(TRPCClientError.TRPCClientError.from(err, {
203
- meta: _res?.meta
204
- }));
205
- });
206
- return ()=>{
207
- cancel();
208
- };
209
- });
210
- };
211
- };
212
- };
213
- }
214
-
215
- const batchRequester = (requesterOpts)=>{
216
- return (batchOps)=>{
217
- const path = batchOps.map((op)=>op.path).join(',');
218
- const inputs = batchOps.map((op)=>op.input);
219
- const { promise , cancel } = httpUtils.jsonHttpRequester({
220
- ...requesterOpts,
221
- path,
222
- inputs,
223
- headers () {
224
- if (!requesterOpts.opts.headers) {
225
- return {};
226
- }
227
- if (typeof requesterOpts.opts.headers === 'function') {
228
- return requesterOpts.opts.headers({
229
- opList: batchOps
230
- });
231
- }
232
- return requesterOpts.opts.headers;
233
- }
234
- });
235
- return {
236
- promise: promise.then((res)=>{
237
- const resJSON = Array.isArray(res.json) ? res.json : batchOps.map(()=>res.json);
238
- const result = resJSON.map((item)=>({
239
- meta: res.meta,
240
- json: item
241
- }));
242
- return result;
243
- }),
244
- cancel
245
- };
246
- };
247
- };
248
- const httpBatchLink = createHTTPBatchLink(batchRequester);
249
-
250
- exports.createHTTPBatchLink = createHTTPBatchLink;
251
- exports.httpBatchLink = httpBatchLink;