@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,612 @@
1
+ import { PGlite } from "@electric-sql/pglite";
2
+ import { Cause, Crypto, Deferred, Effect, Exit, Fiber, Layer, ManagedRuntime, Match, Predicate, Redacted, Schedule, Schema, } from "effect";
3
+ import { SqlClient } from "effect/sql";
4
+ import { Actor, RetentionGap, UnknownCursor } from "../../index.js";
5
+ import { InternalActors } from "../../runtime/actors.js";
6
+ import { checkPayloads, clearPayloads, formatPayloadProblem, } from "../../runtime/payloads/versions.js";
7
+ import { migrate, migrations, migrator } from "../../runtime/database/migrations.js";
8
+ import { Database } from "../../runtime/layer.js";
9
+ import { ActorTest } from "../actor-test.js";
10
+ import { ActorCluster } from "../cluster.js";
11
+ /** What the executor, routes, and subscription handler saw, across deployments of one case. */
12
+ const seen = {
13
+ executed: [],
14
+ deadLetters: [],
15
+ delivered: [],
16
+ /** How the next executor attempts end. */
17
+ executor: "succeed",
18
+ /** Whether the subscription handler accepts deliveries; otherwise it dies and the row backs off. */
19
+ accepting: true,
20
+ };
21
+ const reset = Effect.sync(() => {
22
+ seen.executed.length = 0;
23
+ seen.deadLetters.length = 0;
24
+ seen.delivered.length = 0;
25
+ seen.executor = "succeed";
26
+ seen.accepting = true;
27
+ });
28
+ class Declined extends Schema.TaggedError()("Declined", {}) {
29
+ }
30
+ const Money = Schema.Struct({ amount: Schema.Finite, currency: Schema.String });
31
+ /** `Placed` and `Charge` before the currency change: an amount in US cents. */
32
+ const V0 = { orderId: Schema.String, amount: Schema.Finite };
33
+ const V1 = { orderId: Schema.String, total: Money };
34
+ const toV1 = Actor.migration(V0, V1, (v0) => {
35
+ if (v0.amount < 0)
36
+ throw new Error(`cannot convert ${v0.amount}`);
37
+ return { orderId: v0.orderId, total: { amount: v0.amount, currency: "USD" } };
38
+ }, { downcast: (v1) => ({ orderId: v1.orderId, amount: v1.total.amount }) });
39
+ const migrationsOf = (variant) => Match.value(variant.chain).pipe(Match.when("v0", () => undefined), Match.when("v1-from1", () => ({ from: 1, steps: [] })), Match.orElse(() => [toV1]));
40
+ /**
41
+ * One deployment of `Ledger`: `Place` emits `Placed` and performs `Charge`,
42
+ * `History` reads `Placed` back, and `Audit` follows `Placed` by order id.
43
+ */
44
+ const deployment = (variant) => {
45
+ const current = (variant.chain === "v0" ? V0 : V1);
46
+ const options = {
47
+ migrations: migrationsOf(variant),
48
+ writeVersion: variant.chain === "v1-write0" ? 0 : undefined,
49
+ };
50
+ const Placed = Actor.event("Placed", current, options);
51
+ const Noted = Actor.event("Noted", { text: Schema.String });
52
+ const Charge = Actor.job("Charge", { payload: current, ...options });
53
+ const Place = Actor.command("Place", {
54
+ payload: Schema.Struct({
55
+ orderId: Schema.String,
56
+ amount: Schema.Finite,
57
+ after: Schema.optional(Schema.Finite),
58
+ }),
59
+ });
60
+ const Note = Actor.command("Note", { payload: Schema.String });
61
+ const History = Actor.query("History", {
62
+ success: Schema.Array(Schema.Json),
63
+ error: Schema.Union([UnknownCursor, RetentionGap]),
64
+ });
65
+ const Lost = Actor.command("Lost", { payload: Actor.DeadLetter(Charge) });
66
+ const Watch = Actor.workflow("Watch", {
67
+ payload: { id: Schema.String },
68
+ success: Schema.String,
69
+ key: ({ id }) => id,
70
+ });
71
+ const AwaitPlaced = Watch.wait("placed", Placed);
72
+ const Ledger = Actor.make("Ledger", {
73
+ key: Schema.String,
74
+ events: [Placed, Noted],
75
+ jobs: {
76
+ Charge: {
77
+ job: Charge,
78
+ retry: { times: 1, backoff: { base: "1 second", max: "1 second" } },
79
+ onDeadLetter: Lost,
80
+ },
81
+ },
82
+ api: { Place, Note, History, Watch },
83
+ internal: { Lost },
84
+ policy: {
85
+ deliveryTimeout: "3 seconds",
86
+ },
87
+ });
88
+ const encodePlaced = (event) => Schema.encodeUnknownEffect(Schema.toCodecJson(Placed))(event).pipe(Effect.orDie);
89
+ const encodeCharge = (charge) => Schema.encodeUnknownEffect(Schema.toCodecJson(Charge))(charge).pipe(Effect.orDie);
90
+ const valueOf = (orderId, amount) => variant.chain === "v0" ? { orderId, amount } : { orderId, total: { amount, currency: "USD" } };
91
+ const ledger = Ledger.toLayer(Effect.succeed({
92
+ Place: Effect.fnUntraced(function* ({ orderId, amount, after }) {
93
+ const turn = yield* Ledger.Turn;
94
+ yield* turn.emit(Placed.make(valueOf(orderId, amount)));
95
+ yield* turn.enqueue(Charge.make(valueOf(orderId, amount)), after === undefined ? undefined : { after: `${after} millis` });
96
+ }),
97
+ Note: Effect.fnUntraced(function* (text) {
98
+ yield* (yield* Ledger.Turn).emit(Noted.make({ text }));
99
+ }),
100
+ Watch: () => AwaitPlaced().pipe(Effect.as("placed")),
101
+ Lost: (letter) => encodeCharge(letter.job).pipe(Effect.map((effect) => {
102
+ seen.deadLetters.push({ effect, ambiguous: letter.ambiguous });
103
+ })),
104
+ }));
105
+ const queries = Ledger.toQueryLayer(Effect.succeed({
106
+ History: Effect.fnUntraced(function* () {
107
+ const read = yield* Ledger.Read;
108
+ return yield* Effect.forEach(yield* read.events(Placed), ({ event }) => encodePlaced(event));
109
+ }),
110
+ }));
111
+ const executors = Ledger.toJobLayer(Effect.succeed({
112
+ Charge: (charge) => encodeCharge(charge).pipe(Effect.flatMap((encoded) => {
113
+ seen.executed.push(encoded);
114
+ return Match.value(seen.executor).pipe(Match.when("succeed", () => Effect.void), Match.when("fail", () => Effect.fail(Declined.make({}))), Match.orElse(() => Effect.die(new Error("provider connection reset"))));
115
+ })),
116
+ }));
117
+ const auditLayer = () => {
118
+ const Delivery = Actor.Delivery({ source: Ledger, events: [Placed] });
119
+ const Record = Actor.command("Record", { payload: Delivery });
120
+ const Placements = Actor.subscription("Placements", {
121
+ delivery: Delivery,
122
+ handler: Record,
123
+ route: (event) => event.orderId,
124
+ });
125
+ const Audit = Actor.make("Audit", {
126
+ key: Schema.String,
127
+ api: {},
128
+ internal: { Record },
129
+ subscriptions: [Placements],
130
+ });
131
+ const audit = Audit.toLayer(Effect.succeed({
132
+ Record: (delivery) => Effect.suspend(() => {
133
+ if (!seen.accepting)
134
+ return Effect.die(new Error("not accepting yet"));
135
+ return Predicate.isTagged(delivery, "Event")
136
+ ? encodePlaced(delivery.event).pipe(Effect.map((event) => {
137
+ seen.delivered.push(event);
138
+ }))
139
+ : Effect.void;
140
+ }),
141
+ }));
142
+ return audit;
143
+ };
144
+ const layer = Layer.mergeAll(ledger, queries, executors, variant.audit === true ? auditLayer() : Layer.empty);
145
+ return {
146
+ Ledger,
147
+ layer: layer,
148
+ place: (orderId, amount, after) => Ledger.get(orderId).pipe(Effect.flatMap((ledger) => ledger.Place({ orderId, amount, after }))),
149
+ history: (orderId) => Ledger.get(orderId).pipe(Effect.flatMap((ledger) => ledger.History())),
150
+ /** A `Placed` of the order as this deployment encodes it. */
151
+ placed: (orderId, amount) => encodePlaced(Placed.make(valueOf(orderId, amount))),
152
+ /** A `Charge` of the order as this deployment encodes it. */
153
+ charge: (orderId, amount) => encodeCharge(Charge.make(valueOf(orderId, amount))),
154
+ /** Starts a `Watch` execution and returns its id once it waits. */
155
+ watch: (id) => Ledger.get(id).pipe(Effect.flatMap((ledger) => ledger.Watch({ id })), Effect.map((run) => run.executionId)),
156
+ };
157
+ };
158
+ const Base = deployment({ chain: "v0" });
159
+ const Audited = deployment({ chain: "v0", audit: true });
160
+ const Next = deployment({ chain: "v1" });
161
+ const NextAudited = deployment({ chain: "v1", audit: true });
162
+ const Shortened = deployment({ chain: "v1-from1" });
163
+ const FirstPhase = deployment({ chain: "v1-write0" });
164
+ /** `Ledger` after its `Placed` class, and the workflow waiting on it, were removed. */
165
+ const Unplaced = (() => {
166
+ const Noted = Actor.event("Noted", { text: Schema.String });
167
+ const Note = Actor.command("Note", { payload: Schema.String });
168
+ const Ledger = Actor.make("Ledger", { key: Schema.String, events: [Noted], api: { Note } });
169
+ const layer = Ledger.toLayer(Effect.succeed({
170
+ Note: Effect.fnUntraced(function* (text) {
171
+ yield* (yield* Ledger.Turn).emit(Noted.make({ text }));
172
+ }),
173
+ }));
174
+ return { Ledger, layer: layer };
175
+ })();
176
+ const TENANT = "0b7f3a52-1c4d-4e6f-8a9b-3c5d7e9f1a2b";
177
+ /**
178
+ * One database every deployment of a case shares: a fresh Postgres database,
179
+ * or one in-memory PGlite instance each deployment borrows in turn.
180
+ */
181
+ const caseDatabase = (environment) => Effect.gen(function* () {
182
+ const fresh = yield* environment.freshDatabase;
183
+ if (Redacted.isRedacted(fresh))
184
+ return fresh;
185
+ const pglite = yield* Effect.acquireRelease(Effect.sync(() => new PGlite()).pipe(Effect.tap((instance) => Effect.promise(() => instance.waitReady))), (instance) => Effect.promise(() => instance.close()));
186
+ return { liveClient: pglite };
187
+ });
188
+ /** Runs `body` on a fresh runtime of `actors` against `database`, then stops it. */
189
+ const deploy = (database, actors, body, options) => Effect.gen(function* () {
190
+ const crypto = yield* Crypto.Crypto;
191
+ const runtime = yield* Effect.acquireRelease(Effect.sync(() => ManagedRuntime.make(actors.pipe(Layer.provideMerge(ActorTest.layer({
192
+ database,
193
+ retryWindowMs: 60_000,
194
+ payloadWriterWindow: options?.payloadWriterWindow,
195
+ })), Layer.provideMerge(Layer.succeed(Crypto.Crypto, crypto))))), (runtime) => Effect.promise(() => runtime.dispose()));
196
+ return yield* Effect.promise(() => runtime.runPromiseExit(body.pipe(Actor.tenant(TENANT)))).pipe(Effect.flatten);
197
+ }).pipe(Effect.scoped);
198
+ /** The startup failure of a deployment, pretty-printed; dies if it starts. */
199
+ const refusal = (database, actors) => deploy(database, actors, Effect.void).pipe(Effect.exit, Effect.flatMap((exit) => Exit.isFailure(exit)
200
+ ? Effect.succeed(Cause.pretty(exit.cause))
201
+ : Effect.die(new Error("The deployment started"))));
202
+ const query = (statement) => Effect.gen(function* () {
203
+ return yield* statement(yield* SqlClient.SqlClient);
204
+ }).pipe(Effect.orDie);
205
+ const eventVersions = query((sql) => sql `SELECT payload_version AS version FROM actor_events
206
+ WHERE actor_type = 'Ledger' AND event = 'Placed' ORDER BY sequence`).pipe(Effect.map((rows) => rows.map(({ version }) => version)));
207
+ const effectVersions = query((sql) => sql `SELECT payload_version AS version FROM actor_outbox
208
+ WHERE actor_type = 'Ledger' AND kind = 'job' ORDER BY scheduled_at_ms, intent_id`).pipe(Effect.map((rows) => rows.map(({ version }) => version)));
209
+ const recordedVersions = query((sql) => sql `SELECT kind, version, superseded_at_ms IS NOT NULL AS superseded,
210
+ cleared_at_ms IS NOT NULL AS cleared
211
+ FROM actor_payload_versions WHERE actor_type = 'Ledger' AND tag IN ('Placed', 'Charge')
212
+ ORDER BY kind, version`);
213
+ const status = (executionId) => query((sql) => sql `SELECT status FROM actor_workflow_executions
214
+ WHERE execution_id = ${executionId}`).pipe(Effect.map((rows) => rows[0]?.status));
215
+ /** Waits until `check` holds, driving the relay; dies after 30 seconds. */
216
+ const eventually = (check, options) => Effect.gen(function* () {
217
+ if (options?.drive !== false)
218
+ yield* (yield* ActorTest).advance("0 millis");
219
+ return yield* check;
220
+ }).pipe(Effect.repeat({ schedule: Schedule.spaced("50 millis"), until: (done) => done }), Effect.timeoutOrElse({
221
+ duration: "30 seconds",
222
+ orElse: () => Effect.die(new Error("Timed out waiting for the relay")),
223
+ }), Effect.asVoid);
224
+ /** Moves every recorded supersession back past `Ledger`'s 30-day event horizon. */
225
+ const pastHorizon = query((sql) => sql `UPDATE actor_payload_versions SET superseded_at_ms = superseded_at_ms - 31 * 86400000::bigint
226
+ WHERE actor_type = 'Ledger' AND superseded_at_ms IS NOT NULL`);
227
+ const HOUR = 3_600_000;
228
+ const withCase = (environment, body) => environment.run(Effect.gen(function* () {
229
+ yield* reset;
230
+ yield* body(yield* caseDatabase(environment));
231
+ }).pipe(Effect.orDie));
232
+ /** Payload-version cases: the migration's guard on populated databases, stored payload versions, and upcasting of older events and effects through the chain. */
233
+ export const payloadMigrationsConformance = [
234
+ {
235
+ name: "payload migrations: refuses 0021_payload_versions on a database that already holds events, outbox rows, or dead letters",
236
+ run: ({ expect, environment }) => withCase(environment, (database) => Effect.gen(function* () {
237
+ const client = yield* Layer.build(Redacted.isRedacted(database)
238
+ ? Database.postgres({ url: database, maxConnections: 2 })
239
+ : Database.pglite(database)).pipe(Effect.orDie);
240
+ yield* Effect.gen(function* () {
241
+ const sql = yield* SqlClient.SqlClient;
242
+ yield* migrator(Object.fromEntries(Object.entries(migrations).filter(([id]) => id < "0021")));
243
+ yield* sql `INSERT INTO actor_generations (routing_key, tenant_id, actor_type, actor_id)
244
+ VALUES (1, 't', 'Ledger', 'o1')`;
245
+ yield* sql `INSERT INTO actor_outbox (routing_key, intent_id, bucket, due_at_ms,
246
+ scheduled_at_ms, tenant_id, actor_type, actor_id, target_type, target_id, command,
247
+ payload, caller)
248
+ VALUES (1, 'pending', 0, 42, 42, 't', 'Ledger', 'o1', 'Ledger', 'o1', 'Note', '{}', '{}')`;
249
+ const refused = yield* Effect.exit(migrate);
250
+ expect(Exit.isFailure(refused)).toBe(true);
251
+ expect(Cause.pretty(refused.cause)).toContain("Migration 0021_payload_versions needs a database without events, outbox rows, or dead letters");
252
+ yield* sql `DELETE FROM actor_outbox`;
253
+ expect(yield* migrate).toEqual([
254
+ [21, "payload_versions"],
255
+ [22, "parent_placement"],
256
+ [23, "operator_audit"],
257
+ [24, "adoption"],
258
+ [25, "fleet"],
259
+ [26, "jobs"],
260
+ [27, "coordination"],
261
+ [29, "runner_configuration"],
262
+ ]);
263
+ }).pipe(Effect.provideContext(client));
264
+ })),
265
+ },
266
+ {
267
+ name: "payload migrations: stores the current payload version with each emitted event and performed effect",
268
+ run: ({ expect, environment }) => withCase(environment, (database) => deploy(database, Next.layer, Effect.gen(function* () {
269
+ yield* Next.place("o1", 500, HOUR);
270
+ expect(yield* eventVersions).toEqual([1]);
271
+ expect(yield* effectVersions).toEqual([1]);
272
+ expect(yield* recordedVersions).toEqual([
273
+ { kind: "event", version: 1, superseded: false, cleared: false },
274
+ { kind: "job", version: 1, superseded: false, cleared: false },
275
+ ]);
276
+ const views = yield* query((sql) => sql `SELECT payload_version AS version FROM durable.events
277
+ WHERE actor_type = 'Ledger' UNION ALL
278
+ SELECT payload_version FROM durable.jobs WHERE actor_type = 'Ledger'`);
279
+ expect(views).toEqual([{ version: 1 }, { version: 1 }]);
280
+ }))),
281
+ },
282
+ {
283
+ name: "payload migrations: upcasts version-0 events written before a chain step was added through the chain in read.events, feeds, and subscription deliveries",
284
+ run: ({ expect, environment }) => withCase(environment, (database) => Effect.gen(function* () {
285
+ seen.accepting = false;
286
+ yield* deploy(database, Audited.layer, Audited.place("o1", 500, HOUR));
287
+ yield* deploy(database, NextAudited.layer, Effect.gen(function* () {
288
+ expect(yield* eventVersions).toEqual([0]);
289
+ expect(yield* NextAudited.history("o1")).toEqual([yield* Next.placed("o1", 500)]);
290
+ const internal = yield* InternalActors;
291
+ const ledger = yield* NextAudited.Ledger.get("o1");
292
+ const feed = yield* internal.readFeed(ledger.ref, ["Placed"], undefined, 10);
293
+ expect(feed.map(({ value }) => JSON.parse(value))).toEqual([
294
+ yield* Next.placed("o1", 500),
295
+ ]);
296
+ seen.accepting = true;
297
+ yield* query((sql) => sql `UPDATE actor_subscriptions SET due_at_ms = 0, attempts = 0
298
+ WHERE source_type = 'Ledger'`);
299
+ yield* eventually(Effect.sync(() => seen.delivered.length > 0));
300
+ expect(seen.delivered).toEqual([yield* Next.placed("o1", 500)]);
301
+ }));
302
+ })),
303
+ },
304
+ {
305
+ name: "payload migrations: runs a pending effect written at an older version with the upcast payload",
306
+ run: ({ expect, environment }) => withCase(environment, (database) => Effect.gen(function* () {
307
+ yield* deploy(database, Base.layer, Base.place("o1", 700, HOUR));
308
+ yield* deploy(database, Next.layer, Effect.gen(function* () {
309
+ expect(yield* effectVersions).toEqual([0]);
310
+ yield* (yield* ActorTest).advance("61 minutes");
311
+ yield* eventually(Effect.sync(() => seen.executed.length > 0));
312
+ expect(seen.executed).toEqual([yield* Next.charge("o1", 700)]);
313
+ }));
314
+ })),
315
+ },
316
+ {
317
+ name: "payload migrations: delivers an onDeadLetter route with the upcast effect and keeps the dead letter's version",
318
+ run: ({ expect, environment }) => withCase(environment, (database) => Effect.gen(function* () {
319
+ yield* deploy(database, Base.layer, Base.place("o1", 900, HOUR));
320
+ seen.executor = "fail";
321
+ yield* deploy(database, Next.layer, Effect.gen(function* () {
322
+ yield* (yield* ActorTest).advance("61 minutes");
323
+ yield* eventually(Effect.sync(() => seen.deadLetters.length > 0));
324
+ expect(seen.deadLetters).toEqual([
325
+ { effect: yield* Next.charge("o1", 900), ambiguous: false },
326
+ ]);
327
+ expect(yield* query((sql) => sql `SELECT payload_version AS version
328
+ FROM actor_dead_letters WHERE actor_type = 'Ledger'`)).toEqual([{ version: 0 }]);
329
+ }));
330
+ })),
331
+ },
332
+ {
333
+ name: "payload migrations: resets payload_version to 0 when a settled effect row becomes its route intent",
334
+ run: ({ expect, environment }) => withCase(environment, (database) => deploy(database, Next.layer, Effect.gen(function* () {
335
+ yield* query((sql) => sql `CREATE TABLE payload_route_rows (kind text, command text, payload_version int)`);
336
+ yield* query((sql) => sql `CREATE FUNCTION payload_route_copy() RETURNS trigger AS $$
337
+ BEGIN
338
+ INSERT INTO payload_route_rows VALUES (NEW.kind, NEW.command, NEW.payload_version);
339
+ RETURN NEW;
340
+ END $$ LANGUAGE plpgsql`);
341
+ yield* query((sql) => sql `CREATE TRIGGER payload_route_copy AFTER UPDATE OF kind ON actor_outbox
342
+ FOR EACH ROW EXECUTE FUNCTION payload_route_copy()`);
343
+ seen.executor = "fail";
344
+ yield* Next.place("o1", 300);
345
+ yield* eventually(Effect.sync(() => seen.deadLetters.length > 0));
346
+ expect(yield* query((sql) => sql `
347
+ SELECT kind, command, payload_version FROM payload_route_rows`)).toEqual([{ kind: "intent", command: "Lost", payload_version: 0 }]);
348
+ }))),
349
+ },
350
+ {
351
+ name: "payload migrations: fails a read as a defect, never a skip, when an upcast throws or the stored version is newer than the chain",
352
+ run: ({ expect, environment }) => withCase(environment, (database) => Effect.gen(function* () {
353
+ yield* deploy(database, Base.layer, Effect.gen(function* () {
354
+ yield* Base.place("bad", -1, HOUR);
355
+ yield* Base.place("newer", 1, HOUR);
356
+ }));
357
+ yield* deploy(database, Layer.empty, query((sql) => sql `UPDATE actor_events SET payload_version = 5
358
+ WHERE actor_type = 'Ledger' AND actor_id = 'newer'`));
359
+ yield* deploy(database, Next.layer, Effect.gen(function* () {
360
+ const thrown = yield* Next.history("bad").pipe(Effect.exit);
361
+ expect(Exit.isFailure(thrown)).toBe(true);
362
+ expect(Cause.pretty(thrown.cause)).toContain("cannot convert -1");
363
+ const newer = yield* Next.history("newer").pipe(Effect.exit);
364
+ expect(Exit.isFailure(newer)).toBe(true);
365
+ expect(Cause.pretty(newer.cause)).toContain("payload version 5, newer than this code's chain (1)");
366
+ }));
367
+ })),
368
+ },
369
+ {
370
+ name: "payload migrations: keeps an earlier attempt's ambiguity on the row and in the dead letter when a later attempt fails to decode its payload",
371
+ run: ({ expect, environment }) => withCase(environment, (database) => deploy(database, Next.layer, Effect.gen(function* () {
372
+ seen.executor = "die";
373
+ yield* Next.place("o1", 400);
374
+ yield* eventually(Effect.sync(() => seen.executed.length > 0));
375
+ yield* query((sql) => sql `UPDATE actor_outbox SET payload_version = 9
376
+ WHERE actor_type = 'Ledger' AND kind = 'job'`);
377
+ yield* eventually(query((sql) => sql `SELECT count(*)::int AS n FROM actor_dead_letters
378
+ WHERE actor_type = 'Ledger'`).pipe(Effect.map((rows) => rows[0].n > 0)));
379
+ expect(seen.executed.length).toBe(1);
380
+ const letters = yield* query((sql) => sql `
381
+ SELECT ambiguous, payload_version, cause FROM actor_dead_letters
382
+ WHERE actor_type = 'Ledger'`);
383
+ expect(letters.map(({ ambiguous, payload_version }) => ({ ambiguous, payload_version }))).toEqual([{ ambiguous: true, payload_version: 9 }]);
384
+ expect(letters[0].cause).toContain("payload version 9, newer than this code's chain");
385
+ }))),
386
+ },
387
+ {
388
+ name: "payload migrations: refuses startup after a rollback past a recorded version, and when a shortened chain drops a version still retained",
389
+ run: ({ expect, environment }) => withCase(environment, (database) => Effect.gen(function* () {
390
+ yield* deploy(database, Base.layer, Base.place("o1", 100, HOUR));
391
+ expect(yield* refusal(database, Shortened.layer)).toContain("deploy refused");
392
+ const shortened = yield* deploy(database, Layer.empty, checkPayloads([Shortened.Ledger]).pipe(Effect.orDie));
393
+ expect(shortened.map(formatPayloadProblem)).toEqual([
394
+ "Ledger/Placed (event) version 0 may still be stored below this chain's first version 1; run durable payloads clear once its events are gone",
395
+ "Ledger/Charge (job) version 0 stored in 1 pending job or dead letter row below this chain's first version 1",
396
+ ]);
397
+ yield* deploy(database, Next.layer, Effect.void);
398
+ const rollback = yield* refusal(database, Base.layer);
399
+ expect(rollback).toContain("deploy refused");
400
+ expect(rollback).toContain("version 1 recorded above this chain's current version 0: a rollback past a payload schema change");
401
+ const checked = yield* deploy(database, Layer.empty, checkPayloads([Base.Ledger, Next.Ledger]).pipe(Effect.orDie));
402
+ expect(checked.map(({ actorType, tag }) => `${actorType}/${tag}`)).toEqual([
403
+ "Ledger/Placed",
404
+ "Ledger/Charge",
405
+ ]);
406
+ })),
407
+ },
408
+ {
409
+ name: "payload migrations: refuses a shortened chain after the retention horizon until durable payloads clear finds no row of the dropped version, and refuses again after restoring a snapshot taken before the clear",
410
+ run: ({ expect, environment }) => withCase(environment, (database) => Effect.gen(function* () {
411
+ yield* deploy(database, Base.layer, Effect.gen(function* () {
412
+ yield* Base.place("o1", 100);
413
+ yield* eventually(Effect.sync(() => seen.executed.length > 0));
414
+ }));
415
+ yield* deploy(database, Next.layer, Effect.gen(function* () {
416
+ expect(yield* recordedVersions).toEqual([
417
+ { kind: "event", version: 0, superseded: true, cleared: false },
418
+ { kind: "event", version: 1, superseded: false, cleared: false },
419
+ { kind: "job", version: 0, superseded: true, cleared: false },
420
+ { kind: "job", version: 1, superseded: false, cleared: false },
421
+ ]);
422
+ expect(yield* clearPayloads([Next.Ledger])).toEqual([]);
423
+ }));
424
+ yield* deploy(database, Layer.empty, Effect.gen(function* () {
425
+ yield* pastHorizon;
426
+ expect(yield* clearPayloads([Next.Ledger])).toEqual([
427
+ { actorType: "Ledger", tag: "Placed", version: 0, outcome: "stored" },
428
+ ]);
429
+ yield* query((sql) => sql `CREATE TABLE payload_snapshot AS SELECT * FROM actor_payload_versions`);
430
+ yield* query((sql) => sql `DELETE FROM actor_events WHERE actor_type = 'Ledger' AND payload_version = 0`);
431
+ expect(yield* clearPayloads([Next.Ledger])).toEqual([
432
+ { actorType: "Ledger", tag: "Placed", version: 0, outcome: "cleared" },
433
+ ]);
434
+ }));
435
+ yield* deploy(database, Shortened.layer, Effect.void);
436
+ yield* deploy(database, Layer.empty, query((sql) => sql `DELETE FROM actor_payload_versions`.pipe(Effect.andThen(sql `INSERT INTO actor_payload_versions SELECT * FROM payload_snapshot`))));
437
+ expect(yield* refusal(database, Shortened.layer)).toContain("Ledger/Placed (event) version 0 may still be stored");
438
+ })),
439
+ },
440
+ {
441
+ requiresIndependentConnections: true,
442
+ timeoutMs: 120_000,
443
+ name: "payload migrations: refuses durable payloads clear while a runtime writing that version refreshed within the window, and a runtime past its window refuses new turns until it refreshes",
444
+ run: ({ expect, environment }) => environment.run(Effect.gen(function* () {
445
+ yield* reset;
446
+ const database = yield* environment.freshDatabase;
447
+ const afterRunner0 = Layer.effectDiscard(eventually(query((sql) => sql `SELECT 1 FROM actor_payload_writers
448
+ WHERE actor_type = 'Ledger' AND tag = 'Placed' AND version = 0`).pipe(Effect.map((rows) => rows.length > 0)), { drive: false }));
449
+ const context = yield* Layer.build(ActorTest.cluster({
450
+ database,
451
+ runners: 2,
452
+ shardLockExpiration: "3 seconds",
453
+ actors: Layer.empty,
454
+ runnerActors: (runner) => runner === 0 ? Base.layer : Next.layer.pipe(Layer.provide(afterRunner0)),
455
+ payloadWriterWindow: "2 seconds",
456
+ }));
457
+ yield* Effect.gen(function* () {
458
+ const cluster = yield* ActorCluster;
459
+ yield* cluster.ready;
460
+ const on1 = cluster.on(1);
461
+ expect(yield* on1(recordedVersions)).toEqual([
462
+ { kind: "event", version: 0, superseded: true, cleared: false },
463
+ { kind: "event", version: 1, superseded: false, cleared: false },
464
+ { kind: "job", version: 0, superseded: true, cleared: false },
465
+ { kind: "job", version: 1, superseded: false, cleared: false },
466
+ ]);
467
+ yield* on1(pastHorizon);
468
+ expect(yield* on1(clearPayloads([Next.Ledger]))).toEqual([
469
+ { actorType: "Ledger", tag: "Placed", version: 0, outcome: "writer" },
470
+ ]);
471
+ yield* on1(Effect.gen(function* () {
472
+ const sql = yield* SqlClient.SqlClient;
473
+ const locked = yield* Deferred.make();
474
+ const release = yield* Deferred.make();
475
+ const holder = yield* sql
476
+ .withTransaction(Effect.gen(function* () {
477
+ yield* sql `SELECT 1 FROM actor_payload_writers FOR UPDATE`;
478
+ yield* Deferred.succeed(locked, undefined);
479
+ yield* Deferred.await(release);
480
+ }))
481
+ .pipe(Effect.orDie, Effect.forkScoped);
482
+ yield* Deferred.await(locked);
483
+ yield* Effect.sleep("2500 millis");
484
+ const refused = yield* Next.place("o2", 100).pipe(Effect.flip);
485
+ expect(refused.reason._tag).toBe("Timeout");
486
+ expect(yield* query((sql) => sql `SELECT count(*)::int AS n FROM actor_events
487
+ WHERE actor_type = 'Ledger' AND actor_id = 'o2'`)).toEqual([{ n: 0 }]);
488
+ yield* Deferred.succeed(release, undefined);
489
+ yield* Fiber.join(holder);
490
+ yield* Next.place("o2", 100).pipe(Effect.retry({ schedule: Schedule.spaced("100 millis"), times: 50 }));
491
+ }).pipe(Effect.scoped));
492
+ }).pipe(Effect.provideContext(context));
493
+ })),
494
+ },
495
+ {
496
+ name: "payload migrations: records the writeVersion, not the chain's last version, while a two-phase deploy is in its first phase",
497
+ run: ({ expect, environment }) => withCase(environment, (database) => deploy(database, FirstPhase.layer, Effect.gen(function* () {
498
+ yield* FirstPhase.place("o1", 100, HOUR);
499
+ expect(yield* recordedVersions).toEqual([
500
+ { kind: "event", version: 0, superseded: false, cleared: false },
501
+ { kind: "job", version: 0, superseded: false, cleared: false },
502
+ ]);
503
+ expect(yield* query((sql) => sql `SELECT tag, version
504
+ FROM actor_payload_writers WHERE actor_type = 'Ledger' ORDER BY tag`)).toEqual([
505
+ { tag: "Charge", version: 0 },
506
+ { tag: "Noted", version: 0 },
507
+ { tag: "Placed", version: 0 },
508
+ ]);
509
+ }))),
510
+ },
511
+ {
512
+ name: "payload migrations: writes the old version under writeVersion and reads both versions on one runtime",
513
+ run: ({ expect, environment }) => withCase(environment, (database) => Effect.gen(function* () {
514
+ yield* deploy(database, Next.layer, Next.place("o1", 100, HOUR));
515
+ yield* deploy(database, FirstPhase.layer, Effect.gen(function* () {
516
+ yield* FirstPhase.place("o1", 200);
517
+ expect(yield* eventVersions).toEqual([1, 0]);
518
+ expect(yield* FirstPhase.history("o1")).toEqual([
519
+ yield* Next.placed("o1", 100),
520
+ yield* Next.placed("o1", 200),
521
+ ]);
522
+ yield* eventually(Effect.sync(() => seen.executed.length > 0));
523
+ expect(seen.executed).toEqual([yield* Next.charge("o1", 200)]);
524
+ }));
525
+ const oldReader = yield* refusal(database, Base.layer);
526
+ expect(oldReader).toContain("version 1 recorded above this chain's current version 0");
527
+ })),
528
+ },
529
+ {
530
+ timeoutMs: 60_000,
531
+ name: "payload migrations: refuses removing an event class while a subscription has undelivered events of that tag or an open workflow waits on it",
532
+ run: ({ expect, environment }) => withCase(environment, (database) => Effect.gen(function* () {
533
+ seen.accepting = false;
534
+ yield* deploy(database, Audited.layer, Effect.gen(function* () {
535
+ yield* Audited.place("o1", 100, HOUR);
536
+ yield* eventually(query((sql) => sql `SELECT attempts FROM actor_subscriptions
537
+ WHERE source_type = 'Ledger'`).pipe(Effect.map((rows) => rows.some(({ attempts }) => attempts > 0))));
538
+ }));
539
+ expect(yield* refusal(database, Unplaced.layer)).toContain("Ledger/Placed (event) event class removed while subscription Audit.Placements has undelivered events of it");
540
+ seen.accepting = true;
541
+ yield* deploy(database, Audited.layer, Effect.gen(function* () {
542
+ yield* query((sql) => sql `UPDATE actor_subscriptions SET due_at_ms = 0`);
543
+ yield* eventually(Effect.sync(() => seen.delivered.length > 0));
544
+ }));
545
+ expect(yield* deploy(database, Layer.empty, checkPayloads([Unplaced.Ledger]).pipe(Effect.orDie))).toEqual([]);
546
+ const waiting = yield* caseDatabase(environment);
547
+ const executionId = yield* deploy(waiting, Base.layer, Effect.gen(function* () {
548
+ const id = yield* Base.watch("w");
549
+ yield* eventually(status(id).pipe(Effect.map((held) => held === "suspended")));
550
+ return id;
551
+ }));
552
+ const refused = yield* refusal(waiting, Unplaced.layer);
553
+ expect(refused).toContain("deploy refused");
554
+ expect(refused).toContain("Ledger/Watch workflow removed 1 open execution");
555
+ yield* deploy(waiting, Base.layer, Effect.gen(function* () {
556
+ yield* Base.place("w", 100);
557
+ yield* eventually(status(executionId).pipe(Effect.map((held) => held === "finished")));
558
+ }));
559
+ yield* deploy(waiting, Unplaced.layer, Effect.void);
560
+ })),
561
+ },
562
+ {
563
+ timeoutMs: 60_000,
564
+ name: "payload migrations: replays a subscription receipt after a schema change without CommandConflict",
565
+ run: ({ expect, environment }) => withCase(environment, (database) => Effect.gen(function* () {
566
+ yield* deploy(database, Audited.layer, Effect.gen(function* () {
567
+ yield* Audited.place("o1", 100, HOUR);
568
+ yield* eventually(Effect.sync(() => seen.delivered.length > 0));
569
+ }));
570
+ yield* deploy(database, NextAudited.layer, Effect.gen(function* () {
571
+ yield* query((sql) => sql `UPDATE actor_subscriptions SET delivered = 0, due_at_ms = 0
572
+ WHERE source_type = 'Ledger'`);
573
+ yield* eventually(query((sql) => sql `
574
+ SELECT delivered::text AS delivered, last_error FROM actor_subscriptions
575
+ WHERE source_type = 'Ledger' AND source_id = 'o1'`).pipe(Effect.map((rows) => rows[0]?.delivered === "1")));
576
+ expect(yield* query((sql) => sql `SELECT last_error
577
+ FROM actor_subscriptions WHERE source_type = 'Ledger' AND source_id = 'o1'`)).toEqual([{ last_error: null }]);
578
+ expect(seen.delivered.length).toBe(1);
579
+ }));
580
+ })),
581
+ },
582
+ {
583
+ requiresIndependentConnections: true,
584
+ timeoutMs: 120_000,
585
+ name: "payload migrations: two runners, one with the new chain under writeVersion, both write and read version 0",
586
+ run: ({ expect, environment }) => environment.run(Effect.gen(function* () {
587
+ yield* reset;
588
+ const database = yield* environment.freshDatabase;
589
+ const context = yield* Layer.build(ActorTest.cluster({
590
+ database,
591
+ runners: 2,
592
+ shardLockExpiration: "3 seconds",
593
+ actors: Layer.empty,
594
+ runnerActors: (runner) => (runner === 0 ? FirstPhase.layer : Base.layer),
595
+ }));
596
+ yield* Effect.gen(function* () {
597
+ const cluster = yield* ActorCluster;
598
+ yield* cluster.ready;
599
+ for (const runner of [0, 1])
600
+ for (const id of ["a", "b", "c", "d"])
601
+ yield* cluster.on(runner)((runner === 0 ? FirstPhase : Base).place(`${id}${runner}`, 100));
602
+ expect(new Set(yield* cluster.on(0)(eventVersions))).toEqual(new Set([0]));
603
+ for (const id of ["a0", "b1"]) {
604
+ expect(yield* cluster.on(0)(FirstPhase.history(id))).toEqual([
605
+ yield* Next.placed(id, 100),
606
+ ]);
607
+ expect(yield* cluster.on(1)(Base.history(id))).toEqual([yield* Base.placed(id, 100)]);
608
+ }
609
+ }).pipe(Effect.provideContext(context));
610
+ })),
611
+ },
612
+ ];
@@ -0,0 +1,3 @@
1
+ import type { ConformanceCase } from "../conformance.ts";
2
+ /** Pipeline cases: round trips per turn, statement grouping and order across admission, handler, and commit, and batching of the pipelined worker. */
3
+ export declare const pipelineConformance: ReadonlyArray<ConformanceCase>;