rivetkit 2.3.0-rc.9 → 2.3.0

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 (222) hide show
  1. package/dist/browser/client.d.ts +498 -62
  2. package/dist/browser/client.js +227 -171
  3. package/dist/browser/client.js.map +1 -1
  4. package/dist/browser/inspector/client.js +50 -20
  5. package/dist/browser/inspector/client.js.map +1 -1
  6. package/dist/tsup/actor/errors.cjs +2 -2
  7. package/dist/tsup/actor/errors.d.cts +1 -1
  8. package/dist/tsup/actor/errors.d.ts +1 -1
  9. package/dist/tsup/actor/errors.js +1 -1
  10. package/dist/tsup/agent-os/index.cjs +2163 -2087
  11. package/dist/tsup/agent-os/index.cjs.map +1 -1
  12. package/dist/tsup/agent-os/index.d.cts +496 -69
  13. package/dist/tsup/agent-os/index.d.ts +496 -69
  14. package/dist/tsup/agent-os/index.js +2163 -2087
  15. package/dist/tsup/agent-os/index.js.map +1 -1
  16. package/dist/tsup/{chunk-W7EYSYVI.js → chunk-2OTRTA3J.js} +134 -20
  17. package/dist/tsup/chunk-2OTRTA3J.js.map +1 -0
  18. package/dist/tsup/{chunk-VJFRBJVQ.cjs → chunk-3677IIOV.cjs} +138 -24
  19. package/dist/tsup/chunk-3677IIOV.cjs.map +1 -0
  20. package/dist/tsup/{chunk-4CGA6QJO.cjs → chunk-47HHIEXH.cjs} +24 -9
  21. package/dist/tsup/chunk-47HHIEXH.cjs.map +1 -0
  22. package/dist/tsup/{chunk-F3Q5BFQ6.js → chunk-4JDSFJS5.js} +66 -79
  23. package/dist/tsup/chunk-4JDSFJS5.js.map +1 -0
  24. package/dist/tsup/{chunk-GVTOE34S.cjs → chunk-7QKCIVAY.cjs} +222 -235
  25. package/dist/tsup/chunk-7QKCIVAY.cjs.map +1 -0
  26. package/dist/tsup/{chunk-CPA4Y3RG.cjs → chunk-B6VUNZUD.cjs} +10 -10
  27. package/dist/tsup/chunk-B6VUNZUD.cjs.map +1 -0
  28. package/dist/tsup/{chunk-H37XQU3I.js → chunk-BEI24WTI.js} +2 -2
  29. package/dist/tsup/{chunk-KIWH5H3K.js → chunk-BRP62GZC.js} +3 -3
  30. package/dist/tsup/chunk-BRP62GZC.js.map +1 -0
  31. package/dist/tsup/{chunk-T6YVRM4K.js → chunk-DPIMKYNB.js} +63 -2
  32. package/dist/tsup/chunk-DPIMKYNB.js.map +1 -0
  33. package/dist/tsup/{chunk-Y5NSCZA2.cjs → chunk-DXXJPH55.cjs} +44 -15
  34. package/dist/tsup/chunk-DXXJPH55.cjs.map +1 -0
  35. package/dist/tsup/{chunk-3YY5S6TV.js → chunk-HXUEHHJF.js} +2 -2
  36. package/dist/tsup/chunk-HXUEHHJF.js.map +1 -0
  37. package/dist/tsup/{chunk-4WPEZBK4.cjs → chunk-I4LN3FNT.cjs} +10 -10
  38. package/dist/tsup/chunk-I4LN3FNT.cjs.map +1 -0
  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-QAZLM4WT.cjs → chunk-KORQB2IR.cjs} +3 -3
  42. package/dist/tsup/{chunk-QAZLM4WT.cjs.map → chunk-KORQB2IR.cjs.map} +1 -1
  43. package/dist/tsup/{chunk-MALSPBAF.cjs → chunk-LVTBW2RE.cjs} +3 -3
  44. package/dist/tsup/{chunk-MALSPBAF.cjs.map → chunk-LVTBW2RE.cjs.map} +1 -1
  45. package/dist/tsup/{chunk-H7P7WR2Y.js → chunk-MEHBWPLJ.js} +6 -6
  46. package/dist/tsup/chunk-MEHBWPLJ.js.map +1 -0
  47. package/dist/tsup/{chunk-WQ4HNA4W.cjs → chunk-NIY3RSPX.cjs} +64 -3
  48. package/dist/tsup/chunk-NIY3RSPX.cjs.map +1 -0
  49. package/dist/tsup/{chunk-MMMEZM5J.js → chunk-P2GNQ4RN.js} +4 -4
  50. package/dist/tsup/chunk-P2GNQ4RN.js.map +1 -0
  51. package/dist/tsup/{chunk-KJTA3ATT.js → chunk-UMZVD6DQ.js} +22 -7
  52. package/dist/tsup/chunk-UMZVD6DQ.js.map +1 -0
  53. package/dist/tsup/{chunk-LD5YASJU.cjs → chunk-VE2X4KMG.cjs} +2 -2
  54. package/dist/tsup/{chunk-LD5YASJU.cjs.map → chunk-VE2X4KMG.cjs.map} +1 -1
  55. package/dist/tsup/{chunk-VRCIXJRN.js → chunk-VTTFNQQI.js} +36 -7
  56. package/dist/tsup/chunk-VTTFNQQI.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/client/mod.cjs +9 -9
  60. package/dist/tsup/client/mod.d.cts +5 -5
  61. package/dist/tsup/client/mod.d.ts +5 -5
  62. package/dist/tsup/client/mod.js +8 -8
  63. package/dist/tsup/common/log.cjs +3 -3
  64. package/dist/tsup/common/log.js +2 -2
  65. package/dist/tsup/common/websocket.cjs +4 -4
  66. package/dist/tsup/common/websocket.js +3 -3
  67. package/dist/tsup/{config-0Ta55UV0.d.ts → config-BxWAw3iH.d.ts} +529 -23
  68. package/dist/tsup/{config-Ca8dN4cS.d.cts → config-CZQQ-mso.d.cts} +529 -23
  69. package/dist/tsup/{config-CxjGYf4K.d.cts → config-D49x8NpL.d.cts} +1 -2
  70. package/dist/tsup/{config-CxjGYf4K.d.ts → config-D49x8NpL.d.ts} +1 -2
  71. package/dist/tsup/{context-B_IWbWne.d.ts → context-Bw7xq8w3.d.cts} +8 -8
  72. package/dist/tsup/{context-CUrQ9MHc.d.cts → context-D8QA76sV.d.ts} +8 -8
  73. package/dist/tsup/db/drizzle.cjs +3 -3
  74. package/dist/tsup/db/drizzle.d.cts +1 -1
  75. package/dist/tsup/db/drizzle.d.ts +1 -1
  76. package/dist/tsup/db/drizzle.js +1 -1
  77. package/dist/tsup/db/mod.cjs +2 -2
  78. package/dist/tsup/db/mod.d.cts +2 -2
  79. package/dist/tsup/db/mod.d.ts +2 -2
  80. package/dist/tsup/db/mod.js +1 -1
  81. package/dist/tsup/dynamic/mod.cjs +24 -0
  82. package/dist/tsup/dynamic/mod.cjs.map +1 -0
  83. package/dist/tsup/dynamic/mod.d.cts +37 -0
  84. package/dist/tsup/dynamic/mod.d.ts +37 -0
  85. package/dist/tsup/dynamic/mod.js +24 -0
  86. package/dist/tsup/dynamic/mod.js.map +1 -0
  87. package/dist/tsup/inspector/mod.cjs +6 -6
  88. package/dist/tsup/inspector/mod.js +5 -5
  89. package/dist/tsup/inspector-tab/mod.cjs +173 -0
  90. package/dist/tsup/inspector-tab/mod.cjs.map +1 -0
  91. package/dist/tsup/inspector-tab/mod.d.cts +250 -0
  92. package/dist/tsup/inspector-tab/mod.d.ts +250 -0
  93. package/dist/tsup/inspector-tab/mod.js +173 -0
  94. package/dist/tsup/inspector-tab/mod.js.map +1 -0
  95. package/dist/tsup/mod.cjs +730 -336
  96. package/dist/tsup/mod.cjs.map +1 -1
  97. package/dist/tsup/mod.d.cts +5 -5
  98. package/dist/tsup/mod.d.ts +5 -5
  99. package/dist/tsup/mod.js +633 -239
  100. package/dist/tsup/mod.js.map +1 -1
  101. package/dist/tsup/test/mod.cjs +21 -18
  102. package/dist/tsup/test/mod.cjs.map +1 -1
  103. package/dist/tsup/test/mod.d.cts +4 -4
  104. package/dist/tsup/test/mod.d.ts +4 -4
  105. package/dist/tsup/test/mod.js +18 -15
  106. package/dist/tsup/test/mod.js.map +1 -1
  107. package/dist/tsup/{utils-DVekpm4I.d.cts → utils-DQosb24I.d.cts} +1 -1
  108. package/dist/tsup/{utils-DVekpm4I.d.ts → utils-DQosb24I.d.ts} +1 -1
  109. package/dist/tsup/utils.cjs +3 -3
  110. package/dist/tsup/utils.d.cts +1 -1
  111. package/dist/tsup/utils.d.ts +1 -1
  112. package/dist/tsup/utils.js +2 -2
  113. package/dist/tsup/workflow/mod.cjs +307 -282
  114. package/dist/tsup/workflow/mod.cjs.map +1 -1
  115. package/dist/tsup/workflow/mod.d.cts +6 -6
  116. package/dist/tsup/workflow/mod.d.ts +6 -6
  117. package/dist/tsup/workflow/mod.js +501 -476
  118. package/dist/tsup/workflow/mod.js.map +1 -1
  119. package/package.json +32 -11
  120. package/src/actor/config.ts +159 -51
  121. package/src/actor/contexts/index.ts +7 -2
  122. package/src/actor/definition.ts +17 -19
  123. package/src/actor/driver.ts +3 -3
  124. package/src/actor/errors.ts +9 -3
  125. package/src/actor/instance/mod.ts +26 -34
  126. package/src/actor/keys.ts +1 -1
  127. package/src/actor/mod.ts +22 -20
  128. package/src/actor/schema.ts +2 -2
  129. package/src/agent-os/actor/index.ts +38 -18
  130. package/src/agent-os/actor/preview.ts +1 -2
  131. package/src/agent-os/actor/session.ts +2 -2
  132. package/src/agent-os/config.ts +1 -1
  133. package/src/agent-os/fs/database-vfs.ts +1 -1
  134. package/src/agent-os/index.ts +16 -15
  135. package/src/client/actor-common.ts +87 -54
  136. package/src/client/actor-conn.ts +8 -36
  137. package/src/client/actor-handle.ts +69 -51
  138. package/src/client/actor-query.ts +5 -5
  139. package/src/client/errors.ts +1 -1
  140. package/src/client/lifecycle-errors.ts +2 -4
  141. package/src/client/query.ts +1 -1
  142. package/src/client/queue.ts +8 -3
  143. package/src/client/raw-utils.ts +8 -6
  144. package/src/client/resolve-gateway-target.ts +1 -1
  145. package/src/client/utils.ts +2 -7
  146. package/src/common/actor-websocket.ts +3 -1
  147. package/src/common/bare/actor-persist/v1.ts +205 -163
  148. package/src/common/bare/actor-persist/v2.ts +265 -213
  149. package/src/common/bare/actor-persist/v3.ts +176 -172
  150. package/src/common/bare/actor-persist/v4.ts +254 -253
  151. package/src/common/bare/transport/v1.ts +659 -543
  152. package/src/common/client-protocol-versioned.ts +66 -64
  153. package/src/common/database/config.ts +2 -8
  154. package/src/common/database/native-database.ts +1 -1
  155. package/src/common/database/shared.ts +1 -0
  156. package/src/common/encoding.ts +250 -16
  157. package/src/common/engine.ts +28 -1
  158. package/src/common/eventsource.ts +1 -1
  159. package/src/common/inline-websocket-adapter.ts +14 -13
  160. package/src/common/log.ts +1 -0
  161. package/src/common/router.ts +13 -17
  162. package/src/common/utils.ts +1 -150
  163. package/src/common/websocket-interface.ts +1 -1
  164. package/src/db/mod.ts +1 -1
  165. package/src/devtools-loader/index.ts +4 -7
  166. package/src/devtools-loader/serve-devtools.ts +26 -0
  167. package/src/drivers/engine/actor-driver.ts +58 -56
  168. package/src/dynamic/instance.ts +32 -0
  169. package/src/dynamic/internal.ts +50 -0
  170. package/src/dynamic/isolate-runtime.ts +66 -0
  171. package/src/dynamic/mod.ts +32 -0
  172. package/src/engine-client/actor-http-client.ts +3 -3
  173. package/src/engine-client/actor-websocket-client.ts +6 -5
  174. package/src/engine-client/api-endpoints.ts +51 -2
  175. package/src/engine-client/api-utils.ts +2 -2
  176. package/src/engine-client/driver.ts +1 -1
  177. package/src/engine-client/mod.ts +6 -3
  178. package/src/engine-client/ws-proxy.ts +9 -4
  179. package/src/inspector/client.browser.ts +5 -11
  180. package/src/inspector/mod.ts +1 -3
  181. package/src/inspector-tab/mod.ts +315 -0
  182. package/src/registry/config/envoy.ts +1 -2
  183. package/src/registry/config/index.ts +40 -16
  184. package/src/registry/index.ts +154 -74
  185. package/src/registry/napi-runtime.ts +13 -2
  186. package/src/registry/native-validation.ts +10 -12
  187. package/src/registry/native.ts +367 -181
  188. package/src/registry/process-metrics.ts +250 -0
  189. package/src/registry/runtime.ts +41 -1
  190. package/src/registry/wasm-runtime.ts +18 -2
  191. package/src/registry/write-through-proxy.ts +40 -0
  192. package/src/serde.ts +2 -2
  193. package/src/serverless/configure.ts +18 -7
  194. package/src/test/mod.ts +11 -8
  195. package/src/utils/endpoint-parser.ts +1 -1
  196. package/src/utils/env-vars.ts +6 -0
  197. package/src/utils/router.ts +1 -1
  198. package/src/utils/serve.ts +4 -5
  199. package/src/utils.ts +1 -2
  200. package/src/workflow/context.ts +61 -33
  201. package/src/workflow/driver.ts +4 -6
  202. package/src/workflow/inspector.ts +4 -3
  203. package/src/workflow/mod.ts +15 -17
  204. package/dist/tsup/chunk-2NDZ7JCR.cjs.map +0 -1
  205. package/dist/tsup/chunk-3YY5S6TV.js.map +0 -1
  206. package/dist/tsup/chunk-4CGA6QJO.cjs.map +0 -1
  207. package/dist/tsup/chunk-4WPEZBK4.cjs.map +0 -1
  208. package/dist/tsup/chunk-CPA4Y3RG.cjs.map +0 -1
  209. package/dist/tsup/chunk-F3Q5BFQ6.js.map +0 -1
  210. package/dist/tsup/chunk-GVTOE34S.cjs.map +0 -1
  211. package/dist/tsup/chunk-H7P7WR2Y.js.map +0 -1
  212. package/dist/tsup/chunk-KIWH5H3K.js.map +0 -1
  213. package/dist/tsup/chunk-KJTA3ATT.js.map +0 -1
  214. package/dist/tsup/chunk-MMMEZM5J.js.map +0 -1
  215. package/dist/tsup/chunk-PCBNKI2J.js.map +0 -1
  216. package/dist/tsup/chunk-T6YVRM4K.js.map +0 -1
  217. package/dist/tsup/chunk-VJFRBJVQ.cjs.map +0 -1
  218. package/dist/tsup/chunk-VRCIXJRN.js.map +0 -1
  219. package/dist/tsup/chunk-W7EYSYVI.js.map +0 -1
  220. package/dist/tsup/chunk-WQ4HNA4W.cjs.map +0 -1
  221. package/dist/tsup/chunk-Y5NSCZA2.cjs.map +0 -1
  222. /package/dist/tsup/{chunk-H37XQU3I.js.map → chunk-BEI24WTI.js.map} +0 -0
