@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,669 @@
1
+ import { Cause, Clock, Context, Deferred, Duration, Effect, Exit, Metric, Option, Result, Schedule, Schema, Scope, Stream, Tracer, } from "effect";
2
+ import { ClusterSchema, Entity, EntityId as ClusterEntityId, Sharding, ShardId, } from "effect/cluster";
3
+ import { Rpc } from "effect/rpc";
4
+ import { SqlClient, SqlError } from "effect/sql";
5
+ import { ActorError, ActorUnavailable } from "../../errors/actor.js";
6
+ import { DeliveryFailed, Executed, Outcome, Request } from "../request.js";
7
+ import {} from "../members.js";
8
+ import { ActorRef } from "../../identity/caller.js";
9
+ import { bootstrapTicks } from "../cron/schedule.js";
10
+ import { parentPlacement, routingKey } from "../storage/codec.js";
11
+ import { ShardLease } from "../topology/locks.js";
12
+ import { activationMailbox } from "./mailbox.js";
13
+ import { overloaded } from "../admission.js";
14
+ import { executeBatches } from "../turn/execute.js";
15
+ import { activationOwner } from "../connections/owner.js";
16
+ import { TenantScope } from "../database/tenancy.js";
17
+ import { transientSqlError } from "../database/transient.js";
18
+ import { FrameworkClock } from "../turn/admission.js";
19
+ import { connectionsEntity } from "../connections/protocol.js";
20
+ import { RetryTurn, TurnHooks } from "../turn/hooks.js";
21
+ import { OutboxRuntime } from "../turn/outbox.js";
22
+ import { DefectLog } from "../telemetry/defects.js";
23
+ import { accountsUsage, UsageAccounting } from "../telemetry/usage.js";
24
+ import { count, Metrics, record } from "../telemetry/metrics.js";
25
+ import { requestAttributes, SpanNames, triggerOf } from "../telemetry/spans.js";
26
+ import { activationEngine, kickedExecution, workflowCommands } from "../workflows/engine.js";
27
+ /**
28
+ * Commands are direct: the Cluster message is volatile and the receipt
29
+ * committed inside the turn is the only durable admission record.
30
+ * A lost runner loses only uncommitted work, which the caller retries by id.
31
+ * `Wake` builds the activation without running a turn.
32
+ */
33
+ const makeCommandEntity = (name) => Entity.make(name, [
34
+ Rpc.make("Execute", {
35
+ payload: Request,
36
+ success: Executed,
37
+ error: Schema.Union([ActorError, DeliveryFailed]),
38
+ }),
39
+ Rpc.make("Wake"),
40
+ ]).annotateRpcs(ClusterSchema.Uninterruptible, true);
41
+ /**
42
+ * Cluster entity ids name the tenant and actor id together.
43
+ */
44
+ const EntityId = Schema.fromJsonString(Schema.Tuple([Schema.String, Schema.String]));
45
+ const encodeEntityIdOf = Schema.encodeEffect(EntityId);
46
+ /**
47
+ * A retryable turn failure, and a handler rebuilt after a death, wait
48
+ * `RESTART_BASE × 2^n`, capped at `RESTART_CAP`, where `n` counts the
49
+ * activation's failures and rebuilds since its last settled turn: prompt after
50
+ * a one-off failure, bounded for an actor whose turn fails on every attempt.
51
+ */
52
+ const RESTART_BASE = Duration.millis(50);
53
+ const RESTART_CAP = Duration.seconds(5);
54
+ const restartDelay = (restarts) => Duration.min(Duration.times(RESTART_BASE, 2 ** restarts), RESTART_CAP);
55
+ /**
56
+ * The commands an activation holds, waiting and in its current batch, when its
57
+ * policy declares no `mailboxCapacity`. Cluster refuses the next, which
58
+ * dispatch answers `ActorUnavailable`: a hot actor's backlog then waits in its
59
+ * callers' retries, where it holds no memory or turn connection on this runner.
60
+ */
61
+ export const ACTIVATION_MAILBOX = 1024;
62
+ /** The `outcome` attribute of `akter.turns` and of the turn span. */
63
+ const outcomeOf = (outcome, replayed = false) => replayed
64
+ ? "replay"
65
+ : Outcome.match(outcome, {
66
+ Success: () => "success",
67
+ Failure: () => "failure",
68
+ Defect: () => "defect",
69
+ Acknowledged: () => "acknowledged",
70
+ });
71
+ /** Encodes a tenant and actor id as the Cluster entity id. */
72
+ export const encodeEntityId = (tenantAndId) => encodeEntityIdOf(tenantAndId);
73
+ const decodeEntityId = Schema.decodeEffect(EntityId);
74
+ /**
75
+ * How often a singleton's keeper re-wakes the default tenant's instance, and
76
+ * so bounds how long after its shard moves the instance is resident again.
77
+ */
78
+ const SINGLETON_WAKE_INTERVAL = Duration.seconds(1);
79
+ /**
80
+ * Cluster's lifetime of one entity, shared by every handler a defect restart
81
+ * rebuilds within it.
82
+ */
83
+ const entityScope = Effect.serviceOption(Context.Service("effect/cluster/internal/CurrentActivationScope")).pipe(Effect.flatMap(Option.match({
84
+ onNone: () => Effect.die(new Error("Cluster provided no entity scope")),
85
+ onSome: Effect.succeed,
86
+ })));
87
+ /**
88
+ * Runs a batch under its logs and span: a lone command's turn span, a child
89
+ * of its caller's span, or a batch span linked to every caller's span.
90
+ */
91
+ const withinTurnSpan = (batch) => (effect) => {
92
+ const { request } = batch[0];
93
+ const { ref } = request;
94
+ const lone = batch.length === 1;
95
+ return effect.pipe(Effect.annotateLogs(lone
96
+ ? {
97
+ actor: ref.actor,
98
+ id: ref.id,
99
+ tenant: ref.tenant,
100
+ command: request.command,
101
+ commandId: request.commandId,
102
+ }
103
+ : { actor: ref.actor, id: ref.id, tenant: ref.tenant }), Effect.withSpan(lone ? SpanNames.turn(ref.actor, request.command) : SpanNames.batch(ref.actor), {
104
+ kind: lone ? "server" : "internal",
105
+ attributes: lone
106
+ ? requestAttributes(request)
107
+ : {
108
+ "actor.tenant": ref.tenant,
109
+ "actor.id": ref.id,
110
+ "batch.size": batch.length,
111
+ },
112
+ parent: lone ? Context.getOrUndefined(batch[0].context, Tracer.ParentSpan) : undefined,
113
+ links: lone
114
+ ? []
115
+ : batch.flatMap(({ context }) => {
116
+ const span = Context.getOrUndefined(context, Tracer.ParentSpan);
117
+ return span === undefined ? [] : [{ span, attributes: {} }];
118
+ }),
119
+ }, { captureStackTrace: false }));
120
+ };
121
+ /**
122
+ * Defects that say nothing about the command: the activation restarts and
123
+ * the caller retries the same id.
124
+ */
125
+ const retryable = (cause) => {
126
+ const defect = Cause.squash(cause);
127
+ return Schema.is(RetryTurn)(defect) || (SqlError.isSqlError(defect) && transientSqlError(defect));
128
+ };
129
+ /**
130
+ * One entity definition per actor type name, created on first use. Sharding
131
+ * keeps one RPC client per entity object, by identity, until the runtime
132
+ * closes; a fresh entity per call would retain a client per call.
133
+ */
134
+ const oncePerName = (make) => {
135
+ const made = new Map();
136
+ return (name) => {
137
+ const cached = made.get(name);
138
+ if (cached !== undefined)
139
+ return cached;
140
+ const entity = make(name);
141
+ made.set(name, entity);
142
+ return entity;
143
+ };
144
+ };
145
+ /** The command entity definition for an actor type, created once per name. */
146
+ export const commandEntity = oncePerName(makeCommandEntity);
147
+ /** The connection entity definition for an actor type, created once per name. */
148
+ export const connectionEntity = oncePerName(connectionsEntity);
149
+ /**
150
+ * Writes a singleton's missing cron ticks, then keeps its default tenant's
151
+ * instance awake: one keeper re-wakes it every `SINGLETON_WAKE_INTERVAL`, or
152
+ * half the idle time if shorter, so it moves to a survivor with its shard.
153
+ */
154
+ const keepSingletonAwake = Effect.fnUntraced(function* (registration, entity, services) {
155
+ const sharding = yield* Sharding.Sharding;
156
+ const ref = ActorRef.make({
157
+ tenant: registration.tenant,
158
+ actor: registration.name,
159
+ id: "singleton",
160
+ });
161
+ yield* bootstrapTicks(routingKey({ ref, placement: registration.placement }), ref, registration.cron).pipe(Effect.provideContext(services), Effect.orDie);
162
+ const address = yield* encodeEntityId([registration.tenant, "singleton"]).pipe(Effect.orDie);
163
+ const client = (yield* sharding.makeClient(entity))(address);
164
+ const wakeInterval = Duration.min(SINGLETON_WAKE_INTERVAL, Duration.millis(registration.policy.idleMs / 2));
165
+ yield* sharding.registerSingleton(registration.name, client.Wake().pipe(Effect.timeoutOrElse({ duration: wakeInterval, orElse: () => Effect.void }), Effect.catchCause((cause) => Effect.logDebug("Singleton wake failed", cause)), Effect.repeat(Schedule.spaced(wakeInterval))));
166
+ });
167
+ /**
168
+ * Registers an actor type's command entity with Cluster and starts its
169
+ * activations, worker, and singleton keeper.
170
+ *
171
+ * - One worker per handler runs queued commands as turn batches in delivery
172
+ * order, so an activation has one transaction in flight. Commands enqueue
173
+ * synchronously when Cluster delivers the request, and replies follow the
174
+ * batch's commit; broadcasts go out first. With `pipelining`, the next batch
175
+ * already waiting is taken while the previous one commits. Its admission
176
+ * waits until a batch with a workflow command is published, because that
177
+ * batch's kick can re-arm a running execution's timer under the generation
178
+ * row lock the admission would hold, and the next batch may be the very call
179
+ * that execution's activity is waiting on.
180
+ * - A retryable failure committed nothing. The worker ends the activation,
181
+ * waits its backoff, starts the next one in place, and only then answers each
182
+ * unanswered command `ActorUnavailable`, so a caller never retries into the
183
+ * closed activation and never waits out its delivery timeout when Cluster
184
+ * would drop a re-sent command mid-restart (as during a database failover).
185
+ * Restarts never overlap because the one worker serializes them.
186
+ * - A defect aborts the whole batch; a following batch whose admission was
187
+ * already sent is rolled back unseen. After a deterministic defect the
188
+ * failed batch's commands rerun one per transaction so one bad command cannot
189
+ * keep rolling back its neighbours, and a lone command answers `Defect`.
190
+ * Defect hooks do not run, since they can loop on corrupt state. A defect
191
+ * after the batch committed lets redelivered commands replay their receipts.
192
+ * - Restart backoff is kept per activation, because Cluster's own is shared by
193
+ * every entity of the type and never resets.
194
+ * - Each handler's resources live in a child of the entity's scope, closed when
195
+ * a rebuild supersedes it, the handler closes, or the entity ends, because a
196
+ * defect during shutdown can drop the superseded handler's own scope.
197
+ * - Full-mailbox and full-runner rejections share one Cluster error; only an
198
+ * activation already resident can have a full mailbox, and a rebuilt handler
199
+ * can overlap its predecessor, hence the count.
200
+ * - A singleton starts only on the runner holding its shard's lease. Every
201
+ * runner serves its entity, and one keeper re-wakes the default tenant's
202
+ * instance so it moves to a survivor. A failing singleton build answers every
203
+ * command with its defect instead of retrying forever.
204
+ * - A draining runner refuses a batch, or interrupts its run at the deadline,
205
+ * and every unanswered caller retries elsewhere.
206
+ * - The turn span carries no captured stack: its call site is always this file.
207
+ */
208
+ export const registerActor = Effect.fnUntraced(function* (registration, transport, authorize, gate,
209
+ /** Fails while this runtime may not start turns, e.g. its payload writer rows are stale. */
210
+ writable) {
211
+ const sharding = yield* Sharding.Sharding;
212
+ const defects = yield* DefectLog;
213
+ const typeAttributes = { actor_type: registration.name };
214
+ const activations = Metric.withAttributes(Metrics.activations, typeAttributes);
215
+ const owner = activationOwner({
216
+ registration,
217
+ transport,
218
+ authorize,
219
+ clock: yield* FrameworkClock,
220
+ role: (yield* TenantScope).role,
221
+ });
222
+ const ownedOf = (entityId) => Effect.flatMap(Effect.orDie(decodeEntityId(entityId)), ([tenant, id]) => {
223
+ const ref = { actor: registration.name, tenant, id };
224
+ return owner.enter(entityId, ref, routingKey({ ref, placement: registration.placement }));
225
+ });
226
+ const services = yield* Effect.context();
227
+ const usage = Context.getUnsafe(services, UsageAccounting);
228
+ const accounting = accountsUsage(usage) ? usage : undefined;
229
+ const entity = commandEntity(registration.name);
230
+ const routingKeyOf = (ref) => routingKey({ ref, placement: registration.placement });
231
+ const workflowRoutes = workflowCommands({ registration, routingKeyOf, services });
232
+ const waited = new Set([...registration.workflows.values()].flatMap((workflow) => [...workflow.member.registry.steps.values()].flatMap((step) => step.event === undefined ? [] : [step.event])));
233
+ const resident = new Map();
234
+ const building = new Set();
235
+ const workers = new Map();
236
+ const lease = registration.singleton
237
+ ? Option.getOrUndefined(yield* Effect.serviceOption(ShardLease))
238
+ : undefined;
239
+ /**
240
+ * Counts a handler of `entityId` as resident until its scope closes; a
241
+ * rebuilt handler can overlap its predecessor, hence the count.
242
+ */
243
+ const residentWhile = (entityId) => Effect.acquireRelease(Effect.sync(() => resident.set(entityId, (resident.get(entityId) ?? 0) + 1)).pipe(Effect.andThen(count(Metrics.activationsStarted, typeAttributes, 1)), Effect.andThen(Metric.modify(activations, 1))), () => Effect.sync(() => {
244
+ const left = resident.get(entityId) - 1;
245
+ if (left === 0)
246
+ resident.delete(entityId);
247
+ else
248
+ resident.set(entityId, left);
249
+ }).pipe(Effect.andThen(Metric.modify(activations, -1))));
250
+ /**
251
+ * Runs a delivered command's `queued` hook under the runtime's services,
252
+ * captures the context its turn runs in, and waits for its reply. Defined
253
+ * once per actor type because a generator built for every delivery is
254
+ * compiled again and again as the engine sees new copies of it.
255
+ */
256
+ const awaitReply = Effect.fnUntraced(function* (entry, mailbox) {
257
+ entry.context = yield* Effect.context();
258
+ yield* (yield* TurnHooks)
259
+ .at("queued", entry.request)
260
+ .pipe(Effect.ensuring(Effect.sync(() => mailbox.queued(entry))));
261
+ return yield* Deferred.await(entry.reply);
262
+ }, Effect.provideContext(services));
263
+ /** Counts what a committed batch wrote. */
264
+ const countWritten = Effect.fnUntraced(function* (done) {
265
+ yield* count(Metrics.receiptsReplayed, typeAttributes, done.replays.size);
266
+ yield* count(Metrics.receiptsWritten, typeAttributes, done.written.receipts);
267
+ yield* count(Metrics.eventsAppended, typeAttributes, done.written.events);
268
+ yield* count(Metrics.outboxStaged, { kind: "intent" }, done.written.intents);
269
+ yield* count(Metrics.outboxStaged, { kind: "job" }, done.written.jobs);
270
+ });
271
+ /**
272
+ * Records a deterministic defect in the defect log under its turn span's
273
+ * name and trace, and marks the span's outcome.
274
+ */
275
+ const recordDefect = (request, cause) => Effect.gen(function* () {
276
+ const span = yield* Effect.currentSpan.pipe(Effect.option);
277
+ yield* defects.record({
278
+ span: SpanNames.turn(request.ref.actor, request.command),
279
+ traceId: Option.isSome(span) ? span.value.traceId : "",
280
+ spanId: Option.isSome(span) ? span.value.spanId : "",
281
+ atMs: yield* Clock.currentTimeMillis,
282
+ tenant: request.ref.tenant,
283
+ actorType: request.ref.actor,
284
+ actorId: request.ref.id,
285
+ command: request.command,
286
+ commandId: request.commandId,
287
+ trigger: triggerOf(request),
288
+ cause: Cause.pretty(Cause.die(Cause.squash(cause))),
289
+ });
290
+ yield* Effect.annotateCurrentSpan({ "turn.outcome": "defect" });
291
+ });
292
+ const leaseLostDefect = RetryTurn.make({
293
+ message: "Singleton runner no longer holds its shard lock",
294
+ });
295
+ const leaseLost = Effect.die(leaseLostDefect);
296
+ const restartIncomplete = RetryTurn.make({ message: "Activation restart did not complete" });
297
+ /**
298
+ * What each Cluster entity scope keeps across the handlers a defect restart
299
+ * rebuilds within it: rebuilds and in-place restarts since its last settled
300
+ * turn, absent until the first build so only a rebuild waits; the current
301
+ * handler's scope, closed when a rebuild supersedes it; and the ids of a
302
+ * batch a retryable failure aborted, each to run alone once.
303
+ */
304
+ const memories = new WeakMap();
305
+ const register = sharding.registerEntity(entity, Effect.gen(function* () {
306
+ const activation = yield* entityScope;
307
+ const memory = memories.get(activation) ?? {
308
+ restarts: undefined,
309
+ handler: undefined,
310
+ alone: new Set(),
311
+ };
312
+ memories.set(activation, memory);
313
+ const rebuilt = memory.restarts;
314
+ memory.restarts = rebuilt === undefined ? 0 : rebuilt + 1;
315
+ const { entityId } = yield* Entity.CurrentAddress;
316
+ building.add(entityId);
317
+ yield* Effect.addFinalizer(() => Effect.sync(() => building.delete(entityId)));
318
+ if (rebuilt !== undefined)
319
+ yield* Effect.sleep(restartDelay(rebuilt));
320
+ const [tenant, id] = yield* decodeEntityId(entityId).pipe(Effect.orDie);
321
+ if (memory.handler !== undefined)
322
+ yield* Scope.close(memory.handler, Exit.void);
323
+ const shard = lease === undefined
324
+ ? undefined
325
+ : ShardId.toString(yield* entity.getShardId(ClusterEntityId.make(entityId)));
326
+ if (lease !== undefined && !(yield* lease.holds(shard)))
327
+ return yield* leaseLost;
328
+ /**
329
+ * Why this handler refuses all work: its singleton lease is lost, or an
330
+ * in-place restart failed and the worker ended. Set once, never cleared;
331
+ * Cluster builds a new handler for the next delivery.
332
+ */
333
+ let refused;
334
+ const handler = yield* Scope.fork(activation);
335
+ memory.handler = handler;
336
+ yield* residentWhile(entityId).pipe(Scope.provide(handler));
337
+ const start = Effect.gen(function* () {
338
+ const scope = yield* Scope.fork(handler);
339
+ if (lease !== undefined)
340
+ yield* lease.holds(shard).pipe(Effect.repeat({ schedule: Schedule.spaced(lease.interval), until: (held) => !held }), Effect.andThen(Effect.sync(() => {
341
+ refused = leaseLostDefect;
342
+ })), Effect.andThen(Effect.forkDetach(Scope.close(scope, Exit.void))), Effect.forkIn(scope));
343
+ const owned = yield* ownedOf(entityId).pipe(Scope.provide(scope));
344
+ const activated = yield* registration
345
+ .activate(ActorRef.make({ tenant, actor: registration.name, id }))
346
+ .pipe(Scope.provide(scope), Effect.exit);
347
+ if (Exit.isFailure(activated))
348
+ yield* Effect.logError("Actor activation failed", activated.cause).pipe(Effect.annotateLogs({ actor: registration.name, id, tenant }));
349
+ const started = { scope, owned, activated, engine: undefined };
350
+ return started;
351
+ });
352
+ const built = yield* Effect.context();
353
+ let current = yield* start;
354
+ yield* Effect.addFinalizer(() => Scope.close(handler, Exit.void));
355
+ const policy = registration.policy;
356
+ const statements = registration.tables.length > 0 || registration.blobs.length > 0;
357
+ const mailbox = activationMailbox(memory.alone);
358
+ let phase = "idle";
359
+ const restart = (batch, cause) => Effect.sync(() => {
360
+ refused ??= restartIncomplete;
361
+ }).pipe(Effect.andThen(Effect.forEach(batch, (entry) => entry.request.external !== true
362
+ ? Deferred.failCause(entry.reply, Cause.die(Cause.squash(cause)))
363
+ : Deferred.fail(entry.reply, DeliveryFailed.make({
364
+ error: ActorError.make({
365
+ reason: ActorUnavailable.make({ cause: Cause.squash(cause) }),
366
+ }),
367
+ admitted: entry.admitted === true,
368
+ })), { discard: true })), Effect.andThen(Effect.interrupt));
369
+ const restartActivation = (batch, orphan, cause) => Effect.gen(function* () {
370
+ const failures = memory.restarts ?? 0;
371
+ phase = "restarting";
372
+ memory.restarts = failures + 1;
373
+ yield* Scope.close(current.scope, Exit.void);
374
+ yield* Effect.sleep(restartDelay(failures));
375
+ if (lease !== undefined && !(yield* lease.holds(shard))) {
376
+ refused = leaseLostDefect;
377
+ return yield* Effect.die(leaseLostDefect);
378
+ }
379
+ current = yield* start.pipe(Effect.provideContext(built));
380
+ mailbox.requeue(orphan);
381
+ const unavailable = ActorError.make({
382
+ reason: ActorUnavailable.make({ cause: Cause.squash(cause) }),
383
+ });
384
+ yield* Effect.forEach(batch, (entry) => entry.request.external !== true
385
+ ? Deferred.fail(entry.reply, unavailable)
386
+ : Deferred.fail(entry.reply, DeliveryFailed.make({ error: unavailable, admitted: entry.admitted === true })), { discard: true });
387
+ }).pipe(Effect.uninterruptible, Effect.catchCause((failed) => restart([...batch, ...orphan], failed)));
388
+ const resolve = (batch) => {
389
+ const { activated } = current;
390
+ if (Exit.isSuccess(activated))
391
+ for (const entry of batch)
392
+ entry.command =
393
+ activated.value.get(entry.request.command) ??
394
+ workflowRoutes.get(entry.request.command) ??
395
+ entry.command;
396
+ return batch;
397
+ };
398
+ let taken = [];
399
+ const following = Effect.gen(function* () {
400
+ if (refused !== undefined ||
401
+ !gate.open ||
402
+ Exit.isFailure(current.activated) ||
403
+ Exit.isFailure(yield* Effect.exit(writable)))
404
+ return undefined;
405
+ const batch = resolve(mailbox.take());
406
+ taken.push(...batch);
407
+ return batch.length > 0 ? batch : undefined;
408
+ });
409
+ const labelled = new WeakMap();
410
+ /**
411
+ * The one owner of an ended batch's publication, in this order: wake the
412
+ * relay and running job attempts for obligations the commit made due or
413
+ * cancelled; record the batch's outcomes; end the transient progress of
414
+ * commands and jobs the batch settled; send its broadcasts, feed frames
415
+ * and watch updates to connections; then, per command in delivery order,
416
+ * run its `afterCommit` point, kick the workflow execution it started or
417
+ * resumed, and answer its caller. These steps follow the commit but are
418
+ * not atomic with it or with each other. A failure part-way stops the run
419
+ * as committed, so every command left unanswered is restarted and
420
+ * resolves through its receipt; a lost broadcast is not replayed.
421
+ */
422
+ const publish = Effect.fnUntraced(function* (batch, done) {
423
+ const { owned } = current;
424
+ const outbox = yield* OutboxRuntime;
425
+ if (done.wake)
426
+ yield* outbox.wake;
427
+ if (done.cancelled)
428
+ yield* outbox.cancelled;
429
+ const labels = done.settled.map((settled, index) => Result.isSuccess(settled)
430
+ ? outcomeOf(settled.success, done.replays.has(index))
431
+ : "rejected");
432
+ labelled.set(batch, labels);
433
+ yield* Effect.annotateCurrentSpan({ "actor.generation": done.generation });
434
+ if (batch.length === 1 && Result.isSuccess(done.settled[0]))
435
+ yield* Effect.annotateCurrentSpan({
436
+ "turn.replayed": done.replays.has(0),
437
+ "turn.outcome": labels[0],
438
+ });
439
+ yield* countWritten(done);
440
+ if (owner.hasProgress) {
441
+ for (const [index, settled] of done.settled.entries())
442
+ if (Result.isSuccess(settled) && !Outcome.guards.Defect(settled.success))
443
+ yield* owner.closeProgress(owned, batch[index].request.commandId);
444
+ for (const jobId of done.cancelledJobs)
445
+ yield* owner.closeProgress(owned, jobId);
446
+ }
447
+ if (owner.hasConnections || owner.hasStreams) {
448
+ for (const { request } of batch)
449
+ yield* (yield* TurnHooks).at("beforeFlush", request);
450
+ const feeds = yield* Effect.forEach(done.committed, owner.feedBroadcasts);
451
+ const watches = yield* owner.watchBroadcasts(owned, done.wrote, done.version);
452
+ yield* owner.flush(owned, [...done.broadcasts, ...feeds.flat(), ...watches], done.head);
453
+ }
454
+ for (const [index, settled] of done.settled.entries()) {
455
+ const entry = batch[index];
456
+ if (Result.isFailure(settled)) {
457
+ yield* Deferred.fail(entry.reply, settled.failure);
458
+ continue;
459
+ }
460
+ const outcome = settled.success;
461
+ memory.restarts = 0;
462
+ if (!Outcome.guards.Defect(outcome)) {
463
+ yield* (yield* TurnHooks).at("afterCommit", entry.request);
464
+ const kicked = workflowRoutes.has(entry.request.command)
465
+ ? yield* kickedExecution({ request: entry.request, outcome })
466
+ : undefined;
467
+ if (kicked !== undefined) {
468
+ phase = "workflow kick";
469
+ current.engine ??= yield* activationEngine({
470
+ registration,
471
+ ref: entry.request.ref,
472
+ routingKey: routingKeyOf(entry.request.ref),
473
+ cache: current.owned.cache,
474
+ scope: current.scope,
475
+ deliveryMs: policy.deliveryMs,
476
+ });
477
+ yield* current.engine.kick(kicked.executionId, kicked.interrupt);
478
+ phase = "turn";
479
+ }
480
+ }
481
+ const executed = done.replays.has(index)
482
+ ? { outcome, version: done.version, endedAtMs: done.endedAtMs, replayed: true }
483
+ : { outcome, version: done.version, endedAtMs: done.endedAtMs };
484
+ yield* Deferred.succeed(entry.reply, executed);
485
+ }
486
+ });
487
+ /** Records a finished batch's turn outcomes and duration, or the defect that ended it. */
488
+ const observed = Effect.fnUntraced(function* (batch, started, exit) {
489
+ const { request } = batch[0];
490
+ const lone = batch.length === 1;
491
+ const labels = labelled.get(batch);
492
+ const elapsed = (yield* Clock.currentTimeMillis) - started;
493
+ if (labels === undefined && Exit.isFailure(exit)) {
494
+ if (Cause.hasInterruptsOnly(exit.cause))
495
+ return;
496
+ if (!retryable(exit.cause) && !lone)
497
+ return;
498
+ const deterministic = !retryable(exit.cause);
499
+ if (deterministic)
500
+ yield* recordDefect(request, exit.cause);
501
+ yield* count(Metrics.turns, { ...typeAttributes, outcome: deterministic ? "defect" : "retried" }, batch.length);
502
+ yield* record(Metrics.turnDuration, typeAttributes, elapsed);
503
+ return;
504
+ }
505
+ for (const label of labels ?? [])
506
+ yield* count(Metrics.turns, { ...typeAttributes, outcome: label }, 1);
507
+ yield* record(Metrics.turnDuration, typeAttributes, elapsed);
508
+ });
509
+ const observe = (batch) => (effect) => Effect.flatMap(Clock.currentTimeMillis, (started) => Effect.forEach(batch, ({ request: queued }) => queued.queuedAtMs === undefined
510
+ ? Effect.void
511
+ : record(Metrics.mailboxAge, typeAttributes, Math.max(0, started - queued.queuedAtMs)), { discard: true }).pipe(Effect.andThen(effect), Effect.onExit((exit) => observed(batch, started, exit)), withinTurnSpan(batch)));
512
+ const run = (batch, pipelining) => {
513
+ const { owned } = current;
514
+ return executeBatches({
515
+ first: batch,
516
+ next: pipelining ? following : Effect.undefined,
517
+ prepare: owner.prepare(owned),
518
+ committed: publish,
519
+ publishesUnderLock: (batch) => batch.some(({ request }) => workflowRoutes.has(request.command)),
520
+ observe,
521
+ }, owned.cache, owned.key, policy, registration.mintable, parentPlacement(registration.placement)?.parent, statements, waited, owner.hasConnections ? owner.list(owned) : undefined, registration.cron, accounting);
522
+ };
523
+ const recover = Effect.fnUntraced(function* ({ batch, orphan, cause, committed, poolRefused }) {
524
+ if (poolRefused === true) {
525
+ mailbox.requeue(orphan ?? []);
526
+ yield* Effect.forEach(batch, (entry) => Deferred.fail(entry.reply, overloaded("runner")), {
527
+ discard: true,
528
+ });
529
+ return;
530
+ }
531
+ if (committed || retryable(cause)) {
532
+ if (!committed && batch.length > 1)
533
+ mailbox.isolate(batch.map(({ request }) => request.commandId));
534
+ if (committed || refused !== undefined)
535
+ return yield* restart([...batch, ...(orphan ?? [])], cause);
536
+ return yield* restartActivation(batch, orphan ?? [], cause);
537
+ }
538
+ mailbox.requeue(orphan ?? []);
539
+ if (batch.length === 1) {
540
+ const { request } = batch[0];
541
+ const defect = Cause.squash(cause);
542
+ yield* Effect.logError("Deterministic actor defect", Cause.die(defect)).pipe(Effect.annotateLogs({
543
+ actor: request.ref.actor,
544
+ id: request.ref.id,
545
+ tenant: request.ref.tenant,
546
+ command: request.command,
547
+ commandId: request.commandId,
548
+ }));
549
+ memory.restarts = 0;
550
+ return yield* Deferred.succeed(batch[0].reply, {
551
+ outcome: Outcome.cases.Defect.make({ cause: defect }),
552
+ });
553
+ }
554
+ yield* Effect.logDebug("Turn batch failed; running its commands one at a time", cause);
555
+ for (const entry of batch) {
556
+ const stopped = yield* run(resolve([entry]), false);
557
+ if (stopped !== undefined)
558
+ yield* recover(stopped);
559
+ }
560
+ }, Effect.provideContext(services));
561
+ const turnBatch = Effect.fnUntraced(function* (batch) {
562
+ if (refused !== undefined)
563
+ return yield* restart(batch, Cause.die(refused));
564
+ yield* writable;
565
+ const stopped = yield* run(batch, true);
566
+ if (stopped !== undefined)
567
+ yield* recover(stopped);
568
+ });
569
+ yield* Effect.gen(function* () {
570
+ while (true) {
571
+ phase = "idle";
572
+ taken = [];
573
+ yield* mailbox.await;
574
+ const batch = resolve(mailbox.take());
575
+ if (batch.length === 0)
576
+ continue;
577
+ phase = "turn";
578
+ taken = [...batch];
579
+ if (Exit.isFailure(current.activated)) {
580
+ const { cause } = current.activated;
581
+ yield* Effect.forEach(batch, (entry) => Deferred.succeed(entry.reply, {
582
+ outcome: Outcome.cases.Defect.make({ cause: Cause.squash(cause) }),
583
+ }), { discard: true });
584
+ continue;
585
+ }
586
+ yield* gate.run(turnBatch(batch)).pipe(Effect.catchIf(Schema.is(ActorError), (error) => Effect.forEach(taken, (entry) => Deferred.fail(entry.reply, error), {
587
+ discard: true,
588
+ })), Effect.provideContext(batch[0].context), Effect.catchCauseIf((cause) => !Cause.hasInterruptsOnly(cause), (cause) => restart(batch, cause)));
589
+ }
590
+ }).pipe(Effect.provideContext(services), Effect.forkIn(handler));
591
+ const diagnose = () => ({ worker: phase, mailbox: mailbox.size(), batch: taken.length });
592
+ workers.set(entityId, diagnose);
593
+ building.delete(entityId);
594
+ yield* Effect.addFinalizer(() => Effect.sync(() => {
595
+ if (workers.get(entityId) === diagnose)
596
+ workers.delete(entityId);
597
+ }));
598
+ return entity.of({
599
+ Wake: () => Effect.suspend(() => (refused === undefined ? Effect.void : Effect.die(refused))),
600
+ Execute: ({ payload }) => {
601
+ if (refused !== undefined)
602
+ return Effect.die(refused);
603
+ const { activated } = current;
604
+ if (Exit.isFailure(activated))
605
+ return Effect.succeed({
606
+ outcome: Outcome.cases.Defect.make({ cause: Cause.squash(activated.cause) }),
607
+ });
608
+ const command = activated.value.get(payload.command) ?? workflowRoutes.get(payload.command);
609
+ if (command === undefined)
610
+ return Effect.die(new Error(`Unregistered command ${payload.command}`));
611
+ const entry = {
612
+ request: payload,
613
+ command,
614
+ reply: Deferred.makeUnsafe(),
615
+ context: Context.empty(),
616
+ queued: false,
617
+ };
618
+ mailbox.offer(entry);
619
+ return Rpc.fork(awaitReply(entry, mailbox));
620
+ },
621
+ });
622
+ }), {
623
+ concurrency: 1,
624
+ maxIdleTime: registration.policy.idleMs,
625
+ mailboxCapacity: registration.policy.mailboxCapacity === "unbounded"
626
+ ? ACTIVATION_MAILBOX
627
+ : registration.policy.mailboxCapacity,
628
+ defectRetryPolicy: Schedule.forever,
629
+ });
630
+ const connections = connectionEntity(registration.name);
631
+ const connectionServices = yield* Effect.context();
632
+ yield* register;
633
+ if (owner.hasConnections || owner.hasStreams)
634
+ yield* sharding.registerEntity(connections, Effect.gen(function* () {
635
+ const { entityId } = yield* Entity.CurrentAddress;
636
+ const owned = yield* ownedOf(entityId);
637
+ yield* Effect.addFinalizer(() => owner.endStreams(owned));
638
+ return connections.of({
639
+ Progress: ({ payload }) => owner.progress(owned, payload).pipe(Effect.provideContext(connectionServices)),
640
+ ProgressClosed: ({ payload }) => owner.progressClosed(owned, payload).pipe(Effect.provideContext(connectionServices)),
641
+ Subscribe: ({ payload }) => owner.subscribe(owned, payload).pipe(Stream.provideContext(connectionServices)),
642
+ Open: ({ payload }) => owner.open(owned, payload).pipe(Effect.provideContext(connectionServices)),
643
+ Frame: ({ payload }) => owner.frame(owned, payload).pipe(Effect.provideContext(connectionServices)),
644
+ Close: ({ payload }) => owner.close(owned, payload).pipe(Effect.provideContext(connectionServices)),
645
+ Resync: ({ payload }) => owner.resync(owned, payload).pipe(Effect.provideContext(connectionServices)),
646
+ });
647
+ }), { concurrency: "unbounded", maxIdleTime: registration.policy.idleMs });
648
+ if (owner.hasStreams)
649
+ yield* owner.watchStreams.pipe(Effect.forkScoped);
650
+ if (registration.singleton)
651
+ yield* keepSingletonAwake(registration, entity, services);
652
+ return {
653
+ isResident: (entityId) => resident.has(entityId),
654
+ owner,
655
+ /** This type's view of one activation, for a delivery that timed out. */
656
+ diagnose: (entityId) => ({
657
+ handlers: resident.get(entityId) ?? 0,
658
+ building: building.has(entityId),
659
+ ...(workers.get(entityId)?.() ?? { worker: "none", mailbox: 0, batch: 0 }),
660
+ }),
661
+ /** Activations of this type being rebuilt or restarted in place now. */
662
+ restarting: () => [
663
+ ...new Set([
664
+ ...building,
665
+ ...[...workers].flatMap(([entityId, diagnose]) => diagnose().worker === "restarting" ? [entityId] : []),
666
+ ]),
667
+ ],
668
+ };
669
+ });