@trpc/client 11.0.0-rc.449 → 11.0.0-rc.455

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 (49) hide show
  1. package/dist/TRPCClientError.d.ts.map +1 -1
  2. package/dist/TRPCClientError.js +11 -8
  3. package/dist/TRPCClientError.mjs +12 -9
  4. package/dist/bundle-analysis.json +54 -68
  5. package/dist/internals/TRPCUntypedClient.d.ts.map +1 -1
  6. package/dist/internals/TRPCUntypedClient.js +15 -19
  7. package/dist/internals/TRPCUntypedClient.mjs +15 -19
  8. package/dist/internals/dataLoader.d.ts +2 -6
  9. package/dist/internals/dataLoader.d.ts.map +1 -1
  10. package/dist/internals/dataLoader.js +3 -16
  11. package/dist/internals/dataLoader.mjs +3 -16
  12. package/dist/internals/types.d.ts +0 -15
  13. package/dist/internals/types.d.ts.map +1 -1
  14. package/dist/links/httpBatchLink.d.ts.map +1 -1
  15. package/dist/links/httpBatchLink.js +15 -17
  16. package/dist/links/httpBatchLink.mjs +16 -18
  17. package/dist/links/httpBatchStreamLink.d.ts.map +1 -1
  18. package/dist/links/httpBatchStreamLink.js +40 -43
  19. package/dist/links/httpBatchStreamLink.mjs +41 -44
  20. package/dist/links/httpLink.d.ts.map +1 -1
  21. package/dist/links/httpLink.js +3 -2
  22. package/dist/links/httpLink.mjs +3 -2
  23. package/dist/links/httpSubscriptionLink.js +1 -1
  24. package/dist/links/httpSubscriptionLink.mjs +1 -1
  25. package/dist/links/internals/httpUtils.d.ts +14 -11
  26. package/dist/links/internals/httpUtils.d.ts.map +1 -1
  27. package/dist/links/internals/httpUtils.js +39 -33
  28. package/dist/links/internals/httpUtils.mjs +39 -34
  29. package/dist/links/types.d.ts +2 -12
  30. package/dist/links/types.d.ts.map +1 -1
  31. package/dist/links/wsLink.js +2 -1
  32. package/dist/links/wsLink.mjs +2 -1
  33. package/package.json +4 -4
  34. package/src/TRPCClientError.ts +15 -10
  35. package/src/internals/TRPCUntypedClient.ts +18 -28
  36. package/src/internals/dataLoader.ts +4 -22
  37. package/src/internals/types.ts +0 -18
  38. package/src/links/httpBatchLink.ts +16 -19
  39. package/src/links/httpBatchStreamLink.ts +65 -72
  40. package/src/links/httpLink.ts +3 -2
  41. package/src/links/httpSubscriptionLink.ts +1 -1
  42. package/src/links/internals/httpUtils.ts +58 -44
  43. package/src/links/types.ts +2 -13
  44. package/src/links/wsLink.ts +1 -1
  45. package/dist/internals/getAbortController.d.ts +0 -4
  46. package/dist/internals/getAbortController.d.ts.map +0 -1
  47. package/dist/internals/getAbortController.js +0 -16
  48. package/dist/internals/getAbortController.mjs +0 -14
  49. package/src/internals/getAbortController.ts +0 -20
@@ -1,15 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  var getFetch = require('../../getFetch.js');
4
- var getAbortController = require('../../internals/getAbortController.js');
5
- var TRPCClientError = require('../../TRPCClientError.js');
6
4
  var transformer = require('../../internals/transformer.js');
7
5
 
8
6
  function resolveHTTPLinkOptions(opts) {
9
7
  return {
10
8
  url: opts.url.toString(),
11
9
  fetch: opts.fetch,
12
- AbortController: getAbortController.getAbortController(opts.AbortController),
13
10
  transformer: transformer.getTransformer(opts.transformer),
14
11
  methodOverride: opts.methodOverride
15
12
  };
@@ -68,7 +65,8 @@ const jsonHttpRequester = (opts)=>{
68
65
  getBody
69
66
  });
70
67
  };
