rivetkit 2.1.5 → 2.1.6-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. package/dist/browser/client.d.ts +593 -588
  2. package/dist/browser/client.js +215 -35
  3. package/dist/browser/client.js.map +1 -1
  4. package/dist/browser/inspector/client.js +109 -10
  5. package/dist/browser/inspector/client.js.map +1 -1
  6. package/dist/inspector.tar.gz +0 -0
  7. package/dist/tsup/actor/errors.cjs +2 -2
  8. package/dist/tsup/actor/errors.js +1 -1
  9. package/dist/tsup/{actor-router-consts-D29T1Z-K.d.cts → actor-router-consts-DU-1IdQj.d.cts} +1 -1
  10. package/dist/tsup/{actor-router-consts-D29T1Z-K.d.ts → actor-router-consts-DU-1IdQj.d.ts} +1 -1
  11. package/dist/tsup/chunk-2ELYUO6C.cjs +112 -0
  12. package/dist/tsup/chunk-2ELYUO6C.cjs.map +1 -0
  13. package/dist/tsup/chunk-2LY7RW3Y.cjs +2316 -0
  14. package/dist/tsup/chunk-2LY7RW3Y.cjs.map +1 -0
  15. package/dist/tsup/{chunk-L47L3ZWJ.cjs → chunk-6G7ZNM27.cjs} +11 -6
  16. package/dist/tsup/chunk-6G7ZNM27.cjs.map +1 -0
  17. package/dist/tsup/{chunk-PB5AEMKQ.cjs → chunk-A4KEUCB6.cjs} +84 -34
  18. package/dist/tsup/chunk-A4KEUCB6.cjs.map +1 -0
  19. package/dist/tsup/{chunk-7HTNH26M.js → chunk-AKUJ5OTO.js} +11 -6
  20. package/dist/tsup/chunk-AKUJ5OTO.js.map +1 -0
  21. package/dist/tsup/{chunk-TADUYCHF.js → chunk-C22JYHVT.js} +77 -27
  22. package/dist/tsup/chunk-C22JYHVT.js.map +1 -0
  23. package/dist/tsup/chunk-C4EB42ET.js +1459 -0
  24. package/dist/tsup/chunk-C4EB42ET.js.map +1 -0
  25. package/dist/tsup/chunk-CGGGBIDP.cjs +1459 -0
  26. package/dist/tsup/chunk-CGGGBIDP.cjs.map +1 -0
  27. package/dist/tsup/chunk-CMQPDBBR.cjs +1486 -0
  28. package/dist/tsup/chunk-CMQPDBBR.cjs.map +1 -0
  29. package/dist/tsup/{chunk-GQGRQDRL.cjs → chunk-DH6UINWA.cjs} +4 -4
  30. package/dist/tsup/{chunk-GQGRQDRL.cjs.map → chunk-DH6UINWA.cjs.map} +1 -1
  31. package/dist/tsup/chunk-DK46YYCJ.js +1486 -0
  32. package/dist/tsup/chunk-DK46YYCJ.js.map +1 -0
  33. package/dist/tsup/chunk-EGWXXBZV.js +2316 -0
  34. package/dist/tsup/chunk-EGWXXBZV.js.map +1 -0
  35. package/dist/tsup/{chunk-S662Y6ZU.js → chunk-EONWXYMN.js} +2 -2
  36. package/dist/tsup/{chunk-N4KRDJ56.js → chunk-GFGRBYO2.js} +35 -6
  37. package/dist/tsup/chunk-GFGRBYO2.js.map +1 -0
  38. package/dist/tsup/{chunk-IIJNPVPQ.cjs → chunk-GUHXWPGB.cjs} +1515 -1479
  39. package/dist/tsup/chunk-GUHXWPGB.cjs.map +1 -0
  40. package/dist/tsup/{chunk-TI5PXQGG.cjs → chunk-HNE2AK6C.cjs} +2375 -3713
  41. package/dist/tsup/chunk-HNE2AK6C.cjs.map +1 -0
  42. package/dist/tsup/{chunk-2OK7S6QF.js → chunk-I5I6OALK.js} +2 -2
  43. package/dist/tsup/chunk-IHQAF2HV.cjs +23 -0
  44. package/dist/tsup/chunk-IHQAF2HV.cjs.map +1 -0
  45. package/dist/tsup/{chunk-U5SMSA27.cjs → chunk-JJNZQDUN.cjs} +667 -2517
  46. package/dist/tsup/chunk-JJNZQDUN.cjs.map +1 -0
  47. package/dist/tsup/{chunk-ZPWOYQHN.js → chunk-JJSPHLJN.js} +219 -287
  48. package/dist/tsup/chunk-JJSPHLJN.js.map +1 -0
  49. package/dist/tsup/chunk-JRKPV5NJ.js +481 -0
  50. package/dist/tsup/chunk-JRKPV5NJ.js.map +1 -0
  51. package/dist/tsup/{chunk-VKVNIQRQ.js → chunk-K7MVU5SI.js} +36 -41
  52. package/dist/tsup/chunk-K7MVU5SI.js.map +1 -0
  53. package/dist/tsup/{chunk-KJSYAUOM.js → chunk-MLK3GY6P.js} +43 -27
  54. package/dist/tsup/chunk-MLK3GY6P.js.map +1 -0
  55. package/dist/tsup/{chunk-HYPIHCDT.cjs → chunk-MPLMTJY5.cjs} +123 -23
  56. package/dist/tsup/chunk-MPLMTJY5.cjs.map +1 -0
  57. package/dist/tsup/{chunk-MIX2KB6U.js → chunk-PQWI44WD.js} +1755 -3093
  58. package/dist/tsup/chunk-PQWI44WD.js.map +1 -0
  59. package/dist/tsup/{chunk-SR3KQE7Q.cjs → chunk-SQFCIDCG.cjs} +35 -6
  60. package/dist/tsup/chunk-SQFCIDCG.cjs.map +1 -0
  61. package/dist/tsup/{chunk-WY2SHWXQ.js → chunk-SVHJSM2E.js} +110 -24
  62. package/dist/tsup/chunk-SVHJSM2E.js.map +1 -0
  63. package/dist/tsup/chunk-T5KYKM6R.js +49 -0
  64. package/dist/tsup/chunk-T5KYKM6R.js.map +1 -0
  65. package/dist/tsup/{chunk-7WF2QSIC.cjs → chunk-TJ7DKW6F.cjs} +123 -37
  66. package/dist/tsup/chunk-TJ7DKW6F.cjs.map +1 -0
  67. package/dist/tsup/chunk-UQZRMTM3.js +23 -0
  68. package/dist/tsup/chunk-UQZRMTM3.js.map +1 -0
  69. package/dist/tsup/{chunk-JC6BEPE7.cjs → chunk-V3JSZR5P.cjs} +3 -3
  70. package/dist/tsup/{chunk-JC6BEPE7.cjs.map → chunk-V3JSZR5P.cjs.map} +1 -1
  71. package/dist/tsup/{chunk-OAXJWGMU.cjs → chunk-VBR35EQF.cjs} +271 -339
  72. package/dist/tsup/chunk-VBR35EQF.cjs.map +1 -0
  73. package/dist/tsup/{chunk-EIATSBYZ.js → chunk-VWYO36X4.js} +117 -17
  74. package/dist/tsup/chunk-VWYO36X4.js.map +1 -0
  75. package/dist/tsup/{chunk-JPXO2H55.js → chunk-WW27B6DM.js} +1452 -1416
  76. package/dist/tsup/chunk-WW27B6DM.js.map +1 -0
  77. package/dist/tsup/chunk-YAE3MEJM.cjs +49 -0
  78. package/dist/tsup/chunk-YAE3MEJM.cjs.map +1 -0
  79. package/dist/tsup/{chunk-SRIM3GHD.js → chunk-YGYGANCA.js} +473 -2323
  80. package/dist/tsup/chunk-YGYGANCA.js.map +1 -0
  81. package/dist/tsup/chunk-YZJWZBY5.cjs +481 -0
  82. package/dist/tsup/chunk-YZJWZBY5.cjs.map +1 -0
  83. package/dist/tsup/{chunk-ZFY5J2EP.cjs → chunk-ZZLJ5TSM.cjs} +39 -44
  84. package/dist/tsup/chunk-ZZLJ5TSM.cjs.map +1 -0
  85. package/dist/tsup/client/mod.cjs +10 -7
  86. package/dist/tsup/client/mod.cjs.map +1 -1
  87. package/dist/tsup/client/mod.d.cts +6 -6
  88. package/dist/tsup/client/mod.d.ts +6 -6
  89. package/dist/tsup/client/mod.js +11 -8
  90. package/dist/tsup/common/log.cjs +3 -3
  91. package/dist/tsup/common/log.js +2 -2
  92. package/dist/tsup/common/websocket.cjs +4 -4
  93. package/dist/tsup/common/websocket.js +3 -3
  94. package/dist/tsup/{config-Qj-zLJPc.d.ts → config-C2Wwnc69.d.ts} +142 -208
  95. package/dist/tsup/{config-BiNoIHRs.d.ts → config-DROwzBLT.d.cts} +82 -6
  96. package/dist/tsup/{config-BiNoIHRs.d.cts → config-DROwzBLT.d.ts} +82 -6
  97. package/dist/tsup/{config-iPj5l1bL.d.cts → config-ehT-_3BB.d.cts} +142 -208
  98. package/dist/tsup/{context-DzvH1PBK.d.cts → context-DGMJuAyc.d.ts} +16 -3
  99. package/dist/tsup/{context-CQCMuHND.d.ts → context-Dpp2RJbW.d.cts} +16 -3
  100. package/dist/tsup/db/drizzle/mod.cjs +3 -3
  101. package/dist/tsup/db/drizzle/mod.d.cts +1 -1
  102. package/dist/tsup/db/drizzle/mod.d.ts +1 -1
  103. package/dist/tsup/db/drizzle/mod.js +2 -2
  104. package/dist/tsup/db/mod.cjs +3 -3
  105. package/dist/tsup/db/mod.d.cts +1 -1
  106. package/dist/tsup/db/mod.d.ts +1 -1
  107. package/dist/tsup/db/mod.js +2 -2
  108. package/dist/tsup/{driver-Jo8v-kbU.d.ts → driver-CYZP9QYo.d.ts} +1 -1
  109. package/dist/tsup/{driver-iV8J-WMv.d.cts → driver-CoTFpipv.d.cts} +1 -1
  110. package/dist/tsup/driver-helpers/mod.cjs +7 -5
  111. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  112. package/dist/tsup/driver-helpers/mod.d.cts +17 -18
  113. package/dist/tsup/driver-helpers/mod.d.ts +17 -18
  114. package/dist/tsup/driver-helpers/mod.js +11 -9
  115. package/dist/tsup/driver-test-suite/mod.cjs +1275 -228
  116. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  117. package/dist/tsup/driver-test-suite/mod.d.cts +6 -5
  118. package/dist/tsup/driver-test-suite/mod.d.ts +6 -5
  119. package/dist/tsup/driver-test-suite/mod.js +1581 -534
  120. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  121. package/dist/tsup/inspector/mod.cjs +4 -4
  122. package/dist/tsup/inspector/mod.js +3 -3
  123. package/dist/tsup/mod.cjs +15 -9
  124. package/dist/tsup/mod.cjs.map +1 -1
  125. package/dist/tsup/mod.d.cts +9 -9
  126. package/dist/tsup/mod.d.ts +9 -9
  127. package/dist/tsup/mod.js +19 -13
  128. package/dist/tsup/sandbox/client.cjs +28 -0
  129. package/dist/tsup/sandbox/client.cjs.map +1 -0
  130. package/dist/tsup/sandbox/client.d.cts +88 -0
  131. package/dist/tsup/sandbox/client.d.ts +88 -0
  132. package/dist/tsup/sandbox/client.js +28 -0
  133. package/dist/tsup/sandbox/client.js.map +1 -0
  134. package/dist/tsup/sandbox/index.cjs +761 -0
  135. package/dist/tsup/sandbox/index.cjs.map +1 -0
  136. package/dist/tsup/sandbox/index.d.cts +120 -0
  137. package/dist/tsup/sandbox/index.d.ts +120 -0
  138. package/dist/tsup/sandbox/index.js +761 -0
  139. package/dist/tsup/sandbox/index.js.map +1 -0
  140. package/dist/tsup/sandbox/providers/computesdk.cjs +3 -0
  141. package/dist/tsup/sandbox/providers/computesdk.cjs.map +1 -0
  142. package/dist/tsup/sandbox/providers/computesdk.d.cts +7 -0
  143. package/dist/tsup/sandbox/providers/computesdk.d.ts +7 -0
  144. package/dist/tsup/sandbox/providers/computesdk.js +3 -0
  145. package/dist/tsup/sandbox/providers/computesdk.js.map +1 -0
  146. package/dist/tsup/sandbox/providers/daytona.cjs +3 -0
  147. package/dist/tsup/sandbox/providers/daytona.cjs.map +1 -0
  148. package/dist/tsup/sandbox/providers/daytona.d.cts +1 -0
  149. package/dist/tsup/sandbox/providers/daytona.d.ts +1 -0
  150. package/dist/tsup/sandbox/providers/daytona.js +3 -0
  151. package/dist/tsup/sandbox/providers/daytona.js.map +1 -0
  152. package/dist/tsup/sandbox/providers/docker.cjs +3 -0
  153. package/dist/tsup/sandbox/providers/docker.cjs.map +1 -0
  154. package/dist/tsup/sandbox/providers/docker.d.cts +1 -0
  155. package/dist/tsup/sandbox/providers/docker.d.ts +1 -0
  156. package/dist/tsup/sandbox/providers/docker.js +3 -0
  157. package/dist/tsup/sandbox/providers/docker.js.map +1 -0
  158. package/dist/tsup/sandbox/providers/e2b.cjs +3 -0
  159. package/dist/tsup/sandbox/providers/e2b.cjs.map +1 -0
  160. package/dist/tsup/sandbox/providers/e2b.d.cts +1 -0
  161. package/dist/tsup/sandbox/providers/e2b.d.ts +1 -0
  162. package/dist/tsup/sandbox/providers/e2b.js +3 -0
  163. package/dist/tsup/sandbox/providers/e2b.js.map +1 -0
  164. package/dist/tsup/sandbox/providers/local.cjs +3 -0
  165. package/dist/tsup/sandbox/providers/local.cjs.map +1 -0
  166. package/dist/tsup/sandbox/providers/local.d.cts +1 -0
  167. package/dist/tsup/sandbox/providers/local.d.ts +1 -0
  168. package/dist/tsup/sandbox/providers/local.js +3 -0
  169. package/dist/tsup/sandbox/providers/local.js.map +1 -0
  170. package/dist/tsup/sandbox/providers/modal.cjs +3 -0
  171. package/dist/tsup/sandbox/providers/modal.cjs.map +1 -0
  172. package/dist/tsup/sandbox/providers/modal.d.cts +1 -0
  173. package/dist/tsup/sandbox/providers/modal.d.ts +1 -0
  174. package/dist/tsup/sandbox/providers/modal.js +3 -0
  175. package/dist/tsup/sandbox/providers/modal.js.map +1 -0
  176. package/dist/tsup/sandbox/providers/vercel.cjs +3 -0
  177. package/dist/tsup/sandbox/providers/vercel.cjs.map +1 -0
  178. package/dist/tsup/sandbox/providers/vercel.d.cts +1 -0
  179. package/dist/tsup/sandbox/providers/vercel.d.ts +1 -0
  180. package/dist/tsup/sandbox/providers/vercel.js +3 -0
  181. package/dist/tsup/sandbox/providers/vercel.js.map +1 -0
  182. package/dist/tsup/serve-test-suite/mod.cjs +451 -327
  183. package/dist/tsup/serve-test-suite/mod.cjs.map +1 -1
  184. package/dist/tsup/serve-test-suite/mod.js +362 -238
  185. package/dist/tsup/serve-test-suite/mod.js.map +1 -1
  186. package/dist/tsup/test/mod.cjs +17 -14
  187. package/dist/tsup/test/mod.cjs.map +1 -1
  188. package/dist/tsup/test/mod.d.cts +4 -4
  189. package/dist/tsup/test/mod.d.ts +4 -4
  190. package/dist/tsup/test/mod.js +14 -11
  191. package/dist/tsup/test/mod.js.map +1 -1
  192. package/dist/tsup/utils.cjs +3 -3
  193. package/dist/tsup/utils.js +2 -2
  194. package/dist/tsup/workflow/mod.cjs +6 -6
  195. package/dist/tsup/workflow/mod.d.cts +13 -9
  196. package/dist/tsup/workflow/mod.d.ts +13 -9
  197. package/dist/tsup/workflow/mod.js +5 -5
  198. package/package.json +114 -15
  199. package/src/actor/config.ts +94 -88
  200. package/src/actor/conn/drivers/websocket.ts +2 -1
  201. package/src/actor/contexts/base/actor.ts +27 -4
  202. package/src/actor/database.ts +6 -1
  203. package/src/actor/driver.ts +27 -8
  204. package/src/actor/errors.ts +10 -5
  205. package/src/actor/instance/connection-manager.ts +4 -3
  206. package/src/actor/instance/kv.ts +52 -9
  207. package/src/actor/instance/mod.ts +135 -84
  208. package/src/actor/instance/queue-manager.ts +2 -5
  209. package/src/actor/instance/queue.ts +31 -29
  210. package/src/actor/instance/state-manager.ts +7 -1
  211. package/src/actor/instance/traces-driver.ts +34 -36
  212. package/src/actor/metrics.ts +137 -0
  213. package/src/actor/protocol/old.ts +9 -12
  214. package/src/actor/router-websocket-endpoints.ts +12 -6
  215. package/src/actor/router.ts +46 -9
  216. package/src/actor/schema.ts +14 -22
  217. package/src/client/actor-common.ts +65 -0
  218. package/src/client/actor-conn.ts +71 -9
  219. package/src/client/actor-handle.ts +22 -5
  220. package/src/client/client.ts +32 -6
  221. package/src/client/config.ts +18 -21
  222. package/src/client/mod.ts +1 -0
  223. package/src/client/queue.ts +8 -6
  224. package/src/common/inline-websocket-adapter.ts +8 -2
  225. package/src/common/router.ts +1 -4
  226. package/src/common/utils.ts +2 -5
  227. package/src/db/config.ts +10 -5
  228. package/src/db/drizzle/mod.ts +51 -41
  229. package/src/db/mod.ts +54 -29
  230. package/src/db/shared.ts +42 -8
  231. package/src/driver-helpers/mod.ts +2 -1
  232. package/src/driver-helpers/sqlite-pool.ts +42 -0
  233. package/src/driver-helpers/utils.ts +0 -20
  234. package/src/driver-test-suite/mod.ts +11 -1
  235. package/src/driver-test-suite/tests/access-control.ts +19 -12
  236. package/src/driver-test-suite/tests/action-features.ts +20 -8
  237. package/src/driver-test-suite/tests/actor-conn.ts +94 -8
  238. package/src/driver-test-suite/tests/actor-db-kv-stats.ts +282 -0
  239. package/src/driver-test-suite/tests/actor-db-raw.ts +6 -2
  240. package/src/driver-test-suite/tests/actor-db.ts +101 -31
  241. package/src/driver-test-suite/tests/actor-inspector.ts +174 -32
  242. package/src/driver-test-suite/tests/actor-kv.ts +79 -33
  243. package/src/driver-test-suite/tests/actor-lifecycle.ts +4 -12
  244. package/src/driver-test-suite/tests/actor-queue.ts +125 -17
  245. package/src/driver-test-suite/tests/actor-run.ts +59 -55
  246. package/src/driver-test-suite/tests/actor-sandbox.ts +78 -0
  247. package/src/driver-test-suite/tests/actor-schedule.ts +1 -4
  248. package/src/driver-test-suite/tests/actor-sleep.ts +111 -0
  249. package/src/driver-test-suite/tests/actor-workflow.ts +387 -3
  250. package/src/driver-test-suite/tests/conn-error-serialization.ts +3 -1
  251. package/src/driver-test-suite/tests/raw-websocket.ts +5 -1
  252. package/src/drivers/default.ts +1 -3
  253. package/src/drivers/engine/actor-driver.ts +94 -21
  254. package/src/drivers/engine/config.ts +4 -12
  255. package/src/drivers/engine/mod.ts +1 -5
  256. package/src/drivers/file-system/actor.ts +43 -8
  257. package/src/drivers/file-system/global-state.ts +180 -64
  258. package/src/drivers/file-system/kv-limits.ts +1 -1
  259. package/src/drivers/file-system/sqlite-runtime.ts +13 -4
  260. package/src/engine-process/mod.ts +5 -1
  261. package/src/inspector/actor-inspector.ts +47 -21
  262. package/src/inspector/config.ts +1 -4
  263. package/src/inspector/mod.browser.ts +2 -2
  264. package/src/inspector/mod.ts +4 -1
  265. package/src/inspector/serve-ui.ts +0 -1
  266. package/src/inspector/workflow-history-json.ts +309 -0
  267. package/src/manager/gateway.ts +6 -2
  268. package/src/manager/router.ts +3 -3
  269. package/src/registry/config/index.ts +65 -12
  270. package/src/registry/config/runner.ts +19 -4
  271. package/src/registry/index.ts +42 -89
  272. package/src/sandbox/actor/db.ts +36 -0
  273. package/src/sandbox/actor/index.ts +476 -0
  274. package/src/sandbox/actor/session.ts +350 -0
  275. package/src/sandbox/actor.test.ts +36 -0
  276. package/src/sandbox/client.test.ts +484 -0
  277. package/src/sandbox/client.ts +707 -0
  278. package/src/sandbox/config.ts +151 -0
  279. package/src/sandbox/index.ts +41 -0
  280. package/src/sandbox/providers/computesdk.ts +1 -0
  281. package/src/sandbox/providers/daytona.ts +1 -0
  282. package/src/sandbox/providers/docker.ts +1 -0
  283. package/src/sandbox/providers/e2b.ts +1 -0
  284. package/src/sandbox/providers/local.ts +1 -0
  285. package/src/sandbox/providers/modal.ts +1 -0
  286. package/src/sandbox/providers/vercel.ts +1 -0
  287. package/src/sandbox/session-persist-driver.ts +180 -0
  288. package/src/sandbox/types.ts +138 -0
  289. package/src/serverless/configure.ts +5 -3
  290. package/src/serverless/router.test.ts +17 -9
  291. package/src/serverless/router.ts +20 -13
  292. package/src/test/mod.ts +3 -4
  293. package/src/utils/endpoint-parser.test.ts +6 -2
  294. package/src/utils/endpoint-parser.ts +6 -2
  295. package/src/utils/env-vars.ts +0 -2
  296. package/src/utils/node.ts +1 -1
  297. package/src/utils/serve.ts +10 -5
  298. package/src/utils.ts +6 -1
  299. package/src/workflow/constants.ts +1 -2
  300. package/src/workflow/context.ts +42 -9
  301. package/src/workflow/driver.ts +57 -23
  302. package/src/workflow/inspector.ts +7 -13
  303. package/src/workflow/mod.ts +91 -4
  304. package/dist/tsup/chunk-6LJAZ5R4.cjs +0 -96
  305. package/dist/tsup/chunk-6LJAZ5R4.cjs.map +0 -1
  306. package/dist/tsup/chunk-7HTNH26M.js.map +0 -1
  307. package/dist/tsup/chunk-7WF2QSIC.cjs.map +0 -1
  308. package/dist/tsup/chunk-D2SPAJVT.cjs +0 -645
  309. package/dist/tsup/chunk-D2SPAJVT.cjs.map +0 -1
  310. package/dist/tsup/chunk-EIATSBYZ.js.map +0 -1
  311. package/dist/tsup/chunk-HYPIHCDT.cjs.map +0 -1
  312. package/dist/tsup/chunk-IIJNPVPQ.cjs.map +0 -1
  313. package/dist/tsup/chunk-JPXO2H55.js.map +0 -1
  314. package/dist/tsup/chunk-KJSYAUOM.js.map +0 -1
  315. package/dist/tsup/chunk-L47L3ZWJ.cjs.map +0 -1
  316. package/dist/tsup/chunk-MIX2KB6U.js.map +0 -1
  317. package/dist/tsup/chunk-N4KRDJ56.js.map +0 -1
  318. package/dist/tsup/chunk-OAXJWGMU.cjs.map +0 -1
  319. package/dist/tsup/chunk-PB5AEMKQ.cjs.map +0 -1
  320. package/dist/tsup/chunk-R5OQUSLN.js +0 -645
  321. package/dist/tsup/chunk-R5OQUSLN.js.map +0 -1
  322. package/dist/tsup/chunk-SR3KQE7Q.cjs.map +0 -1
  323. package/dist/tsup/chunk-SRIM3GHD.js.map +0 -1
  324. package/dist/tsup/chunk-TADUYCHF.js.map +0 -1
  325. package/dist/tsup/chunk-TI5PXQGG.cjs.map +0 -1
  326. package/dist/tsup/chunk-U5SMSA27.cjs.map +0 -1
  327. package/dist/tsup/chunk-VKVNIQRQ.js.map +0 -1
  328. package/dist/tsup/chunk-WY2SHWXQ.js.map +0 -1
  329. package/dist/tsup/chunk-ZFY5J2EP.cjs.map +0 -1
  330. package/dist/tsup/chunk-ZPWOYQHN.js.map +0 -1
  331. package/src/db/sqlite-vfs.ts +0 -12
  332. /package/dist/tsup/{chunk-S662Y6ZU.js.map → chunk-EONWXYMN.js.map} +0 -0
  333. /package/dist/tsup/{chunk-2OK7S6QF.js.map → chunk-I5I6OALK.js.map} +0 -0
