import { Ref } from "@confect/core"; import type { Scheduler as ConvexScheduler } from "convex/server"; import type { GenericId } from "convex/values"; import * as Context from "effect/Context"; import * as DateTime from "effect/DateTime"; import * as Duration from "effect/Duration"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; const make = (scheduler: ConvexScheduler) => ({ cancel: (id: GenericId<"_scheduled_functions">) => Effect.promise(() => scheduler.cancel(id)), runAfter: ( delay: Duration.Duration, ref: Ref_, ...args: Ref.OptionalArgs ) => { const delayMs = Duration.toMillis(delay); const functionReference = Ref.getFunctionReference(ref); const encodedArgs = Ref.encodeArgsSync( ref, (args[0] ?? {}) as Ref.Args, ); return Effect.promise(() => scheduler.runAfter(delayMs, functionReference, encodedArgs), ); }, runAt: ( dateTime: DateTime.DateTime, ref: Ref_, ...args: Ref.OptionalArgs ) => { const timestamp = DateTime.toEpochMillis(dateTime); const functionReference = Ref.getFunctionReference(ref); const encodedArgs = Ref.encodeArgsSync( ref, (args[0] ?? {}) as Ref.Args, ); return Effect.promise(() => scheduler.runAt(timestamp, functionReference, encodedArgs), ); }, }); export const Scheduler = Context.Service>( "@confect/server/Scheduler", ); export type Scheduler = typeof Scheduler.Identifier; export const layer = (scheduler: ConvexScheduler) => Layer.succeed(Scheduler, make(scheduler));