@orpc/server 1.7.10 → 1.8.0

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 CHANGED
@@ -30,6 +30,7 @@
30
30
  - **🔗 End-to-End Type Safety**: Ensure type-safe inputs, outputs, and errors from client to server.
31
31
  - **📘 First-Class OpenAPI**: Built-in support that fully adheres to the OpenAPI standard.
32
32
  - **📝 Contract-First Development**: Optionally define your API contract before implementation.
33
+ - **🔍 First-Class OpenTelemetry**: Seamlessly integrate with OpenTelemetry for observability.
33
34
  - **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte, Angular), Pinia Colada, and more.
34
35
  - **🚀 Server Actions**: Fully compatible with React Server Actions on Next.js, TanStack Start, and other platforms.
35
36
  - **🔠 Standard Schema Support**: Works out of the box with Zod, Valibot, ArkType, and other schema validators.
@@ -38,7 +39,6 @@
38
39
  - **📡 SSE & Streaming**: Enjoy full type-safe support for SSE and streaming.
39
40
  - **🌍 Multi-Runtime Support**: Fast and lightweight on Cloudflare, Deno, Bun, Node.js, and beyond.
40
41
  - **🔌 Extendability**: Easily extend functionality with plugins, middleware, and interceptors.
41
- - **🛡️ Reliability**: Well-tested, TypeScript-based, production-ready, and MIT licensed.
42
42
 
43
43
  ## Documentation
44
44
 
