@astrale-os/kernel-client 0.6.0-beta.8 → 0.6.0-beta.80

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 (473) hide show
  1. package/dist/auth/auth.d.ts +25 -10
  2. package/dist/auth/auth.js +5 -7
  3. package/dist/auth/authorization.d.ts +6 -4
  4. package/dist/auth/authorization.js +25 -6
  5. package/dist/auth/credential.d.ts +11 -2
  6. package/dist/auth/credential.js +6 -3
  7. package/dist/auth/identity.d.ts +6 -9
  8. package/dist/auth/identity.js +0 -1
  9. package/dist/auth/index.d.ts +4 -5
  10. package/dist/auth/index.js +2 -4
  11. package/dist/auth/register.d.ts +24 -0
  12. package/dist/auth/register.js +10 -0
  13. package/dist/client/admission.d.ts +4 -2
  14. package/dist/client/admission.js +8 -2
  15. package/dist/client/client.d.ts +4 -3
  16. package/dist/client/client.js +13 -3
  17. package/dist/client/credential.d.ts +4 -3
  18. package/dist/client/credential.js +7 -3
  19. package/dist/client/index.d.ts +1 -2
  20. package/dist/client/index.js +1 -2
  21. package/dist/client/request.d.ts +10 -4
  22. package/dist/client/request.js +33 -6
  23. package/dist/client/result.d.ts +3 -4
  24. package/dist/client/result.js +3 -1
  25. package/dist/client/routing-control.d.ts +0 -1
  26. package/dist/client/routing-control.js +0 -1
  27. package/dist/errors/client-error.d.ts +0 -1
  28. package/dist/errors/client-error.js +2 -1
  29. package/dist/errors/exchange-error.d.ts +19 -0
  30. package/dist/errors/exchange-error.js +9 -0
  31. package/dist/errors/index.d.ts +8 -7
  32. package/dist/errors/index.js +8 -7
  33. package/dist/errors/miss-error.d.ts +0 -1
  34. package/dist/errors/miss-error.js +0 -1
  35. package/dist/errors/protocol-error.d.ts +0 -1
  36. package/dist/errors/protocol-error.js +0 -1
  37. package/dist/errors/response-error.d.ts +0 -1
  38. package/dist/errors/response-error.js +0 -1
  39. package/dist/errors/session-error.d.ts +9 -0
  40. package/dist/errors/session-error.js +9 -0
  41. package/dist/errors/stale-route-error.d.ts +0 -1
  42. package/dist/errors/stale-route-error.js +0 -1
  43. package/dist/errors/transport-error.d.ts +18 -6
  44. package/dist/errors/transport-error.js +11 -7
  45. package/dist/graph/domain/binding.d.ts +22 -0
  46. package/dist/graph/domain/binding.js +123 -0
  47. package/dist/graph/domain/domain.typecheck.d.ts +1 -0
  48. package/dist/graph/domain/domain.typecheck.js +147 -0
  49. package/dist/graph/domain/index.d.ts +3 -0
  50. package/dist/graph/domain/index.js +1 -0
  51. package/dist/graph/domain/model.d.ts +18 -0
  52. package/dist/graph/domain/model.js +1 -0
  53. package/dist/graph/domain/page.d.ts +23 -0
  54. package/dist/graph/domain/page.js +42 -0
  55. package/dist/graph/domain/project.d.ts +8 -0
  56. package/dist/graph/domain/project.js +124 -0
  57. package/dist/graph/domain/provenance.d.ts +6 -0
  58. package/dist/graph/domain/provenance.js +11 -0
  59. package/dist/graph/errors.d.ts +2 -3
  60. package/dist/graph/errors.js +1 -2
  61. package/dist/graph/expectation.d.ts +3 -0
  62. package/dist/graph/expectation.js +6 -0
  63. package/dist/graph/graph.d.ts +12 -8
  64. package/dist/graph/graph.js +0 -1
  65. package/dist/graph/index.d.ts +2 -2
  66. package/dist/graph/index.js +1 -1
  67. package/dist/graph/mutation.d.ts +2 -4
  68. package/dist/graph/mutation.js +10 -2
  69. package/dist/graph/page/index.d.ts +0 -1
  70. package/dist/graph/page/index.js +0 -1
  71. package/dist/graph/page/neighbors.d.ts +4 -5
  72. package/dist/graph/page/neighbors.js +7 -7
  73. package/dist/graph/page/page.d.ts +5 -2
  74. package/dist/graph/page/page.js +0 -1
  75. package/dist/graph/page-contract.d.ts +1 -2
  76. package/dist/graph/page-contract.js +0 -1
  77. package/dist/graph/provenance.d.ts +14 -0
  78. package/dist/graph/provenance.js +42 -0
  79. package/dist/graph/query.d.ts +3 -1
  80. package/dist/graph/query.js +33 -13
  81. package/dist/graph/read.d.ts +3 -4
  82. package/dist/graph/read.js +6 -5
  83. package/dist/index.d.ts +3 -3
  84. package/dist/index.js +2 -2
  85. package/dist/pacer/batcher/batcher.d.ts +0 -1
  86. package/dist/pacer/batcher/batcher.js +0 -1
  87. package/dist/pacer/batcher/defaults.d.ts +0 -1
  88. package/dist/pacer/batcher/defaults.js +0 -1
  89. package/dist/pacer/batcher/index.d.ts +0 -1
  90. package/dist/pacer/batcher/index.js +0 -1
  91. package/dist/pacer/index.d.ts +0 -1
  92. package/dist/pacer/index.js +0 -1
  93. package/dist/pacer/limiter/defaults.d.ts +0 -1
  94. package/dist/pacer/limiter/defaults.js +0 -1
  95. package/dist/pacer/limiter/index.d.ts +0 -1
  96. package/dist/pacer/limiter/index.js +0 -1
  97. package/dist/pacer/limiter/limiter.d.ts +0 -1
  98. package/dist/pacer/limiter/limiter.js +0 -1
  99. package/dist/pacer/queue/defaults.d.ts +0 -1
  100. package/dist/pacer/queue/defaults.js +0 -1
  101. package/dist/pacer/queue/index.d.ts +0 -1
  102. package/dist/pacer/queue/index.js +0 -1
  103. package/dist/pacer/queue/queue.d.ts +0 -1
  104. package/dist/pacer/queue/queue.js +0 -1
  105. package/dist/pacer/retry/defaults.d.ts +0 -1
  106. package/dist/pacer/retry/defaults.js +0 -1
  107. package/dist/pacer/retry/index.d.ts +0 -1
  108. package/dist/pacer/retry/index.js +0 -1
  109. package/dist/pacer/retry/retry.d.ts +0 -1
  110. package/dist/pacer/retry/retry.js +0 -1
  111. package/dist/pool/index.d.ts +0 -1
  112. package/dist/pool/index.js +0 -1
  113. package/dist/pool/pool.d.ts +0 -1
  114. package/dist/pool/pool.js +0 -1
  115. package/dist/pool/target.d.ts +0 -1
  116. package/dist/pool/target.js +0 -1
  117. package/dist/schema/admission.d.ts +1 -2
  118. package/dist/schema/admission.js +0 -1
  119. package/dist/schema/contracts.d.ts +6 -16
  120. package/dist/schema/contracts.js +0 -1
  121. package/dist/schema/index.d.ts +2 -3
  122. package/dist/schema/index.js +1 -2
  123. package/dist/schema/introspection.d.ts +1 -2
  124. package/dist/schema/introspection.js +9 -2
  125. package/dist/schema/operation.d.ts +0 -1
  126. package/dist/schema/operation.js +2 -3
  127. package/dist/schema/schema.d.ts +13 -10
  128. package/dist/schema/schema.js +83 -11
  129. package/dist/session/admission.d.ts +6 -0
  130. package/dist/session/admission.js +59 -0
  131. package/dist/session/bound.d.ts +48 -0
  132. package/dist/session/bound.js +110 -0
  133. package/dist/session/content.d.ts +27 -0
  134. package/dist/session/content.js +158 -0
  135. package/dist/session/context/control.d.ts +0 -1
  136. package/dist/session/context/control.js +0 -1
  137. package/dist/session/context/index.d.ts +0 -1
  138. package/dist/session/context/index.js +0 -1
  139. package/dist/session/context/limits.d.ts +0 -1
  140. package/dist/session/context/limits.js +0 -1
  141. package/dist/session/context/operation.d.ts +5 -2
  142. package/dist/session/context/operation.js +19 -17
  143. package/dist/session/context/policy.d.ts +0 -1
  144. package/dist/session/context/policy.js +0 -1
  145. package/dist/session/credential/index.d.ts +1 -0
  146. package/dist/session/credential/index.js +1 -0
  147. package/dist/session/credential/limits.d.ts +12 -0
  148. package/dist/session/credential/limits.js +12 -0
  149. package/dist/session/credential/provider.d.ts +56 -0
  150. package/dist/session/credential/provider.js +236 -0
  151. package/dist/session/discovery/bundle.d.ts +5 -2
  152. package/dist/session/discovery/bundle.js +34 -15
  153. package/dist/session/discovery/discovery.d.ts +4 -2
  154. package/dist/session/discovery/discovery.js +34 -6
  155. package/dist/session/discovery/index.d.ts +3 -1
  156. package/dist/session/discovery/index.js +1 -1
  157. package/dist/session/discovery/publication.d.ts +0 -1
  158. package/dist/session/discovery/publication.js +4 -4
  159. package/dist/session/discovery/snapshot.d.ts +0 -1
  160. package/dist/session/discovery/snapshot.js +0 -1
  161. package/dist/session/discovery/transport.d.ts +6 -0
  162. package/dist/session/discovery/transport.js +13 -0
  163. package/dist/session/exchange/domain.d.ts +27 -0
  164. package/dist/session/exchange/domain.js +63 -0
  165. package/dist/session/exchange/exchange.d.ts +54 -0
  166. package/dist/session/exchange/exchange.js +58 -0
  167. package/dist/session/exchange/index.d.ts +5 -0
  168. package/dist/session/exchange/index.js +5 -0
  169. package/dist/session/exchange/issuer.d.ts +18 -0
  170. package/dist/session/exchange/issuer.js +149 -0
  171. package/dist/session/exchange/limits.d.ts +10 -0
  172. package/dist/session/exchange/limits.js +10 -0
  173. package/dist/session/exchange/options.d.ts +29 -0
  174. package/dist/session/exchange/options.js +57 -0
  175. package/dist/session/exchange/presentation.d.ts +18 -0
  176. package/dist/session/exchange/presentation.js +73 -0
  177. package/dist/session/exchange/source.d.ts +32 -0
  178. package/dist/session/exchange/source.js +78 -0
  179. package/dist/session/execution.d.ts +65 -0
  180. package/dist/session/execution.js +34 -0
  181. package/dist/session/index.d.ts +9 -4
  182. package/dist/session/index.js +4 -1
  183. package/dist/session/reference.d.ts +40 -12
  184. package/dist/session/reference.js +56 -14
  185. package/dist/session/routing/auth.d.ts +10 -1
  186. package/dist/session/routing/auth.js +8 -2
  187. package/dist/session/routing/cache.d.ts +27 -8
  188. package/dist/session/routing/cache.js +218 -25
  189. package/dist/session/routing/dispatch.d.ts +15 -8
  190. package/dist/session/routing/dispatch.js +121 -48
  191. package/dist/session/routing/envelope.d.ts +2 -1
  192. package/dist/session/routing/envelope.js +14 -10
  193. package/dist/session/routing/index.d.ts +3 -5
  194. package/dist/session/routing/index.js +2 -3
  195. package/dist/session/routing/request.d.ts +9 -1
  196. package/dist/session/routing/request.js +17 -1
  197. package/dist/session/session.d.ts +41 -8
  198. package/dist/session/session.js +129 -41
  199. package/dist/session/session.typecheck.d.ts +0 -1
  200. package/dist/session/session.typecheck.js +172 -3
  201. package/dist/session/views/catalog.d.ts +0 -1
  202. package/dist/session/views/catalog.js +14 -5
  203. package/dist/session/views/index.d.ts +0 -1
  204. package/dist/session/views/index.js +0 -1
  205. package/dist/session/views/resolve.d.ts +0 -1
  206. package/dist/session/views/resolve.js +0 -1
  207. package/dist/store/entity-index.d.ts +0 -1
  208. package/dist/store/entity-index.js +0 -1
  209. package/dist/store/index.d.ts +0 -1
  210. package/dist/store/index.js +0 -1
  211. package/dist/store/memory.d.ts +2 -2
  212. package/dist/store/memory.js +38 -15
  213. package/dist/store/mutation.d.ts +1 -2
  214. package/dist/store/mutation.js +6 -4
  215. package/dist/store/observe.d.ts +0 -1
  216. package/dist/store/observe.js +0 -1
  217. package/dist/store/optimistic.d.ts +0 -1
  218. package/dist/store/optimistic.js +0 -1
  219. package/dist/store/query-key.d.ts +2 -2
  220. package/dist/store/query-key.js +7 -3
  221. package/dist/store/shape.d.ts +4 -2
  222. package/dist/store/shape.js +4 -2
  223. package/dist/store/store.d.ts +2 -4
  224. package/dist/store/store.js +6 -5
  225. package/dist/store/store.typecheck.d.ts +0 -1
  226. package/dist/store/store.typecheck.js +3 -9
  227. package/dist/transport/auto/decision.d.ts +0 -1
  228. package/dist/transport/auto/decision.js +0 -1
  229. package/dist/transport/auto/fallback.d.ts +2 -2
  230. package/dist/transport/auto/fallback.js +10 -11
  231. package/dist/transport/auto/index.d.ts +0 -1
  232. package/dist/transport/auto/index.js +0 -1
  233. package/dist/transport/auto/transport.d.ts +0 -1
  234. package/dist/transport/auto/transport.js +5 -6
  235. package/dist/transport/auto/warning.d.ts +0 -1
  236. package/dist/transport/auto/warning.js +5 -3
  237. package/dist/transport/deadline.d.ts +0 -1
  238. package/dist/transport/deadline.js +0 -1
  239. package/dist/transport/failure.d.ts +7 -0
  240. package/dist/transport/failure.js +9 -0
  241. package/dist/transport/http/byte-stream.d.ts +18 -0
  242. package/dist/transport/http/byte-stream.js +94 -0
  243. package/dist/transport/http/index.d.ts +0 -1
  244. package/dist/transport/http/index.js +0 -1
  245. package/dist/transport/http/response.d.ts +0 -1
  246. package/dist/transport/http/response.js +0 -1
  247. package/dist/transport/http/stream.d.ts +0 -1
  248. package/dist/transport/http/stream.js +7 -7
  249. package/dist/transport/http/transport.d.ts +3 -1
  250. package/dist/transport/http/transport.js +87 -30
  251. package/dist/transport/index.d.ts +0 -1
  252. package/dist/transport/index.js +0 -1
  253. package/dist/transport/transport.d.ts +0 -1
  254. package/dist/transport/transport.js +0 -1
  255. package/dist/transport/websocket/connection.d.ts +0 -1
  256. package/dist/transport/websocket/connection.js +16 -26
  257. package/dist/transport/websocket/exchange.d.ts +0 -1
  258. package/dist/transport/websocket/exchange.js +5 -9
  259. package/dist/transport/websocket/index.d.ts +0 -1
  260. package/dist/transport/websocket/index.js +0 -1
  261. package/dist/transport/websocket/transport.d.ts +0 -1
  262. package/dist/transport/websocket/transport.js +7 -20
  263. package/package.json +12 -14
  264. package/dist/auth/auth.d.ts.map +0 -1
  265. package/dist/auth/auth.js.map +0 -1
  266. package/dist/auth/authorization.d.ts.map +0 -1
  267. package/dist/auth/authorization.js.map +0 -1
  268. package/dist/auth/credential.d.ts.map +0 -1
  269. package/dist/auth/credential.js.map +0 -1
  270. package/dist/auth/identity.d.ts.map +0 -1
  271. package/dist/auth/identity.js.map +0 -1
  272. package/dist/auth/index.d.ts.map +0 -1
  273. package/dist/auth/index.js.map +0 -1
  274. package/dist/auth/provision.d.ts +0 -9
  275. package/dist/auth/provision.d.ts.map +0 -1
  276. package/dist/auth/provision.js +0 -11
  277. package/dist/auth/provision.js.map +0 -1
  278. package/dist/client/admission.d.ts.map +0 -1
  279. package/dist/client/admission.js.map +0 -1
  280. package/dist/client/client.d.ts.map +0 -1
  281. package/dist/client/client.js.map +0 -1
  282. package/dist/client/credential.d.ts.map +0 -1
  283. package/dist/client/credential.js.map +0 -1
  284. package/dist/client/index.d.ts.map +0 -1
  285. package/dist/client/index.js.map +0 -1
  286. package/dist/client/request.d.ts.map +0 -1
  287. package/dist/client/request.js.map +0 -1
  288. package/dist/client/result.d.ts.map +0 -1
  289. package/dist/client/result.js.map +0 -1
  290. package/dist/client/routing-control.d.ts.map +0 -1
  291. package/dist/client/routing-control.js.map +0 -1
  292. package/dist/errors/client-error.d.ts.map +0 -1
  293. package/dist/errors/client-error.js.map +0 -1
  294. package/dist/errors/index.d.ts.map +0 -1
  295. package/dist/errors/index.js.map +0 -1
  296. package/dist/errors/miss-error.d.ts.map +0 -1
  297. package/dist/errors/miss-error.js.map +0 -1
  298. package/dist/errors/protocol-error.d.ts.map +0 -1
  299. package/dist/errors/protocol-error.js.map +0 -1
  300. package/dist/errors/response-error.d.ts.map +0 -1
  301. package/dist/errors/response-error.js.map +0 -1
  302. package/dist/errors/stale-route-error.d.ts.map +0 -1
  303. package/dist/errors/stale-route-error.js.map +0 -1
  304. package/dist/errors/transport-error.d.ts.map +0 -1
  305. package/dist/errors/transport-error.js.map +0 -1
  306. package/dist/graph/errors.d.ts.map +0 -1
  307. package/dist/graph/errors.js.map +0 -1
  308. package/dist/graph/graph.d.ts.map +0 -1
  309. package/dist/graph/graph.js.map +0 -1
  310. package/dist/graph/index.d.ts.map +0 -1
  311. package/dist/graph/index.js.map +0 -1
  312. package/dist/graph/mutation.d.ts.map +0 -1
  313. package/dist/graph/mutation.js.map +0 -1
  314. package/dist/graph/page/index.d.ts.map +0 -1
  315. package/dist/graph/page/index.js.map +0 -1
  316. package/dist/graph/page/neighbors.d.ts.map +0 -1
  317. package/dist/graph/page/neighbors.js.map +0 -1
  318. package/dist/graph/page/page.d.ts.map +0 -1
  319. package/dist/graph/page/page.js.map +0 -1
  320. package/dist/graph/page-contract.d.ts.map +0 -1
  321. package/dist/graph/page-contract.js.map +0 -1
  322. package/dist/graph/query.d.ts.map +0 -1
  323. package/dist/graph/query.js.map +0 -1
  324. package/dist/graph/read.d.ts.map +0 -1
  325. package/dist/graph/read.js.map +0 -1
  326. package/dist/index.d.ts.map +0 -1
  327. package/dist/index.js.map +0 -1
  328. package/dist/pacer/batcher/batcher.d.ts.map +0 -1
  329. package/dist/pacer/batcher/batcher.js.map +0 -1
  330. package/dist/pacer/batcher/defaults.d.ts.map +0 -1
  331. package/dist/pacer/batcher/defaults.js.map +0 -1
  332. package/dist/pacer/batcher/index.d.ts.map +0 -1
  333. package/dist/pacer/batcher/index.js.map +0 -1
  334. package/dist/pacer/index.d.ts.map +0 -1
  335. package/dist/pacer/index.js.map +0 -1
  336. package/dist/pacer/limiter/defaults.d.ts.map +0 -1
  337. package/dist/pacer/limiter/defaults.js.map +0 -1
  338. package/dist/pacer/limiter/index.d.ts.map +0 -1
  339. package/dist/pacer/limiter/index.js.map +0 -1
  340. package/dist/pacer/limiter/limiter.d.ts.map +0 -1
  341. package/dist/pacer/limiter/limiter.js.map +0 -1
  342. package/dist/pacer/queue/defaults.d.ts.map +0 -1
  343. package/dist/pacer/queue/defaults.js.map +0 -1
  344. package/dist/pacer/queue/index.d.ts.map +0 -1
  345. package/dist/pacer/queue/index.js.map +0 -1
  346. package/dist/pacer/queue/queue.d.ts.map +0 -1
  347. package/dist/pacer/queue/queue.js.map +0 -1
  348. package/dist/pacer/retry/defaults.d.ts.map +0 -1
  349. package/dist/pacer/retry/defaults.js.map +0 -1
  350. package/dist/pacer/retry/index.d.ts.map +0 -1
  351. package/dist/pacer/retry/index.js.map +0 -1
  352. package/dist/pacer/retry/retry.d.ts.map +0 -1
  353. package/dist/pacer/retry/retry.js.map +0 -1
  354. package/dist/pool/index.d.ts.map +0 -1
  355. package/dist/pool/index.js.map +0 -1
  356. package/dist/pool/pool.d.ts.map +0 -1
  357. package/dist/pool/pool.js.map +0 -1
  358. package/dist/pool/target.d.ts.map +0 -1
  359. package/dist/pool/target.js.map +0 -1
  360. package/dist/schema/admission.d.ts.map +0 -1
  361. package/dist/schema/admission.js.map +0 -1
  362. package/dist/schema/contracts.d.ts.map +0 -1
  363. package/dist/schema/contracts.js.map +0 -1
  364. package/dist/schema/index.d.ts.map +0 -1
  365. package/dist/schema/index.js.map +0 -1
  366. package/dist/schema/introspection.d.ts.map +0 -1
  367. package/dist/schema/introspection.js.map +0 -1
  368. package/dist/schema/operation.d.ts.map +0 -1
  369. package/dist/schema/operation.js.map +0 -1
  370. package/dist/schema/schema.d.ts.map +0 -1
  371. package/dist/schema/schema.js.map +0 -1
  372. package/dist/session/context/control.d.ts.map +0 -1
  373. package/dist/session/context/control.js.map +0 -1
  374. package/dist/session/context/index.d.ts.map +0 -1
  375. package/dist/session/context/index.js.map +0 -1
  376. package/dist/session/context/limits.d.ts.map +0 -1
  377. package/dist/session/context/limits.js.map +0 -1
  378. package/dist/session/context/operation.d.ts.map +0 -1
  379. package/dist/session/context/operation.js.map +0 -1
  380. package/dist/session/context/policy.d.ts.map +0 -1
  381. package/dist/session/context/policy.js.map +0 -1
  382. package/dist/session/discovery/bundle.d.ts.map +0 -1
  383. package/dist/session/discovery/bundle.js.map +0 -1
  384. package/dist/session/discovery/discovery.d.ts.map +0 -1
  385. package/dist/session/discovery/discovery.js.map +0 -1
  386. package/dist/session/discovery/index.d.ts.map +0 -1
  387. package/dist/session/discovery/index.js.map +0 -1
  388. package/dist/session/discovery/publication.d.ts.map +0 -1
  389. package/dist/session/discovery/publication.js.map +0 -1
  390. package/dist/session/discovery/snapshot.d.ts.map +0 -1
  391. package/dist/session/discovery/snapshot.js.map +0 -1
  392. package/dist/session/index.d.ts.map +0 -1
  393. package/dist/session/index.js.map +0 -1
  394. package/dist/session/reference.d.ts.map +0 -1
  395. package/dist/session/reference.js.map +0 -1
  396. package/dist/session/routing/auth.d.ts.map +0 -1
  397. package/dist/session/routing/auth.js.map +0 -1
  398. package/dist/session/routing/cache.d.ts.map +0 -1
  399. package/dist/session/routing/cache.js.map +0 -1
  400. package/dist/session/routing/dispatch.d.ts.map +0 -1
  401. package/dist/session/routing/dispatch.js.map +0 -1
  402. package/dist/session/routing/envelope.d.ts.map +0 -1
  403. package/dist/session/routing/envelope.js.map +0 -1
  404. package/dist/session/routing/expectation.d.ts +0 -7
  405. package/dist/session/routing/expectation.d.ts.map +0 -1
  406. package/dist/session/routing/expectation.js +0 -2
  407. package/dist/session/routing/expectation.js.map +0 -1
  408. package/dist/session/routing/index.d.ts.map +0 -1
  409. package/dist/session/routing/index.js.map +0 -1
  410. package/dist/session/routing/request.d.ts.map +0 -1
  411. package/dist/session/routing/request.js.map +0 -1
  412. package/dist/session/session.d.ts.map +0 -1
  413. package/dist/session/session.js.map +0 -1
  414. package/dist/session/session.typecheck.d.ts.map +0 -1
  415. package/dist/session/session.typecheck.js.map +0 -1
  416. package/dist/session/views/catalog.d.ts.map +0 -1
  417. package/dist/session/views/catalog.js.map +0 -1
  418. package/dist/session/views/index.d.ts.map +0 -1
  419. package/dist/session/views/index.js.map +0 -1
  420. package/dist/session/views/resolve.d.ts.map +0 -1
  421. package/dist/session/views/resolve.js.map +0 -1
  422. package/dist/store/entity-index.d.ts.map +0 -1
  423. package/dist/store/entity-index.js.map +0 -1
  424. package/dist/store/index.d.ts.map +0 -1
  425. package/dist/store/index.js.map +0 -1
  426. package/dist/store/memory.d.ts.map +0 -1
  427. package/dist/store/memory.js.map +0 -1
  428. package/dist/store/mutation.d.ts.map +0 -1
  429. package/dist/store/mutation.js.map +0 -1
  430. package/dist/store/observe.d.ts.map +0 -1
  431. package/dist/store/observe.js.map +0 -1
  432. package/dist/store/optimistic.d.ts.map +0 -1
  433. package/dist/store/optimistic.js.map +0 -1
  434. package/dist/store/query-key.d.ts.map +0 -1
  435. package/dist/store/query-key.js.map +0 -1
  436. package/dist/store/shape.d.ts.map +0 -1
  437. package/dist/store/shape.js.map +0 -1
  438. package/dist/store/store.d.ts.map +0 -1
  439. package/dist/store/store.js.map +0 -1
  440. package/dist/store/store.typecheck.d.ts.map +0 -1
  441. package/dist/store/store.typecheck.js.map +0 -1
  442. package/dist/transport/auto/decision.d.ts.map +0 -1
  443. package/dist/transport/auto/decision.js.map +0 -1
  444. package/dist/transport/auto/fallback.d.ts.map +0 -1
  445. package/dist/transport/auto/fallback.js.map +0 -1
  446. package/dist/transport/auto/index.d.ts.map +0 -1
  447. package/dist/transport/auto/index.js.map +0 -1
  448. package/dist/transport/auto/transport.d.ts.map +0 -1
  449. package/dist/transport/auto/transport.js.map +0 -1
  450. package/dist/transport/auto/warning.d.ts.map +0 -1
  451. package/dist/transport/auto/warning.js.map +0 -1
  452. package/dist/transport/deadline.d.ts.map +0 -1
  453. package/dist/transport/deadline.js.map +0 -1
  454. package/dist/transport/http/index.d.ts.map +0 -1
  455. package/dist/transport/http/index.js.map +0 -1
  456. package/dist/transport/http/response.d.ts.map +0 -1
  457. package/dist/transport/http/response.js.map +0 -1
  458. package/dist/transport/http/stream.d.ts.map +0 -1
  459. package/dist/transport/http/stream.js.map +0 -1
  460. package/dist/transport/http/transport.d.ts.map +0 -1
  461. package/dist/transport/http/transport.js.map +0 -1
  462. package/dist/transport/index.d.ts.map +0 -1
  463. package/dist/transport/index.js.map +0 -1
  464. package/dist/transport/transport.d.ts.map +0 -1
  465. package/dist/transport/transport.js.map +0 -1
  466. package/dist/transport/websocket/connection.d.ts.map +0 -1
  467. package/dist/transport/websocket/connection.js.map +0 -1
  468. package/dist/transport/websocket/exchange.d.ts.map +0 -1
  469. package/dist/transport/websocket/exchange.js.map +0 -1
  470. package/dist/transport/websocket/index.d.ts.map +0 -1
  471. package/dist/transport/websocket/index.js.map +0 -1
  472. package/dist/transport/websocket/transport.d.ts.map +0 -1
  473. package/dist/transport/websocket/transport.js.map +0 -1
