Skip to content

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Dec 3, 2025

Summary

Adds documentation for two workflow context features that were previously undocumented:

ctx.awaitEvent: Explains how workflows can pause and wait for external events. Documents basic usage first (awaiting by name or by ID), then introduces defineEvent as a separate concept for sharing event names and validators between workflow and sender.

ctx.runWorkflow: Explains how to run nested workflows as a single step, including scheduling options.

The documentation uses focused code snippets and links to example files for complete, compilable implementations.

Updates since last revision

  • Added as const to the defineEvent example name field for proper type inference (per reviewer feedback)
  • Added explicit value: { approved: true } in the sendEvent example to show actual usage
  • Restructured ctx.awaitEvent section: basic usage (by name/ID) is explained first, then defineEvent is introduced separately
  • Uses small, focused code blocks instead of inline code mixed with prose for better readability
  • Links to example/convex/passingSignals.ts for event ID patterns and example/convex/userConfirmation.ts for defineEvent usage

Review & Testing Checklist for Human

  • Verify the as const usage in the defineEvent example is correct and matches the actual API requirements
  • Confirm the relative links to example files render correctly on GitHub
  • Check that the code snippets accurately represent the API (note: snippets are intentionally minimal and may need imports/context to compile)

Notes

Co-Authored-By: Ian Macartney ian@convex.dev

Co-Authored-By: Ian Macartney <ian@convex.dev>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@coderabbitai
Copy link

coderabbitai bot commented Dec 3, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch devin/1764724449-add-await-event-run-workflow-docs

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 3, 2025

Open in StackBlitz

npm i https://pkg.pr.new/get-convex/workflow/@convex-dev/workflow@174

commit: 48b1dab

README.md Outdated
To send the event from elsewhere (e.g., after a user clicks a button):

```ts
import { vWorkflowId, WorkflowManager } from "@convex-dev/workflow";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both this and the above code snippet don't include the workflow variable, and import WorkflowManager but don't use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed! I've added the workflow variable creation and necessary imports to the code snippets:

  • First snippet now shows const workflow = new WorkflowManager(components.workflow) and imports components, internal
  • Second snippet now imports mutation from _generated/server and has a comment noting that workflow and approvalEvent are defined above
  • Third snippet (awaiting by ID) also now shows the full setup with workflow creation

devin-ai-integration bot and others added 3 commits December 3, 2025 01:19
Co-Authored-By: Ian Macartney <ian@convex.dev>
Co-Authored-By: Ian Macartney <ian@convex.dev>
Co-Authored-By: Ian Macartney <ian@convex.dev>
@ianmacartney
Copy link
Contributor

@Nicolapps would this have sufficed for you?

Copy link
Member

@Nicolapps Nicolapps left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

README.md Outdated

```ts
const approvalEvent = defineEvent({
name: "approval",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m a little bit confused by what’s going on here:

  • Why are we using "approval" here and not v.literal("approval")?
  • Why are you using "approval" as const in the example but not here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are great questions about the API design! I documented the current API behavior based on the existing implementation in src/client/index.ts and the example files. The name field is a plain string (not a validator) because defineEvent just returns the spec object as-is for spreading. The as const in the example file is for TypeScript type narrowing but isn't strictly required.

I'll defer to @ianmacartney on whether the API design should be changed or if the documentation should explain the rationale for these choices.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch - the as const was necessary before defineEvent, which captures the literal value.
It isn't a validator, as we need a single concrete value. When we await an event, we register what we're waiting for by the name. So a validator would imply we could pass a union of literals or a string etc.

README.md Outdated
const approval = await ctx.awaitEvent(approvalEvent);

// From a mutation:
await workflow.sendEvent(ctx, { ...approvalEvent, workflowId, value });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line looks confusing to me. Why does the API want you to spread the return value of defineEvent? Instead of having something like:

await workflow.sendEvent(ctx, { event: approvalEvent, workflowId, value: { approved: true } });

Also, the code example here doesn’t show what value is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point about the value not being shown! The spread syntax is how the current API works - defineEvent returns { name, validator } which gets spread into the sendEvent call along with workflowId and value.

I can update the example to show the actual value being passed:

await workflow.sendEvent(ctx, { ...approvalEvent, workflowId, value: { approved: true } });

The API design question about whether it should use { event: approvalEvent } instead of spreading is a good one for @ianmacartney to weigh in on.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great question, and it was something I went back & forth on in the design quite a bit. Essentially defineEvent is a convenience over passing in the name and validator directly.
You can call workflow.sendEvent(ctx, { name, workflowId }) or workflow.sendEvent(ctx, { id: eventId }), and spreading helps keep the types simpler - where the validator and value match in the same generic.

devin-ai-integration bot and others added 2 commits December 4, 2025 18:15
Co-Authored-By: Ian Macartney <ian@convex.dev>
Co-Authored-By: Ian Macartney <ian@convex.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants