@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,44 @@
1
+ import { connect } from "node:net";
2
+ import { Duration, Effect, Schema } from "effect";
3
+ /** An advertised-address list that cannot be read. */
4
+ export class BadAdvertised extends Schema.TaggedError()("BadAdvertised", {
5
+ reason: Schema.String,
6
+ }) {
7
+ }
8
+ /**
9
+ * Parses a comma-separated list of `host:port`, where `host` may be a name,
10
+ * an IPv4 address, or a bracketed IPv6 address. A malformed entry fails
11
+ * instead of being dropped, so a typo cannot pass as "every address reached".
12
+ */
13
+ export const parseAdvertised = (list) => Effect.forEach(list
14
+ .split(",")
15
+ .map((entry) => entry.trim())
16
+ .filter((entry) => entry !== ""), (entry) => {
17
+ const match = /^(\[[0-9a-fA-F:.]+\]|[^:\s[\]]+):(\d{1,5})$/.exec(entry);
18
+ const port = Number(match?.[2]);
19
+ return match === null || port < 1 || port > 65_535
20
+ ? Effect.fail(BadAdvertised.make({ reason: `"${entry}" is not host:port` }))
21
+ : Effect.succeed({ host: match[1].replace(/^\[|\]$/g, ""), port });
22
+ }).pipe(Effect.filterOrFail((addresses) => addresses.length > 0, () => BadAdvertised.make({ reason: "No advertised address given" })));
23
+ /**
24
+ * Opens a TCP connection to `address` and reports whether it was accepted
25
+ * within `timeout`. It proves the address routes to a listener from where this
26
+ * process runs; it says nothing about what listens there.
27
+ */
28
+ const canConnect = (address, timeout) => Effect.callback((resume) => {
29
+ const socket = connect({ host: address.host, port: address.port });
30
+ const finish = (reached) => {
31
+ socket.destroy();
32
+ resume(Effect.succeed(reached));
33
+ };
34
+ socket.setTimeout(Duration.toMillis(Duration.fromInputUnsafe(timeout)));
35
+ socket.once("connect", () => finish(true));
36
+ socket.once("timeout", () => finish(false));
37
+ socket.once("error", () => finish(false));
38
+ return Effect.sync(() => socket.destroy());
39
+ });
40
+ /** The `host:port` of every address this process cannot connect to. */
41
+ export const unreachable = Effect.fnUntraced(function* (addresses, timeout) {
42
+ const missed = yield* Effect.forEach(addresses, (address) => Effect.map(canConnect(address, timeout), (reached) => reached ? [] : [`${address.host}:${address.port}`]), { concurrency: 8 });
43
+ return missed.flat();
44
+ });
@@ -0,0 +1,20 @@
1
+ import { Effect, Redacted, type Scope } from "effect";
2
+ import type { ConformanceCase, ConformanceConnection, ConformanceEnvironment, ConformanceServices, ConformanceSuite } from "../conformance.ts";
3
+ /**
4
+ * Runs `body` on a runtime whose queries read `replica`, in place of the
5
+ * suite's runtime, which is restarted afterwards. Two runtimes never serve one
6
+ * database at once, since both would claim its shards.
7
+ */
8
+ export declare const withReplica: {
9
+ <A>(replica: Redacted.Redacted<string>, body: Effect.Effect<A, never, ConformanceServices | Scope.Scope>): (environment: ConformanceEnvironment) => Promise<A>;
10
+ <A>(environment: ConformanceEnvironment, replica: Redacted.Redacted<string>, body: Effect.Effect<A, never, ConformanceServices | Scope.Scope>): Promise<A>;
11
+ };
12
+ /** Replay on the replica stays paused for the rest of the scope. */
13
+ export declare const pauseReplay: (control: ConformanceConnection) => Effect.Effect<readonly unknown[], never, Scope.Scope>;
14
+ export declare const resumeReplay: (control: ConformanceConnection) => Effect.Effect<void, never, never>;
15
+ /** Waits until the replica has replayed through `version`. */
16
+ export declare const replayedThrough: (control: ConformanceConnection, version: string) => Effect.Effect<void, never, never>;
17
+ /** Read-your-writes cases: durable-version headers on replies and replays, rejection of malformed minimums, and replica reads only once it has replayed the caller's version. */
18
+ export declare const readYourWritesConformance: ReadonlyArray<ConformanceCase>;
19
+ /** Read-your-writes cases call the served HTTP actors. */
20
+ export declare const readYourWritesSuite: ConformanceSuite;
@@ -0,0 +1,192 @@
1
+ import { Effect, Redacted, Schedule } from "effect";
2
+ import { dual } from "effect/Function";
3
+ import { ActorError, InvalidInput } from "../../errors/actor.js";
4
+ import { actorErrorBody } from "../../protocol/wire.js";
5
+ import { HttpRoom, serveHttp, tenantOf, httpSuite } from "./http.js";
6
+ const VERSION = /^(0|[1-9]\d*)$/;
7
+ const baseFetch = globalThis.fetch.bind(globalThis);
8
+ /**
9
+ * Runs `body` on a runtime whose queries read `replica`, in place of the
10
+ * suite's runtime, which is restarted afterwards. Two runtimes never serve one
11
+ * database at once, since both would claim its shards.
12
+ */
13
+ export const withReplica = dual(3, (environment, replica, body) => Effect.runPromise(Effect.gen(function* () {
14
+ yield* environment.stop;
15
+ const runtime = environment.build({ replica });
16
+ return yield* Effect.promise(() => runtime.runPromise(Effect.scoped(body))).pipe(Effect.ensuring(Effect.promise(() => runtime.dispose()).pipe(Effect.andThen(environment.restart))));
17
+ })));
18
+ /** Replay on the replica stays paused for the rest of the scope. */
19
+ export const pauseReplay = (control) => Effect.acquireRelease(control.query("SELECT pg_wal_replay_pause()"), () => Effect.asVoid(control.query("SELECT pg_wal_replay_resume()")));
20
+ export const resumeReplay = (control) => Effect.asVoid(control.query("SELECT pg_wal_replay_resume()"));
21
+ /** Waits until the replica has replayed through `version`. */
22
+ export const replayedThrough = Effect.fnUntraced(function* (control, version) {
23
+ yield* control
24
+ .query("SELECT coalesce(pg_last_wal_replay_lsn() - '0/0' >= $1::numeric, false) AS ready", [
25
+ version,
26
+ ])
27
+ .pipe(Effect.map((rows) => rows[0].ready), Effect.repeat({ schedule: Schedule.spaced("50 millis"), until: (ready) => ready }), Effect.timeoutOrElse({
28
+ duration: "10 seconds",
29
+ orElse: () => Effect.die(`The replica did not replay through ${version}`),
30
+ }));
31
+ });
32
+ const post = (server, token, key) => Effect.gen(function* () {
33
+ const reply = yield* server.send(`/actors/HttpRoom/${key}/Post`, {
34
+ token,
35
+ key: yield* server.mint(),
36
+ body: { text: "a" },
37
+ });
38
+ return reply;
39
+ });
40
+ const count = (server, token, key, minVersion) => server.send(`/actors/HttpRoom/${key}/Count`, {
41
+ token,
42
+ headers: minVersion === undefined ? {} : { "durable-min-version": minVersion },
43
+ });
44
+ /** Read-your-writes cases: durable-version headers on replies and replays, rejection of malformed minimums, and replica reads only once it has replayed the caller's version. */
45
+ export const readYourWritesConformance = [
46
+ {
47
+ name: "answers every committed command with durable-version, and a replay with one at least as high",
48
+ run: ({ expect, environment }) => environment.run(Effect.gen(function* () {
49
+ const server = yield* serveHttp();
50
+ const token = `${yield* tenantOf}:alice`;
51
+ const key = yield* server.mint();
52
+ const first = yield* server.send("/actors/HttpRoom/versioned/Post", {
53
+ token,
54
+ key,
55
+ body: { text: "a" },
56
+ });
57
+ const second = yield* post(server, token, "versioned");
58
+ const replayed = yield* server.send("/actors/HttpRoom/versioned/Post", {
59
+ token,
60
+ key,
61
+ body: { text: "a" },
62
+ });
63
+ const versions = [first, second, replayed].map((reply) => reply.headers.get("durable-version"));
64
+ expect([first.status, second.status, replayed.status]).toEqual([200, 200, 200]);
65
+ expect(versions.every((version) => version !== null && VERSION.test(version))).toBe(true);
66
+ expect(BigInt(versions[1]) > BigInt(versions[0])).toBe(true);
67
+ expect(BigInt(versions[2]) >= BigInt(versions[0])).toBe(true);
68
+ expect(replayed.body).toEqual(first.body);
69
+ })),
70
+ },
71
+ {
72
+ name: "refuses a malformed durable-min-version with InvalidInput",
73
+ run: ({ expect, environment }) => environment.run(Effect.gen(function* () {
74
+ const server = yield* serveHttp();
75
+ const token = `${yield* tenantOf}:alice`;
76
+ for (const malformed of ["", "01", "-1", "1.5", "0x10"]) {
77
+ const reply = yield* count(server, token, "malformed", malformed);
78
+ expect(reply.status).toBe(400);
79
+ expect(reply.body).toEqual(yield* actorErrorBody(ActorError.make({
80
+ reason: InvalidInput.make({
81
+ code: "decode",
82
+ issues: [
83
+ {
84
+ path: "durable-min-version",
85
+ message: "Expected a non-negative decimal integer without leading zeros",
86
+ },
87
+ ],
88
+ }),
89
+ })));
90
+ }
91
+ })),
92
+ },
93
+ {
94
+ name: "reads the replica once it has replayed the caller's version, falls through to the primary while it lags, and serves tokenless reads there",
95
+ requiresReplica: true,
96
+ timeoutMs: 60_000,
97
+ run: ({ expect, environment }) => {
98
+ const replica = environment.replica;
99
+ return withReplica(environment, replica.database, Effect.gen(function* () {
100
+ const control = yield* replica.connect;
101
+ const server = yield* serveHttp();
102
+ const token = `${yield* tenantOf}:alice`;
103
+ const own = (yield* post(server, token, "lag")).headers.get("durable-version");
104
+ yield* replayedThrough(control, own);
105
+ yield* pauseReplay(control);
106
+ const other = (yield* post(server, token, "lag")).headers.get("durable-version");
107
+ expect(yield* count(server, token, "lag", own)).toMatchObject({ status: 200, body: 1 });
108
+ expect(yield* count(server, token, "lag")).toMatchObject({ status: 200, body: 1 });
109
+ expect(yield* count(server, token, "lag", other)).toMatchObject({ status: 200, body: 2 });
110
+ yield* resumeReplay(control);
111
+ yield* replayedThrough(control, other);
112
+ expect(yield* count(server, token, "lag", other)).toMatchObject({ status: 200, body: 2 });
113
+ expect(yield* count(server, token, "lag")).toMatchObject({ status: 200, body: 2 });
114
+ }));
115
+ },
116
+ },
117
+ {
118
+ name: "falls through to the primary when the replica cannot be reached",
119
+ requiresReplica: true,
120
+ run: ({ expect, environment }) => {
121
+ const url = new URL(Redacted.value(environment.replica.database));
122
+ url.port = "1";
123
+ return withReplica(environment, Redacted.make(url.href), Effect.gen(function* () {
124
+ const server = yield* serveHttp();
125
+ const token = `${yield* tenantOf}:alice`;
126
+ const version = (yield* post(server, token, "down")).headers.get("durable-version");
127
+ expect(yield* count(server, token, "down", version)).toMatchObject({
128
+ status: 200,
129
+ body: 1,
130
+ });
131
+ expect(yield* count(server, token, "down")).toMatchObject({ status: 200, body: 1 });
132
+ }));
133
+ },
134
+ },
135
+ {
136
+ name: "the Promise client reads its own writes while the replica lags, sending the greatest version it was issued",
137
+ requiresReplica: true,
138
+ timeoutMs: 60_000,
139
+ run: ({ expect, environment }) => {
140
+ const replica = environment.replica;
141
+ return withReplica(environment, replica.database, Effect.gen(function* () {
142
+ const control = yield* replica.connect;
143
+ const server = yield* serveHttp();
144
+ const tenant = yield* tenantOf;
145
+ const sent = [];
146
+ const issued = [];
147
+ const fetch = (input, init) => {
148
+ sent.push(new Headers(init?.headers));
149
+ return baseFetch(input, init).then((response) => {
150
+ issued.push(response.headers.get("durable-version"));
151
+ return response;
152
+ });
153
+ };
154
+ const rooms = HttpRoom.client({
155
+ baseUrl: server.url,
156
+ headers: { authorization: `Bearer ${tenant}:alice` },
157
+ fetch,
158
+ });
159
+ const room = rooms.get("client");
160
+ yield* Effect.promise(() => room.Post({ text: "a" }));
161
+ yield* replayedThrough(control, issued.at(-1));
162
+ yield* pauseReplay(control);
163
+ yield* Effect.promise(() => room.Post({ text: "b" }));
164
+ const latest = issued.at(-1);
165
+ expect(yield* count(server, `${tenant}:alice`, "client")).toMatchObject({ body: 1 });
166
+ expect(yield* Effect.promise(() => room.Count())).toBe(2);
167
+ expect(sent.at(-1).get("durable-min-version")).toBe(latest);
168
+ expect(VERSION.test(latest)).toBe(true);
169
+ }));
170
+ },
171
+ },
172
+ {
173
+ name: "an in-process handle's query reads the commands its runtime sent while the replica lags",
174
+ requiresReplica: true,
175
+ timeoutMs: 60_000,
176
+ run: ({ expect, environment }) => {
177
+ const replica = environment.replica;
178
+ return withReplica(environment, replica.database, Effect.gen(function* () {
179
+ const control = yield* replica.connect;
180
+ const room = yield* HttpRoom.get("in-process");
181
+ yield* room.Post({ text: "a" }).pipe(Effect.orDie);
182
+ yield* pauseReplay(control);
183
+ yield* room.Post({ text: "b" }).pipe(Effect.orDie);
184
+ expect(yield* room.Count().pipe(Effect.orDie)).toBe(2);
185
+ }));
186
+ },
187
+ },
188
+ ];
189
+ /** Read-your-writes cases call the served HTTP actors. */
190
+ export const readYourWritesSuite = {
191
+ uses: [httpSuite],
192
+ };
@@ -0,0 +1,8 @@
1
+ import { Layer } from "effect";
2
+ import type { ConformanceCase, ConformanceSuite } from "../conformance.ts";
3
+ /** Registers the reducer actor: a reducer-only actor still registers through `toLayer`, with no handlers. */
4
+ export declare const reducerLayer: Layer.Layer<never, never, import("../index.ts").InternalActors>;
5
+ /** Reducer cases: one receipt per committed change, replay without reducing, and rejection of changed input under a reused command id. */
6
+ export declare const reducerConformance: ReadonlyArray<ConformanceCase>;
7
+ /** The reducer actors. */
8
+ export declare const reducerSuite: ConformanceSuite;
@@ -0,0 +1,258 @@
1
+ import { Cause, Effect, Exit, Layer, Result, Schema } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ import { Actor, Actors, CommandConflict } from "../../index.js";
4
+ import { decompress } from "../../runtime/storage/codec.js";
5
+ import { VERSION_KEY } from "../../state/migration.js";
6
+ import { ActorTest } from "../actor-test.js";
7
+ class Overflow extends Schema.TaggedError()("Overflow", { max: Schema.Int }) {
8
+ }
9
+ const TallyV0 = { total: Schema.Int };
10
+ const TallyFields = {
11
+ count: Schema.Int.pipe(Schema.withDecodingDefault(Effect.succeed(0))),
12
+ label: Schema.String.pipe(Schema.withDecodingDefault(Effect.succeed(""))),
13
+ };
14
+ const TallyState = Actor.state(TallyFields, {
15
+ migrations: [
16
+ Actor.migration(TallyV0, TallyFields, ({ total }) => ({ count: total, label: "migrated" })),
17
+ ],
18
+ });
19
+ const reductions = { count: 0 };
20
+ const Add = Actor.reducer("Add", {
21
+ state: TallyState,
22
+ payload: Schema.Int,
23
+ error: Overflow,
24
+ reduce: (state, amount) => {
25
+ reductions.count += 1;
26
+ return state.count + amount > 1_000
27
+ ? Result.fail(Overflow.make({ max: 1_000 }))
28
+ : Result.succeed({ ...state, count: state.count + amount });
29
+ },
30
+ });
31
+ const Label = Actor.reducer("Label", {
32
+ state: TallyState,
33
+ payload: Schema.String,
34
+ reduce: (state, label) => Result.succeed({ ...state, label }),
35
+ });
36
+ const Tick = Actor.reducer("Tick", {
37
+ state: TallyState,
38
+ payload: Schema.Int,
39
+ reduce: (state, amount) => Result.succeed({ ...state, count: state.count + amount }),
40
+ batch: { combine: (first, second) => first + second },
41
+ });
42
+ const Corrupt = Actor.reducer("Corrupt", {
43
+ state: TallyState,
44
+ payload: Schema.Boolean,
45
+ reduce: (state, raise) => {
46
+ if (raise)
47
+ throw new Error("Reducer bug");
48
+ return Result.succeed({ ...state, count: 0.5 });
49
+ },
50
+ });
51
+ const BasketState = Actor.state({
52
+ items: Schema.mutable(Schema.Array(Schema.String)).pipe(Schema.withDecodingDefault(Effect.succeed([]))),
53
+ });
54
+ const Put = Actor.reducer("Put", {
55
+ state: BasketState,
56
+ payload: Schema.String,
57
+ reduce: (state, item) => {
58
+ state.items.push(item);
59
+ return Result.succeed(state);
60
+ },
61
+ });
62
+ const Basket = Actor.make("Basket", { key: Schema.String, state: BasketState, api: { Put } });
63
+ const Tally = Actor.make("Tally", {
64
+ key: Schema.String,
65
+ state: TallyState,
66
+ api: { Add, Label, Tick, Corrupt },
67
+ });
68
+ /** Registers the reducer actor: a reducer-only actor still registers through `toLayer`, with no handlers. */
69
+ export const reducerLayer = Layer.mergeAll(Tally.toLayer(Effect.succeed({})), Basket.toLayer(Effect.succeed({})));
70
+ const storedVersion = Effect.fnUntraced(function* (ref) {
71
+ const sql = yield* SqlClient.SqlClient;
72
+ const [row] = yield* sql `SELECT value FROM actor_state
73
+ WHERE tenant_id = ${ref.tenant} AND actor_type = ${ref.actor} AND actor_id = ${ref.id}
74
+ AND key = ${VERSION_KEY}`;
75
+ return row === undefined ? undefined : decompress(row.value);
76
+ }, Effect.orDie);
77
+ /** Reducer cases: one receipt per committed change, replay without reducing, and rejection of changed input under a reused command id. */
78
+ export const reducerConformance = [
79
+ {
80
+ name: "reducer commits changed state and one receipt, and replays without reducing again",
81
+ run: ({ expect, environment }) => environment.run(Effect.gen(function* () {
82
+ const test = yield* ActorTest;
83
+ const tally = yield* Tally.get("reducer-commit");
84
+ const label = tally.Label("first");
85
+ expect(yield* label).toEqual({ count: 0, label: "first" });
86
+ expect(yield* test.inspect(tally.ref)).toEqual({
87
+ generation: "1",
88
+ state: { label: "first" },
89
+ receipts: 1,
90
+ outbox: 0,
91
+ events: 0,
92
+ jobs: 0,
93
+ });
94
+ const add = tally.Add(7);
95
+ const before = reductions.count;
96
+ expect(yield* add).toEqual({ count: 7, label: "first" });
97
+ expect(yield* add).toEqual({ count: 7, label: "first" });
98
+ expect(yield* label).toEqual({ count: 0, label: "first" });
99
+ expect(reductions.count - before).toBe(1);
100
+ expect(yield* test.inspect(tally.ref)).toEqual({
101
+ generation: "1",
102
+ state: { count: 7, label: "first" },
103
+ receipts: 2,
104
+ outbox: 0,
105
+ events: 0,
106
+ jobs: 0,
107
+ });
108
+ expect(yield* storedVersion(tally.ref)).toBe("1");
109
+ })),
110
+ },
111
+ {
112
+ name: "reducer rejects changed input or another member under the same command id",
113
+ run: ({ expect, environment }) => environment.run(Effect.gen(function* () {
114
+ const test = yield* ActorTest;
115
+ const tally = yield* Tally.get("reducer-conflict");
116
+ const id = yield* (yield* Actors).mintCommandId;
117
+ expect(yield* tally.Add(3).pipe(Actor.commandId(id))).toEqual({ count: 3, label: "" });
118
+ expect(yield* tally.Add(4).pipe(Actor.commandId(id), Effect.flip)).toMatchObject({
119
+ reason: CommandConflict.make({ commandId: id }),
120
+ });
121
+ expect(yield* tally.Tick(3).pipe(Actor.commandId(id), Effect.flip)).toMatchObject({
122
+ reason: CommandConflict.make({ commandId: id }),
123
+ });
124
+ expect(yield* test.inspect(tally.ref)).toMatchObject({
125
+ state: { count: 3 },
126
+ receipts: 1,
127
+ });
128
+ })),
129
+ },
130
+ {
131
+ name: "failing reduce rolls back state and upcast writes and replays its declared error after conditions change",
132
+ run: ({ expect, environment }) => environment.run(Effect.gen(function* () {
133
+ const test = yield* ActorTest;
134
+ const tally = yield* Tally.get("reducer-failure");
135
+ yield* test.seed(tally.ref, { total: 998 }, 0);
136
+ const overflow = tally.Add(5);
137
+ const before = reductions.count;
138
+ expect(yield* overflow.pipe(Effect.flip)).toEqual(Overflow.make({ max: 1_000 }));
139
+ expect(yield* test.inspect(tally.ref)).toEqual({
140
+ generation: "1",
141
+ state: { total: 998 },
142
+ receipts: 1,
143
+ outbox: 0,
144
+ events: 0,
145
+ jobs: 0,
146
+ });
147
+ expect(yield* storedVersion(tally.ref)).toBe(undefined);
148
+ expect(yield* tally.Add(-998)).toEqual({ count: 0, label: "migrated" });
149
+ expect(yield* overflow.pipe(Effect.flip)).toEqual(Overflow.make({ max: 1_000 }));
150
+ expect(reductions.count - before).toBe(2);
151
+ expect(yield* test.inspect(tally.ref)).toEqual({
152
+ generation: "1",
153
+ state: { count: 0, label: "migrated" },
154
+ receipts: 2,
155
+ outbox: 0,
156
+ events: 0,
157
+ jobs: 0,
158
+ });
159
+ expect(yield* storedVersion(tally.ref)).toBe("1");
160
+ })),
161
+ },
162
+ {
163
+ name: "recovers reducer turns crashed beforeCommit and afterCommit with one transition each",
164
+ run: ({ expect, environment }) => environment.run(Effect.gen(function* () {
165
+ const test = yield* ActorTest;
166
+ const tally = yield* Tally.get("reducer-crash");
167
+ const before = reductions.count;
168
+ yield* test.crashNext("beforeCommit");
169
+ expect(yield* tally.Add(23)).toEqual({ count: 23, label: "" });
170
+ expect(reductions.count - before).toBe(2);
171
+ yield* test.crashNext("afterCommit");
172
+ expect(yield* tally.Add(4)).toEqual({ count: 27, label: "" });
173
+ expect(reductions.count - before).toBe(3);
174
+ expect(yield* test.inspect(tally.ref)).toMatchObject({
175
+ state: { count: 27 },
176
+ receipts: 2,
177
+ });
178
+ })),
179
+ },
180
+ {
181
+ name: "recovers failing reducer turns crashed beforeCommit and afterCommit with one terminal receipt each",
182
+ run: ({ expect, environment }) => environment.run(Effect.gen(function* () {
183
+ const test = yield* ActorTest;
184
+ const tally = yield* Tally.get("reducer-failure-crash");
185
+ yield* tally.Add(999);
186
+ const before = reductions.count;
187
+ const beforeCommit = tally.Add(2);
188
+ yield* test.crashNext("beforeCommit");
189
+ expect(yield* beforeCommit.pipe(Effect.flip)).toEqual(Overflow.make({ max: 1_000 }));
190
+ expect(reductions.count - before).toBe(2);
191
+ const afterCommit = tally.Add(3);
192
+ yield* test.crashNext("afterCommit");
193
+ expect(yield* afterCommit.pipe(Effect.flip)).toEqual(Overflow.make({ max: 1_000 }));
194
+ expect(reductions.count - before).toBe(3);
195
+ expect(yield* test.inspect(tally.ref)).toMatchObject({
196
+ state: { count: 999 },
197
+ receipts: 3,
198
+ });
199
+ yield* tally.Add(-999);
200
+ expect(yield* beforeCommit.pipe(Effect.flip)).toEqual(Overflow.make({ max: 1_000 }));
201
+ expect(yield* afterCommit.pipe(Effect.flip)).toEqual(Overflow.make({ max: 1_000 }));
202
+ expect(reductions.count - before).toBe(4);
203
+ expect(yield* test.inspect(tally.ref)).toMatchObject({
204
+ state: { count: 0 },
205
+ receipts: 4,
206
+ });
207
+ })),
208
+ },
209
+ {
210
+ name: "commutative reducer runs as one receipted turn per call and replies void",
211
+ run: ({ expect, environment }) => environment.run(Effect.gen(function* () {
212
+ const test = yield* ActorTest;
213
+ const tally = yield* Tally.get("reducer-commutative");
214
+ const tick = tally.Tick(2);
215
+ expect(yield* tick).toBe(undefined);
216
+ expect(yield* tick).toBe(undefined);
217
+ expect(yield* tally.Tick(5)).toBe(undefined);
218
+ expect(yield* test.inspect(tally.ref)).toMatchObject({
219
+ state: { count: 7 },
220
+ receipts: 2,
221
+ });
222
+ })),
223
+ },
224
+ {
225
+ name: "a throwing reduce or an invalid returned state is a defect with no receipt",
226
+ run: ({ expect, environment }) => environment.run(Effect.gen(function* () {
227
+ const test = yield* ActorTest;
228
+ const tally = yield* Tally.get("reducer-defect");
229
+ yield* tally.Add(1);
230
+ for (const raise of [true, false]) {
231
+ const exit = yield* tally.Corrupt(raise).pipe(Effect.exit);
232
+ expect(Exit.isFailure(exit) && Cause.hasDies(exit.cause)).toBe(true);
233
+ }
234
+ expect(yield* test.inspect(tally.ref)).toMatchObject({
235
+ state: { count: 1 },
236
+ receipts: 1,
237
+ });
238
+ expect(yield* tally.Add(1)).toEqual({ count: 2, label: "" });
239
+ })),
240
+ },
241
+ {
242
+ name: "reducer that mutates its state argument still commits the change",
243
+ run: ({ expect, environment }) => environment.run(Effect.gen(function* () {
244
+ const test = yield* ActorTest;
245
+ const basket = yield* Basket.get("reducer-mutation");
246
+ expect(yield* basket.Put("a")).toEqual({ items: ["a"] });
247
+ expect(yield* basket.Put("b")).toEqual({ items: ["a", "b"] });
248
+ expect(yield* test.inspect(basket.ref)).toMatchObject({
249
+ state: { items: ["a", "b"] },
250
+ receipts: 2,
251
+ });
252
+ })),
253
+ },
254
+ ];
255
+ /** The reducer actors. */
256
+ export const reducerSuite = {
257
+ layer: () => reducerLayer,
258
+ };
@@ -0,0 +1,42 @@
1
+ import { 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 Attempt {
6
+ readonly key: string;
7
+ readonly effectId: string;
8
+ readonly attempt: number;
9
+ readonly runner: number;
10
+ readonly startedAt: number;
11
+ endedAt: number | undefined;
12
+ interrupted: boolean;
13
+ }
14
+ /** Shared by the relay actors and every relay case; each case resets it first. */
15
+ export interface RelayFixture {
16
+ /** Receiver handler runs by intent payload; a rolled-back run counts too. */
17
+ readonly taken: Map<string, number>;
18
+ /** Claims seen at the `afterClaim` fault point, by command id, on any cluster runner. */
19
+ readonly claims: Map<string, number>;
20
+ readonly attempts: Array<Attempt>;
21
+ /** What the receiver does after counting a run. */
22
+ onTake: (id: string) => Effect.Effect<void>;
23
+ /** What the provider does on one attempt; the default succeeds with the key. */
24
+ provider: (attempt: Attempt) => Effect.Effect<string, ProviderDown>;
25
+ /** Behaviour at a fault point on every cluster runner, after its `ActorTest` faults. */
26
+ hook: (point: string, request: Request) => Effect.Effect<void>;
27
+ }
28
+ export declare const relayFixture: () => RelayFixture;
29
+ declare const ProviderDown_base: Schema.Class<ProviderDown, Schema.TaggedStruct<"ProviderDown", {}>, import("effect/Cause").YieldableError>;
30
+ declare class ProviderDown extends ProviderDown_base {
31
+ }
32
+ /** The relay actors' command layers, which every runner builds. */
33
+ export declare const relayLayer: (fixture: RelayFixture) => Layer.Layer<never, never, import("../index.ts").InternalActors>;
34
+ /** The executors of the conformance environment's single runtime. */
35
+ export declare const relayEffects: (fixture: RelayFixture) => Layer.Layer<never, never, import("../index.ts").InternalActors>;
36
+ /** Multi-runner cases: real Postgres only, each on a fresh database and cluster. */
37
+ export declare const relayClusterConformance: ReadonlyArray<ConformanceCase<RelayFixture>>;
38
+ /** Single-runner cases on the conformance environment, shared by PGlite and Postgres. */
39
+ export declare const relayConformance: ReadonlyArray<ConformanceCase<RelayFixture>>;
40
+ /** Relay actors and the executors of runner 0. */
41
+ export declare const relaySuite: ConformanceSuite<RelayFixture>;
42
+ export {};