@@ -1,22 +1,23 @@
1
1
  import {
2
2
  createWorkflowInspectorAdapter
3
- } from "../chunk-MMMEZM5J.js";
3
+ } from "../chunk-P2GNQ4RN.js";
4
+ import "../chunk-UMZVD6DQ.js";
4
5
  import {
5
6
  ACTOR_CONTEXT_INTERNAL_SYMBOL,
7
+ RAW_STATE_SYMBOL,
6
8
  RUN_FUNCTION_CONFIG_SYMBOL
7
- } from "../chunk-T6YVRM4K.js";
8
- import "../chunk-KJTA3ATT.js";
9
+ } from "../chunk-DPIMKYNB.js";
9
10
  import {
10
11
  makeWorkflowKey,
11
12
  workflowStoragePrefix
12
- } from "../chunk-3YY5S6TV.js";
13
- import "../chunk-W7EYSYVI.js";
13
+ } from "../chunk-HXUEHHJF.js";
14
+ import "../chunk-2OTRTA3J.js";
14
15
  import {
15
16
  stringifyError
16
- } from "../chunk-VRCIXJRN.js";
17
+ } from "../chunk-VTTFNQQI.js";
17
18
  import {
18
19
  RivetError
19
- } from "../chunk-KIWH5H3K.js";
20
+ } from "../chunk-BRP62GZC.js";
20
21
 
