rivetkit 0.0.0-skip-ready-wait-flatten-client-options.1cae221 → 0.0.0-sqlite-uds.4e59a38

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 (253) hide show
  1. package/dist/browser/client.d.ts +561 -89
  2. package/dist/browser/client.js +1063 -430
  3. package/dist/browser/client.js.map +1 -1
  4. package/dist/browser/inspector/client.d.ts +22 -2
  5. package/dist/browser/inspector/client.js +1036 -232
  6. package/dist/browser/inspector/client.js.map +1 -1
  7. package/dist/tsup/actor/errors.cjs +6 -2
  8. package/dist/tsup/actor/errors.cjs.map +1 -1
  9. package/dist/tsup/actor/errors.d.cts +1 -74
  10. package/dist/tsup/actor/errors.d.ts +1 -74
  11. package/dist/tsup/actor/errors.js +5 -1
  12. package/dist/tsup/agent-os/index.cjs +2218 -2082
  13. package/dist/tsup/agent-os/index.cjs.map +1 -1
  14. package/dist/tsup/agent-os/index.d.cts +556 -85
  15. package/dist/tsup/agent-os/index.d.ts +556 -85
  16. package/dist/tsup/agent-os/index.js +2220 -2084
  17. package/dist/tsup/agent-os/index.js.map +1 -1
  18. package/dist/tsup/{chunk-NFC5VU36.cjs → chunk-3GC3EP6D.cjs} +18 -10
  19. package/dist/tsup/chunk-3GC3EP6D.cjs.map +1 -0
  20. package/dist/tsup/{chunk-7MRGNVSR.js → chunk-3GLNEWGY.js} +78 -6
  21. package/dist/tsup/chunk-3GLNEWGY.js.map +1 -0
  22. package/dist/tsup/{chunk-V3QNBJ7N.cjs → chunk-4FC7TVS6.cjs} +35 -10
  23. package/dist/tsup/chunk-4FC7TVS6.cjs.map +1 -0
  24. package/dist/tsup/{chunk-POTPHU3P.cjs → chunk-62LSMTP2.cjs} +3 -3
  25. package/dist/tsup/{chunk-POTPHU3P.cjs.map → chunk-62LSMTP2.cjs.map} +1 -1
  26. package/dist/tsup/{chunk-OIKOPSXQ.js → chunk-7IVUT2JT.js} +12 -4
  27. package/dist/tsup/chunk-7IVUT2JT.js.map +1 -0
  28. package/dist/tsup/{chunk-22XU3BVY.cjs → chunk-GEYQLGXC.cjs} +925 -328
  29. package/dist/tsup/chunk-GEYQLGXC.cjs.map +1 -0
  30. package/dist/tsup/{chunk-D2TLG75Y.cjs → chunk-GMN45CQ6.cjs} +10 -10
  31. package/dist/tsup/chunk-GMN45CQ6.cjs.map +1 -0
  32. package/dist/tsup/{chunk-3BFYSYRU.js → chunk-HXUEHHJF.js} +3 -2
  33. package/dist/tsup/chunk-HXUEHHJF.js.map +1 -0
  34. package/dist/tsup/{chunk-IOYKCB6Y.cjs → chunk-I336PMWT.cjs} +44 -9
  35. package/dist/tsup/chunk-I336PMWT.cjs.map +1 -0
  36. package/dist/tsup/{chunk-RZEJJJKU.js → chunk-IB73AMGJ.js} +42 -7
  37. package/dist/tsup/chunk-IB73AMGJ.js.map +1 -0
  38. package/dist/tsup/{chunk-4ZIWB4CQ.js → chunk-ITWJ6Y7G.js} +2 -2
  39. package/dist/tsup/{chunk-PCBNKI2J.js → chunk-JZ7TWV65.js} +1 -1
  40. package/dist/tsup/chunk-JZ7TWV65.js.map +1 -0
  41. package/dist/tsup/{chunk-W54QCENI.js → chunk-KTNBYGRU.js} +134 -20
  42. package/dist/tsup/chunk-KTNBYGRU.js.map +1 -0
  43. package/dist/tsup/{chunk-AK57AL7S.cjs → chunk-OAPVVVTX.cjs} +79 -7
  44. package/dist/tsup/chunk-OAPVVVTX.cjs.map +1 -0
  45. package/dist/tsup/{chunk-TPBHXFB2.cjs → chunk-OUDV3ITX.cjs} +138 -24
  46. package/dist/tsup/chunk-OUDV3ITX.cjs.map +1 -0
  47. package/dist/tsup/{chunk-XNZR7UD2.cjs → chunk-PRXTIERO.cjs} +90 -65
  48. package/dist/tsup/chunk-PRXTIERO.cjs.map +1 -0
  49. package/dist/tsup/{chunk-LLD2D5LO.cjs → chunk-VE2X4KMG.cjs} +3 -2
  50. package/dist/tsup/chunk-VE2X4KMG.cjs.map +1 -0
  51. package/dist/tsup/{chunk-KSG2COSQ.js → chunk-WRZEVVLL.js} +6 -6
  52. package/dist/tsup/chunk-WRZEVVLL.js.map +1 -0
  53. package/dist/tsup/{chunk-LNMB25HW.js → chunk-XAIMHUPG.js} +780 -183
  54. package/dist/tsup/chunk-XAIMHUPG.js.map +1 -0
  55. package/dist/tsup/{chunk-D4TSTM6C.js → chunk-XZ62SWSC.js} +83 -58
  56. package/dist/tsup/chunk-XZ62SWSC.js.map +1 -0
  57. package/dist/tsup/{chunk-2NDZ7JCR.cjs → chunk-ZA7FLHKH.cjs} +1 -1
  58. package/dist/tsup/chunk-ZA7FLHKH.cjs.map +1 -0
  59. package/dist/tsup/{chunk-K34B3OVG.js → chunk-ZZ3WBRPD.js} +34 -9
  60. package/dist/tsup/chunk-ZZ3WBRPD.js.map +1 -0
  61. package/dist/tsup/client/mod.cjs +9 -9
  62. package/dist/tsup/client/mod.cjs.map +1 -1
  63. package/dist/tsup/client/mod.d.cts +8 -9
  64. package/dist/tsup/client/mod.d.ts +8 -9
  65. package/dist/tsup/client/mod.js +8 -8
  66. package/dist/tsup/common/log.cjs +5 -3
  67. package/dist/tsup/common/log.cjs.map +1 -1
  68. package/dist/tsup/common/log.d.cts +5 -1
  69. package/dist/tsup/common/log.d.ts +5 -1
  70. package/dist/tsup/common/log.js +6 -4
  71. package/dist/tsup/common/websocket.cjs +4 -4
  72. package/dist/tsup/common/websocket.js +3 -3
  73. package/dist/tsup/{config-CRdGwwbr.d.cts → config-CxG53eQo.d.cts} +577 -36
  74. package/dist/tsup/{config-kxXbtrJU.d.ts → config-DLOxy81E.d.cts} +5 -5
  75. package/dist/tsup/{config-kxXbtrJU.d.cts → config-DLOxy81E.d.ts} +5 -5
  76. package/dist/tsup/{config-DIpBWm5C.d.ts → config-Ds6DCRhV.d.ts} +577 -36
  77. package/dist/tsup/context-8KlcOYIs.d.cts +129 -0
  78. package/dist/tsup/context-Cfbm4QLr.d.ts +129 -0
  79. package/dist/tsup/db/drizzle.cjs +151 -79
  80. package/dist/tsup/db/drizzle.cjs.map +1 -1
  81. package/dist/tsup/db/drizzle.d.cts +2 -2
  82. package/dist/tsup/db/drizzle.d.ts +2 -2
  83. package/dist/tsup/db/drizzle.js +151 -79
  84. package/dist/tsup/db/drizzle.js.map +1 -1
  85. package/dist/tsup/db/mod.cjs +79 -24
  86. package/dist/tsup/db/mod.cjs.map +1 -1
  87. package/dist/tsup/db/mod.d.cts +2 -2
  88. package/dist/tsup/db/mod.d.ts +2 -2
  89. package/dist/tsup/db/mod.js +78 -23
  90. package/dist/tsup/db/mod.js.map +1 -1
  91. package/dist/tsup/dynamic/mod.cjs +24 -0
  92. package/dist/tsup/dynamic/mod.cjs.map +1 -0
  93. package/dist/tsup/dynamic/mod.d.cts +37 -0
  94. package/dist/tsup/dynamic/mod.d.ts +37 -0
  95. package/dist/tsup/dynamic/mod.js +24 -0
  96. package/dist/tsup/dynamic/mod.js.map +1 -0
  97. package/dist/tsup/inspector/mod.cjs +47 -12
  98. package/dist/tsup/inspector/mod.cjs.map +1 -1
  99. package/dist/tsup/inspector/mod.d.cts +37 -15
  100. package/dist/tsup/inspector/mod.d.ts +37 -15
  101. package/dist/tsup/inspector/mod.js +46 -11
  102. package/dist/tsup/inspector/mod.js.map +1 -1
  103. package/dist/tsup/inspector-tab/mod.cjs +162 -0
  104. package/dist/tsup/inspector-tab/mod.cjs.map +1 -0
  105. package/dist/tsup/inspector-tab/mod.d.cts +240 -0
  106. package/dist/tsup/inspector-tab/mod.d.ts +240 -0
  107. package/dist/tsup/inspector-tab/mod.js +162 -0
  108. package/dist/tsup/inspector-tab/mod.js.map +1 -0
  109. package/dist/tsup/mod.cjs +1078 -479
  110. package/dist/tsup/mod.cjs.map +1 -1
  111. package/dist/tsup/mod.d.cts +5 -6
  112. package/dist/tsup/mod.d.ts +5 -6
  113. package/dist/tsup/mod.js +996 -397
  114. package/dist/tsup/mod.js.map +1 -1
  115. package/dist/tsup/test/mod.cjs +21 -18
  116. package/dist/tsup/test/mod.cjs.map +1 -1
  117. package/dist/tsup/test/mod.d.cts +4 -5
  118. package/dist/tsup/test/mod.d.ts +4 -5
  119. package/dist/tsup/test/mod.js +18 -15
  120. package/dist/tsup/test/mod.js.map +1 -1
  121. package/dist/tsup/utils-CqDnC_PS.d.cts +104 -0
  122. package/dist/tsup/utils-CqDnC_PS.d.ts +104 -0
  123. package/dist/tsup/utils.cjs +3 -3
  124. package/dist/tsup/utils.d.cts +1 -1
  125. package/dist/tsup/utils.d.ts +1 -1
  126. package/dist/tsup/utils.js +2 -2
  127. package/dist/tsup/workflow/mod.cjs +386 -322
  128. package/dist/tsup/workflow/mod.cjs.map +1 -1
  129. package/dist/tsup/workflow/mod.d.cts +8 -9
  130. package/dist/tsup/workflow/mod.d.ts +8 -9
  131. package/dist/tsup/workflow/mod.js +363 -299
  132. package/dist/tsup/workflow/mod.js.map +1 -1
  133. package/package.json +35 -14
  134. package/src/actor/config.ts +188 -59
  135. package/src/actor/contexts/index.ts +7 -2
  136. package/src/actor/definition.ts +17 -19
  137. package/src/actor/driver.ts +3 -3
  138. package/src/actor/errors.ts +70 -7
  139. package/src/actor/instance/mod.ts +39 -56
  140. package/src/actor/keys.ts +2 -1
  141. package/src/actor/mod.ts +22 -20
  142. package/src/actor/schema.ts +2 -2
  143. package/src/agent-os/actor/index.ts +38 -18
  144. package/src/agent-os/actor/preview.ts +1 -2
  145. package/src/agent-os/actor/session.ts +2 -2
  146. package/src/agent-os/config.ts +1 -1
  147. package/src/agent-os/fs/database-vfs.ts +1 -1
  148. package/src/agent-os/index.ts +16 -15
  149. package/src/client/actor-common.ts +88 -62
  150. package/src/client/actor-conn.ts +58 -63
  151. package/src/client/actor-handle.ts +125 -71
  152. package/src/client/actor-query.ts +5 -5
  153. package/src/client/config.ts +3 -3
  154. package/src/client/errors.ts +2 -1
  155. package/src/client/lifecycle-errors.ts +2 -4
  156. package/src/client/query.ts +1 -1
  157. package/src/client/queue.ts +8 -3
  158. package/src/client/raw-utils.ts +10 -10
  159. package/src/client/resolve-gateway-target.ts +1 -1
  160. package/src/client/utils.ts +34 -10
  161. package/src/common/actor-router-consts.ts +7 -4
  162. package/src/common/actor-websocket.ts +3 -1
  163. package/src/common/bare/actor-persist/v1.ts +205 -163
  164. package/src/common/bare/actor-persist/v2.ts +265 -213
  165. package/src/common/bare/actor-persist/v3.ts +176 -172
  166. package/src/common/bare/actor-persist/v4.ts +254 -253
  167. package/src/common/bare/generated/client-protocol/v4.ts +599 -0
  168. package/src/common/bare/generated/inspector/v5.ts +1016 -0
  169. package/src/common/bare/transport/v1.ts +694 -542
  170. package/src/common/client-protocol-versioned.ts +176 -67
  171. package/src/common/client-protocol-zod.ts +7 -0
  172. package/src/common/client-protocol.ts +1 -1
  173. package/src/common/database/config.ts +16 -5
  174. package/src/common/database/mod.test.ts +83 -16
  175. package/src/common/database/mod.ts +86 -30
  176. package/src/common/database/native-database.test.ts +35 -22
  177. package/src/common/database/native-database.ts +26 -10
  178. package/src/common/database/shared.ts +1 -0
  179. package/src/common/encoding.ts +250 -16
  180. package/src/common/engine.ts +28 -1
  181. package/src/common/eventsource.ts +1 -1
  182. package/src/common/inline-websocket-adapter.ts +14 -13
  183. package/src/common/log.ts +15 -8
  184. package/src/common/router.ts +49 -23
  185. package/src/common/utils.ts +10 -202
  186. package/src/common/websocket-interface.ts +1 -1
  187. package/src/db/drizzle.ts +173 -96
  188. package/src/db/mod.ts +1 -1
  189. package/src/devtools-loader/index.ts +4 -7
  190. package/src/devtools-loader/serve-devtools.ts +26 -0
  191. package/src/drivers/engine/actor-driver.ts +76 -73
  192. package/src/dynamic/instance.ts +32 -0
  193. package/src/dynamic/internal.ts +50 -0
  194. package/src/dynamic/isolate-runtime.ts +66 -0
  195. package/src/dynamic/mod.ts +32 -0
  196. package/src/engine-client/actor-http-client.ts +6 -9
  197. package/src/engine-client/actor-websocket-client.ts +14 -13
  198. package/src/engine-client/api-endpoints.ts +51 -2
  199. package/src/engine-client/api-utils.ts +2 -2
  200. package/src/engine-client/driver.ts +3 -4
  201. package/src/engine-client/mod.ts +17 -10
  202. package/src/engine-client/ws-proxy.ts +9 -4
  203. package/src/inspector/client.browser.ts +66 -15
  204. package/src/inspector/mod.ts +2 -4
  205. package/src/inspector-tab/mod.ts +300 -0
  206. package/src/registry/config/envoy.ts +1 -2
  207. package/src/registry/config/index.ts +46 -20
  208. package/src/registry/index.ts +364 -87
  209. package/src/registry/napi-runtime.ts +97 -8
  210. package/src/registry/native-validation.ts +10 -12
  211. package/src/registry/native.ts +592 -343
  212. package/src/registry/process-metrics.ts +250 -0
  213. package/src/registry/runtime.ts +85 -6
  214. package/src/registry/wasm-runtime.ts +72 -3
  215. package/src/registry/write-through-proxy.ts +40 -0
  216. package/src/serde.ts +2 -2
  217. package/src/serverless/configure.ts +19 -8
  218. package/src/test/mod.ts +11 -8
  219. package/src/utils/crypto.ts +14 -0
  220. package/src/utils/endpoint-parser.ts +1 -1
  221. package/src/utils/env-vars.ts +37 -0
  222. package/src/utils/router.ts +1 -1
  223. package/src/utils.ts +1 -2
  224. package/src/workflow/context.ts +703 -240
  225. package/src/workflow/driver.ts +23 -12
  226. package/src/workflow/inspector.ts +12 -3
  227. package/src/workflow/mod.ts +37 -23
  228. package/dist/tsup/chunk-22XU3BVY.cjs.map +0 -1
  229. package/dist/tsup/chunk-2NDZ7JCR.cjs.map +0 -1
  230. package/dist/tsup/chunk-3BFYSYRU.js.map +0 -1
  231. package/dist/tsup/chunk-7MRGNVSR.js.map +0 -1
  232. package/dist/tsup/chunk-AK57AL7S.cjs.map +0 -1
  233. package/dist/tsup/chunk-D2TLG75Y.cjs.map +0 -1
  234. package/dist/tsup/chunk-D4TSTM6C.js.map +0 -1
  235. package/dist/tsup/chunk-IOYKCB6Y.cjs.map +0 -1
  236. package/dist/tsup/chunk-K34B3OVG.js.map +0 -1
  237. package/dist/tsup/chunk-KSG2COSQ.js.map +0 -1
  238. package/dist/tsup/chunk-LLD2D5LO.cjs.map +0 -1
  239. package/dist/tsup/chunk-LNMB25HW.js.map +0 -1
  240. package/dist/tsup/chunk-NFC5VU36.cjs.map +0 -1
  241. package/dist/tsup/chunk-OIKOPSXQ.js.map +0 -1
  242. package/dist/tsup/chunk-PCBNKI2J.js.map +0 -1
  243. package/dist/tsup/chunk-RZEJJJKU.js.map +0 -1
  244. package/dist/tsup/chunk-TPBHXFB2.cjs.map +0 -1
  245. package/dist/tsup/chunk-V3QNBJ7N.cjs.map +0 -1
  246. package/dist/tsup/chunk-W54QCENI.js.map +0 -1
  247. package/dist/tsup/chunk-XNZR7UD2.cjs.map +0 -1
  248. package/dist/tsup/context-B7G6sk7x.d.ts +0 -92
  249. package/dist/tsup/context-DzMRHkjC.d.cts +0 -92
  250. package/dist/tsup/utils-fwx3o3K9.d.cts +0 -18
  251. package/dist/tsup/utils-fwx3o3K9.d.ts +0 -18
  252. package/src/utils/serve.ts +0 -217
  253. /package/dist/tsup/{chunk-4ZIWB4CQ.js.map → chunk-ITWJ6Y7G.js.map} +0 -0
