/** * @since 1.0.0 */ import * as MsgPack from "@effect/platform/MsgPack" import { pipeArguments } from "effect/Pipeable" import * as Predicate from "effect/Predicate" import * as Schema from "effect/Schema" /** * @since 1.0.0 * @category type ids */ export const TypeId: unique symbol = Symbol.for("@effect/experimental/Event") /** * @since 1.0.0 * @category type ids */ export type TypeId = typeof TypeId /** * @since 1.0.0 * @category guards */ export const isEvent = (u: unknown): u is Event => Predicate.hasProperty(u, TypeId) /** * Represents an event in an EventLog. * * @since 1.0.0 * @category models */ export interface Event< out Tag extends string, in out Payload extends Schema.Schema.Any = typeof Schema.Void, in out Success extends Schema.Schema.Any = typeof Schema.Void, in out Error extends Schema.Schema.All = typeof Schema.Never > { readonly [TypeId]: TypeId readonly tag: Tag readonly primaryKey: (payload: Schema.Schema.Type) => string readonly payload: Payload readonly payloadMsgPack: MsgPack.schema readonly success: Success readonly error: Error } /** * @since 1.0.0 * @category models */ export interface EventHandler { readonly _: unique symbol readonly tag: Tag } /** * @since 1.0.0 * @category models */ export declare namespace Event { /** * @since 1.0.0 * @category models */ export interface Any { readonly [TypeId]: TypeId readonly tag: string } /** * @since 1.0.0 * @category models */ export interface AnyWithProps extends Event {} /** * @since 1.0.0 * @category models */ export type ToService = A extends Event< infer _Tag, infer _Payload, infer _Success, infer _Error > ? EventHandler<_Tag> : never /** * @since 1.0.0 * @category models */ export type Tag = A extends Event< infer _Tag, infer _Payload, infer _Success, infer _Error > ? _Tag : never /** * @since 1.0.0 * @category models */ export type ErrorSchema = A extends Event< infer _Tag, infer _Payload, infer _Success, infer _Error > ? _Error : never /** * @since 1.0.0 * @category models */ export type Error = Schema.Schema.Type> /** * @since 1.0.0 * @category models */ export type AddError = A extends Event< infer _Tag, infer _Payload, infer _Success, infer _Error > ? Event<_Tag, _Payload, _Success, _Error | Error> : never /** * @since 1.0.0 * @category models */ export type PayloadSchema = A extends Event< infer _Tag, infer _Payload, infer _Success, infer _Error > ? _Payload : never /** * @since 1.0.0 * @category models */ export type Payload = Schema.Schema.Type> /** * @since 1.0.0 * @category models */ export type TaggedPayload = A extends Event< infer _Tag, infer _Payload, infer _Success, infer _Error > ? { readonly _tag: _Tag readonly payload: Schema.Schema.Type<_Payload> } : never /** * @since 1.0.0 * @category models */ export type SuccessSchema = A extends Event< infer _Tag, infer _Payload, infer _Success, infer _Error > ? _Success : never /** * @since 1.0.0 * @category models */ export type Success = Schema.Schema.Type> /** * @since 1.0.0 * @category models */ export type Context = A extends Event< infer _Name, infer _Payload, infer _Success, infer _Error > ? Schema.Schema.Context<_Payload> | Schema.Schema.Context<_Success> | Schema.Schema.Context<_Error> : never /** * @since 1.0.0 * @category models */ export type WithTag = Extract /** * @since 1.0.0 * @category models */ export type ExcludeTag = Exclude /** * @since 1.0.0 * @category models */ export type PayloadWithTag = Payload> /** * @since 1.0.0 * @category models */ export type SuccessWithTag = Success> /** * @since 1.0.0 * @category models */ export type ErrorWithTag = Error> /** * @since 1.0.0 * @category models */ export type ContextWithTag = Context> } const Proto = { [TypeId]: TypeId, pipe() { return pipeArguments(this, arguments) } } /** * @since 1.0.0 * @category constructors */ export const make = < Tag extends string, Payload extends Schema.Schema.Any = typeof Schema.Void, Success extends Schema.Schema.Any = typeof Schema.Void, Error extends Schema.Schema.All = typeof Schema.Never >(options: { readonly tag: Tag readonly primaryKey: (payload: Schema.Schema.Type) => string readonly payload?: Payload readonly success?: Success readonly error?: Error }): Event => Object.assign(Object.create(Proto), { tag: options.tag, primaryKey: options.primaryKey, payload: options.payload ?? Schema.Void, payloadMsgPack: MsgPack.schema(options.payload ?? Schema.Void), success: options.success ?? Schema.Void, error: options.error ?? Schema.Never })