21
22
  // src/workflow/mod.ts
22
23
  import {
@@ -25,561 +26,585 @@ import {
25
26
  HistoryDivergedError,
26
27
  JoinError,
27
28
  RaceError,
28
- replayWorkflowFromStep,
29
29
  RollbackCheckpointError,
30
30
  RollbackError,
31
+ replayWorkflowFromStep,
31
32
  runWorkflow,
32
33
  StepExhaustedError
33
34
  } from "@rivetkit/workflow-engine";
34
35
  import invariant from "invariant";
35
36
 
36
- // src/workflow/driver.ts
37
- var WORKFLOW_STORAGE_PREFIX = workflowStoragePrefix();
38
- function stripWorkflowKey(prefixed) {
39
- return prefixed.slice(WORKFLOW_STORAGE_PREFIX.length);
40
- }
41
- function computeUpperBound(prefix) {
42
- const upperBound = prefix.slice();
43
- for (let i = upperBound.length - 1; i >= 0; i--) {
44
- if (upperBound[i] !== 255) {
45
- upperBound[i]++;
46
- return upperBound.slice(0, i + 1);
47
- }
48
- }
49
- return null;
50
- }
51
- var ActorWorkflowMessageDriver = class {
52
- #actor;
37
+ // src/workflow/constants.ts
38
+ var WORKFLOW_GUARD_KV_KEY = "__rivet_actor_workflow_guard_triggered";
39
+
40
+ // src/workflow/context.ts
41
+ var ActorWorkflowContext = class _ActorWorkflowContext {
42
+ #inner;
53
43
  #runCtx;
54
- constructor(actor, runCtx) {
55
- this.#actor = actor;
44
+ #actorAccessDepth = 0;
45
+ #allowActorAccess = false;
46
+ #guardViolation = false;
47
+ constructor(inner, runCtx) {
48
+ this.#inner = inner;
56
49
  this.#runCtx = runCtx;
57
50
  }
58
- async addMessage(message) {
59
- await this.#runCtx.internalKeepAwake(
60
- this.#actor.queueManager.enqueue(message.name, message.data)
61
- );
51
+ get workflowId() {
52
+ return this.#inner.workflowId;
62
53
  }
63
- async receiveMessages(opts) {
64
- const messages = await this.#runCtx.internalKeepAwake(
65
- this.#actor.queueManager.receive(
66
- opts.names && opts.names.length > 0 ? [...opts.names] : void 0,
67
- opts.count,
68
- 0,
69
- void 0,
70
- opts.completable
71
- )
72
- );
73
- return messages.map((message) => ({
74
- id: message.id.toString(),
75
- name: message.name,
76
- data: message.body,
77
- sentAt: message.createdAt,
78
- ...opts.completable ? {
79
- complete: async (response) => {
80
- await this.#runCtx.internalKeepAwake(
81
- this.#actor.queueManager.completeMessage(
82
- message,
83
- response
84
- )
85
- );
86
- }
87
- } : {}
88
- }));
54
+ get abortSignal() {
55
+ return this.#inner.abortSignal;
89
56
  }
90
- async completeMessage(messageId, response) {
91
- let parsedId;
92
- try {
93
- parsedId = BigInt(messageId);
94
- } catch {
95
- return;
57
+ get queue() {
58
+ const self = this;
59
+ async function next(name, opts) {
60
+ const message = await self.#inner.queue.next(name, opts);
61
+ return self.#toActorQueueMessage(message);
96
62
  }
97
- await this.#runCtx.internalKeepAwake(
98
- this.#actor.queueManager.completeMessageById(parsedId, response)
99
- );
100
- }
101
- };
102
- var ActorWorkflowDriver = class {
103
- workerPollInterval = 100;
104
- messageDriver;
105
- #actor;
106
- #runCtx;
107
- constructor(actor, runCtx) {
108
- this.#actor = actor;
109
- this.#runCtx = runCtx;
110
- this.messageDriver = new ActorWorkflowMessageDriver(actor, runCtx);
111
- }
112
- async get(key) {
113
- const [value] = await this.#runCtx.internalKeepAwake(
114
- this.#actor.driver.kvBatchGet(this.#actor.id, [
115
- makeWorkflowKey(key)
116
- ])
117
- );
118
- return value ?? null;
119
- }
120
- async set(key, value) {
121
- await this.#runCtx.internalKeepAwake(
122
- this.#actor.driver.kvBatchPut(this.#actor.id, [
123
- [makeWorkflowKey(key), value]
124
- ])
125
- );
126
- }
127
- async delete(key) {
128
- await this.#runCtx.internalKeepAwake(
129
- this.#actor.driver.kvBatchDelete(this.#actor.id, [
130
- makeWorkflowKey(key)
131
- ])
132
- );
63
+ async function nextBatch(name, opts) {
64
+ const messages = await self.#inner.queue.nextBatch(name, opts);
65
+ return messages.map(
66
+ (message) => self.#toActorQueueMessage(message)
67
+ );
68
+ }
69
+ async function send(name, body) {
70
+ self.#ensureActorAccess("queue.send");
71
+ await self.#runCtx.queue.send(name, body);
72
+ }
73
+ return {
74
+ next,
75
+ nextBatch,
76
+ send
77
+ };
133
78
  }