@@ -23,7 +23,10 @@ import {
23
23
  HttpActionResponseSchema,
24
24
  } from "@/schemas/client-protocol-zod/mod";
25
25
  import { bufferToArrayBuffer } from "@/utils";
26
- import type { ActorDefinitionActions } from "./actor-common";
26
+ import type {
27
+ ActorDefinitionActions,
28
+ ActorDefinitionQueueSend,
29
+ } from "./actor-common";
27
30
  import { type ActorConn, ActorConnRaw } from "./actor-conn";
28
31
  import { checkForSchedulingError, queryActor } from "./actor-query";
29
32
  import { type ClientRaw, CREATE_ACTOR_CONN_PROXY } from "./client";
@@ -51,6 +54,7 @@ export class ActorHandleRaw {
51
54
  #encoding: Encoding;
52
55
  #actorQuery: ActorQuery;
53
56
  #params: unknown;
57
+ #getParams?: () => Promise<unknown>;
54
58
  #queueSender: ReturnType<typeof createQueueSender>;
55
59
 
56
60
  /**
@@ -64,6 +68,7 @@ export class ActorHandleRaw {
64
68
  client: any,
65
69
  driver: ManagerDriver,
66
70
  params: unknown,
71
+ getParams: (() => Promise<unknown>) | undefined,
67
72
  encoding: Encoding,
68
73
  actorQuery: ActorQuery,
69
74
  ) {
@@ -72,6 +77,7 @@ export class ActorHandleRaw {
72
77
  this.#encoding = encoding;
73
78
  this.#actorQuery = actorQuery;
74
79
  this.#params = params;
80
+ this.#getParams = getParams;
75
81
  this.#queueSender = createQueueSender({
76
82
  encoding: this.#encoding,
77
83
  params: this.#params,
@@ -86,6 +92,14 @@ export class ActorHandleRaw {
86
92
  });
87
93
  }
88
94
 
95
+ async #resolveConnectionParams(): Promise<unknown> {
96
+ if (this.#getParams) {
97
+ return await this.#getParams();
98
+ }
99
+
100
+ return this.#params;
101
+ }
102
+
89
103
  send(
90
104
  name: string,
91
105
  body: unknown,
@@ -227,6 +241,7 @@ export class ActorHandleRaw {
227
241
  this.#client,
228
242
  this.#driver,
229
243
  this.#params,
244
+ this.#getParams,
230
245
  this.#encoding,
231
246
  this.#actorQuery,
232
247
  );
@@ -253,11 +268,12 @@ export class ActorHandleRaw {
253
268
  /**
254
269
  * Opens a raw WebSocket connection to this actor.
255
270
  */
256
- webSocket(path?: string, protocols?: string | string[]) {
271
+ async webSocket(path?: string, protocols?: string | string[]) {
272
+ const params = await this.#resolveConnectionParams();
257
273
  return rawWebSocket(
258
274
  this.#driver,
259
275
  this.#actorQuery,
260
- this.#params,
276
+ params,
261
277
  path,
262
278
  protocols,
263
279
  );
@@ -335,10 +351,11 @@ export class ActorHandleRaw {
335
351
  */
336
352
  export type ActorHandle<AD extends AnyActorDefinition> = Omit<
337
353
  ActorHandleRaw,
338
- "connect"
354
+ "connect" | "send"
339
355
  > & {
340
356
  // Add typed version of ActorConn (instead of using AnyActorDefinition)
341
357
  connect(): ActorConn<AD>;
342
358
  // Resolve method returns the actor ID
343
359
  resolve(): Promise<string>;
344
- } & ActorDefinitionActions<AD>;
360
+ } & ActorDefinitionQueueSend<AD> &
361
+ ActorDefinitionActions<AD>;
@@ -86,6 +86,11 @@ export interface ActorAccessor<AD extends AnyActorDefinition> {
86
86
  export interface QueryOptions {
87
87
  /** Parameters to pass to the connection. */
88
88
  params?: unknown;
89
+ /**
90
+ * Lazily resolves connection parameters for `.connect()` and `.webSocket()`.
91
+ * This is called each time a new connection is opened.
92
+ */
93
+ getParams?: () => Promise<unknown>;
89
94
  /** Signal to abort the request. */
90
95
  signal?: AbortSignal;
91
96
  }
@@ -200,7 +205,11 @@ export class ClientRaw {
200
205
  },
201
206
  };
202
207
 
203
- const handle = this.#createHandle(opts?.params, actorQuery);
208
+ const handle = this.#createHandle(
209
+ opts?.params,
210
+ opts?.getParams,
211
+ actorQuery,
212
+ );
204
213
  return createActorProxy(handle) as ActorHandle<AD>;
205
214
  }
206
215
 
@@ -235,7 +244,11 @@ export class ClientRaw {
235
244
  },
236
245
  };