@@ -1,41 +1,40 @@
1
- // @ts-nocheck
2
- import type { RunContext } from "@/actor/config";
1
+ import type {
2
+ BranchConfig,
3
+ BranchOutput,
4
+ EntryKindType,
5
+ LoopConfig,
6
+ LoopResult,
7
+ StepConfig,
8
+ TryBlockConfig,
9
+ TryBlockResult,
10
+ TryStepConfig,
11
+ TryStepResult,
12
+ WorkflowContextInterface,
13
+ WorkflowQueueMessage,
14
+ } from "@rivetkit/workflow-engine";
3
15
  import type {
4
16
  QueueFilterName,
5
17
  QueueNextBatchOptions,
6
18
  QueueNextOptions,
7
19
  QueueResultMessageForName,
8
20
  } from "@/actor/config";
9
- import type { Client } from "@/client/client";
10
- import type { Registry } from "@/registry";
21
+ import { RAW_STATE_SYMBOL, type RunContext } from "@/actor/config";
11
22
  import type {
12
- BaseActorDefinition,
13
23
  AnyActorDefinition,
24
+ BaseActorDefinition,
14
25
  } from "@/actor/definition";
15
- import type {
16
- AnyDatabaseProvider,
17
- InferDatabaseClient,
18
- } from "@/common/database/config";
19
26
  import type {
20
27
  EventSchemaConfig,
21
28
  InferEventArgs,
22
29
  InferSchemaMap,
23
30
  QueueSchemaConfig,
24
31
  } from "@/actor/schema";
