workflow 5.0.0-beta.4 → 5.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +5 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +14 -2
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +2 -2
- package/docs/api-reference/vitest/index.mdx +28 -1
- package/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx +16 -6
- package/docs/api-reference/workflow-next/with-workflow.mdx +32 -0
- package/docs/changelog/eager-processing.mdx +595 -0
- package/docs/changelog/index.mdx +2 -1
- package/docs/cookbook/advanced/meta.json +1 -6
- package/docs/cookbook/agent-patterns/agent-cancellation.mdx +29 -78
- package/docs/cookbook/common-patterns/timeouts.mdx +1 -1
- package/docs/cookbook/index.mdx +0 -1
- package/docs/deploying/world/postgres-world.mdx +5 -3
- package/docs/errors/abort-signal-timeout-in-workflow.mdx +80 -0
- package/docs/foundations/cancellation.mdx +460 -0
- package/docs/foundations/errors-and-retries.mdx +7 -3
- package/docs/foundations/meta.json +1 -0
- package/docs/foundations/serialization.mdx +77 -41
- package/docs/getting-started/astro.mdx +6 -0
- package/docs/getting-started/index.mdx +6 -7
- package/docs/getting-started/meta.json +1 -0
- package/docs/getting-started/nestjs.mdx +8 -0
- package/docs/getting-started/nitro.mdx +22 -0
- package/docs/getting-started/sveltekit.mdx +6 -0
- package/docs/getting-started/tanstack-start.mdx +241 -0
- package/docs/how-it-works/cancellation.mdx +287 -0
- package/docs/how-it-works/meta.json +2 -1
- package/docs/internal/index.mdx +19 -0
- package/docs/internal/meta.json +5 -0
- package/docs/internal/serializable-abort-controller.mdx +148 -0
- package/package.json +13 -12
- package/docs/cookbook/advanced/distributed-abort-controller.mdx +0 -318
package/dist/api.d.ts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import '@workflow/core/runtime/world-init';
|
|
2
|
+
export type { Event, StopSleepOptions, StopSleepResult, WorkflowRun, } from '@workflow/core/runtime';
|
|
3
|
+
export { getHookByToken, resumeHook, resumeWebhook, } from '@workflow/core/runtime/resume-hook';
|
|
4
|
+
export { getRun, Run, type WorkflowReadableStream, type WorkflowReadableStreamOptions, } from '@workflow/core/runtime/run';
|
|
5
|
+
export { type StartOptions, start, } from '@workflow/core/runtime/start';
|
|
2
6
|
//# sourceMappingURL=api.d.ts.map
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AASA,OAAO,mCAAmC,CAAC;AAE3C,YAAY,EACV,KAAK,EACL,gBAAgB,EAChB,eAAe,EACf,WAAW,GACZ,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,cAAc,EACd,UAAU,EACV,aAAa,GACd,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,MAAM,EACN,GAAG,EACH,KAAK,sBAAsB,EAC3B,KAAK,6BAA6B,GACnC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,GACN,MAAM,8BAA8B,CAAC"}
|
package/dist/api.js
CHANGED
|
@@ -1,2 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// Side-effect import: ensure `world.ts` is loaded so its module-load
|
|
2
|
+
// `globalThis[GetWorldFnKey] ??= getWorld` registration fires before any
|
|
3
|
+
// host route reaches `getWorldLazy()`. Without this, webpack/turbopack
|
|
4
|
+
// tree-shake `world.ts` out of routes that only use `start` (the most
|
|
5
|
+
// common host-side entry point) and `getWorldLazy()`'s dynamic-import
|
|
6
|
+
// fallback then fails because the bundler inlined `get-world-lazy.js`
|
|
7
|
+
// into the route bundle. Resolved to an empty stub via the `workflow`
|
|
8
|
+
// export condition in VM/step bundles, so this stays host-only.
|
|
9
|
+
// See `@workflow/core/src/runtime/world-init.ts` for the full rationale.
|
|
10
|
+
import '@workflow/core/runtime/world-init';
|
|
11
|
+
export { getHookByToken, resumeHook, resumeWebhook, } from '@workflow/core/runtime/resume-hook';
|
|
12
|
+
export { getRun, Run, } from '@workflow/core/runtime/run';
|
|
13
|
+
export { start, } from '@workflow/core/runtime/start';
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2FwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxxRUFBcUU7QUFDckUseUVBQXlFO0FBQ3pFLHVFQUF1RTtBQUN2RSxzRUFBc0U7QUFDdEUsc0VBQXNFO0FBQ3RFLHNFQUFzRTtBQUN0RSxzRUFBc0U7QUFDdEUsZ0VBQWdFO0FBQ2hFLHlFQUF5RTtBQUN6RSxPQUFPLG1DQUFtQyxDQUFDO0FBUTNDLE9BQU8sRUFDTCxjQUFjLEVBQ2QsVUFBVSxFQUNWLGFBQWEsR0FDZCxNQUFNLG9DQUFvQyxDQUFDO0FBQzVDLE9BQU8sRUFDTCxNQUFNLEVBQ04sR0FBRyxHQUdKLE1BQU0sNEJBQTRCLENBQUM7QUFDcEMsT0FBTyxFQUVMLEtBQUssR0FDTixNQUFNLDhCQUE4QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gU2lkZS1lZmZlY3QgaW1wb3J0OiBlbnN1cmUgYHdvcmxkLnRzYCBpcyBsb2FkZWQgc28gaXRzIG1vZHVsZS1sb2FkXG4vLyBgZ2xvYmFsVGhpc1tHZXRXb3JsZEZuS2V5XSA/Pz0gZ2V0V29ybGRgIHJlZ2lzdHJhdGlvbiBmaXJlcyBiZWZvcmUgYW55XG4vLyBob3N0IHJvdXRlIHJlYWNoZXMgYGdldFdvcmxkTGF6eSgpYC4gV2l0aG91dCB0aGlzLCB3ZWJwYWNrL3R1cmJvcGFja1xuLy8gdHJlZS1zaGFrZSBgd29ybGQudHNgIG91dCBvZiByb3V0ZXMgdGhhdCBvbmx5IHVzZSBgc3RhcnRgICh0aGUgbW9zdFxuLy8gY29tbW9uIGhvc3Qtc2lkZSBlbnRyeSBwb2ludCkgYW5kIGBnZXRXb3JsZExhenkoKWAncyBkeW5hbWljLWltcG9ydFxuLy8gZmFsbGJhY2sgdGhlbiBmYWlscyBiZWNhdXNlIHRoZSBidW5kbGVyIGlubGluZWQgYGdldC13b3JsZC1sYXp5LmpzYFxuLy8gaW50byB0aGUgcm91dGUgYnVuZGxlLiBSZXNvbHZlZCB0byBhbiBlbXB0eSBzdHViIHZpYSB0aGUgYHdvcmtmbG93YFxuLy8gZXhwb3J0IGNvbmRpdGlvbiBpbiBWTS9zdGVwIGJ1bmRsZXMsIHNvIHRoaXMgc3RheXMgaG9zdC1vbmx5LlxuLy8gU2VlIGBAd29ya2Zsb3cvY29yZS9zcmMvcnVudGltZS93b3JsZC1pbml0LnRzYCBmb3IgdGhlIGZ1bGwgcmF0aW9uYWxlLlxuaW1wb3J0ICdAd29ya2Zsb3cvY29yZS9ydW50aW1lL3dvcmxkLWluaXQnO1xuXG5leHBvcnQgdHlwZSB7XG4gIEV2ZW50LFxuICBTdG9wU2xlZXBPcHRpb25zLFxuICBTdG9wU2xlZXBSZXN1bHQsXG4gIFdvcmtmbG93UnVuLFxufSBmcm9tICdAd29ya2Zsb3cvY29yZS9ydW50aW1lJztcbmV4cG9ydCB7XG4gIGdldEhvb2tCeVRva2VuLFxuICByZXN1bWVIb29rLFxuICByZXN1bWVXZWJob29rLFxufSBmcm9tICdAd29ya2Zsb3cvY29yZS9ydW50aW1lL3Jlc3VtZS1ob29rJztcbmV4cG9ydCB7XG4gIGdldFJ1bixcbiAgUnVuLFxuICB0eXBlIFdvcmtmbG93UmVhZGFibGVTdHJlYW0sXG4gIHR5cGUgV29ya2Zsb3dSZWFkYWJsZVN0cmVhbU9wdGlvbnMsXG59IGZyb20gJ0B3b3JrZmxvdy9jb3JlL3J1bnRpbWUvcnVuJztcbmV4cG9ydCB7XG4gIHR5cGUgU3RhcnRPcHRpb25zLFxuICBzdGFydCxcbn0gZnJvbSAnQHdvcmtmbG93L2NvcmUvcnVudGltZS9zdGFydCc7XG4iXX0=
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { createWorld, getWorld, getWorldHandlers, healthCheck, type HealthCheckEndpoint, type HealthCheckOptions, type HealthCheckResult, setWorld,
|
|
1
|
+
export { createWorld, getWorld, getWorldHandlers, healthCheck, type HealthCheckEndpoint, type HealthCheckOptions, type HealthCheckResult, setWorld, workflowEntrypoint, } from '@workflow/core/runtime';
|
|
2
2
|
//# sourceMappingURL=runtime.d.ts.map
|
package/dist/runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,QAAQ,EACR,gBAAgB,EAChB,WAAW,EACX,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,QAAQ,EACR,
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,QAAQ,EACR,gBAAgB,EAChB,WAAW,EACX,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,QAAQ,EACR,kBAAkB,GACnB,MAAM,wBAAwB,CAAC"}
|
package/dist/runtime.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { createWorld, getWorld, getWorldHandlers, healthCheck, setWorld,
|
|
2
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
1
|
+
export { createWorld, getWorld, getWorldHandlers, healthCheck, setWorld, workflowEntrypoint, } from '@workflow/core/runtime';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9ydW50aW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxXQUFXLEVBQ1gsUUFBUSxFQUNSLGdCQUFnQixFQUNoQixXQUFXLEVBSVgsUUFBUSxFQUNSLGtCQUFrQixHQUNuQixNQUFNLHdCQUF3QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHtcbiAgY3JlYXRlV29ybGQsXG4gIGdldFdvcmxkLFxuICBnZXRXb3JsZEhhbmRsZXJzLFxuICBoZWFsdGhDaGVjayxcbiAgdHlwZSBIZWFsdGhDaGVja0VuZHBvaW50LFxuICB0eXBlIEhlYWx0aENoZWNrT3B0aW9ucyxcbiAgdHlwZSBIZWFsdGhDaGVja1Jlc3VsdCxcbiAgc2V0V29ybGQsXG4gIHdvcmtmbG93RW50cnlwb2ludCxcbn0gZnJvbSAnQHdvcmtmbG93L2NvcmUvcnVudGltZSc7XG4iXX0=
|
|
@@ -22,6 +22,30 @@ export default defineConfig({
|
|
|
22
22
|
});
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
Pass a [`WorkflowTestOptions`](#workflowtestoptions) object when your project uses a non-standard layout — for example, a monorepo where `workflows/` does not live at the Vitest config's directory, or when the default `.workflow-data` / `.workflow-vitest` output locations need to move. The plugin forwards these paths to `buildWorkflowTests()` and `setupWorkflowTests()` through Vitest's per-project provided context, so each Vitest workspace project stays isolated.
|
|
26
|
+
|
|
27
|
+
{/* @skip-typecheck - @workflow/vitest not available in docs-typecheck */}
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { defineConfig } from "vitest/config";
|
|
31
|
+
import { workflow } from "@workflow/vitest";
|
|
32
|
+
|
|
33
|
+
export default defineConfig({
|
|
34
|
+
plugins: [
|
|
35
|
+
workflow({
|
|
36
|
+
cwd: "./apps/api",
|
|
37
|
+
rootDir: "./apps/api/test-artifacts",
|
|
38
|
+
}),
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Parameters:**
|
|
44
|
+
|
|
45
|
+
| Parameter | Type | Description |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| `options?` | `WorkflowTestOptions` | Optional configuration |
|
|
48
|
+
|
|
25
49
|
**Returns:** `Plugin[]`
|
|
26
50
|
|
|
27
51
|
## Setup Functions
|
|
@@ -83,7 +107,10 @@ Tears down the workflow test world. Clears the global world and closes the Local
|
|
|
83
107
|
|
|
84
108
|
| Option | Type | Default | Description |
|
|
85
109
|
| --- | --- | --- | --- |
|
|
86
|
-
| `cwd` | `string` | `process.cwd()` | The working directory of the project (where `workflows/` lives) |
|
|
110
|
+
| `cwd` | `string` | `process.cwd()` | The working directory of the project (where `workflows/` lives). Relative paths resolve against `process.cwd()`. |
|
|
111
|
+
| `rootDir` | `string` | same as `cwd` | Root directory used for default test artifacts. When set, `dataDir` and `outDir` default to `<rootDir>/.workflow-data` and `<rootDir>/.workflow-vitest`. Relative paths resolve against `cwd`. |
|
|
112
|
+
| `dataDir` | `string` | `<rootDir>/.workflow-data` | Directory for workflow runtime data written by the test world. Relative paths resolve against `cwd`. |
|
|
113
|
+
| `outDir` | `string` | `<rootDir>/.workflow-vitest` | Directory for generated workflow and step bundles. Relative paths resolve against `cwd`. |
|
|
87
114
|
|
|
88
115
|
## Test Helpers
|
|
89
116
|
|
|
@@ -11,7 +11,7 @@ related:
|
|
|
11
11
|
|
|
12
12
|
`WorkflowRunFailedError` is thrown when awaiting `run.returnValue` on a workflow run whose status is `'failed'`. This indicates that the workflow encountered a fatal error during execution and cannot produce a return value.
|
|
13
13
|
|
|
14
|
-
The `cause` property
|
|
14
|
+
The `cause` property holds the original thrown value, hydrated through the workflow serialization pipeline so its type identity (e.g. `FatalError`, `RetryableError`, custom `Error` subclasses), `cause` chain, and custom properties are preserved. Because any JavaScript value can be thrown, `cause` is typed as `unknown` — narrow it with `instanceof Error` (or a more specific check) before accessing fields like `message`. The high-level error classification is exposed as the top-level `errorCode` property.
|
|
15
15
|
|
|
16
16
|
```typescript lineNumbers
|
|
17
17
|
import { WorkflowRunFailedError } from "workflow/errors"
|
|
@@ -21,9 +21,11 @@ try {
|
|
|
21
21
|
const result = await run.returnValue;
|
|
22
22
|
} catch (error) {
|
|
23
23
|
if (WorkflowRunFailedError.is(error)) { // [!code highlight]
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
if (error.cause instanceof Error) {
|
|
25
|
+
console.error(`Run ${error.runId} failed:`, error.cause.message);
|
|
26
|
+
}
|
|
27
|
+
if (error.errorCode) {
|
|
28
|
+
console.error("Error code:", error.errorCode);
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
}
|
|
@@ -38,8 +40,16 @@ definition={`
|
|
|
38
40
|
interface WorkflowRunFailedError {
|
|
39
41
|
/** The ID of the failed run. */
|
|
40
42
|
runId: string;
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
+
/**
|
|
44
|
+
* The original thrown value from the failed workflow run, hydrated through
|
|
45
|
+
* the workflow serialization pipeline. Preserves the original type identity
|
|
46
|
+
* (Error subclasses, FatalError, custom classes with WORKFLOW_SERIALIZE,
|
|
47
|
+
* etc.) and custom properties. Typed as \`unknown\` because any value can
|
|
48
|
+
* be thrown — narrow with \`instanceof Error\` before accessing fields.
|
|
49
|
+
*/
|
|
50
|
+
cause: unknown;
|
|
51
|
+
/** The high-level error category (e.g. \`USER_ERROR\`, \`RUNTIME_ERROR\`). */
|
|
52
|
+
errorCode?: string;
|
|
43
53
|
/** The error message. */
|
|
44
54
|
message: string;
|
|
45
55
|
}
|
|
@@ -27,6 +27,15 @@ const workflowConfig = {}
|
|
|
27
27
|
export default withWorkflow(nextConfig, workflowConfig); // [!code highlight]
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
<Callout type="warn">
|
|
31
|
+
If a package in `serverExternalPackages` contains workflow code (`"use step"`,
|
|
32
|
+
`"use workflow"`, or serialization classes), `withWorkflow()` automatically
|
|
33
|
+
removes it from `serverExternalPackages` for the current build and prints a
|
|
34
|
+
warning. This ensures the package still gets transformed by the Workflow
|
|
35
|
+
compiler. Remove that package from `serverExternalPackages` in your
|
|
36
|
+
`next.config` to silence the warning.
|
|
37
|
+
</Callout>
|
|
38
|
+
|
|
30
39
|
### Monorepos and Workspace Imports
|
|
31
40
|
|
|
32
41
|
By default, Next.js detects the correct workspace root automatically. If your Next.js app lives in a subdirectory such as `apps/web` and workspace resolution is not working correctly, you can set `outputFileTracingRoot` as a workaround:
|
|
@@ -63,6 +72,7 @@ export default withWorkflow(nextConfig, {
|
|
|
63
72
|
local: {
|
|
64
73
|
port: 4000,
|
|
65
74
|
},
|
|
75
|
+
sourcemap: false,
|
|
66
76
|
},
|
|
67
77
|
});
|
|
68
78
|
```
|
|
@@ -71,6 +81,27 @@ export default withWorkflow(nextConfig, {
|
|
|
71
81
|
| --- | --- | --- | --- |
|
|
72
82
|
| `workflows.lazyDiscovery` | `boolean` | `false` | When `true`, defers workflow discovery until files are requested instead of scanning eagerly at startup. Useful for large projects where startup time matters. |
|
|
73
83
|
| `workflows.local.port` | `number` | — | Overrides the `PORT` environment variable for local development. Has no effect when deployed to Vercel. |
|
|
84
|
+
| `workflows.sourcemap` | `boolean \| 'inline' \| 'linked' \| 'external' \| 'both'` | `'inline'` | Controls source maps on generated workflow bundles. See [Source maps](#source-maps) below. |
|
|
85
|
+
|
|
86
|
+
### Source maps
|
|
87
|
+
|
|
88
|
+
The step bundle and intermediate workflow bundle default to `'inline'` source maps so that stack traces from step errors and workflow VM errors point at your source files. The `sourcemap` option lets you change that:
|
|
89
|
+
|
|
90
|
+
| Value | Behavior |
|
|
91
|
+
| --- | --- |
|
|
92
|
+
| `true` / `'inline'` | Base64-encode the source map and append it to the bundle (default). |
|
|
93
|
+
| `'linked'` | Write a separate `.map` file and add a `sourceMappingURL` comment. |
|
|
94
|
+
| `'external'` | Write a separate `.map` file without the comment. |
|
|
95
|
+
| `'both'` | Emit both inline and external source maps. |
|
|
96
|
+
| `false` | Omit source maps entirely. |
|
|
97
|
+
|
|
98
|
+
Setting `sourcemap: false` is the main escape hatch for users hitting the Vercel 250MB function size limit — it drops the inline source map from every bundle and also skips the source-map-support runtime shim on the Vercel step function. The tradeoff is that workflow VM stack traces will reference generated code (e.g. `evalmachine.<anonymous>`) rather than your source files.
|
|
99
|
+
|
|
100
|
+
<Callout type="info">
|
|
101
|
+
Setting `sourcemap` explicitly affects **all** generated bundles (steps, workflows, webhook). The legacy `WORKFLOW_EMIT_SOURCEMAPS_FOR_DEBUGGING=1` environment variable is narrower — it only toggles source maps on the final workflow wrapper and webhook bundle (which default to off). It continues to work, but new code should use the `sourcemap` option or the `WORKFLOW_SOURCEMAP` environment variable instead.
|
|
102
|
+
</Callout>
|
|
103
|
+
|
|
104
|
+
The option can also be set via the `WORKFLOW_SOURCEMAP` environment variable, which accepts the same values plus `'0'` / `'1'` as aliases for `false` / `true`. Precedence is: explicit config > `WORKFLOW_SOURCEMAP` > per-bundle default.
|
|
74
105
|
|
|
75
106
|
<Callout type="info">
|
|
76
107
|
The `workflows.local` options only affect local development. When deployed to Vercel, the runtime ignores `local` settings and uses the Vercel world automatically.
|
|
@@ -78,6 +109,7 @@ The `workflows.local` options only affect local development. When deployed to Ve
|
|
|
78
109
|
|
|
79
110
|
## Exporting a Function
|
|
80
111
|
|
|
112
|
+
|
|
81
113
|
If you are exporting a function in your `next.config` you will need to ensure you call the function returned from `withWorkflow`.
|
|
82
114
|
|
|
83
115
|
```typescript title="next.config.ts" lineNumbers
|