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
@@ -0,0 +1,92 @@
1
+ import type { DatabaseProviderContext } from "./config";
2
+ import type { Database } from "@rivetkit/sqlite-vfs";
3
+ import type { KvVfsOptions } from "./sqlite-vfs";
4
+
5
+ type ActorKvOperations = DatabaseProviderContext["kv"];
6
+ type SqliteBindings = NonNullable<Parameters<Database["run"]>[1]>;
7
+
8
+ function isSqliteBindingValue(value: unknown): boolean {
9
+ if (
10
+ value === null ||
11
+ typeof value === "number" ||
12
+ typeof value === "string" ||
13
+ typeof value === "bigint" ||
14
+ value instanceof Uint8Array
15
+ ) {
16
+ return true;
17
+ }
18
+
19
+ if (Array.isArray(value)) {
20
+ return value.every((item) => typeof item === "number");
21
+ }
22
+
23
+ return false;
24
+ }
25
+
26
+ export function toSqliteBindings(args: unknown[]): SqliteBindings {
27
+ for (const value of args) {
28
+ if (!isSqliteBindingValue(value)) {
29
+ throw new Error(
30
+ `unsupported sqlite binding type: ${typeof value}`,
31
+ );
32
+ }
33
+ }
34
+
35
+ return args as SqliteBindings;
36
+ }
37
+
38
+ /**
39
+ * Create a KV store wrapper that uses the actor driver's KV operations.
40
+ */
41
+ export function createActorKvStore(kv: ActorKvOperations): KvVfsOptions {
42
+ return {
43
+ get: async (key: Uint8Array) => {
44
+ const results = await kv.batchGet([key]);
45
+ return results[0] ?? null;
46
+ },
47
+ getBatch: async (keys: Uint8Array[]) => {
48
+ return await kv.batchGet(keys);
49
+ },
50
+ put: async (key: Uint8Array, value: Uint8Array) => {
51
+ await kv.batchPut([[key, value]]);
52
+ },
53
+ putBatch: async (entries: [Uint8Array, Uint8Array][]) => {
54
+ await kv.batchPut(entries);
55
+ },
56
+ deleteBatch: async (keys: Uint8Array[]) => {
57
+ await kv.batchDelete(keys);
58
+ },
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Serialize async operations on a shared non-reentrant resource.
64
+ */
65
+ export class AsyncMutex {
66
+ #locked = false;
67
+ #waiting: (() => void)[] = [];
68
+
69
+ async acquire(): Promise<void> {
70
+ while (this.#locked) {
71
+ await new Promise<void>((resolve) => this.#waiting.push(resolve));
72
+ }
73
+ this.#locked = true;
74
+ }
75
+
76
+ release(): void {
77
+ this.#locked = false;
78
+ const next = this.#waiting.shift();
79
+ if (next) {
80
+ next();
81
+ }
82
+ }
83
+
84
+ async run<T>(fn: () => Promise<T>): Promise<T> {
85
+ await this.acquire();
86
+ try {
87
+ return await fn();
88
+ } finally {
89
+ this.release();
90
+ }
91
+ }
92
+ }
@@ -0,0 +1,12 @@
1
+ import { SqliteVfs, type KvVfsOptions } from "@rivetkit/sqlite-vfs";
2
+
3
+ let sqliteVfsInstance: SqliteVfs | null = null;
4
+
5
+ export async function getSqliteVfs(): Promise<SqliteVfs> {
6
+ if (!sqliteVfsInstance) {
7
+ sqliteVfsInstance = new SqliteVfs();
8
+ }
9
+ return sqliteVfsInstance;
10
+ }
11
+
12
+ export type { KvVfsOptions };
@@ -1,4 +1,5 @@
1
1
  export type { ActorDriver } from "@/actor/driver";
2
+ export { KEYS, makeConnKey } from "@/actor/instance/keys";
2
3
  export type { ActorInstance, AnyActorInstance } from "@/actor/instance/mod";
3
4
  export {
4
5
  ALLOWED_PUBLIC_HEADERS,
@@ -10,12 +10,13 @@ import {
10
10
  RegistryConfig,
11
11
  RegistryConfigSchema,
12
12
  } from "@/registry/config";
13
- import { getPort } from "@/test/mod";
14
13
  import { logger } from "./log";
15
14
  import { runActionFeaturesTests } from "./tests/action-features";
15
+ import { runAccessControlTests } from "./tests/access-control";
16
16
  import { runActorConnTests } from "./tests/actor-conn";
17
17
  import { runActorConnHibernationTests } from "./tests/actor-conn-hibernation";
18
18
  import { runActorConnStateTests } from "./tests/actor-conn-state";
19
+ import { runActorDbTests } from "./tests/actor-db";
19
20
  import { runActorDestroyTests } from "./tests/actor-destroy";
20
21
  import { runActorDriverTests } from "./tests/actor-driver";
21
22
  import { runActorErrorHandlingTests } from "./tests/actor-error-handling";
@@ -25,7 +26,11 @@ import { runActorInspectorTests } from "./tests/actor-inspector";
25
26
  import { runActorKvTests } from "./tests/actor-kv";
26
27
  import { runActorMetadataTests } from "./tests/actor-metadata";
27
28
  import { runActorOnStateChangeTests } from "./tests/actor-onstatechange";
29
+ import { runActorQueueTests } from "./tests/actor-queue";
30
+ import { runActorRunTests } from "./tests/actor-run";
31
+ import { runActorStatelessTests } from "./tests/actor-stateless";
28
32
  import { runActorVarsTests } from "./tests/actor-vars";
33
+ import { runActorWorkflowTests } from "./tests/actor-workflow";
29
34
  import { runManagerDriverTests } from "./tests/manager-driver";
30
35
  import { runRawHttpTests } from "./tests/raw-http";
31
36
  import { runRawHttpRequestPropertiesTests } from "./tests/raw-http-request-properties";
@@ -81,67 +86,81 @@ export interface DriverDeployOutput {
81
86
  export function runDriverTests(
82
87
  driverTestConfigPartial: Omit<DriverTestConfig, "clientType" | "encoding">,
83
88
  ) {
84
- const clientTypes: ClientType[] = driverTestConfigPartial.skip?.inline
85
- ? ["http"]
86
- : ["http", "inline"];
87
- for (const clientType of clientTypes) {
88
- describe(`client type (${clientType})`, () => {
89
- const encodings: Encoding[] = ["bare", "cbor", "json"];
89
+ describe("Driver Tests", () => {
90
+ const clientTypes: ClientType[] = driverTestConfigPartial.skip?.inline
91
+ ? ["http"]
92
+ : ["http", "inline"];
93
+ for (const clientType of clientTypes) {
94
+ describe(`client type (${clientType})`, () => {
95
+ const encodings: Encoding[] = ["bare", "cbor", "json"];
90
96
 
91
- for (const encoding of encodings) {
92
- describe(`encoding (${encoding})`, () => {
93
- const driverTestConfig: DriverTestConfig = {
94
- ...driverTestConfigPartial,
95
- clientType,
96
- encoding,
97
- };
97
+ for (const encoding of encodings) {
98
+ describe(`encoding (${encoding})`, () => {
99
+ const driverTestConfig: DriverTestConfig = {
100
+ ...driverTestConfigPartial,
101
+ clientType,
102
+ encoding,
103
+ };
98
104
 
99
- runActorDriverTests(driverTestConfig);
100
- runManagerDriverTests(driverTestConfig);
105
+ runActorDriverTests(driverTestConfig);
106
+ runManagerDriverTests(driverTestConfig);
101
107
 
102
- runActorConnTests(driverTestConfig);
108
+ runActorConnTests(driverTestConfig);
103
109
 
104
- runActorConnStateTests(driverTestConfig);
110
+ runActorConnStateTests(driverTestConfig);
105
111
 
106
- runActorConnHibernationTests(driverTestConfig);
112
+ runActorConnHibernationTests(driverTestConfig);
107
113
 
108
- runActorDestroyTests(driverTestConfig);
114
+ runActorDbTests(driverTestConfig);
109
115
 
110
- runRequestAccessTests(driverTestConfig);
116
+ runActorDestroyTests(driverTestConfig);
111
117
 
112
- runActorHandleTests(driverTestConfig);
118
+ runRequestAccessTests(driverTestConfig);
113
119
 
114
- runActionFeaturesTests(driverTestConfig);
120
+ runActorHandleTests(driverTestConfig);
115
121
 
116
- runActorVarsTests(driverTestConfig);
122
+ runActionFeaturesTests(driverTestConfig);
117
123
 
118
- runActorMetadataTests(driverTestConfig);
124
+ runAccessControlTests(driverTestConfig);
119
125
 
120
- runActorOnStateChangeTests(driverTestConfig);
126
+ runActorVarsTests(driverTestConfig);
121
127
 
122
- runActorErrorHandlingTests(driverTestConfig);
128
+ runActorMetadataTests(driverTestConfig);
123
129
 
124
- runActorInlineClientTests(driverTestConfig);
130
+ runActorOnStateChangeTests(driverTestConfig);
125
131
 
126
- runActorKvTests(driverTestConfig);
132
+ runActorErrorHandlingTests(driverTestConfig);
127
133
 
128
- runRawHttpTests(driverTestConfig);
134
+ runActorQueueTests(driverTestConfig);
129
135
 
130
- runRawHttpRequestPropertiesTests(driverTestConfig);
136
+ runActorRunTests(driverTestConfig);
131
137
 
132
- runRawWebSocketTests(driverTestConfig);
138
+ runActorInlineClientTests(driverTestConfig);
133
139
 
134
- // TODO: re-expose this once we can have actor queries on the gateway
135
- // runRawHttpDirectRegistryTests(driverTestConfig);
140
+ runActorKvTests(driverTestConfig);
136
141
 
137
- // TODO: re-expose this once we can have actor queries on the gateway
138
- // runRawWebSocketDirectRegistryTests(driverTestConfig);
142
+ runActorWorkflowTests(driverTestConfig);
139
143
 
140
- runActorInspectorTests(driverTestConfig);
141
- });
142
- }
143
- });
144
- }
144
+ runActorStatelessTests(driverTestConfig);
145
+
146
+ runRawHttpTests(driverTestConfig);
147
+
148
+ runRawHttpRequestPropertiesTests(driverTestConfig);
149
+
150
+ runRawWebSocketTests(driverTestConfig);
151
+
152
+ // TODO: re-expose this once we can have actor queries on the gateway
153
+ // runRawHttpDirectRegistryTests(driverTestConfig);
154
+
155
+ // TODO: re-expose this once we can have actor queries on the gateway
156
+ // runRawWebSocketDirectRegistryTests(driverTestConfig);
157
+
158
+ runActorInspectorTests(driverTestConfig);
159
+ });
160
+ }
161
+ });
162
+ }
163
+ });
145
164
  }
146
165
 
147
166
  /**
@@ -231,17 +250,24 @@ export async function createTestRuntime(
231
250
 
232
251
  // TODO: I think this whole function is fucked, we should probably switch to calling registry.serve() directly
233
252
  // Start server
234
- const port = await getPort();
235
253
  const server = honoServe({
236
254
  fetch: router.fetch,
237
255
  hostname: "127.0.0.1",
238
- port,
256
+ port: 0,
239
257
  });
258
+ if (!server.listening) {
259
+ await new Promise<void>((resolve) => {
260
+ server.once("listening", () => resolve());
261
+ });
262
+ }
240
263
  invariant(
241
264
  nodeWebSocket.injectWebSocket !== undefined,
242
265
  "should have injectWebSocket",
243
266
  );
244
267
  nodeWebSocket.injectWebSocket(server);
268
+ const address = server.address();
269
+ invariant(address && typeof address !== "string", "missing server address");
270
+ const port = address.port;
245
271
  const serverEndpoint = `http://127.0.0.1:${port}`;
246
272
 
247
273
  logger().info({ msg: "test serer listening", port });
@@ -0,0 +1,218 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import type { DriverTestConfig } from "../mod";
3
+ import { setupDriverTest } from "../utils";
4
+
5
+ export function runAccessControlTests(driverTestConfig: DriverTestConfig) {
6
+ describe("access control", () => {
7
+ test("actions run without entrypoint auth gating", async (c) => {
8
+ const { client } = await setupDriverTest(c, driverTestConfig);
9
+ const handle = client.accessControlActor.getOrCreate(["actions"]);
10
+
11
+ const allowed = await handle.allowedAction("ok");
12
+ expect(allowed).toBe("allowed:ok");
13
+ });
14
+
15
+ test("passes connection id into canPublish context", async (c) => {
16
+ const { client } = await setupDriverTest(c, driverTestConfig);
17
+ const handle = client.accessControlActor.getOrCreate(["publish-ctx"]);
18
+
19
+ await handle.send("allowedQueue", { value: "one" });
20
+
21
+ const connId = await handle.allowedGetLastCanPublishConnId();
22
+ expect(typeof connId).toBe("string");
23
+ expect(connId.length).toBeGreaterThan(0);
24
+ });
25
+
26
+ test("allows and denies queue sends, and ignores undefined queues", async (c) => {
27
+ const { client } = await setupDriverTest(c, driverTestConfig);
28
+ const handle = client.accessControlActor.getOrCreate(["queue"]);
29
+
30
+ await handle.send("allowedQueue", { value: "one" });
31
+ await expect(
32
+ handle.send("blockedQueue", { value: "two" }),
33
+ ).rejects.toMatchObject({
34
+ code: "forbidden",
35
+ });
36
+ await expect(
37
+ handle.send("missingQueue", { value: "three" }),
38
+ ).resolves.toBeUndefined();
39
+ await expect(
40
+ handle.send(
41
+ "missingQueue",
42
+ { value: "four" },
43
+ { wait: true, timeout: 50 },
44
+ ),
45
+ ).resolves.toMatchObject({ status: "completed" });
46
+
47
+ const allowedMessage = await handle.allowedReceiveQueue();
48
+ expect(allowedMessage).toEqual({ value: "one" });
49
+
50
+ const remainingMessage = await handle.allowedReceiveAnyQueue();
51
+ expect(remainingMessage).toBeNull();
52
+ });
53
+
54
+ test("ignores incoming queue sends when actor has no queues config", async (c) => {
55
+ const { client } = await setupDriverTest(c, driverTestConfig);
56
+ const handle = client.accessControlNoQueuesActor.getOrCreate([
57
+ "no-queues",
58
+ ]);
59
+
60
+ await expect(
61
+ handle.send("anyQueue", { value: "ignored" }),
62
+ ).resolves.toBeUndefined();
63
+ await expect(
64
+ handle.send(
65
+ "anyQueue",
66
+ { value: "ignored-wait" },
67
+ { wait: true, timeout: 50 },
68
+ ),
69
+ ).resolves.toMatchObject({ status: "completed" });
70
+ expect(await handle.readAnyQueue()).toBeNull();
71
+ });
72
+
73
+ test("allows and denies subscriptions with canSubscribe", async (c) => {
74
+ const { client } = await setupDriverTest(c, driverTestConfig);
75
+ const handle = client.accessControlActor.getOrCreate([
76
+ "subscription",
77
+ ]);
78
+ const conn = handle.connect();
79
+
80
+ const allowedEventPromise = new Promise<{ value: string }>(
81
+ (resolve, reject) => {
82
+ const unsubscribeError = conn.onError((error) => {
83
+ reject(error);
84
+ });
85
+ const unsubscribeEvent = conn.on(
86
+ "allowedEvent",
87
+ (payload) => {
88
+ unsubscribeError();
89
+ unsubscribeEvent();
90
+ resolve(payload as { value: string });
91
+ },
92
+ );
93
+ },
94
+ );
95
+
96
+ await conn.allowedAction("subscribe-ready");
97
+ await conn.allowedBroadcastAllowedEvent("hello");
98
+ expect(await allowedEventPromise).toEqual({ value: "hello" });
99
+
100
+ const connId = await conn.allowedGetLastCanSubscribeConnId();
101
+ expect(typeof connId).toBe("string");
102
+ expect(connId.length).toBeGreaterThan(0);
103
+
104
+ await conn.dispose();
105
+
106
+ const blockedConn = handle.connect();
107
+ blockedConn.on("blockedEvent", () => { });
108
+ await expect(
109
+ blockedConn.allowedAction("blocked-subscribe-ready"),
110
+ ).rejects.toMatchObject({
111
+ code: "forbidden",
112
+ });
113
+ await blockedConn.dispose();
114
+ });
115
+
116
+ test("broadcasts undefined events without failing subscriptions", async (c) => {
117
+ const { client } = await setupDriverTest(c, driverTestConfig);
118
+ const handle = client.accessControlActor.getOrCreate([
119
+ "undefined-event",
120
+ ]);
121
+ const conn = handle.connect();
122
+
123
+ const eventPromise = new Promise<{ value: string }>((resolve, reject) => {
124
+ const unsubscribeError = conn.onError((error) => {
125
+ reject(error);
126
+ });
127
+ const unsubscribeEvent = conn.on("undefinedEvent", (payload) => {
128
+ unsubscribeError();
129
+ unsubscribeEvent();
130
+ resolve(payload as { value: string });
131
+ });
132
+ });
133
+
134
+ await conn.allowedAction("undefined-subscribe-ready");
135
+ await conn.allowedBroadcastUndefinedEvent("wildcard");
136
+ expect(await eventPromise).toEqual({ value: "wildcard" });
137
+
138
+ await conn.dispose();
139
+ });
140
+
141
+ test("allows and denies raw request handlers", async (c) => {
142
+ const { client } = await setupDriverTest(c, driverTestConfig);
143
+
144
+ const allowedHandle = client.accessControlActor.getOrCreate(
145
+ ["raw-request-allow"],
146
+ {
147
+ params: { allowRequest: true },
148
+ },
149
+ );
150
+ const deniedHandle = client.accessControlActor.getOrCreate(
151
+ ["raw-request-deny"],
152
+ {
153
+ params: { allowRequest: false },
154
+ },
155
+ );
156
+
157
+ const allowedResponse = await allowedHandle.fetch("/status");
158
+ expect(allowedResponse.status).toBe(200);
159
+ expect(await allowedResponse.json()).toEqual({ ok: true });
160
+
161
+ const deniedResponse = await deniedHandle.fetch("/status");
162
+ expect(deniedResponse.status).toBe(403);
163
+ });
164
+
165
+ test("allows and denies raw websocket handlers", async (c) => {
166
+ const { client } = await setupDriverTest(c, driverTestConfig);
167
+
168
+ const allowedHandle = client.accessControlActor.getOrCreate(
169
+ ["raw-websocket-allow"],
170
+ {
171
+ params: { allowWebSocket: true },
172
+ },
173
+ );
174
+ const ws = await allowedHandle.webSocket();
175
+ const welcome = await new Promise<{ type: string }>((resolve) => {
176
+ ws.addEventListener(
177
+ "message",
178
+ (event: any) => {
179
+ resolve(
180
+ JSON.parse(event.data as string) as {
181
+ type: string;
182
+ },
183
+ );
184
+ },
185
+ { once: true },
186
+ );
187
+ });
188
+ expect(welcome.type).toBe("welcome");
189
+ ws.close();
190
+
191
+ const deniedHandle = client.accessControlActor.getOrCreate(
192
+ ["raw-websocket-deny"],
193
+ {
194
+ params: { allowWebSocket: false },
195
+ },
196
+ );
197
+
198
+ let denied = false;
199
+ try {
200
+ const deniedWs = await deniedHandle.webSocket();
201
+ const closeEvent = await new Promise<any>((resolve) => {
202
+ deniedWs.addEventListener(
203
+ "close",
204
+ (event: any) => {
205
+ resolve(event);
206
+ },
207
+ { once: true },
208
+ );
209
+ });
210
+ expect(closeEvent.code).toBe(1011);
211
+ denied = true;
212
+ } catch {
213
+ denied = true;
214
+ }
215
+ expect(denied).toBe(true);
216
+ });
217
+ });
218
+ }
@@ -0,0 +1,73 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import type { DriverTestConfig } from "../mod";
3
+ import { setupDriverTest } from "../utils";
4
+
5
+ export function runActorDbRawTests(driverTestConfig: DriverTestConfig) {
6
+ describe("Actor Database (Raw) Tests", () => {
7
+ describe("Database Basic Operations", () => {
8
+ test("creates and queries database tables", async (c) => {
9
+ const { client } = await setupDriverTest(c, driverTestConfig);
10
+
11
+ const instance = client.dbActorRaw.getOrCreate();
12
+
13
+ // Add values
14
+ await instance.insertValue("Alice");
15
+ await instance.insertValue("Bob");
16
+
17
+ // Query values
18
+ const values = await instance.getValues();
19
+ expect(values).toHaveLength(2);
20
+ expect(values[0].value).toBe("Alice");
21
+ expect(values[1].value).toBe("Bob");
22
+ });
23
+
24
+ test("persists data across actor instances", async (c) => {
25
+ const { client } = await setupDriverTest(c, driverTestConfig);
26
+
27
+ // First instance adds items
28
+ const instance1 = client.dbActorRaw.getOrCreate(["test-persistence"]);
29
+ await instance1.insertValue("Item 1");
30
+ await instance1.insertValue("Item 2");
31
+
32
+ // Second instance (same actor) should see persisted data
33
+ const instance2 = client.dbActorRaw.getOrCreate(["test-persistence"]);
34
+ const count = await instance2.getCount();
35
+ expect(count).toBe(2);
36
+ });
37
+
38
+ test("maintains separate databases for different actors", async (c) => {
39
+ const { client } = await setupDriverTest(c, driverTestConfig);
40
+
41
+ // First actor
42
+ const actor1 = client.dbActorRaw.getOrCreate(["actor-1"]);
43
+ await actor1.insertValue("A");
44
+ await actor1.insertValue("B");
45
+
46
+ // Second actor
47
+ const actor2 = client.dbActorRaw.getOrCreate(["actor-2"]);
48
+ await actor2.insertValue("X");
49
+
50
+ // Verify separate data
51
+ const count1 = await actor1.getCount();
52
+ const count2 = await actor2.getCount();
53
+ expect(count1).toBe(2);
54
+ expect(count2).toBe(1);
55
+ });
56
+ });
57
+
58
+ describe("Database Migrations", () => {
59
+ test("runs migrations on actor startup", async (c) => {
60
+ const { client } = await setupDriverTest(c, driverTestConfig);
61
+
62
+ const instance = client.dbActorRaw.getOrCreate();
63
+
64
+ // Try to insert into the table to verify it exists
65
+ await instance.insertValue("test");
66
+ const values = await instance.getValues();
67
+
68
+ expect(values).toHaveLength(1);
69
+ expect(values[0].value).toBe("test");
70
+ });
71
+ });
72
+ });
73
+ }