237
246
 
238
- const handle = this.#createHandle(opts?.params, actorQuery);
247
+ const handle = this.#createHandle(
248
+ opts?.params,
249
+ opts?.getParams,
250
+ actorQuery,
251
+ );
239
252
  return createActorProxy(handle) as ActorHandle<AD>;
240
253
  }
241
254
 
@@ -273,7 +286,11 @@ export class ClientRaw {
273
286
  },
274
287
  };
275
288
 
276
- const handle = this.#createHandle(opts?.params, actorQuery);
289
+ const handle = this.#createHandle(
290
+ opts?.params,
291
+ opts?.getParams,
292
+ actorQuery,
293
+ );
277
294
  return createActorProxy(handle) as ActorHandle<AD>;
278
295
  }
279
296
 
@@ -332,18 +349,27 @@ export class ClientRaw {
332
349
  actorId,
333
350
  },
334
351
  } satisfies ActorQuery;
335
- const handle = this.#createHandle(opts?.params, getForIdQuery);
352
+ const handle = this.#createHandle(
353
+ opts?.params,
354
+ opts?.getParams,
355
+ getForIdQuery,
356
+ );
336
357
 
337
358
  const proxy = createActorProxy(handle) as ActorHandle<AD>;
338
359
 
339
360
  return proxy;
