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"; import * as QueryTransactionContext from "./QueryTransactionContext"; export type Options = MutationTransactionContext.QueryOptions; const run = Effect.fn("QueryRunner.runQuery")( (effect: Effect.Effect): Effect.Effect => effect, ); const make = (nativeRunQuery: GenericActionCtx["runQuery"]) => { function runQuery( query: Query, ...args: [...Ref.OptionalArgs, options?: undefined] ): Effect.Effect, Ref.Error | Schema.SchemaError>; function runQuery( query: Query, args: Ref.Args, options: | (QueryTransactionContext.Options & { readonly useStaleSnapshot?: never; }) | undefined, ): Effect.Effect< Ref.Returns, Ref.Error | Schema.SchemaError, QueryTransactionContext.QueryTransactionContext >; function runQuery( query: Query, args: Ref.Args, options: Options & { readonly useStaleSnapshot: boolean }, ): Effect.Effect< Ref.Returns, Ref.Error | Schema.SchemaError, MutationTransactionContext.MutationTransactionContext >; function runQuery( query: Query, args: Ref.Args, options: Options | undefined, ): Effect.Effect< Ref.Returns, Ref.Error | Schema.SchemaError, | QueryTransactionContext.QueryTransactionContext | MutationTransactionContext.MutationTransactionContext >; function runQuery( query: Query, args?: Ref.Args, options?: Options, ): Effect.Effect< Ref.Returns, Ref.Error | Schema.SchemaError, | QueryTransactionContext.QueryTransactionContext | MutationTransactionContext.MutationTransactionContext > { return run( Effect.gen(function* () { const actualArgs = (args ?? {}) as Ref.Args; if (options?.useStaleSnapshot !== undefined) { const controls = yield* MutationTransactionContext.MutationTransactionContext; return yield* controls.runQuery(query, actualArgs, options); } if (options !== undefined) { const controls = yield* QueryTransactionContext.QueryTransactionContext; return yield* controls.runQuery(query, actualArgs, options); } return yield* Ref.runWithCodec(query, actualArgs, (ref, encodedArgs) => nativeRunQuery(ref, encodedArgs), ); }), ); } return { runQuery }; }; export const QueryRunner = Context.Service>( "@confect/server/QueryRunner", ); export type QueryRunner = typeof QueryRunner.Identifier; export const layer = (runQuery: GenericActionCtx["runQuery"]) => Layer.succeed(QueryRunner, make(runQuery));