rivetkit 2.0.42 → 2.1.0-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 (322) hide show
  1. package/dist/{tsup/config-CLnylLYY.d.ts → browser/client.d.ts} +2127 -1910
  2. package/dist/browser/client.js +5182 -0
  3. package/dist/browser/client.js.map +1 -0
  4. package/dist/browser/inspector/client.d.ts +130 -0
  5. package/dist/browser/inspector/client.js +2854 -0
  6. package/dist/browser/inspector/client.js.map +1 -0
  7. package/dist/browser/v3-DnYObHH3.d.ts +279 -0
  8. package/dist/schemas/actor-inspector/v2.ts +796 -0
  9. package/dist/schemas/actor-inspector/v3.ts +899 -0
  10. package/dist/schemas/actor-persist/v4.ts +406 -0
  11. package/dist/schemas/client-protocol/v3.ts +554 -0
  12. package/dist/schemas/persist/v1.ts +781 -0
  13. package/dist/schemas/transport/v1.ts +697 -0
  14. package/dist/tsup/actor/errors.cjs +27 -3
  15. package/dist/tsup/actor/errors.cjs.map +1 -1
  16. package/dist/tsup/actor/errors.d.cts +37 -1
  17. package/dist/tsup/actor/errors.d.ts +37 -1
  18. package/dist/tsup/actor/errors.js +26 -1
  19. package/dist/tsup/{actor-router-consts-DzI2szci.d.cts → actor-router-consts-D29T1Z-K.d.cts} +1 -1
  20. package/dist/tsup/{actor-router-consts-DzI2szci.d.ts → actor-router-consts-D29T1Z-K.d.ts} +1 -1
  21. package/dist/tsup/chunk-424PT5DM.js +23 -0
  22. package/dist/tsup/chunk-424PT5DM.js.map +1 -0
  23. package/dist/tsup/{chunk-JDAD2YFA.js → chunk-5ESWDTHJ.js} +148 -273
  24. package/dist/tsup/chunk-5ESWDTHJ.js.map +1 -0
  25. package/dist/tsup/{chunk-FJ3KTN4V.js → chunk-6LIBPELE.js} +119 -11
  26. package/dist/tsup/chunk-6LIBPELE.js.map +1 -0
  27. package/dist/tsup/chunk-6LJAZ5R4.cjs +96 -0
  28. package/dist/tsup/chunk-6LJAZ5R4.cjs.map +1 -0
  29. package/dist/tsup/{chunk-LFVF5SCU.js → chunk-7HTNH26M.js} +126 -1
  30. package/dist/tsup/chunk-7HTNH26M.js.map +1 -0
  31. package/dist/tsup/chunk-7K4CYDGD.js +630 -0
  32. package/dist/tsup/chunk-7K4CYDGD.js.map +1 -0
  33. package/dist/tsup/{chunk-XXGJCOL6.js → chunk-A6YIZWTK.js} +2 -2
  34. package/dist/tsup/chunk-AIYEYMX5.cjs +630 -0
  35. package/dist/tsup/chunk-AIYEYMX5.cjs.map +1 -0
  36. package/dist/tsup/{chunk-Q6W7RJJP.js → chunk-DIGBC2VI.js} +211 -2316
  37. package/dist/tsup/chunk-DIGBC2VI.js.map +1 -0
  38. package/dist/tsup/{chunk-RZW2DNND.cjs → chunk-F6JYU5IK.cjs} +1957 -1039
  39. package/dist/tsup/chunk-F6JYU5IK.cjs.map +1 -0
  40. package/dist/tsup/chunk-HAZL2EPK.cjs +534 -0
  41. package/dist/tsup/chunk-HAZL2EPK.cjs.map +1 -0
  42. package/dist/tsup/chunk-HDQ2JUQT.cjs +23 -0
  43. package/dist/tsup/chunk-HDQ2JUQT.cjs.map +1 -0
  44. package/dist/tsup/chunk-HIDX4C5Y.cjs +1036 -0
  45. package/dist/tsup/chunk-HIDX4C5Y.cjs.map +1 -0
  46. package/dist/tsup/chunk-IVG73YCW.js +534 -0
  47. package/dist/tsup/chunk-IVG73YCW.js.map +1 -0
  48. package/dist/tsup/chunk-KJSYAUOM.js +96 -0
  49. package/dist/tsup/chunk-KJSYAUOM.js.map +1 -0
  50. package/dist/tsup/{chunk-2XQS746M.cjs → chunk-L47L3ZWJ.cjs} +127 -2
  51. package/dist/tsup/chunk-L47L3ZWJ.cjs.map +1 -0
  52. package/dist/tsup/{chunk-H4TB4X25.cjs → chunk-LW6KLR7A.cjs} +126 -18
  53. package/dist/tsup/chunk-LW6KLR7A.cjs.map +1 -0
  54. package/dist/tsup/chunk-LXUQ667X.js +2006 -0
  55. package/dist/tsup/chunk-LXUQ667X.js.map +1 -0
  56. package/dist/tsup/{chunk-GMAVRZSF.js → chunk-M2T62AZQ.js} +1790 -872
  57. package/dist/tsup/chunk-M2T62AZQ.js.map +1 -0
  58. package/dist/tsup/chunk-MZ37VV3P.js +5974 -0
  59. package/dist/tsup/chunk-MZ37VV3P.js.map +1 -0
  60. package/dist/tsup/chunk-N4KRDJ56.js +72 -0
  61. package/dist/tsup/chunk-N4KRDJ56.js.map +1 -0
  62. package/dist/tsup/chunk-NIYZDWMW.cjs +2006 -0
  63. package/dist/tsup/chunk-NIYZDWMW.cjs.map +1 -0
  64. package/dist/tsup/chunk-OMEPCQK2.js +649 -0
  65. package/dist/tsup/chunk-OMEPCQK2.js.map +1 -0
  66. package/dist/tsup/chunk-SR3KQE7Q.cjs +72 -0
  67. package/dist/tsup/chunk-SR3KQE7Q.cjs.map +1 -0
  68. package/dist/tsup/chunk-SSEP6DHP.cjs +2657 -0
  69. package/dist/tsup/chunk-SSEP6DHP.cjs.map +1 -0
  70. package/dist/tsup/chunk-T5YCUGVS.js +1036 -0
  71. package/dist/tsup/chunk-T5YCUGVS.js.map +1 -0
  72. package/dist/tsup/{chunk-EJVBH5VF.cjs → chunk-TPGXWFQT.cjs} +3 -3
  73. package/dist/tsup/{chunk-EJVBH5VF.cjs.map → chunk-TPGXWFQT.cjs.map} +1 -1
  74. package/dist/tsup/{chunk-X35U3YNX.cjs → chunk-TYLXNCA5.cjs} +214 -339
  75. package/dist/tsup/chunk-TYLXNCA5.cjs.map +1 -0
  76. package/dist/tsup/chunk-VKVNIQRQ.js +257 -0
  77. package/dist/tsup/chunk-VKVNIQRQ.js.map +1 -0
  78. package/dist/tsup/chunk-XWBAQO5H.cjs +649 -0
  79. package/dist/tsup/chunk-XWBAQO5H.cjs.map +1 -0
  80. package/dist/tsup/chunk-YQ4LDVD6.cjs +5974 -0
  81. package/dist/tsup/chunk-YQ4LDVD6.cjs.map +1 -0
  82. package/dist/tsup/chunk-ZFY5J2EP.cjs +257 -0
  83. package/dist/tsup/chunk-ZFY5J2EP.cjs.map +1 -0
  84. package/dist/tsup/client/mod.cjs +9 -10
  85. package/dist/tsup/client/mod.cjs.map +1 -1
  86. package/dist/tsup/client/mod.d.cts +11 -5
  87. package/dist/tsup/client/mod.d.ts +11 -5
  88. package/dist/tsup/client/mod.js +8 -8
  89. package/dist/tsup/common/log.cjs +4 -4
  90. package/dist/tsup/common/log.d.cts +2 -2
  91. package/dist/tsup/common/log.d.ts +2 -2
  92. package/dist/tsup/common/log.js +3 -2
  93. package/dist/tsup/common/websocket.cjs +5 -5
  94. package/dist/tsup/common/websocket.js +4 -3
  95. package/dist/tsup/config-BFqid9Gr.d.ts +2574 -0
  96. package/dist/tsup/config-BiNoIHRs.d.cts +80 -0
  97. package/dist/tsup/config-BiNoIHRs.d.ts +80 -0
  98. package/dist/tsup/{config-CZB2-W8x.d.cts → config-CAZphOS1.d.cts} +681 -355
  99. package/dist/tsup/db/drizzle/mod.cjs +49 -0
  100. package/dist/tsup/db/drizzle/mod.cjs.map +1 -0
  101. package/dist/tsup/db/drizzle/mod.d.cts +17 -0
  102. package/dist/tsup/db/drizzle/mod.d.ts +17 -0
  103. package/dist/tsup/db/drizzle/mod.js +49 -0
  104. package/dist/tsup/db/drizzle/mod.js.map +1 -0
  105. package/dist/tsup/db/mod.cjs +9 -0
  106. package/dist/tsup/db/mod.cjs.map +1 -0
  107. package/dist/tsup/db/mod.d.cts +9 -0
  108. package/dist/tsup/db/mod.d.ts +9 -0
  109. package/dist/tsup/db/mod.js +9 -0
  110. package/dist/tsup/db/mod.js.map +1 -0
  111. package/dist/tsup/{driver-D0QX9M11.d.ts → driver-Bxv62E2p.d.ts} +2 -2
  112. package/dist/tsup/{driver-q-zqG7fc.d.cts → driver-DYXwJR5D.d.cts} +2 -2
  113. package/dist/tsup/driver-helpers/mod.cjs +12 -6
  114. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  115. package/dist/tsup/driver-helpers/mod.d.cts +12 -5
  116. package/dist/tsup/driver-helpers/mod.d.ts +12 -5
  117. package/dist/tsup/driver-helpers/mod.js +12 -5
  118. package/dist/tsup/driver-test-suite/mod.cjs +1370 -116
  119. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  120. package/dist/tsup/driver-test-suite/mod.d.cts +10 -4
  121. package/dist/tsup/driver-test-suite/mod.d.ts +10 -4
  122. package/dist/tsup/driver-test-suite/mod.js +2093 -838
  123. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  124. package/dist/tsup/inspector/mod.cjs +29 -3
  125. package/dist/tsup/inspector/mod.cjs.map +1 -1
  126. package/dist/tsup/inspector/mod.d.cts +124 -3
  127. package/dist/tsup/inspector/mod.d.ts +124 -3
  128. package/dist/tsup/inspector/mod.js +72 -45
  129. package/dist/tsup/keys-CydblqMh.d.cts +13 -0
  130. package/dist/tsup/keys-CydblqMh.d.ts +13 -0
  131. package/dist/tsup/mod.cjs +16 -10
  132. package/dist/tsup/mod.cjs.map +1 -1
  133. package/dist/tsup/mod.d.cts +26 -14
  134. package/dist/tsup/mod.d.ts +26 -14
  135. package/dist/tsup/mod.js +20 -13
  136. package/dist/tsup/serve-test-suite/mod.cjs +1165 -83
  137. package/dist/tsup/serve-test-suite/mod.cjs.map +1 -1
  138. package/dist/tsup/serve-test-suite/mod.js +1114 -29
  139. package/dist/tsup/serve-test-suite/mod.js.map +1 -1
  140. package/dist/tsup/test/mod.cjs +84 -11
  141. package/dist/tsup/test/mod.cjs.map +1 -1
  142. package/dist/tsup/test/mod.d.cts +10 -5
  143. package/dist/tsup/test/mod.d.ts +10 -5
  144. package/dist/tsup/test/mod.js +85 -11
  145. package/dist/tsup/test/mod.js.map +1 -1
  146. package/dist/tsup/utils.cjs +10 -4
  147. package/dist/tsup/utils.cjs.map +1 -1
  148. package/dist/tsup/utils.d.cts +72 -2
  149. package/dist/tsup/utils.d.ts +72 -2
  150. package/dist/tsup/utils.js +9 -2
  151. package/dist/tsup/v3-DnYObHH3.d.cts +279 -0
  152. package/dist/tsup/v3-DnYObHH3.d.ts +279 -0
  153. package/dist/tsup/workflow/mod.cjs +16 -0
  154. package/dist/tsup/workflow/mod.cjs.map +1 -0
  155. package/dist/tsup/workflow/mod.d.cts +83 -0
  156. package/dist/tsup/workflow/mod.d.ts +83 -0
  157. package/dist/tsup/workflow/mod.js +16 -0
  158. package/dist/tsup/workflow/mod.js.map +1 -0
  159. package/package.json +62 -5
  160. package/src/actor/config.ts +478 -68
  161. package/src/actor/conn/mod.ts +68 -16
  162. package/src/actor/conn/state-manager.ts +2 -2
  163. package/src/actor/contexts/action.ts +20 -12
  164. package/src/actor/contexts/base/actor.ts +137 -7
  165. package/src/actor/contexts/base/conn-init.ts +27 -7
  166. package/src/actor/contexts/base/conn.ts +27 -18
  167. package/src/actor/contexts/before-action-response.ts +9 -2
  168. package/src/actor/contexts/before-connect.ts +7 -2
  169. package/src/actor/contexts/connect.ts +9 -2
  170. package/src/actor/contexts/create-conn-state.ts +7 -2
  171. package/src/actor/contexts/create-vars.ts +16 -3
  172. package/src/actor/contexts/create.ts +16 -3
  173. package/src/actor/contexts/destroy.ts +9 -3
  174. package/src/actor/contexts/disconnect.ts +10 -4
  175. package/src/actor/contexts/index.ts +4 -3
  176. package/src/actor/contexts/request.ts +23 -6
  177. package/src/actor/contexts/run.ts +47 -0
  178. package/src/actor/contexts/sleep.ts +9 -3
  179. package/src/actor/contexts/state-change.ts +9 -3
  180. package/src/actor/contexts/wake.ts +9 -3
  181. package/src/actor/contexts/websocket.ts +23 -6
  182. package/src/actor/database.ts +8 -18
  183. package/src/actor/definition.ts +20 -6
  184. package/src/actor/driver.ts +32 -3
  185. package/src/actor/errors.ts +127 -0
  186. package/src/actor/instance/connection-manager.ts +183 -80
  187. package/src/actor/instance/event-manager.ts +26 -15
  188. package/src/actor/instance/keys.ts +117 -0
  189. package/src/actor/instance/mod.ts +784 -174
  190. package/src/actor/instance/queue-manager.ts +603 -0
  191. package/src/actor/instance/queue.ts +287 -0
  192. package/src/actor/instance/schedule-manager.ts +49 -7
  193. package/src/actor/instance/state-manager.ts +35 -11
  194. package/src/actor/instance/traces-driver.ts +128 -0
  195. package/src/actor/mod.ts +26 -2
  196. package/src/actor/protocol/old.ts +28 -13
  197. package/src/actor/protocol/serde.ts +1 -1
  198. package/src/actor/router-endpoints.ts +177 -21
  199. package/src/actor/router-websocket-endpoints.ts +18 -29
  200. package/src/actor/router.ts +177 -0
  201. package/src/actor/schema.ts +291 -0
  202. package/src/actor/utils.ts +40 -0
  203. package/src/client/actor-common.ts +1 -1
  204. package/src/client/actor-conn.ts +100 -33
  205. package/src/client/actor-handle.ts +61 -33
  206. package/src/client/client.ts +2 -4
  207. package/src/client/config.ts +1 -1
  208. package/src/client/mod.browser.ts +2 -0
  209. package/src/client/mod.ts +1 -4
  210. package/src/client/queue.ts +146 -0
  211. package/src/client/utils.ts +1 -1
  212. package/src/common/log.ts +1 -1
  213. package/src/common/utils.ts +3 -3
  214. package/src/db/config.ts +100 -0
  215. package/src/db/drizzle/mod.ts +226 -0
  216. package/src/db/drizzle/sqlite-core.ts +22 -0
  217. package/src/db/mod.ts +125 -0
  218. package/src/db/shared.ts +92 -0
  219. package/src/db/sqlite-vfs.ts +12 -0
  220. package/src/driver-helpers/mod.ts +1 -0
  221. package/src/driver-test-suite/mod.ts +69 -43
  222. package/src/driver-test-suite/tests/access-control.ts +218 -0
  223. package/src/driver-test-suite/tests/actor-db-raw.ts +73 -0
  224. package/src/driver-test-suite/tests/actor-db.ts +394 -0
  225. package/src/driver-test-suite/tests/actor-inspector.ts +259 -358
  226. package/src/driver-test-suite/tests/actor-kv.ts +41 -20
  227. package/src/driver-test-suite/tests/actor-queue.ts +324 -0
  228. package/src/driver-test-suite/tests/actor-run.ts +181 -0
  229. package/src/driver-test-suite/tests/actor-schedule.ts +5 -2
  230. package/src/driver-test-suite/tests/actor-sleep.ts +3 -3
  231. package/src/driver-test-suite/tests/actor-stateless.ts +70 -0
  232. package/src/driver-test-suite/tests/actor-workflow.ts +108 -0
  233. package/src/driver-test-suite/tests/manager-driver.ts +11 -0
  234. package/src/driver-test-suite/tests/raw-http-request-properties.ts +1 -1
  235. package/src/driver-test-suite/tests/raw-websocket.ts +12 -12
  236. package/src/drivers/default.ts +7 -2
  237. package/src/drivers/engine/actor-driver.ts +45 -37
  238. package/src/drivers/engine/config.ts +1 -1
  239. package/src/drivers/file-system/actor.ts +20 -2
  240. package/src/drivers/file-system/global-state.ts +569 -258
  241. package/src/drivers/file-system/kv-limits.ts +70 -0
  242. package/src/drivers/file-system/manager.ts +22 -6
  243. package/src/drivers/file-system/mod.ts +39 -16
  244. package/src/drivers/file-system/sqlite-runtime.ts +210 -0
  245. package/src/inspector/actor-inspector.ts +224 -102
  246. package/src/inspector/config.ts +1 -1
  247. package/src/inspector/handler.ts +102 -20
  248. package/src/inspector/mod.browser.ts +8 -0
  249. package/src/inspector/mod.ts +2 -0
  250. package/src/inspector/serve-ui.ts +40 -0
  251. package/src/inspector/transport.ts +18 -0
  252. package/src/inspector/utils.ts +5 -39
  253. package/src/manager/gateway.ts +1 -1
  254. package/src/manager/protocol/mod.ts +1 -1
  255. package/src/manager/protocol/query.ts +1 -1
  256. package/src/manager/router-schema.ts +1 -1
  257. package/src/manager/router.ts +38 -12
  258. package/src/manager-api/actors.ts +1 -1
  259. package/src/manager-api/common.ts +1 -1
  260. package/src/registry/config/driver.ts +1 -1
  261. package/src/registry/config/index.ts +212 -43
  262. package/src/registry/config/legacy-runner.ts +1 -1
  263. package/src/registry/config/runner.ts +1 -1
  264. package/src/registry/config/serverless.ts +1 -1
  265. package/src/registry/index.ts +7 -5
  266. package/src/remote-manager-driver/api-utils.ts +1 -1
  267. package/src/schemas/actor-inspector/mod.ts +1 -1
  268. package/src/schemas/actor-inspector/versioned.ts +195 -8
  269. package/src/schemas/actor-persist/versioned.ts +87 -7
  270. package/src/schemas/client-protocol/mod.ts +1 -1
  271. package/src/schemas/client-protocol/versioned.ts +127 -11
  272. package/src/schemas/client-protocol-zod/mod.ts +16 -1
  273. package/src/schemas/persist/mod.ts +1 -0
  274. package/src/schemas/transport/mod.ts +1 -0
  275. package/src/serde.ts +1 -1
  276. package/src/serve-test-suite/mod.ts +10 -9
  277. package/src/test/mod.ts +15 -56
  278. package/src/utils/endpoint-parser.test.ts +1 -1
  279. package/src/utils/endpoint-parser.ts +1 -1
  280. package/src/utils/env-vars.ts +12 -1
  281. package/src/utils/node.ts +15 -2
  282. package/src/utils.test.ts +34 -0
  283. package/src/utils.ts +140 -6
  284. package/src/workflow/constants.ts +2 -0
  285. package/src/workflow/context.ts +532 -0
  286. package/src/workflow/driver.ts +191 -0
  287. package/src/workflow/inspector.ts +268 -0
  288. package/src/workflow/mod.ts +122 -0
  289. package/dist/tsup/chunk-2IJTYN6K.cjs +0 -278
  290. package/dist/tsup/chunk-2IJTYN6K.cjs.map +0 -1
  291. package/dist/tsup/chunk-2XQS746M.cjs.map +0 -1
  292. package/dist/tsup/chunk-3VP5CSHV.cjs +0 -114
  293. package/dist/tsup/chunk-3VP5CSHV.cjs.map +0 -1
  294. package/dist/tsup/chunk-AQFSQMBG.js +0 -114
  295. package/dist/tsup/chunk-AQFSQMBG.js.map +0 -1
  296. package/dist/tsup/chunk-E6ZE2YEA.js +0 -664
  297. package/dist/tsup/chunk-E6ZE2YEA.js.map +0 -1
  298. package/dist/tsup/chunk-FJ3KTN4V.js.map +0 -1
  299. package/dist/tsup/chunk-GBENOENJ.cjs +0 -8
  300. package/dist/tsup/chunk-GBENOENJ.cjs.map +0 -1
  301. package/dist/tsup/chunk-GD7UXGOE.cjs +0 -4762
  302. package/dist/tsup/chunk-GD7UXGOE.cjs.map +0 -1
  303. package/dist/tsup/chunk-GMAVRZSF.js.map +0 -1
  304. package/dist/tsup/chunk-H4TB4X25.cjs.map +0 -1
  305. package/dist/tsup/chunk-JDAD2YFA.js.map +0 -1
  306. package/dist/tsup/chunk-KCOVZOPS.js +0 -1946
  307. package/dist/tsup/chunk-KCOVZOPS.js.map +0 -1
  308. package/dist/tsup/chunk-KDFWJKMJ.cjs +0 -664
  309. package/dist/tsup/chunk-KDFWJKMJ.cjs.map +0 -1
  310. package/dist/tsup/chunk-LFVF5SCU.js.map +0 -1
  311. package/dist/tsup/chunk-Q6W7RJJP.js.map +0 -1
  312. package/dist/tsup/chunk-RUW5CZ5Z.cjs +0 -1949
  313. package/dist/tsup/chunk-RUW5CZ5Z.cjs.map +0 -1
  314. package/dist/tsup/chunk-RZW2DNND.cjs.map +0 -1
  315. package/dist/tsup/chunk-TCOEBUUE.js +0 -278
  316. package/dist/tsup/chunk-TCOEBUUE.js.map +0 -1
  317. package/dist/tsup/chunk-X35U3YNX.cjs.map +0 -1
  318. package/dist/tsup/keys-Chhy4ylv.d.cts +0 -8
  319. package/dist/tsup/keys-Chhy4ylv.d.ts +0 -8
  320. package/dist/tsup/v1-Gq4avTK3.d.cts +0 -240
  321. package/dist/tsup/v1-Gq4avTK3.d.ts +0 -240
  322. /package/dist/tsup/{chunk-XXGJCOL6.js.map → chunk-A6YIZWTK.js.map} +0 -0
