@orpc/client 0.0.0-next.f7af1c4 → 0.0.0-next.f8cfaa5

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 (31) hide show
  1. package/README.md +3 -0
  2. package/dist/adapters/fetch/index.d.mts +3 -3
  3. package/dist/adapters/fetch/index.d.ts +3 -3
  4. package/dist/adapters/fetch/index.mjs +3 -2
  5. package/dist/adapters/message-port/index.d.mts +28 -7
  6. package/dist/adapters/message-port/index.d.ts +28 -7
  7. package/dist/adapters/message-port/index.mjs +25 -10
  8. package/dist/adapters/standard/index.d.mts +3 -3
  9. package/dist/adapters/standard/index.d.ts +3 -3
  10. package/dist/adapters/standard/index.mjs +3 -2
  11. package/dist/adapters/websocket/index.d.mts +3 -3
  12. package/dist/adapters/websocket/index.d.ts +3 -3
  13. package/dist/adapters/websocket/index.mjs +4 -3
  14. package/dist/index.d.mts +4 -4
  15. package/dist/index.d.ts +4 -4
  16. package/dist/index.mjs +4 -3
  17. package/dist/plugins/index.d.mts +51 -5
  18. package/dist/plugins/index.d.ts +51 -5
  19. package/dist/plugins/index.mjs +80 -2
  20. package/dist/shared/client.BH1AYT_p.d.mts +83 -0
  21. package/dist/shared/client.BH1AYT_p.d.ts +83 -0
  22. package/dist/shared/client.BLtwTQUg.mjs +40 -0
  23. package/dist/shared/{client.CVVVqf1Y.d.ts → client.BxV-mzeR.d.ts} +2 -2
  24. package/dist/shared/{client.9Pe_7OOW.mjs → client.C3KE2j2B.mjs} +3 -40
  25. package/dist/shared/{client.Bwgm6dgk.d.mts → client.CPgZaUox.d.mts} +1 -1
  26. package/dist/shared/{client._Y_enhib.d.mts → client.D8lMmWVC.d.mts} +2 -2
  27. package/dist/shared/{client.BG98rYdO.d.ts → client.De8SW4Kw.d.ts} +1 -1
  28. package/dist/shared/{client._7ROGDgw.mjs → client.u8ryIrF8.mjs} +2 -1
  29. package/package.json +6 -6
  30. package/dist/shared/client.BOYsZIRq.d.mts +0 -29
  31. package/dist/shared/client.BOYsZIRq.d.ts +0 -29
package/README.md CHANGED
@@ -17,6 +17,9 @@
17
17
  <a href="https://discord.gg/TXEbwRBvQn">
18
18
  <img alt="Discord" src="https://img.shields.io/discord/1308966753044398161?color=7389D8&label&logo=discord&logoColor=ffffff" />
19
19
  </a>
20
+ <a href="https://deepwiki.com/unnoq/orpc">
21
+ <img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki">
22
+ </a>
20
23
  </div>
21
24
 
22
25
  <h3 align="center">Typesafe APIs Made Simple 🪄</h3>
@@ -1,9 +1,9 @@
1
1
  import { Interceptor } from '@orpc/shared';