25
- import type { WorkflowContextInterface } from "@rivetkit/workflow-engine";
32
+ import type { Client } from "@/client/client";
26
33
  import type {
27
- BranchConfig,
28
- BranchOutput,
29
- EntryKindType,
30
- LoopConfig,
31
- LoopResult,
32
- StepConfig,
33
- TryBlockConfig,
34
- TryBlockResult,
35
- TryStepConfig,
36
- TryStepResult,
37
- WorkflowQueueMessage,
38
- } from "@rivetkit/workflow-engine";
34
+ AnyDatabaseProvider,
35
+ InferDatabaseClient,
36
+ } from "@/common/database/config";
37
+ import type { Registry } from "@/registry";
39
38
  import { WORKFLOW_GUARD_KV_KEY } from "./constants";
40
39
 
41
40
  type WorkflowActorQueueNextOptions<
@@ -56,7 +55,177 @@ type WorkflowActorQueueNextBatchOptions<
56
55
  type WorkflowActorQueueNextBatchOptionsFallback<TCompletable extends boolean> =
57
56
  Omit<QueueNextBatchOptions<string, TCompletable>, "signal">;
58
57
 
59
- type ActorWorkflowLoopConfig<
58
+ // Step run callbacks receive a WorkflowStepContext, which is the only place
59
+ // actor data (state/db/vars/client) may be touched.
60
+ type WorkflowStepRun<
61
+ T,
62
+ TState,
63
+ TConnParams,
64
+ TConnState,
65
+ TVars,
66
+ TInput,
67
+ TDatabase extends AnyDatabaseProvider,
68
+ TEvents extends EventSchemaConfig,
69
+ TQueues extends QueueSchemaConfig,
70
+ > = (
71
+ step: WorkflowStepContext<
72
+ TState,
73
+ TConnParams,
74
+ TConnState,
75
+ TVars,
76
+ TInput,
77
+ TDatabase,
78
+ TEvents,
79
+ TQueues
80
+ >,
81
+ ) => Promise<T>;
82
+
83
+ // Step rollback callbacks compensate a committed step, so they also run with a
84
+ // WorkflowStepContext to mutate actor data.
85
+ type WorkflowStepRollback<
86
+ T,
87
+ TState,
88
+ TConnParams,
89
+ TConnState,
90
+ TVars,
91
+ TInput,
92
+ TDatabase extends AnyDatabaseProvider,
93
+ TEvents extends EventSchemaConfig,
94
+ TQueues extends QueueSchemaConfig,
95
+ > = (
96
+ step: WorkflowStepContext<
97
+ TState,
98
+ TConnParams,
99
+ TConnState,
100
+ TVars,
101
+ TInput,
102
+ TDatabase,
103
+ TEvents,
104
+ TQueues
105
+ >,
106
+ output: T,
107
+ ) => Promise<void>;
108
+
109
+ // Orchestration callbacks (try/loop/race/join) receive a WorkflowContext,
110
+ // because inside them you sequence further steps rather than touch actor data.
111
+ type WorkflowContextRun<
112
+ T,
113
+ TState,
114
+ TConnParams,
115
+ TConnState,
116
+ TVars,
117
+ TInput,
118
+ TDatabase extends AnyDatabaseProvider,
119
+ TEvents extends EventSchemaConfig,
120
+ TQueues extends QueueSchemaConfig,
121
+ > = (
122
+ ctx: WorkflowContext<
123
+ TState,
124
+ TConnParams,
125
+ TConnState,
126
+ TVars,
127
+ TInput,
128
+ TDatabase,
129
+ TEvents,
130
+ TQueues
131
+ >,
132
+ ) => Promise<T>;
133
+
134
+ export type WorkflowStepConfig<
135
+ T,
136
+ TState,
137
+ TConnParams,
138
+ TConnState,
139
+ TVars,
140
+ TInput,
141
+ TDatabase extends AnyDatabaseProvider,
142
+ TEvents extends EventSchemaConfig,
143
+ TQueues extends QueueSchemaConfig,
144
+ > = Omit<StepConfig<T>, "run" | "rollback"> & {
145
+ run: WorkflowStepRun<
146
+ T,
147
+ TState,
148
+ TConnParams,
149
+ TConnState,
150
+ TVars,
151
+ TInput,
152
+ TDatabase,
153
+ TEvents,
154
+ TQueues
155
+ >;
156
+ rollback?: WorkflowStepRollback<
157
+ T,
158
+ TState,
159
+ TConnParams,
160
+ TConnState,
161
+ TVars,
162
+ TInput,
163
+ TDatabase,
164
+ TEvents,
165
+ TQueues
166
+ >;
167
+ };
168
+
169
+ export type WorkflowTryStepConfig<
170
+ T,
171
+ TState,
172
+ TConnParams,
173
+ TConnState,
174
+ TVars,
175
+ TInput,
176
+ TDatabase extends AnyDatabaseProvider,
177
+ TEvents extends EventSchemaConfig,
178
+ TQueues extends QueueSchemaConfig,
179
+ > = Omit<TryStepConfig<T>, "run" | "rollback"> & {
180
+ run: WorkflowStepRun<
181
+ T,
182
+ TState,
183
+ TConnParams,
184
+ TConnState,
185
+ TVars,
186
+ TInput,
187
+ TDatabase,
188
+ TEvents,
189
+ TQueues
190
+ >;
191
+ rollback?: WorkflowStepRollback<
192
+ T,
193
+ TState,
194
+ TConnParams,
195
+ TConnState,
196
+ TVars,
197
+ TInput,
198
+ TDatabase,
199
+ TEvents,
200
+ TQueues
201
+ >;
202
+ };
203
+
204
+ export type WorkflowTryConfig<
205
+ T,
206
+ TState,
207
+ TConnParams,
208
+ TConnState,
209
+ TVars,
210
+ TInput,
211
+ TDatabase extends AnyDatabaseProvider,
212
+ TEvents extends EventSchemaConfig,
213
+ TQueues extends QueueSchemaConfig,
214
+ > = Omit<TryBlockConfig<T>, "run"> & {
215
+ run: WorkflowContextRun<
216
+ T,
217
+ TState,
218
+ TConnParams,
219
+ TConnState,
220
+ TVars,
221
+ TInput,
222
+ TDatabase,
223
+ TEvents,
224
+ TQueues
225
+ >;
226
+ };
227
+
228
+ export type WorkflowLoopConfig<
60
229
  S,