134
- async deletePrefix(prefix) {
135
- const start = makeWorkflowKey(prefix);
136
- const end = computeUpperBound(start);
137
- if (end) {
138
- await this.#runCtx.internalKeepAwake(
139
- this.#actor.driver.kvDeleteRange(this.#actor.id, start, end)
79
+ async step(nameOrConfig, run) {
80
+ if (typeof nameOrConfig === "string") {
81
+ if (!run) {
82
+ throw new Error("Step run function missing");
83
+ }
84
+ return await this.#wrapActive(
85
+ () => this.#inner.step(
86
+ nameOrConfig,
87
+ () => this.#withActorAccessAndStateRollback(run)
88
+ )
140
89
  );
141
- } else {
142
- const entries = await this.#runCtx.internalKeepAwake(
143
- this.#actor.driver.kvListPrefix(this.#actor.id, start)
90
+ }
91
+ const stepConfig = nameOrConfig;
92
+ const config = {
93
+ ...stepConfig,
94
+ run: () => this.#withActorAccessAndStateRollback(stepConfig.run)
95
+ };
96
+ return await this.#wrapActive(() => this.#inner.step(config));
97
+ }
98
+ async tryStep(nameOrConfig, run) {
99
+ if (typeof nameOrConfig === "string") {
100
+ if (!run) {
101
+ throw new Error("Step run function missing");
102
+ }
103
+ return await this.#wrapActive(
104
+ () => this.#inner.tryStep(
105
+ nameOrConfig,
106
+ () => this.#withActorAccessAndStateRollback(run)
107
+ )
144
108
  );
145
- if (entries.length === 0) {
146
- return;
109
+ }
110
+ const stepConfig = nameOrConfig;
111
+ const config = {
112
+ ...stepConfig,
113
+ run: () => this.#withActorAccessAndStateRollback(stepConfig.run)
114
+ };
115
+ return await this.#wrapActive(() => this.#inner.tryStep(config));
116
+ }
117
+ async try(nameOrConfig, run) {
118
+ if (typeof nameOrConfig === "string") {
119
+ if (!run) {
120
+ throw new Error("Try run function missing");
147
121
  }
148
- await this.#runCtx.internalKeepAwake(
149
- this.#actor.driver.kvBatchDelete(
150
- this.#actor.id,
151
- entries.map(([key]) => key)
122
+ return await this.#wrapActive(
123
+ () => this.#inner.try(
124
+ nameOrConfig,
125
+ async (ctx) => run(this.#createChildContext(ctx))
152
126
  )
153
127
  );
154
128
  }
129
+ const tryConfig = nameOrConfig;
130
+ const config = {
131
+ ...tryConfig,
132
+ run: async (ctx) => tryConfig.run(this.#createChildContext(ctx))
133
+ };
134
+ return await this.#wrapActive(() => this.#inner.try(config));
155
135
  }
156
- async deleteRange(start, end) {
157
- await this.#runCtx.internalKeepAwake(
158
- this.#actor.driver.kvDeleteRange(
159
- this.#actor.id,
160
- makeWorkflowKey(start),
161
- makeWorkflowKey(end)
162
- )
163
- );
136
+ async loop(nameOrConfig, run) {
137
+ if (typeof nameOrConfig === "string") {
138
+ if (!run) {
139
+ throw new Error("Loop run function missing");
140
+ }
141
+ return await this.#wrapActive(
142
+ () => this.#inner.loop(
143
+ nameOrConfig,
144
+ async (ctx) => run(this.#createChildContext(ctx))
145
+ )
146
+ );
147
+ }
148
+ const wrapped = {
149
+ ...nameOrConfig,
150
+ run: async (ctx, state) => nameOrConfig.run(this.#createChildContext(ctx), state)
151
+ };
152
+ return await this.#wrapActive(() => this.#inner.loop(wrapped));
164
153
  }
165
- async list(prefix) {
166
- const entries = await this.#runCtx.internalKeepAwake(
167
- this.#actor.driver.kvListPrefix(
168
- this.#actor.id,
169
- makeWorkflowKey(prefix)
170
- )
171
- );
172
- return entries.map(([key, value]) => ({
173
- key: stripWorkflowKey(key),
174
- value
175
- }));
154
+ sleep(name, durationMs) {
155
+ return this.#inner.sleep(name, durationMs);
176
156
  }
177
- async batch(writes) {
178
- if (writes.length === 0) return;
179
- await this.#runCtx.internalKeepAwake(
180
- Promise.all([
181
- this.#actor.driver.kvBatchPut(
182
- this.#actor.id,
183
- writes.map(({ key, value }) => [
184
- makeWorkflowKey(key),
185
- value
186
- ])
187
- ),
188
- this.#actor.stateManager.saveState({
189
- immediate: true
190
- })
191
- ])
192
- );
157
+ sleepUntil(name, timestampMs) {
158
+ return this.#inner.sleepUntil(name, timestampMs);
193
159
  }
194
- async setAlarm(_workflowId, wakeAt) {
195
- await this.#runCtx.internalKeepAwake(
196
- this.#actor.driver.setAlarm(this.#actor, wakeAt)
197
- );
160
+ destroy() {
161
+ this.#ensureActorAccess("destroy");
162
+ this.#runCtx.destroy();
198
163
  }
