@workflow/core 4.0.1-beta.9 → 4.1.0-beta.52

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 (184) hide show
  1. package/dist/builtins.js +1 -1
  2. package/dist/class-serialization.d.ts +26 -0
  3. package/dist/class-serialization.d.ts.map +1 -0
  4. package/dist/class-serialization.js +66 -0
  5. package/dist/create-hook.js +1 -1
  6. package/dist/define-hook.d.ts +40 -25
  7. package/dist/define-hook.d.ts.map +1 -1
  8. package/dist/define-hook.js +22 -27
  9. package/dist/events-consumer.d.ts.map +1 -1
  10. package/dist/events-consumer.js +5 -1
  11. package/dist/flushable-stream.d.ts +82 -0
  12. package/dist/flushable-stream.d.ts.map +1 -0
  13. package/dist/flushable-stream.js +214 -0
  14. package/dist/global.d.ts +4 -1
  15. package/dist/global.d.ts.map +1 -1
  16. package/dist/global.js +21 -9
  17. package/dist/index.d.ts +2 -2
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +2 -2
  20. package/dist/logger.js +1 -1
  21. package/dist/observability.d.ts +60 -0
  22. package/dist/observability.d.ts.map +1 -1
  23. package/dist/observability.js +265 -32
  24. package/dist/private.d.ts +10 -1
  25. package/dist/private.d.ts.map +1 -1
  26. package/dist/private.js +6 -1
  27. package/dist/runtime/helpers.d.ts +52 -0
  28. package/dist/runtime/helpers.d.ts.map +1 -0
  29. package/dist/runtime/helpers.js +264 -0
  30. package/dist/runtime/resume-hook.d.ts +17 -12
  31. package/dist/runtime/resume-hook.d.ts.map +1 -1
  32. package/dist/runtime/resume-hook.js +79 -64
  33. package/dist/runtime/run.d.ts +100 -0
  34. package/dist/runtime/run.d.ts.map +1 -0
  35. package/dist/runtime/run.js +132 -0
  36. package/dist/runtime/start.d.ts +15 -1
  37. package/dist/runtime/start.d.ts.map +1 -1
  38. package/dist/runtime/start.js +72 -46
  39. package/dist/runtime/step-handler.d.ts +7 -0
  40. package/dist/runtime/step-handler.d.ts.map +1 -0
  41. package/dist/runtime/step-handler.js +337 -0
  42. package/dist/runtime/suspension-handler.d.ts +25 -0
  43. package/dist/runtime/suspension-handler.d.ts.map +1 -0
  44. package/dist/runtime/suspension-handler.js +182 -0
  45. package/dist/runtime/world.d.ts.map +1 -1
  46. package/dist/runtime/world.js +20 -21
  47. package/dist/runtime.d.ts +4 -105
  48. package/dist/runtime.d.ts.map +1 -1
  49. package/dist/runtime.js +97 -531
  50. package/dist/schemas.d.ts +1 -15
  51. package/dist/schemas.d.ts.map +1 -1
  52. package/dist/schemas.js +2 -15
  53. package/dist/serialization.d.ts +112 -21
  54. package/dist/serialization.d.ts.map +1 -1
  55. package/dist/serialization.js +469 -85
  56. package/dist/sleep.d.ts +10 -0
  57. package/dist/sleep.d.ts.map +1 -1
  58. package/dist/sleep.js +1 -1
  59. package/dist/source-map.d.ts +10 -0
  60. package/dist/source-map.d.ts.map +1 -0
  61. package/dist/source-map.js +56 -0
  62. package/dist/step/context-storage.d.ts +2 -1
  63. package/dist/step/context-storage.d.ts.map +1 -1
  64. package/dist/step/context-storage.js +1 -1
  65. package/dist/step/get-closure-vars.d.ts +9 -0
  66. package/dist/step/get-closure-vars.d.ts.map +1 -0
  67. package/dist/step/get-closure-vars.js +16 -0
  68. package/dist/step/get-step-metadata.js +1 -1
  69. package/dist/step/get-workflow-metadata.js +1 -1
  70. package/dist/step/writable-stream.d.ts +10 -2
  71. package/dist/step/writable-stream.d.ts.map +1 -1
  72. package/dist/step/writable-stream.js +6 -5
  73. package/dist/step.d.ts +1 -1
  74. package/dist/step.d.ts.map +1 -1
  75. package/dist/step.js +93 -47
  76. package/dist/symbols.d.ts +6 -0
  77. package/dist/symbols.d.ts.map +1 -1
  78. package/dist/symbols.js +7 -1
  79. package/dist/telemetry/semantic-conventions.d.ts +66 -38
  80. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  81. package/dist/telemetry/semantic-conventions.js +16 -3
  82. package/dist/telemetry.d.ts +8 -4
  83. package/dist/telemetry.d.ts.map +1 -1
  84. package/dist/telemetry.js +39 -6
  85. package/dist/types.js +1 -1
  86. package/dist/util.d.ts +5 -24
  87. package/dist/util.d.ts.map +1 -1
  88. package/dist/util.js +19 -38
  89. package/dist/version.d.ts +2 -0
  90. package/dist/version.d.ts.map +1 -0
  91. package/dist/version.js +3 -0
  92. package/dist/vm/index.js +2 -2
  93. package/dist/vm/uuid.js +1 -1
  94. package/dist/workflow/create-hook.js +1 -1
  95. package/dist/workflow/define-hook.d.ts +3 -3
  96. package/dist/workflow/define-hook.d.ts.map +1 -1
  97. package/dist/workflow/define-hook.js +1 -1
  98. package/dist/workflow/get-workflow-metadata.js +1 -1
  99. package/dist/workflow/hook.d.ts.map +1 -1
  100. package/dist/workflow/hook.js +49 -14
  101. package/dist/workflow/index.d.ts +1 -1
  102. package/dist/workflow/index.d.ts.map +1 -1
  103. package/dist/workflow/index.js +2 -2
  104. package/dist/workflow/sleep.d.ts +1 -1
  105. package/dist/workflow/sleep.d.ts.map +1 -1
  106. package/dist/workflow/sleep.js +26 -39
  107. package/dist/workflow/writable-stream.d.ts +1 -1
  108. package/dist/workflow/writable-stream.d.ts.map +1 -1
  109. package/dist/workflow/writable-stream.js +1 -1
  110. package/dist/workflow.d.ts +1 -1
  111. package/dist/workflow.d.ts.map +1 -1
  112. package/dist/workflow.js +72 -9
  113. package/docs/api-reference/create-hook.mdx +134 -0
  114. package/docs/api-reference/create-webhook.mdx +226 -0
  115. package/docs/api-reference/define-hook.mdx +207 -0
  116. package/docs/api-reference/fatal-error.mdx +38 -0
  117. package/docs/api-reference/fetch.mdx +140 -0
  118. package/docs/api-reference/get-step-metadata.mdx +77 -0
  119. package/docs/api-reference/get-workflow-metadata.mdx +45 -0
  120. package/docs/api-reference/get-writable.mdx +292 -0
  121. package/docs/api-reference/index.mdx +56 -0
  122. package/docs/api-reference/meta.json +3 -0
  123. package/docs/api-reference/retryable-error.mdx +107 -0
  124. package/docs/api-reference/sleep.mdx +60 -0
  125. package/docs/foundations/common-patterns.mdx +254 -0
  126. package/docs/foundations/errors-and-retries.mdx +191 -0
  127. package/docs/foundations/hooks.mdx +456 -0
  128. package/docs/foundations/idempotency.mdx +56 -0
  129. package/docs/foundations/index.mdx +33 -0
  130. package/docs/foundations/meta.json +14 -0
  131. package/docs/foundations/serialization.mdx +158 -0
  132. package/docs/foundations/starting-workflows.mdx +212 -0
  133. package/docs/foundations/streaming.mdx +570 -0
  134. package/docs/foundations/workflows-and-steps.mdx +198 -0
  135. package/docs/how-it-works/code-transform.mdx +335 -0
  136. package/docs/how-it-works/event-sourcing.mdx +255 -0
  137. package/docs/how-it-works/framework-integrations.mdx +438 -0
  138. package/docs/how-it-works/meta.json +10 -0
  139. package/docs/how-it-works/understanding-directives.mdx +612 -0
  140. package/package.json +31 -25
  141. package/dist/builtins.js.map +0 -1
  142. package/dist/create-hook.js.map +0 -1
  143. package/dist/define-hook.js.map +0 -1
  144. package/dist/events-consumer.js.map +0 -1
  145. package/dist/global.js.map +0 -1
  146. package/dist/index.js.map +0 -1
  147. package/dist/logger.js.map +0 -1
  148. package/dist/observability.js.map +0 -1
  149. package/dist/parse-name.d.ts +0 -25
  150. package/dist/parse-name.d.ts.map +0 -1
  151. package/dist/parse-name.js +0 -40
  152. package/dist/parse-name.js.map +0 -1
  153. package/dist/private.js.map +0 -1
  154. package/dist/runtime/resume-hook.js.map +0 -1
  155. package/dist/runtime/start.js.map +0 -1
  156. package/dist/runtime/world.js.map +0 -1
  157. package/dist/runtime.js.map +0 -1
  158. package/dist/schemas.js.map +0 -1
  159. package/dist/serialization.js.map +0 -1
  160. package/dist/sleep.js.map +0 -1
  161. package/dist/step/context-storage.js.map +0 -1
  162. package/dist/step/get-step-metadata.js.map +0 -1
  163. package/dist/step/get-workflow-metadata.js.map +0 -1
  164. package/dist/step/writable-stream.js.map +0 -1
  165. package/dist/step.js.map +0 -1
  166. package/dist/symbols.js.map +0 -1
  167. package/dist/telemetry/semantic-conventions.js.map +0 -1
  168. package/dist/telemetry.js.map +0 -1
  169. package/dist/types.js.map +0 -1
  170. package/dist/util.js.map +0 -1
  171. package/dist/vm/index.js.map +0 -1
  172. package/dist/vm/uuid.js.map +0 -1
  173. package/dist/workflow/create-hook.js.map +0 -1
  174. package/dist/workflow/define-hook.js.map +0 -1
  175. package/dist/workflow/get-workflow-metadata.js.map +0 -1
  176. package/dist/workflow/hook.js.map +0 -1
  177. package/dist/workflow/index.js.map +0 -1
  178. package/dist/workflow/sleep.js.map +0 -1
  179. package/dist/workflow/writable-stream.js.map +0 -1
  180. package/dist/workflow.js.map +0 -1
  181. package/dist/writable-stream.d.ts +0 -23
  182. package/dist/writable-stream.d.ts.map +0 -1
  183. package/dist/writable-stream.js +0 -17
  184. package/dist/writable-stream.js.map +0 -1
