@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,26 @@
1
+ import { Effect, Layer } from "effect";
2
+ import type { ConformanceCase, ConformanceSuite } from "../conformance.ts";
3
+ /** One executor attempt as the fake provider saw it. */
4
+ interface Attempt {
5
+ readonly runner: number;
6
+ readonly attempt: number;
7
+ interrupted: boolean;
8
+ }
9
+ /** Shared by the drain actors and every drain case; each case resets it first. */
10
+ export interface DrainFixture {
11
+ /** Deposit handler runs by command id, rolled-back runs included. */
12
+ readonly runs: Map<string, number>;
13
+ readonly attempts: Array<Attempt>;
14
+ /** What the provider does on one attempt; the default succeeds with the key. */
15
+ provider: (key: string) => Effect.Effect<string>;
16
+ /** What a deposit does after counting its run, before it commits. */
17
+ onDeposit: Effect.Effect<void>;
18
+ }
19
+ export declare const drainFixture: () => DrainFixture;
20
+ /** The account and sender commands, which every runner builds. */
21
+ export declare const drainLayer: (fixture: DrainFixture) => Layer.Layer<never, never, import("../index.ts").InternalActors>;
22
+ /** Drain cases: readiness, clean drain, deadline rollback with a same-id retry, and survivor takeover. */
23
+ export declare const drainConformance: ReadonlyArray<ConformanceCase<DrainFixture>>;
24
+ /** Drain actors, beside the connection room they hold open. */
25
+ export declare const drainSuite: ConformanceSuite<DrainFixture>;
26
+ export {};
@@ -0,0 +1,540 @@
1
+ import { Clock, Deferred, Duration, Effect, Exit, Fiber, Layer, Schedule, Schema } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ import { Actor, Actors } from "../../index.js";
4
+ import { RuntimeControl } from "../../runtime/drain.js";
5
+ import { ActorTest } from "../actor-test.js";
6
+ import { ActorCluster } from "../cluster.js";
7
+ import { connectionsLayer, Live, Room, connectionsSuite, } from "./connections/actors.js";
8
+ import { next } from "./connections/harness.js";
9
+ export const drainFixture = () => ({
10
+ runs: new Map(),
11
+ attempts: [],
12
+ provider: (key) => Effect.succeed(key),
13
+ onDeposit: Effect.void,
14
+ });
15
+ const reset = (fixture) => Effect.sync(() => {
16
+ fixture.runs.clear();
17
+ fixture.attempts.length = 0;
18
+ fixture.provider = (key) => Effect.succeed(key);
19
+ fixture.onDeposit = Effect.void;
20
+ });
21
+ const Charge = Actor.job("Charge", {
22
+ payload: { key: Schema.String },
23
+ success: Schema.String,
24
+ });
25
+ const Deposit = Actor.command("Deposit", { payload: Schema.Finite, success: Schema.Finite });
26
+ const Bill = Actor.command("Bill", { payload: Schema.String });
27
+ const Transfer = Actor.command("Transfer", {
28
+ payload: Schema.Struct({ to: Schema.String, amount: Schema.Finite }),
29
+ });
30
+ const Charged = Actor.command("Charged", { payload: Schema.String });
31
+ const ChargeFailed = Actor.command("ChargeFailed", { payload: Actor.DeadLetter(Charge) });
32
+ const Letter = Schema.Struct({ attempts: Schema.Int, ambiguous: Schema.Boolean });
33
+ const Account = Actor.make("Account", {
34
+ key: Schema.String,
35
+ state: Actor.state({
36
+ balance: Schema.Finite.pipe(Schema.withDecodingDefault(Effect.succeed(0))),
37
+ charged: Schema.Array(Schema.String).pipe(Schema.withDecodingDefault(Effect.succeed([]))),
38
+ letters: Schema.Array(Letter).pipe(Schema.withDecodingDefault(Effect.succeed([]))),
39
+ }),
40
+ jobs: {
41
+ Charge: { job: Charge, retry: { times: 0 }, onSuccess: Charged, onDeadLetter: ChargeFailed },
42
+ },
43
+ api: { Deposit, Bill },
44
+ internal: { Charged, ChargeFailed },
45
+ });
46
+ /** Sends deposits to accounts as intents. */
47
+ const Sender = Actor.make("Sender", { key: Schema.String, api: { Transfer } });
48
+ /** The account and sender commands, which every runner builds. */
49
+ export const drainLayer = (fixture) => Layer.merge(Sender.toLayer(Effect.succeed({
50
+ Transfer: Effect.fnUntraced(function* ({ to, amount }) {
51
+ yield* (yield* Account.intents(to)).Deposit(amount);
52
+ }),
53
+ })), drainAccounts(fixture));
54
+ const drainAccounts = (fixture) => Account.toLayer(Effect.succeed({
55
+ Deposit: Effect.fnUntraced(function* (amount) {
56
+ const turn = yield* Account.Turn;
57
+ fixture.runs.set(turn.commandId, (fixture.runs.get(turn.commandId) ?? 0) + 1);
58
+ yield* fixture.onDeposit;
59
+ yield* turn.state.set({ balance: turn.state.balance + amount });
60
+ return turn.state.balance;
61
+ }),
62
+ Bill: Effect.fnUntraced(function* (key) {
63
+ yield* (yield* Account.Turn).enqueue(Charge.make({ key }));
64
+ }),
65
+ Charged: Effect.fnUntraced(function* (key) {
66
+ const turn = yield* Account.Turn;
67
+ yield* turn.state.set({ charged: [...turn.state.charged, key] });
68
+ }),
69
+ ChargeFailed: Effect.fnUntraced(function* ({ attempts, ambiguous }) {
70
+ const turn = yield* Account.Turn;
71
+ yield* turn.state.set({ letters: [...turn.state.letters, { attempts, ambiguous }] });
72
+ }),
73
+ }));
74
+ /** The `Charge` executor of `runner`; a case builds it on the runners it chooses. */
75
+ const chargeExecutor = (fixture, runner) => Account.toJobLayer(Effect.succeed({
76
+ Charge: ({ key }) => Effect.gen(function* () {
77
+ const attempt = {
78
+ runner,
79
+ attempt: (yield* Account.Executor).attempt,
80
+ interrupted: false,
81
+ };
82
+ fixture.attempts.push(attempt);
83
+ return yield* Effect.suspend(() => fixture.provider(key)).pipe(Effect.onExit((exit) => Effect.sync(() => {
84
+ attempt.interrupted = Exit.hasInterrupts(exit);
85
+ })));
86
+ }),
87
+ }));
88
+ const EXPIRATION_SECONDS = 3;
89
+ /** Builds a fresh database and three runners on it, with executors on `executors`. */
90
+ const withCluster = (environment, fixture, settings, body) => environment.run(Effect.gen(function* () {
91
+ yield* reset(fixture);
92
+ const database = yield* environment.freshDatabase;
93
+ const context = yield* Layer.build(ActorTest.cluster({
94
+ database,
95
+ runners: 3,
96
+ shardLockExpiration: `${EXPIRATION_SECONDS} seconds`,
97
+ actors: settings.connections === undefined
98
+ ? drainLayer(fixture)
99
+ : Layer.merge(drainLayer(fixture), connectionsLayer(settings.connections)),
100
+ runnerActors: (runner) => (settings.executors ?? []).includes(runner)
101
+ ? chargeExecutor(fixture, runner)
102
+ : Layer.empty,
103
+ relay: { poll: settings.poll ?? "200 millis" },
104
+ executors: { lease: "3 seconds" },
105
+ }));
106
+ return yield* body.pipe(Effect.provideContext(context));
107
+ }));
108
+ const on = (runner, effect) => ActorCluster.use((cluster) => cluster.on(runner)(effect));
109
+ const account = (id) => Account.get(id);
110
+ const deposit = (runner, id, amount, commandId) => on(runner, account(id).pipe(Effect.flatMap((handle) => commandId === undefined
111
+ ? handle.Deposit(amount)
112
+ : handle.Deposit(amount).pipe(Actor.commandId(commandId)))));
113
+ const mint = (runner) => on(runner, Actors.use((actors) => actors.mintCommandId));
114
+ const refOf = (id, of = account, runner = 0) => on(runner, Effect.map(of(id), (handle) => handle.ref));
115
+ const inspect = (runner, ref) => on(runner, ActorTest.use((test) => test.inspect(ref)));
116
+ const stateOf = (runner, id) => Effect.flatMap(refOf(id, account, runner), (ref) => inspect(runner, ref));
117
+ const readiness = (runner) => on(runner, RuntimeControl.use((control) => control.readiness));
118
+ const drain = (runner, deadline) => on(runner, RuntimeControl.use((control) => control.drain({ deadline })));
119
+ /** An actor id, an account's by default, placed on a runner that `accept`s its owner. */
120
+ const placed = (prefix, accept, of = account) => Effect.gen(function* () {
121
+ const cluster = yield* ActorCluster;
122
+ for (let index = 0;; index++) {
123
+ const id = `${prefix}-${index}`;
124
+ const owner = yield* cluster.owner(yield* refOf(id, of));
125
+ if (owner !== undefined && accept(owner))
126
+ return { id, owner };
127
+ }
128
+ });
129
+ const eventually = (check, what) => check.pipe(Effect.repeat({ schedule: Schedule.spaced("25 millis"), until: (held) => held }), Effect.timeoutOrElse({
130
+ duration: "30 seconds",
131
+ orElse: () => Effect.die(new Error(`Timed out waiting for ${what}`)),
132
+ }), Effect.asVoid);
133
+ /** Database time in epoch milliseconds, the clock outbox due times use. */
134
+ const NOW_MS = "floor(extract(epoch FROM clock_timestamp()) * 1000)";
135
+ /** The one `Charge` row of the case, as the relay left it. */
136
+ const chargeRow = (runner) => on(runner, Effect.gen(function* () {
137
+ const sql = yield* SqlClient.SqlClient;
138
+ return yield* sql `
139
+ SELECT attempts, ambiguous, due_at_ms > ${sql.literal(NOW_MS)} AS leased
140
+ FROM actor_outbox WHERE kind = 'job' AND command = 'Charge'`;
141
+ }).pipe(Effect.orDie));
142
+ /**
143
+ * Pauses the next deposit on the owner of `id` at `point`, calls it from
144
+ * another runner under a fixed command id, and drains the owner with
145
+ * `deadline` while it is paused.
146
+ */
147
+ const drainDuringTurn = (expect, fixture, point) => Effect.gen(function* () {
148
+ const cluster = yield* ActorCluster;
149
+ const id = `paused-${point}`;
150
+ const ref = yield* refOf(id);
151
+ const owner = (yield* cluster.owner(ref));
152
+ const caller = (owner + 1) % cluster.runners;
153
+ expect(yield* deposit(caller, id, 1)).toBe(1);
154
+ const commandId = yield* mint(caller);
155
+ const pause = yield* on(owner, ActorTest.use((test) => test.pauseNext(point)));
156
+ const call = yield* deposit(caller, id, 2, commandId).pipe(Effect.forkChild);
157
+ yield* pause.reached;
158
+ expect(yield* drain(owner, "200 millis")).toEqual({
159
+ outcome: "deadline-expired",
160
+ interruptedTurns: 1,
161
+ interruptedJobs: 0,
162
+ });
163
+ expect(yield* inspect(caller, ref)).toMatchObject(point === "beforeCommit"
164
+ ? { state: { balance: 1 }, receipts: 1 }
165
+ : { state: { balance: 3 }, receipts: 2 });
166
+ yield* cluster.shutdown(owner);
167
+ expect(yield* Fiber.join(call)).toBe(3);
168
+ expect(yield* inspect(caller, ref)).toMatchObject({ state: { balance: 3 }, receipts: 2 });
169
+ return { commandId, caller };
170
+ });
171
+ /** Drain cases: readiness, clean drain, deadline rollback with a same-id retry, and survivor takeover. */
172
+ export const drainConformance = [
173
+ {
174
+ name: "drain: reports ready, then drains cleanly, turns unready, and refuses new commands",
175
+ run: ({ expect, environment, fixture }) => Effect.runPromise(Effect.gen(function* () {
176
+ yield* reset(fixture);
177
+ yield* Effect.promise(() => environment.run(Effect.gen(function* () {
178
+ const control = yield* RuntimeControl;
179
+ expect(yield* control.readiness).toEqual({ ready: true });
180
+ const single = yield* account("single");
181
+ expect(yield* single.Deposit(1)).toBe(1);
182
+ const clean = { outcome: "clean", interruptedTurns: 0, interruptedJobs: 0 };
183
+ expect(yield* control.drain({ deadline: "5 seconds" })).toEqual(clean);
184
+ expect(yield* control.readiness).toEqual({ ready: false, reason: "drained" });
185
+ expect(yield* control.drain({ deadline: "1 millis" })).toEqual(clean);
186
+ const refused = yield* single.Deposit(1).pipe(Effect.flip);
187
+ expect(refused.reason._tag).toBe("ActorUnavailable");
188
+ })));
189
+ }).pipe(Effect.ensuring(environment.restart))),
190
+ },
191
+ {
192
+ name: "drain: rolls back a turn the deadline interrupts, and its retry under the same id commits once",
193
+ run: ({ expect, environment, fixture }) => Effect.runPromise(Effect.gen(function* () {
194
+ yield* reset(fixture);
195
+ const hold = yield* Deferred.make();
196
+ const started = yield* Deferred.make();
197
+ const { commandId, tenant } = yield* Effect.promise(() => environment.run(Effect.gen(function* () {
198
+ const control = yield* RuntimeControl;
199
+ const held = yield* account("held");
200
+ expect(yield* held.Deposit(1)).toBe(1);
201
+ const commandId = yield* (yield* Actors).mintCommandId;
202
+ fixture.onDeposit = Deferred.succeed(started, undefined).pipe(Effect.andThen(Deferred.await(hold)));
203
+ const call = yield* held
204
+ .Deposit(2)
205
+ .pipe(Actor.commandId(commandId), Effect.ignore, Effect.forkChild);
206
+ yield* Deferred.await(started);
207
+ expect(yield* control.drain({ deadline: "100 millis" })).toEqual({
208
+ outcome: "deadline-expired",
209
+ interruptedTurns: 1,
210
+ interruptedJobs: 0,
211
+ });
212
+ yield* Fiber.interrupt(call);
213
+ expect(yield* (yield* ActorTest).inspect(held.ref)).toMatchObject({
214
+ state: { balance: 1 },
215
+ receipts: 1,
216
+ });
217
+ return { commandId, tenant: (yield* ActorTest).tenant };
218
+ })));
219
+ fixture.onDeposit = Effect.void;
220
+ yield* environment.restart;
221
+ yield* Effect.promise(() => environment.run(Effect.gen(function* () {
222
+ const held = yield* account("held").pipe(Actor.tenant(tenant));
223
+ expect(yield* held.Deposit(2).pipe(Actor.commandId(commandId))).toBe(3);
224
+ expect(yield* held.Deposit(2).pipe(Actor.commandId(commandId))).toBe(3);
225
+ expect(yield* (yield* ActorTest).inspect(held.ref)).toMatchObject({
226
+ state: { balance: 3 },
227
+ receipts: 2,
228
+ });
229
+ expect(fixture.runs.get(commandId)).toBe(2);
230
+ })));
231
+ })),
232
+ },
233
+ {
234
+ name: "drain: finishes an in-flight turn, refuses new commands, and a survivor takes the actors at once",
235
+ requiresFreshDatabase: true,
236
+ requiresIndependentConnections: true,
237
+ timeoutMs: 90_000,
238
+ run: ({ expect, environment, fixture }) => withCluster(environment, fixture, {}, Effect.gen(function* () {
239
+ const cluster = yield* ActorCluster;
240
+ const { id, owner } = yield* placed("clean", () => true);
241
+ const caller = (owner + 1) % cluster.runners;
242
+ expect(yield* deposit(caller, id, 1)).toBe(1);
243
+ expect(yield* readiness(owner)).toEqual({ ready: true });
244
+ const pause = yield* on(owner, ActorTest.use((test) => test.pauseNext("beforeCommit")));
245
+ const call = yield* deposit(caller, id, 2).pipe(Effect.forkChild);
246
+ yield* pause.reached;
247
+ const draining = yield* drain(owner, "30 seconds").pipe(Effect.forkChild);
248
+ yield* eventually(Effect.map(readiness(owner), (ready) => !ready.ready && ready.reason === "draining"), "the runner to turn unready");
249
+ const elsewhere = yield* placed("elsewhere", (placedOn) => placedOn !== owner);
250
+ const refused = yield* deposit(owner, elsewhere.id, 1).pipe(Effect.flip);
251
+ expect(refused.reason._tag).toBe("ActorUnavailable");
252
+ yield* pause.release;
253
+ expect(yield* Fiber.join(draining)).toEqual({
254
+ outcome: "clean",
255
+ interruptedTurns: 0,
256
+ interruptedJobs: 0,
257
+ });
258
+ expect(yield* Fiber.join(call)).toBe(3);
259
+ expect(yield* readiness(owner)).toEqual({ ready: false, reason: "drained" });
260
+ yield* cluster.shutdown(owner);
261
+ const released = yield* Clock.currentTimeMillis;
262
+ expect(yield* deposit(caller, id, 4)).toBe(7);
263
+ const served = yield* Clock.currentTimeMillis;
264
+ expect(served - released < EXPIRATION_SECONDS * 1000).toBe(true);
265
+ const next = yield* cluster.owner(yield* refOf(id, account, caller));
266
+ expect(next !== undefined && next !== owner).toBe(true);
267
+ expect(yield* stateOf(caller, id)).toMatchObject({ state: { balance: 7 }, receipts: 3 });
268
+ expect(yield* readiness(caller)).toEqual({ ready: true });
269
+ })),
270
+ },
271
+ {
272
+ name: "drain: starts no following batch behind the turn it finishes, and the waiting command commits once on a survivor",
273
+ requiresFreshDatabase: true,
274
+ requiresIndependentConnections: true,
275
+ timeoutMs: 90_000,
276
+ run: ({ expect, environment, fixture }) => withCluster(environment, fixture, {}, Effect.gen(function* () {
277
+ const cluster = yield* ActorCluster;
278
+ const { id, owner } = yield* placed("following", () => true);
279
+ const caller = (owner + 1) % cluster.runners;
280
+ const ref = yield* refOf(id);
281
+ expect(yield* deposit(caller, id, 1)).toBe(1);
282
+ const commandId = yield* mint(caller);
283
+ const held = yield* on(owner, ActorTest.use((test) => test.pauseNext("beforeCommit")));
284
+ const first = yield* deposit(caller, id, 2).pipe(Effect.forkChild);
285
+ yield* held.reached;
286
+ const queued = yield* on(owner, ActorTest.use((test) => test.pauseNext("queued")));
287
+ const second = yield* deposit(caller, id, 3, commandId).pipe(Effect.forkChild);
288
+ yield* queued.reached;
289
+ yield* queued.release;
290
+ const draining = yield* drain(owner, "30 seconds").pipe(Effect.forkChild);
291
+ yield* eventually(Effect.map(readiness(owner), (ready) => !ready.ready && ready.reason === "draining"), "the runner to turn unready");
292
+ yield* held.release;
293
+ expect(yield* Fiber.join(draining)).toEqual({
294
+ outcome: "clean",
295
+ interruptedTurns: 0,
296
+ interruptedJobs: 0,
297
+ });
298
+ expect(yield* Fiber.join(first)).toBe(3);
299
+ expect(fixture.runs.get(commandId) ?? 0).toBe(0);
300
+ expect(yield* inspect(caller, ref)).toMatchObject({ state: { balance: 3 }, receipts: 2 });
301
+ yield* cluster.shutdown(owner);
302
+ expect(yield* Fiber.join(second)).toBe(6);
303
+ expect(fixture.runs.get(commandId)).toBe(1);
304
+ expect(yield* inspect(caller, ref)).toMatchObject({ state: { balance: 6 }, receipts: 3 });
305
+ })),
306
+ },
307
+ {
308
+ name: "drain: rolls back a turn the deadline interrupts before its commit, reports it, and the caller's retry commits once on the next owner",
309
+ requiresFreshDatabase: true,
310
+ requiresIndependentConnections: true,
311
+ timeoutMs: 90_000,
312
+ run: ({ expect, environment, fixture }) => withCluster(environment, fixture, {}, Effect.gen(function* () {
313
+ const { commandId } = yield* drainDuringTurn(expect, fixture, "beforeCommit");
314
+ expect(fixture.runs.get(commandId)).toBe(2);
315
+ })),
316
+ },
317
+ {
318
+ name: "drain: a turn the deadline interrupts while its sent COMMIT is still running commits once, and the caller's retry returns its output",
319
+ requiresFreshDatabase: true,
320
+ requiresIndependentConnections: true,
321
+ timeoutMs: 90_000,
322
+ run: ({ expect, environment, fixture }) => withCluster(environment, fixture, {}, Effect.gen(function* () {
323
+ const cluster = yield* ActorCluster;
324
+ const id = "commit-sent";
325
+ const ref = yield* refOf(id);
326
+ const owner = (yield* cluster.owner(ref));
327
+ const caller = (owner + 1) % cluster.runners;
328
+ expect(yield* deposit(caller, id, 1)).toBe(1);
329
+ const commandId = yield* mint(caller);
330
+ const held = yield* Deferred.make();
331
+ const release = yield* Deferred.make();
332
+ yield* on(caller, Effect.gen(function* () {
333
+ const sql = yield* SqlClient.SqlClient;
334
+ yield* sql.unsafe(`CREATE FUNCTION hold_commit() RETURNS trigger LANGUAGE plpgsql AS $$
335
+ BEGIN PERFORM pg_advisory_xact_lock(4242); RETURN NULL; END $$`);
336
+ yield* sql.unsafe(`CREATE CONSTRAINT TRIGGER hold_commit AFTER INSERT ON actor_receipts
337
+ DEFERRABLE INITIALLY DEFERRED FOR EACH ROW
338
+ WHEN (NEW.command_id = '${commandId}') EXECUTE FUNCTION hold_commit()`);
339
+ yield* sql `SELECT pg_advisory_xact_lock(4242)`.pipe(Effect.andThen(Deferred.succeed(held, undefined)), Effect.andThen(Deferred.await(release)), sql.withTransaction, Effect.forkDetach);
340
+ }).pipe(Effect.orDie));
341
+ yield* Deferred.await(held);
342
+ const call = yield* deposit(caller, id, 2, commandId).pipe(Effect.forkChild);
343
+ yield* eventually(on(caller, Effect.gen(function* () {
344
+ const sql = yield* SqlClient.SqlClient;
345
+ const waiting = yield* sql `SELECT 1 FROM pg_stat_activity
346
+ WHERE wait_event_type = 'Lock' AND wait_event = 'advisory'
347
+ AND upper(query) LIKE 'COMMIT%'`;
348
+ return waiting.length > 0;
349
+ }).pipe(Effect.orDie)), "the turn's COMMIT to wait on the advisory lock");
350
+ expect(yield* drain(owner, "200 millis")).toEqual({
351
+ outcome: "deadline-expired",
352
+ interruptedTurns: 1,
353
+ interruptedJobs: 0,
354
+ });
355
+ yield* Deferred.succeed(release, undefined);
356
+ yield* cluster.shutdown(owner);
357
+ expect(yield* Fiber.join(call)).toBe(3);
358
+ expect(yield* inspect(caller, ref)).toMatchObject({ state: { balance: 3 }, receipts: 2 });
359
+ expect(fixture.runs.get(commandId)).toBe(2);
360
+ })),
361
+ },
362
+ {
363
+ name: "drain: replays the receipt of a turn the deadline interrupted after its commit, without running it again",
364
+ requiresFreshDatabase: true,
365
+ requiresIndependentConnections: true,
366
+ timeoutMs: 90_000,
367
+ run: ({ expect, environment, fixture }) => withCluster(environment, fixture, {}, Effect.gen(function* () {
368
+ const { commandId } = yield* drainDuringTurn(expect, fixture, "afterCommit");
369
+ expect(fixture.runs.get(commandId)).toBe(1);
370
+ })),
371
+ },
372
+ {
373
+ name: "drain: claims no effect while draining, and the pending effect runs once on a runner that starts later",
374
+ requiresFreshDatabase: true,
375
+ requiresIndependentConnections: true,
376
+ timeoutMs: 90_000,
377
+ run: ({ expect, environment, fixture }) => withCluster(environment, fixture, { executors: [0] }, Effect.gen(function* () {
378
+ const cluster = yield* ActorCluster;
379
+ const { id, owner } = yield* placed("unclaimed", (placedOn) => placedOn !== 0);
380
+ expect(yield* drain(0, "5 seconds")).toEqual({
381
+ outcome: "clean",
382
+ interruptedTurns: 0,
383
+ interruptedJobs: 0,
384
+ });
385
+ yield* on(owner, account(id).pipe(Effect.flatMap((handle) => handle.Bill("late"))));
386
+ yield* Effect.sleep("1500 millis");
387
+ expect(fixture.attempts.length).toBe(0);
388
+ expect(yield* chargeRow(owner)).toMatchObject([{ attempts: 0, ambiguous: false }]);
389
+ yield* cluster.shutdown(0);
390
+ yield* cluster.restart(0);
391
+ yield* eventually(Effect.map(stateOf(owner, id), (inspection) => inspection.jobs + inspection.outbox === 0), "the pending effect to run");
392
+ expect(yield* stateOf(owner, id)).toMatchObject({ state: { charged: ["late"] } });
393
+ expect(fixture.attempts).toEqual([{ runner: 0, attempt: 1, interrupted: false }]);
394
+ })),
395
+ },
396
+ {
397
+ name: "drain: interrupts an effect attempt at the deadline, keeps it ambiguous, and it dead-letters as ambiguous without running again",
398
+ requiresFreshDatabase: true,
399
+ requiresIndependentConnections: true,
400
+ timeoutMs: 90_000,
401
+ run: ({ expect, environment, fixture }) => withCluster(environment, fixture, { executors: [0] }, Effect.gen(function* () {
402
+ const cluster = yield* ActorCluster;
403
+ const { id, owner } = yield* placed("ambiguous", (placedOn) => placedOn !== 0);
404
+ fixture.provider = () => Effect.never;
405
+ yield* on(owner, account(id).pipe(Effect.flatMap((handle) => handle.Bill("stuck"))));
406
+ yield* eventually(Effect.sync(() => fixture.attempts.length === 1), "the attempt to start");
407
+ expect(yield* drain(0, "200 millis")).toEqual({
408
+ outcome: "deadline-expired",
409
+ interruptedTurns: 0,
410
+ interruptedJobs: 1,
411
+ });
412
+ expect(fixture.attempts).toEqual([{ runner: 0, attempt: 1, interrupted: true }]);
413
+ expect(yield* chargeRow(owner)).toEqual([{ attempts: 1, ambiguous: true, leased: true }]);
414
+ yield* cluster.shutdown(0);
415
+ yield* cluster.restart(0);
416
+ yield* eventually(Effect.map(stateOf(owner, id), (inspection) => inspection.jobs + inspection.outbox === 0), "the interrupted effect to be taken over");
417
+ expect((yield* stateOf(owner, id)).state).toEqual({
418
+ letters: [{ attempts: 1, ambiguous: true }],
419
+ });
420
+ expect(fixture.attempts.length).toBe(1);
421
+ })),
422
+ },
423
+ {
424
+ name: "drain: releases an intent delivery it had claimed, and a survivor delivers it once",
425
+ requiresFreshDatabase: true,
426
+ requiresIndependentConnections: true,
427
+ timeoutMs: 90_000,
428
+ run: ({ expect, environment, fixture }) => withCluster(environment, fixture, { poll: "1 hour" }, Effect.gen(function* () {
429
+ const cluster = yield* ActorCluster;
430
+ const sender = yield* placed("sender", () => true, Sender.get);
431
+ const drained = sender.owner;
432
+ const survivor = (drained + 1) % cluster.runners;
433
+ const receiver = yield* placed("receiver", (placedOn) => placedOn !== drained);
434
+ const pause = yield* on(drained, ActorTest.use((test) => test.pauseNext("afterClaim")));
435
+ yield* on(survivor, Sender.get(sender.id).pipe(Effect.flatMap((handle) => handle.Transfer({ to: receiver.id, amount: 5 }))));
436
+ yield* pause.reached;
437
+ expect(yield* drain(drained, "5 seconds")).toEqual({
438
+ outcome: "clean",
439
+ interruptedTurns: 0,
440
+ interruptedJobs: 0,
441
+ });
442
+ const [row] = yield* on(survivor, Effect.gen(function* () {
443
+ const sql = yield* SqlClient.SqlClient;
444
+ return yield* sql `
445
+ SELECT due_at_ms <= ${sql.literal(NOW_MS)} AS due FROM actor_outbox WHERE kind = 'intent'`;
446
+ }).pipe(Effect.orDie));
447
+ expect(row).toEqual({ due: true });
448
+ yield* on(survivor, ActorTest.use((test) => test.advance("0 millis")));
449
+ expect(yield* stateOf(survivor, receiver.id)).toMatchObject({
450
+ state: { balance: 5 },
451
+ receipts: 1,
452
+ outbox: 0,
453
+ });
454
+ expect([...fixture.runs.values()]).toEqual([1]);
455
+ })),
456
+ },
457
+ {
458
+ name: "drain: drains a runner under load without losing or repeating a command",
459
+ requiresFreshDatabase: true,
460
+ requiresIndependentConnections: true,
461
+ timeoutMs: 120_000,
462
+ run: ({ expect, environment, fixture }) => withCluster(environment, fixture, {}, Effect.gen(function* () {
463
+ const cluster = yield* ActorCluster;
464
+ const drained = 0;
465
+ const ids = Array.from({ length: 12 }, (_, index) => `load-${index}`);
466
+ const calls = Array.from({ length: 120 }, (_, index) => ids[index % ids.length]);
467
+ const load = yield* Effect.forEach(calls, (id, index) => deposit(1 + (index % 2), id, 1), { concurrency: 8, discard: true }).pipe(Effect.forkChild);
468
+ yield* eventually(Effect.sync(() => fixture.runs.size >= 20), "the load to start");
469
+ const report = yield* drain(drained, "5 seconds");
470
+ expect(report.outcome).toBe("clean");
471
+ yield* cluster.shutdown(drained);
472
+ yield* Fiber.join(load);
473
+ for (const id of ids) {
474
+ const inspection = yield* stateOf(1, id);
475
+ const sent = calls.filter((call) => call === id).length;
476
+ expect(inspection).toMatchObject({ state: { balance: sent }, receipts: sent });
477
+ }
478
+ expect(fixture.runs.size).toBe(calls.length);
479
+ })),
480
+ },
481
+ {
482
+ name: "drain: returns within its deadline while a turn, a relay delivery, and a held connection are in flight, and reports the turn it cut off",
483
+ requiresFreshDatabase: true,
484
+ requiresIndependentConnections: true,
485
+ timeoutMs: 120_000,
486
+ run: ({ expect, environment, fixture, fixtureOf }) => withCluster(environment, fixture, { connections: fixtureOf(connectionsSuite) }, Effect.gen(function* () {
487
+ const cluster = yield* ActorCluster;
488
+ const drained = 0;
489
+ const survivor = 1;
490
+ const room = yield* placed("room", (placedOn) => placedOn === drained, Room.get);
491
+ const roomRef = yield* refOf(room.id, Room.get);
492
+ const connection = yield* on(drained, ActorTest.use((test) => test.connect(roomRef, Live, { name: "alice" })));
493
+ yield* next(connection);
494
+ const sender = yield* placed("sender", (placedOn) => placedOn === drained, Sender.get);
495
+ const receiver = yield* placed("receiver", (placedOn) => placedOn !== drained);
496
+ const receiving = yield* on(receiver.owner, ActorTest.use((test) => test.pauseNext("beforeCommit")));
497
+ yield* on(survivor, Sender.get(sender.id).pipe(Effect.flatMap((handle) => handle.Transfer({ to: receiver.id, amount: 5 }))));
498
+ yield* receiving.reached;
499
+ const locked = yield* Deferred.make();
500
+ const unlock = yield* Deferred.make();
501
+ yield* cluster.sql `SELECT 1 FROM actor_outbox WHERE kind = 'intent' FOR UPDATE`.pipe(Effect.andThen(Deferred.succeed(locked, undefined)), Effect.andThen(Deferred.await(unlock)), cluster.sql.withTransaction, Effect.orDie, Effect.forkChild);
502
+ yield* Deferred.await(locked);
503
+ const held = yield* placed("held", (placedOn) => placedOn === drained);
504
+ expect(yield* deposit(survivor, held.id, 1)).toBe(1);
505
+ const turning = yield* on(drained, ActorTest.use((test) => test.pauseNext("beforeCommit")));
506
+ const call = yield* deposit(survivor, held.id, 2).pipe(Effect.forkChild);
507
+ yield* turning.reached;
508
+ const slowDatabase = yield* Effect.sleep("1500 millis").pipe(Effect.andThen(turning.release), Effect.andThen(Effect.sleep("3 seconds")), Effect.andThen(Deferred.succeed(unlock, undefined)), Effect.forkChild);
509
+ const started = yield* Clock.currentTimeMillis;
510
+ const report = yield* drain(drained, "500 millis");
511
+ const took = (yield* Clock.currentTimeMillis) - started;
512
+ expect(report).toEqual({
513
+ outcome: "deadline-expired",
514
+ interruptedTurns: 1,
515
+ interruptedJobs: 0,
516
+ });
517
+ expect(took < 500 + 1_000).toBe(true);
518
+ yield* Fiber.join(slowDatabase);
519
+ yield* receiving.release;
520
+ yield* cluster.shutdown(drained);
521
+ expect(yield* Fiber.join(call)).toBe(3);
522
+ yield* eventually(Effect.map(stateOf(survivor, receiver.id), (inspection) => inspection.outbox === 0), "the transfer to be delivered");
523
+ expect(yield* stateOf(survivor, receiver.id)).toMatchObject({
524
+ state: { balance: 5 },
525
+ receipts: 1,
526
+ });
527
+ expect(yield* stateOf(survivor, held.id)).toMatchObject({
528
+ state: { balance: 3 },
529
+ receipts: 2,
530
+ });
531
+ expect([...fixture.runs.values()].reduce((sum, runs) => sum + runs, 0)).toBe(4);
532
+ })),
533
+ },
534
+ ];
535
+ /** Drain actors, beside the connection room they hold open. */
536
+ export const drainSuite = {
537
+ fixture: drainFixture,
538
+ layer: drainLayer,
539
+ uses: [connectionsSuite],
540
+ };
@@ -0,0 +1,38 @@
1
+ import { Cause, Effect, Layer, Schema } from "effect";
2
+ import type { Request } from "../../runtime/request.ts";
3
+ import type { ConformanceCase, ConformanceSuite } from "../conformance.ts";
4
+ /** One executor attempt as the fake provider saw it; times are this process's clock. */
5
+ interface ControlAttempt {
6
+ readonly label: string;
7
+ readonly actor: string;
8
+ readonly effect: string;
9
+ readonly jobId: string;
10
+ readonly attempt: number;
11
+ readonly runner: number;
12
+ readonly startedAt: number;
13
+ endedAt: number | undefined;
14
+ interrupted: boolean;
15
+ }
16
+ /** Shared by the effect-control actors and cases; each case resets it first. */
17
+ export interface EffectControlFixture {
18
+ readonly attempts: Array<ControlAttempt>;
19
+ /** What the provider does on one attempt; the default succeeds with the label. */
20
+ provider: (attempt: ControlAttempt) => Effect.Effect<string, ControlDown>;
21
+ /** Behaviour at a fault point on every cluster runner. */
22
+ hook: (point: string, request: Request) => Effect.Effect<void>;
23
+ }
24
+ export declare const effectControlFixture: () => EffectControlFixture;
25
+ declare const ControlDown_base: Schema.Class<ControlDown, Schema.TaggedStruct<"ControlDown", {}>, Cause.YieldableError>;
26
+ declare class ControlDown extends ControlDown_base {
27
+ }
28
+ /** The effect-control actors' command layers, which every runner builds. */
29
+ export declare const effectControlLayer: Layer.Layer<never, never, import("../index.ts").InternalActors>;
30
+ /** The executors of the conformance environment's single runtime. */
31
+ export declare const effectControlEffects: (fixture: EffectControlFixture) => Layer.Layer<never, never, import("../index.ts").InternalActors>;
32
+ /** Single-runtime cases, on every backend. */
33
+ export declare const effectControlConformance: ReadonlyArray<ConformanceCase<EffectControlFixture>>;
34
+ /** Multi-runner cases: real Postgres only, each on a fresh database and cluster. */
35
+ export declare const effectControlClusterConformance: ReadonlyArray<ConformanceCase<EffectControlFixture>>;
36
+ /** Effect-control actors and the executors of runner 0. */
37
+ export declare const effectControlSuite: ConformanceSuite<EffectControlFixture>;
38
+ export {};