199
- async clearAlarm(_workflowId) {
200
- return;
164
+ async rollbackCheckpoint(name) {
165
+ await this.#wrapActive(() => this.#inner.rollbackCheckpoint(name));
201
166
  }
202
- waitForMessages(messageNames, abortSignal) {
203
- return this.#actor.queueManager.waitForNames(
204
- messageNames.length > 0 ? messageNames : void 0,
205
- abortSignal
167
+ async join(name, branches) {
168
+ const wrappedBranches = Object.fromEntries(
169
+ Object.entries(branches).map(([key, branch]) => [
170
+ key,
171
+ {
172
+ run: async (ctx) => branch.run(this.#createChildContext(ctx))
173
+ }
174
+ ])
175
+ );
176
+ return await this.#wrapActive(
177
+ () => this.#inner.join(name, wrappedBranches)
206
178
  );
207
179
  }
208
- };
209
- var NoopWorkflowMessageDriver = class {
210
- async addMessage(_message) {
211
- throw new Error("Workflow control driver does not support messages");
180
+ async race(name, branches) {
181
+ const wrappedBranches = branches.map((branch) => ({
182
+ name: branch.name,
183
+ run: (ctx) => branch.run(this.#createChildContext(ctx))
184
+ }));
185
+ return await this.#wrapActive(
186
+ () => this.#inner.race(name, wrappedBranches)
187
+ );
212
188
  }
213
- async receiveMessages(_opts) {
214
- throw new Error("Workflow control driver does not support messages");
189
+ async removed(name, originalType) {
190
+ await this.#wrapActive(() => this.#inner.removed(name, originalType));
215
191
  }
216
- async completeMessage(_messageId, _response) {
217
- throw new Error("Workflow control driver does not support messages");
192
+ isEvicted() {
193
+ return this.#inner.isEvicted();
218
194
  }
219
- };
220
- var ActorWorkflowControlDriver = class {
221
- workerPollInterval = 100;
222
- messageDriver = new NoopWorkflowMessageDriver();
223
- #actor;
224
- constructor(actor) {
225
- this.#actor = actor;
195
+ get state() {
196
+ this.#ensureActorAccess("state");
197
+ return this.#runCtx.state;
226
198
  }
227
- async get(key) {
228
- const [value] = await this.#actor.driver.kvBatchGet(this.#actor.id, [
229
- makeWorkflowKey(key)
230
- ]);
231
- return value ?? null;
199
+ get vars() {
200
+ this.#ensureActorAccess("vars");
201
+ return this.#runCtx.vars;
232
202
  }
233
- async set(key, value) {
234
- await this.#actor.driver.kvBatchPut(this.#actor.id, [
235
- [makeWorkflowKey(key), value]
236
- ]);
203
+ client() {
204
+ this.#ensureActorAccess("client");
205
+ return this.#runCtx.client();
237
206
  }
238
- async delete(key) {
239
- await this.#actor.driver.kvBatchDelete(this.#actor.id, [
240
- makeWorkflowKey(key)
241
- ]);
207
+ get db() {
208
+ this.#ensureActorAccess("db");
209
+ return this.#runCtx.db;
242
210
  }
243
- async deletePrefix(prefix) {
244
- const start = makeWorkflowKey(prefix);
245
- const end = computeUpperBound(start);
246
- if (end) {
247
- await this.#actor.driver.kvDeleteRange(this.#actor.id, start, end);
248
- return;
249
- }
250
- const entries = await this.#actor.driver.kvListPrefix(
251
- this.#actor.id,
252
- start
253
- );
254
- if (entries.length === 0) {
255
- return;
256
- }
257
- await this.#actor.driver.kvBatchDelete(
258
- this.#actor.id,
259
- entries.map(([key]) => key)
260
- );
211
+ get log() {
212
+ return this.#runCtx.log;
261
213
  }
262
- async deleteRange(start, end) {
263
- await this.#actor.driver.kvDeleteRange(
264
- this.#actor.id,
265
- makeWorkflowKey(start),
266
- makeWorkflowKey(end)
267
- );
214
+ /** @deprecated No-op. Use `keepAwake(promise)` or `waitUntil(promise)` instead. */
215
+ setPreventSleep(_prevent) {
216
+ this.#ensureActorAccess("setPreventSleep");
268
217
  }
269
- async list(prefix) {
270
- const entries = await this.#actor.driver.kvListPrefix(
271
- this.#actor.id,
272
- makeWorkflowKey(prefix)
273
- );
274
- return entries.map(([key, value]) => ({
275
- key: stripWorkflowKey(key),
276
- value
277
- }));
218
+ /** @deprecated No-op. Always returns `false`. */
219
+ get preventSleep() {
220
+ this.#ensureActorAccess("preventSleep");
221
+ return false;
278
222
  }
279
- async batch(writes) {
280
- if (writes.length === 0) {
281
- return;
282
- }
283
- await this.#actor.driver.kvBatchPut(
284
- this.#actor.id,
285
- writes.map(({ key, value }) => [makeWorkflowKey(key), value])
286
- );
223
+ /**
224
+ * Holds the actor awake for the duration of the provided promise. The
225
+ * actor cannot idle-sleep or finalize the sleep grace period until the
226
+ * promise settles.
227
+ */
228
+ keepAwake(promise) {
229
+ this.#ensureActorAccess("keepAwake");
230
+ return this.#runCtx.keepAwake(promise);
287
231
  }
288
- async setAlarm(_workflowId, wakeAt) {
289
- await this.#actor.driver.setAlarm(this.#actor, wakeAt);
232
+ /**
233
+ * Registers a promise that the sleep grace period will wait on. Use this
234
+ * for best-effort flush/cleanup work that may complete inside the grace
235
+ * window. For work the actor must stay running through, prefer
236
+ * `c.keepAwake(promise)` which also blocks idle sleep.
237
+ */
238
+ waitUntil(promise) {
239
+ this.#ensureActorAccess("waitUntil");
240
+ this.#runCtx.waitUntil(promise);
290
241
  }
291
- async clearAlarm(_workflowId) {
292
- return;
242
+ get actorId() {
243
+ return this.#runCtx.actorId;
293
244
  }
294
- waitForMessages(_messageNames, _abortSignal) {
295
- throw new Error("Workflow control driver does not support messages");
245
+ broadcast(name, ...args) {
246
+ this.#ensureActorAccess("broadcast");
247
+ this.#runCtx.broadcast(
248
+ name,
249
+ ...args
250
+ );
296
251
  }
297
- };
298
-
299
- // src/workflow/constants.ts
300
- var WORKFLOW_GUARD_KV_KEY = "__rivet_actor_workflow_guard_triggered";
301
-
302
- // src/workflow/context.ts
303
- var ActorWorkflowContext = class _ActorWorkflowContext {
304
- #inner;
305
- #runCtx;
306
- #actorAccessDepth = 0;
307
- #allowActorAccess = false;
308
- #guardViolation = false;
309
- constructor(inner, runCtx) {
310
- this.#inner = inner;
311
- this.#runCtx = runCtx;
252
+ #toActorQueueMessage(message) {
253
+ let id;
254
+ try {
255
+ id = BigInt(message.id);
256
+ } catch {
257
+ throw new Error(`Invalid queue message id "${message.id}"`);
258
+ }
259
+ return {
260
+ id,
261
+ name: message.name,
262
+ body: message.body,
263
+ createdAt: message.createdAt,
264
+ ...message.complete ? { complete: message.complete } : {}
265
+ };
312
266
  }
313
- get workflowId() {
314
- return this.#inner.workflowId;
267
+ async #wrapActive(run) {
268
+ return await this.#runCtx.internalKeepAwake(run);
315
269
  }
316
- get abortSignal() {
317
- return this.#inner.abortSignal;
270
+ async #withActorAccess(run) {
271
+ this.#actorAccessDepth++;
272
+ if (this.#actorAccessDepth === 1) {
273
+ this.#allowActorAccess = true;
274
+ }
275
+ try {
276
+ return await run();
277
+ } finally {
278
+ this.#actorAccessDepth--;
279
+ if (this.#actorAccessDepth === 0) {
280
+ this.#allowActorAccess = false;
281
+ }
282
+ }
318
283
  }
319
- get queue() {
320
- const self = this;
321
- async function next(name, opts) {
322
- const message = await self.#inner.queue.next(name, opts);
323
- return self.#toActorQueueMessage(message);
284
+ async #withActorAccessAndStateRollback(run) {
285
+ let stateSnapshot = null;
286
+ try {
287
+ stateSnapshot = { state: this.#runCtx[RAW_STATE_SYMBOL]() };
288
+ } catch (error) {
289
+ this.#runCtx.log.debug({
290
+ msg: "failed to get state, likely due to being stateless workflow",
291
+ error
292
+ });
324
293
  }
325
- async function nextBatch(name, opts) {
326
- const messages = await self.#inner.queue.nextBatch(name, opts);
327
- return messages.map(
328
- (message) => self.#toActorQueueMessage(message)
329
- );
294
+ if (stateSnapshot) {
295
+ stateSnapshot.state = structuredClone(stateSnapshot.state);
330
296
  }
331
- async function send(name, body) {
332
- self.#ensureActorAccess("queue.send");
333
- await self.#runCtx.queue.send(name, body);
297
+ const varsSnapshot = structuredClone(this.#runCtx.vars);
298
+ try {
299
+ return await this.#withActorAccess(run);
300
+ } catch (error) {
301
+ if (stateSnapshot) {
302
+ this.#runCtx.state = stateSnapshot.state;
303
+ }
304
+ this.#runCtx.vars = varsSnapshot;
305
+ throw error;
334
306
  }
335
- return {
336
- next,
337
- nextBatch,
338
- send
339
- };
340
307
  }
341
- async step(nameOrConfig, run) {
342
- if (typeof nameOrConfig === "string") {
343
- if (!run) {
344
- throw new Error("Step run function missing");
345
- }
346
- return await this.#wrapActive(
347
- () => this.#inner.step(
348
- nameOrConfig,
349
- () => this.#withActorAccess(run)
350
- )
308
+ #ensureActorAccess(feature) {
309
+ if (!this.#allowActorAccess) {
310
+ this.#guardViolation = true;
311
+ this.#markGuardTriggered();
312
+ throw new Error(
313
+ `${feature} is only available inside workflow steps`
351
314
  );
352
315
  }
353
- const stepConfig = nameOrConfig;
354
- const config = {
355
- ...stepConfig,
356
- run: () => this.#withActorAccess(stepConfig.run)
357
- };
358
- return await this.#wrapActive(() => this.#inner.step(config));
359
316
  }
360
- async tryStep(nameOrConfig, run) {
361
- if (typeof nameOrConfig === "string") {
362
- if (!run) {
363
- throw new Error("Step run function missing");
317
+ consumeGuardViolation() {
318
+ const violated = this.#guardViolation;
319
+ this.#guardViolation = false;
320
+ return violated;
321
+ }
322
+ #markGuardTriggered() {
323
+ try {
324
+ const state = this.#runCtx.state;
325
+ if (state && typeof state === "object" && "guardTriggered" in state) {
326
+ state.guardTriggered = true;
364
327
  }
365
- return await this.#wrapActive(
366
- () => this.#inner.tryStep(
367
- nameOrConfig,
368
- () => this.#withActorAccess(run)
369
- )
370
- );
328
+ } catch {
371
329
  }
372
- const stepConfig = nameOrConfig;
373
- const config = {
374
- ...stepConfig,
375
- run: () => this.#withActorAccess(stepConfig.run)
376
- };
377
- return await this.#wrapActive(() => this.#inner.tryStep(config));
330
+ this.#runCtx.waitUntil(
331
+ (async () => {
332
+ try {
333
+ await this.#runCtx.kv.put(WORKFLOW_GUARD_KV_KEY, "true");
334
+ } catch (error) {
335
+ this.#runCtx.log.error({
336
+ msg: "failed to persist workflow guard flag",
337
+ error
338
+ });
339
+ }
340
+ })()
341
+ );
378
342
  }
379
- async try(nameOrConfig, run) {
380
- if (typeof nameOrConfig === "string") {
381
- if (!run) {
382
- throw new Error("Try run function missing");
383
- }
384
- return await this.#wrapActive(
385
- () => this.#inner.try(
386
- nameOrConfig,
387
- async (ctx) => run(this.#createChildContext(ctx))
388
- )
389
- );
343
+ #createChildContext(ctx) {
344
+ return new _ActorWorkflowContext(ctx, this.#runCtx);
345
+ }
346
+ };
347
+
348
+ // src/workflow/driver.ts
349
+ var WORKFLOW_STORAGE_PREFIX = workflowStoragePrefix();
350
+ function stripWorkflowKey(prefixed) {
351
+ return prefixed.slice(WORKFLOW_STORAGE_PREFIX.length);
352
+ }
353
+ function computeUpperBound(prefix) {
354
+ const upperBound = prefix.slice();
355
+ for (let i = upperBound.length - 1; i >= 0; i--) {
356
+ if (upperBound[i] !== 255) {
357
+ upperBound[i]++;
358
+ return upperBound.slice(0, i + 1);
390
359
  }
391
- const tryConfig = nameOrConfig;
392
- const config = {
393
- ...tryConfig,
394
- run: async (ctx) => tryConfig.run(this.#createChildContext(ctx))
395
- };
396
- return await this.#wrapActive(() => this.#inner.try(config));
397
360
  }
398
- async loop(nameOrConfig, run) {
399
- if (typeof nameOrConfig === "string") {
400
- if (!run) {
401
- throw new Error("Loop run function missing");
402
- }
403
- return await this.#wrapActive(
404
- () => this.#inner.loop(
405
- nameOrConfig,
406
- async (ctx) => run(this.#createChildContext(ctx))
407
- )
408
- );
361
+ return null;
362
+ }
363
+ var ActorWorkflowMessageDriver = class {
364
+ #actor;
365
+ #runCtx;
366
+ constructor(actor, runCtx) {
367
+ this.#actor = actor;
368
+ this.#runCtx = runCtx;
369
+ }
370
+ async addMessage(message) {
371
+ await this.#runCtx.internalKeepAwake(
372
+ this.#actor.queueManager.enqueue(message.name, message.data)
373
+ );
374
+ }
375
+ async receiveMessages(opts) {
376
+ const messages = await this.#runCtx.internalKeepAwake(
377
+ this.#actor.queueManager.receive(
378
+ opts.names && opts.names.length > 0 ? [...opts.names] : void 0,
379
+ opts.count,
380
+ 0,
381
+ void 0,
382
+ opts.completable
383
+ )
384
+ );
385
+ return messages.map((message) => ({
386
+ id: message.id.toString(),
387
+ name: message.name,
388
+ data: message.body,
389
+ sentAt: message.createdAt,
390
+ ...opts.completable ? {
391
+ complete: async (response) => {
392
+ await this.#runCtx.internalKeepAwake(
393
+ this.#actor.queueManager.completeMessage(
394
+ message,
395
+ response
396
+ )
397
+ );
398
+ }
399
+ } : {}
400
+ }));
401
+ }
402
+ async completeMessage(messageId, response) {
403
+ let parsedId;
404
+ try {
405
+ parsedId = BigInt(messageId);
406
+ } catch {
407
+ return;
409
408
  }
410
- const wrapped = {
411
- ...nameOrConfig,
412
- run: async (ctx, state) => nameOrConfig.run(this.#createChildContext(ctx), state)
413
- };
414
- return await this.#wrapActive(() => this.#inner.loop(wrapped));
409
+ await this.#runCtx.internalKeepAwake(
410
+ this.#actor.queueManager.completeMessageById(parsedId, response)
411
+ );
415
412
  }
416
- sleep(name, durationMs) {
417
- return this.#inner.sleep(name, durationMs);
413
+ };
414
+ var ActorWorkflowDriver = class {
415
+ workerPollInterval = 100;
416
+ messageDriver;
417
+ #actor;
418
+ #runCtx;
419
+ constructor(actor, runCtx) {
420
+ this.#actor = actor;
421
+ this.#runCtx = runCtx;
422
+ this.messageDriver = new ActorWorkflowMessageDriver(actor, runCtx);
418
423
  }
419
- sleepUntil(name, timestampMs) {
420
- return this.#inner.sleepUntil(name, timestampMs);
424
+ async get(key) {
425
+ const [value] = await this.#runCtx.internalKeepAwake(
426
+ this.#actor.driver.kvBatchGet(this.#actor.id, [
427
+ makeWorkflowKey(key)
428
+ ])
429
+ );
430
+ return value ?? null;
431
+ }
432
+ async set(key, value) {
433
+ await this.#runCtx.internalKeepAwake(
434
+ this.#actor.driver.kvBatchPut(this.#actor.id, [
435
+ [makeWorkflowKey(key), value]
436
+ ])
437
+ );
438
+ }
439
+ async delete(key) {
440
+ await this.#runCtx.internalKeepAwake(
441
+ this.#actor.driver.kvBatchDelete(this.#actor.id, [
442
+ makeWorkflowKey(key)
443
+ ])
444
+ );
445
+ }
446
+ async deletePrefix(prefix) {
447
+ const start = makeWorkflowKey(prefix);
448
+ const end = computeUpperBound(start);
449
+ if (end) {
450
+ await this.#runCtx.internalKeepAwake(
451
+ this.#actor.driver.kvDeleteRange(this.#actor.id, start, end)
452
+ );
453
+ } else {
454
+ const entries = await this.#runCtx.internalKeepAwake(
455
+ this.#actor.driver.kvListPrefix(this.#actor.id, start)
456
+ );
457
+ if (entries.length === 0) {
458
+ return;
459
+ }
460
+ await this.#runCtx.internalKeepAwake(
461
+ this.#actor.driver.kvBatchDelete(
462
+ this.#actor.id,
463
+ entries.map(([key]) => key)
464
+ )
465
+ );
466
+ }
421
467
  }
