@orpc/client 2.0.0-beta.4 → 2.0.0-beta.41
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 +97 -94
- package/dist/adapters/fetch/index.d.mts +16 -33
- package/dist/adapters/fetch/index.d.ts +16 -33
- package/dist/adapters/fetch/index.mjs +33 -30
- package/dist/adapters/message-port/index.d.mts +13 -8
- package/dist/adapters/message-port/index.d.ts +13 -8
- package/dist/adapters/message-port/index.mjs +27 -17
- package/dist/adapters/standard/index.d.mts +9 -10
- package/dist/adapters/standard/index.d.ts +9 -10
- package/dist/adapters/standard/index.mjs +5 -5
- package/dist/adapters/websocket/index.d.mts +33 -18
- package/dist/adapters/websocket/index.d.ts +33 -18
- package/dist/adapters/websocket/index.mjs +45 -24
- package/dist/index.d.mts +62 -61
- package/dist/index.d.ts +62 -61
- package/dist/index.mjs +47 -54
- package/dist/plugins/index.d.mts +174 -13
- package/dist/plugins/index.d.ts +174 -13
- package/dist/plugins/index.mjs +580 -198
- package/dist/shared/{client.BdItY5DT.d.mts → client.BPa_Mmuh.d.mts} +25 -4
- package/dist/shared/{client.BdItY5DT.d.ts → client.BPa_Mmuh.d.ts} +25 -4
- package/dist/shared/{client.Cby_-GGh.d.mts → client.BjbdW5Rj.d.mts} +2 -2
- package/dist/shared/{client.DXhchJ84.mjs → client.Bstqyaro.mjs} +25 -30
- package/dist/shared/{client.Dnfj8jnT.mjs → client.DD2eNne_.mjs} +20 -15
- package/dist/shared/{client.CPF3hX6O.d.ts → client.DiHfJmHK.d.ts} +2 -2
- package/dist/shared/client.DpkGsZt-.mjs +486 -0
- package/dist/shared/{client.8ug8I-zu.d.mts → client.Dw9_40WO.d.mts} +57 -16
- package/dist/shared/{client.8ug8I-zu.d.ts → client.Dw9_40WO.d.ts} +57 -16
- package/package.json +22 -8
- package/dist/shared/client.DMXKFDyV.mjs +0 -343
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StandardBody } from '@
|
|
1
|
+
import { StandardBody } from '@standard-server/core';
|
|
2
2
|
import { Segment } from '@orpc/shared';
|
|
3
3
|
|
|
4
4
|
type RPCJsonSerializationMeta = [type: string, ...path: Segment[]];
|
|
@@ -16,7 +16,10 @@ type RPCJsonSerialization = {
|
|
|
16
16
|
interface RPCJsonSerializerHandler {
|
|
17
17
|
condition(value: unknown): boolean;
|
|
18
18
|
serialize(value: any): unknown;
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* `serialized` comes from the wire, so validate its type and throw on mismatch.
|
|
21
|
+
*/
|
|
22
|
+
deserialize(serialized: unknown): unknown;
|
|
20
23
|
/**
|
|
21
24
|
* If false, the result of this serializer will not be further processed by other serializers,
|
|
22
25
|
* even if it matches their conditions and treat it as final serialized value.
|
|
@@ -60,10 +63,10 @@ interface RPCJsonSerializerOptions {
|
|
|
60
63
|
*
|
|
61
64
|
* **Disabling:** Set a key to `undefined` to remove a built-in handler:
|
|
62
65
|
* ```ts
|
|
63
|
-
* handlers: {
|
|
66
|
+
* handlers: { url: undefined }
|
|
64
67
|
* ```
|
|
65
68
|
*
|
|
66
|
-
* Built-in type keys: `undefined`, `bigint`, `date`, `nan`, `
|
|
69
|
+
* Built-in type keys: `undefined`, `bigint`, `date`, `nan`, `infinity`, `url`, `set`, `map`.
|
|
67
70
|
*/
|
|
68
71
|
handlers?: Record<string, undefined | RPCJsonSerializerHandler> | undefined;
|
|
69
72
|
/**
|
|
@@ -73,11 +76,23 @@ interface RPCJsonSerializerOptions {
|
|
|
73
76
|
*/
|
|
74
77
|
omitUndefinedProperties?: boolean | undefined;
|
|
75
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Serializes and deserializes native types like Date, BigInt, Set, and Map
|
|
81
|
+
* into a JSON value plus separate metadata describing how to restore them.
|
|
82
|
+
*
|
|
83
|
+
* @see {@link https://orpc.dev/docs/rpc/serializer#rpc-json-serializer | RPC Serializer - RPC JSON Serializer}
|
|
84
|
+
*/
|
|
76
85
|
declare class RPCJsonSerializer {
|
|
77
86
|
private readonly handlers;
|
|
87
|
+
private readonly inlineBuiltInHandlers;
|
|
88
|
+
private readonly handlerEntries;
|
|
78
89
|
private readonly omitUndefinedProperties;
|
|
79
90
|
constructor(options?: RPCJsonSerializerOptions);
|
|
80
91
|
serialize(data: unknown): RPCJsonSerialization;
|
|
92
|
+
/**
|
|
93
|
+
* `segments` is a shared mutable stack (push/pop while walking),
|
|
94
|
+
* so it must be copied before being stored in `meta` or `maps`.
|
|
95
|
+
*/
|
|
81
96
|
private serializeValue;
|
|
82
97
|
deserialize(serialized: RPCJsonSerialization): unknown;
|
|
83
98
|
}
|
|
@@ -97,6 +112,12 @@ interface RPCSerializerOptions extends RPCJsonSerializerOptions {
|
|
|
97
112
|
*/
|
|
98
113
|
serialize?: RPCSerializerSerializeOptions | undefined;
|
|
99
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Serializes and deserializes data for the RPC protocol,
|
|
117
|
+
* preserving native types like Date, BigInt, Set, and Map that plain JSON cannot represent.
|
|
118
|
+
*
|
|
119
|
+
* @see {@link https://orpc.dev/docs/rpc/serializer | RPC Serializer}
|
|
120
|
+
*/
|
|
100
121
|
declare class RPCSerializer {
|
|
101
122
|
private readonly jsonSerializer;
|
|
102
123
|
private readonly defaultSerializeOptions;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StandardBody } from '@
|
|
1
|
+
import { StandardBody } from '@standard-server/core';
|
|
2
2
|
import { Segment } from '@orpc/shared';
|
|
3
3
|
|
|
4
4
|
type RPCJsonSerializationMeta = [type: string, ...path: Segment[]];
|
|
@@ -16,7 +16,10 @@ type RPCJsonSerialization = {
|
|
|
16
16
|
interface RPCJsonSerializerHandler {
|
|
17
17
|
condition(value: unknown): boolean;
|
|
18
18
|
serialize(value: any): unknown;
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* `serialized` comes from the wire, so validate its type and throw on mismatch.
|
|
21
|
+
*/
|
|
22
|
+
deserialize(serialized: unknown): unknown;
|
|
20
23
|
/**
|
|
21
24
|
* If false, the result of this serializer will not be further processed by other serializers,
|
|
22
25
|
* even if it matches their conditions and treat it as final serialized value.
|
|
@@ -60,10 +63,10 @@ interface RPCJsonSerializerOptions {
|
|
|
60
63
|
*
|
|
61
64
|
* **Disabling:** Set a key to `undefined` to remove a built-in handler:
|
|
62
65
|
* ```ts
|
|
63
|
-
* handlers: {
|
|
66
|
+
* handlers: { url: undefined }
|
|
64
67
|
* ```
|
|
65
68
|
*
|
|
66
|
-
* Built-in type keys: `undefined`, `bigint`, `date`, `nan`, `
|
|
69
|
+
* Built-in type keys: `undefined`, `bigint`, `date`, `nan`, `infinity`, `url`, `set`, `map`.
|
|
67
70
|
*/
|
|
68
71
|
handlers?: Record<string, undefined | RPCJsonSerializerHandler> | undefined;
|
|
69
72
|
/**
|
|
@@ -73,11 +76,23 @@ interface RPCJsonSerializerOptions {
|
|
|
73
76
|
*/
|
|
74
77
|
omitUndefinedProperties?: boolean | undefined;
|
|
75
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Serializes and deserializes native types like Date, BigInt, Set, and Map
|
|
81
|
+
* into a JSON value plus separate metadata describing how to restore them.
|
|
82
|
+
*
|
|
83
|
+
* @see {@link https://orpc.dev/docs/rpc/serializer#rpc-json-serializer | RPC Serializer - RPC JSON Serializer}
|
|
84
|
+
*/
|
|
76
85
|
declare class RPCJsonSerializer {
|
|
77
86
|
private readonly handlers;
|
|
87
|
+
private readonly inlineBuiltInHandlers;
|
|
88
|
+
private readonly handlerEntries;
|
|
78
89
|
private readonly omitUndefinedProperties;
|
|
79
90
|
constructor(options?: RPCJsonSerializerOptions);
|
|
80
91
|
serialize(data: unknown): RPCJsonSerialization;
|
|
92
|
+
/**
|
|
93
|
+
* `segments` is a shared mutable stack (push/pop while walking),
|
|
94
|
+
* so it must be copied before being stored in `meta` or `maps`.
|
|
95
|
+
*/
|
|
81
96
|
private serializeValue;
|
|
82
97
|
deserialize(serialized: RPCJsonSerialization): unknown;
|
|
83
98
|
}
|
|
@@ -97,6 +112,12 @@ interface RPCSerializerOptions extends RPCJsonSerializerOptions {
|
|
|
97
112
|
*/
|
|
98
113
|
serialize?: RPCSerializerSerializeOptions | undefined;
|
|
99
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Serializes and deserializes data for the RPC protocol,
|
|
117
|
+
* preserving native types like Date, BigInt, Set, and Map that plain JSON cannot represent.
|
|
118
|
+
*
|
|
119
|
+
* @see {@link https://orpc.dev/docs/rpc/serializer | RPC Serializer}
|
|
120
|
+
*/
|
|
100
121
|
declare class RPCSerializer {
|
|
101
122
|
private readonly jsonSerializer;
|
|
102
123
|
private readonly defaultSerializeOptions;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Promisable, OrderablePlugin, Interceptor } from '@orpc/shared';
|
|
2
|
-
import { StandardRequest, StandardLazyResponse } from '@
|
|
3
|
-
import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.
|
|
2
|
+
import { StandardRequest, StandardLazyResponse } from '@standard-server/core';
|
|
3
|
+
import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.Dw9_40WO.mjs';
|
|
4
4
|
|
|
5
5
|
type StandardLinkCodecDecodedResponse = {
|
|
6
6
|
kind: 'output';
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { sortPlugins, runWithSpan, ORPC_NAME, isAsyncIteratorObject, override, traceAsyncIterator,
|
|
2
|
-
import { mergeStandardHeaders, parseStandardUrl } from '@
|
|
3
|
-
import { toStandardHeaders } from '@
|
|
4
|
-
import {
|
|
5
|
-
import { R as RPCSerializer, i as isORPCErrorJson, c as createORPCErrorFromJson } from './client.DMXKFDyV.mjs';
|
|
1
|
+
import { sortPlugins, runWithSpan, ORPC_NAME, getTracer, isAsyncIteratorObject, override, traceAsyncIterator, traceReadableStream, intercept, value, pathToHttpPath, stringifyJSON } from '@orpc/shared';
|
|
2
|
+
import { mergeStandardHeaders, parseStandardUrl } from '@standard-server/core';
|
|
3
|
+
import { toStandardHeaders } from '@standard-server/fetch';
|
|
4
|
+
import { R as RPCSerializer, c as createORPCErrorFromMalformedResponse, i as isORPCErrorJson, a as createORPCErrorFromJson } from './client.DpkGsZt-.mjs';
|
|
6
5
|
|
|
7
6
|
class CompositeStandardLinkPlugin {
|
|
8
7
|
name = "~composite";
|
|
@@ -37,50 +36,46 @@ class StandardLink {
|
|
|
37
36
|
return runWithSpan(`${ORPC_NAME}.${path.join("/")}`, (span) => {
|
|
38
37
|
span?.setAttribute("rpc.system", ORPC_NAME);
|
|
39
38
|
span?.setAttribute("rpc.method", path.join("."));
|
|
40
|
-
if (isAsyncIteratorObject(input)) {
|
|
41
|
-
input = override(input, traceAsyncIterator("
|
|
39
|
+
if (getTracer() && isAsyncIteratorObject(input)) {
|
|
40
|
+
input = override(input, traceAsyncIterator("consume_async_iterator_object_input", input));
|
|
41
|
+
} else if (getTracer() && input instanceof ReadableStream) {
|
|
42
|
+
input = override(input, traceReadableStream("consume_octet_stream_input", input));
|
|
42
43
|
}
|
|
43
44
|
return intercept(this.interceptors, { ...options, path, input }, async ({ path: path2, input: input2, ...options2 }) => {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
const activeSpan = otel?.trace.getActiveSpan() ?? span;
|
|
47
|
-
if (activeSpan && otel) {
|
|
48
|
-
activeContext = otel.trace.setSpan(otel.context.active(), activeSpan);
|
|
49
|
-
}
|
|
45
|
+
const tracer = getTracer();
|
|
46
|
+
const activeSpan = tracer?.getActiveSpan() ?? span;
|
|
50
47
|
let request = await runWithSpan(
|
|
51
|
-
{ name: "encode_input",
|
|
48
|
+
{ name: "encode_input", parent: activeSpan },
|
|
52
49
|
() => this.codec.encodeInput(input2, path2, options2)
|
|
53
50
|
);
|
|
54
|
-
if (
|
|
51
|
+
if (activeSpan && tracer?.inject) {
|
|
55
52
|
const headers = { ...request.headers };
|
|
56
|
-
|
|
53
|
+
tracer.inject(activeSpan, headers);
|
|
57
54
|
request = { ...request, headers };
|
|
58
55
|
}
|
|
59
56
|
const response = await intercept(
|
|
60
57
|
this.transportInterceptors,
|
|
61
58
|
{ ...options2, path: path2, request },
|
|
62
59
|
({ path: path3, request: request2, ...options3 }) => {
|
|
63
|
-
|
|
64
|
-
const activeTransportSpan = otel?.trace.getActiveSpan() ?? activeSpan;
|
|
65
|
-
if (activeTransportSpan && otel) {
|
|
66
|
-
activeTransportContext = otel.trace.setSpan(otel.context.active(), activeTransportSpan);
|
|
67
|
-
}
|
|
60
|
+
const activeTransportSpan = tracer?.getActiveSpan() ?? activeSpan;
|
|
68
61
|
return runWithSpan(
|
|
69
|
-
{ name: "send_request",
|
|
62
|
+
{ name: "send_request", parent: activeTransportSpan },
|
|
70
63
|
() => this.transport.send(request2, path3, options3)
|
|
71
64
|
);
|
|
72
65
|
}
|
|
73
66
|
);
|
|
74
67
|
const decodedResult = await runWithSpan(
|
|
75
|
-
{ name: "decode_response",
|
|
68
|
+
{ name: "decode_response", parent: activeSpan },
|
|
76
69
|
() => this.codec.decodeResponse(response, path2, options2)
|
|
77
70
|
);
|
|
78
71
|
if (decodedResult.kind === "error") {
|
|
79
72
|
throw decodedResult.error;
|
|
80
73
|
}
|
|
81
74
|
const output = decodedResult.output;
|
|
82
|
-
if (isAsyncIteratorObject(output)) {
|
|
83
|
-
return override(output, traceAsyncIterator("
|
|
75
|
+
if (getTracer() && isAsyncIteratorObject(output)) {
|
|
76
|
+
return override(output, traceAsyncIterator("consume_async_iterator_object_output", output));
|
|
77
|
+
} else if (getTracer() && output instanceof ReadableStream) {
|
|
78
|
+
return override(output, traceReadableStream("consume_octet_stream_output", output));
|
|
84
79
|
}
|
|
85
80
|
return output;
|
|
86
81
|
});
|
|
@@ -139,13 +134,15 @@ class RPCLinkCodec {
|
|
|
139
134
|
};
|
|
140
135
|
}
|
|
141
136
|
async decodeResponse(response) {
|
|
142
|
-
const isOk = response.status
|
|
137
|
+
const isOk = response.status < 400;
|
|
143
138
|
const body = await response.resolveBody();
|
|
144
139
|
const deserialized = await (async () => {
|
|
145
140
|
try {
|
|
146
141
|
return this.serializer.deserialize(body);
|
|
147
142
|
} catch (cause) {
|
|
148
|
-
throw
|
|
143
|
+
throw createORPCErrorFromMalformedResponse({
|
|
144
|
+
message: "Invalid RPC response format.",
|
|
145
|
+
response: { status: response.status, headers: response.headers, body },
|
|
149
146
|
cause
|
|
150
147
|
});
|
|
151
148
|
}
|
|
@@ -156,9 +153,7 @@ class RPCLinkCodec {
|
|
|
156
153
|
}
|
|
157
154
|
return {
|
|
158
155
|
kind: "error",
|
|
159
|
-
error:
|
|
160
|
-
data: { headers: response.headers, status: response.status, body: deserialized }
|
|
161
|
-
})
|
|
156
|
+
error: createORPCErrorFromMalformedResponse({ response: { headers: response.headers, status: response.status, body } })
|
|
162
157
|
};
|
|
163
158
|
}
|
|
164
159
|
return { kind: "output", output: deserialized };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveMaybeOptionalOptions,
|
|
1
|
+
import { resolveMaybeOptionalOptions, getConstructors } from '@orpc/shared';
|
|
2
2
|
|
|
3
3
|
const COMMON_ERROR_STATUS_MAP = {
|
|
4
4
|
BAD_REQUEST: 400,
|
|
@@ -11,6 +11,7 @@ const COMMON_ERROR_STATUS_MAP = {
|
|
|
11
11
|
TIMEOUT: 408,
|
|
12
12
|
CONFLICT: 409,
|
|
13
13
|
GONE: 410,
|
|
14
|
+
LENGTH_REQUIRED: 411,
|
|
14
15
|
PRECONDITION_FAILED: 412,
|
|
15
16
|
PAYLOAD_TOO_LARGE: 413,
|
|
16
17
|
UNSUPPORTED_MEDIA_TYPE: 415,
|
|
@@ -33,20 +34,16 @@ class ORPCError extends Error {
|
|
|
33
34
|
ORPCErrorConstructors.add(ORPCError);
|
|
34
35
|
}
|
|
35
36
|
/**
|
|
36
|
-
* @
|
|
37
|
-
* The `__branch` property is used for type branding, helping TypeScript distinguish
|
|
37
|
+
* @remarks
|
|
38
|
+
* **Note**: The `__branch` property is used for type branding, helping TypeScript distinguish
|
|
38
39
|
* an `ORPCError` instance from plain objects with a similar structure.
|
|
39
40
|
*/
|
|
40
41
|
name = "ORPCError";
|
|
41
42
|
/**
|
|
42
|
-
* Indicates whether the error matches a definition in the procedure's `.errors` map
|
|
43
|
+
* Indicates whether the error matches a definition in the procedure's `.errors` map,
|
|
44
|
+
* which makes its type inferable on the client.
|
|
43
45
|
*/
|
|
44
46
|
defined = false;
|
|
45
|
-
/**
|
|
46
|
-
* Indicates whether the error's type is inferable at the TypeScript level.
|
|
47
|
-
* This is typically true when the error is explicitly defined or returned within a handler.
|
|
48
|
-
*/
|
|
49
|
-
inferable = false;
|
|
50
47
|
code;
|
|
51
48
|
data;
|
|
52
49
|
constructor(code, ...rest) {
|
|
@@ -59,7 +56,6 @@ class ORPCError extends Error {
|
|
|
59
56
|
toJSON() {
|
|
60
57
|
return {
|
|
61
58
|
defined: this.defined,
|
|
62
|
-
inferable: this.inferable,
|
|
63
59
|
code: this.code,
|
|
64
60
|
message: this.message,
|
|
65
61
|
data: this.data
|
|
@@ -81,12 +77,21 @@ class ORPCError extends Error {
|
|
|
81
77
|
if (!ORPCErrorConstructors.has(this)) {
|
|
82
78
|
return super[Symbol.hasInstance](instance);
|
|
83
79
|
}
|
|
84
|
-
const constructor
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
for (const constructor of getConstructors(instance)) {
|
|
81
|
+
if (ORPCErrorConstructors.has(constructor)) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
87
84
|
}
|
|
88
|
-
return
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
class MalformedResponseError extends Error {
|
|
89
|
+
name = "MalformedResponseError";
|
|
90
|
+
response;
|
|
91
|
+
constructor(options) {
|
|
92
|
+
super(options.message, options);
|
|
93
|
+
this.response = options.response;
|
|
89
94
|
}
|
|
90
95
|
}
|
|
91
96
|
|
|
92
|
-
export { COMMON_ERROR_STATUS_MAP as C, ORPCError as O };
|
|
97
|
+
export { COMMON_ERROR_STATUS_MAP as C, MalformedResponseError as M, ORPCError as O };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Promisable, OrderablePlugin, Interceptor } from '@orpc/shared';
|
|
2
|
-
import { StandardRequest, StandardLazyResponse } from '@
|
|
3
|
-
import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.
|
|
2
|
+
import { StandardRequest, StandardLazyResponse } from '@standard-server/core';
|
|
3
|
+
import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.Dw9_40WO.js';
|
|
4
4
|
|
|
5
5
|
type StandardLinkCodecDecodedResponse = {
|
|
6
6
|
kind: 'output';
|