Skip to content

Commit f1b1446

Browse files
committed
nested workflow
1 parent ec6a2b5 commit f1b1446

File tree

10 files changed

+397
-166
lines changed

10 files changed

+397
-166
lines changed

example/convex/_generated/api.d.ts

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,21 @@ export declare const components: {
105105
startedAt: number;
106106
workId?: string;
107107
}
108+
| {
109+
args: any;
110+
argsSize: number;
111+
completedAt?: number;
112+
handle: string;
113+
inProgress: boolean;
114+
kind: "workflow";
115+
name: string;
116+
runResult?:
117+
| { kind: "success"; returnValue: any }
118+
| { error: string; kind: "failed" }
119+
| { kind: "canceled" };
120+
startedAt: number;
121+
workflowId?: string;
122+
}
108123
| {
109124
args: { eventId?: string };
110125
argsSize: number;
@@ -118,7 +133,6 @@ export declare const components: {
118133
| { error: string; kind: "failed" }
119134
| { kind: "canceled" };
120135
startedAt: number;
121-
workId?: string;
122136
};
123137
stepNumber: number;
124138
workflowId: string;
@@ -170,6 +184,21 @@ export declare const components: {
170184
startedAt: number;
171185
workId?: string;
172186
}
187+
| {
188+
args: any;
189+
argsSize: number;
190+
completedAt?: number;
191+
handle: string;
192+
inProgress: boolean;
193+
kind: "workflow";
194+
name: string;
195+
runResult?:
196+
| { kind: "success"; returnValue: any }
197+
| { error: string; kind: "failed" }
198+
| { kind: "canceled" };
199+
startedAt: number;
200+
workflowId?: string;
201+
}
173202
| {
174203
args: { eventId?: string };
175204
argsSize: number;
@@ -183,7 +212,6 @@ export declare const components: {
183212
| { error: string; kind: "failed" }
184213
| { kind: "canceled" };
185214
startedAt: number;
186-
workId?: string;
187215
};
188216
}>;
189217
workflowId: string;
@@ -218,6 +246,21 @@ export declare const components: {
218246
startedAt: number;
219247
workId?: string;
220248
}
249+
| {
250+
args: any;
251+
argsSize: number;
252+
completedAt?: number;
253+
handle: string;
254+
inProgress: boolean;
255+
kind: "workflow";
256+
name: string;
257+
runResult?:
258+
| { kind: "success"; returnValue: any }
259+
| { error: string; kind: "failed" }
260+
| { kind: "canceled" };
261+
startedAt: number;
262+
workflowId?: string;
263+
}
221264
| {
222265
args: { eventId?: string };
223266
argsSize: number;
@@ -231,7 +274,6 @@ export declare const components: {
231274
| { error: string; kind: "failed" }
232275
| { kind: "canceled" };
233276
startedAt: number;
234-
workId?: string;
235277
};
236278
stepNumber: number;
237279
workflowId: string;
@@ -302,6 +344,21 @@ export declare const components: {
302344
startedAt: number;
303345
workId?: string;
304346
}
347+
| {
348+
args: any;
349+
argsSize: number;
350+
completedAt?: number;
351+
handle: string;
352+
inProgress: boolean;
353+
kind: "workflow";
354+
name: string;
355+
runResult?:
356+
| { kind: "success"; returnValue: any }
357+
| { error: string; kind: "failed" }
358+
| { kind: "canceled" };
359+
startedAt: number;
360+
workflowId?: string;
361+
}
305362
| {
306363
args: { eventId?: string };
307364
argsSize: number;
@@ -315,7 +372,6 @@ export declare const components: {
315372
| { error: string; kind: "failed" }
316373
| { kind: "canceled" };
317374
startedAt: number;
318-
workId?: string;
319375
};
320376
stepNumber: number;
321377
workflowId: string;

src/client/step.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ export type StepRequest = {
3737
| {
3838
kind: "event";
3939
args: { eventId?: EventId<string> };
40+
}
41+
| {
42+
kind: "workflow";
43+
function: FunctionReference<"mutation", "internal">;
44+
args: unknown;
4045
};
4146
retry: RetryBehavior | boolean | undefined;
4247
schedulerOptions: SchedulerOptions;
@@ -163,15 +168,22 @@ export class StepExecutor {
163168
target.kind === "function"
164169
? {
165170
kind: "function" as const,
166-
...commonFields,
167171
functionType: target.functionType,
168172
handle: await createFunctionHandle(target.function),
169-
}
170-
: {
171-
kind: "event" as const,
172173
...commonFields,
173-
args: target.args,
174-
};
174+
}
175+
: target.kind === "workflow"
176+
? {
177+
kind: "workflow" as const,
178+
handle: await createFunctionHandle(target.function),
179+
...commonFields,
180+
}
181+
: {
182+
kind: "event" as const,
183+
eventId: target.args.eventId,
184+
...commonFields,
185+
args: target.args,
186+
};
175187
return {
176188
retry: message.retry,
177189
schedulerOptions: message.schedulerOptions,

src/client/stepContext.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,24 @@ export class StepContext implements WorkflowStep {
4242
return this.runFunction("action", action, args, opts);
4343
}
4444

45+
async runWorkflow<Workflow extends FunctionReference<"mutation", "internal">>(
46+
workflow: Workflow,
47+
args: FunctionArgs<Workflow>,
48+
opts?: RunOptions,
49+
): Promise<FunctionReturnType<Workflow>> {
50+
const { name, ...schedulerOptions } = opts ?? {};
51+
return this.run({
52+
name: name ?? safeFunctionName(workflow),
53+
target: {
54+
kind: "workflow",
55+
function: workflow,
56+
args,
57+
},
58+
retry: undefined,
59+
schedulerOptions,
60+
});
61+
}
62+
4563
async awaitEvent<T, Name extends string = string>(
4664
event: EventSpec<Name, T>,
4765
): Promise<T> {

src/client/types.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,19 @@ export type WorkflowStep = {
8282
opts?: RunOptions & RetryOption,
8383
): Promise<FunctionReturnType<Action>>;
8484

85+
/**
86+
* Run a workflow with the given name and arguments.
87+
*
88+
* @param workflow - The workflow to run, like `internal.index.exampleWorkflow`.
89+
* @param args - The arguments to the workflow function.
90+
* @param opts - Options for retrying, scheduling and naming the workflow.
91+
*/
92+
runWorkflow<Workflow extends FunctionReference<"mutation", "internal">>(
93+
workflow: Workflow,
94+
args: FunctionArgs<Workflow>,
95+
opts?: RunOptions,
96+
): Promise<FunctionReturnType<Workflow>>;
97+
8598
/**
8699
* Blocks until a matching event is sent to this workflow.
87100
*

src/component/_generated/api.d.ts

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,21 @@ export type Mounts = {
9999
startedAt: number;
100100
workId?: string;
101101
}
102+
| {
103+
args: any;
104+
argsSize: number;
105+
completedAt?: number;
106+
handle: string;
107+
inProgress: boolean;
108+
kind: "workflow";
109+
name: string;
110+
runResult?:
111+
| { kind: "success"; returnValue: any }
112+
| { error: string; kind: "failed" }
113+
| { kind: "canceled" };
114+
startedAt: number;
115+
workflowId?: string;
116+
}
102117
| {
103118
args: { eventId?: string };
104119
argsSize: number;
@@ -112,7 +127,6 @@ export type Mounts = {
112127
| { error: string; kind: "failed" }
113128
| { kind: "canceled" };
114129
startedAt: number;
115-
workId?: string;
116130
};
117131
stepNumber: number;
118132
workflowId: string;
@@ -164,6 +178,21 @@ export type Mounts = {
164178
startedAt: number;
165179
workId?: string;
166180
}
181+
| {
182+
args: any;
183+
argsSize: number;
184+
completedAt?: number;
185+
handle: string;
186+
inProgress: boolean;
187+
kind: "workflow";
188+
name: string;
189+
runResult?:
190+
| { kind: "success"; returnValue: any }
191+
| { error: string; kind: "failed" }
192+
| { kind: "canceled" };
193+
startedAt: number;
194+
workflowId?: string;
195+
}
167196
| {
168197
args: { eventId?: string };
169198
argsSize: number;
@@ -177,7 +206,6 @@ export type Mounts = {
177206
| { error: string; kind: "failed" }
178207
| { kind: "canceled" };
179208
startedAt: number;
180-
workId?: string;
181209
};
182210
}>;
183211
workflowId: string;
@@ -212,6 +240,21 @@ export type Mounts = {
212240
startedAt: number;
213241
workId?: string;
214242
}
243+
| {
244+
args: any;
245+
argsSize: number;
246+
completedAt?: number;
247+
handle: string;
248+
inProgress: boolean;
249+
kind: "workflow";
250+
name: string;
251+
runResult?:
252+
| { kind: "success"; returnValue: any }
253+
| { error: string; kind: "failed" }
254+
| { kind: "canceled" };
255+
startedAt: number;
256+
workflowId?: string;
257+
}
215258
| {
216259
args: { eventId?: string };
217260
argsSize: number;
@@ -225,7 +268,6 @@ export type Mounts = {
225268
| { error: string; kind: "failed" }
226269
| { kind: "canceled" };
227270
startedAt: number;
228-
workId?: string;
229271
};
230272
stepNumber: number;
231273
workflowId: string;
@@ -296,6 +338,21 @@ export type Mounts = {
296338
startedAt: number;
297339
workId?: string;
298340
}
341+
| {
342+
args: any;
343+
argsSize: number;
344+
completedAt?: number;
345+
handle: string;
346+
inProgress: boolean;
347+
kind: "workflow";
348+
name: string;
349+
runResult?:
350+
| { kind: "success"; returnValue: any }
351+
| { error: string; kind: "failed" }
352+
| { kind: "canceled" };
353+
startedAt: number;
354+
workflowId?: string;
355+
}
299356
| {
300357
args: { eventId?: string };
301358
argsSize: number;
@@ -309,7 +366,6 @@ export type Mounts = {
309366
| { error: string; kind: "failed" }
310367
| { kind: "canceled" };
311368
startedAt: number;
312-
workId?: string;
313369
};
314370
stepNumber: number;
315371
workflowId: string;

src/component/event.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ export async function awaitEvent(
5858
}
5959
assert(entry.step.kind === "event", "Step is not an event");
6060
entry.step.eventId = event._id;
61-
await ctx.db.replace(entry._id, entry);
6261
// if there's a name, see if there's one to consume.
6362
// if it's there, mark it consumed and swap in the result.
6463
return entry;

0 commit comments

Comments
 (0)