Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b5b4a9b
up the max journal size to 8MB
ianmacartney Sep 23, 2025
0a6c5c9
reorganize types and call steps in batches
ianmacartney Sep 23, 2025
fa7d43a
make step.workflowId typed
ianmacartney Sep 24, 2025
5c5593a
stricter types
ianmacartney Sep 25, 2025
24b8f2c
build update
ianmacartney Sep 25, 2025
72f513b
type nit
ianmacartney Sep 25, 2025
1c90249
support date.now
ianmacartney Sep 25, 2025
21f0324
support console in workflows
ianmacartney Sep 25, 2025
6400878
pass in oncomplete for workflow
ianmacartney Sep 25, 2025
907a278
update example
ianmacartney Sep 25, 2025
4e5452b
more paranoid parsing of stepId
ianmacartney Sep 25, 2025
8aa530c
use name for workflow process
ianmacartney Sep 25, 2025
e6edc78
fix reorg
ianmacartney Sep 25, 2025
ba83449
no separate example install
ianmacartney Sep 25, 2025
fd23f6e
count isn't supported in convex til
ianmacartney Sep 25, 2025
0ec950e
more explicit console wrapping
ianmacartney Sep 25, 2025
d881eb4
log error in workflows
ianmacartney Sep 25, 2025
03f5044
add console to example
ianmacartney Sep 25, 2025
3b28a85
console
ianmacartney Sep 25, 2025
399d4b4
clean up environment
ianmacartney Sep 25, 2025
0947f52
comment how to cleanup
ianmacartney Sep 25, 2025
b99312b
ignore build info
ianmacartney Sep 25, 2025
847ac63
readme
ianmacartney Sep 25, 2025
2000135
update workpool
ianmacartney Sep 25, 2025
8f3105e
0.2.7-alpha.0
ianmacartney Sep 25, 2025
fa9fffd
update workpool fix
ianmacartney Sep 27, 2025
1217aaf
console cleanups
ianmacartney Sep 25, 2025
1f9c3c0
lint
ianmacartney Sep 25, 2025
194752b
error formatting with stack
ianmacartney Sep 25, 2025
baedaeb
clean up environment patching
ianmacartney Sep 27, 2025
b434ed2
check generation number before logging or marking other failures
ianmacartney Sep 25, 2025
f226715
test environment
ianmacartney Oct 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ node_modules
frontend/package.json
# npm pack output
*.tgz
*.tsbuildinfo
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## 0.2.7 alpha

- Support for console logging & timing in workflows
- Support for Date.now() in workflows
- Batches the call to start steps
- Adds the workflow name to the workpool execution for observability
- Logs any error that shows up in the workflow body
- Will call onComplete for Workflows with startAsync that fail
on their first invocation.
- Increases the max journal size from 1MB to 8MB
- Adds the WorkflowId type to step.workflowId

## 0.2.6

- Allow calling components directly from steps
Expand Down
27 changes: 8 additions & 19 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,37 @@
## Running locally

```sh
npm i
cd example
npm i
npx convex dev
npm run setup
npm run dev
```

## Testing

```sh
rm -rf dist/ && npm run build
npm run clean
npm run typecheck
npm run test
cd example
npm run lint
cd ..
npm run test
```

## Deploying

### Building a one-off package

```sh
rm -rf dist/ && npm run build
npm run clean
npm run build
npm pack
```

### Deploying a new version

```sh
# this will change the version and commit it (if you run it in the root directory)
npm version patch
npm publish --dry-run
# sanity check files being included
npm publish
git push --tags
npm run release
```

#### Alpha release

The same as above, but it requires extra flags so the release is only installed with `@alpha`:

```sh
npm version prerelease --preid alpha
npm publish --tag alpha
npm run alpha
```
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Welcome to the world of Convex workflows.
- Output from previous steps is available to pass to subsequent steps.
- Run queries, mutations, and actions.
- Specify retry behavior on a per-step basis, along with a default policy.
- Specify how many workflows can run in parallel to manage load.
- Specify how many workflow steps can run in parallel to manage load.
- Cancel long-running workflows.
- Clean up workflows after they're done.