61
230
  T,
62
231
  TState,
@@ -69,7 +238,7 @@ type ActorWorkflowLoopConfig<
69
238
  TQueues extends QueueSchemaConfig,
70
239
  > = Omit<LoopConfig<S, T>, "run"> & {
71
240
  run: (
72
- ctx: ActorWorkflowContext<
241
+ ctx: WorkflowContext<
73
242
  TState,
74
243
  TConnParams,
75
244
  TConnState,
@@ -80,10 +249,12 @@ type ActorWorkflowLoopConfig<
80
249
  TQueues
81
250
  >,
82
251
  state: S,
83
- ) => Promise<LoopResult<S, T> | (S extends undefined ? void : never)>;
252
+ ) => Promise<
253
+ LoopResult<S, T> | (S extends undefined ? undefined | void : never)
254
+ >;
84
255
  };
85
256
 
86
- type ActorWorkflowBranchConfig<
257
+ export type WorkflowBranchConfig<
87
258
  TOutput,
88
259
  TState,
89
260
  TConnParams,
@@ -94,8 +265,54 @@ type ActorWorkflowBranchConfig<
94
265
  TEvents extends EventSchemaConfig,
95
266
  TQueues extends QueueSchemaConfig,
96
267
  > = {
97
- run: (
98
- ctx: ActorWorkflowContext<
268
+ run: WorkflowContextRun<
269
+ TOutput,
270
+ TState,
271
+ TConnParams,
272
+ TConnState,
273
+ TVars,
274
+ TInput,
275
+ TDatabase,
276
+ TEvents,
277
+ TQueues
278
+ >;
279
+ };
280
+
281
+ // Marks a step context inactive once its step has finished. Module-private so it
282
+ // never appears on the public surface.
283
+ const DEACTIVATE_STEP = Symbol("workflow.step.deactivate");
284
+
285
+ /**
286
+ * The context handed to a workflow step (`step` / `tryStep` callbacks). This is
287
+ * the only scope where actor data (state, vars, db, client) and side effects
288
+ * (broadcast, queue.send) are reachable. It is valid only while its step is
289
+ * executing; using it after the step resolves throws.
290
+ */
291
+ export class WorkflowStepContext<
292
+ TState,
293
+ TConnParams,
294
+ TConnState,
295
+ TVars,
296
+ TInput,
297
+ TDatabase extends AnyDatabaseProvider,
298
+ TEvents extends EventSchemaConfig = Record<never, never>,
299
+ TQueues extends QueueSchemaConfig = Record<never, never>,
300
+ > {
301
+ #runCtx: RunContext<
302
+ TState,
303
+ TConnParams,
304
+ TConnState,
305
+ TVars,
306
+ TInput,
307
+ TDatabase,
308
+ TEvents,
309
+ TQueues
310
+ >;
311
+ #active = true;
312
+ #onGuardViolation: () => void;
313
+
314
+ constructor(
315
+ runCtx: RunContext<
99
316
  TState,
100
317
  TConnParams,
101
318
  TConnState,
@@ -105,10 +322,133 @@ type ActorWorkflowBranchConfig<
105
322
  TEvents,
106
323
  TQueues
107
324
  >,
108
- ) => Promise<TOutput>;
109
- };
325
+ onGuardViolation: () => void,
326
+ ) {
327
+ this.#runCtx = runCtx;
328
+ this.#onGuardViolation = onGuardViolation;
329
+ }
330
+
331
+ [DEACTIVATE_STEP](): void {
332
+ this.#active = false;
333
+ }
334
+
335
+ #ensureActive(feature: string): void {
336
+ if (!this.#active) {
337
+ this.#onGuardViolation();
338
+ throw new Error(
339
+ `${feature} is only available inside workflow steps`,
340
+ );
341
+ }
342
+ }
343
+
344
+ get actorId(): string {
345
+ return this.#runCtx.actorId;
346
+ }
347
+
348
+ get name(): string {
349
+ return this.#runCtx.name;
350
+ }
351
+
352
+ get key(): string[] {
353
+ return this.#runCtx.key;
354
+ }
355
+
356
+ get log() {
357
+ return this.#runCtx.log;
358
+ }
359
+
360
+ get abortSignal(): AbortSignal {
361
+ return this.#runCtx.abortSignal;
362
+ }
363
+
364
+ get state(): TState extends never ? never : TState {
365
+ this.#ensureActive("state");
366
+ return this.#runCtx.state as TState extends never ? never : TState;
367
+ }
368
+
369
+ get vars(): TVars extends never ? never : TVars {
370
+ this.#ensureActive("vars");
371
+ return this.#runCtx.vars as TVars extends never ? never : TVars;
372
+ }
373
+
374
+ get db(): TDatabase extends never ? never : InferDatabaseClient<TDatabase> {
375
+ this.#ensureActive("db");
376
+ return this.#runCtx.db as TDatabase extends never
377
+ ? never
378
+ : InferDatabaseClient<TDatabase>;
379
+ }
380
+
381
+ client<R extends Registry<any> = Registry<any>>(): Client<R> {
382
+ this.#ensureActive("client");
383
+ return this.#runCtx.client<R>();
384
+ }
385
+
386
+ broadcast<K extends keyof TEvents & string>(
387
+ name: K,
388
+ ...args: InferEventArgs<InferSchemaMap<TEvents>[K]>
389
+ ): void;
390
+ broadcast(
391
+ name: keyof TEvents extends never ? string : never,
392
+ ...args: Array<unknown>
393
+ ): void;
394
+ broadcast(name: string, ...args: Array<unknown>): void {
395
+ this.#ensureActive("broadcast");
396
+ this.#runCtx.broadcast(
397
+ name as never,
398
+ ...(args as unknown[] as never[]),
399
+ );
400
+ }
401
+
402
+ get queue() {
403
+ const self = this;
404
+ function send<K extends keyof TQueues & string>(
405
+ name: K,
406
+ body: InferSchemaMap<TQueues>[K],
407
+ ): Promise<void>;
408
+ function send(
409
+ name: keyof TQueues extends never ? string : never,
410
+ body: unknown,
411
+ ): Promise<void>;
412
+ async function send(name: string, body: unknown): Promise<void> {
413
+ self.#ensureActive("queue.send");
414
+ await self.#runCtx.queue.send(name as never, body as never);
415
+ }
416
+ return { send };
417
+ }
110
418
 
