From 74b095f85d5b25de14a65d9ed03022da226871fb Mon Sep 17 00:00:00 2001 From: Ian Macartney Date: Fri, 17 Oct 2025 14:12:18 -0700 Subject: [PATCH] allow fluent syntax for defining workflows --- example/convex/nestedWorkflow.ts | 14 ++++--- src/client/index.ts | 69 +++++++++++++++++++++++++------- 2 files changed, 62 insertions(+), 21 deletions(-) diff --git a/example/convex/nestedWorkflow.ts b/example/convex/nestedWorkflow.ts index ae4590f..1f737f1 100644 --- a/example/convex/nestedWorkflow.ts +++ b/example/convex/nestedWorkflow.ts @@ -3,9 +3,12 @@ import { workflow } from "./example"; import { internal } from "./_generated/api"; import { internalMutation } from "./_generated/server"; -export const parentWorkflow = workflow.define({ - args: { prompt: v.string() }, - handler: async (ctx, args) => { +export const parentWorkflow = workflow + .define({ + args: { prompt: v.string() }, + returns: v.number(), + }) + .handler(async (ctx, args) => { console.log("Starting confirmation workflow"); const length = await ctx.runWorkflow( internal.nestedWorkflow.childWorkflow, @@ -16,12 +19,11 @@ export const parentWorkflow = workflow.define({ foo: args.prompt, }); console.log("Step result:", stepResult); - }, -}); + return stepResult; + }); export const childWorkflow = workflow.define({ args: { foo: v.string() }, - returns: v.number(), handler: async (_ctx, args) => { console.log("Starting nested workflow"); return args.foo.length; diff --git a/src/client/index.ts b/src/client/index.ts index a64c685..785d817 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -15,12 +15,7 @@ import { type RegisteredMutation, type ReturnValueForOptionalValidator, } from "convex/server"; -import type { - Infer, - ObjectType, - PropertyValidators, - Validator, -} from "convex/values"; +import type { ObjectType, PropertyValidators, Validator } from "convex/values"; import type { Step } from "../component/schema.js"; import type { EventId, @@ -118,15 +113,59 @@ export class WorkflowManager { fn: "You should not call this directly, call workflow.start instead"; args: ObjectType; }, - ReturnsValidator extends Validator - ? Infer - : void - > { - return workflowMutation( - this.component, - workflow, - this.options?.workpoolOptions, - ); + ReturnValueForOptionalValidator + >; + define< + ArgsValidator extends PropertyValidators, + ReturnsValidator extends Validator | void, + >( + workflow: Omit< + WorkflowDefinition, + "handler" + >, + ): { + handler: ( + handler: ( + step: WorkflowCtx, + args: ObjectType, + ) => Promise>, + ) => RegisteredMutation< + "internal", + { + fn: "You should not call this directly, call workflow.start instead"; + args: ObjectType; + }, + ReturnValueForOptionalValidator + >; + }; + define< + ArgsValidator extends PropertyValidators, + ReturnsValidator extends Validator | void, + >( + workflow: + | Omit, "handler"> + | WorkflowDefinition, + ): unknown { + if ("handler" in workflow) { + return workflowMutation( + this.component, + workflow, + this.options?.workpoolOptions, + ); + } + return { + handler: ( + handler: ( + step: WorkflowCtx, + args: ObjectType, + ) => Promise>, + ) => + workflowMutation( + this.component, + { ...workflow, handler }, + this.options?.workpoolOptions, + ), + }; } /**