Skip to content

Commit d7161a6

Browse files
Document events and nested workflows
1 parent 9f81a6e commit d7161a6

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,62 @@ export const exampleWorkflow = workflow.define({
415415
});
416416
```
417417

418+
### Awaiting events with `ctx.awaitEvent`
419+
420+
Use `ctx.awaitEvent` inside a workflow handler to pause until an external event
421+
is delivered. This is useful for human-in-the-loop flows or coordinating with
422+
other systems.
423+
424+
At its simplest, you can wait for an event **by name**:
425+
426+
```ts
427+
await ctx.awaitEvent({ name: "approval" });
428+
```
429+
430+
or for a **specific event by ID**:
431+
432+
```ts
433+
await ctx.awaitEvent({ id: signalId });
434+
```
435+
436+
To unblock a waiting workflow, call `workflow.sendEvent` from a mutation or
437+
action. You can send a value with the event, or send an error that will cause
438+
`ctx.awaitEvent` to throw. See
439+
[`example/convex/passingSignals.ts`](./example/convex/passingSignals.ts) for a
440+
complete example of creating events, passing their IDs around, and sending
441+
signals.
442+
443+
#### Sharing event definitions with `defineEvent`
444+
445+
Use `defineEvent` to define an event's name and validator in one place, then
446+
share it between the workflow and the sender:
447+
448+
```ts
449+
const approvalEvent = defineEvent({
450+
name: "approval" as const,
451+
validator: v.object({ approved: v.boolean() }),
452+
});
453+
454+
// In the workflow:
455+
const approval = await ctx.awaitEvent(approvalEvent);
456+
457+
// From a mutation:
458+
await workflow.sendEvent(ctx, { ...approvalEvent, workflowId, value: { approved: true } });
459+
```
460+
461+
See [`example/convex/userConfirmation.ts`](./example/convex/userConfirmation.ts)
462+
for a full approval flow built this way.
463+
464+
### Running nested workflows with `ctx.runWorkflow`
465+
466+
Use `ctx.runWorkflow` to run another workflow as a single step in the current
467+
one. The parent workflow waits for the nested workflow to finish and receives
468+
its return value: `const result = await ctx.runWorkflow(internal.example.childWorkflow, { args });`
469+
470+
You can also specify scheduling options like `{ runAfter: 5000 }` to delay the
471+
nested workflow. See [`example/convex/nestedWorkflow.ts`](./example/convex/nestedWorkflow.ts)
472+
for a complete parent/child workflow example.
473+
418474
## Tips and troubleshooting
419475

420476
### Circular dependencies

example/convex/userConfirmation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { components, internal } from "./_generated/api";
88
import { internalAction, internalMutation } from "./_generated/server";
99

1010
export const approvalEvent = defineEvent({
11-
name: "approval" as const,
11+
name: "approval",
1212
validator: v.union(
1313
v.object({ approved: v.literal(true), choice: v.number() }),
1414
v.object({ approved: v.literal(false), reason: v.string() }),

0 commit comments

Comments
 (0)