@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,189 @@
1
+ import { Clock, DateTime, Duration, Effect, Option, Result, Schema, Semaphore } from "effect";
2
+ import { Base64Url } from "effect/encoding";
3
+ import { Headers, HttpClient } from "effect/http";
4
+ import { ActorUnavailable } from "../../errors/actor.js";
5
+ import { Anonymous, User } from "../../identity/caller.js";
6
+ import { bearerToken, Credential, unauthorized, } from "../auth.js";
7
+ import { ASSERTION_HEADER, ASSERTION_TYPE, KEY_REFRESH_TYPE } from "./binding.js";
8
+ /** An edge verification key: an Ed25519 public JWK, valid from `nbf` until `exp` (epoch seconds). */
9
+ export const AssertionKey = Schema.Struct({
10
+ kid: Schema.NonEmptyString,
11
+ kty: Schema.Literal("OKP"),
12
+ crv: Schema.Literal("Ed25519"),
13
+ x: Schema.NonEmptyString,
14
+ nbf: Schema.optionalKey(Schema.Finite),
15
+ exp: Schema.optionalKey(Schema.Finite),
16
+ });
17
+ /** The key set the control plane publishes for runners. */
18
+ export const AssertionKeySet = Schema.Struct({ keys: Schema.Array(AssertionKey) });
19
+ /** The most an assertion may live, from `iat` to `exp`. */
20
+ export const MAX_ASSERTION_SECONDS = 60;
21
+ /** Clock skew allowed on `iat` and `exp`; edge and runners run synchronized clocks. */
22
+ export const ASSERTION_SKEW_MS = 5_000;
23
+ /** An unknown `kid` rereads the key set at most this often. */
24
+ const UNKNOWN_KID_REFRESH_MS = 60_000;
25
+ /** The JWS header of type `typ`. EdDSA with Ed25519 only: `none` and every other algorithm are refused. */
26
+ const headerOf = (typ) => Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Struct({
27
+ alg: Schema.Literal("EdDSA"),
28
+ typ: Schema.Literal(typ),
29
+ kid: Schema.NonEmptyString,
30
+ crit: Schema.optionalKey(Schema.Never),
31
+ })));
32
+ const decodeAssertionHeader = headerOf(ASSERTION_TYPE);
33
+ const decodeRefreshHeader = headerOf(KEY_REFRESH_TYPE);
34
+ /** The claims of an edge's key-set refresh push. */
35
+ export const KeyRefreshClaims = Schema.Struct({
36
+ iss: Schema.String,
37
+ aud: Schema.String,
38
+ iat: Schema.Finite,
39
+ exp: Schema.Finite,
40
+ });
41
+ const decodeRefreshClaims = Schema.decodeUnknownOption(Schema.fromJsonString(KeyRefreshClaims));
42
+ const Digest = Schema.String.check(Schema.isPattern(/^[0-9a-f]{64}$/u));
43
+ /** The claims an edge signs; `actor`, `id`, `member`, and `cid` are there for logs. */
44
+ export const AssertionClaims = Schema.Struct({
45
+ iss: Schema.String,
46
+ aud: Schema.String,
47
+ region: Schema.String,
48
+ iat: Schema.Finite,
49
+ exp: Schema.Finite,
50
+ tenant: Schema.String,
51
+ caller: Schema.Union([User, Anonymous]),
52
+ req: Digest,
53
+ /** The streaming session id, on assertions for a WebSocket open or renewal. */
54
+ sid: Schema.optionalKey(Schema.NonEmptyString),
55
+ /** The external credential's own expiry in epoch seconds, which caps a live session. */
56
+ cexp: Schema.optionalKey(Schema.Finite),
57
+ actor: Schema.optionalKey(Schema.String),
58
+ id: Schema.optionalKey(Schema.String),
59
+ member: Schema.optionalKey(Schema.String),
60
+ cid: Schema.optionalKey(Schema.String),
61
+ });
62
+ const decodeClaims = Schema.decodeUnknownOption(Schema.fromJsonString(AssertionClaims));
63
+ const decodeKeySet = Schema.decodeUnknownEffect(AssertionKeySet);
64
+ const invalid = unauthorized("invalid_credentials");
65
+ const utf8 = new TextEncoder();
66
+ const headerToken = (request) => Option.match(Headers.get(request.headers, ASSERTION_HEADER), {
67
+ onNone: () => Effect.fail(unauthorized("missing_credentials")),
68
+ onSome: (value) => Effect.succeed(value.trim()),
69
+ });
70
+ /** The compact JWS from a WebSocket frame's `Bearer` credential, or from `durable-assertion`. */
71
+ const tokenOf = (request) => request.credential === undefined ? headerToken(request) : bearerToken(request);
72
+ const verifySignature = Effect.fnUntraced(function* (key, signature, signed) {
73
+ const imported = yield* Effect.tryPromise({
74
+ try: () => crypto.subtle.importKey("jwk", { kty: key.kty, crv: key.crv, x: key.x }, { name: "Ed25519" }, false, ["verify"]),
75
+ catch: () => invalid,
76
+ });
77
+ return yield* Effect.tryPromise({
78
+ try: () => crypto.subtle.verify({ name: "Ed25519" }, imported, new Uint8Array(signature), utf8.encode(signed)),
79
+ catch: () => invalid,
80
+ });
81
+ });
82
+ /**
83
+ * Verifies the hosted edge's signed assertion, the only provider a hosted
84
+ * runner uses. It checks the signature, key, issuer, deployment, region, and
85
+ * lifetime here; the server then checks the request binding against the
86
+ * request it received before any turn.
87
+ *
88
+ * A key set older than `refreshEvery` is reread before use, and a runner that
89
+ * can't reread it refuses with `ActorUnavailable` rather than keep trusting
90
+ * keys the control plane may have removed. The provider's `refreshKeys` takes
91
+ * the edge's signed push and rereads the key set at once, however recently it
92
+ * was read, so a revoked key stops verifying without waiting for
93
+ * `refreshEvery`; repeating a push is harmless.
94
+ */
95
+ export const assertion = (options) => {
96
+ const refreshMs = Duration.toMillis(Duration.fromInputUnsafe(options.refreshEvery ?? "5 minutes"));
97
+ const lock = Semaphore.makeUnsafe(1);
98
+ const source = options.keys;
99
+ let cached = source instanceof URL ? undefined : { keys: source.keys, at: Number.POSITIVE_INFINITY };
100
+ const fetchKeys = (url) => Effect.gen(function* () {
101
+ const client = HttpClient.filterStatusOk(yield* HttpClient.HttpClient);
102
+ const response = yield* client.get(url);
103
+ return (yield* decodeKeySet(yield* response.json)).keys;
104
+ }).pipe(Effect.mapError(() => ActorUnavailable.make({
105
+ cause: new Error("Actor.auth.assertion could not fetch its key set"),
106
+ })));
107
+ const keysFor = (unknownKid) => lock.withPermit(Effect.gen(function* () {
108
+ const now = yield* Clock.currentTimeMillis;
109
+ if (source instanceof URL &&
110
+ (cached === undefined ||
111
+ now - cached.at >= refreshMs ||
112
+ (unknownKid && now - cached.at >= UNKNOWN_KID_REFRESH_MS)))
113
+ cached = { keys: yield* fetchKeys(source), at: now };
114
+ return cached.keys;
115
+ }));
116
+ /** The claims text of a JWS of type `decodeHeader` signed by a published, valid key. */
117
+ const signedClaims = Effect.fnUntraced(function* (token, decodeHeader) {
118
+ const parts = token.split(".");
119
+ if (parts.length !== 3)
120
+ return yield* invalid;
121
+ const [encodedHeader, encodedClaims, encodedSignature] = parts;
122
+ const headerText = Base64Url.decodeString(encodedHeader);
123
+ const claimsText = Base64Url.decodeString(encodedClaims);
124
+ const signature = Base64Url.decode(encodedSignature);
125
+ if (Result.isFailure(headerText) || Result.isFailure(claimsText) || Result.isFailure(signature))
126
+ return yield* invalid;
127
+ const header = decodeHeader(headerText.success);
128
+ if (Option.isNone(header))
129
+ return yield* invalid;
130
+ const kid = header.value.kid;
131
+ const seconds = (yield* Clock.currentTimeMillis) / 1000;
132
+ const skew = ASSERTION_SKEW_MS / 1000;
133
+ const usable = (keys) => keys.find((key) => key.kid === kid &&
134
+ (key.nbf === undefined || key.nbf <= seconds + skew) &&
135
+ (key.exp === undefined || key.exp > seconds - skew));
136
+ const key = usable(yield* keysFor(false)) ?? usable(yield* keysFor(true));
137
+ if (key === undefined)
138
+ return yield* invalid;
139
+ if (!(yield* verifySignature(key, signature.success, `${encodedHeader}.${encodedClaims}`)))
140
+ return yield* invalid;
141
+ return claimsText.success;
142
+ });
143
+ /** Whether `iat` and `exp` give a lifetime within the cap, issued and unexpired within skew. */
144
+ const lifetime = Effect.fnUntraced(function* (claims) {
145
+ const seconds = (yield* Clock.currentTimeMillis) / 1000;
146
+ const skew = ASSERTION_SKEW_MS / 1000;
147
+ if (claims.exp <= claims.iat ||
148
+ claims.exp - claims.iat > MAX_ASSERTION_SECONDS ||
149
+ claims.iat > seconds + skew)
150
+ return yield* invalid;
151
+ if (claims.exp <= seconds - skew)
152
+ return yield* unauthorized("expired");
153
+ });
154
+ const authenticate = Effect.fnUntraced(function* (request) {
155
+ const claimsText = yield* signedClaims(yield* tokenOf(request), decodeAssertionHeader);
156
+ const claims = decodeClaims(claimsText);
157
+ if (Option.isNone(claims))
158
+ return yield* invalid;
159
+ const { iss, aud, region, iat, exp, tenant, caller, req, sid, cexp } = claims.value;
160
+ if (iss !== options.issuer || aud !== options.audience || region !== options.region)
161
+ return yield* invalid;
162
+ yield* lifetime({ iat, exp });
163
+ const binding = sid === undefined ? { request: req } : { request: req, session: sid };
164
+ const authenticated = { caller, tenant, binding };
165
+ if (cexp === undefined)
166
+ return authenticated;
167
+ const expiresAt = DateTime.make(cexp * 1000);
168
+ if (Option.isNone(expiresAt))
169
+ return yield* invalid;
170
+ return { ...authenticated, expiresAt: expiresAt.value };
171
+ });
172
+ const refreshKeys = Effect.fnUntraced(function* (request) {
173
+ const claims = decodeRefreshClaims(yield* signedClaims(yield* headerToken(request), decodeRefreshHeader));
174
+ if (Option.isNone(claims))
175
+ return yield* invalid;
176
+ if (claims.value.iss !== options.issuer || claims.value.aud !== options.audience)
177
+ return yield* invalid;
178
+ yield* lifetime(claims.value);
179
+ if (source instanceof URL)
180
+ yield* lock.withPermit(Effect.gen(function* () {
181
+ cached = { keys: yield* fetchKeys(source), at: yield* Clock.currentTimeMillis };
182
+ }));
183
+ });
184
+ return {
185
+ credentials: [Credential.Assertion()],
186
+ authenticate: authenticate,
187
+ refreshKeys: refreshKeys,
188
+ };
189
+ };
@@ -0,0 +1,200 @@
1
+ import { Data, type DateTime, Effect } from "effect";
2
+ import { Headers } from "effect/http";
3
+ import type { ActorUnavailable } from "../errors/actor.ts";
4
+ import { Unauthorized } from "../errors/actor.ts";
5
+ import { Anonymous, User } from "../identity/caller.ts";
6
+ /** What a provider may read: headers, cookies when it asks for them, and a frame credential. Never the body. */
7
+ export interface AuthRequest {
8
+ readonly headers: Headers.Headers;
9
+ /** Empty unless the provider accepts a cookie credential. */
10
+ readonly cookies: Readonly<Record<string, string>>;
11
+ /**
12
+ * A credential carried outside the headers, such as a WebSocket `hello`
13
+ * frame's `authorization`; it has the header's form, `Bearer <token>`.
14
+ */
15
+ readonly credential?: string;
16
+ }
17
+ /** What a provider resolves a request to: who is calling, in which tenant, and until when. */
18
+ export interface Authenticated {
19
+ readonly caller: typeof User.Type | typeof Anonymous.Type;
20
+ readonly tenant: string;
21
+ /** The credential's own expiry, which caps live sessions. */
22
+ readonly expiresAt?: DateTime.Utc;
23
+ /**
24
+ * The one request the credential was issued for: the server refuses the
25
+ * request unless it rebuilds the same digest from what it received.
26
+ */
27
+ readonly binding?: Binding;
28
+ }
29
+ /** Ties a credential to one request, so a captured credential cannot be replayed on another. */
30
+ export interface Binding {
31
+ /** The SHA-256 hex of the canonical request string. */
32
+ readonly request: string;
33
+ /** The streaming session the credential belongs to; a renewal must name the same one. */
34
+ readonly session?: string;
35
+ }
36
+ /** A credential a provider reads, documented as one OpenAPI security scheme. */
37
+ export type Credential = Data.TaggedEnum<{
38
+ /** `authorization: Bearer <token>`. */
39
+ Bearer: {};
40
+ /** `authorization: Bearer <jwt>`, documented with `bearerFormat: JWT`. */
41
+ Jwt: {};
42
+ /** The named cookie. */
43
+ Cookie: {
44
+ readonly name: string;
45
+ };
46
+ /** `durable-assertion: <jws>`, a hosted edge's signed assertion. */
47
+ Assertion: {};
48
+ }>;
49
+ /** Constructors and matchers for `Credential`. */
50
+ export declare const Credential: {
51
+ readonly $is: <Tag extends "Assertion" | "Bearer" | "Cookie" | "Jwt">(tag: Tag) => (u: unknown) => u is Extract<{
52
+ readonly _tag: "Assertion";
53
+ }, {
54
+ readonly _tag: Tag;
55
+ }> | Extract<{
56
+ readonly _tag: "Bearer";
57
+ }, {
58
+ readonly _tag: Tag;
59
+ }> | Extract<{
60
+ readonly _tag: "Cookie";
61
+ readonly name: string;
62
+ }, {
63
+ readonly _tag: Tag;
64
+ }> | Extract<{
65
+ readonly _tag: "Jwt";
66
+ }, {
67
+ readonly _tag: Tag;
68
+ }>;
69
+ readonly $match: {
70
+ <Cases extends { readonly [Tag in "Assertion" | "Bearer" | "Cookie" | "Jwt"]: (args: Extract<{
71
+ readonly _tag: "Assertion";
72
+ } | {
73
+ readonly _tag: "Bearer";
74
+ } | {
75
+ readonly _tag: "Cookie";
76
+ readonly name: string;
77
+ } | {
78
+ readonly _tag: "Jwt";
79
+ }, {
80
+ readonly _tag: Tag;
81
+ }>) => any; }>(cases: Cases): (value: {
82
+ readonly _tag: "Assertion";
83
+ } | {
84
+ readonly _tag: "Bearer";
85
+ } | {
86
+ readonly _tag: "Cookie";
87
+ readonly name: string;
88
+ } | {
89
+ readonly _tag: "Jwt";
90
+ }) => import("effect/Unify").Unify<ReturnType<Cases["Assertion" | "Bearer" | "Cookie" | "Jwt"]>>;
91
+ <Cases extends { readonly [Tag in "Assertion" | "Bearer" | "Cookie" | "Jwt"]: (args: Extract<{
92
+ readonly _tag: "Assertion";
93
+ } | {
94
+ readonly _tag: "Bearer";
95
+ } | {
96
+ readonly _tag: "Cookie";
97
+ readonly name: string;
98
+ } | {
99
+ readonly _tag: "Jwt";
100
+ }, {
101
+ readonly _tag: Tag;
102
+ }>) => any; }>(value: {
103
+ readonly _tag: "Assertion";
104
+ } | {
105
+ readonly _tag: "Bearer";
106
+ } | {
107
+ readonly _tag: "Cookie";
108
+ readonly name: string;
109
+ } | {
110
+ readonly _tag: "Jwt";
111
+ }, cases: Cases): import("effect/Unify").Unify<ReturnType<Cases["Assertion" | "Bearer" | "Cookie" | "Jwt"]>>;
112
+ };
113
+ readonly Assertion: Data.TaggedEnum.ConstructorFrom<{
114
+ readonly _tag: "Assertion";
115
+ }, "_tag">;
116
+ readonly Bearer: Data.TaggedEnum.ConstructorFrom<{
117
+ readonly _tag: "Bearer";
118
+ }, "_tag">;
119
+ readonly Cookie: Data.TaggedEnum.ConstructorFrom<{
120
+ readonly _tag: "Cookie";
121
+ readonly name: string;
122
+ }, "_tag">;
123
+ readonly Jwt: Data.TaggedEnum.ConstructorFrom<{
124
+ readonly _tag: "Jwt";
125
+ }, "_tag">;
126
+ };
127
+ /** One way to authenticate every request an `Actor.serve` layer answers. */
128
+ export interface AuthProvider<R = never> {
129
+ /**
130
+ * The credentials the provider accepts, any one of which authenticates a
131
+ * request; empty when it reads none. A `Cookie` entry is also what lets
132
+ * `authenticate` see the request's cookies.
133
+ */
134
+ readonly credentials: ReadonlyArray<Credential>;
135
+ readonly authenticate: (request: AuthRequest) => Effect.Effect<Authenticated, Unauthorized | ActorUnavailable, R>;
136
+ /**
137
+ * Rereads the provider's verification keys at once, for a request that
138
+ * proves it comes from the key issuer. A provider that has one is served
139
+ * a refresh route beside the protocol routes.
140
+ */
141
+ readonly refreshKeys?: (request: AuthRequest) => Effect.Effect<void, Unauthorized | ActorUnavailable, R>;
142
+ }
143
+ /** An `Unauthorized` failure with the given reason code. */
144
+ export declare const unauthorized: (code: Unauthorized["code"]) => Unauthorized;
145
+ /**
146
+ * The token of an `authorization: Bearer` header, or of the request's frame
147
+ * credential, which carries the same `Bearer <token>` value.
148
+ */
149
+ export declare const bearerToken: (request: AuthRequest) => Effect.Effect<string, never, never> | Effect.Effect<never, Unauthorized, never>;
150
+ /** Every request is `Anonymous` in the `"default"` tenant; any credential it carries is ignored. */
151
+ export declare const none: AuthProvider;
152
+ /** Verifies a request's credential; fails `Unauthorized` when it is missing, invalid, or expired. */
153
+ type Authenticate<R> = (request: AuthRequest) => Effect.Effect<Authenticated, Unauthorized, R>;
154
+ /**
155
+ * Options of a custom provider. It reads `authorization: Bearer` unless it
156
+ * names a cookie; one that reads both sets `bearer: true` as well.
157
+ */
158
+ type MakeOptions<R> = {
159
+ readonly authenticate: Authenticate<R>;
160
+ readonly cookies?: undefined;
161
+ readonly bearer?: true;
162
+ } | {
163
+ readonly authenticate: Authenticate<R>;
164
+ /** The cookie that carries the credential; the provider receives every request cookie. */
165
+ readonly cookies: {
166
+ readonly name: string;
167
+ };
168
+ readonly bearer?: boolean;
169
+ };
170
+ /**
171
+ * A custom provider: an `authenticate` function that reads a bearer token, or
172
+ * options naming a cookie. Throws when the cookie name is not an HTTP token.
173
+ *
174
+ * @example
175
+ * ```ts
176
+ * Actor.auth.make((request) =>
177
+ * Effect.succeed({ caller: User.make({ subject: "ada" }), tenant: "acme" }),
178
+ * )
179
+ * ```
180
+ */
181
+ export declare const make: <R = never>(provider: Authenticate<R> | MakeOptions<R>) => AuthProvider<R>;
182
+ /** Whether the provider accepts a cookie credential, and so receives request cookies. */
183
+ export declare const readsCookies: (provider: AuthProvider<unknown>) => boolean;
184
+ /** Whether the tenant is a valid id and, for a `User`, its subject and encoded caller fit their byte limits. */
185
+ export declare const withinLimits: (authenticated: Authenticated) => boolean;
186
+ /** The default cap on the UTF-8 bytes of one credential a request carries. */
187
+ export declare const CREDENTIAL_BYTES: number;
188
+ /**
189
+ * Whether a credential `provider` would read from the request is over `limit`
190
+ * UTF-8 bytes: the `authorization` header or a frame credential, the cookie
191
+ * header for a cookie provider, and `durable-assertion` for an assertion
192
+ * provider. Checked before the provider runs, so it never parses an oversized one.
193
+ */
194
+ export declare const oversizedCredential: (options: {
195
+ readonly provider: AuthProvider<unknown>;
196
+ readonly headers: Headers.Headers;
197
+ readonly limit: number;
198
+ readonly credential?: string | undefined;
199
+ }) => boolean;
200
+ export {};
@@ -0,0 +1,92 @@
1
+ import { Data, Effect, Option, Predicate, Schema } from "effect";
2
+ import { Headers } from "effect/http";
3
+ import { Unauthorized } from "../errors/actor.js";
4
+ import { Anonymous, User } from "../identity/caller.js";
5
+ import { ASSERTION_HEADER } from "./assertion/binding.js";
6
+ /** Constructors and matchers for `Credential`. */
7
+ export const Credential = Data.taggedEnum();
8
+ /** An `Unauthorized` failure with the given reason code. */
9
+ export const unauthorized = (code) => Unauthorized.make({ code });
10
+ /**
11
+ * The token of an `authorization: Bearer` header, or of the request's frame
12
+ * credential, which carries the same `Bearer <token>` value.
13
+ */
14
+ export const bearerToken = (request) => {
15
+ const header = request.credential === undefined
16
+ ? Headers.get(request.headers, "authorization")
17
+ : Option.some(request.credential);
18
+ if (Option.isNone(header))
19
+ return Effect.fail(unauthorized("missing_credentials"));
20
+ const match = /^Bearer[ ]+([^ ]+)[ ]*$/i.exec(header.value);
21
+ return match === null
22
+ ? Effect.fail(unauthorized("invalid_credentials"))
23
+ : Effect.succeed(match[1]);
24
+ };
25
+ /** Every request is `Anonymous` in the `"default"` tenant; any credential it carries is ignored. */
26
+ export const none = {
27
+ credentials: [],
28
+ authenticate: () => Effect.succeed({ caller: Anonymous.make({}), tenant: "default" }),
29
+ };
30
+ /** RFC 6265's cookie-name, which is an RFC 9110 token. */
31
+ const cookieName = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
32
+ /**
33
+ * A custom provider: an `authenticate` function that reads a bearer token, or
34
+ * options naming a cookie. Throws when the cookie name is not an HTTP token.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * Actor.auth.make((request) =>
39
+ * Effect.succeed({ caller: User.make({ subject: "ada" }), tenant: "acme" }),
40
+ * )
41
+ * ```
42
+ */
43
+ export const make = (provider) => {
44
+ if (Predicate.isFunction(provider))
45
+ return { credentials: [Credential.Bearer()], authenticate: provider };
46
+ if (provider.cookies === undefined)
47
+ return { credentials: [Credential.Bearer()], authenticate: provider.authenticate };
48
+ if (!cookieName.test(provider.cookies.name))
49
+ throw new Error(`Actor.auth.make: ${JSON.stringify(provider.cookies.name)} is not a cookie name`);
50
+ const cookie = Credential.Cookie({ name: provider.cookies.name });
51
+ return {
52
+ credentials: provider.bearer === true ? [Credential.Bearer(), cookie] : [cookie],
53
+ authenticate: provider.authenticate,
54
+ };
55
+ };
56
+ /** Whether the provider accepts a cookie credential, and so receives request cookies. */
57
+ export const readsCookies = (provider) => provider.credentials.some(Credential.$is("Cookie"));
58
+ const Tenant = Schema.String.check(Schema.isPattern(/^[A-Za-z0-9._:-]{1,128}$/u));
59
+ const isTenant = Schema.is(Tenant);
60
+ const utf8 = new TextEncoder();
61
+ /** Maximum UTF-8 bytes of a `User.subject`. */
62
+ const SUBJECT_BYTES = 512;
63
+ /** Maximum UTF-8 bytes of the JSON-encoded caller. */
64
+ const CALLER_BYTES = 1024;
65
+ /** Whether the tenant is a valid id and, for a `User`, its subject and encoded caller fit their byte limits. */
66
+ export const withinLimits = (authenticated) => {
67
+ if (!isTenant(authenticated.tenant))
68
+ return false;
69
+ if (!Schema.is(User)(authenticated.caller))
70
+ return true;
71
+ const subject = utf8.encode(authenticated.caller.subject).byteLength;
72
+ return (subject >= 1 &&
73
+ subject <= SUBJECT_BYTES &&
74
+ utf8.encode(JSON.stringify(authenticated.caller)).byteLength <= CALLER_BYTES);
75
+ };
76
+ /** The default cap on the UTF-8 bytes of one credential a request carries. */
77
+ export const CREDENTIAL_BYTES = 8 * 1024;
78
+ /**
79
+ * Whether a credential `provider` would read from the request is over `limit`
80
+ * UTF-8 bytes: the `authorization` header or a frame credential, the cookie
81
+ * header for a cookie provider, and `durable-assertion` for an assertion
82
+ * provider. Checked before the provider runs, so it never parses an oversized one.
83
+ */
84
+ export const oversizedCredential = (options) => {
85
+ const over = (value) => value !== undefined && utf8.encode(value).byteLength > options.limit;
86
+ const header = (name) => Option.getOrUndefined(Headers.get(options.headers, name));
87
+ return (over(options.credential) ||
88
+ over(header("authorization")) ||
89
+ (readsCookies(options.provider) && over(header("cookie"))) ||
90
+ (options.provider.credentials.some(Credential.$is("Assertion")) &&
91
+ over(header(ASSERTION_HEADER))));
92
+ };
@@ -0,0 +1,10 @@
1
+ import { Effect } from "effect";
2
+ import { InternalActors } from "../runtime/actors.ts";
3
+ /**
4
+ * The database clock without a database read per request: an offset from the
5
+ * monotonic clock, resampled every 10 seconds, keeping the sample with the
6
+ * shortest round trip, so the estimate is off by at most that round trip.
7
+ */
8
+ export declare const databaseClock: Effect.Effect<{
9
+ now: () => number;
10
+ }, never, InternalActors | import("effect/Scope").Scope>;
@@ -0,0 +1,25 @@
1
+ import { Effect } from "effect";
2
+ import { InternalActors } from "../runtime/actors.js";
3
+ const SAMPLE_EVERY = "10 seconds";
4
+ /** A sample older than this is replaced even if its round trip was shorter. */
5
+ const STALE_MS = 60_000;
6
+ /**
7
+ * The database clock without a database read per request: an offset from the
8
+ * monotonic clock, resampled every 10 seconds, keeping the sample with the
9
+ * shortest round trip, so the estimate is off by at most that round trip.
10
+ */
11
+ export const databaseClock = Effect.gen(function* () {
12
+ const actors = yield* InternalActors;
13
+ const sample = Effect.gen(function* () {
14
+ const sent = performance.now();
15
+ const database = yield* actors.databaseNow;
16
+ const received = performance.now();
17
+ return { offset: database - (sent + received) / 2, rtt: received - sent, at: received };
18
+ });
19
+ let best = yield* sample.pipe(Effect.orDie);
20
+ yield* sample.pipe(Effect.delay(SAMPLE_EVERY), Effect.tap((next) => Effect.sync(() => {
21
+ if (next.rtt <= best.rtt || next.at - best.at >= STALE_MS)
22
+ best = next;
23
+ })), Effect.ignore, Effect.forever, Effect.forkScoped);
24
+ return { now: () => Math.round(performance.now() + best.offset) };
25
+ });
@@ -0,0 +1,65 @@
1
+ import { Duration, Schema } from "effect";
2
+ import { HttpClient } from "effect/http";
3
+ import { type AuthProvider } from "./auth.ts";
4
+ /** A JWS algorithm `Actor.auth.jwt` can verify. */
5
+ type Algorithm = "RS256" | "RS384" | "RS512" | "PS256" | "PS384" | "PS512" | "ES256" | "ES384" | "EdDSA";
6
+ /** A JSON Web Key as `Actor.auth.jwt` reads it; unrecognized members are dropped. */
7
+ export declare const Jwk: Schema.Struct<{
8
+ readonly kty: Schema.String;
9
+ readonly kid: Schema.optionalKey<Schema.String>;
10
+ readonly alg: Schema.optionalKey<Schema.String>;
11
+ readonly use: Schema.optionalKey<Schema.String>;
12
+ readonly crv: Schema.optionalKey<Schema.String>;
13
+ readonly n: Schema.optionalKey<Schema.String>;
14
+ readonly e: Schema.optionalKey<Schema.String>;
15
+ readonly x: Schema.optionalKey<Schema.String>;
16
+ readonly y: Schema.optionalKey<Schema.String>;
17
+ }>;
18
+ /** A JSON Web Key as `Actor.auth.jwt` reads it. */
19
+ export type Jwk = typeof Jwk.Type;
20
+ /** A static JSON Web Key Set. */
21
+ interface Jwks {
22
+ readonly keys: ReadonlyArray<Jwk>;
23
+ }
24
+ /** The verified payload of a JWT, handed to the `tenant` and `subject` callbacks. */
25
+ type Claims = Readonly<Record<string, Schema.Json>>;
26
+ /** Options of `Actor.auth.jwt`. */
27
+ interface JwtOptions<Keys extends URL | Jwks> {
28
+ /** The required `iss` claim. */
29
+ readonly issuer: string;
30
+ /** The token's `aud` must include at least one of these. */
31
+ readonly audience: string | ReadonlyArray<string>;
32
+ /** A JWKS URL, fetched when first needed and refetched for an unknown `kid` at most once a minute, or static keys. */
33
+ readonly jwks: Keys;
34
+ /** The tenant, from verified claims only. A single-tenant application returns `"default"`. */
35
+ readonly tenant: (claims: Claims) => string;
36
+ /** The stable subject; defaults to the `sub` claim. */
37
+ readonly subject?: (claims: Claims) => string;
38
+ /** Accepted asymmetric algorithms. Default `RS256`, `ES256`, and `EdDSA`. */
39
+ readonly algorithms?: ReadonlyArray<Algorithm>;
40
+ /** Default 30 seconds. */
41
+ readonly clockTolerance?: Duration.Input;
42
+ }
43
+ /**
44
+ * Verifies `authorization: Bearer` JWTs signed with an asymmetric key. `exp`
45
+ * is required; `iss` must equal `issuer` and `aud` must name an `audience`;
46
+ * `nbf` and `exp` are checked within `clockTolerance`. Tokens with `crit`
47
+ * headers or an algorithm outside `algorithms` are refused. A missing
48
+ * `authorization` header fails `missing_credentials`, an expired token
49
+ * `expired`, and every other failure `invalid_credentials`. With a JWKS URL
50
+ * the provider needs an `HttpClient`, and an unreachable key set fails
51
+ * `ActorUnavailable`.
52
+ * The credential's `exp` becomes the session's `expiresAt`.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * Actor.auth.jwt({
57
+ * issuer: "https://issuer.example.com",
58
+ * audience: "my-api",
59
+ * jwks: new URL("https://issuer.example.com/.well-known/jwks.json"),
60
+ * tenant: () => "default",
61
+ * })
62
+ * ```
63
+ */
64
+ export declare const jwt: <Keys extends URL | Jwks>(options: JwtOptions<Keys>) => AuthProvider<Keys extends URL ? HttpClient.HttpClient : never>;
65
+ export {};