| /** | |
| * Defines schema-backed contracts for individual RPC procedures. | |
| * | |
| * An `Rpc` describes one remote procedure by recording its tag, payload schema, | |
| * success schema, error schema, defect schema, middleware, and annotations. | |
| * Clients and servers read the same declaration, so the procedure contract is | |
| * independent of the transport used to call it. This module includes | |
| * constructors, type helpers for deriving client and handler shapes, exit | |
| * schemas, and handler wrappers for special execution modes. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| import type * as Cause from "../../Cause.ts" | |
| import * as Context from "../../Context.ts" | |
| import type { Deferred } from "../../Deferred.ts" | |
| import type { Effect } from "../../Effect.ts" | |
| import type { Exit as Exit_ } from "../../Exit.ts" | |
| import * as Option from "../../Option.ts" | |
| import { type Pipeable, pipeArguments } from "../../Pipeable.ts" | |
| import * as Predicate from "../../Predicate.ts" | |
| import * as PrimaryKey from "../../PrimaryKey.ts" | |
| import type * as Queue from "../../Queue.ts" | |
| import * as Schema from "../../Schema.ts" | |
| import type { Stream } from "../../Stream.ts" | |
| import type * as Struct from "../../Struct.ts" | |
| import type { NoInfer } from "../../Types.ts" | |
| import type { Headers } from "../http/Headers.ts" | |
| import type { RequestId } from "./RpcMessage.ts" | |
| import type * as RpcMiddleware from "./RpcMiddleware.ts" | |
| import * as RpcSchema from "./RpcSchema.ts" | |
| const TypeId = "~effect/rpc/Rpc" | |
| /** | |
| * Returns `true` when the value is an `Rpc` definition. | |
| * | |
| * @category guards | |
| * @since 4.0.0 | |
| */ | |
| export const isRpc = (u: unknown): u is Rpc<any, any, any> => Predicate.hasProperty(u, TypeId) | |
| /** | |
| * Schema for RPC defects. | |
| * | |
| * **Details** | |
| * | |
| * Defect schemas decode and encode without services and can be constructed from | |
| * `null`, `undefined`, or an object value. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export interface DefectSchema extends Schema.Top { | |
| readonly Type: unknown | |
| make(input: null, options?: Schema.MakeOptions): unknown | |
| make(input: undefined, options?: Schema.MakeOptions): unknown | |
| make(input: {}, options?: Schema.MakeOptions): unknown | |
| readonly DecodingServices: never | |
| readonly EncodingServices: never | |
| } | |
| /** | |
| * Represents a typed RPC definition. | |
| * | |
| * **Details** | |
| * | |
| * An RPC is identified by a tag and carries payload, success, error, defect, | |
| * middleware, and annotation metadata used by RPC clients and servers. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export interface Rpc< | |
| in out Tag extends string, | |
| out Payload extends Schema.Top = Schema.Void, | |
| out Success extends Schema.Top = Schema.Void, | |
| out Error extends Schema.Top = Schema.Never, | |
| out Middleware extends RpcMiddleware.AnyService = never, | |
| out Requires = never | |
| > extends Pipeable { | |
| new(_: never): {} | |
| readonly [TypeId]: typeof TypeId | |
| readonly _tag: Tag | |
| readonly key: string | |
| readonly payloadSchema: Payload | |
| readonly successSchema: Success | |
| readonly errorSchema: Error | |
| readonly defectSchema: Schema.Top | |
| readonly annotations: Context.Context<never> | |
| readonly middlewares: ReadonlySet<Middleware> | |
| readonly "~requires": Requires | |
| /** | |
| * Set the schema for the success response of the rpc. | |
| */ | |
| setSuccess<S extends Schema.Top>(schema: S): Rpc< | |
| Tag, | |
| Payload, | |
| S, | |
| Error, | |
| Middleware, | |
| Requires | |
| > | |
| /** | |
| * Set the schema for the error response of the rpc. | |
| */ | |
| setError<E extends Schema.Top>(schema: E): Rpc< | |
| Tag, | |
| Payload, | |
| Success, | |
| E, | |
| Middleware, | |
| Requires | |
| > | |
| /** | |
| * Set the schema for the payload of the rpc. | |
| */ | |
| setPayload<P extends Schema.Top | Schema.Struct.Fields>( | |
| schema: P | |
| ): Rpc< | |
| Tag, | |
| P extends Schema.Struct.Fields ? Schema.Struct<P> : P, | |
| Success, | |
| Error, | |
| Middleware, | |
| Requires | |
| > | |
| /** | |
| * Add an `RpcMiddleware` to this procedure. | |
| */ | |
| middleware<M extends RpcMiddleware.AnyService>(middleware: M): Rpc< | |
| Tag, | |
| Payload, | |
| Success, | |
| Error, | |
| Middleware | M, | |
| RpcMiddleware.ApplyServices<M["Identifier"], Requires> | |
| > | |
| /** | |
| * Set the schema for the error response of the rpc. | |
| */ | |
| prefix<const Prefix extends string>(prefix: Prefix): Rpc< | |
| `${Prefix}${Tag}`, | |
| Payload, | |
| Success, | |
| Error, | |
| Middleware, | |
| Requires | |
| > | |
| /** | |
| * Add an annotation on the rpc. | |
| */ | |
| annotate<I, S>( | |
| tag: Context.Key<I, S>, | |
| value: NoInfer<S> | |
| ): Rpc<Tag, Payload, Success, Error, Middleware, Requires> | |
| /** | |
| * Merge the annotations of the rpc with the provided annotations. | |
| */ | |
| annotateMerge<I>( | |
| annotations: Context.Context<I> | |
| ): Rpc<Tag, Payload, Success, Error, Middleware, Requires> | |
| } | |
| /** | |
| * Represents server-side metadata for the client associated with an RPC request. | |
| * | |
| * **When to use** | |
| * | |
| * Use to inspect or annotate the connected client while handling an RPC request | |
| * on the server. | |
| * | |
| * **Details** | |
| * | |
| * It stores the client id and request annotations that handlers can read or | |
| * extend. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export class ServerClient { | |
| readonly id: number | |
| annotations: Context.Context<never> | |
| constructor(id: number) { | |
| this.id = id | |
| this.annotations = Context.empty() | |
| } | |
| annotate<I, S>( | |
| tag: Context.Key<I, S>, | |
| value: NoInfer<S> | |
| ): ServerClient { | |
| this.annotations = Context.add(this.annotations, tag, value) | |
| return this | |
| } | |
| } | |
| /** | |
| * Represents the server-side implementation of an RPC. | |
| * | |
| * **Details** | |
| * | |
| * The handler receives the decoded request plus client, request id, headers, | |
| * and RPC metadata, and returns either an effectful result or a stream result. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export interface Handler<Tag extends string> { | |
| readonly _: unique symbol | |
| readonly tag: Tag | |
| readonly handler: (request: any, options: { | |
| readonly client: ServerClient | |
| readonly requestId: RequestId | |
| readonly headers: Headers | |
| readonly rpc: Any | |
| }) => Effect<{} | Deferred<any, any>, any> | Stream<any, any> | |
| readonly context: Context.Context<never> | |
| } | |
| /** | |
| * An erased RPC definition that preserves the common runtime metadata shared by | |
| * all RPCs. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export interface Any extends Pipeable { | |
| readonly [TypeId]: typeof TypeId | |
| readonly _tag: string | |
| readonly key: string | |
| readonly annotations: Context.Context<never> | |
| } | |
| /** | |
| * An erased RPC definition with all schema, middleware, annotation, and service | |
| * metadata available. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export interface AnyWithProps extends Pipeable { | |
| readonly [TypeId]: typeof TypeId | |
| readonly _tag: string | |
| readonly key: string | |
| readonly payloadSchema: Schema.Top | |
| readonly successSchema: Schema.Top | |
| readonly errorSchema: Schema.Top | |
| readonly defectSchema: Schema.Top | |
| readonly annotations: Context.Context<never> | |
| readonly middlewares: ReadonlySet<RpcMiddleware.AnyServiceWithProps> | |
| readonly "~requires": any | |
| } | |
| /** | |
| * Extracts the tag string from an `Rpc`. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type Tag<R> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? _Tag | |
| : never | |
| /** | |
| * Extracts the success schema from an `Rpc`. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type SuccessSchema<R> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? _Success | |
| : never | |
| /** | |
| * Extracts the decoded success value type from an `Rpc`. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type Success<R> = SuccessSchema<R>["Type"] | |
| /** | |
| * Extracts the encoded success value type from an `Rpc`. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type SuccessEncoded<R> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? _Success["Encoded"] | |
| : never | |
| /** | |
| * Extracts the success schema used in an RPC exit. | |
| * | |
| * **Details** | |
| * | |
| * For streaming RPCs, this is the stream element schema; otherwise it is the | |
| * RPC success schema. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type SuccessExitSchema<R> = SuccessSchema<R> extends RpcSchema.Stream<infer _A, infer _E> ? _A : SuccessSchema<R> | |
| /** | |
| * Extracts the decoded success value carried by an RPC exit. | |
| * | |
| * **Details** | |
| * | |
| * For streaming RPCs, the immediate exit success is `void` because stream | |
| * elements are delivered separately. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type SuccessExit<R> = Success<R> extends infer T ? T extends Stream<infer _A, infer _E, infer _Env> ? void : T | |
| : never | |
| /** | |
| * Extracts the decoded stream element type from a streaming RPC, or `never` for | |
| * non-streaming RPCs. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type SuccessChunk<R> = Success<R> extends Stream<infer _A, infer _E, infer _Env> ? _A : never | |
| /** | |
| * Extracts the RPC error schema, including error schemas contributed by | |
| * middleware. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type ErrorSchema<R> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? _Error | _Middleware["error"] | |
| : never | |
| /** | |
| * Extracts the decoded error value type from an `Rpc`, including middleware | |
| * errors. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type Error<R> = Schema.Schema.Type<ErrorSchema<R>> | |
| /** | |
| * Extracts the error schema used in an RPC exit. | |
| * | |
| * **Details** | |
| * | |
| * For streaming RPCs, this includes both the stream error schema and the RPC | |
| * error schema; otherwise it is the RPC error schema. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type ErrorExitSchema<R> = SuccessSchema<R> extends RpcSchema.Stream<infer _A, infer _E> ? _E | ErrorSchema<R> | |
| : ErrorSchema<R> | |
| /** | |
| * Extracts the decoded error type used by an RPC exit. | |
| * | |
| * **Details** | |
| * | |
| * For streaming RPCs, this includes both stream errors and RPC errors. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type ErrorExit<R> = Success<R> extends Stream<infer _A, infer _E, infer _Env> ? _E | Error<R> : Error<R> | |
| /** | |
| * The `Exit` type produced for an RPC, using the RPC's exit success and exit | |
| * error types. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type Exit<R> = Exit_<SuccessExit<R>, ErrorExit<R>> | |
| /** | |
| * Extracts the payload constructor input type accepted by the RPC payload | |
| * schema. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type PayloadConstructor<R> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? _Payload["~type.make.in"] | |
| : never | |
| /** | |
| * Extracts the decoded payload type from an `Rpc`. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type Payload<R> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? _Payload["Type"] | |
| : never | |
| /** | |
| * Extracts all schema services required to encode or decode an RPC's payload, | |
| * success, error, and middleware error schemas. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type Services<R> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? | |
| | _Payload["DecodingServices"] | |
| | _Payload["EncodingServices"] | |
| | _Success["DecodingServices"] | |
| | _Success["EncodingServices"] | |
| | _Error["DecodingServices"] | |
| | _Error["EncodingServices"] | |
| | _Middleware["error"]["DecodingServices"] | |
| | _Middleware["error"]["EncodingServices"] | |
| : never | |
| /** | |
| * Extracts the schema services required on the client side of an RPC. | |
| * | |
| * **Details** | |
| * | |
| * This includes payload encoding services and success, error, and middleware | |
| * error decoding services. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type ServicesClient<R> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? | |
| | _Payload["EncodingServices"] | |
| | _Success["DecodingServices"] | |
| | _Error["DecodingServices"] | |
| | _Middleware["error"]["DecodingServices"] | |
| : never | |
| /** | |
| * Extracts the schema services required on the server side of an RPC. | |
| * | |
| * **Details** | |
| * | |
| * This includes payload decoding services and success, error, and middleware | |
| * error encoding services. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type ServicesServer<R> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? | |
| | _Payload["DecodingServices"] | |
| | _Success["EncodingServices"] | |
| | _Error["EncodingServices"] | |
| | _Middleware["error"]["EncodingServices"] | |
| : never | |
| /** | |
| * Extracts the service identifiers for middleware attached to an `Rpc`. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type Middleware<R> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? Context.Service.Identifier<_Middleware> | |
| : never | |
| /** | |
| * Extracts client-side middleware service requirements for middleware marked as | |
| * required on the client. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type MiddlewareClient<R> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? _Middleware extends { readonly requiredForClient: true } ? RpcMiddleware.ForClient<_Middleware["Identifier"]> | |
| : never | |
| : never | |
| /** | |
| * Returns an RPC type with an additional error schema unioned into its error | |
| * channel. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type AddError<R extends Any, Error extends Schema.Top> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? Rpc< | |
| _Tag, | |
| _Payload, | |
| _Success, | |
| _Error | Error, | |
| _Middleware, | |
| _Requires | |
| > : | |
| never | |
| /** | |
| * Returns an RPC type with additional middleware and the corresponding | |
| * middleware service requirements applied. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type AddMiddleware<R extends Any, Middleware extends RpcMiddleware.AnyService> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? Rpc< | |
| _Tag, | |
| _Payload, | |
| _Success, | |
| _Error, | |
| _Middleware | Middleware, | |
| RpcMiddleware.ApplyServices<Middleware["Identifier"], _Requires> | |
| > : | |
| never | |
| /** | |
| * Converts an RPC definition into the corresponding `Handler` type. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type ToHandler<R extends Any> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? Handler<_Tag> : | |
| never | |
| /** | |
| * The function signature for implementing an RPC handler. | |
| * | |
| * **Details** | |
| * | |
| * The function receives the decoded payload and request metadata, and returns | |
| * the RPC result shape, optionally wrapped with `Wrapper` options. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type ToHandlerFn<Current extends Any, R = any> = ( | |
| payload: Payload<Current>, | |
| options: { | |
| readonly client: ServerClient | |
| readonly requestId: RequestId | |
| readonly headers: Headers | |
| readonly rpc: Current | |
| } | |
| ) => WrapperOr<ResultFrom<Current, R>> | |
| /** | |
| * Returns `true` when the RPC with the specified tag has a streaming success | |
| * schema, or `never` otherwise. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type IsStream<R extends Any, Tag extends string> = R extends Rpc< | |
| Tag, | |
| infer _Payload, | |
| RpcSchema.Stream<infer _A, infer _E>, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? true : | |
| never | |
| /** | |
| * Extracts the RPC with the specified tag from an RPC union. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type ExtractTag<R extends Any, Tag extends string> = R extends Rpc< | |
| Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? R : | |
| never | |
| /** | |
| * Extracts the services provided by middleware on the RPC with the specified | |
| * tag. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type ExtractProvides<R extends Any, Tag extends string> = R extends Rpc< | |
| Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? RpcMiddleware.Provides<_Middleware["Identifier"]> : | |
| never | |
| /** | |
| * Extracts the service requirements of the RPC with the specified tag. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type ExtractRequires<R extends Any, Tag extends string> = R extends Rpc< | |
| Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? _Requires : | |
| never | |
| /** | |
| * Removes the services provided by middleware for the specified RPC tag from an | |
| * environment type. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type ExcludeProvides<Env, R extends Any, Tag extends string> = Exclude< | |
| Env, | |
| ExtractProvides<R, Tag> | |
| > | |
| /** | |
| * Computes the allowed handler result type for an RPC. | |
| * | |
| * **Details** | |
| * | |
| * Streaming RPCs may return a stream or an effect that produces a queue. Other | |
| * RPCs return an effect that succeeds with the success value or a deferred | |
| * success value. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type ResultFrom<R extends Any, Services> = R extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? [_Success] extends [RpcSchema.Stream<infer _SA, infer _SE>] ? | |
| | Stream< | |
| _SA["Type"], | |
| _SE["Type"] | _Error["Type"], | |
| Services | |
| > | |
| | Effect< | |
| Queue.Dequeue<_SA["Type"], _SE["Type"] | _Error["Type"] | Cause.Done>, | |
| _SE["Type"] | Schema.Schema.Type<_Error>, | |
| Services | |
| > : | |
| Effect< | |
| _Success["Type"] | Deferred<_Success["Type"], _Error["Type"]>, | |
| _Error["Type"], | |
| Services | |
| > : | |
| never | |
| /** | |
| * Returns an RPC type with the specified string prefix added to its tag while | |
| * preserving its payload, success, error, middleware, and requirements. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export type Prefixed<Rpcs extends Any, Prefix extends string> = Rpcs extends Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? Rpc< | |
| `${Prefix}${_Tag}`, | |
| _Payload, | |
| _Success, | |
| _Error, | |
| _Middleware, | |
| _Requires | |
| > | |
| : never | |
| const Proto = { | |
| [TypeId]: TypeId, | |
| pipe() { | |
| return pipeArguments(this, arguments) | |
| }, | |
| setSuccess( | |
| this: AnyWithProps, | |
| successSchema: Schema.Top | |
| ) { | |
| return makeProto({ | |
| _tag: this._tag, | |
| payloadSchema: this.payloadSchema, | |
| successSchema, | |
| errorSchema: this.errorSchema, | |
| defectSchema: this.defectSchema, | |
| annotations: this.annotations, | |
| middlewares: this.middlewares | |
| }) | |
| }, | |
| setError(this: AnyWithProps, errorSchema: Schema.Top) { | |
| return makeProto({ | |
| _tag: this._tag, | |
| payloadSchema: this.payloadSchema, | |
| successSchema: this.successSchema, | |
| errorSchema, | |
| defectSchema: this.defectSchema, | |
| annotations: this.annotations, | |
| middlewares: this.middlewares | |
| }) | |
| }, | |
| setPayload(this: AnyWithProps, payloadSchema: Schema.Struct<any> | Schema.Struct.Fields) { | |
| return makeProto({ | |
| _tag: this._tag, | |
| payloadSchema: Schema.isSchema(payloadSchema) ? payloadSchema as any : Schema.Struct(payloadSchema as any), | |
| successSchema: this.successSchema, | |
| errorSchema: this.errorSchema, | |
| defectSchema: this.defectSchema, | |
| annotations: this.annotations, | |
| middlewares: this.middlewares | |
| }) | |
| }, | |
| middleware(this: AnyWithProps, middleware: RpcMiddleware.AnyService) { | |
| return makeProto({ | |
| _tag: this._tag, | |
| payloadSchema: this.payloadSchema, | |
| successSchema: this.successSchema, | |
| errorSchema: this.errorSchema, | |
| defectSchema: this.defectSchema, | |
| annotations: this.annotations, | |
| middlewares: new Set([...this.middlewares, middleware]) | |
| }) | |
| }, | |
| prefix(this: AnyWithProps, prefix: string) { | |
| return makeProto({ | |
| _tag: `${prefix}${this._tag}`, | |
| payloadSchema: this.payloadSchema, | |
| successSchema: this.successSchema, | |
| errorSchema: this.errorSchema, | |
| defectSchema: this.defectSchema, | |
| annotations: this.annotations, | |
| middlewares: this.middlewares | |
| }) | |
| }, | |
| annotate(this: AnyWithProps, tag: Context.Key<any, any>, value: any) { | |
| return makeProto({ | |
| _tag: this._tag, | |
| payloadSchema: this.payloadSchema, | |
| successSchema: this.successSchema, | |
| errorSchema: this.errorSchema, | |
| defectSchema: this.defectSchema, | |
| middlewares: this.middlewares, | |
| annotations: Context.add(this.annotations, tag, value) | |
| }) | |
| }, | |
| annotateMerge(this: AnyWithProps, context: Context.Context<any>) { | |
| return makeProto({ | |
| _tag: this._tag, | |
| payloadSchema: this.payloadSchema, | |
| successSchema: this.successSchema, | |
| errorSchema: this.errorSchema, | |
| defectSchema: this.defectSchema, | |
| middlewares: this.middlewares, | |
| annotations: Context.merge(this.annotations, context) | |
| }) | |
| } | |
| } | |
| const makeProto = < | |
| const Tag extends string, | |
| Payload extends Schema.Top, | |
| Success extends Schema.Top, | |
| Error extends Schema.Top, | |
| Middleware extends RpcMiddleware.AnyService, | |
| Requires | |
| >(options: { | |
| readonly _tag: Tag | |
| readonly payloadSchema: Payload | |
| readonly successSchema: Success | |
| readonly errorSchema: Error | |
| readonly defectSchema: Schema.Top | |
| readonly annotations: Context.Context<never> | |
| readonly middlewares: ReadonlySet<Middleware> | |
| }): Rpc<Tag, Payload, Success, Error, Middleware, Requires> => { | |
| function Rpc() {} | |
| Object.setPrototypeOf(Rpc, Proto) | |
| Object.assign(Rpc, options) | |
| Rpc.key = `effect/rpc/Rpc/${options._tag}` | |
| return Rpc as any | |
| } | |
| /** | |
| * Creates an RPC definition with the supplied tag and optional schemas. | |
| * | |
| * **Details** | |
| * | |
| * Payload options can be either a schema or struct fields. `stream: true` wraps | |
| * the success and error schemas in a stream schema and sets the normal error | |
| * schema to `Schema.Never`. `primaryKey` creates a payload class with a | |
| * primary key derived from the payload value. | |
| * | |
| * @category constructors | |
| * @since 4.0.0 | |
| */ | |
| export const make = < | |
| const Tag extends string, | |
| Payload extends Schema.Top | Schema.Struct.Fields = Schema.Void, | |
| Success extends Schema.Top = Schema.Void, | |
| Error extends Schema.Top = Schema.Never, | |
| const Stream extends boolean = false | |
| >(tag: Tag, options?: { | |
| readonly payload?: Payload | |
| readonly success?: Success | |
| readonly error?: Error | |
| readonly defect?: DefectSchema | |
| readonly stream?: Stream | |
| readonly primaryKey?: [Payload] extends [Schema.Struct.Fields] ? (( | |
| payload: Payload extends Schema.Struct.Fields ? Struct.Simplify<Schema.Struct<Payload>["Type"]> : Payload["Type"] | |
| ) => string) : | |
| never | |
| }): Rpc< | |
| Tag, | |
| Payload extends Schema.Struct.Fields ? Schema.Struct<Payload> : Payload, | |
| Stream extends true ? RpcSchema.Stream<Success, Error> : Success, | |
| Stream extends true ? typeof Schema.Never : Error | |
| > => { | |
| const successSchema = options?.success ?? Schema.Void | |
| const errorSchema = options?.error ?? Schema.Never | |
| const defectSchema = options?.defect ?? Schema.Defect() | |
| let payloadSchema: any | |
| if (options?.primaryKey) { | |
| payloadSchema = class Payload extends Schema.Class<Payload>(`effect/rpc/Rpc/${tag}`)(options.payload as any) { | |
| [PrimaryKey.symbol](): string { | |
| return options.primaryKey!(this as any) | |
| } | |
| } | |
| } else { | |
| payloadSchema = Schema.isSchema(options?.payload) | |
| ? options?.payload as any | |
| : options?.payload | |
| ? Schema.Struct(options?.payload as any) | |
| : Schema.Void | |
| } | |
| return makeProto({ | |
| _tag: tag, | |
| payloadSchema, | |
| successSchema: options?.stream ? | |
| RpcSchema.Stream(successSchema, errorSchema) : | |
| successSchema, | |
| errorSchema: options?.stream ? Schema.Never : errorSchema, | |
| defectSchema, | |
| annotations: Context.empty(), | |
| middlewares: new Set<never>() | |
| }) as any | |
| } | |
| /** | |
| * Creates a custom `Rpc` constructor that can transform the output schemas. | |
| * | |
| * **Example** (Paginated RPC constructor) | |
| * | |
| * ```ts | |
| * import { Schema } from "effect" | |
| * import { Rpc } from "effect/unstable/rpc" | |
| * | |
| * // Create a custom Rpc wrapper definition by transforming the success and error | |
| * // schemas. | |
| * export interface RpcWithPagination extends Rpc.Custom { | |
| * readonly out: Rpc.Custom.Out< | |
| * Paginated<this["success"]>, | |
| * this["error"] | |
| * > | |
| * } | |
| * | |
| * // The type definition for the transformed success schema. | |
| * export interface Paginated<S extends Schema.Top> extends | |
| * Schema.Struct<{ | |
| * readonly offset: Schema.Number | |
| * readonly total: Schema.Number | |
| * readonly results: Schema.$Array<S> | |
| * }> | |
| * {} | |
| * | |
| * // You can then implement the schema transformation using `Rpc.custom` | |
| * export const makePaginated = Rpc.custom<RpcWithPagination>((schemas) => ({ | |
| * ...schemas, | |
| * success: Schema.Struct({ | |
| * offset: Schema.Number, | |
| * total: Schema.Number, | |
| * results: Schema.Array(schemas.success) | |
| * }) | |
| * })) | |
| * | |
| * // You can then use the custom constructor in the same way `Rpc.make` is used. | |
| * export const listAllRpc = makePaginated("listAll", { | |
| * success: Schema.String | |
| * }) | |
| * ``` | |
| * | |
| * @category constructors | |
| * @since 4.0.0 | |
| */ | |
| export const custom = <Def extends Custom>( | |
| f: (options: Custom.OutDefault) => (Def & Custom.OutDefault)["out"] | |
| ) => | |
| < | |
| const Tag extends string, | |
| Payload extends Schema.Top | Schema.Struct.Fields = Schema.Void, | |
| Success extends Schema.Top = Schema.Void, | |
| Error extends Schema.Top = Schema.Never, | |
| const Stream extends boolean = false, | |
| Out extends Custom.OutDefault = Custom.Kind<Def, Success, Error> | |
| >(tag: Tag, options?: { | |
| readonly payload?: Payload | |
| readonly success?: Success | |
| readonly error?: Error | |
| readonly defect?: DefectSchema | |
| readonly stream?: Stream | |
| readonly primaryKey?: [Payload] extends [Schema.Struct.Fields] ? (( | |
| payload: Payload extends Schema.Struct.Fields ? Struct.Simplify<Schema.Struct<Payload>["Type"]> : Payload["Type"] | |
| ) => string) : | |
| never | |
| }): Rpc< | |
| Tag, | |
| Payload extends Schema.Struct.Fields ? Schema.Struct<Payload> : Payload, | |
| Stream extends true ? RpcSchema.Stream<Out["success"], Out["error"]> : Out["success"], | |
| Stream extends true ? typeof Schema.Never : Out["error"] | |
| > => { | |
| const success = options?.success ?? Schema.Void | |
| const error = options?.error ?? Schema.Never | |
| const defect = options?.defect ?? Schema.Defect() | |
| const out = f({ | |
| success, | |
| error, | |
| defect | |
| }) | |
| return make(tag, { | |
| ...out, | |
| primaryKey: options?.primaryKey, | |
| payload: options?.payload, | |
| stream: options?.stream | |
| }) as any | |
| } | |
| /** | |
| * Defines the type-level contract for an RPC custom constructor. | |
| * | |
| * **Details** | |
| * | |
| * A custom constructor receives the original success, error, and defect schemas | |
| * and returns transformed output schemas through `out`. | |
| * | |
| * @category constructors | |
| * @since 4.0.0 | |
| */ | |
| export interface Custom { | |
| readonly out: Custom.OutDefault | |
| readonly success: Schema.Top | |
| readonly error: Schema.Top | |
| readonly defect: DefectSchema | |
| } | |
| /** | |
| * Helper types for defining RPC custom constructors. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| export declare namespace Custom { | |
| /** | |
| * The transformed schemas produced by a custom RPC constructor. | |
| * | |
| * @category constructors | |
| * @since 4.0.0 | |
| */ | |
| export interface Out< | |
| Success extends Schema.Top, | |
| Error extends Schema.Top | |
| > { | |
| readonly success: Success | |
| readonly error: Error | |
| readonly defect: DefectSchema | |
| } | |
| /** | |
| * The default custom-constructor output shape for arbitrary success and error | |
| * schemas. | |
| * | |
| * @category constructors | |
| * @since 4.0.0 | |
| */ | |
| export type OutDefault = Out<Schema.Top, Schema.Top> | |
| /** | |
| * Applies a custom constructor definition to concrete success and error | |
| * schemas and returns its transformed output schema type. | |
| * | |
| * @category constructors | |
| * @since 4.0.0 | |
| */ | |
| export type Kind< | |
| Def extends Custom, | |
| Success extends Schema.Top, | |
| Error extends Schema.Top | |
| > = (Def & { | |
| readonly success: Success | |
| readonly error: Error | |
| })["out"] | |
| } | |
| const exitSchemaCache = new WeakMap<Any, Schema.Exit<Schema.Top, Schema.Top, DefectSchema>>() | |
| /** | |
| * Builds the `Schema.Exit` used to encode and decode RPC results. | |
| * | |
| * **Details** | |
| * | |
| * The failure side includes the RPC error schema, middleware error schemas, and | |
| * stream error schema for streaming RPCs. Streaming RPCs use `Schema.Void` for | |
| * the exit success value. The schema is cached per RPC definition. | |
| * | |
| * @category constructors | |
| * @since 4.0.0 | |
| */ | |
| export const exitSchema = <R extends Any>( | |
| self: R | |
| ): Schema.Exit< | |
| SuccessExitSchema<R>, | |
| ErrorExitSchema<R>, | |
| DefectSchema | |
| > => { | |
| if (exitSchemaCache.has(self)) { | |
| return exitSchemaCache.get(self) as any | |
| } | |
| const rpc = self as any as AnyWithProps | |
| const failures = new Set<Schema.Top>([rpc.errorSchema]) | |
| const streamSchemas = RpcSchema.getStreamSchemas(rpc.successSchema) | |
| if (Option.isSome(streamSchemas)) { | |
| failures.add(streamSchemas.value.error) | |
| } | |
| for (const middleware of rpc.middlewares) { | |
| failures.add(middleware.error) | |
| } | |
| const schema = Schema.Exit( | |
| Option.isSome(streamSchemas) ? Schema.Void : rpc.successSchema, | |
| Schema.Union([...failures]), | |
| rpc.defectSchema | |
| ) | |
| exitSchemaCache.set(self, schema as any) | |
| return schema as any | |
| } | |
| const WrapperTypeId = "~effect/rpc/Rpc/Wrapper" | |
| /** | |
| * Wraps a handler result with execution options for the RPC server. | |
| * | |
| * **Details** | |
| * | |
| * `fork` requests concurrent execution, and `uninterruptible` requests | |
| * uninterruptible execution. | |
| * | |
| * @category wrapping | |
| * @since 4.0.0 | |
| */ | |
| export interface Wrapper<A> { | |
| readonly [WrapperTypeId]: typeof WrapperTypeId | |
| readonly value: A | |
| readonly fork: boolean | |
| readonly uninterruptible: boolean | |
| } | |
| /** | |
| * A value that may be returned directly or wrapped with RPC server execution | |
| * options. | |
| * | |
| * @category wrapping | |
| * @since 4.0.0 | |
| */ | |
| export type WrapperOr<A> = A | Wrapper<A> | |
| /** | |
| * Returns `true` when the value is an RPC `Wrapper`. | |
| * | |
| * @category wrapping | |
| * @since 4.0.0 | |
| */ | |
| export const isWrapper = (u: object): u is Wrapper<any> => WrapperTypeId in u | |
| /** | |
| * Wraps a handler result with RPC server execution options. | |
| * | |
| * **Details** | |
| * | |
| * When the value is already wrapped, unspecified options are inherited from the | |
| * existing wrapper. | |
| * | |
| * @category wrapping | |
| * @since 4.0.0 | |
| */ | |
| export const wrap = (options: { | |
| readonly fork?: boolean | undefined | |
| readonly uninterruptible?: boolean | undefined | |
| }) => | |
| <A extends object>(value: A): Wrapper<A> => | |
| isWrapper(value) ? | |
| { | |
| [WrapperTypeId]: WrapperTypeId, | |
| value: value.value, | |
| fork: options.fork ?? value.fork, | |
| uninterruptible: options.uninterruptible ?? value.uninterruptible | |
| } : | |
| { | |
| [WrapperTypeId]: WrapperTypeId, | |
| value, | |
| fork: options.fork ?? false, | |
| uninterruptible: options.uninterruptible ?? false | |
| } | |
| /** | |
| * Returns the wrapped response value when the input is an RPC `Wrapper`, or the | |
| * input itself when it is already unwrapped. | |
| * | |
| * @category wrapping | |
| * @since 4.0.0 | |
| */ | |
| export const unwrap = <A extends object>(value: WrapperOr<A>): A => isWrapper(value) ? value.value : value | |
| /** | |
| * Maps the value inside an RPC wrapper, preserving wrapper options such as | |
| * `fork` and `uninterruptible`; unwrapped values are mapped directly. | |
| * | |
| * @category wrapping | |
| * @since 4.0.0 | |
| */ | |
| export const wrapMap = <A extends object, B extends object>(self: WrapperOr<A>, f: (value: A) => B): WrapperOr<B> => { | |
| if (isWrapper(self)) { | |
| return wrap(self)(f(self.value)) | |
| } | |
| return f(self) | |
| } | |
| /** | |
| * Wraps a response Effect or Stream so the RPC server executes it concurrently | |
| * regardless of the server concurrency setting. | |
| * | |
| * @category wrapping | |
| * @since 4.0.0 | |
| */ | |
| export const fork: <A extends object>(value: A) => Wrapper<A> = wrap({ fork: true }) | |
| /** | |
| * Wraps a response Effect or Stream so the RPC server runs it in an uninterruptible region. | |
| * | |
| * @category wrapping | |
| * @since 4.0.0 | |
| */ | |
| export const uninterruptible: <A extends object>(value: A) => Wrapper<A> = wrap({ uninterruptible: true }) | |
Xet Storage Details
- Size:
- 32.1 kB
- Xet hash:
- a63d23908d10971e6c5a76d95757a00e8582bf40637a5aa21958a5c4ab3a929d
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.