@orpc/client 2.0.0-beta.43 → 2.0.0-beta.45
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.
- package/README.md +56 -57
- package/dist/adapters/fetch/index.d.mts +3 -3
- package/dist/adapters/fetch/index.d.ts +3 -3
- package/dist/adapters/fetch/index.mjs +9 -3
- package/dist/adapters/message-port/index.d.mts +2 -2
- package/dist/adapters/message-port/index.d.ts +2 -2
- package/dist/adapters/message-port/index.mjs +3 -3
- package/dist/adapters/standard/index.d.mts +8 -8
- package/dist/adapters/standard/index.d.ts +8 -8
- package/dist/adapters/standard/index.mjs +3 -3
- package/dist/adapters/websocket/index.d.mts +9 -9
- package/dist/adapters/websocket/index.d.ts +9 -9
- package/dist/adapters/websocket/index.mjs +3 -3
- package/dist/index.d.mts +9 -20
- package/dist/index.d.ts +9 -20
- package/dist/index.mjs +3 -3
- package/dist/plugins/index.d.mts +51 -37
- package/dist/plugins/index.d.ts +51 -37
- package/dist/plugins/index.mjs +20 -10
- package/dist/shared/{client.Dw9_40WO.d.mts → client.BoHJeq15.d.mts} +36 -11
- package/dist/shared/{client.Dw9_40WO.d.ts → client.BoHJeq15.d.ts} +36 -11
- package/dist/shared/{client.Bstqyaro.mjs → client.Bpyj1NM2.mjs} +11 -8
- package/dist/shared/{client.DiHfJmHK.d.ts → client.CkwtFnrc.d.mts} +5 -5
- package/dist/shared/{client.BjbdW5Rj.d.mts → client.DBDKICdk.d.ts} +5 -5
- package/dist/shared/{client.BPa_Mmuh.d.mts → client.DqIWeNhQ.d.mts} +7 -8
- package/dist/shared/{client.BPa_Mmuh.d.ts → client.DqIWeNhQ.d.ts} +7 -8
- package/dist/shared/{client.DD2eNne_.mjs → client.LF04eOvL.mjs} +24 -6
- package/dist/shared/{client.DpkGsZt-.mjs → client._wG5INmC.mjs} +69 -50
- package/package.json +8 -8
package/dist/plugins/index.d.ts
CHANGED
|
@@ -3,7 +3,19 @@ import { StandardUrl, StandardHeaders, StandardRequest, StandardLazyResponse } f
|
|
|
3
3
|
import { ClientContext } from '../index.js';
|
|
4
4
|
import { StandardLinkPlugin, StandardLinkTransportInterceptorOptions, StandardLinkOptions, StandardLinkInterceptorOptions } from '../adapters/standard/index.js';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Header that marks a request as a batch, set by the Batch Link Plugin and detected by the Batch Handler Plugin.
|
|
8
|
+
* Nothing between the client and server, such as a CORS policy or proxy, should block or strip it.
|
|
9
|
+
*
|
|
10
|
+
* @see {@link https://orpc.dev/docs/plugins/batch#setup | Batch Plugin - Setup}
|
|
11
|
+
*/
|
|
12
|
+
declare const BATCH_HEADER = "orpc-batch";
|
|
13
|
+
/**
|
|
14
|
+
* Default `maxSize` of both the Batch Link Plugin and the Batch Handler Plugin.
|
|
15
|
+
*
|
|
16
|
+
* @see {@link https://orpc.dev/docs/plugins/batch#max-size | Batch Plugin - Max Size}
|
|
17
|
+
*/
|
|
18
|
+
declare const DEFAULT_BATCH_MAX_SIZE = 10;
|
|
7
19
|
interface BatchLinkPluginGroup<T extends ClientContext> {
|
|
8
20
|
/**
|
|
9
21
|
* Determines whether a request should be included in this batch group.
|
|
@@ -21,7 +33,7 @@ interface BatchLinkPluginGroup<T extends ClientContext> {
|
|
|
21
33
|
*
|
|
22
34
|
* @default []
|
|
23
35
|
*/
|
|
24
|
-
path?: Value<string[], [items: [StandardLinkTransportInterceptorOptions<T>, ...StandardLinkTransportInterceptorOptions<T>[]]]
|
|
36
|
+
path?: Value<string[], [items: [StandardLinkTransportInterceptorOptions<T>, ...StandardLinkTransportInterceptorOptions<T>[]]]> | undefined;
|
|
25
37
|
}
|
|
26
38
|
interface BatchLinkPluginOptions<T extends ClientContext> {
|
|
27
39
|
groups: [BatchLinkPluginGroup<T>, ...BatchLinkPluginGroup<T>[]];
|
|
@@ -30,20 +42,22 @@ interface BatchLinkPluginOptions<T extends ClientContext> {
|
|
|
30
42
|
*
|
|
31
43
|
* @default () => true
|
|
32
44
|
*/
|
|
33
|
-
filter?: Value<boolean, [options: StandardLinkTransportInterceptorOptions<T>]
|
|
45
|
+
filter?: Value<boolean, [options: StandardLinkTransportInterceptorOptions<T>]> | undefined;
|
|
34
46
|
/**
|
|
35
47
|
* Only requests with the same scope are batched together.
|
|
36
48
|
* On the server, return a value unique to the incoming request so different users never share a batch.
|
|
37
49
|
*
|
|
38
50
|
* @default () => undefined
|
|
39
51
|
*/
|
|
40
|
-
scope?: (options: StandardLinkTransportInterceptorOptions<T>) => unknown;
|
|
52
|
+
scope?: ((options: StandardLinkTransportInterceptorOptions<T>) => unknown) | undefined;
|
|
41
53
|
/**
|
|
42
|
-
* The maximum number of requests in the batch.
|
|
54
|
+
* The maximum number of requests in the batch. Larger batches are split.
|
|
55
|
+
* Keep it at or below the server Batch Handler Plugin's `maxSize`, which rejects larger batches with a `413`.
|
|
43
56
|
*
|
|
44
|
-
* @default 10
|
|
57
|
+
* @default DEFAULT_BATCH_MAX_SIZE (10)
|
|
58
|
+
* @see {@link https://orpc.dev/docs/plugins/batch#max-size | Batch Plugin - Max Size}
|
|
45
59
|
*/
|
|
46
|
-
maxSize?: Value<Promisable<number>, [subOptionsList: [StandardLinkTransportInterceptorOptions<T>, ...StandardLinkTransportInterceptorOptions<T>[]]]
|
|
60
|
+
maxSize?: Value<Promisable<number>, [subOptionsList: [StandardLinkTransportInterceptorOptions<T>, ...StandardLinkTransportInterceptorOptions<T>[]]]> | undefined;
|
|
47
61
|
/**
|
|
48
62
|
* How long (in ms) to wait for more requests before sending the batch,
|
|
49
63
|
* counted from the first queued request.
|
|
@@ -51,19 +65,13 @@ interface BatchLinkPluginOptions<T extends ClientContext> {
|
|
|
51
65
|
*
|
|
52
66
|
* @default 0
|
|
53
67
|
*/
|
|
54
|
-
wait?: number;
|
|
55
|
-
/**
|
|
56
|
-
* The batch response mode.
|
|
57
|
-
*
|
|
58
|
-
* @default 'streaming'
|
|
59
|
-
*/
|
|
60
|
-
mode?: Value<BatchLinkPluginMode, [subOptionsList: [StandardLinkTransportInterceptorOptions<T>, ...StandardLinkTransportInterceptorOptions<T>[]]]>;
|
|
68
|
+
wait?: number | undefined;
|
|
61
69
|
/**
|
|
62
70
|
* URL for the batch request.
|
|
63
71
|
*
|
|
64
72
|
* @default URL of the first subrequest in the batch + '/__batch__'
|
|
65
73
|
*/
|
|
66
|
-
url?: Value<Promisable<StandardUrl>, [subOptionsList: [StandardLinkTransportInterceptorOptions<T>, ...StandardLinkTransportInterceptorOptions<T>[]]]
|
|
74
|
+
url?: Value<Promisable<StandardUrl>, [subOptionsList: [StandardLinkTransportInterceptorOptions<T>, ...StandardLinkTransportInterceptorOptions<T>[]]]> | undefined;
|
|
67
75
|
/**
|
|
68
76
|
* The maximum length of the URL that runtime supports,
|
|
69
77
|
* if exceeded, the batch will be split into smaller batches and sent sequentially.
|
|
@@ -72,25 +80,25 @@ interface BatchLinkPluginOptions<T extends ClientContext> {
|
|
|
72
80
|
*
|
|
73
81
|
* @default 2083
|
|
74
82
|
*/
|
|
75
|
-
maxUrlLength?: Value<Promisable<number>, [subOptionsList: [StandardLinkTransportInterceptorOptions<T>, ...StandardLinkTransportInterceptorOptions<T>[]]]
|
|
83
|
+
maxUrlLength?: Value<Promisable<number>, [subOptionsList: [StandardLinkTransportInterceptorOptions<T>, ...StandardLinkTransportInterceptorOptions<T>[]]]> | undefined;
|
|
76
84
|
/**
|
|
77
85
|
* Headers used for the batch request.
|
|
78
86
|
*
|
|
79
87
|
* @default Common headers among all subrequests in the batch.
|
|
80
88
|
*/
|
|
81
|
-
headers?: Value<Promisable<StandardHeaders>, [subOptionsList: [StandardLinkTransportInterceptorOptions<T>, ...StandardLinkTransportInterceptorOptions<T>[]]]
|
|
89
|
+
headers?: Value<Promisable<StandardHeaders>, [subOptionsList: [StandardLinkTransportInterceptorOptions<T>, ...StandardLinkTransportInterceptorOptions<T>[]]]> | undefined;
|
|
82
90
|
/**
|
|
83
91
|
* Map each subrequest in the batch before it is sent.
|
|
84
92
|
*
|
|
85
93
|
* @default Removes headers that are duplicated with the batch headers
|
|
86
94
|
*/
|
|
87
|
-
mapSubrequest?: (subOptions: StandardLinkTransportInterceptorOptions<T>, partialBatchRequest: Pick<StandardRequest, 'url' | 'headers'>) => StandardRequest;
|
|
95
|
+
mapSubrequest?: ((subOptions: StandardLinkTransportInterceptorOptions<T>, partialBatchRequest: Pick<StandardRequest, 'url' | 'headers'>) => StandardRequest) | undefined;
|
|
88
96
|
/**
|
|
89
97
|
* Maps each subresponse before returning the final response.
|
|
90
98
|
*
|
|
91
99
|
* @default Low-priority merges headers from the batch response into each subresponse.
|
|
92
100
|
*/
|
|
93
|
-
mapSubresponse?: (subResponse: StandardLazyResponse, batchResponse: StandardLazyResponse, subOptions: StandardLinkTransportInterceptorOptions<T>) => StandardLazyResponse;
|
|
101
|
+
mapSubresponse?: ((subResponse: StandardLazyResponse, batchResponse: StandardLazyResponse, subOptions: StandardLinkTransportInterceptorOptions<T>) => StandardLazyResponse) | undefined;
|
|
94
102
|
}
|
|
95
103
|
/**
|
|
96
104
|
* Combines multiple client requests into a single batch request
|
|
@@ -108,7 +116,6 @@ declare class BatchLinkPlugin<T extends ClientContext> implements StandardLinkPl
|
|
|
108
116
|
private readonly scope;
|
|
109
117
|
private readonly maxSize;
|
|
110
118
|
private readonly wait;
|
|
111
|
-
private readonly mode;
|
|
112
119
|
private readonly batchUrl;
|
|
113
120
|
private readonly maxUrlLength;
|
|
114
121
|
private readonly batchHeaders;
|
|
@@ -151,14 +158,14 @@ interface DedupeLinkPluginOptions<T extends ClientContext> {
|
|
|
151
158
|
*
|
|
152
159
|
* @default ({ request }) => request.method === 'GET' || request.method === 'QUERY'
|
|
153
160
|
*/
|
|
154
|
-
filter?: Value<boolean, [options: StandardLinkTransportInterceptorOptions<T>]
|
|
161
|
+
filter?: Value<boolean, [options: StandardLinkTransportInterceptorOptions<T>]> | undefined;
|
|
155
162
|
/**
|
|
156
163
|
* Only requests with the same scope are deduplicated together.
|
|
157
164
|
* On the server, return a value unique to the incoming request so different users never share a response.
|
|
158
165
|
*
|
|
159
166
|
* @default () => undefined
|
|
160
167
|
*/
|
|
161
|
-
scope?: (options: StandardLinkTransportInterceptorOptions<T>) => unknown;
|
|
168
|
+
scope?: ((options: StandardLinkTransportInterceptorOptions<T>) => unknown) | undefined;
|
|
162
169
|
/**
|
|
163
170
|
* How long (in ms) to wait for more identical requests before sending,
|
|
164
171
|
* counted from the first queued request.
|
|
@@ -166,7 +173,7 @@ interface DedupeLinkPluginOptions<T extends ClientContext> {
|
|
|
166
173
|
*
|
|
167
174
|
* @default 0
|
|
168
175
|
*/
|
|
169
|
-
wait?: number;
|
|
176
|
+
wait?: number | undefined;
|
|
170
177
|
}
|
|
171
178
|
/**
|
|
172
179
|
* Prevents redundant requests by deduplicating similar in-flight requests,
|
|
@@ -195,7 +202,7 @@ interface RequestCompressionLinkPluginOptions<T extends ClientContext> {
|
|
|
195
202
|
*
|
|
196
203
|
* @default 'gzip'
|
|
197
204
|
*/
|
|
198
|
-
encoding?: 'gzip' | 'deflate' | 'deflate-raw';
|
|
205
|
+
encoding?: 'gzip' | 'deflate' | 'deflate-raw' | undefined;
|
|
199
206
|
/**
|
|
200
207
|
* The minimum request size in bytes required to trigger compression.
|
|
201
208
|
* Requests smaller than this threshold will not be compressed to avoid overhead.
|
|
@@ -203,7 +210,7 @@ interface RequestCompressionLinkPluginOptions<T extends ClientContext> {
|
|
|
203
210
|
*
|
|
204
211
|
* @default 1024 (1KB)
|
|
205
212
|
*/
|
|
206
|
-
threshold?: number;
|
|
213
|
+
threshold?: number | undefined;
|
|
207
214
|
/**
|
|
208
215
|
* Determines whether a request with the given Content-Type should be compressed.
|
|
209
216
|
* Only consulted for binary transfers (streams, files, and file form-data parts).
|
|
@@ -211,7 +218,7 @@ interface RequestCompressionLinkPluginOptions<T extends ClientContext> {
|
|
|
211
218
|
*
|
|
212
219
|
* @default isCompressibleContentType (covers common text-based formats)
|
|
213
220
|
*/
|
|
214
|
-
isCompressibleContentType?: (contentType: string | null | undefined, options: StandardLinkTransportInterceptorOptions<T>) => boolean;
|
|
221
|
+
isCompressibleContentType?: ((contentType: string | null | undefined, options: StandardLinkTransportInterceptorOptions<T>) => boolean) | undefined;
|
|
215
222
|
}
|
|
216
223
|
/**
|
|
217
224
|
* Compresses request bodies before sending them to the server,
|
|
@@ -239,7 +246,7 @@ interface ResponseCompressionLinkPluginOptions<_T extends ClientContext> {
|
|
|
239
246
|
*
|
|
240
247
|
* @default ['gzip', 'deflate']
|
|
241
248
|
*/
|
|
242
|
-
encodings?: readonly ('gzip' | 'deflate' | 'deflate-raw')[];
|
|
249
|
+
encodings?: readonly ('gzip' | 'deflate' | 'deflate-raw')[] | undefined;
|
|
243
250
|
}
|
|
244
251
|
/**
|
|
245
252
|
* Advertises Accept-Encoding on requests and decompresses response bodies
|
|
@@ -286,7 +293,7 @@ interface RetryLinkPluginContext {
|
|
|
286
293
|
*
|
|
287
294
|
* @default 0
|
|
288
295
|
*/
|
|
289
|
-
retry?: Value<Promisable<number>, [Omit<StandardLinkInterceptorOptions<RetryLinkPluginContext>, 'next'>]
|
|
296
|
+
retry?: Value<Promisable<number>, [Omit<StandardLinkInterceptorOptions<RetryLinkPluginContext>, 'next'>]> | undefined;
|
|
290
297
|
/**
|
|
291
298
|
* Delay (in ms) before retrying.
|
|
292
299
|
*
|
|
@@ -295,17 +302,17 @@ interface RetryLinkPluginContext {
|
|
|
295
302
|
*
|
|
296
303
|
* @default (o) => o.lastEventRetry ?? 2000
|
|
297
304
|
*/
|
|
298
|
-
retryDelay?: Value<Promisable<number>, [RetryLinkPluginAttemptOptions<RetryLinkPluginContext>]
|
|
305
|
+
retryDelay?: Value<Promisable<number>, [RetryLinkPluginAttemptOptions<RetryLinkPluginContext>]> | undefined;
|
|
299
306
|
/**
|
|
300
307
|
* Determine whether to retry.
|
|
301
308
|
*
|
|
302
|
-
* @default
|
|
309
|
+
* @default (o) => isRetryableError(o.error)
|
|
303
310
|
*/
|
|
304
|
-
shouldRetry?: Value<Promisable<boolean>, [RetryLinkPluginAttemptOptions<RetryLinkPluginContext>]
|
|
311
|
+
shouldRetry?: Value<Promisable<boolean>, [RetryLinkPluginAttemptOptions<RetryLinkPluginContext>]> | undefined;
|
|
305
312
|
/**
|
|
306
313
|
* Hook called before each retry. Can return a cleanup callback.
|
|
307
314
|
*/
|
|
308
|
-
onRetry?: (options: RetryLinkPluginAttemptOptions<RetryLinkPluginContext>) => void | ((isSuccess: boolean) => void);
|
|
315
|
+
onRetry?: ((options: RetryLinkPluginAttemptOptions<RetryLinkPluginContext>) => void | ((isSuccess: boolean) => void)) | undefined;
|
|
309
316
|
}
|
|
310
317
|
interface RetryLinkPluginOptions<_T extends RetryLinkPluginContext> {
|
|
311
318
|
/**
|
|
@@ -313,6 +320,13 @@ interface RetryLinkPluginOptions<_T extends RetryLinkPluginContext> {
|
|
|
313
320
|
*/
|
|
314
321
|
default?: RetryLinkPluginContext | undefined;
|
|
315
322
|
}
|
|
323
|
+
/**
|
|
324
|
+
* Default `shouldRetry` check of `RetryLinkPlugin`. Returns `false` only for errors
|
|
325
|
+
* from a 4xx response other than `408` and `429`.
|
|
326
|
+
*
|
|
327
|
+
* @see {@link https://orpc.dev/docs/plugins/retry#client-error-responses | Retry Plugin - Client Error Responses}
|
|
328
|
+
*/
|
|
329
|
+
declare function isRetryableError(error: unknown): boolean;
|
|
316
330
|
/**
|
|
317
331
|
* Automatically retries failed requests based on customizable retry strategies,
|
|
318
332
|
* improving the resilience of your application.
|
|
@@ -341,7 +355,7 @@ interface RetryAfterLinkPluginOptions<T extends ClientContext> {
|
|
|
341
355
|
condition?: Value<boolean, [
|
|
342
356
|
response: StandardLazyResponse,
|
|
343
357
|
options: StandardLinkTransportInterceptorOptions<T>
|
|
344
|
-
]
|
|
358
|
+
]> | undefined;
|
|
345
359
|
/**
|
|
346
360
|
* Maximum attempts before giving up retries.
|
|
347
361
|
*
|
|
@@ -350,7 +364,7 @@ interface RetryAfterLinkPluginOptions<T extends ClientContext> {
|
|
|
350
364
|
maxAttempts?: Value<number, [
|
|
351
365
|
response: StandardLazyResponse,
|
|
352
366
|
options: StandardLinkTransportInterceptorOptions<T>
|
|
353
|
-
]
|
|
367
|
+
]> | undefined;
|
|
354
368
|
/**
|
|
355
369
|
* Maximum timeout in milliseconds to wait before giving up retries.
|
|
356
370
|
*
|
|
@@ -359,7 +373,7 @@ interface RetryAfterLinkPluginOptions<T extends ClientContext> {
|
|
|
359
373
|
timeout?: Value<number, [
|
|
360
374
|
response: StandardLazyResponse,
|
|
361
375
|
options: StandardLinkTransportInterceptorOptions<T>
|
|
362
|
-
]
|
|
376
|
+
]> | undefined;
|
|
363
377
|
}
|
|
364
378
|
/**
|
|
365
379
|
* The Retry After Link Plugin automatically retries requests based on server `retry-after` header.
|
|
@@ -402,5 +416,5 @@ declare class TimeoutLinkPlugin<T extends ClientContext> implements StandardLink
|
|
|
402
416
|
init(options: StandardLinkOptions<T>): StandardLinkOptions<T>;
|
|
403
417
|
}
|
|
404
418
|
|
|
405
|
-
export { BatchLinkPlugin, RetryLinkPlugin as ClientRetryPlugin, DedupeLinkPlugin, DedupeLinkPlugin as DedupeRequestsPlugin, RequestCompressionLinkPlugin, ResponseCompressionLinkPlugin, RetryAfterLinkPlugin, RetryAfterLinkPlugin as RetryAfterPlugin, RetryLinkPlugin, TimeoutLinkPlugin };
|
|
406
|
-
export type { BatchLinkPluginGroup,
|
|
419
|
+
export { BATCH_HEADER, BatchLinkPlugin, RetryLinkPlugin as ClientRetryPlugin, DEFAULT_BATCH_MAX_SIZE, DedupeLinkPlugin, DedupeLinkPlugin as DedupeRequestsPlugin, RequestCompressionLinkPlugin, ResponseCompressionLinkPlugin, RetryAfterLinkPlugin, RetryAfterLinkPlugin as RetryAfterPlugin, RetryLinkPlugin, TimeoutLinkPlugin, isRetryableError };
|
|
420
|
+
export type { BatchLinkPluginGroup, BatchLinkPluginOptions, RetryLinkPluginContext as ClientRetryPluginContext, DedupeLinkPluginGroup, DedupeLinkPluginOptions, RequestCompressionLinkPluginOptions, ResponseCompressionLinkPluginOptions, RetryAfterLinkPluginOptions, RetryLinkPluginAttemptOptions, RetryLinkPluginContext, RetryLinkPluginOptions, TimeoutLinkPluginOptions };
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -2,8 +2,10 @@ import { toArray, value, splitInHalf, promiseWithResolvers, safeEncodeURICompone
|
|
|
2
2
|
import { parseStandardUrl, flattenStandardHeader, generateContentDisposition, getEventMeta } from '@standard-server/core';
|
|
3
3
|
import { ClientPeer, isServerPeerSendMessage, decodePeerMessage } from '@standard-server/peer';
|
|
4
4
|
import { toFetchHeaders, toStandardBody } from '@standard-server/fetch';
|
|
5
|
-
import { C as COMMON_ERROR_STATUS_MAP } from '../shared/client.
|
|
5
|
+
import { O as ORPCError, R as ResponseError, C as COMMON_ERROR_STATUS_MAP } from '../shared/client.LF04eOvL.mjs';
|
|
6
6
|
|
|
7
|
+
const BATCH_HEADER = "orpc-batch";
|
|
8
|
+
const DEFAULT_BATCH_MAX_SIZE = 10;
|
|
7
9
|
class BatchLinkPlugin {
|
|
8
10
|
name = "~batch";
|
|
9
11
|
groups;
|
|
@@ -11,7 +13,6 @@ class BatchLinkPlugin {
|
|
|
11
13
|
scope;
|
|
12
14
|
maxSize;
|
|
13
15
|
wait;
|
|
14
|
-
mode;
|
|
15
16
|
batchUrl;
|
|
16
17
|
maxUrlLength;
|
|
17
18
|
batchHeaders;
|
|
@@ -22,9 +23,8 @@ class BatchLinkPlugin {
|
|
|
22
23
|
this.groups = options.groups;
|
|
23
24
|
this.filter = options.filter ?? (() => true);
|
|
24
25
|
this.scope = options.scope ?? (() => void 0);
|
|
25
|
-
this.maxSize = options.maxSize ??
|
|
26
|
+
this.maxSize = options.maxSize ?? DEFAULT_BATCH_MAX_SIZE;
|
|
26
27
|
this.wait = options.wait ?? 0;
|
|
27
|
-
this.mode = options.mode ?? "streaming";
|
|
28
28
|
this.batchUrl = options.url ?? ((options2) => {
|
|
29
29
|
const [pathname] = parseStandardUrl(options2[0].request.url);
|
|
30
30
|
return `${pathname}/__batch__`;
|
|
@@ -141,7 +141,6 @@ class BatchLinkPlugin {
|
|
|
141
141
|
}
|
|
142
142
|
const url = await value(this.batchUrl, subOptionsList);
|
|
143
143
|
const headers = await value(this.batchHeaders, subOptionsList);
|
|
144
|
-
const mode = value(this.mode, subOptionsList);
|
|
145
144
|
let suppressErrorFromCurrentBatch = false;
|
|
146
145
|
const controller = new AbortController();
|
|
147
146
|
const pendingMessages = [];
|
|
@@ -185,7 +184,7 @@ class BatchLinkPlugin {
|
|
|
185
184
|
const request = {
|
|
186
185
|
url,
|
|
187
186
|
method,
|
|
188
|
-
headers: { ...headers, "
|
|
187
|
+
headers: { ...headers, [BATCH_HEADER]: "1" },
|
|
189
188
|
signal: controller.signal
|
|
190
189
|
};
|
|
191
190
|
if (method === "GET") {
|
|
@@ -745,6 +744,14 @@ function parseContentEncodings(header) {
|
|
|
745
744
|
return header.split(",").map((part) => part.trim().toLowerCase());
|
|
746
745
|
}
|
|
747
746
|
|
|
747
|
+
function isRetryableError(error) {
|
|
748
|
+
const responseError = error instanceof ORPCError ? error.cause : error;
|
|
749
|
+
if (!(responseError instanceof ResponseError)) {
|
|
750
|
+
return true;
|
|
751
|
+
}
|
|
752
|
+
const { status } = responseError.response;
|
|
753
|
+
return status < 400 || status >= 500 || status === COMMON_ERROR_STATUS_MAP.TIMEOUT || status === COMMON_ERROR_STATUS_MAP.TOO_MANY_REQUESTS;
|
|
754
|
+
}
|
|
748
755
|
class RetryLinkPlugin {
|
|
749
756
|
defaultRetry;
|
|
750
757
|
defaultRetryDelay;
|
|
@@ -754,7 +761,7 @@ class RetryLinkPlugin {
|
|
|
754
761
|
constructor(options = {}) {
|
|
755
762
|
this.defaultRetry = options.default?.retry ?? 0;
|
|
756
763
|
this.defaultRetryDelay = options.default?.retryDelay ?? ((o) => o.lastEventRetry ?? 2e3);
|
|
757
|
-
this.defaultShouldRetry = options.default?.shouldRetry ??
|
|
764
|
+
this.defaultShouldRetry = options.default?.shouldRetry ?? ((o) => isRetryableError(o.error));
|
|
758
765
|
this.defaultOnRetry = options.default?.onRetry;
|
|
759
766
|
}
|
|
760
767
|
init(options) {
|
|
@@ -774,13 +781,14 @@ class RetryLinkPlugin {
|
|
|
774
781
|
let lastEventRetry;
|
|
775
782
|
let callback;
|
|
776
783
|
let attempt = 1;
|
|
784
|
+
let isIteratorAborted = false;
|
|
777
785
|
const callNext = async (initialError) => {
|
|
778
786
|
let currentError = initialError;
|
|
779
787
|
while (true) {
|
|
780
788
|
const updatedCallOptions = { ...callOptions, lastEventId };
|
|
781
789
|
let retryDelayMs = 0;
|
|
782
790
|
if (currentError) {
|
|
783
|
-
if (attempt > maxAttempts) {
|
|
791
|
+
if (isIteratorAborted || attempt > maxAttempts) {
|
|
784
792
|
throw currentError.error;
|
|
785
793
|
}
|
|
786
794
|
const attemptOptions = {
|
|
@@ -802,6 +810,9 @@ class RetryLinkPlugin {
|
|
|
802
810
|
try {
|
|
803
811
|
if (currentError) {
|
|
804
812
|
await sleep(retryDelayMs, { signal: updatedCallOptions.signal });
|
|
813
|
+
if (isIteratorAborted) {
|
|
814
|
+
throw currentError.error;
|
|
815
|
+
}
|
|
805
816
|
attempt++;
|
|
806
817
|
}
|
|
807
818
|
currentError = void 0;
|
|
@@ -822,7 +833,6 @@ class RetryLinkPlugin {
|
|
|
822
833
|
return output;
|
|
823
834
|
}
|
|
824
835
|
let current = output;
|
|
825
|
-
let isIteratorAborted = false;
|
|
826
836
|
return override(() => current, new AsyncIteratorClass(
|
|
827
837
|
async () => {
|
|
828
838
|
while (true) {
|
|
@@ -958,4 +968,4 @@ class TimeoutLinkPlugin {
|
|
|
958
968
|
}
|
|
959
969
|
}
|
|
960
970
|
|
|
961
|
-
export { BatchLinkPlugin, RetryLinkPlugin as ClientRetryPlugin, DedupeLinkPlugin, DedupeLinkPlugin as DedupeRequestsPlugin, RequestCompressionLinkPlugin, ResponseCompressionLinkPlugin, RetryAfterLinkPlugin, RetryAfterLinkPlugin as RetryAfterPlugin, RetryLinkPlugin, TimeoutLinkPlugin };
|
|
971
|
+
export { BATCH_HEADER, BatchLinkPlugin, RetryLinkPlugin as ClientRetryPlugin, DEFAULT_BATCH_MAX_SIZE, DedupeLinkPlugin, DedupeLinkPlugin as DedupeRequestsPlugin, RequestCompressionLinkPlugin, ResponseCompressionLinkPlugin, RetryAfterLinkPlugin, RetryAfterLinkPlugin as RetryAfterPlugin, RetryLinkPlugin, TimeoutLinkPlugin, isRetryableError };
|
|
@@ -10,7 +10,7 @@ interface ClientOptions<T extends ClientContext> {
|
|
|
10
10
|
context: T;
|
|
11
11
|
}
|
|
12
12
|
type FriendlyClientOptions<T extends ClientContext> = Omit<ClientOptions<T>, 'context'> & (object extends T ? {
|
|
13
|
-
context?: T;
|
|
13
|
+
context?: T | undefined;
|
|
14
14
|
} : {
|
|
15
15
|
context: T;
|
|
16
16
|
});
|
|
@@ -134,7 +134,7 @@ type ORPCErrorCode = Registry extends {
|
|
|
134
134
|
ORPCErrorCode: infer T extends string;
|
|
135
135
|
} ? T : (keyof typeof COMMON_ERROR_STATUS_MAP) | (string & {});
|
|
136
136
|
type ORPCErrorOptions<TData> = ErrorOptions & {
|
|
137
|
-
message?: string;
|
|
137
|
+
message?: string | undefined;
|
|
138
138
|
} & (undefined extends TData ? {
|
|
139
139
|
data?: TData;
|
|
140
140
|
} : {
|
|
@@ -186,23 +186,48 @@ interface ORPCErrorJSON<TCode extends string, TData> extends Pick<ORPCError<TCod
|
|
|
186
186
|
}
|
|
187
187
|
type AnyORPCError = ORPCError<any, any>;
|
|
188
188
|
type AnyORPCErrorJSON = ORPCErrorJSON<any, any>;
|
|
189
|
-
interface
|
|
190
|
-
|
|
189
|
+
interface ResponseErrorOptions extends ErrorOptions {
|
|
190
|
+
/**
|
|
191
|
+
* @default inferred from the response status
|
|
192
|
+
*/
|
|
193
|
+
message?: string | undefined;
|
|
194
|
+
response: StandardResponse;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Error carrying the resolved response a link received. Links set it as the `cause`
|
|
198
|
+
* of an `ORPCError` decoded from an error response, so details that are not part
|
|
199
|
+
* of the error itself, such as its status or headers, stay available.
|
|
200
|
+
*
|
|
201
|
+
* @see {@link https://orpc.dev/docs/rpc/link#error-responses | RPC Link - Error Responses}
|
|
202
|
+
* @see {@link https://orpc.dev/docs/openapi/link#error-responses | OpenAPI Link - Error Responses}
|
|
203
|
+
*/
|
|
204
|
+
declare class ResponseError extends Error {
|
|
205
|
+
readonly name: string;
|
|
191
206
|
response: StandardResponse;
|
|
207
|
+
constructor(options: ResponseErrorOptions);
|
|
208
|
+
}
|
|
209
|
+
interface MalformedResponseErrorOptions extends ResponseErrorOptions {
|
|
210
|
+
/**
|
|
211
|
+
* @default inferred from the response body or status
|
|
212
|
+
*/
|
|
213
|
+
message?: string | undefined;
|
|
192
214
|
}
|
|
193
215
|
/**
|
|
194
|
-
* Error
|
|
195
|
-
*
|
|
196
|
-
* `
|
|
216
|
+
* Error thrown by links when a response does not follow the expected oRPC format,
|
|
217
|
+
* for example when a proxy or gateway answers instead of your handler. Extends
|
|
218
|
+
* `ResponseError`, so it carries the resolved response. Unless overridden via
|
|
219
|
+
* `options.message`, the message is inferred from the response body or status.
|
|
220
|
+
*
|
|
221
|
+
* Unlike `ORPCError`, it reaches a handler's callers as a generic `INTERNAL_SERVER_ERROR`
|
|
222
|
+
* when thrown from the handler, so an upstream's response is not sent to them.
|
|
197
223
|
*
|
|
198
224
|
* @see {@link https://orpc.dev/docs/rpc/link#malformed-responses | RPC Link - Malformed Responses}
|
|
199
225
|
* @see {@link https://orpc.dev/docs/openapi/link#malformed-responses | OpenAPI Link - Malformed Responses}
|
|
200
226
|
*/
|
|
201
|
-
declare class MalformedResponseError extends
|
|
227
|
+
declare class MalformedResponseError extends ResponseError {
|
|
202
228
|
readonly name = "MalformedResponseError";
|
|
203
|
-
response: StandardResponse;
|
|
204
229
|
constructor(options: MalformedResponseErrorOptions);
|
|
205
230
|
}
|
|
206
231
|
|
|
207
|
-
export {
|
|
208
|
-
export type { AnyORPCError as A, ClientContext as C, FriendlyClientOptions as F, InferClientContext as I,
|
|
232
|
+
export { MalformedResponseError as M, ResponseError as R, ORPCError as h, COMMON_ERROR_STATUS_MAP as j };
|
|
233
|
+
export type { AnyORPCError as A, ClientContext as C, FriendlyClientOptions as F, InferClientContext as I, NestedClient as N, ORPCErrorCode as O, ClientOptions as a, ClientLink as b, AnyNestedClient as c, InferClientError as d, Client as e, ClientRest as f, ORPCErrorJSON as g, AnyORPCErrorJSON as i, InferClientBodyInputs as k, InferClientBodyOutputs as l, InferClientErrors as m, InferClientInputs as n, InferClientOutputs as o, MalformedResponseErrorOptions as p, ORPCErrorOptions as q, ResponseErrorOptions as r };
|
|
@@ -10,7 +10,7 @@ interface ClientOptions<T extends ClientContext> {
|
|
|
10
10
|
context: T;
|
|
11
11
|
}
|
|
12
12
|
type FriendlyClientOptions<T extends ClientContext> = Omit<ClientOptions<T>, 'context'> & (object extends T ? {
|
|
13
|
-
context?: T;
|
|
13
|
+
context?: T | undefined;
|
|
14
14
|
} : {
|
|
15
15
|
context: T;
|
|
16
16
|
});
|
|
@@ -134,7 +134,7 @@ type ORPCErrorCode = Registry extends {
|
|
|
134
134
|
ORPCErrorCode: infer T extends string;
|
|
135
135
|
} ? T : (keyof typeof COMMON_ERROR_STATUS_MAP) | (string & {});
|
|
136
136
|
type ORPCErrorOptions<TData> = ErrorOptions & {
|
|
137
|
-
message?: string;
|
|
137
|
+
message?: string | undefined;
|
|
138
138
|
} & (undefined extends TData ? {
|
|
139
139
|
data?: TData;
|
|
140
140
|
} : {
|
|
@@ -186,23 +186,48 @@ interface ORPCErrorJSON<TCode extends string, TData> extends Pick<ORPCError<TCod
|
|
|
186
186
|
}
|
|
187
187
|
type AnyORPCError = ORPCError<any, any>;
|
|
188
188
|
type AnyORPCErrorJSON = ORPCErrorJSON<any, any>;
|
|
189
|
-
interface
|
|
190
|
-
|
|
189
|
+
interface ResponseErrorOptions extends ErrorOptions {
|
|
190
|
+
/**
|
|
191
|
+
* @default inferred from the response status
|
|
192
|
+
*/
|
|
193
|
+
message?: string | undefined;
|
|
194
|
+
response: StandardResponse;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Error carrying the resolved response a link received. Links set it as the `cause`
|
|
198
|
+
* of an `ORPCError` decoded from an error response, so details that are not part
|
|
199
|
+
* of the error itself, such as its status or headers, stay available.
|
|
200
|
+
*
|
|
201
|
+
* @see {@link https://orpc.dev/docs/rpc/link#error-responses | RPC Link - Error Responses}
|
|
202
|
+
* @see {@link https://orpc.dev/docs/openapi/link#error-responses | OpenAPI Link - Error Responses}
|
|
203
|
+
*/
|
|
204
|
+
declare class ResponseError extends Error {
|
|
205
|
+
readonly name: string;
|
|
191
206
|
response: StandardResponse;
|
|
207
|
+
constructor(options: ResponseErrorOptions);
|
|
208
|
+
}
|
|
209
|
+
interface MalformedResponseErrorOptions extends ResponseErrorOptions {
|
|
210
|
+
/**
|
|
211
|
+
* @default inferred from the response body or status
|
|
212
|
+
*/
|
|
213
|
+
message?: string | undefined;
|
|
192
214
|
}
|
|
193
215
|
/**
|
|
194
|
-
* Error
|
|
195
|
-
*
|
|
196
|
-
* `
|
|
216
|
+
* Error thrown by links when a response does not follow the expected oRPC format,
|
|
217
|
+
* for example when a proxy or gateway answers instead of your handler. Extends
|
|
218
|
+
* `ResponseError`, so it carries the resolved response. Unless overridden via
|
|
219
|
+
* `options.message`, the message is inferred from the response body or status.
|
|
220
|
+
*
|
|
221
|
+
* Unlike `ORPCError`, it reaches a handler's callers as a generic `INTERNAL_SERVER_ERROR`
|
|
222
|
+
* when thrown from the handler, so an upstream's response is not sent to them.
|
|
197
223
|
*
|
|
198
224
|
* @see {@link https://orpc.dev/docs/rpc/link#malformed-responses | RPC Link - Malformed Responses}
|
|
199
225
|
* @see {@link https://orpc.dev/docs/openapi/link#malformed-responses | OpenAPI Link - Malformed Responses}
|
|
200
226
|
*/
|
|
201
|
-
declare class MalformedResponseError extends
|
|
227
|
+
declare class MalformedResponseError extends ResponseError {
|
|
202
228
|
readonly name = "MalformedResponseError";
|
|
203
|
-
response: StandardResponse;
|
|
204
229
|
constructor(options: MalformedResponseErrorOptions);
|
|
205
230
|
}
|
|
206
231
|
|
|
207
|
-
export {
|
|
208
|
-
export type { AnyORPCError as A, ClientContext as C, FriendlyClientOptions as F, InferClientContext as I,
|
|
232
|
+
export { MalformedResponseError as M, ResponseError as R, ORPCError as h, COMMON_ERROR_STATUS_MAP as j };
|
|
233
|
+
export type { AnyORPCError as A, ClientContext as C, FriendlyClientOptions as F, InferClientContext as I, NestedClient as N, ORPCErrorCode as O, ClientOptions as a, ClientLink as b, AnyNestedClient as c, InferClientError as d, Client as e, ClientRest as f, ORPCErrorJSON as g, AnyORPCErrorJSON as i, InferClientBodyInputs as k, InferClientBodyOutputs as l, InferClientErrors as m, InferClientInputs as n, InferClientOutputs as o, MalformedResponseErrorOptions as p, ORPCErrorOptions as q, ResponseErrorOptions as r };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { sortPlugins, runWithSpan, ORPC_NAME, getTracer, isAsyncIteratorObject, override, traceAsyncIterator, traceReadableStream, intercept, value, pathToHttpPath, stringifyJSON } from '@orpc/shared';
|
|
2
2
|
import { mergeStandardHeaders, parseStandardUrl } from '@standard-server/core';
|
|
3
3
|
import { toStandardHeaders } from '@standard-server/fetch';
|
|
4
|
-
import {
|
|
4
|
+
import { M as MalformedResponseError, R as ResponseError } from './client.LF04eOvL.mjs';
|
|
5
|
+
import { R as RPCSerializer, i as isORPCErrorJson, c as createORPCErrorFromJson } from './client._wG5INmC.mjs';
|
|
5
6
|
|
|
6
7
|
class CompositeStandardLinkPlugin {
|
|
7
8
|
name = "~composite";
|
|
@@ -30,7 +31,7 @@ class StandardLink {
|
|
|
30
31
|
interceptors;
|
|
31
32
|
transportInterceptors;
|
|
32
33
|
/**
|
|
33
|
-
* @throws ORPCError, transport-level errors (network failures, timeouts, etc.)
|
|
34
|
+
* @throws ORPCError, MalformedResponseError, transport-level errors (network failures, timeouts, etc.)
|
|
34
35
|
*/
|
|
35
36
|
call(path, input, options) {
|
|
36
37
|
return runWithSpan(`${ORPC_NAME}.${path.join("/")}`, (span) => {
|
|
@@ -140,7 +141,7 @@ class RPCLinkCodec {
|
|
|
140
141
|
try {
|
|
141
142
|
return this.serializer.deserialize(body);
|
|
142
143
|
} catch (cause) {
|
|
143
|
-
throw
|
|
144
|
+
throw new MalformedResponseError({
|
|
144
145
|
message: "Invalid RPC response format.",
|
|
145
146
|
response: { status: response.status, headers: response.headers, body },
|
|
146
147
|
cause
|
|
@@ -149,12 +150,14 @@ class RPCLinkCodec {
|
|
|
149
150
|
})();
|
|
150
151
|
if (!isOk) {
|
|
151
152
|
if (isORPCErrorJson(deserialized)) {
|
|
152
|
-
return {
|
|
153
|
+
return {
|
|
154
|
+
kind: "error",
|
|
155
|
+
error: createORPCErrorFromJson(deserialized, {
|
|
156
|
+
cause: new ResponseError({ response: { status: response.status, headers: response.headers, body } })
|
|
157
|
+
})
|
|
158
|
+
};
|
|
153
159
|
}
|
|
154
|
-
|
|
155
|
-
kind: "error",
|
|
156
|
-
error: createORPCErrorFromMalformedResponse({ response: { headers: response.headers, status: response.status, body } })
|
|
157
|
-
};
|
|
160
|
+
throw new MalformedResponseError({ response: { headers: response.headers, status: response.status, body } });
|
|
158
161
|
}
|
|
159
162
|
return { kind: "output", output: deserialized };
|
|
160
163
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Promisable, OrderablePlugin, Interceptor } from '@orpc/shared';
|
|
2
2
|
import { StandardRequest, StandardLazyResponse } from '@standard-server/core';
|
|
3
|
-
import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.
|
|
3
|
+
import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.BoHJeq15.mjs';
|
|
4
4
|
|
|
5
5
|
type StandardLinkCodecDecodedResponse = {
|
|
6
6
|
kind: 'output';
|
|
@@ -72,13 +72,13 @@ interface StandardLinkOptions<T extends ClientContext> {
|
|
|
72
72
|
* Interceptors that execute around the entire call, including transport and codec.
|
|
73
73
|
* Useful for error handling, logging, metrics, ...
|
|
74
74
|
*/
|
|
75
|
-
interceptors?: StandardLinkInterceptor<T>[];
|
|
75
|
+
interceptors?: StandardLinkInterceptor<T>[] | undefined;
|
|
76
76
|
/**
|
|
77
77
|
* Interceptors that execute around the transport layer, after encoding and before decoding.
|
|
78
78
|
* Useful for modifying the request or response, adding transport-level logging, ...
|
|
79
79
|
*/
|
|
80
|
-
transportInterceptors?: StandardLinkTransportInterceptor<T>[];
|
|
81
|
-
plugins?: StandardLinkPlugin<T>[];
|
|
80
|
+
transportInterceptors?: StandardLinkTransportInterceptor<T>[] | undefined;
|
|
81
|
+
plugins?: StandardLinkPlugin<T>[] | undefined;
|
|
82
82
|
}
|
|
83
83
|
declare class StandardLink<T extends ClientContext> implements ClientLink<T> {
|
|
84
84
|
private readonly codec;
|
|
@@ -87,7 +87,7 @@ declare class StandardLink<T extends ClientContext> implements ClientLink<T> {
|
|
|
87
87
|
private readonly transportInterceptors;
|
|
88
88
|
constructor(codec: StandardLinkCodec<T>, transport: StandardLinkTransport<T>, options?: StandardLinkOptions<T>);
|
|
89
89
|
/**
|
|
90
|
-
* @throws ORPCError, transport-level errors (network failures, timeouts, etc.)
|
|
90
|
+
* @throws ORPCError, MalformedResponseError, transport-level errors (network failures, timeouts, etc.)
|
|
91
91
|
*/
|
|
92
92
|
call(path: string[], input: unknown, options: ClientOptions<T>): Promise<unknown>;
|
|
93
93
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Promisable, OrderablePlugin, Interceptor } from '@orpc/shared';
|
|
2
2
|
import { StandardRequest, StandardLazyResponse } from '@standard-server/core';
|
|
3
|
-
import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.
|
|
3
|
+
import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.BoHJeq15.js';
|
|
4
4
|
|
|
5
5
|
type StandardLinkCodecDecodedResponse = {
|
|
6
6
|
kind: 'output';
|
|
@@ -72,13 +72,13 @@ interface StandardLinkOptions<T extends ClientContext> {
|
|
|
72
72
|
* Interceptors that execute around the entire call, including transport and codec.
|
|
73
73
|
* Useful for error handling, logging, metrics, ...
|
|
74
74
|
*/
|
|
75
|
-
interceptors?: StandardLinkInterceptor<T>[];
|
|
75
|
+
interceptors?: StandardLinkInterceptor<T>[] | undefined;
|
|
76
76
|
/**
|
|
77
77
|
* Interceptors that execute around the transport layer, after encoding and before decoding.
|
|
78
78
|
* Useful for modifying the request or response, adding transport-level logging, ...
|
|
79
79
|
*/
|
|
80
|
-
transportInterceptors?: StandardLinkTransportInterceptor<T>[];
|
|
81
|
-
plugins?: StandardLinkPlugin<T>[];
|
|
80
|
+
transportInterceptors?: StandardLinkTransportInterceptor<T>[] | undefined;
|
|
81
|
+
plugins?: StandardLinkPlugin<T>[] | undefined;
|
|
82
82
|
}
|
|
83
83
|
declare class StandardLink<T extends ClientContext> implements ClientLink<T> {
|
|
84
84
|
private readonly codec;
|
|
@@ -87,7 +87,7 @@ declare class StandardLink<T extends ClientContext> implements ClientLink<T> {
|
|
|
87
87
|
private readonly transportInterceptors;
|
|
88
88
|
constructor(codec: StandardLinkCodec<T>, transport: StandardLinkTransport<T>, options?: StandardLinkOptions<T>);
|
|
89
89
|
/**
|
|
90
|
-
* @throws ORPCError, transport-level errors (network failures, timeouts, etc.)
|
|
90
|
+
* @throws ORPCError, MalformedResponseError, transport-level errors (network failures, timeouts, etc.)
|
|
91
91
|
*/
|
|
92
92
|
call(path: string[], input: unknown, options: ClientOptions<T>): Promise<unknown>;
|
|
93
93
|
}
|