@@ -1,39 +1,25 @@
1
1
  import {
2
2
  importWebSocket,
3
3
  logger
4
- } from "./chunk-XXGJCOL6.js";
4
+ } from "./chunk-A6YIZWTK.js";
5
5
  import {
6
- ACTOR_VERSIONED,
7
- ActionContext,
8
- ActorContext,
9
- BeforeConnectContext,
10
- CONN_CONNECTED_SYMBOL,
11
- CONN_DRIVER_SYMBOL,
12
- CONN_SEND_MESSAGE_SYMBOL,
13
- CONN_SPEAKS_RIVETKIT_SYMBOL,
14
- CONN_STATE_MANAGER_SYMBOL,
15
- CONN_VERSIONED,
16
6
  CURRENT_VERSION,
17
- CURRENT_VERSION2,
18
- CachedSerializer,
19
- Conn,
20
- ConnectContext,
21
- CreateConnStateContext,
22
- DeadlineError,
23
7
  EncodingSchema,
24
8
  HEADER_CONN_PARAMS,
25
9
  HEADER_ENCODING,
26
10
  HEADER_RIVET_TOKEN,
27
11
  HTTP_ACTION_REQUEST_VERSIONED,
28
12
  HTTP_ACTION_RESPONSE_VERSIONED,
13
+ HTTP_QUEUE_SEND_REQUEST_VERSIONED,
14
+ HTTP_QUEUE_SEND_RESPONSE_VERSIONED,
29
15
  HTTP_RESPONSE_ERROR_VERSIONED,
30
16
  HttpActionRequestSchema,
31
17
  HttpActionResponseSchema,
18
+ HttpQueueSendRequestSchema,
19
+ HttpQueueSendResponseSchema,
32
20
  HttpResponseErrorSchema,
33
- KEYS,
34
21
  PATH_CONNECT,
35
22
  PATH_WEBSOCKET_PREFIX,
36
- RequestContext,
37
23
  TO_CLIENT_VERSIONED,
38
24
  TO_SERVER_VERSIONED,
39
25
  ToClientSchema,
@@ -41,36 +27,25 @@ import {
41
27
  WS_PROTOCOL_CONN_PARAMS,
42
28
  WS_PROTOCOL_ENCODING,
43
29
  WS_PROTOCOL_STANDARD,
44
- WebSocketContext,
45
- assertUnreachable as assertUnreachable2,
46
30
  contentTypeForEncoding,
47
- createHttpDriver,
48
- deadline,
49
31
  deserializeActorKey,
50
32
  deserializeWithEncoding,
51
- generateSecureToken,
52
33
  inputDataToBuffer,
53
- isConnStatePath,
54
- isStatePath,
55
34
  jsonStringifyCompat,
56
- makeConnKey,
57
- processMessage,
58
35
  serializeActorKey,
59
36
  serializeWithEncoding,
60
37
  tryParseEndpoint,
61
38
  uint8ArrayToBase64
62
- } from "./chunk-GMAVRZSF.js";
39
+ } from "./chunk-M2T62AZQ.js";
40
+ import {
41
+ assertUnreachable as assertUnreachable2
42
+ } from "./chunk-T5YCUGVS.js";
63
43
  import {
64
- EXTRA_ERROR_LOG,
65
- SinglePromiseQueue,
66
44
  VERSION,
67
- arrayBuffersEqual,
68
45
  assertUnreachable,
69
46
  bufferToArrayBuffer,
70
47
  combineUrlPath,
71
48
  deconstructError,
72
- getBaseLogger,
73
- getIncludeTarget,
74
49
  getLogMessage,
75
50
  getLogger,
76
51
  getNextPhase,
@@ -80,25 +55,14 @@ import {
80
55
  getRivetRunner,
81
56
  getRivetToken,
82
57
  httpUserAgent,
83
- isCborSerializable,
84
58
  noopNext,
85
59
  promiseWithResolvers,
86
60
  stringifyError
87
- } from "./chunk-FJ3KTN4V.js";
61
+ } from "./chunk-6LIBPELE.js";
88
62
  import {
89
- ActionNotFound,
90
- ActionTimedOut,
91
63
  ActorNotFound,
92
- DatabaseNotEnabled,
93
- InternalError,
94
- InvalidRequest,
95
- InvalidRequestHandlerResponse,
96
- InvalidStateType,
97
- OutgoingMessageTooLong,
98
- RequestHandlerNotDefined,
99
- StateNotEnabled,
100
- VarsNotEnabled
101
- } from "./chunk-LFVF5SCU.js";
64
+ InvalidRequest
65
+ } from "./chunk-7HTNH26M.js";
102
66
 
103
67
  // src/devtools-loader/log.ts
