rivetkit 2.3.4 → 2.3.5-rc.1

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 (161) hide show
  1. package/dist/browser/client.d.ts +157 -9
  2. package/dist/browser/client.js +518 -542
  3. package/dist/browser/client.js.map +1 -1
  4. package/dist/browser/inspector/client.d.ts +101 -2
  5. package/dist/browser/inspector/client.js +1245 -227
  6. package/dist/browser/inspector/client.js.map +1 -1
  7. package/dist/tsup/agent-os/index.cjs +103 -36
  8. package/dist/tsup/agent-os/index.cjs.map +1 -1
  9. package/dist/tsup/agent-os/index.d.cts +159 -11
  10. package/dist/tsup/agent-os/index.d.ts +159 -11
  11. package/dist/tsup/agent-os/index.js +103 -36
  12. package/dist/tsup/agent-os/index.js.map +1 -1
  13. package/dist/tsup/{chunk-7X4M7ZRA.cjs → chunk-4XKED5P5.cjs} +146 -177
  14. package/dist/tsup/chunk-4XKED5P5.cjs.map +1 -0
  15. package/dist/tsup/{chunk-Q7NBMTF3.cjs → chunk-6HQCLWAW.cjs} +384 -4
  16. package/dist/tsup/chunk-6HQCLWAW.cjs.map +1 -0
  17. package/dist/tsup/{chunk-JZ7TWV65.js → chunk-7AFZMFPQ.js} +15 -1
  18. package/dist/tsup/chunk-7AFZMFPQ.js.map +1 -0
  19. package/dist/tsup/{chunk-M7DCRMOZ.js → chunk-B4IZU537.js} +382 -2
  20. package/dist/tsup/chunk-B4IZU537.js.map +1 -0
  21. package/dist/tsup/{chunk-3MHDOUD7.cjs → chunk-G3CCRCTK.cjs} +14 -9
  22. package/dist/tsup/chunk-G3CCRCTK.cjs.map +1 -0
  23. package/dist/tsup/{chunk-CMPFZ724.js → chunk-GAV4PKFT.js} +16 -47
  24. package/dist/tsup/{chunk-CMPFZ724.js.map → chunk-GAV4PKFT.js.map} +1 -1
  25. package/dist/tsup/{chunk-HXUEHHJF.js → chunk-JI6GZ2C2.js} +2 -11
  26. package/dist/tsup/{chunk-HXUEHHJF.js.map → chunk-JI6GZ2C2.js.map} +1 -1
  27. package/dist/tsup/{chunk-3SNFA373.cjs → chunk-M3FCXL3Q.cjs} +3 -3
  28. package/dist/tsup/{chunk-3SNFA373.cjs.map → chunk-M3FCXL3Q.cjs.map} +1 -1
  29. package/dist/tsup/{chunk-GXW3VFJQ.js → chunk-MGTSVSUC.js} +2 -2
  30. package/dist/tsup/{chunk-VE2X4KMG.cjs → chunk-MYWZCDML.cjs} +2 -11
  31. package/dist/tsup/chunk-MYWZCDML.cjs.map +1 -0
  32. package/dist/tsup/{chunk-M5TAM4JV.js → chunk-NIC3QLKL.js} +3 -3
  33. package/dist/tsup/{chunk-H4XOUVGP.js → chunk-P4OGQ4JL.js} +5 -7
  34. package/dist/tsup/{chunk-H4XOUVGP.js.map → chunk-P4OGQ4JL.js.map} +1 -1
  35. package/dist/tsup/{chunk-EOSGY3DC.js → chunk-PAG6G46L.js} +2 -2
  36. package/dist/tsup/{chunk-XIX5DOZN.js → chunk-SHBE77IT.js} +14 -9
  37. package/dist/tsup/chunk-SHBE77IT.js.map +1 -0
  38. package/dist/tsup/{chunk-SRT2DPN3.cjs → chunk-TNIWIUNV.cjs} +9 -11
  39. package/dist/tsup/chunk-TNIWIUNV.cjs.map +1 -0
  40. package/dist/tsup/{chunk-UPOCJPEQ.cjs → chunk-TR5NLR5V.cjs} +4 -4
  41. package/dist/tsup/{chunk-UPOCJPEQ.cjs.map → chunk-TR5NLR5V.cjs.map} +1 -1
  42. package/dist/tsup/{chunk-ZA7FLHKH.cjs → chunk-UEULFXUI.cjs} +16 -2
  43. package/dist/tsup/chunk-UEULFXUI.cjs.map +1 -0
  44. package/dist/tsup/{chunk-T4MURX4P.cjs → chunk-UJ2FQY63.cjs} +7 -7
  45. package/dist/tsup/{chunk-T4MURX4P.cjs.map → chunk-UJ2FQY63.cjs.map} +1 -1
  46. package/dist/tsup/client/mod.cjs +7 -8
  47. package/dist/tsup/client/mod.cjs.map +1 -1
  48. package/dist/tsup/client/mod.d.cts +5 -4
  49. package/dist/tsup/client/mod.d.ts +5 -4
  50. package/dist/tsup/client/mod.js +6 -7
  51. package/dist/tsup/common/log.cjs +2 -2
  52. package/dist/tsup/common/log.js +1 -1
  53. package/dist/tsup/common/websocket.cjs +3 -3
  54. package/dist/tsup/common/websocket.js +2 -2
  55. package/dist/tsup/{config-D49x8NpL.d.cts → config-BxOimoGX.d.cts} +16 -0
  56. package/dist/tsup/{config-D49x8NpL.d.ts → config-BxOimoGX.d.ts} +16 -0
  57. package/dist/tsup/{config-ZkIsRFsN.d.ts → config-BzdqbLAP.d.ts} +164 -27
  58. package/dist/tsup/{config-BfBhjEbk.d.cts → config-CPPEwn_e.d.cts} +164 -27
  59. package/dist/tsup/{context-sZ9GlaBK.d.cts → context-DSA9gFXB.d.cts} +2 -2
  60. package/dist/tsup/{context-B7-84u9K.d.ts → context-wWv-K2K_.d.ts} +2 -2
  61. package/dist/tsup/db/drizzle.cjs +120 -68
  62. package/dist/tsup/db/drizzle.cjs.map +1 -1
  63. package/dist/tsup/db/drizzle.d.cts +8 -3
  64. package/dist/tsup/db/drizzle.d.ts +8 -3
  65. package/dist/tsup/db/drizzle.js +120 -68
  66. package/dist/tsup/db/drizzle.js.map +1 -1
  67. package/dist/tsup/db/mod.cjs +74 -22
  68. package/dist/tsup/db/mod.cjs.map +1 -1
  69. package/dist/tsup/db/mod.d.cts +4 -3
  70. package/dist/tsup/db/mod.d.ts +4 -3
  71. package/dist/tsup/db/mod.js +74 -22
  72. package/dist/tsup/db/mod.js.map +1 -1
  73. package/dist/tsup/dynamic/mod.cjs +2 -2
  74. package/dist/tsup/dynamic/mod.d.cts +3 -3
  75. package/dist/tsup/dynamic/mod.d.ts +3 -3
  76. package/dist/tsup/dynamic/mod.js +1 -1
  77. package/dist/tsup/inspector/mod.cjs +4 -5
  78. package/dist/tsup/inspector/mod.cjs.map +1 -1
  79. package/dist/tsup/inspector/mod.js +3 -4
  80. package/dist/tsup/inspector/mod.js.map +1 -1
  81. package/dist/tsup/inspector-tab/mod.cjs +2 -2
  82. package/dist/tsup/inspector-tab/mod.cjs.map +1 -1
  83. package/dist/tsup/inspector-tab/mod.d.cts +5 -5
  84. package/dist/tsup/inspector-tab/mod.d.ts +5 -5
  85. package/dist/tsup/inspector-tab/mod.js +1 -1
  86. package/dist/tsup/inspector-tab/mod.js.map +1 -1
  87. package/dist/tsup/mod.cjs +605 -158
  88. package/dist/tsup/mod.cjs.map +1 -1
  89. package/dist/tsup/mod.d.cts +5 -5
  90. package/dist/tsup/mod.d.ts +5 -5
  91. package/dist/tsup/mod.js +528 -81
  92. package/dist/tsup/mod.js.map +1 -1
  93. package/dist/tsup/test/mod.cjs +10 -11
  94. package/dist/tsup/test/mod.cjs.map +1 -1
  95. package/dist/tsup/test/mod.d.cts +3 -3
  96. package/dist/tsup/test/mod.d.ts +3 -3
  97. package/dist/tsup/test/mod.js +6 -7
  98. package/dist/tsup/test/mod.js.map +1 -1
  99. package/dist/tsup/utils-CV0akuDD.d.ts +162 -0
  100. package/dist/tsup/utils-DQDCphrl.d.cts +162 -0
  101. package/dist/tsup/utils.cjs +6 -2
  102. package/dist/tsup/utils.cjs.map +1 -1
  103. package/dist/tsup/utils.d.cts +3 -146
  104. package/dist/tsup/utils.d.ts +3 -146
  105. package/dist/tsup/utils.js +5 -1
  106. package/dist/tsup/workflow/mod.cjs +198 -151
  107. package/dist/tsup/workflow/mod.cjs.map +1 -1
  108. package/dist/tsup/workflow/mod.d.cts +5 -5
  109. package/dist/tsup/workflow/mod.d.ts +5 -5
  110. package/dist/tsup/workflow/mod.js +187 -140
  111. package/dist/tsup/workflow/mod.js.map +1 -1
  112. package/package.json +8 -8
  113. package/src/actor/config.test.ts +14 -0
  114. package/src/actor/config.ts +104 -16
  115. package/src/actor/definition.ts +18 -7
  116. package/src/agent-os/actor/index.ts +2 -2
  117. package/src/common/bare/generated/actor-runtime-socket-protocol/v1.ts +848 -0
  118. package/src/common/bare/generated/inspector/v6.ts +1367 -0
  119. package/src/common/database/config.ts +24 -0
  120. package/src/common/database/mod.test.ts +148 -59
  121. package/src/common/database/mod.ts +93 -23
  122. package/src/common/database/native-database.test.ts +9 -0
  123. package/src/common/database/native-database.ts +151 -0
  124. package/src/common/database/shared.ts +15 -0
  125. package/src/common/encoding.ts +28 -21
  126. package/src/db/drizzle.test.ts +157 -0
  127. package/src/db/drizzle.ts +170 -79
  128. package/src/dynamic/isolate-runtime.ts +0 -2
  129. package/src/engine-client/driver.ts +0 -15
  130. package/src/engine-client/mod.ts +0 -41
  131. package/src/inspector/client.browser.ts +69 -8
  132. package/src/inspector-tab/mod.ts +1 -0
  133. package/src/registry/config/index.ts +1 -35
  134. package/src/registry/napi-runtime.ts +204 -16
  135. package/src/registry/native.ts +200 -30
  136. package/src/registry/runtime.ts +146 -3
  137. package/src/registry/wasm-runtime.ts +217 -6
  138. package/src/utils.ts +3 -0
  139. package/src/workflow/context.ts +5 -27
  140. package/src/workflow/driver.test.ts +62 -0
  141. package/src/workflow/driver.ts +231 -113
  142. package/src/workflow/mod.ts +3 -3
  143. package/dist/tsup/chunk-3MHDOUD7.cjs.map +0 -1
  144. package/dist/tsup/chunk-7X4M7ZRA.cjs.map +0 -1
  145. package/dist/tsup/chunk-JZ7TWV65.js.map +0 -1
  146. package/dist/tsup/chunk-M7DCRMOZ.js.map +0 -1
  147. package/dist/tsup/chunk-Q7NBMTF3.cjs.map +0 -1
  148. package/dist/tsup/chunk-SRT2DPN3.cjs.map +0 -1
  149. package/dist/tsup/chunk-VE2X4KMG.cjs.map +0 -1
  150. package/dist/tsup/chunk-W6WPKZ6I.js +0 -382
  151. package/dist/tsup/chunk-W6WPKZ6I.js.map +0 -1
  152. package/dist/tsup/chunk-XIX5DOZN.js.map +0 -1
  153. package/dist/tsup/chunk-Z7PSQWMC.cjs +0 -382
  154. package/dist/tsup/chunk-Z7PSQWMC.cjs.map +0 -1
  155. package/dist/tsup/chunk-ZA7FLHKH.cjs.map +0 -1
  156. package/src/actor/driver.ts +0 -141
  157. package/src/actor/instance/mod.ts +0 -2484
  158. package/src/drivers/engine/actor-driver.ts +0 -2473
  159. /package/dist/tsup/{chunk-GXW3VFJQ.js.map → chunk-MGTSVSUC.js.map} +0 -0
  160. /package/dist/tsup/{chunk-M5TAM4JV.js.map → chunk-NIC3QLKL.js.map} +0 -0
  161. /package/dist/tsup/{chunk-EOSGY3DC.js.map → chunk-PAG6G46L.js.map} +0 -0
