@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,175 @@
1
+ import * as NodeSocket from "@effect/platform-node-shared/NodeSocket";
2
+ import * as NodeSocketServer from "@effect/platform-node-shared/NodeSocketServer";
3
+ import { constants, createPrivateKey, X509Certificate } from "node:crypto";
4
+ import { connect, createSecureContext } from "node:tls";
5
+ import { Clock, Context, Duration, Effect, Layer, Option, Redacted, Scope } from "effect";
6
+ import { Runners, ShardingConfig } from "effect/cluster";
7
+ import { RpcClient, RpcSerialization } from "effect/rpc";
8
+ import { Socket, SocketServer } from "effect/socket";
9
+ import { identity } from "./credentials.js";
10
+ /**
11
+ * Whether a verified peer certificate belongs to the deployment `expected`
12
+ * names: its subject alternative names are exactly that one URI, so no
13
+ * extra name, Akter identity or otherwise, rides along.
14
+ */
15
+ const belongs = (peer, expected) => peer?.subjectaltname === `URI:${expected}`;
16
+ const certificates = (pem) => (pem.match(/-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/gu) ?? []).map((block) => new X509Certificate(block));
17
+ const issued = (certificate, by) => certificate.checkIssued(by) && certificate.verify(by.publicKey);
18
+ /**
19
+ * Checks credentials before any peer sees them and builds the TLS context
20
+ * that presents them, so a runner refuses to start, or keeps its previous
21
+ * credentials, rather than present a certificate its peers would refuse:
22
+ * one for another deployment, one outside its validity window, one its key
23
+ * does not match, or one no trusted authority issued. Session tickets are
24
+ * off, so every connection runs a full handshake and its peer's chain and
25
+ * validity are checked again rather than resumed from an earlier session.
26
+ */
27
+ const prepare = (credentials, expected, now) => {
28
+ const authorities = certificates(credentials.ca);
29
+ const chain = certificates(credentials.certificate);
30
+ const leaf = chain[0];
31
+ if (authorities.length === 0 || authorities.some((authority) => !authority.ca))
32
+ throw new Error("Runner credentials need at least one certificate authority in ca");
33
+ if (leaf === undefined)
34
+ throw new Error("Runner credentials need a certificate");
35
+ if (!belongs({ subjectaltname: leaf.subjectAltName }, expected))
36
+ throw new Error(`Runner certificate must name only the identity ${expected}`);
37
+ if (now < Date.parse(leaf.validFrom) || now > Date.parse(leaf.validTo))
38
+ throw new Error(`Runner certificate is valid only from ${leaf.validFrom} to ${leaf.validTo}`);
39
+ if (!leaf.checkPrivateKey(createPrivateKey(Redacted.value(credentials.key))))
40
+ throw new Error("Runner key does not match its certificate");
41
+ for (const [index, certificate] of chain.entries()) {
42
+ const next = chain[index + 1];
43
+ if (next === undefined
44
+ ? !authorities.some((authority) => issued(certificate, authority))
45
+ : !issued(certificate, next))
46
+ throw new Error("Runner certificate is not issued by a certificate authority in ca");
47
+ }
48
+ return {
49
+ context: createSecureContext({
50
+ ca: credentials.ca,
51
+ cert: credentials.certificate,
52
+ key: Redacted.value(credentials.key),
53
+ minVersion: "TLSv1.3",
54
+ secureOptions: constants.SSL_OP_NO_TICKET,
55
+ }),
56
+ expires: Date.parse(leaf.validTo),
57
+ };
58
+ };
59
+ /**
60
+ * Whether this runner can still peer: false once its current certificate has
61
+ * expired, or once no credential load has succeeded for longer than the
62
+ * transport's `unhealthyAfter`. Readiness reports `peering` while it is false.
63
+ */
64
+ export class PeerHealth extends Context.Service()("@rikalabs/akter/runtime/peering/transport/PeerHealth") {
65
+ }
66
+ /**
67
+ * Every client names the same server, so the listener picks the current
68
+ * credentials through its SNI callback whatever address the peer dialled.
69
+ */
70
+ const SERVER_NAME = "runner.akter.internal";
71
+ /**
72
+ * Runner-to-runner TCP with mutual TLS 1.3. Each side presents its
73
+ * deployment's certificate and accepts a peer only when the peer's chain
74
+ * reaches a trusted authority, is within its validity window, and carries
75
+ * exactly this deployment's identity; a plaintext peer, a peer without a
76
+ * certificate, and a peer of another deployment never reach the runner's RPC
77
+ * handler. Credentials are reloaded every `refreshEvery`: new connections use
78
+ * the latest valid ones, established connections keep the session they
79
+ * authenticated, and credentials that fail validation are logged and
80
+ * ignored while the previous ones stay in use. A runner whose certificate has
81
+ * expired, or whose loads have failed for `unhealthyAfter`, stops reporting
82
+ * ready.
83
+ */
84
+ export const mtls = (options) => {
85
+ const expected = identity(options.deployment);
86
+ const duration = (value, name) => {
87
+ const result = Duration.fromInputUnsafe(value);
88
+ if (!Number.isFinite(Duration.toMillis(result)) || Duration.toMillis(result) < 1)
89
+ throw new Error(`${name} must be finite and at least 1 millisecond`);
90
+ return result;
91
+ };
92
+ const refreshEvery = duration(options.refreshEvery ?? "1 minute", "refreshEvery");
93
+ const refreshTimeout = duration(options.refreshTimeout ?? "10 seconds", "refreshTimeout");
94
+ const unhealthyAfter = duration(options.unhealthyAfter ?? "5 minutes", "unhealthyAfter");
95
+ return Layer.effectContext(Effect.gen(function* () {
96
+ const load = Effect.flatMap(options.credentials, (credentials) => Effect.flatMap(Clock.currentTimeMillis, (now) => Effect.sync(() => ({ ...prepare(credentials, expected, now), loaded: now })))).pipe(Effect.timeoutOrElse({
97
+ duration: refreshTimeout,
98
+ orElse: () => Effect.die(new Error(`Runner peer credentials took longer than ${Duration.toMillis(refreshTimeout)} ms`)),
99
+ }));
100
+ let current = yield* load.pipe(Effect.orDie);
101
+ yield* load.pipe(Effect.tap((next) => Effect.sync(() => {
102
+ current = next;
103
+ })), Effect.catchCause((cause) => Effect.logWarning("Runner peer credentials were not reloaded; keeping the current ones", cause)), Effect.delay(refreshEvery), Effect.forever, Effect.forkScoped);
104
+ const health = PeerHealth.of({
105
+ healthy: Effect.map(Clock.currentTimeMillis, (now) => now <= current.expires && now - current.loaded <= Duration.toMillis(unhealthyAfter)),
106
+ });
107
+ const config = yield* ShardingConfig.ShardingConfig;
108
+ const listen = Option.orElse(config.runnerListenAddress, () => config.runnerAddress);
109
+ if (Option.isNone(listen))
110
+ return yield* Effect.die(new Error("Runner.mtls needs a runner listen address"));
111
+ const server = yield* NodeSocketServer.makeTls({
112
+ host: listen.value.host,
113
+ port: listen.value.port,
114
+ minVersion: "TLSv1.3",
115
+ requestCert: true,
116
+ rejectUnauthorized: true,
117
+ secureOptions: constants.SSL_OP_NO_TICKET,
118
+ SNICallback: (_name, done) => done(null, current.context),
119
+ });
120
+ const accepted = (socket) => socket.authorized &&
121
+ !socket.isSessionReused() &&
122
+ belongs(socket.getPeerCertificate(), expected);
123
+ /**
124
+ * Opens one connection with the credentials current at that moment.
125
+ * The handshake stays interruptible, so the reader's open timeout
126
+ * abandons a listener that never answers it, such as a plaintext peer.
127
+ */
128
+ const open = (address) => Effect.gen(function* () {
129
+ let socket;
130
+ let secured = false;
131
+ yield* Scope.addFinalizer(yield* Effect.scope, Effect.sync(() => (secured ? socket?.destroySoon() : socket?.destroy())));
132
+ return yield* Effect.callback((resume) => {
133
+ socket = connect({
134
+ host: address.host,
135
+ port: address.port,
136
+ servername: SERVER_NAME,
137
+ secureContext: current.context,
138
+ rejectUnauthorized: true,
139
+ checkServerIdentity: (_host, peer) => belongs(peer, expected)
140
+ ? undefined
141
+ : new Error(`Peer at ${address.host}:${address.port} is not a runner of ${expected}`),
142
+ });
143
+ const opened = socket;
144
+ const refuse = (cause) => resume(Effect.fail(Socket.SocketError.make({
145
+ reason: Socket.SocketOpenError.make({ kind: "Unknown", cause }),
146
+ })));
147
+ opened.once("secureConnect", () => {
148
+ if (!accepted(opened)) {
149
+ opened.destroy();
150
+ return refuse(new Error(`Peer at ${address.host}:${address.port} is not a runner of ${expected}`));
151
+ }
152
+ secured = true;
153
+ resume(Effect.succeed(opened));
154
+ });
155
+ opened.once("error", refuse);
156
+ });
157
+ });
158
+ const serialization = yield* RpcSerialization.RpcSerialization;
159
+ return Context.make(SocketServer.SocketServer, SocketServer.SocketServer.of({
160
+ address: server.address,
161
+ run: (handler) => server.run((socket) => Effect.gen(function* () {
162
+ const connection = Option.getOrUndefined(yield* Effect.serviceOption(NodeSocket.NetSocket));
163
+ if (connection !== undefined && accepted(connection))
164
+ return yield* handler(socket);
165
+ connection?.destroy();
166
+ })),
167
+ })).pipe(Context.add(Runners.RpcClientProtocol, Runners.RpcClientProtocol.of({
168
+ codecFor: serialization.codecFor,
169
+ make: Effect.fnUntraced(function* (address) {
170
+ const socket = yield* NodeSocket.fromDuplex(open(address), { openTimeout: 1000 });
171
+ return yield* RpcClient.makeProtocolSocket().pipe(Effect.provideService(Socket.Socket, socket), Effect.provideService(RpcSerialization.RpcSerialization, serialization));
172
+ }, Effect.orDie),
173
+ })), Context.add(PeerHealth, health));
174
+ }));
175
+ };
@@ -0,0 +1,18 @@
1
+ import { Context, type Crypto, Effect } from "effect";
2
+ import { Sharding } from "effect/cluster";
3
+ import { SqlClient } from "effect/sql";
4
+ import { ActorError } from "../errors/actor.ts";
5
+ import { type InternalActors } from "./actors.ts";
6
+ import { type Request } from "./request.ts";
7
+ import { type QueryRegistration, type Registration } from "./members.ts";
8
+ import type { Holder } from "./connections/holder.ts";
9
+ export declare const committedReads: ({ registrations, queryRegistrations, services, allow, primary, replica, holder, }: {
10
+ readonly registrations: ReadonlyMap<string, Registration>;
11
+ readonly queryRegistrations: ReadonlyMap<string, QueryRegistration>;
12
+ readonly services: Context.Context<SqlClient.SqlClient | Crypto.Crypto | Sharding.Sharding>;
13
+ readonly allow: (request: Request, kind?: "command" | "query" | "stream") => Effect.Effect<void, ActorError>;
14
+ readonly primary: SqlClient.SqlClient;
15
+ readonly replica: SqlClient.SqlClient | undefined;
16
+ /** This runner's connection holder, where a watch parks. */
17
+ readonly holder: Holder;
18
+ }) => Pick<InternalActors["Service"], "exists" | "query" | "watch" | "pollWorkflow">;
@@ -0,0 +1,169 @@
1
+ import { Context, Effect, Semaphore } from "effect";
2
+ import { Sharding } from "effect/cluster";
3
+ import { SqlClient, SqlError } from "effect/sql";
4
+ import { ActorError, ActorUnavailable, InvalidInput, NotCreated, Timeout } from "../errors/actor.js";
5
+ import {} from "./actors.js";
6
+ import { Outcome } from "./request.js";
7
+ import {} from "./members.js";
8
+ import { watchStream } from "./connections/watch.js";
9
+ import { caughtUp, QueryPool } from "./database/replica.js";
10
+ import { withTenant } from "./database/tenancy.js";
11
+ import { replayEvents } from "./events/replay.js";
12
+ import { decompress, routingKey } from "./storage/codec.js";
13
+ import { accountsUsage, UsageAccounting } from "./telemetry/usage.js";
14
+ import { decodeResult } from "./workflows/engine.js";
15
+ /**
16
+ * The runtime's reads of committed rows outside any turn: whether an actor
17
+ * exists, a query member's answer, and a workflow execution's status. Each
18
+ * read runs on the caller's node without an activation, generation fence,
19
+ * receipt, or command id, rechecks access after it reads, and fails an
20
+ * unreachable database as `ActorUnavailable`.
21
+ */
22
+ /** Watch reruns one runner runs at once; another waits for a place. */
23
+ const WATCH_RERUNS = 64;
24
+ export const committedReads = ({ registrations, queryRegistrations, services, allow, primary, replica, holder, }) => {
25
+ const reruns = Semaphore.makeUnsafe(WATCH_RERUNS);
26
+ const queryPool = Context.get(services, QueryPool);
27
+ const usage = Context.getUnsafe(services, UsageAccounting);
28
+ const accounting = accountsUsage(usage) ? usage : undefined;
29
+ const exists = Effect.fnUntraced(function* (ref) {
30
+ const registration = registrations.get(ref.actor);
31
+ if (registration === undefined)
32
+ return yield* ActorError.make({
33
+ reason: ActorUnavailable.make({ cause: new Error("Actor not registered") }),
34
+ });
35
+ const sql = yield* SqlClient.SqlClient;
36
+ const rows = yield* sql `
37
+ SELECT 1 FROM actor_generations
38
+ WHERE routing_key = ${routingKey({ ref, placement: registration.placement })}
39
+ AND tenant_id = ${ref.tenant} AND actor_type = ${ref.actor} AND actor_id = ${ref.id}`.pipe(withTenant(ref.tenant));
40
+ return rows.length > 0;
41
+ }, Effect.provideContext(services), Effect.catchIf(SqlError.isSqlError, (cause) => Effect.fail(ActorError.make({ reason: ActorUnavailable.make({ cause }) }))));
42
+ /**
43
+ * A query's answer. A watch's rerun passes `reads` and skips both access
44
+ * checks, because its session was authorized at open and is reauthorized
45
+ * on its bound; the recorder fills `reads`.
46
+ */
47
+ const query = Effect.fnUntraced(function* (request, minVersion, reads) {
48
+ const registration = queryRegistrations.get(request.ref.actor);
49
+ const query = registration?.queries.get(request.command);
50
+ if (registration === undefined || query === undefined)
51
+ return yield* ActorError.make({
52
+ reason: ActorUnavailable.make({ cause: new Error("Query not registered") }),
53
+ });
54
+ if (reads === undefined)
55
+ yield* allow(request, "query");
56
+ const key = routingKey({ ref: request.ref, placement: registration.placement });
57
+ const read = (client) => Effect.gen(function* () {
58
+ const rows = yield* client `
59
+ SELECT event_sequence::text AS head, NULL AS key, NULL::bytea AS value
60
+ FROM actor_generations
61
+ WHERE routing_key = ${key} AND tenant_id = ${request.ref.tenant}
62
+ AND actor_type = ${request.ref.actor} AND actor_id = ${request.ref.id}
63
+ UNION ALL
64
+ SELECT NULL, key, value
65
+ FROM actor_state
66
+ WHERE routing_key = ${key} AND tenant_id = ${request.ref.tenant}
67
+ AND actor_type = ${request.ref.actor} AND actor_id = ${request.ref.id}`;
68
+ let head;
69
+ const state = [];
70
+ for (const row of rows)
71
+ if (row.head !== null)
72
+ head = row.head;
73
+ else
74
+ state.push([row.key, decompress(row.value)]);
75
+ if (head === undefined)
76
+ state.length = 0;
77
+ const cursor = head ?? "0";
78
+ const outcome = yield* query.run(request, state, cursor, (tag, after, limit) => replayEvents(request.ref, key, [tag], after, BigInt(cursor), limit).pipe(Effect.catchIf(SqlError.isSqlError, Effect.die), Effect.provideService(SqlClient.SqlClient, client), Effect.provideContext(services)), reads);
79
+ if (Outcome.guards.Defect(outcome) && SqlError.isSqlError(outcome.cause))
80
+ return yield* outcome.cause;
81
+ return outcome;
82
+ }).pipe(withTenant(request.ref.tenant), Effect.provideService(SqlClient.SqlClient, client));
83
+ const owned = registration.tables.length > 0 || registration.blobs.length > 0;
84
+ const local = owned ? primary : (queryPool ?? primary);
85
+ const outcome = yield* Effect.gen(function* () {
86
+ if (owned || replica === undefined)
87
+ return yield* read(local);
88
+ if (minVersion !== undefined) {
89
+ const ready = yield* caughtUp(replica, minVersion).pipe(Effect.catchIf(SqlError.isSqlError, () => Effect.succeed(false)));
90
+ if (!ready)
91
+ return yield* read(local);
92
+ }
93
+ return yield* read(replica).pipe(Effect.catchIf(SqlError.isSqlError, () => read(local)));
94
+ }).pipe(Effect.timeoutOrElse({
95
+ duration: registration.timeoutMs,
96
+ orElse: () => Effect.fail(ActorError.make({ reason: Timeout.make({ commandId: request.commandId }) })),
97
+ }));
98
+ if (reads === undefined) {
99
+ yield* allow(request, "query");
100
+ if (accounting !== undefined && !Outcome.guards.Defect(outcome))
101
+ yield* accounting.read({
102
+ ref: request.ref,
103
+ requestToken: request.usageToken,
104
+ watch: false,
105
+ sql: primary,
106
+ });
107
+ }
108
+ return outcome;
109
+ }, Effect.provideContext(services), Effect.catchIf(SqlError.isSqlError, (cause) => Effect.fail(ActorError.make({ reason: ActorUnavailable.make({ cause }) }))));
110
+ return {
111
+ exists,
112
+ query: (request, minVersion) => query(request, minVersion),
113
+ watch: (request, { minVersion, expiresAt }) => Effect.gen(function* () {
114
+ const registration = registrations.get(request.ref.actor);
115
+ const watched = queryRegistrations.get(request.ref.actor)?.queries.get(request.command);
116
+ if (registration === undefined || watched === undefined)
117
+ return yield* ActorError.make({
118
+ reason: ActorUnavailable.make({ cause: new Error("Query not registered") }),
119
+ });
120
+ if (!watched.watch)
121
+ return yield* ActorError.make({ reason: InvalidInput.make({ code: "not_watchable" }) });
122
+ if (!(yield* exists(request.ref)))
123
+ return yield* ActorError.make({ reason: NotCreated.make({}) });
124
+ const rerun = (version, reads) => reruns.withPermit(Effect.suspend(() => query(request, version(), reads)));
125
+ const { usageToken } = request;
126
+ let counted = false;
127
+ return yield* watchStream({
128
+ holder,
129
+ request,
130
+ minIntervalMs: registration.policy.watch.minIntervalMs,
131
+ reconcileMs: registration.policy.watch.reconcileMs,
132
+ minVersion,
133
+ expiresAt,
134
+ rerun: accounting === undefined || usageToken === undefined
135
+ ? rerun
136
+ : (version, reads) => rerun(version, reads).pipe(Effect.tap((outcome) => counted || Outcome.guards.Defect(outcome)
137
+ ? Effect.void
138
+ : allow(request, "query").pipe(Effect.andThen(accounting.read({
139
+ ref: request.ref,
140
+ requestToken: usageToken,
141
+ watch: true,
142
+ sql: primary,
143
+ })), Effect.tap(() => Effect.sync(() => void (counted = true))), Effect.catchIf(SqlError.isSqlError, (cause) => Effect.fail(ActorError.make({ reason: ActorUnavailable.make({ cause }) })))))),
144
+ });
145
+ }),
146
+ pollWorkflow: Effect.fnUntraced(function* (request) {
147
+ const registration = registrations.get(request.ref.actor) ?? queryRegistrations.get(request.ref.actor);
148
+ if (registration === undefined)
149
+ return yield* ActorError.make({
150
+ reason: ActorUnavailable.make({ cause: new Error("Actor not registered") }),
151
+ });
152
+ yield* allow(request);
153
+ const sql = yield* SqlClient.SqlClient;
154
+ const [row] = yield* sql `
155
+ SELECT status, result FROM actor_workflow_executions
156
+ WHERE routing_key = ${routingKey({ ref: request.ref, placement: registration.placement })}
157
+ AND execution_id = ${request.payload} AND tenant_id = ${request.ref.tenant}
158
+ AND actor_type = ${request.ref.actor} AND actor_id = ${request.ref.id}
159
+ AND workflow = ${request.command}`.pipe(withTenant(request.ref.tenant));
160
+ yield* allow(request);
161
+ if (row === undefined)
162
+ return undefined;
163
+ return {
164
+ finished: row.status === "finished",
165
+ result: row.result === null ? undefined : yield* decodeResult(row.result),
166
+ };
167
+ }, Effect.provideContext(services), Effect.catchIf(SqlError.isSqlError, (cause) => Effect.fail(ActorError.make({ reason: ActorUnavailable.make({ cause }) })))),
168
+ };
169
+ };
@@ -0,0 +1,36 @@
1
+ import { Context, Crypto, Effect } from "effect";
2
+ import { Sharding } from "effect/cluster";
3
+ import { SqlClient } from "effect/sql";
4
+ /**
5
+ * Builds the runtime's readiness answer, returned as `serving`: not ready
6
+ * while routing is shut down, assigned shards are not acquired, a mutual TLS
7
+ * transport can no longer peer, or nothing is registered, otherwise ready
8
+ * when storage answers. PGlite always answers from the layer's own lifetime, since
9
+ * a single connection held by a turn would make a probe report unready;
10
+ * Postgres storage answers are reused for at most a second; public runner
11
+ * registration snapshots are checked on each probe.
12
+ */
13
+ export declare const servingReadiness: (args_0: {
14
+ readonly sharding: Sharding.Sharding["Service"];
15
+ readonly services: Context.Context<SqlClient.SqlClient | Crypto.Crypto | Sharding.Sharding>;
16
+ readonly registrations: ReadonlyMap<string, unknown>;
17
+ readonly queryRegistrations: ReadonlyMap<string, unknown>;
18
+ readonly jobRegistrations: ReadonlyMap<string, unknown>;
19
+ }) => Effect.Effect<{
20
+ serving: Effect.Effect<{
21
+ readonly ready: false;
22
+ readonly reason: "routing";
23
+ } | {
24
+ readonly ready: false;
25
+ readonly reason: "unregistered";
26
+ } | {
27
+ readonly ready: false;
28
+ readonly reason: "storage";
29
+ } | {
30
+ readonly ready: false;
31
+ readonly reason: "peering";
32
+ } | {
33
+ readonly reason?: undefined;
34
+ readonly ready: true;
35
+ }, never, never>;
36
+ }, never, never>;
@@ -0,0 +1,44 @@
1
+ import { Context, Crypto, Effect, Option } from "effect";
2
+ import { PgliteClient } from "@effect/sql-pglite";
3
+ import { Sharding } from "effect/cluster";
4
+ import { SqlClient } from "effect/sql";
5
+ import { PeerHealth } from "./peering/transport.js";
6
+ import { RunnerReadiness } from "./runner.js";
7
+ /** How long readiness waits for the database before it reports storage unavailable. */
8
+ const READINESS_STORAGE_TIMEOUT = "2 seconds";
9
+ /** How long readiness reuses its last storage answer. */
10
+ const READINESS_CACHE = "1 second";
11
+ /**
12
+ * Builds the runtime's readiness answer, returned as `serving`: not ready
13
+ * while routing is shut down, assigned shards are not acquired, a mutual TLS
14
+ * transport can no longer peer, or nothing is registered, otherwise ready
15
+ * when storage answers. PGlite always answers from the layer's own lifetime, since
16
+ * a single connection held by a turn would make a probe report unready;
17
+ * Postgres storage answers are reused for at most a second; public runner
18
+ * registration snapshots are checked on each probe.
19
+ */
20
+ export const servingReadiness = Effect.fnUntraced(function* ({ sharding, services, registrations, queryRegistrations, jobRegistrations, }) {
21
+ const embedded = Option.isSome(yield* Effect.serviceOption(PgliteClient.PgliteClient));
22
+ const runner = yield* Effect.serviceOption(RunnerReadiness);
23
+ const peering = yield* Effect.serviceOption(PeerHealth);
24
+ const storage = embedded
25
+ ? Effect.succeed(true)
26
+ : yield* Effect.gen(function* () {
27
+ const sql = yield* SqlClient.SqlClient;
28
+ return yield* sql `SELECT 1`.pipe(Effect.timeoutOption(READINESS_STORAGE_TIMEOUT), Effect.map(Option.isSome), Effect.orElseSucceed(() => false));
29
+ }).pipe(Effect.provideContext(services), Effect.cachedWithTTL(READINESS_CACHE));
30
+ const serving = Effect.gen(function* () {
31
+ if (yield* sharding.isShutdown)
32
+ return { ready: false, reason: "routing" };
33
+ if (registrations.size + queryRegistrations.size + jobRegistrations.size === 0)
34
+ return { ready: false, reason: "unregistered" };
35
+ if (!(yield* storage))
36
+ return { ready: false, reason: "storage" };
37
+ if (Option.isSome(peering) && !(yield* peering.value.healthy))
38
+ return { ready: false, reason: "peering" };
39
+ if (Option.isSome(runner) && !(yield* runner.value.acquired(sharding)))
40
+ return { ready: false, reason: "routing" };
41
+ return { ready: true };
42
+ });
43
+ return { serving };
44
+ });
@@ -0,0 +1,58 @@
1
+ import { Context, Crypto, Effect } from "effect";
2
+ import { Sharding } from "effect/cluster";
3
+ import { SqlClient, SqlError } from "effect/sql";
4
+ import type { ActorError } from "../errors/actor.ts";
5
+ import type { JobRegistration, QueryRegistration, Registration } from "./members.ts";
6
+ import type { InternalActors } from "./actors.ts";
7
+ import type { PayloadDeclaration } from "../members/payload.ts";
8
+ import type { AnyOwnedTable } from "../tables/owned.ts";
9
+ import type { HeldActorType } from "./connections/holder.ts";
10
+ import type { Owner } from "./connections/owner.ts";
11
+ import type { Authorize } from "./connections/streams.ts";
12
+ import type { Transport } from "./connections/transport.ts";
13
+ import type { tenantContent } from "./content/store.ts";
14
+ import type { TurnGate } from "./drain.ts";
15
+ import { registerActor } from "./entity/register.ts";
16
+ import type { SubscriptionRelay } from "./subscriptions/relay.ts";
17
+ import { DefectLog } from "./telemetry/defects.ts";
18
+ import { FrameworkClock } from "./turn/admission.ts";
19
+ import { OutboxRuntime } from "./turn/outbox.ts";
20
+ /**
21
+ * Registers actor, query, and job layers with the runtime. Each
22
+ * registration is refused unless its placement, tables, content, workflows,
23
+ * payload versions, and routed subscriptions agree with the database and the
24
+ * runtime's configuration; an accepted one is recorded for the relay, the
25
+ * connection holder, and the sweeps, and forgotten when its layer's scope
26
+ * closes.
27
+ */
28
+ export declare const actorRegistration: ({ registrations, queryRegistrations, jobRegistrations, residency, diagnostics, owners, heldTypes, heldType, sweepsWorkflows, checked, services, frameworkClock, content, retryWindowMs, tableRole, adoptionRole, enforcedTypes, writerDeclarations, refreshPayloadWriters, subscriptions, transport, authorize, gate, writable, defectLog, outbox, }: {
29
+ readonly registrations: Map<string, Registration>;
30
+ readonly queryRegistrations: Map<string, QueryRegistration>;
31
+ readonly jobRegistrations: Map<string, JobRegistration>;
32
+ readonly residency: Map<string, (entityId: string) => boolean>;
33
+ /** Each actor type's view of its activations, for a delivery that timed out. */
34
+ readonly diagnostics: Map<string, Pick<Effect.Success<ReturnType<typeof registerActor>>, "diagnose" | "restarting">>;
35
+ readonly owners: Map<string, Owner>;
36
+ readonly heldTypes: Map<string, HeldActorType>;
37
+ readonly heldType: (registration: Registration) => HeldActorType;
38
+ readonly sweepsWorkflows: Set<string>;
39
+ readonly checked: Set<AnyOwnedTable>;
40
+ readonly services: Context.Context<SqlClient.SqlClient | Crypto.Crypto | Sharding.Sharding>;
41
+ readonly frameworkClock: (typeof FrameworkClock)["Service"];
42
+ readonly content: ReturnType<typeof tenantContent> | undefined;
43
+ readonly retryWindowMs: number;
44
+ readonly tableRole: string | undefined;
45
+ /** The writer role of enforced adopted tables, when the runtime has one. */
46
+ readonly adoptionRole: string | undefined;
47
+ /** Actor types whose turns take the writer role; filled as each type registers. */
48
+ readonly enforcedTypes: Set<string>;
49
+ readonly writerDeclarations: Array<PayloadDeclaration>;
50
+ readonly refreshPayloadWriters: Effect.Effect<void, SqlError.SqlError>;
51
+ readonly subscriptions: SubscriptionRelay;
52
+ readonly transport: Transport;
53
+ readonly authorize: Authorize;
54
+ readonly gate: TurnGate;
55
+ readonly writable: Effect.Effect<void, ActorError>;
56
+ readonly defectLog: DefectLog["Service"];
57
+ readonly outbox: (typeof OutboxRuntime)["Service"];
58
+ }) => Pick<InternalActors["Service"], "register" | "registerQueries" | "registerJobs">;