@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,43 @@
1
+ import { SQL } from "drizzle-orm";
2
+ import * as PostgresDrizzle from "drizzle-orm/effect-postgres";
3
+ import { Effect, Option } from "effect";
4
+ import { SqlClient, SqlError } from "effect/sql";
5
+ import { type Group, type Filter, type AnyOwnedTable, type ScopedRead, type TableScope } from "../../tables/owned.ts";
6
+ type Database = PostgresDrizzle.EffectPgDatabase;
7
+ /** Drizzle bound to the runtime's own client, so it shares the turn connection. */
8
+ export declare const rowsDatabase: Effect.Effect<Option.None<Database> | Option.Some<Database>, never, never>;
9
+ /**
10
+ * Renders an application filter on `table` as SQL after `copyFilter` has
11
+ * checked and copied it, for reads the framework builds outside a turn.
12
+ */
13
+ export declare const filterSql: ({ table, filter, }: {
14
+ readonly table: AnyOwnedTable;
15
+ readonly filter: Filter<AnyOwnedTable>;
16
+ }) => SQL<unknown> | undefined;
17
+ /**
18
+ * Binds owned-table reads and, when `write` is set, mutations to one turn's
19
+ * actor. Writes join the turn's transaction or fail; reads outside a
20
+ * transaction, as in a stream handler, run in their own tenant transaction.
21
+ * Drizzle wraps driver failures, so the inner `SqlError` is surfaced to let it
22
+ * decide between a retried turn and a deterministic defect. Off-turn contexts
23
+ * get no mutation methods at all, whatever their static type. A group query is
24
+ * read once per part and re-built from the framework's own client, so the
25
+ * caller's select object never runs.
26
+ */
27
+ export declare const bindTables: (database: Option.Option<Database>, scope: TableScope, write: boolean, checked: ReadonlySet<AnyOwnedTable>) => Effect.Effect<{
28
+ rows: (table: AnyOwnedTable) => ScopedRead<AnyOwnedTable>;
29
+ group: Group;
30
+ }, never, SqlClient.SqlClient>;
31
+ /** How a layer registers adopted tables: its writer role, and whether the registering layer writes them. */
32
+ export interface AdoptionStartup {
33
+ readonly role: string | undefined;
34
+ readonly writes: boolean;
35
+ }
36
+ /**
37
+ * Records which actor type owns each declared table and checks that the
38
+ * physical table's primary key leads with the ownership columns. A table
39
+ * claimed by another actor type, missing, or keyed without ownership fails
40
+ * startup instead of running unscoped.
41
+ */
42
+ export declare const checkTables: (actor: string, tables: readonly AnyOwnedTable[], role: string | undefined, adoption: AdoptionStartup) => Effect.Effect<boolean, SqlError.SqlError, SqlClient.SqlClient>;
43
+ export {};
@@ -0,0 +1,592 @@
1
+ import { PgClient } from "@effect/sql-pg";
2
+ import { PgliteClient } from "@effect/sql-pglite";
3
+ import { and, Column, count, entityKind, eq, getTableColumns, is, noopEncoder, Param, relationsFilterToSQL, relationsOrderToSQL, SQL, sql as fragment, StringChunk, Table, } from "drizzle-orm";
4
+ import * as PostgresDrizzle from "drizzle-orm/effect-postgres";
5
+ import * as PgliteDrizzle from "drizzle-orm/effect-pglite";
6
+ import { PgSelectBase, } from "drizzle-orm/pg-core";
7
+ import { Cause, Effect, Option, Predicate } from "effect";
8
+ import { SqlClient, SqlError } from "effect/sql";
9
+ import { checkAdoptedTable, checkOwnedTable, inTenant, TenantScope } from "../database/tenancy.js";
10
+ import { checkEnforcedTable, checkWriterRole } from "../adoption/startup.js";
11
+ import { ownerIndexExists, ownerIndexSql } from "../adoption/plan.js";
12
+ import { routingKey as routingKeyOf } from "../storage/codec.js";
13
+ import { OWNERSHIP, ownership, } from "../../tables/owned.js";
14
+ /** Drizzle bound to the runtime's own client, so it shares the turn connection. */
15
+ export const rowsDatabase = Effect.gen(function* () {
16
+ const pglite = yield* Effect.serviceOption(PgliteClient.PgliteClient);
17
+ if (Option.isSome(pglite)) {
18
+ const database = yield* PgliteDrizzle.makeWithDefaults().pipe(Effect.provideService(PgliteClient.PgliteClient, pglite.value));
19
+ return Option.some(database);
20
+ }
21
+ const postgres = yield* Effect.serviceOption(PgClient.PgClient);
22
+ if (Option.isNone(postgres))
23
+ return Option.none();
24
+ return Option.some(yield* PostgresDrizzle.makeWithDefaults().pipe(Effect.provideService(PgClient.PgClient, postgres.value)));
25
+ });
26
+ const isEntity = (value) => value instanceof Object && entityKind in value.constructor;
27
+ const isRecord = (value) => {
28
+ const prototype = value === null || value === undefined ? undefined : Object.getPrototypeOf(value);
29
+ return prototype === Object.prototype || prototype === null;
30
+ };
31
+ const CANONICAL_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
32
+ const reject = (message) => {
33
+ throw new Error(message);
34
+ };
35
+ const checkColumn = (info, key, write) => {
36
+ if (info.ownerKeys.includes(key) && (write || !info.adopted || key === info.routingKey))
37
+ reject(`Ownership column ${key} of ${info.name} comes from the turn, not the application`);
38
+ if (!info.columns.includes(key))
39
+ reject(`Unknown column ${key} of ${info.name}`);
40
+ };
41
+ /**
42
+ * Copies an application value into fresh primitives, dates, bytes, arrays, and
43
+ * plain records. Drizzle renders anything with `getSQL` as SQL, so a function,
44
+ * class instance, or SQL wrapper anywhere inside is rejected, and the copy
45
+ * means a getter cannot change the value after it was checked. Dates are
46
+ * structured-cloned so own properties such as `getSQL` are dropped.
47
+ */
48
+ const copyOperand = (info, value) => {
49
+ if (value === null || value === undefined)
50
+ return value;
51
+ if (Predicate.isString(value) ||
52
+ Predicate.isNumber(value) ||
53
+ Predicate.isBigInt(value) ||
54
+ Predicate.isBoolean(value))
55
+ return value;
56
+ const prototype = Object.getPrototypeOf(value);
57
+ if (prototype === Date.prototype)
58
+ return structuredClone(value);
59
+ if (value instanceof Uint8Array && (prototype === Uint8Array.prototype || Buffer.isBuffer(value)))
60
+ return Uint8Array.from(value);
61
+ if (Array.isArray(value) && prototype === Array.prototype)
62
+ return value.map((item) => copyOperand(info, item));
63
+ if (!isRecord(value))
64
+ return reject(`Values on ${info.name} are plain data, not SQL or objects`);
65
+ const copy = {};
66
+ for (const key of Object.keys(value)) {
67
+ if (key === "RAW")
68
+ reject(`RAW filters on ${info.name} are not supported`);
69
+ copy[key] = copyOperand(info, value[key]);
70
+ }
71
+ return copy;
72
+ };
73
+ const copyValues = (info, values) => {
74
+ if (!isRecord(values))
75
+ reject(`Rows of ${info.name} are plain objects`);
76
+ for (const key of Object.keys(values))
77
+ checkColumn(info, key, true);
78
+ return copyOperand(info, values);
79
+ };
80
+ /**
81
+ * Copies a filter, rejecting `RAW` and reserved columns. A bare date or byte
82
+ * string as a column's value is refused because Drizzle reads any object there
83
+ * as an operator map and would match every row instead of one.
84
+ */
85
+ const copyFilter = (info, filter) => {
86
+ if (!isRecord(filter))
87
+ return reject(`Filters on ${info.name} are plain objects`);
88
+ const copy = {};
89
+ for (const key of Object.keys(filter)) {
90
+ const value = filter[key];
91
+ if (key === "RAW")
92
+ reject(`RAW filters on ${info.name} are not supported`);
93
+ else if (key === "AND" || key === "OR") {
94
+ if (!Array.isArray(value))
95
+ return reject(`${key} on ${info.name} takes an array`);
96
+ copy[key] = value.map((item) => copyFilter(info, item));
97
+ }
98
+ else if (key === "NOT")
99
+ copy[key] = copyFilter(info, value);
100
+ else {
101
+ checkColumn(info, key, false);
102
+ const operand = copyOperand(info, value);
103
+ if (operand instanceof Date || operand instanceof Uint8Array)
104
+ reject(`Compare ${key} of ${info.name} with { eq: value }`);
105
+ copy[key] = operand;
106
+ }
107
+ }
108
+ return copy;
109
+ };
110
+ /**
111
+ * Renders an application filter on `table` as SQL after `copyFilter` has
112
+ * checked and copied it, for reads the framework builds outside a turn.
113
+ */
114
+ export const filterSql = ({ table, filter, }) => {
115
+ const info = ownership(table);
116
+ if (info === undefined)
117
+ return reject("Filters apply to owned tables");
118
+ return relationsFilterToSQL(table, copyFilter(info, filter));
119
+ };
120
+ const checkOrder = (info, order) => {
121
+ for (const [key, direction] of Object.entries(order)) {
122
+ checkColumn(info, key, false);
123
+ if (direction !== "asc" && direction !== "desc")
124
+ reject(`Order on ${info.name} is "asc" or "desc"`);
125
+ }
126
+ };
127
+ /**
128
+ * The words Drizzle's comparison, boolean, pattern, and aggregate operators
129
+ * emit; any other SQL text in a group query is rejected so raw fragments
130
+ * cannot name other tables, subqueries, or comments.
131
+ */
132
+ const OPERATOR_TEXT = /^(?:\s+|[(),*=<>!~@&|]+|and|or|not|in|is|null|like|ilike|between|asc|desc|nulls|first|last|distinct|true|false|count|sum|avg|min|max|lower|upper|coalesce)*$/i;
133
+ const GROUP = {
134
+ name: "a group query",
135
+ schema: undefined,
136
+ table: "",
137
+ columns: [],
138
+ primaryKey: [],
139
+ owner: undefined,
140
+ adopted: false,
141
+ access: "read",
142
+ ownerKeys: [],
143
+ ownerColumns: [],
144
+ routingKey: undefined,
145
+ tenantKey: "",
146
+ actorKey: "",
147
+ tenantKind: "text",
148
+ actorKind: "text",
149
+ placement: undefined,
150
+ };
151
+ /**
152
+ * Rebuilds a group query's expressions from values read once, so what was
153
+ * checked is exactly what renders: getters, proxies, and hidden `getSQL`
154
+ * members on the caller's objects never reach Drizzle. Columns resolve to the
155
+ * real columns of the query's owned tables, text must be operator words with
156
+ * balanced parentheses (the scope predicate is parenthesized beside it), and
157
+ * parameters carry copied plain data. A decoder only maps result values in
158
+ * JavaScript, so it is rebound rather than trusted; a column decoder resolves
159
+ * like any other column.
160
+ */
161
+ const groupRebuilder = (tables) => {
162
+ const column = (node) => {
163
+ const table = node.table;
164
+ const name = node.name;
165
+ if (!tables.includes(table))
166
+ return reject("Group queries reference columns of the tables they select from or join");
167
+ if (ownership(table).ownerColumns.includes(name))
168
+ return reject("Group queries do not read or filter ownership columns");
169
+ const real = Object.values(getTableColumns(table)).find((candidate) => candidate.name === name);
170
+ return real ?? reject(`Unknown column ${name}`);
171
+ };
172
+ const expression = (root) => {
173
+ let depth = 0;
174
+ const walk = (node) => {
175
+ if (node === undefined)
176
+ return undefined;
177
+ if (Array.isArray(node))
178
+ return node.map(walk);
179
+ if (is(node, StringChunk)) {
180
+ const text = String(node.value);
181
+ if (!OPERATOR_TEXT.test(text))
182
+ reject(`Group queries support Drizzle operators, not raw SQL: ${text}`);
183
+ for (const character of text) {
184
+ if (character === "(")
185
+ depth += 1;
186
+ else if (character === ")")
187
+ depth -= 1;
188
+ if (depth < 0)
189
+ reject("Group query expressions must balance their parentheses");
190
+ }
191
+ return new StringChunk(text);
192
+ }
193
+ if (is(node, SQL.Aliased)) {
194
+ const alias = String(node.fieldAlias);
195
+ return new SQL.Aliased(walk(node.sql), alias);
196
+ }
197
+ if (is(node, SQL)) {
198
+ const decoder = node.decoder;
199
+ const rebuilt = new SQL(walk([...node.queryChunks]));
200
+ rebuilt.decoder = is(decoder, Column)
201
+ ? column(decoder)
202
+ : { mapFromDriverValue: decoder.mapFromDriverValue.bind(decoder) };
203
+ return rebuilt;
204
+ }
205
+ if (is(node, Column))
206
+ return column(node);
207
+ if (is(node, Param)) {
208
+ const encoder = node.encoder;
209
+ const value = copyOperand(GROUP, node.value);
210
+ if (encoder === noopEncoder)
211
+ return new Param(value);
212
+ if (is(encoder, Column))
213
+ return new Param(value, column(encoder));
214
+ return reject("Group query parameters are plain values");
215
+ }
216
+ if (isEntity(node))
217
+ return reject("Group queries cannot reference tables, subqueries, names, or placeholders");
218
+ return copyOperand(GROUP, node);
219
+ };
220
+ const rebuilt = walk(root);
221
+ if (depth !== 0)
222
+ reject("Group query expressions must balance their parentheses");
223
+ return rebuilt;
224
+ };
225
+ const selection = (fields) => {
226
+ if (is(fields, Column))
227
+ return column(fields);
228
+ if (is(fields, SQL) || is(fields, SQL.Aliased))
229
+ return expression(fields);
230
+ if (isEntity(fields) || !isRecord(fields))
231
+ return reject("Group queries select columns and Drizzle expressions");
232
+ const copy = {};
233
+ for (const key of Object.keys(fields))
234
+ copy[key] = selection(fields[key]);
235
+ return copy;
236
+ };
237
+ return { expression, selection };
238
+ };
239
+ /**
240
+ * Binds owned-table reads and, when `write` is set, mutations to one turn's
241
+ * actor. Writes join the turn's transaction or fail; reads outside a
242
+ * transaction, as in a stream handler, run in their own tenant transaction.
243
+ * Drizzle wraps driver failures, so the inner `SqlError` is surfaced to let it
244
+ * decide between a retried turn and a deterministic defect. Off-turn contexts
245
+ * get no mutation methods at all, whatever their static type. A group query is
246
+ * read once per part and re-built from the framework's own client, so the
247
+ * caller's select object never runs.
248
+ */
249
+ export const bindTables = Effect.fnUntraced(function* (database, scope, write, checked) {
250
+ const sql = yield* SqlClient.SqlClient;
251
+ const connection = yield* Effect.serviceOption(sql.transactionService);
252
+ const { role } = yield* TenantScope;
253
+ if (write && Option.isNone(connection))
254
+ return yield* Effect.die(new Error("Owned rows need the turn transaction"));
255
+ const db = Option.getOrUndefined(database);
256
+ const run = (build) => Effect.andThen(scope.guard, () => Option.isNone(database)
257
+ ? Effect.die(new Error("Owned tables need a PgClient or PgliteClient database"))
258
+ : Effect.suspend(build).pipe((effect) => Option.isSome(connection)
259
+ ? Effect.provideService(effect, sql.transactionService, connection.value)
260
+ : inTenant({ sql, role, tenant: scope.ref.tenant })(effect), Effect.catch((error) => {
261
+ const wrapped = Predicate.hasProperty(error, "cause") ? error.cause : undefined;
262
+ const cause = Cause.isCause(wrapped) ? Cause.squash(wrapped) : wrapped;
263
+ return Effect.die(SqlError.isSqlError(cause) ? cause : error);
264
+ })));
265
+ const { ref } = scope;
266
+ const routingKey = routingKeyOf({ ref, placement: scope.placement });
267
+ const ownerOf = (info) => {
268
+ const owner = { [info.tenantKey]: ref.tenant, [info.actorKey]: ref.id };
269
+ if (info.routingKey === undefined)
270
+ return owner;
271
+ return { ...owner, [info.routingKey]: routingKey };
272
+ };
273
+ /**
274
+ * Off-turn contexts and read-adopted tables get no mutation methods at all,
275
+ * whatever their static type.
276
+ */
277
+ const rows = (table) => {
278
+ const info = ownership(table);
279
+ const check = () => {
280
+ if (info === undefined || !scope.tables.includes(table))
281
+ reject(`${info?.name ?? "This table"} is not an owned table of ${ref.actor}`);
282
+ if (info.tenantKind === "uuid" && !CANONICAL_UUID.test(ref.tenant))
283
+ reject(`${info.name} maps a uuid tenant column, and tenant ${ref.tenant} is not a lowercase uuid`);
284
+ if (info.actorKind === "uuid" && !CANONICAL_UUID.test(ref.id))
285
+ reject(`${info.name} maps a uuid actor column, and actor id ${ref.id} is not a lowercase uuid`);
286
+ return info;
287
+ };
288
+ const columns = getTableColumns(table);
289
+ const where = (filter) => {
290
+ const info = check();
291
+ const copy = filter === undefined ? {} : copyFilter(info, filter);
292
+ return and(info.routingKey === undefined ? undefined : eq(columns[info.routingKey], routingKey), eq(columns[info.tenantKey], ref.tenant), eq(columns[info.actorKey], ref.id), relationsFilterToSQL(table, copy));
293
+ };
294
+ const fields = () => Object.fromEntries(check().columns.map((key) => [key, columns[key]]));
295
+ const order = (orderBy) => {
296
+ if (orderBy === undefined)
297
+ return [];
298
+ checkOrder(check(), orderBy);
299
+ const sql = relationsOrderToSQL(table, orderBy);
300
+ return sql === undefined ? [] : [sql];
301
+ };
302
+ const list = (options) => {
303
+ const query = db
304
+ .select(fields())
305
+ .from(table)
306
+ .where(where(options.where))
307
+ .orderBy(...order(options.orderBy))
308
+ .$dynamic();
309
+ const limited = options.limit === undefined ? query : query.limit(options.limit);
310
+ return options.offset === undefined ? limited : limited.offset(options.offset);
311
+ };
312
+ const prepare = (values) => {
313
+ const info = check();
314
+ const list = Array.isArray(values) ? values : [values];
315
+ const owner = ownerOf(info);
316
+ return {
317
+ info,
318
+ list: list.map((value) => ({ ...copyValues(info, value), ...owner })),
319
+ };
320
+ };
321
+ const wrote = Effect.sync(() => scope.wrote?.(check().name));
322
+ const filtered = (mutation) => ({
323
+ where: (filter) => run(() => mutation(filter)).pipe(Effect.tap(() => wrote), Effect.asVoid),
324
+ });
325
+ const read = {
326
+ one: (options = {}) => run(() => list({ ...options, limit: 1 })).pipe(Effect.map((found) => Option.fromNullishOr(found[0]))),
327
+ all: (options = {}) => run(() => list(options)),
328
+ count: (options = {}) => run(() => db
329
+ .select({ rows: count() })
330
+ .from(table)
331
+ .where(where(options.where))
332
+ .pipe(Effect.map((found) => found[0]?.rows ?? 0))),
333
+ };
334
+ if (!write || info?.access === "read")
335
+ return read;
336
+ return {
337
+ ...read,
338
+ insert: (values) => run(() => {
339
+ const { list } = prepare(values);
340
+ return list.length === 0 ? Effect.void : db.insert(table).values(list);
341
+ }).pipe(Effect.tap(() => wrote), Effect.asVoid),
342
+ upsert: (values) => run(() => {
343
+ const { info, list } = prepare(values);
344
+ if (list.length === 0)
345
+ return Effect.void;
346
+ const target = (info.adopted ? info.primaryKey : [...OWNERSHIP, ...info.primaryKey]).map((key) => columns[key]);
347
+ const set = Object.fromEntries([...new Set(list.flatMap((value) => Object.keys(value)))].flatMap((key) => info.primaryKey.includes(key) || (info.ownerKeys.includes(key) && !info.adopted)
348
+ ? []
349
+ : [[key, fragment `excluded.${fragment.identifier(columns[key].name)}`]]));
350
+ const insert = db.insert(table).values(list);
351
+ if (!info.adopted)
352
+ return Object.keys(set).length === 0
353
+ ? insert.onConflictDoNothing({ target })
354
+ : insert.onConflictDoUpdate({ target, set });
355
+ delete set[info.tenantKey];
356
+ delete set[info.actorKey];
357
+ const first = columns[info.primaryKey[0]];
358
+ const applied = insert
359
+ .onConflictDoUpdate({
360
+ target,
361
+ set: Object.keys(set).length === 0
362
+ ? { [info.primaryKey[0]]: fragment `excluded.${fragment.identifier(first.name)}` }
363
+ : set,
364
+ setWhere: and(eq(columns[info.tenantKey], ref.tenant), eq(columns[info.actorKey], ref.id)),
365
+ })
366
+ .returning({ key: first });
367
+ return applied.pipe(Effect.flatMap((written) => written.length === list.length
368
+ ? Effect.void
369
+ : Effect.die(new Error(`An upsert of ${info.name} reached a primary key that belongs to another actor`))));
370
+ }).pipe(Effect.tap(() => wrote), Effect.asVoid),
371
+ update: (values) => filtered((filter) => {
372
+ const copy = copyValues(check(), values);
373
+ if (Object.keys(copy).length === 0)
374
+ reject(`An update of ${check().name} sets at least one column`);
375
+ return db.update(table).set(copy).where(where(filter));
376
+ }),
377
+ delete: () => filtered((filter) => db.delete(table).where(where(filter))),
378
+ };
379
+ };
380
+ const inGroup = (table) => {
381
+ const columns = getTableColumns(table);
382
+ const info = ownership(table);
383
+ return and(eq(columns[info.routingKey], routingKey), eq(columns[info.tenantKey], ref.tenant));
384
+ };
385
+ const ownedTable = (table) => {
386
+ if (!is(table, Table) || !checked.has(table))
387
+ return reject("Group queries read tables registered by an actor type, not aliases or subqueries");
388
+ if (ownership(table).access === "read")
389
+ return reject("Group queries cannot read a table adopted for reading only");
390
+ return table;
391
+ };
392
+ const bound = (value) => {
393
+ if (value === undefined)
394
+ return undefined;
395
+ if (!Predicate.isNumber(value))
396
+ return reject("Group query limits are numbers");
397
+ return value;
398
+ };
399
+ const group = (build) => run(() => {
400
+ const query = build({
401
+ select: db.select.bind(db),
402
+ selectDistinct: db.selectDistinct.bind(db),
403
+ });
404
+ if (!is(query, PgSelectBase))
405
+ return reject("A group query is a Drizzle select");
406
+ const config = {
407
+ ...query.config,
408
+ };
409
+ if ((config.withList?.length ?? 0) > 0)
410
+ reject("Group queries cannot use WITH");
411
+ if (config.setOperators.length > 0)
412
+ reject("Group queries cannot use set operators");
413
+ if (config.lockingClause !== undefined)
414
+ reject("Group queries are read-only and take no locks");
415
+ if (config.comment !== undefined)
416
+ reject("Group queries take no SQL comments");
417
+ if (config.distinct !== undefined && config.distinct !== false && config.distinct !== true)
418
+ reject("Group queries support selectDistinct, not DISTINCT ON");
419
+ const from = ownedTable(config.table);
420
+ const joins = [...(config.joins ?? [])].map((join) => {
421
+ const joinType = join.joinType;
422
+ const lateral = join.lateral;
423
+ if ((joinType !== "inner" && joinType !== "left") || lateral === true)
424
+ reject("Group queries support inner and left joins");
425
+ return { joinType, table: ownedTable(join.table), on: join.on };
426
+ });
427
+ const rebuild = groupRebuilder([from, ...joins.map((join) => join.table)]);
428
+ const fields = rebuild.selection(config.fields);
429
+ const where = rebuild.expression(config.where);
430
+ const having = rebuild.expression(config.having);
431
+ const orderBy = rebuild.expression([...(config.orderBy ?? [])]);
432
+ const groupBy = rebuild.expression([...(config.groupBy ?? [])]);
433
+ const limit = bound(config.limit);
434
+ const offset = bound(config.offset);
435
+ let fresh = (config.distinct === true ? db.selectDistinct(fields) : db.select(fields))
436
+ .from(from)
437
+ .$dynamic();
438
+ for (const join of joins) {
439
+ const on = and(rebuild.expression(join.on), inGroup(join.table));
440
+ fresh =
441
+ join.joinType === "inner"
442
+ ? fresh.innerJoin(join.table, on)
443
+ : fresh.leftJoin(join.table, on);
444
+ }
445
+ fresh = fresh.where(and(inGroup(from), where));
446
+ if (groupBy.length > 0)
447
+ fresh = fresh.groupBy(...groupBy);
448
+ if (having !== undefined)
449
+ fresh = fresh.having(having);
450
+ if (orderBy.length > 0)
451
+ fresh = fresh.orderBy(...orderBy);
452
+ if (limit !== undefined)
453
+ fresh = fresh.limit(limit);
454
+ if (offset !== undefined)
455
+ fresh = fresh.offset(offset);
456
+ const rows = fresh;
457
+ return rows;
458
+ });
459
+ return { rows, group };
460
+ });
461
+ /**
462
+ * Refuses an adopted table whose physical state does not match its
463
+ * declaration: a writable one needs its `actor_adoptions` row (which
464
+ * `durable adopt observe` writes) with the declared type and columns and a
465
+ * bigint `routing_key`; every adopted table needs mapped columns of a mappable
466
+ * type and an index that leads with them. Each message names the fix.
467
+ */
468
+ const checkAdoptedDeclaration = Effect.fnUntraced(function* ({ actor, table, info, schema, role, adoption, }) {
469
+ const sql = yield* SqlClient.SqlClient;
470
+ const columns = getTableColumns(table);
471
+ const tenantColumn = columns[info.tenantKey].name;
472
+ const actorColumn = columns[info.actorKey].name;
473
+ const refuse = (message) => Effect.die(new Error(`Adopted table ${info.name} ${message}`));
474
+ const physical = yield* sql `
475
+ SELECT a.attname AS name, t.typname AS type FROM pg_attribute a
476
+ JOIN pg_class c ON c.oid = a.attrelid JOIN pg_namespace n ON n.oid = c.relnamespace
477
+ JOIN pg_type t ON t.oid = a.atttypid
478
+ WHERE n.nspname = ${schema} AND c.relname = ${info.table} AND a.attnum > 0 AND NOT a.attisdropped`;
479
+ if (physical.length === 0)
480
+ return yield* refuse("does not exist");
481
+ for (const [column, kind] of [
482
+ [tenantColumn, info.tenantKind],
483
+ [actorColumn, info.actorKind],
484
+ ]) {
485
+ const found = physical.find((candidate) => candidate.name === column);
486
+ if (found === undefined)
487
+ return yield* refuse(`has no column ${column}`);
488
+ if ((found.type === "uuid") !== (kind === "uuid") ||
489
+ !["text", "varchar", "uuid"].includes(found.type))
490
+ return yield* refuse(`maps ${column}, which is ${found.type}, not the declared ${kind} column`);
491
+ }
492
+ let enforcement;
493
+ if (info.access === "write") {
494
+ const [recorded] = yield* sql `SELECT actor_type, tenant_column, actor_column, mode, writer_role, allowed_roles
495
+ FROM actor_adoptions WHERE table_schema = ${schema} AND table_name = ${info.table}`;
496
+ if (recorded === undefined)
497
+ return yield* refuse(`has no adoption record; run durable adopt observe ${info.table} before serving it`);
498
+ if (recorded.actor_type !== actor)
499
+ return yield* refuse(`is adopted by actor ${recorded.actor_type}, not ${actor}`);
500
+ if (recorded.tenant_column !== tenantColumn || recorded.actor_column !== actorColumn)
501
+ return yield* refuse(`was adopted with columns (${recorded.tenant_column}, ${recorded.actor_column}) but declares (${tenantColumn}, ${actorColumn}); run durable adopt observe ${info.table} again`);
502
+ if (recorded.mode === "enforce")
503
+ enforcement = { writerRole: recorded.writer_role, allowedRoles: recorded.allowed_roles };
504
+ const routing = physical.find((candidate) => candidate.name === "routing_key");
505
+ if (routing?.type !== "int8")
506
+ return yield* refuse(`has no bigint routing_key; run durable adopt observe ${info.table}`);
507
+ }
508
+ const target = {
509
+ schema,
510
+ table: info.table,
511
+ access: info.access,
512
+ tenantColumn,
513
+ actorColumn,
514
+ };
515
+ if (!(yield* ownerIndexExists(target)))
516
+ return yield* refuse(`needs an index that leads with its owner columns: ${ownerIndexSql(target)}`);
517
+ if (role !== undefined)
518
+ yield* checkAdoptedTable(schema, info.table, role, info.access === "write");
519
+ if (enforcement === undefined || !adoption.writes)
520
+ return enforcement !== undefined;
521
+ if (role !== undefined && role !== enforcement.writerRole)
522
+ return yield* refuse(`is enforced for writer role ${enforcement.writerRole}, but row-level security takes ${role}; both options must name the same role`);
523
+ yield* checkEnforcedTable({
524
+ target: { schema, table: info.table, tenantColumn, actorColumn, actor },
525
+ ...enforcement,
526
+ runtimeRole: adoption.role,
527
+ refuse,
528
+ });
529
+ return true;
530
+ });
531
+ /**
532
+ * Records which actor type owns each declared table and checks that the
533
+ * physical table's primary key leads with the ownership columns. A table
534
+ * claimed by another actor type, missing, or keyed without ownership fails
535
+ * startup instead of running unscoped.
536
+ */
537
+ export const checkTables = Effect.fnUntraced(function* (actor, tables, role, adoption) {
538
+ const sql = yield* SqlClient.SqlClient;
539
+ const guarded = [];
540
+ let enforced = false;
541
+ for (const table of tables) {
542
+ const info = ownership(table);
543
+ const schema = info.schema ?? (yield* sql `SELECT current_schema() AS schema`)[0].schema;
544
+ guarded.push({ schema, table: info.table });
545
+ if (info.adopted) {
546
+ const isEnforced = yield* checkAdoptedDeclaration({
547
+ actor,
548
+ table,
549
+ info,
550
+ schema,
551
+ role,
552
+ adoption,
553
+ });
554
+ if (isEnforced && adoption.writes)
555
+ enforced = true;
556
+ yield* sql `INSERT INTO actor_tables (table_schema, table_name, actor_type)
557
+ VALUES (${schema}, ${info.table}, ${actor}) ON CONFLICT DO NOTHING`;
558
+ const [claimed] = yield* sql `
559
+ SELECT actor_type FROM actor_tables WHERE table_schema = ${schema} AND table_name = ${info.table}`;
560
+ if (claimed?.actor_type !== actor)
561
+ return yield* Effect.die(new Error(`Table ${info.name} is owned by actor ${claimed?.actor_type}, not ${actor}`));
562
+ continue;
563
+ }
564
+ const key = yield* sql `
565
+ SELECT a.attname AS name FROM pg_index i
566
+ JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
567
+ WHERE i.indisprimary AND i.indrelid = (
568
+ SELECT c.oid FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
569
+ WHERE n.nspname = ${schema} AND c.relname = ${info.table})
570
+ ORDER BY array_position(i.indkey::int2[], a.attnum)`;
571
+ const columns = getTableColumns(table);
572
+ const expected = [...OWNERSHIP, ...info.primaryKey.map((column) => columns[column].name)];
573
+ if (key.map(({ name }) => name).join() !== expected.join())
574
+ return yield* Effect.die(new Error(`Owned table ${info.name} needs primary key (${expected.join(", ")}); apply its drizzle-kit migration`));
575
+ if (role !== undefined)
576
+ yield* checkOwnedTable(schema, info.table, role);
577
+ yield* sql `INSERT INTO actor_tables (table_schema, table_name, actor_type)
578
+ VALUES (${schema}, ${info.table}, ${actor}) ON CONFLICT DO NOTHING`;
579
+ const [recorded] = yield* sql `
580
+ SELECT actor_type FROM actor_tables WHERE table_schema = ${schema} AND table_name = ${info.table}`;
581
+ if (recorded?.actor_type !== actor)
582
+ return yield* Effect.die(new Error(`Table ${info.name} is owned by actor ${recorded?.actor_type}, not ${actor}`));
583
+ }
584
+ if (!enforced)
585
+ return false;
586
+ yield* checkWriterRole({
587
+ role: adoption.role,
588
+ tables: guarded,
589
+ refuse: (message) => Effect.die(new Error(`Adoption writer role: ${message}`)),
590
+ });
591
+ return true;
592
+ });