111
- export class ActorWorkflowContext<
419
+ /**
420
+ * Holds the actor awake for the duration of the provided promise. The actor
421
+ * cannot idle-sleep or finalize the sleep grace period until the promise
422
+ * settles.
423
+ */
424
+ keepAwake<T>(promise: Promise<T>): Promise<T> {
425
+ this.#ensureActive("keepAwake");
426
+ return this.#runCtx.keepAwake(promise);
427
+ }
428
+
429
+ /**
430
+ * Registers a promise that the sleep grace period will wait on. Use this for
431
+ * best-effort flush/cleanup work that may complete inside the grace window.
432
+ */
433
+ waitUntil(promise: Promise<void>): void {
434
+ this.#ensureActive("waitUntil");
435
+ this.#runCtx.waitUntil(promise);
436
+ }
437
+
438
+ destroy(): void {
439
+ this.#ensureActive("destroy");
440
+ this.#runCtx.destroy();
441
+ }
442
+ }
443
+
444
+ /**
445
+ * The context handed to the workflow function and to orchestration callbacks
446
+ * (`try` / `loop` / `race` / `join`). It exposes the deterministic, replayable
447
+ * workflow primitives (step, sleep, queue waits, control flow). It deliberately
448
+ * does NOT expose actor data; reach `state`, `db`, `vars`, `client`, and
449
+ * `broadcast` through the step context passed to `step` / `tryStep`.
450
+ */
451
+ export class WorkflowContext<
112
452
  TState,
113
453
  TConnParams,
114
454
  TConnState,
@@ -117,8 +457,7 @@ export class ActorWorkflowContext<
117
457
  TDatabase extends AnyDatabaseProvider,
118
458
  TEvents extends EventSchemaConfig = Record<never, never>,
119
459
  TQueues extends QueueSchemaConfig = Record<never, never>,