2
2
  import { StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
3
3
  import { ToFetchRequestOptions } from '@orpc/standard-server-fetch';
4
- import { b as ClientContext, c as ClientOptions } from '../../shared/client.BOYsZIRq.mjs';
5
- import { a as StandardLinkPlugin, f as StandardLinkClient } from '../../shared/client.Bwgm6dgk.mjs';
6
- import { f as StandardRPCLinkOptions, g as StandardRPCLink } from '../../shared/client._Y_enhib.mjs';
4
+ import { b as ClientContext, c as ClientOptions } from '../../shared/client.BH1AYT_p.mjs';
5
+ import { a as StandardLinkPlugin, f as StandardLinkClient } from '../../shared/client.CPgZaUox.mjs';
6
+ import { f as StandardRPCLinkOptions, g as StandardRPCLink } from '../../shared/client.D8lMmWVC.mjs';
7
7
 
8
8
  interface LinkFetchPlugin<T extends ClientContext> extends StandardLinkPlugin<T> {
9
9
  initRuntimeAdapter?(options: LinkFetchClientOptions<T>): void;
@@ -1,9 +1,9 @@
1
1
  import { Interceptor } from '@orpc/shared';
2
2
  import { StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
3
3
  import { ToFetchRequestOptions } from '@orpc/standard-server-fetch';
4
- import { b as ClientContext, c as ClientOptions } from '../../shared/client.BOYsZIRq.js';
5
- import { a as StandardLinkPlugin, f as StandardLinkClient } from '../../shared/client.BG98rYdO.js';
6
- import { f as StandardRPCLinkOptions, g as StandardRPCLink } from '../../shared/client.CVVVqf1Y.js';
4
+ import { b as ClientContext, c as ClientOptions } from '../../shared/client.BH1AYT_p.js';
5
+ import { a as StandardLinkPlugin, f as StandardLinkClient } from '../../shared/client.De8SW4Kw.js';
6
+ import { f as StandardRPCLinkOptions, g as StandardRPCLink } from '../../shared/client.BxV-mzeR.js';
7
7
 
8
8
  interface LinkFetchPlugin<T extends ClientContext> extends StandardLinkPlugin<T> {
9
9
  initRuntimeAdapter?(options: LinkFetchClientOptions<T>): void;
@@ -1,8 +1,9 @@
1
1
  import { toArray, intercept } from '@orpc/shared';
2
2
  import { toFetchRequest, toStandardLazyResponse } from '@orpc/standard-server-fetch';
3
- import { C as CompositeStandardLinkPlugin, c as StandardRPCLink } from '../../shared/client._7ROGDgw.mjs';
3
+ import { C as CompositeStandardLinkPlugin, c as StandardRPCLink } from '../../shared/client.u8ryIrF8.mjs';
4
4
  import '@orpc/standard-server';
5
- import '../../shared/client.9Pe_7OOW.mjs';
5
+ import '../../shared/client.C3KE2j2B.mjs';
6
+ import '../../shared/client.BLtwTQUg.mjs';
6
7
 
7
8
  class CompositeLinkFetchPlugin extends CompositeStandardLinkPlugin {
8
9
  initRuntimeAdapter(options) {
@@ -1,8 +1,9 @@
1
+ import { Value, Promisable } from '@orpc/shared';
1
2
  import { StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
2
- import { b as ClientContext, c as ClientOptions } from '../../shared/client.BOYsZIRq.mjs';
3
- import { f as StandardLinkClient } from '../../shared/client.Bwgm6dgk.mjs';
4
- import { f as StandardRPCLinkOptions, g as StandardRPCLink } from '../../shared/client._Y_enhib.mjs';
5
- import '@orpc/shared';
3
+ import { DecodedRequestMessage } from '@orpc/standard-server-peer';
4
+ import { b as ClientContext, c as ClientOptions } from '../../shared/client.BH1AYT_p.mjs';
5
+ import { f as StandardLinkClient } from '../../shared/client.CPgZaUox.mjs';
6
+ import { f as StandardRPCLinkOptions, g as StandardRPCLink } from '../../shared/client.D8lMmWVC.mjs';
6
7
 
7
8
  /**
8
9
  * The message port used by electron in main process
@@ -11,7 +12,7 @@ interface MessagePortMainLike {
11
12
  on: <T extends string>(event: T, callback: (event?: {
12
13
  data: any;
13
14
  }) => void) => void;
14
- postMessage: (data: any) => void;
15
+ postMessage: (data: any, transfer?: any[]) => void;
15
16
  }
16
17
  /**
17
18
  * The message port used by browser extension
@@ -29,13 +30,33 @@ type SupportedMessagePort = Pick<MessagePort, 'addEventListener' | 'postMessage'
29
30
  /**
30
31
  * Message port can support [The structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm)
31
32
  */
32
- type SupportedMessagePortData = string | ArrayBufferLike | Uint8Array;
33
- declare function postMessagePortMessage(port: SupportedMessagePort, data: SupportedMessagePortData): void;
33
+ type SupportedMessagePortData = any;
34
+ declare function postMessagePortMessage(port: SupportedMessagePort, data: SupportedMessagePortData, transfer?: any[]): void;
34
35
  declare function onMessagePortMessage(port: SupportedMessagePort, callback: (data: SupportedMessagePortData) => void): void;
35
36
  declare function onMessagePortClose(port: SupportedMessagePort, callback: () => void): void;
36
37
 
37
38
  interface LinkMessagePortClientOptions {
38
39
  port: SupportedMessagePort;
40
+ /**
41
+ * By default, oRPC serializes request/response messages to string/binary data before sending over message port.
42
+ * If needed, you can define the this option to utilize full power of [MessagePort: postMessage() method](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/postMessage),
43
+ * such as transferring ownership of objects to the other side or support unserializable objects like `OffscreenCanvas`.
44
+ *
45
+ * @remarks
46
+ * - return null | undefined to disable this feature
47
+ *
48
+ * @warning Make sure your message port supports `transfer` before using this feature.
49
+ * @example
50
+ * ```ts
51
+ * experimental_transfer: (message, port) => {
52
+ * const transfer = deepFindTransferableObjects(message) // implement your own logic
53
+ * return transfer.length ? transfer : null // only enable when needed
54
+ * }
55
+ * ```
56
+ *
57
+ * @see {@link https://orpc.unnoq.com/docs/adapters/message-port#transfer Message Port Transfer Docs}
58
+ */
59
+ experimental_transfer?: Value<Promisable<object[] | null | undefined>, [message: DecodedRequestMessage, port: SupportedMessagePort]>;
39
60
  }
40
61
  declare class LinkMessagePortClient<T extends ClientContext> implements StandardLinkClient<T> {
41
62
  private readonly peer;
@@ -1,8 +1,9 @@
1
+ import { Value, Promisable } from '@orpc/shared';
1
2
  import { StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
2
- import { b as ClientContext, c as ClientOptions } from '../../shared/client.BOYsZIRq.js';
3
- import { f as StandardLinkClient } from '../../shared/client.BG98rYdO.js';
4
- import { f as StandardRPCLinkOptions, g as StandardRPCLink } from '../../shared/client.CVVVqf1Y.js';
5
- import '@orpc/shared';
3
+ import { DecodedRequestMessage } from '@orpc/standard-server-peer';
4
+ import { b as ClientContext, c as ClientOptions } from '../../shared/client.BH1AYT_p.js';
5
+ import { f as StandardLinkClient } from '../../shared/client.De8SW4Kw.js';
6
+ import { f as StandardRPCLinkOptions, g as StandardRPCLink } from '../../shared/client.BxV-mzeR.js';
6
7
 
7
8
  /**
8
9
  * The message port used by electron in main process
@@ -11,7 +12,7 @@ interface MessagePortMainLike {
11
12
  on: <T extends string>(event: T, callback: (event?: {
12
13
  data: any;
13
14
  }) => void) => void;
14
- postMessage: (data: any) => void;
15
+ postMessage: (data: any, transfer?: any[]) => void;
15
16
  }
16
17
  /**
17
18
  * The message port used by browser extension
@@ -29,13 +30,33 @@ type SupportedMessagePort = Pick<MessagePort, 'addEventListener' | 'postMessage'
29
30
  /**
30
31
  * Message port can support [The structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm)
31
32
  */
32
- type SupportedMessagePortData = string | ArrayBufferLike | Uint8Array;
33
- declare function postMessagePortMessage(port: SupportedMessagePort, data: SupportedMessagePortData): void;
33
+ type SupportedMessagePortData = any;
34
+ declare function postMessagePortMessage(port: SupportedMessagePort, data: SupportedMessagePortData, transfer?: any[]): void;
34
35
  declare function onMessagePortMessage(port: SupportedMessagePort, callback: (data: SupportedMessagePortData) => void): void;
35
36
  declare function onMessagePortClose(port: SupportedMessagePort, callback: () => void): void;
36
37
 
37
38
  interface LinkMessagePortClientOptions {
38
39
  port: SupportedMessagePort;
40
+ /**
41
+ * By default, oRPC serializes request/response messages to string/binary data before sending over message port.
42
+ * If needed, you can define the this option to utilize full power of [MessagePort: postMessage() method](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/postMessage),
43
+ * such as transferring ownership of objects to the other side or support unserializable objects like `OffscreenCanvas`.
44
+ *
45
+ * @remarks
46
+ * - return null | undefined to disable this feature
47
+ *
48
+ * @warning Make sure your message port supports `transfer` before using this feature.
49
+ * @example
50
+ * ```ts
51
+ * experimental_transfer: (message, port) => {
52
+ * const transfer = deepFindTransferableObjects(message) // implement your own logic
53
+ * return transfer.length ? transfer : null // only enable when needed
54
+ * }
55
+ * ```
56
+ *
57
+ * @see {@link https://orpc.unnoq.com/docs/adapters/message-port#transfer Message Port Transfer Docs}
58
+ */
59
+ experimental_transfer?: Value<Promisable<object[] | null | undefined>, [message: DecodedRequestMessage, port: SupportedMessagePort]>;
39
60
  }
40
61
  declare class LinkMessagePortClient<T extends ClientContext> implements StandardLinkClient<T> {
41
62
  private readonly peer;
@@ -1,12 +1,17 @@
1
- import { ClientPeer } from '@orpc/standard-server-peer';
2
- import '@orpc/shared';
3
- import { c as StandardRPCLink } from '../../shared/client._7ROGDgw.mjs';
1
+ import { value, isObject } from '@orpc/shared';
2
+ import { experimental_ClientPeerWithoutCodec, serializeRequestMessage, encodeRequestMessage, deserializeResponseMessage, decodeResponseMessage } from '@orpc/standard-server-peer';
3
+ import { c as StandardRPCLink } from '../../shared/client.u8ryIrF8.mjs';
4
4
  import '@orpc/standard-server';
5
- import '../../shared/client.9Pe_7OOW.mjs';
5
+ import '../../shared/client.C3KE2j2B.mjs';
6
6
  import '@orpc/standard-server-fetch';
7
+ import '../../shared/client.BLtwTQUg.mjs';
7
8
 
8
- function postMessagePortMessage(port, data) {
9
- port.postMessage(data);
9
+ function postMessagePortMessage(port, data, transfer) {
10
+ if (transfer) {
11
+ port.postMessage(data, transfer);
12
+ } else {
13
+ port.postMessage(data);
14
+ }
10
15
  }
11
16
  function onMessagePortMessage(port, callback) {
12
17
  if ("addEventListener" in port) {
@@ -46,11 +51,21 @@ function onMessagePortClose(port, callback) {
46
51
  class LinkMessagePortClient {
47
52
  peer;
48
53
  constructor(options) {
49
- this.peer = new ClientPeer((message) => {
50
- return postMessagePortMessage(options.port, message);
54
+ this.peer = new experimental_ClientPeerWithoutCodec(async (message) => {
55
+ const [id, type, payload] = message;
56
+ const transfer = await value(options.experimental_transfer, message, options.port);
57
+ if (transfer) {
58
+ postMessagePortMessage(options.port, serializeRequestMessage(id, type, payload), transfer);
59
+ } else {
60
+ postMessagePortMessage(options.port, await encodeRequestMessage(id, type, payload));
61
+ }
51
62
  });
52
63
  onMessagePortMessage(options.port, async (message) => {
53
- await this.peer.message(message);
64
+ if (isObject(message)) {
65
+ await this.peer.message(deserializeResponseMessage(message));
66
+ } else {
67
+ await this.peer.message(await decodeResponseMessage(message));
68
+ }
54
69
  });
55
70
  onMessagePortClose(options.port, () => {
56
71
  this.peer.close();
@@ -65,7 +80,7 @@ class LinkMessagePortClient {
65
80
  class RPCLink extends StandardRPCLink {
66
81
  constructor(options) {
67
82
  const linkClient = new LinkMessagePortClient(options);
68
- super(linkClient, { ...options, url: "orpc:/" });
83
+ super(linkClient, { ...options, url: "orpc://localhost" });
69
84
  }
70
85
  }
71
86
 
@@ -1,7 +1,7 @@
1
- export { C as CompositeStandardLinkPlugin, d as StandardLink, f as StandardLinkClient, S as StandardLinkClientInterceptorOptions, e as StandardLinkCodec, c as StandardLinkInterceptorOptions, b as StandardLinkOptions, a as StandardLinkPlugin } from '../../shared/client.Bwgm6dgk.mjs';
2
- export { S as STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES, c as StandardRPCCustomJsonSerializer, b as StandardRPCJsonSerialized, a as StandardRPCJsonSerializedMetaItem, e as StandardRPCJsonSerializer, d as StandardRPCJsonSerializerOptions, g as StandardRPCLink, i as StandardRPCLinkCodec, h as StandardRPCLinkCodecOptions, f as StandardRPCLinkOptions, j as StandardRPCSerializer } from '../../shared/client._Y_enhib.mjs';
1
+ export { C as CompositeStandardLinkPlugin, d as StandardLink, f as StandardLinkClient, S as StandardLinkClientInterceptorOptions, e as StandardLinkCodec, c as StandardLinkInterceptorOptions, b as StandardLinkOptions, a as StandardLinkPlugin } from '../../shared/client.CPgZaUox.mjs';
2
+ export { S as STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES, c as StandardRPCCustomJsonSerializer, b as StandardRPCJsonSerialized, a as StandardRPCJsonSerializedMetaItem, e as StandardRPCJsonSerializer, d as StandardRPCJsonSerializerOptions, g as StandardRPCLink, i as StandardRPCLinkCodec, h as StandardRPCLinkCodecOptions, f as StandardRPCLinkOptions, j as StandardRPCSerializer } from '../../shared/client.D8lMmWVC.mjs';
3
3
  import { StandardHeaders } from '@orpc/standard-server';
4
- import { H as HTTPPath } from '../../shared/client.BOYsZIRq.mjs';
4
+ import { H as HTTPPath } from '../../shared/client.BH1AYT_p.mjs';
5
5
  import '@orpc/shared';
6
6
 
7
7
  declare function toHttpPath(path: readonly string[]): HTTPPath;
@@ -1,7 +1,7 @@
1
- export { C as CompositeStandardLinkPlugin, d as StandardLink, f as StandardLinkClient, S as StandardLinkClientInterceptorOptions, e as StandardLinkCodec, c as StandardLinkInterceptorOptions, b as StandardLinkOptions, a as StandardLinkPlugin } from '../../shared/client.BG98rYdO.js';
2
- export { S as STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES, c as StandardRPCCustomJsonSerializer, b as StandardRPCJsonSerialized, a as StandardRPCJsonSerializedMetaItem, e as StandardRPCJsonSerializer, d as StandardRPCJsonSerializerOptions, g as StandardRPCLink, i as StandardRPCLinkCodec, h as StandardRPCLinkCodecOptions, f as StandardRPCLinkOptions, j as StandardRPCSerializer } from '../../shared/client.CVVVqf1Y.js';
1
+ export { C as CompositeStandardLinkPlugin, d as StandardLink, f as StandardLinkClient, S as StandardLinkClientInterceptorOptions, e as StandardLinkCodec, c as StandardLinkInterceptorOptions, b as StandardLinkOptions, a as StandardLinkPlugin } from '../../shared/client.De8SW4Kw.js';
2
+ export { S as STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES, c as StandardRPCCustomJsonSerializer, b as StandardRPCJsonSerialized, a as StandardRPCJsonSerializedMetaItem, e as StandardRPCJsonSerializer, d as StandardRPCJsonSerializerOptions, g as StandardRPCLink, i as StandardRPCLinkCodec, h as StandardRPCLinkCodecOptions, f as StandardRPCLinkOptions, j as StandardRPCSerializer } from '../../shared/client.BxV-mzeR.js';
3
3
  import { StandardHeaders } from '@orpc/standard-server';
4
- import { H as HTTPPath } from '../../shared/client.BOYsZIRq.js';
4
+ import { H as HTTPPath } from '../../shared/client.BH1AYT_p.js';
5
5
  import '@orpc/shared';
6
6
 
7
7
  declare function toHttpPath(path: readonly string[]): HTTPPath;
@@ -1,5 +1,6 @@
1
- export { C as CompositeStandardLinkPlugin, a as STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES, S as StandardLink, b as StandardRPCJsonSerializer, c as StandardRPCLink, d as StandardRPCLinkCodec, e as StandardRPCSerializer, g as getMalformedResponseErrorCode, t as toHttpPath, f as toStandardHeaders } from '../../shared/client._7ROGDgw.mjs';
1
+ export { C as CompositeStandardLinkPlugin, a as STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES, S as StandardLink, b as StandardRPCJsonSerializer, c as StandardRPCLink, d as StandardRPCLinkCodec, e as StandardRPCSerializer, g as getMalformedResponseErrorCode, t as toHttpPath, f as toStandardHeaders } from '../../shared/client.u8ryIrF8.mjs';
2
2
  import '@orpc/shared';
3
3
  import '@orpc/standard-server';
4
- import '../../shared/client.9Pe_7OOW.mjs';
4
+ import '../../shared/client.C3KE2j2B.mjs';
5
5
  import '@orpc/standard-server-fetch';
6
+ import '../../shared/client.BLtwTQUg.mjs';
@@ -1,7 +1,7 @@
1
1
  import { StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
2
- import { b as ClientContext, c as ClientOptions } from '../../shared/client.BOYsZIRq.mjs';
3
- import { f as StandardLinkClient } from '../../shared/client.Bwgm6dgk.mjs';
4
- import { f as StandardRPCLinkOptions, g as StandardRPCLink } from '../../shared/client._Y_enhib.mjs';
2
+ import { b as ClientContext, c as ClientOptions } from '../../shared/client.BH1AYT_p.mjs';
3
+ import { f as StandardLinkClient } from '../../shared/client.CPgZaUox.mjs';
4
+ import { f as StandardRPCLinkOptions, g as StandardRPCLink } from '../../shared/client.D8lMmWVC.mjs';
5
5
  import '@orpc/shared';
6
6
 
7
7
  interface LinkWebsocketClientOptions {
@@ -1,7 +1,7 @@
1
1
  import { StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
2
- import { b as ClientContext, c as ClientOptions } from '../../shared/client.BOYsZIRq.js';
3
- import { f as StandardLinkClient } from '../../shared/client.BG98rYdO.js';
4
- import { f as StandardRPCLinkOptions, g as StandardRPCLink } from '../../shared/client.CVVVqf1Y.js';
2
+ import { b as ClientContext, c as ClientOptions } from '../../shared/client.BH1AYT_p.js';
3
+ import { f as StandardLinkClient } from '../../shared/client.De8SW4Kw.js';
4
+ import { f as StandardRPCLinkOptions, g as StandardRPCLink } from '../../shared/client.BxV-mzeR.js';
5
5
  import '@orpc/shared';
6
6
 
7
7
  interface LinkWebsocketClientOptions {
@@ -1,9 +1,10 @@
1
1
  import { readAsBuffer } from '@orpc/shared';
2
2
  import { ClientPeer } from '@orpc/standard-server-peer';
3
- import { c as StandardRPCLink } from '../../shared/client._7ROGDgw.mjs';
3
+ import { c as StandardRPCLink } from '../../shared/client.u8ryIrF8.mjs';
4
4
  import '@orpc/standard-server';
5
- import '../../shared/client.9Pe_7OOW.mjs';
5
+ import '../../shared/client.C3KE2j2B.mjs';
6
6
  import '@orpc/standard-server-fetch';
7
+ import '../../shared/client.BLtwTQUg.mjs';
7
8
 
8
9
  const WEBSOCKET_CONNECTING = 0;
9
10
  class LinkWebsocketClient {
@@ -39,7 +40,7 @@ class LinkWebsocketClient {
39
40
  class RPCLink extends StandardRPCLink {
40
41
  constructor(options) {
41
42
  const linkClient = new LinkWebsocketClient(options);
42
- super(linkClient, { ...options, url: "orpc:/" });
43
+ super(linkClient, { ...options, url: "orpc://localhost" });
43
44
  }
44
45
  }
45
46
 
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
- import { N as NestedClient, C as ClientLink, I as InferClientContext, a as ClientPromiseResult, b as ClientContext, F as FriendlyClientOptions, c as ClientOptions, d as Client, e as ClientRest } from './shared/client.BOYsZIRq.mjs';
2
- export { f as HTTPMethod, H as HTTPPath } from './shared/client.BOYsZIRq.mjs';
1
+ import { N as NestedClient, C as ClientLink, I as InferClientContext, a as ClientPromiseResult, b as ClientContext, F as FriendlyClientOptions, c as ClientOptions, d as Client, e as ClientRest } from './shared/client.BH1AYT_p.mjs';
2
+ export { f as HTTPMethod, H as HTTPPath, h as InferClientBodyInputs, j as InferClientBodyOutputs, l as InferClientErrorUnion, k as InferClientErrors, g as InferClientInputs, i as InferClientOutputs } from './shared/client.BH1AYT_p.mjs';
3
3
  import { MaybeOptionalOptions, ThrowableError, OnFinishState, Promisable, AsyncIteratorClass } from '@orpc/shared';
4
- export { AsyncIteratorClass, EventPublisher, EventPublisherOptions, EventPublisherSubscribeIteratorOptions, Registry, ThrowableError, asyncIteratorToStream as eventIteratorToStream, onError, onFinish, onStart, onSuccess, streamToAsyncIteratorClass as streamToEventIterator } from '@orpc/shared';
4
+ export { AsyncIteratorClass, EventPublisher, EventPublisherOptions, EventPublisherSubscribeIteratorOptions, Registry, ThrowableError, asyncIteratorToStream as eventIteratorToStream, asyncIteratorToUnproxiedDataStream as eventIteratorToUnproxiedDataStream, onError, onFinish, onStart, onSuccess, streamToAsyncIteratorClass as streamToEventIterator } from '@orpc/shared';
5
5
  export { ErrorEvent } from '@orpc/standard-server';
6
6
 
7
7
  interface createORPCClientOptions {
@@ -207,7 +207,7 @@ type SafeClient<T extends NestedClient<any>> = T extends Client<infer UContext,
207
207
  declare function createSafeClient<T extends NestedClient<any>>(client: T): SafeClient<T>;
208
208
 
209
209
  declare const ORPC_CLIENT_PACKAGE_NAME = "@orpc/client";
210
- declare const ORPC_CLIENT_PACKAGE_VERSION = "0.0.0-next.f7af1c4";
210
+ declare const ORPC_CLIENT_PACKAGE_VERSION = "0.0.0-next.f8cfaa5";
211
211
 
212
212
  /**
213
213
  * DynamicLink provides a way to dynamically resolve and delegate calls to other ClientLinks
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { N as NestedClient, C as ClientLink, I as InferClientContext, a as ClientPromiseResult, b as ClientContext, F as FriendlyClientOptions, c as ClientOptions, d as Client, e as ClientRest } from './shared/client.BOYsZIRq.js';
2
- export { f as HTTPMethod, H as HTTPPath } from './shared/client.BOYsZIRq.js';
1
+ import { N as NestedClient, C as ClientLink, I as InferClientContext, a as ClientPromiseResult, b as ClientContext, F as FriendlyClientOptions, c as ClientOptions, d as Client, e as ClientRest } from './shared/client.BH1AYT_p.js';
2
+ export { f as HTTPMethod, H as HTTPPath, h as InferClientBodyInputs, j as InferClientBodyOutputs, l as InferClientErrorUnion, k as InferClientErrors, g as InferClientInputs, i as InferClientOutputs } from './shared/client.BH1AYT_p.js';
3
3
  import { MaybeOptionalOptions, ThrowableError, OnFinishState, Promisable, AsyncIteratorClass } from '@orpc/shared';
4
- export { AsyncIteratorClass, EventPublisher, EventPublisherOptions, EventPublisherSubscribeIteratorOptions, Registry, ThrowableError, asyncIteratorToStream as eventIteratorToStream, onError, onFinish, onStart, onSuccess, streamToAsyncIteratorClass as streamToEventIterator } from '@orpc/shared';
4
+ export { AsyncIteratorClass, EventPublisher, EventPublisherOptions, EventPublisherSubscribeIteratorOptions, Registry, ThrowableError, asyncIteratorToStream as eventIteratorToStream, asyncIteratorToUnproxiedDataStream as eventIteratorToUnproxiedDataStream, onError, onFinish, onStart, onSuccess, streamToAsyncIteratorClass as streamToEventIterator } from '@orpc/shared';
5
5
  export { ErrorEvent } from '@orpc/standard-server';
6
6
 
7
7
  interface createORPCClientOptions {
@@ -207,7 +207,7 @@ type SafeClient<T extends NestedClient<any>> = T extends Client<infer UContext,
207
207
  declare function createSafeClient<T extends NestedClient<any>>(client: T): SafeClient<T>;
208
208
 
209
209
  declare const ORPC_CLIENT_PACKAGE_NAME = "@orpc/client";
210
- declare const ORPC_CLIENT_PACKAGE_VERSION = "0.0.0-next.f7af1c4";
210
+ declare const ORPC_CLIENT_PACKAGE_VERSION = "0.0.0-next.f8cfaa5";
211
211
 
212
212
  /**
213
213
  * DynamicLink provides a way to dynamically resolve and delegate calls to other ClientLinks
package/dist/index.mjs CHANGED
@@ -1,7 +1,8 @@
1
1
  import { preventNativeAwait, isTypescriptObject } from '@orpc/shared';
2
- export { AsyncIteratorClass, EventPublisher, asyncIteratorToStream as eventIteratorToStream, onError, onFinish, onStart, onSuccess, streamToAsyncIteratorClass as streamToEventIterator } from '@orpc/shared';
3
- import { i as isDefinedError } from './shared/client.9Pe_7OOW.mjs';
4
- export { C as COMMON_ORPC_ERROR_DEFS, c as ORPCError, O as ORPC_CLIENT_PACKAGE_NAME, a as ORPC_CLIENT_PACKAGE_VERSION, g as createORPCErrorFromJson, b as fallbackORPCErrorMessage, f as fallbackORPCErrorStatus, e as isORPCErrorJson, d as isORPCErrorStatus, m as mapEventIterator, t as toORPCError } from './shared/client.9Pe_7OOW.mjs';
2
+ export { AsyncIteratorClass, EventPublisher, asyncIteratorToStream as eventIteratorToStream, asyncIteratorToUnproxiedDataStream as eventIteratorToUnproxiedDataStream, onError, onFinish, onStart, onSuccess, streamToAsyncIteratorClass as streamToEventIterator } from '@orpc/shared';
3
+ import { i as isDefinedError } from './shared/client.C3KE2j2B.mjs';
4
+ export { C as COMMON_ORPC_ERROR_DEFS, c as ORPCError, O as ORPC_CLIENT_PACKAGE_NAME, a as ORPC_CLIENT_PACKAGE_VERSION, g as createORPCErrorFromJson, b as fallbackORPCErrorMessage, f as fallbackORPCErrorStatus, e as isORPCErrorJson, d as isORPCErrorStatus, t as toORPCError } from './shared/client.C3KE2j2B.mjs';
5
+ export { m as mapEventIterator } from './shared/client.BLtwTQUg.mjs';
5
6
  export { ErrorEvent } from '@orpc/standard-server';
6
7
 
7
8
  async function safe(promise) {
@@ -1,8 +1,8 @@
1
1
  import { Value, Promisable } from '@orpc/shared';
2
- import { StandardHeaders, StandardRequest } from '@orpc/standard-server';
2
+ import { StandardHeaders, StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
3
3
  import { BatchResponseMode } from '@orpc/standard-server/batch';
4
- import { S as StandardLinkClientInterceptorOptions, a as StandardLinkPlugin, b as StandardLinkOptions, c as StandardLinkInterceptorOptions } from '../shared/client.Bwgm6dgk.mjs';
5
- import { b as ClientContext } from '../shared/client.BOYsZIRq.mjs';
4
+ import { S as StandardLinkClientInterceptorOptions, a as StandardLinkPlugin, b as StandardLinkOptions, c as StandardLinkInterceptorOptions } from '../shared/client.CPgZaUox.mjs';
5
+ import { b as ClientContext } from '../shared/client.BH1AYT_p.mjs';
6
6
 
7
7
  interface BatchLinkPluginGroup<T extends ClientContext> {
8
8
  condition(options: StandardLinkClientInterceptorOptions<T>): boolean;
@@ -162,6 +162,52 @@ declare class ClientRetryPlugin<T extends ClientRetryPluginContext> implements S
162
162
  init(options: StandardLinkOptions<T>): void;
163
163
  }
164
164
 
165
+ interface RetryAfterPluginOptions<T extends ClientContext> {
166
+ /**
167
+ * Override condition to determine whether to retry or not.
168
+ *
169
+ * @default ((response) => response.status === 429 || response.status === 503)
170
+ */
171
+ condition?: Value<boolean, [
172
+ response: StandardLazyResponse,
173
+ options: StandardLinkClientInterceptorOptions<T>
174
+ ]>;
175
+ /**
176
+ * Maximum attempts before giving up retries.
177
+ *
178
+ * @default 3
179
+ */
180
+ maxAttempts?: Value<number, [
181
+ response: StandardLazyResponse,
182
+ options: StandardLinkClientInterceptorOptions<T>
183
+ ]>;
184
+ /**
185
+ * Maximum timeout in milliseconds to wait before giving up retries.
186
+ *
187
+ * @default 5 * 60 * 1000 (5 minutes)
188
+ */
189
+ timeout?: Value<number, [
190
+ response: StandardLazyResponse,
191
+ options: StandardLinkClientInterceptorOptions<T>
192
+ ]>;
193
+ }
194
+ /**
195
+ * The Retry After Plugin automatically retries requests based on server `Retry-After` headers.
196
+ * This is particularly useful for handling rate limiting and temporary server unavailability.
197
+ *
198
+ * @see {@link https://orpc.unnoq.com/docs/plugins/retry-after Retry After Plugin Docs}
199
+ */
200
+ declare class RetryAfterPlugin<T extends ClientContext> implements StandardLinkPlugin<T> {
201
+ private readonly condition;
202
+ private readonly maxAttempts;
203
+ private readonly timeout;
204
+ order: number;
205
+ constructor(options?: RetryAfterPluginOptions<T>);
206
+ init(options: StandardLinkOptions<T>): void;
207
+ private parseRetryAfterHeader;
208
+ private delayExecution;
209
+ }
210
+
165
211
  interface SimpleCsrfProtectionLinkPluginOptions<T extends ClientContext> {
166
212
  /**
167
213
  * The name of the header to check.
@@ -199,5 +245,5 @@ declare class SimpleCsrfProtectionLinkPlugin<T extends ClientContext> implements
199
245
  init(options: StandardLinkOptions<T>): void;
200
246
  }
201
247
 
202
- export { BatchLinkPlugin, ClientRetryPlugin, ClientRetryPluginInvalidEventIteratorRetryResponse, DedupeRequestsPlugin, SimpleCsrfProtectionLinkPlugin };
203
- export type { BatchLinkPluginGroup, BatchLinkPluginOptions, ClientRetryPluginAttemptOptions, ClientRetryPluginContext, ClientRetryPluginOptions, DedupeRequestsPluginGroup, DedupeRequestsPluginOptions, SimpleCsrfProtectionLinkPluginOptions };
248
+ export { BatchLinkPlugin, ClientRetryPlugin, ClientRetryPluginInvalidEventIteratorRetryResponse, DedupeRequestsPlugin, RetryAfterPlugin, SimpleCsrfProtectionLinkPlugin };
249
+ export type { BatchLinkPluginGroup, BatchLinkPluginOptions, ClientRetryPluginAttemptOptions, ClientRetryPluginContext, ClientRetryPluginOptions, DedupeRequestsPluginGroup, DedupeRequestsPluginOptions, RetryAfterPluginOptions, SimpleCsrfProtectionLinkPluginOptions };
@@ -1,8 +1,8 @@
1
1
  import { Value, Promisable } from '@orpc/shared';
2
- import { StandardHeaders, StandardRequest } from '@orpc/standard-server';
2
+ import { StandardHeaders, StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
3
3
  import { BatchResponseMode } from '@orpc/standard-server/batch';
4
- import { S as StandardLinkClientInterceptorOptions, a as StandardLinkPlugin, b as StandardLinkOptions, c as StandardLinkInterceptorOptions } from '../shared/client.BG98rYdO.js';
5
- import { b as ClientContext } from '../shared/client.BOYsZIRq.js';
4
+ import { S as StandardLinkClientInterceptorOptions, a as StandardLinkPlugin, b as StandardLinkOptions, c as StandardLinkInterceptorOptions } from '../shared/client.De8SW4Kw.js';
5
+ import { b as ClientContext } from '../shared/client.BH1AYT_p.js';
6
6
 
7
7
  interface BatchLinkPluginGroup<T extends ClientContext> {
8
8
  condition(options: StandardLinkClientInterceptorOptions<T>): boolean;
@@ -162,6 +162,52 @@ declare class ClientRetryPlugin<T extends ClientRetryPluginContext> implements S
162
162
  init(options: StandardLinkOptions<T>): void;
163
163
  }
164
164
 
165
+ interface RetryAfterPluginOptions<T extends ClientContext> {
166
+ /**
167
+ * Override condition to determine whether to retry or not.
168
+ *
169
+ * @default ((response) => response.status === 429 || response.status === 503)
170
+ */
171
+ condition?: Value<boolean, [
172
+ response: StandardLazyResponse,
173
+ options: StandardLinkClientInterceptorOptions<T>
174
+ ]>;
175
+ /**
176
+ * Maximum attempts before giving up retries.
177
+ *
178
+ * @default 3
179
+ */
180
+ maxAttempts?: Value<number, [
181
+ response: StandardLazyResponse,
182
+ options: StandardLinkClientInterceptorOptions<T>
183
+ ]>;
184
+ /**
185
+ * Maximum timeout in milliseconds to wait before giving up retries.
186
+ *
187
+ * @default 5 * 60 * 1000 (5 minutes)
188
+ */
189
+ timeout?: Value<number, [
190
+ response: StandardLazyResponse,
191
+ options: StandardLinkClientInterceptorOptions<T>
192
+ ]>;
193
+ }
194
+ /**
195
+ * The Retry After Plugin automatically retries requests based on server `Retry-After` headers.
196
+ * This is particularly useful for handling rate limiting and temporary server unavailability.
197
+ *
198
+ * @see {@link https://orpc.unnoq.com/docs/plugins/retry-after Retry After Plugin Docs}
199
+ */
200
+ declare class RetryAfterPlugin<T extends ClientContext> implements StandardLinkPlugin<T> {
201
+ private readonly condition;
202
+ private readonly maxAttempts;
203
+ private readonly timeout;
204
+ order: number;
205
+ constructor(options?: RetryAfterPluginOptions<T>);
206
+ init(options: StandardLinkOptions<T>): void;
207
+ private parseRetryAfterHeader;
208
+ private delayExecution;
209
+ }
210
+
165
211
  interface SimpleCsrfProtectionLinkPluginOptions<T extends ClientContext> {
166
212
  /**
167
213
  * The name of the header to check.
@@ -199,5 +245,5 @@ declare class SimpleCsrfProtectionLinkPlugin<T extends ClientContext> implements
199
245
  init(options: StandardLinkOptions<T>): void;
200
246
  }
201
247
 
202
- export { BatchLinkPlugin, ClientRetryPlugin, ClientRetryPluginInvalidEventIteratorRetryResponse, DedupeRequestsPlugin, SimpleCsrfProtectionLinkPlugin };
203
- export type { BatchLinkPluginGroup, BatchLinkPluginOptions, ClientRetryPluginAttemptOptions, ClientRetryPluginContext, ClientRetryPluginOptions, DedupeRequestsPluginGroup, DedupeRequestsPluginOptions, SimpleCsrfProtectionLinkPluginOptions };
248
+ export { BatchLinkPlugin, ClientRetryPlugin, ClientRetryPluginInvalidEventIteratorRetryResponse, DedupeRequestsPlugin, RetryAfterPlugin, SimpleCsrfProtectionLinkPlugin };
249
+ export type { BatchLinkPluginGroup, BatchLinkPluginOptions, ClientRetryPluginAttemptOptions, ClientRetryPluginContext, ClientRetryPluginOptions, DedupeRequestsPluginGroup, DedupeRequestsPluginOptions, RetryAfterPluginOptions, SimpleCsrfProtectionLinkPluginOptions };
@@ -1,6 +1,7 @@
1
1
  import { isAsyncIteratorObject, defer, value, splitInHalf, toArray, stringifyJSON, overlayProxy, AsyncIteratorClass } from '@orpc/shared';
2
2
  import { toBatchRequest, parseBatchResponse, toBatchAbortSignal } from '@orpc/standard-server/batch';
3
- import { replicateStandardLazyResponse, getEventMeta } from '@orpc/standard-server';
3
+ import { replicateStandardLazyResponse, getEventMeta, flattenHeader } from '@orpc/standard-server';
4
+ import { C as COMMON_ORPC_ERROR_DEFS } from '../shared/client.C3KE2j2B.mjs';
4
5
 
5
6
  class BatchLinkPlugin {
6
7
  groups;
@@ -371,6 +372,83 @@ class ClientRetryPlugin {
371
372
  }
372
373
  }
373
374
 
375
+ class RetryAfterPlugin {
376
+ condition;
377
+ maxAttempts;
378
+ timeout;
379
+ order = 19e5;
380
+ constructor(options = {}) {
381
+ this.condition = options.condition ?? ((response) => response.status === COMMON_ORPC_ERROR_DEFS.TOO_MANY_REQUESTS.status || response.status === COMMON_ORPC_ERROR_DEFS.SERVICE_UNAVAILABLE.status);
382
+ this.maxAttempts = options.maxAttempts ?? 3;
383
+ this.timeout = options.timeout ?? 5 * 60 * 1e3;
384
+ }
385
+ init(options) {
386
+ options.clientInterceptors ??= [];
387
+ options.clientInterceptors.push(async (interceptorOptions) => {
388
+ const startTime = Date.now();
389
+ let attemptCount = 0;
390
+ while (true) {
391
+ attemptCount++;
392
+ const response = await interceptorOptions.next();
393
+ if (!value(this.condition, response, interceptorOptions)) {
394
+ return response;
395
+ }
396
+ const retryAfterHeader = flattenHeader(response.headers["retry-after"]);
397
+ const retryAfterMs = this.parseRetryAfterHeader(retryAfterHeader);
398
+ if (retryAfterMs === void 0) {
399
+ return response;
400
+ }
401
+ if (attemptCount >= value(this.maxAttempts, response, interceptorOptions)) {
402
+ return response;
403
+ }
404
+ const timeoutMs = value(this.timeout, response, interceptorOptions);
405
+ const elapsedTime = Date.now() - startTime;
406
+ if (elapsedTime + retryAfterMs > timeoutMs) {
407
+ return response;
408
+ }
409
+ await this.delayExecution(retryAfterMs, interceptorOptions.signal);
410
+ if (interceptorOptions.signal?.aborted) {
411
+ return response;
412
+ }
413
+ }
414
+ });
415
+ }
416
+ parseRetryAfterHeader(value2) {
417
+ value2 = value2?.trim();
418
+ if (!value2) {
419
+ return void 0;
420
+ }
421
+ const seconds = Number(value2);
422
+ if (Number.isFinite(seconds)) {
423
+ return Math.max(0, seconds * 1e3);
424
+ }
425
+ const retryDate = Date.parse(value2);
426
+ if (!Number.isNaN(retryDate)) {
427
+ return Math.max(0, retryDate - Date.now());
428
+ }
429
+ return void 0;
430
+ }
431
+ delayExecution(ms, signal) {
432
+ return new Promise((resolve) => {
433
+ if (signal?.aborted) {
434
+ resolve();
435
+ return;
436
+ }
437
+ let timeout;
438
+ const onAbort = () => {
439
+ clearTimeout(timeout);
440
+ timeout = void 0;
441
+ resolve();
442
+ };
443
+ signal?.addEventListener("abort", onAbort, { once: true });
444
+ timeout = setTimeout(() => {
445
+ signal?.removeEventListener("abort", onAbort);
446
+ resolve();
447
+ }, ms);
448
+ });
449
+ }
450
+ }
451
+
374
452
  class SimpleCsrfProtectionLinkPlugin {
375
453
  headerName;
376
454
  headerValue;
@@ -404,4 +482,4 @@ class SimpleCsrfProtectionLinkPlugin {
404
482
  }
405
483
  }
406
484
 
407
- export { BatchLinkPlugin, ClientRetryPlugin, ClientRetryPluginInvalidEventIteratorRetryResponse, DedupeRequestsPlugin, SimpleCsrfProtectionLinkPlugin };
485
+ export { BatchLinkPlugin, ClientRetryPlugin, ClientRetryPluginInvalidEventIteratorRetryResponse, DedupeRequestsPlugin, RetryAfterPlugin, SimpleCsrfProtectionLinkPlugin };
@@ -0,0 +1,83 @@
1
+ import { PromiseWithError } from '@orpc/shared';
2
+
3
+ type HTTPPath = `/${string}`;
4
+ type HTTPMethod = 'HEAD' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
5
+ type ClientContext = Record<PropertyKey, any>;
6
+ interface ClientOptions<T extends ClientContext> {
7
+ signal?: AbortSignal;
8
+ lastEventId?: string | undefined;
9
+ context: T;
10
+ }
11
+ type FriendlyClientOptions<T extends ClientContext> = Omit<ClientOptions<T>, 'context'> & (Record<never, never> extends T ? {
12
+ context?: T;
13
+ } : {
14
+ context: T;
15
+ });
16
+ type ClientRest<TClientContext extends ClientContext, TInput> = Record<never, never> extends TClientContext ? undefined extends TInput ? [input?: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options: FriendlyClientOptions<TClientContext>];
17
+ type ClientPromiseResult<TOutput, TError> = PromiseWithError<TOutput, TError>;
18
+ interface Client<TClientContext extends ClientContext, TInput, TOutput, TError> {
19
+ (...rest: ClientRest<TClientContext, TInput>): ClientPromiseResult<TOutput, TError>;
20
+ }
21
+ type NestedClient<TClientContext extends ClientContext> = Client<TClientContext, any, any, any> | {
22
+ [k: string]: NestedClient<TClientContext>;
23
+ };
24
+ type InferClientContext<T extends NestedClient<any>> = T extends NestedClient<infer U> ? U : never;
25
+ interface ClientLink<TClientContext extends ClientContext> {
26
+ call: (path: readonly string[], input: unknown, options: ClientOptions<TClientContext>) => Promise<unknown>;
27
+ }
28
+ /**
29
+ * Recursively infers the **input types** from a client.
30
+ *
31
+ * Produces a nested map where each endpoint's input type is preserved.
32
+ */
33
+ type InferClientInputs<T extends NestedClient<any>> = T extends Client<any, infer U, any, any> ? U : {
34
+ [K in keyof T]: T[K] extends NestedClient<any> ? InferClientInputs<T[K]> : never;
35
+ };
36
+ /**
37
+ * Recursively infers the **body input types** from a client.
38
+ *
39
+ * If an endpoint's input includes `{ body: ... }`, only the `body` portion is extracted.
40
+ * Produces a nested map of body input types.
41
+ */
42
+ type InferClientBodyInputs<T extends NestedClient<any>> = T extends Client<any, infer U, any, any> ? U extends {
43
+ body: infer UBody;
44
+ } ? UBody : U : {
45
+ [K in keyof T]: T[K] extends NestedClient<any> ? InferClientBodyInputs<T[K]> : never;
46
+ };
47
+ /**
48
+ * Recursively infers the **output types** from a client.
49
+ *
50
+ * Produces a nested map where each endpoint's output type is preserved.
51
+ */
52
+ type InferClientOutputs<T extends NestedClient<any>> = T extends Client<any, any, infer U, any> ? U : {
53
+ [K in keyof T]: T[K] extends NestedClient<any> ? InferClientOutputs<T[K]> : never;
54
+ };
55
+ /**
56
+ * Recursively infers the **body output types** from a client.
57
+ *
58
+ * If an endpoint's output includes `{ body: ... }`, only the `body` portion is extracted.
59
+ * Produces a nested map of body output types.
60
+ */
61
+ type InferClientBodyOutputs<T extends NestedClient<any>> = T extends Client<any, any, infer U, any> ? U extends {
62
+ body: infer UBody;
63
+ } ? UBody : U : {
64
+ [K in keyof T]: T[K] extends NestedClient<any> ? InferClientBodyOutputs<T[K]> : never;
65
+ };
66
+ /**
67
+ * Recursively infers the **error types** from a client when you use [type-safe errors](https://orpc.unnoq.com/docs/error-handling#type‐safe-error-handling).
68
+ *
69
+ * Produces a nested map where each endpoint's error type is preserved.
70
+ */
71
+ type InferClientErrors<T extends NestedClient<any>> = T extends Client<any, any, any, infer U> ? U : {
72
+ [K in keyof T]: T[K] extends NestedClient<any> ? InferClientErrors<T[K]> : never;
73
+ };
74
+ /**
75
+ * Recursively infers a **union of all error types** from a client when you use [type-safe errors](https://orpc.unnoq.com/docs/error-handling#type‐safe-error-handling).
76
+ *
77
+ * Useful when you want to handle all possible errors from any endpoint at once.
78
+ */
79
+ type InferClientErrorUnion<T extends NestedClient<any>> = T extends Client<any, any, any, infer U> ? U : {
80
+ [K in keyof T]: T[K] extends NestedClient<any> ? InferClientErrorUnion<T[K]> : never;
81
+ }[keyof T];
82
+
83
+ export type { ClientLink as C, FriendlyClientOptions as F, HTTPPath as H, InferClientContext as I, NestedClient as N, ClientPromiseResult as a, ClientContext as b, ClientOptions as c, Client as d, ClientRest as e, HTTPMethod as f, InferClientInputs as g, InferClientBodyInputs as h, InferClientOutputs as i, InferClientBodyOutputs as j, InferClientErrors as k, InferClientErrorUnion as l };
@@ -0,0 +1,83 @@
1
+ import { PromiseWithError } from '@orpc/shared';
2
+
3
+ type HTTPPath = `/${string}`;
4
+ type HTTPMethod = 'HEAD' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
5
+ type ClientContext = Record<PropertyKey, any>;
6
+ interface ClientOptions<T extends ClientContext> {
7
+ signal?: AbortSignal;
8
+ lastEventId?: string | undefined;
9
+ context: T;
10
+ }
11
+ type FriendlyClientOptions<T extends ClientContext> = Omit<ClientOptions<T>, 'context'> & (Record<never, never> extends T ? {
12
+ context?: T;
13
+ } : {
14
+ context: T;
15
+ });
16
+ type ClientRest<TClientContext extends ClientContext, TInput> = Record<never, never> extends TClientContext ? undefined extends TInput ? [input?: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options: FriendlyClientOptions<TClientContext>];
17
+ type ClientPromiseResult<TOutput, TError> = PromiseWithError<TOutput, TError>;
18
+ interface Client<TClientContext extends ClientContext, TInput, TOutput, TError> {
19
+ (...rest: ClientRest<TClientContext, TInput>): ClientPromiseResult<TOutput, TError>;
20
+ }
21
+ type NestedClient<TClientContext extends ClientContext> = Client<TClientContext, any, any, any> | {
22
+ [k: string]: NestedClient<TClientContext>;
23
+ };
24
+ type InferClientContext<T extends NestedClient<any>> = T extends NestedClient<infer U> ? U : never;
25
+ interface ClientLink<TClientContext extends ClientContext> {
26
+ call: (path: readonly string[], input: unknown, options: ClientOptions<TClientContext>) => Promise<unknown>;
27
+ }
28
+ /**
29
+ * Recursively infers the **input types** from a client.
30
+ *
31
+ * Produces a nested map where each endpoint's input type is preserved.
32
+ */
33
+ type InferClientInputs<T extends NestedClient<any>> = T extends Client<any, infer U, any, any> ? U : {
34
+ [K in keyof T]: T[K] extends NestedClient<any> ? InferClientInputs<T[K]> : never;
35
+ };
36
+ /**
37
+ * Recursively infers the **body input types** from a client.
38
+ *
39
+ * If an endpoint's input includes `{ body: ... }`, only the `body` portion is extracted.
40
+ * Produces a nested map of body input types.
41
+ */
42
+ type InferClientBodyInputs<T extends NestedClient<any>> = T extends Client<any, infer U, any, any> ? U extends {
43
+ body: infer UBody;
44
+ } ? UBody : U : {
45
+ [K in keyof T]: T[K] extends NestedClient<any> ? InferClientBodyInputs<T[K]> : never;
46
+ };
47
+ /**
48
+ * Recursively infers the **output types** from a client.
49
+ *
50
+ * Produces a nested map where each endpoint's output type is preserved.
51
+ */
52
+ type InferClientOutputs<T extends NestedClient<any>> = T extends Client<any, any, infer U, any> ? U : {
53
+ [K in keyof T]: T[K] extends NestedClient<any> ? InferClientOutputs<T[K]> : never;
54
+ };
55
+ /**
56
+ * Recursively infers the **body output types** from a client.
57
+ *
58
+ * If an endpoint's output includes `{ body: ... }`, only the `body` portion is extracted.
59
+ * Produces a nested map of body output types.
60
+ */
61
+ type InferClientBodyOutputs<T extends NestedClient<any>> = T extends Client<any, any, infer U, any> ? U extends {
62
+ body: infer UBody;
63
+ } ? UBody : U : {
64
+ [K in keyof T]: T[K] extends NestedClient<any> ? InferClientBodyOutputs<T[K]> : never;
65
+ };
66
+ /**
67
+ * Recursively infers the **error types** from a client when you use [type-safe errors](https://orpc.unnoq.com/docs/error-handling#type‐safe-error-handling).
68
+ *
69
+ * Produces a nested map where each endpoint's error type is preserved.
70
+ */
71
+ type InferClientErrors<T extends NestedClient<any>> = T extends Client<any, any, any, infer U> ? U : {
72
+ [K in keyof T]: T[K] extends NestedClient<any> ? InferClientErrors<T[K]> : never;
73
+ };
74
+ /**
75
+ * Recursively infers a **union of all error types** from a client when you use [type-safe errors](https://orpc.unnoq.com/docs/error-handling#type‐safe-error-handling).
76
+ *
77
+ * Useful when you want to handle all possible errors from any endpoint at once.
78
+ */
79
+ type InferClientErrorUnion<T extends NestedClient<any>> = T extends Client<any, any, any, infer U> ? U : {
80
+ [K in keyof T]: T[K] extends NestedClient<any> ? InferClientErrorUnion<T[K]> : never;
81
+ }[keyof T];
82
+
83
+ export type { ClientLink as C, FriendlyClientOptions as F, HTTPPath as H, InferClientContext as I, NestedClient as N, ClientPromiseResult as a, ClientContext as b, ClientOptions as c, Client as d, ClientRest as e, HTTPMethod as f, InferClientInputs as g, InferClientBodyInputs as h, InferClientOutputs as i, InferClientBodyOutputs as j, InferClientErrors as k, InferClientErrorUnion as l };
@@ -0,0 +1,40 @@
1
+ import { AsyncIteratorClass, isTypescriptObject } from '@orpc/shared';
2
+ import { getEventMeta, withEventMeta } from '@orpc/standard-server';
3
+
4
+ function mapEventIterator(iterator, maps) {
5
+ const mapError = async (error) => {
6
+ let mappedError = await maps.error(error);
7
+ if (mappedError !== error) {
8
+ const meta = getEventMeta(error);
9
+ if (meta && isTypescriptObject(mappedError)) {
10
+ mappedError = withEventMeta(mappedError, meta);
11
+ }
12
+ }
13
+ return mappedError;
14
+ };
15
+ return new AsyncIteratorClass(async () => {
16
+ const { done, value } = await (async () => {
17
+ try {
18
+ return await iterator.next();
19
+ } catch (error) {
20
+ throw await mapError(error);
21
+ }
22
+ })();
23
+ let mappedValue = await maps.value(value, done);
24
+ if (mappedValue !== value) {
25
+ const meta = getEventMeta(value);
26
+ if (meta && isTypescriptObject(mappedValue)) {
27
+ mappedValue = withEventMeta(mappedValue, meta);
28
+ }
29
+ }
30
+ return { done, value: mappedValue };
31
+ }, async () => {
32
+ try {
33
+ await iterator.return?.();
34
+ } catch (error) {
35
+ throw await mapError(error);
36
+ }
37
+ });
38
+ }
39
+
40
+ export { mapEventIterator as m };
@@ -1,5 +1,5 @@
1
- import { b as ClientContext, c as ClientOptions, f as HTTPMethod } from './client.BOYsZIRq.js';
2
- import { e as StandardLinkCodec, b as StandardLinkOptions, d as StandardLink, f as StandardLinkClient } from './client.BG98rYdO.js';
1
+ import { b as ClientContext, c as ClientOptions, f as HTTPMethod } from './client.BH1AYT_p.js';
2
+ import { e as StandardLinkCodec, b as StandardLinkOptions, d as StandardLink, f as StandardLinkClient } from './client.De8SW4Kw.js';
3
3
  import { Segment, Value, Promisable } from '@orpc/shared';
4
4
  import { StandardHeaders, StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
5
5
 
@@ -1,8 +1,7 @@
1
- import { resolveMaybeOptionalOptions, getConstructor, isObject, AsyncIteratorClass, isTypescriptObject } from '@orpc/shared';
2
- import { getEventMeta, withEventMeta } from '@orpc/standard-server';
1
+ import { resolveMaybeOptionalOptions, getConstructor, isObject } from '@orpc/shared';
3
2
 
4
3
  const ORPC_CLIENT_PACKAGE_NAME = "@orpc/client";
5
- const ORPC_CLIENT_PACKAGE_VERSION = "0.0.0-next.f7af1c4";
4
+ const ORPC_CLIENT_PACKAGE_VERSION = "0.0.0-next.f8cfaa5";
6
5
 
7
6
  const COMMON_ORPC_ERROR_DEFS = {
8
7
  BAD_REQUEST: {
@@ -169,40 +168,4 @@ function createORPCErrorFromJson(json, options = {}) {
169
168
  });
170
169
  }
171
170
 
172
- function mapEventIterator(iterator, maps) {
173
- const mapError = async (error) => {
174
- let mappedError = await maps.error(error);
175
- if (mappedError !== error) {
176
- const meta = getEventMeta(error);
177
- if (meta && isTypescriptObject(mappedError)) {
178
- mappedError = withEventMeta(mappedError, meta);
179
- }
180
- }
181
- return mappedError;
182
- };
183
- return new AsyncIteratorClass(async () => {
184
- const { done, value } = await (async () => {
185
- try {
186
- return await iterator.next();
187
- } catch (error) {
188
- throw await mapError(error);
189
- }
190
- })();
191
- let mappedValue = await maps.value(value, done);
192
- if (mappedValue !== value) {
193
- const meta = getEventMeta(value);
194
- if (meta && isTypescriptObject(mappedValue)) {
195
- mappedValue = withEventMeta(mappedValue, meta);
196
- }
197
- }
198
- return { done, value: mappedValue };
199
- }, async () => {
200
- try {
201
- await iterator.return?.();
202
- } catch (error) {
203
- throw await mapError(error);
204
- }
205
- });
206
- }
207
-
208
- export { COMMON_ORPC_ERROR_DEFS as C, ORPC_CLIENT_PACKAGE_NAME as O, ORPC_CLIENT_PACKAGE_VERSION as a, fallbackORPCErrorMessage as b, ORPCError as c, isORPCErrorStatus as d, isORPCErrorJson as e, fallbackORPCErrorStatus as f, createORPCErrorFromJson as g, isDefinedError as i, mapEventIterator as m, toORPCError as t };
171
+ export { COMMON_ORPC_ERROR_DEFS as C, ORPC_CLIENT_PACKAGE_NAME as O, ORPC_CLIENT_PACKAGE_VERSION as a, fallbackORPCErrorMessage as b, ORPCError as c, isORPCErrorStatus as d, isORPCErrorJson as e, fallbackORPCErrorStatus as f, createORPCErrorFromJson as g, isDefinedError as i, toORPCError as t };
@@ -1,6 +1,6 @@
1
1
  import { Interceptor } from '@orpc/shared';
2
2
  import { StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
3
- import { b as ClientContext, c as ClientOptions, C as ClientLink } from './client.BOYsZIRq.mjs';
3
+ import { b as ClientContext, c as ClientOptions, C as ClientLink } from './client.BH1AYT_p.mjs';
4
4
 
5
5
  interface StandardLinkPlugin<T extends ClientContext> {
6
6
  order?: number;
@@ -1,5 +1,5 @@
1
- import { b as ClientContext, c as ClientOptions, f as HTTPMethod } from './client.BOYsZIRq.mjs';
2
- import { e as StandardLinkCodec, b as StandardLinkOptions, d as StandardLink, f as StandardLinkClient } from './client.Bwgm6dgk.mjs';
1
+ import { b as ClientContext, c as ClientOptions, f as HTTPMethod } from './client.BH1AYT_p.mjs';
2
+ import { e as StandardLinkCodec, b as StandardLinkOptions, d as StandardLink, f as StandardLinkClient } from './client.CPgZaUox.mjs';
3
3
  import { Segment, Value, Promisable } from '@orpc/shared';
4
4
  import { StandardHeaders, StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
5
5
 
@@ -1,6 +1,6 @@
1
1
  import { Interceptor } from '@orpc/shared';
2
2
  import { StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
3
- import { b as ClientContext, c as ClientOptions, C as ClientLink } from './client.BOYsZIRq.js';
3
+ import { b as ClientContext, c as ClientOptions, C as ClientLink } from './client.BH1AYT_p.js';
4
4
 
5
5
  interface StandardLinkPlugin<T extends ClientContext> {
6
6
  order?: number;
@@ -1,7 +1,8 @@
1
1
  import { toArray, runWithSpan, ORPC_NAME, isAsyncIteratorObject, asyncIteratorWithSpan, intercept, getGlobalOtelConfig, isObject, value, stringifyJSON } from '@orpc/shared';
2
2
  import { mergeStandardHeaders, ErrorEvent } from '@orpc/standard-server';
3
- import { C as COMMON_ORPC_ERROR_DEFS, d as isORPCErrorStatus, e as isORPCErrorJson, g as createORPCErrorFromJson, c as ORPCError, m as mapEventIterator, t as toORPCError } from './client.9Pe_7OOW.mjs';
3
+ import { C as COMMON_ORPC_ERROR_DEFS, d as isORPCErrorStatus, e as isORPCErrorJson, g as createORPCErrorFromJson, c as ORPCError, t as toORPCError } from './client.C3KE2j2B.mjs';
4
4
  import { toStandardHeaders as toStandardHeaders$1 } from '@orpc/standard-server-fetch';
5
+ import { m as mapEventIterator } from './client.BLtwTQUg.mjs';
5
6
 
6
7
  class CompositeStandardLinkPlugin {
7
8
  plugins;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/client",
3
3
  "type": "module",
4
- "version": "0.0.0-next.f7af1c4",
4
+ "version": "0.0.0-next.f8cfaa5",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -49,13 +49,13 @@
49
49
  "dist"
50
50
  ],
51
51
  "dependencies": {
52
- "@orpc/standard-server-fetch": "0.0.0-next.f7af1c4",
53
- "@orpc/standard-server": "0.0.0-next.f7af1c4",
54
- "@orpc/standard-server-peer": "0.0.0-next.f7af1c4",
55
- "@orpc/shared": "0.0.0-next.f7af1c4"
52
+ "@orpc/shared": "0.0.0-next.f8cfaa5",
53
+ "@orpc/standard-server": "0.0.0-next.f8cfaa5",
54
+ "@orpc/standard-server-fetch": "0.0.0-next.f8cfaa5",
55
+ "@orpc/standard-server-peer": "0.0.0-next.f8cfaa5"
56
56
  },
57
57
  "devDependencies": {
58
- "zod": "^4.1.11"
58
+ "zod": "^4.1.12"
59
59
  },
60
60
  "scripts": {
61
61
  "build": "unbuild",
@@ -1,29 +0,0 @@
1
- import { PromiseWithError } from '@orpc/shared';
2
-
3
- type HTTPPath = `/${string}`;
4
- type HTTPMethod = 'HEAD' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
5
- type ClientContext = Record<PropertyKey, any>;
6
- interface ClientOptions<T extends ClientContext> {
7
- signal?: AbortSignal;
8
- lastEventId?: string | undefined;
9
- context: T;
10
- }
11
- type FriendlyClientOptions<T extends ClientContext> = Omit<ClientOptions<T>, 'context'> & (Record<never, never> extends T ? {
12
- context?: T;
13
- } : {
14
- context: T;
15
- });
16
- type ClientRest<TClientContext extends ClientContext, TInput> = Record<never, never> extends TClientContext ? undefined extends TInput ? [input?: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options: FriendlyClientOptions<TClientContext>];
17
- type ClientPromiseResult<TOutput, TError> = PromiseWithError<TOutput, TError>;
18
- interface Client<TClientContext extends ClientContext, TInput, TOutput, TError> {
19
- (...rest: ClientRest<TClientContext, TInput>): ClientPromiseResult<TOutput, TError>;
20
- }
21
- type NestedClient<TClientContext extends ClientContext> = Client<TClientContext, any, any, any> | {
22
- [k: string]: NestedClient<TClientContext>;
23
- };
24
- type InferClientContext<T extends NestedClient<any>> = T extends NestedClient<infer U> ? U : never;
25
- interface ClientLink<TClientContext extends ClientContext> {
26
- call: (path: readonly string[], input: unknown, options: ClientOptions<TClientContext>) => Promise<unknown>;
27
- }
28
-
29
- export type { ClientLink as C, FriendlyClientOptions as F, HTTPPath as H, InferClientContext as I, NestedClient as N, ClientPromiseResult as a, ClientContext as b, ClientOptions as c, Client as d, ClientRest as e, HTTPMethod as f };
@@ -1,29 +0,0 @@
1
- import { PromiseWithError } from '@orpc/shared';
2
-
3
- type HTTPPath = `/${string}`;
4
- type HTTPMethod = 'HEAD' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
5
- type ClientContext = Record<PropertyKey, any>;
6
- interface ClientOptions<T extends ClientContext> {
7
- signal?: AbortSignal;
8
- lastEventId?: string | undefined;
9
- context: T;
10
- }
11
- type FriendlyClientOptions<T extends ClientContext> = Omit<ClientOptions<T>, 'context'> & (Record<never, never> extends T ? {
12
- context?: T;
13
- } : {
14
- context: T;
15
- });
16
- type ClientRest<TClientContext extends ClientContext, TInput> = Record<never, never> extends TClientContext ? undefined extends TInput ? [input?: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options: FriendlyClientOptions<TClientContext>];
17
- type ClientPromiseResult<TOutput, TError> = PromiseWithError<TOutput, TError>;
18
- interface Client<TClientContext extends ClientContext, TInput, TOutput, TError> {
19
- (...rest: ClientRest<TClientContext, TInput>): ClientPromiseResult<TOutput, TError>;
20
- }
21
- type NestedClient<TClientContext extends ClientContext> = Client<TClientContext, any, any, any> | {
22
- [k: string]: NestedClient<TClientContext>;
23
- };
24
- type InferClientContext<T extends NestedClient<any>> = T extends NestedClient<infer U> ? U : never;
25
- interface ClientLink<TClientContext extends ClientContext> {
26
- call: (path: readonly string[], input: unknown, options: ClientOptions<TClientContext>) => Promise<unknown>;
27
- }
28
-
29
- export type { ClientLink as C, FriendlyClientOptions as F, HTTPPath as H, InferClientContext as I, NestedClient as N, ClientPromiseResult as a, ClientContext as b, ClientOptions as c, Client as d, ClientRest as e, HTTPMethod as f };