@orpc/server 1.14.11 → 1.14.13

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 (78) hide show
  1. package/README.md +98 -52
  2. package/dist/adapters/aws-lambda/index.d.mts +46 -0
  3. package/dist/adapters/aws-lambda/index.d.ts +46 -0
  4. package/dist/adapters/aws-lambda/index.mjs +40 -0
  5. package/dist/adapters/bun-ws/index.d.mts +36 -0
  6. package/dist/adapters/bun-ws/index.d.ts +36 -0
  7. package/dist/adapters/bun-ws/index.mjs +47 -0
  8. package/dist/adapters/crossws/index.d.mts +21 -45
  9. package/dist/adapters/crossws/index.d.ts +21 -45
  10. package/dist/adapters/crossws/index.mjs +18 -40
  11. package/dist/adapters/fastify/index.d.mts +53 -0
  12. package/dist/adapters/fastify/index.d.ts +53 -0
  13. package/dist/adapters/fastify/index.mjs +52 -0
  14. package/dist/adapters/fetch/index.d.mts +96 -64
  15. package/dist/adapters/fetch/index.d.ts +96 -64
  16. package/dist/adapters/fetch/index.mjs +139 -34
  17. package/dist/adapters/message-port/index.d.mts +34 -49
  18. package/dist/adapters/message-port/index.d.ts +34 -49
  19. package/dist/adapters/message-port/index.mjs +37 -68
  20. package/dist/adapters/node/index.d.mts +71 -63
  21. package/dist/adapters/node/index.d.ts +71 -63
  22. package/dist/adapters/node/index.mjs +113 -36
  23. package/dist/adapters/standard/index.d.mts +18 -16
  24. package/dist/adapters/standard/index.d.ts +18 -16
  25. package/dist/adapters/standard/index.mjs +5 -5
  26. package/dist/adapters/standard-peer/index.d.mts +14 -12
  27. package/dist/adapters/standard-peer/index.d.ts +14 -12
  28. package/dist/adapters/standard-peer/index.mjs +21 -2
  29. package/dist/adapters/websocket/index.d.mts +38 -53
  30. package/dist/adapters/websocket/index.d.ts +38 -53
  31. package/dist/adapters/websocket/index.mjs +42 -59
  32. package/dist/adapters/ws/index.d.mts +31 -0
  33. package/dist/adapters/ws/index.d.ts +31 -0
  34. package/dist/adapters/ws/index.mjs +41 -0
  35. package/dist/helpers/index.d.mts +4 -4
  36. package/dist/helpers/index.d.ts +4 -4
  37. package/dist/helpers/index.mjs +5 -13
  38. package/dist/hibernation/index.d.mts +44 -0
  39. package/dist/hibernation/index.d.ts +44 -0
  40. package/dist/hibernation/index.mjs +65 -0
  41. package/dist/index.d.mts +770 -166
  42. package/dist/index.d.ts +770 -166
  43. package/dist/index.mjs +399 -306
  44. package/dist/plugins/index.d.mts +121 -214
  45. package/dist/plugins/index.d.ts +121 -214
  46. package/dist/plugins/index.mjs +214 -576
  47. package/dist/shared/server.7cEtMB30.d.ts +74 -0
  48. package/dist/shared/server.B8gYOD5g.d.mts +12 -0
  49. package/dist/shared/server.BqadksTP.d.mts +74 -0
  50. package/dist/shared/server.C8_sRzQB.d.mts +42 -0
  51. package/dist/shared/server.CMf4nKky.mjs +230 -0
  52. package/dist/shared/server.ChyoA9XY.d.ts +42 -0
  53. package/dist/shared/server.D8IXzfqT.d.ts +32 -0
  54. package/dist/shared/server.DEBcqOjg.mjs +418 -0
  55. package/dist/shared/{server.W91HSRkE.mjs → server.DZ5BIITo.mjs} +2 -2
  56. package/dist/shared/server.DzE6WeuY.d.mts +32 -0
  57. package/dist/shared/server.EfTOZ2Q7.d.ts +12 -0
  58. package/dist/shared/server.TEVCLCFC.mjs +39 -0
  59. package/dist/shared/server.qKsRrdxW.d.mts +193 -0
  60. package/dist/shared/server.qKsRrdxW.d.ts +193 -0
  61. package/package.json +56 -26
  62. package/dist/extensions/callable.d.mts +0 -10
  63. package/dist/extensions/callable.d.ts +0 -10
  64. package/dist/extensions/callable.mjs +0 -11
  65. package/dist/shared/server.15O7oC1p.d.mts +0 -61
  66. package/dist/shared/server.B4BnEWWm.d.mts +0 -67
  67. package/dist/shared/server.BhsVw7m7.d.ts +0 -104
  68. package/dist/shared/server.BoiFpNT7.mjs +0 -224
  69. package/dist/shared/server.COPVXhDG.mjs +0 -271
  70. package/dist/shared/server.CX4vUnDk.mjs +0 -11
  71. package/dist/shared/server.CcR4kgje.d.mts +0 -206
  72. package/dist/shared/server.CcR4kgje.d.ts +0 -206
  73. package/dist/shared/server.CnN50DHH.d.ts +0 -67
  74. package/dist/shared/server.DBs0rrf9.mjs +0 -41
  75. package/dist/shared/server.DDFizwfU.d.mts +0 -104
  76. package/dist/shared/server.D_QauotT.mjs +0 -30
  77. package/dist/shared/server.DofEOwf-.mjs +0 -237
  78. package/dist/shared/server.m3szVJGU.d.ts +0 -61