104
68
  function logger2() {
@@ -129,7 +93,7 @@ import * as cbor2 from "cbor-x";
129
93
  import invariant2 from "invariant";
130
94
 
131
95
  // src/remote-manager-driver/api-utils.ts
132
- import { z } from "zod";
96
+ import { z } from "zod/v4";
133
97
 
134
98
  // src/client/utils.ts
135
99
  import * as cbor from "cbor-x";
@@ -138,7 +102,7 @@ import invariant from "invariant";
138
102
  // src/client/errors.ts
139
103
  var ActorClientError = class extends Error {
140
104
  };
141
- var InternalError2 = class extends ActorClientError {
105
+ var InternalError = class extends ActorClientError {
142
106
  };
143
107
  var ManagerError = class extends ActorClientError {
144
108
  constructor(error, opts) {
@@ -976,7 +940,7 @@ function apiActorToOutput(actor) {
976
940
  }
977
941
 
978
942
  // src/client/actor-conn.ts
979
- import * as cbor3 from "cbor-x";
943
+ import * as cbor4 from "cbor-x";
980
944
  import invariant3 from "invariant";
981
945
  import pRetry2 from "p-retry";
982
946
 
@@ -1061,8 +1025,74 @@ async function checkForSchedulingError(group, code, actorId, query, driver) {
1061
1025
  return null;
1062
1026
  }
1063
1027
 
1028
+ // src/client/queue.ts
1029
+ import * as cbor3 from "cbor-x";
1030
+ function createQueueSender(senderOptions) {
1031
+ async function send(name, body, options) {
1032
+ const wait = (options == null ? void 0 : options.wait) ?? false;
1033
+ const timeout = options == null ? void 0 : options.timeout;
1034
+ const result = await sendHttpRequest({
1035
+ url: `http://actor/queue/${encodeURIComponent(name)}`,
1036
+ method: "POST",
1037
+ headers: {
1038
+ [HEADER_ENCODING]: senderOptions.encoding,
1039
+ ...senderOptions.params !== void 0 ? {
1040
+ [HEADER_CONN_PARAMS]: JSON.stringify(
1041
+ senderOptions.params
1042
+ )
1043
+ } : {}
1044
+ },
1045
+ body: { body, wait, timeout },
1046
+ encoding: senderOptions.encoding,
1047
+ customFetch: senderOptions.customFetch,
1048
+ signal: options == null ? void 0 : options.signal,
1049
+ requestVersion: CURRENT_VERSION,
1050
+ requestVersionedDataHandler: HTTP_QUEUE_SEND_REQUEST_VERSIONED,
1051
+ responseVersion: CURRENT_VERSION,
1052
+ responseVersionedDataHandler: HTTP_QUEUE_SEND_RESPONSE_VERSIONED,
1053
+ requestZodSchema: HttpQueueSendRequestSchema,
1054
+ responseZodSchema: HttpQueueSendResponseSchema,
1055
+ requestToJson: (value) => ({
1056
+ ...value,
1057
+ name
1058
+ }),
1059
+ requestToBare: (value) => ({
1060
+ name: value.name ?? name,
1061
+ body: bufferToArrayBuffer(cbor3.encode(value.body)),
1062
+ wait: value.wait ?? false,
1063
+ timeout: value.timeout !== void 0 ? BigInt(value.timeout) : null
1064
+ }),
1065
+ responseFromJson: (json) => {
1066
+ if (json.response === void 0) {
1067
+ return { status: json.status };
1068
+ }
1069
+ return {
1070
+ status: json.status,
1071
+ response: json.response
1072
+ };
1073
+ },
1074
+ responseFromBare: (bare) => {
1075
+ if (bare.response === null || bare.response === void 0) {
1076
+ return { status: bare.status };
1077
+ }
1078
+ return {
1079
+ status: bare.status,
1080
+ response: cbor3.decode(new Uint8Array(bare.response))
1081
+ };
1082
+ }
1083
+ });
1084
+ if (wait) {
1085
+ return result;
1086
+ }
1087
+ return;
1088
+ }
1089
+ return {
1090
+ send
1091
+ };
1092
+ }
1093
+
1064
1094
  // src/client/actor-conn.ts
1065
- var CONNECT_SYMBOL = Symbol("connect");
1095
+ var CONNECT_SYMBOL = /* @__PURE__ */ Symbol("connect");
1066
1096
  var ActorConnRaw = class {
1067
1097
  #disposed = false;
1068
1098
  /* Will be aborted on dispose. */
@@ -1076,9 +1106,11 @@ var ActorConnRaw = class {
1076
1106
  #eventSubscriptions = /* @__PURE__ */ new Map();
1077
1107
  #errorHandlers = /* @__PURE__ */ new Set();
1078
1108
  #openHandlers = /* @__PURE__ */ new Set();
1109
+ #openScheduled = false;
1079
1110
  #closeHandlers = /* @__PURE__ */ new Set();
1080
1111
  #statusChangeHandlers = /* @__PURE__ */ new Set();
1081
1112
  #actionIdCounter = 0;
1113
+ #queueSender;
1082
1114
  /**
1083
1115
  * Interval that keeps the NodeJS process alive if this is the only thing running.
1084
1116
  *
@@ -1107,8 +1139,26 @@ var ActorConnRaw = class {
1107
1139
  this.#params = params;
1108
1140
  this.#encoding = encoding;
1109
1141
  this.#actorQuery = actorQuery;
1142
+ this.#queueSender = createQueueSender({
1143
+ encoding: this.#encoding,
1144
+ params: this.#params,
1145
+ customFetch: async (request) => {
1146
+ if (!this.#actorId) {
1147
+ const { actorId } = await queryActor(
1148
+ void 0,
1149
+ this.#actorQuery,
1150
+ this.#driver
1151
+ );
1152
+ this.#actorId = actorId;
1153
+ }
1154
+ return this.#driver.sendRequest(this.#actorId, request);
1155
+ }
1156
+ });
1110
1157
  this.#keepNodeAliveInterval = setInterval(() => 6e4);
1111
1158
  }
1159
+ send(name, body, options) {
1160
+ return this.#queueSender.send(name, body, options);
1161
+ }
1112
1162
  /**
1113
1163
  * Call a raw action connection. See {@link ActorConn} for type-safe action calls.
1114
1164
  *
@@ -1123,7 +1173,7 @@ var ActorConnRaw = class {
1123
1173
  logger().debug({ msg: "action", name: opts.name, args: opts.args });
1124
1174
  const actionId = this.#actionIdCounter;
1125
1175
  this.#actionIdCounter += 1;
1126
- const { promise, resolve, reject } = promiseWithResolvers();
1176
+ const { promise, resolve, reject } = promiseWithResolvers((reason) => logger().warn({ msg: "unhandled action promise rejection", reason }));
1127
1177
  this.#actionsInFlight.set(actionId, {
1128
1178
  name: opts.name,
1129
1179
  resolve,
@@ -1153,12 +1203,11 @@ var ActorConnRaw = class {
1153
1203
  return output;
1154
1204
  }
1155
1205
  /**
1156
- * Do not call this directly.
1157
- enc
1158
- * Establishes a connection to the server using the specified endpoint & encoding & driver.
1159
- *
1160
- * @protected
1161
- */
1206
+ * Do not call this directly.
1207
+ * Establishes a connection to the server using the specified endpoint & encoding & driver.
1208
+ *
1209
+ * @protected
1210
+ */
1162
1211
  [CONNECT_SYMBOL]() {
1163
1212
  this.#connectWithRetry();
1164
1213
  }
@@ -1231,7 +1280,7 @@ var ActorConnRaw = class {
1231
1280
  try {
1232
1281
  if (this.#onOpenPromise)
1233
1282
  throw new Error("#onOpenPromise already defined");
1234
- this.#onOpenPromise = promiseWithResolvers();
1283
+ this.#onOpenPromise = promiseWithResolvers((reason) => logger().warn({ msg: "unhandled open promise rejection", reason }));
1235
1284
  await this.#connectWebSocket();
1236
1285
  await this.#onOpenPromise.promise;
1237
1286
  } finally {
@@ -1307,29 +1356,46 @@ var ActorConnRaw = class {
1307
1356
  }
1308
1357
  return;
1309
1358
  }
1310
- logger().debug({
1311
- msg: "socket open",
1312
- messageQueueLength: this.#messageQueue.length,
1313
- connId: this.#connId
1314
- });
1315
- this.#setConnStatus("connected");
1316
- if (this.#onOpenPromise) {
1317
- this.#onOpenPromise.resolve(void 0);
1318
- } else {
1319
- logger().warn({ msg: "#onOpenPromise is undefined" });
1320
- }
1321
- for (const eventName of this.#eventSubscriptions.keys()) {
1322
- this.#sendSubscription(eventName, true);
1359
+ if (this.#connStatus === "connected" || this.#openScheduled) {
1360
+ return;
1323
1361
  }
1324
- const queue = this.#messageQueue;
1325
- this.#messageQueue = [];
1326
- logger().debug({
1327
- msg: "flushing message queue",
1328
- queueLength: queue.length
1362
+ this.#openScheduled = true;
1363
+ queueMicrotask(() => {
1364
+ this.#openScheduled = false;
1365
+ if (this.#disposed) {
1366
+ logger().debug({
1367
+ msg: "handleOnOpen scheduled after dispose, closing websocket"
1368
+ });
1369
+ if (this.#websocket) {
1370
+ this.#websocket.close(1e3, "Disposed");
1371
+ this.#websocket = void 0;
1372
+ }
1373
+ return;
1374
+ }
1375
+ logger().debug({
1376
+ msg: "socket open",
1377
+ messageQueueLength: this.#messageQueue.length,
1378
+ connId: this.#connId
1379
+ });
1380
+ this.#setConnStatus("connected");
1381
+ if (this.#onOpenPromise) {
1382
+ this.#onOpenPromise.resolve(void 0);
1383
+ } else {
1384
+ logger().warn({ msg: "#onOpenPromise is undefined" });
1385
+ }
1386
+ for (const eventName of this.#eventSubscriptions.keys()) {
1387
+ this.#sendSubscription(eventName, true);
1388
+ }
1389
+ const queue = this.#messageQueue;
1390
+ this.#messageQueue = [];
1391
+ logger().debug({
1392
+ msg: "flushing message queue",
1393
+ queueLength: queue.length
1394
+ });
1395
+ for (const msg of queue) {
1396
+ this.#sendMessage(msg);
1397
+ }
1329
1398
  });
1330
- for (const msg of queue) {
1331
- this.#sendMessage(msg);
1332
- }
1333
1399
  }
1334
1400
  /** Called by the onmessage event from drivers. */
1335
1401
  async #handleOnMessage(data) {
@@ -1531,7 +1597,7 @@ var ActorConnRaw = class {
1531
1597
  name: action.name
1532
1598
  }))
1533
1599
  });
1534
- throw new InternalError2(`No in flight response for ${id}`);
1600
+ throw new InternalError(`No in flight response for ${id}`);
1535
1601
  }
1536
1602
  this.#actionsInFlight.delete(id);
1537
1603
  logger().debug({
@@ -1707,7 +1773,14 @@ var ActorConnRaw = class {
1707
1773
  messageType: message.body.tag,
1708
1774
  actionName: (_a = message.body.val) == null ? void 0 : _a.name
1709
1775
  });
1710
- if (readyState === 1) {
1776
+ if (this.#connStatus !== "connected") {
1777
+ logger().debug({
1778
+ msg: "websocket init pending, queueing message",
1779
+ connStatus: this.#connStatus,
1780
+ messageType: message.body.tag
1781
+ });
1782
+ queueMessage = true;
1783
+ } else if (readyState === 1) {
1711
1784
  try {
1712
1785
  const messageSerialized = serializeWithEncoding(
1713
1786
  this.#encoding,
@@ -1727,7 +1800,7 @@ var ActorConnRaw = class {
1727
1800
  id: msg.body.val.id,
1728
1801
  name: msg.body.val.name,
1729
1802
  args: bufferToArrayBuffer(
1730
- cbor3.encode(msg.body.val.args)
1803
+ cbor4.encode(msg.body.val.args)
1731
1804
  )
1732
1805
  }
1733
1806
  }
@@ -1792,7 +1865,7 @@ var ActorConnRaw = class {
1792
1865
  group: msg.body.val.group,
1793
1866
  code: msg.body.val.code,
1794
1867
  message: msg.body.val.message,
1795
- metadata: msg.body.val.metadata ? cbor3.decode(
1868
+ metadata: msg.body.val.metadata ? cbor4.decode(
1796
1869
  new Uint8Array(
1797
1870
  msg.body.val.metadata
1798
1871
  )
@@ -1807,7 +1880,7 @@ var ActorConnRaw = class {
1807
1880
  tag: "ActionResponse",
1808
1881
  val: {
1809
1882
  id: msg.body.val.id,
1810
- output: cbor3.decode(
1883
+ output: cbor4.decode(
1811
1884
  new Uint8Array(msg.body.val.output)
1812
1885
  )
1813
1886
  }
@@ -1819,7 +1892,7 @@ var ActorConnRaw = class {
1819
1892
  tag: "Event",
1820
1893
  val: {
1821
1894
  name: msg.body.val.name,
1822
- args: cbor3.decode(
1895
+ args: cbor4.decode(
1823
1896
  new Uint8Array(msg.body.val.args)
1824
1897
  )
1825
1898
  }
@@ -1872,7 +1945,7 @@ var ActorConnRaw = class {
1872
1945
  if (this.#websocket) {
1873
1946
  const ws = this.#websocket;
1874
1947
  if (ws.readyState !== 2 && ws.readyState !== 3) {
1875
- const { promise, resolve } = promiseWithResolvers();
1948
+ const { promise, resolve } = promiseWithResolvers((reason) => logger().warn({ msg: "unhandled websocket close promise rejection", reason }));
1876
1949
  ws.addEventListener("close", () => resolve(void 0));
1877
1950
  ws.close(1e3, "Disposed");
1878
1951
  await promise;
@@ -1899,7 +1972,7 @@ var ActorConnRaw = class {
1899
1972
  };
1900
1973
 
1901
1974
  // src/client/actor-handle.ts
1902
- import * as cbor4 from "cbor-x";
1975
+ import * as cbor5 from "cbor-x";
1903
1976
  import invariant5 from "invariant";
1904
1977
 
1905
1978
  // src/client/raw-utils.ts
@@ -2004,6 +2077,7 @@ var ActorHandleRaw = class {
2004
2077
  #encoding;
2005
2078
  #actorQuery;
2006
2079
  #params;
2080
+ #queueSender;
2007
2081
  /**
2008
2082
  * Do not call this directly.
2009
2083
  *
@@ -2017,6 +2091,21 @@ var ActorHandleRaw = class {
2017
2091
  this.#encoding = encoding;
2018
2092
  this.#actorQuery = actorQuery;
2019
2093
  this.#params = params;
2094
+ this.#queueSender = createQueueSender({
2095
+ encoding: this.#encoding,
2096
+ params: this.#params,
2097
+ customFetch: async (request) => {
2098
+ const { actorId } = await queryActor(
2099
+ void 0,
2100
+ this.#actorQuery,
2101
+ this.#driver
2102
+ );
2103
+ return this.#driver.sendRequest(actorId, request);
2104
+ }
2105
+ });
2106
+ }
2107
+ send(name, body, options) {
2108
+ return this.#queueSender.send(name, body, options);
2020
2109
  }
2021
2110
  /**
2022
2111
  * Call a raw action. This method sends an HTTP request to invoke the named action.
@@ -2067,12 +2156,12 @@ var ActorHandleRaw = class {
2067
2156
  }),
2068
2157
  // BARE Request: args needs to be CBOR-encoded
2069
2158
  requestToBare: (args) => ({
2070
- args: bufferToArrayBuffer(cbor4.encode(args))
2159
+ args: bufferToArrayBuffer(cbor5.encode(args))
2071
2160
  }),
2072
2161
  // JSON Response: output is the raw value
2073
2162
  responseFromJson: (json) => json.output,
2074
2163
  // BARE Response: output is ArrayBuffer that needs CBOR-decoding
2075
- responseFromBare: (bare) => cbor4.decode(new Uint8Array(bare.output))
2164
+ responseFromBare: (bare) => cbor5.decode(new Uint8Array(bare.output))
2076
2165
  });
2077
2166
  return responseData;
2078
2167
  } catch (err) {
@@ -2120,13 +2209,10 @@ var ActorHandleRaw = class {
2120
2209
  );
2121
2210
  }
2122
2211
  /**
2123
- * Makes a raw HTTP request to the actor.
2124
- *
2125
- * @param input - The URL, path, or Request object
2126
- * @param init - Standard fetch RequestInit options
2127
- * @returns Promise<Response> - The raw HTTP response
2212
+ * Fetches a resource from this actor via the /request endpoint. This is a
2213
+ * convenience wrapper around the raw HTTP API.
2128
2214
  */
2129
- async fetch(input, init) {
2215
+ fetch(input, init) {
2130
2216
  return rawHttpFetch(
2131
2217
  this.#driver,
2132
2218
  this.#actorQuery,
@@ -2136,13 +2222,9 @@ var ActorHandleRaw = class {
2136
2222
  );
2137
2223
  }
2138
2224
  /**
2139
- * Creates a raw WebSocket connection to the actor.
2140
- *
2141
- * @param path - The path for the WebSocket connection (e.g., "stream")
2142
- * @param protocols - Optional WebSocket subprotocols
2143
- * @returns WebSocket - A raw WebSocket connection
2225
+ * Opens a raw WebSocket connection to this actor.
2144
2226
  */
2145
- async websocket(path, protocols) {
2227
+ webSocket(path, protocols) {
2146
2228
  return rawWebSocket(
2147
2229
  this.#driver,
2148
2230
  this.#actorQuery,
@@ -2154,16 +2236,18 @@ var ActorHandleRaw = class {
2154
2236
  /**
2155
2237
  * Resolves the actor to get its unique actor ID.
2156
2238
  */
2157
- async resolve({ signal } = {}) {
2158
- if ("getForKey" in this.#actorQuery || "getOrCreateForKey" in this.#actorQuery) {
2159
- let name;
2160
- if ("getForKey" in this.#actorQuery) {
2161
- name = this.#actorQuery.getForKey.name;
2162
- } else if ("getOrCreateForKey" in this.#actorQuery) {
2163
- name = this.#actorQuery.getOrCreateForKey.name;
2164
- } else {
2165
- assertUnreachable2(this.#actorQuery);
2166
- }
2239
+ async resolve() {
2240
+ if ("getForKey" in this.#actorQuery) {
2241
+ const name = this.#actorQuery.getForKey.name;
2242
+ const { actorId } = await queryActor(
2243
+ void 0,
2244
+ this.#actorQuery,
2245
+ this.#driver
2246
+ );
2247
+ this.#actorQuery = { getForId: { actorId, name } };
2248
+ return actorId;
2249
+ } else if ("getOrCreateForKey" in this.#actorQuery) {
2250
+ const name = this.#actorQuery.getOrCreateForKey.name;
2167
2251
  const { actorId } = await queryActor(
2168
2252
  void 0,
2169
2253
  this.#actorQuery,
@@ -2193,8 +2277,8 @@ var ActorHandleRaw = class {
2193
2277
  };
2194
2278
 
2195
2279
  // src/client/client.ts
2196
- var ACTOR_CONNS_SYMBOL = Symbol("actorConns");
2197
- var CREATE_ACTOR_CONN_PROXY = Symbol("createActorConnProxy");
2280
+ var ACTOR_CONNS_SYMBOL = /* @__PURE__ */ Symbol("actorConns");
2281
+ var CREATE_ACTOR_CONN_PROXY = /* @__PURE__ */ Symbol("createActorConnProxy");
2198
2282
  var ClientRaw = class {
2199
2283
  #disposed = false;
2200
2284
  [ACTOR_CONNS_SYMBOL] = /* @__PURE__ */ new Set();
@@ -2426,9 +2510,7 @@ function createActorProxy(handle) {
2426
2510
  },
2427
2511
  // Support for 'in' operator
2428
2512
  has(target, prop) {
2429
- if (typeof prop === "string") {
2430
- return true;
2431
- }
2513
+ if (typeof prop === "string") return true;
2432
2514
  return Reflect.has(target, prop);
2433
2515
  },
2434
2516
  // Support instanceof checks
@@ -2462,7 +2544,7 @@ function createActorProxy(handle) {
2462
2544
  }
2463
2545
 
2464
2546
  // src/client/config.ts
2465
- import z2 from "zod";
2547
+ import z2 from "zod/v4";
2466
2548
  function getDefaultEndpoint() {
2467
2549
  var _a;
2468
2550
  if (typeof window !== "undefined" && ((_a = window.location) == null ? void 0 : _a.origin)) {
@@ -2541,2207 +2623,20 @@ function convertRegistryConfigToClientConfig(config) {
2541
2623
  };
2542
2624
  }
2543
2625
 
2544
- // src/actor/instance/mod.ts
2545
- import invariant7 from "invariant";
2546
-
2547
- // src/inspector/actor-inspector.ts
2548
- import * as cbor5 from "cbor-x";
2549
- import { createNanoEvents } from "nanoevents";
2550
- var ActorInspector = class {
2551
- constructor(actor) {
2552
- this.actor = actor;
2553
- this.emitter.on("eventFired", (event) => {
2554
- const commonParams = {
2555
- id: crypto.randomUUID(),
2556
- timestamp: BigInt(Date.now())
2557
- };
2558
- this.#lastEvents.push({
2559
- ...commonParams,
2560
- ...transformEvent(event)
2561
- });
2562
- if (this.#lastEvents.length > 100) {
2563
- this.#lastEvents = this.#lastEvents.slice(-100);
2564
- }
2565
- });
2566
- }
2567
- emitter = createNanoEvents();
2568
- #lastEvents = [];
2569
- getLastEvents() {
2570
- return this.#lastEvents;
2571
- }
2572
- clearEvents() {
2573
- this.#lastEvents = [];
2574
- this.emitter.emit("eventsChanged");
2575
- }
2576
- // actor accessor methods
2577
- isDatabaseEnabled() {
2578
- try {
2579
- return this.actor.db !== void 0;
2580
- } catch {
2581
- return false;
2582
- }
2583
- }
2584
- isStateEnabled() {
2585
- return this.actor.stateEnabled;
2586
- }
2587
- getState() {
2588
- if (!this.actor.stateEnabled) {
2589
- throw new StateNotEnabled();
2590
- }
2591
- return bufferToArrayBuffer(
2592
- cbor5.encode(this.actor.stateManager.persistRaw.state)
2593
- );
2594
- }
2595
- getRpcs() {
2596
- return this.actor.actions;
2597
- }
2598
- getConnections() {
2599
- return Array.from(
2600
- this.actor.connectionManager.connections.entries()
2601
- ).map(([id, conn]) => {
2602
- var _a, _b;
2603
- const connStateManager = conn[CONN_STATE_MANAGER_SYMBOL];
2604
- return {
2605
- type: (_a = conn[CONN_DRIVER_SYMBOL]) == null ? void 0 : _a.type,
2606
- id,
2607
- details: bufferToArrayBuffer(
2608
- cbor5.encode({
2609
- type: (_b = conn[CONN_DRIVER_SYMBOL]) == null ? void 0 : _b.type,
2610
- params: conn.params,
2611
- stateEnabled: connStateManager.stateEnabled,
2612
- state: connStateManager.stateEnabled ? connStateManager.state : void 0,
2613
- subscriptions: conn.subscriptions.size,
2614
- isHibernatable: conn.isHibernatable
2615
- // TODO: Include underlying hibernatable metadata +
2616
- // path + headers
2617
- })
2618
- )
2619
- };
2620
- });
2621
- }
2622
- async setState(state) {
2623
- if (!this.actor.stateEnabled) {
2624
- throw new StateNotEnabled();
2625
- }
2626
- this.actor.stateManager.state = cbor5.decode(Buffer.from(state));
2627
- await this.actor.stateManager.saveState({ immediate: true });
2628
- }
2629
- async executeAction(name, params) {
2630
- const conn = await this.actor.connectionManager.prepareAndConnectConn(
2631
- createHttpDriver(),
2632
- // TODO: This may cause issues
2633
- void 0,
2634
- void 0,
2635
- void 0,
2636
- void 0
2637
- );
2638
- try {
2639
- return bufferToArrayBuffer(
2640
- cbor5.encode(
2641
- await this.actor.executeAction(
2642
- new ActionContext(this.actor, conn),
2643
- name,
2644
- cbor5.decode(Buffer.from(params))
2645
- )
2646
- )
2647
- );
2648
- } finally {
2649
- conn.disconnect();
2650
- }
2651
- }
2652
- };
2653
- function transformEvent(event) {
2654
- if (event.type === "action") {
2655
- return {
2656
- body: {
2657
- tag: "ActionEvent",
2658
- val: {
2659
- name: event.name,
2660
- args: bufferToArrayBuffer(cbor5.encode(event.args)),
2661
- connId: event.connId
2662
- }
2663
- }
2664
- };
2665
- } else if (event.type === "subscribe") {
2666
- return {
2667
- body: {
2668
- tag: "SubscribeEvent",
2669
- val: {
2670
- eventName: event.eventName,
2671
- connId: event.connId
2672
- }
2673
- }
2674
- };
2675
- } else if (event.type === "unsubscribe") {
2676
- return {
2677
- body: {
2678
- tag: "UnSubscribeEvent",
2679
- val: {
2680
- eventName: event.eventName,
2681
- connId: event.connId
2682
- }
2683
- }
2684
- };
2685
- } else if (event.type === "event") {
2686
- return {
2687
- body: {
2688
- tag: "FiredEvent",
2689
- val: {
2690
- eventName: event.eventName,
2691
- args: bufferToArrayBuffer(cbor5.encode(event.args)),
2692
- connId: event.connId
2693
- }
2694
- }
2695
- };
2696
- } else if (event.type === "broadcast") {
2697
- return {
2698
- body: {
2699
- tag: "BroadcastEvent",
2700
- val: {
2701
- eventName: event.eventName,
2702
- args: bufferToArrayBuffer(cbor5.encode(event.args))
2703
- }
2704
- }
2705
- };
2706
- } else {
2707
- assertUnreachable(event);
2626
+ // src/client/mod.ts
2627
+ function createClient(endpointOrConfig) {
2628
+ const configInput = endpointOrConfig === void 0 ? {} : typeof endpointOrConfig === "string" ? { endpoint: endpointOrConfig } : endpointOrConfig;
2629
+ const config = ClientConfigSchema.parse(configInput);
2630
+ const driver = new RemoteManagerDriver(config);
2631
+ if (config.devtools) {
2632
+ injectDevtools(config);
2708
2633
  }
2709
- }
2710
-
2711
- // src/actor/conn/persisted.ts
2712
- import * as cbor6 from "cbor-x";
2713
- function convertConnToBarePersistedConn(persist) {
2714
- return {
2715
- id: persist.id,
2716
- parameters: bufferToArrayBuffer(cbor6.encode(persist.parameters)),
2717
- state: bufferToArrayBuffer(cbor6.encode(persist.state)),
2718
- subscriptions: persist.subscriptions.map((sub) => ({
2719
- eventName: sub.eventName
2720
- })),
2721
- gatewayId: persist.gatewayId,
2722
- requestId: persist.requestId,
2723
- serverMessageIndex: persist.serverMessageIndex,
2724
- clientMessageIndex: persist.clientMessageIndex,
2725
- requestPath: persist.requestPath,
2726
- requestHeaders: new Map(Object.entries(persist.requestHeaders))
2727
- };
2728
- }
2729
- function convertConnFromBarePersistedConn(bareData) {
2730
- return {
2731
- id: bareData.id,
2732
- parameters: cbor6.decode(new Uint8Array(bareData.parameters)),
2733
- state: cbor6.decode(new Uint8Array(bareData.state)),
2734
- subscriptions: bareData.subscriptions.map((sub) => ({
2735
- eventName: sub.eventName
2736
- })),
2737
- gatewayId: bareData.gatewayId,
2738
- requestId: bareData.requestId,
2739
- serverMessageIndex: bareData.serverMessageIndex,
2740
- clientMessageIndex: bareData.clientMessageIndex,
2741
- requestPath: bareData.requestPath,
2742
- requestHeaders: Object.fromEntries(bareData.requestHeaders)
2743
- };
2744
- }
2745
-
2746
- // src/actor/schedule.ts
2747
- var Schedule = class {
2748
- #actor;
2749
- constructor(actor) {
2750
- this.#actor = actor;
2751
- }
2752
- async after(duration, fn, ...args) {
2753
- await this.#actor.scheduleEvent(Date.now() + duration, fn, args);
2754
- }
2755
- async at(timestamp, fn, ...args) {
2756
- await this.#actor.scheduleEvent(timestamp, fn, args);
2757
- }
2758
- };
2759
-
2760
- // src/actor/instance/connection-manager.ts
2761
- import invariant6 from "invariant";
2762
- var ConnectionManager = class {
2763
- #actor;
2764
- #connections = /* @__PURE__ */ new Map();
2765
- /** Connections that have had their state changed and need to be persisted. */
2766
- #connsWithPersistChanged = /* @__PURE__ */ new Set();
2767
- constructor(actor) {
2768
- this.#actor = actor;
2769
- }
2770
- get connections() {
2771
- return this.#connections;
2772
- }
2773
- getConnForId(id) {
2774
- return this.#connections.get(id);
2775
- }
2776
- get connsWithPersistChanged() {
2777
- return this.#connsWithPersistChanged;
2778
- }
2779
- clearConnWithPersistChanged() {
2780
- this.#connsWithPersistChanged.clear();
2781
- }
2782
- markConnWithPersistChanged(conn) {
2783
- invariant6(
2784
- conn.isHibernatable,
2785
- "cannot mark non-hibernatable conn for persist"
2786
- );
2787
- this.#actor.rLog.debug({
2788
- msg: "marked connection as changed",
2789
- connId: conn.id,
2790
- totalChanged: this.#connsWithPersistChanged.size
2791
- });
2792
- this.#connsWithPersistChanged.add(conn.id);
2793
- this.#actor.stateManager.savePersistThrottled();
2794
- }
2795
- // MARK: - Connection Lifecycle
2796
- /**
2797
- * Handles pre-connection logic (i.e. auth & create state) before actually connecting the connection.
2798
- */
2799
- async prepareConn(driver, params, request, requestPath, requestHeaders, isHibernatable, isRestoringHibernatable) {
2800
- this.#actor.assertReady();
2801
- if (isRestoringHibernatable) {
2802
- return this.#reconnectHibernatableConn(driver);
2803
- }
2804
- if (this.#actor.config.onBeforeConnect) {
2805
- const ctx = new BeforeConnectContext(this.#actor, request);
2806
- await this.#actor.config.onBeforeConnect(ctx, params);
2807
- }
2808
- let connState;
2809
- if (this.#actor.connStateEnabled) {
2810
- connState = await this.#createConnState(params, request);
2811
- }
2812
- let connData;
2813
- if (isHibernatable) {
2814
- const hibernatable = driver.hibernatable;
2815
- invariant6(hibernatable, "must have hibernatable");
2816
- invariant6(requestPath, "missing requestPath for hibernatable ws");
2817
- invariant6(
2818
- requestHeaders,
2819
- "missing requestHeaders for hibernatable ws"
2820
- );
2821
- connData = {
2822
- hibernatable: {
2823
- id: crypto.randomUUID(),
2824
- parameters: params,
2825
- state: connState,
2826
- subscriptions: [],
2827
- gatewayId: hibernatable.gatewayId,
2828
- requestId: hibernatable.requestId,
2829
- clientMessageIndex: 0,
2830
- // First message index will be 1, so we start at 0
2831
- serverMessageIndex: 0,
2832
- requestPath,
2833
- requestHeaders
2834
- }
2835
- };
2836
- } else {
2837
- connData = {
2838
- ephemeral: {
2839
- id: crypto.randomUUID(),
2840
- parameters: params,
2841
- state: connState
2842
- }
2843
- };
2844
- }
2845
- const conn = new Conn(this.#actor, connData);
2846
- conn[CONN_DRIVER_SYMBOL] = driver;
2847
- return conn;
2848
- }
2849
- /**
2850
- * Adds a connection form prepareConn to the actor and calls onConnect.
2851
- *
2852
- * This method is intentionally not async since it needs to be called in
2853
- * `onOpen` for WebSockets. If this is async, the order of open events will
2854
- * be messed up and cause race conditions that can drop WebSocket messages.
2855
- * So all async work in prepareConn.
2856
- */
2857
- connectConn(conn) {
2858
- invariant6(!this.#connections.has(conn.id), "conn already connected");
2859
- this.#connections.set(conn.id, conn);
2860
- if (this.#actor.driver.onCreateConn) {
2861
- this.#actor.driver.onCreateConn(conn);
2862
- }
2863
- if (conn.isHibernatable) {
2864
- this.markConnWithPersistChanged(conn);
2865
- }
2866
- this.#callOnConnect(conn);
2867
- this.#actor.inspector.emitter.emit("connectionsUpdated");
2868
- this.#actor.resetSleepTimer();
2869
- conn[CONN_CONNECTED_SYMBOL] = true;
2870
- if (conn[CONN_SPEAKS_RIVETKIT_SYMBOL]) {
2871
- const initData = { actorId: this.#actor.id, connectionId: conn.id };
2872
- conn[CONN_SEND_MESSAGE_SYMBOL](
2873
- new CachedSerializer(
2874
- initData,
2875
- TO_CLIENT_VERSIONED,
2876
- CURRENT_VERSION,
2877
- ToClientSchema,
2878
- // JSON: identity conversion (no nested data to encode)
2879
- (value) => ({
2880
- body: {
2881
- tag: "Init",
2882
- val: value
2883
- }
2884
- }),
2885
- // BARE/CBOR: identity conversion (no nested data to encode)
2886
- (value) => ({
2887
- body: {
2888
- tag: "Init",
2889
- val: value
2890
- }
2891
- })
2892
- )
2893
- );
2894
- }
2895
- }
2896
- #reconnectHibernatableConn(driver) {
2897
- invariant6(driver.hibernatable, "missing requestIdBuf");
2898
- const existingConn = this.findHibernatableConn(
2899
- driver.hibernatable.gatewayId,
2900
- driver.hibernatable.requestId
2901
- );
2902
- invariant6(
2903
- existingConn,
2904
- "cannot find connection for restoring connection"
2905
- );
2906
- this.#actor.rLog.debug({
2907
- msg: "reconnecting hibernatable websocket connection",
2908
- connectionId: existingConn.id
2909
- });
2910
- if (existingConn[CONN_DRIVER_SYMBOL]) {
2911
- this.#disconnectExistingDriver(existingConn);
2912
- }
2913
- existingConn[CONN_DRIVER_SYMBOL] = driver;
2914
- this.#actor.resetSleepTimer();
2915
- existingConn[CONN_CONNECTED_SYMBOL] = true;
2916
- this.#actor.inspector.emitter.emit("connectionsUpdated");
2917
- return existingConn;
2918
- }
2919
- #disconnectExistingDriver(conn) {
2920
- const driver = conn[CONN_DRIVER_SYMBOL];
2921
- if (driver == null ? void 0 : driver.disconnect) {
2922
- driver.disconnect(
2923
- this.#actor,
2924
- conn,
2925
- "Reconnecting hibernatable websocket with new driver state"
2926
- );
2927
- }
2928
- }
2929
- /**
2930
- * Handle connection disconnection.
2931
- *
2932
- * This is called by `Conn.disconnect`. This should not call `Conn.disconnect.`
2933
- */
2934
- async connDisconnected(conn) {
2935
- this.#connections.delete(conn.id);
2936
- this.#actor.rLog.debug({ msg: "removed conn", connId: conn.id });
2937
- if (this.#actor.driver.onDestroyConn) {
2938
- this.#actor.driver.onDestroyConn(conn);
2939
- }
2940
- for (const eventName of [...conn.subscriptions.values()]) {
2941
- this.#actor.eventManager.removeSubscription(eventName, conn, true);
2942
- }
2943
- this.#actor.resetSleepTimer();
2944
- this.#actor.inspector.emitter.emit("connectionsUpdated");
2945
- if (this.#actor.config.onDisconnect) {
2946
- try {
2947
- const result = this.#actor.config.onDisconnect(
2948
- this.#actor.actorContext,
2949
- conn
2950
- );
2951
- if (result instanceof Promise) {
2952
- result.catch((error) => {
2953
- this.#actor.rLog.error({
2954
- msg: "error in `onDisconnect`",
2955
- error: stringifyError(error)
2956
- });
2957
- });
2958
- }
2959
- } catch (error) {
2960
- this.#actor.rLog.error({
2961
- msg: "error in `onDisconnect`",
2962
- error: stringifyError(error)
2963
- });
2964
- }
2965
- }
2966
- this.#connsWithPersistChanged.delete(conn.id);
2967
- if (conn.isHibernatable) {
2968
- const key = makeConnKey(conn.id);
2969
- try {
2970
- await this.#actor.driver.kvBatchDelete(this.#actor.id, [key]);
2971
- this.#actor.rLog.debug({
2972
- msg: "removed connection from KV",
2973
- connId: conn.id
2974
- });
2975
- } catch (err) {
2976
- this.#actor.rLog.error({
2977
- msg: "kvBatchDelete failed for conn",
2978
- err: stringifyError(err)
2979
- });
2980
- }
2981
- }
2982
- }
2983
- /**
2984
- * Utilify function for call sites that don't need a separate prepare and connect phase.
2985
- */
2986
- async prepareAndConnectConn(driver, params, request, requestPath, requestHeaders) {
2987
- const conn = await this.prepareConn(
2988
- driver,
2989
- params,
2990
- request,
2991
- requestPath,
2992
- requestHeaders,
2993
- false,
2994
- false
2995
- );
2996
- this.connectConn(conn);
2997
- return conn;
2998
- }
2999
- // MARK: - Persistence
3000
- /**
3001
- * Restores connections from persisted data during actor initialization.
3002
- */
3003
- restoreConnections(connections) {
3004
- for (const connPersist of connections) {
3005
- const conn = new Conn(this.#actor, {
3006
- hibernatable: connPersist
3007
- });
3008
- this.#connections.set(conn.id, conn);
3009
- if (this.#actor.driver.onCreateConn) {
3010
- this.#actor.driver.onCreateConn(conn);
3011
- }
3012
- for (const sub of connPersist.subscriptions) {
3013
- this.#actor.eventManager.addSubscription(
3014
- sub.eventName,
3015
- conn,
3016
- true
3017
- );
3018
- }
3019
- }
3020
- }
3021
- // MARK: - Private Helpers
3022
- findHibernatableConn(gatewayIdBuf, requestIdBuf) {
3023
- return Array.from(this.#connections.values()).find((conn) => {
3024
- const connStateManager = conn[CONN_STATE_MANAGER_SYMBOL];
3025
- const h = connStateManager.hibernatableDataRaw;
3026
- return h && arrayBuffersEqual(h.gatewayId, gatewayIdBuf) && arrayBuffersEqual(h.requestId, requestIdBuf);
3027
- });
3028
- }
3029
- async #createConnState(params, request) {
3030
- if ("createConnState" in this.#actor.config) {
3031
- const ctx = new CreateConnStateContext(this.#actor, request);
3032
- const dataOrPromise = this.#actor.config.createConnState(
3033
- ctx,
3034
- params
3035
- );
3036
- if (dataOrPromise instanceof Promise) {
3037
- return await deadline(
3038
- dataOrPromise,
3039
- this.#actor.config.options.createConnStateTimeout
3040
- );
3041
- }
3042
- return dataOrPromise;
3043
- } else if ("connState" in this.#actor.config) {
3044
- return structuredClone(this.#actor.config.connState);
3045
- }
3046
- throw new Error(
3047
- "Could not create connection state from 'createConnState' or 'connState'"
3048
- );
3049
- }
3050
- #callOnConnect(conn) {
3051
- if (this.#actor.config.onConnect) {
3052
- try {
3053
- const ctx = new ConnectContext(this.#actor, conn);
3054
- const result = this.#actor.config.onConnect(ctx, conn);
3055
- if (result instanceof Promise) {
3056
- deadline(
3057
- result,
3058
- this.#actor.config.options.onConnectTimeout
3059
- ).catch((error) => {
3060
- this.#actor.rLog.error({
3061
- msg: "error in `onConnect`, closing socket",
3062
- error
3063
- });
3064
- conn == null ? void 0 : conn.disconnect("`onConnect` failed");
3065
- });
3066
- }
3067
- } catch (error) {
3068
- this.#actor.rLog.error({
3069
- msg: "error in `onConnect`",
3070
- error: stringifyError(error)
3071
- });
3072
- conn == null ? void 0 : conn.disconnect("`onConnect` failed");
3073
- }
3074
- }
3075
- }
3076
- };
3077
-
3078
- // src/actor/instance/event-manager.ts
3079
- import * as cbor7 from "cbor-x";
3080
- var EventManager = class {
3081
- #actor;
3082
- #subscriptionIndex = /* @__PURE__ */ new Map();
3083
- constructor(actor) {
3084
- this.#actor = actor;
3085
- }
3086
- // MARK: - Public API
3087
- /**
3088
- * Adds a subscription for a connection to an event.
3089
- *
3090
- * @param eventName - The name of the event to subscribe to
3091
- * @param connection - The connection subscribing to the event
3092
- * @param fromPersist - Whether this subscription is being restored from persistence
3093
- */
3094
- addSubscription(eventName, connection, fromPersist) {
3095
- if (connection.subscriptions.has(eventName)) {
3096
- this.#actor.rLog.debug({
3097
- msg: "connection already has subscription",
3098
- eventName,
3099
- connId: connection.id
3100
- });
3101
- return;
3102
- }
3103
- connection.subscriptions.add(eventName);
3104
- let subscribers = this.#subscriptionIndex.get(eventName);
3105
- if (!subscribers) {
3106
- subscribers = /* @__PURE__ */ new Set();
3107
- this.#subscriptionIndex.set(eventName, subscribers);
3108
- }
3109
- subscribers.add(connection);
3110
- if (!fromPersist) {
3111
- connection[CONN_STATE_MANAGER_SYMBOL].addSubscription({
3112
- eventName
3113
- });
3114
- this.#actor.stateManager.saveState({ immediate: true });
3115
- }
3116
- this.#actor.rLog.debug({
3117
- msg: "subscription added",
3118
- eventName,
3119
- connId: connection.id,
3120
- totalSubscribers: subscribers.size
3121
- });
3122
- }
3123
- /**
3124
- * Removes a subscription for a connection from an event.
3125
- *
3126
- * @param eventName - The name of the event to unsubscribe from
3127
- * @param connection - The connection unsubscribing from the event
3128
- * @param fromRemoveConn - Whether this is being called as part of connection removal
3129
- */
3130
- removeSubscription(eventName, connection, fromRemoveConn) {
3131
- if (!connection.subscriptions.has(eventName)) {
3132
- this.#actor.rLog.warn({
3133
- msg: "connection does not have subscription",
3134
- eventName,
3135
- connId: connection.id
3136
- });
3137
- return;
3138
- }
3139
- connection.subscriptions.delete(eventName);
3140
- const subscribers = this.#subscriptionIndex.get(eventName);
3141
- if (subscribers) {
3142
- subscribers.delete(connection);
3143
- if (subscribers.size === 0) {
3144
- this.#subscriptionIndex.delete(eventName);
3145
- }
3146
- }
3147
- if (!fromRemoveConn) {
3148
- const removed = connection[CONN_STATE_MANAGER_SYMBOL].removeSubscription({ eventName });
3149
- if (!removed) {
3150
- this.#actor.rLog.warn({
3151
- msg: "subscription does not exist in persist",
3152
- eventName,
3153
- connId: connection.id
3154
- });
3155
- }
3156
- this.#actor.stateManager.saveState({ immediate: true });
3157
- }
3158
- this.#actor.rLog.debug({
3159
- msg: "subscription removed",
3160
- eventName,
3161
- connId: connection.id,
3162
- remainingSubscribers: (subscribers == null ? void 0 : subscribers.size) || 0
3163
- });
3164
- }
3165
- /**
3166
- * Broadcasts an event to all subscribed connections.
3167
- *
3168
- * @param name - The name of the event to broadcast
3169
- * @param args - The arguments to send with the event
3170
- */
3171
- broadcast(name, ...args) {
3172
- this.#actor.assertReady();
3173
- this.#actor.inspector.emitter.emit("eventFired", {
3174
- type: "broadcast",
3175
- eventName: name,
3176
- args
3177
- });
3178
- const subscribers = this.#subscriptionIndex.get(name);
3179
- if (!subscribers || subscribers.size === 0) {
3180
- this.#actor.rLog.debug({
3181
- msg: "no subscribers for event",
3182
- eventName: name
3183
- });
3184
- return;
3185
- }
3186
- const eventData = { name, args };
3187
- const toClientSerializer = new CachedSerializer(
3188
- eventData,
3189
- TO_CLIENT_VERSIONED,
3190
- CURRENT_VERSION,
3191
- ToClientSchema,
3192
- // JSON: args is the raw value (array of arguments)
3193
- (value) => ({
3194
- body: {
3195
- tag: "Event",
3196
- val: {
3197
- name: value.name,
3198
- args: value.args
3199
- }
3200
- }
3201
- }),
3202
- // BARE/CBOR: args needs to be CBOR-encoded to ArrayBuffer
3203
- (value) => ({
3204
- body: {
3205
- tag: "Event",
3206
- val: {
3207
- name: value.name,
3208
- args: bufferToArrayBuffer(cbor7.encode(value.args))
3209
- }
3210
- }
3211
- })
3212
- );
3213
- let sentCount = 0;
3214
- for (const connection of subscribers) {
3215
- if (connection[CONN_SPEAKS_RIVETKIT_SYMBOL]) {
3216
- try {
3217
- connection[CONN_SEND_MESSAGE_SYMBOL](toClientSerializer);
3218
- sentCount++;
3219
- } catch (error) {
3220
- if (error instanceof OutgoingMessageTooLong) {
3221
- throw error;
3222
- }
3223
- this.#actor.rLog.error({
3224
- msg: "failed to send event to connection",
3225
- eventName: name,
3226
- connId: connection.id,
3227
- error: error instanceof Error ? error.message : String(error)
3228
- });
3229
- }
3230
- }
3231
- }
3232
- this.#actor.rLog.debug({
3233
- msg: "event broadcasted",
3234
- eventName: name,
3235
- subscriberCount: subscribers.size,
3236
- sentCount
3237
- });
3238
- }
3239
- /**
3240
- * Gets all subscribers for a specific event.
3241
- *
3242
- * @param eventName - The name of the event
3243
- * @returns Set of connections subscribed to the event, or undefined if no subscribers
3244
- */
3245
- getSubscribers(eventName) {
3246
- return this.#subscriptionIndex.get(eventName);
3247
- }
3248
- /**
3249
- * Gets all events and their subscriber counts.
3250
- *
3251
- * @returns Map of event names to subscriber counts
3252
- */
3253
- getEventStats() {
3254
- const stats = /* @__PURE__ */ new Map();
3255
- for (const [eventName, subscribers] of this.#subscriptionIndex) {
3256
- stats.set(eventName, subscribers.size);
3257
- }
3258
- return stats;
3259
- }
3260
- /**
3261
- * Clears all subscriptions for a connection.
3262
- * Used during connection cleanup.
3263
- *
3264
- * @param connection - The connection to clear subscriptions for
3265
- */
3266
- clearConnectionSubscriptions(connection) {
3267
- for (const eventName of [...connection.subscriptions.values()]) {
3268
- this.removeSubscription(eventName, connection, true);
3269
- }
3270
- }
3271
- /**
3272
- * Gets the total number of unique events being subscribed to.
3273
- */
3274
- get eventCount() {
3275
- return this.#subscriptionIndex.size;
3276
- }
3277
- /**
3278
- * Gets the total number of subscriptions across all events.
3279
- */
3280
- get totalSubscriptionCount() {
3281
- let total = 0;
3282
- for (const subscribers of this.#subscriptionIndex.values()) {
3283
- total += subscribers.size;
3284
- }
3285
- return total;
3286
- }
3287
- /**
3288
- * Checks if an event has any subscribers.
3289
- *
3290
- * @param eventName - The name of the event to check
3291
- * @returns True if the event has at least one subscriber
3292
- */
3293
- hasSubscribers(eventName) {
3294
- const subscribers = this.#subscriptionIndex.get(eventName);
3295
- return subscribers !== void 0 && subscribers.size > 0;
3296
- }
3297
- };
3298
-
3299
- // src/actor/instance/persisted.ts
3300
- import * as cbor8 from "cbor-x";
3301
- function convertActorToBarePersisted(persist) {
3302
- return {
3303
- input: persist.input !== void 0 ? bufferToArrayBuffer(cbor8.encode(persist.input)) : null,
3304
- hasInitialized: persist.hasInitialized,
3305
- state: bufferToArrayBuffer(cbor8.encode(persist.state)),
3306
- scheduledEvents: persist.scheduledEvents.map((event) => ({
3307
- eventId: event.eventId,
3308
- timestamp: BigInt(event.timestamp),
3309
- action: event.action,
3310
- args: event.args ?? null
3311
- }))
3312
- };
3313
- }
3314
- function convertActorFromBarePersisted(bareData) {
3315
- return {
3316
- input: bareData.input ? cbor8.decode(new Uint8Array(bareData.input)) : void 0,
3317
- hasInitialized: bareData.hasInitialized,
3318
- state: cbor8.decode(new Uint8Array(bareData.state)),
3319
- scheduledEvents: bareData.scheduledEvents.map((event) => ({
3320
- eventId: event.eventId,
3321
- timestamp: Number(event.timestamp),
3322
- action: event.action,
3323
- args: event.args ?? void 0
3324
- }))
3325
- };
3326
- }
3327
-
3328
- // src/actor/instance/schedule-manager.ts
3329
- import * as cbor9 from "cbor-x";
3330
- var ScheduleManager = class {
3331
- #actor;
3332
- #actorDriver;
3333
- #alarmWriteQueue = new SinglePromiseQueue();
3334
- #config;
3335
- // ActorConfig type
3336
- #persist;
3337
- // Reference to PersistedActor
3338
- constructor(actor, actorDriver, config) {
3339
- this.#actor = actor;
3340
- this.#actorDriver = actorDriver;
3341
- this.#config = config;
3342
- }
3343
- // MARK: - Public API
3344
- /**
3345
- * Sets the persist object reference.
3346
- * Called after StateManager initializes the persist proxy.
3347
- */
3348
- setPersist(persist) {
3349
- this.#persist = persist;
3350
- }
3351
- /**
3352
- * Schedules an event to be executed at a specific timestamp.
3353
- *
3354
- * @param timestamp - Unix timestamp in milliseconds when the event should fire
3355
- * @param action - The name of the action to execute
3356
- * @param args - Arguments to pass to the action
3357
- */
3358
- async scheduleEvent(timestamp, action, args) {
3359
- const newEvent = {
3360
- eventId: crypto.randomUUID(),
3361
- timestamp,
3362
- action,
3363
- args: bufferToArrayBuffer(cbor9.encode(args))
3364
- };
3365
- await this.#scheduleEventInner(newEvent);
3366
- }
3367
- /**
3368
- * Triggers any pending alarms that are due.
3369
- * This method is idempotent and safe to call multiple times.
3370
- */
3371
- async onAlarm() {
3372
- var _a, _b, _c;
3373
- const now = Date.now();
3374
- this.#actor.log.debug({
3375
- msg: "alarm triggered",
3376
- now,
3377
- events: ((_b = (_a = this.#persist) == null ? void 0 : _a.scheduledEvents) == null ? void 0 : _b.length) || 0
3378
- });
3379
- if (!((_c = this.#persist) == null ? void 0 : _c.scheduledEvents)) {
3380
- this.#actor.rLog.debug({ msg: "no scheduled events" });
3381
- return;
3382
- }
3383
- const dueIndex = this.#persist.scheduledEvents.findIndex(
3384
- (x) => x.timestamp <= now
3385
- );
3386
- if (dueIndex === -1) {
3387
- this.#actor.rLog.debug({ msg: "no events are due yet" });
3388
- if (this.#persist.scheduledEvents.length > 0) {
3389
- const nextTs = this.#persist.scheduledEvents[0].timestamp;
3390
- this.#actor.log.debug({
3391
- msg: "alarm fired early, rescheduling for next event",
3392
- now,
3393
- nextTs,
3394
- delta: nextTs - now
3395
- });
3396
- await this.#queueSetAlarm(nextTs);
3397
- }
3398
- return;
3399
- }
3400
- const dueEvents = this.#persist.scheduledEvents.splice(0, dueIndex + 1);
3401
- this.#actor.log.debug({
3402
- msg: "running events",
3403
- count: dueEvents.length
3404
- });
3405
- if (this.#persist.scheduledEvents.length > 0) {
3406
- const nextTs = this.#persist.scheduledEvents[0].timestamp;
3407
- this.#actor.log.info({
3408
- msg: "setting next alarm",
3409
- nextTs,
3410
- remainingEvents: this.#persist.scheduledEvents.length
3411
- });
3412
- await this.#queueSetAlarm(nextTs);
3413
- }
3414
- await this.#executeDueEvents(dueEvents);
3415
- }
3416
- /**
3417
- * Initializes alarms on actor startup.
3418
- * Sets the alarm for the next scheduled event if any exist.
3419
- */
3420
- async initializeAlarms() {
3421
- var _a, _b;
3422
- if (((_b = (_a = this.#persist) == null ? void 0 : _a.scheduledEvents) == null ? void 0 : _b.length) > 0) {
3423
- await this.#queueSetAlarm(
3424
- this.#persist.scheduledEvents[0].timestamp
3425
- );
3426
- }
3427
- }
3428
- /**
3429
- * Waits for any pending alarm write operations to complete.
3430
- */
3431
- async waitForPendingAlarmWrites() {
3432
- if (this.#alarmWriteQueue.runningDrainLoop) {
3433
- await this.#alarmWriteQueue.runningDrainLoop;
3434
- }
3435
- }
3436
- /**
3437
- * Gets statistics about scheduled events.
3438
- */
3439
- getScheduleStats() {
3440
- var _a;
3441
- if (!((_a = this.#persist) == null ? void 0 : _a.scheduledEvents)) {
3442
- return {
3443
- totalEvents: 0,
3444
- nextEventTime: null,
3445
- overdueCount: 0
3446
- };
3447
- }
3448
- const now = Date.now();
3449
- const events = this.#persist.scheduledEvents;
3450
- return {
3451
- totalEvents: events.length,
3452
- nextEventTime: events.length > 0 ? events[0].timestamp : null,
3453
- overdueCount: events.filter(
3454
- (e) => e.timestamp <= now
3455
- ).length
3456
- };
3457
- }
3458
- /**
3459
- * Cancels a scheduled event by its ID.
3460
- *
3461
- * @param eventId - The ID of the event to cancel
3462
- * @returns True if the event was found and cancelled
3463
- */
3464
- async cancelEvent(eventId) {
3465
- var _a;
3466
- if (!((_a = this.#persist) == null ? void 0 : _a.scheduledEvents)) {
3467
- return false;
3468
- }
3469
- const index = this.#persist.scheduledEvents.findIndex(
3470
- (e) => e.eventId === eventId
3471
- );
3472
- if (index === -1) {
3473
- return false;
3474
- }
3475
- const wasFirst = index === 0;
3476
- this.#persist.scheduledEvents.splice(index, 1);
3477
- if (wasFirst && this.#persist.scheduledEvents.length > 0) {
3478
- await this.#queueSetAlarm(
3479
- this.#persist.scheduledEvents[0].timestamp
3480
- );
3481
- }
3482
- this.#actor.log.info({
3483
- msg: "cancelled scheduled event",
3484
- eventId,
3485
- remainingEvents: this.#persist.scheduledEvents.length
3486
- });
3487
- return true;
3488
- }
3489
- // MARK: - Private Helpers
3490
- async #scheduleEventInner(newEvent) {
3491
- var _a;
3492
- this.#actor.log.info({
3493
- msg: "scheduling event",
3494
- eventId: newEvent.eventId,
3495
- timestamp: newEvent.timestamp,
3496
- action: newEvent.action
3497
- });
3498
- if (!((_a = this.#persist) == null ? void 0 : _a.scheduledEvents)) {
3499
- throw new Error("Persist not initialized");
3500
- }
3501
- const insertIndex = this.#persist.scheduledEvents.findIndex(
3502
- (x) => x.timestamp > newEvent.timestamp
3503
- );
3504
- if (insertIndex === -1) {
3505
- this.#persist.scheduledEvents.push(newEvent);
3506
- } else {
3507
- this.#persist.scheduledEvents.splice(insertIndex, 0, newEvent);
3508
- }
3509
- if (insertIndex === 0 || this.#persist.scheduledEvents.length === 1) {
3510
- this.#actor.log.info({
3511
- msg: "setting alarm for new event",
3512
- timestamp: newEvent.timestamp,
3513
- eventCount: this.#persist.scheduledEvents.length
3514
- });
3515
- await this.#queueSetAlarm(newEvent.timestamp);
3516
- }
3517
- }
3518
- async #executeDueEvents(events) {
3519
- for (const event of events) {
3520
- try {
3521
- this.#actor.log.info({
3522
- msg: "executing scheduled event",
3523
- eventId: event.eventId,
3524
- timestamp: event.timestamp,
3525
- action: event.action
3526
- });
3527
- const actions = this.#config.actions ?? {};
3528
- const fn = actions[event.action];
3529
- if (!fn) {
3530
- throw new Error(
3531
- `Missing action for scheduled event: ${event.action}`
3532
- );
3533
- }
3534
- if (typeof fn !== "function") {
3535
- throw new Error(
3536
- `Scheduled event action ${event.action} is not a function (got ${typeof fn})`
3537
- );
3538
- }
3539
- const args = event.args ? cbor9.decode(new Uint8Array(event.args)) : [];
3540
- const result = fn.call(
3541
- void 0,
3542
- this.#actor.actorContext,
3543
- ...args
3544
- );
3545
- if (result instanceof Promise) {
3546
- await result;
3547
- }
3548
- this.#actor.log.debug({
3549
- msg: "scheduled event completed",
3550
- eventId: event.eventId,
3551
- action: event.action
3552
- });
3553
- } catch (error) {
3554
- this.#actor.log.error({
3555
- msg: "error executing scheduled event",
3556
- error: stringifyError(error),
3557
- eventId: event.eventId,
3558
- timestamp: event.timestamp,
3559
- action: event.action
3560
- });
3561
- }
3562
- }
3563
- }
3564
- async #queueSetAlarm(timestamp) {
3565
- await this.#alarmWriteQueue.enqueue(async () => {
3566
- await this.#actorDriver.setAlarm(this.#actor, timestamp);
3567
- });
3568
- }
3569
- /**
3570
- * Gets the next scheduled event, if any.
3571
- */
3572
- getNextEvent() {
3573
- var _a;
3574
- if (!((_a = this.#persist) == null ? void 0 : _a.scheduledEvents) || this.#persist.scheduledEvents.length === 0) {
3575
- return null;
3576
- }
3577
- return this.#persist.scheduledEvents[0];
3578
- }
3579
- /**
3580
- * Gets all scheduled events.
3581
- */
3582
- getAllEvents() {
3583
- var _a;
3584
- return ((_a = this.#persist) == null ? void 0 : _a.scheduledEvents) || [];
3585
- }
3586
- /**
3587
- * Clears all scheduled events.
3588
- * Use with caution - this removes all pending scheduled events.
3589
- */
3590
- clearAllEvents() {
3591
- var _a;
3592
- if ((_a = this.#persist) == null ? void 0 : _a.scheduledEvents) {
3593
- this.#persist.scheduledEvents = [];
3594
- this.#actor.log.warn({ msg: "cleared all scheduled events" });
3595
- }
3596
- }
3597
- };
3598
-
3599
- // src/actor/instance/state-manager.ts
3600
- import { idToStr } from "@rivetkit/engine-runner";
3601
- import onChange from "@rivetkit/on-change";
3602
- var StateManager = class {
3603
- #actor;
3604
- #actorDriver;
3605
- // State tracking
3606
- #persist;
3607
- #persistRaw;
3608
- #persistChanged = false;
3609
- #isInOnStateChange = false;
3610
- // Save management
3611
- #persistWriteQueue = new SinglePromiseQueue();
3612
- #lastSaveTime = 0;
3613
- #pendingSaveTimeout;
3614
- #pendingSaveScheduledTimestamp;
3615
- #onPersistSavedPromise;
3616
- // Configuration
3617
- #config;
3618
- // ActorConfig type
3619
- #stateSaveInterval;
3620
- constructor(actor, actorDriver, config) {
3621
- this.#actor = actor;
3622
- this.#actorDriver = actorDriver;
3623
- this.#config = config;
3624
- this.#stateSaveInterval = config.options.stateSaveInterval || 100;
3625
- }
3626
- // MARK: - Public API
3627
- get persist() {
3628
- return this.#persist;
3629
- }
3630
- get persistRaw() {
3631
- return this.#persistRaw;
3632
- }
3633
- get persistChanged() {
3634
- return this.#persistChanged;
3635
- }
3636
- get state() {
3637
- this.#validateStateEnabled();
3638
- return this.#persist.state;
3639
- }
3640
- set state(value) {
3641
- this.#validateStateEnabled();
3642
- this.#persist.state = value;
3643
- }
3644
- get stateEnabled() {
3645
- return "createState" in this.#config || "state" in this.#config;
3646
- }
3647
- // MARK: - Initialization
3648
- /**
3649
- * Initializes state from persisted data or creates new state.
3650
- */
3651
- async initializeState(persistData) {
3652
- if (!persistData.hasInitialized) {
3653
- let stateData;
3654
- if (this.stateEnabled) {
3655
- this.#actor.rLog.info({ msg: "actor state initializing" });
3656
- if ("createState" in this.#config) {
3657
- stateData = await this.#config.createState(
3658
- this.#actor.actorContext,
3659
- persistData.input
3660
- );
3661
- } else if ("state" in this.#config) {
3662
- stateData = structuredClone(this.#config.state);
3663
- } else {
3664
- throw new Error(
3665
- "Both 'createState' or 'state' were not defined"
3666
- );
3667
- }
3668
- } else {
3669
- this.#actor.rLog.debug({ msg: "state not enabled" });
3670
- }
3671
- persistData.state = stateData;
3672
- persistData.hasInitialized = true;
3673
- const bareData = convertActorToBarePersisted(persistData);
3674
- await this.#actorDriver.kvBatchPut(this.#actor.id, [
3675
- [
3676
- KEYS.PERSIST_DATA,
3677
- ACTOR_VERSIONED.serializeWithEmbeddedVersion(
3678
- bareData,
3679
- CURRENT_VERSION2
3680
- )
3681
- ]
3682
- ]);
3683
- }
3684
- this.initPersistProxy(persistData);
3685
- }
3686
- /**
3687
- * Creates proxy for persist object that handles automatic state change detection.
3688
- */
3689
- initPersistProxy(target) {
3690
- this.#persistRaw = target;
3691
- if (target === null || typeof target !== "object") {
3692
- let invalidPath = "";
3693
- if (!isCborSerializable(
3694
- target,
3695
- (path) => {
3696
- invalidPath = path;
3697
- },
3698
- ""
3699
- )) {
3700
- throw new InvalidStateType({ path: invalidPath });
3701
- }
3702
- return target;
3703
- }
3704
- if (this.#persist) {
3705
- onChange.unsubscribe(this.#persist);
3706
- }
3707
- this.#persist = onChange(
3708
- target,
3709
- (path, value, _previousValue, _applyData) => {
3710
- this.#handleStateChange(path, value);
3711
- },
3712
- { ignoreDetached: true }
3713
- );
3714
- }
3715
- // MARK: - State Persistence
3716
- /**
3717
- * Forces the state to get saved.
3718
- */
3719
- async saveState(opts) {
3720
- var _a;
3721
- this.#actor.assertReady(opts.allowStoppingState);
3722
- if (this.#persistChanged) {
3723
- if (opts.immediate) {
3724
- await this.#savePersistInner();
3725
- } else {
3726
- if (!this.#onPersistSavedPromise) {
3727
- this.#onPersistSavedPromise = promiseWithResolvers();
3728
- }
3729
- this.savePersistThrottled(opts.maxWait);
3730
- await ((_a = this.#onPersistSavedPromise) == null ? void 0 : _a.promise);
3731
- }
3732
- }
3733
- }
3734
- /**
3735
- * Throttled save state method. Used to write to KV at a reasonable cadence.
3736
- *
3737
- * Passing a maxWait will override the stateSaveInterval with the min
3738
- * between that and the maxWait.
3739
- */
3740
- savePersistThrottled(maxWait) {
3741
- const now = Date.now();
3742
- const timeSinceLastSave = now - this.#lastSaveTime;
3743
- let saveDelay = Math.max(
3744
- 0,
3745
- this.#stateSaveInterval - timeSinceLastSave
3746
- );
3747
- if (maxWait !== void 0) {
3748
- saveDelay = Math.min(saveDelay, maxWait);
3749
- }
3750
- if (this.#pendingSaveTimeout !== void 0 && this.#pendingSaveScheduledTimestamp !== void 0) {
3751
- const newScheduledTimestamp = now + saveDelay;
3752
- if (newScheduledTimestamp < this.#pendingSaveScheduledTimestamp) {
3753
- clearTimeout(this.#pendingSaveTimeout);
3754
- this.#pendingSaveTimeout = void 0;
3755
- this.#pendingSaveScheduledTimestamp = void 0;
3756
- } else {
3757
- return;
3758
- }
3759
- }
3760
- if (saveDelay > 0) {
3761
- this.#pendingSaveScheduledTimestamp = now + saveDelay;
3762
- this.#pendingSaveTimeout = setTimeout(() => {
3763
- this.#pendingSaveTimeout = void 0;
3764
- this.#pendingSaveScheduledTimestamp = void 0;
3765
- this.#savePersistInner().catch((error) => {
3766
- this.#actor.rLog.error({
3767
- msg: "error saving persist data in scheduled save",
3768
- error: stringifyError(error)
3769
- });
3770
- });
3771
- }, saveDelay);
3772
- } else {
3773
- this.#savePersistInner().catch((error) => {
3774
- this.#actor.rLog.error({
3775
- msg: "error saving persist data immediately",
3776
- error: stringifyError(error)
3777
- });
3778
- });
3779
- }
3780
- }
3781
- /**
3782
- * Clears any pending save timeout.
3783
- */
3784
- clearPendingSaveTimeout() {
3785
- if (this.#pendingSaveTimeout) {
3786
- clearTimeout(this.#pendingSaveTimeout);
3787
- this.#pendingSaveTimeout = void 0;
3788
- this.#pendingSaveScheduledTimestamp = void 0;
3789
- }
3790
- }
3791
- /**
3792
- * Waits for any pending write operations to complete.
3793
- */
3794
- async waitForPendingWrites() {
3795
- if (this.#persistWriteQueue.runningDrainLoop) {
3796
- await this.#persistWriteQueue.runningDrainLoop;
3797
- }
3798
- }
3799
- // MARK: - Private Helpers
3800
- #validateStateEnabled() {
3801
- if (!this.stateEnabled) {
3802
- throw new StateNotEnabled();
3803
- }
3804
- }
3805
- #handleStateChange(path, value) {
3806
- const actorStatePath = isStatePath(path);
3807
- const connStatePath = isConnStatePath(path);
3808
- if (actorStatePath || connStatePath) {
3809
- let invalidPath = "";
3810
- if (!isCborSerializable(
3811
- value,
3812
- (invalidPathPart) => {
3813
- invalidPath = invalidPathPart;
3814
- },
3815
- ""
3816
- )) {
3817
- throw new InvalidStateType({
3818
- path: path + (invalidPath ? `.${invalidPath}` : "")
3819
- });
3820
- }
3821
- }
3822
- this.#actor.rLog.debug({
3823
- msg: "onChange triggered, setting persistChanged=true",
3824
- path
3825
- });
3826
- this.#persistChanged = true;
3827
- if (actorStatePath) {
3828
- this.#actor.inspector.emitter.emit(
3829
- "stateUpdated",
3830
- this.#persist.state
3831
- );
3832
- }
3833
- if (actorStatePath && this.#config.onStateChange && this.#actor.isReady() && !this.#isInOnStateChange) {
3834
- try {
3835
- this.#isInOnStateChange = true;
3836
- this.#config.onStateChange(
3837
- this.#actor.actorContext,
3838
- this.#persistRaw.state
3839
- );
3840
- } catch (error) {
3841
- this.#actor.rLog.error({
3842
- msg: "error in `_onStateChange`",
3843
- error: stringifyError(error)
3844
- });
3845
- } finally {
3846
- this.#isInOnStateChange = false;
3847
- }
3848
- }
3849
- }
3850
- async #savePersistInner() {
3851
- var _a, _b;
3852
- this.#actor.rLog.info({
3853
- msg: "savePersistInner called",
3854
- persistChanged: this.#persistChanged,
3855
- connsWithPersistChangedSize: this.#actor.connectionManager.connsWithPersistChanged.size,
3856
- connsWithPersistChangedIds: Array.from(
3857
- this.#actor.connectionManager.connsWithPersistChanged
3858
- )
3859
- });
3860
- try {
3861
- this.#lastSaveTime = Date.now();
3862
- const hasChanges = this.#persistChanged || this.#actor.connectionManager.connsWithPersistChanged.size > 0;
3863
- if (hasChanges) {
3864
- await this.#persistWriteQueue.enqueue(async () => {
3865
- this.#actor.rLog.debug({
3866
- msg: "saving persist",
3867
- actorChanged: this.#persistChanged,
3868
- connectionsChanged: this.#actor.connectionManager.connsWithPersistChanged.size
3869
- });
3870
- const entries = [];
3871
- if (this.#persistChanged) {
3872
- this.#persistChanged = false;
3873
- const bareData = convertActorToBarePersisted(
3874
- this.#persistRaw
3875
- );
3876
- entries.push([
3877
- KEYS.PERSIST_DATA,
3878
- ACTOR_VERSIONED.serializeWithEmbeddedVersion(
3879
- bareData,
3880
- CURRENT_VERSION2
3881
- )
3882
- ]);
3883
- }
3884
- const connections = [];
3885
- for (const connId of this.#actor.connectionManager.connsWithPersistChanged) {
3886
- const conn = this.#actor.conns.get(connId);
3887
- if (!conn) {
3888
- this.#actor.rLog.warn({
3889
- msg: "connection not found in conns map",
3890
- connId
3891
- });
3892
- continue;
3893
- }
3894
- const connStateManager = conn[CONN_STATE_MANAGER_SYMBOL];
3895
- const hibernatableDataRaw = connStateManager.hibernatableDataRaw;
3896
- if (!hibernatableDataRaw) {
3897
- this.#actor.log.warn({
3898
- msg: "missing raw hibernatable data for conn in getChangedConnectionsData",
3899
- connId: conn.id
3900
- });
3901
- continue;
3902
- }
3903
- this.#actor.rLog.info({
3904
- msg: "persisting connection",
3905
- connId,
3906
- gatewayId: idToStr(hibernatableDataRaw.requestId),
3907
- requestId: idToStr(hibernatableDataRaw.requestId),
3908
- serverMessageIndex: hibernatableDataRaw.serverMessageIndex,
3909
- clientMessageIndex: hibernatableDataRaw.clientMessageIndex,
3910
- hasState: hibernatableDataRaw.state !== void 0
3911
- });
3912
- const bareData = convertConnToBarePersistedConn(
3913
- hibernatableDataRaw
3914
- );
3915
- const connData = CONN_VERSIONED.serializeWithEmbeddedVersion(
3916
- bareData,
3917
- CURRENT_VERSION2
3918
- );
3919
- entries.push([makeConnKey(connId), connData]);
3920
- connections.push(conn);
3921
- }
3922
- this.#actor.rLog.info({
3923
- msg: "prepared entries for kvBatchPut",
3924
- totalEntries: entries.length,
3925
- connectionEntries: connections.length,
3926
- connectionIds: connections.map((c) => c.id)
3927
- });
3928
- if (this.#actorDriver.onBeforePersistConn) {
3929
- for (const conn of connections) {
3930
- this.#actorDriver.onBeforePersistConn(conn);
3931
- }
3932
- }
3933
- this.#actor.connectionManager.clearConnWithPersistChanged();
3934
- this.#actor.rLog.info({
3935
- msg: "calling kvBatchPut",
3936
- actorId: this.#actor.id,
3937
- entriesCount: entries.length
3938
- });
3939
- await this.#actorDriver.kvBatchPut(this.#actor.id, entries);
3940
- this.#actor.rLog.info({
3941
- msg: "kvBatchPut completed successfully"
3942
- });
3943
- if (this.#actorDriver.onAfterPersistConn) {
3944
- for (const conn of connections) {
3945
- this.#actorDriver.onAfterPersistConn(conn);
3946
- }
3947
- }
3948
- this.#actor.rLog.debug({ msg: "persist saved" });
3949
- });
3950
- } else {
3951
- this.#actor.rLog.info({
3952
- msg: "savePersistInner skipped - no changes"
3953
- });
3954
- }
3955
- (_a = this.#onPersistSavedPromise) == null ? void 0 : _a.resolve();
3956
- } catch (error) {
3957
- this.#actor.rLog.error({
3958
- msg: "error saving persist",
3959
- error: stringifyError(error)
3960
- });
3961
- (_b = this.#onPersistSavedPromise) == null ? void 0 : _b.reject(error);
3962
- throw error;
3963
- }
3964
- }
3965
- };
3966
-
3967
- // src/actor/instance/mod.ts
3968
- var CanSleep = /* @__PURE__ */ ((CanSleep2) => {
3969
- CanSleep2[CanSleep2["Yes"] = 0] = "Yes";
3970
- CanSleep2[CanSleep2["NotReady"] = 1] = "NotReady";
3971
- CanSleep2[CanSleep2["NotStarted"] = 2] = "NotStarted";
3972
- CanSleep2[CanSleep2["ActiveConns"] = 3] = "ActiveConns";
3973
- CanSleep2[CanSleep2["ActiveHonoHttpRequests"] = 4] = "ActiveHonoHttpRequests";
3974
- return CanSleep2;
3975
- })(CanSleep || {});
3976
- var ActorInstance = class {
3977
- // MARK: - Core Properties
3978
- actorContext;
3979
- #config;
3980
- driver;
3981
- #inlineClient;
3982
- #actorId;
3983
- #name;
3984
- #key;
3985
- #region;
3986
- // MARK: - Managers
3987
- connectionManager;
3988
- stateManager;
3989
- eventManager;
3990
- #scheduleManager;
3991
- // MARK: - Logging
3992
- #log;
3993
- #rLog;
3994
- // MARK: - Lifecycle State
3995
- /**
3996
- * If the core actor initiation has set up.
3997
- *
3998
- * Almost all actions on this actor will throw an error if false.
3999
- **/
4000
- #ready = false;
4001
- /**
4002
- * If the actor has fully started.
4003
- *
4004
- * The only purpose of this is to prevent sleeping until started.
4005
- */
4006
- #started = false;
4007
- #sleepCalled = false;
4008
- #destroyCalled = false;
4009
- #stopCalled = false;
4010
- #sleepTimeout;
4011
- #abortController = new AbortController();
4012
- // MARK: - Variables & Database
4013
- #vars;
4014
- #db;
4015
- // MARK: - Background Tasks
4016
- #backgroundPromises = [];
4017
- // MARK: - HTTP/WebSocket Tracking
4018
- #activeHonoHttpRequests = 0;
4019
- // MARK: - Deprecated (kept for compatibility)
4020
- #schedule;
4021
- // MARK: - Inspector
4022
- #inspectorToken;
4023
- #inspector = new ActorInspector(this);
4024
- // MARK: - Constructor
4025
- constructor(config) {
4026
- this.#config = config;
4027
- this.actorContext = new ActorContext(this);
4028
- }
4029
- // MARK: - Public Getters
4030
- get log() {
4031
- invariant7(this.#log, "log not configured");
4032
- return this.#log;
4033
- }
4034
- get rLog() {
4035
- invariant7(this.#rLog, "log not configured");
4036
- return this.#rLog;
4037
- }
4038
- get isStopping() {
4039
- return this.#stopCalled;
4040
- }
4041
- get id() {
4042
- return this.#actorId;
4043
- }
4044
- get name() {
4045
- return this.#name;
4046
- }
4047
- get key() {
4048
- return this.#key;
4049
- }
4050
- get region() {
4051
- return this.#region;
4052
- }
4053
- get inlineClient() {
4054
- return this.#inlineClient;
4055
- }
4056
- get inspector() {
4057
- return this.#inspector;
4058
- }
4059
- get inspectorToken() {
4060
- return this.#inspectorToken;
4061
- }
4062
- get conns() {
4063
- return this.connectionManager.connections;
4064
- }
4065
- get schedule() {
4066
- return this.#schedule;
4067
- }
4068
- get abortSignal() {
4069
- return this.#abortController.signal;
4070
- }
4071
- get actions() {
4072
- return Object.keys(this.#config.actions ?? {});
4073
- }
4074
- get config() {
4075
- return this.#config;
4076
- }
4077
- // MARK: - State Access
4078
- get persist() {
4079
- return this.stateManager.persist;
4080
- }
4081
- get state() {
4082
- return this.stateManager.state;
4083
- }
4084
- set state(value) {
4085
- this.stateManager.state = value;
4086
- }
4087
- get stateEnabled() {
4088
- return this.stateManager.stateEnabled;
4089
- }
4090
- get connStateEnabled() {
4091
- return "createConnState" in this.#config || "connState" in this.#config;
4092
- }
4093
- // MARK: - Variables & Database
4094
- get vars() {
4095
- this.#validateVarsEnabled();
4096
- invariant7(this.#vars !== void 0, "vars not enabled");
4097
- return this.#vars;
4098
- }
4099
- get db() {
4100
- if (!this.#db) {
4101
- throw new DatabaseNotEnabled();
4102
- }
4103
- return this.#db;
4104
- }
4105
- // MARK: - Initialization
4106
- async start(actorDriver, inlineClient, actorId, name, key, region) {
4107
- var _a, _b;
4108
- this.driver = actorDriver;
4109
- this.#inlineClient = inlineClient;
4110
- this.#actorId = actorId;
4111
- this.#name = name;
4112
- this.#key = key;
4113
- this.#region = region;
4114
- this.#initializeLogging();
4115
- this.connectionManager = new ConnectionManager(this);
4116
- this.stateManager = new StateManager(this, actorDriver, this.#config);
4117
- this.eventManager = new EventManager(this);
4118
- this.#scheduleManager = new ScheduleManager(
4119
- this,
4120
- actorDriver,
4121
- this.#config
4122
- );
4123
- this.#schedule = new Schedule(this);
4124
- await this.#loadState();
4125
- await this.#initializeInspectorToken();
4126
- if (this.#varsEnabled) {
4127
- await this.#initializeVars();
4128
- }
4129
- await this.#callOnStart();
4130
- await this.#setupDatabase();
4131
- await this.#scheduleManager.initializeAlarms();
4132
- this.#ready = true;
4133
- await ((_b = (_a = this.driver).onBeforeActorStart) == null ? void 0 : _b.call(_a, this));
4134
- this.#started = true;
4135
- this.#rLog.info({ msg: "actor started" });
4136
- this.resetSleepTimer();
4137
- await this.onAlarm();
4138
- }
4139
- // MARK: - Ready Check
4140
- isReady() {
4141
- return this.#ready;
4142
- }
4143
- assertReady(allowStoppingState = false) {
4144
- if (!this.#ready) throw new InternalError("Actor not ready");
4145
- if (!allowStoppingState && this.#stopCalled)
4146
- throw new InternalError("Actor is stopping");
4147
- }
4148
- // MARK: - Stop
4149
- async onStop(mode) {
4150
- if (this.#stopCalled) {
4151
- this.#rLog.warn({ msg: "already stopping actor" });
4152
- return;
4153
- }
4154
- this.#stopCalled = true;
4155
- this.#rLog.info({
4156
- msg: "setting stopCalled=true",
4157
- mode
4158
- });
4159
- if (this.#sleepTimeout) {
4160
- clearTimeout(this.#sleepTimeout);
4161
- this.#sleepTimeout = void 0;
4162
- }
4163
- try {
4164
- this.#abortController.abort();
4165
- } catch {
4166
- }
4167
- if (mode === "sleep") {
4168
- await this.#callOnSleep();
4169
- } else if (mode === "destroy") {
4170
- await this.#callOnDestroy();
4171
- } else {
4172
- assertUnreachable2(mode);
4173
- }
4174
- await this.#disconnectConnections();
4175
- await this.#waitBackgroundPromises(
4176
- this.#config.options.waitUntilTimeout
4177
- );
4178
- this.#rLog.info({ msg: "clearing pending save timeouts" });
4179
- this.stateManager.clearPendingSaveTimeout();
4180
- this.#rLog.info({ msg: "saving state immediately" });
4181
- await this.stateManager.saveState({
4182
- immediate: true,
4183
- allowStoppingState: true
4184
- });
4185
- await this.stateManager.waitForPendingWrites();
4186
- await this.#scheduleManager.waitForPendingAlarmWrites();
4187
- }
4188
- // MARK: - Sleep
4189
- startSleep() {
4190
- var _a;
4191
- if (this.#stopCalled || this.#destroyCalled) {
4192
- this.#rLog.debug({
4193
- msg: "cannot call startSleep if actor already stopping"
4194
- });
4195
- return;
4196
- }
4197
- if (this.#sleepCalled) {
4198
- this.#rLog.warn({
4199
- msg: "cannot call startSleep twice, actor already sleeping"
4200
- });
4201
- return;
4202
- }
4203
- this.#sleepCalled = true;
4204
- const sleep = (_a = this.driver.startSleep) == null ? void 0 : _a.bind(this.driver, this.#actorId);
4205
- invariant7(this.#sleepingSupported, "sleeping not supported");
4206
- invariant7(sleep, "no sleep on driver");
4207
- this.#rLog.info({ msg: "actor sleeping" });
4208
- setImmediate(() => {
4209
- sleep();
4210
- });
4211
- }
4212
- // MARK: - Destroy
4213
- startDestroy() {
4214
- if (this.#stopCalled || this.#sleepCalled) {
4215
- this.#rLog.debug({
4216
- msg: "cannot call startDestroy if actor already stopping or sleeping"
4217
- });
4218
- return;
4219
- }
4220
- if (this.#destroyCalled) {
4221
- this.#rLog.warn({
4222
- msg: "cannot call startDestroy twice, actor already destroying"
4223
- });
4224
- return;
4225
- }
4226
- this.#destroyCalled = true;
4227
- const destroy = this.driver.startDestroy.bind(
4228
- this.driver,
4229
- this.#actorId
4230
- );
4231
- this.#rLog.info({ msg: "actor destroying" });
4232
- setImmediate(() => {
4233
- destroy();
4234
- });
4235
- }
4236
- // MARK: - HTTP Request Tracking
4237
- beginHonoHttpRequest() {
4238
- this.#activeHonoHttpRequests++;
4239
- this.resetSleepTimer();
4240
- }
4241
- endHonoHttpRequest() {
4242
- this.#activeHonoHttpRequests--;
4243
- if (this.#activeHonoHttpRequests < 0) {
4244
- this.#activeHonoHttpRequests = 0;
4245
- this.#rLog.warn({
4246
- msg: "active hono requests went below 0, this is a RivetKit bug",
4247
- ...EXTRA_ERROR_LOG
4248
- });
4249
- }
4250
- this.resetSleepTimer();
4251
- }
4252
- // MARK: - Message Processing
4253
- async processMessage(message, conn) {
4254
- await processMessage(message, this, conn, {
4255
- onExecuteAction: async (ctx, name, args) => {
4256
- this.inspector.emitter.emit("eventFired", {
4257
- type: "action",
4258
- name,
4259
- args,
4260
- connId: conn.id
4261
- });
4262
- return await this.executeAction(ctx, name, args);
4263
- },
4264
- onSubscribe: async (eventName, conn2) => {
4265
- this.inspector.emitter.emit("eventFired", {
4266
- type: "subscribe",
4267
- eventName,
4268
- connId: conn2.id
4269
- });
4270
- this.eventManager.addSubscription(eventName, conn2, false);
4271
- },
4272
- onUnsubscribe: async (eventName, conn2) => {
4273
- this.inspector.emitter.emit("eventFired", {
4274
- type: "unsubscribe",
4275
- eventName,
4276
- connId: conn2.id
4277
- });
4278
- this.eventManager.removeSubscription(eventName, conn2, false);
4279
- }
4280
- });
4281
- }
4282
- // MARK: - Action Execution
4283
- async executeAction(ctx, actionName, args) {
4284
- this.assertReady();
4285
- const actions = this.#config.actions ?? {};
4286
- if (!(actionName in actions)) {
4287
- this.#rLog.warn({ msg: "action does not exist", actionName });
4288
- throw new ActionNotFound(actionName);
4289
- }
4290
- const actionFunction = actions[actionName];
4291
- if (typeof actionFunction !== "function") {
4292
- this.#rLog.warn({
4293
- msg: "action is not a function",
4294
- actionName,
4295
- type: typeof actionFunction
4296
- });
4297
- throw new ActionNotFound(actionName);
4298
- }
4299
- try {
4300
- this.#rLog.debug({
4301
- msg: "executing action",
4302
- actionName,
4303
- args
4304
- });
4305
- const outputOrPromise = actionFunction.call(
4306
- void 0,
4307
- ctx,
4308
- ...args
4309
- );
4310
- let output;
4311
- if (outputOrPromise instanceof Promise) {
4312
- output = await deadline(
4313
- outputOrPromise,
4314
- this.#config.options.actionTimeout
4315
- );
4316
- } else {
4317
- output = outputOrPromise;
4318
- }
4319
- if (this.#config.onBeforeActionResponse) {
4320
- try {
4321
- const processedOutput = this.#config.onBeforeActionResponse(
4322
- this.actorContext,
4323
- actionName,
4324
- args,
4325
- output
4326
- );
4327
- if (processedOutput instanceof Promise) {
4328
- output = await processedOutput;
4329
- } else {
4330
- output = processedOutput;
4331
- }
4332
- } catch (error) {
4333
- this.#rLog.error({
4334
- msg: "error in `onBeforeActionResponse`",
4335
- error: stringifyError(error)
4336
- });
4337
- }
4338
- }
4339
- return output;
4340
- } catch (error) {
4341
- if (error instanceof DeadlineError) {
4342
- throw new ActionTimedOut();
4343
- }
4344
- this.#rLog.error({
4345
- msg: "action error",
4346
- actionName,
4347
- error: stringifyError(error)
4348
- });
4349
- throw error;
4350
- } finally {
4351
- this.stateManager.savePersistThrottled();
4352
- }
4353
- }
4354
- // MARK: - HTTP/WebSocket Handlers
4355
- async handleRawRequest(conn, request) {
4356
- this.assertReady();
4357
- if (!this.#config.onRequest) {
4358
- throw new RequestHandlerNotDefined();
4359
- }
4360
- try {
4361
- const ctx = new RequestContext(this, conn, request);
4362
- const response = await this.#config.onRequest(ctx, request);
4363
- if (!response) {
4364
- throw new InvalidRequestHandlerResponse();
4365
- }
4366
- return response;
4367
- } catch (error) {
4368
- this.#rLog.error({
4369
- msg: "onRequest error",
4370
- error: stringifyError(error)
4371
- });
4372
- throw error;
4373
- } finally {
4374
- this.stateManager.savePersistThrottled();
4375
- }
4376
- }
4377
- handleRawWebSocket(conn, websocket, request) {
4378
- this.assertReady();
4379
- if (!this.#config.onWebSocket) {
4380
- throw new InternalError("onWebSocket handler not defined");
4381
- }
4382
- try {
4383
- this.resetSleepTimer();
4384
- const ctx = new WebSocketContext(this, conn, request);
4385
- const voidOrPromise = this.#config.onWebSocket(ctx, websocket);
4386
- if (voidOrPromise instanceof Promise) {
4387
- voidOrPromise.then(() => {
4388
- this.stateManager.savePersistThrottled();
4389
- });
4390
- } else {
4391
- this.stateManager.savePersistThrottled();
4392
- }
4393
- } catch (error) {
4394
- this.#rLog.error({
4395
- msg: "onWebSocket error",
4396
- error: stringifyError(error)
4397
- });
4398
- throw error;
4399
- }
4400
- }
4401
- // MARK: - Scheduling
4402
- async scheduleEvent(timestamp, action, args) {
4403
- await this.#scheduleManager.scheduleEvent(timestamp, action, args);
4404
- }
4405
- async onAlarm() {
4406
- this.resetSleepTimer();
4407
- await this.#scheduleManager.onAlarm();
4408
- }
4409
- // MARK: - Background Tasks
4410
- waitUntil(promise) {
4411
- this.assertReady();
4412
- const nonfailablePromise = promise.then(() => {
4413
- this.#rLog.debug({ msg: "wait until promise complete" });
4414
- }).catch((error) => {
4415
- this.#rLog.error({
4416
- msg: "wait until promise failed",
4417
- error: stringifyError(error)
4418
- });
4419
- });
4420
- this.#backgroundPromises.push(nonfailablePromise);
4421
- }
4422
- // MARK: - Private Helper Methods
4423
- #initializeLogging() {
4424
- var _a, _b;
4425
- const logParams = {
4426
- actor: this.#name,
4427
- key: serializeActorKey(this.#key),
4428
- actorId: this.#actorId
4429
- };
4430
- const extraLogParams = (_b = (_a = this.driver).getExtraActorLogParams) == null ? void 0 : _b.call(_a);
4431
- if (extraLogParams) Object.assign(logParams, extraLogParams);
4432
- this.#log = getBaseLogger().child(
4433
- Object.assign(
4434
- getIncludeTarget() ? { target: "actor" } : {},
4435
- logParams
4436
- )
4437
- );
4438
- this.#rLog = getBaseLogger().child(
4439
- Object.assign(
4440
- getIncludeTarget() ? { target: "actor-runtime" } : {},
4441
- logParams
4442
- )
4443
- );
4444
- }
4445
- async #loadState() {
4446
- const [persistDataBuffer] = await this.driver.kvBatchGet(
4447
- this.#actorId,
4448
- [KEYS.PERSIST_DATA]
4449
- );
4450
- invariant7(
4451
- persistDataBuffer !== null,
4452
- "persist data has not been set, it should be set when initialized"
4453
- );
4454
- const bareData = ACTOR_VERSIONED.deserializeWithEmbeddedVersion(persistDataBuffer);
4455
- const persistData = convertActorFromBarePersisted(bareData);
4456
- if (persistData.hasInitialized) {
4457
- await this.#restoreExistingActor(persistData);
4458
- } else {
4459
- await this.#createNewActor(persistData);
4460
- }
4461
- this.#scheduleManager.setPersist(this.stateManager.persist);
4462
- }
4463
- async #createNewActor(persistData) {
4464
- this.#rLog.info({ msg: "actor creating" });
4465
- await this.stateManager.initializeState(persistData);
4466
- if (this.#config.onCreate) {
4467
- await this.#config.onCreate(
4468
- this.actorContext,
4469
- persistData.input
4470
- );
4471
- }
4472
- }
4473
- async #restoreExistingActor(persistData) {
4474
- const connEntries = await this.driver.kvListPrefix(
4475
- this.#actorId,
4476
- KEYS.CONN_PREFIX
4477
- );
4478
- const connections = [];
4479
- for (const [_key, value] of connEntries) {
4480
- try {
4481
- const bareData = CONN_VERSIONED.deserializeWithEmbeddedVersion(
4482
- new Uint8Array(value)
4483
- );
4484
- const conn = convertConnFromBarePersistedConn(bareData);
4485
- connections.push(conn);
4486
- } catch (error) {
4487
- this.#rLog.error({
4488
- msg: "failed to decode connection",
4489
- error: stringifyError(error)
4490
- });
4491
- }
4492
- }
4493
- this.#rLog.info({
4494
- msg: "actor restoring",
4495
- connections: connections.length
4496
- });
4497
- this.stateManager.initPersistProxy(persistData);
4498
- this.connectionManager.restoreConnections(connections);
4499
- }
4500
- async #initializeInspectorToken() {
4501
- const [tokenBuffer] = await this.driver.kvBatchGet(this.#actorId, [
4502
- KEYS.INSPECTOR_TOKEN
4503
- ]);
4504
- if (tokenBuffer !== null) {
4505
- const decoder = new TextDecoder();
4506
- this.#inspectorToken = decoder.decode(tokenBuffer);
4507
- this.#rLog.debug({ msg: "loaded existing inspector token" });
4508
- } else {
4509
- this.#inspectorToken = generateSecureToken();
4510
- const tokenBytes = new TextEncoder().encode(this.#inspectorToken);
4511
- await this.driver.kvBatchPut(this.#actorId, [
4512
- [KEYS.INSPECTOR_TOKEN, tokenBytes]
4513
- ]);
4514
- this.#rLog.debug({ msg: "generated new inspector token" });
4515
- }
4516
- }
4517
- async #initializeVars() {
4518
- let vars;
4519
- if ("createVars" in this.#config) {
4520
- const dataOrPromise = this.#config.createVars(
4521
- this.actorContext,
4522
- this.driver.getContext(this.#actorId)
4523
- );
4524
- if (dataOrPromise instanceof Promise) {
4525
- vars = await deadline(
4526
- dataOrPromise,
4527
- this.#config.options.createVarsTimeout
4528
- );
4529
- } else {
4530
- vars = dataOrPromise;
4531
- }
4532
- } else if ("vars" in this.#config) {
4533
- vars = structuredClone(this.#config.vars);
4534
- } else {
4535
- throw new Error(
4536
- "Could not create variables from 'createVars' or 'vars'"
4537
- );
4538
- }
4539
- this.#vars = vars;
4540
- }
4541
- async #callOnStart() {
4542
- this.#rLog.info({ msg: "actor starting" });
4543
- if (this.#config.onWake) {
4544
- const result = this.#config.onWake(this.actorContext);
4545
- if (result instanceof Promise) {
4546
- await result;
4547
- }
4548
- }
4549
- }
4550
- async #callOnSleep() {
4551
- if (this.#config.onSleep) {
4552
- try {
4553
- this.#rLog.debug({ msg: "calling onSleep" });
4554
- const result = this.#config.onSleep(this.actorContext);
4555
- if (result instanceof Promise) {
4556
- await deadline(result, this.#config.options.onSleepTimeout);
4557
- }
4558
- this.#rLog.debug({ msg: "onSleep completed" });
4559
- } catch (error) {
4560
- if (error instanceof DeadlineError) {
4561
- this.#rLog.error({ msg: "onSleep timed out" });
4562
- } else {
4563
- this.#rLog.error({
4564
- msg: "error in onSleep",
4565
- error: stringifyError(error)
4566
- });
4567
- }
4568
- }
4569
- }
4570
- }
4571
- async #callOnDestroy() {
4572
- if (this.#config.onDestroy) {
4573
- try {
4574
- this.#rLog.debug({ msg: "calling onDestroy" });
4575
- const result = this.#config.onDestroy(this.actorContext);
4576
- if (result instanceof Promise) {
4577
- await deadline(
4578
- result,
4579
- this.#config.options.onDestroyTimeout
4580
- );
4581
- }
4582
- this.#rLog.debug({ msg: "onDestroy completed" });
4583
- } catch (error) {
4584
- if (error instanceof DeadlineError) {
4585
- this.#rLog.error({ msg: "onDestroy timed out" });
4586
- } else {
4587
- this.#rLog.error({
4588
- msg: "error in onDestroy",
4589
- error: stringifyError(error)
4590
- });
4591
- }
4592
- }
4593
- }
4594
- }
4595
- async #setupDatabase() {
4596
- var _a, _b;
4597
- if ("db" in this.#config && this.#config.db) {
4598
- const client = await this.#config.db.createClient({
4599
- getDatabase: () => this.driver.getDatabase(this.#actorId)
4600
- });
4601
- this.#rLog.info({ msg: "database migration starting" });
4602
- await ((_b = (_a = this.#config.db).onMigrate) == null ? void 0 : _b.call(_a, client));
4603
- this.#rLog.info({ msg: "database migration complete" });
4604
- this.#db = client;
4605
- }
4606
- }
4607
- async #disconnectConnections() {
4608
- const promises = [];
4609
- this.#rLog.debug({
4610
- msg: "disconnecting connections on actor stop",
4611
- totalConns: this.connectionManager.connections.size
4612
- });
4613
- for (const connection of this.connectionManager.connections.values()) {
4614
- this.#rLog.debug({
4615
- msg: "checking connection for disconnect",
4616
- connId: connection.id,
4617
- isHibernatable: connection.isHibernatable
4618
- });
4619
- if (!connection.isHibernatable) {
4620
- this.#rLog.debug({
4621
- msg: "disconnecting non-hibernatable connection on actor stop",
4622
- connId: connection.id
4623
- });
4624
- promises.push(connection.disconnect());
4625
- } else {
4626
- this.#rLog.debug({
4627
- msg: "preserving hibernatable connection on actor stop",
4628
- connId: connection.id
4629
- });
4630
- }
4631
- }
4632
- const res = await Promise.race([
4633
- Promise.all(promises).then(() => false),
4634
- new Promise(
4635
- (res2) => globalThis.setTimeout(() => res2(true), 1500)
4636
- )
4637
- ]);
4638
- if (res) {
4639
- this.#rLog.warn({
4640
- msg: "timed out waiting for connections to close, shutting down anyway"
4641
- });
4642
- }
4643
- }
4644
- async #waitBackgroundPromises(timeoutMs) {
4645
- const pending = this.#backgroundPromises;
4646
- if (pending.length === 0) {
4647
- this.#rLog.debug({ msg: "no background promises" });
4648
- return;
4649
- }
4650
- const timedOut = await Promise.race([
4651
- Promise.allSettled(pending).then(() => false),
4652
- new Promise(
4653
- (resolve) => setTimeout(() => resolve(true), timeoutMs)
4654
- )
4655
- ]);
4656
- if (timedOut) {
4657
- this.#rLog.error({
4658
- msg: "timed out waiting for background tasks",
4659
- count: pending.length,
4660
- timeoutMs
4661
- });
4662
- } else {
4663
- this.#rLog.debug({ msg: "background promises finished" });
4664
- }
4665
- }
4666
- resetSleepTimer() {
4667
- if (this.#config.options.noSleep || !this.#sleepingSupported) return;
4668
- if (this.#stopCalled) return;
4669
- const canSleep = this.#canSleep();
4670
- this.#rLog.debug({
4671
- msg: "resetting sleep timer",
4672
- canSleep: CanSleep[canSleep],
4673
- existingTimeout: !!this.#sleepTimeout,
4674
- timeout: this.#config.options.sleepTimeout
4675
- });
4676
- if (this.#sleepTimeout) {
4677
- clearTimeout(this.#sleepTimeout);
4678
- this.#sleepTimeout = void 0;
4679
- }
4680
- if (this.#sleepCalled) return;
4681
- if (canSleep === 0 /* Yes */) {
4682
- this.#sleepTimeout = setTimeout(() => {
4683
- this.startSleep();
4684
- }, this.#config.options.sleepTimeout);
4685
- }
4686
- }
4687
- #canSleep() {
4688
- if (!this.#ready) return 1 /* NotReady */;
4689
- if (!this.#started) return 1 /* NotReady */;
4690
- if (this.#activeHonoHttpRequests > 0)
4691
- return 4 /* ActiveHonoHttpRequests */;
4692
- for (const _conn of this.connectionManager.connections.values()) {
4693
- return 3 /* ActiveConns */;
4694
- }
4695
- return 0 /* Yes */;
4696
- }
4697
- get #sleepingSupported() {
4698
- return this.driver.startSleep !== void 0;
4699
- }
4700
- get #varsEnabled() {
4701
- return "createVars" in this.#config || "vars" in this.#config;
4702
- }
4703
- #validateVarsEnabled() {
4704
- if (!this.#varsEnabled) {
4705
- throw new VarsNotEnabled();
4706
- }
4707
- }
4708
- };
4709
-
4710
- // src/actor/definition.ts
4711
- var ActorDefinition = class {
4712
- #config;
4713
- constructor(config) {
4714
- this.#config = config;
4715
- }
4716
- get config() {
4717
- return this.#config;
4718
- }
4719
- instantiate() {
4720
- return new ActorInstance(this.#config);
4721
- }
4722
- };
4723
- function lookupInRegistry(config, name) {
4724
- const definition = config.use[name];
4725
- if (!definition) throw new Error(`no actor in registry for name ${name}`);
4726
- return definition;
4727
- }
4728
-
4729
- // src/client/mod.ts
4730
- function createClient(endpointOrConfig) {
4731
- const configInput = endpointOrConfig === void 0 ? {} : typeof endpointOrConfig === "string" ? { endpoint: endpointOrConfig } : endpointOrConfig;
4732
- const config = ClientConfigSchema.parse(configInput);
4733
- const driver = new RemoteManagerDriver(config);
4734
- if (config.devtools) {
4735
- injectDevtools(config);
4736
- }
4737
- return createClientWithDriver(driver, config);
2634
+ return createClientWithDriver(driver, config);
4738
2635
  }
4739
2636
 
4740
2637
  export {
4741
- ActorDefinition,
4742
- lookupInRegistry,
4743
2638
  ActorClientError,
4744
- InternalError2 as InternalError,
2639
+ InternalError,
4745
2640
  ManagerError,
4746
2641
  MalformedResponseMessage,
4747
2642
  ActorError,
@@ -4759,4 +2654,4 @@ export {
4759
2654
  RemoteManagerDriver,
4760
2655
  createClient
4761
2656
  };
4762
- //# sourceMappingURL=chunk-Q6W7RJJP.js.map
2657
+ //# sourceMappingURL=chunk-DIGBC2VI.js.map