@rikalabs/akter 0.1.0-alpha.0

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 (603) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +8 -0
  4. package/README.md +116 -0
  5. package/dist/actor/codecs.d.ts +77 -0
  6. package/dist/actor/codecs.js +87 -0
  7. package/dist/actor/connections.d.ts +34 -0
  8. package/dist/actor/connections.js +145 -0
  9. package/dist/actor/definition.d.ts +893 -0
  10. package/dist/actor/definition.js +147 -0
  11. package/dist/actor/descriptor.d.ts +172 -0
  12. package/dist/actor/descriptor.js +367 -0
  13. package/dist/actor/handles.d.ts +77 -0
  14. package/dist/actor/handles.js +265 -0
  15. package/dist/actor/jobs.d.ts +10 -0
  16. package/dist/actor/jobs.js +137 -0
  17. package/dist/actor/layers.d.ts +41 -0
  18. package/dist/actor/layers.js +177 -0
  19. package/dist/actor/reads.d.ts +47 -0
  20. package/dist/actor/reads.js +224 -0
  21. package/dist/actor/served.d.ts +120 -0
  22. package/dist/actor/served.js +72 -0
  23. package/dist/actor/turns.d.ts +13 -0
  24. package/dist/actor/turns.js +332 -0
  25. package/dist/actor/workflows.d.ts +16 -0
  26. package/dist/actor/workflows.js +37 -0
  27. package/dist/client/calls.d.ts +47 -0
  28. package/dist/client/calls.js +425 -0
  29. package/dist/client/clock.d.ts +56 -0
  30. package/dist/client/clock.js +119 -0
  31. package/dist/client/fleet-page.d.ts +15 -0
  32. package/dist/client/fleet-page.js +13 -0
  33. package/dist/client/fleet.d.ts +29 -0
  34. package/dist/client/fleet.js +51 -0
  35. package/dist/client/index.d.ts +17 -0
  36. package/dist/client/index.js +6 -0
  37. package/dist/client/make.d.ts +157 -0
  38. package/dist/client/make.js +221 -0
  39. package/dist/client/offline/queue.d.ts +118 -0
  40. package/dist/client/offline/queue.js +292 -0
  41. package/dist/client/offline/store.d.ts +74 -0
  42. package/dist/client/offline/store.js +78 -0
  43. package/dist/client/optimistic.d.ts +57 -0
  44. package/dist/client/optimistic.js +136 -0
  45. package/dist/client/report.d.ts +2 -0
  46. package/dist/client/report.js +8 -0
  47. package/dist/client/sessions/connection.d.ts +118 -0
  48. package/dist/client/sessions/connection.js +162 -0
  49. package/dist/client/sessions/feed.d.ts +42 -0
  50. package/dist/client/sessions/feed.js +43 -0
  51. package/dist/client/sessions/sse.d.ts +47 -0
  52. package/dist/client/sessions/sse.js +112 -0
  53. package/dist/client/sessions/stream.d.ts +28 -0
  54. package/dist/client/sessions/stream.js +35 -0
  55. package/dist/client/sessions/watch.d.ts +34 -0
  56. package/dist/client/sessions/watch.js +40 -0
  57. package/dist/client/transport.d.ts +37 -0
  58. package/dist/client/transport.js +66 -0
  59. package/dist/contexts/command.d.ts +132 -0
  60. package/dist/contexts/command.js +20 -0
  61. package/dist/contexts/connection.d.ts +68 -0
  62. package/dist/contexts/connection.js +0 -0
  63. package/dist/contexts/job.d.ts +49 -0
  64. package/dist/contexts/job.js +0 -0
  65. package/dist/contexts/workflow.d.ts +147 -0
  66. package/dist/contexts/workflow.js +22 -0
  67. package/dist/errors/actor.d.ts +200 -0
  68. package/dist/errors/actor.js +271 -0
  69. package/dist/errors/content.d.ts +19 -0
  70. package/dist/errors/content.js +14 -0
  71. package/dist/errors/database.d.ts +22 -0
  72. package/dist/errors/database.js +23 -0
  73. package/dist/errors/events.d.ts +17 -0
  74. package/dist/errors/events.js +14 -0
  75. package/dist/errors/subscription.d.ts +12 -0
  76. package/dist/errors/subscription.js +8 -0
  77. package/dist/errors/workflow.d.ts +28 -0
  78. package/dist/errors/workflow.js +17 -0
  79. package/dist/handles/actors.d.ts +17 -0
  80. package/dist/handles/actors.js +7 -0
  81. package/dist/handles/content.d.ts +59 -0
  82. package/dist/handles/content.js +36 -0
  83. package/dist/handles/intents.d.ts +164 -0
  84. package/dist/handles/intents.js +214 -0
  85. package/dist/handles/run.d.ts +31 -0
  86. package/dist/handles/run.js +21 -0
  87. package/dist/handles/workflow.d.ts +27 -0
  88. package/dist/handles/workflow.js +23 -0
  89. package/dist/identity/caller.d.ts +105 -0
  90. package/dist/identity/caller.js +68 -0
  91. package/dist/identity/child.d.ts +18 -0
  92. package/dist/identity/child.js +39 -0
  93. package/dist/identity/command.d.ts +19 -0
  94. package/dist/identity/command.js +21 -0
  95. package/dist/identity/connection.d.ts +24 -0
  96. package/dist/identity/connection.js +29 -0
  97. package/dist/identity/content.d.ts +18 -0
  98. package/dist/identity/content.js +12 -0
  99. package/dist/identity/digest.d.ts +4 -0
  100. package/dist/identity/digest.js +5 -0
  101. package/dist/identity/execution.d.ts +32 -0
  102. package/dist/identity/execution.js +63 -0
  103. package/dist/identity/mint.d.ts +51 -0
  104. package/dist/identity/mint.js +76 -0
  105. package/dist/identity/version.d.ts +2 -0
  106. package/dist/identity/version.js +3 -0
  107. package/dist/index.d.ts +159 -0
  108. package/dist/index.js +97 -0
  109. package/dist/members/blob.d.ts +43 -0
  110. package/dist/members/blob.js +29 -0
  111. package/dist/members/command.d.ts +109 -0
  112. package/dist/members/command.js +61 -0
  113. package/dist/members/connection.d.ts +55 -0
  114. package/dist/members/connection.js +49 -0
  115. package/dist/members/event.d.ts +36 -0
  116. package/dist/members/event.js +24 -0
  117. package/dist/members/job.d.ts +157 -0
  118. package/dist/members/job.js +67 -0
  119. package/dist/members/payload.d.ts +93 -0
  120. package/dist/members/payload.js +145 -0
  121. package/dist/members/reducer.d.ts +64 -0
  122. package/dist/members/reducer.js +27 -0
  123. package/dist/members/stream.d.ts +36 -0
  124. package/dist/members/stream.js +14 -0
  125. package/dist/members/subscription.d.ts +182 -0
  126. package/dist/members/subscription.js +91 -0
  127. package/dist/members/workflow.d.ts +99 -0
  128. package/dist/members/workflow.js +2 -0
  129. package/dist/policies/access.d.ts +35 -0
  130. package/dist/policies/access.js +6 -0
  131. package/dist/policies/command.d.ts +127 -0
  132. package/dist/policies/command.js +45 -0
  133. package/dist/policies/job.d.ts +28 -0
  134. package/dist/policies/job.js +60 -0
  135. package/dist/policies/schedules.d.ts +33 -0
  136. package/dist/policies/schedules.js +131 -0
  137. package/dist/protocol/frames.d.ts +66 -0
  138. package/dist/protocol/frames.js +55 -0
  139. package/dist/protocol/inspection.d.ts +807 -0
  140. package/dist/protocol/inspection.js +243 -0
  141. package/dist/protocol/wire.d.ts +184 -0
  142. package/dist/protocol/wire.js +150 -0
  143. package/dist/runtime/actors.d.ts +155 -0
  144. package/dist/runtime/actors.js +4 -0
  145. package/dist/runtime/admission.d.ts +34 -0
  146. package/dist/runtime/admission.js +72 -0
  147. package/dist/runtime/adoption/backfill.d.ts +27 -0
  148. package/dist/runtime/adoption/backfill.js +144 -0
  149. package/dist/runtime/adoption/enforce.d.ts +55 -0
  150. package/dist/runtime/adoption/enforce.js +241 -0
  151. package/dist/runtime/adoption/observe.d.ts +43 -0
  152. package/dist/runtime/adoption/observe.js +139 -0
  153. package/dist/runtime/adoption/plan.d.ts +45 -0
  154. package/dist/runtime/adoption/plan.js +192 -0
  155. package/dist/runtime/adoption/startup.d.ts +32 -0
  156. package/dist/runtime/adoption/startup.js +76 -0
  157. package/dist/runtime/adoption/status.d.ts +23 -0
  158. package/dist/runtime/adoption/status.js +47 -0
  159. package/dist/runtime/adoption/target.d.ts +33 -0
  160. package/dist/runtime/adoption/target.js +49 -0
  161. package/dist/runtime/connections/holder.d.ts +221 -0
  162. package/dist/runtime/connections/holder.js +816 -0
  163. package/dist/runtime/connections/owner.d.ts +263 -0
  164. package/dist/runtime/connections/owner.js +896 -0
  165. package/dist/runtime/connections/protocol.d.ts +441 -0
  166. package/dist/runtime/connections/protocol.js +222 -0
  167. package/dist/runtime/connections/reads.d.ts +24 -0
  168. package/dist/runtime/connections/reads.js +19 -0
  169. package/dist/runtime/connections/streams.d.ts +62 -0
  170. package/dist/runtime/connections/streams.js +128 -0
  171. package/dist/runtime/connections/transport.d.ts +40 -0
  172. package/dist/runtime/connections/transport.js +68 -0
  173. package/dist/runtime/connections/watch.d.ts +52 -0
  174. package/dist/runtime/connections/watch.js +159 -0
  175. package/dist/runtime/content/grant.d.ts +34 -0
  176. package/dist/runtime/content/grant.js +58 -0
  177. package/dist/runtime/content/store.d.ts +63 -0
  178. package/dist/runtime/content/store.js +294 -0
  179. package/dist/runtime/cron/key.d.ts +2 -0
  180. package/dist/runtime/cron/key.js +2 -0
  181. package/dist/runtime/cron/schedule.d.ts +69 -0
  182. package/dist/runtime/cron/schedule.js +144 -0
  183. package/dist/runtime/database/bounded.d.ts +43 -0
  184. package/dist/runtime/database/bounded.js +108 -0
  185. package/dist/runtime/database/connection.d.ts +8 -0
  186. package/dist/runtime/database/connection.js +18 -0
  187. package/dist/runtime/database/coordination.d.ts +19 -0
  188. package/dist/runtime/database/coordination.js +72 -0
  189. package/dist/runtime/database/flock.d.ts +10 -0
  190. package/dist/runtime/database/flock.js +60 -0
  191. package/dist/runtime/database/gate.d.ts +26 -0
  192. package/dist/runtime/database/gate.js +54 -0
  193. package/dist/runtime/database/keepalive.d.ts +11 -0
  194. package/dist/runtime/database/keepalive.js +22 -0
  195. package/dist/runtime/database/migrations.d.ts +177 -0
  196. package/dist/runtime/database/migrations.js +1018 -0
  197. package/dist/runtime/database/neki/migrations.d.ts +31 -0
  198. package/dist/runtime/database/neki/migrations.js +276 -0
  199. package/dist/runtime/database/neki/session.d.ts +23 -0
  200. package/dist/runtime/database/neki/session.js +31 -0
  201. package/dist/runtime/database/pglite.d.ts +21 -0
  202. package/dist/runtime/database/pglite.js +74 -0
  203. package/dist/runtime/database/replica.d.ts +41 -0
  204. package/dist/runtime/database/replica.js +51 -0
  205. package/dist/runtime/database/shards.d.ts +21 -0
  206. package/dist/runtime/database/shards.js +37 -0
  207. package/dist/runtime/database/snapshot.d.ts +7 -0
  208. package/dist/runtime/database/snapshot.js +7 -0
  209. package/dist/runtime/database/tenancy.d.ts +69 -0
  210. package/dist/runtime/database/tenancy.js +145 -0
  211. package/dist/runtime/database/transient.d.ts +10 -0
  212. package/dist/runtime/database/transient.js +25 -0
  213. package/dist/runtime/drain.d.ts +132 -0
  214. package/dist/runtime/drain.js +109 -0
  215. package/dist/runtime/entity/mailbox.d.ts +86 -0
  216. package/dist/runtime/entity/mailbox.js +121 -0
  217. package/dist/runtime/entity/register.d.ts +424 -0
  218. package/dist/runtime/entity/register.js +669 -0
  219. package/dist/runtime/events/append.d.ts +192 -0
  220. package/dist/runtime/events/append.js +128 -0
  221. package/dist/runtime/events/cursor.d.ts +2 -0
  222. package/dist/runtime/events/cursor.js +5 -0
  223. package/dist/runtime/events/replay.d.ts +20 -0
  224. package/dist/runtime/events/replay.js +45 -0
  225. package/dist/runtime/feeds.d.ts +26 -0
  226. package/dist/runtime/feeds.js +100 -0
  227. package/dist/runtime/fleet/checks.d.ts +17 -0
  228. package/dist/runtime/fleet/checks.js +106 -0
  229. package/dist/runtime/fleet/maintainer.d.ts +38 -0
  230. package/dist/runtime/fleet/maintainer.js +383 -0
  231. package/dist/runtime/fleet/pgoutput.d.ts +41 -0
  232. package/dist/runtime/fleet/pgoutput.js +102 -0
  233. package/dist/runtime/fleet/setup.d.ts +36 -0
  234. package/dist/runtime/fleet/setup.js +58 -0
  235. package/dist/runtime/fleet/subscribe.d.ts +42 -0
  236. package/dist/runtime/fleet/subscribe.js +147 -0
  237. package/dist/runtime/index.d.ts +66 -0
  238. package/dist/runtime/index.js +37 -0
  239. package/dist/runtime/inspector/http.d.ts +19 -0
  240. package/dist/runtime/inspector/http.js +36 -0
  241. package/dist/runtime/inspector/layer.d.ts +46 -0
  242. package/dist/runtime/inspector/layer.js +180 -0
  243. package/dist/runtime/inspector/queries.d.ts +711 -0
  244. package/dist/runtime/inspector/queries.js +494 -0
  245. package/dist/runtime/jobs/attempt.d.ts +254 -0
  246. package/dist/runtime/jobs/attempt.js +413 -0
  247. package/dist/runtime/jobs/isolation.d.ts +20 -0
  248. package/dist/runtime/jobs/isolation.js +10 -0
  249. package/dist/runtime/jobs/progress.d.ts +95 -0
  250. package/dist/runtime/jobs/progress.js +144 -0
  251. package/dist/runtime/layer.d.ts +260 -0
  252. package/dist/runtime/layer.js +876 -0
  253. package/dist/runtime/members.d.ts +381 -0
  254. package/dist/runtime/members.js +8 -0
  255. package/dist/runtime/operators/audit.d.ts +64 -0
  256. package/dist/runtime/operators/audit.js +56 -0
  257. package/dist/runtime/operators/auth.d.ts +29 -0
  258. package/dist/runtime/operators/auth.js +42 -0
  259. package/dist/runtime/operators/export.d.ts +68 -0
  260. package/dist/runtime/operators/export.js +137 -0
  261. package/dist/runtime/operators/grants.d.ts +45 -0
  262. package/dist/runtime/operators/grants.js +40 -0
  263. package/dist/runtime/operators/repair.d.ts +206 -0
  264. package/dist/runtime/operators/repair.js +226 -0
  265. package/dist/runtime/operators/routes.d.ts +35 -0
  266. package/dist/runtime/operators/routes.js +190 -0
  267. package/dist/runtime/operators/seed.d.ts +123 -0
  268. package/dist/runtime/operators/seed.js +123 -0
  269. package/dist/runtime/payloads/versions.d.ts +65 -0
  270. package/dist/runtime/payloads/versions.js +240 -0
  271. package/dist/runtime/peering/authority.d.ts +42 -0
  272. package/dist/runtime/peering/authority.js +132 -0
  273. package/dist/runtime/peering/credentials.d.ts +21 -0
  274. package/dist/runtime/peering/credentials.js +13 -0
  275. package/dist/runtime/peering/transport.d.ts +51 -0
  276. package/dist/runtime/peering/transport.js +175 -0
  277. package/dist/runtime/queries.d.ts +18 -0
  278. package/dist/runtime/queries.js +169 -0
  279. package/dist/runtime/readiness.d.ts +36 -0
  280. package/dist/runtime/readiness.js +44 -0
  281. package/dist/runtime/registration.d.ts +58 -0
  282. package/dist/runtime/registration.js +186 -0
  283. package/dist/runtime/request.d.ts +158 -0
  284. package/dist/runtime/request.js +102 -0
  285. package/dist/runtime/retry.d.ts +8 -0
  286. package/dist/runtime/retry.js +11 -0
  287. package/dist/runtime/runner.d.ts +93 -0
  288. package/dist/runtime/runner.js +122 -0
  289. package/dist/runtime/storage/codec.d.ts +39 -0
  290. package/dist/runtime/storage/codec.js +41 -0
  291. package/dist/runtime/storage/generation.d.ts +69 -0
  292. package/dist/runtime/storage/generation.js +49 -0
  293. package/dist/runtime/storage/placements.d.ts +15 -0
  294. package/dist/runtime/storage/placements.js +38 -0
  295. package/dist/runtime/storage/platform.d.ts +6 -0
  296. package/dist/runtime/storage/platform.js +9 -0
  297. package/dist/runtime/storage/retention.d.ts +73 -0
  298. package/dist/runtime/storage/retention.js +158 -0
  299. package/dist/runtime/subscriptions/identity.d.ts +31 -0
  300. package/dist/runtime/subscriptions/identity.js +45 -0
  301. package/dist/runtime/subscriptions/relay.d.ts +175 -0
  302. package/dist/runtime/subscriptions/relay.js +763 -0
  303. package/dist/runtime/subscriptions/storage.d.ts +40 -0
  304. package/dist/runtime/subscriptions/storage.js +98 -0
  305. package/dist/runtime/sweeps.d.ts +39 -0
  306. package/dist/runtime/sweeps.js +54 -0
  307. package/dist/runtime/telemetry/defects.d.ts +57 -0
  308. package/dist/runtime/telemetry/defects.js +43 -0
  309. package/dist/runtime/telemetry/metrics.d.ts +52 -0
  310. package/dist/runtime/telemetry/metrics.js +138 -0
  311. package/dist/runtime/telemetry/routes.d.ts +19 -0
  312. package/dist/runtime/telemetry/routes.js +18 -0
  313. package/dist/runtime/telemetry/sampler.d.ts +26 -0
  314. package/dist/runtime/telemetry/sampler.js +101 -0
  315. package/dist/runtime/telemetry/spans.d.ts +38 -0
  316. package/dist/runtime/telemetry/spans.js +44 -0
  317. package/dist/runtime/telemetry/usage.d.ts +52 -0
  318. package/dist/runtime/telemetry/usage.js +30 -0
  319. package/dist/runtime/topology/admission.d.ts +13 -0
  320. package/dist/runtime/topology/admission.js +36 -0
  321. package/dist/runtime/topology/locks.d.ts +56 -0
  322. package/dist/runtime/topology/locks.js +81 -0
  323. package/dist/runtime/topology/messages.d.ts +15 -0
  324. package/dist/runtime/topology/messages.js +32 -0
  325. package/dist/runtime/turn/admission.d.ts +22 -0
  326. package/dist/runtime/turn/admission.js +41 -0
  327. package/dist/runtime/turn/blobs.d.ts +38 -0
  328. package/dist/runtime/turn/blobs.js +215 -0
  329. package/dist/runtime/turn/execute.d.ts +208 -0
  330. package/dist/runtime/turn/execute.js +972 -0
  331. package/dist/runtime/turn/group.d.ts +165 -0
  332. package/dist/runtime/turn/group.js +326 -0
  333. package/dist/runtime/turn/hooks.d.ts +44 -0
  334. package/dist/runtime/turn/hooks.js +28 -0
  335. package/dist/runtime/turn/outbox.d.ts +159 -0
  336. package/dist/runtime/turn/outbox.js +269 -0
  337. package/dist/runtime/turn/pipeline.d.ts +68 -0
  338. package/dist/runtime/turn/pipeline.js +83 -0
  339. package/dist/runtime/turn/receipt.d.ts +81 -0
  340. package/dist/runtime/turn/receipt.js +32 -0
  341. package/dist/runtime/turn/relay.d.ts +179 -0
  342. package/dist/runtime/turn/relay.js +685 -0
  343. package/dist/runtime/turn/rows.d.ts +43 -0
  344. package/dist/runtime/turn/rows.js +592 -0
  345. package/dist/runtime/workflows/compatibility.d.ts +125 -0
  346. package/dist/runtime/workflows/compatibility.js +285 -0
  347. package/dist/runtime/workflows/engine.d.ts +107 -0
  348. package/dist/runtime/workflows/engine.js +826 -0
  349. package/dist/runtime/workflows/manifest.d.ts +34 -0
  350. package/dist/runtime/workflows/manifest.js +39 -0
  351. package/dist/runtime/workflows/steps.d.ts +33 -0
  352. package/dist/runtime/workflows/steps.js +152 -0
  353. package/dist/serve/api.d.ts +99 -0
  354. package/dist/serve/api.js +403 -0
  355. package/dist/serve/assertion/binding.d.ts +41 -0
  356. package/dist/serve/assertion/binding.js +92 -0
  357. package/dist/serve/assertion/verify.d.ts +93 -0
  358. package/dist/serve/assertion/verify.js +189 -0
  359. package/dist/serve/auth.d.ts +200 -0
  360. package/dist/serve/auth.js +92 -0
  361. package/dist/serve/clock.d.ts +10 -0
  362. package/dist/serve/clock.js +25 -0
  363. package/dist/serve/jwt.d.ts +65 -0
  364. package/dist/serve/jwt.js +202 -0
  365. package/dist/serve/layer.d.ts +98 -0
  366. package/dist/serve/layer.js +809 -0
  367. package/dist/serve/mcp/endpoint.d.ts +39 -0
  368. package/dist/serve/mcp/endpoint.js +187 -0
  369. package/dist/serve/mcp/tools.d.ts +37 -0
  370. package/dist/serve/mcp/tools.js +125 -0
  371. package/dist/serve/origin.d.ts +6 -0
  372. package/dist/serve/origin.js +21 -0
  373. package/dist/serve/sessions/feed.d.ts +79 -0
  374. package/dist/serve/sessions/feed.js +115 -0
  375. package/dist/serve/sessions/socket.d.ts +56 -0
  376. package/dist/serve/sessions/socket.js +212 -0
  377. package/dist/serve/sessions/sse.d.ts +27 -0
  378. package/dist/serve/sessions/sse.js +26 -0
  379. package/dist/serve/sessions/stream.d.ts +9 -0
  380. package/dist/serve/sessions/stream.js +9 -0
  381. package/dist/serve/sessions/watch.d.ts +12 -0
  382. package/dist/serve/sessions/watch.js +11 -0
  383. package/dist/serve/wire.d.ts +16 -0
  384. package/dist/serve/wire.js +50 -0
  385. package/dist/state/blob.d.ts +71 -0
  386. package/dist/state/blob.js +0 -0
  387. package/dist/state/migration.d.ts +53 -0
  388. package/dist/state/migration.js +29 -0
  389. package/dist/tables/fleet.d.ts +170 -0
  390. package/dist/tables/fleet.js +214 -0
  391. package/dist/tables/owned.d.ts +250 -0
  392. package/dist/tables/owned.js +233 -0
  393. package/dist/testing/actor-test.d.ts +360 -0
  394. package/dist/testing/actor-test.js +337 -0
  395. package/dist/testing/cluster.d.ts +93 -0
  396. package/dist/testing/cluster.js +296 -0
  397. package/dist/testing/conformance/access.d.ts +5 -0
  398. package/dist/testing/conformance/access.js +531 -0
  399. package/dist/testing/conformance/admission.d.ts +11 -0
  400. package/dist/testing/conformance/admission.js +182 -0
  401. package/dist/testing/conformance/adoption.d.ts +2 -0
  402. package/dist/testing/conformance/adoption.js +1019 -0
  403. package/dist/testing/conformance/assertions.d.ts +202 -0
  404. package/dist/testing/conformance/assertions.js +849 -0
  405. package/dist/testing/conformance/batches.d.ts +41 -0
  406. package/dist/testing/conformance/batches.js +388 -0
  407. package/dist/testing/conformance/blobs.d.ts +14 -0
  408. package/dist/testing/conformance/blobs.js +405 -0
  409. package/dist/testing/conformance/capacity.d.ts +8 -0
  410. package/dist/testing/conformance/capacity.js +433 -0
  411. package/dist/testing/conformance/client.d.ts +5 -0
  412. package/dist/testing/conformance/client.js +719 -0
  413. package/dist/testing/conformance/cold-serve.d.ts +16 -0
  414. package/dist/testing/conformance/cold-serve.js +254 -0
  415. package/dist/testing/conformance/connections/actors.d.ts +1143 -0
  416. package/dist/testing/conformance/connections/actors.js +180 -0
  417. package/dist/testing/conformance/connections/harness.d.ts +1754 -0
  418. package/dist/testing/conformance/connections/harness.js +142 -0
  419. package/dist/testing/conformance/connections/holders.d.ts +4 -0
  420. package/dist/testing/conformance/connections/holders.js +165 -0
  421. package/dist/testing/conformance/connections/lifecycle.d.ts +4 -0
  422. package/dist/testing/conformance/connections/lifecycle.js +113 -0
  423. package/dist/testing/conformance/connections/limits.d.ts +4 -0
  424. package/dist/testing/conformance/connections/limits.js +127 -0
  425. package/dist/testing/conformance/connections/reauthorization.d.ts +4 -0
  426. package/dist/testing/conformance/connections/reauthorization.js +170 -0
  427. package/dist/testing/conformance/connections/resync.d.ts +4 -0
  428. package/dist/testing/conformance/connections/resync.js +360 -0
  429. package/dist/testing/conformance/connections/takeover.d.ts +4 -0
  430. package/dist/testing/conformance/connections/takeover.js +287 -0
  431. package/dist/testing/conformance/connections.d.ts +4 -0
  432. package/dist/testing/conformance/connections.js +15 -0
  433. package/dist/testing/conformance/content-blobs.d.ts +16 -0
  434. package/dist/testing/conformance/content-blobs.js +534 -0
  435. package/dist/testing/conformance/counter.d.ts +16 -0
  436. package/dist/testing/conformance/counter.js +813 -0
  437. package/dist/testing/conformance/cron.d.ts +5 -0
  438. package/dist/testing/conformance/cron.js +665 -0
  439. package/dist/testing/conformance/drain.d.ts +26 -0
  440. package/dist/testing/conformance/drain.js +540 -0
  441. package/dist/testing/conformance/effect-control.d.ts +38 -0
  442. package/dist/testing/conformance/effect-control.js +1059 -0
  443. package/dist/testing/conformance/effects.d.ts +23 -0
  444. package/dist/testing/conformance/effects.js +432 -0
  445. package/dist/testing/conformance/events.d.ts +28 -0
  446. package/dist/testing/conformance/events.js +335 -0
  447. package/dist/testing/conformance/export.d.ts +2 -0
  448. package/dist/testing/conformance/export.js +368 -0
  449. package/dist/testing/conformance/fleet.d.ts +444 -0
  450. package/dist/testing/conformance/fleet.js +1009 -0
  451. package/dist/testing/conformance/groups.d.ts +7 -0
  452. package/dist/testing/conformance/groups.js +353 -0
  453. package/dist/testing/conformance/heap.d.ts +3 -0
  454. package/dist/testing/conformance/heap.js +149 -0
  455. package/dist/testing/conformance/http.d.ts +2809 -0
  456. package/dist/testing/conformance/http.js +1234 -0
  457. package/dist/testing/conformance/inspection-views.d.ts +8 -0
  458. package/dist/testing/conformance/inspection-views.js +272 -0
  459. package/dist/testing/conformance/inspector.d.ts +7 -0
  460. package/dist/testing/conformance/inspector.js +650 -0
  461. package/dist/testing/conformance/mint.d.ts +58 -0
  462. package/dist/testing/conformance/mint.js +692 -0
  463. package/dist/testing/conformance/multi-runner.d.ts +8 -0
  464. package/dist/testing/conformance/multi-runner.js +403 -0
  465. package/dist/testing/conformance/neki/plan.d.ts +19 -0
  466. package/dist/testing/conformance/neki/plan.js +30 -0
  467. package/dist/testing/conformance/observability.d.ts +3 -0
  468. package/dist/testing/conformance/observability.js +343 -0
  469. package/dist/testing/conformance/offline.d.ts +4 -0
  470. package/dist/testing/conformance/offline.js +474 -0
  471. package/dist/testing/conformance/operator-harness.d.ts +57 -0
  472. package/dist/testing/conformance/operator-harness.js +78 -0
  473. package/dist/testing/conformance/operator.d.ts +3 -0
  474. package/dist/testing/conformance/operator.js +379 -0
  475. package/dist/testing/conformance/outbox-cross-shard.d.ts +14 -0
  476. package/dist/testing/conformance/outbox-cross-shard.js +160 -0
  477. package/dist/testing/conformance/outbox.d.ts +36 -0
  478. package/dist/testing/conformance/outbox.js +437 -0
  479. package/dist/testing/conformance/payload-migrations.d.ts +3 -0
  480. package/dist/testing/conformance/payload-migrations.js +612 -0
  481. package/dist/testing/conformance/pipeline.d.ts +3 -0
  482. package/dist/testing/conformance/pipeline.js +1040 -0
  483. package/dist/testing/conformance/placement.d.ts +22 -0
  484. package/dist/testing/conformance/placement.js +539 -0
  485. package/dist/testing/conformance/platform.d.ts +40 -0
  486. package/dist/testing/conformance/platform.js +101 -0
  487. package/dist/testing/conformance/progress.d.ts +39 -0
  488. package/dist/testing/conformance/progress.js +666 -0
  489. package/dist/testing/conformance/properties.d.ts +6 -0
  490. package/dist/testing/conformance/properties.js +295 -0
  491. package/dist/testing/conformance/protocols.d.ts +4 -0
  492. package/dist/testing/conformance/protocols.js +618 -0
  493. package/dist/testing/conformance/provider/advertise.d.ts +21 -0
  494. package/dist/testing/conformance/provider/advertise.js +44 -0
  495. package/dist/testing/conformance/read-your-writes.d.ts +20 -0
  496. package/dist/testing/conformance/read-your-writes.js +192 -0
  497. package/dist/testing/conformance/reducers.d.ts +8 -0
  498. package/dist/testing/conformance/reducers.js +258 -0
  499. package/dist/testing/conformance/relay.d.ts +42 -0
  500. package/dist/testing/conformance/relay.js +1115 -0
  501. package/dist/testing/conformance/restore.d.ts +43 -0
  502. package/dist/testing/conformance/restore.js +341 -0
  503. package/dist/testing/conformance/retention.d.ts +14 -0
  504. package/dist/testing/conformance/retention.js +463 -0
  505. package/dist/testing/conformance/rls.d.ts +24 -0
  506. package/dist/testing/conformance/rls.js +576 -0
  507. package/dist/testing/conformance/simulation.d.ts +31 -0
  508. package/dist/testing/conformance/simulation.js +167 -0
  509. package/dist/testing/conformance/single-shard.d.ts +2 -0
  510. package/dist/testing/conformance/single-shard.js +125 -0
  511. package/dist/testing/conformance/singleton.d.ts +3 -0
  512. package/dist/testing/conformance/singleton.js +293 -0
  513. package/dist/testing/conformance/statements.d.ts +60 -0
  514. package/dist/testing/conformance/statements.js +108 -0
  515. package/dist/testing/conformance/streams.d.ts +7 -0
  516. package/dist/testing/conformance/streams.js +280 -0
  517. package/dist/testing/conformance/subscriptions/access.d.ts +4 -0
  518. package/dist/testing/conformance/subscriptions/access.js +98 -0
  519. package/dist/testing/conformance/subscriptions/actors.d.ts +4910 -0
  520. package/dist/testing/conformance/subscriptions/actors.js +372 -0
  521. package/dist/testing/conformance/subscriptions/cluster.d.ts +4 -0
  522. package/dist/testing/conformance/subscriptions/cluster.js +89 -0
  523. package/dist/testing/conformance/subscriptions/delivery.d.ts +4 -0
  524. package/dist/testing/conformance/subscriptions/delivery.js +253 -0
  525. package/dist/testing/conformance/subscriptions/deploys.d.ts +4 -0
  526. package/dist/testing/conformance/subscriptions/deploys.js +162 -0
  527. package/dist/testing/conformance/subscriptions/epochs.d.ts +4 -0
  528. package/dist/testing/conformance/subscriptions/epochs.js +169 -0
  529. package/dist/testing/conformance/subscriptions/failures.d.ts +4 -0
  530. package/dist/testing/conformance/subscriptions/failures.js +108 -0
  531. package/dist/testing/conformance/subscriptions/feeds.d.ts +4 -0
  532. package/dist/testing/conformance/subscriptions/feeds.js +218 -0
  533. package/dist/testing/conformance/subscriptions/harness.d.ts +124 -0
  534. package/dist/testing/conformance/subscriptions/harness.js +143 -0
  535. package/dist/testing/conformance/subscriptions/operator.d.ts +4 -0
  536. package/dist/testing/conformance/subscriptions/operator.js +128 -0
  537. package/dist/testing/conformance/subscriptions/retention.d.ts +4 -0
  538. package/dist/testing/conformance/subscriptions/retention.js +288 -0
  539. package/dist/testing/conformance/subscriptions/routing.d.ts +4 -0
  540. package/dist/testing/conformance/subscriptions/routing.js +179 -0
  541. package/dist/testing/conformance/subscriptions.d.ts +4 -0
  542. package/dist/testing/conformance/subscriptions.js +19 -0
  543. package/dist/testing/conformance/tables.d.ts +125 -0
  544. package/dist/testing/conformance/tables.js +664 -0
  545. package/dist/testing/conformance/transports/actors.d.ts +1907 -0
  546. package/dist/testing/conformance/transports/actors.js +163 -0
  547. package/dist/testing/conformance/transports/client.d.ts +3 -0
  548. package/dist/testing/conformance/transports/client.js +237 -0
  549. package/dist/testing/conformance/transports/feeds.d.ts +3 -0
  550. package/dist/testing/conformance/transports/feeds.js +232 -0
  551. package/dist/testing/conformance/transports/harness.d.ts +93 -0
  552. package/dist/testing/conformance/transports/harness.js +84 -0
  553. package/dist/testing/conformance/transports/streams.d.ts +3 -0
  554. package/dist/testing/conformance/transports/streams.js +96 -0
  555. package/dist/testing/conformance/transports/websocket.d.ts +3 -0
  556. package/dist/testing/conformance/transports/websocket.js +384 -0
  557. package/dist/testing/conformance/transports/wire.d.ts +141 -0
  558. package/dist/testing/conformance/transports/wire.js +204 -0
  559. package/dist/testing/conformance/transports.d.ts +3 -0
  560. package/dist/testing/conformance/transports.js +11 -0
  561. package/dist/testing/conformance/watch.d.ts +59 -0
  562. package/dist/testing/conformance/watch.js +879 -0
  563. package/dist/testing/conformance/workflow-engine.d.ts +97 -0
  564. package/dist/testing/conformance/workflow-engine.js +253 -0
  565. package/dist/testing/conformance/workflow-versions.d.ts +3 -0
  566. package/dist/testing/conformance/workflow-versions.js +545 -0
  567. package/dist/testing/conformance/workflows/access.d.ts +4 -0
  568. package/dist/testing/conformance/workflows/access.js +147 -0
  569. package/dist/testing/conformance/workflows/actors.d.ts +2317 -0
  570. package/dist/testing/conformance/workflows/actors.js +305 -0
  571. package/dist/testing/conformance/workflows/basics.d.ts +4 -0
  572. package/dist/testing/conformance/workflows/basics.js +144 -0
  573. package/dist/testing/conformance/workflows/engine.d.ts +4 -0
  574. package/dist/testing/conformance/workflows/engine.js +80 -0
  575. package/dist/testing/conformance/workflows/guards.d.ts +4 -0
  576. package/dist/testing/conformance/workflows/guards.js +172 -0
  577. package/dist/testing/conformance/workflows/harness.d.ts +14 -0
  578. package/dist/testing/conformance/workflows/harness.js +44 -0
  579. package/dist/testing/conformance/workflows/recovery.d.ts +4 -0
  580. package/dist/testing/conformance/workflows/recovery.js +181 -0
  581. package/dist/testing/conformance/workflows/starts.d.ts +4 -0
  582. package/dist/testing/conformance/workflows/starts.js +57 -0
  583. package/dist/testing/conformance/workflows/suspension.d.ts +4 -0
  584. package/dist/testing/conformance/workflows/suspension.js +106 -0
  585. package/dist/testing/conformance/workflows/waits.d.ts +4 -0
  586. package/dist/testing/conformance/workflows/waits.js +284 -0
  587. package/dist/testing/conformance/workflows.d.ts +4 -0
  588. package/dist/testing/conformance/workflows.js +19 -0
  589. package/dist/testing/conformance.d.ts +330 -0
  590. package/dist/testing/conformance.js +364 -0
  591. package/dist/testing/database.d.ts +31 -0
  592. package/dist/testing/database.js +70 -0
  593. package/dist/testing/foundation.d.ts +41 -0
  594. package/dist/testing/foundation.js +517 -0
  595. package/dist/testing/index.d.ts +20 -0
  596. package/dist/testing/index.js +12 -0
  597. package/dist/testing/property.d.ts +40 -0
  598. package/dist/testing/property.js +95 -0
  599. package/dist/testing/simulate-cluster.d.ts +112 -0
  600. package/dist/testing/simulate-cluster.js +257 -0
  601. package/dist/testing/simulate.d.ts +90 -0
  602. package/dist/testing/simulate.js +127 -0
  603. package/package.json +1 -0
