import * as Ref from "@confect/core/Ref"; import type { GenericActionCtx } from "convex/server"; import * as Context from "effect/Context"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; import type * as Schema from "effect/Schema"; import * as MutationTransactionContext from "./MutationTransactionContext"; export type Options = MutationTransactionContext.MutationOptions; const run = Effect.fn("MutationRunner.runMutation")( (effect: Effect.Effect): Effect.Effect => effect, ); const make = (nativeRunMutation: GenericActionCtx["runMutation"]) => { function runMutation( mutation: Mutation, ...args: [...Ref.OptionalArgs, options?: undefined] ): Effect.Effect< Ref.Returns, Ref.Error | Schema.SchemaError >; function runMutation( mutation: Mutation, args: Ref.Args, options: Options | undefined, ): Effect.Effect< Ref.Returns, Ref.Error | Schema.SchemaError, MutationTransactionContext.MutationTransactionContext >; function runMutation( mutation: Mutation, args?: Ref.Args, options?: Options, ): Effect.Effect< Ref.Returns, Ref.Error | Schema.SchemaError, MutationTransactionContext.MutationTransactionContext > { return run( Effect.gen(function* () { const actualArgs = (args ?? {}) as Ref.Args; if (options !== undefined) { const controls = yield* MutationTransactionContext.MutationTransactionContext; return yield* controls.runMutation(mutation, actualArgs, options); } return yield* Ref.runWithCodec( mutation, actualArgs, (ref, encodedArgs) => nativeRunMutation(ref, encodedArgs), ); }), ); } return { runMutation }; }; export const MutationRunner = Context.Service>( "@confect/server/MutationRunner", ); export type MutationRunner = typeof MutationRunner.Identifier; export const layer = (runMutation: GenericActionCtx["runMutation"]) => Layer.succeed(MutationRunner, make(runMutation));