@@ -50,6 +50,7 @@ You can find the full documentation [here](https://orpc.unnoq.com).
50
50
  - [@orpc/server](https://www.npmjs.com/package/@orpc/server): Build your API or implement API contract.
51
51
  - [@orpc/client](https://www.npmjs.com/package/@orpc/client): Consume your API on the client with type-safety.
52
52
  - [@orpc/openapi](https://www.npmjs.com/package/@orpc/openapi): Generate OpenAPI specs and handle OpenAPI requests.
53
+ - [@orpc/otel](https://www.npmjs.com/package/@orpc/otel): [OpenTelemetry](https://opentelemetry.io/) integration for observability.
53
54
  - [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Deeply integrate oRPC with [NestJS](https://nestjs.com/).
54
55
  - [@orpc/react](https://www.npmjs.com/package/@orpc/react): Utilities for integrating oRPC with React and React Server Actions.
55
56
  - [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): [TanStack Query](https://tanstack.com/query/latest) integration.
@@ -7,9 +7,9 @@ import '@orpc/standard-server-fetch';
7
7
  import '@orpc/client';
8
8
  import { S as StrictGetMethodPlugin } from '../../shared/server.BW-nUGgA.mjs';
9
9
  import '@orpc/contract';
10
- import { b as StandardRPCHandler } from '../../shared/server.CIL9uKTN.mjs';
10
+ import { b as StandardRPCHandler } from '../../shared/server.CYRYFTxo.mjs';
11
11
  import '@orpc/client/standard';
12
- import '../../shared/server.NeumLVdS.mjs';
12
+ import '../../shared/server.B_fj3X5m.mjs';
13
13
 
14
14
  class AwsLambdaHandler {
15
15
  constructor(standardHandler, options = {}) {
@@ -1,13 +1,13 @@
1
1
  import { resolveMaybeOptionalOptions } from '@orpc/shared';
2
2
  import { ServerPeer } from '@orpc/standard-server-peer';
3
- import { h as handleStandardServerPeerMessage } from '../../shared/server.C6Q5sqYw.mjs';
3
+ import { c as createServerPeerHandleRequestFn } from '../../shared/server.UVMTOWrk.mjs';
4
4
  import '@orpc/client';
5
5
  import '@orpc/standard-server';
6
6
  import '@orpc/contract';
7
- import { b as StandardRPCHandler } from '../../shared/server.CIL9uKTN.mjs';
7
+ import { b as StandardRPCHandler } from '../../shared/server.CYRYFTxo.mjs';
8
8
  import '@orpc/client/standard';
9
9
  import '../../shared/server.DZ5BIITo.mjs';
10
- import '../../shared/server.NeumLVdS.mjs';
10
+ import '../../shared/server.B_fj3X5m.mjs';
11
11
 
12
12
  class BunWsHandler {
13
13
  constructor(standardHandler) {
@@ -17,16 +17,16 @@ class BunWsHandler {
17
17
  async message(ws, message, ...rest) {
18
18
  let peer = this.peers.get(ws);
19
19
  if (!peer) {
20
- this.peers.set(ws, peer = new ServerPeer((message2) => {
21
- ws.send(message2);
22
- }));
20
+ this.peers.set(ws, peer = new ServerPeer(
21
+ (message2) => {
22
+ ws.send(message2);
23
+ }
24
+ ));
23
25
  }
24
26
  const encodedMessage = typeof message === "string" ? message : new Uint8Array(message.buffer, message.byteOffset, message.byteLength);
25
- await handleStandardServerPeerMessage(
26
- this.standardHandler,
27
- peer,
27
+ await peer.message(
28
28
  encodedMessage,
29
- resolveMaybeOptionalOptions(rest)
29
+ createServerPeerHandleRequestFn(this.standardHandler, resolveMaybeOptionalOptions(rest))
30
30
  );
31
31
  }
32
32
  close(ws) {
@@ -1,13 +1,13 @@
1
1
  import { resolveMaybeOptionalOptions } from '@orpc/shared';
2
2
  import { ServerPeer } from '@orpc/standard-server-peer';
3
- import { h as handleStandardServerPeerMessage } from '../../shared/server.C6Q5sqYw.mjs';
3
+ import { c as createServerPeerHandleRequestFn } from '../../shared/server.UVMTOWrk.mjs';
4
4
  import '@orpc/client';
5
5
  import '@orpc/standard-server';
6
6
  import '@orpc/contract';
7
- import { b as StandardRPCHandler } from '../../shared/server.CIL9uKTN.mjs';
7
+ import { b as StandardRPCHandler } from '../../shared/server.CYRYFTxo.mjs';
8
8
  import '@orpc/client/standard';
9
9
  import '../../shared/server.DZ5BIITo.mjs';
10
- import '../../shared/server.NeumLVdS.mjs';
10
+ import '../../shared/server.B_fj3X5m.mjs';
11
11
 
12
12
  class experimental_CrosswsHandler {
13
13
  constructor(standardHandler) {
@@ -22,11 +22,9 @@ class experimental_CrosswsHandler {
22
22
  }));
23
23
  }
24
24
  const encodedMessage = typeof message.rawData === "string" ? message.rawData : message.uint8Array();
25
- await handleStandardServerPeerMessage(
26
- this.standardHandler,
27
- peer,
25
+ await peer.message(
28
26
  encodedMessage,
29
- resolveMaybeOptionalOptions(rest)
27
+ createServerPeerHandleRequestFn(this.standardHandler, resolveMaybeOptionalOptions(rest))
30
28
  );
31
29
  }
32
30
  close(ws) {
@@ -4,11 +4,11 @@ import { toStandardLazyRequest, toFetchResponse } from '@orpc/standard-server-fe
4
4
  import { r as resolveFriendlyStandardHandleOptions } from '../../shared/server.DZ5BIITo.mjs';
5
5
  import '@orpc/standard-server';
6
6
  import '@orpc/contract';
7
- import { C as CompositeStandardHandlerPlugin, b as StandardRPCHandler } from '../../shared/server.CIL9uKTN.mjs';
7
+ import { C as CompositeStandardHandlerPlugin, b as StandardRPCHandler } from '../../shared/server.CYRYFTxo.mjs';
8
8
  import '@orpc/client/standard';
9
9
  import '@orpc/standard-server/batch';
10
10
  import { S as StrictGetMethodPlugin } from '../../shared/server.BW-nUGgA.mjs';
11
- import '../../shared/server.NeumLVdS.mjs';
11
+ import '../../shared/server.B_fj3X5m.mjs';
12
12
 
13
13
  class BodyLimitPlugin {
14
14
  maxBodySize;
@@ -1,14 +1,14 @@
1
1
  import { postMessagePortMessage, onMessagePortMessage, onMessagePortClose } from '@orpc/client/message-port';
2
2
  import { resolveMaybeOptionalOptions } from '@orpc/shared';
3
3
  import { ServerPeer } from '@orpc/standard-server-peer';
4
- import { h as handleStandardServerPeerMessage } from '../../shared/server.C6Q5sqYw.mjs';
4
+ import { c as createServerPeerHandleRequestFn } from '../../shared/server.UVMTOWrk.mjs';
5
5
  import '@orpc/client';
6
6
  import '@orpc/standard-server';
7
7
  import '@orpc/contract';
8
- import { b as StandardRPCHandler } from '../../shared/server.CIL9uKTN.mjs';
8
+ import { b as StandardRPCHandler } from '../../shared/server.CYRYFTxo.mjs';
9
9
  import '@orpc/client/standard';
10
10
  import '../../shared/server.DZ5BIITo.mjs';
11
- import '../../shared/server.NeumLVdS.mjs';
11
+ import '../../shared/server.B_fj3X5m.mjs';
12
12
 
13
13
  class MessagePortHandler {
14
14
  constructor(standardHandler) {
@@ -19,11 +19,9 @@ class MessagePortHandler {
19
19
  return postMessagePortMessage(port, message);
20
20
  });
21
21
  onMessagePortMessage(port, async (message) => {
22
- await handleStandardServerPeerMessage(
23
- this.standardHandler,
24
- peer,
22
+ await peer.message(
25
23
  message,
26
- resolveMaybeOptionalOptions(rest)
24
+ createServerPeerHandleRequestFn(this.standardHandler, resolveMaybeOptionalOptions(rest))
27
25
  );
28
26
  });
29
27
  onMessagePortClose(port, () => {
@@ -4,12 +4,12 @@ import { toStandardLazyRequest, sendStandardResponse } from '@orpc/standard-serv
4
4
  import { r as resolveFriendlyStandardHandleOptions } from '../../shared/server.DZ5BIITo.mjs';
5
5
  import '@orpc/standard-server';
6
6
  import '@orpc/contract';
7
- import { C as CompositeStandardHandlerPlugin, b as StandardRPCHandler } from '../../shared/server.CIL9uKTN.mjs';
7
+ import { C as CompositeStandardHandlerPlugin, b as StandardRPCHandler } from '../../shared/server.CYRYFTxo.mjs';
8
8
  import '@orpc/client/standard';
9
9
  import '@orpc/standard-server/batch';
10
10
  import '@orpc/standard-server-fetch';
11
11
  import { S as StrictGetMethodPlugin } from '../../shared/server.BW-nUGgA.mjs';
12
- import '../../shared/server.NeumLVdS.mjs';
12
+ import '../../shared/server.B_fj3X5m.mjs';
13
13
 
14
14
  class BodyLimitPlugin {
15
15
  maxBodySize;
@@ -1,8 +1,8 @@
1
- export { C as CompositeStandardHandlerPlugin, S as StandardHandler, a as StandardRPCCodec, b as StandardRPCHandler, c as StandardRPCMatcher } from '../../shared/server.CIL9uKTN.mjs';
1
+ export { C as CompositeStandardHandlerPlugin, S as StandardHandler, a as StandardRPCCodec, b as StandardRPCHandler, c as StandardRPCMatcher } from '../../shared/server.CYRYFTxo.mjs';
2
2
  export { r as resolveFriendlyStandardHandleOptions } from '../../shared/server.DZ5BIITo.mjs';
3
3
  import '@orpc/client/standard';
4
4
  import '@orpc/client';
5
5
  import '@orpc/shared';
6
6
  import '@orpc/standard-server';
7
- import '../../shared/server.NeumLVdS.mjs';
7
+ import '../../shared/server.B_fj3X5m.mjs';
8
8
  import '@orpc/contract';
@@ -1,4 +1,4 @@
1
- import { ServerPeer, EncodedMessage } from '@orpc/standard-server-peer';
1
+ import { ServerPeer, EncodedMessage, ServerPeerHandleRequestFn } from '@orpc/standard-server-peer';
2
2
  import { C as Context } from '../../shared/server.CYNGeoCm.mjs';
3
3
  import { f as StandardHandler } from '../../shared/server.gqRxT-yN.mjs';
4
4
  import { F as FriendlyStandardHandleOptions } from '../../shared/server.BEFBl-Cb.mjs';
@@ -8,7 +8,11 @@ import '@orpc/shared';
8
8
  import '@orpc/standard-server';
9
9
 
10
10
  type HandleStandardServerPeerMessageOptions<T extends Context> = Omit<FriendlyStandardHandleOptions<T>, 'prefix'>;
11
+ /**
12
+ * @deprecated Use `createServerPeerRequestHandleFn` instead.
13
+ */
11
14
  declare function handleStandardServerPeerMessage<T extends Context>(handler: StandardHandler<T>, peer: ServerPeer, message: EncodedMessage, options: HandleStandardServerPeerMessageOptions<T>): Promise<void>;
15
+ declare function createServerPeerHandleRequestFn<T extends Context>(handler: StandardHandler<T>, options: HandleStandardServerPeerMessageOptions<T>): ServerPeerHandleRequestFn;
12
16
 
13
- export { handleStandardServerPeerMessage };
17
+ export { createServerPeerHandleRequestFn, handleStandardServerPeerMessage };
14
18
  export type { HandleStandardServerPeerMessageOptions };
@@ -1,4 +1,4 @@
1
- import { ServerPeer, EncodedMessage } from '@orpc/standard-server-peer';
1
+ import { ServerPeer, EncodedMessage, ServerPeerHandleRequestFn } from '@orpc/standard-server-peer';
2
2
  import { C as Context } from '../../shared/server.CYNGeoCm.js';
3
3
  import { f as StandardHandler } from '../../shared/server.Bmh5xd4n.js';
4
4
  import { F as FriendlyStandardHandleOptions } from '../../shared/server.B7b2w3_i.js';
@@ -8,7 +8,11 @@ import '@orpc/shared';
8
8
  import '@orpc/standard-server';
9
9
 
10
10
  type HandleStandardServerPeerMessageOptions<T extends Context> = Omit<FriendlyStandardHandleOptions<T>, 'prefix'>;
11
+ /**
12
+ * @deprecated Use `createServerPeerRequestHandleFn` instead.
13
+ */
11
14
  declare function handleStandardServerPeerMessage<T extends Context>(handler: StandardHandler<T>, peer: ServerPeer, message: EncodedMessage, options: HandleStandardServerPeerMessageOptions<T>): Promise<void>;
15
+ declare function createServerPeerHandleRequestFn<T extends Context>(handler: StandardHandler<T>, options: HandleStandardServerPeerMessageOptions<T>): ServerPeerHandleRequestFn;
12
16
 
13
- export { handleStandardServerPeerMessage };
17
+ export { createServerPeerHandleRequestFn, handleStandardServerPeerMessage };
14
18
  export type { HandleStandardServerPeerMessageOptions };
@@ -1,4 +1,4 @@
1
- export { h as handleStandardServerPeerMessage } from '../../shared/server.C6Q5sqYw.mjs';
1
+ export { c as createServerPeerHandleRequestFn, h as handleStandardServerPeerMessage } from '../../shared/server.UVMTOWrk.mjs';
2
2
  import '@orpc/client';
3
3
  import '@orpc/shared';
4
4
  import '@orpc/standard-server';
@@ -1,13 +1,13 @@
1
1
  import { readAsBuffer, resolveMaybeOptionalOptions } from '@orpc/shared';
2
2
  import { ServerPeer } from '@orpc/standard-server-peer';
3
- import { h as handleStandardServerPeerMessage } from '../../shared/server.C6Q5sqYw.mjs';
3
+ import { c as createServerPeerHandleRequestFn } from '../../shared/server.UVMTOWrk.mjs';
4
4
  import '@orpc/client';
5
5
  import '@orpc/standard-server';
6
6
  import '@orpc/contract';
7
- import { b as StandardRPCHandler } from '../../shared/server.CIL9uKTN.mjs';
7
+ import { b as StandardRPCHandler } from '../../shared/server.CYRYFTxo.mjs';
8
8
  import '@orpc/client/standard';
9
9
  import '../../shared/server.DZ5BIITo.mjs';
10
- import '../../shared/server.NeumLVdS.mjs';
10
+ import '../../shared/server.B_fj3X5m.mjs';
11
11
 
12
12
  class WebsocketHandler {
13
13
  #peers = /* @__PURE__ */ new WeakMap();
@@ -40,11 +40,9 @@ class WebsocketHandler {
40
40
  this.#peers.set(ws, peer = new ServerPeer(ws.send.bind(ws)));
41
41
  }
42
42
  const message = data instanceof Blob ? await readAsBuffer(data) : data;
43
- await handleStandardServerPeerMessage(
44
- this.#handler,
45
- peer,
43
+ await peer.message(
46
44
  message,
47
- resolveMaybeOptionalOptions(rest)
45
+ createServerPeerHandleRequestFn(this.#handler, resolveMaybeOptionalOptions(rest))
48
46
  );
49
47
  }
50
48
  /**
@@ -1,13 +1,13 @@
1
1
  import { readAsBuffer, resolveMaybeOptionalOptions } from '@orpc/shared';
2
2
  import { ServerPeer } from '@orpc/standard-server-peer';
3
- import { h as handleStandardServerPeerMessage } from '../../shared/server.C6Q5sqYw.mjs';
3
+ import { c as createServerPeerHandleRequestFn } from '../../shared/server.UVMTOWrk.mjs';
4
4
  import '@orpc/client';
5
5
  import '@orpc/standard-server';
6
6
  import '@orpc/contract';
7
- import { b as StandardRPCHandler } from '../../shared/server.CIL9uKTN.mjs';
7
+ import { b as StandardRPCHandler } from '../../shared/server.CYRYFTxo.mjs';
8
8
  import '@orpc/client/standard';
9
9
  import '../../shared/server.DZ5BIITo.mjs';
10
- import '../../shared/server.NeumLVdS.mjs';
10
+ import '../../shared/server.B_fj3X5m.mjs';
11
11
 
12
12
  class WsHandler {
13
13
  constructor(standardHandler) {
@@ -17,11 +17,9 @@ class WsHandler {
17
17
  const peer = new ServerPeer(ws.send.bind(ws));
18
18
  ws.addEventListener("message", async (event) => {
19
19
  const message = Array.isArray(event.data) ? await readAsBuffer(new Blob(event.data)) : event.data;
20
- await handleStandardServerPeerMessage(
21
- this.standardHandler,
22
- peer,
20
+ await peer.message(
23
21
  message,
24
- resolveMaybeOptionalOptions(rest)
22
+ createServerPeerHandleRequestFn(this.standardHandler, resolveMaybeOptionalOptions(rest))
25
23
  );
26
24
  });
27
25
  ws.addEventListener("close", () => {
@@ -1,13 +1,13 @@
1
1
  import { StandardRPCJsonSerializerOptions } from '@orpc/client/standard';
2
2
  import { g as StandardHandlerPlugin, e as StandardHandlerOptions } from '../shared/server.gqRxT-yN.mjs';
3
- import { experimental_HibernationEventIterator } from '@orpc/standard-server';
4
- export { experimental_HibernationEventIterator, experimental_HibernationEventIteratorCallback } from '@orpc/standard-server';
3
+ import { HibernationEventIterator } from '@orpc/standard-server';
4
+ export { HibernationEventIterator, HibernationEventIteratorCallback } from '@orpc/standard-server';
5
5
  import { C as Context, R as Router } from '../shared/server.CYNGeoCm.mjs';
6
6
  import '@orpc/client';
7
7
  import '@orpc/contract';
8
8
  import '@orpc/shared';
9
9
 
10
- interface experimental_EncodeHibernationRPCEventOptions extends StandardRPCJsonSerializerOptions {
10
+ interface EncodeHibernationRPCEventOptions extends StandardRPCJsonSerializerOptions {
11
11
  /**
12
12
  * The type of event, each type corresponds a different operation
13
13
  *
@@ -24,21 +24,21 @@ interface experimental_EncodeHibernationRPCEventOptions extends StandardRPCJsonS
24
24
  *
25
25
  * @see {@link https://orpc.unnoq.com/docs/plugins/hibernation Hibernation Plugin}
26
26
  */
27
- declare function experimental_encodeHibernationRPCEvent(id: string, payload: unknown, options?: experimental_EncodeHibernationRPCEventOptions): string;
27
+ declare function encodeHibernationRPCEvent(id: string, payload: unknown, options?: EncodeHibernationRPCEventOptions): string;
28
28
 
29
- interface experimental_HibernationPluginContext {
30
- iterator?: experimental_HibernationEventIterator<any>;
29
+ interface HibernationPluginContext {
30
+ iterator?: HibernationEventIterator<any>;
31
31
  }
32
32
  /**
33
33
  * Enable Hibernation APIs
34
34
  *
35
35
  * @see {@link https://orpc.unnoq.com/docs/plugins/hibernation Hibernation Plugin}
36
36
  */
37
- declare class experimental_HibernationPlugin<T extends Context> implements StandardHandlerPlugin<T> {
37
+ declare class HibernationPlugin<T extends Context> implements StandardHandlerPlugin<T> {
38
38
  readonly CONTEXT_SYMBOL: symbol;
39
39
  order: number;
40
40
  init(options: StandardHandlerOptions<T>, _router: Router<any, T>): void;
41
41
  }
42
42
 
43
- export { experimental_HibernationPlugin, experimental_encodeHibernationRPCEvent };
44
- export type { experimental_EncodeHibernationRPCEventOptions, experimental_HibernationPluginContext };
43
+ export { HibernationPlugin, encodeHibernationRPCEvent };
44
+ export type { EncodeHibernationRPCEventOptions, HibernationPluginContext };
@@ -1,13 +1,13 @@
1
1
  import { StandardRPCJsonSerializerOptions } from '@orpc/client/standard';
2
2
  import { g as StandardHandlerPlugin, e as StandardHandlerOptions } from '../shared/server.Bmh5xd4n.js';
3
- import { experimental_HibernationEventIterator } from '@orpc/standard-server';
4
- export { experimental_HibernationEventIterator, experimental_HibernationEventIteratorCallback } from '@orpc/standard-server';
3
+ import { HibernationEventIterator } from '@orpc/standard-server';
4
+ export { HibernationEventIterator, HibernationEventIteratorCallback } from '@orpc/standard-server';
5
5
  import { C as Context, R as Router } from '../shared/server.CYNGeoCm.js';
6
6
  import '@orpc/client';
7
7
  import '@orpc/contract';
8
8
  import '@orpc/shared';
9
9
 
10
- interface experimental_EncodeHibernationRPCEventOptions extends StandardRPCJsonSerializerOptions {
10
+ interface EncodeHibernationRPCEventOptions extends StandardRPCJsonSerializerOptions {
11
11
  /**
12
12
  * The type of event, each type corresponds a different operation
13
13
  *
@@ -24,21 +24,21 @@ interface experimental_EncodeHibernationRPCEventOptions extends StandardRPCJsonS
24
24
  *
25
25
  * @see {@link https://orpc.unnoq.com/docs/plugins/hibernation Hibernation Plugin}
26
26
  */
27
- declare function experimental_encodeHibernationRPCEvent(id: string, payload: unknown, options?: experimental_EncodeHibernationRPCEventOptions): string;
27
+ declare function encodeHibernationRPCEvent(id: string, payload: unknown, options?: EncodeHibernationRPCEventOptions): string;
28
28
 
29
- interface experimental_HibernationPluginContext {
30
- iterator?: experimental_HibernationEventIterator<any>;
29
+ interface HibernationPluginContext {
30
+ iterator?: HibernationEventIterator<any>;
31
31
  }
32
32
  /**
33
33
  * Enable Hibernation APIs
34
34
  *
35
35
  * @see {@link https://orpc.unnoq.com/docs/plugins/hibernation Hibernation Plugin}
36
36
  */
37
- declare class experimental_HibernationPlugin<T extends Context> implements StandardHandlerPlugin<T> {
37
+ declare class HibernationPlugin<T extends Context> implements StandardHandlerPlugin<T> {
38
38
  readonly CONTEXT_SYMBOL: symbol;
39
39
  order: number;
40
40
  init(options: StandardHandlerOptions<T>, _router: Router<any, T>): void;
41
41
  }
42
42
 
43
- export { experimental_HibernationPlugin, experimental_encodeHibernationRPCEvent };
44
- export type { experimental_EncodeHibernationRPCEventOptions, experimental_HibernationPluginContext };
43
+ export { HibernationPlugin, encodeHibernationRPCEvent };
44
+ export type { EncodeHibernationRPCEventOptions, HibernationPluginContext };
@@ -1,11 +1,11 @@
1
1
  import { toORPCError } from '@orpc/client';
2
2
  import { StandardRPCJsonSerializer } from '@orpc/client/standard';
3
3
  import { stringifyJSON } from '@orpc/shared';
4
- import { getEventMeta, experimental_HibernationEventIterator } from '@orpc/standard-server';
5
- export { experimental_HibernationEventIterator } from '@orpc/standard-server';
4
+ import { getEventMeta, HibernationEventIterator } from '@orpc/standard-server';
5
+ export { HibernationEventIterator } from '@orpc/standard-server';
6
6
  import { MessageType } from '@orpc/standard-server-peer';
7
7
 
8
- function experimental_encodeHibernationRPCEvent(id, payload, options = {}) {
8
+ function encodeHibernationRPCEvent(id, payload, options = {}) {
9
9
  const { event = "message", ...rest } = options;
10
10
  const serializer = new StandardRPCJsonSerializer(rest);
11
11
  const data = event === "error" ? toORPCError(payload).toJSON() : payload;
@@ -21,7 +21,7 @@ function experimental_encodeHibernationRPCEvent(id, payload, options = {}) {
21
21
  });
22
22
  }
23
23
 
24
- class experimental_HibernationPlugin {
24
+ class HibernationPlugin {
25
25
  CONTEXT_SYMBOL = Symbol("ORPC_HIBERNATION_CONTEXT");
26
26
  order = 2e6;
27
27
  // make sure execute after the batch plugin
@@ -33,8 +33,8 @@ class experimental_HibernationPlugin {
33
33
  const result = await options2.next({
34
34
  ...options2,
35
35
  context: {
36
- [this.CONTEXT_SYMBOL]: hibernationContext,
37
- ...options2.context
36
+ ...options2.context,
37
+ [this.CONTEXT_SYMBOL]: hibernationContext
38
38
  }
39
39
  });
40
40
  if (!result.matched || !hibernationContext.iterator) {
@@ -54,7 +54,7 @@ class experimental_HibernationPlugin {
54
54
  throw new TypeError("[HibernationPlugin] Hibernation context has been corrupted or modified by another plugin or interceptor");
55
55
  }
56
56
  const output = await options2.next();
57
- if (output instanceof experimental_HibernationEventIterator) {
57
+ if (output instanceof HibernationEventIterator) {
58
58
  hibernationContext.iterator = output;
59
59
  }
60
60
  return output;
@@ -62,4 +62,4 @@ class experimental_HibernationPlugin {
62
62
  }
63
63
  }
64
64
 
65
- export { experimental_HibernationPlugin, experimental_encodeHibernationRPCEvent };
65
+ export { HibernationPlugin, encodeHibernationRPCEvent };
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { mergeErrorMap, mergeMeta, mergeRoute, mergePrefix, mergeTags, isContractProcedure, getContractRouter, fallbackContractConfig } from '@orpc/contract';
2
2
  export { ValidationError, eventIterator, type } from '@orpc/contract';
3
- import { P as Procedure, b as addMiddleware, c as createProcedureClient, e as enhanceRouter, l as lazy, s as setHiddenRouterContract, u as unlazy, g as getRouter, i as isProcedure, d as isLazy, f as createAssertedLazyProcedure } from './shared/server.NeumLVdS.mjs';
4
- export { L as LAZY_SYMBOL, p as call, r as createAccessibleLazyRouter, a as createContractedProcedure, h as createORPCErrorConstructorMap, q as getHiddenRouterContract, j as getLazyMeta, n as isStartWithMiddlewares, m as mergeCurrentContext, o as mergeMiddlewares, k as middlewareOutputFn, w as resolveContractProcedures, t as traverseContractProcedures, x as unlazyRouter, v as validateORPCError } from './shared/server.NeumLVdS.mjs';
3
+ import { P as Procedure, b as addMiddleware, c as createProcedureClient, e as enhanceRouter, l as lazy, s as setHiddenRouterContract, u as unlazy, g as getRouter, i as isProcedure, d as isLazy, f as createAssertedLazyProcedure } from './shared/server.B_fj3X5m.mjs';
4
+ export { L as LAZY_SYMBOL, p as call, r as createAccessibleLazyRouter, a as createContractedProcedure, h as createORPCErrorConstructorMap, q as getHiddenRouterContract, j as getLazyMeta, n as isStartWithMiddlewares, m as mergeCurrentContext, o as mergeMiddlewares, k as middlewareOutputFn, w as resolveContractProcedures, t as traverseContractProcedures, x as unlazyRouter, v as validateORPCError } from './shared/server.B_fj3X5m.mjs';
5
5
  import { toORPCError } from '@orpc/client';
6
6
  export { ORPCError, isDefinedError, safe } from '@orpc/client';
7
7
  import { resolveMaybeOptionalOptions } from '@orpc/shared';
@@ -1,4 +1,4 @@
1
- import { value, isAsyncIteratorObject, clone } from '@orpc/shared';
1
+ import { runWithSpan, value, setSpanError, isAsyncIteratorObject, clone } from '@orpc/shared';
2
2
  import { flattenHeader } from '@orpc/standard-server';
3
3
  import { parseBatchRequest, toBatchResponse } from '@orpc/standard-server/batch';
4
4
  import { toFetchHeaders } from '@orpc/standard-server-fetch';
@@ -33,65 +33,74 @@ class BatchHandlerPlugin {
33
33
  }
34
34
  let isParsing = false;
35
35
  try {
36
- isParsing = true;
37
- const parsed = parseBatchRequest({ ...options2.request, body: await options2.request.body() });
38
- isParsing = false;
39
- const maxSize = await value(this.maxSize, options2);
40
- if (parsed.length > maxSize) {
41
- return {
42
- matched: true,
43
- response: {
44
- status: 413,
45
- headers: {},
46
- body: "Batch request size exceeds the maximum allowed size"
47
- }
48
- };
49
- }
50
- const responses = parsed.map(
51
- (request, index) => {
52
- const mapped = this.mapRequestItem(request, options2);
53
- return options2.next({ ...options2, request: { ...mapped, body: () => Promise.resolve(mapped.body) } }).then(({ response: response2, matched }) => {
54
- if (matched) {
55
- if (response2.body instanceof Blob || response2.body instanceof FormData || isAsyncIteratorObject(response2.body)) {
56
- return {
57
- index,
58
- status: 500,
59
- headers: {},
60
- body: "Batch responses do not support file/blob, or event-iterator. Please call this procedure separately outside of the batch request."
61
- };
62
- }
63
- return { ...response2, index };
36
+ return await runWithSpan({ name: "handle_batch_request" }, async (span) => {
37
+ const mode = xHeader === "buffered" ? "buffered" : "streaming";
38
+ isParsing = true;
39
+ const parsed = parseBatchRequest({ ...options2.request, body: await options2.request.body() });
40
+ isParsing = false;
41
+ span?.setAttribute("batch.mode", mode);
42
+ span?.setAttribute("batch.size", parsed.length);
43
+ const maxSize = await value(this.maxSize, options2);
44
+ if (parsed.length > maxSize) {
45
+ const message = "Batch request size exceeds the maximum allowed size";
46
+ setSpanError(span, message);
47
+ return {
48
+ matched: true,
49
+ response: {
50
+ status: 413,
51
+ headers: {},
52
+ body: message
64
53
  }
65
- return { index, status: 404, headers: {}, body: "No procedure matched" };
66
- }).catch(() => {
67
- return { index, status: 500, headers: {}, body: "Internal server error" };
68
- });
54
+ };
69
55
  }
70
- );
71
- await Promise.race(responses);
72
- const status = await value(this.successStatus, responses, options2);
73
- const headers = await value(this.headers, responses, options2);
74
- const response = await toBatchResponse({
75
- status,
76
- headers,
77
- mode: xHeader === "buffered" ? "buffered" : "streaming",
78
- body: async function* () {
79
- const promises = [...responses];
80
- while (true) {
81
- const handling = promises.filter((p) => p !== void 0);
82
- if (handling.length === 0) {
83
- return;
84
- }
85
- const result = await Promise.race(handling);
86
- promises[result.index] = void 0;
87
- yield result;
56
+ const responses = parsed.map(
57
+ (request, index) => {
58
+ const mapped = this.mapRequestItem(request, options2);
59
+ return options2.next({ ...options2, request: { ...mapped, body: () => Promise.resolve(mapped.body) } }).then(({ response: response2, matched }) => {
60
+ span?.addEvent(`response.${index}.${matched ? "success" : "not_matched"}`);
61
+ if (matched) {
62
+ if (response2.body instanceof Blob || response2.body instanceof FormData || isAsyncIteratorObject(response2.body)) {
63
+ return {
64
+ index,
65
+ status: 500,
66
+ headers: {},
67
+ body: "Batch responses do not support file/blob, or event-iterator. Please call this procedure separately outside of the batch request."
68
+ };
69
+ }
70
+ return { ...response2, index };
71
+ }
72
+ return { index, status: 404, headers: {}, body: "No procedure matched" };
73
+ }).catch((err) => {
74
+ Promise.reject(err);
75
+ return { index, status: 500, headers: {}, body: "Internal server error" };
76
+ });
88
77
  }
89
- }()
78
+ );
79
+ await Promise.race(responses);
80
+ const status = await value(this.successStatus, responses, options2);
81
+ const headers = await value(this.headers, responses, options2);
82
+ const response = await toBatchResponse({
83
+ status,
84
+ headers,
85
+ mode,
86
+ body: async function* () {
87
+ const promises = [...responses];
88
+ while (true) {
89
+ const handling = promises.filter((p) => p !== void 0);
90
+ if (handling.length === 0) {
91
+ return;
92
+ }
93
+ const result = await Promise.race(handling);
94
+ promises[result.index] = void 0;
95
+ yield result;
96
+ }
97
+ }()
98
+ });
99
+ return {
100
+ matched: true,
101
+ response
102
+ };
90
103
  });
91
- return {
92
- matched: true,
93
- response
94
- };
95
104
  } catch (cause) {
96
105
  if (isParsing) {
97
106
  return {
@@ -1,6 +1,7 @@
1
1
  import { isContractProcedure, ValidationError, mergePrefix, mergeErrorMap, enhanceRoute } from '@orpc/contract';
2
- import { resolveMaybeOptionalOptions, toArray, value, intercept } from '@orpc/shared';
2
+ import { resolveMaybeOptionalOptions, toArray, value, runWithSpan, intercept, isAsyncIteratorObject, asyncIteratorWithSpan } from '@orpc/shared';
3
3
  import { fallbackORPCErrorStatus, ORPCError } from '@orpc/client';
4
+ import { HibernationEventIterator } from '@orpc/standard-server';
4
5
 
5
6
  const LAZY_SYMBOL = Symbol("ORPC_LAZY_SYMBOL");
6
7
  function lazy(loader, meta = {}) {
@@ -116,20 +117,36 @@ function createProcedureClient(lazyableProcedure, ...rest) {
116
117
  const context = await value(options.context ?? {}, clientContext);
117
118
  const errors = createORPCErrorConstructorMap(procedure["~orpc"].errorMap);
118
119
  try {
119
- return await intercept(
120
- toArray(options.interceptors),
121
- {
122
- context,
123
- input,
124
- // input only optional when it undefinable so we can safely cast it
125
- errors,
126
- path,
127
- procedure,
128
- signal: callerOptions?.signal,
129
- lastEventId: callerOptions?.lastEventId
130
- },
131
- (interceptorOptions) => executeProcedureInternal(interceptorOptions.procedure, interceptorOptions)
120
+ const output = await runWithSpan(
121
+ { name: "call_procedure", signal: callerOptions?.signal },
122
+ (span) => {
123
+ span?.setAttribute("procedure.path", [...path]);
124
+ return intercept(
125
+ toArray(options.interceptors),
126
+ {
127
+ context,
128
+ input,
129
+ // input only optional when it undefinable so we can safely cast it
130
+ errors,
131
+ path,
132
+ procedure,
133
+ signal: callerOptions?.signal,
134
+ lastEventId: callerOptions?.lastEventId
135
+ },
136
+ (interceptorOptions) => executeProcedureInternal(interceptorOptions.procedure, interceptorOptions)
137
+ );
138
+ }
132
139
  );
140
+ if (isAsyncIteratorObject(output)) {
141
+ if (output instanceof HibernationEventIterator) {
142
+ return output;
143
+ }
144
+ return asyncIteratorWithSpan(
145
+ { name: "consume_event_iterator_output", signal: callerOptions?.signal },
146
+ output
147
+ );
148
+ }
149
+ return output;
133
150
  } catch (e) {
134
151
  if (!(e instanceof ORPCError)) {
135
152
  throw e;
@@ -144,31 +161,41 @@ async function validateInput(procedure, input) {
144
161
  if (!schema) {
145
162
  return input;
146
163
  }
147
- const result = await schema["~standard"].validate(input);
148
- if (result.issues) {
149
- throw new ORPCError("BAD_REQUEST", {
150
- message: "Input validation failed",
151
- data: {
152
- issues: result.issues
153
- },
154
- cause: new ValidationError({ message: "Input validation failed", issues: result.issues })
155
- });
156
- }
157
- return result.value;
164
+ return runWithSpan(
165
+ { name: "validate_input" },
166
+ async () => {
167
+ const result = await schema["~standard"].validate(input);
168
+ if (result.issues) {
169
+ throw new ORPCError("BAD_REQUEST", {
170
+ message: "Input validation failed",
171
+ data: {
172
+ issues: result.issues
173
+ },
174
+ cause: new ValidationError({ message: "Input validation failed", issues: result.issues })
175
+ });
176
+ }
177
+ return result.value;
178
+ }
179
+ );
158
180
  }
159
181
  async function validateOutput(procedure, output) {
160
182
  const schema = procedure["~orpc"].outputSchema;
161
183
  if (!schema) {
162
184
  return output;
163
185
  }
164
- const result = await schema["~standard"].validate(output);
165
- if (result.issues) {
166
- throw new ORPCError("INTERNAL_SERVER_ERROR", {
167
- message: "Output validation failed",
168
- cause: new ValidationError({ message: "Output validation failed", issues: result.issues })
169
- });
170
- }
171
- return result.value;
186
+ return runWithSpan(
187
+ { name: "validate_output" },
188
+ async () => {
189
+ const result = await schema["~standard"].validate(output);
190
+ if (result.issues) {
191
+ throw new ORPCError("INTERNAL_SERVER_ERROR", {
192
+ message: "Output validation failed",
193
+ cause: new ValidationError({ message: "Output validation failed", issues: result.issues })
194
+ });
195
+ }
196
+ return result.value;
197
+ }
198
+ );
172
199
  }
173
200
  async function executeProcedureInternal(procedure, options) {
174
201
  const middlewares = procedure["~orpc"].middlewares;
@@ -180,17 +207,28 @@ async function executeProcedureInternal(procedure, options) {
180
207
  currentInput = await validateInput(procedure, currentInput);
181
208
  }
182
209
  const mid = middlewares[index];
183
- const output = mid ? (await mid({
184
- ...options,
185
- context,
186
- next: async (...[nextOptions]) => {
187
- const nextContext = nextOptions?.context ?? {};
188
- return {
189
- output: await next(index + 1, mergeCurrentContext(context, nextContext), currentInput),
190
- context: nextContext
191
- };
210
+ const output = mid ? await runWithSpan(
211
+ { name: `middleware.${mid.name}`, signal: options.signal },
212
+ async (span) => {
213
+ span?.setAttribute("middleware.index", index);
214
+ span?.setAttribute("middleware.name", mid.name);
215
+ const result = await mid({
216
+ ...options,
217
+ context,
218
+ next: async (...[nextOptions]) => {
219
+ const nextContext = nextOptions?.context ?? {};
220
+ return {
221
+ output: await next(index + 1, mergeCurrentContext(context, nextContext), currentInput),
222
+ context: nextContext
223
+ };
224
+ }
225
+ }, currentInput, middlewareOutputFn);
226
+ return result.output;
192
227
  }
193
- }, currentInput, middlewareOutputFn)).output : await procedure["~orpc"].handler({ ...options, context, input: currentInput });
228
+ ) : await runWithSpan(
229
+ { name: "handler", signal: options.signal },
230
+ () => procedure["~orpc"].handler({ ...options, context, input: currentInput })
231
+ );
194
232
  if (index === outputValidationIndex) {
195
233
  return await validateOutput(procedure, output);
196
234
  }
@@ -1,8 +1,8 @@
1
1
  import { toHttpPath, StandardRPCJsonSerializer, StandardRPCSerializer } from '@orpc/client/standard';
2
2
  import { ORPCError, toORPCError } from '@orpc/client';
3
- import { toArray, intercept, parseEmptyableJSON, NullProtoObj, value } from '@orpc/shared';
3
+ import { toArray, intercept, runWithSpan, ORPC_NAME, isAsyncIteratorObject, asyncIteratorWithSpan, setSpanError, parseEmptyableJSON, NullProtoObj, value } from '@orpc/shared';
4
4
  import { flattenHeader } from '@orpc/standard-server';
5
- import { c as createProcedureClient, t as traverseContractProcedures, i as isProcedure, u as unlazy, g as getRouter, a as createContractedProcedure } from './server.NeumLVdS.mjs';
5
+ import { c as createProcedureClient, t as traverseContractProcedures, i as isProcedure, u as unlazy, g as getRouter, a as createContractedProcedure } from './server.B_fj3X5m.mjs';
6
6
 
7
7
  class CompositeStandardHandlerPlugin {
8
8
  plugins;
@@ -39,49 +39,74 @@ class StandardHandler {
39
39
  this.rootInterceptors,
40
40
  { ...options, request, prefix },
41
41
  async (interceptorOptions) => {
42
- let isDecoding = false;
43
- try {
44
- return await intercept(
45
- this.interceptors,
46
- interceptorOptions,
47
- async ({ request: request2, context, prefix: prefix2 }) => {
48
- const method = request2.method;
49
- const url = request2.url;
50
- const pathname = prefix2 ? url.pathname.replace(prefix2, "") : url.pathname;
51
- const match = await this.matcher.match(method, `/${pathname.replace(/^\/|\/$/g, "")}`);
52
- if (!match) {
53
- return { matched: false, response: void 0 };
42
+ return runWithSpan(
43
+ { name: `${request.method} ${request.url.pathname}` },
44
+ async (span) => {
45
+ let step;
46
+ try {
47
+ return await intercept(
48
+ this.interceptors,
49
+ interceptorOptions,
50
+ async ({ request: request2, context, prefix: prefix2 }) => {
51
+ const method = request2.method;
52
+ const url = request2.url;
53
+ const pathname = prefix2 ? url.pathname.replace(prefix2, "") : url.pathname;
54
+ const match = await runWithSpan(
55
+ { name: "find_procedure" },
56
+ () => this.matcher.match(method, `/${pathname.replace(/^\/|\/$/g, "")}`)
57
+ );
58
+ if (!match) {
59
+ return { matched: false, response: void 0 };
60
+ }
61
+ span?.updateName(`${ORPC_NAME}.${match.path.join("/")}`);
62
+ span?.setAttribute("rpc.system", ORPC_NAME);
63
+ span?.setAttribute("rpc.method", match.path.join("."));
64
+ step = "decode_input";
65
+ let input = await runWithSpan(
66
+ { name: "decode_input" },
67
+ () => this.codec.decode(request2, match.params, match.procedure)
68
+ );
69
+ step = void 0;
70
+ if (isAsyncIteratorObject(input)) {
71
+ input = asyncIteratorWithSpan(
72
+ { name: "consume_event_iterator_input", signal: request2.signal },
73
+ input
74
+ );
75
+ }
76
+ const client = createProcedureClient(match.procedure, {
77
+ context,
78
+ path: match.path,
79
+ interceptors: this.clientInterceptors
80
+ });
81
+ step = "call_procedure";
82
+ const output = await client(input, {
83
+ signal: request2.signal,
84
+ lastEventId: flattenHeader(request2.headers["last-event-id"])
85
+ });
86
+ step = void 0;
87
+ const response = this.codec.encode(output, match.procedure);
88
+ return {
89
+ matched: true,
90
+ response
91
+ };
92
+ }
93
+ );
94
+ } catch (e) {
95
+ if (step !== "call_procedure") {
96
+ setSpanError(span, e);
54
97
  }
55
- const client = createProcedureClient(match.procedure, {
56
- context,
57
- path: match.path,
58
- interceptors: this.clientInterceptors
59
- });
60
- isDecoding = true;
61
- const input = await this.codec.decode(request2, match.params, match.procedure);
62
- isDecoding = false;
63
- const output = await client(input, {
64
- signal: request2.signal,
65
- lastEventId: flattenHeader(request2.headers["last-event-id"])
66
- });
67
- const response = this.codec.encode(output, match.procedure);
98
+ const error = step === "decode_input" && !(e instanceof ORPCError) ? new ORPCError("BAD_REQUEST", {
99
+ message: `Malformed request. Ensure the request body is properly formatted and the 'Content-Type' header is set correctly.`,
100
+ cause: e
101
+ }) : toORPCError(e);
102
+ const response = this.codec.encodeError(error);
68
103
  return {
69
104
  matched: true,
70
105
  response
71
106
  };
72
107
  }
73
- );
74
- } catch (e) {
75
- const error = isDecoding && !(e instanceof ORPCError) ? new ORPCError("BAD_REQUEST", {
76
- message: `Malformed request. Ensure the request body is properly formatted and the 'Content-Type' header is set correctly.`,
77
- cause: e
78
- }) : toORPCError(e);
79
- const response = this.codec.encodeError(error);
80
- return {
81
- matched: true,
82
- response
83
- };
84
- }
108
+ }
109
+ );
85
110
  }
86
111
  );
87
112
  }
@@ -0,0 +1,26 @@
1
+ import '@orpc/client';
2
+ import '@orpc/shared';
3
+ import '@orpc/standard-server';
4
+ import '@orpc/contract';
5
+ import '@orpc/client/standard';
6
+ import { r as resolveFriendlyStandardHandleOptions } from './server.DZ5BIITo.mjs';
7
+
8
+ async function handleStandardServerPeerMessage(handler, peer, message, options) {
9
+ const [id, request] = await peer.message(message);
10
+ if (!request) {
11
+ return;
12
+ }
13
+ const handle = createServerPeerHandleRequestFn(handler, options);
14
+ await peer.response(id, await handle(request));
15
+ }
16
+ function createServerPeerHandleRequestFn(handler, options) {
17
+ return async (request) => {
18
+ const { response } = await handler.handle(
19
+ { ...request, body: () => Promise.resolve(request.body) },
20
+ resolveFriendlyStandardHandleOptions(options)
21
+ );
22
+ return response ?? { status: 404, headers: {}, body: "No procedure matched" };
23
+ };
24
+ }
25
+
26
+ export { createServerPeerHandleRequestFn as c, handleStandardServerPeerMessage as h };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/server",
3
3
  "type": "module",
4
- "version": "1.7.10",
4
+ "version": "1.8.0",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -102,14 +102,14 @@
102
102
  },
103
103
  "dependencies": {
104
104
  "cookie": "^1.0.2",
105
- "@orpc/client": "1.7.10",
106
- "@orpc/contract": "1.7.10",
107
- "@orpc/shared": "1.7.10",
108
- "@orpc/standard-server-fetch": "1.7.10",
109
- "@orpc/standard-server-node": "1.7.10",
110
- "@orpc/standard-server": "1.7.10",
111
- "@orpc/standard-server-peer": "1.7.10",
112
- "@orpc/standard-server-aws-lambda": "1.7.10"
105
+ "@orpc/client": "1.8.0",
106
+ "@orpc/shared": "1.8.0",
107
+ "@orpc/standard-server": "1.8.0",
108
+ "@orpc/contract": "1.8.0",
109
+ "@orpc/standard-server-aws-lambda": "1.8.0",
110
+ "@orpc/standard-server-fetch": "1.8.0",
111
+ "@orpc/standard-server-node": "1.8.0",
112
+ "@orpc/standard-server-peer": "1.8.0"
113
113
  },
114
114
  "devDependencies": {
115
115
  "@types/ws": "^8.18.1",
@@ -1,20 +0,0 @@
1
- import '@orpc/client';
2
- import '@orpc/shared';
3
- import '@orpc/standard-server';
4
- import '@orpc/contract';
5
- import '@orpc/client/standard';
6
- import { r as resolveFriendlyStandardHandleOptions } from './server.DZ5BIITo.mjs';
7
-
8
- async function handleStandardServerPeerMessage(handler, peer, message, options) {
9
- const [id, request] = await peer.message(message);
10
- if (!request) {
11
- return;
12
- }
13
- const { response } = await handler.handle(
14
- { ...request, body: () => Promise.resolve(request.body) },
15
- resolveFriendlyStandardHandleOptions(options)
16
- );
17
- await peer.response(id, response ?? { status: 404, headers: {}, body: "No procedure matched" });
18
- }
19
-
20
- export { handleStandardServerPeerMessage as h };