@@ -0,0 +1,159 @@
1
+ import { Context, Crypto, Effect, Schema } from "effect";
2
+ import { SqlClient, type SqlError, type Statement } from "effect/sql";
3
+ import type { RegisteredSubscription } from "../members.ts";
4
+ import { type StagedOutbox } from "../../handles/intents.ts";
5
+ import { type ActorRef } from "../../identity/caller.ts";
6
+ /**
7
+ * The due-work bucket: the top eight bits of `routing_key`. Every runner's
8
+ * relay probes each bucket's `(bucket, kind, due_at_ms)` index range, so actors
9
+ * with nothing due are never read.
10
+ */
11
+ export declare const bucketOf: (routingKey: bigint) => number;
12
+ /** The inclusive range of values `bucketOf` returns. */
13
+ export declare const BUCKETS: {
14
+ readonly first: -128;
15
+ readonly last: 127;
16
+ };
17
+ /**
18
+ * Runtime settings a turn needs to write intents: the deployment retry window,
19
+ * which becomes each intent's receipt horizon past its due time, and the
20
+ * relay's wake signal.
21
+ */
22
+ export declare const OutboxRuntime: Context.Reference<{
23
+ readonly retryWindowMs: number;
24
+ /** Wakes this runner's relay to claim due rows now instead of at its next poll. */
25
+ readonly wake: Effect.Effect<void>;
26
+ /** Makes this runner's running attempts check for cancellation now. */
27
+ readonly cancelled: Effect.Effect<void>;
28
+ /**
29
+ * Routed subscriptions registered on this runner whose source is
30
+ * `sourceType`, with their subscriber type; a publishing turn inserts their
31
+ * missing source-side rows.
32
+ */
33
+ readonly routed: (sourceType: string) => ReadonlyArray<RegisteredSubscription & {
34
+ readonly subscriberType: string;
35
+ }>;
36
+ }>;
37
+ /** A `text[]` expression of `values`, each bound as its own text parameter so every driver binds it alike. */
38
+ export declare const textArray: ({ sql, values, }: {
39
+ readonly sql: SqlClient.SqlClient;
40
+ readonly values: ReadonlyArray<string>;
41
+ }) => Statement.Statement<import("effect/sql/SqlConnection").Row>;
42
+ /** Codec between a string array and its JSON text. */
43
+ export declare const StringsJson: Schema.fromJsonString<Schema.$Array<Schema.String>>;
44
+ /** The payload of a `control` row: the registration change a subscribing turn stages for the relay to apply at the source. */
45
+ export declare const ControlPayload: Schema.fromJsonString<Schema.Struct<{
46
+ readonly op: Schema.Literals<readonly ["subscribe", "remove"]>;
47
+ readonly epoch: Schema.String;
48
+ /** Where a subscribe starts: `"now"`, `"start"`, or an exclusive cursor. */
49
+ readonly start: Schema.String;
50
+ readonly events: Schema.$Array<Schema.String>;
51
+ }>>;
52
+ /** Codec between a `Caller` and the JSON text stored in an outbox row's `caller` column. */
53
+ export declare const CallerJson: Schema.fromJsonString<Schema.toTaggedUnion<"_tag", readonly [Schema.TaggedStruct<"User", {
54
+ readonly subject: Schema.NonEmptyString;
55
+ }>, Schema.TaggedStruct<"Anonymous", {}>, Schema.TaggedStruct<"System", {
56
+ readonly source: Schema.Literals<readonly ["process", "actor", "timer", "cron", "workflow", "job", "subscription"]>;
57
+ readonly ref: Schema.optional<Schema.Struct<{
58
+ readonly tenant: Schema.NonEmptyString;
59
+ readonly actor: Schema.NonEmptyString;
60
+ readonly id: Schema.NonEmptyString;
61
+ }>>;
62
+ readonly onBehalfOf: Schema.optional<Schema.Struct<{
63
+ readonly subject: Schema.NonEmptyString;
64
+ }>>;
65
+ readonly mint: Schema.optional<Schema.Struct<{
66
+ readonly commandId: Schema.String;
67
+ readonly ordinal: Schema.Int;
68
+ }>>;
69
+ }>]>>;
70
+ /** What the relay needs to hear once a turn's outbox writes commit; filled in as the statements reply. */
71
+ export interface OutboxReplies {
72
+ /** Some row is due now, so the relay should wake. */
73
+ wake: boolean;
74
+ /** The turn cancelled a job attempt that is running. */
75
+ cancelled: boolean;
76
+ /** Started jobs the turn cancelled; their owner stops showing their progress. */
77
+ cancelledIds: Array<string>;
78
+ }
79
+ /**
80
+ * The statements that write one turn's intents, jobs, and subscription
81
+ * changes inside its transaction, and the job ids of the new job rows in
82
+ * `outbox.jobs` order. In order they: delete committed rows whose keys the
83
+ * turn replaced; cancel committed jobs whose keys it cancelled or enqueued
84
+ * again; insert the staged rows; upsert each subscription's cursor row and
85
+ * stage its control row; shift delayed rows; order capped jobs. No
86
+ * statement takes a parameter from another's reply, so they can be sent as one
87
+ * group; `replies` is complete once every statement has replied.
88
+ *
89
+ * `databaseNow` is the time due times are measured from; it is read only when
90
+ * there are rows to insert. When it was read before the handler ran, `commit`
91
+ * moves each relative delay to the commit statement's clock by one shift, read
92
+ * once because `clock_timestamp()` changes while a statement runs, and its
93
+ * `slackMs` extends the receipt horizon of those rows over the turn's longest
94
+ * possible run.
95
+ *
96
+ * A row's id is the receiver's command id, and its expiry keeps that receipt
97
+ * at least one retry window past the due time. A job row names its job
98
+ * in `command` and targets its own actor, where its routes deliver; the relay
99
+ * runs its executor when it is due.
100
+ *
101
+ * A never-claimed cancelled job is deleted; a claim that won the row lock
102
+ * first makes that delete skip it, and the later update statement then sees it
103
+ * running. A started job keeps its row as evidence and gives up its key:
104
+ * one not running is settled by the next claim, a running one by its attempt
105
+ * or, once its lease ends, by any runner.
106
+ *
107
+ * Each subscription change moves the subscriber's cursor row to a new epoch,
108
+ * kept forever so the epoch never goes back, and stages the control row that
109
+ * carries that epoch to the source, replacing a pending earlier change for the
110
+ * same subscription and source. A `"now"` start is set by the source when the registration
111
+ * reaches it; `"start"` is cursor 0.
112
+ */
113
+ export declare const outboxStatements: <R>(routingKey: bigint, sender: {
114
+ readonly tenant: string;
115
+ readonly actor: string;
116
+ readonly id: string;
117
+ }, outbox: StagedOutbox, databaseNow: Effect.Effect<number, SqlError.SqlError, R>, commit?: {
118
+ readonly slackMs: number;
119
+ } | undefined) => Effect.Effect<{
120
+ statements: Effect.Effect<void, SqlError.SqlError, never>[];
121
+ replies: OutboxReplies;
122
+ jobIds: string[];
123
+ }, SqlError.SqlError, R | Crypto.Crypto | SqlClient.SqlClient>;
124
+ /**
125
+ * Orders a turn's capped jobs behind every earlier job of their type on
126
+ * this actor that became due no later. Claims take capped rows by
127
+ * `(ready_at_ms, intent_id)`, but the turn's clock has only millisecond
128
+ * resolution and is read before the actor's lock is taken, and job ids
129
+ * end in a random UUID: jobs enqueued in one turn, or in turns that read
130
+ * the same millisecond, would otherwise run in any order. The actor's lock
131
+ * serializes its turns, so the rows this statement reads are every earlier
132
+ * enqueue. It runs after any delay shift, so `scheduled_at_ms` is final.
133
+ *
134
+ * Within the turn, an earlier row of one job type that is due at the same
135
+ * time or no later always ends ahead of the rows after it. The latest
136
+ * `ready_at_ms` of earlier committed rows is probed twice, over rows not
137
+ * running and over running rows, each reading one partial index.
138
+ */
139
+ export declare const orderCapped: ({ sql, routingKey, sender, capped, }: {
140
+ readonly sql: SqlClient.SqlClient;
141
+ readonly routingKey: bigint;
142
+ readonly sender: ActorRef;
143
+ readonly capped: ReadonlyArray<{
144
+ readonly id: string;
145
+ readonly job: string;
146
+ readonly dueAt: number;
147
+ }>;
148
+ }) => Effect.Effect<void, SqlError.SqlError, never>;
149
+ /**
150
+ * Writes one turn's intents and jobs now, reading the database time only
151
+ * when there are rows to insert. Returns the `OutboxReplies`, so the caller can
152
+ * wake the relay after commit when a row is due and tell it about cancelled
153
+ * attempts.
154
+ */
155
+ export declare const writeOutbox: (routingKey: bigint, sender: {
156
+ readonly tenant: string;
157
+ readonly actor: string;
158
+ readonly id: string;
159
+ }, outbox: StagedOutbox) => Effect.Effect<OutboxReplies, SqlError.SqlError, Crypto.Crypto | SqlClient.SqlClient>;
@@ -0,0 +1,269 @@
1
+ import { Context, Crypto, Effect, Match, Schema } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ import { Due, jobKey } from "../../handles/intents.js";
4
+ import { Caller, System } from "../../identity/caller.js";
5
+ import { databaseTime, FrameworkClock } from "./admission.js";
6
+ /**
7
+ * The due-work bucket: the top eight bits of `routing_key`. Every runner's
8
+ * relay probes each bucket's `(bucket, kind, due_at_ms)` index range, so actors
9
+ * with nothing due are never read.
10
+ */
11
+ export const bucketOf = (routingKey) => Number(routingKey >> 56n);
12
+ /** The inclusive range of values `bucketOf` returns. */
13
+ export const BUCKETS = { first: -128, last: 127 };
14
+ /**
15
+ * Runtime settings a turn needs to write intents: the deployment retry window,
16
+ * which becomes each intent's receipt horizon past its due time, and the
17
+ * relay's wake signal.
18
+ */
19
+ export const OutboxRuntime = Context.Reference("akter/OutboxRuntime", {
20
+ defaultValue: () => ({
21
+ retryWindowMs: 86_400_000,
22
+ wake: Effect.void,
23
+ cancelled: Effect.void,
24
+ routed: () => [],
25
+ }),
26
+ });
27
+ /** A `text[]` expression of `values`, each bound as its own text parameter so every driver binds it alike. */
28
+ export const textArray = ({ sql, values, }) => sql `ARRAY[${sql.csv(values.map((value) => sql `${value}::text`))}]::text[]`;
29
+ /** Codec between a string array and its JSON text. */
30
+ export const StringsJson = Schema.fromJsonString(Schema.Array(Schema.String));
31
+ /** The payload of a `control` row: the registration change a subscribing turn stages for the relay to apply at the source. */
32
+ export const ControlPayload = Schema.fromJsonString(Schema.Struct({
33
+ op: Schema.Literals(["subscribe", "remove"]),
34
+ epoch: Schema.String,
35
+ /** Where a subscribe starts: `"now"`, `"start"`, or an exclusive cursor. */
36
+ start: Schema.String,
37
+ events: Schema.Array(Schema.String),
38
+ }));
39
+ /** The outbox key of a subscription's control row, so a later change replaces a pending one. */
40
+ const controlKey = (change) => JSON.stringify(["$sub", change.subscription, change.source.actor, change.source.id]);
41
+ /** Codec between a `Caller` and the JSON text stored in an outbox row's `caller` column. */
42
+ export const CallerJson = Schema.fromJsonString(Caller);
43
+ /**
44
+ * The statements that write one turn's intents, jobs, and subscription
45
+ * changes inside its transaction, and the job ids of the new job rows in
46
+ * `outbox.jobs` order. In order they: delete committed rows whose keys the
47
+ * turn replaced; cancel committed jobs whose keys it cancelled or enqueued
48
+ * again; insert the staged rows; upsert each subscription's cursor row and
49
+ * stage its control row; shift delayed rows; order capped jobs. No
50
+ * statement takes a parameter from another's reply, so they can be sent as one
51
+ * group; `replies` is complete once every statement has replied.
52
+ *
53
+ * `databaseNow` is the time due times are measured from; it is read only when
54
+ * there are rows to insert. When it was read before the handler ran, `commit`
55
+ * moves each relative delay to the commit statement's clock by one shift, read
56
+ * once because `clock_timestamp()` changes while a statement runs, and its
57
+ * `slackMs` extends the receipt horizon of those rows over the turn's longest
58
+ * possible run.
59
+ *
60
+ * A row's id is the receiver's command id, and its expiry keeps that receipt
61
+ * at least one retry window past the due time. A job row names its job
62
+ * in `command` and targets its own actor, where its routes deliver; the relay
63
+ * runs its executor when it is due.
64
+ *
65
+ * A never-claimed cancelled job is deleted; a claim that won the row lock
66
+ * first makes that delete skip it, and the later update statement then sees it
67
+ * running. A started job keeps its row as evidence and gives up its key:
68
+ * one not running is settled by the next claim, a running one by its attempt
69
+ * or, once its lease ends, by any runner.
70
+ *
71
+ * Each subscription change moves the subscriber's cursor row to a new epoch,
72
+ * kept forever so the epoch never goes back, and stages the control row that
73
+ * carries that epoch to the source, replacing a pending earlier change for the
74
+ * same subscription and source. A `"now"` start is set by the source when the registration
75
+ * reaches it; `"start"` is cursor 0.
76
+ */
77
+ export const outboxStatements = Effect.fnUntraced(function* (routingKey, sender, outbox, databaseNow, commit) {
78
+ const sql = yield* SqlClient.SqlClient;
79
+ const clock = yield* FrameworkClock;
80
+ const { tenant, actor, id } = sender;
81
+ const statements = [];
82
+ const replies = { wake: false, cancelled: false, cancelledIds: [] };
83
+ const actorRow = sql `routing_key = ${routingKey} AND tenant_id = ${tenant}
84
+ AND actor_type = ${actor} AND actor_id = ${id}`;
85
+ const statementNow = sql `floor(extract(epoch FROM clock_timestamp()) * 1000)::bigint + ${clock.offsetMillis()}`;
86
+ if (outbox.replaced.length > 0)
87
+ statements.push(Effect.asVoid(sql `DELETE FROM actor_outbox WHERE ${actorRow} AND timer_key IN ${sql.in(outbox.replaced)}`));
88
+ if (outbox.cancelledJobs.length > 0) {
89
+ const keys = sql.in(outbox.cancelledJobs.map(jobKey));
90
+ statements.push(Effect.asVoid(sql `DELETE FROM actor_outbox WHERE ${actorRow} AND kind = 'job'
91
+ AND timer_key IN ${keys} AND attempts = 0 AND NOT running`));
92
+ statements.push(Effect.map(sql `UPDATE actor_outbox
93
+ SET cancelled_at_ms = stamp.at, timer_key = NULL, waiting = false,
94
+ due_at_ms = CASE WHEN running THEN due_at_ms ELSE least(due_at_ms, stamp.at) END
95
+ FROM (SELECT ${statementNow} AS at) AS stamp
96
+ WHERE ${actorRow} AND kind = 'job' AND timer_key IN ${keys}
97
+ RETURNING running, intent_id`, (marked) => {
98
+ replies.cancelledIds.push(...marked.map((row) => row.intent_id));
99
+ replies.cancelled ||= marked.some((row) => row.running);
100
+ replies.wake ||= marked.some((row) => !row.running);
101
+ }));
102
+ }
103
+ if (outbox.intents.length === 0 && outbox.jobs.length === 0 && outbox.subscriptions.length === 0)
104
+ return { statements, replies, jobIds: [] };
105
+ const crypto = yield* Crypto.Crypto;
106
+ const { retryWindowMs } = yield* OutboxRuntime;
107
+ const now = yield* databaseNow;
108
+ replies.wake ||= outbox.subscriptions.length > 0;
109
+ const rows = [];
110
+ const rowId = (dueAt, slackMs = 0) => crypto.randomUUIDv4.pipe(Effect.orDie, Effect.map((uuid) => `v1.${now}.${Math.max(dueAt, now) + slackMs + retryWindowMs}.${uuid}`));
111
+ const dueOf = (due) => due === undefined
112
+ ? now
113
+ : Due.match(due, {
114
+ After: ({ millis }) => now + millis,
115
+ At: ({ epochMillis }) => epochMillis,
116
+ });
117
+ const delayed = [];
118
+ const rowIdOf = Effect.fnUntraced(function* (due, dueAt) {
119
+ const relative = commit !== undefined && due?._tag === "After";
120
+ const rowIdentity = yield* rowId(dueAt, relative ? commit.slackMs : 0);
121
+ if (relative)
122
+ delayed.push(rowIdentity);
123
+ return rowIdentity;
124
+ });
125
+ for (const intent of outbox.intents) {
126
+ const dueAt = dueOf(intent.due);
127
+ replies.wake ||= dueAt <= now;
128
+ rows.push({
129
+ routing_key: routingKey,
130
+ intent_id: yield* rowIdOf(intent.due, dueAt),
131
+ kind: "intent",
132
+ bucket: bucketOf(routingKey),
133
+ due_at_ms: dueAt,
134
+ scheduled_at_ms: dueAt,
135
+ ready_at_ms: null,
136
+ tenant_id: tenant,
137
+ actor_type: actor,
138
+ actor_id: id,
139
+ timer_key: intent.key ?? null,
140
+ target_type: intent.target.actor,
141
+ target_id: intent.target.id,
142
+ command: intent.command,
143
+ payload: intent.payload,
144
+ payload_version: 0,
145
+ caller: yield* Schema.encodeEffect(CallerJson)(intent.caller).pipe(Effect.orDie),
146
+ });
147
+ }
148
+ const capped = [];
149
+ const jobIds = [];
150
+ for (const job of outbox.jobs) {
151
+ const dueAt = dueOf(job.due);
152
+ const intentId = yield* rowIdOf(job.due, dueAt);
153
+ replies.wake ||= dueAt <= now;
154
+ if (job.capped)
155
+ capped.push({ id: intentId, job: job.job, dueAt });
156
+ jobIds.push(intentId);
157
+ rows.push({
158
+ routing_key: routingKey,
159
+ intent_id: intentId,
160
+ kind: "job",
161
+ bucket: bucketOf(routingKey),
162
+ due_at_ms: dueAt,
163
+ scheduled_at_ms: dueAt,
164
+ ready_at_ms: dueAt,
165
+ tenant_id: tenant,
166
+ actor_type: actor,
167
+ actor_id: id,
168
+ timer_key: job.key === undefined ? null : jobKey(job.key),
169
+ target_type: actor,
170
+ target_id: id,
171
+ command: job.job,
172
+ payload: job.payload,
173
+ payload_version: job.version,
174
+ caller: yield* Schema.encodeEffect(CallerJson)(job.caller).pipe(Effect.orDie),
175
+ });
176
+ }
177
+ if (rows.length > 0)
178
+ statements.push(Effect.asVoid(sql `INSERT INTO actor_outbox ${sql.insert(rows)}`));
179
+ const caller = yield* Schema.encodeEffect(CallerJson)(System.make({ source: "actor", ref: sender })).pipe(Effect.orDie);
180
+ for (const change of outbox.subscriptions) {
181
+ const subscribe = change.op === "subscribe";
182
+ const applied = Match.value(change.from).pipe(Match.when("now", () => "-1"), Match.when("start", () => "0"), Match.orElse((cursor) => cursor));
183
+ statements.push(Effect.asVoid(sql `WITH cursor AS (
184
+ INSERT INTO actor_subscription_cursors (routing_key, tenant_id, actor_type, actor_id,
185
+ subscription, source_type, source_id, epoch, active, applied)
186
+ VALUES (${routingKey}, ${tenant}, ${actor}, ${id}, ${change.subscription},
187
+ ${change.source.actor}, ${change.source.id}, 1, ${subscribe}, ${subscribe ? applied : "-1"})
188
+ ON CONFLICT (routing_key, tenant_id, actor_type, actor_id, subscription, source_type, source_id)
189
+ DO UPDATE SET epoch = actor_subscription_cursors.epoch + 1, active = EXCLUDED.active,
190
+ applied = CASE WHEN EXCLUDED.active THEN EXCLUDED.applied
191
+ ELSE actor_subscription_cursors.applied END
192
+ RETURNING epoch)
193
+ INSERT INTO actor_outbox (routing_key, intent_id, kind, bucket, due_at_ms, scheduled_at_ms,
194
+ tenant_id, actor_type, actor_id, timer_key, target_type, target_id, command, payload, caller)
195
+ SELECT ${routingKey}, ${yield* rowId(now)}, 'control', ${bucketOf(routingKey)}, ${now}, ${now},
196
+ ${tenant}, ${actor}, ${id}, ${controlKey(change)}, ${change.source.actor}, ${change.source.id},
197
+ ${change.subscription},
198
+ json_build_object('op', ${change.op}::text, 'epoch', cursor.epoch::text,
199
+ 'start', ${change.from}::text, 'events', to_jsonb(${textArray({ sql, values: change.events })}))::text,
200
+ ${caller}
201
+ FROM cursor
202
+ ON CONFLICT (routing_key, tenant_id, actor_type, actor_id, timer_key) WHERE timer_key IS NOT NULL
203
+ DO UPDATE SET intent_id = EXCLUDED.intent_id, payload = EXCLUDED.payload,
204
+ due_at_ms = EXCLUDED.due_at_ms, scheduled_at_ms = EXCLUDED.scheduled_at_ms,
205
+ attempts = 0, last_error = NULL`));
206
+ }
207
+ if (delayed.length > 0)
208
+ statements.push(Effect.asVoid(sql `UPDATE actor_outbox
209
+ SET due_at_ms = due_at_ms + moved.shift, scheduled_at_ms = scheduled_at_ms + moved.shift,
210
+ ready_at_ms = ready_at_ms + moved.shift
211
+ FROM (SELECT ${statementNow} - ${now} AS shift) AS moved
212
+ WHERE routing_key = ${routingKey} AND intent_id IN ${sql.in(delayed)}`));
213
+ if (capped.length > 0)
214
+ statements.push(orderCapped({ sql, routingKey, sender, capped }));
215
+ return { statements, replies, jobIds };
216
+ });
217
+ /**
218
+ * Orders a turn's capped jobs behind every earlier job of their type on
219
+ * this actor that became due no later. Claims take capped rows by
220
+ * `(ready_at_ms, intent_id)`, but the turn's clock has only millisecond
221
+ * resolution and is read before the actor's lock is taken, and job ids
222
+ * end in a random UUID: jobs enqueued in one turn, or in turns that read
223
+ * the same millisecond, would otherwise run in any order. The actor's lock
224
+ * serializes its turns, so the rows this statement reads are every earlier
225
+ * enqueue. It runs after any delay shift, so `scheduled_at_ms` is final.
226
+ *
227
+ * Within the turn, an earlier row of one job type that is due at the same
228
+ * time or no later always ends ahead of the rows after it. The latest
229
+ * `ready_at_ms` of earlier committed rows is probed twice, over rows not
230
+ * running and over running rows, each reading one partial index.
231
+ */
232
+ export const orderCapped = ({ sql, routingKey, sender, capped, }) => {
233
+ const ranked = capped.map((row, index) => {
234
+ const earlier = capped.slice(0, index).filter(({ job }) => job === row.job);
235
+ return {
236
+ id: row.id,
237
+ tied: earlier.filter(({ dueAt }) => dueAt === row.dueAt).length,
238
+ before: earlier.filter(({ dueAt }) => dueAt <= row.dueAt).length,
239
+ };
240
+ });
241
+ const ids = ranked.map(({ id }) => id);
242
+ const latestOf = (rows) => sql `(SELECT max(e.ready_at_ms)
243
+ FROM actor_outbox e
244
+ WHERE e.routing_key = o.routing_key AND e.tenant_id = o.tenant_id
245
+ AND e.actor_type = o.actor_type AND e.actor_id = o.actor_id AND e.command = o.command
246
+ AND e.kind = 'job' AND ${rows}
247
+ AND e.scheduled_at_ms <= o.scheduled_at_ms
248
+ AND e.intent_id NOT IN ${sql.in(ids)})`;
249
+ const latest = sql `greatest(${latestOf(sql `NOT e.running`)}, ${latestOf(sql `e.running`)})`;
250
+ return Effect.asVoid(sql `UPDATE actor_outbox o
251
+ SET ready_at_ms = greatest(o.scheduled_at_ms + v.tied,
252
+ coalesce(${latest}, o.scheduled_at_ms - 1) + 1 + v.before)
253
+ FROM (VALUES ${sql.csv(ranked.map(({ id, tied, before }) => sql `(${id}::text, ${tied}::int, ${before}::int)`))}) AS v(intent_id, tied, before)
254
+ WHERE o.routing_key = ${routingKey} AND o.tenant_id = ${sender.tenant}
255
+ AND o.actor_type = ${sender.actor} AND o.actor_id = ${sender.id}
256
+ AND o.intent_id = v.intent_id`);
257
+ };
258
+ /**
259
+ * Writes one turn's intents and jobs now, reading the database time only
260
+ * when there are rows to insert. Returns the `OutboxReplies`, so the caller can
261
+ * wake the relay after commit when a row is due and tell it about cancelled
262
+ * attempts.
263
+ */
264
+ export const writeOutbox = Effect.fnUntraced(function* (routingKey, sender, outbox) {
265
+ const staged = yield* outboxStatements(routingKey, sender, outbox, databaseTime);
266
+ for (const statement of staged.statements)
267
+ yield* statement;
268
+ return staged.replies;
269
+ });
@@ -0,0 +1,68 @@
1
+ import { PgPool, type PgConnection } from "@effect/sql-pg";
2
+ import { Context, Effect, Fiber, Layer } from "effect";
3
+ import type { Scope } from "effect";
4
+ import type { SqlError } from "effect/sql";
5
+ declare const TurnConnections_base: Context.ServiceClass<TurnConnections, "@rikalabs/akter/runtime/turn/pipeline/TurnConnections", {
6
+ /** Leases one session for the enclosing scope; the session returns to the pool when the scope closes. */
7
+ readonly lease: Effect.Effect<PgConnection.PgConnection, SqlError.SqlError, Scope.Scope>;
8
+ /** Takes a connection out of the pool, so its session never serves another turn. */
9
+ readonly invalidate: (connection: PgConnection.PgConnection) => Effect.Effect<void>;
10
+ /** Sessions turns hold now, and turns still waiting for one. */
11
+ readonly sessions: () => {
12
+ readonly leased: number;
13
+ readonly waiting: number;
14
+ };
15
+ }>;
16
+ /**
17
+ * Connections a turn leases for itself alone. Each one is multiplexed and
18
+ * never pinned, so a turn can queue a group of statements without waiting for
19
+ * each reply; a pinned transaction would serialize them.
20
+ */
21
+ export declare class TurnConnections extends TurnConnections_base {
22
+ }
23
+ /**
24
+ * Settings merged over the turn pool's own. Tests pass a socket factory here
25
+ * to count the flights one turn puts on the wire.
26
+ */
27
+ export declare const TurnPoolSettings: Context.Reference<Partial<PgPool.Config>>;
28
+ /**
29
+ * The turn pool: `maxConnections` sessions, each handed to one turn at a
30
+ * time. A concurrency of one keeps the lease exclusive while the session
31
+ * stays unpinned. A lease first takes a bounded admission slot, refused at
32
+ * once past `maxConnections` plus the waiter allowance, then waits for a
33
+ * session first come, first served, so a turn never waits behind turns that
34
+ * asked after it. Both slots stay with the lease's scope and return with the
35
+ * session.
36
+ *
37
+ * On Neki, each session first runs the Neki session settings.
38
+ */
39
+ export declare const turnConnections: (options: PgPool.Config) => Layer.Layer<TurnConnections, SqlError.SqlError, never>;
40
+ /**
41
+ * Puts one statement on the session. The runtime passes a sender that queues
42
+ * its deferred statements in the same flight, ahead of the statement.
43
+ */
44
+ export type Send = <A>(statement: Effect.Effect<A, SqlError.SqlError>) => Effect.Effect<A, SqlError.SqlError>;
45
+ export { asSqlConnection } from "../database/connection.ts";
46
+ /**
47
+ * Queues a group of statements for one flight without waiting for replies.
48
+ *
49
+ * Each statement starts on its own fiber before the next is forked, so the
50
+ * driver queues them in submission order and flushes them together. Queuing
51
+ * is uninterruptible, so a group is queued whole or not at all. The fibers
52
+ * live in `scope`, so a group can be queued in one step and awaited in the
53
+ * next.
54
+ */
55
+ export declare const queueStatements: ({ scope, group, }: {
56
+ readonly scope: Scope.Scope;
57
+ readonly group: ReadonlyArray<Effect.Effect<void, SqlError.SqlError>>;
58
+ }) => Effect.Effect<Fiber.Fiber<void, SqlError.SqlError>[], never, never>;
59
+ /**
60
+ * Waits for every reply of a queued group, in order. Every reply is awaited
61
+ * before the first failure is reported, so the session has nothing of the
62
+ * group in flight afterwards. Only the wait can be interrupted.
63
+ */
64
+ export declare const awaitReplies: (fibers: ReadonlyArray<Fiber.Fiber<void, SqlError.SqlError>>) => Effect.Effect<void, SqlError.SqlError, never>;
65
+ /** Sends a group of statements as one flight, on child fibers, and waits for every reply. */
66
+ export declare const sendPipelined: (group: ReadonlyArray<Effect.Effect<void, SqlError.SqlError>>) => Effect.Effect<void, SqlError.SqlError, never>;
67
+ /** Runs a group one statement at a time, for a database with nothing to pipeline. */
68
+ export declare const sendSequentially: (group: ReadonlyArray<Effect.Effect<void, SqlError.SqlError>>) => Effect.Effect<void, SqlError.SqlError, never>;
@@ -0,0 +1,83 @@
1
+ import { PgPool } from "@effect/sql-pg";
2
+ import { Context, Duration, Effect, Exit, Fiber, Layer } from "effect";
3
+ import { fairGate } from "../database/gate.js";
4
+ import { nekiLease, NekiTurnSessions } from "../database/neki/session.js";
5
+ import { admissionLimit } from "../admission.js";
6
+ import { POOL_WAITERS, poolRefusal } from "../database/bounded.js";
7
+ /**
8
+ * Connections a turn leases for itself alone. Each one is multiplexed and
9
+ * never pinned, so a turn can queue a group of statements without waiting for
10
+ * each reply; a pinned transaction would serialize them.
11
+ */
12
+ export class TurnConnections extends Context.Service()("@rikalabs/akter/runtime/turn/pipeline/TurnConnections") {
13
+ }
14
+ /**
15
+ * Settings merged over the turn pool's own. Tests pass a socket factory here
16
+ * to count the flights one turn puts on the wire.
17
+ */
18
+ export const TurnPoolSettings = Context.Reference("akter/TurnPoolSettings", { defaultValue: () => ({}) });
19
+ /**
20
+ * The turn pool: `maxConnections` sessions, each handed to one turn at a
21
+ * time. A concurrency of one keeps the lease exclusive while the session
22
+ * stays unpinned. A lease first takes a bounded admission slot, refused at
23
+ * once past `maxConnections` plus the waiter allowance, then waits for a
24
+ * session first come, first served, so a turn never waits behind turns that
25
+ * asked after it. Both slots stay with the lease's scope and return with the
26
+ * session.
27
+ *
28
+ * On Neki, each session first runs the Neki session settings.
29
+ */
30
+ export const turnConnections = (options) => Layer.effect(TurnConnections, Effect.gen(function* () {
31
+ const settings = yield* TurnPoolSettings;
32
+ const neki = yield* NekiTurnSessions;
33
+ const config = { ...options, ...settings };
34
+ const pool = yield* PgPool.make({
35
+ ...config,
36
+ multiplex: true,
37
+ multiplexConcurrency: 1,
38
+ });
39
+ const slots = config.maxConnections ?? 10;
40
+ const admission = admissionLimit({ limit: slots + POOL_WAITERS, wait: Duration.zero });
41
+ const gate = fairGate(slots);
42
+ const acquire = Effect.andThen(gate.take, neki ? nekiLease(pool) : pool.get);
43
+ let leased = 0;
44
+ let waiting = 0;
45
+ return TurnConnections.of({
46
+ lease: Effect.suspend(() => {
47
+ waiting += 1;
48
+ return Effect.andThen(admission.take.pipe(Effect.mapError(poolRefusal)), acquire).pipe(Effect.ensuring(Effect.sync(() => {
49
+ waiting -= 1;
50
+ })), Effect.tap(() => Effect.acquireRelease(Effect.sync(() => {
51
+ leased += 1;
52
+ }), () => Effect.sync(() => {
53
+ leased -= 1;
54
+ }))));
55
+ }),
56
+ invalidate: pool.invalidate,
57
+ sessions: () => ({ leased, waiting }),
58
+ });
59
+ }));
60
+ export { asSqlConnection } from "../database/connection.js";
61
+ /**
62
+ * Queues a group of statements for one flight without waiting for replies.
63
+ *
64
+ * Each statement starts on its own fiber before the next is forked, so the
65
+ * driver queues them in submission order and flushes them together. Queuing
66
+ * is uninterruptible, so a group is queued whole or not at all. The fibers
67
+ * live in `scope`, so a group can be queued in one step and awaited in the
68
+ * next.
69
+ */
70
+ export const queueStatements = ({ scope, group, }) => Effect.uninterruptible(Effect.forEach(group, (statement) => Effect.forkIn(statement, scope, { startImmediately: true, uninterruptible: false })));
71
+ /**
72
+ * Waits for every reply of a queued group, in order. Every reply is awaited
73
+ * before the first failure is reported, so the session has nothing of the
74
+ * group in flight afterwards. Only the wait can be interrupted.
75
+ */
76
+ export const awaitReplies = (fibers) => Effect.forEach(fibers, Fiber.await).pipe(Effect.flatMap((exits) => {
77
+ const failed = exits.find(Exit.isFailure);
78
+ return failed === undefined ? Effect.void : Effect.failCause(failed.cause);
79
+ }));
80
+ /** Sends a group of statements as one flight, on child fibers, and waits for every reply. */
81
+ export const sendPipelined = (group) => Effect.uninterruptible(Effect.forEach(group, (statement) => Effect.forkChild(statement, { startImmediately: true, uninterruptible: false }))).pipe(Effect.flatMap(awaitReplies));
82
+ /** Runs a group one statement at a time, for a database with nothing to pipeline. */
83
+ export const sendSequentially = (group) => Effect.forEach(group, (statement) => statement, { discard: true });
@@ -0,0 +1,81 @@
1
+ import { Crypto, Effect, Schema } from "effect";
2
+ import { ActorError } from "../../errors/actor.ts";
3
+ import { Outcome } from "../request.ts";
4
+ /** Encodes an outcome to the JSON text a receipt stores. */
5
+ export declare const encodeOutcome: (outcome: Outcome) => Effect.Effect<string, Schema.SchemaError, never>;
6
+ /** SHA-256 over Postgres's JSONB text normalization of a payload, as stored in receipts. */
7
+ export declare const hashCanonical: (canonical: string) => Effect.Effect<string, never, Crypto.Crypto>;
8
+ /** A retained `actor_receipts` row as read back: the admission facts a replay checks and the encoded outcome it returns. */
9
+ export interface StoredReceipt {
10
+ readonly caller_key: string;
11
+ readonly command: string;
12
+ readonly payload_hash: string;
13
+ readonly outcome: string;
14
+ }
15
+ /**
16
+ * Access and conflict rules for a retained receipt, shared by admission and
17
+ * replay. Fails with `ActorError` `Unauthorized` when the caller differs and
18
+ * `CommandConflict` when the command or payload hash differs; otherwise it
19
+ * returns the stored outcome. A stored outcome that cannot be decoded is a defect.
20
+ */
21
+ export declare const checkReceipt: (request: {
22
+ readonly ref: {
23
+ readonly tenant: string;
24
+ readonly actor: string;
25
+ readonly id: string;
26
+ };
27
+ readonly caller: {
28
+ readonly _tag: "Anonymous";
29
+ } | {
30
+ readonly _tag: "System";
31
+ readonly source: "actor" | "cron" | "job" | "process" | "subscription" | "timer" | "workflow";
32
+ readonly ref?: {
33
+ readonly tenant: string;
34
+ readonly actor: string;
35
+ readonly id: string;
36
+ } | undefined;
37
+ readonly onBehalfOf?: {
38
+ readonly subject: string;
39
+ } | undefined;
40
+ readonly mint?: {
41
+ readonly commandId: string;
42
+ readonly ordinal: number;
43
+ } | undefined;
44
+ } | {
45
+ readonly _tag: "User";
46
+ readonly subject: string;
47
+ };
48
+ readonly command: string;
49
+ readonly commandId: string;
50
+ readonly payload: string;
51
+ readonly external?: boolean | undefined;
52
+ readonly clockOffset?: number | undefined;
53
+ readonly redelivered?: boolean | undefined;
54
+ readonly intent?: {
55
+ readonly tenant: string;
56
+ readonly actor: string;
57
+ readonly id: string;
58
+ } | undefined;
59
+ readonly delivery?: {
60
+ readonly subscription: string;
61
+ readonly sourceType: string;
62
+ readonly sourceId: string;
63
+ readonly epoch: string;
64
+ readonly kind: "event" | "gap" | "rejected";
65
+ readonly position: string;
66
+ } | undefined;
67
+ readonly queuedAtMs?: number | undefined;
68
+ readonly usageToken?: string | undefined;
69
+ }, hash: string, receipt: StoredReceipt) => Effect.Effect<{
70
+ readonly _tag: "Acknowledged";
71
+ readonly reason: "AlreadyApplied" | "NotCreated" | "Stale" | "Unsubscribed";
72
+ } | {
73
+ readonly _tag: "Defect";
74
+ readonly cause: unknown;
75
+ } | {
76
+ readonly _tag: "Failure";
77
+ readonly value: string;
78
+ } | {
79
+ readonly _tag: "Success";
80
+ readonly value: string;
81
+ }, ActorError, never>;