/** * @since 1.0.0 */ import * as Effect from "effect/Effect" import * as Effectable from "effect/Effectable" import { dual } from "effect/Function" import type * as Types from "effect/Types" import * as Procedure from "./Procedure.js" /** * @since 1.0.0 * @category type ids */ export const TypeId: unique symbol = Symbol.for("@effect/experimental/Machine/ProcedureList") /** * @since 1.0.0 * @category type ids */ export type TypeId = typeof TypeId /** * @since 1.0.0 * @category models */ export interface ProcedureList< State, Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R > extends Effect.Effect> { readonly [TypeId]: TypeId readonly initialState: State readonly public: ReadonlyArray> readonly private: ReadonlyArray> readonly identifier: string } const Proto = { ...Effectable.CommitPrototype, [TypeId]: TypeId, commit() { return Effect.succeed(this) } } const makeProto = ( options: { readonly initialState: State readonly public: ReadonlyArray> readonly private: ReadonlyArray> readonly identifier: string } ): ProcedureList => Object.assign(Object.create(Proto), options) /** * @since 1.0.0 * @category constructors */ export const make = (initialState: State, options?: { readonly identifier?: string }): ProcedureList => makeProto({ initialState, public: [], private: [], identifier: options?.identifier ?? "Unknown" }) /** * @since 1.0.0 * @category combinators */ export const addProcedure: { /** * @since 1.0.0 * @category combinators */ < Req extends Procedure.TaggedRequest.Any, State, R2 >(procedure: Procedure.Procedure): < Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R >( self: ProcedureList ) => ProcedureList /** * @since 1.0.0 * @category combinators */ < State, Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R, Req extends Procedure.TaggedRequest.Any, R2 >( self: ProcedureList, procedure: Procedure.Procedure ): ProcedureList } = dual( 2, < State, Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R, Req extends Procedure.TaggedRequest.Any, R2 >( self: ProcedureList, procedure: Procedure.Procedure ): ProcedureList => makeProto({ ...self, public: [...self.public, procedure] as any }) ) /** * @since 1.0.0 * @category combinators */ export const addProcedurePrivate: { /** * @since 1.0.0 * @category combinators */ < Req extends Procedure.TaggedRequest.Any, State, R2 >(procedure: Procedure.Procedure): < Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R >( self: ProcedureList ) => ProcedureList /** * @since 1.0.0 * @category combinators */ < State, Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R, Req extends Procedure.TaggedRequest.Any, R2 >( self: ProcedureList, procedure: Procedure.Procedure ): ProcedureList } = dual( 2, < State, Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R, Req extends Procedure.TaggedRequest.Any, R2 >( self: ProcedureList, procedure: Procedure.Procedure ): ProcedureList => makeProto({ ...self, private: [...self.private, procedure] as any }) ) /** * @since 1.0.0 * @category combinators */ export const add = (): { < State, Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R2 >( tag: Req["_tag"], handler: Procedure.Handler, Types.NoInfer | Types.NoInfer, R2> ): ( self: ProcedureList ) => ProcedureList < State, Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R, R2 >( self: ProcedureList, tag: Req["_tag"], handler: Procedure.Handler, Types.NoInfer | Types.NoInfer, R2> ): ProcedureList } => dual( 3, < State, Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R, R2 >( self: ProcedureList, tag: Req["_tag"], handler: Procedure.Handler, Types.NoInfer | Types.NoInfer, R2> ): ProcedureList => addProcedure(self, Procedure.make()()(tag, handler)) ) /** * @since 1.0.0 * @category combinators */ export const addPrivate = (): { < State, Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R2 >( tag: Req["_tag"], handler: Procedure.Handler, Types.NoInfer | Types.NoInfer, R2> ): ( self: ProcedureList ) => ProcedureList < State, Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R, R2 >( self: ProcedureList, tag: Req["_tag"], handler: Procedure.Handler, Types.NoInfer | Types.NoInfer, R2> ): ProcedureList } => dual( 3, < State, Public extends Procedure.TaggedRequest.Any, Private extends Procedure.TaggedRequest.Any, R, R2 >( self: ProcedureList, tag: Req["_tag"], handler: Procedure.Handler, Types.NoInfer | Types.NoInfer, R2> ): ProcedureList => addProcedurePrivate(self, Procedure.make()()(tag, handler)) ) /** * @since 1.0.0 * @category combinators */ export const withInitialState: { /** * @since 1.0.0 * @category combinators */ (initialState: Types.NoInfer): ( self: ProcedureList ) => ProcedureList /** * @since 1.0.0 * @category combinators */ ( self: ProcedureList, initialState: Types.NoInfer ): ProcedureList } = dual(2, ( self: ProcedureList, initialState: Types.NoInfer ): ProcedureList => makeProto({ ...self, initialState }))