@orpc/standard-server-peer
Advanced tools
+123
-39
| import { Promisable, AsyncIdQueueCloseOptions as AsyncIdQueueCloseOptions$1, SetSpanErrorOptions, AsyncIteratorClassCleanupFn, AsyncIteratorClass } from '@orpc/shared'; | ||
| import { StandardRequest, StandardResponse, EventMeta } from '@orpc/standard-server'; | ||
| import { StandardRequest, EventMeta, StandardResponse, StandardBody, StandardHeaders } from '@orpc/standard-server'; | ||
@@ -9,2 +9,91 @@ type EncodedMessage = string | ArrayBufferLike | Uint8Array; | ||
| declare enum MessageType { | ||
| REQUEST = 1, | ||
| RESPONSE = 2, | ||
| EVENT_ITERATOR = 3, | ||
| ABORT_SIGNAL = 4 | ||
| } | ||
| type EventIteratorEvent = 'message' | 'error' | 'done'; | ||
| interface EventIteratorPayload { | ||
| event: EventIteratorEvent; | ||
| data: unknown; | ||
| meta?: EventMeta; | ||
| } | ||
| interface RequestMessageMap { | ||
| [MessageType.REQUEST]: Omit<StandardRequest, 'signal'>; | ||
| [MessageType.EVENT_ITERATOR]: EventIteratorPayload; | ||
| [MessageType.ABORT_SIGNAL]: void; | ||
| } | ||
| interface ResponseMessageMap { | ||
| [MessageType.RESPONSE]: StandardResponse; | ||
| [MessageType.EVENT_ITERATOR]: EventIteratorPayload; | ||
| [MessageType.ABORT_SIGNAL]: void; | ||
| } | ||
| interface BaseMessageFormat<P = unknown> { | ||
| /** | ||
| * Client-guaranteed unique identifier | ||
| */ | ||
| i: string; | ||
| /** | ||
| * @default REQUEST | RESPONSE | ||
| */ | ||
| t?: MessageType; | ||
| p: P; | ||
| } | ||
| interface SerializedEventIteratorPayload { | ||
| e: EventIteratorEvent; | ||
| d: unknown; | ||
| m?: EventMeta; | ||
| } | ||
| interface SerializedRequestPayload { | ||
| /** | ||
| * The url of the request | ||
| * | ||
| * might be relative path if origin is `http://orpc` | ||
| */ | ||
| u: string; | ||
| b: StandardBody; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| h?: StandardHeaders; | ||
| /** | ||
| * @default POST | ||
| */ | ||
| m?: string; | ||
| } | ||
| interface SerializedResponsePayload { | ||
| /** | ||
| * @default 200 | ||
| */ | ||
| s?: number; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| h?: StandardHeaders; | ||
| b: StandardBody; | ||
| } | ||
| type DecodedMessageUnion<TMap extends RequestMessageMap | ResponseMessageMap> = { | ||
| [K in keyof TMap]: [id: string, type: K, payload: TMap[K]]; | ||
| }[keyof TMap]; | ||
| type DecodedRequestMessage = DecodedMessageUnion<RequestMessageMap>; | ||
| type DecodedResponseMessage = DecodedMessageUnion<ResponseMessageMap>; | ||
| /** | ||
| * New serialization functions without Blob handling | ||
| */ | ||
| declare function serializeRequestMessage<T extends keyof RequestMessageMap>(id: string, type: T, payload: RequestMessageMap[T]): BaseMessageFormat; | ||
| declare function deserializeRequestMessage(message: BaseMessageFormat): DecodedRequestMessage; | ||
| declare function serializeResponseMessage<T extends keyof ResponseMessageMap>(id: string, type: T, payload: ResponseMessageMap[T]): BaseMessageFormat; | ||
| declare function deserializeResponseMessage(message: BaseMessageFormat): DecodedResponseMessage; | ||
| /** | ||
| * Original encode/decode functions now using the new serialize/deserialize functions | ||
| */ | ||
| declare function encodeRequestMessage<T extends keyof RequestMessageMap>(id: string, type: T, payload: RequestMessageMap[T]): Promise<EncodedMessage>; | ||
| declare function decodeRequestMessage(raw: EncodedMessage): Promise<DecodedRequestMessage>; | ||
| declare function encodeResponseMessage<T extends keyof ResponseMessageMap>(id: string, type: T, payload: ResponseMessageMap[T]): Promise<EncodedMessage>; | ||
| declare function decodeResponseMessage(raw: EncodedMessage): Promise<DecodedResponseMessage>; | ||
| interface experimental_RequestMessageSendFn { | ||
| (message: DecodedRequestMessage): Promisable<void>; | ||
| } | ||
| interface ClientPeerCloseOptions extends AsyncIdQueueCloseOptions$1 { | ||
@@ -19,2 +108,11 @@ /** | ||
| declare class ClientPeer { | ||
| private readonly peer; | ||
| constructor(send: EncodedMessageSendFn); | ||
| get length(): number; | ||
| open(id: string): AbortController; | ||
| request(request: StandardRequest): Promise<StandardResponse>; | ||
| message(raw: EncodedMessage): Promise<void>; | ||
| close(options?: AsyncIdQueueCloseOptions$1): void; | ||
| } | ||
| declare class experimental_ClientPeerWithoutCodec { | ||
| private readonly idGenerator; | ||
@@ -38,42 +136,10 @@ /** | ||
| private readonly send; | ||
| constructor(send: EncodedMessageSendFn); | ||
| constructor(send: experimental_RequestMessageSendFn); | ||
| get length(): number; | ||
| open(id: string): AbortController; | ||
| request(request: StandardRequest): Promise<StandardResponse>; | ||
| message(raw: EncodedMessage): Promise<void>; | ||
| message([id, type, payload]: DecodedResponseMessage): Promise<void>; | ||
| close(options?: AsyncIdQueueCloseOptions$1): void; | ||
| } | ||
| declare enum MessageType { | ||
| REQUEST = 1, | ||
| RESPONSE = 2, | ||
| EVENT_ITERATOR = 3, | ||
| ABORT_SIGNAL = 4 | ||
| } | ||
| type EventIteratorEvent = 'message' | 'error' | 'done'; | ||
| interface EventIteratorPayload { | ||
| event: EventIteratorEvent; | ||
| data: unknown; | ||
| meta?: EventMeta; | ||
| } | ||
| interface RequestMessageMap { | ||
| [MessageType.REQUEST]: Omit<StandardRequest, 'signal'>; | ||
| [MessageType.EVENT_ITERATOR]: EventIteratorPayload; | ||
| [MessageType.ABORT_SIGNAL]: void; | ||
| } | ||
| interface ResponseMessageMap { | ||
| [MessageType.RESPONSE]: StandardResponse; | ||
| [MessageType.EVENT_ITERATOR]: EventIteratorPayload; | ||
| [MessageType.ABORT_SIGNAL]: void; | ||
| } | ||
| type DecodedMessageUnion<TMap extends RequestMessageMap | ResponseMessageMap> = { | ||
| [K in keyof TMap]: [id: string, type: K, payload: TMap[K]]; | ||
| }[keyof TMap]; | ||
| type DecodedRequestMessage = DecodedMessageUnion<RequestMessageMap>; | ||
| type DecodedResponseMessage = DecodedMessageUnion<ResponseMessageMap>; | ||
| declare function encodeRequestMessage<T extends keyof RequestMessageMap>(id: string, type: T, payload: RequestMessageMap[T]): Promise<EncodedMessage>; | ||
| declare function decodeRequestMessage(raw: EncodedMessage): Promise<DecodedRequestMessage>; | ||
| declare function encodeResponseMessage<T extends keyof ResponseMessageMap>(id: string, type: T, payload: ResponseMessageMap[T]): Promise<EncodedMessage>; | ||
| declare function decodeResponseMessage(raw: EncodedMessage): Promise<DecodedResponseMessage>; | ||
| interface AsyncIdQueueCloseOptions { | ||
@@ -103,2 +169,5 @@ id?: string; | ||
| interface experimental_ResponseMessageSendFn { | ||
| (message: DecodedResponseMessage): Promisable<void>; | ||
| } | ||
| interface ServerPeerHandleRequestFn { | ||
@@ -116,3 +185,18 @@ (request: StandardRequest): Promise<StandardResponse>; | ||
| declare class ServerPeer { | ||
| private readonly peer; | ||
| constructor(send: EncodedMessageSendFn); | ||
| get length(): number; | ||
| open(id: string): AbortController; | ||
| /** | ||
| * @todo This method will return Promise<void> in the next major version. | ||
| */ | ||
| message(raw: EncodedMessage, handleRequest?: ServerPeerHandleRequestFn): Promise<[id: string, StandardRequest | undefined]>; | ||
| /** | ||
| * @deprecated Please pass the `handleRequest` (second arg) function to the `message` method instead. | ||
| */ | ||
| response(id: string, response: StandardResponse): Promise<void>; | ||
| close({ abort, ...options }?: ServerPeerCloseOptions): void; | ||
| } | ||
| declare class experimental_ServerPeerWithoutCodec { | ||
| /** | ||
| * Queue of event iterator messages sent from client, awaiting consumption | ||
@@ -126,3 +210,3 @@ */ | ||
| private readonly send; | ||
| constructor(send: EncodedMessageSendFn); | ||
| constructor(send: experimental_ResponseMessageSendFn); | ||
| get length(): number; | ||
@@ -133,3 +217,3 @@ open(id: string): AbortController; | ||
| */ | ||
| message(raw: EncodedMessage, handleRequest?: ServerPeerHandleRequestFn): Promise<[id: string, StandardRequest | undefined]>; | ||
| message([id, type, payload]: DecodedRequestMessage, handleRequest?: ServerPeerHandleRequestFn): Promise<[id: string, StandardRequest | undefined]>; | ||
| /** | ||
@@ -142,3 +226,3 @@ * @deprecated Please pass the `handleRequest` (second arg) function to the `message` method instead. | ||
| export { ClientPeer, MessageType, ServerPeer, decodeRequestMessage, decodeResponseMessage, encodeRequestMessage, encodeResponseMessage, resolveEventIterator, toEventIterator }; | ||
| export type { ClientPeerCloseOptions, DecodedRequestMessage, DecodedResponseMessage, EncodedMessage, EncodedMessageSendFn, EventIteratorEvent, EventIteratorPayload, RequestMessageMap, ResponseMessageMap, ServerPeerCloseOptions, ServerPeerHandleRequestFn, ToEventIteratorOptions }; | ||
| export { ClientPeer, MessageType, ServerPeer, decodeRequestMessage, decodeResponseMessage, deserializeRequestMessage, deserializeResponseMessage, encodeRequestMessage, encodeResponseMessage, experimental_ClientPeerWithoutCodec, experimental_ServerPeerWithoutCodec, resolveEventIterator, serializeRequestMessage, serializeResponseMessage, toEventIterator }; | ||
| export type { BaseMessageFormat, ClientPeerCloseOptions, DecodedMessageUnion, DecodedRequestMessage, DecodedResponseMessage, EncodedMessage, EncodedMessageSendFn, EventIteratorEvent, EventIteratorPayload, RequestMessageMap, ResponseMessageMap, SerializedEventIteratorPayload, SerializedRequestPayload, SerializedResponsePayload, ServerPeerCloseOptions, ServerPeerHandleRequestFn, ToEventIteratorOptions, experimental_RequestMessageSendFn, experimental_ResponseMessageSendFn }; |
+123
-39
| import { Promisable, AsyncIdQueueCloseOptions as AsyncIdQueueCloseOptions$1, SetSpanErrorOptions, AsyncIteratorClassCleanupFn, AsyncIteratorClass } from '@orpc/shared'; | ||
| import { StandardRequest, StandardResponse, EventMeta } from '@orpc/standard-server'; | ||
| import { StandardRequest, EventMeta, StandardResponse, StandardBody, StandardHeaders } from '@orpc/standard-server'; | ||
@@ -9,2 +9,91 @@ type EncodedMessage = string | ArrayBufferLike | Uint8Array; | ||
| declare enum MessageType { | ||
| REQUEST = 1, | ||
| RESPONSE = 2, | ||
| EVENT_ITERATOR = 3, | ||
| ABORT_SIGNAL = 4 | ||
| } | ||
| type EventIteratorEvent = 'message' | 'error' | 'done'; | ||
| interface EventIteratorPayload { | ||
| event: EventIteratorEvent; | ||
| data: unknown; | ||
| meta?: EventMeta; | ||
| } | ||
| interface RequestMessageMap { | ||
| [MessageType.REQUEST]: Omit<StandardRequest, 'signal'>; | ||
| [MessageType.EVENT_ITERATOR]: EventIteratorPayload; | ||
| [MessageType.ABORT_SIGNAL]: void; | ||
| } | ||
| interface ResponseMessageMap { | ||
| [MessageType.RESPONSE]: StandardResponse; | ||
| [MessageType.EVENT_ITERATOR]: EventIteratorPayload; | ||
| [MessageType.ABORT_SIGNAL]: void; | ||
| } | ||
| interface BaseMessageFormat<P = unknown> { | ||
| /** | ||
| * Client-guaranteed unique identifier | ||
| */ | ||
| i: string; | ||
| /** | ||
| * @default REQUEST | RESPONSE | ||
| */ | ||
| t?: MessageType; | ||
| p: P; | ||
| } | ||
| interface SerializedEventIteratorPayload { | ||
| e: EventIteratorEvent; | ||
| d: unknown; | ||
| m?: EventMeta; | ||
| } | ||
| interface SerializedRequestPayload { | ||
| /** | ||
| * The url of the request | ||
| * | ||
| * might be relative path if origin is `http://orpc` | ||
| */ | ||
| u: string; | ||
| b: StandardBody; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| h?: StandardHeaders; | ||
| /** | ||
| * @default POST | ||
| */ | ||
| m?: string; | ||
| } | ||
| interface SerializedResponsePayload { | ||
| /** | ||
| * @default 200 | ||
| */ | ||
| s?: number; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| h?: StandardHeaders; | ||
| b: StandardBody; | ||
| } | ||
| type DecodedMessageUnion<TMap extends RequestMessageMap | ResponseMessageMap> = { | ||
| [K in keyof TMap]: [id: string, type: K, payload: TMap[K]]; | ||
| }[keyof TMap]; | ||
| type DecodedRequestMessage = DecodedMessageUnion<RequestMessageMap>; | ||
| type DecodedResponseMessage = DecodedMessageUnion<ResponseMessageMap>; | ||
| /** | ||
| * New serialization functions without Blob handling | ||
| */ | ||
| declare function serializeRequestMessage<T extends keyof RequestMessageMap>(id: string, type: T, payload: RequestMessageMap[T]): BaseMessageFormat; | ||
| declare function deserializeRequestMessage(message: BaseMessageFormat): DecodedRequestMessage; | ||
| declare function serializeResponseMessage<T extends keyof ResponseMessageMap>(id: string, type: T, payload: ResponseMessageMap[T]): BaseMessageFormat; | ||
| declare function deserializeResponseMessage(message: BaseMessageFormat): DecodedResponseMessage; | ||
| /** | ||
| * Original encode/decode functions now using the new serialize/deserialize functions | ||
| */ | ||
| declare function encodeRequestMessage<T extends keyof RequestMessageMap>(id: string, type: T, payload: RequestMessageMap[T]): Promise<EncodedMessage>; | ||
| declare function decodeRequestMessage(raw: EncodedMessage): Promise<DecodedRequestMessage>; | ||
| declare function encodeResponseMessage<T extends keyof ResponseMessageMap>(id: string, type: T, payload: ResponseMessageMap[T]): Promise<EncodedMessage>; | ||
| declare function decodeResponseMessage(raw: EncodedMessage): Promise<DecodedResponseMessage>; | ||
| interface experimental_RequestMessageSendFn { | ||
| (message: DecodedRequestMessage): Promisable<void>; | ||
| } | ||
| interface ClientPeerCloseOptions extends AsyncIdQueueCloseOptions$1 { | ||
@@ -19,2 +108,11 @@ /** | ||
| declare class ClientPeer { | ||
| private readonly peer; | ||
| constructor(send: EncodedMessageSendFn); | ||
| get length(): number; | ||
| open(id: string): AbortController; | ||
| request(request: StandardRequest): Promise<StandardResponse>; | ||
| message(raw: EncodedMessage): Promise<void>; | ||
| close(options?: AsyncIdQueueCloseOptions$1): void; | ||
| } | ||
| declare class experimental_ClientPeerWithoutCodec { | ||
| private readonly idGenerator; | ||
@@ -38,42 +136,10 @@ /** | ||
| private readonly send; | ||
| constructor(send: EncodedMessageSendFn); | ||
| constructor(send: experimental_RequestMessageSendFn); | ||
| get length(): number; | ||
| open(id: string): AbortController; | ||
| request(request: StandardRequest): Promise<StandardResponse>; | ||
| message(raw: EncodedMessage): Promise<void>; | ||
| message([id, type, payload]: DecodedResponseMessage): Promise<void>; | ||
| close(options?: AsyncIdQueueCloseOptions$1): void; | ||
| } | ||
| declare enum MessageType { | ||
| REQUEST = 1, | ||
| RESPONSE = 2, | ||
| EVENT_ITERATOR = 3, | ||
| ABORT_SIGNAL = 4 | ||
| } | ||
| type EventIteratorEvent = 'message' | 'error' | 'done'; | ||
| interface EventIteratorPayload { | ||
| event: EventIteratorEvent; | ||
| data: unknown; | ||
| meta?: EventMeta; | ||
| } | ||
| interface RequestMessageMap { | ||
| [MessageType.REQUEST]: Omit<StandardRequest, 'signal'>; | ||
| [MessageType.EVENT_ITERATOR]: EventIteratorPayload; | ||
| [MessageType.ABORT_SIGNAL]: void; | ||
| } | ||
| interface ResponseMessageMap { | ||
| [MessageType.RESPONSE]: StandardResponse; | ||
| [MessageType.EVENT_ITERATOR]: EventIteratorPayload; | ||
| [MessageType.ABORT_SIGNAL]: void; | ||
| } | ||
| type DecodedMessageUnion<TMap extends RequestMessageMap | ResponseMessageMap> = { | ||
| [K in keyof TMap]: [id: string, type: K, payload: TMap[K]]; | ||
| }[keyof TMap]; | ||
| type DecodedRequestMessage = DecodedMessageUnion<RequestMessageMap>; | ||
| type DecodedResponseMessage = DecodedMessageUnion<ResponseMessageMap>; | ||
| declare function encodeRequestMessage<T extends keyof RequestMessageMap>(id: string, type: T, payload: RequestMessageMap[T]): Promise<EncodedMessage>; | ||
| declare function decodeRequestMessage(raw: EncodedMessage): Promise<DecodedRequestMessage>; | ||
| declare function encodeResponseMessage<T extends keyof ResponseMessageMap>(id: string, type: T, payload: ResponseMessageMap[T]): Promise<EncodedMessage>; | ||
| declare function decodeResponseMessage(raw: EncodedMessage): Promise<DecodedResponseMessage>; | ||
| interface AsyncIdQueueCloseOptions { | ||
@@ -103,2 +169,5 @@ id?: string; | ||
| interface experimental_ResponseMessageSendFn { | ||
| (message: DecodedResponseMessage): Promisable<void>; | ||
| } | ||
| interface ServerPeerHandleRequestFn { | ||
@@ -116,3 +185,18 @@ (request: StandardRequest): Promise<StandardResponse>; | ||
| declare class ServerPeer { | ||
| private readonly peer; | ||
| constructor(send: EncodedMessageSendFn); | ||
| get length(): number; | ||
| open(id: string): AbortController; | ||
| /** | ||
| * @todo This method will return Promise<void> in the next major version. | ||
| */ | ||
| message(raw: EncodedMessage, handleRequest?: ServerPeerHandleRequestFn): Promise<[id: string, StandardRequest | undefined]>; | ||
| /** | ||
| * @deprecated Please pass the `handleRequest` (second arg) function to the `message` method instead. | ||
| */ | ||
| response(id: string, response: StandardResponse): Promise<void>; | ||
| close({ abort, ...options }?: ServerPeerCloseOptions): void; | ||
| } | ||
| declare class experimental_ServerPeerWithoutCodec { | ||
| /** | ||
| * Queue of event iterator messages sent from client, awaiting consumption | ||
@@ -126,3 +210,3 @@ */ | ||
| private readonly send; | ||
| constructor(send: EncodedMessageSendFn); | ||
| constructor(send: experimental_ResponseMessageSendFn); | ||
| get length(): number; | ||
@@ -133,3 +217,3 @@ open(id: string): AbortController; | ||
| */ | ||
| message(raw: EncodedMessage, handleRequest?: ServerPeerHandleRequestFn): Promise<[id: string, StandardRequest | undefined]>; | ||
| message([id, type, payload]: DecodedRequestMessage, handleRequest?: ServerPeerHandleRequestFn): Promise<[id: string, StandardRequest | undefined]>; | ||
| /** | ||
@@ -142,3 +226,3 @@ * @deprecated Please pass the `handleRequest` (second arg) function to the `message` method instead. | ||
| export { ClientPeer, MessageType, ServerPeer, decodeRequestMessage, decodeResponseMessage, encodeRequestMessage, encodeResponseMessage, resolveEventIterator, toEventIterator }; | ||
| export type { ClientPeerCloseOptions, DecodedRequestMessage, DecodedResponseMessage, EncodedMessage, EncodedMessageSendFn, EventIteratorEvent, EventIteratorPayload, RequestMessageMap, ResponseMessageMap, ServerPeerCloseOptions, ServerPeerHandleRequestFn, ToEventIteratorOptions }; | ||
| export { ClientPeer, MessageType, ServerPeer, decodeRequestMessage, decodeResponseMessage, deserializeRequestMessage, deserializeResponseMessage, encodeRequestMessage, encodeResponseMessage, experimental_ClientPeerWithoutCodec, experimental_ServerPeerWithoutCodec, resolveEventIterator, serializeRequestMessage, serializeResponseMessage, toEventIterator }; | ||
| export type { BaseMessageFormat, ClientPeerCloseOptions, DecodedMessageUnion, DecodedRequestMessage, DecodedResponseMessage, EncodedMessage, EncodedMessageSendFn, EventIteratorEvent, EventIteratorPayload, RequestMessageMap, ResponseMessageMap, SerializedEventIteratorPayload, SerializedRequestPayload, SerializedResponsePayload, ServerPeerCloseOptions, ServerPeerHandleRequestFn, ToEventIteratorOptions, experimental_RequestMessageSendFn, experimental_ResponseMessageSendFn }; |
+158
-61
| import { isAsyncIteratorObject, stringifyJSON, readAsBuffer, AsyncIteratorClass, startSpan, runInSpanContext, isTypescriptObject, setSpanError, runWithSpan, SequentialIdGenerator, AsyncIdQueue, getGlobalOtelConfig, clone, AbortError } from '@orpc/shared'; | ||
| import { generateContentDisposition, flattenHeader, getFilenameFromContentDisposition, withEventMeta, ErrorEvent, getEventMeta, isEventIteratorHeaders, HibernationEventIterator } from '@orpc/standard-server'; | ||
| const SHORTABLE_ORIGIN = "orpc://localhost"; | ||
| const SHORTABLE_ORIGIN_MATCHER = /^orpc:\/\/localhost\//; | ||
| const SHORTABLE_ORIGIN = "http://orpc"; | ||
| const SHORTABLE_ORIGIN_MATCHER = /^http:\/\/orpc\//; | ||
| var MessageType = /* @__PURE__ */ ((MessageType2) => { | ||
@@ -13,3 +13,3 @@ MessageType2[MessageType2["REQUEST"] = 1] = "REQUEST"; | ||
| })(MessageType || {}); | ||
| async function encodeRequestMessage(id, type, payload) { | ||
| function serializeRequestMessage(id, type, payload) { | ||
| if (type === 3 /* EVENT_ITERATOR */) { | ||
@@ -22,31 +22,22 @@ const eventPayload = payload; | ||
| }; | ||
| return encodeRawMessage({ i: id, t: type, p: serializedPayload2 }); | ||
| return { i: id, t: type, p: serializedPayload2 }; | ||
| } | ||
| if (type === 4 /* ABORT_SIGNAL */) { | ||
| return encodeRawMessage({ i: id, t: type, p: payload }); | ||
| return { i: id, t: type, p: payload }; | ||
| } | ||
| const request = payload; | ||
| const { body: processedBody, headers: processedHeaders } = await serializeBodyAndHeaders( | ||
| request.body, | ||
| request.headers | ||
| ); | ||
| const serializedPayload = { | ||
| u: request.url.toString().replace(SHORTABLE_ORIGIN_MATCHER, "/"), | ||
| b: processedBody instanceof Blob ? void 0 : processedBody, | ||
| h: Object.keys(processedHeaders).length > 0 ? processedHeaders : void 0, | ||
| b: request.body, | ||
| h: Object.keys(request.headers).length > 0 ? request.headers : void 0, | ||
| m: request.method === "POST" ? void 0 : request.method | ||
| }; | ||
| const baseMessage = { | ||
| return { | ||
| i: id, | ||
| p: serializedPayload | ||
| }; | ||
| if (processedBody instanceof Blob) { | ||
| return encodeRawMessage(baseMessage, processedBody); | ||
| } | ||
| return encodeRawMessage(baseMessage); | ||
| } | ||
| async function decodeRequestMessage(raw) { | ||
| const { json: message, buffer } = await decodeRawMessage(raw); | ||
| function deserializeRequestMessage(message) { | ||
| const id = message.i; | ||
| const type = message.t; | ||
| const type = message.t ?? 1 /* REQUEST */; | ||
| if (type === 3 /* EVENT_ITERATOR */) { | ||
@@ -60,12 +51,10 @@ const payload2 = message.p; | ||
| const payload = message.p; | ||
| const headers = payload.h ?? {}; | ||
| const body = await deserializeBody(headers, payload.b, buffer); | ||
| return [id, 1 /* REQUEST */, { | ||
| url: payload.u.startsWith("/") ? new URL(`${SHORTABLE_ORIGIN}${payload.u}`) : new URL(payload.u), | ||
| headers, | ||
| headers: payload.h ?? {}, | ||
| method: payload.m ?? "POST", | ||
| body | ||
| body: payload.b | ||
| }]; | ||
| } | ||
| async function encodeResponseMessage(id, type, payload) { | ||
| function serializeResponseMessage(id, type, payload) { | ||
| if (type === 3 /* EVENT_ITERATOR */) { | ||
@@ -78,28 +67,19 @@ const eventPayload = payload; | ||
| }; | ||
| return encodeRawMessage({ i: id, t: type, p: serializedPayload2 }); | ||
| return { i: id, t: type, p: serializedPayload2 }; | ||
| } | ||
| if (type === 4 /* ABORT_SIGNAL */) { | ||
| return encodeRawMessage({ i: id, t: type, p: void 0 }); | ||
| return { i: id, t: type, p: void 0 }; | ||
| } | ||
| const response = payload; | ||
| const { body: processedBody, headers: processedHeaders } = await serializeBodyAndHeaders( | ||
| response.body, | ||
| response.headers | ||
| ); | ||
| const serializedPayload = { | ||
| s: response.status === 200 ? void 0 : response.status, | ||
| h: Object.keys(processedHeaders).length > 0 ? processedHeaders : void 0, | ||
| b: processedBody instanceof Blob ? void 0 : processedBody | ||
| h: Object.keys(response.headers).length > 0 ? response.headers : void 0, | ||
| b: response.body | ||
| }; | ||
| const baseMessage = { | ||
| return { | ||
| i: id, | ||
| p: serializedPayload | ||
| }; | ||
| if (processedBody instanceof Blob) { | ||
| return encodeRawMessage(baseMessage, processedBody); | ||
| } | ||
| return encodeRawMessage(baseMessage); | ||
| } | ||
| async function decodeResponseMessage(raw) { | ||
| const { json: message, buffer } = await decodeRawMessage(raw); | ||
| function deserializeResponseMessage(message) { | ||
| const id = message.i; | ||
@@ -115,6 +95,68 @@ const type = message.t; | ||
| const payload = message.p; | ||
| const headers = payload.h ?? {}; | ||
| const body = await deserializeBody(headers, payload.b, buffer); | ||
| return [id, 2 /* RESPONSE */, { status: payload.s ?? 200, headers, body }]; | ||
| return [id, 2 /* RESPONSE */, { | ||
| status: payload.s ?? 200, | ||
| headers: payload.h ?? {}, | ||
| body: payload.b | ||
| }]; | ||
| } | ||
| async function encodeRequestMessage(id, type, payload) { | ||
| if (type === 3 /* EVENT_ITERATOR */ || type === 4 /* ABORT_SIGNAL */) { | ||
| return encodeRawMessage(serializeRequestMessage(id, type, payload)); | ||
| } | ||
| const request = payload; | ||
| const { body: processedBody, headers: processedHeaders } = await serializeBodyAndHeaders( | ||
| request.body, | ||
| request.headers | ||
| ); | ||
| const modifiedRequest = { | ||
| ...request, | ||
| body: processedBody instanceof Blob ? void 0 : processedBody, | ||
| headers: processedHeaders | ||
| }; | ||
| const baseMessage = serializeRequestMessage(id, 1 /* REQUEST */, modifiedRequest); | ||
| if (processedBody instanceof Blob) { | ||
| return encodeRawMessage(baseMessage, processedBody); | ||
| } | ||
| return encodeRawMessage(baseMessage); | ||
| } | ||
| async function decodeRequestMessage(raw) { | ||
| const { json: message, buffer } = await decodeRawMessage(raw); | ||
| const [id, type, payload] = deserializeRequestMessage(message); | ||
| if (type === 3 /* EVENT_ITERATOR */ || type === 4 /* ABORT_SIGNAL */) { | ||
| return [id, type, payload]; | ||
| } | ||
| const request = payload; | ||
| const body = await deserializeBody(request.headers, request.body, buffer); | ||
| return [id, type, { ...request, body }]; | ||
| } | ||
| async function encodeResponseMessage(id, type, payload) { | ||
| if (type === 3 /* EVENT_ITERATOR */ || type === 4 /* ABORT_SIGNAL */) { | ||
| return encodeRawMessage(serializeResponseMessage(id, type, payload)); | ||
| } | ||
| const response = payload; | ||
| const { body: processedBody, headers: processedHeaders } = await serializeBodyAndHeaders( | ||
| response.body, | ||
| response.headers | ||
| ); | ||
| const modifiedResponse = { | ||
| ...response, | ||
| body: processedBody instanceof Blob ? void 0 : processedBody, | ||
| headers: processedHeaders | ||
| }; | ||
| const baseMessage = serializeResponseMessage(id, 2 /* RESPONSE */, modifiedResponse); | ||
| if (processedBody instanceof Blob) { | ||
| return encodeRawMessage(baseMessage, processedBody); | ||
| } | ||
| return encodeRawMessage(baseMessage); | ||
| } | ||
| async function decodeResponseMessage(raw) { | ||
| const { json: message, buffer } = await decodeRawMessage(raw); | ||
| const [id, type, payload] = deserializeResponseMessage(message); | ||
| if (type === 3 /* EVENT_ITERATOR */ || type === 4 /* ABORT_SIGNAL */) { | ||
| return [id, type, payload]; | ||
| } | ||
| const response = payload; | ||
| const body = await deserializeBody(response.headers, response.body, buffer); | ||
| return [id, type, { ...response, body }]; | ||
| } | ||
| async function serializeBodyAndHeaders(body, originalHeaders) { | ||
@@ -309,2 +351,25 @@ const headers = { ...originalHeaders }; | ||
| class ClientPeer { | ||
| peer; | ||
| constructor(send) { | ||
| this.peer = new experimental_ClientPeerWithoutCodec(async ([id, type, payload]) => { | ||
| await send(await encodeRequestMessage(id, type, payload)); | ||
| }); | ||
| } | ||
| get length() { | ||
| return this.peer.length; | ||
| } | ||
| open(id) { | ||
| return this.peer.open(id); | ||
| } | ||
| async request(request) { | ||
| return this.peer.request(request); | ||
| } | ||
| async message(raw) { | ||
| return this.peer.message(await decodeResponseMessage(raw)); | ||
| } | ||
| close(options = {}) { | ||
| return this.peer.close(options); | ||
| } | ||
| } | ||
| class experimental_ClientPeerWithoutCodec { | ||
| idGenerator = new SequentialIdGenerator(); | ||
@@ -329,7 +394,8 @@ /** | ||
| constructor(send) { | ||
| this.send = async (id, ...rest) => encodeRequestMessage(id, ...rest).then(async (raw) => { | ||
| this.send = async (message) => { | ||
| const id = message[0]; | ||
| if (this.serverControllers.has(id)) { | ||
| await send(raw); | ||
| await send(message); | ||
| } | ||
| }); | ||
| }; | ||
| } | ||
@@ -364,5 +430,5 @@ get length() { | ||
| } | ||
| await this.send(id, MessageType.REQUEST, request); | ||
| await this.send([id, MessageType.REQUEST, request]); | ||
| if (signal?.aborted) { | ||
| await this.send(id, MessageType.ABORT_SIGNAL, void 0); | ||
| await this.send([id, MessageType.ABORT_SIGNAL, void 0]); | ||
| throw signal.reason; | ||
@@ -372,3 +438,3 @@ } | ||
| signal?.addEventListener("abort", abortListener = async () => { | ||
| await this.send(id, MessageType.ABORT_SIGNAL, void 0); | ||
| await this.send([id, MessageType.ABORT_SIGNAL, void 0]); | ||
| this.close({ id, reason: signal.reason }); | ||
@@ -385,3 +451,3 @@ }, { once: true }); | ||
| } | ||
| await this.send(id, MessageType.EVENT_ITERATOR, payload); | ||
| await this.send([id, MessageType.EVENT_ITERATOR, payload]); | ||
| return "next"; | ||
@@ -398,3 +464,3 @@ }); | ||
| if (reason !== "next") { | ||
| await this.send(id, MessageType.ABORT_SIGNAL, void 0); | ||
| await this.send([id, MessageType.ABORT_SIGNAL, void 0]); | ||
| } | ||
@@ -421,4 +487,3 @@ } finally { | ||
| } | ||
| async message(raw) { | ||
| const [id, type, payload] = await decodeResponseMessage(raw); | ||
| async message([id, type, payload]) { | ||
| if (type === MessageType.ABORT_SIGNAL) { | ||
@@ -457,3 +522,32 @@ this.serverControllers.get(id)?.abort(); | ||
| class ServerPeer { | ||
| peer; | ||
| constructor(send) { | ||
| this.peer = new experimental_ServerPeerWithoutCodec(async ([id, type, payload]) => { | ||
| await send(await encodeResponseMessage(id, type, payload)); | ||
| }); | ||
| } | ||
| get length() { | ||
| return this.peer.length; | ||
| } | ||
| open(id) { | ||
| return this.peer.open(id); | ||
| } | ||
| /** | ||
| * @todo This method will return Promise<void> in the next major version. | ||
| */ | ||
| async message(raw, handleRequest) { | ||
| return this.peer.message(await decodeRequestMessage(raw), handleRequest); | ||
| } | ||
| /** | ||
| * @deprecated Please pass the `handleRequest` (second arg) function to the `message` method instead. | ||
| */ | ||
| async response(id, response) { | ||
| return this.peer.response(id, response); | ||
| } | ||
| close({ abort = true, ...options } = {}) { | ||
| return this.peer.close({ ...options, abort }); | ||
| } | ||
| } | ||
| class experimental_ServerPeerWithoutCodec { | ||
| /** | ||
| * Queue of event iterator messages sent from client, awaiting consumption | ||
@@ -468,7 +562,8 @@ */ | ||
| constructor(send) { | ||
| this.send = (id, ...rest) => encodeResponseMessage(id, ...rest).then(async (raw) => { | ||
| this.send = async (message) => { | ||
| const id = message[0]; | ||
| if (this.clientControllers.has(id)) { | ||
| await send(raw); | ||
| await send(message); | ||
| } | ||
| }); | ||
| }; | ||
| } | ||
@@ -487,4 +582,3 @@ get length() { | ||
| */ | ||
| async message(raw, handleRequest) { | ||
| const [id, type, payload] = await decodeRequestMessage(raw); | ||
| async message([id, type, payload], handleRequest) { | ||
| if (type === MessageType.ABORT_SIGNAL) { | ||
@@ -500,2 +594,5 @@ this.close({ id, reason: new AbortError("Client aborted the request") }); | ||
| } | ||
| if (this.clientControllers.has(id)) { | ||
| return [id, void 0]; | ||
| } | ||
| const clientController = this.open(id); | ||
@@ -511,3 +608,3 @@ const signal = clientController.signal; | ||
| if (reason !== "next") { | ||
| await this.send(id, MessageType.ABORT_SIGNAL, void 0); | ||
| await this.send([id, MessageType.ABORT_SIGNAL, void 0]); | ||
| } | ||
@@ -556,3 +653,3 @@ }, | ||
| try { | ||
| await this.send(id, MessageType.RESPONSE, response); | ||
| await this.send([id, MessageType.RESPONSE, response]); | ||
| if (!signal.aborted && isAsyncIteratorObject(response.body)) { | ||
@@ -567,3 +664,3 @@ if (response.body instanceof HibernationEventIterator) { | ||
| } | ||
| await this.send(id, MessageType.EVENT_ITERATOR, payload); | ||
| await this.send([id, MessageType.EVENT_ITERATOR, payload]); | ||
| return "next"; | ||
@@ -595,2 +692,2 @@ }); | ||
| export { ClientPeer, MessageType, ServerPeer, decodeRequestMessage, decodeResponseMessage, encodeRequestMessage, encodeResponseMessage, resolveEventIterator, toEventIterator }; | ||
| export { ClientPeer, MessageType, ServerPeer, decodeRequestMessage, decodeResponseMessage, deserializeRequestMessage, deserializeResponseMessage, encodeRequestMessage, encodeResponseMessage, experimental_ClientPeerWithoutCodec, experimental_ServerPeerWithoutCodec, resolveEventIterator, serializeRequestMessage, serializeResponseMessage, toEventIterator }; |
+6
-5
| { | ||
| "name": "@orpc/standard-server-peer", | ||
| "type": "module", | ||
| "version": "0.0.0-next.4748dc5", | ||
| "version": "0.0.0-next.47dbd93", | ||
| "license": "MIT", | ||
| "homepage": "https://unnoq.com", | ||
| "homepage": "https://orpc.com", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/unnoq/orpc.git", | ||
| "url": "git+https://github.com/middleapi/orpc.git", | ||
| "directory": "packages/standard-server-peer" | ||
@@ -15,2 +15,3 @@ }, | ||
| ], | ||
| "sideEffects": false, | ||
| "exports": { | ||
@@ -27,4 +28,4 @@ ".": { | ||
| "dependencies": { | ||
| "@orpc/shared": "0.0.0-next.4748dc5", | ||
| "@orpc/standard-server": "0.0.0-next.4748dc5" | ||
| "@orpc/shared": "0.0.0-next.47dbd93", | ||
| "@orpc/standard-server": "0.0.0-next.47dbd93" | ||
| }, | ||
@@ -31,0 +32,0 @@ "scripts": { |
+131
-12
| <div align="center"> | ||
| <image align="center" src="https://orpc.unnoq.com/logo.webp" width=280 alt="oRPC logo" /> | ||
| <image align="center" src="https://orpc.dev/logo.webp" width=280 alt="oRPC logo" /> | ||
| </div> | ||
@@ -8,4 +8,4 @@ | ||
| <div align="center"> | ||
| <a href="https://codecov.io/gh/unnoq/orpc"> | ||
| <img alt="codecov" src="https://codecov.io/gh/unnoq/orpc/branch/main/graph/badge.svg"> | ||
| <a href="https://codecov.io/gh/middleapi/orpc"> | ||
| <img alt="codecov" src="https://codecov.io/gh/middleapi/orpc/branch/main/graph/badge.svg"> | ||
| </a> | ||
@@ -15,4 +15,4 @@ <a href="https://www.npmjs.com/package/@orpc/standard-server-peer"> | ||
| </a> | ||
| <a href="https://github.com/unnoq/orpc/blob/main/LICENSE"> | ||
| <img alt="MIT License" src="https://img.shields.io/github/license/unnoq/orpc?logo=open-source-initiative" /> | ||
| <a href="https://github.com/middleapi/orpc/blob/main/LICENSE"> | ||
| <img alt="MIT License" src="https://img.shields.io/github/license/middleapi/orpc?logo=open-source-initiative" /> | ||
| </a> | ||
@@ -22,3 +22,3 @@ <a href="https://discord.gg/TXEbwRBvQn"> | ||
| </a> | ||
| <a href="https://deepwiki.com/unnoq/orpc"> | ||
| <a href="https://deepwiki.com/middleapi/orpc"> | ||
| <img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"> | ||
@@ -51,3 +51,3 @@ </a> | ||
| You can find the full documentation [here](https://orpc.unnoq.com). | ||
| You can find the full documentation [here](https://orpc.dev). | ||
@@ -77,6 +77,125 @@ ## Packages | ||
| <p align="center"> | ||
| <a href="https://cdn.jsdelivr.net/gh/unnoq/unnoq/sponsors.svg"> | ||
| <img src='https://cdn.jsdelivr.net/gh/unnoq/unnoq/sponsors.svg'/> | ||
| </a> | ||
| If you find oRPC valuable and would like to support its development, you can do so here: [GitHub Sponsors](https://github.com/sponsors/dinwwwh). | ||
| ### π Platinum Sponsor | ||
| <table> | ||
| <tr> | ||
| <td align="center"><a href="https://screenshotone.com/?ref=orpc" target="_blank" rel="noopener" title="ScreenshotOne.com"><img src="https://avatars.githubusercontent.com/u/97035603?v=4" width="279" alt="ScreenshotOne.com"/><br />ScreenshotOne.com</a></td> | ||
| </tr> | ||
| </table> | ||
| ### π₯ Silver Sponsor | ||
| <table> | ||
| <tr> | ||
| <td align="center"><a href="https://misskey.io/?ref=orpc" target="_blank" rel="noopener" title="ζδΈγγ"><img src="https://avatars.githubusercontent.com/u/37681609?u=0dd4c7e4ba937cbb52b068c55914b1d8164dc0c7&v=4" width="209" alt="ζδΈγγ"/><br />ζδΈγγ</a></td> | ||
| </tr> | ||
| </table> | ||
| ### π₯ Bronze Sponsor | ||
| <table> | ||
| <tr> | ||
| <td align="center"><a href="https://plancraft.com/?ref=orpc" target="_blank" rel="noopener" title="plancraft"><img src="https://avatars.githubusercontent.com/u/46482287?v=4" width="167" alt="plancraft"/><br />plancraft</a></td> | ||
| </tr> | ||
| </table> | ||
| ### Generous Sponsors | ||
| <table> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/ln-markets?ref=orpc" target="_blank" rel="noopener" title="LN Markets"><img src="https://avatars.githubusercontent.com/u/70597625?v=4" width="139" alt="LN Markets"/><br />LN Markets</a></td> | ||
| </tr> | ||
| </table> | ||
| ### Sponsors | ||
| <table> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/hrmcdonald?ref=orpc" target="_blank" rel="noopener" title="Reece McDonald"><img src="https://avatars.githubusercontent.com/u/39349270?v=4" width="119" alt="Reece McDonald"/><br />Reece McDonald</a></td> | ||
| <td align="center"><a href="https://github.com/nicognaW?ref=orpc" target="_blank" rel="noopener" title="nk"><img src="https://avatars.githubusercontent.com/u/66731869?u=4699bda3a9092d3ec34fbd959450767bcc8b8b6d&v=4" width="119" alt="nk"/><br />nk</a></td> | ||
| <td align="center"><a href="https://github.com/supastarter?ref=orpc" target="_blank" rel="noopener" title="supastarter"><img src="https://avatars.githubusercontent.com/u/110960143?v=4" width="119" alt="supastarter"/><br />supastarter</a></td> | ||
| <td align="center"><a href="https://github.com/divmgl?ref=orpc" target="_blank" rel="noopener" title="Dexter Miguel"><img src="https://avatars.githubusercontent.com/u/5452298?u=645993204be8696c085ecf0d228c3062efe2ed65&v=4" width="119" alt="Dexter Miguel"/><br />Dexter Miguel</a></td> | ||
| <td align="center"><a href="https://github.com/herrfugbaum?ref=orpc" target="_blank" rel="noopener" title="herrfugbaum"><img src="https://avatars.githubusercontent.com/u/12859776?u=644dc1666d0220bc0468eb0de3c56b919f635b16&v=4" width="119" alt="herrfugbaum"/><br />herrfugbaum</a></td> | ||
| <td align="center"><a href="https://github.com/ryota-murakami?ref=orpc" target="_blank" rel="noopener" title="Ryota Murakami"><img src="https://avatars.githubusercontent.com/u/5501268?u=599389e03340734325726ca3f8f423c021d47d7f&v=4" width="119" alt="Ryota Murakami"/><br />Ryota Murakami</a></td> | ||
| <td align="center"><a href="https://github.com/dcramer?ref=orpc" target="_blank" rel="noopener" title="David Cramer"><img src="https://avatars.githubusercontent.com/u/23610?v=4" width="119" alt="David Cramer"/><br />David Cramer</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/valerii15298?ref=orpc" target="_blank" rel="noopener" title="Valerii Petryniak"><img src="https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&v=4" width="119" alt="Valerii Petryniak"/><br />Valerii Petryniak</a></td> | ||
| <td align="center"><a href="https://github.com/letstri?ref=orpc" target="_blank" rel="noopener" title="Valerii Strilets"><img src="https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&v=4" width="119" alt="Valerii Strilets"/><br />Valerii Strilets</a></td> | ||
| <td align="center"><a href="https://github.com/K-Mistele?ref=orpc" target="_blank" rel="noopener" title="Kyle Mistele"><img src="https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&v=4" width="119" alt="Kyle Mistele"/><br />Kyle Mistele</a></td> | ||
| <td align="center"><a href="https://github.com/andrewpeters9?ref=orpc" target="_blank" rel="noopener" title="Andrew Peters"><img src="https://avatars.githubusercontent.com/u/36251325?v=4" width="119" alt="Andrew Peters"/><br />Andrew Peters</a></td> | ||
| <td align="center"><a href="https://github.com/R44VC0RP?ref=orpc" target="_blank" rel="noopener" title="Ryan Vogel"><img src="https://avatars.githubusercontent.com/u/89211796?u=1857347b9787d8d8a7ea5bfc333f96be92d5a683&v=4" width="119" alt="Ryan Vogel"/><br />Ryan Vogel</a></td> | ||
| <td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="119" alt="christ12938"/><br />christ12938</a></td> | ||
| <td align="center"><a href="https://github.com/peter-adam-dy?ref=orpc" target="_blank" rel="noopener" title="Peter Adam"><img src="https://avatars.githubusercontent.com/u/132129459?u=4f3dbbb3b443990b56acb7d6a5d11ed2c555f6db&v=4" width="119" alt="Peter Adam"/><br />Peter Adam</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&v=4" width="119" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td> | ||
| <td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&v=4" width="119" alt="shota"/><br />shota</a></td> | ||
| </tr> | ||
| </table> | ||
| ### Backers | ||
| <table> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/rhinodavid?ref=orpc" target="_blank" rel="noopener" title="David Walsh"><img src="https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&v=4" width="104" alt="David Walsh"/><br />David Walsh</a></td> | ||
| <td align="center"><a href="https://github.com/ChromeGG?ref=orpc" target="_blank" rel="noopener" title="Adam Tkaczyk"><img src="https://avatars.githubusercontent.com/u/39050595?u=a58ca6042a6950e94e6e92442db76ef584279bc0&v=4" width="104" alt="Adam Tkaczyk"/><br />Adam Tkaczyk</a></td> | ||
| <td align="center"><a href="https://github.com/Robbe95?ref=orpc" target="_blank" rel="noopener" title="Robbe Vaes"><img src="https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&v=4" width="104" alt="Robbe Vaes"/><br />Robbe Vaes</a></td> | ||
| <td align="center"><a href="https://github.com/aidansunbury?ref=orpc" target="_blank" rel="noopener" title="Aidan Sunbury"><img src="https://avatars.githubusercontent.com/u/64103161?v=4" width="104" alt="Aidan Sunbury"/><br />Aidan Sunbury</a></td> | ||
| <td align="center"><a href="https://github.com/soonoo?ref=orpc" target="_blank" rel="noopener" title="soonoo"><img src="https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&v=4" width="104" alt="soonoo"/><br />soonoo</a></td> | ||
| <td align="center"><a href="https://github.com/kporten?ref=orpc" target="_blank" rel="noopener" title="Kevin Porten"><img src="https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&v=4" width="104" alt="Kevin Porten"/><br />Kevin Porten</a></td> | ||
| <td align="center"><a href="https://github.com/pumpkinlink?ref=orpc" target="_blank" rel="noopener" title="Denis"><img src="https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&v=4" width="104" alt="Denis"/><br />Denis</a></td> | ||
| <td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&v=4" width="104" alt="Christopher Kapic"/><br />Christopher Kapic</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/thomasballinger?ref=orpc" target="_blank" rel="noopener" title="Tom Ballinger"><img src="https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&v=4" width="104" alt="Tom Ballinger"/><br />Tom Ballinger</a></td> | ||
| <td align="center"><a href="https://github.com/SSam0419?ref=orpc" target="_blank" rel="noopener" title="Sam"><img src="https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&v=4" width="104" alt="Sam"/><br />Sam</a></td> | ||
| <td align="center"><a href="https://github.com/Titoine?ref=orpc" target="_blank" rel="noopener" title="Titoine"><img src="https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&v=4" width="104" alt="Titoine"/><br />Titoine</a></td> | ||
| <td align="center"><a href="https://github.com/Mnigos?ref=orpc" target="_blank" rel="noopener" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&v=4" width="104" alt="Igor Makowski"/><br />Igor Makowski</a></td> | ||
| <td align="center"><a href="https://github.com/steelbrain?ref=orpc" target="_blank" rel="noopener" title="Anees Iqbal"><img src="https://avatars.githubusercontent.com/u/4278113?u=22b80b5399eed68ac76cd58b02961b0481f1db11&v=4" width="104" alt="Anees Iqbal"/><br />Anees Iqbal</a></td> | ||
| <td align="center"><a href="https://github.com/hanayashiki?ref=orpc" target="_blank" rel="noopener" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&v=4" width="104" alt="hanayashiki"/><br />hanayashiki</a></td> | ||
| <td align="center"><a href="https://github.com/ldub?ref=orpc" target="_blank" rel="noopener" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&v=4" width="104" alt="Lev Dubinets"/><br />Lev Dubinets</a></td> | ||
| <td align="center"><a href="https://github.com/piscis?ref=orpc" target="_blank" rel="noopener" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&v=4" width="104" alt="Alex"/><br />Alex</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/nattstack?ref=orpc" target="_blank" rel="noopener" title="nattstack"><img src="https://avatars.githubusercontent.com/u/31426677?u=fa9dbb8b3e66eb0ea3c88db5dc07f31c8c5418fe&v=4" width="104" alt="nattstack"/><br />nattstack</a></td> | ||
| <td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=29e91400dbd4a9c217048a8f59562c4f740498e6&v=4" width="104" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td> | ||
| </tr> | ||
| </table> | ||
| ### Past Sponsors | ||
| <p> | ||
| <a href="https://github.com/MrMaxie?ref=orpc" target="_blank" rel="noopener" title="Maxie"><img src="https://avatars.githubusercontent.com/u/3857836?u=5e6b57973d4385d655663ffdd836e487856f2984&v=4" width="32" height="32" alt="Maxie" /></a> | ||
| <a href="https://github.com/Stijn-Timmer?ref=orpc" target="_blank" rel="noopener" title="Stijn Timmer"><img src="https://avatars.githubusercontent.com/u/100147665?u=106b2c18e9c98a61861b4ee7fc100f5b9906a6c9&v=4" width="32" height="32" alt="Stijn Timmer" /></a> | ||
| <a href="https://github.com/u1-liquid?ref=orpc" target="_blank" rel="noopener" title="γγγγγ¨γΌγ«γ "><img src="https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&v=4" width="32" height="32" alt="γγγγγ¨γΌγ«γ " /></a> | ||
| <a href="https://github.com/zuplo?ref=orpc" target="_blank" rel="noopener" title="Zuplo"><img src="https://avatars.githubusercontent.com/u/85497839?v=4" width="32" height="32" alt="Zuplo" /></a> | ||
| <a href="https://github.com/motopods?ref=orpc" target="_blank" rel="noopener" title="motopods"><img src="https://avatars.githubusercontent.com/u/58200641?v=4" width="32" height="32" alt="motopods" /></a> | ||
| <a href="https://github.com/franciscohermida?ref=orpc" target="_blank" rel="noopener" title="Francisco Hermida"><img src="https://avatars.githubusercontent.com/u/483242?u=bbcbc80eb9d8781ff401f7dafc3b59cd7bea0561&v=4" width="32" height="32" alt="Francisco Hermida" /></a> | ||
| <a href="https://github.com/theoludwig?ref=orpc" target="_blank" rel="noopener" title="ThΓ©o LUDWIG"><img src="https://avatars.githubusercontent.com/u/25207499?u=a6a9653725a2f574c07893748806668e0598cdbe&v=4" width="32" height="32" alt="ThΓ©o LUDWIG" /></a> | ||
| <a href="https://github.com/abhay-ramesh?ref=orpc" target="_blank" rel="noopener" title="Abhay Ramesh"><img src="https://avatars.githubusercontent.com/u/66196314?u=c5c2b0327b26606c2efcfaf17046ab18c3d25c57&v=4" width="32" height="32" alt="Abhay Ramesh" /></a> | ||
| <a href="https://github.com/shr-ink?ref=orpc" target="_blank" rel="noopener" title="shr.ink oΓΌ"><img src="https://avatars.githubusercontent.com/u/139700438?v=4" width="32" height="32" alt="shr.ink oΓΌ" /></a> | ||
| <a href="https://github.com/johngerome?ref=orpc" target="_blank" rel="noopener" title="0x4e32"><img src="https://avatars.githubusercontent.com/u/2002000?u=24e8dd943cfc862aa284d858a023532c75071ade&v=4" width="32" height="32" alt="0x4e32" /></a> | ||
| <a href="https://github.com/yzuyr?ref=orpc" target="_blank" rel="noopener" title="Ryuz"><img src="https://avatars.githubusercontent.com/u/196539378?u=d38374588d219b6748b16406982f6559411466d4&v=4" width="32" height="32" alt="Ryuz" /></a> | ||
| <a href="https://github.com/happyboy2022?ref=orpc" target="_blank" rel="noopener" title="happyboy"><img src="https://avatars.githubusercontent.com/u/103669586?u=65b49c4b893ed3703909fbb3a7a22313f3f9c121&v=4" width="32" height="32" alt="happyboy" /></a> | ||
| <a href="https://github.com/YiCChi?ref=orpc" target="_blank" rel="noopener" title="yicchi"><img src="https://avatars.githubusercontent.com/u/86967274?u=6c2756f09fe15dd94d572f560e979cd157982852&v=4" width="32" height="32" alt="yicchi" /></a> | ||
| <a href="https://github.com/cloudycotton?ref=orpc" target="_blank" rel="noopener" title="Saksham"><img src="https://avatars.githubusercontent.com/u/168998965?u=9b9634a5aed66a51c1b880663272725b00b92b14&v=4" width="32" height="32" alt="Saksham" /></a> | ||
| <a href="https://github.com/hrynevychroman?ref=orpc" target="_blank" rel="noopener" title="Roman Hrynevych"><img src="https://avatars.githubusercontent.com/u/82209198?u=1a1d111ab3d589855b9cc8a7fefb1b5c6a4fbbaf&v=4" width="32" height="32" alt="Roman Hrynevych" /></a> | ||
| <a href="https://github.com/rokitgg?ref=orpc" target="_blank" rel="noopener" title="rokitg"><img src="https://avatars.githubusercontent.com/u/125133357?u=06c74aefaa2236b06a2e5fba5a5c612339f45912&v=4" width="32" height="32" alt="rokitg" /></a> | ||
| <a href="https://github.com/omarkhatibgg?ref=orpc" target="_blank" rel="noopener" title="Omar Khatib"><img src="https://avatars.githubusercontent.com/u/9054278?u=afbba7331b85c51b8eee4130f5fd31b1017dc919&v=4" width="32" height="32" alt="Omar Khatib" /></a> | ||
| <a href="https://github.com/YuSabo90002?ref=orpc" target="_blank" rel="noopener" title="Yu-Sabo"><img src="https://avatars.githubusercontent.com/u/13120582?v=4" width="32" height="32" alt="Yu-Sabo" /></a> | ||
| <a href="https://github.com/bapspatil?ref=orpc" target="_blank" rel="noopener" title="Bapusaheb Patil"><img src="https://avatars.githubusercontent.com/u/16699418?u=6d9d8e0a64a6f91ca1c4d559c72d931172bdcbbd&v=4" width="32" height="32" alt="Bapusaheb Patil" /></a> | ||
| <a href="https://github.com/ripgrim?ref=orpc" target="_blank" rel="noopener" title="grim"><img src="https://avatars.githubusercontent.com/u/75869731?u=b17c42ec2309552fdb822a86b25a2f99146a4d72&v=4" width="32" height="32" alt="grim" /></a> | ||
| <a href="https://github.com/nelsonlaidev?ref=orpc" target="_blank" rel="noopener" title="Nelson Lai"><img src="https://avatars.githubusercontent.com/u/75498339?u=2fc0e0b95dd184c5ffb744df977cb15a18b60672&v=4" width="32" height="32" alt="Nelson Lai" /></a> | ||
| <a href="https://github.com/nguyenlc1993?ref=orpc" target="_blank" rel="noopener" title="LΓͺ Cao NguyΓͺn"><img src="https://avatars.githubusercontent.com/u/13871971?u=83c8b69d9e35b589c4e1f066cc113b1d9461386f&v=4" width="32" height="32" alt="LΓͺ Cao NguyΓͺn" /></a> | ||
| <a href="https://github.com/wobsoriano?ref=orpc" target="_blank" rel="noopener" title="Robert Soriano"><img src="https://avatars.githubusercontent.com/u/13049130?u=6d72104182e7c9ed25934815313fb69107332111&v=4" width="32" height="32" alt="Robert Soriano" /></a> | ||
| <a href="https://github.com/SKostyukovich?ref=orpc" target="_blank" rel="noopener" title="SKostyukovich"><img src="https://avatars.githubusercontent.com/u/10700067?v=4" width="32" height="32" alt="SKostyukovich" /></a> | ||
| <a href="https://github.com/FabworksHQ?ref=orpc" target="_blank" rel="noopener" title="Fabworks"><img src="https://avatars.githubusercontent.com/u/160179500?v=4" width="32" height="32" alt="Fabworks" /></a> | ||
| <a href="https://github.com/NovakAnton?ref=orpc" target="_blank" rel="noopener" title="Novak Antonijevic"><img src="https://avatars.githubusercontent.com/u/157126729?u=ae49fa22292d55c0434ff0ca008206155b18663b&v=4" width="32" height="32" alt="Novak Antonijevic" /></a> | ||
| <a href="https://github.com/laduniestu?ref=orpc" target="_blank" rel="noopener" title="Laduni Estu Syalwa"><img src="https://avatars.githubusercontent.com/u/44757637?u=a2fc1ea8f7d827a96721176f79d30592d1c48059&v=4" width="32" height="32" alt="Laduni Estu Syalwa" /></a> | ||
| <a href="https://github.com/yukimotochern?ref=orpc" target="_blank" rel="noopener" title="Chen, Zhi-Yuan"><img src="https://avatars.githubusercontent.com/u/20896173?u=945c33fc21725e4d566a0d02afc54b136ca1d67a&v=4" width="32" height="32" alt="Chen, Zhi-Yuan" /></a> | ||
| <a href="https://github.com/illarionvk?ref=orpc" target="_blank" rel="noopener" title="Illarion Koperski"><img src="https://avatars.githubusercontent.com/u/5012724?u=7cfa13652f7ac5fb3c56d880e3eb3fbe40c3ea34&v=4" width="32" height="32" alt="Illarion Koperski" /></a> | ||
| <a href="https://github.com/Scrumplex?ref=orpc" target="_blank" rel="noopener" title="Sefa Eyeoglu"><img src="https://avatars.githubusercontent.com/u/11587657?u=ab503582165c0bbff0cca47ce31c9450bb1553c9&v=4" width="32" height="32" alt="Sefa Eyeoglu" /></a> | ||
| </p> | ||
@@ -86,2 +205,2 @@ | ||
| Distributed under the MIT License. See [LICENSE](https://github.com/unnoq/orpc/blob/main/LICENSE) for more information. | ||
| Distributed under the MIT License. See [LICENSE](https://github.com/middleapi/orpc/blob/main/LICENSE) for more information. |
64616
75.36%884
26.11%201
145.12%+ Added
+ Added
- Removed
- Removed