@@ -1,44 +1,153 @@
1
- import { sortPlugins, intercept, resolveMaybeOptionalOptions, toArray } from '@orpc/shared';
2
- import { toStandardLazyRequest, toFetchResponse } from '@standardserver/fetch';
3
- import { r as resolveFriendlyStandardHandlerHandleOptions } from '../../shared/server.W91HSRkE.mjs';
4
- import { C as CSRFGuardHandlerPlugin } from '../../shared/server.D_QauotT.mjs';
5
- import { R as RPCHandlerCodec, S as StandardHandler } from '../../shared/server.COPVXhDG.mjs';
6
- import '@orpc/client';
7
- import '@standardserver/core';
8
- import '../../shared/server.DofEOwf-.mjs';
1
+ import { ORPCError } from '@orpc/client';
2
+ import { toArray, intercept, resolveMaybeOptionalOptions } from '@orpc/shared';
3
+ import { toStandardLazyRequest, toFetchResponse } from '@orpc/standard-server-fetch';
4
+ import { r as resolveFriendlyStandardHandleOptions } from '../../shared/server.DZ5BIITo.mjs';
5
+ import { C as CompositeStandardHandlerPlugin, b as StandardRPCHandler } from '../../shared/server.CMf4nKky.mjs';
6
+ import { S as StrictGetMethodPlugin } from '../../shared/server.TEVCLCFC.mjs';
7
+ import '@orpc/client/standard';
8
+ import '@orpc/standard-server';
9
+ import '../../shared/server.DEBcqOjg.mjs';
9
10
  import '@orpc/contract';
10
- import '../../shared/server.BoiFpNT7.mjs';
11
11
 
