@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,192 @@
1
+ import { Effect } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ import { adoptionTargets, qualifiedName } from "./target.js";
4
+ const identifier = (name) => `"${name.replaceAll('"', '""')}"`;
5
+ /** `"schema"."table"`, quoted for the SQL the CLI prints and runs. */
6
+ export const quotedTable = (target) => `${identifier(target.schema)}.${identifier(target.table)}`;
7
+ /** The index columns a scoped statement leads with: `routing_key` first when the runtime writes the table. */
8
+ export const ownerIndexColumns = (target) => [
9
+ ...(target.access === "write" ? ["routing_key"] : []),
10
+ target.tenantColumn,
11
+ target.actorColumn,
12
+ ];
13
+ /** The statement that adds an index leading with the mapped columns. */
14
+ export const ownerIndexSql = (target) => `CREATE INDEX CONCURRENTLY IF NOT EXISTS ${identifier(`${target.table}_durable_owner`)} ON ${quotedTable(target)} (${ownerIndexColumns(target).map(identifier).join(", ")})`;
15
+ /**
16
+ * The problems that stop a table from being adopted as declared: it must
17
+ * exist, its mapped columns must exist, and they must be text, varchar, or uuid
18
+ * with a deterministic collation. Shared by `plan` and `observe`.
19
+ */
20
+ export const mappingProblems = Effect.fnUntraced(function* (target) {
21
+ const sql = yield* SqlClient.SqlClient;
22
+ const exists = yield* sql `SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
23
+ WHERE n.nspname = ${target.schema} AND c.relname = ${target.table} AND c.relkind IN ('r', 'p')`;
24
+ if (exists.length === 0)
25
+ return [`${qualifiedName(target)} does not exist`];
26
+ const columns = yield* sql `
27
+ SELECT a.attname AS name, t.typname AS type, co.collisdeterministic AS deterministic,
28
+ a.attnotnull AS not_null
29
+ FROM pg_attribute a
30
+ JOIN pg_class c ON c.oid = a.attrelid JOIN pg_namespace n ON n.oid = c.relnamespace
31
+ JOIN pg_type t ON t.oid = a.atttypid
32
+ LEFT JOIN pg_collation co ON co.oid = a.attcollation AND a.attcollation <> 0
33
+ WHERE n.nspname = ${target.schema} AND c.relname = ${target.table}
34
+ AND a.attnum > 0 AND NOT a.attisdropped
35
+ AND a.attname IN (${target.tenantColumn}, ${target.actorColumn})`;
36
+ const problems = [];
37
+ for (const [role, name, kind] of [
38
+ ["tenant", target.tenantColumn, target.tenantKind],
39
+ ["actor", target.actorColumn, target.actorKind],
40
+ ]) {
41
+ const column = columns.find((candidate) => candidate.name === name);
42
+ if (column === undefined) {
43
+ problems.push(`${role} column ${name} does not exist in ${qualifiedName(target)}`);
44
+ continue;
45
+ }
46
+ if (column.type === "citext" || !["text", "varchar", "uuid"].includes(column.type)) {
47
+ problems.push(`${role} column ${name} is ${column.type}; only text, varchar, and uuid columns can be mapped`);
48
+ continue;
49
+ }
50
+ if ((column.type === "uuid") !== (kind === "uuid"))
51
+ problems.push(`${role} column ${name} is ${column.type} but is declared as a ${kind} column`);
52
+ if (column.deterministic === false)
53
+ problems.push(`${role} column ${name} has a nondeterministic collation`);
54
+ }
55
+ return problems;
56
+ });
57
+ const tableOid = (target) => `(SELECT c.oid FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = '${target.schema.replaceAll("'", "''")}' AND c.relname = '${target.table.replaceAll("'", "''")}')`;
58
+ const hasOwnerIndex = Effect.fnUntraced(function* (target) {
59
+ const sql = yield* SqlClient.SqlClient;
60
+ const expected = ownerIndexColumns(target);
61
+ const leading = yield* sql.unsafe(`SELECT array_agg(a.attname ORDER BY k.ord) AS columns
62
+ FROM pg_index i
63
+ JOIN pg_class ic ON ic.oid = i.indexrelid
64
+ JOIN pg_am am ON am.oid = ic.relam AND am.amname = 'btree'
65
+ CROSS JOIN LATERAL unnest(i.indkey::int2[]) WITH ORDINALITY AS k(attnum, ord)
66
+ JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = k.attnum
67
+ WHERE i.indrelid = ${tableOid(target)} AND i.indpred IS NULL AND i.indexprs IS NULL
68
+ AND k.ord <= ${expected.length}
69
+ GROUP BY i.indexrelid`);
70
+ return leading.some((index) => index.columns.length === expected.length && index.columns.join() === expected.join());
71
+ });
72
+ /** True when an index leading with the mapped columns exists, so scoped statements do not scan the table. */
73
+ export const ownerIndexExists = hasOwnerIndex;
74
+ /**
75
+ * Reads the catalog for every adopted table of `actors` and reports what
76
+ * adoption would meet, and the SQL each step would run. Changes nothing.
77
+ */
78
+ export const planAdoption = Effect.fnUntraced(function* (actors, only) {
79
+ const sql = yield* SqlClient.SqlClient;
80
+ const plans = [];
81
+ for (const target of yield* adoptionTargets(actors, only)) {
82
+ const name = qualifiedName(target);
83
+ const problems = [...(yield* mappingProblems(target))];
84
+ const warnings = [];
85
+ const exists = !problems.some((problem) => problem.endsWith("does not exist"));
86
+ if (!exists) {
87
+ plans.push({
88
+ table: name,
89
+ actor: target.actor,
90
+ access: target.access,
91
+ problems,
92
+ warnings,
93
+ foreignKeys: [],
94
+ triggers: [],
95
+ rules: [],
96
+ views: [],
97
+ owner: "",
98
+ writers: [],
99
+ indexSql: undefined,
100
+ steps: [],
101
+ });
102
+ continue;
103
+ }
104
+ const oid = tableOid(target);
105
+ const foreign = yield* sql.unsafe(`SELECT con.conname AS name, pg_get_constraintdef(con.oid) AS definition,
106
+ con.confrelid = ${oid} AS incoming, con.confdeltype AS delete_action
107
+ FROM pg_constraint con
108
+ WHERE con.contype = 'f' AND (con.conrelid = ${oid} OR con.confrelid = ${oid})
109
+ ORDER BY con.conname`);
110
+ const triggers = yield* sql.unsafe(`SELECT tgname AS name FROM pg_trigger
111
+ WHERE tgrelid = ${oid} AND NOT tgisinternal AND tgname NOT LIKE 'actor\\_adoption\\_%'
112
+ ORDER BY tgname`);
113
+ const rules = yield* sql.unsafe(`SELECT rulename AS name FROM pg_rules
114
+ WHERE schemaname = '${target.schema.replaceAll("'", "''")}'
115
+ AND tablename = '${target.table.replaceAll("'", "''")}'
116
+ ORDER BY rulename`);
117
+ const views = yield* sql.unsafe(`SELECT DISTINCT vn.nspname || '.' || v.relname AS name
118
+ FROM pg_depend d
119
+ JOIN pg_rewrite r ON r.oid = d.objid
120
+ JOIN pg_class v ON v.oid = r.ev_class AND v.relkind = 'v'
121
+ JOIN pg_namespace vn ON vn.oid = v.relnamespace
122
+ WHERE d.refobjid = ${oid} AND d.classid = 'pg_rewrite'::regclass
123
+ ORDER BY 1`);
124
+ const owner = (yield* sql.unsafe(`SELECT r.rolname AS name FROM pg_class c JOIN pg_roles r ON r.oid = c.relowner
125
+ WHERE c.oid = ${oid}`))[0].name;
126
+ const writers = yield* sql.unsafe(`SELECT r.rolname AS name FROM pg_roles r
127
+ WHERE r.rolname !~ '^pg_' AND has_table_privilege(r.oid, ${oid}, 'INSERT, UPDATE, DELETE, TRUNCATE')
128
+ ORDER BY r.rolname`);
129
+ const keyless = target.primaryKey.length === 0 && target.access === "write";
130
+ if (keyless)
131
+ problems.push(`${name} has no primary key, which upserts and backfill need`);
132
+ for (const column of [target.tenantColumn, target.actorColumn]) {
133
+ const notNull = yield* sql.unsafe(`SELECT attnotnull AS not_null FROM pg_attribute
134
+ WHERE attrelid = ${oid} AND attname = '${column.replaceAll("'", "''")}'`);
135
+ if (notNull[0]?.not_null === false)
136
+ warnings.push(`${column} is nullable; enforce adds a check constraint and refuses rows with NULL`);
137
+ }
138
+ for (const key of foreign) {
139
+ if (key.incoming)
140
+ continue;
141
+ if (target.access === "write")
142
+ warnings.push(`foreign key ${key.name} from ${name} to a shared parent adds multixact contention on a high-volume actor table`);
143
+ if (key.delete_action === "c" || key.delete_action === "n")
144
+ warnings.push(`foreign key ${key.name} of ${name} has ${key.delete_action === "c" ? "ON DELETE CASCADE" : "ON DELETE SET NULL"} on its parent, so a parent delete would change this table as its owner; enforce refuses until it is resolved`);
145
+ }
146
+ const indexed = yield* hasOwnerIndex(target);
147
+ const index = indexed ? undefined : ownerIndexSql(target);
148
+ if (index !== undefined)
149
+ warnings.push(`no index leads with (${ownerIndexColumns(target).join(", ")}); every scoped statement scans the table and startup refuses`);
150
+ const quoted = quotedTable(target);
151
+ const indexSteps = index === undefined ? [] : [index];
152
+ const steps = target.access === "read"
153
+ ? indexSteps
154
+ : [
155
+ ...indexSteps,
156
+ `ALTER TABLE ${quoted} ADD COLUMN IF NOT EXISTS routing_key bigint`,
157
+ `CREATE TRIGGER actor_adoption_observe_insert AFTER INSERT ON ${quoted} REFERENCING NEW TABLE AS new_rows FOR EACH STATEMENT EXECUTE FUNCTION actor_adoption_observe()`,
158
+ `CREATE TRIGGER actor_adoption_observe_update AFTER UPDATE ON ${quoted} REFERENCING OLD TABLE AS old_rows NEW TABLE AS new_rows FOR EACH STATEMENT EXECUTE FUNCTION actor_adoption_observe()`,
159
+ `CREATE TRIGGER actor_adoption_observe_delete AFTER DELETE ON ${quoted} REFERENCING OLD TABLE AS old_rows FOR EACH STATEMENT EXECUTE FUNCTION actor_adoption_observe()`,
160
+ `CREATE TRIGGER actor_adoption_observe_truncate AFTER TRUNCATE ON ${quoted} FOR EACH STATEMENT EXECUTE FUNCTION actor_adoption_observe()`,
161
+ ];
162
+ plans.push({
163
+ table: name,
164
+ actor: target.actor,
165
+ access: target.access,
166
+ problems,
167
+ warnings,
168
+ foreignKeys: foreign.map((key) => `${key.name}: ${key.definition}`),
169
+ triggers: triggers.map(({ name }) => name),
170
+ rules: rules.map(({ name }) => name),
171
+ views: views.map(({ name }) => name),
172
+ owner,
173
+ writers: writers.map(({ name }) => name),
174
+ indexSql: index,
175
+ steps,
176
+ });
177
+ }
178
+ return plans;
179
+ });
180
+ /** What `plan` prints: one block per table. */
181
+ export const formatAdoptionPlan = (plan) => [
182
+ `${plan.table} (${plan.actor}, ${plan.access === "read" ? "read only" : "writable"})`,
183
+ ...plan.problems.map((problem) => ` problem: ${problem}`),
184
+ ...plan.warnings.map((warning) => ` warning: ${warning}`),
185
+ ...(plan.owner === "" ? [] : [` owner: ${plan.owner}`]),
186
+ ...(plan.writers.length === 0 ? [] : [` roles that can write: ${plan.writers.join(", ")}`]),
187
+ ...plan.foreignKeys.map((key) => ` foreign key ${key}`),
188
+ ...plan.triggers.map((trigger) => ` existing trigger ${trigger}`),
189
+ ...plan.rules.map((rule) => ` existing rule ${rule}`),
190
+ ...plan.views.map((view) => ` view over the table: ${view}`),
191
+ ...plan.steps.map((step) => ` ${step};`),
192
+ ].join("\n");
@@ -0,0 +1,32 @@
1
+ import { Effect } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ import type { AdoptionTarget } from "./target.ts";
4
+ /**
5
+ * Refuses an enforced table whose protection was changed behind the
6
+ * runtime's back. `refuse` names the table and the fix. The guard triggers
7
+ * must exist, be enabled always, and carry exactly the recorded writer,
8
+ * allowed roles, columns, and actor type; no role but the writer and the
9
+ * allowed ones may hold a write privilege, so a grant added later is caught
10
+ * here and by the trigger.
11
+ */
12
+ export declare const checkEnforcedTable: (args_0: {
13
+ readonly target: Pick<AdoptionTarget, "schema" | "table" | "tenantColumn" | "actorColumn" | "actor">;
14
+ readonly writerRole: string;
15
+ readonly allowedRoles: ReadonlyArray<string>;
16
+ readonly runtimeRole: string | undefined;
17
+ readonly refuse: (message: string) => Effect.Effect<never>;
18
+ }) => Effect.Effect<undefined, import("effect/sql/SqlError").SqlError, SqlClient.SqlClient>;
19
+ /**
20
+ * Refuses a writer role a turn cannot run as: it must exist, this login must
21
+ * be able to take it, and it must read and write every framework table and
22
+ * every table in `tables` without owning one, because the whole turn runs as
23
+ * the writer.
24
+ */
25
+ export declare const checkWriterRole: (args_0: {
26
+ readonly role: string;
27
+ readonly tables: ReadonlyArray<{
28
+ readonly schema: string;
29
+ readonly table: string;
30
+ }>;
31
+ readonly refuse: (message: string) => Effect.Effect<never>;
32
+ }) => Effect.Effect<undefined, import("effect/sql/SqlError").SqlError, SqlClient.SqlClient>;
@@ -0,0 +1,76 @@
1
+ import { Effect } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ import { guardArguments, writeGrants } from "./enforce.js";
4
+ const GUARD_ROW_TYPE = 31;
5
+ const GUARD_TRUNCATE_TYPE = 34;
6
+ /**
7
+ * Refuses an enforced table whose protection was changed behind the
8
+ * runtime's back. `refuse` names the table and the fix. The guard triggers
9
+ * must exist, be enabled always, and carry exactly the recorded writer,
10
+ * allowed roles, columns, and actor type; no role but the writer and the
11
+ * allowed ones may hold a write privilege, so a grant added later is caught
12
+ * here and by the trigger.
13
+ */
14
+ export const checkEnforcedTable = Effect.fnUntraced(function* ({ target, writerRole, allowedRoles, runtimeRole, refuse, }) {
15
+ const sql = yield* SqlClient.SqlClient;
16
+ if (runtimeRole === undefined)
17
+ return yield* refuse(`is enforced for writer role ${writerRole}; start the runtime with adoption: { role: "${writerRole}" }`);
18
+ if (runtimeRole !== writerRole)
19
+ return yield* refuse(`is enforced for writer role ${writerRole}, but the runtime takes ${runtimeRole}; set adoption.role to ${writerRole}`);
20
+ const triggers = yield* sql `
21
+ SELECT t.tgname AS name, t.tgenabled AS enabled, t.tgtype::int AS type,
22
+ p.proname AS function, encode(t.tgargs, 'escape') AS arguments
23
+ FROM pg_trigger t
24
+ JOIN pg_class c ON c.oid = t.tgrelid JOIN pg_namespace n ON n.oid = c.relnamespace
25
+ JOIN pg_proc p ON p.oid = t.tgfoid
26
+ WHERE n.nspname = ${target.schema} AND c.relname = ${target.table} AND NOT t.tgisinternal
27
+ AND t.tgname IN ('actor_adoption_guard', 'actor_adoption_guard_truncate')`;
28
+ const expected = guardArguments({ target, writerRole, allowedRoles });
29
+ for (const [name, type] of [
30
+ ["actor_adoption_guard", GUARD_ROW_TYPE],
31
+ ["actor_adoption_guard_truncate", GUARD_TRUNCATE_TYPE],
32
+ ]) {
33
+ const found = triggers.find((trigger) => trigger.name === name);
34
+ if (found === undefined)
35
+ return yield* refuse(`is enforced but its guard trigger ${name} is missing; run durable adopt release ${target.table} --to observe and enforce it again`);
36
+ if (found.enabled !== "A")
37
+ return yield* refuse(`is enforced but its guard trigger ${name} is not enabled always; run ALTER TABLE ${target.table} ENABLE ALWAYS TRIGGER ${name}`);
38
+ if (found.function !== "actor_adoption_guard" || found.type !== type)
39
+ return yield* refuse(`is enforced but its trigger ${name} is not the framework guard`);
40
+ if (found.arguments !== `${expected.join("\\000")}\\000`)
41
+ return yield* refuse(`is enforced but its guard trigger ${name} does not carry the recorded writer, allowed roles, and columns`);
42
+ }
43
+ const stray = (yield* writeGrants(target)).filter((grant) => grant.grantee !== writerRole && !allowedRoles.includes(grant.grantee));
44
+ if (stray.length > 0)
45
+ return yield* refuse(`is enforced but ${[...new Set(stray.map((grant) => grant.grantee))].join(", ")} hold write privileges again; revoke them (REVOKE INSERT, UPDATE, DELETE, TRUNCATE ON ${target.table} FROM …)`);
46
+ });
47
+ /**
48
+ * Refuses a writer role a turn cannot run as: it must exist, this login must
49
+ * be able to take it, and it must read and write every framework table and
50
+ * every table in `tables` without owning one, because the whole turn runs as
51
+ * the writer.
52
+ */
53
+ export const checkWriterRole = Effect.fnUntraced(function* ({ role, tables, refuse, }) {
54
+ const sql = yield* SqlClient.SqlClient;
55
+ const [found] = yield* sql `
56
+ SELECT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = ${role}) AS exists`;
57
+ if (found?.exists !== true)
58
+ return yield* refuse(`writer role ${role} does not exist`);
59
+ yield* sql `SELECT set_config('role', ${role}, true)`.pipe(sql.withTransaction, Effect.catch(() => refuse(`this login cannot SET ROLE ${role}`)));
60
+ const owned = yield* sql `
61
+ SELECT n.nspname AS schema, c.relname AS table,
62
+ pg_has_role(${role}, c.relowner, 'USAGE') AS owned,
63
+ has_table_privilege(${role}, c.oid, 'SELECT') AND has_table_privilege(${role}, c.oid, 'INSERT')
64
+ AND has_table_privilege(${role}, c.oid, 'UPDATE') AND has_table_privilege(${role}, c.oid, 'DELETE') AS usable
65
+ FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
66
+ WHERE c.relkind = 'r' AND (
67
+ (n.oid = current_schema()::regnamespace AND (c.relname LIKE 'actor\\_%' OR c.relname LIKE 'tenant\\_content%'))
68
+ OR (n.nspname, c.relname) IN (${sql.csv(tables.map(({ schema, table }) => sql `(${schema}, ${table})`))}))
69
+ ORDER BY 1, 2`;
70
+ for (const table of owned) {
71
+ if (table.owned)
72
+ return yield* refuse(`writer role ${role} owns ${table.schema}.${table.table}; the writer must not own a table it is guarded on`);
73
+ if (!table.usable)
74
+ return yield* refuse(`writer role ${role} cannot read and write ${table.schema}.${table.table}; grant it SELECT, INSERT, UPDATE, and DELETE`);
75
+ }
76
+ });
@@ -0,0 +1,23 @@
1
+ import { Effect } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ /** One adopted table as `durable adopt status` reports it. */
4
+ export interface AdoptionStatus {
5
+ readonly table: string;
6
+ readonly actor: string;
7
+ readonly mode: "observe" | "enforce";
8
+ /** Rows still without a `routing_key`; enforcement needs none. */
9
+ readonly unbackfilled: number;
10
+ /** The last write neither the runtime nor an allowed role made, in epoch milliseconds. */
11
+ readonly lastLegacyWriteMs: number | undefined;
12
+ readonly writerRole: string | undefined;
13
+ /** Roles that may still write the table directly; adoption is complete when this is empty. */
14
+ readonly allowedRoles: ReadonlyArray<string>;
15
+ }
16
+ /**
17
+ * Every recorded adoption in the database, with its unbackfilled row count
18
+ * and its last legacy write. Reads only the catalog and the recorded writes,
19
+ * so it needs no actor definitions.
20
+ */
21
+ export declare const adoptionStatus: Effect.Effect<AdoptionStatus[], import("effect/sql/SqlError").SqlError, SqlClient.SqlClient>;
22
+ /** One line per adopted table. */
23
+ export declare const formatAdoptionStatus: (status: AdoptionStatus) => string;
@@ -0,0 +1,47 @@
1
+ import { DateTime, Effect } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ /**
4
+ * Every recorded adoption in the database, with its unbackfilled row count
5
+ * and its last legacy write. Reads only the catalog and the recorded writes,
6
+ * so it needs no actor definitions.
7
+ */
8
+ export const adoptionStatus = Effect.gen(function* () {
9
+ const sql = yield* SqlClient.SqlClient;
10
+ const adoptions = yield* sql `SELECT table_schema, table_name, actor_type, mode, writer_role, allowed_roles
11
+ FROM actor_adoptions ORDER BY table_schema, table_name`;
12
+ const statuses = [];
13
+ for (const adoption of adoptions) {
14
+ const table = `"${adoption.table_schema.replaceAll('"', '""')}"."${adoption.table_name.replaceAll('"', '""')}"`;
15
+ const [counted] = yield* sql.unsafe(`SELECT count(*)::text AS unbackfilled FROM ${table} WHERE routing_key IS NULL`);
16
+ const [last] = yield* sql `
17
+ SELECT max(observed_at_ms)::text AS last FROM actor_adoption_writes
18
+ WHERE table_schema = ${adoption.table_schema} AND table_name = ${adoption.table_name}
19
+ AND NOT in_turn AND NOT allowed`;
20
+ statuses.push({
21
+ table: `${adoption.table_schema}.${adoption.table_name}`,
22
+ actor: adoption.actor_type,
23
+ mode: adoption.mode,
24
+ unbackfilled: Number(counted.unbackfilled),
25
+ lastLegacyWriteMs: last?.last == null ? undefined : Number(last.last),
26
+ writerRole: adoption.writer_role ?? undefined,
27
+ allowedRoles: adoption.allowed_roles,
28
+ });
29
+ }
30
+ return statuses;
31
+ });
32
+ /** One line per adopted table. */
33
+ export const formatAdoptionStatus = (status) => [
34
+ `${status.table} ${status.actor} ${status.mode}`,
35
+ `${status.unbackfilled} rows without routing_key`,
36
+ status.lastLegacyWriteMs === undefined
37
+ ? "no legacy write recorded"
38
+ : `last legacy write ${DateTime.formatIso(DateTime.makeUnsafe(status.lastLegacyWriteMs))}`,
39
+ ...(status.mode === "enforce"
40
+ ? [
41
+ `writer ${status.writerRole}`,
42
+ status.allowedRoles.length === 0
43
+ ? "no allowed roles: adoption is complete"
44
+ : `allowed roles ${status.allowedRoles.join(", ")}`,
45
+ ]
46
+ : []),
47
+ ].join(" ");
@@ -0,0 +1,33 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ import { type AdoptionAccess, type MappedKind } from "../../tables/owned.ts";
4
+ import type { Placement } from "../storage/codec.ts";
5
+ declare const AdoptionRefused_base: Schema.Class<AdoptionRefused, Schema.TaggedStruct<"AdoptionRefused", {
6
+ readonly message: Schema.String;
7
+ }>, import("effect/Cause").YieldableError>;
8
+ /** A command's precondition failed; the message names the table and the fix. */
9
+ export declare class AdoptionRefused extends AdoptionRefused_base {
10
+ }
11
+ /** One existing table an actor type declares with `Actor.table(existing, { owner })`. */
12
+ export interface AdoptionTarget {
13
+ readonly actor: string;
14
+ readonly placement: Placement;
15
+ readonly access: AdoptionAccess;
16
+ readonly schema: string;
17
+ readonly table: string;
18
+ readonly tenantColumn: string;
19
+ readonly actorColumn: string;
20
+ readonly tenantKind: MappedKind;
21
+ readonly actorKind: MappedKind;
22
+ /** SQL names of the primary key columns, in key order. */
23
+ readonly primaryKey: ReadonlyArray<string>;
24
+ }
25
+ /** The table's name as `schema.table`, which the CLI and every report print. */
26
+ export declare const qualifiedName: (target: Pick<AdoptionTarget, "schema" | "table">) => string;
27
+ /**
28
+ * The adopted tables of `actors`, resolved against the connection's current
29
+ * schema. `only` is a table name or `schema.table`; naming a table no actor
30
+ * adopts is refused, so a typo never silently does nothing.
31
+ */
32
+ export declare const adoptionTargets: (actors: readonly WeakKey[], only?: string | undefined) => Effect.Effect<AdoptionTarget[], AdoptionRefused | import("effect/sql/SqlError").SqlError, SqlClient.SqlClient>;
33
+ export {};
@@ -0,0 +1,49 @@
1
+ import { getTableColumns } from "drizzle-orm";
2
+ import { Effect, Schema } from "effect";
3
+ import { SqlClient } from "effect/sql";
4
+ import { descriptorOf } from "../../actor/descriptor.js";
5
+ import { ownership } from "../../tables/owned.js";
6
+ /** A command's precondition failed; the message names the table and the fix. */
7
+ export class AdoptionRefused extends Schema.TaggedError()("AdoptionRefused", {
8
+ message: Schema.String,
9
+ }) {
10
+ }
11
+ /** The table's name as `schema.table`, which the CLI and every report print. */
12
+ export const qualifiedName = (target) => `${target.schema}.${target.table}`;
13
+ /**
14
+ * The adopted tables of `actors`, resolved against the connection's current
15
+ * schema. `only` is a table name or `schema.table`; naming a table no actor
16
+ * adopts is refused, so a typo never silently does nothing.
17
+ */
18
+ export const adoptionTargets = Effect.fnUntraced(function* (actors, only) {
19
+ const sql = yield* SqlClient.SqlClient;
20
+ const current = (yield* sql `SELECT current_schema() AS schema`)[0].schema;
21
+ const targets = [];
22
+ for (const actor of actors) {
23
+ const declared = descriptorOf(actor);
24
+ for (const table of declared?.tables ?? []) {
25
+ const info = ownership(table);
26
+ if (!info.adopted)
27
+ continue;
28
+ const columns = getTableColumns(table);
29
+ targets.push({
30
+ actor: declared.name,
31
+ placement: declared.placement,
32
+ access: info.access,
33
+ schema: info.schema ?? current,
34
+ table: info.table,
35
+ tenantColumn: columns[info.tenantKey].name,
36
+ actorColumn: columns[info.actorKey].name,
37
+ tenantKind: info.tenantKind,
38
+ actorKind: info.actorKind,
39
+ primaryKey: info.primaryKey.map((key) => columns[key].name),
40
+ });
41
+ }
42
+ }
43
+ if (only === undefined)
44
+ return targets;
45
+ const named = targets.filter((target) => target.table === only || qualifiedName(target) === only);
46
+ if (named.length === 0)
47
+ return yield* AdoptionRefused.make({ message: `No actor type adopts a table named ${only}` });
48
+ return named;
49
+ });