@@ -0,0 +1,158 @@
1
+ ---
2
+ title: Serialization
3
+ description: Understand how workflow data is serialized and persisted across suspensions and resumptions.
4
+ ---
5
+
6
+ All function arguments and return values passed between workflow and step functions must be serializable. Workflow DevKit uses a custom serialization system built on top of [devalue](https://github.com/sveltejs/devalue). This system supports standard JSON types, as well as a few additional popular Web API types.
7
+
8
+ <Callout type="info">
9
+ The serialization system ensures that all data persists correctly across workflow suspensions and resumptions, enabling durable execution.
10
+ </Callout>
11
+
12
+ ## Supported Serializable Types
13
+
14
+ The following types can be serialized and passed through workflow functions:
15
+
16
+ **Standard JSON Types:**
17
+
18
+ - `string`
19
+ - `number`
20
+ - `boolean`
21
+ - `null`
22
+ - Arrays of serializable values
23
+ - Objects with string keys and serializable values
24
+
25
+ **Extended Types:**
26
+
27
+ - `undefined`
28
+ - `bigint`
29
+ - `ArrayBuffer`
30
+ - `BigInt64Array`, `BigUint64Array`
31
+ - `Date`
32
+ - `Float32Array`, `Float64Array`
33
+ - `Int8Array`, `Int16Array`, `Int32Array`
34
+ - `Map<Serializable, Serializable>`
35
+ - `RegExp`
36
+ - `Set<Serializable>`
37
+ - `URL`
38
+ - `URLSearchParams`
39
+ - `Uint8Array`, `Uint8ClampedArray`, `Uint16Array`, `Uint32Array`
40
+
41
+ **Notable:**
42
+
43
+ <Callout type="info">
44
+ These types have special handling and are explained in detail in the sections below.
45
+ </Callout>
46
+
47
+ - `Headers`
48
+ - `Request`
49
+ - `Response`
50
+ - `ReadableStream<Serializable>`
51
+ - `WritableStream<Serializable>`
52
+
53
+ ## Streaming
54
+
55
+ `ReadableStream` and `WritableStream` are supported as serializable types with special handling. These streams can be passed between workflow and step functions while maintaining their streaming capabilities.
56
+
57
+ For complete information about using streams in workflows, including patterns for AI streaming, file processing, and progress updates, see the [Streaming Guide](/docs/foundations/streaming).
58
+
59
+ ## Request & Response
60
+
61
+ The Web API [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) APIs are supported by the serialization system,
62
+ and can be passed around between workflow and step functions similarly to other data types.
63
+
64
+ As a convenience, these two APIs are treated slightly differently when used
65
+ within a workflow function: calling the `text()` / `json()` / `arrayBuffer()` instance
66
+ methods is automatically treated as a step function invocation. This allows you to consume
67
+ the body directly in the workflow context while maintaining proper serialization and caching.
68
+
69
+ For example, consider how receiving a webhook request provides the entire `Request`
70
+ instance into the workflow context. You may consume the body of that request directly
71
+ in the workflow, which will be cached as a step result for future resumptions of the workflow:
72
+
73
+ ```typescript title="workflows/webhook.ts" lineNumbers
74
+ import { createWebhook } from "workflow";
75
+
76
+ export async function handleWebhookWorkflow() {
77
+ "use workflow";
78
+
79
+ const webhook = createWebhook();
80
+ const request = await webhook;
81
+
82
+ // The body of the request will only be consumed once // [!code highlight]
83
+ const body = await request.json(); // [!code highlight]
84
+
85
+ // …
86
+ }
87
+ ```
88
+
89
+ ### Using `fetch` in Workflows
90
+
91
+ Because `Request` and `Response` are serializable, Workflow DevKit provides a `fetch` function that can be used directly in workflow functions:
92
+
93
+ ```typescript title="workflows/api-call.ts" lineNumbers
94
+ import { fetch } from "workflow"; // [!code highlight]
95
+
96
+ export async function apiWorkflow() {
97
+ "use workflow";
98
+
99
+ // fetch can be called directly in workflows // [!code highlight]
100
+ const response = await fetch("https://api.example.com/data"); // [!code highlight]
101
+ const data = await response.json();
102
+
103
+ return data;
104
+ }
105
+ ```
106
+
107
+ The implementation is straightforward - `fetch` from workflow is a step function that wraps the standard `fetch`:
108
+
109
+ ```typescript title="Implementation" lineNumbers
110
+ export async function fetch(...args: Parameters<typeof globalThis.fetch>) {
111
+ "use step";
112
+ return globalThis.fetch(...args);
113
+ }
114
+ ```
115
+
116
+ This allows you to make HTTP requests directly in workflow functions while maintaining deterministic replay behavior through automatic caching.
117
+
118
+ ## Pass-by-Value Semantics
119
+
120
+ **Parameters are passed by value, not by reference.** Steps receive deserialized copies of data. Mutations inside a step won't affect the original in the workflow.
121
+
122
+ **Incorrect:**
123
+
124
+ ```typescript title="workflows/incorrect-mutation.ts" lineNumbers
125
+ export async function updateUserWorkflow(userId: string) {
126
+ "use workflow";
127
+
128
+ let user = { id: userId, name: "John", email: "john@example.com" };
129
+ await updateUserStep(user);
130
+
131
+ // user.email is still "john@example.com" // [!code highlight]
132
+ console.log(user.email); // [!code highlight]
133
+ }
134
+
135
+ async function updateUserStep(user: { id: string; name: string; email: string }) {
136
+ "use step";
137
+ user.email = "newemail@example.com"; // Changes are lost // [!code highlight]
138
+ }
139
+ ```
140
+
141
+ **Correct - return the modified data:**
142
+
143
+ ```typescript title="workflows/correct-mutation.ts" lineNumbers
144
+ export async function updateUserWorkflow(userId: string) {
145
+ "use workflow";
146
+
147
+ let user = { id: userId, name: "John", email: "john@example.com" };
148
+ user = await updateUserStep(user); // Reassign the return value // [!code highlight]
149
+
150
+ console.log(user.email); // "newemail@example.com"
151
+ }
152
+
153
+ async function updateUserStep(user: { id: string; name: string; email: string }) {
154
+ "use step";
155
+ user.email = "newemail@example.com";
156
+ return user; // [!code highlight]
157
+ }
158
+ ```
@@ -0,0 +1,212 @@
1
+ ---
2
+ title: Starting Workflows
3
+ description: Trigger workflow execution with the start() function and track progress with Run objects.
4
+ ---
5
+
6
+ Once you've defined your workflow functions, you need to trigger them to begin execution. This is done using the `start()` function from `workflow/api`, which enqueues a new workflow run and returns a `Run` object that you can use to track its progress.
7
+
8
+ ## The `start()` Function
9
+
10
+ The [`start()`](/docs/api-reference/workflow-api/start) function is used to programmatically trigger workflow executions from runtime contexts like API routes, Server Actions, or any server-side code.
11
+
12
+ ```typescript lineNumbers
13
+ import { start } from "workflow/api";
14
+ import { handleUserSignup } from "./workflows/user-signup";
15
+
16
+ export async function POST(request: Request) {
17
+ const { email } = await request.json();
18
+
19
+ // Start the workflow
20
+ const run = await start(handleUserSignup, [email]); // [!code highlight]
21
+
22
+ return Response.json({
23
+ message: "Workflow started",
24
+ runId: run.runId
25
+ });
26
+ }
27
+ ```
28
+
29
+ **Key Points:**
30
+
31
+ - `start()` returns immediately after enqueuing the workflow - it doesn't wait for completion
32
+ - The first argument is your workflow function
33
+ - The second argument is an array of arguments to pass to the workflow (optional if the workflow takes no arguments)
34
+ - All arguments must be [serializable](/docs/foundations/serialization)
35
+
36
+ **Learn more**: [`start()` API Reference](/docs/api-reference/workflow-api/start)
37
+
38
+ ## The `Run` Object
39
+
40
+ When you call `start()`, it returns a [`Run`](/docs/api-reference/workflow-api/start#returns) object that provides access to the workflow's status and results.
41
+
42
+ ```typescript lineNumbers
43
+ import { start } from "workflow/api";
44
+ import { processOrder } from "./workflows/process-order";
45
+
46
+ const run = await start(processOrder, [/* orderId */]);
47
+
48
+ // The run object has properties you can await
49
+ console.log("Run ID:", run.runId);
50
+
51
+ // Check the workflow status
52
+ const status = await run.status; // "running" | "completed" | "failed"
53
+
54
+ // Get the workflow's return value (blocks until completion)
55
+ const result = await run.returnValue;
56
+ ```
57
+
58
+ **Key Properties:**
59
+
60
+ - `runId` - Unique identifier for this workflow run
61
+ - `status` - Current status of the workflow (async)
62
+ - `returnValue` - The value returned by the workflow function (async, blocks until completion)
63
+ - `readable` - ReadableStream for streaming updates from the workflow
64
+
65
+ <Callout type="info">
66
+ Most `Run` properties are async getters that return promises. You need to `await` them to get their values. For a complete list of properties and methods, see the API reference below.
67
+ </Callout>
68
+
69
+ **Learn more**: [`Run` API Reference](/docs/api-reference/workflow-api/start#returns)
70
+
71
+ ## Common Patterns
72
+
73
+ ### Fire and Forget
74
+
75
+ The most common pattern is to start a workflow and immediately return, letting it execute in the background:
76
+
77
+ ```typescript lineNumbers
78
+ import { start } from "workflow/api";
79
+ import { sendNotifications } from "./workflows/notifications";
80
+
81
+ export async function POST(request: Request) {
82
+ // Start workflow and don't wait for it
83
+ const run = await start(sendNotifications, [userId]);
84
+
85
+ // Return immediately
86
+ return Response.json({
87
+ message: "Notifications queued",
88
+ runId: run.runId
89
+ });
90
+ }
91
+ ```
92
+
93
+ ### Wait for Completion
94
+
95
+ If you need to wait for the workflow to complete before responding:
96
+
97
+ ```typescript lineNumbers
98
+ import { start } from "workflow/api";
99
+ import { generateReport } from "./workflows/reports";
100
+
101
+ export async function POST(request: Request) {
102
+ const run = await start(generateReport, [reportId]);
103
+
104
+ // Wait for the workflow to complete
105
+ const report = await run.returnValue; // [!code highlight]
106
+
107
+ return Response.json({ report });
108
+ }
109
+ ```
110
+
111
+ <Callout type="warn">
112
+ Be cautious when waiting for `returnValue` - if your workflow takes a long time, your API route may timeout.
113
+ </Callout>
114
+
115
+ ### Stream Updates to Client
116
+
117
+ Stream real-time updates from your workflow as it executes, without waiting for completion:
118
+
119
+ ```typescript lineNumbers
120
+ import { start } from "workflow/api";
121
+ import { generateAIContent } from "./workflows/ai-generation";
122
+
123
+ export async function POST(request: Request) {
124
+ const { prompt } = await request.json();
125
+
126
+ // Start the workflow
127
+ const run = await start(generateAIContent, [prompt]);
128
+
129
+ // Get the readable stream (can also use run.readable as shorthand)
130
+ const stream = run.getReadable(); // [!code highlight]
131
+
132
+ // Return the stream immediately
133
+ return new Response(stream, {
134
+ headers: {
135
+ "Content-Type": "application/octet-stream",
136
+ },
137
+ });
138
+ }
139
+ ```
140
+
141
+ Your workflow can write to the stream using [`getWritable()`](/docs/api-reference/workflow/get-writable):
142
+
143
+ ```typescript lineNumbers
144
+ import { getWritable } from "workflow";
145
+
146
+ export async function generateAIContent(prompt: string) {
147
+ "use workflow";
148
+
149
+ const writable = getWritable(); // [!code highlight]
150
+
151
+ await streamContentToClient(writable, prompt);
152
+
153
+ return { status: "complete" };
154
+ }
155
+
156
+ async function streamContentToClient(
157
+ writable: WritableStream,
158
+ prompt: string
159
+ ) {
160
+ "use step";
161
+
162
+ const writer = writable.getWriter();
163
+
164
+ // Stream updates as they become available
165
+ for (let i = 0; i < 10; i++) {
166
+ const chunk = new TextEncoder().encode(`Update ${i}\n`);
167
+ await writer.write(chunk);
168
+ }
169
+
170
+ writer.releaseLock();
171
+ }
172
+ ```
173
+
174
+ <Callout type="info">
175
+ Streams are particularly useful for AI workflows where you want to show progress to users in real-time, or for long-running processes that produce intermediate results.
176
+ </Callout>
177
+
178
+ **Learn more**: [Streaming in Workflows](/docs/foundations/serialization#streaming)
179
+
180
+ ### Check Status Later
181
+
182
+ You can retrieve a workflow run later using its `runId` with [`getRun()`](/docs/api-reference/workflow-api/get-run):
183
+
184
+ ```typescript lineNumbers
185
+ import { getRun } from "workflow/api";
186
+
187
+ export async function GET(request: Request) {
188
+ const url = new URL(request.url);
189
+ const runId = url.searchParams.get("runId");
190
+
191
+ // Retrieve the existing run
192
+ const run = getRun(runId); // [!code highlight]
193
+
194
+ // Check its status
195
+ const status = await run.status;
196
+
197
+ if (status === "completed") {
198
+ const result = await run.returnValue;
199
+ return Response.json({ result });
200
+ }
201
+
202
+ return Response.json({ status });
203
+ }
204
+ ```
205
+
206
+ ## Next Steps
207
+
208
+ Now that you understand how to start workflows and track their execution:
209
+
210
+ - Learn about [Common Patterns](/docs/foundations/common-patterns) for organizing complex workflows
211
+ - Explore [Errors & Retrying](/docs/foundations/errors-and-retries) to handle failures gracefully
212
+ - Check the [`start()` API Reference](/docs/api-reference/workflow-api/start) for complete details