import { Effect, Layer } from "effect"; import * as RpcDefinition from "../RpcDefinition"; type AnyArgs = Array; type EntrypointRpcMethod = (...args: AnyArgs) => Effect.Effect; export type EntrypointRpc = Record; export const provideEntrypointServices = ( layer: Layer.Layer, services: Layer.Layer, ): Layer.Layer => layer.pipe(Layer.provideMerge(services)) as Layer.Layer; export const defineEntrypointRpcMethods = ( target: string, prototype: object, rpc: EntrypointRpc | undefined, reservedMethodNames: ReadonlySet, run: (self: Self, effect: Effect.Effect) => Promise, ): void => { const methods = rpc ?? {}; RpcDefinition.assertNoReservedMethods(target, methods, reservedMethodNames); for (const [key, method] of Object.entries(methods)) { Object.defineProperty(prototype, key, { enumerable: true, value(this: Self, ...args: AnyArgs) { return run( this, Effect.suspend(() => method(...args)), ); }, }); } }; export const assumeEntrypointClass = (entrypoint: unknown): Class => entrypoint as Class;