12
- class CompositeFetchHandlerPlugin {
13
- name = "~composite/fetch-handler";
14
- plugins;
15
- constructor(plugins = []) {
16
- this.plugins = sortPlugins(plugins);
12
+ class BodyLimitPlugin {
13
+ maxBodySize;
14
+ constructor(options) {
15
+ this.maxBodySize = options.maxBodySize;
17
16
  }
18
- initFetchHandlerOptions(options) {
19
- for (const plugin of this.plugins) {
20
- if (plugin.initFetchHandlerOptions) {
21
- options = plugin.initFetchHandlerOptions(options);
17
+ initRuntimeAdapter(options) {
18
+ options.adapterInterceptors ??= [];
19
+ options.adapterInterceptors.push(async (options2) => {
20
+ if (!options2.request.body) {
21
+ return options2.next();
22
+ }
23
+ let currentBodySize = 0;
24
+ const rawReader = options2.request.body.getReader();
25
+ const reader = new ReadableStream({
26
+ start: async (controller) => {
27
+ try {
28
+ if (Number(options2.request.headers.get("content-length")) > this.maxBodySize) {
29
+ controller.error(new ORPCError("PAYLOAD_TOO_LARGE"));
30
+ return;
31
+ }
32
+ while (true) {
33
+ const { done, value } = await rawReader.read();
34
+ if (done) {
35
+ break;
36
+ }
37
+ currentBodySize += value.length;
38
+ if (currentBodySize > this.maxBodySize) {
39
+ controller.error(new ORPCError("PAYLOAD_TOO_LARGE"));
40
+ break;
41
+ }
42
+ controller.enqueue(value);
43
+ }
44
+ } finally {
45
+ controller.close();
46
+ }
47
+ }
48
+ });
49
+ const requestInit = { body: reader, duplex: "half" };
50
+ return options2.next({
51
+ ...options2,
52
+ request: new Request(options2.request, requestInit)
53
+ });
54
+ });
55
+ }
56
+ }
57
+
58
+ const ORDERED_SUPPORTED_ENCODINGS = ["gzip", "deflate"];
59
+ class CompressionPlugin {
60
+ encodings;
61
+ threshold;
62
+ filter;
63
+ constructor(options = {}) {
64
+ this.encodings = options.encodings ?? ORDERED_SUPPORTED_ENCODINGS;
65
+ this.threshold = options.threshold ?? 1024;
66
+ this.filter = (request, response) => {
67
+ const hasContentDisposition = response.headers.has("content-disposition");
68
+ const contentType = response.headers.get("content-type");
69
+ if (!hasContentDisposition && contentType?.startsWith("text/event-stream")) {
70
+ return false;
71
+ }
72
+ return options.filter ? options.filter(request, response) : isCompressibleContentType(contentType);
73
+ };
74
+ }
75
+ initRuntimeAdapter(options) {
76
+ options.adapterInterceptors ??= [];
77
+ options.adapterInterceptors.unshift(async (options2) => {
78
+ const result = await options2.next();
79
+ if (!result.matched) {
80
+ return result;
81
+ }
82
+ const response = result.response;
83
+ if (response.headers.has("content-encoding") || response.headers.has("transfer-encoding") || isNoTransformCacheControl(response.headers.get("cache-control"))) {
84
+ return result;
85
+ }
86
+ const contentLength = response.headers.get("content-length");
87
+ if (contentLength && Number(contentLength) < this.threshold) {
88
+ return result;
89
+ }
90
+ const acceptEncoding = options2.request.headers.get("accept-encoding")?.split(",").map((enc) => enc.trim().split(";")[0]);
91
+ const encoding = this.encodings.find((enc) => acceptEncoding?.includes(enc));
92
+ if (!response.body || encoding === void 0) {
93
+ return result;
22
94
  }
95
+ if (!this.filter(options2.request, response)) {
96
+ return result;
97
+ }
98
+ const compressedBody = response.body.pipeThrough(new CompressionStream(encoding));
99
+ const compressedHeaders = new Headers(response.headers);
100
+ compressedHeaders.delete("content-length");
101
+ compressedHeaders.set("content-encoding", encoding);
102
+ return {
103
+ ...result,
104
+ response: new Response(compressedBody, {
105
+ status: response.status,
106
+ statusText: response.statusText,
107
+ headers: compressedHeaders
108
+ })
109
+ };
110
+ });
111
+ }
112
+ }
113
+ const COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/(?!event-stream(?:[;\s]|$))[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
114
+ function isCompressibleContentType(contentType) {
115
+ if (contentType === null) {
116
+ return false;
117
+ }
118
+ return COMPRESSIBLE_CONTENT_TYPE_REGEX.test(contentType);
119
+ }
120
+ const CACHE_CONTROL_NO_TRANSFORM_REGEX = /(?:^|,)\s*no-transform\s*(?:,|$)/i;
121
+ function isNoTransformCacheControl(cacheControl) {
122
+ if (cacheControl === null) {
123
+ return false;
124
+ }
125
+ return CACHE_CONTROL_NO_TRANSFORM_REGEX.test(cacheControl);
126
+ }
127
+
128
+ class CompositeFetchHandlerPlugin extends CompositeStandardHandlerPlugin {
129
+ initRuntimeAdapter(options) {
130
+ for (const plugin of this.plugins) {
131
+ plugin.initRuntimeAdapter?.(options);
23
132
  }
24
- return options;
25
133
  }
26
134
  }
27
135
 
28
136
  class FetchHandler {
29
137
  constructor(standardHandler, options = {}) {
30
138
  this.standardHandler = standardHandler;
31
- options = new CompositeFetchHandlerPlugin(options.plugins).initFetchHandlerOptions(options);
32
- this.fetchInterceptors = options.fetchInterceptors;
33
- this.toFetchResponseOptions = options.toFetchResponse;
139
+ const plugin = new CompositeFetchHandlerPlugin(options.plugins);
140
+ plugin.initRuntimeAdapter(options);
141
+ this.adapterInterceptors = toArray(options.adapterInterceptors);
142
+ this.toFetchResponseOptions = options;
34
143
  }
35
144
  toFetchResponseOptions;
36
- fetchInterceptors;
145
+ adapterInterceptors;
37
146
  async handle(request, ...rest) {
38
147
  return intercept(
39
- this.fetchInterceptors,
148
+ this.adapterInterceptors,
40
149
  {
41
- ...resolveFriendlyStandardHandlerHandleOptions(resolveMaybeOptionalOptions(rest)),
150
+ ...resolveFriendlyStandardHandleOptions(resolveMaybeOptionalOptions(rest)),
42
151
  request,
43
152
  toFetchResponseOptions: this.toFetchResponseOptions
44
153
  },
@@ -59,16 +168,12 @@ class FetchHandler {
59
168
 
60
169
  class RPCHandler extends FetchHandler {
61
170
  constructor(router, options = {}) {
62
- if (options.csrfGuardHandlerPlugin?.enabled !== false) {
63
- options = {
64
- ...options,
65
- plugins: [...toArray(options.plugins), new CSRFGuardHandlerPlugin()]
66
- };
171
+ if (options.strictGetMethodPluginEnabled ?? true) {
172
+ options.plugins ??= [];
173
+ options.plugins.push(new StrictGetMethodPlugin());
67
174
  }
68
- const codec = new RPCHandlerCodec(router, options);
69
- const handler = new StandardHandler(codec, options);
70
- super(handler, options);
175
+ super(new StandardRPCHandler(router, options), options);
71
176
  }
72
177
  }
73
178
 
74
- export { CompositeFetchHandlerPlugin, FetchHandler, RPCHandler };
179
+ export { BodyLimitPlugin, CompositeFetchHandlerPlugin, CompressionPlugin, FetchHandler, RPCHandler };
@@ -1,71 +1,56 @@
1
1
  import { SupportedMessagePort } from '@orpc/client/message-port';
2
2
  import { Value, Promisable, MaybeOptionalOptions } from '@orpc/shared';
3
- import { ServerPeer, EncodePeerMessageOptions, DecodePeerMessageOptions } from '@standardserver/peer';
4
- import { C as Context } from '../../shared/server.CcR4kgje.mjs';
5
- import { S as StandardHandler, a as StandardHandlerOptions } from '../../shared/server.DDFizwfU.mjs';
6
- import { StandardPeerRequestHandlerOptions } from '../standard-peer/index.mjs';
7
- import { R as Router } from '../../shared/server.15O7oC1p.mjs';
8
- import { R as RPCHandlerCodecOptions } from '../../shared/server.B4BnEWWm.mjs';
3
+ import { DecodedResponseMessage } from '@orpc/standard-server-peer';
4
+ import { C as Context, R as Router } from '../../shared/server.qKsRrdxW.mjs';
5
+ import { f as StandardHandler } from '../../shared/server.BqadksTP.mjs';
6
+ import { HandleStandardServerPeerMessageOptions } from '../standard-peer/index.mjs';
7
+ import { S as StandardRPCHandlerOptions } from '../../shared/server.DzE6WeuY.mjs';
9
8
  import '@orpc/client';
10
9
  import '@orpc/contract';
11
- import '@standardserver/core';
10
+ import '@orpc/standard-server';
11
+ import '../../shared/server.B8gYOD5g.mjs';
12
+ import '@orpc/client/standard';
13
+ import '../../shared/server.C8_sRzQB.mjs';
12
14
 
13
- type DecodedResponseMessage = ConstructorParameters<typeof ServerPeer>[0] extends (message: infer TMessage) => unknown ? TMessage : never;
14
15
  interface MessagePortHandlerOptions<_T extends Context> {
15
16
  /**
16
- * By default, oRPC encodes peer messages as strings or binary data before sending them over the message port.
17
- * Use this option to bypass encoding and leverage the full capabilities of the
18
- * [MessagePort: postMessage() method](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/postMessage),
19
- * such as transferring object ownership or supporting non-serializable objects like `OffscreenCanvas` or improving performance.
17
+ * By default, oRPC serializes request/response messages to string/binary data before sending over message port.
18
+ * 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),
19
+ * such as transferring ownership of objects to the other side or support unserializable objects like `OffscreenCanvas`.
20
20
  *
21
21
  * @remarks
22
- * - Returning `null` or `undefined` disables this feature.
22
+ * - return null | undefined to disable this feature
23
23
  *
24
- * @warning Ensure your message port implementation supports `transferable` objects before enabling this.
24
+ * @warning Make sure your message port supports `transfer` before using this feature.
25
+ * @example
26
+ * ```ts
27
+ * experimental_transfer: (message, port) => {
28
+ * const transfer = deepFindTransferableObjects(message) // implement your own logic
29
+ * return transfer.length ? transfer : null // only enable when needed
30
+ * }
31
+ * ```
32
+ *
33
+ * @see {@link https://orpc.dev/docs/adapters/message-port#transfer Message Port Transfer Docs}
25
34
  */
26
35
  experimental_transfer?: Value<Promisable<object[] | null | undefined>, [message: DecodedResponseMessage, port: SupportedMessagePort]>;
27
- /**
28
- * Options for encoding peer messages. such as `prefix` for distinguishing messages on the same channel..
29
- */
30
- encodePeerMessage?: EncodePeerMessageOptions | undefined;
31
- /**
32
- * Options for decoding peer messages. such as `prefix` for distinguishing messages on the same channel..
33
- */
34
- decodePeerMessage?: DecodePeerMessageOptions | undefined;
35
36
  }
36
37
  declare class MessagePortHandler<T extends Context> {
37
- private readonly handler;
38
- private readonly peers;
38
+ private readonly standardHandler;
39
39
  private readonly transfer;
40
- private readonly encodePeerMessageOptions;
41
- private readonly decodePeerMessageOptions;
42
- constructor(handler: StandardHandler<T>, options?: NoInfer<MessagePortHandlerOptions<T>>);
43
- /**
44
- * Attaches message and close listeners to a message port.
45
- *
46
- * Prefer this over calling `.message()` and `.close()` manually.
47
- */
48
- upgrade(port: SupportedMessagePort, ...rest: MaybeOptionalOptions<StandardPeerRequestHandlerOptions<T>>): void;
49
- /**
50
- * Handles a single message received from a message port.
51
- *
52
- * @param port The message port instance. Use the same instance for all messages.
53
- */
54
- message(port: SupportedMessagePort, data: unknown, ...rest: MaybeOptionalOptions<StandardPeerRequestHandlerOptions<T>>): Promise<{
55
- matched: boolean;
56
- }>;
57
- /**
58
- * Cleans up peer state for a closed message port.
59
- *
60
- * @param port The same message port instance passed to `.message()`.
61
- */
62
- close(port: SupportedMessagePort): Promise<void>;
40
+ constructor(standardHandler: StandardHandler<T>, options?: NoInfer<MessagePortHandlerOptions<T>>);
41
+ upgrade(port: SupportedMessagePort, ...rest: MaybeOptionalOptions<HandleStandardServerPeerMessageOptions<T>>): void;
63
42
  }
64
43
 
65
- interface RPCHandlerOptions<T extends Context> extends StandardHandlerOptions<T>, RPCHandlerCodecOptions<T>, MessagePortHandlerOptions<T> {
44
+ interface RPCHandlerOptions<T extends Context> extends StandardRPCHandlerOptions<T>, MessagePortHandlerOptions<T> {
66
45
  }
46
+ /**
47
+ * RPC Handler for common message port implementations.
48
+ *
49
+ * @see {@link https://orpc.dev/docs/rpc-handler RPC Handler Docs}
50
+ * @see {@link https://orpc.dev/docs/adapters/message-port Message Port Adapter Docs}
51
+ */
67
52
  declare class RPCHandler<T extends Context> extends MessagePortHandler<T> {
68
- constructor(router: Router<T>, options?: NoInfer<RPCHandlerOptions<T>>);
53
+ constructor(router: Router<any, T>, options?: NoInfer<RPCHandlerOptions<T>>);
69
54
  }
70
55
 
71
56
  export { MessagePortHandler, RPCHandler };
@@ -1,71 +1,56 @@
1
1
  import { SupportedMessagePort } from '@orpc/client/message-port';
2
2
  import { Value, Promisable, MaybeOptionalOptions } from '@orpc/shared';
3
- import { ServerPeer, EncodePeerMessageOptions, DecodePeerMessageOptions } from '@standardserver/peer';
4
- import { C as Context } from '../../shared/server.CcR4kgje.js';
5
- import { S as StandardHandler, a as StandardHandlerOptions } from '../../shared/server.BhsVw7m7.js';
6
- import { StandardPeerRequestHandlerOptions } from '../standard-peer/index.js';
7
- import { R as Router } from '../../shared/server.m3szVJGU.js';
8
- import { R as RPCHandlerCodecOptions } from '../../shared/server.CnN50DHH.js';
3
+ import { DecodedResponseMessage } from '@orpc/standard-server-peer';
4
+ import { C as Context, R as Router } from '../../shared/server.qKsRrdxW.js';
5
+ import { f as StandardHandler } from '../../shared/server.7cEtMB30.js';
6
+ import { HandleStandardServerPeerMessageOptions } from '../standard-peer/index.js';
7
+ import { S as StandardRPCHandlerOptions } from '../../shared/server.D8IXzfqT.js';
9
8
  import '@orpc/client';
10
9
  import '@orpc/contract';
11
- import '@standardserver/core';
10
+ import '@orpc/standard-server';
11
+ import '../../shared/server.EfTOZ2Q7.js';
12
+ import '@orpc/client/standard';
13
+ import '../../shared/server.ChyoA9XY.js';
12
14
 
13
- type DecodedResponseMessage = ConstructorParameters<typeof ServerPeer>[0] extends (message: infer TMessage) => unknown ? TMessage : never;
14
15
  interface MessagePortHandlerOptions<_T extends Context> {
15
16
  /**
16
- * By default, oRPC encodes peer messages as strings or binary data before sending them over the message port.
17
- * Use this option to bypass encoding and leverage the full capabilities of the
18
- * [MessagePort: postMessage() method](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/postMessage),
19
- * such as transferring object ownership or supporting non-serializable objects like `OffscreenCanvas` or improving performance.
17
+ * By default, oRPC serializes request/response messages to string/binary data before sending over message port.
18
+ * 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),
19
+ * such as transferring ownership of objects to the other side or support unserializable objects like `OffscreenCanvas`.
20
20
  *
21
21
  * @remarks
22
- * - Returning `null` or `undefined` disables this feature.
22
+ * - return null | undefined to disable this feature
23
23
  *
24
- * @warning Ensure your message port implementation supports `transferable` objects before enabling this.
24
+ * @warning Make sure your message port supports `transfer` before using this feature.
25
+ * @example
26
+ * ```ts
27
+ * experimental_transfer: (message, port) => {
28
+ * const transfer = deepFindTransferableObjects(message) // implement your own logic
29
+ * return transfer.length ? transfer : null // only enable when needed
30
+ * }
31
+ * ```
32
+ *
33
+ * @see {@link https://orpc.dev/docs/adapters/message-port#transfer Message Port Transfer Docs}
25
34
  */
26
35
  experimental_transfer?: Value<Promisable<object[] | null | undefined>, [message: DecodedResponseMessage, port: SupportedMessagePort]>;
27
- /**
28
- * Options for encoding peer messages. such as `prefix` for distinguishing messages on the same channel..
29
- */
30
- encodePeerMessage?: EncodePeerMessageOptions | undefined;
31
- /**
32
- * Options for decoding peer messages. such as `prefix` for distinguishing messages on the same channel..
33
- */
34
- decodePeerMessage?: DecodePeerMessageOptions | undefined;
35
36
  }
36
37
  declare class MessagePortHandler<T extends Context> {
37
- private readonly handler;
38
- private readonly peers;
38
+ private readonly standardHandler;
39
39
  private readonly transfer;
40
- private readonly encodePeerMessageOptions;
41
- private readonly decodePeerMessageOptions;
42
- constructor(handler: StandardHandler<T>, options?: NoInfer<MessagePortHandlerOptions<T>>);
43
- /**
44
- * Attaches message and close listeners to a message port.
45
- *
46
- * Prefer this over calling `.message()` and `.close()` manually.
47
- */
48
- upgrade(port: SupportedMessagePort, ...rest: MaybeOptionalOptions<StandardPeerRequestHandlerOptions<T>>): void;
49
- /**
50
- * Handles a single message received from a message port.
51
- *
52
- * @param port The message port instance. Use the same instance for all messages.
53
- */
54
- message(port: SupportedMessagePort, data: unknown, ...rest: MaybeOptionalOptions<StandardPeerRequestHandlerOptions<T>>): Promise<{
55
- matched: boolean;
56
- }>;
57
- /**
58
- * Cleans up peer state for a closed message port.
59
- *
60
- * @param port The same message port instance passed to `.message()`.
61
- */
62
- close(port: SupportedMessagePort): Promise<void>;
40
+ constructor(standardHandler: StandardHandler<T>, options?: NoInfer<MessagePortHandlerOptions<T>>);
41
+ upgrade(port: SupportedMessagePort, ...rest: MaybeOptionalOptions<HandleStandardServerPeerMessageOptions<T>>): void;
63
42
  }
64
43
 
65
- interface RPCHandlerOptions<T extends Context> extends StandardHandlerOptions<T>, RPCHandlerCodecOptions<T>, MessagePortHandlerOptions<T> {
44
+ interface RPCHandlerOptions<T extends Context> extends StandardRPCHandlerOptions<T>, MessagePortHandlerOptions<T> {
66
45
  }
46
+ /**
47
+ * RPC Handler for common message port implementations.
48
+ *
49
+ * @see {@link https://orpc.dev/docs/rpc-handler RPC Handler Docs}
50
+ * @see {@link https://orpc.dev/docs/adapters/message-port Message Port Adapter Docs}
51
+ */
67
52
  declare class RPCHandler<T extends Context> extends MessagePortHandler<T> {
68
- constructor(router: Router<T>, options?: NoInfer<RPCHandlerOptions<T>>);
53
+ constructor(router: Router<any, T>, options?: NoInfer<RPCHandlerOptions<T>>);
69
54
  }
70
55
 
71
56
  export { MessagePortHandler, RPCHandler };
@@ -1,85 +1,54 @@
1
- import { onMessagePortMessage, onMessagePortClose, postMessagePortMessage } from '@orpc/client/message-port';
2
- import { value, resolveMaybeOptionalOptions } from '@orpc/shared';
3
- import { ServerPeer, encodePeerMessage, decodePeerMessage, isClientPeerSendMessage, isPeerMessage } from '@standardserver/peer';
4
- import { c as createStandardPeerRequestHandler } from '../../shared/server.CX4vUnDk.mjs';
5
- import { R as RPCHandlerCodec, S as StandardHandler } from '../../shared/server.COPVXhDG.mjs';
1
+ import { postMessagePortMessage, onMessagePortMessage, onMessagePortClose } from '@orpc/client/message-port';
2
+ import { value, resolveMaybeOptionalOptions, isObject } from '@orpc/shared';
3
+ import { experimental_ServerPeerWithoutCodec, serializeResponseMessage, encodeResponseMessage, deserializeRequestMessage, decodeRequestMessage } from '@orpc/standard-server-peer';
4
+ import { createServerPeerHandleRequestFn } from '../standard-peer/index.mjs';
5
+ import { b as StandardRPCHandler } from '../../shared/server.CMf4nKky.mjs';
6
+ import '../../shared/server.DZ5BIITo.mjs';
7
+ import '@orpc/client/standard';
6
8
  import '@orpc/client';
7
- import '@standardserver/core';
8
- import '../../shared/server.DofEOwf-.mjs';
9
+ import '@orpc/standard-server';
10
+ import '../../shared/server.DEBcqOjg.mjs';
9
11
  import '@orpc/contract';
10
- import '../../shared/server.BoiFpNT7.mjs';
11
12
 
12
13
  class MessagePortHandler {
13
- constructor(handler, options = {}) {
14
- this.handler = handler;
14
+ constructor(standardHandler, options = {}) {
15
+ this.standardHandler = standardHandler;
15
16
  this.transfer = options.experimental_transfer;
16
- this.encodePeerMessageOptions = options.encodePeerMessage;
17
- this.decodePeerMessageOptions = options.decodePeerMessage;
18
17
  }
19
- peers = /* @__PURE__ */ new WeakMap();
20
18
  transfer;
21
- encodePeerMessageOptions;
22
- decodePeerMessageOptions;
23
- /**
24
- * Attaches message and close listeners to a message port.
25
- *
26
- * Prefer this over calling `.message()` and `.close()` manually.
27
- */
28
19
  upgrade(port, ...rest) {
29
- onMessagePortMessage(port, (message) => this.message(port, message, ...rest));
30
- onMessagePortClose(port, () => this.close(port));
31
- }
32
- /**
33
- * Handles a single message received from a message port.
34
- *
35
- * @param port The message port instance. Use the same instance for all messages.
36
- */
37
- async message(port, data, ...rest) {
38
- let peer = this.peers.get(port);
39
- if (!peer) {
40
- this.peers.set(port, peer = new ServerPeer(async (message) => {
41
- const transfer = await value(this.transfer, message, port);
42
- if (transfer) {
43
- postMessagePortMessage(port, message, transfer);
44
- } else {
45
- postMessagePortMessage(port, await encodePeerMessage(message, this.encodePeerMessageOptions));
46
- }
47
- }));
48
- }
49
- let peerMessage;
50
- if (typeof data === "string" || data instanceof Uint8Array) {
51
- const result = decodePeerMessage(data, this.decodePeerMessageOptions);
52
- if (result.matched && isClientPeerSendMessage(result.message)) {
53
- peerMessage = result.message;
20
+ const peer = new experimental_ServerPeerWithoutCodec(async (message) => {
21
+ const [id, type, payload] = message;
22
+ const transfer = await value(this.transfer, message, port);
23
+ if (transfer) {
24
+ postMessagePortMessage(port, serializeResponseMessage(id, type, payload), transfer);
25
+ } else {
26
+ postMessagePortMessage(port, await encodeResponseMessage(id, type, payload));
54
27
  }
55
- } else if (isPeerMessage(data) && isClientPeerSendMessage(data)) {
56
- peerMessage = data;
57
- }
58
- if (peerMessage === void 0) {
59
- return { matched: false };
60
- }
61
- await peer.message(peerMessage, createStandardPeerRequestHandler(this.handler, resolveMaybeOptionalOptions(rest)));
62
- return { matched: true };
63
- }
64
- /**
65
- * Cleans up peer state for a closed message port.
66
- *
67
- * @param port The same message port instance passed to `.message()`.
68
- */
69
- async close(port) {
70
- const peer = this.peers.get(port);
71
- if (peer) {
72
- this.peers.delete(port);
73
- await peer.close();
74
- }
28
+ });
29
+ onMessagePortMessage(port, async (message) => {
30
+ const handleFn = createServerPeerHandleRequestFn(this.standardHandler, resolveMaybeOptionalOptions(rest));
31
+ if (isObject(message)) {
32
+ await peer.message(
33
+ deserializeRequestMessage(message),
34
+ handleFn
35
+ );
36
+ } else {
37
+ await peer.message(
38
+ await decodeRequestMessage(message),
39
+ handleFn
40
+ );
41
+ }
42
+ });
43
+ onMessagePortClose(port, () => {
44
+ peer.close();
45
+ });
75
46
  }
76
47
  }
77
48
 
78
49
  class RPCHandler extends MessagePortHandler {
79
50
  constructor(router, options = {}) {
80
- const codec = new RPCHandlerCodec(router, options);
81
- const handler = new StandardHandler(codec, options);
82
- super(handler, options);
51
+ super(new StandardRPCHandler(router, options), options);
83
52
  }
84
53
  }
85
54