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));