rivetkit 2.1.4 → 2.1.6-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 (333) hide show
  1. package/dist/browser/client.d.ts +593 -588
  2. package/dist/browser/client.js +215 -35
  3. package/dist/browser/client.js.map +1 -1
  4. package/dist/browser/inspector/client.js +109 -10
  5. package/dist/browser/inspector/client.js.map +1 -1
  6. package/dist/inspector.tar.gz +0 -0
  7. package/dist/tsup/actor/errors.cjs +2 -2
  8. package/dist/tsup/actor/errors.js +1 -1
  9. package/dist/tsup/{actor-router-consts-D29T1Z-K.d.cts → actor-router-consts-DU-1IdQj.d.cts} +1 -1
  10. package/dist/tsup/{actor-router-consts-D29T1Z-K.d.ts → actor-router-consts-DU-1IdQj.d.ts} +1 -1
  11. package/dist/tsup/chunk-2ELYUO6C.cjs +112 -0
  12. package/dist/tsup/chunk-2ELYUO6C.cjs.map +1 -0
  13. package/dist/tsup/chunk-2LY7RW3Y.cjs +2316 -0
  14. package/dist/tsup/chunk-2LY7RW3Y.cjs.map +1 -0
  15. package/dist/tsup/{chunk-L47L3ZWJ.cjs → chunk-6G7ZNM27.cjs} +11 -6
  16. package/dist/tsup/chunk-6G7ZNM27.cjs.map +1 -0
  17. package/dist/tsup/{chunk-LK36OGGO.cjs → chunk-A4KEUCB6.cjs} +84 -34
  18. package/dist/tsup/chunk-A4KEUCB6.cjs.map +1 -0
  19. package/dist/tsup/{chunk-7HTNH26M.js → chunk-AKUJ5OTO.js} +11 -6
  20. package/dist/tsup/chunk-AKUJ5OTO.js.map +1 -0
  21. package/dist/tsup/{chunk-ANKZ2FS6.js → chunk-C22JYHVT.js} +77 -27
  22. package/dist/tsup/chunk-C22JYHVT.js.map +1 -0
  23. package/dist/tsup/chunk-C4EB42ET.js +1459 -0
  24. package/dist/tsup/chunk-C4EB42ET.js.map +1 -0
  25. package/dist/tsup/chunk-CGGGBIDP.cjs +1459 -0
  26. package/dist/tsup/chunk-CGGGBIDP.cjs.map +1 -0
  27. package/dist/tsup/chunk-CMQPDBBR.cjs +1486 -0
  28. package/dist/tsup/chunk-CMQPDBBR.cjs.map +1 -0
  29. package/dist/tsup/{chunk-AQD4CBZ2.cjs → chunk-DH6UINWA.cjs} +4 -4
  30. package/dist/tsup/{chunk-AQD4CBZ2.cjs.map → chunk-DH6UINWA.cjs.map} +1 -1
  31. package/dist/tsup/chunk-DK46YYCJ.js +1486 -0
  32. package/dist/tsup/chunk-DK46YYCJ.js.map +1 -0
  33. package/dist/tsup/chunk-EGWXXBZV.js +2316 -0
  34. package/dist/tsup/chunk-EGWXXBZV.js.map +1 -0
  35. package/dist/tsup/{chunk-HBYEYBIC.js → chunk-EONWXYMN.js} +2 -2
  36. package/dist/tsup/{chunk-N4KRDJ56.js → chunk-GFGRBYO2.js} +35 -6
  37. package/dist/tsup/chunk-GFGRBYO2.js.map +1 -0
  38. package/dist/tsup/{chunk-TEUL4UYN.cjs → chunk-GUHXWPGB.cjs} +1515 -1479
  39. package/dist/tsup/chunk-GUHXWPGB.cjs.map +1 -0
  40. package/dist/tsup/{chunk-3B6PCYJB.cjs → chunk-HNE2AK6C.cjs} +2375 -3713
  41. package/dist/tsup/chunk-HNE2AK6C.cjs.map +1 -0
  42. package/dist/tsup/{chunk-5UEFNG7P.js → chunk-I5I6OALK.js} +2 -2
  43. package/dist/tsup/chunk-IHQAF2HV.cjs +23 -0
  44. package/dist/tsup/chunk-IHQAF2HV.cjs.map +1 -0
  45. package/dist/tsup/{chunk-UWAGLDT6.cjs → chunk-JJNZQDUN.cjs} +667 -2517
  46. package/dist/tsup/chunk-JJNZQDUN.cjs.map +1 -0
  47. package/dist/tsup/{chunk-M6H4XIF4.js → chunk-JJSPHLJN.js} +219 -287
  48. package/dist/tsup/chunk-JJSPHLJN.js.map +1 -0
  49. package/dist/tsup/chunk-JRKPV5NJ.js +481 -0
  50. package/dist/tsup/chunk-JRKPV5NJ.js.map +1 -0
  51. package/dist/tsup/{chunk-VKVNIQRQ.js → chunk-K7MVU5SI.js} +36 -41
  52. package/dist/tsup/chunk-K7MVU5SI.js.map +1 -0
  53. package/dist/tsup/{chunk-KJSYAUOM.js → chunk-MLK3GY6P.js} +43 -27
  54. package/dist/tsup/chunk-MLK3GY6P.js.map +1 -0
  55. package/dist/tsup/{chunk-4KSHPFXF.cjs → chunk-MPLMTJY5.cjs} +123 -23
  56. package/dist/tsup/chunk-MPLMTJY5.cjs.map +1 -0
  57. package/dist/tsup/{chunk-UDMRZR6A.js → chunk-PQWI44WD.js} +1755 -3093
  58. package/dist/tsup/chunk-PQWI44WD.js.map +1 -0
  59. package/dist/tsup/{chunk-SR3KQE7Q.cjs → chunk-SQFCIDCG.cjs} +35 -6
  60. package/dist/tsup/chunk-SQFCIDCG.cjs.map +1 -0
  61. package/dist/tsup/{chunk-3GTO6H3E.js → chunk-SVHJSM2E.js} +110 -24
  62. package/dist/tsup/chunk-SVHJSM2E.js.map +1 -0
  63. package/dist/tsup/chunk-T5KYKM6R.js +49 -0
  64. package/dist/tsup/chunk-T5KYKM6R.js.map +1 -0
  65. package/dist/tsup/{chunk-GXRVSSVD.cjs → chunk-TJ7DKW6F.cjs} +123 -37
  66. package/dist/tsup/chunk-TJ7DKW6F.cjs.map +1 -0
  67. package/dist/tsup/chunk-UQZRMTM3.js +23 -0
  68. package/dist/tsup/chunk-UQZRMTM3.js.map +1 -0
  69. package/dist/tsup/{chunk-QPADHLDU.cjs → chunk-V3JSZR5P.cjs} +3 -3
  70. package/dist/tsup/{chunk-QPADHLDU.cjs.map → chunk-V3JSZR5P.cjs.map} +1 -1
  71. package/dist/tsup/{chunk-HKOSZKKZ.cjs → chunk-VBR35EQF.cjs} +271 -339
  72. package/dist/tsup/chunk-VBR35EQF.cjs.map +1 -0
  73. package/dist/tsup/{chunk-DZXDUGLL.js → chunk-VWYO36X4.js} +117 -17
  74. package/dist/tsup/chunk-VWYO36X4.js.map +1 -0
  75. package/dist/tsup/{chunk-I6PL6QIY.js → chunk-WW27B6DM.js} +1452 -1416
  76. package/dist/tsup/chunk-WW27B6DM.js.map +1 -0
  77. package/dist/tsup/chunk-YAE3MEJM.cjs +49 -0
  78. package/dist/tsup/chunk-YAE3MEJM.cjs.map +1 -0
  79. package/dist/tsup/{chunk-KTWY3K6Z.js → chunk-YGYGANCA.js} +473 -2323
  80. package/dist/tsup/chunk-YGYGANCA.js.map +1 -0
  81. package/dist/tsup/chunk-YZJWZBY5.cjs +481 -0
  82. package/dist/tsup/chunk-YZJWZBY5.cjs.map +1 -0
  83. package/dist/tsup/{chunk-ZFY5J2EP.cjs → chunk-ZZLJ5TSM.cjs} +39 -44
  84. package/dist/tsup/chunk-ZZLJ5TSM.cjs.map +1 -0
  85. package/dist/tsup/client/mod.cjs +10 -7
  86. package/dist/tsup/client/mod.cjs.map +1 -1
  87. package/dist/tsup/client/mod.d.cts +6 -6
  88. package/dist/tsup/client/mod.d.ts +6 -6
  89. package/dist/tsup/client/mod.js +11 -8
  90. package/dist/tsup/common/log.cjs +3 -3
  91. package/dist/tsup/common/log.js +2 -2
  92. package/dist/tsup/common/websocket.cjs +4 -4
  93. package/dist/tsup/common/websocket.js +3 -3
  94. package/dist/tsup/{config-Qj-zLJPc.d.ts → config-C2Wwnc69.d.ts} +142 -208
  95. package/dist/tsup/{config-BiNoIHRs.d.ts → config-DROwzBLT.d.cts} +82 -6
  96. package/dist/tsup/{config-BiNoIHRs.d.cts → config-DROwzBLT.d.ts} +82 -6
  97. package/dist/tsup/{config-iPj5l1bL.d.cts → config-ehT-_3BB.d.cts} +142 -208
  98. package/dist/tsup/{context-DzvH1PBK.d.cts → context-DGMJuAyc.d.ts} +16 -3
  99. package/dist/tsup/{context-CQCMuHND.d.ts → context-Dpp2RJbW.d.cts} +16 -3
  100. package/dist/tsup/db/drizzle/mod.cjs +3 -3
  101. package/dist/tsup/db/drizzle/mod.d.cts +1 -1
  102. package/dist/tsup/db/drizzle/mod.d.ts +1 -1
  103. package/dist/tsup/db/drizzle/mod.js +2 -2
  104. package/dist/tsup/db/mod.cjs +3 -3
  105. package/dist/tsup/db/mod.d.cts +1 -1
  106. package/dist/tsup/db/mod.d.ts +1 -1
  107. package/dist/tsup/db/mod.js +2 -2
  108. package/dist/tsup/{driver-Jo8v-kbU.d.ts → driver-CYZP9QYo.d.ts} +1 -1
  109. package/dist/tsup/{driver-iV8J-WMv.d.cts → driver-CoTFpipv.d.cts} +1 -1
  110. package/dist/tsup/driver-helpers/mod.cjs +7 -5
  111. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  112. package/dist/tsup/driver-helpers/mod.d.cts +17 -18
  113. package/dist/tsup/driver-helpers/mod.d.ts +17 -18
  114. package/dist/tsup/driver-helpers/mod.js +11 -9
  115. package/dist/tsup/driver-test-suite/mod.cjs +1275 -228
  116. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  117. package/dist/tsup/driver-test-suite/mod.d.cts +6 -5
  118. package/dist/tsup/driver-test-suite/mod.d.ts +6 -5
  119. package/dist/tsup/driver-test-suite/mod.js +1581 -534
  120. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  121. package/dist/tsup/inspector/mod.cjs +4 -4
  122. package/dist/tsup/inspector/mod.js +3 -3
  123. package/dist/tsup/mod.cjs +15 -9
  124. package/dist/tsup/mod.cjs.map +1 -1
  125. package/dist/tsup/mod.d.cts +9 -9
  126. package/dist/tsup/mod.d.ts +9 -9
  127. package/dist/tsup/mod.js +19 -13
  128. package/dist/tsup/sandbox/client.cjs +28 -0
  129. package/dist/tsup/sandbox/client.cjs.map +1 -0
  130. package/dist/tsup/sandbox/client.d.cts +88 -0
  131. package/dist/tsup/sandbox/client.d.ts +88 -0
  132. package/dist/tsup/sandbox/client.js +28 -0
  133. package/dist/tsup/sandbox/client.js.map +1 -0
  134. package/dist/tsup/sandbox/index.cjs +761 -0
  135. package/dist/tsup/sandbox/index.cjs.map +1 -0
  136. package/dist/tsup/sandbox/index.d.cts +120 -0
  137. package/dist/tsup/sandbox/index.d.ts +120 -0
  138. package/dist/tsup/sandbox/index.js +761 -0
  139. package/dist/tsup/sandbox/index.js.map +1 -0
  140. package/dist/tsup/sandbox/providers/computesdk.cjs +3 -0
  141. package/dist/tsup/sandbox/providers/computesdk.cjs.map +1 -0
  142. package/dist/tsup/sandbox/providers/computesdk.d.cts +7 -0
  143. package/dist/tsup/sandbox/providers/computesdk.d.ts +7 -0
  144. package/dist/tsup/sandbox/providers/computesdk.js +3 -0
  145. package/dist/tsup/sandbox/providers/computesdk.js.map +1 -0
  146. package/dist/tsup/sandbox/providers/daytona.cjs +3 -0
  147. package/dist/tsup/sandbox/providers/daytona.cjs.map +1 -0
  148. package/dist/tsup/sandbox/providers/daytona.d.cts +1 -0
  149. package/dist/tsup/sandbox/providers/daytona.d.ts +1 -0
  150. package/dist/tsup/sandbox/providers/daytona.js +3 -0
  151. package/dist/tsup/sandbox/providers/daytona.js.map +1 -0
  152. package/dist/tsup/sandbox/providers/docker.cjs +3 -0
  153. package/dist/tsup/sandbox/providers/docker.cjs.map +1 -0
  154. package/dist/tsup/sandbox/providers/docker.d.cts +1 -0
  155. package/dist/tsup/sandbox/providers/docker.d.ts +1 -0
  156. package/dist/tsup/sandbox/providers/docker.js +3 -0
  157. package/dist/tsup/sandbox/providers/docker.js.map +1 -0
  158. package/dist/tsup/sandbox/providers/e2b.cjs +3 -0
  159. package/dist/tsup/sandbox/providers/e2b.cjs.map +1 -0
  160. package/dist/tsup/sandbox/providers/e2b.d.cts +1 -0
  161. package/dist/tsup/sandbox/providers/e2b.d.ts +1 -0
  162. package/dist/tsup/sandbox/providers/e2b.js +3 -0
  163. package/dist/tsup/sandbox/providers/e2b.js.map +1 -0
  164. package/dist/tsup/sandbox/providers/local.cjs +3 -0
  165. package/dist/tsup/sandbox/providers/local.cjs.map +1 -0
  166. package/dist/tsup/sandbox/providers/local.d.cts +1 -0
  167. package/dist/tsup/sandbox/providers/local.d.ts +1 -0
  168. package/dist/tsup/sandbox/providers/local.js +3 -0
  169. package/dist/tsup/sandbox/providers/local.js.map +1 -0
  170. package/dist/tsup/sandbox/providers/modal.cjs +3 -0
  171. package/dist/tsup/sandbox/providers/modal.cjs.map +1 -0
  172. package/dist/tsup/sandbox/providers/modal.d.cts +1 -0
  173. package/dist/tsup/sandbox/providers/modal.d.ts +1 -0
  174. package/dist/tsup/sandbox/providers/modal.js +3 -0
  175. package/dist/tsup/sandbox/providers/modal.js.map +1 -0
  176. package/dist/tsup/sandbox/providers/vercel.cjs +3 -0
  177. package/dist/tsup/sandbox/providers/vercel.cjs.map +1 -0
  178. package/dist/tsup/sandbox/providers/vercel.d.cts +1 -0
  179. package/dist/tsup/sandbox/providers/vercel.d.ts +1 -0
  180. package/dist/tsup/sandbox/providers/vercel.js +3 -0
  181. package/dist/tsup/sandbox/providers/vercel.js.map +1 -0
  182. package/dist/tsup/serve-test-suite/mod.cjs +451 -327
  183. package/dist/tsup/serve-test-suite/mod.cjs.map +1 -1
  184. package/dist/tsup/serve-test-suite/mod.js +362 -238
  185. package/dist/tsup/serve-test-suite/mod.js.map +1 -1
  186. package/dist/tsup/test/mod.cjs +17 -14
  187. package/dist/tsup/test/mod.cjs.map +1 -1
  188. package/dist/tsup/test/mod.d.cts +4 -4
  189. package/dist/tsup/test/mod.d.ts +4 -4
  190. package/dist/tsup/test/mod.js +14 -11
  191. package/dist/tsup/test/mod.js.map +1 -1
  192. package/dist/tsup/utils.cjs +3 -3
  193. package/dist/tsup/utils.js +2 -2
  194. package/dist/tsup/workflow/mod.cjs +6 -6
  195. package/dist/tsup/workflow/mod.d.cts +13 -9
  196. package/dist/tsup/workflow/mod.d.ts +13 -9
  197. package/dist/tsup/workflow/mod.js +5 -5
  198. package/package.json +113 -14
  199. package/src/actor/config.ts +94 -88
  200. package/src/actor/conn/drivers/websocket.ts +2 -1
  201. package/src/actor/contexts/base/actor.ts +27 -4
  202. package/src/actor/database.ts +6 -1
  203. package/src/actor/driver.ts +27 -8
  204. package/src/actor/errors.ts +10 -5
  205. package/src/actor/instance/connection-manager.ts +4 -3
  206. package/src/actor/instance/kv.ts +52 -9
  207. package/src/actor/instance/mod.ts +135 -84
  208. package/src/actor/instance/queue-manager.ts +2 -5
  209. package/src/actor/instance/queue.ts +31 -29
  210. package/src/actor/instance/state-manager.ts +7 -1
  211. package/src/actor/instance/traces-driver.ts +34 -36
  212. package/src/actor/metrics.ts +137 -0
  213. package/src/actor/protocol/old.ts +9 -12
  214. package/src/actor/router-websocket-endpoints.ts +12 -6
  215. package/src/actor/router.ts +46 -9
  216. package/src/actor/schema.ts +14 -22
  217. package/src/client/actor-common.ts +65 -0
  218. package/src/client/actor-conn.ts +71 -9
  219. package/src/client/actor-handle.ts +22 -5
  220. package/src/client/client.ts +32 -6
  221. package/src/client/config.ts +18 -21
  222. package/src/client/mod.ts +1 -0
  223. package/src/client/queue.ts +8 -6
  224. package/src/common/inline-websocket-adapter.ts +8 -2
  225. package/src/common/router.ts +1 -4
  226. package/src/common/utils.ts +2 -5
  227. package/src/db/config.ts +10 -5
  228. package/src/db/drizzle/mod.ts +51 -41
  229. package/src/db/mod.ts +54 -29
  230. package/src/db/shared.ts +42 -8
  231. package/src/driver-helpers/mod.ts +2 -1
  232. package/src/driver-helpers/sqlite-pool.ts +42 -0
  233. package/src/driver-helpers/utils.ts +0 -20
  234. package/src/driver-test-suite/mod.ts +11 -1
  235. package/src/driver-test-suite/tests/access-control.ts +19 -12
  236. package/src/driver-test-suite/tests/action-features.ts +20 -8
  237. package/src/driver-test-suite/tests/actor-conn.ts +94 -8
  238. package/src/driver-test-suite/tests/actor-db-kv-stats.ts +282 -0
  239. package/src/driver-test-suite/tests/actor-db-raw.ts +6 -2
  240. package/src/driver-test-suite/tests/actor-db.ts +101 -31
  241. package/src/driver-test-suite/tests/actor-inspector.ts +174 -32
  242. package/src/driver-test-suite/tests/actor-kv.ts +79 -33
  243. package/src/driver-test-suite/tests/actor-lifecycle.ts +4 -12
  244. package/src/driver-test-suite/tests/actor-queue.ts +125 -17
  245. package/src/driver-test-suite/tests/actor-run.ts +59 -55
  246. package/src/driver-test-suite/tests/actor-sandbox.ts +78 -0
  247. package/src/driver-test-suite/tests/actor-schedule.ts +1 -4
  248. package/src/driver-test-suite/tests/actor-sleep.ts +111 -0
  249. package/src/driver-test-suite/tests/actor-workflow.ts +387 -3
  250. package/src/driver-test-suite/tests/conn-error-serialization.ts +3 -1
  251. package/src/driver-test-suite/tests/raw-websocket.ts +5 -1
  252. package/src/drivers/default.ts +1 -3
  253. package/src/drivers/engine/actor-driver.ts +94 -21
  254. package/src/drivers/engine/config.ts +4 -12
  255. package/src/drivers/engine/mod.ts +1 -5
  256. package/src/drivers/file-system/actor.ts +43 -8
  257. package/src/drivers/file-system/global-state.ts +180 -64
  258. package/src/drivers/file-system/kv-limits.ts +1 -1
  259. package/src/drivers/file-system/sqlite-runtime.ts +13 -4
  260. package/src/engine-process/mod.ts +5 -1
  261. package/src/inspector/actor-inspector.ts +47 -21
  262. package/src/inspector/config.ts +1 -4
  263. package/src/inspector/mod.browser.ts +2 -2
  264. package/src/inspector/mod.ts +4 -1
  265. package/src/inspector/serve-ui.ts +0 -1
  266. package/src/inspector/workflow-history-json.ts +309 -0
  267. package/src/manager/gateway.ts +6 -2
  268. package/src/manager/router.ts +3 -3
  269. package/src/registry/config/index.ts +65 -12
  270. package/src/registry/config/runner.ts +19 -4
  271. package/src/registry/index.ts +42 -89
  272. package/src/sandbox/actor/db.ts +36 -0
  273. package/src/sandbox/actor/index.ts +476 -0
  274. package/src/sandbox/actor/session.ts +350 -0
  275. package/src/sandbox/actor.test.ts +36 -0
  276. package/src/sandbox/client.test.ts +484 -0
  277. package/src/sandbox/client.ts +707 -0
  278. package/src/sandbox/config.ts +151 -0
  279. package/src/sandbox/index.ts +41 -0
  280. package/src/sandbox/providers/computesdk.ts +1 -0
  281. package/src/sandbox/providers/daytona.ts +1 -0
  282. package/src/sandbox/providers/docker.ts +1 -0
  283. package/src/sandbox/providers/e2b.ts +1 -0
  284. package/src/sandbox/providers/local.ts +1 -0
  285. package/src/sandbox/providers/modal.ts +1 -0
  286. package/src/sandbox/providers/vercel.ts +1 -0
  287. package/src/sandbox/session-persist-driver.ts +180 -0
  288. package/src/sandbox/types.ts +138 -0
  289. package/src/serverless/configure.ts +5 -3
  290. package/src/serverless/router.test.ts +17 -9
  291. package/src/serverless/router.ts +20 -13
  292. package/src/test/mod.ts +3 -4
  293. package/src/utils/endpoint-parser.test.ts +6 -2
  294. package/src/utils/endpoint-parser.ts +6 -2
  295. package/src/utils/env-vars.ts +0 -2
  296. package/src/utils/node.ts +1 -1
  297. package/src/utils/serve.ts +10 -5
  298. package/src/utils.ts +6 -1
  299. package/src/workflow/constants.ts +1 -2
  300. package/src/workflow/context.ts +42 -9
  301. package/src/workflow/driver.ts +57 -23
  302. package/src/workflow/inspector.ts +7 -13
  303. package/src/workflow/mod.ts +91 -4
  304. package/dist/tsup/chunk-3B6PCYJB.cjs.map +0 -1
  305. package/dist/tsup/chunk-3GTO6H3E.js.map +0 -1
  306. package/dist/tsup/chunk-4KSHPFXF.cjs.map +0 -1
  307. package/dist/tsup/chunk-6LJAZ5R4.cjs +0 -96
  308. package/dist/tsup/chunk-6LJAZ5R4.cjs.map +0 -1
  309. package/dist/tsup/chunk-7HTNH26M.js.map +0 -1
  310. package/dist/tsup/chunk-ANKZ2FS6.js.map +0 -1
  311. package/dist/tsup/chunk-DZXDUGLL.js.map +0 -1
  312. package/dist/tsup/chunk-GXRVSSVD.cjs.map +0 -1
  313. package/dist/tsup/chunk-H5TSEPN4.cjs +0 -645
  314. package/dist/tsup/chunk-H5TSEPN4.cjs.map +0 -1
  315. package/dist/tsup/chunk-HKOSZKKZ.cjs.map +0 -1
  316. package/dist/tsup/chunk-I6PL6QIY.js.map +0 -1
  317. package/dist/tsup/chunk-KJSYAUOM.js.map +0 -1
  318. package/dist/tsup/chunk-KTWY3K6Z.js.map +0 -1
  319. package/dist/tsup/chunk-L47L3ZWJ.cjs.map +0 -1
  320. package/dist/tsup/chunk-LK36OGGO.cjs.map +0 -1
  321. package/dist/tsup/chunk-M6H4XIF4.js.map +0 -1
  322. package/dist/tsup/chunk-N4KRDJ56.js.map +0 -1
  323. package/dist/tsup/chunk-SR3KQE7Q.cjs.map +0 -1
  324. package/dist/tsup/chunk-TEFYRRAK.js +0 -645
  325. package/dist/tsup/chunk-TEFYRRAK.js.map +0 -1
  326. package/dist/tsup/chunk-TEUL4UYN.cjs.map +0 -1
  327. package/dist/tsup/chunk-UDMRZR6A.js.map +0 -1
  328. package/dist/tsup/chunk-UWAGLDT6.cjs.map +0 -1
  329. package/dist/tsup/chunk-VKVNIQRQ.js.map +0 -1
  330. package/dist/tsup/chunk-ZFY5J2EP.cjs.map +0 -1
  331. package/src/db/sqlite-vfs.ts +0 -12
  332. /package/dist/tsup/{chunk-HBYEYBIC.js.map → chunk-EONWXYMN.js.map} +0 -0
  333. /package/dist/tsup/{chunk-5UEFNG7P.js.map → chunk-I5I6OALK.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
- createClientWithDriver
3
- } from "./chunk-I6PL6QIY.js";
2
+ decodeWorkflowHistoryTransport
3
+ } from "./chunk-EONWXYMN.js";
4
4
  import {
5
5
  ACTOR_VERSIONED,
6
6
  ActionContext,
@@ -27,20 +27,11 @@ import {
27
27
  ToClientSchema,
28
28
  WebSocketContext,
29
29
  createHttpDriver,
30
- getInitialActorKvState,
31
- getNodeCrypto,
32
- getNodeFs,
33
- getNodeFsSync,
34
- getNodeOs,
35
- getNodePath,
36
- getRequireFn,
37
30
  handleAction,
38
31
  handleQueueSend,
39
32
  handleRawRequest,
40
33
  handleRouteError,
41
34
  handleRouteNotFound,
42
- importNodeDependencies,
43
- importSqliteVfs,
44
35
  inspectorLogger,
45
36
  loggerMiddleware,
46
37
  parseWebSocketProtocols,
@@ -48,7 +39,7 @@ import {
48
39
  routeWebSocket,
49
40
  serializeActorKey,
50
41
  timingSafeEqual
51
- } from "./chunk-UDMRZR6A.js";
42
+ } from "./chunk-PQWI44WD.js";
52
43
  import {
53
44
  ActorContext,
54
45
  DeadlineError,
@@ -69,7 +60,7 @@ import {
69
60
  queueMessagesPrefix,
70
61
  queueMetadataKey,
71
62
  tracesStoragePrefix
72
- } from "./chunk-ANKZ2FS6.js";
63
+ } from "./chunk-C22JYHVT.js";
73
64
  import {
74
65
  EXTRA_ERROR_LOG,
75
66
  SinglePromiseQueue,
@@ -78,21 +69,17 @@ import {
78
69
  bufferToArrayBuffer,
79
70
  getBaseLogger,
80
71
  getIncludeTarget,
81
- getLogger,
82
72
  getRivetExperimentalOtel,
83
73
  isCborSerializable,
84
74
  isDev,
85
75
  noopNext,
86
76
  promiseWithResolvers,
87
- setLongTimeout,
88
77
  stringifyError
89
- } from "./chunk-DZXDUGLL.js";
78
+ } from "./chunk-VWYO36X4.js";
90
79
  import {
91
80
  ActionNotFound,
92
81
  ActionTimedOut,
93
82
  ActorAborted,
94
- ActorDuplicateKey,
95
- ActorStopping,
96
83
  DatabaseNotEnabled,
97
84
  Forbidden,
98
85
  InternalError,
@@ -107,18 +94,255 @@ import {
107
94
  RequestHandlerNotDefined,
108
95
  StateNotEnabled,
109
96
  VarsNotEnabled
110
- } from "./chunk-7HTNH26M.js";
97
+ } from "./chunk-AKUJ5OTO.js";
111
98
 
112
99
  // src/actor/instance/mod.ts
113
100
  import {
114
101
  createNoopTraces,
115
102
  createTraces
116
103
  } from "@rivetkit/traces";
104
+
105
+ // src/actor/metrics.ts
106
+ var ActorMetrics = class {
107
+ // KV operations
108
+ kvGet = { calls: 0, keys: 0, totalMs: 0 };
109
+ kvGetBatch = { calls: 0, keys: 0, totalMs: 0 };
110
+ kvPut = { calls: 0, keys: 0, totalMs: 0 };
111
+ kvPutBatch = { calls: 0, keys: 0, totalMs: 0 };
112
+ kvDeleteBatch = { calls: 0, keys: 0, totalMs: 0 };
113
+ // SQL statements
114
+ sqlSelects = 0;
115
+ sqlInserts = 0;
116
+ sqlUpdates = 0;
117
+ sqlDeletes = 0;
118
+ sqlOther = 0;
119
+ sqlTotalMs = 0;
120
+ // Actions
121
+ actionCalls = 0;
122
+ actionErrors = 0;
123
+ actionTotalMs = 0;
124
+ // Connections
125
+ connectionsOpened = 0;
126
+ connectionsClosed = 0;
127
+ trackSql(query, durationMs) {
128
+ const token = query.trimStart().slice(0, 8).toUpperCase();
129
+ if (token.startsWith("SELECT") || token.startsWith("PRAGMA") || token.startsWith("WITH")) {
130
+ this.sqlSelects++;
131
+ } else if (token.startsWith("INSERT")) {
132
+ this.sqlInserts++;
133
+ } else if (token.startsWith("UPDATE")) {
134
+ this.sqlUpdates++;
135
+ } else if (token.startsWith("DELETE")) {
136
+ this.sqlDeletes++;
137
+ } else {
138
+ this.sqlOther++;
139
+ }
140
+ this.sqlTotalMs += durationMs;
141
+ }
142
+ snapshot() {
143
+ return {
144
+ kv_operations: {
145
+ type: "labeled_timing",
146
+ help: "KV round trips by operation type",
147
+ values: {
148
+ get: { ...this.kvGet },
149
+ getBatch: { ...this.kvGetBatch },
150
+ put: { ...this.kvPut },
151
+ putBatch: { ...this.kvPutBatch },
152
+ deleteBatch: { ...this.kvDeleteBatch }
153
+ }
154
+ },
155
+ sql_statements: {
156
+ type: "labeled_counter",
157
+ help: "SQL statements executed by type",
158
+ values: {
159
+ select: this.sqlSelects,
160
+ insert: this.sqlInserts,
161
+ update: this.sqlUpdates,
162
+ delete: this.sqlDeletes,
163
+ other: this.sqlOther
164
+ }
165
+ },
166
+ sql_duration_ms: {
167
+ type: "counter",
168
+ help: "Total SQL execution time in milliseconds",
169
+ value: this.sqlTotalMs
170
+ },
171
+ action_calls: {
172
+ type: "counter",
173
+ help: "Total action invocations",
174
+ value: this.actionCalls
175
+ },
176
+ action_errors: {
177
+ type: "counter",
178
+ help: "Total action errors",
179
+ value: this.actionErrors
180
+ },
181
+ action_duration_ms: {
182
+ type: "counter",
183
+ help: "Total action execution time in milliseconds",
184
+ value: this.actionTotalMs
185
+ },
186
+ connections_opened: {
187
+ type: "counter",
188
+ help: "Total WebSocket connections opened",
189
+ value: this.connectionsOpened
190
+ },
191
+ connections_closed: {
192
+ type: "counter",
193
+ help: "Total WebSocket connections closed",
194
+ value: this.connectionsClosed
195
+ }
196
+ };
197
+ }
198
+ };
199
+
200
+ // src/actor/instance/mod.ts
117
201
  import invariant2 from "invariant";
118
202
 
119
203
  // src/inspector/actor-inspector.ts
120
- import * as cbor from "cbor-x";
204
+ import * as cbor2 from "cbor-x";
121
205
  import { createNanoEvents } from "nanoevents";
206
+
207
+ // src/inspector/workflow-history-json.ts
208
+ import * as cbor from "cbor-x";
209
+ function decodeWorkflowCbor(data) {
210
+ if (data === null) {
211
+ return null;
212
+ }
213
+ try {
214
+ return cbor.decode(new Uint8Array(data));
215
+ } catch {
216
+ return null;
217
+ }
218
+ }
219
+ function serializeWorkflowLocation(location) {
220
+ return location.map((segment) => {
221
+ if (segment.tag === "WorkflowNameIndex") {
222
+ return {
223
+ tag: segment.tag,
224
+ val: segment.val
225
+ };
226
+ }
227
+ return {
228
+ tag: segment.tag,
229
+ val: {
230
+ loop: segment.val.loop,
231
+ iteration: segment.val.iteration
232
+ }
233
+ };
234
+ });
235
+ }
236
+ function serializeWorkflowBranches(branches) {
237
+ return Object.fromEntries(
238
+ Array.from(branches.entries()).map(([name, branch]) => [
239
+ name,
240
+ {
241
+ status: branch.status,
242
+ output: decodeWorkflowCbor(branch.output),
243
+ error: branch.error
244
+ }
245
+ ])
246
+ );
247
+ }
248
+ function serializeWorkflowEntryKind(kind) {
249
+ switch (kind.tag) {
250
+ case "WorkflowStepEntry":
251
+ return {
252
+ tag: kind.tag,
253
+ val: {
254
+ output: decodeWorkflowCbor(kind.val.output),
255
+ error: kind.val.error
256
+ }
257
+ };
258
+ case "WorkflowLoopEntry":
259
+ return {
260
+ tag: kind.tag,
261
+ val: {
262
+ state: decodeWorkflowCbor(kind.val.state),
263
+ iteration: kind.val.iteration,
264
+ output: decodeWorkflowCbor(kind.val.output)
265
+ }
266
+ };
267
+ case "WorkflowSleepEntry":
268
+ return {
269
+ tag: kind.tag,
270
+ val: {
271
+ deadline: Number(kind.val.deadline),
272
+ state: kind.val.state
273
+ }
274
+ };
275
+ case "WorkflowMessageEntry":
276
+ return {
277
+ tag: kind.tag,
278
+ val: {
279
+ name: kind.val.name,
280
+ messageData: decodeWorkflowCbor(kind.val.messageData)
281
+ }
282
+ };
283
+ case "WorkflowRollbackCheckpointEntry":
284
+ return {
285
+ tag: kind.tag,
286
+ val: {
287
+ name: kind.val.name
288
+ }
289
+ };
290
+ case "WorkflowJoinEntry":
291
+ return {
292
+ tag: kind.tag,
293
+ val: {
294
+ branches: serializeWorkflowBranches(kind.val.branches)
295
+ }
296
+ };
297
+ case "WorkflowRaceEntry":
298
+ return {
299
+ tag: kind.tag,
300
+ val: {
301
+ winner: kind.val.winner,
302
+ branches: serializeWorkflowBranches(kind.val.branches)
303
+ }
304
+ };
305
+ case "WorkflowRemovedEntry":
306
+ return {
307
+ tag: kind.tag,
308
+ val: {
309
+ originalType: kind.val.originalType,
310
+ originalName: kind.val.originalName
311
+ }
312
+ };
313
+ }
314
+ }
315
+ function serializeWorkflowHistoryForJson(data) {
316
+ if (data === null) {
317
+ return null;
318
+ }
319
+ const history = decodeWorkflowHistoryTransport(data);
320
+ return {
321
+ nameRegistry: [...history.nameRegistry],
322
+ entries: history.entries.map((entry) => ({
323
+ id: entry.id,
324
+ location: serializeWorkflowLocation(entry.location),
325
+ kind: serializeWorkflowEntryKind(entry.kind)
326
+ })),
327
+ entryMetadata: Object.fromEntries(
328
+ Array.from(history.entryMetadata.entries()).map(([entryId, meta]) => [
329
+ entryId,
330
+ {
331
+ status: meta.status,
332
+ error: meta.error,
333
+ attempts: meta.attempts,
334
+ lastAttemptAt: Number(meta.lastAttemptAt),
335
+ createdAt: Number(meta.createdAt),
336
+ completedAt: meta.completedAt === null ? null : Number(meta.completedAt),
337
+ rollbackCompletedAt: meta.rollbackCompletedAt === null ? null : Number(meta.rollbackCompletedAt),
338
+ rollbackError: meta.rollbackError
339
+ }
340
+ ])
341
+ )
342
+ };
343
+ }
344
+
345
+ // src/inspector/actor-inspector.ts
122
346
  var ActorInspector = class {
123
347
  constructor(actor) {
124
348
  this.actor = actor;
@@ -145,9 +369,7 @@ var ActorInspector = class {
145
369
  const maxSize = this.actor.config.options.maxQueueSize;
146
370
  const safeLimit = Math.max(0, Math.floor(limit));
147
371
  const messages = await this.actor.queueManager.getMessages();
148
- const sorted = messages.sort(
149
- (a, b) => a.createdAt - b.createdAt
150
- );
372
+ const sorted = messages.sort((a, b) => a.createdAt - b.createdAt);
151
373
  const limited = safeLimit > 0 ? sorted.slice(0, safeLimit) : [];
152
374
  return {
153
375
  size: BigInt(this.#lastQueueSize),
@@ -218,7 +440,7 @@ var ActorInspector = class {
218
440
  records: ((_a = countResult == null ? void 0 : countResult[0]) == null ? void 0 : _a.count) ?? 0
219
441
  });
220
442
  }
221
- return bufferToArrayBuffer(cbor.encode({ tables: tableInfos }));
443
+ return bufferToArrayBuffer(cbor2.encode({ tables: tableInfos }));
222
444
  }
223
445
  async getDatabaseTableRows(table, limit, offset) {
224
446
  if (!this.isDatabaseEnabled()) {
@@ -233,7 +455,7 @@ var ActorInspector = class {
233
455
  safeLimit,
234
456
  safeOffset
235
457
  );
236
- return bufferToArrayBuffer(cbor.encode(result));
458
+ return bufferToArrayBuffer(cbor2.encode(result));
237
459
  }
238
460
  isStateEnabled() {
239
461
  return this.actor.stateEnabled;
@@ -243,7 +465,7 @@ var ActorInspector = class {
243
465
  throw new StateNotEnabled();
244
466
  }
245
467
  return bufferToArrayBuffer(
246
- cbor.encode(this.actor.stateManager.persistRaw.state)
468
+ cbor2.encode(this.actor.stateManager.persistRaw.state)
247
469
  );
248
470
  }
249
471
  getRpcs() {
@@ -259,7 +481,7 @@ var ActorInspector = class {
259
481
  type: (_a = conn[CONN_DRIVER_SYMBOL]) == null ? void 0 : _a.type,
260
482
  id,
261
483
  details: bufferToArrayBuffer(
262
- cbor.encode({
484
+ cbor2.encode({
263
485
  type: (_b = conn[CONN_DRIVER_SYMBOL]) == null ? void 0 : _b.type,
264
486
  params: conn.params,
265
487
  stateEnabled: connStateManager.stateEnabled,
@@ -277,7 +499,7 @@ var ActorInspector = class {
277
499
  if (!this.actor.stateEnabled) {
278
500
  throw new StateNotEnabled();
279
501
  }
280
- this.actor.stateManager.state = cbor.decode(Buffer.from(state));
502
+ this.actor.stateManager.state = cbor2.decode(Buffer.from(state));
281
503
  await this.actor.stateManager.saveState({ immediate: true });
282
504
  }
283
505
  async executeAction(name, params) {
@@ -291,11 +513,11 @@ var ActorInspector = class {
291
513
  );
292
514
  try {
293
515
  return bufferToArrayBuffer(
294
- cbor.encode(
516
+ cbor2.encode(
295
517
  await this.actor.executeAction(
296
518
  new ActionContext(this.actor, conn),
297
519
  name,
298
- cbor.decode(Buffer.from(params))
520
+ cbor2.decode(Buffer.from(params))
299
521
  )
300
522
  )
301
523
  );
@@ -318,6 +540,20 @@ var ActorInspector = class {
318
540
  this.actor.stateManager.state = state;
319
541
  await this.actor.stateManager.saveState({ immediate: true });
320
542
  }
543
+ async getDatabaseSchemaJson() {
544
+ return toHttpJsonCompatible(
545
+ cbor2.decode(Buffer.from(await this.getDatabaseSchema()))
546
+ );
547
+ }
548
+ async getDatabaseTableRowsJson(table, limit, offset) {
549
+ return toHttpJsonCompatible(
550
+ cbor2.decode(
551
+ Buffer.from(
552
+ await this.getDatabaseTableRows(table, limit, offset)
553
+ )
554
+ )
555
+ );
556
+ }
321
557
  getConnectionsJson() {
322
558
  return Array.from(
323
559
  this.actor.connectionManager.connections.entries()
@@ -361,11 +597,10 @@ var ActorInspector = class {
361
597
  return result;
362
598
  }
363
599
  getWorkflowHistoryJson() {
364
- const bigIntReplacer = (_key, value) => typeof value === "bigint" ? Number(value) : value;
365
- const history = this.getWorkflowHistory();
366
- const safeHistory = history ? JSON.parse(JSON.stringify(history, bigIntReplacer)) : null;
367
600
  return {
368
- history: safeHistory,
601
+ history: serializeWorkflowHistoryForJson(
602
+ this.getWorkflowHistory()
603
+ ),
369
604
  isWorkflowEnabled: this.isWorkflowEnabled()
370
605
  };
371
606
  }
@@ -385,14 +620,22 @@ var ActorInspector = class {
385
620
  function escapeDoubleQuotes(value) {
386
621
  return value.replace(/"/g, '""');
387
622
  }
623
+ function toHttpJsonCompatible(value) {
624
+ return JSON.parse(
625
+ JSON.stringify(
626
+ value,
627
+ (_key, nestedValue) => typeof nestedValue === "bigint" ? Number(nestedValue) : nestedValue instanceof Uint8Array ? Array.from(nestedValue) : nestedValue
628
+ )
629
+ );
630
+ }
388
631
 
389
632
  // src/actor/conn/persisted.ts
390
- import * as cbor2 from "cbor-x";
633
+ import * as cbor3 from "cbor-x";
391
634
  function convertConnToBarePersistedConn(persist) {
392
635
  return {
393
636
  id: persist.id,
394
- parameters: bufferToArrayBuffer(cbor2.encode(persist.parameters)),
395
- state: bufferToArrayBuffer(cbor2.encode(persist.state)),
637
+ parameters: bufferToArrayBuffer(cbor3.encode(persist.parameters)),
638
+ state: bufferToArrayBuffer(cbor3.encode(persist.state)),
396
639
  subscriptions: persist.subscriptions.map((sub) => ({
397
640
  eventName: sub.eventName
398
641
  })),
@@ -407,8 +650,8 @@ function convertConnToBarePersistedConn(persist) {
407
650
  function convertConnFromBarePersistedConn(bareData) {
408
651
  return {
409
652
  id: bareData.id,
410
- parameters: cbor2.decode(new Uint8Array(bareData.parameters)),
411
- state: cbor2.decode(new Uint8Array(bareData.state)),
653
+ parameters: cbor3.decode(new Uint8Array(bareData.parameters)),
654
+ state: cbor3.decode(new Uint8Array(bareData.state)),
412
655
  subscriptions: bareData.subscriptions.map((sub) => ({
413
656
  eventName: sub.eventName
414
657
  })),
@@ -680,7 +923,9 @@ var ConnectionManager = class {
680
923
  if (conn.isHibernatable) {
681
924
  const key = makeConnKey(conn.id);
682
925
  try {
683
- await this.#actor.driver.kvBatchDelete(this.#actor.id, [key]);
926
+ await this.#actor.driver.kvBatchDelete(this.#actor.id, [
927
+ key
928
+ ]);
684
929
  this.#actor.rLog.debug({
685
930
  msg: "removed connection from KV",
686
931
  connId: conn.id
@@ -844,7 +1089,7 @@ var ConnectionManager = class {
844
1089
  };
845
1090
 
846
1091
  // src/actor/instance/event-manager.ts
847
- import * as cbor3 from "cbor-x";
1092
+ import * as cbor4 from "cbor-x";
848
1093
  var EventManager = class {
849
1094
  #actor;
850
1095
  #subscriptionIndex = /* @__PURE__ */ new Map();
@@ -972,7 +1217,7 @@ var EventManager = class {
972
1217
  tag: "Event",
973
1218
  val: {
974
1219
  name: value.name,
975
- args: bufferToArrayBuffer(cbor3.encode(value.args))
1220
+ args: bufferToArrayBuffer(cbor4.encode(value.args))
976
1221
  }
977
1222
  }
978
1223
  })
@@ -1064,12 +1309,12 @@ var EventManager = class {
1064
1309
  };
1065
1310
 
1066
1311
  // src/actor/instance/persisted.ts
1067
- import * as cbor4 from "cbor-x";
1312
+ import * as cbor5 from "cbor-x";
1068
1313
  function convertActorToBarePersisted(persist) {
1069
1314
  return {
1070
- input: persist.input !== void 0 ? bufferToArrayBuffer(cbor4.encode(persist.input)) : null,
1315
+ input: persist.input !== void 0 ? bufferToArrayBuffer(cbor5.encode(persist.input)) : null,
1071
1316
  hasInitialized: persist.hasInitialized,
1072
- state: bufferToArrayBuffer(cbor4.encode(persist.state)),
1317
+ state: bufferToArrayBuffer(cbor5.encode(persist.state)),
1073
1318
  scheduledEvents: persist.scheduledEvents.map((event) => ({
1074
1319
  eventId: event.eventId,
1075
1320
  timestamp: BigInt(event.timestamp),
@@ -1080,9 +1325,9 @@ function convertActorToBarePersisted(persist) {
1080
1325
  }
1081
1326
  function convertActorFromBarePersisted(bareData) {
1082
1327
  return {
1083
- input: bareData.input ? cbor4.decode(new Uint8Array(bareData.input)) : void 0,
1328
+ input: bareData.input ? cbor5.decode(new Uint8Array(bareData.input)) : void 0,
1084
1329
  hasInitialized: bareData.hasInitialized,
1085
- state: cbor4.decode(new Uint8Array(bareData.state)),
1330
+ state: cbor5.decode(new Uint8Array(bareData.state)),
1086
1331
  scheduledEvents: bareData.scheduledEvents.map((event) => ({
1087
1332
  eventId: event.eventId,
1088
1333
  timestamp: Number(event.timestamp),
@@ -1093,7 +1338,7 @@ function convertActorFromBarePersisted(bareData) {
1093
1338
  }
1094
1339
 
1095
1340
  // src/actor/instance/queue-manager.ts
1096
- import * as cbor5 from "cbor-x";
1341
+ import * as cbor6 from "cbor-x";
1097
1342
  var DEFAULT_METADATA = {
1098
1343
  nextId: 1n,
1099
1344
  size: 0
@@ -1156,7 +1401,7 @@ var QueueManager = class {
1156
1401
  throw new QueueMessageInvalid(invalidPath);
1157
1402
  }
1158
1403
  const createdAt = Date.now();
1159
- const bodyCborBuffer = cbor5.encode(body);
1404
+ const bodyCborBuffer = cbor6.encode(body);
1160
1405
  const encodedMessage = QUEUE_MESSAGE_VERSIONED.serializeWithEmbeddedVersion(
1161
1406
  {
1162
1407
  name,
@@ -1419,7 +1664,7 @@ var QueueManager = class {
1419
1664
  const decodedPayload = QUEUE_MESSAGE_VERSIONED.deserializeWithEmbeddedVersion(
1420
1665
  value
1421
1666
  );
1422
- const body = cbor5.decode(new Uint8Array(decodedPayload.body));
1667
+ const body = cbor6.decode(new Uint8Array(decodedPayload.body));
1423
1668
  decoded.push({
1424
1669
  id: messageId,
1425
1670
  name: decodedPayload.name,
@@ -1527,7 +1772,7 @@ var QueueManager = class {
1527
1772
  };
1528
1773
 
1529
1774
  // src/actor/instance/schedule-manager.ts
1530
- import * as cbor6 from "cbor-x";
1775
+ import * as cbor7 from "cbor-x";
1531
1776
  var ScheduleManager = class {
1532
1777
  #actor;
1533
1778
  #actorDriver;
@@ -1536,10 +1781,10 @@ var ScheduleManager = class {
1536
1781
  // ActorConfig type
1537
1782
  #persist;
1538
1783
  // Reference to PersistedActor
1539
- constructor(actor, actorDriver, config4) {
1784
+ constructor(actor, actorDriver, config) {
1540
1785
  this.#actor = actor;
1541
1786
  this.#actorDriver = actorDriver;
1542
- this.#config = config4;
1787
+ this.#config = config;
1543
1788
  }
1544
1789
  // MARK: - Public API
1545
1790
  /**
@@ -1561,7 +1806,7 @@ var ScheduleManager = class {
1561
1806
  eventId: crypto.randomUUID(),
1562
1807
  timestamp,
1563
1808
  action,
1564
- args: bufferToArrayBuffer(cbor6.encode(args))
1809
+ args: bufferToArrayBuffer(cbor7.encode(args))
1565
1810
  };
1566
1811
  this.#actor.emitTraceEvent("schedule.created", {
1567
1812
  "rivet.schedule.event_id": newEvent.eventId,
@@ -1760,7 +2005,7 @@ var ScheduleManager = class {
1760
2005
  `Scheduled event action ${event.action} is not a function (got ${typeof fn})`
1761
2006
  );
1762
2007
  }
1763
- const args = event.args ? cbor6.decode(new Uint8Array(event.args)) : [];
2008
+ const args = event.args ? cbor7.decode(new Uint8Array(event.args)) : [];
1764
2009
  const result = this.#actor.traces.withSpan(
1765
2010
  span,
1766
2011
  () => fn.call(void 0, this.#actor.actorContext, ...args)
@@ -1849,11 +2094,11 @@ var StateManager = class {
1849
2094
  #config;
1850
2095
  // ActorConfig type
1851
2096
  #stateSaveInterval;
1852
- constructor(actor, actorDriver, config4) {
2097
+ constructor(actor, actorDriver, config) {
1853
2098
  this.#actor = actor;
1854
2099
  this.#actorDriver = actorDriver;
1855
- this.#config = config4;
1856
- this.#stateSaveInterval = config4.options.stateSaveInterval || 100;
2100
+ this.#config = config;
2101
+ this.#stateSaveInterval = config.options.stateSaveInterval || 100;
1857
2102
  }
1858
2103
  // MARK: - Public API
1859
2104
  get persist() {
@@ -1960,7 +2205,12 @@ var StateManager = class {
1960
2205
  await this.#savePersistInner();
1961
2206
  } else {
1962
2207
  if (!this.#onPersistSavedPromise) {
1963
- this.#onPersistSavedPromise = promiseWithResolvers((reason) => loggerWithoutContext().warn({ msg: "unhandled persist saved promise rejection", reason }));
2208
+ this.#onPersistSavedPromise = promiseWithResolvers(
2209
+ (reason) => loggerWithoutContext().warn({
2210
+ msg: "unhandled persist saved promise rejection",
2211
+ reason
2212
+ })
2213
+ );
1964
2214
  }
1965
2215
  this.savePersistThrottled(opts.maxWait);
1966
2216
  await ((_a = this.#onPersistSavedPromise) == null ? void 0 : _a.promise);
@@ -2221,14 +2471,15 @@ function concatPrefix(prefix, key) {
2221
2471
  function stripPrefix(prefix, key) {
2222
2472
  return key.slice(prefix.length);
2223
2473
  }
2224
- function compareBytes(a, b) {
2225
- const len = Math.min(a.length, b.length);
2226
- for (let i = 0; i < len; i++) {
2227
- if (a[i] !== b[i]) {
2228
- return a[i] - b[i];
2474
+ function computeUpperBound(prefix) {
2475
+ const upperBound = prefix.slice();
2476
+ for (let i = upperBound.length - 1; i >= 0; i--) {
2477
+ if (upperBound[i] !== 255) {
2478
+ upperBound[i]++;
2479
+ return upperBound.slice(0, i + 1);
2229
2480
  }
2230
2481
  }
2231
- return a.length - b.length;
2482
+ return null;
2232
2483
  }
2233
2484
  var ActorTracesDriver = class {
2234
2485
  #driver;
@@ -2257,17 +2508,26 @@ var ActorTracesDriver = class {
2257
2508
  }
2258
2509
  async deletePrefix(prefix) {
2259
2510
  const fullPrefix = concatPrefix(this.#prefix, prefix);
2260
- const entries = await this.#driver.kvListPrefix(
2261
- this.#actorId,
2262
- fullPrefix
2263
- );
2264
- if (entries.length === 0) {
2265
- return;
2511
+ const fullEnd = computeUpperBound(fullPrefix);
2512
+ if (fullEnd) {
2513
+ await this.#driver.kvDeleteRange(
2514
+ this.#actorId,
2515
+ fullPrefix,
2516
+ fullEnd
2517
+ );
2518
+ } else {
2519
+ const entries = await this.#driver.kvListPrefix(
2520
+ this.#actorId,
2521
+ fullPrefix
2522
+ );
2523
+ if (entries.length === 0) {
2524
+ return;
2525
+ }
2526
+ await this.#driver.kvBatchDelete(
2527
+ this.#actorId,
2528
+ entries.map(([key]) => key)
2529
+ );
2266
2530
  }
2267
- await this.#driver.kvBatchDelete(
2268
- this.#actorId,
2269
- entries.map(([key]) => key)
2270
- );
2271
2531
  }
2272
2532
  async list(prefix) {
2273
2533
  const fullPrefix = concatPrefix(this.#prefix, prefix);
@@ -2281,20 +2541,13 @@ var ActorTracesDriver = class {
2281
2541
  }));
2282
2542
  }
2283
2543
  async listRange(start, end, options) {
2284
- const fullStart = concatPrefix(this.#prefix, start);
2285
- const fullEnd = concatPrefix(this.#prefix, end);
2286
- const entries = await this.#driver.kvListPrefix(
2544
+ const entries = await this.#driver.kvListRange(
2287
2545
  this.#actorId,
2288
- this.#prefix
2546
+ concatPrefix(this.#prefix, start),
2547
+ concatPrefix(this.#prefix, end),
2548
+ options
2289
2549
  );
2290
- const filtered = entries.filter(([key]) => {
2291
- return compareBytes(key, fullStart) >= 0 && compareBytes(key, fullEnd) < 0;
2292
- }).sort(([keyA], [keyB]) => compareBytes(keyA, keyB));
2293
- if (options == null ? void 0 : options.reverse) {
2294
- filtered.reverse();
2295
- }
2296
- const limited = (options == null ? void 0 : options.limit) ? filtered.slice(0, options.limit) : filtered;
2297
- return limited.map(([key, value]) => ({
2550
+ return entries.map(([key, value]) => ({
2298
2551
  key: stripPrefix(this.#prefix, key),
2299
2552
  value
2300
2553
  }));
@@ -2318,11 +2571,12 @@ var CanSleep = /* @__PURE__ */ ((CanSleep2) => {
2318
2571
  CanSleep2[CanSleep2["Yes"] = 0] = "Yes";
2319
2572
  CanSleep2[CanSleep2["NotReady"] = 1] = "NotReady";
2320
2573
  CanSleep2[CanSleep2["NotStarted"] = 2] = "NotStarted";
2321
- CanSleep2[CanSleep2["ActiveConns"] = 3] = "ActiveConns";
2322
- CanSleep2[CanSleep2["ActiveDisconnectCallbacks"] = 4] = "ActiveDisconnectCallbacks";
2323
- CanSleep2[CanSleep2["ActiveHonoHttpRequests"] = 5] = "ActiveHonoHttpRequests";
2324
- CanSleep2[CanSleep2["ActiveKeepAwake"] = 6] = "ActiveKeepAwake";
2325
- CanSleep2[CanSleep2["ActiveRun"] = 7] = "ActiveRun";
2574
+ CanSleep2[CanSleep2["PreventSleep"] = 3] = "PreventSleep";
2575
+ CanSleep2[CanSleep2["ActiveConns"] = 4] = "ActiveConns";
2576
+ CanSleep2[CanSleep2["ActiveDisconnectCallbacks"] = 5] = "ActiveDisconnectCallbacks";
2577
+ CanSleep2[CanSleep2["ActiveHonoHttpRequests"] = 6] = "ActiveHonoHttpRequests";
2578
+ CanSleep2[CanSleep2["ActiveKeepAwake"] = 7] = "ActiveKeepAwake";
2579
+ CanSleep2[CanSleep2["ActiveRun"] = 8] = "ActiveRun";
2326
2580
  return CanSleep2;
2327
2581
  })(CanSleep || {});
2328
2582
  var ActorInstance = class {
@@ -2367,6 +2621,7 @@ var ActorInstance = class {
2367
2621
  #vars;
2368
2622
  #db;
2369
2623
  #sqliteVfs;
2624
+ #metrics = new ActorMetrics();
2370
2625
  // MARK: - Background Tasks
2371
2626
  #backgroundPromises = [];
2372
2627
  #runPromise;
@@ -2375,6 +2630,7 @@ var ActorInstance = class {
2375
2630
  // MARK: - HTTP/WebSocket Tracking
2376
2631
  #activeHonoHttpRequests = 0;
2377
2632
  #activeKeepAwakeCount = 0;
2633
+ #preventSleep = false;
2378
2634
  // MARK: - Deprecated (kept for compatibility)
2379
2635
  #schedule;
2380
2636
  // MARK: - Inspector
@@ -2390,8 +2646,8 @@ var ActorInstance = class {
2390
2646
  */
2391
2647
  overrides = {};
2392
2648
  // MARK: - Constructor
2393
- constructor(config4) {
2394
- this.#config = config4;
2649
+ constructor(config) {
2650
+ this.#config = config;
2395
2651
  this.actorContext = new ActorContext(this);
2396
2652
  this.#inspector = new ActorInspector(this);
2397
2653
  }
@@ -2431,6 +2687,9 @@ var ActorInstance = class {
2431
2687
  get inspectorToken() {
2432
2688
  return this.#inspectorToken;
2433
2689
  }
2690
+ get metrics() {
2691
+ return this.#metrics;
2692
+ }
2434
2693
  // MARK: - Tracing
2435
2694
  getCurrentTraceSpan() {
2436
2695
  return this.#traces.getCurrentSpan();
@@ -2482,6 +2741,9 @@ var ActorInstance = class {
2482
2741
  get abortSignal() {
2483
2742
  return this.#abortController.signal;
2484
2743
  }
2744
+ get preventSleep() {
2745
+ return this.#preventSleep;
2746
+ }
2485
2747
  get actions() {
2486
2748
  return Object.keys(this.#config.actions ?? {});
2487
2749
  }
@@ -2590,7 +2852,12 @@ var ActorInstance = class {
2590
2852
  this.#abortController.abort();
2591
2853
  } catch {
2592
2854
  }
2593
- await this.#waitForRunHandler(this.overrides.runStopTimeout !== void 0 ? Math.min(this.#config.options.runStopTimeout, this.overrides.runStopTimeout) : this.#config.options.runStopTimeout);
2855
+ await this.#waitForRunHandler(
2856
+ this.overrides.runStopTimeout !== void 0 ? Math.min(
2857
+ this.#config.options.runStopTimeout,
2858
+ this.overrides.runStopTimeout
2859
+ ) : this.#config.options.runStopTimeout
2860
+ );
2594
2861
  if (mode === "sleep") {
2595
2862
  await this.#callOnSleep();
2596
2863
  } else if (mode === "destroy") {
@@ -2598,10 +2865,13 @@ var ActorInstance = class {
2598
2865
  } else {
2599
2866
  assertUnreachable(mode);
2600
2867
  }
2601
- await this.#disconnectConnections();
2602
2868
  await this.#waitBackgroundPromises(
2603
- this.overrides.waitUntilTimeout !== void 0 ? Math.min(this.#config.options.waitUntilTimeout, this.overrides.waitUntilTimeout) : this.#config.options.waitUntilTimeout
2869
+ this.overrides.waitUntilTimeout !== void 0 ? Math.min(
2870
+ this.#config.options.waitUntilTimeout,
2871
+ this.overrides.waitUntilTimeout
2872
+ ) : this.#config.options.waitUntilTimeout
2604
2873
  );
2874
+ await this.#disconnectConnections();
2605
2875
  this.#rLog.info({ msg: "clearing pending save timeouts" });
2606
2876
  this.stateManager.clearPendingSaveTimeout();
2607
2877
  this.#rLog.info({ msg: "saving state immediately" });
@@ -2698,7 +2968,10 @@ var ActorInstance = class {
2698
2968
  });
2699
2969
  }
2700
2970
  async assertCanSubscribe(ctx, eventName) {
2701
- const canSubscribe = getEventCanSubscribe(this.#config.events, eventName);
2971
+ const canSubscribe = getEventCanSubscribe(
2972
+ this.#config.events,
2973
+ eventName
2974
+ );
2702
2975
  if (!canSubscribe) {
2703
2976
  return;
2704
2977
  }
@@ -2741,7 +3014,9 @@ var ActorInstance = class {
2741
3014
  throw new ActionNotFound(actionName);
2742
3015
  }
2743
3016
  this.#activeKeepAwakeCount++;
3017
+ this.#metrics.actionCalls++;
2744
3018
  this.resetSleepTimer();
3019
+ const actionStart = performance.now();
2745
3020
  const actionSpan = this.startTraceSpan(`actor.action.${actionName}`, {
2746
3021
  "rivet.action.name": actionName
2747
3022
  });
@@ -2790,6 +3065,7 @@ var ActorInstance = class {
2790
3065
  return output;
2791
3066
  });
2792
3067
  } catch (error) {
3068
+ this.#metrics.actionErrors++;
2793
3069
  const isTimeout = error instanceof DeadlineError;
2794
3070
  const message = isTimeout ? "ActionTimedOut" : stringifyError(error);
2795
3071
  this.#traces.setAttributes(actionSpan, {
@@ -2810,6 +3086,7 @@ var ActorInstance = class {
2810
3086
  });
2811
3087
  throw error;
2812
3088
  } finally {
3089
+ this.#metrics.actionTotalMs += performance.now() - actionStart;
2813
3090
  if (!spanEnded && actionSpan.isActive()) {
2814
3091
  this.#traces.endSpan(actionSpan, {
2815
3092
  status: { code: "OK" }
@@ -2969,6 +3246,15 @@ var ActorInstance = class {
2969
3246
  this.resetSleepTimer();
2970
3247
  }
2971
3248
  }
3249
+ setPreventSleep(prevent) {
3250
+ if (this.#preventSleep === prevent) return;
3251
+ this.#preventSleep = prevent;
3252
+ this.#rLog.debug({
3253
+ msg: "updated prevent sleep state",
3254
+ prevent
3255
+ });
3256
+ this.resetSleepTimer();
3257
+ }
2972
3258
  beginQueueWait() {
2973
3259
  this.assertReady(true);
2974
3260
  this.#activeQueueWaitCount++;
@@ -3004,11 +3290,11 @@ var ActorInstance = class {
3004
3290
  ...attributes ?? {}
3005
3291
  };
3006
3292
  }
3007
- #patchLoggerForTraces(logger3) {
3293
+ #patchLoggerForTraces(logger) {
3008
3294
  const levels = ["trace", "debug", "info", "warn", "error", "fatal"];
3009
3295
  for (const level of levels) {
3010
- const original = logger3[level].bind(logger3);
3011
- logger3[level] = ((...args) => {
3296
+ const original = logger[level].bind(logger);
3297
+ logger[level] = ((...args) => {
3012
3298
  this.#emitLogEvent(level, args);
3013
3299
  return original(...args);
3014
3300
  });
@@ -3195,7 +3481,10 @@ var ActorInstance = class {
3195
3481
  if (result instanceof Promise) {
3196
3482
  await deadline(
3197
3483
  result,
3198
- this.overrides.onSleepTimeout !== void 0 ? Math.min(this.#config.options.onSleepTimeout, this.overrides.onSleepTimeout) : this.#config.options.onSleepTimeout
3484
+ this.overrides.onSleepTimeout !== void 0 ? Math.min(
3485
+ this.#config.options.onSleepTimeout,
3486
+ this.overrides.onSleepTimeout
3487
+ ) : this.#config.options.onSleepTimeout
3199
3488
  );
3200
3489
  }
3201
3490
  }
@@ -3226,7 +3515,10 @@ var ActorInstance = class {
3226
3515
  if (result instanceof Promise) {
3227
3516
  await deadline(
3228
3517
  result,
3229
- this.overrides.onDestroyTimeout !== void 0 ? Math.min(this.#config.options.onDestroyTimeout, this.overrides.onDestroyTimeout) : this.#config.options.onDestroyTimeout
3518
+ this.overrides.onDestroyTimeout !== void 0 ? Math.min(
3519
+ this.#config.options.onDestroyTimeout,
3520
+ this.overrides.onDestroyTimeout
3521
+ ) : this.#config.options.onDestroyTimeout
3230
3522
  );
3231
3523
  }
3232
3524
  }
@@ -3266,19 +3558,12 @@ var ActorInstance = class {
3266
3558
  });
3267
3559
  return;
3268
3560
  }
3269
- this.emitTraceEvent(
3270
- "actor.crash",
3271
- { "rivet.actor.reason": "run_exited" },
3272
- runSpan
3273
- );
3274
- this.endTraceSpan(runSpan, {
3275
- code: "ERROR",
3276
- message: "run exited unexpectedly"
3277
- });
3278
- this.#rLog.warn({
3279
- msg: "run handler exited unexpectedly, crashing actor to reschedule"
3561
+ if (runSpan.isActive()) {
3562
+ this.endTraceSpan(runSpan, { code: "OK" });
3563
+ }
3564
+ this.#rLog.info({
3565
+ msg: "run handler exited"
3280
3566
  });
3281
- this.startDestroy();
3282
3567
  }).catch((error) => {
3283
3568
  if (this.#stopCalled) {
3284
3569
  if (runSpan.isActive()) {
@@ -3290,29 +3575,23 @@ var ActorInstance = class {
3290
3575
  });
3291
3576
  return;
3292
3577
  }
3293
- this.emitTraceEvent(
3294
- "actor.crash",
3295
- {
3296
- "rivet.actor.reason": "run_error",
3297
- "error.message": stringifyError(error)
3298
- },
3299
- runSpan
3300
- );
3301
3578
  this.endTraceSpan(runSpan, {
3302
3579
  code: "ERROR",
3303
3580
  message: stringifyError(error)
3304
3581
  });
3305
3582
  this.#rLog.error({
3306
- msg: "run handler threw error, crashing actor to reschedule",
3583
+ msg: "run handler threw error",
3307
3584
  error: stringifyError(error)
3308
3585
  });
3309
- this.startDestroy();
3310
3586
  }).finally(() => {
3311
3587
  this.#runHandlerActive = false;
3312
3588
  this.resetSleepTimer();
3313
3589
  });
3314
3590
  } else if (runSpan.isActive()) {
3315
3591
  this.endTraceSpan(runSpan, { code: "OK" });
3592
+ this.#rLog.info({
3593
+ msg: "run handler exited"
3594
+ });
3316
3595
  this.#runHandlerActive = false;
3317
3596
  this.resetSleepTimer();
3318
3597
  }
@@ -3345,18 +3624,23 @@ var ActorInstance = class {
3345
3624
  let client;
3346
3625
  try {
3347
3626
  if (!this.#sqliteVfs && this.driver.createSqliteVfs) {
3348
- this.#sqliteVfs = await this.driver.createSqliteVfs();
3627
+ this.#sqliteVfs = await this.driver.createSqliteVfs(this.#actorId);
3349
3628
  }
3350
3629
  client = await this.#config.db.createClient({
3351
3630
  actorId: this.#actorId,
3352
- overrideRawDatabaseClient: this.driver.overrideRawDatabaseClient ? () => this.driver.overrideRawDatabaseClient(this.#actorId) : void 0,
3353
- overrideDrizzleDatabaseClient: this.driver.overrideDrizzleDatabaseClient ? () => this.driver.overrideDrizzleDatabaseClient(this.#actorId) : void 0,
3631
+ overrideRawDatabaseClient: this.driver.overrideRawDatabaseClient ? () => this.driver.overrideRawDatabaseClient(
3632
+ this.#actorId
3633
+ ) : void 0,
3634
+ overrideDrizzleDatabaseClient: this.driver.overrideDrizzleDatabaseClient ? () => this.driver.overrideDrizzleDatabaseClient(
3635
+ this.#actorId
3636
+ ) : void 0,
3354
3637
  kv: {
3355
3638
  batchPut: (entries) => this.driver.kvBatchPut(this.#actorId, entries),
3356
3639
  batchGet: (keys) => this.driver.kvBatchGet(this.#actorId, keys),
3357
3640
  batchDelete: (keys) => this.driver.kvBatchDelete(this.#actorId, keys)
3358
3641
  },
3359
- sqliteVfs: this.#sqliteVfs
3642
+ sqliteVfs: this.#sqliteVfs,
3643
+ metrics: this.#metrics
3360
3644
  });
3361
3645
  this.#rLog.info({ msg: "database migration starting" });
3362
3646
  await ((_b = (_a = this.#config.db).onMigrate) == null ? void 0 : _b.call(_a, client));
@@ -3391,7 +3675,9 @@ var ActorInstance = class {
3391
3675
  });
3392
3676
  throw error;
3393
3677
  }
3394
- const wrappedError = new Error(`Database setup failed: ${String(error)}`);
3678
+ const wrappedError = new Error(
3679
+ `Database setup failed: ${String(error)}`
3680
+ );
3395
3681
  this.#rLog.error({
3396
3682
  msg: "database setup failed with non-Error object",
3397
3683
  error: String(error),
@@ -3511,17 +3797,18 @@ var ActorInstance = class {
3511
3797
  #canSleep() {
3512
3798
  if (!this.#ready) return 1 /* NotReady */;
3513
3799
  if (!this.#started) return 1 /* NotReady */;
3800
+ if (this.#preventSleep) return 3 /* PreventSleep */;
3514
3801
  if (this.#activeHonoHttpRequests > 0)
3515
- return 5 /* ActiveHonoHttpRequests */;
3516
- if (this.#activeKeepAwakeCount > 0) return 6 /* ActiveKeepAwake */;
3802
+ return 6 /* ActiveHonoHttpRequests */;
3803
+ if (this.#activeKeepAwakeCount > 0) return 7 /* ActiveKeepAwake */;
3517
3804
  if (this.#runHandlerActive && this.#activeQueueWaitCount === 0) {
3518
- return 7 /* ActiveRun */;
3805
+ return 8 /* ActiveRun */;
3519
3806
  }
3520
3807
  for (const _conn of this.connectionManager.connections.values()) {
3521
- return 3 /* ActiveConns */;
3808
+ return 4 /* ActiveConns */;
3522
3809
  }
3523
3810
  if (this.connectionManager.pendingDisconnectCount > 0) {
3524
- return 4 /* ActiveDisconnectCallbacks */;
3811
+ return 5 /* ActiveDisconnectCallbacks */;
3525
3812
  }
3526
3813
  return 0 /* Yes */;
3527
3814
  }
@@ -3541,8 +3828,8 @@ var ActorInstance = class {
3541
3828
  // src/actor/definition.ts
3542
3829
  var ActorDefinition = class {
3543
3830
  #config;
3544
- constructor(config4) {
3545
- this.#config = config4;
3831
+ constructor(config) {
3832
+ this.#config = config;
3546
3833
  }
3547
3834
  get config() {
3548
3835
  return this.#config;
@@ -3551,15 +3838,15 @@ var ActorDefinition = class {
3551
3838
  return new ActorInstance(this.#config);
3552
3839
  }
3553
3840
  };
3554
- function lookupInRegistry(config4, name) {
3555
- const definition = config4.use[name];
3841
+ function lookupInRegistry(config, name) {
3842
+ const definition = config.use[name];
3556
3843
  if (!definition) throw new Error(`no actor in registry for name ${name}`);
3557
3844
  return definition;
3558
3845
  }
3559
3846
 
3560
3847
  // src/actor/router.ts
3561
3848
  import { Hono } from "hono";
3562
- function createActorRouter(config4, actorDriver, getUpgradeWebSocket, isTest) {
3849
+ function createActorRouter(config, actorDriver, getUpgradeWebSocket, isTest) {
3563
3850
  const router = new Hono({
3564
3851
  strict: false
3565
3852
  });
@@ -3584,7 +3871,8 @@ function createActorRouter(config4, actorDriver, getUpgradeWebSocket, isTest) {
3584
3871
  router.get("/metadata", async (c) => {
3585
3872
  return c.json({
3586
3873
  runtime: "rivetkit",
3587
- version: VERSION
3874
+ version: VERSION,
3875
+ type: isDev() ? "local" : "deployed"
3588
3876
  });
3589
3877
  });
3590
3878
  if (isTest) {
@@ -3621,7 +3909,7 @@ function createActorRouter(config4, actorDriver, getUpgradeWebSocket, isTest) {
3621
3909
  c2.req.raw,
3622
3910
  c2.req.path,
3623
3911
  c2.req.header(),
3624
- config4,
3912
+ config,
3625
3913
  actorDriver,
3626
3914
  c2.env.actorId,
3627
3915
  encoding,
@@ -3641,10 +3929,10 @@ function createActorRouter(config4, actorDriver, getUpgradeWebSocket, isTest) {
3641
3929
  }
3642
3930
  );
3643
3931
  }
3644
- if (config4.inspector.enabled) {
3932
+ if (config.inspector.enabled) {
3645
3933
  const inspectorAuth = async (c) => {
3646
3934
  var _a;
3647
- if (isDev() && !config4.inspector.token()) {
3935
+ if (isDev() && !config.inspector.token()) {
3648
3936
  inspectorLogger().warn({
3649
3937
  msg: "RIVET_INSPECTOR_TOKEN is not set, skipping inspector auth in development mode"
3650
3938
  });
@@ -3654,7 +3942,7 @@ function createActorRouter(config4, actorDriver, getUpgradeWebSocket, isTest) {
3654
3942
  if (!userToken) {
3655
3943
  return c.text("Unauthorized", 401);
3656
3944
  }
3657
- const inspectorToken = config4.inspector.token();
3945
+ const inspectorToken = config.inspector.token();
3658
3946
  if (!inspectorToken) {
3659
3947
  return c.text("Unauthorized", 401);
3660
3948
  }
@@ -3738,6 +4026,33 @@ function createActorRouter(config4, actorDriver, getUpgradeWebSocket, isTest) {
3738
4026
  const result = actor.inspector.getWorkflowHistoryJson();
3739
4027
  return c.json(result);
3740
4028
  });
4029
+ router.get("/inspector/database/schema", async (c) => {
4030
+ const authResponse = await inspectorAuth(c);
4031
+ if (authResponse) return authResponse;
4032
+ const actor = await actorDriver.loadActor(c.env.actorId);
4033
+ const schema = await actor.inspector.getDatabaseSchemaJson();
4034
+ return c.json({ schema });
4035
+ });
4036
+ router.get("/inspector/database/rows", async (c) => {
4037
+ const authResponse = await inspectorAuth(c);
4038
+ if (authResponse) return authResponse;
4039
+ const actor = await actorDriver.loadActor(c.env.actorId);
4040
+ const table = c.req.query("table");
4041
+ if (!table) {
4042
+ return c.json(
4043
+ { error: "Missing required table query parameter" },
4044
+ 400
4045
+ );
4046
+ }
4047
+ const limit = parseInt(c.req.query("limit") ?? "100", 10);
4048
+ const offset = parseInt(c.req.query("offset") ?? "0", 10);
4049
+ const rows = await actor.inspector.getDatabaseTableRowsJson(
4050
+ table,
4051
+ limit,
4052
+ offset
4053
+ );
4054
+ return c.json({ rows });
4055
+ });
3741
4056
  router.get("/inspector/summary", async (c) => {
3742
4057
  const authResponse = await inspectorAuth(c);
3743
4058
  if (authResponse) return authResponse;
@@ -3745,13 +4060,11 @@ function createActorRouter(config4, actorDriver, getUpgradeWebSocket, isTest) {
3745
4060
  const isStateEnabled = actor.inspector.isStateEnabled();
3746
4061
  const isDatabaseEnabled = actor.inspector.isDatabaseEnabled();
3747
4062
  const isWorkflowEnabled = actor.inspector.isWorkflowEnabled();
4063
+ const workflowHistory = actor.inspector.getWorkflowHistoryJson().history;
3748
4064
  const state = isStateEnabled ? actor.inspector.getStateJson() : void 0;
3749
4065
  const connections = actor.inspector.getConnectionsJson();
3750
4066
  const rpcs = actor.inspector.getRpcs();
3751
4067
  const queueSize = actor.inspector.getQueueSize();
3752
- const workflowHistory = actor.inspector.getWorkflowHistory();
3753
- const bigIntReplacer = (_key, value) => typeof value === "bigint" ? Number(value) : value;
3754
- const safeWorkflowHistory = workflowHistory ? JSON.parse(JSON.stringify(workflowHistory, bigIntReplacer)) : null;
3755
4068
  return c.json({
3756
4069
  state,
3757
4070
  connections,
@@ -3760,21 +4073,27 @@ function createActorRouter(config4, actorDriver, getUpgradeWebSocket, isTest) {
3760
4073
  isStateEnabled,
3761
4074
  isDatabaseEnabled,
3762
4075
  isWorkflowEnabled,
3763
- workflowHistory: safeWorkflowHistory
4076
+ workflowHistory
3764
4077
  });
3765
4078
  });
4079
+ router.get("/inspector/metrics", async (c) => {
4080
+ const authResponse = await inspectorAuth(c);
4081
+ if (authResponse) return authResponse;
4082
+ const actor = await actorDriver.loadActor(c.env.actorId);
4083
+ return c.json(actor.metrics.snapshot());
4084
+ });
3766
4085
  }
3767
4086
  router.post("/action/:action", async (c) => {
3768
4087
  const actionName = c.req.param("action");
3769
- return handleAction(c, config4, actorDriver, actionName, c.env.actorId);
4088
+ return handleAction(c, config, actorDriver, actionName, c.env.actorId);
3770
4089
  });
3771
4090
  router.post("/queue", async (c) => {
3772
- return handleQueueSend(c, config4, actorDriver, c.env.actorId);
4091
+ return handleQueueSend(c, config, actorDriver, c.env.actorId);
3773
4092
  });
3774
4093
  router.post("/queue/:name", async (c) => {
3775
4094
  return handleQueueSend(
3776
4095
  c,
3777
- config4,
4096
+ config,
3778
4097
  actorDriver,
3779
4098
  c.env.actorId,
3780
4099
  c.req.param("name")
@@ -3807,2178 +4126,9 @@ function createActorRouter(config4, actorDriver, getUpgradeWebSocket, isTest) {
3807
4126
  return router;
3808
4127
  }
3809
4128
 
3810
- // src/common/inline-websocket-adapter.ts
3811
- import { WSContext } from "hono/ws";
3812
- import { VirtualWebSocket } from "@rivetkit/virtual-websocket";
3813
- function logger() {
3814
- return getLogger("inline-websocket-adapter");
3815
- }
3816
- var InlineWebSocketAdapter = class {
3817
- #handler;
3818
- #wsContext;
3819
- #readyState = 0;
3820
- #clientWs;
3821
- #actorWs;
3822
- constructor(handler) {
3823
- this.#handler = handler;
3824
- this.#clientWs = new VirtualWebSocket({
3825
- getReadyState: () => this.#readyState,
3826
- onSend: (data) => {
3827
- try {
3828
- this.#handler.onMessage({ data }, this.#wsContext);
3829
- this.#actorWs.triggerMessage(data);
3830
- } catch (err) {
3831
- this.#handleError(err);
3832
- this.#close(1011, "Internal error processing message");
3833
- }
3834
- },
3835
- onClose: (code, reason) => this.#close(code, reason)
3836
- });
3837
- this.#actorWs = new VirtualWebSocket({
3838
- getReadyState: () => this.#readyState,
3839
- onSend: (data) => this.#clientWs.triggerMessage(data),
3840
- onClose: (code, reason) => this.#close(code, reason)
3841
- });
3842
- this.#wsContext = new WSContext({
3843
- raw: this.#actorWs,
3844
- send: (data) => {
3845
- logger().debug({ msg: "WSContext.send called" });
3846
- this.#clientWs.triggerMessage(data);
3847
- },
3848
- close: (code, reason) => {
3849
- logger().debug({ msg: "WSContext.close called", code, reason });
3850
- this.#close(code || 1e3, reason || "");
3851
- },
3852
- readyState: 1
3853
- });
3854
- setTimeout(() => {
3855
- this.#initialize();
3856
- }, 0);
3857
- }
3858
- /** Get the client-side WebSocket (for proxy/client code) */
3859
- get clientWebSocket() {
3860
- return this.#clientWs;
3861
- }
3862
- /** Get the actor-side WebSocket (passed to actor via wsContext.raw) */
3863
- get actorWebSocket() {
3864
- return this.#actorWs;
3865
- }
3866
- async #initialize() {
3867
- try {
3868
- logger().debug({ msg: "websocket initializing" });
3869
- this.#readyState = 1;
3870
- logger().debug({ msg: "calling handler.onOpen with WSContext" });
3871
- this.#handler.onOpen(void 0, this.#wsContext);
3872
- this.#clientWs.triggerOpen();
3873
- this.#actorWs.triggerOpen();
3874
- } catch (err) {
3875
- this.#handleError(err);
3876
- this.#close(1011, "Internal error during initialization");
3877
- }
3878
- }
3879
- #handleError(err) {
3880
- logger().error({
3881
- msg: "error in websocket",
3882
- error: err,
3883
- errorMessage: err instanceof Error ? err.message : String(err),
3884
- stack: err instanceof Error ? err.stack : void 0
3885
- });
3886
- try {
3887
- this.#handler.onError(err, this.#wsContext);
3888
- } catch (handlerErr) {
3889
- logger().error({ msg: "error in onError handler", error: handlerErr });
3890
- }
3891
- this.#clientWs.triggerError(err);
3892
- this.#actorWs.triggerError(err);
3893
- }
3894
- #close(code, reason) {
3895
- if (this.#readyState === 3 || this.#readyState === 2) {
3896
- return;
3897
- }
3898
- logger().debug({ msg: "closing websocket", code, reason });
3899
- this.#readyState = 2;
3900
- try {
3901
- this.#handler.onClose({ code, reason, wasClean: true }, this.#wsContext);
3902
- } catch (err) {
3903
- logger().error({ msg: "error closing websocket", error: err });
3904
- } finally {
3905
- this.#readyState = 3;
3906
- this.#clientWs.triggerClose(code, reason);
3907
- this.#actorWs.triggerClose(code, reason);
3908
- }
3909
- }
3910
- };
3911
- function createInlineWebSocket(handler) {
3912
- const adapter = new InlineWebSocketAdapter(handler);
3913
- return adapter.clientWebSocket;
3914
- }
3915
-
3916
- // src/drivers/file-system/mod.ts
3917
- import { z } from "zod";
3918
-
3919
- // src/drivers/file-system/actor.ts
3920
- var FileSystemActorDriver = class {
3921
- #config;
3922
- #managerDriver;
3923
- #inlineClient;
3924
- #state;
3925
- constructor(config4, managerDriver, inlineClient, state) {
3926
- this.#config = config4;
3927
- this.#managerDriver = managerDriver;
3928
- this.#inlineClient = inlineClient;
3929
- this.#state = state;
3930
- }
3931
- async loadActor(actorId) {
3932
- return this.#state.startActor(
3933
- this.#config,
3934
- this.#inlineClient,
3935
- this,
3936
- actorId
3937
- );
3938
- }
3939
- /**
3940
- * Get the current storage directory path
3941
- */
3942
- get storagePath() {
3943
- return this.#state.storagePath;
3944
- }
3945
- getContext(_actorId) {
3946
- return {};
3947
- }
3948
- async kvBatchPut(actorId, entries) {
3949
- await this.#state.kvBatchPut(actorId, entries);
3950
- }
3951
- async kvBatchGet(actorId, keys) {
3952
- return await this.#state.kvBatchGet(actorId, keys);
3953
- }
3954
- async kvBatchDelete(actorId, keys) {
3955
- await this.#state.kvBatchDelete(actorId, keys);
3956
- }
3957
- async kvListPrefix(actorId, prefix) {
3958
- return await this.#state.kvListPrefix(actorId, prefix);
3959
- }
3960
- async setAlarm(actor, timestamp) {
3961
- await this.#state.setActorAlarm(actor.id, timestamp);
3962
- }
3963
- /** Creates a SQLite VFS instance for creating KV-backed databases */
3964
- async createSqliteVfs() {
3965
- return await importSqliteVfs();
3966
- }
3967
- startSleep(actorId) {
3968
- this.#state.sleepActor(actorId);
3969
- }
3970
- async startDestroy(actorId) {
3971
- await this.#state.destroyActor(actorId);
3972
- }
3973
- async onBeforeActorStart(actor) {
3974
- await actor.cleanupPersistedConnections("file-system-driver.start");
3975
- }
3976
- };
3977
-
3978
- // src/drivers/file-system/global-state.ts
3979
- import invariant3 from "invariant";
3980
-
3981
- // src/schemas/file-system-driver/versioned.ts
3982
- import { createVersionedDataHandler } from "vbare";
3983
-
3984
- // dist/schemas/file-system-driver/v1.ts
3985
- import * as bare from "@rivetkit/bare-ts";
3986
- var config = /* @__PURE__ */ bare.Config({});
3987
- function read0(bc) {
3988
- const len = bare.readUintSafe(bc);
3989
- if (len === 0) {
3990
- return [];
3991
- }
3992
- const result = [bare.readString(bc)];
3993
- for (let i = 1; i < len; i++) {
3994
- result[i] = bare.readString(bc);
3995
- }
3996
- return result;
3997
- }
3998
- function write0(bc, x) {
3999
- bare.writeUintSafe(bc, x.length);
4000
- for (let i = 0; i < x.length; i++) {
4001
- bare.writeString(bc, x[i]);
4002
- }
4003
- }
4004
- function readActorState(bc) {
4005
- return {
4006
- actorId: bare.readString(bc),
4007
- name: bare.readString(bc),
4008
- key: read0(bc),
4009
- persistedData: bare.readData(bc),
4010
- createdAt: bare.readU64(bc)
4011
- };
4012
- }
4013
- function writeActorState(bc, x) {
4014
- bare.writeString(bc, x.actorId);
4015
- bare.writeString(bc, x.name);
4016
- write0(bc, x.key);
4017
- bare.writeData(bc, x.persistedData);
4018
- bare.writeU64(bc, x.createdAt);
4019
- }
4020
- function encodeActorState(x) {
4021
- const bc = new bare.ByteCursor(
4022
- new Uint8Array(config.initialBufferLength),
4023
- config
4024
- );
4025
- writeActorState(bc, x);
4026
- return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
4027
- }
4028
- function decodeActorState(bytes) {
4029
- const bc = new bare.ByteCursor(bytes, config);
4030
- const result = readActorState(bc);
4031
- if (bc.offset < bc.view.byteLength) {
4032
- throw new bare.BareError(bc.offset, "remaining bytes");
4033
- }
4034
- return result;
4035
- }
4036
- function readActorAlarm(bc) {
4037
- return {
4038
- actorId: bare.readString(bc),
4039
- timestamp: bare.readUint(bc)
4040
- };
4041
- }
4042
- function writeActorAlarm(bc, x) {
4043
- bare.writeString(bc, x.actorId);
4044
- bare.writeUint(bc, x.timestamp);
4045
- }
4046
- function encodeActorAlarm(x) {
4047
- const bc = new bare.ByteCursor(
4048
- new Uint8Array(config.initialBufferLength),
4049
- config
4050
- );
4051
- writeActorAlarm(bc, x);
4052
- return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
4053
- }
4054
- function decodeActorAlarm(bytes) {
4055
- const bc = new bare.ByteCursor(bytes, config);
4056
- const result = readActorAlarm(bc);
4057
- if (bc.offset < bc.view.byteLength) {
4058
- throw new bare.BareError(bc.offset, "remaining bytes");
4059
- }
4060
- return result;
4061
- }
4062
-
4063
- // dist/schemas/file-system-driver/v2.ts
4064
- import * as bare2 from "@rivetkit/bare-ts";
4065
- var config2 = /* @__PURE__ */ bare2.Config({});
4066
- function readActorKvEntry(bc) {
4067
- return {
4068
- key: bare2.readData(bc),
4069
- value: bare2.readData(bc)
4070
- };
4071
- }
4072
- function writeActorKvEntry(bc, x) {
4073
- bare2.writeData(bc, x.key);
4074
- bare2.writeData(bc, x.value);
4075
- }
4076
- function read02(bc) {
4077
- const len = bare2.readUintSafe(bc);
4078
- if (len === 0) {
4079
- return [];
4080
- }
4081
- const result = [bare2.readString(bc)];
4082
- for (let i = 1; i < len; i++) {
4083
- result[i] = bare2.readString(bc);
4084
- }
4085
- return result;
4086
- }
4087
- function write02(bc, x) {
4088
- bare2.writeUintSafe(bc, x.length);
4089
- for (let i = 0; i < x.length; i++) {
4090
- bare2.writeString(bc, x[i]);
4091
- }
4092
- }
4093
- function read1(bc) {
4094
- const len = bare2.readUintSafe(bc);
4095
- if (len === 0) {
4096
- return [];
4097
- }
4098
- const result = [readActorKvEntry(bc)];
4099
- for (let i = 1; i < len; i++) {
4100
- result[i] = readActorKvEntry(bc);
4101
- }
4102
- return result;
4103
- }
4104
- function write1(bc, x) {
4105
- bare2.writeUintSafe(bc, x.length);
4106
- for (let i = 0; i < x.length; i++) {
4107
- writeActorKvEntry(bc, x[i]);
4108
- }
4109
- }
4110
- function readActorState2(bc) {
4111
- return {
4112
- actorId: bare2.readString(bc),
4113
- name: bare2.readString(bc),
4114
- key: read02(bc),
4115
- kvStorage: read1(bc),
4116
- createdAt: bare2.readU64(bc)
4117
- };
4118
- }
4119
- function writeActorState2(bc, x) {
4120
- bare2.writeString(bc, x.actorId);
4121
- bare2.writeString(bc, x.name);
4122
- write02(bc, x.key);
4123
- write1(bc, x.kvStorage);
4124
- bare2.writeU64(bc, x.createdAt);
4125
- }
4126
- function encodeActorState2(x) {
4127
- const bc = new bare2.ByteCursor(
4128
- new Uint8Array(config2.initialBufferLength),
4129
- config2
4130
- );
4131
- writeActorState2(bc, x);
4132
- return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
4133
- }
4134
- function decodeActorState2(bytes) {
4135
- const bc = new bare2.ByteCursor(bytes, config2);
4136
- const result = readActorState2(bc);
4137
- if (bc.offset < bc.view.byteLength) {
4138
- throw new bare2.BareError(bc.offset, "remaining bytes");
4139
- }
4140
- return result;
4141
- }
4142
- function readActorAlarm2(bc) {
4143
- return {
4144
- actorId: bare2.readString(bc),
4145
- timestamp: bare2.readUint(bc)
4146
- };
4147
- }
4148
- function writeActorAlarm2(bc, x) {
4149
- bare2.writeString(bc, x.actorId);
4150
- bare2.writeUint(bc, x.timestamp);
4151
- }
4152
- function encodeActorAlarm2(x) {
4153
- const bc = new bare2.ByteCursor(
4154
- new Uint8Array(config2.initialBufferLength),
4155
- config2
4156
- );
4157
- writeActorAlarm2(bc, x);
4158
- return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
4159
- }
4160
- function decodeActorAlarm2(bytes) {
4161
- const bc = new bare2.ByteCursor(bytes, config2);
4162
- const result = readActorAlarm2(bc);
4163
- if (bc.offset < bc.view.byteLength) {
4164
- throw new bare2.BareError(bc.offset, "remaining bytes");
4165
- }
4166
- return result;
4167
- }
4168
-
4169
- // dist/schemas/file-system-driver/v3.ts
4170
- import * as bare3 from "@rivetkit/bare-ts";
4171
- var config3 = /* @__PURE__ */ bare3.Config({});
4172
- function readActorKvEntry2(bc) {
4173
- return {
4174
- key: bare3.readData(bc),
4175
- value: bare3.readData(bc)
4176
- };
4177
- }
4178
- function writeActorKvEntry2(bc, x) {
4179
- bare3.writeData(bc, x.key);
4180
- bare3.writeData(bc, x.value);
4181
- }
4182
- function read03(bc) {
4183
- const len = bare3.readUintSafe(bc);
4184
- if (len === 0) {
4185
- return [];
4186
- }
4187
- const result = [bare3.readString(bc)];
4188
- for (let i = 1; i < len; i++) {
4189
- result[i] = bare3.readString(bc);
4190
- }
4191
- return result;
4192
- }
4193
- function write03(bc, x) {
4194
- bare3.writeUintSafe(bc, x.length);
4195
- for (let i = 0; i < x.length; i++) {
4196
- bare3.writeString(bc, x[i]);
4197
- }
4198
- }
4199
- function read12(bc) {
4200
- const len = bare3.readUintSafe(bc);
4201
- if (len === 0) {
4202
- return [];
4203
- }
4204
- const result = [readActorKvEntry2(bc)];
4205
- for (let i = 1; i < len; i++) {
4206
- result[i] = readActorKvEntry2(bc);
4207
- }
4208
- return result;
4209
- }
4210
- function write12(bc, x) {
4211
- bare3.writeUintSafe(bc, x.length);
4212
- for (let i = 0; i < x.length; i++) {
4213
- writeActorKvEntry2(bc, x[i]);
4214
- }
4215
- }
4216
- function read2(bc) {
4217
- return bare3.readBool(bc) ? bare3.readU64(bc) : null;
4218
- }
4219
- function write2(bc, x) {
4220
- bare3.writeBool(bc, x !== null);
4221
- if (x !== null) {
4222
- bare3.writeU64(bc, x);
4223
- }
4224
- }
4225
- function readActorState3(bc) {
4226
- return {
4227
- actorId: bare3.readString(bc),
4228
- name: bare3.readString(bc),
4229
- key: read03(bc),
4230
- kvStorage: read12(bc),
4231
- createdAt: bare3.readU64(bc),
4232
- startTs: read2(bc),
4233
- connectableTs: read2(bc),
4234
- sleepTs: read2(bc),
4235
- destroyTs: read2(bc)
4236
- };
4237
- }
4238
- function writeActorState3(bc, x) {
4239
- bare3.writeString(bc, x.actorId);
4240
- bare3.writeString(bc, x.name);
4241
- write03(bc, x.key);
4242
- write12(bc, x.kvStorage);
4243
- bare3.writeU64(bc, x.createdAt);
4244
- write2(bc, x.startTs);
4245
- write2(bc, x.connectableTs);
4246
- write2(bc, x.sleepTs);
4247
- write2(bc, x.destroyTs);
4248
- }
4249
- function encodeActorState3(x) {
4250
- const bc = new bare3.ByteCursor(
4251
- new Uint8Array(config3.initialBufferLength),
4252
- config3
4253
- );
4254
- writeActorState3(bc, x);
4255
- return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
4256
- }
4257
- function decodeActorState3(bytes) {
4258
- const bc = new bare3.ByteCursor(bytes, config3);
4259
- const result = readActorState3(bc);
4260
- if (bc.offset < bc.view.byteLength) {
4261
- throw new bare3.BareError(bc.offset, "remaining bytes");
4262
- }
4263
- return result;
4264
- }
4265
- function readActorAlarm3(bc) {
4266
- return {
4267
- actorId: bare3.readString(bc),
4268
- timestamp: bare3.readUint(bc)
4269
- };
4270
- }
4271
- function writeActorAlarm3(bc, x) {
4272
- bare3.writeString(bc, x.actorId);
4273
- bare3.writeUint(bc, x.timestamp);
4274
- }
4275
- function encodeActorAlarm3(x) {
4276
- const bc = new bare3.ByteCursor(
4277
- new Uint8Array(config3.initialBufferLength),
4278
- config3
4279
- );
4280
- writeActorAlarm3(bc, x);
4281
- return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
4282
- }
4283
- function decodeActorAlarm3(bytes) {
4284
- const bc = new bare3.ByteCursor(bytes, config3);
4285
- const result = readActorAlarm3(bc);
4286
- if (bc.offset < bc.view.byteLength) {
4287
- throw new bare3.BareError(bc.offset, "remaining bytes");
4288
- }
4289
- return result;
4290
- }
4291
-
4292
- // src/schemas/file-system-driver/versioned.ts
4293
- var CURRENT_VERSION3 = 3;
4294
- var v1ToV2 = (v1State) => {
4295
- const kvStorage = [];
4296
- if (v1State.persistedData) {
4297
- const key = new Uint8Array([1]);
4298
- kvStorage.push({
4299
- key: bufferToArrayBuffer(key),
4300
- value: v1State.persistedData
4301
- });
4302
- }
4303
- return {
4304
- actorId: v1State.actorId,
4305
- name: v1State.name,
4306
- key: v1State.key,
4307
- kvStorage,
4308
- createdAt: v1State.createdAt
4309
- };
4310
- };
4311
- var v2ToV3 = (v2State) => {
4312
- return {
4313
- actorId: v2State.actorId,
4314
- name: v2State.name,
4315
- key: v2State.key,
4316
- kvStorage: v2State.kvStorage,
4317
- createdAt: v2State.createdAt,
4318
- startTs: null,
4319
- connectableTs: null,
4320
- sleepTs: null,
4321
- destroyTs: null
4322
- };
4323
- };
4324
- var v3ToV2 = (v3State) => {
4325
- return {
4326
- actorId: v3State.actorId,
4327
- name: v3State.name,
4328
- key: v3State.key,
4329
- kvStorage: v3State.kvStorage,
4330
- createdAt: v3State.createdAt
4331
- };
4332
- };
4333
- var v2ToV1 = (v2State) => {
4334
- const persistDataEntry = v2State.kvStorage.find((entry) => {
4335
- const key = new Uint8Array(entry.key);
4336
- return key.length === 1 && key[0] === 1;
4337
- });
4338
- return {
4339
- actorId: v2State.actorId,
4340
- name: v2State.name,
4341
- key: v2State.key,
4342
- persistedData: (persistDataEntry == null ? void 0 : persistDataEntry.value) || new ArrayBuffer(0),
4343
- createdAt: v2State.createdAt
4344
- };
4345
- };
4346
- var ACTOR_STATE_VERSIONED = createVersionedDataHandler({
4347
- deserializeVersion: (bytes, version) => {
4348
- switch (version) {
4349
- case 1:
4350
- return decodeActorState(bytes);
4351
- case 2:
4352
- return decodeActorState2(bytes);
4353
- case 3:
4354
- return decodeActorState3(bytes);
4355
- default:
4356
- throw new Error(`Unknown version ${version}`);
4357
- }
4358
- },
4359
- serializeVersion: (data, version) => {
4360
- switch (version) {
4361
- case 1:
4362
- return encodeActorState(data);
4363
- case 2:
4364
- return encodeActorState2(data);
4365
- case 3:
4366
- return encodeActorState3(data);
4367
- default:
4368
- throw new Error(`Unknown version ${version}`);
4369
- }
4370
- },
4371
- deserializeConverters: () => [v1ToV2, v2ToV3],
4372
- serializeConverters: () => [v3ToV2, v2ToV1]
4373
- });
4374
- var ACTOR_ALARM_VERSIONED = createVersionedDataHandler({
4375
- deserializeVersion: (bytes, version) => {
4376
- switch (version) {
4377
- case 1:
4378
- return decodeActorAlarm(bytes);
4379
- case 2:
4380
- return decodeActorAlarm2(bytes);
4381
- case 3:
4382
- return decodeActorAlarm3(bytes);
4383
- default:
4384
- throw new Error(`Unknown version ${version}`);
4385
- }
4386
- },
4387
- serializeVersion: (data, version) => {
4388
- switch (version) {
4389
- case 1:
4390
- return encodeActorAlarm(data);
4391
- case 2:
4392
- return encodeActorAlarm2(data);
4393
- case 3:
4394
- return encodeActorAlarm3(data);
4395
- default:
4396
- throw new Error(`Unknown version ${version}`);
4397
- }
4398
- },
4399
- deserializeConverters: () => [],
4400
- serializeConverters: () => []
4401
- });
4402
-
4403
- // src/drivers/file-system/log.ts
4404
- function logger2() {
4405
- return getLogger("driver-fs");
4406
- }
4407
-
4408
- // src/drivers/file-system/utils.ts
4409
- function generateActorId(name, key) {
4410
- const jsonString = JSON.stringify([name, key]);
4411
- const crypto2 = getNodeCrypto();
4412
- const hash = crypto2.createHash("sha256").update(jsonString).digest("hex").substring(0, 16);
4413
- return hash;
4414
- }
4415
- function createHashForPath(dirPath) {
4416
- const path = getNodePath();
4417
- const normalizedPath = path.normalize(dirPath);
4418
- const lastComponent = path.basename(normalizedPath);
4419
- const crypto2 = getNodeCrypto();
4420
- const hash = crypto2.createHash("sha256").update(normalizedPath).digest("hex").substring(0, 8);
4421
- return `${lastComponent}-${hash}`;
4422
- }
4423
- function getStoragePath() {
4424
- const dataPath = getDataPath("rivetkit");
4425
- const dirHash = createHashForPath(process.cwd());
4426
- const path = getNodePath();
4427
- return path.join(dataPath, dirHash);
4428
- }
4429
- async function pathExists(path) {
4430
- try {
4431
- const fs = getNodeFs();
4432
- await fs.access(path);
4433
- return true;
4434
- } catch {
4435
- return false;
4436
- }
4437
- }
4438
- async function ensureDirectoryExists(directoryPath) {
4439
- if (!await pathExists(directoryPath)) {
4440
- const fs = getNodeFs();
4441
- await fs.mkdir(directoryPath, { recursive: true });
4442
- }
4443
- }
4444
- function ensureDirectoryExistsSync(directoryPath) {
4445
- const fsSync = getNodeFsSync();
4446
- if (!fsSync.existsSync(directoryPath)) {
4447
- fsSync.mkdirSync(directoryPath, { recursive: true });
4448
- }
4449
- }
4450
- function getDataPath(appName) {
4451
- const platform = process.platform;
4452
- const os = getNodeOs();
4453
- const homeDir = os.homedir();
4454
- const path = getNodePath();
4455
- switch (platform) {
4456
- case "win32":
4457
- return path.join(
4458
- process.env.APPDATA || path.join(homeDir, "AppData", "Roaming"),
4459
- appName
4460
- );
4461
- case "darwin":
4462
- return path.join(
4463
- homeDir,
4464
- "Library",
4465
- "Application Support",
4466
- appName
4467
- );
4468
- default:
4469
- return path.join(
4470
- process.env.XDG_DATA_HOME || path.join(homeDir, ".local", "share"),
4471
- appName
4472
- );
4473
- }
4474
- }
4475
-
4476
- // src/drivers/file-system/sqlite-runtime.ts
4477
- function normalizeParams(params) {
4478
- if (!params || params.length === 0) {
4479
- return [];
4480
- }
4481
- return params.map((value) => {
4482
- if (value instanceof Uint8Array) {
4483
- return Buffer.from(value);
4484
- }
4485
- return value;
4486
- });
4487
- }
4488
- function createPreparedDatabaseAdapter(rawDb, prepare) {
4489
- return {
4490
- exec: (sql) => {
4491
- rawDb.exec(sql);
4492
- },
4493
- run: (sql, params) => {
4494
- const stmt = prepare(sql);
4495
- stmt.run(...normalizeParams(params));
4496
- },
4497
- get: (sql, params) => {
4498
- const stmt = prepare(sql);
4499
- return stmt.get(...normalizeParams(params));
4500
- },
4501
- all: (sql, params) => {
4502
- const stmt = prepare(sql);
4503
- return stmt.all(...normalizeParams(params));
4504
- },
4505
- close: () => {
4506
- rawDb.close();
4507
- }
4508
- };
4509
- }
4510
- function configureSqliteRuntimeDatabase(rawDb, path) {
4511
- rawDb.exec("PRAGMA busy_timeout = 5000");
4512
- if (path !== ":memory:") {
4513
- rawDb.exec("PRAGMA journal_mode = WAL");
4514
- }
4515
- }
4516
- function loadSqliteRuntime() {
4517
- const requireFn = getRequireFn();
4518
- const loadErrors = [];
4519
- try {
4520
- const bunSqlite = requireFn(
4521
- /* webpackIgnore: true */
4522
- "bun:sqlite"
4523
- );
4524
- const BunDatabase = bunSqlite.Database;
4525
- if (BunDatabase) {
4526
- return {
4527
- kind: "bun",
4528
- open: (path) => {
4529
- var _a;
4530
- const rawDb = new BunDatabase(path);
4531
- configureSqliteRuntimeDatabase(rawDb, path);
4532
- const query = (_a = rawDb.query) == null ? void 0 : _a.bind(rawDb);
4533
- if (!query) throw new Error("bun:sqlite database missing query method");
4534
- return createPreparedDatabaseAdapter(rawDb, query);
4535
- }
4536
- };
4537
- }
4538
- } catch (error) {
4539
- loadErrors.push(`bun:sqlite unavailable: ${String(error)}`);
4540
- }
4541
- try {
4542
- const nodeSqlite = requireFn(
4543
- /* webpackIgnore: true */
4544
- "node:sqlite"
4545
- );
4546
- const NodeDatabaseSync = nodeSqlite.DatabaseSync;
4547
- if (NodeDatabaseSync) {
4548
- return {
4549
- kind: "node",
4550
- open: (path) => {
4551
- var _a;
4552
- const rawDb = new NodeDatabaseSync(path);
4553
- configureSqliteRuntimeDatabase(rawDb, path);
4554
- const prepare = (_a = rawDb.prepare) == null ? void 0 : _a.bind(rawDb);
4555
- if (!prepare) {
4556
- throw new Error("node:sqlite DatabaseSync missing prepare method");
4557
- }
4558
- return createPreparedDatabaseAdapter(rawDb, prepare);
4559
- }
4560
- };
4561
- }
4562
- } catch (error) {
4563
- loadErrors.push(`node:sqlite unavailable: ${String(error)}`);
4564
- }
4565
- try {
4566
- const betterSqlite3Module = requireFn(
4567
- /* webpackIgnore: true */
4568
- "better-sqlite3"
4569
- );
4570
- const BetterSqlite3 = typeof betterSqlite3Module === "function" ? betterSqlite3Module : betterSqlite3Module.default;
4571
- if (BetterSqlite3) {
4572
- return {
4573
- kind: "better-sqlite3",
4574
- open: (path) => {
4575
- var _a;
4576
- const rawDb = new BetterSqlite3(path);
4577
- configureSqliteRuntimeDatabase(rawDb, path);
4578
- const prepare = (_a = rawDb.prepare) == null ? void 0 : _a.bind(rawDb);
4579
- if (!prepare) {
4580
- throw new Error("better-sqlite3 database missing prepare method");
4581
- }
4582
- return createPreparedDatabaseAdapter(rawDb, prepare);
4583
- }
4584
- };
4585
- }
4586
- } catch (error) {
4587
- loadErrors.push(`better-sqlite3 unavailable: ${String(error)}`);
4588
- throw new Error(
4589
- `No SQLite runtime available. Tried bun:sqlite, node:sqlite, and better-sqlite3. Install better-sqlite3 (e.g. "pnpm add better-sqlite3") if native runtimes are unavailable.
4590
- ${loadErrors.join("\n")}`
4591
- );
4592
- }
4593
- throw new Error(
4594
- `No SQLite runtime available. Tried bun:sqlite, node:sqlite, and better-sqlite3.
4595
- ${loadErrors.join("\n")}`
4596
- );
4597
- }
4598
- function computePrefixUpperBound(prefix) {
4599
- if (prefix.length === 0) {
4600
- return void 0;
4601
- }
4602
- const upperBound = new Uint8Array(prefix);
4603
- for (let i = upperBound.length - 1; i >= 0; i--) {
4604
- if (upperBound[i] !== 255) {
4605
- upperBound[i] += 1;
4606
- return upperBound.slice(0, i + 1);
4607
- }
4608
- }
4609
- return void 0;
4610
- }
4611
- function ensureUint8Array(value, fieldName) {
4612
- if (value instanceof Uint8Array) {
4613
- return value;
4614
- }
4615
- if (value instanceof ArrayBuffer) {
4616
- return new Uint8Array(value);
4617
- }
4618
- if (ArrayBuffer.isView(value)) {
4619
- return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
4620
- }
4621
- throw new Error(`SQLite row field "${fieldName}" is not binary data`);
4622
- }
4623
-
4624
- // src/drivers/file-system/kv-limits.ts
4625
- var KV_MAX_KEY_SIZE = 2 * 1024;
4626
- var KV_MAX_VALUE_SIZE = 128 * 1024;
4627
- var KV_MAX_KEYS = 128;
4628
- var KV_MAX_PUT_PAYLOAD_SIZE = 976 * 1024;
4629
- var KV_MAX_STORAGE_SIZE = 10 * 1024 * 1024 * 1024;
4630
- var KV_KEY_WRAPPER_OVERHEAD_SIZE = 2;
4631
- function estimateKvSize(db) {
4632
- const row = db.get(
4633
- "SELECT COALESCE(SUM(LENGTH(key) + LENGTH(value)), 0) AS total FROM kv"
4634
- );
4635
- return row ? Number(row.total ?? 0) : 0;
4636
- }
4637
- function validateKvKey(key, keyLabel = "key") {
4638
- if (key.byteLength + KV_KEY_WRAPPER_OVERHEAD_SIZE > KV_MAX_KEY_SIZE) {
4639
- throw new Error(`${keyLabel} is too long (max 2048 bytes)`);
4640
- }
4641
- }
4642
- function validateKvKeys(keys) {
4643
- if (keys.length > KV_MAX_KEYS) {
4644
- throw new Error("a maximum of 128 keys is allowed");
4645
- }
4646
- for (const key of keys) {
4647
- validateKvKey(key);
4648
- }
4649
- }
4650
- function validateKvEntries(entries, totalSize) {
4651
- if (entries.length > KV_MAX_KEYS) {
4652
- throw new Error("A maximum of 128 key-value entries is allowed");
4653
- }
4654
- let payloadSize = 0;
4655
- for (const [key, value] of entries) {
4656
- payloadSize += key.byteLength + KV_KEY_WRAPPER_OVERHEAD_SIZE + value.byteLength;
4657
- }
4658
- if (payloadSize > KV_MAX_PUT_PAYLOAD_SIZE) {
4659
- throw new Error("total payload is too large (max 976 KiB)");
4660
- }
4661
- const storageRemaining = Math.max(0, KV_MAX_STORAGE_SIZE - totalSize);
4662
- if (payloadSize > storageRemaining) {
4663
- throw new Error(
4664
- `not enough space left in storage (${storageRemaining} bytes remaining, current payload is ${payloadSize} bytes)`
4665
- );
4666
- }
4667
- for (const [key, value] of entries) {
4668
- validateKvKey(key);
4669
- if (value.byteLength > KV_MAX_VALUE_SIZE) {
4670
- throw new Error(
4671
- `value is too large (max ${KV_MAX_VALUE_SIZE / 1024} KiB)`
4672
- );
4673
- }
4674
- }
4675
- }
4676
-
4677
- // src/drivers/file-system/global-state.ts
4678
- var FileSystemGlobalState = class {
4679
- #storagePath;
4680
- #stateDir;
4681
- #dbsDir;
4682
- #alarmsDir;
4683
- #persist;
4684
- #sqliteRuntime;
4685
- #actorKvDatabases = /* @__PURE__ */ new Map();
4686
- // IMPORTANT: Never delete from this map. Doing so will result in race
4687
- // conditions since the actor generation will cease to be tracked
4688
- // correctly. Always increment generation if a new actor is created.
4689
- #actors = /* @__PURE__ */ new Map();
4690
- #actorCountOnStartup = 0;
4691
- #runnerParams;
4692
- get persist() {
4693
- return this.#persist;
4694
- }
4695
- get storagePath() {
4696
- return this.#storagePath;
4697
- }
4698
- get actorCountOnStartup() {
4699
- return this.#actorCountOnStartup;
4700
- }
4701
- constructor(options = {}) {
4702
- const { persist = true, customPath, useNativeSqlite = true } = options;
4703
- if (!useNativeSqlite) {
4704
- throw new Error(
4705
- "File-system driver no longer supports non-SQLite KV storage."
4706
- );
4707
- }
4708
- this.#persist = persist;
4709
- this.#sqliteRuntime = loadSqliteRuntime();
4710
- this.#storagePath = persist ? customPath ?? getStoragePath() : "/tmp";
4711
- const path = getNodePath();
4712
- this.#stateDir = path.join(this.#storagePath, "state");
4713
- this.#dbsDir = path.join(this.#storagePath, "databases");
4714
- this.#alarmsDir = path.join(this.#storagePath, "alarms");
4715
- if (this.#persist) {
4716
- ensureDirectoryExistsSync(this.#stateDir);
4717
- ensureDirectoryExistsSync(this.#dbsDir);
4718
- ensureDirectoryExistsSync(this.#alarmsDir);
4719
- try {
4720
- const fsSync = getNodeFsSync();
4721
- const actorIds = fsSync.readdirSync(this.#stateDir);
4722
- this.#actorCountOnStartup = actorIds.length;
4723
- } catch (error) {
4724
- logger2().error({ msg: "failed to count actors", error });
4725
- }
4726
- logger2().debug({
4727
- msg: "file system driver ready",
4728
- dir: this.#storagePath,
4729
- actorCount: this.#actorCountOnStartup,
4730
- sqliteRuntime: this.#sqliteRuntime.kind
4731
- });
4732
- try {
4733
- this.#cleanupTempFilesSync();
4734
- } catch (err) {
4735
- logger2().error({
4736
- msg: "failed to cleanup temp files",
4737
- error: err
4738
- });
4739
- }
4740
- try {
4741
- this.#migrateLegacyKvToSqliteOnStartupSync();
4742
- } catch (error) {
4743
- logger2().error({
4744
- msg: "failed legacy kv startup migration",
4745
- error
4746
- });
4747
- throw error;
4748
- }
4749
- } else {
4750
- logger2().debug({
4751
- msg: "memory driver ready",
4752
- sqliteRuntime: this.#sqliteRuntime.kind
4753
- });
4754
- }
4755
- }
4756
- getActorStatePath(actorId) {
4757
- return getNodePath().join(this.#stateDir, actorId);
4758
- }
4759
- getActorDbPath(actorId) {
4760
- return getNodePath().join(this.#dbsDir, `${actorId}.db`);
4761
- }
4762
- getActorAlarmPath(actorId) {
4763
- return getNodePath().join(this.#alarmsDir, actorId);
4764
- }
4765
- #getActorKvDatabasePath(actorId) {
4766
- if (this.#persist) {
4767
- return this.getActorDbPath(actorId);
4768
- }
4769
- return ":memory:";
4770
- }
4771
- #ensureActorKvTables(db) {
4772
- db.exec(`
4773
- CREATE TABLE IF NOT EXISTS kv (
4774
- key BLOB PRIMARY KEY NOT NULL,
4775
- value BLOB NOT NULL
4776
- )
4777
- `);
4778
- }
4779
- #getOrCreateActorKvDatabase(actorId) {
4780
- const existing = this.#actorKvDatabases.get(actorId);
4781
- if (existing) {
4782
- return existing;
4783
- }
4784
- const dbPath = this.#getActorKvDatabasePath(actorId);
4785
- if (this.#persist) {
4786
- const path = getNodePath();
4787
- ensureDirectoryExistsSync(path.dirname(dbPath));
4788
- }
4789
- let db;
4790
- try {
4791
- db = this.#sqliteRuntime.open(dbPath);
4792
- } catch (error) {
4793
- throw new Error(
4794
- `failed to open actor kv database for actor ${actorId} at ${dbPath}: ${error}`
4795
- );
4796
- }
4797
- this.#ensureActorKvTables(db);
4798
- this.#actorKvDatabases.set(actorId, db);
4799
- return db;
4800
- }
4801
- #closeActorKvDatabase(actorId) {
4802
- const db = this.#actorKvDatabases.get(actorId);
4803
- if (!db) {
4804
- return;
4805
- }
4806
- try {
4807
- db.close();
4808
- } finally {
4809
- this.#actorKvDatabases.delete(actorId);
4810
- }
4811
- }
4812
- #putKvEntriesInDb(db, entries) {
4813
- if (entries.length === 0) {
4814
- return;
4815
- }
4816
- db.exec("BEGIN");
4817
- try {
4818
- for (const [key, value] of entries) {
4819
- db.run("INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)", [
4820
- key,
4821
- value
4822
- ]);
4823
- }
4824
- db.exec("COMMIT");
4825
- } catch (error) {
4826
- try {
4827
- db.exec("ROLLBACK");
4828
- } catch {
4829
- }
4830
- throw error;
4831
- }
4832
- }
4833
- #isKvDbPopulated(db) {
4834
- const row = db.get(
4835
- "SELECT COUNT(*) AS count FROM kv"
4836
- );
4837
- const count = row ? Number(row.count) : 0;
4838
- return count > 0;
4839
- }
4840
- #migrateLegacyKvToSqliteOnStartupSync() {
4841
- const fsSync = getNodeFsSync();
4842
- if (!fsSync.existsSync(this.#stateDir)) {
4843
- return;
4844
- }
4845
- const actorIds = fsSync.readdirSync(this.#stateDir).filter((id) => !id.includes(".tmp."));
4846
- for (const actorId of actorIds) {
4847
- const statePath = this.getActorStatePath(actorId);
4848
- let state;
4849
- try {
4850
- const stateBytes = fsSync.readFileSync(statePath);
4851
- state = ACTOR_STATE_VERSIONED.deserializeWithEmbeddedVersion(
4852
- new Uint8Array(stateBytes)
4853
- );
4854
- } catch (error) {
4855
- logger2().warn({
4856
- msg: "failed to parse actor state during startup migration",
4857
- actorId,
4858
- error
4859
- });
4860
- continue;
4861
- }
4862
- if (!state.kvStorage || state.kvStorage.length === 0) {
4863
- continue;
4864
- }
4865
- const dbPath = this.getActorDbPath(actorId);
4866
- const path = getNodePath();
4867
- ensureDirectoryExistsSync(path.dirname(dbPath));
4868
- const db = this.#sqliteRuntime.open(dbPath);
4869
- try {
4870
- this.#ensureActorKvTables(db);
4871
- if (this.#isKvDbPopulated(db)) {
4872
- continue;
4873
- }
4874
- const legacyEntries = state.kvStorage.map((entry) => [
4875
- new Uint8Array(entry.key),
4876
- new Uint8Array(entry.value)
4877
- ]);
4878
- this.#putKvEntriesInDb(db, legacyEntries);
4879
- logger2().info({
4880
- msg: "migrated legacy actor kv storage to sqlite",
4881
- actorId,
4882
- entryCount: legacyEntries.length
4883
- });
4884
- } finally {
4885
- db.close();
4886
- }
4887
- }
4888
- }
4889
- async *getActorsIterator(params) {
4890
- let actorIds = Array.from(this.#actors.keys()).sort();
4891
- const fsSync = getNodeFsSync();
4892
- if (fsSync.existsSync(this.#stateDir)) {
4893
- actorIds = fsSync.readdirSync(this.#stateDir).filter((id) => !id.includes(".tmp")).sort();
4894
- }
4895
- const startIndex = params.cursor ? actorIds.indexOf(params.cursor) + 1 : 0;
4896
- for (let i = startIndex; i < actorIds.length; i++) {
4897
- const actorId = actorIds[i];
4898
- if (!actorId) {
4899
- continue;
4900
- }
4901
- try {
4902
- const state = await this.loadActorStateOrError(actorId);
4903
- yield state;
4904
- } catch (error) {
4905
- logger2().error({
4906
- msg: "failed to load actor state",
4907
- actorId,
4908
- error
4909
- });
4910
- }
4911
- }
4912
- }
4913
- /**
4914
- * Ensures an entry exists for this actor.
4915
- *
4916
- * Used for #createActor and #loadActor.
4917
- */
4918
- #upsertEntry(actorId) {
4919
- let entry = this.#actors.get(actorId);
4920
- if (entry) {
4921
- return entry;
4922
- }
4923
- entry = {
4924
- id: actorId,
4925
- lifecycleState: 0 /* NONEXISTENT */,
4926
- generation: crypto.randomUUID()
4927
- };
4928
- this.#actors.set(actorId, entry);
4929
- return entry;
4930
- }
4931
- /**
4932
- * Creates a new actor and writes to file system.
4933
- */
4934
- async createActor(actorId, name, key, input) {
4935
- await this.#waitForActorStop(actorId);
4936
- let entry = this.#upsertEntry(actorId);
4937
- if (entry.state) {
4938
- throw new ActorDuplicateKey(name, key);
4939
- }
4940
- if (this.isActorStopping(actorId)) {
4941
- await this.#waitForActorStop(actorId);
4942
- entry = this.#upsertEntry(actorId);
4943
- }
4944
- if (entry.lifecycleState === 4 /* DESTROYED */) {
4945
- entry.lifecycleState = 0 /* NONEXISTENT */;
4946
- entry.generation = crypto.randomUUID();
4947
- }
4948
- const initialKvState = getInitialActorKvState(input);
4949
- await this.#withActorWrite(actorId, async (lockedEntry) => {
4950
- lockedEntry.state = {
4951
- actorId,
4952
- name,
4953
- key,
4954
- createdAt: BigInt(Date.now()),
4955
- kvStorage: [],
4956
- startTs: null,
4957
- connectableTs: null,
4958
- sleepTs: null,
4959
- destroyTs: null
4960
- };
4961
- lockedEntry.lifecycleState = 1 /* AWAKE */;
4962
- if (this.#persist) {
4963
- await this.#performWrite(
4964
- actorId,
4965
- lockedEntry.generation,
4966
- lockedEntry.state
4967
- );
4968
- }
4969
- if (initialKvState.length > 0) {
4970
- const db = this.#getOrCreateActorKvDatabase(actorId);
4971
- this.#putKvEntriesInDb(db, initialKvState);
4972
- }
4973
- });
4974
- return entry;
4975
- }
4976
- /**
4977
- * Loads the actor from disk or returns the existing actor entry. This will return an entry even if the actor does not actually exist.
4978
- */
4979
- async loadActor(actorId) {
4980
- const entry = this.#upsertEntry(actorId);
4981
- if (entry.lifecycleState === 4 /* DESTROYED */) {
4982
- return entry;
4983
- }
4984
- if (entry.state) {
4985
- return entry;
4986
- }
4987
- if (!this.#persist) {
4988
- return entry;
4989
- }
4990
- if (entry.loadPromise) {
4991
- await entry.loadPromise;
4992
- return entry;
4993
- }
4994
- entry.loadPromise = this.loadActorState(entry);
4995
- return entry.loadPromise;
4996
- }
4997
- async loadActorState(entry) {
4998
- const stateFilePath = this.getActorStatePath(entry.id);
4999
- try {
5000
- const fs = getNodeFs();
5001
- const stateData = await fs.readFile(stateFilePath);
5002
- const loadedState = ACTOR_STATE_VERSIONED.deserializeWithEmbeddedVersion(
5003
- new Uint8Array(stateData)
5004
- );
5005
- entry.state = {
5006
- ...loadedState,
5007
- kvStorage: []
5008
- };
5009
- return entry;
5010
- } catch (innerError) {
5011
- if (innerError.code === "ENOENT") {
5012
- entry.loadPromise = void 0;
5013
- return entry;
5014
- }
5015
- const error = new Error(
5016
- `Failed to load actor state: ${innerError}`
5017
- );
5018
- throw error;
5019
- }
5020
- }
5021
- async loadOrCreateActor(actorId, name, key, input) {
5022
- await this.#waitForActorStop(actorId);
5023
- const entry = await this.loadActor(actorId);
5024
- if (!entry.state) {
5025
- if (this.isActorStopping(actorId)) {
5026
- await this.#waitForActorStop(actorId);
5027
- return await this.loadOrCreateActor(actorId, name, key, input);
5028
- }
5029
- if (entry.lifecycleState === 4 /* DESTROYED */) {
5030
- entry.lifecycleState = 0 /* NONEXISTENT */;
5031
- entry.generation = crypto.randomUUID();
5032
- }
5033
- const initialKvState = getInitialActorKvState(input);
5034
- await this.#withActorWrite(actorId, async (lockedEntry) => {
5035
- lockedEntry.state = {
5036
- actorId,
5037
- name,
5038
- key,
5039
- createdAt: BigInt(Date.now()),
5040
- kvStorage: [],
5041
- startTs: null,
5042
- connectableTs: null,
5043
- sleepTs: null,
5044
- destroyTs: null
5045
- };
5046
- if (this.#persist) {
5047
- await this.#performWrite(
5048
- actorId,
5049
- lockedEntry.generation,
5050
- lockedEntry.state
5051
- );
5052
- }
5053
- if (initialKvState.length > 0) {
5054
- const db = this.#getOrCreateActorKvDatabase(actorId);
5055
- this.#putKvEntriesInDb(db, initialKvState);
5056
- }
5057
- });
5058
- }
5059
- return entry;
5060
- }
5061
- async sleepActor(actorId) {
5062
- var _a, _b;
5063
- invariant3(
5064
- this.#persist,
5065
- "cannot sleep actor with memory driver, must use file system driver"
5066
- );
5067
- const actor = this.#upsertEntry(actorId);
5068
- invariant3(actor, `tried to sleep ${actorId}, does not exist`);
5069
- if (this.isActorStopping(actorId)) {
5070
- return;
5071
- }
5072
- actor.lifecycleState = 2 /* STARTING_SLEEP */;
5073
- actor.stopPromise = promiseWithResolvers((reason) => logger2().warn({ msg: "unhandled actor sleep stop promise rejection", reason }));
5074
- if (actor.loadPromise) await actor.loadPromise.catch();
5075
- if ((_a = actor.startPromise) == null ? void 0 : _a.promise)
5076
- await actor.startPromise.promise.catch();
5077
- try {
5078
- if (actor.state) {
5079
- await this.#withActorWrite(actorId, async (lockedEntry) => {
5080
- if (!lockedEntry.state) {
5081
- return;
5082
- }
5083
- lockedEntry.state = {
5084
- ...lockedEntry.state,
5085
- sleepTs: BigInt(Date.now())
5086
- };
5087
- if (this.#persist) {
5088
- await this.#performWrite(
5089
- actorId,
5090
- lockedEntry.generation,
5091
- lockedEntry.state
5092
- );
5093
- }
5094
- });
5095
- }
5096
- invariant3(actor.actor, "actor should be loaded");
5097
- await actor.actor.onStop("sleep");
5098
- } finally {
5099
- await this.#withActorWrite(actorId, async () => {
5100
- });
5101
- this.#closeActorKvDatabase(actorId);
5102
- (_b = actor.stopPromise) == null ? void 0 : _b.resolve();
5103
- actor.stopPromise = void 0;
5104
- this.#actors.delete(actorId);
5105
- }
5106
- }
5107
- async destroyActor(actorId) {
5108
- var _a, _b;
5109
- const actor = this.#upsertEntry(actorId);
5110
- if (this.isActorStopping(actorId)) {
5111
- return;
5112
- }
5113
- actor.lifecycleState = 3 /* STARTING_DESTROY */;
5114
- actor.stopPromise = promiseWithResolvers((reason) => logger2().warn({ msg: "unhandled actor destroy stop promise rejection", reason }));
5115
- if (actor.loadPromise) await actor.loadPromise.catch();
5116
- if ((_a = actor.startPromise) == null ? void 0 : _a.promise)
5117
- await actor.startPromise.promise.catch();
5118
- try {
5119
- if (actor.state) {
5120
- await this.#withActorWrite(actorId, async (lockedEntry) => {
5121
- if (!lockedEntry.state) {
5122
- return;
5123
- }
5124
- lockedEntry.state = {
5125
- ...lockedEntry.state,
5126
- destroyTs: BigInt(Date.now())
5127
- };
5128
- if (this.#persist) {
5129
- await this.#performWrite(
5130
- actorId,
5131
- lockedEntry.generation,
5132
- lockedEntry.state
5133
- );
5134
- }
5135
- });
5136
- }
5137
- if (actor.actor) {
5138
- await actor.actor.onStop("destroy");
5139
- }
5140
- await this.#withActorWrite(actorId, async () => {
5141
- });
5142
- this.#closeActorKvDatabase(actorId);
5143
- if (actor.alarmTimeout) {
5144
- actor.alarmTimeout.abort();
5145
- }
5146
- if (this.#persist) {
5147
- const fs = getNodeFs();
5148
- await Promise.all([
5149
- // Delete actor state file
5150
- (async () => {
5151
- try {
5152
- await fs.unlink(this.getActorStatePath(actorId));
5153
- } catch (err) {
5154
- if ((err == null ? void 0 : err.code) !== "ENOENT") {
5155
- logger2().error({
5156
- msg: "failed to delete actor state file",
5157
- actorId,
5158
- error: stringifyError(err)
5159
- });
5160
- }
5161
- }
5162
- })(),
5163
- // Delete actor database file
5164
- (async () => {
5165
- try {
5166
- await fs.unlink(this.getActorDbPath(actorId));
5167
- } catch (err) {
5168
- if ((err == null ? void 0 : err.code) !== "ENOENT") {
5169
- logger2().error({
5170
- msg: "failed to delete actor database file",
5171
- actorId,
5172
- error: stringifyError(err)
5173
- });
5174
- }
5175
- }
5176
- })(),
5177
- // Delete actor alarm file
5178
- (async () => {
5179
- try {
5180
- await fs.unlink(this.getActorAlarmPath(actorId));
5181
- } catch (err) {
5182
- if ((err == null ? void 0 : err.code) !== "ENOENT") {
5183
- logger2().error({
5184
- msg: "failed to delete actor alarm file",
5185
- actorId,
5186
- error: stringifyError(err)
5187
- });
5188
- }
5189
- }
5190
- })()
5191
- ]);
5192
- }
5193
- } finally {
5194
- await this.#withActorWrite(actorId, async () => {
5195
- });
5196
- (_b = actor.stopPromise) == null ? void 0 : _b.resolve();
5197
- actor.stopPromise = void 0;
5198
- actor.state = void 0;
5199
- actor.loadPromise = void 0;
5200
- actor.actor = void 0;
5201
- actor.startPromise = void 0;
5202
- actor.alarmTimeout = void 0;
5203
- actor.alarmTimeout = void 0;
5204
- actor.pendingWriteResolver = void 0;
5205
- actor.lifecycleState = 4 /* DESTROYED */;
5206
- }
5207
- }
5208
- /**
5209
- * Save actor state to disk.
5210
- */
5211
- async writeActor(actorId, generation, state) {
5212
- if (!this.#persist) {
5213
- return;
5214
- }
5215
- await this.#withActorWrite(actorId, async () => {
5216
- await this.#performWrite(actorId, generation, state);
5217
- });
5218
- }
5219
- isGenerationCurrentAndNotDestroyed(actorId, generation) {
5220
- const entry = this.#upsertEntry(actorId);
5221
- if (!entry) return false;
5222
- return entry.generation === generation && entry.lifecycleState !== 3 /* STARTING_DESTROY */;
5223
- }
5224
- isActorStopping(actorId) {
5225
- const entry = this.#upsertEntry(actorId);
5226
- if (!entry) return false;
5227
- return entry.lifecycleState === 2 /* STARTING_SLEEP */ || entry.lifecycleState === 3 /* STARTING_DESTROY */;
5228
- }
5229
- async #waitForActorStop(actorId) {
5230
- while (true) {
5231
- const entry = this.#actors.get(actorId);
5232
- if (!(entry == null ? void 0 : entry.stopPromise)) {
5233
- return;
5234
- }
5235
- try {
5236
- await entry.stopPromise.promise;
5237
- } catch {
5238
- return;
5239
- }
5240
- }
5241
- }
5242
- async #withActorWrite(actorId, fn) {
5243
- const entry = this.#actors.get(actorId);
5244
- invariant3(entry, "actor entry does not exist");
5245
- const previousWrite = entry.pendingWriteResolver;
5246
- const currentWrite = promiseWithResolvers((reason) => logger2().warn({ msg: "unhandled kv write promise rejection", reason }));
5247
- entry.pendingWriteResolver = currentWrite;
5248
- if (previousWrite) {
5249
- try {
5250
- await previousWrite.promise;
5251
- } catch {
5252
- }
5253
- }
5254
- try {
5255
- return await fn(entry);
5256
- } finally {
5257
- currentWrite.resolve();
5258
- if (entry.pendingWriteResolver === currentWrite) {
5259
- entry.pendingWriteResolver = void 0;
5260
- }
5261
- }
5262
- }
5263
- async #waitForPendingWrite(actorId) {
5264
- const entry = this.#actors.get(actorId);
5265
- if (!(entry == null ? void 0 : entry.pendingWriteResolver)) {
5266
- return;
5267
- }
5268
- while (entry.pendingWriteResolver) {
5269
- const pending = entry.pendingWriteResolver;
5270
- try {
5271
- await pending.promise;
5272
- } catch {
5273
- }
5274
- }
5275
- }
5276
- async setActorAlarm(actorId, timestamp) {
5277
- const entry = this.#actors.get(actorId);
5278
- invariant3(entry, "actor entry does not exist");
5279
- const writeGeneration = entry.generation;
5280
- if (this.isActorStopping(actorId)) {
5281
- logger2().info("skipping set alarm since actor stopping");
5282
- return;
5283
- }
5284
- if (this.#persist) {
5285
- const alarmPath = this.getActorAlarmPath(actorId);
5286
- const crypto2 = getNodeCrypto();
5287
- const tempPath = `${alarmPath}.tmp.${crypto2.randomUUID()}`;
5288
- try {
5289
- const path = getNodePath();
5290
- await ensureDirectoryExists(path.dirname(alarmPath));
5291
- const alarmData = {
5292
- actorId,
5293
- timestamp: BigInt(timestamp)
5294
- };
5295
- const data = ACTOR_ALARM_VERSIONED.serializeWithEmbeddedVersion(
5296
- alarmData,
5297
- CURRENT_VERSION3
5298
- );
5299
- const fs = getNodeFs();
5300
- await fs.writeFile(tempPath, data);
5301
- if (!this.isGenerationCurrentAndNotDestroyed(
5302
- actorId,
5303
- writeGeneration
5304
- )) {
5305
- logger2().debug(
5306
- "skipping writing alarm since actor destroying or new generation"
5307
- );
5308
- return;
5309
- }
5310
- await fs.rename(tempPath, alarmPath);
5311
- } catch (error) {
5312
- try {
5313
- const fs = getNodeFs();
5314
- await fs.unlink(tempPath);
5315
- } catch {
5316
- }
5317
- logger2().error({
5318
- msg: "failed to write alarm",
5319
- actorId,
5320
- error
5321
- });
5322
- throw new Error(`Failed to write alarm: ${error}`);
5323
- }
5324
- }
5325
- this.#scheduleAlarmTimeout(actorId, timestamp);
5326
- }
5327
- /**
5328
- * Perform the actual write operation with atomic writes
5329
- */
5330
- async #performWrite(actorId, generation, state) {
5331
- const dataPath = this.getActorStatePath(actorId);
5332
- const crypto2 = getNodeCrypto();
5333
- const tempPath = `${dataPath}.tmp.${crypto2.randomUUID()}`;
5334
- try {
5335
- const path = getNodePath();
5336
- await ensureDirectoryExists(path.dirname(dataPath));
5337
- const bareState = {
5338
- actorId: state.actorId,
5339
- name: state.name,
5340
- key: state.key,
5341
- createdAt: state.createdAt,
5342
- kvStorage: state.kvStorage,
5343
- startTs: state.startTs,
5344
- connectableTs: state.connectableTs,
5345
- sleepTs: state.sleepTs,
5346
- destroyTs: state.destroyTs
5347
- };
5348
- const serializedState = ACTOR_STATE_VERSIONED.serializeWithEmbeddedVersion(
5349
- bareState,
5350
- CURRENT_VERSION3
5351
- );
5352
- const fs = getNodeFs();
5353
- await fs.writeFile(tempPath, serializedState);
5354
- if (!this.isGenerationCurrentAndNotDestroyed(actorId, generation)) {
5355
- logger2().debug(
5356
- "skipping writing alarm since actor destroying or new generation"
5357
- );
5358
- return;
5359
- }
5360
- await fs.rename(tempPath, dataPath);
5361
- } catch (error) {
5362
- try {
5363
- const fs = getNodeFs();
5364
- await fs.unlink(tempPath);
5365
- } catch {
5366
- }
5367
- logger2().error({
5368
- msg: "failed to save actor state",
5369
- actorId,
5370
- error
5371
- });
5372
- throw new Error(`Failed to save actor state: ${error}`);
5373
- }
5374
- }
5375
- /**
5376
- * Call this method after the actor driver has been initiated.
5377
- *
5378
- * This will trigger all initial alarms from the file system.
5379
- *
5380
- * This needs to be sync since DriverConfig.actor is sync
5381
- */
5382
- onRunnerStart(config4, inlineClient, actorDriver) {
5383
- if (this.#runnerParams) {
5384
- return;
5385
- }
5386
- this.#runnerParams = {
5387
- config: config4,
5388
- inlineClient,
5389
- actorDriver
5390
- };
5391
- try {
5392
- this.#loadAlarmsSync();
5393
- } catch (err) {
5394
- logger2().error({
5395
- msg: "failed to load alarms on startup",
5396
- error: err
5397
- });
5398
- }
5399
- }
5400
- async startActor(config4, inlineClient, actorDriver, actorId) {
5401
- var _a;
5402
- await this.#waitForActorStop(actorId);
5403
- let entry = await this.loadActor(actorId);
5404
- if (!entry.state) {
5405
- throw new Error(
5406
- `Actor does not exist and cannot be started: "${actorId}"`
5407
- );
5408
- }
5409
- if (entry.startPromise) {
5410
- await entry.startPromise.promise;
5411
- invariant3(entry.actor, "actor should have loaded");
5412
- return entry.actor;
5413
- }
5414
- if (entry.actor) {
5415
- if (entry.actor.isStopping || this.isActorStopping(actorId)) {
5416
- await this.#waitForActorStop(actorId);
5417
- entry = await this.loadActor(actorId);
5418
- if (!entry.state) {
5419
- throw new Error(
5420
- `Actor does not exist and cannot be started: "${actorId}"`
5421
- );
5422
- }
5423
- } else {
5424
- return entry.actor;
5425
- }
5426
- }
5427
- entry.startPromise = promiseWithResolvers((reason) => logger2().warn({ msg: "unhandled actor start promise rejection", reason }));
5428
- try {
5429
- const definition = lookupInRegistry(config4, entry.state.name);
5430
- entry.actor = await definition.instantiate();
5431
- entry.lifecycleState = 1 /* AWAKE */;
5432
- await entry.actor.start(
5433
- actorDriver,
5434
- inlineClient,
5435
- actorId,
5436
- entry.state.name,
5437
- entry.state.key,
5438
- "unknown"
5439
- );
5440
- const now = BigInt(Date.now());
5441
- await this.#withActorWrite(actorId, async (lockedEntry) => {
5442
- if (!lockedEntry.state) {
5443
- throw new Error(
5444
- `Actor does not exist and cannot be started: "${actorId}"`
5445
- );
5446
- }
5447
- lockedEntry.state = {
5448
- ...lockedEntry.state,
5449
- startTs: now,
5450
- connectableTs: now,
5451
- sleepTs: null
5452
- // Clear sleep timestamp when actor wakes up
5453
- };
5454
- if (this.#persist) {
5455
- await this.#performWrite(
5456
- actorId,
5457
- lockedEntry.generation,
5458
- lockedEntry.state
5459
- );
5460
- }
5461
- });
5462
- entry.startPromise.resolve();
5463
- entry.startPromise = void 0;
5464
- return entry.actor;
5465
- } catch (innerError) {
5466
- const error = new Error(
5467
- `Failed to start actor ${actorId}: ${innerError}`,
5468
- { cause: innerError }
5469
- );
5470
- (_a = entry.startPromise) == null ? void 0 : _a.reject(error);
5471
- entry.startPromise = void 0;
5472
- throw error;
5473
- }
5474
- }
5475
- async loadActorStateOrError(actorId) {
5476
- const state = (await this.loadActor(actorId)).state;
5477
- if (!state) throw new Error(`Actor does not exist: ${actorId}`);
5478
- return state;
5479
- }
5480
- getActorOrError(actorId) {
5481
- const entry = this.#actors.get(actorId);
5482
- if (!entry) throw new Error(`No entry for actor: ${actorId}`);
5483
- return entry;
5484
- }
5485
- async createDatabase(actorId) {
5486
- return this.getActorDbPath(actorId);
5487
- }
5488
- /**
5489
- * Load all persisted alarms from disk and schedule their timers.
5490
- */
5491
- #loadAlarmsSync() {
5492
- try {
5493
- const fsSync = getNodeFsSync();
5494
- const files = fsSync.existsSync(this.#alarmsDir) ? fsSync.readdirSync(this.#alarmsDir) : [];
5495
- for (const file of files) {
5496
- if (file.includes(".tmp.")) continue;
5497
- const path = getNodePath();
5498
- const fullPath = path.join(this.#alarmsDir, file);
5499
- try {
5500
- const buf = fsSync.readFileSync(fullPath);
5501
- const alarmData = ACTOR_ALARM_VERSIONED.deserializeWithEmbeddedVersion(
5502
- new Uint8Array(buf)
5503
- );
5504
- const timestamp = Number(alarmData.timestamp);
5505
- if (Number.isFinite(timestamp)) {
5506
- this.#scheduleAlarmTimeout(
5507
- alarmData.actorId,
5508
- timestamp
5509
- );
5510
- } else {
5511
- logger2().debug({
5512
- msg: "invalid alarm file contents",
5513
- file
5514
- });
5515
- }
5516
- } catch (err) {
5517
- logger2().error({
5518
- msg: "failed to read alarm file",
5519
- file,
5520
- error: stringifyError(err)
5521
- });
5522
- }
5523
- }
5524
- } catch (err) {
5525
- logger2().error({
5526
- msg: "failed to list alarms directory",
5527
- error: err
5528
- });
5529
- }
5530
- }
5531
- /**
5532
- * Schedule an alarm timer for an actor without writing to disk.
5533
- */
5534
- #scheduleAlarmTimeout(actorId, timestamp) {
5535
- var _a;
5536
- const entry = this.#upsertEntry(actorId);
5537
- if (entry.alarmTimestamp !== void 0 && timestamp >= entry.alarmTimestamp) {
5538
- logger2().debug({
5539
- msg: "skipping alarm schedule (later than existing)",
5540
- actorId,
5541
- timestamp,
5542
- current: entry.alarmTimestamp
5543
- });
5544
- return;
5545
- }
5546
- logger2().debug({ msg: "scheduling alarm", actorId, timestamp });
5547
- (_a = entry.alarmTimeout) == null ? void 0 : _a.abort();
5548
- entry.alarmTimestamp = timestamp;
5549
- const delay = Math.max(0, timestamp - Date.now());
5550
- entry.alarmTimeout = setLongTimeout(async () => {
5551
- entry.alarmTimestamp = void 0;
5552
- if (this.#persist) {
5553
- try {
5554
- const fs = getNodeFs();
5555
- await fs.unlink(this.getActorAlarmPath(actorId));
5556
- } catch (err) {
5557
- if ((err == null ? void 0 : err.code) !== "ENOENT") {
5558
- logger2().debug({
5559
- msg: "failed to remove alarm file",
5560
- actorId,
5561
- error: stringifyError(err)
5562
- });
5563
- }
5564
- }
5565
- }
5566
- try {
5567
- logger2().debug({ msg: "triggering alarm", actorId, timestamp });
5568
- const loaded = await this.loadActor(actorId);
5569
- if (!loaded.state)
5570
- throw new Error(`Actor does not exist: ${actorId}`);
5571
- const runnerParams = this.#runnerParams;
5572
- invariant3(runnerParams, "missing runner params");
5573
- if (!loaded.actor) {
5574
- await this.startActor(
5575
- runnerParams.config,
5576
- runnerParams.inlineClient,
5577
- runnerParams.actorDriver,
5578
- actorId
5579
- );
5580
- }
5581
- invariant3(loaded.actor, "actor should be loaded after wake");
5582
- await loaded.actor.onAlarm();
5583
- } catch (err) {
5584
- logger2().error({
5585
- msg: "failed to handle alarm",
5586
- actorId,
5587
- error: stringifyError(err)
5588
- });
5589
- }
5590
- }, delay);
5591
- }
5592
- /**
5593
- * Cleanup stale temp files on startup (synchronous)
5594
- */
5595
- #cleanupTempFilesSync() {
5596
- try {
5597
- const fsSync = getNodeFsSync();
5598
- const files = fsSync.readdirSync(this.#stateDir);
5599
- const tempFiles = files.filter((f) => f.includes(".tmp."));
5600
- const oneHourAgo = Date.now() - 36e5;
5601
- for (const tempFile of tempFiles) {
5602
- try {
5603
- const path = getNodePath();
5604
- const fullPath = path.join(this.#stateDir, tempFile);
5605
- const stat = fsSync.statSync(fullPath);
5606
- if (stat.mtimeMs < oneHourAgo) {
5607
- fsSync.unlinkSync(fullPath);
5608
- logger2().info({
5609
- msg: "cleaned up stale temp file",
5610
- file: tempFile
5611
- });
5612
- }
5613
- } catch (err) {
5614
- logger2().debug({
5615
- msg: "failed to cleanup temp file",
5616
- file: tempFile,
5617
- error: err
5618
- });
5619
- }
5620
- }
5621
- } catch (err) {
5622
- logger2().error({
5623
- msg: "failed to read actors directory for cleanup",
5624
- error: err
5625
- });
5626
- }
5627
- }
5628
- /**
5629
- * Batch put KV entries for an actor.
5630
- */
5631
- async kvBatchPut(actorId, entries) {
5632
- await this.loadActor(actorId);
5633
- await this.#withActorWrite(actorId, async (entry) => {
5634
- if (!entry.state) {
5635
- if (this.isActorStopping(actorId)) {
5636
- return;
5637
- }
5638
- throw new Error(`Actor ${actorId} state not loaded`);
5639
- }
5640
- const db = this.#getOrCreateActorKvDatabase(actorId);
5641
- const totalSize = estimateKvSize(db);
5642
- validateKvEntries(entries, totalSize);
5643
- this.#putKvEntriesInDb(db, entries);
5644
- });
5645
- }
5646
- /**
5647
- * Batch get KV entries for an actor.
5648
- */
5649
- async kvBatchGet(actorId, keys) {
5650
- const entry = await this.loadActor(actorId);
5651
- await this.#waitForPendingWrite(actorId);
5652
- if (!entry.state) {
5653
- if (this.isActorStopping(actorId)) {
5654
- throw new Error(`Actor ${actorId} is stopping`);
5655
- } else {
5656
- throw new Error(`Actor ${actorId} state not loaded`);
5657
- }
5658
- }
5659
- validateKvKeys(keys);
5660
- const db = this.#getOrCreateActorKvDatabase(actorId);
5661
- const results = [];
5662
- for (const key of keys) {
5663
- const row = db.get(
5664
- "SELECT value FROM kv WHERE key = ?",
5665
- [key]
5666
- );
5667
- if (!row) {
5668
- results.push(null);
5669
- continue;
5670
- }
5671
- results.push(ensureUint8Array(row.value, "value"));
5672
- }
5673
- return results;
5674
- }
5675
- /**
5676
- * Batch delete KV entries for an actor.
5677
- */
5678
- async kvBatchDelete(actorId, keys) {
5679
- await this.loadActor(actorId);
5680
- await this.#withActorWrite(actorId, async (entry) => {
5681
- if (!entry.state) {
5682
- if (this.isActorStopping(actorId)) {
5683
- return;
5684
- }
5685
- throw new Error(`Actor ${actorId} state not loaded`);
5686
- }
5687
- if (keys.length === 0) {
5688
- return;
5689
- }
5690
- validateKvKeys(keys);
5691
- const db = this.#getOrCreateActorKvDatabase(actorId);
5692
- db.exec("BEGIN");
5693
- try {
5694
- for (const key of keys) {
5695
- db.run("DELETE FROM kv WHERE key = ?", [key]);
5696
- }
5697
- db.exec("COMMIT");
5698
- } catch (error) {
5699
- try {
5700
- db.exec("ROLLBACK");
5701
- } catch {
5702
- }
5703
- throw error;
5704
- }
5705
- });
5706
- }
5707
- /**
5708
- * List KV entries with a given prefix for an actor.
5709
- */
5710
- async kvListPrefix(actorId, prefix) {
5711
- const entry = await this.loadActor(actorId);
5712
- await this.#waitForPendingWrite(actorId);
5713
- if (!entry.state) {
5714
- if (this.isActorStopping(actorId)) {
5715
- throw new Error(`Actor ${actorId} is destroying`);
5716
- } else {
5717
- throw new Error(`Actor ${actorId} state not loaded`);
5718
- }
5719
- }
5720
- validateKvKey(prefix, "prefix key");
5721
- const db = this.#getOrCreateActorKvDatabase(actorId);
5722
- const upperBound = computePrefixUpperBound(prefix);
5723
- const rows = upperBound ? db.all(
5724
- "SELECT key, value FROM kv WHERE key >= ? AND key < ? ORDER BY key ASC",
5725
- [prefix, upperBound]
5726
- ) : db.all(
5727
- "SELECT key, value FROM kv WHERE key >= ? ORDER BY key ASC",
5728
- [prefix]
5729
- );
5730
- return rows.map((row) => [
5731
- ensureUint8Array(row.key, "key"),
5732
- ensureUint8Array(row.value, "value")
5733
- ]);
5734
- }
5735
- };
5736
-
5737
- // src/drivers/file-system/manager.ts
5738
- import invariant4 from "invariant";
5739
- var FileSystemManagerDriver = class {
5740
- #config;
5741
- #state;
5742
- #driverConfig;
5743
- #getUpgradeWebSocket;
5744
- #actorDriver;
5745
- #actorRouter;
5746
- constructor(config4, state, driverConfig) {
5747
- this.#config = config4;
5748
- this.#state = state;
5749
- this.#driverConfig = driverConfig;
5750
- const inlineClient = createClientWithDriver(this);
5751
- this.#actorDriver = this.#driverConfig.actor(
5752
- config4,
5753
- this,
5754
- inlineClient
5755
- );
5756
- this.#actorRouter = createActorRouter(
5757
- this.#config,
5758
- this.#actorDriver,
5759
- void 0,
5760
- config4.test.enabled
5761
- );
5762
- }
5763
- async sendRequest(actorId, actorRequest) {
5764
- return await this.#actorRouter.fetch(actorRequest, {
5765
- actorId
5766
- });
5767
- }
5768
- async openWebSocket(path, actorId, encoding, params) {
5769
- const normalizedPath = path.startsWith("/") ? path : `/${path}`;
5770
- const fakeUrl = `http://inline-actor${normalizedPath}`;
5771
- const fakeRequest = new Request(fakeUrl, {
5772
- method: "GET"
5773
- });
5774
- const pathOnly = normalizedPath.split("?")[0];
5775
- const { gatewayId, requestId } = createHibernatableRequestMetadata();
5776
- const wsHandler = await routeWebSocket(
5777
- fakeRequest,
5778
- pathOnly,
5779
- {},
5780
- this.#config,
5781
- this.#actorDriver,
5782
- actorId,
5783
- encoding,
5784
- params,
5785
- gatewayId,
5786
- requestId,
5787
- true,
5788
- false
5789
- );
5790
- return createInlineWebSocket(wsHandler);
5791
- }
5792
- async proxyRequest(c, actorRequest, actorId) {
5793
- return await this.#actorRouter.fetch(actorRequest, {
5794
- actorId
5795
- });
5796
- }
5797
- async proxyWebSocket(c, path, actorId, encoding, params) {
5798
- var _a;
5799
- const upgradeWebSocket = (_a = this.#getUpgradeWebSocket) == null ? void 0 : _a.call(this);
5800
- invariant4(upgradeWebSocket, "missing getUpgradeWebSocket");
5801
- const pathOnly = path.split("?")[0];
5802
- const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
5803
- const { gatewayId, requestId } = createHibernatableRequestMetadata();
5804
- const wsHandler = await routeWebSocket(
5805
- // TODO: Create new request with new path
5806
- c.req.raw,
5807
- normalizedPath,
5808
- c.req.header(),
5809
- this.#config,
5810
- this.#actorDriver,
5811
- actorId,
5812
- encoding,
5813
- params,
5814
- gatewayId,
5815
- requestId,
5816
- true,
5817
- false
5818
- );
5819
- return upgradeWebSocket(() => wsHandler)(c, noopNext());
5820
- }
5821
- async buildGatewayUrl(actorId) {
5822
- const port = this.#config.managerPort ?? 6420;
5823
- return `http://127.0.0.1:${port}/gateway/${encodeURIComponent(actorId)}`;
5824
- }
5825
- async getForId({
5826
- actorId
5827
- }) {
5828
- const actor = await this.#state.loadActor(actorId);
5829
- if (!actor.state) {
5830
- return void 0;
5831
- }
5832
- if (this.#state.isActorStopping(actorId)) {
5833
- throw new ActorStopping(actorId);
5834
- }
5835
- return actorStateToOutput(actor.state);
5836
- }
5837
- async getWithKey({
5838
- name,
5839
- key
5840
- }) {
5841
- const actorId = generateActorId(name, key);
5842
- const actor = await this.#state.loadActor(actorId);
5843
- if (actor.state) {
5844
- return actorStateToOutput(actor.state);
5845
- }
5846
- return void 0;
5847
- }
5848
- async getOrCreateWithKey(input) {
5849
- const actorId = generateActorId(input.name, input.key);
5850
- await this.#state.loadOrCreateActor(
5851
- actorId,
5852
- input.name,
5853
- input.key,
5854
- input.input
5855
- );
5856
- await this.#actorDriver.loadActor(actorId);
5857
- const state = await this.#state.loadActorStateOrError(actorId);
5858
- return actorStateToOutput(state);
5859
- }
5860
- async createActor({ name, key, input }) {
5861
- const actorId = generateActorId(name, key);
5862
- await this.#state.createActor(actorId, name, key, input);
5863
- await this.#actorDriver.loadActor(actorId);
5864
- const state = await this.#state.loadActorStateOrError(actorId);
5865
- return actorStateToOutput(state);
5866
- }
5867
- async listActors({ name }) {
5868
- const actors = [];
5869
- const itr = this.#state.getActorsIterator({});
5870
- for await (const actor of itr) {
5871
- if (actor.name === name) {
5872
- actors.push(actorStateToOutput(actor));
5873
- }
5874
- }
5875
- actors.sort((a, b) => {
5876
- const aTs = a.createTs ?? 0;
5877
- const bTs = b.createTs ?? 0;
5878
- return bTs - aTs;
5879
- });
5880
- return actors;
5881
- }
5882
- async kvGet(actorId, key) {
5883
- const response = await this.#state.kvBatchGet(actorId, [key]);
5884
- return response[0] !== null ? new TextDecoder().decode(response[0]) : null;
5885
- }
5886
- displayInformation() {
5887
- return {
5888
- properties: {
5889
- ...this.#state.persist ? { Data: this.#state.storagePath } : {},
5890
- Instances: this.#state.actorCountOnStartup.toString()
5891
- }
5892
- };
5893
- }
5894
- extraStartupLog() {
5895
- return {
5896
- instances: this.#state.actorCountOnStartup,
5897
- data: this.#state.storagePath
5898
- };
5899
- }
5900
- setGetUpgradeWebSocket(getUpgradeWebSocket) {
5901
- this.#getUpgradeWebSocket = getUpgradeWebSocket;
5902
- }
5903
- };
5904
- function actorStateToOutput(state) {
5905
- return {
5906
- actorId: state.actorId,
5907
- name: state.name,
5908
- key: state.key,
5909
- createTs: Number(state.createdAt),
5910
- startTs: state.startTs !== null ? Number(state.startTs) : null,
5911
- connectableTs: state.connectableTs !== null ? Number(state.connectableTs) : null,
5912
- sleepTs: state.sleepTs !== null ? Number(state.sleepTs) : null,
5913
- destroyTs: state.destroyTs !== null ? Number(state.destroyTs) : null
5914
- };
5915
- }
5916
- function createHibernatableRequestMetadata() {
5917
- const gatewayId = new Uint8Array(4);
5918
- const requestId = new Uint8Array(4);
5919
- crypto.getRandomValues(gatewayId);
5920
- crypto.getRandomValues(requestId);
5921
- return {
5922
- gatewayId: gatewayId.buffer.slice(0),
5923
- requestId: requestId.buffer.slice(0)
5924
- };
5925
- }
5926
-
5927
- // src/drivers/file-system/mod.ts
5928
- var CreateFileSystemDriverOptionsSchema = z.object({
5929
- /** Custom path for storage. */
5930
- path: z.string().optional(),
5931
- /** Deprecated: file-system driver KV is now always SQLite-backed. */
5932
- useNativeSqlite: z.boolean().optional()
5933
- });
5934
- function createFileSystemOrMemoryDriver(persist = true, options) {
5935
- importNodeDependencies();
5936
- if ((options == null ? void 0 : options.useNativeSqlite) === false) {
5937
- throw new Error(
5938
- "File-system driver no longer supports non-SQLite KV storage. Remove useNativeSqlite: false."
5939
- );
5940
- }
5941
- const stateOptions = {
5942
- persist,
5943
- customPath: options == null ? void 0 : options.path,
5944
- useNativeSqlite: true
5945
- };
5946
- const state = new FileSystemGlobalState(stateOptions);
5947
- const driverConfig = {
5948
- name: persist ? "file-system" : "memory",
5949
- displayName: persist ? "File System" : "Memory",
5950
- manager: (config4) => new FileSystemManagerDriver(config4, state, driverConfig),
5951
- actor: (config4, managerDriver, inlineClient) => {
5952
- const actorDriver = new FileSystemActorDriver(
5953
- config4,
5954
- managerDriver,
5955
- inlineClient,
5956
- state
5957
- );
5958
- state.onRunnerStart(config4, inlineClient, actorDriver);
5959
- return actorDriver;
5960
- },
5961
- autoStartActorDriver: true
5962
- };
5963
- return driverConfig;
5964
- }
5965
- function createFileSystemDriver(opts) {
5966
- const validatedOpts = opts ? CreateFileSystemDriverOptionsSchema.parse(opts) : void 0;
5967
- return createFileSystemOrMemoryDriver(true, validatedOpts);
5968
- }
5969
- function createMemoryDriver() {
5970
- return createFileSystemOrMemoryDriver(false);
5971
- }
5972
-
5973
4129
  export {
5974
4130
  ActorDefinition,
5975
4131
  lookupInRegistry,
5976
- createActorRouter,
5977
- InlineWebSocketAdapter,
5978
- getStoragePath,
5979
- ensureDirectoryExists,
5980
- createFileSystemOrMemoryDriver,
5981
- createFileSystemDriver,
5982
- createMemoryDriver
4132
+ createActorRouter
5983
4133
  };
5984
- //# sourceMappingURL=chunk-KTWY3K6Z.js.map
4134
+ //# sourceMappingURL=chunk-YGYGANCA.js.map