422
- destroy() {
423
- this.#ensureActorAccess("destroy");
424
- this.#runCtx.destroy();
468
+ async deleteRange(start, end) {
469
+ await this.#runCtx.internalKeepAwake(
470
+ this.#actor.driver.kvDeleteRange(
471
+ this.#actor.id,
472
+ makeWorkflowKey(start),
473
+ makeWorkflowKey(end)
474
+ )
475
+ );
425
476
  }
426
- async rollbackCheckpoint(name) {
427
- await this.#wrapActive(() => this.#inner.rollbackCheckpoint(name));
477
+ async list(prefix) {
478
+ const entries = await this.#runCtx.internalKeepAwake(
479
+ this.#actor.driver.kvListPrefix(
480
+ this.#actor.id,
481
+ makeWorkflowKey(prefix)
482
+ )
483
+ );
484
+ return entries.map(([key, value]) => ({
485
+ key: stripWorkflowKey(key),
486
+ value
487
+ }));
428
488
  }
429
- async join(name, branches) {
430
- const wrappedBranches = Object.fromEntries(
431
- Object.entries(branches).map(([key, branch]) => [
432
- key,
433
- {
434
- run: async (ctx) => branch.run(this.#createChildContext(ctx))
435
- }
489
+ async batch(writes) {
490
+ if (writes.length === 0) return;
491
+ await this.#runCtx.internalKeepAwake(
492
+ Promise.all([
493
+ this.#actor.driver.kvBatchPut(
494
+ this.#actor.id,
495
+ writes.map(({ key, value }) => [
496
+ makeWorkflowKey(key),
497
+ value
498
+ ])
499
+ ),
500
+ this.#actor.stateManager.saveState({
501
+ immediate: true
502
+ })
436
503
  ])
437
504
  );
438
- return await this.#wrapActive(
439
- () => this.#inner.join(name, wrappedBranches)
440
- );
441
505
  }