340
361
  }
341
362
 
342
- #createHandle(params: unknown, actorQuery: ActorQuery): ActorHandleRaw {
363
+ #createHandle(
364
+ params: unknown,
365
+ getParams: (() => Promise<unknown>) | undefined,
366
+ actorQuery: ActorQuery,
367
+ ): ActorHandleRaw {
343
368
  return new ActorHandleRaw(
344
369
  this,
345
370
  this.#driver,
346
371
  params,
372
+ getParams,
347
373
  this.#encodingKind,
348
374
  actorQuery,
349
375
  );
@@ -554,5 +580,5 @@ function createActorProxy<AD extends AnyActorDefinition>(
554
580
  }
555
581
  return undefined;
556
582
  },
557
- }) as ActorHandle<AD> | ActorConn<AD>;
583
+ }) as unknown as ActorHandle<AD> | ActorConn<AD>;
558
584
  }
@@ -11,19 +11,9 @@ import {
11
11
  import type { RegistryConfig } from "@/registry/config";
12
12
  import { tryParseEndpoint } from "@/utils/endpoint-parser";
13
13
 
14
- /**
15
- * Gets the default endpoint for the client.
16
- *
17
- * In browser: uses current origin + /api/rivet
18
- *
19
- * Server-side: uses 127.0.0.1:6420
20
- */
21
- function getDefaultEndpoint(): string {
22
- if (typeof window !== "undefined" && window.location?.origin) {
23
- return `${window.location.origin}/api/rivet`;
24
- }
25
- return "http://127.0.0.1:6420";
26
- }
14
+ const DEFAULT_ENDPOINT = "http://localhost:6420";
15
+
16
+ let hasWarnedMissingEndpoint = false;
27
17
 
28
18
  /**
29
19
  * Base client config schema without transforms so it can be merged in to other schemas.
@@ -38,18 +28,25 @@ export const ClientConfigSchemaBase = z.object({
38
28
  *
39
29
  * Can also be set via RIVET_ENDPOINT environment variables.
40
30
  *
41
- * Defaults to current origin + /api/rivet in browser, or 127.0.0.1:6420 server-side.
31
+ * Defaults to http://localhost:6420.
42
32
  */
43
33
  endpoint: z
44
34
  .string()
45
35
  .optional()
46
- .transform(
47
- (val) =>
48
- val ??
49
- getRivetEngine() ??
50
- getRivetEndpoint() ??
51
- getDefaultEndpoint(),
52
- ),
36
+ .transform((val) => {
37
+ const resolved =
38
+ val ?? getRivetEngine() ?? getRivetEndpoint();
39
+ if (!resolved && !hasWarnedMissingEndpoint) {
40
+ hasWarnedMissingEndpoint = true;
41
+ console.warn(
42
+ `[rivetkit] No endpoint provided to client. Defaulting to ${DEFAULT_ENDPOINT}. ` +
43
+ `Starting in 2.2.0, an explicit endpoint will be required. ` +
44
+ `Pass an endpoint to createClient() or createRivetKit(), ` +
45
+ `or set the RIVET_ENDPOINT environment variable.`,
46
+ );
47
+ }
48
+ return resolved ?? DEFAULT_ENDPOINT;
49
+ }),
53
50
 
54
51
  /** Token to use to authenticate with the API. */
55
52
  token: z
package/src/client/mod.ts CHANGED
@@ -34,6 +34,7 @@ export { ActorHandleRaw } from "./actor-handle";
34
34
  export type {
35
35
  ActorAccessor,
36
36
  Client,
37
+ ClientConfigInput,
37
38
  ClientRaw,
38
39
  CreateOptions,
39
40
  ExtractActorsFromRegistry,
@@ -43,9 +43,9 @@ export interface QueueSendNoWaitOptions {
43
43
 
44
44
  export type QueueSendOptions = QueueSendWaitOptions | QueueSendNoWaitOptions;
45
45
 
46
- export interface QueueSendResult {
46
+ export interface QueueSendResult<TResponse = unknown> {
47
47
  status: "completed" | "timedOut";
48
- response?: unknown;
48
+ response?: TResponse;
49
49
  }
50
50
 
51
51
  interface QueueSenderOptions {
@@ -54,7 +54,9 @@ interface QueueSenderOptions {
54
54
  customFetch: (request: Request) => Promise<Response>;
55
55
  }
56
56
 
57
- export function createQueueSender(senderOptions: QueueSenderOptions): QueueSender {
57
+ export function createQueueSender(
58
+ senderOptions: QueueSenderOptions,
59
+ ): QueueSender {
58
60
  async function send(
59
61
  name: string,
60
62
  body: unknown,
@@ -100,8 +102,7 @@ export function createQueueSender(senderOptions: QueueSenderOptions): QueueSende
100
102
  requestVersion: CLIENT_PROTOCOL_CURRENT_VERSION,
101
103
  requestVersionedDataHandler: HTTP_QUEUE_SEND_REQUEST_VERSIONED,
102
104
  responseVersion: CLIENT_PROTOCOL_CURRENT_VERSION,
103
- responseVersionedDataHandler:
104
- HTTP_QUEUE_SEND_RESPONSE_VERSIONED,
105
+ responseVersionedDataHandler: HTTP_QUEUE_SEND_RESPONSE_VERSIONED,
105
106
  requestZodSchema: HttpQueueSendRequestSchema,
106
107
  responseZodSchema: HttpQueueSendResponseSchema,
107
108
  requestToJson: (value): HttpQueueSendRequestJson => ({
@@ -112,7 +113,8 @@ export function createQueueSender(senderOptions: QueueSenderOptions): QueueSende
112
113
  name: value.name ?? name,
113
114
  body: bufferToArrayBuffer(cbor.encode(value.body)),
114
115
  wait: value.wait ?? false,
115
- timeout: value.timeout !== undefined ? BigInt(value.timeout) : null,
116
+ timeout:
117
+ value.timeout !== undefined ? BigInt(value.timeout) : null,
116
118
  }),
117
119
  responseFromJson: (json): QueueSendResult => {
118
120
  if (json.response === undefined) {
@@ -111,7 +111,10 @@ export class InlineWebSocketAdapter {
111
111
  try {
112
112
  this.#handler.onError(err, this.#wsContext);
113
113
  } catch (handlerErr) {
114
- logger().error({ msg: "error in onError handler", error: handlerErr });
114
+ logger().error({
115
+ msg: "error in onError handler",
116
+ error: handlerErr,
117
+ });
115
118
  }
116
119
 
117
120
  // Fire error event to both sides
@@ -129,7 +132,10 @@ export class InlineWebSocketAdapter {
129
132
  this.#readyState = 2; // CLOSING
130
133
 
131
134
  try {
132
- this.#handler.onClose({ code, reason, wasClean: true }, this.#wsContext);
135
+ this.#handler.onClose(
136
+ { code, reason, wasClean: true },
137
+ this.#wsContext,
138
+ );
133
139
  } catch (err) {
134
140
  logger().error({ msg: "error closing websocket", error: err });
135
141
  } finally {
@@ -5,10 +5,7 @@ import {
5
5
  getRequestEncoding,
6
6
  getRequestExposeInternalError,
7
7
  } from "@/actor/router-endpoints";
8
- import {
9
- buildActorNames,
10
- type RegistryConfig,
11
- } from "@/registry/config";
8
+ import { buildActorNames, type RegistryConfig } from "@/registry/config";
12
9
  import type * as protocol from "@/schemas/client-protocol/mod";
13
10
  import {
14
11
  CURRENT_VERSION as CLIENT_PROTOCOL_CURRENT_VERSION,
@@ -299,10 +299,7 @@ export function deconstructError(
299
299
 
300
300
  export function stringifyError(error: unknown): string {
301
301
  if (error instanceof Error) {
302
- if (
303
- typeof process !== "undefined" &&
304
- getLogErrorStack()
305
- ) {
302
+ if (typeof process !== "undefined" && getLogErrorStack()) {
306
303
  return `${error.name}: ${error.message}${error.stack ? `\n${error.stack}` : ""}`;
307
304
  } else {
308
305
  return `${error.name}: ${error.message}`;
@@ -335,5 +332,5 @@ function getErrorMessage(err: unknown): string {
335
332
 
336
333
  /** Generates a `Next` handler to pass to middleware in order to be able to call arbitrary middleware. */
337
334
  export function noopNext(): Next {
338
- return async () => { };
335
+ return async () => {};
339
336
  }
package/src/db/config.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type { SqliteVfs } from "@rivetkit/sqlite-vfs";
1
+ import type { ISqliteVfs } from "@rivetkit/sqlite-vfs";
2
+ import type { ActorMetrics } from "@/actor/metrics";
2
3
 
3
4
  export type AnyDatabaseProvider = DatabaseProvider<any> | undefined;
4
5
 
@@ -35,11 +36,15 @@ export interface DatabaseProviderContext {
35
36
  };
36
37
 
37
38
  /**
38
- * SQLite VFS instance for creating KV-backed databases.
39
- * This should be actor-scoped because @rivetkit/sqlite is not re-entrant per
40
- * module instance.
39
+ * SQLite VFS handle for creating KV-backed databases.
40
+ * May be a standalone VFS or a pooled handle from SqliteVfsPool.
41
41
  */
42
- sqliteVfs?: SqliteVfs;
42
+ sqliteVfs?: ISqliteVfs;
43
+
44
+ /**
45
+ * Actor metrics instance. When provided, KV and SQL operations are tracked.
46
+ */
47
+ metrics?: ActorMetrics;
43
48
  }
44
49
 
45
50
  export type DatabaseProvider<DB extends RawAccess> = {
@@ -1,4 +1,4 @@
1
- import type { Database } from "@rivetkit/sqlite-vfs";
1
+ import type { IDatabase } from "@rivetkit/sqlite-vfs";
2
2
  import {
3
3
  drizzle as proxyDrizzle,
4
4
  type SqliteRemoteDatabase,
@@ -31,7 +31,7 @@ interface DatabaseFactoryConfig<
31
31
  * Create a sqlite-proxy async callback from a @rivetkit/sqlite Database
32
32
  */
33
33
  function createProxyCallback(
34
- waDb: Database,
34
+ waDb: IDatabase,
35
35
  mutex: AsyncMutex,
36
36
  isClosed: () => boolean,
37
37
  ) {
@@ -40,7 +40,7 @@ function createProxyCallback(
40
40
  params: any[],
41
41
  method: "run" | "all" | "values" | "get",
42
42
  ): Promise<{ rows: any }> => {
43
- return mutex.run(async () => {
43
+ return await mutex.run(async () => {
44
44
  if (isClosed()) {
45
45
  throw new Error("database is closed");
46
46
  }
@@ -69,30 +69,25 @@ function createProxyCallback(
69
69
  * Migrations use the same embedded format as drizzle-orm's durable-sqlite.
70
70
  */
71
71
  async function runInlineMigrations(
72
- waDb: Database,
73
- mutex: AsyncMutex,
72
+ waDb: IDatabase,
74
73
  migrations: any,
75
74
  ): Promise<void> {
76
75
  // Create migrations table
77
- await mutex.run(() =>
78
- waDb.exec(`
76
+ await waDb.exec(`
79
77
  CREATE TABLE IF NOT EXISTS __drizzle_migrations (
80
78
  id INTEGER PRIMARY KEY AUTOINCREMENT,
81
79
  hash TEXT NOT NULL,
82
80
  created_at INTEGER
83
81
  )
84
- `),
85
- );
82
+ `);
86
83
 
87
84
  // Get the last applied migration
88
85
  let lastCreatedAt = 0;
89
- await mutex.run(() =>
90
- waDb.exec(
91
- "SELECT id, hash, created_at FROM __drizzle_migrations ORDER BY created_at DESC LIMIT 1",
92
- (row) => {
93
- lastCreatedAt = Number(row[2]) || 0;
94
- },
95
- ),
86
+ await waDb.exec(
87
+ "SELECT id, hash, created_at FROM __drizzle_migrations ORDER BY created_at DESC LIMIT 1",
88
+ (row) => {
89
+ lastCreatedAt = Number(row[2]) || 0;
90
+ },
96
91
  );
97
92
 
98
93
  // Apply pending migrations from journal entries
@@ -109,14 +104,12 @@ async function runInlineMigrations(
109
104
  if (!sql) continue;
110
105
 
111
106
  // Execute migration SQL
112
- await mutex.run(() => waDb.exec(sql));
107
+ await waDb.exec(sql);
113
108
 
114
109
  // Record migration
115
- await mutex.run(() =>
116
- waDb.run(
117
- "INSERT INTO __drizzle_migrations (hash, created_at) VALUES (?, ?)",
118
- [entry.tag, entry.when],
119
- ),
110
+ await waDb.run(
111
+ "INSERT INTO __drizzle_migrations (hash, created_at) VALUES (?, ?)",
112
+ [entry.tag, entry.when],
120
113
  );
121
114
  }
122
115
  }
@@ -126,9 +119,13 @@ export function db<
126
119
  >(
127
120
  config?: DatabaseFactoryConfig<TSchema>,
128
121
  ): DatabaseProvider<SqliteRemoteDatabase<TSchema> & RawAccess> {
129
- // Store the @rivetkit/sqlite Database instance alongside the drizzle client
130
- let waDbInstance: Database | null = null;
131
- const mutex = new AsyncMutex();
122
+ // Map from drizzle client to the underlying @rivetkit/sqlite Database.
123
+ // Uses WeakMap so entries are garbage-collected when the client is.
124
+ // This replaces the previous shared `waDbInstance` variable which caused
125
+ // a race when multiple actors of the same type created databases
126
+ // concurrently: the last writer won, and earlier actors' migrations
127
+ // ran on the wrong database.
128
+ const clientToRawDb = new WeakMap<object, IDatabase>();
132
129
 
133
130
  return {
134
131
  createClient: async (ctx) => {
@@ -139,9 +136,12 @@ export function db<
139
136
  );
140
137
  }
141
138
 
142
- const kvStore = createActorKvStore(ctx.kv);
139
+ const kvStore = createActorKvStore(ctx.kv, ctx.metrics);
143
140
  const waDb = await ctx.sqliteVfs.open(ctx.actorId, kvStore);
144
- waDbInstance = waDb;
141
+ // Per-client mutex so actors of the same type do not serialize
142
+ // against each other. Each actor has its own database handle and
143
+ // its own closed flag, so there is no shared state to guard.
144
+ const mutex = new AsyncMutex();
145
145
  let closed = false;
146
146
  const ensureOpen = () => {
147
147
  if (closed) {
@@ -155,14 +155,17 @@ export function db<
155
155
  // Create the drizzle instance using sqlite-proxy
156
156
  const client = proxyDrizzle<TSchema>(callback, config);
157
157
 
158
- return Object.assign(client, {
158
+ const result = Object.assign(client, {
159
159
  execute: async <
160
- TRow extends Record<string, unknown> = Record<string, unknown>,
160
+ TRow extends Record<string, unknown> = Record<
161
+ string,
162
+ unknown
163
+ >,
161
164
  >(
162
165
  query: string,
163
166
  ...args: unknown[]
164
167
  ): Promise<TRow[]> => {
165
- return mutex.run(async () => {
168
+ return await mutex.run(async () => {
166
169
  ensureOpen();
167
170
 
168
171
  if (args.length > 0) {
@@ -172,7 +175,11 @@ export function db<
172
175
  );
173
176
  return result.rows.map((row: unknown[]) => {
174
177
  const obj: Record<string, unknown> = {};
175
- for (let i = 0; i < result.columns.length; i++) {
178
+ for (
179
+ let i = 0;
180
+ i < result.columns.length;
181
+ i++
182
+ ) {
176
183
  obj[result.columns[i]] = row[i];
177
184
  }
178
185
  return obj;
@@ -199,22 +206,25 @@ export function db<
199
206
  });
200
207
  },
201
208
  close: async () => {
202
- await mutex.run(async () => {
203
- if (closed) {
204
- return;
205
- }
209
+ const shouldClose = await mutex.run(async () => {
210
+ if (closed) return false;
206
211
  closed = true;
207
- await waDb.close();
208
- waDbInstance = null;
212
+ return true;
209
213
  });
214
+ if (shouldClose) {
215
+ await waDb.close();
216
+ }
210
217
  },
211
218
  } satisfies RawAccess);
219
+
220
+ clientToRawDb.set(result, waDb);
221
+ return result;
212
222
  },
213
- onMigrate: async (_client) => {
214
- if (config?.migrations && waDbInstance) {
223
+ onMigrate: async (client) => {
224
+ const waDb = clientToRawDb.get(client as object);
225
+ if (config?.migrations && waDb) {
215
226
  await runInlineMigrations(
216
- waDbInstance,
217
- mutex,
227
+ waDb,
218
228
  config.migrations,
219
229
  );
220
230
  }
package/src/db/mod.ts CHANGED
@@ -21,7 +21,10 @@ export function db({
21
21
  // Use the override
22
22
  return {
23
23
  execute: async <
24
- TRow extends Record<string, unknown> = Record<string, unknown>,
24
+ TRow extends Record<string, unknown> = Record<
25
+ string,
26
+ unknown
27
+ >,
25
28
  >(
26
29
  query: string,
27
30
  ...args: unknown[]
@@ -36,10 +39,12 @@ export function db({
36
39
 
37
40
  // Construct KV-backed client using actor driver's KV operations
38
41
  if (!ctx.sqliteVfs) {
39
- throw new Error("SqliteVfs instance not provided in context. The driver must provide a sqliteVfs instance.");
42
+ throw new Error(
43
+ "SqliteVfs instance not provided in context. The driver must provide a sqliteVfs instance.",
44
+ );
40
45
  }
41
46
 
42
- const kvStore = createActorKvStore(ctx.kv);
47
+ const kvStore = createActorKvStore(ctx.kv, ctx.metrics);
43
48
  const db = await ctx.sqliteVfs.open(ctx.actorId, kvStore);
44
49
  let closed = false;
45
50
  const mutex = new AsyncMutex();
@@ -51,7 +56,10 @@ export function db({
51
56
 
52
57
  return {
53
58
  execute: async <
54
- TRow extends Record<string, unknown> = Record<string, unknown>,
59
+ TRow extends Record<string, unknown> = Record<
60
+ string,
61
+ unknown
62
+ >,
55
63
  >(
56
64
  query: string,
57
65
  ...args: unknown[]
@@ -59,57 +67,74 @@ export function db({
59
67
  return await mutex.run(async () => {
60
68
  ensureOpen();
61
69
 
70
+ const start = performance.now();
71
+
62
72
  // `db.exec` does not support binding `?` placeholders.
63
73
  // Use `db.query` for statements that return rows and `db.run` for
64
74
  // statements that mutate data when parameters are provided.
65
75
  // Keep using `db.exec` for non-parameterized SQL because it
66
76
  // supports multi-statement migrations.
77
+ let result: TRow[];
67
78
  if (args.length > 0) {
68
79
  const bindings = toSqliteBindings(args);
69
- const token = query.trimStart().slice(0, 16).toUpperCase();
80
+ const token = query
81
+ .trimStart()
82
+ .slice(0, 16)
83
+ .toUpperCase();
70
84
  const returnsRows =
71
85
  token.startsWith("SELECT") ||
72
86
  token.startsWith("PRAGMA") ||
73
- token.startsWith("WITH");
87
+ token.startsWith("WITH") ||
88
+ /\bRETURNING\b/i.test(query);
74
89
 
75
90
  if (returnsRows) {
76
- const { rows, columns } = await db.query(query, bindings);
77
- return rows.map((row: unknown[]) => {
91
+ const { rows, columns } = await db.query(
92
+ query,
93
+ bindings,
94
+ );
95
+ result = rows.map((row: unknown[]) => {
78
96
  const rowObj: Record<string, unknown> = {};
79
97
  for (let i = 0; i < columns.length; i++) {
80
98
  rowObj[columns[i]] = row[i];
81
99
  }
82
100
  return rowObj;
83
101
  }) as TRow[];
102
+ } else {
103
+ await db.run(query, bindings);
104
+ result = [] as TRow[];
84
105
  }
85
-
86
- await db.run(query, bindings);
87
- return [] as TRow[];
106
+ } else {
107
+ const results: Record<string, unknown>[] = [];
108
+ let columnNames: string[] | null = null;
109
+ await db.exec(
110
+ query,
111
+ (row: unknown[], columns: string[]) => {
112
+ if (!columnNames) {
113
+ columnNames = columns;
114
+ }
115
+ const rowObj: Record<string, unknown> = {};
116
+ for (let i = 0; i < row.length; i++) {
117
+ rowObj[columnNames[i]] = row[i];
118
+ }
119
+ results.push(rowObj);
120
+ },
121
+ );
122
+ result = results as TRow[];
88
123
  }
89
124
 
90
- const results: Record<string, unknown>[] = [];
91
- let columnNames: string[] | null = null;
92
- await db.exec(query, (row: unknown[], columns: string[]) => {
93
- if (!columnNames) {
94
- columnNames = columns;
95
- }
96
- const rowObj: Record<string, unknown> = {};
97
- for (let i = 0; i < row.length; i++) {
98
- rowObj[columnNames[i]] = row[i];
99
- }
100
- results.push(rowObj);
101
- });
102
- return results as TRow[];
125
+ ctx.metrics?.trackSql(query, performance.now() - start);
126
+ return result;
103
127
  });
104
128
  },
105
129
  close: async () => {
106
- await mutex.run(async () => {
107
- if (closed) {
108
- return;
109
- }
130
+ const shouldClose = await mutex.run(async () => {
131
+ if (closed) return false;
110
132
  closed = true;
111
- await db.close();
133
+ return true;
112
134
  });
135
+ if (shouldClose) {
136
+ await db.close();
137
+ }
113
138
  },
114
139
  } satisfies RawAccess;
115
140
  },