@@ -1,5 +1,5 @@
1
- import { stringifyError } from "@/common/utils";
2
1
  import type { SqliteNativeMetrics } from "@/common/database/config";
2
+ import { stringifyError } from "@/common/utils";
3
3
  import type { RegistryConfig } from "./config";
4
4
  import { logger } from "./log";
5
5
 
@@ -15,6 +15,7 @@ export type ActorContextHandle = OpaqueHandle<"actorContext">;
15
15
  export type ConnHandle = OpaqueHandle<"conn">;
16
16
  export type WebSocketHandle = OpaqueHandle<"webSocket">;
17
17
  export type CancellationTokenHandle = OpaqueHandle<"cancellationToken">;
18
+ export type SqliteTransactionHandle = OpaqueHandle<"sqliteTransaction">;
18
19
 
19
20
  export type RuntimeBytes = Uint8Array;
20
21
 
@@ -46,6 +47,11 @@ export interface RuntimeStateDeltaPayload {
46
47
  connHibernationRemoved: string[];
47
48
  }
48
49
 
50
+ export interface RuntimeWorkflowKvWrite {
51
+ key: RuntimeBytes;
52
+ value: RuntimeBytes;
53
+ }
54
+
49
55
  export interface RuntimeRequestSaveOpts {
50
56
  immediate?: boolean;
51
57
  maxWaitMs?: number;
@@ -80,6 +86,50 @@ export interface RuntimeQueueSendResult {
80
86
  response?: RuntimeBytes;
81
87
  }
82
88
 
89
+ export interface RuntimeScheduledEventInfo {
90
+ id: string;
91
+ action: string;
92
+ args: RuntimeBytes;
93
+ runAt: number;
94
+ }
95
+
96
+ export interface RuntimeCronJobInfo {
97
+ name: string;
98
+ kind: "cron" | "every";
99
+ action: string;
100
+ args: RuntimeBytes;
101
+ nextRunAt: number;
102
+ lastRunAt?: number;
103
+ expression?: string;
104
+ timezone?: string;
105
+ intervalMs?: number;
106
+ maxHistory: number;
107
+ }
108
+
109
+ export interface RuntimeScheduleErrorInfo {
110
+ group: string;
111
+ code: string;
112
+ message: string;
113
+ metadata?: unknown;
114
+ }
115
+
116
+ export interface RuntimeCronFire {
117
+ action: string;
118
+ scheduledAt: number;
119
+ firedAt: number;
120
+ finishedAt?: number;
121
+ result: "running" | "ok" | "error" | "skipped";
122
+ error?: RuntimeScheduleErrorInfo;
123
+ }
124
+
125
+ export interface RuntimeScheduledFireInfo {
126
+ kind: "at" | "cron" | "every";
127
+ id: string;
128
+ name?: string;
129
+ scheduledAt: number;
130
+ firedAt: number;
131
+ }
132
+
83
133
  export interface RuntimeQueueNextBatchOptions {
84
134
  names?: string[];
85
135
  count?: number;
@@ -152,6 +202,10 @@ export type RuntimeSqlBindParam =
152
202
 
153
203
  export type RuntimeSqlBindParams = RuntimeSqlBindParam[] | null;
154
204
 
205
+ export interface RuntimeActorRuntimeSocketEndpointInfo {
206
+ path: string;
207
+ }
208
+
155
209
  export interface RuntimeSqlQueryResult {
156
210
  columns: string[];
157
211
  rows: unknown[][];
@@ -164,6 +218,11 @@ export interface RuntimeSqlExecuteResult extends RuntimeSqlQueryResult {
164
218
  lastInsertRowId?: number | null;
165
219
  }
166
220
 
221
+ export interface RuntimeSqlBatchStatement {
222
+ sql: string;
223
+ params?: RuntimeSqlBindParams;
224
+ }
225
+
167
226
  export function normalizeRuntimeSqlExecuteResult(
168
227
  result: RuntimeSqlQueryResult & {
169
228
  changes: number;
@@ -183,6 +242,9 @@ export interface RuntimeSqlDatabase {
183
242
  sql: string,
184
243
  params?: RuntimeSqlBindParams,
185
244
  ): Promise<RuntimeSqlExecuteResult>;
245
+ executeBatch(
246
+ statements: RuntimeSqlBatchStatement[],
247
+ ): Promise<RuntimeSqlExecuteResult[]>;
186
248
  query(
187
249
  sql: string,
188
250
  params?: RuntimeSqlBindParams,
@@ -191,16 +253,30 @@ export interface RuntimeSqlDatabase {
191
253
  sql: string,
192
254
  params?: RuntimeSqlBindParams,
193
255
  ): Promise<RuntimeSqlRunResult>;
256
+ beginTransaction(
257
+ timeoutMs?: number,
258
+ ): Promise<RuntimeSqlTransactionDatabase>;
194
259
  metrics?(): SqliteNativeMetrics | null;
195
260
  takeLastKvError?(): string | null;
196
261
  close(): Promise<void>;
197
262
  }
198
263
 
264
+ export interface RuntimeSqlTransactionDatabase {
265
+ exec(sql: string): Promise<RuntimeSqlExecResult>;
266
+ execute(
267
+ sql: string,
268
+ params?: RuntimeSqlBindParams,
269
+ ): Promise<RuntimeSqlExecuteResult>;
270
+ commit(): Promise<void>;
271
+ rollback(): Promise<void>;
272
+ }
273
+
199
274
  export interface RuntimeActorConfig {
200
275
  name?: string;
201
276
  icon?: string;
202
277
  hasDatabase?: boolean;
203
278
  remoteSqlite?: boolean;
279
+ enableActorRuntimeSocket?: boolean;
204
280
  hasState?: boolean;
205
281
  canHibernateWebsocket?: boolean;
206
282
  stateSaveIntervalMs?: number;
@@ -221,6 +297,7 @@ export interface RuntimeActorConfig {
221
297
  connectionLivenessTimeoutMs?: number;
222
298
  connectionLivenessIntervalMs?: number;
223
299
  maxQueueSize?: number;
300
+ maxSchedules?: number;
224
301
  maxQueueMessageSize?: number;
225
302
  maxIncomingMessageSize?: number;
226
303
  maxOutgoingMessageSize?: number;
@@ -410,6 +487,10 @@ export interface CoreRuntime {
410
487
  ctx: ActorContextHandle,
411
488
  payload: RuntimeStateDeltaPayload,
412
489
  ): Promise<void>;
490
+ actorSaveStateAndWorkflowBatch(
491
+ ctx: ActorContextHandle,
492
+ writes: RuntimeWorkflowKvWrite[],
493
+ ): Promise<void>;
413
494
  actorId(ctx: ActorContextHandle): string;
414
495
  actorName(ctx: ActorContextHandle): string;
415
496
  actorKey(ctx: ActorContextHandle): RuntimeActorKeySegment[];
@@ -491,6 +572,29 @@ export interface CoreRuntime {
491
572
  sql: string,
492
573
  params?: RuntimeSqlBindParams,
493
574
  ): Promise<RuntimeSqlExecuteResult>;
575
+ actorSqlExecuteBatch(
576
+ ctx: ActorContextHandle,
577
+ statements: RuntimeSqlBatchStatement[],
578
+ ): Promise<RuntimeSqlExecuteResult[]>;
579
+ actorSqlBeginTransaction(
580
+ ctx: ActorContextHandle,
581
+ timeoutMs?: number,
582
+ ): Promise<SqliteTransactionHandle>;
583
+ actorSqlTransactionExec(
584
+ transaction: SqliteTransactionHandle,
585
+ sql: string,
586
+ ): Promise<RuntimeSqlExecResult>;
587
+ actorSqlTransactionExecute(
588
+ transaction: SqliteTransactionHandle,
589
+ sql: string,
590
+ params?: RuntimeSqlBindParams,
591
+ ): Promise<RuntimeSqlExecuteResult>;
592
+ actorSqlTransactionCommit(
593
+ transaction: SqliteTransactionHandle,
594
+ ): Promise<void>;
595
+ actorSqlTransactionRollback(
596
+ transaction: SqliteTransactionHandle,
597
+ ): Promise<void>;
494
598
  actorSqlQuery(
495
599
  ctx: ActorContextHandle,
496
600
  sql: string,
@@ -504,6 +608,9 @@ export interface CoreRuntime {
504
608
  actorSqlMetrics(ctx: ActorContextHandle): SqliteNativeMetrics | null;
505
609
  actorSqlTakeLastKvError(ctx: ActorContextHandle): string | null;
506
610
  actorSqlClose(ctx: ActorContextHandle): Promise<void>;
611
+ actorRuntimeSocketProvision(
612
+ ctx: ActorContextHandle,
613
+ ): Promise<RuntimeActorRuntimeSocketEndpointInfo>;
507
614
 
508
615
  actorQueueSend(
509
616
  ctx: ActorContextHandle,
@@ -549,13 +656,49 @@ export interface CoreRuntime {
549
656
  durationMs: number,
550
657
  actionName: string,
551
658
  args: RuntimeBytes,
552
- ): void;
659
+ ): Promise<string>;
553
660
  actorScheduleAt(
554
661
  ctx: ActorContextHandle,
555
662
  timestampMs: number,
556
663
  actionName: string,
557
664
  args: RuntimeBytes,
558
- ): void;
665
+ ): Promise<string>;
666
+ actorScheduleCancel(ctx: ActorContextHandle, id: string): Promise<boolean>;
667
+ actorScheduleGet(
668
+ ctx: ActorContextHandle,
669
+ id: string,
670
+ ): Promise<RuntimeScheduledEventInfo | undefined>;
671
+ actorScheduleList(
672
+ ctx: ActorContextHandle,
673
+ ): Promise<RuntimeScheduledEventInfo[]>;
674
+ actorCronSet(
675
+ ctx: ActorContextHandle,
676
+ name: string,
677
+ expression: string,
678
+ timezone: string | undefined,
679
+ actionName: string,
680
+ args: RuntimeBytes,
681
+ maxHistory: number | undefined,
682
+ ): Promise<void>;
683
+ actorCronEvery(
684
+ ctx: ActorContextHandle,
685
+ name: string,
686
+ intervalMs: number,
687
+ actionName: string,
688
+ args: RuntimeBytes,
689
+ maxHistory: number | undefined,
690
+ ): Promise<void>;
691
+ actorCronGet(
692
+ ctx: ActorContextHandle,
693
+ name: string,
694
+ ): Promise<RuntimeCronJobInfo | undefined>;
695
+ actorCronList(ctx: ActorContextHandle): Promise<RuntimeCronJobInfo[]>;
696
+ actorCronDelete(ctx: ActorContextHandle, name: string): Promise<boolean>;
697
+ actorCronHistory(
698
+ ctx: ActorContextHandle,
699
+ name: string,
700
+ limit: number | undefined,
701
+ ): Promise<RuntimeCronFire[]>;
559
702
 
560
703
  connId(conn: ConnHandle): string;
561
704
  connParams(conn: ConnHandle): RuntimeBytes;
@@ -33,12 +33,16 @@ import type {
33
33
  RuntimeQueueNextBatchOptions,
34
34
  RuntimeQueueTryNextBatchOptions,
35
35
  RuntimeQueueWaitOptions,
36
+ RuntimeCronFire,
37
+ RuntimeCronJobInfo,
36
38
  RuntimeRegistryRouteResponse,
37
39
  RuntimeRequestSaveOpts,
38
40
  RuntimeServeConfig,
41
+ RuntimeScheduledEventInfo,
39
42
  RuntimeServerlessRequest,
40
43
  RuntimeServerlessResponseHead,
41
44
  RuntimeServerlessStreamCallback,
45
+ RuntimeSqlBatchStatement,
42
46
  RuntimeSqlBindParams,
43
47
  RuntimeSqlDatabase,
44
48
  RuntimeSqlExecResult,
@@ -47,6 +51,8 @@ import type {
47
51
  RuntimeSqlRunResult,
48
52
  RuntimeStateDeltaPayload,
49
53
  RuntimeWebSocketEvent,
54
+ RuntimeWorkflowKvWrite,
55
+ SqliteTransactionHandle,
50
56
  WebSocketHandle,
51
57
  } from "./runtime";
52
58
  import { normalizeRuntimeSqlExecuteResult } from "./runtime";
@@ -464,6 +470,17 @@ export class WasmCoreRuntime implements CoreRuntime {
464
470
  await callHandleAsync(asWasmActorContext(ctx), "saveState", payload);
465
471
  }
466
472
 
473
+ async actorSaveStateAndWorkflowBatch(
474
+ ctx: ActorContextHandle,
475
+ writes: RuntimeWorkflowKvWrite[],
476
+ ): Promise<void> {
477
+ await callHandleAsync(
478
+ asWasmActorContext(ctx),
479
+ "saveStateAndWorkflowBatch",
480
+ writes,
481
+ );
482
+ }
483
+
467
484
  actorId(ctx: ActorContextHandle): string {
468
485
  return callHandle(asWasmActorContext(ctx), "actorId");
469
486
  }
@@ -701,6 +718,74 @@ export class WasmCoreRuntime implements CoreRuntime {
701
718
  return normalizeRuntimeSqlExecuteResult(result);
702
719
  }
703
720
 
721
+ async actorSqlExecuteBatch(
722
+ ctx: ActorContextHandle,
723
+ statements: RuntimeSqlBatchStatement[],
724
+ ): Promise<RuntimeSqlExecuteResult[]> {
725
+ const results = await callWasm(() =>
726
+ this.#actorSql(ctx).executeBatch(statements),
727
+ );
728
+ return results.map(normalizeRuntimeSqlExecuteResult);
729
+ }
730
+
731
+ async actorSqlBeginTransaction(
732
+ ctx: ActorContextHandle,
733
+ timeoutMs?: number,
734
+ ): Promise<SqliteTransactionHandle> {
735
+ return (await callWasm(() =>
736
+ this.#actorSql(ctx).beginTransaction(timeoutMs),
737
+ )) as unknown as SqliteTransactionHandle;
738
+ }
739
+
740
+ async actorSqlTransactionExec(
741
+ transaction: SqliteTransactionHandle,
742
+ sql: string,
743
+ ): Promise<RuntimeSqlExecResult> {
744
+ return await callWasm(() =>
745
+ (
746
+ transaction as unknown as {
747
+ exec(sql: string): Promise<RuntimeSqlExecResult>;
748
+ }
749
+ ).exec(sql),
750
+ );
751
+ }
752
+
753
+ async actorSqlTransactionExecute(
754
+ transaction: SqliteTransactionHandle,
755
+ sql: string,
756
+ params?: RuntimeSqlBindParams,
757
+ ): Promise<RuntimeSqlExecuteResult> {
758
+ const result = await callWasm(() =>
759
+ (
760
+ transaction as unknown as {
761
+ execute(
762
+ sql: string,
763
+ params?: RuntimeSqlBindParams,
764
+ ): Promise<RuntimeSqlExecuteResult>;
765
+ }
766
+ ).execute(sql, params),
767
+ );
768
+ return normalizeRuntimeSqlExecuteResult(result);
769
+ }
770
+
771
+ async actorSqlTransactionCommit(
772
+ transaction: SqliteTransactionHandle,
773
+ ): Promise<void> {
774
+ await callWasm(() =>
775
+ (transaction as unknown as { commit(): Promise<void> }).commit(),
776
+ );
777
+ }
778
+
779
+ async actorSqlTransactionRollback(
780
+ transaction: SqliteTransactionHandle,
781
+ ): Promise<void> {
782
+ await callWasm(() =>
783
+ (
784
+ transaction as unknown as { rollback(): Promise<void> }
785
+ ).rollback(),
786
+ );
787
+ }
788
+
704
789
  async actorSqlQuery(
705
790
  ctx: ActorContextHandle,
706
791
  sql: string,
@@ -736,6 +821,20 @@ export class WasmCoreRuntime implements CoreRuntime {
736
821
  await callWasm(() => database.close());
737
822
  }
738
823
 
824
+ async actorRuntimeSocketProvision(
825
+ _ctx: ActorContextHandle,
826
+ ): Promise<never> {
827
+ throw new RivetError(
828
+ "actor_runtime_socket",
829
+ "unsupported",
830
+ "Actor Runtime Socket is only available on Unix native runtimes.",
831
+ {
832
+ public: true,
833
+ metadata: { runtime: "wasm" },
834
+ },
835
+ );
836
+ }
837
+
739
838
  async actorQueueSend(
740
839
  ctx: ActorContextHandle,
741
840
  name: string,
@@ -845,24 +944,136 @@ export class WasmCoreRuntime implements CoreRuntime {
845
944
  await callHandleAsync(queue, "reset");
846
945
  }
847
946
 
848
- actorScheduleAfter(
947
+ async actorScheduleAfter(
849
948
  ctx: ActorContextHandle,
850
949
  durationMs: number | bigint,
851
950
  actionName: string,
852
951
  args: RuntimeBytes,
853
- ): void {
952
+ ): Promise<string> {
854
953
  const schedule = childHandle(asWasmActorContext(ctx), "schedule");
855
- callHandle(schedule, "after", wasmNumber(durationMs), actionName, args);
954
+ return await callHandleAsync<string>(
955
+ schedule,
956
+ "after",
957
+ wasmNumber(durationMs),
958
+ actionName,
959
+ args,
960
+ );
856
961
  }
857
962
 
858
- actorScheduleAt(
963
+ async actorScheduleAt(
859
964
  ctx: ActorContextHandle,
860
965
  timestampMs: number | bigint,
861
966
  actionName: string,
862
967
  args: RuntimeBytes,
863
- ): void {
968
+ ): Promise<string> {
969
+ const schedule = childHandle(asWasmActorContext(ctx), "schedule");
970
+ return await callHandleAsync<string>(
971
+ schedule,
972
+ "at",
973
+ wasmNumber(timestampMs),
974
+ actionName,
975
+ args,
976
+ );
977
+ }
978
+
979
+ async actorScheduleCancel(ctx: ActorContextHandle, id: string) {
980
+ const schedule = childHandle(asWasmActorContext(ctx), "schedule");
981
+ return await callHandleAsync<boolean>(schedule, "cancel", id);
982
+ }
983
+
984
+ async actorScheduleGet(ctx: ActorContextHandle, id: string) {
985
+ const schedule = childHandle(asWasmActorContext(ctx), "schedule");
986
+ return await callHandleAsync<RuntimeScheduledEventInfo | undefined>(
987
+ schedule,
988
+ "get",
989
+ id,
990
+ );
991
+ }
992
+
993
+ async actorScheduleList(ctx: ActorContextHandle) {
994
+ const schedule = childHandle(asWasmActorContext(ctx), "schedule");
995
+ return await callHandleAsync<RuntimeScheduledEventInfo[]>(
996
+ schedule,
997
+ "list",
998
+ );
999
+ }
1000
+
1001
+ async actorCronSet(
1002
+ ctx: ActorContextHandle,
1003
+ name: string,
1004
+ expression: string,
1005
+ timezone: string | undefined,
1006
+ actionName: string,
1007
+ args: RuntimeBytes,
1008
+ maxHistory: number | undefined,
1009
+ ) {
864
1010
  const schedule = childHandle(asWasmActorContext(ctx), "schedule");
865
- callHandle(schedule, "at", wasmNumber(timestampMs), actionName, args);
1011
+ await callHandleAsync(
1012
+ schedule,
1013
+ "cronSet",
1014
+ name,
1015
+ expression,
1016
+ timezone,
1017
+ actionName,
1018
+ args,
1019
+ maxHistory,
1020
+ );
1021
+ }
1022
+
1023
+ async actorCronEvery(
1024
+ ctx: ActorContextHandle,
1025
+ name: string,
1026
+ intervalMs: number,
1027
+ actionName: string,
1028
+ args: RuntimeBytes,
1029
+ maxHistory: number | undefined,
1030
+ ) {
1031
+ const schedule = childHandle(asWasmActorContext(ctx), "schedule");
1032
+ await callHandleAsync(
1033
+ schedule,
1034
+ "cronEvery",
1035
+ name,
1036
+ intervalMs,
1037
+ actionName,
1038
+ args,
1039
+ maxHistory,
1040
+ );
1041
+ }
1042
+
1043
+ async actorCronGet(ctx: ActorContextHandle, name: string) {
1044
+ const schedule = childHandle(asWasmActorContext(ctx), "schedule");
1045
+ return await callHandleAsync<RuntimeCronJobInfo | undefined>(
1046
+ schedule,
1047
+ "cronGet",
1048
+ name,
1049
+ );
1050
+ }
1051
+
1052
+ async actorCronList(ctx: ActorContextHandle) {
1053
+ const schedule = childHandle(asWasmActorContext(ctx), "schedule");
1054
+ return await callHandleAsync<RuntimeCronJobInfo[]>(
1055
+ schedule,
1056
+ "cronList",
1057
+ );
1058
+ }
1059
+
1060
+ async actorCronDelete(ctx: ActorContextHandle, name: string) {
1061
+ const schedule = childHandle(asWasmActorContext(ctx), "schedule");
1062
+ return await callHandleAsync<boolean>(schedule, "cronDelete", name);
1063
+ }
1064
+
1065
+ async actorCronHistory(
1066
+ ctx: ActorContextHandle,
1067
+ name: string,
1068
+ limit: number | undefined,
1069
+ ) {
1070
+ const schedule = childHandle(asWasmActorContext(ctx), "schedule");
1071
+ return await callHandleAsync<RuntimeCronFire[]>(
1072
+ schedule,
1073
+ "cronHistory",
1074
+ name,
1075
+ limit,
1076
+ );
866
1077
  }
867
1078
 
868
1079
  connId(conn: ConnHandle): string {
package/src/utils.ts CHANGED
@@ -10,6 +10,9 @@ export { stringifyError };
10
10
  /** @experimental */
11
11
  export { assertUnreachable };
12
12
 
13
+ /** @experimental */
14
+ export { jsonParseCompat, jsonStringifyCompat } from "./common/encoding";
15
+
13
16
  /**
14
17
  * Joins multiple abort signals into one.
15
18
  *
@@ -17,8 +17,8 @@ import type {
17
17
  QueueNextBatchOptions,
18
18
  QueueNextOptions,
19
19
  QueueResultMessageForName,
20
+ RunContext,
20
21
  } from "@/actor/config";
21
- import { RAW_STATE_SYMBOL, type RunContext } from "@/actor/config";
22
22
  import type {
23
23
  AnyActorDefinition,
24
24
  BaseActorDefinition,
@@ -469,7 +469,6 @@ export class WorkflowContext<
469
469
  TEvents,
470
470
  TQueues
471
471
  >;
472
-
473
472
  constructor(
474
473
  inner: WorkflowContextInterface,
475
474
  runCtx: RunContext<
@@ -968,9 +967,9 @@ export class WorkflowContext<
968
967
  return this.#inner.isEvicted();
969
968
  }
970
969
 
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.
970
+ // Runs a user step body inside a fresh step context and deactivates the step
971
+ // context once the body settles. Workflows are roll-forward only, so state and
972
+ // vars mutations made before a failure always remain visible.
974
973
  async #runStep<T>(
975
974
  run: WorkflowStepRun<
976
975
  T,
@@ -995,28 +994,8 @@ export class WorkflowContext<
995
994
  TQueues
996
995
  >(this.#runCtx, () => this.#markGuardTriggered());
997
996
 
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);
1011
-
1012
997
  try {
1013
998
  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
999
  } finally {
1021
1000
  stepCtx[DEACTIVATE_STEP]();
1022
1001
  }
@@ -1040,8 +1019,7 @@ export class WorkflowContext<
1040
1019
  };
1041
1020
  }
1042
1021
 
1043
- // Runs a step rollback compensation with an active step context. Rollbacks
1044
- // intentionally mutate actor state, so their writes are not snapshotted.
1022
+ // Runs a step rollback compensation with an active step context.
1045
1023
  async #runRollback<T>(
1046
1024
  rollback: WorkflowStepRollback<
1047
1025
  T,
@@ -0,0 +1,62 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { ActorWorkflowDriver, chunkWorkflowWrites } from "./driver";
3
+
4
+ function write(keyBytes: number, valueBytes: number) {
5
+ return {
6
+ key: new Uint8Array(keyBytes),
7
+ value: new Uint8Array(valueBytes),
8
+ };
9
+ }
10
+
11
+ describe("workflow sqlite batching", () => {
12
+ test.each([
13
+ [127, 1],
14
+ [128, 1],
15
+ [129, 2],
16
+ ])("chunks %i rows into %i transaction(s)", (rowCount, chunkCount) => {
17
+ const chunks = chunkWorkflowWrites(
18
+ Array.from({ length: rowCount }, () => write(1, 1)),
19
+ );
20
+ expect(chunks).toHaveLength(chunkCount);
21
+ expect(chunks.flat()).toHaveLength(rowCount);
22
+ expect(chunks.every((chunk) => chunk.length <= 128)).toBe(true);
23
+ });
24
+
25
+ test("splits immediately above the 512 KiB payload budget", () => {
26
+ // Each persisted key also includes the two-byte workflow namespace.
27
+ const exact = [write(1, 256 * 1024 - 3), write(1, 256 * 1024 - 3)];
28
+ expect(chunkWorkflowWrites(exact)).toHaveLength(1);
29
+
30
+ const over = [write(1, 256 * 1024 - 3), write(1, 256 * 1024 - 2)];
31
+ expect(chunkWorkflowWrites(over)).toHaveLength(2);
32
+ });
33
+
34
+ test("delegates actor state and the whole workflow batch to one atomic runtime call", async () => {
35
+ let receivedWrites: Array<{ key: Uint8Array; value: Uint8Array }> = [];
36
+ const sql = {
37
+ query: async () => ({ columns: [], rows: [] }),
38
+ execute: async () => [],
39
+ run: async () => ({ changes: 0 }),
40
+ executeBatch: async () => [],
41
+ };
42
+ const actor = {
43
+ stateManager: {
44
+ saveStateAndWorkflowBatch: async (
45
+ writes: Array<{ key: Uint8Array; value: Uint8Array }>,
46
+ ) => {
47
+ receivedWrites = writes;
48
+ },
49
+ },
50
+ queueManager: {},
51
+ };
52
+ const runCtx = {
53
+ sql,
54
+ internalKeepAwake: async <T>(promise: Promise<T>) => await promise,
55
+ };
56
+ const driver = new ActorWorkflowDriver(actor as never, runCtx as never);
57
+ const writes = [write(1, 1), write(2, 2)];
58
+ await driver.batch(writes);
59
+ expect(driver.atomicBatch).toBe(true);
60
+ expect(receivedWrites).toBe(writes);
61
+ });
62
+ });