@workflow/core 5.0.0-beta.39 → 5.0.0-beta.40

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.
Files changed (95) hide show
  1. package/dist/classify-error.d.ts.map +1 -1
  2. package/dist/classify-error.js +5 -2
  3. package/dist/correlation-id.d.ts +109 -0
  4. package/dist/correlation-id.d.ts.map +1 -0
  5. package/dist/correlation-id.js +139 -0
  6. package/dist/describe-error.d.ts.map +1 -1
  7. package/dist/describe-error.js +14 -1
  8. package/dist/events-consumer.d.ts +1 -0
  9. package/dist/events-consumer.d.ts.map +1 -1
  10. package/dist/events-consumer.js +11 -3
  11. package/dist/private.d.ts +17 -1
  12. package/dist/private.d.ts.map +1 -1
  13. package/dist/private.js +1 -1
  14. package/dist/runtime/constants.d.ts +19 -0
  15. package/dist/runtime/constants.d.ts.map +1 -1
  16. package/dist/runtime/constants.js +30 -1
  17. package/dist/runtime/deployment-guard.d.ts +99 -0
  18. package/dist/runtime/deployment-guard.d.ts.map +1 -0
  19. package/dist/runtime/deployment-guard.js +154 -0
  20. package/dist/runtime/quickjs-assets.generated.d.ts +14 -0
  21. package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -0
  22. package/dist/runtime/quickjs-assets.generated.js +30 -0
  23. package/dist/runtime/quickjs-entrypoint.d.ts +124 -0
  24. package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
  25. package/dist/runtime/quickjs-entrypoint.js +1429 -0
  26. package/dist/runtime/quickjs-runtime.d.ts +193 -0
  27. package/dist/runtime/quickjs-runtime.d.ts.map +1 -0
  28. package/dist/runtime/quickjs-runtime.js +1944 -0
  29. package/dist/runtime/run.d.ts +2 -0
  30. package/dist/runtime/run.d.ts.map +1 -1
  31. package/dist/runtime/run.js +9 -4
  32. package/dist/runtime/runs.d.ts +18 -1
  33. package/dist/runtime/runs.d.ts.map +1 -1
  34. package/dist/runtime/runs.js +96 -2
  35. package/dist/runtime/start.d.ts.map +1 -1
  36. package/dist/runtime/start.js +9 -1
  37. package/dist/runtime/suspension-handler.d.ts +7 -0
  38. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  39. package/dist/runtime/suspension-handler.js +29 -2
  40. package/dist/runtime/vm-mode.d.ts +44 -0
  41. package/dist/runtime/vm-mode.d.ts.map +1 -0
  42. package/dist/runtime/vm-mode.js +62 -0
  43. package/dist/runtime/vm-serde-bundle.generated.d.ts +14 -0
  44. package/dist/runtime/vm-serde-bundle.generated.d.ts.map +1 -0
  45. package/dist/runtime/vm-serde-bundle.generated.js +16 -0
  46. package/dist/runtime.d.ts +1 -1
  47. package/dist/runtime.d.ts.map +1 -1
  48. package/dist/runtime.js +484 -47
  49. package/dist/serialization/codec-devalue-vm.d.ts +9 -0
  50. package/dist/serialization/codec-devalue-vm.d.ts.map +1 -0
  51. package/dist/serialization/codec-devalue-vm.js +137 -0
  52. package/dist/serialization/reducers/class-vm.d.ts +20 -0
  53. package/dist/serialization/reducers/class-vm.d.ts.map +1 -0
  54. package/dist/serialization/reducers/class-vm.js +77 -0
  55. package/dist/serialization/reducers/common-vm.d.ts +15 -0
  56. package/dist/serialization/reducers/common-vm.d.ts.map +1 -0
  57. package/dist/serialization/reducers/common-vm.js +579 -0
  58. package/dist/serialization/reducers/common.d.ts.map +1 -1
  59. package/dist/serialization/reducers/common.js +28 -6
  60. package/dist/serialization/reducers/step-function-vm.d.ts +44 -0
  61. package/dist/serialization/reducers/step-function-vm.d.ts.map +1 -0
  62. package/dist/serialization/reducers/step-function-vm.js +97 -0
  63. package/dist/serialization/vm-bundle-entry.d.ts +12 -0
  64. package/dist/serialization/vm-bundle-entry.d.ts.map +1 -0
  65. package/dist/serialization/vm-bundle-entry.js +58 -0
  66. package/dist/serialization/workflow-vm.d.ts +24 -0
  67. package/dist/serialization/workflow-vm.d.ts.map +1 -0
  68. package/dist/serialization/workflow-vm.js +66 -0
  69. package/dist/serialization.d.ts +2 -1
  70. package/dist/serialization.d.ts.map +1 -1
  71. package/dist/serialization.js +26 -21
  72. package/dist/source-map.d.ts +20 -0
  73. package/dist/source-map.d.ts.map +1 -1
  74. package/dist/source-map.js +47 -1
  75. package/dist/step.d.ts.map +1 -1
  76. package/dist/step.js +7 -2
  77. package/dist/telemetry/semantic-conventions.d.ts +78 -0
  78. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  79. package/dist/telemetry/semantic-conventions.js +56 -1
  80. package/dist/telemetry.d.ts +5 -0
  81. package/dist/telemetry.d.ts.map +1 -1
  82. package/dist/telemetry.js +13 -13
  83. package/dist/version.d.ts +1 -1
  84. package/dist/version.js +2 -2
  85. package/dist/workflow/abort-controller.d.ts.map +1 -1
  86. package/dist/workflow/abort-controller.js +6 -4
  87. package/dist/workflow/attribute-dispatcher.js +2 -2
  88. package/dist/workflow/hook.js +2 -2
  89. package/dist/workflow/sleep.js +2 -2
  90. package/dist/workflow.d.ts +49 -2
  91. package/dist/workflow.d.ts.map +1 -1
  92. package/dist/workflow.js +723 -569
  93. package/docs/api-reference/create-hook.mdx +1 -1
  94. package/docs/foundations/starting-workflows.mdx +74 -1
  95. package/package.json +8 -7