120
- > implements WorkflowContextInterface
121
- {
460
+ > {
122
461
  #inner: WorkflowContextInterface;
123
462
  #runCtx: RunContext<
124
463
  TState,
@@ -130,9 +469,6 @@ export class ActorWorkflowContext<
130
469
  TEvents,
131
470
  TQueues
132
471
  >;
133
- #actorAccessDepth = 0;
134
- #allowActorAccess = false;
135
- #guardViolation = false;
136
472
 
137
473
  constructor(
138
474
  inner: WorkflowContextInterface,
@@ -159,6 +495,22 @@ export class ActorWorkflowContext<
159
495
  return this.#inner.abortSignal;
160
496
  }
161
497
 
498
+ get actorId(): string {
499
+ return this.#runCtx.actorId;
500
+ }
501
+
502
+ get name(): string {
503
+ return this.#runCtx.name;
504
+ }
505
+
506
+ get key(): string[] {
507
+ return this.#runCtx.key;
508
+ }
509
+
510
+ get log() {
511
+ return this.#runCtx.log;
512
+ }
513
+
162
514
  get queue() {
163
515
  const self = this;
164
516
  function next<
@@ -178,10 +530,9 @@ export class ActorWorkflowContext<
178
530
  TCompletable
179
531
  >
180
532
  >;
181
- async function next(
182
- name: string,
183
- opts?: WorkflowActorQueueNextOptions<string, boolean>,
184
- ): Promise<WorkflowQueueMessage<unknown>> {
533
+ // The implementation signature stays broad so the schema-typed public
534
+ // overloads above remain compatible with it.
535
+ async function next(name: string, opts?: any): Promise<any> {
185
536
  const message = await self.#inner.queue.next(name, opts);
186
537
  return self.#toActorQueueMessage(message);
187
538
  }
@@ -207,108 +558,232 @@ export class ActorWorkflowContext<
207
558
  >
208
559
  >
209
560
  >;
210
- async function nextBatch(
211
- name: string,
212
- opts?: WorkflowActorQueueNextBatchOptions<string, boolean>,
213
- ): Promise<Array<WorkflowQueueMessage<unknown>>> {
561
+ async function nextBatch(name: string, opts?: any): Promise<any> {
214
562
  const messages = await self.#inner.queue.nextBatch(name, opts);
215
563
  return messages.map((message) =>
216
564
  self.#toActorQueueMessage(message),
217
565
  );
218
566
  }
219
567
 
220
- function send<K extends keyof TQueues & string>(
221
- name: K,
222
- body: InferSchemaMap<TQueues>[K],
223
- ): Promise<void>;
224
- function send(
225
- name: keyof TQueues extends never ? string : never,
226
- body: unknown,
227
- ): Promise<void>;
228
- async function send(name: string, body: unknown): Promise<void> {
229
- self.#ensureActorAccess("queue.send");
230
- await self.#runCtx.queue.send(name as never, body as never);
231
- }
232
-
233
568
  return {
234
569
  next,
235
570
  nextBatch,
236
- send,
237
571
  };
238
572
  }
239
573
 
574
+ step<T>(
575
+ name: string,
576
+ run: WorkflowStepRun<
577
+ T,
578
+ TState,
579
+ TConnParams,
580
+ TConnState,
581
+ TVars,
582
+ TInput,
583
+ TDatabase,
584
+ TEvents,
585
+ TQueues
586
+ >,
587
+ ): Promise<T>;
588
+ step<T>(
589
+ config: WorkflowStepConfig<
590
+ T,
591
+ TState,
592
+ TConnParams,
593
+ TConnState,
594
+ TVars,
595
+ TInput,
596
+ TDatabase,
597
+ TEvents,
598
+ TQueues
599
+ >,
600
+ ): Promise<T>;
240
601
  async step<T>(
241
- nameOrConfig: string | Parameters<WorkflowContextInterface["step"]>[0],
242
- run?: () => Promise<T>,
602
+ nameOrConfig:
603
+ | string
604
+ | WorkflowStepConfig<
605
+ T,
606
+ TState,
607
+ TConnParams,
608
+ TConnState,
609
+ TVars,
610
+ TInput,
611
+ TDatabase,
612
+ TEvents,
613
+ TQueues
614
+ >,
615
+ run?: WorkflowStepRun<
616
+ T,
617
+ TState,
618
+ TConnParams,
619
+ TConnState,
620
+ TVars,
621
+ TInput,
622
+ TDatabase,
623
+ TEvents,
624
+ TQueues
625
+ >,
243
626
  ): Promise<T> {
244
627
  if (typeof nameOrConfig === "string") {
245
628
  if (!run) {
246
629
  throw new Error("Step run function missing");
247
630
  }
631
+ const stepRun = run;
248
632
  return await this.#wrapActive(() =>
249
- this.#inner.step(nameOrConfig, () =>
250
- this.#withActorAccess(run),
251
- ),
633
+ this.#inner.step(nameOrConfig, () => this.#runStep(stepRun)),
252
634
  );
253
635
  }
254
- const stepConfig = nameOrConfig as StepConfig<T>;
636
+ const stepConfig = nameOrConfig;
637
+ const rollback = stepConfig.rollback;
255
638
  const config: StepConfig<T> = {
256
639
  ...stepConfig,
257
- run: () => this.#withActorAccess(stepConfig.run),
640
+ run: () => this.#runStep(stepConfig.run),
641
+ rollback: rollback
642
+ ? (_ctx, output) => this.#runRollback(rollback, output)
643
+ : undefined,
258
644
  };
259
645
  return await this.#wrapActive(() => this.#inner.step(config));
260
646
  }
261
647
 
648
+ tryStep<T>(
649
+ name: string,
650
+ run: WorkflowStepRun<
651
+ T,
652
+ TState,
653
+ TConnParams,
654
+ TConnState,
655
+ TVars,
656
+ TInput,
657
+ TDatabase,
658
+ TEvents,
659
+ TQueues
660
+ >,
661
+ ): Promise<TryStepResult<T>>;
662
+ tryStep<T>(
663
+ config: WorkflowTryStepConfig<
664
+ T,
665
+ TState,
666
+ TConnParams,
667
+ TConnState,
668
+ TVars,
669
+ TInput,
670
+ TDatabase,
671
+ TEvents,
672
+ TQueues
673
+ >,
674
+ ): Promise<TryStepResult<T>>;
262
675
  async tryStep<T>(
263
676
  nameOrConfig:
264
677
  | string
265
- | Parameters<WorkflowContextInterface["tryStep"]>[0],
266
- run?: () => Promise<T>,
678
+ | WorkflowTryStepConfig<
679
+ T,
680
+ TState,
681
+ TConnParams,
682
+ TConnState,
683
+ TVars,
684
+ TInput,
685
+ TDatabase,
686
+ TEvents,
687
+ TQueues
688
+ >,
689
+ run?: WorkflowStepRun<
690
+ T,
691
+ TState,
692
+ TConnParams,
693
+ TConnState,
694
+ TVars,
695
+ TInput,
696
+ TDatabase,
697
+ TEvents,
698
+ TQueues
699
+ >,
267
700
  ): Promise<TryStepResult<T>> {
268
701
  if (typeof nameOrConfig === "string") {
269
702
  if (!run) {
270
703
  throw new Error("Step run function missing");
271
704
  }
705
+ const stepRun = run;
272
706
  return await this.#wrapActive(() =>
273
- this.#inner.tryStep(nameOrConfig, () =>
274
- this.#withActorAccess(run),
275
- ),
707
+ this.#inner.tryStep(nameOrConfig, () => this.#runStep(stepRun)),
276
708
  );
277
709
  }
278
- const stepConfig = nameOrConfig as TryStepConfig<T>;
710
+ const stepConfig = nameOrConfig;
711
+ const rollback = stepConfig.rollback;
279
712
  const config: TryStepConfig<T> = {
280
713
  ...stepConfig,
281
- run: () => this.#withActorAccess(stepConfig.run),
714
+ run: () => this.#runStep(stepConfig.run),
715
+ rollback: rollback
716
+ ? (_ctx, output) => this.#runRollback(rollback, output)
717
+ : undefined,
282
718
  };
283
719
  return await this.#wrapActive(() => this.#inner.tryStep(config));
284
720
  }
285
721
 
