@orpc/standard-server 0.0.0-next.fd6982a → 0.0.0-next.fe5c63f

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,7 +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
- - **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte), Pinia Colada, and more.
33
+ - **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte, Angular), Pinia Colada, and more.
34
34
  - **🚀 Server Actions**: Fully compatible with React Server Actions on Next.js, TanStack Start, and other platforms.
35
35
  - **🔠 Standard Schema Support**: Works out of the box with Zod, Valibot, ArkType, and other schema validators.
36
36
  - **🗃️ Native Types**: Supports native types like Date, File, Blob, BigInt, URL, and more.
@@ -49,14 +49,12 @@ You can find the full documentation [here](https://orpc.unnoq.com).
49
49
  - [@orpc/contract](https://www.npmjs.com/package/@orpc/contract): Build your API contract.
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
- - [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Deeply integrate oRPC with NestJS.
52
+ - [@orpc/openapi](https://www.npmjs.com/package/@orpc/openapi): Generate OpenAPI specs and handle OpenAPI requests.
53
+ - [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Deeply integrate oRPC with [NestJS](https://nestjs.com/).
53
54
  - [@orpc/react](https://www.npmjs.com/package/@orpc/react): Utilities for integrating oRPC with React and React Server Actions.
54
- - [@orpc/react-query](https://www.npmjs.com/package/@orpc/react-query): Integration with [React Query](https://tanstack.com/query/latest/docs/framework/react/overview).
55
- - [@orpc/vue-query](https://www.npmjs.com/package/@orpc/vue-query): Integration with [Vue Query](https://tanstack.com/query/latest/docs/framework/vue/overview).
56
- - [@orpc/solid-query](https://www.npmjs.com/package/@orpc/solid-query): Integration with [Solid Query](https://tanstack.com/query/latest/docs/framework/solid/overview).
57
- - [@orpc/svelte-query](https://www.npmjs.com/package/@orpc/svelte-query): Integration with [Svelte Query](https://tanstack.com/query/latest/docs/framework/svelte/overview).
55
+ - [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): [TanStack Query](https://tanstack.com/query/latest) integration.
58
56
  - [@orpc/vue-colada](https://www.npmjs.com/package/@orpc/vue-colada): Integration with [Pinia Colada](https://pinia-colada.esm.dev/).
59
- - [@orpc/openapi](https://www.npmjs.com/package/@orpc/openapi): Generate OpenAPI specs and handle OpenAPI requests.
57
+ - [@orpc/hey-api](https://www.npmjs.com/package/@orpc/hey-api): [Hey API](https://heyapi.dev/) integration.
60
58
  - [@orpc/zod](https://www.npmjs.com/package/@orpc/zod): More schemas that [Zod](https://zod.dev/) doesn't support yet.
61
59
  - [@orpc/valibot](https://www.npmjs.com/package/@orpc/valibot): OpenAPI spec generation from [Valibot](https://valibot.dev/).
62
60
  - [@orpc/arktype](https://www.npmjs.com/package/@orpc/arktype): OpenAPI spec generation from [ArkType](https://arktype.io/).
@@ -1,4 +1,5 @@
1
- import { S as StandardHeaders, b as StandardRequest, d as StandardResponse } from '../shared/standard-server.R_NaHlxw.mjs';
1
+ import { S as StandardHeaders, c as StandardRequest, e as StandardResponse } from '../shared/standard-server.BD8Sg1A5.mjs';
2
+ import { Promisable } from '@orpc/shared';
2
3
 
3
4
  interface ToBatchRequestOptions {
4
5
  url: URL;
@@ -9,16 +10,21 @@ interface ToBatchRequestOptions {
9
10
  declare function toBatchRequest(options: ToBatchRequestOptions): StandardRequest;
10
11
  declare function parseBatchRequest(request: StandardRequest): StandardRequest[];
11
12
 
13
+ type BatchResponseMode = 'streaming' | 'buffered';
12
14
  interface BatchResponseBodyItem extends StandardResponse {
13
15
  index: number;
14
16
  }
15
17
  interface ToBatchResponseOptions extends StandardResponse {
16
18
  body: AsyncIteratorObject<BatchResponseBodyItem>;
19
+ /**
20
+ * @default 'streaming'
21
+ */
22
+ mode?: BatchResponseMode;
17
23
  }
18
- declare function toBatchResponse(options: ToBatchResponseOptions): StandardResponse;
24
+ declare function toBatchResponse(options: ToBatchResponseOptions): Promisable<StandardResponse>;
19
25
  declare function parseBatchResponse(response: StandardResponse): AsyncGenerator<BatchResponseBodyItem>;
20
26
 
21
27
  declare function toBatchAbortSignal(signals: readonly (AbortSignal | undefined)[]): AbortSignal | undefined;
22
28
 
23
29
  export { parseBatchRequest, parseBatchResponse, toBatchAbortSignal, toBatchRequest, toBatchResponse };
24
- export type { BatchResponseBodyItem, ToBatchRequestOptions, ToBatchResponseOptions };
30
+ export type { BatchResponseBodyItem, BatchResponseMode, ToBatchRequestOptions, ToBatchResponseOptions };
@@ -1,4 +1,5 @@
1
- import { S as StandardHeaders, b as StandardRequest, d as StandardResponse } from '../shared/standard-server.R_NaHlxw.js';
1
+ import { S as StandardHeaders, c as StandardRequest, e as StandardResponse } from '../shared/standard-server.BD8Sg1A5.js';
2
+ import { Promisable } from '@orpc/shared';
2
3
 
3
4
  interface ToBatchRequestOptions {
4
5
  url: URL;
@@ -9,16 +10,21 @@ interface ToBatchRequestOptions {
9
10
  declare function toBatchRequest(options: ToBatchRequestOptions): StandardRequest;
10
11
  declare function parseBatchRequest(request: StandardRequest): StandardRequest[];
11
12
 
13
+ type BatchResponseMode = 'streaming' | 'buffered';
12
14
  interface BatchResponseBodyItem extends StandardResponse {
13
15
  index: number;
14
16
  }
15
17
  interface ToBatchResponseOptions extends StandardResponse {
16
18
  body: AsyncIteratorObject<BatchResponseBodyItem>;
19
+ /**
20
+ * @default 'streaming'
21
+ */
22
+ mode?: BatchResponseMode;
17
23
  }
18
- declare function toBatchResponse(options: ToBatchResponseOptions): StandardResponse;
24
+ declare function toBatchResponse(options: ToBatchResponseOptions): Promisable<StandardResponse>;
19
25
  declare function parseBatchResponse(response: StandardResponse): AsyncGenerator<BatchResponseBodyItem>;
20
26
 
21
27
  declare function toBatchAbortSignal(signals: readonly (AbortSignal | undefined)[]): AbortSignal | undefined;
22
28
 
23
29
  export { parseBatchRequest, parseBatchResponse, toBatchAbortSignal, toBatchRequest, toBatchResponse };
24
- export type { BatchResponseBodyItem, ToBatchRequestOptions, ToBatchResponseOptions };
30
+ export type { BatchResponseBodyItem, BatchResponseMode, ToBatchRequestOptions, ToBatchResponseOptions };
@@ -62,8 +62,35 @@ function parseBatchRequest(request) {
62
62
  }
63
63
 
64
64
  function toBatchResponse(options) {
65
+ const mode = options.mode ?? "streaming";
66
+ const minifyResponseItem = (item) => {
67
+ return {
68
+ index: item.index,
69
+ status: item.status === options.status ? void 0 : item.status,
70
+ headers: Object.keys(item.headers).length ? item.headers : void 0,
71
+ body: item.body
72
+ };
73
+ };
74
+ if (mode === "buffered") {
75
+ return (async () => {
76
+ try {
77
+ const body = [];
78
+ for await (const item of options.body) {
79
+ body.push(minifyResponseItem(item));
80
+ }
81
+ return {
82
+ headers: options.headers,
83
+ status: options.status,
84
+ body
85
+ };
86
+ } finally {
87
+ await options.body.return?.();
88
+ }
89
+ })();
90
+ }
65
91
  return {
66
- ...options,
92
+ headers: options.headers,
93
+ status: options.status,
67
94
  body: async function* () {
68
95
  try {
69
96
  for await (const item of options.body) {
@@ -75,37 +102,39 @@ function toBatchResponse(options) {
75
102
  };
76
103
  }
77
104
  } finally {
78
- options.body.return?.();
105
+ await options.body.return?.();
79
106
  }
80
107
  }()
81
108
  };
82
109
  }
83
110
  function parseBatchResponse(response) {
84
111
  const body = response.body;
85
- if (!isAsyncIteratorObject(body)) {
86
- throw new TypeError("Invalid batch response", {
87
- cause: response
88
- });
89
- }
90
- return async function* () {
91
- try {
92
- for await (const item of body) {
93
- if (!isObject(item) || !("index" in item) || typeof item.index !== "number") {
94
- throw new TypeError("Invalid batch response", {
95
- cause: item
96
- });
112
+ if (isAsyncIteratorObject(body) || Array.isArray(body)) {
113
+ return async function* () {
114
+ try {
115
+ for await (const item of body) {
116
+ if (!isObject(item) || !("index" in item) || typeof item.index !== "number") {
117
+ throw new TypeError("Invalid batch response", {
118
+ cause: item
119
+ });
120
+ }
121
+ yield {
122
+ index: item.index,
123
+ status: item.status ?? response.status,
124
+ headers: item.headers ?? {},
125
+ body: item.body
126
+ };
127
+ }
128
+ } finally {
129
+ if (isAsyncIteratorObject(body)) {
130
+ await body.return?.();
97
131
  }
98
- yield {
99
- index: item.index,
100
- status: item.status ?? response.status,
101
- headers: item.headers ?? {},
102
- body: item.body
103
- };
104
132
  }
105
- } finally {
106
- await body.return?.();
107
- }
108
- }();
133
+ }();
134
+ }
135
+ throw new TypeError("Invalid batch response", {
136
+ cause: response
137
+ });
109
138
  }
110
139
 
111
140
  export { parseBatchRequest, parseBatchResponse, toBatchAbortSignal, toBatchRequest, toBatchResponse };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
- import { S as StandardHeaders } from './shared/standard-server.R_NaHlxw.mjs';
2
- export { a as StandardBody, c as StandardLazyRequest, e as StandardLazyResponse, b as StandardRequest, d as StandardResponse } from './shared/standard-server.R_NaHlxw.mjs';
1
+ import { AsyncIteratorClass } from '@orpc/shared';
2
+ import { S as StandardHeaders, a as StandardLazyResponse } from './shared/standard-server.BD8Sg1A5.mjs';
3
+ export { b as StandardBody, d as StandardLazyRequest, c as StandardRequest, e as StandardResponse } from './shared/standard-server.BD8Sg1A5.mjs';
3
4
 
4
5
  interface EventMessage {
5
6
  event: string | undefined;
@@ -52,10 +53,23 @@ type EventMeta = Partial<Pick<EventMessage, 'retry' | 'id' | 'comments'>>;
52
53
  declare function withEventMeta<T extends object>(container: T, meta: EventMeta): T;
53
54
  declare function getEventMeta(container: unknown): EventMeta | undefined;
54
55
 
56
+ interface experimental_HibernationEventIteratorCallback {
57
+ (id: string): void;
58
+ }
59
+ declare class experimental_HibernationEventIterator<T, TReturn = unknown, TNext = unknown> extends AsyncIteratorClass<T, TReturn, TNext> {
60
+ /**
61
+ * this property is not transferred to the client, so it should be optional for type safety
62
+ */
63
+ readonly hibernationCallback?: experimental_HibernationEventIteratorCallback;
64
+ constructor(hibernationCallback: experimental_HibernationEventIteratorCallback);
65
+ }
66
+
55
67
  declare function generateContentDisposition(filename: string): string;
56
68
  declare function getFilenameFromContentDisposition(contentDisposition: string): string | undefined;
57
69
  declare function mergeStandardHeaders(a: StandardHeaders, b: StandardHeaders): StandardHeaders;
58
70
  declare function flattenHeader(header: string | readonly string[] | undefined): string | undefined;
71
+ declare function replicateStandardLazyResponse(response: StandardLazyResponse, count: number): StandardLazyResponse[];
72
+ declare function isEventIteratorHeaders(headers: StandardHeaders): boolean;
59
73
 
60
- export { ErrorEvent, EventDecoder, EventDecoderError, EventDecoderStream, EventEncoderError, StandardHeaders, assertEventComment, assertEventId, assertEventName, assertEventRetry, decodeEventMessage, encodeEventComments, encodeEventData, encodeEventMessage, flattenHeader, generateContentDisposition, getEventMeta, getFilenameFromContentDisposition, mergeStandardHeaders, withEventMeta };
61
- export type { ErrorEventOptions, EventDecoderOptions, EventMessage, EventMeta };
74
+ export { ErrorEvent, EventDecoder, EventDecoderError, EventDecoderStream, EventEncoderError, StandardHeaders, StandardLazyResponse, assertEventComment, assertEventId, assertEventName, assertEventRetry, decodeEventMessage, encodeEventComments, encodeEventData, encodeEventMessage, experimental_HibernationEventIterator, flattenHeader, generateContentDisposition, getEventMeta, getFilenameFromContentDisposition, isEventIteratorHeaders, mergeStandardHeaders, replicateStandardLazyResponse, withEventMeta };
75
+ export type { ErrorEventOptions, EventDecoderOptions, EventMessage, EventMeta, experimental_HibernationEventIteratorCallback };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { S as StandardHeaders } from './shared/standard-server.R_NaHlxw.js';
2
- export { a as StandardBody, c as StandardLazyRequest, e as StandardLazyResponse, b as StandardRequest, d as StandardResponse } from './shared/standard-server.R_NaHlxw.js';
1
+ import { AsyncIteratorClass } from '@orpc/shared';
2
+ import { S as StandardHeaders, a as StandardLazyResponse } from './shared/standard-server.BD8Sg1A5.js';
3
+ export { b as StandardBody, d as StandardLazyRequest, c as StandardRequest, e as StandardResponse } from './shared/standard-server.BD8Sg1A5.js';
3
4
 
4
5
  interface EventMessage {
5
6
  event: string | undefined;
@@ -52,10 +53,23 @@ type EventMeta = Partial<Pick<EventMessage, 'retry' | 'id' | 'comments'>>;
52
53
  declare function withEventMeta<T extends object>(container: T, meta: EventMeta): T;
53
54
  declare function getEventMeta(container: unknown): EventMeta | undefined;
54
55
 
56
+ interface experimental_HibernationEventIteratorCallback {
57
+ (id: string): void;
58
+ }
59
+ declare class experimental_HibernationEventIterator<T, TReturn = unknown, TNext = unknown> extends AsyncIteratorClass<T, TReturn, TNext> {
60
+ /**
61
+ * this property is not transferred to the client, so it should be optional for type safety
62
+ */
63
+ readonly hibernationCallback?: experimental_HibernationEventIteratorCallback;
64
+ constructor(hibernationCallback: experimental_HibernationEventIteratorCallback);
65
+ }
66
+
55
67
  declare function generateContentDisposition(filename: string): string;
56
68
  declare function getFilenameFromContentDisposition(contentDisposition: string): string | undefined;
57
69
  declare function mergeStandardHeaders(a: StandardHeaders, b: StandardHeaders): StandardHeaders;
58
70
  declare function flattenHeader(header: string | readonly string[] | undefined): string | undefined;
71
+ declare function replicateStandardLazyResponse(response: StandardLazyResponse, count: number): StandardLazyResponse[];
72
+ declare function isEventIteratorHeaders(headers: StandardHeaders): boolean;
59
73
 
60
- export { ErrorEvent, EventDecoder, EventDecoderError, EventDecoderStream, EventEncoderError, StandardHeaders, assertEventComment, assertEventId, assertEventName, assertEventRetry, decodeEventMessage, encodeEventComments, encodeEventData, encodeEventMessage, flattenHeader, generateContentDisposition, getEventMeta, getFilenameFromContentDisposition, mergeStandardHeaders, withEventMeta };
61
- export type { ErrorEventOptions, EventDecoderOptions, EventMessage, EventMeta };
74
+ export { ErrorEvent, EventDecoder, EventDecoderError, EventDecoderStream, EventEncoderError, StandardHeaders, StandardLazyResponse, assertEventComment, assertEventId, assertEventName, assertEventRetry, decodeEventMessage, encodeEventComments, encodeEventData, encodeEventMessage, experimental_HibernationEventIterator, flattenHeader, generateContentDisposition, getEventMeta, getFilenameFromContentDisposition, isEventIteratorHeaders, mergeStandardHeaders, replicateStandardLazyResponse, withEventMeta };
75
+ export type { ErrorEventOptions, EventDecoderOptions, EventMessage, EventMeta, experimental_HibernationEventIteratorCallback };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { isTypescriptObject, toArray } from '@orpc/shared';
1
+ import { isTypescriptObject, AsyncIteratorClass, toArray, once, isAsyncIteratorObject, replicateAsyncIterator } from '@orpc/shared';
2
2
 
3
3
  class EventEncoderError extends TypeError {
4
4
  }
@@ -182,6 +182,23 @@ function getEventMeta(container) {
182
182
  return isTypescriptObject(container) ? Reflect.get(container, EVENT_SOURCE_META_SYMBOL) : void 0;
183
183
  }
184
184
 
185
+ class experimental_HibernationEventIterator extends AsyncIteratorClass {
186
+ /**
187
+ * this property is not transferred to the client, so it should be optional for type safety
188
+ */
189
+ hibernationCallback;
190
+ constructor(hibernationCallback) {
191
+ super(async () => {
192
+ throw new Error("Cannot iterate over hibernating iterator directly");
193
+ }, async (reason) => {
194
+ if (reason !== "next") {
195
+ throw new Error("Cannot cleanup hibernating iterator directly");
196
+ }
197
+ });
198
+ this.hibernationCallback = hibernationCallback;
199
+ }
200
+ }
201
+
185
202
  function generateContentDisposition(filename) {
186
203
  const escapedFileName = filename.replace(/"/g, '\\"');
187
204
  const encodedFilenameStar = encodeURIComponent(filename).replace(/['()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`).replace(/%(7C|60|5E)/g, (str, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
@@ -223,5 +240,30 @@ function flattenHeader(header) {
223
240
  }
224
241
  return header.join(", ");
225
242
  }
243
+ function replicateStandardLazyResponse(response, count) {
244
+ const replicated = [];
245
+ let bodyPromise;
246
+ let replicatedAsyncIteratorObjects;
247
+ for (let i = 0; i < count; i++) {
248
+ replicated.push({
249
+ ...response,
250
+ body: once(async () => {
251
+ if (replicatedAsyncIteratorObjects) {
252
+ return replicatedAsyncIteratorObjects.shift();
253
+ }
254
+ const body = await (bodyPromise ??= response.body());
255
+ if (!isAsyncIteratorObject(body)) {
256
+ return body;
257
+ }
258
+ replicatedAsyncIteratorObjects = replicateAsyncIterator(body, count);
259
+ return replicatedAsyncIteratorObjects.shift();
260
+ })
261
+ });
262
+ }
263
+ return replicated;
264
+ }
265
+ function isEventIteratorHeaders(headers) {
266
+ return Boolean(flattenHeader(headers["content-type"])?.startsWith("text/event-stream") && flattenHeader(headers["content-disposition"]) === void 0);
267
+ }
226
268
 
227
- export { ErrorEvent, EventDecoder, EventDecoderError, EventDecoderStream, EventEncoderError, assertEventComment, assertEventId, assertEventName, assertEventRetry, decodeEventMessage, encodeEventComments, encodeEventData, encodeEventMessage, flattenHeader, generateContentDisposition, getEventMeta, getFilenameFromContentDisposition, mergeStandardHeaders, withEventMeta };
269
+ export { ErrorEvent, EventDecoder, EventDecoderError, EventDecoderStream, EventEncoderError, assertEventComment, assertEventId, assertEventName, assertEventRetry, decodeEventMessage, encodeEventComments, encodeEventData, encodeEventMessage, experimental_HibernationEventIterator, flattenHeader, generateContentDisposition, getEventMeta, getFilenameFromContentDisposition, isEventIteratorHeaders, mergeStandardHeaders, replicateStandardLazyResponse, withEventMeta };
@@ -35,4 +35,4 @@ interface StandardLazyResponse extends Omit<StandardResponse, 'body'> {
35
35
  body: () => Promise<StandardBody>;
36
36
  }
37
37
 
38
- export type { StandardHeaders as S, StandardBody as a, StandardRequest as b, StandardLazyRequest as c, StandardResponse as d, StandardLazyResponse as e };
38
+ export type { StandardHeaders as S, StandardLazyResponse as a, StandardBody as b, StandardRequest as c, StandardLazyRequest as d, StandardResponse as e };
@@ -35,4 +35,4 @@ interface StandardLazyResponse extends Omit<StandardResponse, 'body'> {
35
35
  body: () => Promise<StandardBody>;
36
36
  }
37
37
 
38
- export type { StandardHeaders as S, StandardBody as a, StandardRequest as b, StandardLazyRequest as c, StandardResponse as d, StandardLazyResponse as e };
38
+ export type { StandardHeaders as S, StandardLazyResponse as a, StandardBody as b, StandardRequest as c, StandardLazyRequest as d, StandardResponse as e };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/standard-server",
3
3
  "type": "module",
4
- "version": "0.0.0-next.fd6982a",
4
+ "version": "0.0.0-next.fe5c63f",
5
5
  "license": "MIT",
6
6
  "homepage": "https://unnoq.com",
7
7
  "repository": {
@@ -28,7 +28,7 @@
28
28
  "dist"
29
29
  ],
30
30
  "dependencies": {
31
- "@orpc/shared": "0.0.0-next.fd6982a"
31
+ "@orpc/shared": "0.0.0-next.fe5c63f"
32
32
  },
33
33
  "scripts": {
34
34
  "build": "unbuild",