@@ -71,11 +71,12 @@ export const userOnboarding = workflow.define({
7171});
7272```
7373
74- This component adds durably executed _ workflows_ to Convex. Combine Convex queries, mutations,
75- and actions into long-lived workflows, and the system will always fully execute a workflow
76- to completion.
74+ This component adds durably executed _ workflows_ to Convex. Combine Convex
75+ queries, mutations, and actions into long-lived workflows, and the system will
76+ always fully execute a workflow to completion.
7777
78- Open a [ GitHub issue] ( https://github.com/get-convex/workflow/issues ) with any feedback or bugs you find.
78+ Open a [ GitHub issue] ( https://github.com/get-convex/workflow/issues ) with any
79+ feedback or bugs you find.
7980
8081## Installation
8182
@@ -89,16 +90,16 @@ Then, install the component within your `convex/convex.config.ts` file:
8990
9091``` ts
9192// convex/convex.config.ts
92- import workflow from " @convex-dev/workflow/convex.config" ;
93+ import workflow from " @convex-dev/workflow/convex.config.js " ;
9394import { defineApp } from " convex/server" ;
9495
9596const app = defineApp ();
9697app .use (workflow );
9798export default app ;
9899```
99100
100- Finally, create a workflow manager within your ` convex/ ` folder, and point it
101- to the installed component:
101+ Finally, create a workflow manager within your ` convex/ ` folder, and point it to
102+ the installed component:
102103
103104``` ts
104105// convex/index.ts
@@ -114,13 +115,13 @@ The first step is to define a workflow using `workflow.define()`. This function
114115is designed to feel like a Convex action but with a few restrictions:
115116
1161171 . The workflow runs in the background, so it can't return a value.
117- 2 . The workflow must be _ deterministic_ , so it should implement most of its logic
118- by calling out to other Convex functions. We restrict access to some
118+ 2 . The workflow must be _ deterministic_ , so it should implement most of its
119+ logic by calling out to other Convex functions. We restrict access to some
119120 non-deterministic functions like ` fetch ` and ` crypto ` . Others we patch, such
120121 as ` console ` for logging, ` Math.random() ` (seeded PRNG) and ` Date ` for time.
121122
122- Note: To help avoid type cycles, always annotate the return type of the ` handler `
123- with the return type of the workflow.
123+ Note: To help avoid type cycles, always annotate the return type of the
124+ ` handler ` with the return type of the workflow.
124125
125126``` ts
126127export const exampleWorkflow = workflow .define ({
@@ -157,8 +158,8 @@ export const exampleAction = internalAction({
157158
158159### Starting a workflow
159160
160- Once you've defined a workflow, you can start it from a mutation or action
161- using ` workflow.start() ` .
161+ Once you've defined a workflow, you can start it from a mutation or action using
162+ ` workflow.start() ` .
162163
163164``` ts
164165export const kickoffWorkflow = mutation ({
@@ -228,8 +229,8 @@ export const handleOnComplete = mutation({
228229
229230### Running steps in parallel
230231
231- You can run steps in parallel by calling ` step.runAction() ` multiple times in
232- a ` Promise.all() ` call.
232+ You can run steps in parallel by calling ` step.runAction() ` multiple times in a
233+ ` Promise.all() ` call.
233234
234235``` ts
235236export const exampleWorkflow = workflow .define ({
@@ -243,20 +244,21 @@ export const exampleWorkflow = workflow.define({
243244});
244245```
245246
246- Note: The workflow will not proceed until all steps fired off at once have completed.
247+ Note: The workflow will not proceed until all steps fired off at once have
248+ completed.
247249
248250### Specifying retry behavior
249251
250252Sometimes actions fail due to transient errors, whether it was an unreliable
251253third-party API or a server restart. You can have the workflow automatically
252- retry actions using best practices (exponential backoff & jitter).
253- By default there are no retries, and the workflow will fail.
254+ retry actions using best practices (exponential backoff & jitter). By default
255+ there are no retries, and the workflow will fail.
254256
255257You can specify default retry behavior for all workflows on the WorkflowManager,
256258or override it on a per-workflow basis.
257259
258- You can also specify a custom retry behavior per-step, to opt-out of retries
259- for actions that may want at-most-once semantics.
260+ You can also specify a custom retry behavior per-step, to opt-out of retries for
261+ actions that may want at-most-once semantics.
260262
261263Workpool options:
262264
@@ -270,8 +272,8 @@ If you specify any of these, it will override the
270272- ` retryActionsByDefault ` : Whether to retry actions, by default is false.
271273 - If you specify a retry behavior at the step level, it will always retry.
272274
273- At the step level, you can also specify ` true ` or ` false ` to disable or use
274- the default policy.
275+ At the step level, you can also specify ` true ` or ` false ` to disable or use the
276+ default policy.
275277
276278``` ts
277279const workflow = new WorkflowManager (components .workflow , {
@@ -306,11 +308,10 @@ export const exampleWorkflow = workflow.define({
306308### Specifying step parallelism
307309
308310You can specify how many steps can run in parallel by setting the
309- ` maxParallelism ` workpool option. It has a reasonable default.
310- On the free tier, you should not exceed 20, otherwise your other scheduled
311- functions may become delayed while competing for available functions with your
312- workflow steps.
313- On a Pro account, you should not exceed 100 across all your workflows and workpools.
311+ ` maxParallelism ` workpool option. It has a reasonable default. On the free tier,
312+ you should not exceed 20, otherwise your other scheduled functions may become
313+ delayed while competing for available functions with your workflow steps. On a
314+ Pro account, you should not exceed 100 across all your workflows and workpools.
314315If you want to do a lot of work in parallel, you should employ batching, where
315316each workflow operates on a batch of work, e.g. scraping a list of links instead
316317of one link per workflow.
@@ -328,8 +329,8 @@ const workflow = new WorkflowManager(components.workflow, {
328329
329330### Checking a workflow's status
330331
331- The ` workflow.start() ` method returns a ` WorkflowId ` , which can then be used for querying
332- a workflow's status.
332+ The ` workflow.start() ` method returns a ` WorkflowId ` , which can then be used for
333+ querying a workflow's status.
333334
334335``` ts
335336export const kickoffWorkflow = action ({
@@ -349,8 +350,9 @@ export const kickoffWorkflow = action({
349350
350351### Canceling a workflow
351352
352- You can cancel a workflow with ` workflow.cancel() ` , halting the workflow's execution immmediately.
353- In-progress calls to ` step.runAction() ` , however, will finish executing.
353+ You can cancel a workflow with ` workflow.cancel() ` , halting the workflow's
354+ execution immmediately. In-progress calls to ` step.runAction() ` , however, will
355+ finish executing.
354356
355357``` ts
356358export const kickoffWorkflow = action ({
@@ -370,8 +372,9 @@ export const kickoffWorkflow = action({
370372
371373### Cleaning up a workflow
372374
373- After a workflow has completed, you can clean up its storage with ` workflow.cleanup() ` .
374- Completed workflows are not automatically cleaned up by the system.
375+ After a workflow has completed, you can clean up its storage with
376+ ` workflow.cleanup() ` . Completed workflows are not automatically cleaned up by
377+ the system.
375378
376379``` ts
377380export const kickoffWorkflow = action ({
@@ -402,8 +405,8 @@ export const kickoffWorkflow = action({
402405
403406You can specify a custom name for a step by passing a ` name ` option to the step.
404407
405- This allows the events emitted to your logs to be more descriptive.
406- By default it uses the ` file/folder:function ` name.
408+ This allows the events emitted to your logs to be more descriptive. By default
409+ it uses the ` file/folder:function ` name.
407410
408411``` ts
409412export const exampleWorkflow = workflow .define ({
@@ -418,9 +421,11 @@ export const exampleWorkflow = workflow.define({
418421
419422### Circular dependencies
420423
421- Having the return value of workflows depend on other Convex functions can lead to circular dependencies due to the
422- ` internal.foo.bar ` way of specifying functions. The way to fix this is to explicitly type the return value of the
423- workflow. When in doubt, add return types to more ` handler ` functions, like this:
424+ Having the return value of workflows depend on other Convex functions can lead
425+ to circular dependencies due to the ` internal.foo.bar ` way of specifying
426+ functions. The way to fix this is to explicitly type the return value of the
427+ workflow. When in doubt, add return types to more ` handler ` functions, like
428+ this:
424429
425430``` diff
426431 export const supportAgentWorkflow = workflow.define({
@@ -441,8 +446,8 @@ workflow. When in doubt, add return types to more `handler` functions, like this
441446
442447### More concise workflows
443448
444- To avoid the noise of ` internal.foo.* ` syntax, you can use a variable.
445- For instance, if you define all your steps in ` convex/steps.ts ` , you can do this:
449+ To avoid the noise of ` internal.foo.* ` syntax, you can use a variable. For
450+ instance, if you define all your steps in ` convex/steps.ts ` , you can do this:
446451
447452``` diff
448453 const s = internal.steps;
@@ -469,15 +474,16 @@ Here are a few limitations to keep in mind:
469474 mutation apply and limit the number and size of steps you can perform to 16MiB
470475 (including the workflow state overhead). See more about mutation limits here:
471476 https://docs.convex.dev/production/state/limits#transactions
472- - We currently do not collect backtraces from within function calls from workflows.
477+ - We currently do not collect backtraces from within function calls from
478+ workflows.
473479- If you need to use side effects like ` fetch ` or use cryptographic randomness,
474480 you'll need to do that in a step, not in the workflow definition.
475481- ` Math.random ` is deterministic and not suitable for cryptographic use. It is,
476482 however, useful for sharding, jitter, and other pseudo-random applications.
477483- If the implementation of the workflow meaningfully changes (steps added,
478- removed, or reordered) then it will fail with a determinism violation.
479- The implementation should stay stable for the lifetime of active workflows.
480- See [ this issue] ( https://github.com/get-convex/workflow/issues/35 ) for ideas
481- on how to make this better.
484+ removed, or reordered) then it will fail with a determinism violation. The
485+ implementation should stay stable for the lifetime of active workflows. See
486+ [ this issue] ( https://github.com/get-convex/workflow/issues/35 ) for ideas on
487+ how to make this better.
482488
483489<!-- END: Include on https://convex.dev/components -->
0 commit comments