Expand Down Expand Up @@ -447,10 +447,8 @@ Here are a few limitations to keep in mind:
mutation apply and limit the number and size of steps you can perform to 16MiB
(including the workflow state overhead). See more about mutation limits here:
https://docs.convex.dev/production/state/limits#transactions
- `console.log()` isn't currently captured, so you may see duplicate log lines
within your Convex dashboard if you log within the workflow definition.
- We currently do not collect backtraces from within function calls from workflows.
- If you need to use side effects like `fetch`, `Math.random()`, or `Date.now()`,
- If you need to use side effects like `fetch` or use randomness,
you'll need to do that in a step, not in the workflow definition.
- If the implementation of the workflow meaningfully changes (steps added,
removed, or reordered) then it will fail with a determinism violation.
Expand Down
3 changes: 3 additions & 0 deletions convex.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"functions": "example/convex"
}
16 changes: 0 additions & 16 deletions example/.gitignore

This file was deleted.

47 changes: 24 additions & 23 deletions example/convex/_generated/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,31 +91,32 @@ export declare const components: {
};
}
>;
startStep: FunctionReference<
startSteps: FunctionReference<
"mutation",
"internal",
{
generationNumber: number;
name: string;
retry?:
| boolean
| { base: number; initialBackoffMs: number; maxAttempts: number };
schedulerOptions?: { runAt?: number } | { runAfter?: number };
step: {
args: any;
argsSize: number;
completedAt?: number;
functionType: "query" | "mutation" | "action";
handle: string;
inProgress: boolean;
name: string;
runResult?:
| { kind: "success"; returnValue: any }
| { error: string; kind: "failed" }
| { kind: "canceled" };
startedAt: number;
workId?: string;
};
steps: Array<{
retry?:
| boolean
| { base: number; initialBackoffMs: number; maxAttempts: number };
schedulerOptions?: { runAt?: number } | { runAfter?: number };
step: {
args: any;
argsSize: number;
completedAt?: number;
functionType: "query" | "mutation" | "action";
handle: string;
inProgress: boolean;
name: string;
runResult?:
| { kind: "success"; returnValue: any }
| { error: string; kind: "failed" }
| { kind: "canceled" };
startedAt: number;
workId?: string;
};
}>;
workflowId: string;
workpoolOptions?: {
defaultRetryBehavior?: {
Expand All @@ -128,7 +129,7 @@ export declare const components: {
retryActionsByDefault?: boolean;
};
},
{
Array<{
_creationTime: number;
_id: string;
step: {
Expand All @@ -148,7 +149,7 @@ export declare const components: {
};
stepNumber: number;
workflowId: string;
}
}>
>;
};
workflow: {
Expand Down
14 changes: 12 additions & 2 deletions example/convex/example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@ export const exampleWorkflow = workflow.define({
windSpeed: number;
windGust: number;
}> => {
console.time("overall");
console.time("geocoding");
// Run in parallel!
const [{ latitude, longitude, name }, weather2] = await Promise.all([
step.runAction(internal.example.getGeocoding, args, { runAfter: 100 }),
step.runAction(internal.example.getGeocoding, args, { retry: true }),
]);
console.log("Is geocoding is consistent?", latitude === weather2.latitude);

console.timeLog("geocoding", name);
console.time("weather");
const weather = await step.runAction(internal.example.getWeather, {
latitude,
longitude,
Expand All @@ -45,6 +48,12 @@ export const exampleWorkflow = workflow.define({
console.log(
`Weather in ${name}: ${farenheit.toFixed(1)}°F (${temperature}°C), ${windSpeed} km/h, ${windGust} km/h`,
);
console.timeLog("weather", temperature);
await step.runMutation(internal.example.updateFlow, {
workflowId: step.workflowId,
out: { name, celsius, farenheit, windSpeed, windGust },
});
console.timeEnd("overall");
return { name, celsius, farenheit, windSpeed, windGust };
},
workpoolOptions: {
Expand Down Expand Up @@ -109,7 +118,8 @@ export const flowCompleted = internalMutation({
await ctx.db.patch(flow._id, {
out: args.result,
});
await workflow.cleanup(ctx, args.workflowId);
// To delete the workflow data after it completes:
// await workflow.cleanup(ctx, args.workflowId);
},
});

Expand Down
4 changes: 2 additions & 2 deletions example/convex/setup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import schema from "./schema";
export const modules = import.meta.glob("./**/*.*s");

// Sorry about everything
import componentSchema from "../node_modules/@convex-dev/workflow/src/component/schema";
import componentSchema from "../../node_modules/@convex-dev/workflow/src/component/schema";
export { componentSchema };
export const componentModules = import.meta.glob(
"../node_modules/@convex-dev/workflow/src/component/**/*.ts",
"../../node_modules/@convex-dev/workflow/src/component/**/*.ts",
);

export function initConvexTest() {
Expand Down
Loading