442
- async race(name, branches) {
443
- const wrappedBranches = branches.map((branch) => ({
444
- name: branch.name,
445
- run: (ctx) => branch.run(this.#createChildContext(ctx))
446
- }));
447
- return await this.#wrapActive(
448
- () => this.#inner.race(name, wrappedBranches)
506
+ async setAlarm(_workflowId, wakeAt) {
507
+ await this.#runCtx.internalKeepAwake(
508
+ this.#actor.driver.setAlarm(this.#actor, wakeAt)
449
509
  );
450
510
  }
451
- async removed(name, originalType) {
452
- await this.#wrapActive(() => this.#inner.removed(name, originalType));
453
- }
454
- isEvicted() {
455
- return this.#inner.isEvicted();
456
- }
457
- get state() {
458
- this.#ensureActorAccess("state");
459
- return this.#runCtx.state;
460
- }
461
- get vars() {
462
- this.#ensureActorAccess("vars");
463
- return this.#runCtx.vars;
511
+ async clearAlarm(_workflowId) {
512
+ return;
464
513
  }
465
- client() {
466
- this.#ensureActorAccess("client");
467
- return this.#runCtx.client();
514
+ waitForMessages(messageNames, abortSignal) {
515
+ return this.#actor.queueManager.waitForNames(
516
+ messageNames.length > 0 ? messageNames : void 0,
517
+ abortSignal
518
+ );
468
519
  }
469
- get db() {
470
- this.#ensureActorAccess("db");
471
- return this.#runCtx.db;
520
+ };
521
+ var NoopWorkflowMessageDriver = class {
522
+ async addMessage(_message) {
523
+ throw new Error("Workflow control driver does not support messages");
472
524
  }
473
- get log() {
474
- return this.#runCtx.log;
525
+ async receiveMessages(_opts) {
526
+ throw new Error("Workflow control driver does not support messages");
475
527
  }
476
- /** @deprecated No-op. Use `keepAwake(promise)` or `waitUntil(promise)` instead. */
477
- setPreventSleep(_prevent) {
478
- this.#ensureActorAccess("setPreventSleep");
528
+ async completeMessage(_messageId, _response) {
529
+ throw new Error("Workflow control driver does not support messages");
479
530
  }
480
- /** @deprecated No-op. Always returns `false`. */
481
- get preventSleep() {
482
- this.#ensureActorAccess("preventSleep");
483
- return false;
531
+ };
532
+ var ActorWorkflowControlDriver = class {
533
+ workerPollInterval = 100;
534
+ messageDriver = new NoopWorkflowMessageDriver();
535
+ #actor;
536
+ constructor(actor) {
537
+ this.#actor = actor;
484
538
  }
485
- /**
486
- * Holds the actor awake for the duration of the provided promise. The
487
- * actor cannot idle-sleep or finalize the sleep grace period until the
488
- * promise settles.
489
- */
490
- keepAwake(promise) {
491
- this.#ensureActorAccess("keepAwake");
492
- return this.#runCtx.keepAwake(promise);
539
+ async get(key) {
540
+ const [value] = await this.#actor.driver.kvBatchGet(this.#actor.id, [
541
+ makeWorkflowKey(key)
542
+ ]);
543
+ return value ?? null;
493
544
  }
494
- /**
495
- * Registers a promise that the sleep grace period will wait on. Use this
496
- * for best-effort flush/cleanup work that may complete inside the grace
497
- * window. For work the actor must stay running through, prefer
498
- * `c.keepAwake(promise)` which also blocks idle sleep.
499
- */
500
- waitUntil(promise) {
501
- this.#ensureActorAccess("waitUntil");
502
- this.#runCtx.waitUntil(promise);
545
+ async set(key, value) {
546
+ await this.#actor.driver.kvBatchPut(this.#actor.id, [
547
+ [makeWorkflowKey(key), value]
548
+ ]);
503
549
  }
504
- get actorId() {
505
- return this.#runCtx.actorId;
550
+ async delete(key) {
551
+ await this.#actor.driver.kvBatchDelete(this.#actor.id, [
552
+ makeWorkflowKey(key)
553
+ ]);
506
554
  }
507
- broadcast(name, ...args) {
508
- this.#ensureActorAccess("broadcast");
509
- this.#runCtx.broadcast(
510
- name,
511
- ...args
555
+ async deletePrefix(prefix) {
556
+ const start = makeWorkflowKey(prefix);
557
+ const end = computeUpperBound(start);
558
+ if (end) {
559
+ await this.#actor.driver.kvDeleteRange(this.#actor.id, start, end);
560
+ return;
561
+ }
562
+ const entries = await this.#actor.driver.kvListPrefix(
563
+ this.#actor.id,
564
+ start
512
565
  );
513
- }
514
- #toActorQueueMessage(message) {
515
- let id;
516
- try {
517
- id = BigInt(message.id);
518
- } catch {
519
- throw new Error(`Invalid queue message id "${message.id}"`);
566
+ if (entries.length === 0) {
567
+ return;
520
568
  }
521
- return {
522
- id,
523
- name: message.name,
524
- body: message.body,
525
- createdAt: message.createdAt,
526
- ...message.complete ? { complete: message.complete } : {}
527
- };
569
+ await this.#actor.driver.kvBatchDelete(
570
+ this.#actor.id,
571
+ entries.map(([key]) => key)
572
+ );
528
573
  }
529
- async #wrapActive(run) {
530
- return await this.#runCtx.internalKeepAwake(run);
574
+ async deleteRange(start, end) {
575
+ await this.#actor.driver.kvDeleteRange(
576
+ this.#actor.id,
577
+ makeWorkflowKey(start),
578
+ makeWorkflowKey(end)
579
+ );
531
580
  }
532
- async #withActorAccess(run) {
533
- this.#actorAccessDepth++;
534
- if (this.#actorAccessDepth === 1) {
535
- this.#allowActorAccess = true;
536
- }
537
- try {
538
- return await run();
539
- } finally {
540
- this.#actorAccessDepth--;
541
- if (this.#actorAccessDepth === 0) {
542
- this.#allowActorAccess = false;
543
- }
544
- }
581
+ async list(prefix) {
582
+ const entries = await this.#actor.driver.kvListPrefix(
583
+ this.#actor.id,
584
+ makeWorkflowKey(prefix)
585
+ );
586
+ return entries.map(([key, value]) => ({
587
+ key: stripWorkflowKey(key),
588
+ value
589
+ }));
545
590
  }
