/** * @since 0.67.0 */ import type * as Effect from "effect/Effect" import type * as Exit from "effect/Exit" import { dual } from "effect/Function" import { globalValue } from "effect/GlobalValue" import * as serializable_ from "./internal/serializable.js" import type * as ParseResult from "./ParseResult.js" import * as Schema from "./Schema.js" // --------------------------------------------- // Serializable // --------------------------------------------- /** * @since 0.67.0 * @category symbol */ export const symbol: unique symbol = serializable_.symbol as any /** * The `Serializable` trait allows objects to define their own schema for * serialization. * * @since 0.67.0 * @category model */ export interface Serializable { readonly [symbol]: Schema.Schema } /** * @since 0.67.0 * @category model */ export declare namespace Serializable { /** * @since 0.68.15 */ export type Type = T extends Serializable ? A : never /** * @since 0.68.15 */ export type Encoded = T extends Serializable ? I : never /** * @since 0.67.0 */ export type Context = T extends Serializable ? R : never /** * @since 0.69.0 */ export type Any = Serializable /** * @since 0.69.0 */ export type All = | Any | Serializable | Serializable | Serializable } /** * @since 0.69.0 */ export const asSerializable = ( serializable: S ): Serializable, Serializable.Encoded, Serializable.Context> => serializable as any /** * @since 0.67.0 * @category accessor */ export const selfSchema = (self: Serializable): Schema.Schema => self[symbol] /** * @since 0.67.0 * @category encoding */ export const serialize = (self: Serializable): Effect.Effect => Schema.encodeUnknown(self[symbol])(self) /** * @since 0.67.0 * @category decoding */ export const deserialize: { /** * @since 0.67.0 * @category decoding */ (value: unknown): (self: Serializable) => Effect.Effect /** * @since 0.67.0 * @category decoding */ (self: Serializable, value: unknown): Effect.Effect } = dual( 2, (self: Serializable, value: unknown): Effect.Effect => Schema.decodeUnknown(self[symbol])(value) ) // --------------------------------------------- // WithResult // --------------------------------------------- /** * @since 0.67.0 * @category symbol */ export const symbolResult: unique symbol = serializable_.symbolResult as any /** * The `WithResult` trait is designed to encapsulate the outcome of an * operation, distinguishing between success and failure cases. Each case is * associated with a schema that defines the structure and types of the success * or failure data. * * @since 0.67.0 * @category model */ export interface WithResult { readonly [symbolResult]: { readonly success: Schema.Schema readonly failure: Schema.Schema } } /** * @since 0.67.0 * @category model */ export declare namespace WithResult { /** * @since 0.68.16 */ export type Success = T extends WithResult ? _A : never /** * @since 0.69.0 */ export type SuccessEncoded = T extends WithResult ? _I : never /** * @since 0.69.0 */ export type Failure = T extends WithResult ? _E : never /** * @since 0.69.0 */ export type FailureEncoded = T extends WithResult ? _EI : never /** * @since 0.67.0 */ export type Context = T extends WithResult ? R : never /** * @since 0.69.0 */ export type Any = WithResult /** * @since 0.69.0 */ export type All = | Any | WithResult } /** * @since 0.69.0 */ export const asWithResult = ( withExit: WR ): WithResult< WithResult.Success, WithResult.SuccessEncoded, WithResult.Failure, WithResult.FailureEncoded, WithResult.Context > => withExit as any /** * @since 0.67.0 * @category accessor */ export const failureSchema = (self: WithResult): Schema.Schema => self[symbolResult].failure /** * @since 0.67.0 * @category accessor */ export const successSchema = (self: WithResult): Schema.Schema => self[symbolResult].success const exitSchemaCache = globalValue( "@effect/schema/Serializable/exitSchemaCache", () => new WeakMap>() ) /** * @since 0.67.0 * @category accessor */ export const exitSchema = (self: WithResult): Schema.Schema< Exit.Exit, Schema.ExitEncoded, R > => { const proto = Object.getPrototypeOf(self) if (!(symbolResult in proto)) { return Schema.Exit({ failure: failureSchema(self), success: successSchema(self), defect: Schema.Defect }) } let schema = exitSchemaCache.get(proto) if (schema === undefined) { schema = Schema.Exit({ failure: failureSchema(self), success: successSchema(self), defect: Schema.Defect }) exitSchemaCache.set(proto, schema) } return schema } /** * @since 0.67.0 * @category encoding */ export const serializeFailure: { /** * @since 0.67.0 * @category encoding */ (value: FA): ( self: WithResult ) => Effect.Effect /** * @since 0.67.0 * @category encoding */ (self: WithResult, value: FA): Effect.Effect } = dual( 2, (self: WithResult, value: FA): Effect.Effect => Schema.encode(self[symbolResult].failure)(value) ) /** * @since 0.67.0 * @category decoding */ export const deserializeFailure: { /** * @since 0.67.0 * @category decoding */ ( value: unknown ): (self: WithResult) => Effect.Effect /** * @since 0.67.0 * @category decoding */ (self: WithResult, value: unknown): Effect.Effect } = dual( 2, ( self: WithResult, value: unknown ): Effect.Effect => Schema.decodeUnknown(self[symbolResult].failure)(value) ) /** * @since 0.67.0 * @category encoding */ export const serializeSuccess: { /** * @since 0.67.0 * @category encoding */ (value: SA): ( self: WithResult ) => Effect.Effect /** * @since 0.67.0 * @category encoding */ (self: WithResult, value: SA): Effect.Effect } = dual( 2, (self: WithResult, value: SA): Effect.Effect => Schema.encode(self[symbolResult].success)(value) ) /** * @since 0.67.0 * @category decoding */ export const deserializeSuccess: { /** * @since 0.67.0 * @category decoding */ (value: unknown): ( self: WithResult ) => Effect.Effect /** * @since 0.67.0 * @category decoding */ (self: WithResult, value: unknown): Effect.Effect } = dual( 2, ( self: WithResult, value: unknown ): Effect.Effect => Schema.decodeUnknown(self[symbolResult].success)(value) ) /** * @since 0.67.0 * @category encoding */ export const serializeExit: { /** * @since 0.67.0 * @category encoding */ (value: Exit.Exit): ( self: WithResult ) => Effect.Effect, ParseResult.ParseError, R> /** * @since 0.67.0 * @category encoding */ ( self: WithResult, value: Exit.Exit ): Effect.Effect, ParseResult.ParseError, R> } = dual(2, ( self: WithResult, value: Exit.Exit ): Effect.Effect, ParseResult.ParseError, R> => Schema.encode(exitSchema(self))(value)) /** * @since 0.67.0 * @category decoding */ export const deserializeExit: { /** * @since 0.67.0 * @category decoding */ (value: unknown): ( self: WithResult ) => Effect.Effect, ParseResult.ParseError, R> /** * @since 0.67.0 * @category decoding */ ( self: WithResult, value: unknown ): Effect.Effect, ParseResult.ParseError, R> } = dual(2, ( self: WithResult, value: unknown ): Effect.Effect, ParseResult.ParseError, R> => Schema.decodeUnknown(exitSchema(self))(value)) // --------------------------------------------- // SerializableWithResult // --------------------------------------------- /** * The `SerializableWithResult` trait is specifically designed to model remote * procedures that require serialization of their input and output, managing * both successful and failed outcomes. * * This trait combines functionality from both the `Serializable` and `WithResult` * traits to handle data serialization and the bifurcation of operation results * into success or failure categories. * * @since 0.67.0 * @category model */ export interface SerializableWithResult< A, I, R, Success, SuccessEncoded, Failure, FailureEncoded, ResultR > extends Serializable, WithResult {} /** * @since 0.67.0 * @category model */ export declare namespace SerializableWithResult { /** * @since 0.69.0 */ export type Context

= P extends SerializableWithResult ? SR | RR : never /** * @since 0.69.0 */ export type Any = SerializableWithResult /** * @since 0.69.0 */ export type All = | Any | SerializableWithResult } /** * @since 0.69.0 */ export const asSerializableWithResult = ( procedure: SWR ): SerializableWithResult< Serializable.Type, Serializable.Encoded, Serializable.Context, WithResult.Success, WithResult.SuccessEncoded, WithResult.Failure, WithResult.FailureEncoded, WithResult.Context > => procedure as any