@@ -0,0 +1,54 @@
1
+ import type { MintedCredential, UnresolvedIdentityExpr } from '@astrale-os/kernel-core/auth';
2
+ import type { IssuerId } from '@astrale-os/kernel-core/auth/issuer';
3
+ import type { Client } from '../../client/index.js';
4
+ import type { SchemaOptions } from '../../schema/schema.js';
5
+ import type { Fetch } from '../../transport/http/index.js';
6
+ import type { SessionOperation, SessionPolicy } from '../context/index.js';
7
+ import type { SessionCredential } from '../credential/index.js';
8
+ import type { EffectiveAuth, SessionAuth } from '../routing/index.js';
9
+ import type { ExchangeRequest } from './options.js';
10
+ /** Everything an exchange reaches: the Session's source Kernel and authority, and the Domain legs. */
11
+ export interface ExchangeDependencies {
12
+ readonly kernel: IssuerId;
13
+ /** Unauthenticated Client for the source Kernel invocation endpoint. */
14
+ readonly source: () => Client;
15
+ /** The Session's source authority, when the Session has one. */
16
+ readonly auth?: SessionAuth;
17
+ readonly fetch: Fetch;
18
+ readonly policy: Readonly<SessionPolicy>;
19
+ readonly limits: SchemaOptions;
20
+ readonly maximumResponseBytes: number;
21
+ /** Open one operation for work shared by several Calls; it fails once the Session closes. */
22
+ readonly operation: (signal?: AbortSignal) => SessionOperation;
23
+ }
24
+ /** One Domain-issued Kernel credential and the delegation the Domain exchanged for it. */
25
+ export interface DomainCredential extends SessionCredential {
26
+ readonly delegation: MintedCredential;
27
+ }
28
+ export interface DomainExchangeRequest {
29
+ readonly issuer: IssuerId;
30
+ /** Requested delegation lifetime; the source credential's remaining lifetime bounds it. */
31
+ readonly ttlSeconds: number;
32
+ readonly attenuation: UnresolvedIdentityExpr;
33
+ /**
34
+ * Lifetime the returned credential must exceed. A source that bounds the delegation within it is
35
+ * exhausted rather than exchanged.
36
+ */
37
+ readonly coverageMs?: number;
38
+ }
39
+ /** The attenuation that delegates the source caller's own identity. */
40
+ export declare const SELF_ATTENUATION: Readonly<{
41
+ readonly kind: 'identity';
42
+ readonly self: true;
43
+ }>;
44
+ /**
45
+ * Delegate the source caller to one Domain issuer and redeem that delegation at the issuer's
46
+ * advertised endpoint for the Domain's credential to the source Kernel.
47
+ */
48
+ export declare function exchangeDomainCredential(dependencies: ExchangeDependencies, source: EffectiveAuth, request: DomainExchangeRequest, operation: SessionOperation): Promise<DomainCredential>;
49
+ /**
50
+ * One Domain credential for a named Domain issuer, as `session.exchange` returns it. When the
51
+ * request asks for more than the Session delegation, the credential covers that delegation, and the
52
+ * source is renewed once if the current one can no longer feed it.
53
+ */
54
+ export declare function acquireDomainCredential(dependencies: ExchangeDependencies, request: ExchangeRequest, operation: SessionOperation): Promise<SessionCredential>;
@@ -0,0 +1,58 @@
1
+ import { credentialApi, IDENTITY_DELEGATE_PATH } from '../../auth/credential.js';
2
+ import { identityApi } from '../../auth/identity.js';
3
+ import { delegationCoverageMs } from '../credential/index.js';
4
+ import { resolveAuth } from '../routing/index.js';
5
+ import { redeem, tokenEndpoint } from './issuer.js';
6
+ import { delegationTtl, isAuthority, renewing, sourceCaller, sourceExhausted } from './source.js';
7
+ /** The attenuation that delegates the source caller's own identity. */
8
+ export const SELF_ATTENUATION = Object.freeze({ kind: 'identity', self: true });
9
+ /**
10
+ * Delegate the source caller to one Domain issuer and redeem that delegation at the issuer's
11
+ * advertised endpoint for the Domain's credential to the source Kernel.
12
+ */
13
+ export async function exchangeDomainCredential(dependencies, source, request, operation) {
14
+ const caller = sourceCaller(dependencies, source, operation);
15
+ const [endpoint, principal] = await Promise.all([
16
+ tokenEndpoint(dependencies, request.issuer, operation),
17
+ identityApi(caller.call)
18
+ .whoami()
19
+ .then(({ id }) => id),
20
+ ]);
21
+ const ttlSeconds = delegationTtl(source.credential, request.ttlSeconds, request.coverageMs);
22
+ const delegation = await credentialApi(caller.call).delegate(principal, {
23
+ audience: request.issuer,
24
+ ttlSeconds,
25
+ attenuation: request.attenuation,
26
+ });
27
+ const credential = await redeem(dependencies, request.issuer, endpoint, delegation, operation);
28
+ // A Domain credential never outlives its source, so only a fresher source can lengthen it.
29
+ const bySource = ttlSeconds < request.ttlSeconds;
30
+ if (bySource && credential.expiresAt - Date.now() <= (request.coverageMs ?? 0)) {
31
+ throw sourceExhausted();
32
+ }
33
+ return Object.freeze({ ...credential, delegation });
34
+ }
35
+ /**
36
+ * One Domain credential for a named Domain issuer, as `session.exchange` returns it. When the
37
+ * request asks for more than the Session delegation, the credential covers that delegation, and the
38
+ * source is renewed once if the current one can no longer feed it.
39
+ */
40
+ export async function acquireDomainCredential(dependencies, request, operation) {
41
+ const { auth } = dependencies;
42
+ const call = {
43
+ target: IDENTITY_DELEGATE_PATH,
44
+ input: { audience: request.issuer, ttlSeconds: request.ttlSeconds },
45
+ };
46
+ const coverageMs = auth === undefined ? 0 : delegationCoverageMs(auth.ttlSeconds);
47
+ const exchange = (source) => exchangeDomainCredential(dependencies, source, {
48
+ issuer: request.issuer,
49
+ ttlSeconds: request.ttlSeconds,
50
+ attenuation: source.delegate?.attenuation ?? SELF_ATTENUATION,
51
+ ...(request.ttlSeconds * 1_000 > coverageMs ? { coverageMs } : {}),
52
+ }, operation);
53
+ const source = await resolveAuth(auth, call, operation);
54
+ const exchanged = auth === undefined || !isAuthority(source)
55
+ ? await exchange(source)
56
+ : await renewing(auth, call, source, operation, exchange);
57
+ return Object.freeze({ credential: exchanged.credential, expiresAt: exchanged.expiresAt });
58
+ }
@@ -0,0 +1,5 @@
1
+ export { callableOrigin, installedIssuer } from './domain.js';
2
+ export { acquireDomainCredential, exchangeDomainCredential, SELF_ATTENUATION, type DomainCredential, type DomainExchangeRequest, type ExchangeDependencies, } from './exchange.js';
3
+ export { admitExchangeOptions, admitExchangeRequest, type ExchangeRequest, type SessionExchangeOptions, type SessionExchangeRequest, } from './options.js';
4
+ export { createSessionExchange, type SessionExchange } from './presentation.js';
5
+ export { isAuthority } from './source.js';
@@ -0,0 +1,5 @@
1
+ export { callableOrigin, installedIssuer } from './domain.js';
2
+ export { acquireDomainCredential, exchangeDomainCredential, SELF_ATTENUATION, } from './exchange.js';
3
+ export { admitExchangeOptions, admitExchangeRequest, } from './options.js';
4
+ export { createSessionExchange } from './presentation.js';
5
+ export { isAuthority } from './source.js';
@@ -0,0 +1,18 @@
1
+ import type { MintedCredential } from '@astrale-os/kernel-core/auth';
2
+ import type { IssuerId } from '@astrale-os/kernel-core/auth/issuer';
3
+ import type { SessionOperation } from '../context/index.js';
4
+ import type { SessionCredential } from '../credential/index.js';
5
+ import type { ExchangeDependencies } from './exchange.js';
6
+ type IssuerDependencies = Pick<ExchangeDependencies, 'kernel' | 'fetch' | 'policy' | 'maximumResponseBytes'>;
7
+ /**
8
+ * The token exchange endpoint a Domain issuer advertises. Endpoint policy applies here, so a denied
9
+ * endpoint is never returned and no delegation is minted for it.
10
+ */
11
+ export declare function tokenEndpoint(dependencies: IssuerDependencies, domain: IssuerId, operation: SessionOperation): Promise<string>;
12
+ /**
13
+ * Present a delegation at a Domain's token endpoint and admit the returned credential as provider
14
+ * evidence: it must be the exchange representation served with `Cache-Control: no-store`, its
15
+ * issuer that Domain, its audience the source Kernel, and its signed expiry the reported one.
16
+ */
17
+ export declare function redeem(dependencies: IssuerDependencies, domain: IssuerId, endpoint: string, delegation: MintedCredential, operation: SessionOperation): Promise<SessionCredential>;
18
+ export {};
@@ -0,0 +1,149 @@
1
+ import { inspect } from '@astrale-os/kernel-core/auth/credential';
2
+ import { codecs, issuer } from '@astrale-os/kernel-protocol';
3
+ import { ProtocolError } from '@astrale-os/kernel-protocol/errors';
4
+ import { ClientError, ExchangeError, SessionError } from '../../errors/index.js';
5
+ import { allowEndpoint, runSessionOperation } from '../context/index.js';
6
+ import { boundedResponse, requireExactResponse } from '../discovery/index.js';
7
+ const DISCOVERY = Object.freeze({ name: 'discovery', invalid: 'discovery' });
8
+ const TOKEN_EXCHANGE = Object.freeze({ name: 'token exchange', invalid: 'invalid-response' });
9
+ /**
10
+ * The token exchange endpoint a Domain issuer advertises. Endpoint policy applies here, so a denied
11
+ * endpoint is never returned and no delegation is minted for it.
12
+ */
13
+ export async function tokenEndpoint(dependencies, domain, operation) {
14
+ const configuration = await fetchAdmitted(dependencies, DISCOVERY, new URL(issuer.paths(domain).configuration, domain).href, operation, (body) => issuer.acceptConfiguration(body, domain));
15
+ const endpoint = configuration.token_exchange_endpoint;
16
+ if (endpoint === undefined) {
17
+ throw new ExchangeError('The installed Domain does not advertise token exchange.', {
18
+ failure: 'unsupported',
19
+ });
20
+ }
21
+ allowEndpoint(endpoint, dependencies.policy);
22
+ return endpoint;
23
+ }
24
+ /**
25
+ * Present a delegation at a Domain's token endpoint and admit the returned credential as provider
26
+ * evidence: it must be the exchange representation served with `Cache-Control: no-store`, its
27
+ * issuer that Domain, its audience the source Kernel, and its signed expiry the reported one.
28
+ */
29
+ export async function redeem(dependencies, domain, endpoint, delegation, operation) {
30
+ const exchanged = await fetchAdmitted(dependencies, TOKEN_EXCHANGE, endpoint, operation, (body, headers) => {
31
+ requireCredentialHeaders(headers);
32
+ return issuer.exchange.acceptResponse(body);
33
+ }, delegation);
34
+ let claims;
35
+ try {
36
+ claims = inspect(exchanged.token);
37
+ }
38
+ catch (cause) {
39
+ throw invalidResponse('Domain token exchange returned an invalid credential.', cause);
40
+ }
41
+ if (claims.iss !== domain ||
42
+ claims.aud !== dependencies.kernel ||
43
+ claims.claims.exp !== exchanged.expiresAt) {
44
+ throw invalidResponse('Domain token exchange returned an inconsistent credential.');
45
+ }
46
+ const expiresAt = exchanged.expiresAt * 1_000;
47
+ if (expiresAt <= Date.now()) {
48
+ throw invalidResponse('Domain token exchange returned an expired credential.');
49
+ }
50
+ return Object.freeze({ credential: exchanged.token, expiresAt });
51
+ }
52
+ /** Fetch one issuer leg and admit its JSON body; every failure names the leg that caused it. */
53
+ async function fetchAdmitted(dependencies, leg, url, operation, admit, credential) {
54
+ allowEndpoint(url, dependencies.policy);
55
+ return runSessionOperation(operation, async (signal) => {
56
+ const init = {
57
+ method: credential === undefined ? 'GET' : 'POST',
58
+ headers: {
59
+ accept: credential === undefined ? 'application/json' : issuer.exchange.MEDIA_TYPE,
60
+ ...(credential === undefined ? {} : { authorization: `Bearer ${credential}` }),
61
+ },
62
+ credentials: 'omit',
63
+ cache: 'no-store',
64
+ referrerPolicy: 'no-referrer',
65
+ redirect: 'manual',
66
+ signal,
67
+ };
68
+ let response;
69
+ try {
70
+ response = await dependencies.fetch(url, init);
71
+ }
72
+ catch (cause) {
73
+ if (signal.aborted)
74
+ throw cause;
75
+ throw new ExchangeError(`Domain ${leg.name} could not be reached.`, {
76
+ failure: 'unavailable',
77
+ cause,
78
+ });
79
+ }
80
+ try {
81
+ requireExactResponse(response, url, 'Domain token exchange');
82
+ if (!response.ok)
83
+ throw await refusal(response, leg, signal);
84
+ return admit(codecs.json.decode(await boundedResponse(response, dependencies.maximumResponseBytes, signal)), response.headers);
85
+ }
86
+ catch (cause) {
87
+ throw signal.aborted ? cause : unadmitted(cause, leg);
88
+ }
89
+ finally {
90
+ // Also release unread bodies rejected by URL, status, or declared-size validation.
91
+ void response.body?.cancel().catch(() => undefined);
92
+ }
93
+ });
94
+ async function refusal(response, leg, signal) {
95
+ const status = `Domain ${leg.name} returned HTTP ${response.status}.`;
96
+ const refused = leg === TOKEN_EXCHANGE ? await domainError(response, signal) : undefined;
97
+ return refused === undefined
98
+ ? new ExchangeError(status, { failure: leg.invalid })
99
+ : new ExchangeError(`${status} ${refused.payload.code}: ${refused.message}`, {
100
+ failure: 'rejected',
101
+ cause: refused,
102
+ });
103
+ }
104
+ async function domainError(response, signal) {
105
+ try {
106
+ const body = await boundedResponse(response, dependencies.maximumResponseBytes, signal);
107
+ return new ProtocolError(issuer.exchange.acceptErrorResponse(codecs.json.decode(body)).error);
108
+ }
109
+ catch {
110
+ return undefined;
111
+ }
112
+ }
113
+ }
114
+ /**
115
+ * Report evidence the leg could not admit under that leg's failure. Validation failures of the
116
+ * representation (type, syntax, response shape) become exchange failures; anything else, including
117
+ * Session interruption and unknown defects, keeps its own identity.
118
+ */
119
+ function unadmitted(cause, leg) {
120
+ if (cause instanceof ExchangeError || cause instanceof SessionError)
121
+ return cause;
122
+ if (cause instanceof ClientError || cause instanceof TypeError || cause instanceof SyntaxError) {
123
+ return new ExchangeError(`Domain ${leg.name} returned an invalid response.`, {
124
+ failure: leg.invalid,
125
+ cause,
126
+ });
127
+ }
128
+ return cause;
129
+ }
130
+ /** A credential is served as the exchange representation and never stored by an HTTP cache. */
131
+ function requireCredentialHeaders(headers) {
132
+ const mediaType = headers.get('content-type')?.split(';', 1)[0].trim().toLowerCase();
133
+ if (mediaType !== issuer.exchange.MEDIA_TYPE) {
134
+ throw invalidResponse('Domain token exchange returned an unsupported Content-Type.');
135
+ }
136
+ const directives = headers
137
+ .get('cache-control')
138
+ ?.split(',')
139
+ .map((directive) => directive.trim().toLowerCase()) ?? [];
140
+ if (!directives.includes('no-store')) {
141
+ throw invalidResponse('Domain token exchange response is missing Cache-Control: no-store.');
142
+ }
143
+ }
144
+ function invalidResponse(message, cause) {
145
+ return new ExchangeError(message, {
146
+ failure: 'invalid-response',
147
+ ...(cause === undefined ? {} : { cause }),
148
+ });
149
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Delegation lifetime requested for each Domain credential when the caller names none. Short enough
3
+ * that a leaked Domain credential is worth little, long enough that a script re-exchanges each
4
+ * Domain a few times an hour rather than once per call.
5
+ */
6
+ export declare const DEFAULT_EXCHANGE_TTL_SECONDS: number;
7
+ /** Lifetime kept below the source credential, which the Kernel refuses to let a delegation reach. */
8
+ export declare const ISSUANCE_MARGIN_SECONDS = 5;
9
+ /** Source credentials whose Domain credentials one Session retains at once. */
10
+ export declare const MAXIMUM_EXCHANGE_SOURCES = 8;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Delegation lifetime requested for each Domain credential when the caller names none. Short enough
3
+ * that a leaked Domain credential is worth little, long enough that a script re-exchanges each
4
+ * Domain a few times an hour rather than once per call.
5
+ */
6
+ export const DEFAULT_EXCHANGE_TTL_SECONDS = 5 * 60;
7
+ /** Lifetime kept below the source credential, which the Kernel refuses to let a delegation reach. */
8
+ export const ISSUANCE_MARGIN_SECONDS = 5;
9
+ /** Source credentials whose Domain credentials one Session retains at once. */
10
+ export const MAXIMUM_EXCHANGE_SOURCES = 8;
@@ -0,0 +1,29 @@
1
+ import { type IssuerId } from '@astrale-os/kernel-core/auth/issuer';
2
+ import type { SessionControlOptions } from '../context/index.js';
3
+ import type { SessionAuth } from '../routing/index.js';
4
+ /** Present each Domain callable with its declaring Domain's credential instead of the source one. */
5
+ export interface SessionExchangeOptions {
6
+ /**
7
+ * Delegation lifetime requested for each Domain credential. The source credential's remaining
8
+ * lifetime and the Domain's own ceiling may shorten it.
9
+ */
10
+ readonly ttlSeconds?: number;
11
+ }
12
+ /** One explicit exchange through a named Domain issuer. */
13
+ export interface SessionExchangeRequest extends SessionControlOptions {
14
+ /** Requested delegation lifetime; the source credential and the Domain may shorten it. */
15
+ readonly ttlSeconds?: number;
16
+ }
17
+ /** An admitted explicit exchange. */
18
+ export interface ExchangeRequest {
19
+ readonly issuer: IssuerId;
20
+ readonly ttlSeconds: number;
21
+ readonly control: Readonly<SessionControlOptions>;
22
+ }
23
+ /**
24
+ * Admit exchange options against the Session auth they extend. Every Domain credential must still
25
+ * cover the Session delegation, so a request that could never cover it is rejected.
26
+ */
27
+ export declare function admitExchangeOptions(input: SessionExchangeOptions | undefined, auth: SessionAuth | undefined): Readonly<Required<SessionExchangeOptions>> | undefined;
28
+ /** Admit an explicit exchange: the canonical absolute issuer URL of the named Domain and its lifetime. */
29
+ export declare function admitExchangeRequest(domain: string, input: SessionExchangeRequest | undefined): ExchangeRequest;
@@ -0,0 +1,57 @@
1
+ import { accept as acceptIssuer } from '@astrale-os/kernel-core/auth/issuer';
2
+ import { admitControlOptions } from '../context/index.js';
3
+ import { delegationCoverageMs } from '../credential/index.js';
4
+ import { DEFAULT_EXCHANGE_TTL_SECONDS } from './limits.js';
5
+ /**
6
+ * Admit exchange options against the Session auth they extend. Every Domain credential must still
7
+ * cover the Session delegation, so a request that could never cover it is rejected.
8
+ */
9
+ export function admitExchangeOptions(input, auth) {
10
+ if (input === undefined)
11
+ return undefined;
12
+ if (input === null || typeof input !== 'object' || Array.isArray(input)) {
13
+ throw new TypeError('Session exchange options are invalid.');
14
+ }
15
+ if (Reflect.ownKeys(input).some((key) => key !== 'ttlSeconds')) {
16
+ throw new TypeError('Session exchange options contain unexpected fields.');
17
+ }
18
+ if (auth === undefined)
19
+ throw new TypeError('Session exchange requires Session auth.');
20
+ const ttlSeconds = admitTtlSeconds(input.ttlSeconds);
21
+ if (ttlSeconds * 1_000 <= delegationCoverageMs(auth.ttlSeconds)) {
22
+ throw new TypeError('Session exchange ttlSeconds must exceed the Session auth ttlSeconds.');
23
+ }
24
+ return Object.freeze({ ttlSeconds });
25
+ }
26
+ /** Admit an explicit exchange: the canonical absolute issuer URL of the named Domain and its lifetime. */
27
+ export function admitExchangeRequest(domain, input) {
28
+ if (input !== undefined &&
29
+ (input === null || typeof input !== 'object' || Array.isArray(input))) {
30
+ throw new TypeError('Session exchange request is invalid.');
31
+ }
32
+ const ttlSeconds = admitTtlSeconds(input?.ttlSeconds);
33
+ const control = admitControlOptions(input === undefined
34
+ ? undefined
35
+ : {
36
+ ...(input.signal === undefined ? {} : { signal: input.signal }),
37
+ ...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
38
+ });
39
+ return Object.freeze({ issuer: admitDomainIssuer(domain), ttlSeconds, control });
40
+ }
41
+ function admitTtlSeconds(input) {
42
+ const ttlSeconds = input ?? DEFAULT_EXCHANGE_TTL_SECONDS;
43
+ if (!Number.isSafeInteger(ttlSeconds) || ttlSeconds < 1) {
44
+ throw new TypeError('Session exchange ttlSeconds must be a positive safe integer.');
45
+ }
46
+ return ttlSeconds;
47
+ }
48
+ function admitDomainIssuer(input) {
49
+ try {
50
+ const issuer = acceptIssuer(input);
51
+ void new URL(issuer);
52
+ return issuer;
53
+ }
54
+ catch (cause) {
55
+ throw new TypeError('Domain issuer is invalid.', { cause });
56
+ }
57
+ }
@@ -0,0 +1,18 @@
1
+ import type { AuthExchange, SessionAuth } from '../routing/index.js';
2
+ import type { ExchangeDependencies } from './exchange.js';
3
+ import type { SessionExchangeOptions } from './options.js';
4
+ /** The per-Call exchange a Session applies after resolving its source authority. */
5
+ export interface SessionExchange extends AuthExchange {
6
+ clear(): void;
7
+ }
8
+ /**
9
+ * Present each Call whose callable a remote installed Domain declares with the credential that
10
+ * Domain exchanged for the Call's source caller.
11
+ *
12
+ * Kernel callables, locally executed Domains, targets that name no Domain, and anonymous Calls keep
13
+ * the source authority unchanged. Domain credentials are held per source credential and replaced at
14
+ * the Session delegation threshold.
15
+ */
16
+ export declare function createSessionExchange(dependencies: ExchangeDependencies & {
17
+ readonly auth: SessionAuth;
18
+ }, options: Readonly<Required<SessionExchangeOptions>>): SessionExchange;
@@ -0,0 +1,73 @@
1
+ import { ClientError } from '../../errors/index.js';
2
+ import { runSessionOperation } from '../context/index.js';
3
+ import { createSessionCredentialProvider, delegationCoverageMs } from '../credential/index.js';
4
+ import { createInstallations, declaringOrigin, isKernelOrigin } from './domain.js';
5
+ import { exchangeDomainCredential, SELF_ATTENUATION } from './exchange.js';
6
+ import { MAXIMUM_EXCHANGE_SOURCES } from './limits.js';
7
+ import { isAuthority, renewing } from './source.js';
8
+ /**
9
+ * Present each Call whose callable a remote installed Domain declares with the credential that
10
+ * Domain exchanged for the Call's source caller.
11
+ *
12
+ * Kernel callables, locally executed Domains, targets that name no Domain, and anonymous Calls keep
13
+ * the source authority unchanged. Domain credentials are held per source credential and replaced at
14
+ * the Session delegation threshold.
15
+ */
16
+ export function createSessionExchange(dependencies, options) {
17
+ const { auth } = dependencies;
18
+ const coverageMs = delegationCoverageMs(auth.ttlSeconds);
19
+ const installations = createInstallations(dependencies);
20
+ const sources = new Map();
21
+ return Object.freeze({ resolve, clear });
22
+ async function resolve(call, effective, operation) {
23
+ if (!isAuthority(effective))
24
+ return effective;
25
+ const origin = declaringOrigin(call.target);
26
+ if (origin === undefined || isKernelOrigin(origin))
27
+ return effective;
28
+ const domain = await installations.issuerOf(origin, effective, operation);
29
+ if (domain === undefined)
30
+ return effective;
31
+ return renewing(auth, call, effective, operation, async (source) => {
32
+ if (source.delegate.ttlSeconds > auth.ttlSeconds) {
33
+ throw new ClientError('Session delegation outlives the Domain credential it would carry.');
34
+ }
35
+ const provider = providerFor(source, domain);
36
+ const exchanged = await runSessionOperation(operation, (signal) => provider.acquire(signal));
37
+ return Object.freeze({ credential: exchanged.credential, delegate: source.delegate });
38
+ });
39
+ }
40
+ function clear() {
41
+ installations.clear();
42
+ sources.clear();
43
+ }
44
+ function providerFor(source, domain) {
45
+ const held = heldFor(source.credential);
46
+ const known = held.get(domain);
47
+ if (known !== undefined)
48
+ return known;
49
+ const provider = createSessionCredentialProvider({
50
+ ttlSeconds: auth.ttlSeconds,
51
+ mint: (signal) => exchangeDomainCredential(dependencies, source, {
52
+ issuer: domain,
53
+ ttlSeconds: options.ttlSeconds,
54
+ attenuation: SELF_ATTENUATION,
55
+ coverageMs,
56
+ }, dependencies.operation(signal)),
57
+ });
58
+ held.set(domain, provider);
59
+ return provider;
60
+ }
61
+ /** Domain credentials never cross source credentials; the oldest source is forgotten first. */
62
+ function heldFor(credential) {
63
+ const known = sources.get(credential);
64
+ if (known !== undefined)
65
+ return known;
66
+ const held = new Map();
67
+ sources.set(credential, held);
68
+ if (sources.size > MAXIMUM_EXCHANGE_SOURCES) {
69
+ sources.delete(sources.keys().next().value);
70
+ }
71
+ return held;
72
+ }
73
+ }
@@ -0,0 +1,32 @@
1
+ import type { invocation } from '@astrale-os/kernel-protocol';
2
+ import type { AuthCall } from '../../auth/auth.js';
3
+ import type { Call, Result } from '../../client/index.js';
4
+ import type { SessionOperation } from '../context/index.js';
5
+ import type { EffectiveAuth, SessionAuth } from '../routing/index.js';
6
+ import type { ExchangeDependencies } from './exchange.js';
7
+ import { ExchangeError } from '../../errors/index.js';
8
+ /** A resolved source that carries both a credential and its delegation. */
9
+ export type SourceAuthority = Required<EffectiveAuth>;
10
+ /** Source Kernel syscalls issued as exactly one admitted source caller within one operation. */
11
+ export interface SourceCaller {
12
+ dispatch(call: Call): Promise<Result>;
13
+ readonly call: AuthCall;
14
+ }
15
+ /** The source credential can no longer grant a delegation that covers what its exchange carries. */
16
+ export declare function sourceExhausted(): ExchangeError;
17
+ export declare function isAuthority(auth: EffectiveAuth): auth is SourceAuthority;
18
+ /** The source Kernel conversation of one exchange, acting as exactly the admitted source caller. */
19
+ export declare function sourceCaller(dependencies: Pick<ExchangeDependencies, 'source'>, auth: EffectiveAuth, operation: SessionOperation): SourceCaller;
20
+ /**
21
+ * Bound a requested delegation by the source credential's expiry less the issuance margin: the
22
+ * Kernel rejects a delegation that outlives its source, judged by its own clock. An opaque or
23
+ * transport-held source leaves the bound to the Kernel. A source that cannot grant one second, or
24
+ * bounds the delegation within `coverageMs`, is exhausted.
25
+ */
26
+ export declare function delegationTtl(credential: string | undefined, ttlSeconds: number, coverageMs?: number): number;
27
+ /**
28
+ * Run `attempt` with the resolved source, and once more with a renewed source if that one proved
29
+ * exhausted. The Session auth is refreshed only while it still resolves the exhausted credential, so
30
+ * concurrent Calls share one renewal; an auth that cannot refresh keeps the failure.
31
+ */
32
+ export declare function renewing<T>(auth: SessionAuth, call: invocation.Call, source: SourceAuthority, operation: SessionOperation, attempt: (source: SourceAuthority) => Promise<T>): Promise<T>;
@@ -0,0 +1,78 @@
1
+ import { inspect } from '@astrale-os/kernel-core/auth/credential';
2
+ import { ExchangeError } from '../../errors/index.js';
3
+ import { runSessionOperation, sessionTransportOptions } from '../context/index.js';
4
+ import { requireResultKind, resolveAuth } from '../routing/index.js';
5
+ import { ISSUANCE_MARGIN_SECONDS } from './limits.js';
6
+ /** The source credential can no longer grant a delegation that covers what its exchange carries. */
7
+ export function sourceExhausted() {
8
+ return new ExchangeError('The source credential expires too soon for a Domain token exchange.', {
9
+ failure: 'source-exhausted',
10
+ });
11
+ }
12
+ export function isAuthority(auth) {
13
+ return auth.credential !== undefined && auth.delegate !== undefined;
14
+ }
15
+ /** The source Kernel conversation of one exchange, acting as exactly the admitted source caller. */
16
+ export function sourceCaller(dependencies, auth, operation) {
17
+ const client = dependencies.source();
18
+ const caller = auth.credential === undefined ? client : client.as(auth.credential);
19
+ const dispatch = (input) => runSessionOperation(operation, () => caller.dispatch(input, {
20
+ ...sessionTransportOptions(operation),
21
+ ...(auth.delegate === undefined ? {} : { delegate: auth.delegate }),
22
+ }));
23
+ const call = async (target, input) => requireResultKind('value', await dispatch({ target, input })).value;
24
+ return Object.freeze({ dispatch, call });
25
+ }
26
+ /**
27
+ * Bound a requested delegation by the source credential's expiry less the issuance margin: the
28
+ * Kernel rejects a delegation that outlives its source, judged by its own clock. An opaque or
29
+ * transport-held source leaves the bound to the Kernel. A source that cannot grant one second, or
30
+ * bounds the delegation within `coverageMs`, is exhausted.
31
+ */
32
+ export function delegationTtl(credential, ttlSeconds, coverageMs = 0) {
33
+ const remaining = remainingSeconds(credential);
34
+ if (remaining === undefined || remaining >= ttlSeconds)
35
+ return ttlSeconds;
36
+ if (remaining < 1 || remaining * 1_000 <= coverageMs)
37
+ throw sourceExhausted();
38
+ return remaining;
39
+ }
40
+ /**
41
+ * Run `attempt` with the resolved source, and once more with a renewed source if that one proved
42
+ * exhausted. The Session auth is refreshed only while it still resolves the exhausted credential, so
43
+ * concurrent Calls share one renewal; an auth that cannot refresh keeps the failure.
44
+ */
45
+ export async function renewing(auth, call, source, operation, attempt) {
46
+ try {
47
+ return await attempt(source);
48
+ }
49
+ catch (cause) {
50
+ if (!(cause instanceof ExchangeError) || cause.failure !== 'source-exhausted')
51
+ throw cause;
52
+ let renewed = await resolveAuth(auth, call, operation);
53
+ if (renewed.credential === source.credential && auth.refresh !== undefined) {
54
+ const refresh = auth.refresh;
55
+ await runSessionOperation(operation, async (signal) => {
56
+ await refresh(signal);
57
+ });
58
+ renewed = await resolveAuth(auth, call, operation);
59
+ }
60
+ if (!isAuthority(renewed) || renewed.credential === source.credential)
61
+ throw cause;
62
+ return attempt(renewed);
63
+ }
64
+ }
65
+ function remainingSeconds(credential) {
66
+ if (credential === undefined)
67
+ return undefined;
68
+ let expiresAt;
69
+ try {
70
+ expiresAt = inspect(credential).claims.exp;
71
+ }
72
+ catch {
73
+ return undefined;
74
+ }
75
+ if (typeof expiresAt !== 'number' || !Number.isSafeInteger(expiresAt))
76
+ return undefined;
77
+ return expiresAt - Math.ceil(Date.now() / 1_000) - ISSUANCE_MARGIN_SECONDS;
78
+ }