546
- #ensureActorAccess(feature) {
547
- if (!this.#allowActorAccess) {
548
- this.#guardViolation = true;
549
- this.#markGuardTriggered();
550
- throw new Error(
551
- `${feature} is only available inside workflow steps`
552
- );
591
+ async batch(writes) {
592
+ if (writes.length === 0) {
593
+ return;
553
594
  }
595
+ await this.#actor.driver.kvBatchPut(
596
+ this.#actor.id,
597
+ writes.map(({ key, value }) => [makeWorkflowKey(key), value])
598
+ );
554
599
  }
555
- consumeGuardViolation() {
556
- const violated = this.#guardViolation;
557
- this.#guardViolation = false;
558
- return violated;
600
+ async setAlarm(_workflowId, wakeAt) {
601
+ await this.#actor.driver.setAlarm(this.#actor, wakeAt);
559
602
  }
560
- #markGuardTriggered() {
561
- try {
562
- const state = this.#runCtx.state;
563
- if (state && typeof state === "object" && "guardTriggered" in state) {
564
- state.guardTriggered = true;
565
- }
566
- } catch {
567
- }
568
- this.#runCtx.waitUntil(
569
- (async () => {
570
- try {
571
- await this.#runCtx.kv.put(WORKFLOW_GUARD_KV_KEY, "true");
572
- } catch (error) {
573
- this.#runCtx.log.error({
574
- msg: "failed to persist workflow guard flag",
575
- error
576
- });
577
- }
578
- })()
579
- );
603
+ async clearAlarm(_workflowId) {
604
+ return;
580
605
  }
581
- #createChildContext(ctx) {
582
- return new _ActorWorkflowContext(ctx, this.#runCtx);
606
+ waitForMessages(_messageNames, _abortSignal) {
607
+ throw new Error("Workflow control driver does not support messages");
583
608
  }
584
609
  };
585
610