71
- async function fetchHTTPResponse(opts, ac) {
68
+ async function fetchHTTPResponse(opts) {
69
+ opts.signal?.throwIfAborted();
72
70
  const url = opts.getUrl(opts);
73
71
  const body = opts.getBody(opts);
74
72
  const { type } = opts;
@@ -90,43 +88,50 @@ async function fetchHTTPResponse(opts, ac) {
90
88
  };
91
89
  return getFetch.getFetch(opts.fetch)(url, {
92
90
  method: opts.methodOverride ?? METHOD[type],
93
- signal: ac?.signal,
91
+ signal: opts.signal,
94
92
  body,
95
93
  headers
96
94
  });
97
95
  }
98
- function httpRequest(opts) {
99
- const ac = opts.AbortController ? new opts.AbortController() : null;
96
+ async function httpRequest(opts) {
100
97
  const meta = {};
101
- let done = false;
102
- const promise = new Promise((resolve, reject)=>{
103
- fetchHTTPResponse(opts, ac).then((_res)=>{
104
- meta.response = _res;
105
- done = true;
106
- return _res.json();
107
- }).then((json)=>{
108
- meta.responseJSON = json;
109
- resolve({
110
- json: json,
111
- meta
112
- });
113
- }).catch((err)=>{
114
- done = true;
115
- reject(TRPCClientError.TRPCClientError.from(err, {
116
- meta
117
- }));
118
- });
119
- });
120
- const cancel = ()=>{
121
- if (!done) {
122
- ac?.abort();
123
- }
124
- };
98
+ const res = await fetchHTTPResponse(opts);
99
+ meta.response = res;
100
+ const json = await res.json();
101
+ meta.responseJSON = json;
125
102
  return {
126
- promise,
127
- cancel
103
+ json: json,
104
+ meta
128
105
  };
129
106
  }
107
+ /**
108
+ * Merges multiple abort signals into a single one
109
+ * - When all signals have been aborted, the merged signal will be aborted
110
+ */ function mergeAbortSignals(opts) {
111
+ const ac = new AbortController();
112
+ if (opts.some((o)=>!o.signal)) {
113
+ return ac;
114
+ }
115
+ const count = opts.length;
116
+ let abortedCount = 0;
117
+ const onAbort = ()=>{
118
+ if (++abortedCount === count) {
119
+ ac.abort();
120
+ }
121
+ };
122
+ for (const o of opts){
123
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
124
+ const signal = o.signal;
125
+ if (signal.aborted) {
126
+ onAbort();
127
+ } else {
128
+ signal.addEventListener('abort', onAbort, {
129
+ once: true
130
+ });
131
+ }
132
+ }
133
+ return ac;
134
+ }
130
135
 
131
136
  exports.fetchHTTPResponse = fetchHTTPResponse;
132
137
  exports.getBody = getBody;
@@ -134,4 +139,5 @@ exports.getInput = getInput;
134
139
  exports.getUrl = getUrl;
135
140
  exports.httpRequest = httpRequest;
136
141
  exports.jsonHttpRequester = jsonHttpRequester;
142
+ exports.mergeAbortSignals = mergeAbortSignals;
137
143
  exports.resolveHTTPLinkOptions = resolveHTTPLinkOptions;
@@ -1,13 +1,10 @@
1
1
  import { getFetch } from '../../getFetch.mjs';
2
- import { getAbortController } from '../../internals/getAbortController.mjs';
3
- import { TRPCClientError } from '../../TRPCClientError.mjs';
4
2
  import { getTransformer } from '../../internals/transformer.mjs';
5
3
 
6
4
  function resolveHTTPLinkOptions(opts) {
7
5
  return {
8
6
  url: opts.url.toString(),
9
7
  fetch: opts.fetch,
10
- AbortController: getAbortController(opts.AbortController),
11
8
  transformer: getTransformer(opts.transformer),
12
9
  methodOverride: opts.methodOverride
13
10
  };
@@ -66,7 +63,8 @@ const jsonHttpRequester = (opts)=>{
66
63
  getBody
67
64
  });
68
65
  };
69
- async function fetchHTTPResponse(opts, ac) {
66
+ async function fetchHTTPResponse(opts) {
67
+ opts.signal?.throwIfAborted();
70
68
  const url = opts.getUrl(opts);
71
69
  const body = opts.getBody(opts);
72
70
  const { type } = opts;
@@ -88,42 +86,49 @@ async function fetchHTTPResponse(opts, ac) {
88
86
  };
89
87
  return getFetch(opts.fetch)(url, {
90
88
  method: opts.methodOverride ?? METHOD[type],
91
- signal: ac?.signal,
89
+ signal: opts.signal,
92
90
  body,
93
91
  headers
94
92
  });
95
93
  }
96
- function httpRequest(opts) {
97
- const ac = opts.AbortController ? new opts.AbortController() : null;
94
+ async function httpRequest(opts) {
98
95
  const meta = {};
99
- let done = false;
100
- const promise = new Promise((resolve, reject)=>{
101
- fetchHTTPResponse(opts, ac).then((_res)=>{
102
- meta.response = _res;
103
- done = true;
104
- return _res.json();
105
- }).then((json)=>{
106
- meta.responseJSON = json;
107
- resolve({
108
- json: json,
109
- meta
110
- });
111
- }).catch((err)=>{
112
- done = true;
113
- reject(TRPCClientError.from(err, {
114
- meta
115
- }));
116
- });
117
- });
118
- const cancel = ()=>{
119
- if (!done) {
120
- ac?.abort();
121
- }
122
- };
96
+ const res = await fetchHTTPResponse(opts);
97
+ meta.response = res;
98
+ const json = await res.json();
99
+ meta.responseJSON = json;
123
100
  return {
124
- promise,
125
- cancel
101
+ json: json,
102
+ meta
126
103
  };
127
104
  }
105
+ /**
106
+ * Merges multiple abort signals into a single one
107
+ * - When all signals have been aborted, the merged signal will be aborted
108
+ */ function mergeAbortSignals(opts) {
109
+ const ac = new AbortController();
110
+ if (opts.some((o)=>!o.signal)) {
111
+ return ac;
112
+ }
113
+ const count = opts.length;
114
+ let abortedCount = 0;
115
+ const onAbort = ()=>{
116
+ if (++abortedCount === count) {
117
+ ac.abort();
118
+ }
119
+ };
120
+ for (const o of opts){
121
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
122
+ const signal = o.signal;
123
+ if (signal.aborted) {
124
+ onAbort();
125
+ } else {
126
+ signal.addEventListener('abort', onAbort, {
127
+ once: true
128
+ });
129
+ }
130
+ }
131
+ return ac;
132
+ }
128
133
 
129
- export { fetchHTTPResponse, getBody, getInput, getUrl, httpRequest, jsonHttpRequester, resolveHTTPLinkOptions };
134
+ export { fetchHTTPResponse, getBody, getInput, getUrl, httpRequest, jsonHttpRequester, mergeAbortSignals, resolveHTTPLinkOptions };
@@ -1,19 +1,8 @@
1
1
  import type { Observable, Observer } from '@trpc/server/observable';
2
- import type { InferrableClientTypes, TRPCResultMessage, TRPCSuccessResponse } from '@trpc/server/unstable-core-do-not-import';
2
+ import type { InferrableClientTypes, Maybe, TRPCResultMessage, TRPCSuccessResponse } from '@trpc/server/unstable-core-do-not-import';
3
3
  import type { ResponseEsque } from '../internals/types';
4
4
  import type { TRPCClientError } from '../TRPCClientError';
5
5
  export { isNonJsonSerializable, isFormData, isOctetType, } from './internals/contentTypes';
6
- /**
7
- * @internal
8
- */
9
- export type CancelFn = () => void;
10
- /**
11
- * @internal
12
- */
13
- export type PromiseAndCancel<TValue> = {
14
- promise: Promise<TValue>;
15
- cancel: CancelFn;
16
- };
17
6
  /**
18
7
  * @internal
19
8
  */
@@ -28,6 +17,7 @@ export type Operation<TInput = unknown> = {
28
17
  input: TInput;
29
18
  path: string;
30
19
  context: OperationContext;
20
+ signal: Maybe<AbortSignal>;
31
21
  };
32
22
  interface HeadersInitEsque {
33
23
  [Symbol.iterator](): IterableIterator<[string, string]>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/links/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,KAAK,EACV,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EACL,qBAAqB,EACrB,UAAU,EACV,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAElC;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,MAAM,IAAI;IACrC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,MAAM,EAAE,QAAQ,CAAC;CAClB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAAG;AAEpE;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,MAAM,GAAG,OAAO,IAAI;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,cAAc,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF,UAAU,gBAAgB;IACxB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,gBAAgB,GAChB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,WAAW,KAClB,OAAO,CAAC,aAAa,CAAC,CAAC;AAE5B,MAAM,WAAW,iBAAiB;CAEjC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB,CAAC,OAAO;IAC9C,MAAM,EACF,iBAAiB,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,GACpC,mBAAmB,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,MAAM,yBAAyB,CACnC,WAAW,SAAS,qBAAqB,EACzC,OAAO,IACL,UAAU,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;AAE/E;;GAEG;AACH,MAAM,MAAM,uBAAuB,CACjC,WAAW,SAAS,qBAAqB,EACzC,OAAO,IACL,QAAQ,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;AAE7E;;GAEG;AACH,MAAM,MAAM,aAAa,CACvB,WAAW,SAAS,qBAAqB,EACzC,MAAM,GAAG,OAAO,EAChB,OAAO,GAAG,OAAO,IACf,CAAC,IAAI,EAAE;IACT,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACtB,IAAI,EAAE,CACJ,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,KAClB,yBAAyB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CACtD,KAAK,yBAAyB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,QAAQ,CAAC,WAAW,SAAS,qBAAqB,IAAI,CAChE,IAAI,EAAE,iBAAiB,KACpB,aAAa,CAAC,WAAW,CAAC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/links/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,KAAK,EACV,qBAAqB,EACrB,KAAK,EACL,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EACL,qBAAqB,EACrB,UAAU,EACV,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAAG;AAEpE;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,MAAM,GAAG,OAAO,IAAI;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,cAAc,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;CAC5B,CAAC;AAEF,UAAU,gBAAgB;IACxB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,gBAAgB,GAChB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,WAAW,KAClB,OAAO,CAAC,aAAa,CAAC,CAAC;AAE5B,MAAM,WAAW,iBAAiB;CAEjC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB,CAAC,OAAO;IAC9C,MAAM,EACF,iBAAiB,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,GACpC,mBAAmB,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,MAAM,yBAAyB,CACnC,WAAW,SAAS,qBAAqB,EACzC,OAAO,IACL,UAAU,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;AAE/E;;GAEG;AACH,MAAM,MAAM,uBAAuB,CACjC,WAAW,SAAS,qBAAqB,EACzC,OAAO,IACL,QAAQ,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;AAE7E;;GAEG;AACH,MAAM,MAAM,aAAa,CACvB,WAAW,SAAS,qBAAqB,EACzC,MAAM,GAAG,OAAO,EAChB,OAAO,GAAG,OAAO,IACf,CAAC,IAAI,EAAE;IACT,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACtB,IAAI,EAAE,CACJ,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,KAClB,yBAAyB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CACtD,KAAK,yBAAyB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,QAAQ,CAAC,WAAW,SAAS,qBAAqB,IAAI,CAChE,IAAI,EAAE,iBAAiB,KACpB,aAAa,CAAC,WAAW,CAAC,CAAC"}
@@ -322,7 +322,8 @@ class TRPCWebSocketClosedError extends Error {
322
322
  path,
323
323
  input,
324
324
  id,
325
- context
325
+ context,
326
+ signal: null
326
327
  }, {
327
328
  error (err) {
328
329
  observer.error(err);
@@ -320,7 +320,8 @@ class TRPCWebSocketClosedError extends Error {
320
320
  path,
321
321
  input,
322
322
  id,
323
- context
323
+ context,
324
+ signal: null
324
325
  }, {
325
326
  error (err) {
326
327
  observer.error(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trpc/client",
3
- "version": "11.0.0-rc.449+42acce6ac",
3
+ "version": "11.0.0-rc.455+244538dd3",
4
4
  "description": "The tRPC client library",
5
5
  "author": "KATT",
6
6
  "license": "MIT",
@@ -76,10 +76,10 @@
76
76
  "!**/*.test.*"
77
77
  ],
78
78
  "peerDependencies": {
79
- "@trpc/server": "11.0.0-rc.449+42acce6ac"
79
+ "@trpc/server": "11.0.0-rc.455+244538dd3"
80
80
  },
81
81
  "devDependencies": {
82
- "@trpc/server": "11.0.0-rc.449+42acce6ac",
82
+ "@trpc/server": "11.0.0-rc.455+244538dd3",
83
83
  "@types/isomorphic-fetch": "^0.0.39",
84
84
  "@types/node": "^20.10.0",
85
85
  "eslint": "^8.56.0",
@@ -96,5 +96,5 @@
96
96
  "funding": [
97
97
  "https://trpc.io/sponsor"
98
98
  ],
99
- "gitHead": "42acce6ac165dd489ebc11721e1c4dd15f4d8b7a"
99
+ "gitHead": "244538dd3d42c0df05c7a491def21562e3cce253"
100
100
  }
@@ -5,7 +5,6 @@ import type {
5
5
  TRPCErrorResponse,
6
6
  } from '@trpc/server/unstable-core-do-not-import';
7
7
  import {
8
- getCauseFromUnknown,
9
8
  isObject,
10
9
  type DefaultErrorShape,
11
10
  } from '@trpc/server/unstable-core-do-not-import';
@@ -40,6 +39,16 @@ function isTRPCErrorResponse(obj: unknown): obj is TRPCErrorResponse<any> {
40
39
  );
41
40
  }
42
41
 
42
+ function getMessageFromUnknownError(err: unknown, fallback: string): string {
43
+ if (typeof err === 'string') {
44
+ return err;
45
+ }
46
+ if (isObject(err) && typeof err['message'] === 'string') {
47
+ return err['message'];
48
+ }
49
+ return fallback;
50
+ }
51
+
43
52
  export class TRPCClientError<TRouterOrProcedure extends InferrableClientTypes>
44
53
  extends Error
45
54
  implements TRPCClientErrorBase<inferErrorShape<TRouterOrProcedure>>
@@ -102,16 +111,12 @@ export class TRPCClientError<TRouterOrProcedure extends InferrableClientTypes>
102
111
  result: cause,
103
112
  });
104
113
  }
105
- if (!(cause instanceof Error)) {
106
- return new TRPCClientError('Unknown error', {
114
+ return new TRPCClientError(
115
+ getMessageFromUnknownError(cause, 'Unknown error'),
116
+ {
107
117
  ...opts,
108
118
  cause: cause as any,
109
- });
110
- }
111
-
112
- return new TRPCClientError(cause.message, {
113
- ...opts,
114
- cause: getCauseFromUnknown(cause),
115
- });
119
+ },
120
+ );
116
121
  }
117
122
  }
@@ -6,6 +6,7 @@ import { observableToPromise, share } from '@trpc/server/observable';
6
6
  import type {
7
7
  AnyRouter,
8
8
  InferrableClientTypes,
9
+ Maybe,
9
10
  TypeError,
10
11
  } from '@trpc/server/unstable-core-do-not-import';
11
12
  import { createChain } from '../links/internals/createChain';
@@ -65,53 +66,41 @@ export class TRPCUntypedClient<TRouter extends AnyRouter> {
65
66
  this.links = opts.links.map((link) => link(this.runtime));
66
67
  }
67
68
 
68
- private $request<TInput = unknown, TOutput = unknown>({
69
- type,
70
- input,
71
- path,
72
- context = {},
73
- }: {
69
+ private $request<TInput = unknown, TOutput = unknown>(opts: {
74
70
  type: TRPCType;
75
71
  input: TInput;
76
72
  path: string;
77
73
  context?: OperationContext;
74
+ signal: Maybe<AbortSignal>;
78
75
  }) {
79
76
  const chain$ = createChain<AnyRouter, TInput, TOutput>({
80
77
  links: this.links as OperationLink<any, any, any>[],
81
78
  op: {
79
+ ...opts,
80
+ context: opts.context ?? {},
82
81
  id: ++this.requestId,
83
- type,
84
- path,
85
- input,
86
- context,
87
82
  },
88
83
  });
89
84
  return chain$.pipe(share());
90
85
  }
91
- private requestAsPromise<TInput = unknown, TOutput = unknown>(opts: {
86
+
87
+ private async requestAsPromise<TInput = unknown, TOutput = unknown>(opts: {
92
88
  type: TRPCType;
93
89
  input: TInput;
94
90
  path: string;
95
91
  context?: OperationContext;
96
- signal?: AbortSignal;
92
+ signal: Maybe<AbortSignal>;
97
93
  }): Promise<TOutput> {
98
- const req$ = this.$request<TInput, TOutput>(opts);
99
- type TValue = inferObservableValue<typeof req$>;
100
- const { promise, abort } = observableToPromise<TValue>(req$);
101
-
102
- const abortablePromise = new Promise<TOutput>((resolve, reject) => {
103
- opts.signal?.addEventListener('abort', abort);
104
-
105
- promise
106
- .then((envelope) => {
107
- resolve((envelope.result as any).data);
108
- })
109
- .catch((err) => {
110
- reject(TRPCClientError.from(err));
111
- });
112
- });
94
+ try {
95
+ const req$ = this.$request<TInput, TOutput>(opts);
96
+ type TValue = inferObservableValue<typeof req$>;
113
97
 
114
- return abortablePromise;
98
+ const envelope = await observableToPromise<TValue>(req$);
99
+ const data = (envelope.result as any).data;
100
+ return data;
101
+ } catch (err) {
102
+ throw TRPCClientError.from(err as Error);
103
+ }
115
104
  }
116
105
  public query(path: string, input?: unknown, opts?: TRPCRequestOptions) {
117
106
  return this.requestAsPromise<unknown, unknown>({
@@ -144,6 +133,7 @@ export class TRPCUntypedClient<TRouter extends AnyRouter> {
144
133
  path,
145
134
  input,
146
135
  context: opts?.context,
136
+ signal: null,
147
137
  });
148
138
  return observable$.subscribe({
149
139
  next(envelope) {
@@ -1,5 +1,4 @@
1
1
  /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
- import type { CancelFn, PromiseAndCancel } from '../links/types';
3
2
 
4
3
  type BatchItem<TKey, TValue> = {
5
4
  aborted: boolean;
@@ -10,14 +9,10 @@ type BatchItem<TKey, TValue> = {
10
9
  };
11
10
  type Batch<TKey, TValue> = {
12
11
  items: BatchItem<TKey, TValue>[];
13
- cancel: CancelFn;
14
12
  };
15
13
  export type BatchLoader<TKey, TValue> = {
16
14
  validate: (keys: TKey[]) => boolean;
17
- fetch: (keys: TKey[]) => {
18
- promise: Promise<TValue[] | Promise<TValue>[]>;
19
- cancel: CancelFn;
20
- };
15
+ fetch: (keys: TKey[]) => Promise<TValue[] | Promise<TValue>[]>;
21
16
  };
22
17
 
23
18
  /**
@@ -99,15 +94,11 @@ export function dataLoader<TKey, TValue>(
99
94
  }
100
95
  const batch: Batch<TKey, TValue> = {
101
96
  items,
102
- cancel: throwFatalError,
103
97
  };
104
98
  for (const item of items) {
105
99
  item.batch = batch;
106
100
  }
107
- const { promise, cancel } = batchLoader.fetch(
108
- batch.items.map((_item) => _item.key),
109
- );
110
- batch.cancel = cancel;
101
+ const promise = batchLoader.fetch(batch.items.map((_item) => _item.key));
111
102
 
112
103
  promise
113
104
  .then(async (result) => {
@@ -141,7 +132,7 @@ export function dataLoader<TKey, TValue>(
141
132
  });
142
133
  }
143
134
  }
144
- function load(key: TKey): PromiseAndCancel<TValue> {
135
+ function load(key: TKey): Promise<TValue> {
145
136
  const item: BatchItem<TKey, TValue> = {
146
137
  aborted: false,
147
138
  key,
@@ -163,17 +154,8 @@ export function dataLoader<TKey, TValue>(
163
154
  if (!dispatchTimer) {
164
155
  dispatchTimer = setTimeout(dispatch);
165
156
  }
166
- const cancel = () => {
167
- item.aborted = true;
168
-
169
- if (item.batch?.items.every((item) => item.aborted)) {
170
- // All items in the batch have been cancelled
171
- item.batch.cancel();
172
- item.batch = null;
173
- }
174
- };
175
157
 
176
- return { promise, cancel };
158
+ return promise;
177
159
  }
178
160
 
179
161
  return {
@@ -1,21 +1,3 @@
1
- export type AbortControllerEsque = new () => AbortControllerInstanceEsque;
2
-
3
- /**
4
- * Allows you to abort one or more requests.
5
- */
6
- export interface AbortControllerInstanceEsque {
7
- /**
8
- * The AbortSignal object associated with this object.
9
- */
10
- readonly signal: AbortSignal;
11
-
12
- /**
13
- * Sets this object's AbortSignal's aborted flag and signals to
14
- * any observers that the associated activity is to be aborted.
15
- */
16
- abort(): void;
17
- }
18
-
19
1
  /**
20
2
  * A subset of the standard fetch function type needed by tRPC internally.
21
3
  * @see fetch from lib.dom.d.ts
@@ -10,6 +10,7 @@ import type { HTTPResult } from './internals/httpUtils';
10
10
  import {
11
11
  getUrl,
12
12
  jsonHttpRequester,
13
+ mergeAbortSignals,
13
14
  resolveHTTPLinkOptions,
14
15
  } from './internals/httpUtils';
15
16
  import type { Operation, TRPCLink } from './types';
@@ -41,15 +42,17 @@ export function httpBatchLink<TRouter extends AnyRouter>(
41
42
  type,
42
43
  path,
43
44
  inputs,
45
+ signal: null,
44
46
  });
45
47
 
46
48
  return url.length <= maxURLLength;
47
49
  },
48
- fetch(batchOps) {
50
+ async fetch(batchOps) {
49
51
  const path = batchOps.map((op) => op.path).join(',');
50
52
  const inputs = batchOps.map((op) => op.input);
53
+ const ac = mergeAbortSignals(batchOps);
51
54
 
52
- const requester = jsonHttpRequester({
55
+ const res = await jsonHttpRequester({
53
56
  ...resolvedOpts,
54
57
  path,
55
58
  inputs,
@@ -65,22 +68,16 @@ export function httpBatchLink<TRouter extends AnyRouter>(
65
68
  }
66
69
  return opts.headers;
67
70
  },
71
+ signal: ac.signal,
68
72
  });
69
- return {
70
- cancel: requester.cancel,
71
- promise: requester.promise.then((res) => {
72
- const resJSON = Array.isArray(res.json)
73
- ? res.json
74
- : batchOps.map(() => res.json);
75
-
76
- const result = resJSON.map((item) => ({
77
- meta: res.meta,
78
- json: item,
79
- }));
80
-
81
- return result;
82
- }),
83
- };
73
+ const resJSON = Array.isArray(res.json)
74
+ ? res.json
75
+ : batchOps.map(() => res.json);
76
+ const result = resJSON.map((item) => ({
77
+ meta: res.meta,
78
+ json: item,
79
+ }));
80
+ return result;
84
81
  },
85
82
  };
86
83
  };
@@ -98,7 +95,7 @@ export function httpBatchLink<TRouter extends AnyRouter>(
98
95
  );
99
96
  }
100
97
  const loader = loaders[op.type];
101
- const { promise, cancel } = loader.load(op);
98
+ const promise = loader.load(op);
102
99
 
103
100
  let _res = undefined as HTTPResult | undefined;
104
101
  promise
@@ -132,7 +129,7 @@ export function httpBatchLink<TRouter extends AnyRouter>(
132
129
  });
133
130
 
134
131
  return () => {
135
- cancel();
132
+ // noop
136
133
  };
137
134
  });
138
135
  };