722
+ try<T>(
723
+ name: string,
724
+ run: WorkflowContextRun<
725
+ T,
726
+ TState,
727
+ TConnParams,
728
+ TConnState,
729
+ TVars,
730
+ TInput,
731
+ TDatabase,
732
+ TEvents,
733
+ TQueues
734
+ >,
735
+ ): Promise<TryBlockResult<T>>;
736
+ try<T>(
737
+ config: WorkflowTryConfig<
738
+ T,
739
+ TState,
740
+ TConnParams,
741
+ TConnState,
742
+ TVars,
743
+ TInput,
744
+ TDatabase,
745
+ TEvents,
746
+ TQueues
747
+ >,
748
+ ): Promise<TryBlockResult<T>>;
286
749
  async try<T>(
287
- nameOrConfig: string | Parameters<WorkflowContextInterface["try"]>[0],
288
- run?: (
289
- ctx: ActorWorkflowContext<
290
- TState,
291
- TConnParams,
292
- TConnState,
293
- TVars,
294
- TInput,
295
- TDatabase,
296
- TEvents,
297
- TQueues
298
- >,
299
- ) => Promise<T>,
750
+ nameOrConfig:
751
+ | string
752
+ | WorkflowTryConfig<
753
+ T,
754
+ TState,
755
+ TConnParams,
756
+ TConnState,
757
+ TVars,
758
+ TInput,
759
+ TDatabase,
760
+ TEvents,
761
+ TQueues
762
+ >,
763
+ run?: WorkflowContextRun<
764
+ T,
765
+ TState,
766
+ TConnParams,
767
+ TConnState,
768
+ TVars,
769
+ TInput,
770
+ TDatabase,
771
+ TEvents,
772
+ TQueues
773
+ >,
300
774
  ): Promise<TryBlockResult<T>> {
301
775
  if (typeof nameOrConfig === "string") {
302
776
  if (!run) {
303
777
  throw new Error("Try run function missing");
304
778
  }
779
+ const tryRun = run;
305
780
  return await this.#wrapActive(() =>
306
781
  this.#inner.try(nameOrConfig, async (ctx) =>
307
- run(this.#createChildContext(ctx)),
782
+ tryRun(this.#createChildContext(ctx)),
308
783
  ),
309
784
  );
310
785
  }
311
- const tryConfig = nameOrConfig as TryBlockConfig<T>;
786
+ const tryConfig = nameOrConfig;
312
787
  const config: TryBlockConfig<T> = {
313
788
  ...tryConfig,
314
789
  run: async (ctx) => tryConfig.run(this.#createChildContext(ctx)),
@@ -316,10 +791,10 @@ export class ActorWorkflowContext<
316
791
  return await this.#wrapActive(() => this.#inner.try(config));
317
792
  }
318
793
 
319
- async loop<T>(
794
+ loop<T>(
320
795
  name: string,
321
796
  run: (
322
- ctx: ActorWorkflowContext<
797
+ ctx: WorkflowContext<
323
798
  TState,
324
799
  TConnParams,
325
800
  TConnState,
@@ -329,16 +804,10 @@ export class ActorWorkflowContext<
329
804
  TEvents,
330
805
  TQueues
331
806
  >,
332
- ) => Promise<LoopResult<undefined, T> | void>,
807
+ ) => Promise<LoopResult<undefined, T> | undefined | void>,
333
808
  ): Promise<T>;
334
- async loop<T>(
335
- name: string,
336
- run: (
337
- ctx: WorkflowContextInterface,
338
- ) => Promise<LoopResult<undefined, T> | void>,
339
- ): Promise<T>;
340
- async loop<S, T>(
341
- config: ActorWorkflowLoopConfig<
809
+ loop<S, T>(
810
+ config: WorkflowLoopConfig<
342
811
  S,
343
812
  T,
344
813
  TState,
@@ -351,12 +820,10 @@ export class ActorWorkflowContext<
351
820
  TQueues
352
821
  >,
353
822
  ): Promise<T>;
354
- async loop<S, T>(config: LoopConfig<S, T>): Promise<T>;
355
823
  async loop(
356
824
  nameOrConfig:
357
825
  | string
358
- | LoopConfig<any, any>
359
- | ActorWorkflowLoopConfig<
826
+ | WorkflowLoopConfig<
360
827
  any,
361
828
  any,
362
829
  TState,
@@ -369,7 +836,7 @@ export class ActorWorkflowContext<
369
836
  TQueues
370
837
  >,
371
838
  run?: (
372
- ctx: ActorWorkflowContext<
839
+ ctx: WorkflowContext<
373
840
  TState,
374
841
  TConnParams,
375
842
  TConnState,
@@ -379,22 +846,32 @@ export class ActorWorkflowContext<
379
846
  TEvents,
380
847
  TQueues
381
848
  >,
382
- ) => Promise<LoopResult<undefined, any> | void>,
849
+ ) => Promise<LoopResult<undefined, any> | undefined | void>,
383
850
  ): Promise<any> {
384
851
  if (typeof nameOrConfig === "string") {
385
852
  if (!run) {
386
853
  throw new Error("Loop run function missing");
387
854
  }
855
+ const loopRun = run;
388
856
  return await this.#wrapActive(() =>
389
- this.#inner.loop(nameOrConfig, async (ctx) =>
390
- run(this.#createChildContext(ctx)),
857
+ this.#inner.loop(
858
+ nameOrConfig,
859
+ // A void return (no explicit Loop result) is undefined at
860
+ // runtime, which the engine treats as continue.
861
+ async (
862
+ ctx,
863
+ ): Promise<LoopResult<undefined, any> | undefined> =>
864
+ (await loopRun(this.#createChildContext(ctx))) ??
865
+ undefined,
391
866
  ),
392
867
  );
393
868
  }
869
+ const loopConfig = nameOrConfig;
394
870
  const wrapped: LoopConfig<any, any> = {
395
- ...nameOrConfig,
396
- run: async (ctx, state) =>
397
- nameOrConfig.run(this.#createChildContext(ctx), state),
871
+ ...loopConfig,
872
+ run: (async (ctx, state) =>
873
+ (await loopConfig.run(this.#createChildContext(ctx), state)) ??
874
+ undefined) as LoopConfig<any, any>["run"],
398
875
  };
399
876
  return await this.#wrapActive(() => this.#inner.loop(wrapped));
400
877
  }
@@ -407,11 +884,6 @@ export class ActorWorkflowContext<
407
884
  return this.#inner.sleepUntil(name, timestampMs);
408
885
  }
409
886
 
410
- destroy(): void {
411
- this.#ensureActorAccess("destroy");
412
- this.#runCtx.destroy();
413
- }
414
-
415
887
  async rollbackCheckpoint(name: string): Promise<void> {
416
888
  await this.#wrapActive(() => this.#inner.rollbackCheckpoint(name));
417
889
  }
@@ -419,7 +891,7 @@ export class ActorWorkflowContext<
419
891
  async join<
420
892
  T extends Record<
421
893
  string,
422
- ActorWorkflowBranchConfig<
894
+ WorkflowBranchConfig<
423
895
  unknown,
424
896
  TState,
425
897
  TConnParams,
@@ -439,7 +911,10 @@ export class ActorWorkflowContext<
439
911
  name: string,
440
912
  branches: T,
441
913
  ): Promise<{ [K in keyof T]: BranchOutput<T[K]> }>;
442
- async join(name: string, branches: Record<string, BranchConfig<unknown>>) {
914
+ async join(
915
+ name: string,
916
+ branches: Record<string, { run: (ctx: any) => Promise<unknown> }>,
917
+ ) {
443
918
  const wrappedBranches = Object.fromEntries(
444
919
  Object.entries(branches).map(([key, branch]) => [
445
920
  key,
@@ -458,25 +933,17 @@ export class ActorWorkflowContext<
458
933
  name: string,
459
934
  branches: Array<{
460
935
  name: string;
461
- run: (
462
- ctx: ActorWorkflowContext<
463
- TState,
464
- TConnParams,
465
- TConnState,
466
- TVars,
467
- TInput,
468
- TDatabase,
469
- TEvents,
470
- TQueues
471
- >,
472
- ) => Promise<T>;
473
- }>,
474
- ): Promise<{ winner: string; value: T }>;
475
- async race<T>(
476
- name: string,
477
- branches: Array<{
478
- name: string;
479
- run: (ctx: WorkflowContextInterface) => Promise<T>;
936
+ run: WorkflowContextRun<
937
+ T,
938
+ TState,
939
+ TConnParams,
940
+ TConnState,
941
+ TVars,
942
+ TInput,
943
+ TDatabase,
944
+ TEvents,
945
+ TQueues
946
+ >;
480
947
  }>,
481
948
  ): Promise<{ winner: string; value: T }> {
482
949
  const wrappedBranches = branches.map((branch) => ({
@@ -493,86 +960,66 @@ export class ActorWorkflowContext<
493
960
  await this.#wrapActive(() => this.#inner.removed(name, originalType));
494
961
  }
495
962
 
496
- isEvicted(): boolean {
497
- return this.#inner.isEvicted();
498
- }
499
-
500
- get state(): TState extends never ? never : TState {
501
- this.#ensureActorAccess("state");
502
- return this.#runCtx.state as TState extends never ? never : TState;
503
- }
504
-
505
- get vars(): TVars extends never ? never : TVars {
506
- this.#ensureActorAccess("vars");
507
- return this.#runCtx.vars as TVars extends never ? never : TVars;
508
- }
509
-
510
- client<R extends Registry<any> = Registry<any>>(): Client<R> {
511
- this.#ensureActorAccess("client");
512
- return this.#runCtx.client<R>();
513
- }
514
-
515
- get db(): TDatabase extends never ? never : InferDatabaseClient<TDatabase> {
516
- this.#ensureActorAccess("db");
517
- return this.#runCtx.db as TDatabase extends never
518
- ? never
519
- : InferDatabaseClient<TDatabase>;
520
- }
521
-
522
- get log() {
523
- return this.#runCtx.log;
524
- }
525
-
526
- /** @deprecated No-op. Use `keepAwake(promise)` or `waitUntil(promise)` instead. */
527
- setPreventSleep(_prevent: boolean): void {
528
- this.#ensureActorAccess("setPreventSleep");
963
+ getVersion(name: string, latest: number): Promise<number> {
964
+ return this.#wrapActive(() => this.#inner.getVersion(name, latest));
529
965
  }
530
966
 
531
- /** @deprecated No-op. Always returns `false`. */
532
- get preventSleep(): boolean {
533
- this.#ensureActorAccess("preventSleep");
534
- return false;
535
- }
536
-
537
- /**
538
- * Holds the actor awake for the duration of the provided promise. The
539
- * actor cannot idle-sleep or finalize the sleep grace period until the
540
- * promise settles.
541
- */
542
- keepAwake<T>(promise: Promise<T>): Promise<T> {
543
- this.#ensureActorAccess("keepAwake");
544
- return this.#runCtx.keepAwake(promise);
967
+ isEvicted(): boolean {
968
+ return this.#inner.isEvicted();
545
969
  }
546
970
 
547
- /**
548
- * Registers a promise that the sleep grace period will wait on. Use this
549
- * for best-effort flush/cleanup work that may complete inside the grace
550
- * window. For work the actor must stay running through, prefer
551
- * `c.keepAwake(promise)` which also blocks idle sleep.
552
- */
553
- waitUntil(promise: Promise<void>): void {
554
- this.#ensureActorAccess("waitUntil");
555
- this.#runCtx.waitUntil(promise);
556
- }
971
+ // Runs a user step body inside a fresh step context, snapshotting actor
972
+ // state/vars so a thrown step rolls back its mutations, and deactivating the
973
+ // step context once the body settles so it cannot be used after the step.
974
+ async #runStep<T>(
975
+ run: WorkflowStepRun<
976
+ T,
977
+ TState,
978
+ TConnParams,
979
+ TConnState,
980
+ TVars,
981
+ TInput,
982
+ TDatabase,
983
+ TEvents,
984
+ TQueues
985
+ >,
986
+ ): Promise<T> {
987
+ const stepCtx = new WorkflowStepContext<
988
+ TState,
989
+ TConnParams,
990
+ TConnState,
991
+ TVars,
992
+ TInput,
993
+ TDatabase,
994
+ TEvents,
995
+ TQueues
996
+ >(this.#runCtx, () => this.#markGuardTriggered());
557
997
 
558
- get actorId(): string {
559
- return this.#runCtx.actorId;
560
- }
998
+ let stateSnapshot: { state: TState } | null = null;
999
+ try {
1000
+ stateSnapshot = { state: this.#runCtx[RAW_STATE_SYMBOL]() };
1001
+ } catch (error) {
1002
+ this.#runCtx.log.debug({
1003
+ msg: "failed to get state, likely due to being stateless workflow",
1004
+ error,
1005
+ });
1006
+ }
1007
+ if (stateSnapshot) {
1008
+ stateSnapshot.state = structuredClone(stateSnapshot.state);
1009
+ }
1010
+ const varsSnapshot = structuredClone(this.#runCtx.vars);
561
1011
 
562
- broadcast<K extends keyof TEvents & string>(
563
- name: K,
564
- ...args: InferEventArgs<InferSchemaMap<TEvents>[K]>
565
- ): void;
566
- broadcast(
567
- name: keyof TEvents extends never ? string : never,
568
- ...args: Array<unknown>
569
- ): void;
570
- broadcast(name: string, ...args: Array<unknown>): void {
571
- this.#ensureActorAccess("broadcast");
572
- this.#runCtx.broadcast(
573
- name as never,
574
- ...(args as unknown[] as never[]),
575
- );
1012
+ try {
1013
+ return await run(stepCtx);
1014
+ } catch (error) {
1015
+ if (stateSnapshot) {
1016
+ this.#runCtx.state = stateSnapshot.state;
1017
+ }
1018
+ this.#runCtx.vars = varsSnapshot;
1019
+ throw error;
1020
+ } finally {
1021
+ stepCtx[DEACTIVATE_STEP]();
1022
+ }
576
1023
  }
577
1024
 
578
1025
  #toActorQueueMessage<T>(
@@ -593,41 +1040,45 @@ export class ActorWorkflowContext<
593
1040
  };
594
1041
  }
595
1042
 
596
- async #wrapActive<T>(run: () => Promise<T>): Promise<T> {
597
- return await this.#runCtx.internalKeepAwake(run);
598
- }
599
-
600
- async #withActorAccess<T>(run: () => Promise<T>): Promise<T> {
601
- this.#actorAccessDepth++;
602
- if (this.#actorAccessDepth === 1) {
603
- this.#allowActorAccess = true;
604
- }
1043
+ // Runs a step rollback compensation with an active step context. Rollbacks
1044
+ // intentionally mutate actor state, so their writes are not snapshotted.
1045
+ async #runRollback<T>(
1046
+ rollback: WorkflowStepRollback<
1047
+ T,
1048
+ TState,
1049
+ TConnParams,
1050
+ TConnState,
1051
+ TVars,
1052
+ TInput,
1053
+ TDatabase,
1054
+ TEvents,
1055
+ TQueues
1056
+ >,
1057
+ output: T,
1058
+ ): Promise<void> {
1059
+ const stepCtx = new WorkflowStepContext<
1060
+ TState,
1061
+ TConnParams,
1062
+ TConnState,
1063
+ TVars,
1064
+ TInput,
1065
+ TDatabase,
1066
+ TEvents,
1067
+ TQueues
1068
+ >(this.#runCtx, () => this.#markGuardTriggered());
605
1069
  try {
606
- return await run();
1070
+ await rollback(stepCtx, output);
607
1071
  } finally {
608
- this.#actorAccessDepth--;
609
- if (this.#actorAccessDepth === 0) {
610
- this.#allowActorAccess = false;
611
- }
612
- }
613
- }
614
-
615
- #ensureActorAccess(feature: string): void {
616
- if (!this.#allowActorAccess) {
617
- this.#guardViolation = true;
618
- this.#markGuardTriggered();
619
- throw new Error(
620
- `${feature} is only available inside workflow steps`,
621
- );
1072
+ stepCtx[DEACTIVATE_STEP]();
622
1073
  }
623
1074
  }
624
1075
 
625
- consumeGuardViolation(): boolean {
626
- const violated = this.#guardViolation;
627
- this.#guardViolation = false;
628
- return violated;
1076
+ async #wrapActive<T>(run: () => Promise<T>): Promise<T> {
1077
+ return await this.#runCtx.internalKeepAwake(run);
629
1078
  }
630
1079
 
1080
+ // Records that a step context was used outside its step. Mirrors the value
1081
+ // onto actor state and a KV flag so callers can observe the violation.
631
1082
  #markGuardTriggered(): void {
632
1083
  try {
633
1084
  const state = this.#runCtx.state as Record<string, unknown>;
@@ -658,7 +1109,7 @@ export class ActorWorkflowContext<
658
1109
 
659
1110
  #createChildContext(
660
1111
  ctx: WorkflowContextInterface,
661
- ): ActorWorkflowContext<
1112
+ ): WorkflowContext<
662
1113
  TState,
663
1114
  TConnParams,
664
1115
  TConnState,
@@ -668,7 +1119,7 @@ export class ActorWorkflowContext<
668
1119
  TEvents,
669
1120
  TQueues
670
1121
  > {
671
- return new ActorWorkflowContext(ctx, this.#runCtx);
1122
+ return new WorkflowContext(ctx, this.#runCtx);
672
1123
  }
673
1124
  }
674
1125
 
@@ -684,7 +1135,7 @@ export type WorkflowContextOf<AD extends AnyActorDefinition> =
684
1135
  infer Q extends QueueSchemaConfig,
685
1136
  any
686
1137
  >
687
- ? ActorWorkflowContext<S, CP, CS, V, I, DB, E, Q>
1138
+ ? WorkflowContext<S, CP, CS, V, I, DB, E, Q>
688
1139
  : never;
689
1140
 
690
1141
  export type WorkflowLoopContextOf<AD extends AnyActorDefinition> =
@@ -694,4 +1145,16 @@ export type WorkflowBranchContextOf<AD extends AnyActorDefinition> =
694
1145
  WorkflowContextOf<AD>;
695
1146
 
696
1147
  export type WorkflowStepContextOf<AD extends AnyActorDefinition> =
697
- WorkflowContextOf<AD>;
1148
+ AD extends BaseActorDefinition<
1149
+ infer S,
1150
+ infer CP,
1151
+ infer CS,
1152
+ infer V,
1153
+ infer I,
1154
+ infer DB extends AnyDatabaseProvider,
1155
+ infer E extends EventSchemaConfig,
1156
+ infer Q extends QueueSchemaConfig,
1157
+ any
1158
+ >
1159
+ ? WorkflowStepContext<S, CP, CS, V, I, DB, E, Q>
1160
+ : never;