@@ -187,7 +187,7 @@ After the workflow ends, [`getHookByToken()`](/docs/api-reference/workflow-api/g
187
187
  </Callout>
188
188
 
189
189
  <Callout type="warn">
190
- This option is experimental. If the configured World does not support it, the workflow fails when registering the Hook. `createWebhook()` does not accept this option.
190
+ This option is experimental. Worlds can limit how long tokens are retained; see [World configuration](/docs/configuration/worlds) for each World's limit. If the configured World does not support minimum retention, the workflow fails when registering the Hook. `createWebhook()` does not accept this option.
191
191
  </Callout>
192
192
 
193
193
  ### Waiting for Multiple Payloads
@@ -80,6 +80,35 @@ Most `Run` properties are async getters that return promises. You need to `await
80
80
 
81
81
  ## Common Patterns
82
82
 
83
+ ### Starting Workflows from Workflow Functions
84
+
85
+ You can also call `start()` directly inside workflow functions to spawn child workflows. For choosing between this and awaiting a workflow function directly, see [Workflow Composition](/cookbook/common-patterns/workflow-composition).
86
+
87
+ ```typescript lineNumbers
88
+ import { start } from "workflow/api";
89
+ import { childWorkflow } from "./workflows/child";
90
+
91
+ export async function parentWorkflow(inputValue: number) {
92
+ "use workflow";
93
+
94
+ const childRun = await start(childWorkflow, [inputValue]); // [!code highlight]
95
+
96
+ // childRun is a full Run object — use it like normal
97
+ const childResult = await childRun.returnValue;
98
+ return { childRunId: childRun.runId, childResult };
99
+ }
100
+ ```
101
+
102
+ When `start()` is called inside a workflow function, it automatically executes through an internal step to maintain deterministic replay. The returned `Run` object works just like it does outside workflows — properties like `.runId`, `.status`, `.returnValue`, and methods like `.cancel()` are all available. Each property access or method call executes as a separate step under the hood.
103
+
104
+ <Callout type="info">
105
+ Inside workflow functions, each `Run` property access (e.g., `run.status`, `run.returnValue`) triggers a workflow step. This means each access is recorded in the event log and replayed deterministically.
106
+ </Callout>
107
+
108
+ <Callout type="warn">
109
+ Awaiting `returnValue` polls the child run every second, and the polling step holds its worker slot open for as long as the child takes to finish. Worker-based Worlds must be sized to cover the peak number of these polls in flight. If the child workflow is long-running, spawn it without awaiting `returnValue` and have it resume a [hook](/docs/foundations/hooks) when it completes — see the [`startAndWait()` pattern](/cookbook/advanced/child-workflows).
110
+ </Callout>
111
+
83
112
  ### Fire and Forget
84
113
 
85
114
  The most common pattern is to start a workflow and immediately return, letting it execute in the background:
@@ -148,7 +177,7 @@ export async function POST(request: Request) {
148
177
  }
149
178
  ```
150
179
 
151
- Your workflow can obtain a writable stream using [`getWritable()`](/docs/api-reference/workflow/get-writable):
180
+ Your workflow can write to the stream using [`getWritable()`](/docs/api-reference/workflow/get-writable):
152
181
 
153
182
  ```typescript lineNumbers
154
183
  import { getWritable } from "workflow";
@@ -213,6 +242,50 @@ export async function GET(request: Request) {
213
242
  }
214
243
  ```
215
244
 
245
+ ### Recursive and Repeating Workflows
246
+
247
+ A workflow can start a new instance of itself. This is useful when a single long-running workflow would accumulate too many events — large event logs become slower to replay, more expensive to store, and harder to inspect in the UI. By breaking work into smaller runs that chain together, each run stays lean.
248
+
249
+ ```typescript lineNumbers
250
+ import { start } from "workflow/api";
251
+ declare function fetchBatch(cursor?: string): Promise<{ items: string[]; nextCursor?: string }>; // @setup
252
+ declare function processBatch(items: string[]): Promise<void>; // @setup
253
+
254
+ export async function processQueue(cursor?: string) {
255
+ "use workflow";
256
+
257
+ const { items, nextCursor } = await fetchBatch(cursor);
258
+ await processBatch(items);
259
+
260
+ if (nextCursor) {
261
+ // Continue processing in a new workflow run
262
+ await start(processQueue, [nextCursor]); // [!code highlight]
263
+ }
264
+ }
265
+ ```
266
+
267
+ This pattern also enables **repeating cron-like workflows**. A workflow can complete its work, sleep, and then schedule a new instance of itself — creating an indefinite chain without any single run growing too large:
268
+
269
+ ```typescript lineNumbers
270
+ import { sleep } from "workflow";
271
+ import { start } from "workflow/api";
272
+ declare function refreshMetrics(): Promise<void>; // @setup
273
+
274
+ export async function syncDashboard() {
275
+ "use workflow";
276
+
277
+ await refreshMetrics();
278
+ await sleep("1h");
279
+
280
+ // Schedule the next run
281
+ await start(syncDashboard); // [!code highlight]
282
+ }
283
+ ```
284
+
285
+ #### Starting against the latest deployment
286
+
287
+ By default a chained run starts on the same deployment as its parent. For workflows that chain over long periods, pass [`deploymentId: "latest"`](/docs/api-reference/workflow-api/start#using-deploymentid-latest) so the next run picks up new code. [Versioning](/docs/foundations/versioning#self-upgrading-workflows) covers this pattern in full, including how the serialized state acts as the migration boundary between versions.
288
+
216
289
  ## Next Steps
217
290
 
218
291
  Now that you understand how to start workflows and track their execution:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workflow/core",
3
- "version": "5.0.0-beta.39",
3
+ "version": "5.0.0-beta.40",
4
4
  "description": "Core runtime and engine for Workflow SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -84,21 +84,22 @@
84
84
  "@jridgewell/trace-mapping": "0.3.31",
85
85
  "@standard-schema/spec": "1.0.0",
86
86
  "@types/ms": "2.1.0",
87
- "@vercel/functions": "^3.4.3",
87
+ "@vercel/functions": "^3.8.0",
88
88
  "debug": "4.4.3",
89
89
  "devalue": "5.9.0",
90
90
  "ms": "2.1.3",
91
91
  "nanoid": "5.1.6",
92
+ "quickjs-wasi": "3.1.0",
92
93
  "seedrandom": "3.0.5",
93
94
  "semver": "7.7.4",
94
95
  "ulid": "~3.0.1",
95
96
  "zod": "~4.3.6",
96
- "@workflow/errors": "5.0.0-beta.15",
97
+ "@workflow/errors": "5.0.0-beta.16",
97
98
  "@workflow/serde": "5.0.0-beta.2",
98
99
  "@workflow/utils": "5.0.0-beta.8",
99
- "@workflow/world": "5.0.0-beta.24",
100
- "@workflow/world-local": "5.0.0-beta.33",
101
- "@workflow/world-vercel": "5.0.0-beta.35"
100
+ "@workflow/world": "5.0.0-beta.25",
101
+ "@workflow/world-local": "5.0.0-beta.34",
102
+ "@workflow/world-vercel": "5.0.0-beta.36"
102
103
  },
103
104
  "devDependencies": {
104
105
  "@opentelemetry/api": "1.9.0",
@@ -123,7 +124,7 @@
123
124
  }
124
125
  },
125
126
  "scripts": {
126
- "build": "genversion --es6 src/version.ts && tsc",
127
+ "build": "genversion --es6 src/version.ts && node scripts/build-vm-serde-bundle.js && node scripts/build-quickjs-assets.js && tsc",
127
128
  "dev": "genversion --es6 src/version.ts && tsc --watch",
128
129
  "clean": "tsc --build --clean && rm -rf dist src/version.ts docs ||:",
129
130
  "test": "cross-env WORKFLOW_TARGET_WORLD=local vitest run src",