@procedures/client 0.0.0-stage → 0.2.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 (777) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE +21 -0
  3. package/README.md +832 -2
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/adapters/http/client/index.d.ts +11 -0
  6. package/dist/adapters/http/client/index.d.ts.map +1 -0
  7. package/dist/adapters/http/client/index.js +18 -0
  8. package/dist/adapters/http/client/index.js.map +1 -0
  9. package/dist/adapters/http/client/transport.d.ts +72 -0
  10. package/dist/adapters/http/client/transport.d.ts.map +1 -0
  11. package/dist/adapters/http/client/transport.js +282 -0
  12. package/dist/adapters/http/client/transport.js.map +1 -0
  13. package/dist/adapters/http/client/types.d.ts +27 -0
  14. package/dist/adapters/http/client/types.d.ts.map +1 -0
  15. package/dist/adapters/http/client/types.js +8 -0
  16. package/dist/adapters/http/client/types.js.map +1 -0
  17. package/dist/adapters/http/index.d.ts +7 -0
  18. package/dist/adapters/http/index.d.ts.map +1 -0
  19. package/dist/adapters/http/index.js +7 -0
  20. package/dist/adapters/http/index.js.map +1 -0
  21. package/dist/adapters/http/server/index.d.ts +9 -0
  22. package/dist/adapters/http/server/index.d.ts.map +1 -0
  23. package/dist/adapters/http/server/index.js +10 -0
  24. package/dist/adapters/http/server/index.js.map +1 -0
  25. package/dist/adapters/http/server/strategies.d.ts +39 -0
  26. package/dist/adapters/http/server/strategies.d.ts.map +1 -0
  27. package/dist/adapters/http/server/strategies.js +90 -0
  28. package/dist/adapters/http/server/strategies.js.map +1 -0
  29. package/dist/adapters/http/server/transport.d.ts +66 -0
  30. package/dist/adapters/http/server/transport.d.ts.map +1 -0
  31. package/dist/adapters/http/server/transport.js +562 -0
  32. package/dist/adapters/http/server/transport.js.map +1 -0
  33. package/dist/adapters/http/server/types.d.ts +71 -0
  34. package/dist/adapters/http/server/types.d.ts.map +1 -0
  35. package/dist/adapters/http/server/types.js +7 -0
  36. package/dist/adapters/http/server/types.js.map +1 -0
  37. package/dist/adapters/http/shared/constants.d.ts +95 -0
  38. package/dist/adapters/http/shared/constants.d.ts.map +1 -0
  39. package/dist/adapters/http/shared/constants.js +102 -0
  40. package/dist/adapters/http/shared/constants.js.map +1 -0
  41. package/dist/adapters/http/shared/errors.d.ts +78 -0
  42. package/dist/adapters/http/shared/errors.d.ts.map +1 -0
  43. package/dist/adapters/http/shared/errors.js +151 -0
  44. package/dist/adapters/http/shared/errors.js.map +1 -0
  45. package/dist/adapters/http/shared/headers.d.ts +122 -0
  46. package/dist/adapters/http/shared/headers.d.ts.map +1 -0
  47. package/dist/adapters/http/shared/headers.js +216 -0
  48. package/dist/adapters/http/shared/headers.js.map +1 -0
  49. package/dist/adapters/http/shared/index.d.ts +12 -0
  50. package/dist/adapters/http/shared/index.d.ts.map +1 -0
  51. package/dist/adapters/http/shared/index.js +17 -0
  52. package/dist/adapters/http/shared/index.js.map +1 -0
  53. package/dist/adapters/http/shared/status-codes.d.ts +92 -0
  54. package/dist/adapters/http/shared/status-codes.d.ts.map +1 -0
  55. package/dist/adapters/http/shared/status-codes.js +189 -0
  56. package/dist/adapters/http/shared/status-codes.js.map +1 -0
  57. package/dist/adapters/http/shared/strategies.d.ts +90 -0
  58. package/dist/adapters/http/shared/strategies.d.ts.map +1 -0
  59. package/dist/adapters/http/shared/strategies.js +180 -0
  60. package/dist/adapters/http/shared/strategies.js.map +1 -0
  61. package/dist/adapters/local/client/index.d.ts +8 -0
  62. package/dist/adapters/local/client/index.d.ts.map +1 -0
  63. package/dist/adapters/local/client/index.js +8 -0
  64. package/dist/adapters/local/client/index.js.map +1 -0
  65. package/dist/adapters/local/client/transport.d.ts +81 -0
  66. package/dist/adapters/local/client/transport.d.ts.map +1 -0
  67. package/dist/adapters/local/client/transport.js +172 -0
  68. package/dist/adapters/local/client/transport.js.map +1 -0
  69. package/dist/adapters/local/client/types.d.ts +39 -0
  70. package/dist/adapters/local/client/types.d.ts.map +1 -0
  71. package/dist/adapters/local/client/types.js +13 -0
  72. package/dist/adapters/local/client/types.js.map +1 -0
  73. package/dist/adapters/metadata.d.ts +10 -0
  74. package/dist/adapters/metadata.d.ts.map +1 -0
  75. package/dist/adapters/metadata.js +19 -0
  76. package/dist/adapters/metadata.js.map +1 -0
  77. package/dist/adapters/mock/client/builder.d.ts +35 -0
  78. package/dist/adapters/mock/client/builder.d.ts.map +1 -0
  79. package/dist/adapters/mock/client/builder.js +58 -0
  80. package/dist/adapters/mock/client/builder.js.map +1 -0
  81. package/dist/adapters/mock/client/index.d.ts +9 -0
  82. package/dist/adapters/mock/client/index.d.ts.map +1 -0
  83. package/dist/adapters/mock/client/index.js +10 -0
  84. package/dist/adapters/mock/client/index.js.map +1 -0
  85. package/dist/adapters/mock/client/transport.d.ts +149 -0
  86. package/dist/adapters/mock/client/transport.d.ts.map +1 -0
  87. package/dist/adapters/mock/client/transport.js +289 -0
  88. package/dist/adapters/mock/client/transport.js.map +1 -0
  89. package/dist/adapters/mock/client/types.d.ts +86 -0
  90. package/dist/adapters/mock/client/types.d.ts.map +1 -0
  91. package/dist/adapters/mock/client/types.js +7 -0
  92. package/dist/adapters/mock/client/types.js.map +1 -0
  93. package/dist/adapters/websocket/client/index.d.ts +9 -0
  94. package/dist/adapters/websocket/client/index.d.ts.map +1 -0
  95. package/dist/adapters/websocket/client/index.js +9 -0
  96. package/dist/adapters/websocket/client/index.js.map +1 -0
  97. package/dist/adapters/websocket/client/transport.d.ts +106 -0
  98. package/dist/adapters/websocket/client/transport.d.ts.map +1 -0
  99. package/dist/adapters/websocket/client/transport.js +647 -0
  100. package/dist/adapters/websocket/client/transport.js.map +1 -0
  101. package/dist/adapters/websocket/client/types.d.ts +192 -0
  102. package/dist/adapters/websocket/client/types.d.ts.map +1 -0
  103. package/dist/adapters/websocket/client/types.js +17 -0
  104. package/dist/adapters/websocket/client/types.js.map +1 -0
  105. package/dist/adapters/websocket/index.d.ts +8 -0
  106. package/dist/adapters/websocket/index.d.ts.map +1 -0
  107. package/dist/adapters/websocket/index.js +8 -0
  108. package/dist/adapters/websocket/index.js.map +1 -0
  109. package/dist/adapters/websocket/server/index.d.ts +8 -0
  110. package/dist/adapters/websocket/server/index.d.ts.map +1 -0
  111. package/dist/adapters/websocket/server/index.js +8 -0
  112. package/dist/adapters/websocket/server/index.js.map +1 -0
  113. package/dist/adapters/websocket/server/transport.d.ts +112 -0
  114. package/dist/adapters/websocket/server/transport.d.ts.map +1 -0
  115. package/dist/adapters/websocket/server/transport.js +619 -0
  116. package/dist/adapters/websocket/server/transport.js.map +1 -0
  117. package/dist/adapters/websocket/server/types.d.ts +140 -0
  118. package/dist/adapters/websocket/server/types.d.ts.map +1 -0
  119. package/dist/adapters/websocket/server/types.js +7 -0
  120. package/dist/adapters/websocket/server/types.js.map +1 -0
  121. package/dist/browser.d.ts +51 -0
  122. package/dist/browser.d.ts.map +1 -0
  123. package/dist/browser.js +89 -0
  124. package/dist/browser.js.map +1 -0
  125. package/dist/client/batch-executor.d.ts +160 -0
  126. package/dist/client/batch-executor.d.ts.map +1 -0
  127. package/dist/client/batch-executor.js +397 -0
  128. package/dist/client/batch-executor.js.map +1 -0
  129. package/dist/client/call-types.d.ts +271 -0
  130. package/dist/client/call-types.d.ts.map +1 -0
  131. package/dist/client/call-types.js +208 -0
  132. package/dist/client/call-types.js.map +1 -0
  133. package/dist/client/client.d.ts +525 -0
  134. package/dist/client/client.d.ts.map +1 -0
  135. package/dist/client/client.js +1011 -0
  136. package/dist/client/client.js.map +1 -0
  137. package/dist/client/consumption.d.ts +191 -0
  138. package/dist/client/consumption.d.ts.map +1 -0
  139. package/dist/client/consumption.js +98 -0
  140. package/dist/client/consumption.js.map +1 -0
  141. package/dist/client/context.d.ts +116 -0
  142. package/dist/client/context.d.ts.map +1 -0
  143. package/dist/client/context.js +111 -0
  144. package/dist/client/context.js.map +1 -0
  145. package/dist/client/errors/codes.d.ts +71 -0
  146. package/dist/client/errors/codes.d.ts.map +1 -0
  147. package/dist/client/errors/codes.js +81 -0
  148. package/dist/client/errors/codes.js.map +1 -0
  149. package/dist/client/errors/factory.d.ts +102 -0
  150. package/dist/client/errors/factory.d.ts.map +1 -0
  151. package/dist/client/errors/factory.js +210 -0
  152. package/dist/client/errors/factory.js.map +1 -0
  153. package/dist/client/errors/http-errors.d.ts +47 -0
  154. package/dist/client/errors/http-errors.d.ts.map +1 -0
  155. package/dist/client/errors/http-errors.js +548 -0
  156. package/dist/client/errors/http-errors.js.map +1 -0
  157. package/dist/client/errors/http-status.d.ts +73 -0
  158. package/dist/client/errors/http-status.d.ts.map +1 -0
  159. package/dist/client/errors/http-status.js +79 -0
  160. package/dist/client/errors/http-status.js.map +1 -0
  161. package/dist/client/errors/index.d.ts +36 -0
  162. package/dist/client/errors/index.d.ts.map +1 -0
  163. package/dist/client/errors/index.js +40 -0
  164. package/dist/client/errors/index.js.map +1 -0
  165. package/dist/client/errors/registry.d.ts +38 -0
  166. package/dist/client/errors/registry.d.ts.map +1 -0
  167. package/dist/client/errors/registry.js +535 -0
  168. package/dist/client/errors/registry.js.map +1 -0
  169. package/dist/client/errors/types.d.ts +112 -0
  170. package/dist/client/errors/types.d.ts.map +1 -0
  171. package/dist/client/errors/types.js +45 -0
  172. package/dist/client/errors/types.js.map +1 -0
  173. package/dist/client/index.d.ts +44 -0
  174. package/dist/client/index.d.ts.map +1 -0
  175. package/dist/client/index.js +36 -0
  176. package/dist/client/index.js.map +1 -0
  177. package/dist/client/middleware/auth.d.ts +90 -0
  178. package/dist/client/middleware/auth.d.ts.map +1 -0
  179. package/dist/client/middleware/auth.js +98 -0
  180. package/dist/client/middleware/auth.js.map +1 -0
  181. package/dist/client/middleware/batching.d.ts +102 -0
  182. package/dist/client/middleware/batching.d.ts.map +1 -0
  183. package/dist/client/middleware/batching.js +245 -0
  184. package/dist/client/middleware/batching.js.map +1 -0
  185. package/dist/client/middleware/cache.d.ts +124 -0
  186. package/dist/client/middleware/cache.d.ts.map +1 -0
  187. package/dist/client/middleware/cache.js +208 -0
  188. package/dist/client/middleware/cache.js.map +1 -0
  189. package/dist/client/middleware/circuit-breaker.d.ts +113 -0
  190. package/dist/client/middleware/circuit-breaker.d.ts.map +1 -0
  191. package/dist/client/middleware/circuit-breaker.js +236 -0
  192. package/dist/client/middleware/circuit-breaker.js.map +1 -0
  193. package/dist/client/middleware/contexts.d.ts +199 -0
  194. package/dist/client/middleware/contexts.d.ts.map +1 -0
  195. package/dist/client/middleware/contexts.js +74 -0
  196. package/dist/client/middleware/contexts.js.map +1 -0
  197. package/dist/client/middleware/items.d.ts +37 -0
  198. package/dist/client/middleware/items.d.ts.map +1 -0
  199. package/dist/client/middleware/items.js +100 -0
  200. package/dist/client/middleware/items.js.map +1 -0
  201. package/dist/client/middleware/lru.d.ts +32 -0
  202. package/dist/client/middleware/lru.d.ts.map +1 -0
  203. package/dist/client/middleware/lru.js +62 -0
  204. package/dist/client/middleware/lru.js.map +1 -0
  205. package/dist/client/middleware/pagination.d.ts +114 -0
  206. package/dist/client/middleware/pagination.d.ts.map +1 -0
  207. package/dist/client/middleware/pagination.js +148 -0
  208. package/dist/client/middleware/pagination.js.map +1 -0
  209. package/dist/client/middleware/rate-limit.d.ts +105 -0
  210. package/dist/client/middleware/rate-limit.d.ts.map +1 -0
  211. package/dist/client/middleware/rate-limit.js +222 -0
  212. package/dist/client/middleware/rate-limit.js.map +1 -0
  213. package/dist/client/middleware/retry.d.ts +100 -0
  214. package/dist/client/middleware/retry.d.ts.map +1 -0
  215. package/dist/client/middleware/retry.js +150 -0
  216. package/dist/client/middleware/retry.js.map +1 -0
  217. package/dist/client/middleware/timeout.d.ts +91 -0
  218. package/dist/client/middleware/timeout.d.ts.map +1 -0
  219. package/dist/client/middleware/timeout.js +253 -0
  220. package/dist/client/middleware/timeout.js.map +1 -0
  221. package/dist/client/middleware/tracing.d.ts +118 -0
  222. package/dist/client/middleware/tracing.d.ts.map +1 -0
  223. package/dist/client/middleware/tracing.js +152 -0
  224. package/dist/client/middleware/tracing.js.map +1 -0
  225. package/dist/client/route-resolver.d.ts +181 -0
  226. package/dist/client/route-resolver.d.ts.map +1 -0
  227. package/dist/client/route-resolver.js +300 -0
  228. package/dist/client/route-resolver.js.map +1 -0
  229. package/dist/client/typed-method.d.ts +29 -0
  230. package/dist/client/typed-method.d.ts.map +1 -0
  231. package/dist/client/typed-method.js +36 -0
  232. package/dist/client/typed-method.js.map +1 -0
  233. package/dist/client/typed.d.ts +102 -0
  234. package/dist/client/typed.d.ts.map +1 -0
  235. package/dist/client/typed.js +52 -0
  236. package/dist/client/typed.js.map +1 -0
  237. package/dist/client/types.d.ts +305 -0
  238. package/dist/client/types.d.ts.map +1 -0
  239. package/dist/client/types.js +26 -0
  240. package/dist/client/types.js.map +1 -0
  241. package/dist/client/validation/index.d.ts +34 -0
  242. package/dist/client/validation/index.d.ts.map +1 -0
  243. package/dist/client/validation/index.js +36 -0
  244. package/dist/client/validation/index.js.map +1 -0
  245. package/dist/client/validation/middleware.d.ts +82 -0
  246. package/dist/client/validation/middleware.d.ts.map +1 -0
  247. package/dist/client/validation/middleware.js +138 -0
  248. package/dist/client/validation/middleware.js.map +1 -0
  249. package/dist/client/validation/types.d.ts +118 -0
  250. package/dist/client/validation/types.d.ts.map +1 -0
  251. package/dist/client/validation/types.js +59 -0
  252. package/dist/client/validation/types.js.map +1 -0
  253. package/dist/collections/async/async-queue.d.ts +144 -0
  254. package/dist/collections/async/async-queue.d.ts.map +1 -0
  255. package/dist/collections/async/async-queue.js +347 -0
  256. package/dist/collections/async/async-queue.js.map +1 -0
  257. package/dist/collections/async/channels.d.ts +188 -0
  258. package/dist/collections/async/channels.d.ts.map +1 -0
  259. package/dist/collections/async/channels.js +312 -0
  260. package/dist/collections/async/channels.js.map +1 -0
  261. package/dist/collections/behaviors/bounded.d.ts +79 -0
  262. package/dist/collections/behaviors/bounded.d.ts.map +1 -0
  263. package/dist/collections/behaviors/bounded.js +384 -0
  264. package/dist/collections/behaviors/bounded.js.map +1 -0
  265. package/dist/collections/behaviors/evented.d.ts +154 -0
  266. package/dist/collections/behaviors/evented.d.ts.map +1 -0
  267. package/dist/collections/behaviors/evented.js +299 -0
  268. package/dist/collections/behaviors/evented.js.map +1 -0
  269. package/dist/collections/behaviors/lru.d.ts +84 -0
  270. package/dist/collections/behaviors/lru.d.ts.map +1 -0
  271. package/dist/collections/behaviors/lru.js +330 -0
  272. package/dist/collections/behaviors/lru.js.map +1 -0
  273. package/dist/collections/behaviors/readonly.d.ts +73 -0
  274. package/dist/collections/behaviors/readonly.d.ts.map +1 -0
  275. package/dist/collections/behaviors/readonly.js +158 -0
  276. package/dist/collections/behaviors/readonly.js.map +1 -0
  277. package/dist/collections/behaviors/safe.d.ts +163 -0
  278. package/dist/collections/behaviors/safe.d.ts.map +1 -0
  279. package/dist/collections/behaviors/safe.js +172 -0
  280. package/dist/collections/behaviors/safe.js.map +1 -0
  281. package/dist/collections/behaviors/synchronized.d.ts +88 -0
  282. package/dist/collections/behaviors/synchronized.d.ts.map +1 -0
  283. package/dist/collections/behaviors/synchronized.js +294 -0
  284. package/dist/collections/behaviors/synchronized.js.map +1 -0
  285. package/dist/collections/behaviors/ttl.d.ts +118 -0
  286. package/dist/collections/behaviors/ttl.d.ts.map +1 -0
  287. package/dist/collections/behaviors/ttl.js +338 -0
  288. package/dist/collections/behaviors/ttl.js.map +1 -0
  289. package/dist/collections/core/effects.d.ts +176 -0
  290. package/dist/collections/core/effects.d.ts.map +1 -0
  291. package/dist/collections/core/effects.js +180 -0
  292. package/dist/collections/core/effects.js.map +1 -0
  293. package/dist/collections/core/events.d.ts +192 -0
  294. package/dist/collections/core/events.d.ts.map +1 -0
  295. package/dist/collections/core/events.js +291 -0
  296. package/dist/collections/core/events.js.map +1 -0
  297. package/dist/collections/core/middleware.d.ts +231 -0
  298. package/dist/collections/core/middleware.d.ts.map +1 -0
  299. package/dist/collections/core/middleware.js +161 -0
  300. package/dist/collections/core/middleware.js.map +1 -0
  301. package/dist/collections/core/policies.d.ts +220 -0
  302. package/dist/collections/core/policies.d.ts.map +1 -0
  303. package/dist/collections/core/policies.js +48 -0
  304. package/dist/collections/core/policies.js.map +1 -0
  305. package/dist/collections/core/traits.d.ts +142 -0
  306. package/dist/collections/core/traits.d.ts.map +1 -0
  307. package/dist/collections/core/traits.js +8 -0
  308. package/dist/collections/core/traits.js.map +1 -0
  309. package/dist/collections/examples.d.ts +13 -0
  310. package/dist/collections/examples.d.ts.map +1 -0
  311. package/dist/collections/examples.js +302 -0
  312. package/dist/collections/examples.js.map +1 -0
  313. package/dist/collections/fx/collectors.d.ts +190 -0
  314. package/dist/collections/fx/collectors.d.ts.map +1 -0
  315. package/dist/collections/fx/collectors.js +369 -0
  316. package/dist/collections/fx/collectors.js.map +1 -0
  317. package/dist/collections/fx/iter.d.ts +166 -0
  318. package/dist/collections/fx/iter.d.ts.map +1 -0
  319. package/dist/collections/fx/iter.js +421 -0
  320. package/dist/collections/fx/iter.js.map +1 -0
  321. package/dist/collections/impl/array-deque.d.ts +107 -0
  322. package/dist/collections/impl/array-deque.d.ts.map +1 -0
  323. package/dist/collections/impl/array-deque.js +381 -0
  324. package/dist/collections/impl/array-deque.js.map +1 -0
  325. package/dist/collections/impl/array-list.d.ts +101 -0
  326. package/dist/collections/impl/array-list.d.ts.map +1 -0
  327. package/dist/collections/impl/array-list.js +387 -0
  328. package/dist/collections/impl/array-list.js.map +1 -0
  329. package/dist/collections/impl/hash-map.d.ts +141 -0
  330. package/dist/collections/impl/hash-map.d.ts.map +1 -0
  331. package/dist/collections/impl/hash-map.js +450 -0
  332. package/dist/collections/impl/hash-map.js.map +1 -0
  333. package/dist/collections/impl/hash-set.d.ts +125 -0
  334. package/dist/collections/impl/hash-set.d.ts.map +1 -0
  335. package/dist/collections/impl/hash-set.js +264 -0
  336. package/dist/collections/impl/hash-set.js.map +1 -0
  337. package/dist/collections/impl/linked-hash-map.d.ts +141 -0
  338. package/dist/collections/impl/linked-hash-map.d.ts.map +1 -0
  339. package/dist/collections/impl/linked-hash-map.js +472 -0
  340. package/dist/collections/impl/linked-hash-map.js.map +1 -0
  341. package/dist/collections/impl/linked-list.d.ts +109 -0
  342. package/dist/collections/impl/linked-list.d.ts.map +1 -0
  343. package/dist/collections/impl/linked-list.js +491 -0
  344. package/dist/collections/impl/linked-list.js.map +1 -0
  345. package/dist/collections/impl/priority-queue.d.ts +134 -0
  346. package/dist/collections/impl/priority-queue.d.ts.map +1 -0
  347. package/dist/collections/impl/priority-queue.js +336 -0
  348. package/dist/collections/impl/priority-queue.js.map +1 -0
  349. package/dist/collections/impl/tree-map.d.ts +146 -0
  350. package/dist/collections/impl/tree-map.d.ts.map +1 -0
  351. package/dist/collections/impl/tree-map.js +781 -0
  352. package/dist/collections/impl/tree-map.js.map +1 -0
  353. package/dist/collections/impl/tree-set.d.ts +112 -0
  354. package/dist/collections/impl/tree-set.d.ts.map +1 -0
  355. package/dist/collections/impl/tree-set.js +374 -0
  356. package/dist/collections/impl/tree-set.js.map +1 -0
  357. package/dist/collections/index.d.ts +105 -0
  358. package/dist/collections/index.d.ts.map +1 -0
  359. package/dist/collections/index.js +135 -0
  360. package/dist/collections/index.js.map +1 -0
  361. package/dist/collections/interfaces/collection.d.ts +119 -0
  362. package/dist/collections/interfaces/collection.d.ts.map +1 -0
  363. package/dist/collections/interfaces/collection.js +8 -0
  364. package/dist/collections/interfaces/collection.js.map +1 -0
  365. package/dist/collections/interfaces/list.d.ts +247 -0
  366. package/dist/collections/interfaces/list.d.ts.map +1 -0
  367. package/dist/collections/interfaces/list.js +8 -0
  368. package/dist/collections/interfaces/list.js.map +1 -0
  369. package/dist/collections/interfaces/map.d.ts +344 -0
  370. package/dist/collections/interfaces/map.d.ts.map +1 -0
  371. package/dist/collections/interfaces/map.js +8 -0
  372. package/dist/collections/interfaces/map.js.map +1 -0
  373. package/dist/collections/interfaces/queue.d.ts +304 -0
  374. package/dist/collections/interfaces/queue.d.ts.map +1 -0
  375. package/dist/collections/interfaces/queue.js +8 -0
  376. package/dist/collections/interfaces/queue.js.map +1 -0
  377. package/dist/collections/interfaces/set.d.ts +137 -0
  378. package/dist/collections/interfaces/set.d.ts.map +1 -0
  379. package/dist/collections/interfaces/set.js +8 -0
  380. package/dist/collections/interfaces/set.js.map +1 -0
  381. package/dist/collections/storage/api.d.ts +109 -0
  382. package/dist/collections/storage/api.d.ts.map +1 -0
  383. package/dist/collections/storage/api.js +182 -0
  384. package/dist/collections/storage/api.js.map +1 -0
  385. package/dist/collections/storage/hybrid.d.ts +164 -0
  386. package/dist/collections/storage/hybrid.d.ts.map +1 -0
  387. package/dist/collections/storage/hybrid.js +416 -0
  388. package/dist/collections/storage/hybrid.js.map +1 -0
  389. package/dist/collections/storage/index.d.ts +16 -0
  390. package/dist/collections/storage/index.d.ts.map +1 -0
  391. package/dist/collections/storage/index.js +13 -0
  392. package/dist/collections/storage/index.js.map +1 -0
  393. package/dist/collections/storage/interface.d.ts +141 -0
  394. package/dist/collections/storage/interface.d.ts.map +1 -0
  395. package/dist/collections/storage/interface.js +23 -0
  396. package/dist/collections/storage/interface.js.map +1 -0
  397. package/dist/collections/storage/memory.d.ts +68 -0
  398. package/dist/collections/storage/memory.d.ts.map +1 -0
  399. package/dist/collections/storage/memory.js +154 -0
  400. package/dist/collections/storage/memory.js.map +1 -0
  401. package/dist/collections/utils/defaults.d.ts +135 -0
  402. package/dist/collections/utils/defaults.d.ts.map +1 -0
  403. package/dist/collections/utils/defaults.js +322 -0
  404. package/dist/collections/utils/defaults.js.map +1 -0
  405. package/dist/collections/utils/factories.d.ts +144 -0
  406. package/dist/collections/utils/factories.d.ts.map +1 -0
  407. package/dist/collections/utils/factories.js +293 -0
  408. package/dist/collections/utils/factories.js.map +1 -0
  409. package/dist/collections/utils/helpers.d.ts +137 -0
  410. package/dist/collections/utils/helpers.d.ts.map +1 -0
  411. package/dist/collections/utils/helpers.js +221 -0
  412. package/dist/collections/utils/helpers.js.map +1 -0
  413. package/dist/collections.d.ts +12 -0
  414. package/dist/collections.d.ts.map +1 -0
  415. package/dist/collections.js +10 -0
  416. package/dist/collections.js.map +1 -0
  417. package/dist/components/define.d.ts +134 -0
  418. package/dist/components/define.d.ts.map +1 -0
  419. package/dist/components/define.js +486 -0
  420. package/dist/components/define.js.map +1 -0
  421. package/dist/components/index.d.ts +39 -0
  422. package/dist/components/index.d.ts.map +1 -0
  423. package/dist/components/index.js +38 -0
  424. package/dist/components/index.js.map +1 -0
  425. package/dist/components/types.d.ts +264 -0
  426. package/dist/components/types.d.ts.map +1 -0
  427. package/dist/components/types.js +46 -0
  428. package/dist/components/types.js.map +1 -0
  429. package/dist/events/bus.d.ts +193 -0
  430. package/dist/events/bus.d.ts.map +1 -0
  431. package/dist/events/bus.js +511 -0
  432. package/dist/events/bus.js.map +1 -0
  433. package/dist/events/index.d.ts +34 -0
  434. package/dist/events/index.d.ts.map +1 -0
  435. package/dist/events/index.js +36 -0
  436. package/dist/events/index.js.map +1 -0
  437. package/dist/events/types.d.ts +242 -0
  438. package/dist/events/types.d.ts.map +1 -0
  439. package/dist/events/types.js +8 -0
  440. package/dist/events/types.js.map +1 -0
  441. package/dist/index.d.ts +17 -0
  442. package/dist/index.d.ts.map +1 -0
  443. package/dist/index.js +17 -0
  444. package/dist/index.js.map +1 -0
  445. package/dist/middleware/compose.d.ts +88 -0
  446. package/dist/middleware/compose.d.ts.map +1 -0
  447. package/dist/middleware/compose.js +108 -0
  448. package/dist/middleware/compose.js.map +1 -0
  449. package/dist/middleware/index.d.ts +12 -0
  450. package/dist/middleware/index.d.ts.map +1 -0
  451. package/dist/middleware/index.js +11 -0
  452. package/dist/middleware/index.js.map +1 -0
  453. package/dist/middleware/types.d.ts +112 -0
  454. package/dist/middleware/types.d.ts.map +1 -0
  455. package/dist/middleware/types.js +14 -0
  456. package/dist/middleware/types.js.map +1 -0
  457. package/dist/procedures/capability.d.ts +111 -0
  458. package/dist/procedures/capability.d.ts.map +1 -0
  459. package/dist/procedures/capability.js +269 -0
  460. package/dist/procedures/capability.js.map +1 -0
  461. package/dist/procedures/cli/announce.d.ts +67 -0
  462. package/dist/procedures/cli/announce.d.ts.map +1 -0
  463. package/dist/procedures/cli/announce.js +392 -0
  464. package/dist/procedures/cli/announce.js.map +1 -0
  465. package/dist/procedures/cli/discover.d.ts +66 -0
  466. package/dist/procedures/cli/discover.d.ts.map +1 -0
  467. package/dist/procedures/cli/discover.js +310 -0
  468. package/dist/procedures/cli/discover.js.map +1 -0
  469. package/dist/procedures/cli/index.d.ts +13 -0
  470. package/dist/procedures/cli/index.d.ts.map +1 -0
  471. package/dist/procedures/cli/index.js +203 -0
  472. package/dist/procedures/cli/index.js.map +1 -0
  473. package/dist/procedures/cli/init.d.ts +17 -0
  474. package/dist/procedures/cli/init.d.ts.map +1 -0
  475. package/dist/procedures/cli/init.js +336 -0
  476. package/dist/procedures/cli/init.js.map +1 -0
  477. package/dist/procedures/collection/index.d.ts +10 -0
  478. package/dist/procedures/collection/index.d.ts.map +1 -0
  479. package/dist/procedures/collection/index.js +10 -0
  480. package/dist/procedures/collection/index.js.map +1 -0
  481. package/dist/procedures/collection/procedures.d.ts +21 -0
  482. package/dist/procedures/collection/procedures.d.ts.map +1 -0
  483. package/dist/procedures/collection/procedures.js +210 -0
  484. package/dist/procedures/collection/procedures.js.map +1 -0
  485. package/dist/procedures/collection/schemas.d.ts +131 -0
  486. package/dist/procedures/collection/schemas.d.ts.map +1 -0
  487. package/dist/procedures/collection/schemas.js +422 -0
  488. package/dist/procedures/collection/schemas.js.map +1 -0
  489. package/dist/procedures/collection/storage.d.ts +53 -0
  490. package/dist/procedures/collection/storage.d.ts.map +1 -0
  491. package/dist/procedures/collection/storage.js +2 -0
  492. package/dist/procedures/collection/storage.js.map +1 -0
  493. package/dist/procedures/core/array.d.ts +276 -0
  494. package/dist/procedures/core/array.d.ts.map +1 -0
  495. package/dist/procedures/core/array.js +639 -0
  496. package/dist/procedures/core/array.js.map +1 -0
  497. package/dist/procedures/core/comparison.d.ts +85 -0
  498. package/dist/procedures/core/comparison.d.ts.map +1 -0
  499. package/dist/procedures/core/comparison.js +158 -0
  500. package/dist/procedures/core/comparison.js.map +1 -0
  501. package/dist/procedures/core/index.d.ts +261 -0
  502. package/dist/procedures/core/index.d.ts.map +1 -0
  503. package/dist/procedures/core/index.js +588 -0
  504. package/dist/procedures/core/index.js.map +1 -0
  505. package/dist/procedures/core/logic.d.ts +144 -0
  506. package/dist/procedures/core/logic.d.ts.map +1 -0
  507. package/dist/procedures/core/logic.js +169 -0
  508. package/dist/procedures/core/logic.js.map +1 -0
  509. package/dist/procedures/core/math.d.ts +139 -0
  510. package/dist/procedures/core/math.d.ts.map +1 -0
  511. package/dist/procedures/core/math.js +275 -0
  512. package/dist/procedures/core/math.js.map +1 -0
  513. package/dist/procedures/core/meta.d.ts +111 -0
  514. package/dist/procedures/core/meta.d.ts.map +1 -0
  515. package/dist/procedures/core/meta.js +244 -0
  516. package/dist/procedures/core/meta.js.map +1 -0
  517. package/dist/procedures/core/object.d.ts +109 -0
  518. package/dist/procedures/core/object.d.ts.map +1 -0
  519. package/dist/procedures/core/object.js +272 -0
  520. package/dist/procedures/core/object.js.map +1 -0
  521. package/dist/procedures/core/operands.d.ts +51 -0
  522. package/dist/procedures/core/operands.d.ts.map +1 -0
  523. package/dist/procedures/core/operands.js +90 -0
  524. package/dist/procedures/core/operands.js.map +1 -0
  525. package/dist/procedures/core/outputs.d.ts +28 -0
  526. package/dist/procedures/core/outputs.d.ts.map +1 -0
  527. package/dist/procedures/core/outputs.js +42 -0
  528. package/dist/procedures/core/outputs.js.map +1 -0
  529. package/dist/procedures/core/results.d.ts +202 -0
  530. package/dist/procedures/core/results.d.ts.map +1 -0
  531. package/dist/procedures/core/results.js +106 -0
  532. package/dist/procedures/core/results.js.map +1 -0
  533. package/dist/procedures/core/schemas.d.ts +48 -0
  534. package/dist/procedures/core/schemas.d.ts.map +1 -0
  535. package/dist/procedures/core/schemas.js +102 -0
  536. package/dist/procedures/core/schemas.js.map +1 -0
  537. package/dist/procedures/core/string.d.ts +138 -0
  538. package/dist/procedures/core/string.d.ts.map +1 -0
  539. package/dist/procedures/core/string.js +270 -0
  540. package/dist/procedures/core/string.js.map +1 -0
  541. package/dist/procedures/core/type.d.ts +101 -0
  542. package/dist/procedures/core/type.d.ts.map +1 -0
  543. package/dist/procedures/core/type.js +210 -0
  544. package/dist/procedures/core/type.js.map +1 -0
  545. package/dist/procedures/define-procedure.d.ts +187 -0
  546. package/dist/procedures/define-procedure.d.ts.map +1 -0
  547. package/dist/procedures/define-procedure.js +357 -0
  548. package/dist/procedures/define-procedure.js.map +1 -0
  549. package/dist/procedures/define.d.ts +228 -0
  550. package/dist/procedures/define.d.ts.map +1 -0
  551. package/dist/procedures/define.js +300 -0
  552. package/dist/procedures/define.js.map +1 -0
  553. package/dist/procedures/discovery.d.ts +57 -0
  554. package/dist/procedures/discovery.d.ts.map +1 -0
  555. package/dist/procedures/discovery.js +68 -0
  556. package/dist/procedures/discovery.js.map +1 -0
  557. package/dist/procedures/effects.d.ts +15 -0
  558. package/dist/procedures/effects.d.ts.map +1 -0
  559. package/dist/procedures/effects.js +18 -0
  560. package/dist/procedures/effects.js.map +1 -0
  561. package/dist/procedures/index.d.ts +27 -0
  562. package/dist/procedures/index.d.ts.map +1 -0
  563. package/dist/procedures/index.js +54 -0
  564. package/dist/procedures/index.js.map +1 -0
  565. package/dist/procedures/interceptors.d.ts +82 -0
  566. package/dist/procedures/interceptors.d.ts.map +1 -0
  567. package/dist/procedures/interceptors.js +194 -0
  568. package/dist/procedures/interceptors.js.map +1 -0
  569. package/dist/procedures/invoke.d.ts +155 -0
  570. package/dist/procedures/invoke.d.ts.map +1 -0
  571. package/dist/procedures/invoke.js +343 -0
  572. package/dist/procedures/invoke.js.map +1 -0
  573. package/dist/procedures/module.d.ts +54 -0
  574. package/dist/procedures/module.d.ts.map +1 -0
  575. package/dist/procedures/module.js +103 -0
  576. package/dist/procedures/module.js.map +1 -0
  577. package/dist/procedures/policy.d.ts +70 -0
  578. package/dist/procedures/policy.d.ts.map +1 -0
  579. package/dist/procedures/policy.js +138 -0
  580. package/dist/procedures/policy.js.map +1 -0
  581. package/dist/procedures/ref.d.ts +606 -0
  582. package/dist/procedures/ref.d.ts.map +1 -0
  583. package/dist/procedures/ref.js +895 -0
  584. package/dist/procedures/ref.js.map +1 -0
  585. package/dist/procedures/registry.d.ts +208 -0
  586. package/dist/procedures/registry.d.ts.map +1 -0
  587. package/dist/procedures/registry.js +402 -0
  588. package/dist/procedures/registry.js.map +1 -0
  589. package/dist/procedures/schema.d.ts +126 -0
  590. package/dist/procedures/schema.d.ts.map +1 -0
  591. package/dist/procedures/schema.js +108 -0
  592. package/dist/procedures/schema.js.map +1 -0
  593. package/dist/procedures/storage/adapter.d.ts +148 -0
  594. package/dist/procedures/storage/adapter.d.ts.map +1 -0
  595. package/dist/procedures/storage/adapter.js +214 -0
  596. package/dist/procedures/storage/adapter.js.map +1 -0
  597. package/dist/procedures/storage/api.d.ts +125 -0
  598. package/dist/procedures/storage/api.d.ts.map +1 -0
  599. package/dist/procedures/storage/api.js +220 -0
  600. package/dist/procedures/storage/api.js.map +1 -0
  601. package/dist/procedures/storage/factory.d.ts +134 -0
  602. package/dist/procedures/storage/factory.d.ts.map +1 -0
  603. package/dist/procedures/storage/factory.js +166 -0
  604. package/dist/procedures/storage/factory.js.map +1 -0
  605. package/dist/procedures/storage/hybrid.d.ts +193 -0
  606. package/dist/procedures/storage/hybrid.d.ts.map +1 -0
  607. package/dist/procedures/storage/hybrid.js +519 -0
  608. package/dist/procedures/storage/hybrid.js.map +1 -0
  609. package/dist/procedures/storage/index.d.ts +17 -0
  610. package/dist/procedures/storage/index.d.ts.map +1 -0
  611. package/dist/procedures/storage/index.js +17 -0
  612. package/dist/procedures/storage/index.js.map +1 -0
  613. package/dist/procedures/storage/procedures.d.ts +39 -0
  614. package/dist/procedures/storage/procedures.d.ts.map +1 -0
  615. package/dist/procedures/storage/procedures.js +261 -0
  616. package/dist/procedures/storage/procedures.js.map +1 -0
  617. package/dist/procedures/storage/serialization.d.ts +123 -0
  618. package/dist/procedures/storage/serialization.d.ts.map +1 -0
  619. package/dist/procedures/storage/serialization.js +216 -0
  620. package/dist/procedures/storage/serialization.js.map +1 -0
  621. package/dist/procedures/storage/synced-registry.d.ts +246 -0
  622. package/dist/procedures/storage/synced-registry.d.ts.map +1 -0
  623. package/dist/procedures/storage/synced-registry.js +575 -0
  624. package/dist/procedures/storage/synced-registry.js.map +1 -0
  625. package/dist/procedures/storage/types.d.ts +130 -0
  626. package/dist/procedures/storage/types.d.ts.map +1 -0
  627. package/dist/procedures/storage/types.js +8 -0
  628. package/dist/procedures/storage/types.js.map +1 -0
  629. package/dist/procedures/types.d.ts +468 -0
  630. package/dist/procedures/types.d.ts.map +1 -0
  631. package/dist/procedures/types.js +23 -0
  632. package/dist/procedures/types.js.map +1 -0
  633. package/dist/register.d.ts +8 -0
  634. package/dist/register.d.ts.map +1 -0
  635. package/dist/register.js +9 -0
  636. package/dist/register.js.map +1 -0
  637. package/dist/server/browser-guard.d.ts +69 -0
  638. package/dist/server/browser-guard.d.ts.map +1 -0
  639. package/dist/server/browser-guard.js +103 -0
  640. package/dist/server/browser-guard.js.map +1 -0
  641. package/dist/server/host-policy.d.ts +81 -0
  642. package/dist/server/host-policy.d.ts.map +1 -0
  643. package/dist/server/host-policy.js +104 -0
  644. package/dist/server/host-policy.js.map +1 -0
  645. package/dist/server/index.d.ts +46 -0
  646. package/dist/server/index.d.ts.map +1 -0
  647. package/dist/server/index.js +42 -0
  648. package/dist/server/index.js.map +1 -0
  649. package/dist/server/method.d.ts +24 -0
  650. package/dist/server/method.d.ts.map +1 -0
  651. package/dist/server/method.js +29 -0
  652. package/dist/server/method.js.map +1 -0
  653. package/dist/server/procedure-server.d.ts +226 -0
  654. package/dist/server/procedure-server.d.ts.map +1 -0
  655. package/dist/server/procedure-server.js +348 -0
  656. package/dist/server/procedure-server.js.map +1 -0
  657. package/dist/server/server.d.ts +161 -0
  658. package/dist/server/server.d.ts.map +1 -0
  659. package/dist/server/server.js +279 -0
  660. package/dist/server/server.js.map +1 -0
  661. package/dist/server/types.d.ts +106 -0
  662. package/dist/server/types.d.ts.map +1 -0
  663. package/dist/server/types.js +29 -0
  664. package/dist/server/types.js.map +1 -0
  665. package/package.json +117 -3
  666. package/src/adapters/http/client/index.ts +51 -0
  667. package/src/adapters/http/client/transport.ts +338 -0
  668. package/src/adapters/http/client/types.ts +33 -0
  669. package/src/adapters/http/index.ts +7 -0
  670. package/src/adapters/http/server/index.ts +14 -0
  671. package/src/adapters/http/server/strategies.ts +105 -0
  672. package/src/adapters/http/server/transport.ts +623 -0
  673. package/src/adapters/http/server/types.ts +81 -0
  674. package/src/adapters/http/shared/constants.ts +108 -0
  675. package/src/adapters/http/shared/errors.ts +199 -0
  676. package/src/adapters/http/shared/headers.ts +291 -0
  677. package/src/adapters/http/shared/index.ts +21 -0
  678. package/src/adapters/http/shared/status-codes.ts +212 -0
  679. package/src/adapters/http/shared/strategies.ts +255 -0
  680. package/src/adapters/local/client/index.ts +11 -0
  681. package/src/adapters/local/client/transport.ts +188 -0
  682. package/src/adapters/local/client/types.ts +50 -0
  683. package/src/adapters/metadata.ts +17 -0
  684. package/src/adapters/mock/client/builder.ts +64 -0
  685. package/src/adapters/mock/client/index.ts +19 -0
  686. package/src/adapters/mock/client/transport.ts +352 -0
  687. package/src/adapters/mock/client/types.ts +99 -0
  688. package/src/adapters/websocket/client/index.ts +18 -0
  689. package/src/adapters/websocket/client/transport.ts +733 -0
  690. package/src/adapters/websocket/client/types.ts +235 -0
  691. package/src/adapters/websocket/index.ts +24 -0
  692. package/src/adapters/websocket/server/index.ts +18 -0
  693. package/src/adapters/websocket/server/transport.ts +705 -0
  694. package/src/adapters/websocket/server/types.ts +169 -0
  695. package/src/browser.ts +401 -0
  696. package/src/client/batch-executor.ts +514 -0
  697. package/src/client/call-types.ts +491 -0
  698. package/src/client/client.ts +1229 -0
  699. package/src/client/consumption.ts +288 -0
  700. package/src/client/context.ts +228 -0
  701. package/src/client/errors/README.md +279 -0
  702. package/src/client/errors/codes.ts +88 -0
  703. package/src/client/errors/factory.ts +263 -0
  704. package/src/client/errors/http-errors.ts +601 -0
  705. package/src/client/errors/http-status.ts +82 -0
  706. package/src/client/errors/index.ts +72 -0
  707. package/src/client/errors/registry.ts +595 -0
  708. package/src/client/errors/types.ts +139 -0
  709. package/src/client/index.ts +124 -0
  710. package/src/client/middleware/auth.ts +132 -0
  711. package/src/client/middleware/cache.ts +316 -0
  712. package/src/client/middleware/circuit-breaker.ts +339 -0
  713. package/src/client/middleware/contexts.ts +319 -0
  714. package/src/client/middleware/items.ts +114 -0
  715. package/src/client/middleware/lru.ts +66 -0
  716. package/src/client/middleware/pagination.ts +213 -0
  717. package/src/client/middleware/rate-limit.ts +315 -0
  718. package/src/client/middleware/retry.ts +236 -0
  719. package/src/client/middleware/timeout.ts +308 -0
  720. package/src/client/middleware/tracing.ts +191 -0
  721. package/src/client/route-resolver.ts +407 -0
  722. package/src/client/typed-method.ts +65 -0
  723. package/src/client/typed.ts +140 -0
  724. package/src/client/types.ts +372 -0
  725. package/src/client/validation/index.ts +56 -0
  726. package/src/client/validation/middleware.ts +254 -0
  727. package/src/client/validation/types.ts +162 -0
  728. package/src/events/bus.ts +594 -0
  729. package/src/events/index.ts +67 -0
  730. package/src/events/types.ts +263 -0
  731. package/src/index.ts +33 -0
  732. package/src/middleware/compose.ts +159 -0
  733. package/src/middleware/index.ts +28 -0
  734. package/src/middleware/types.ts +166 -0
  735. package/src/procedures/capability.ts +333 -0
  736. package/src/procedures/cli/announce.ts +470 -0
  737. package/src/procedures/cli/discover.ts +390 -0
  738. package/src/procedures/cli/index.ts +231 -0
  739. package/src/procedures/cli/init.ts +370 -0
  740. package/src/procedures/collection/index.ts +51 -0
  741. package/src/procedures/collection/procedures.ts +257 -0
  742. package/src/procedures/collection/schemas.ts +550 -0
  743. package/src/procedures/collection/storage.ts +53 -0
  744. package/src/procedures/core/array.ts +1026 -0
  745. package/src/procedures/core/comparison.ts +265 -0
  746. package/src/procedures/core/index.ts +898 -0
  747. package/src/procedures/core/logic.ts +225 -0
  748. package/src/procedures/core/math.ts +471 -0
  749. package/src/procedures/core/meta.ts +389 -0
  750. package/src/procedures/core/object.ts +429 -0
  751. package/src/procedures/core/operands.ts +119 -0
  752. package/src/procedures/core/outputs.ts +48 -0
  753. package/src/procedures/core/results.ts +296 -0
  754. package/src/procedures/core/schemas.ts +123 -0
  755. package/src/procedures/core/string.ts +460 -0
  756. package/src/procedures/core/type.ts +346 -0
  757. package/src/procedures/define-procedure.ts +532 -0
  758. package/src/procedures/define.ts +387 -0
  759. package/src/procedures/discovery.ts +76 -0
  760. package/src/procedures/effects.ts +24 -0
  761. package/src/procedures/index.ts +239 -0
  762. package/src/procedures/interceptors.ts +273 -0
  763. package/src/procedures/invoke.ts +506 -0
  764. package/src/procedures/module.ts +117 -0
  765. package/src/procedures/policy.ts +171 -0
  766. package/src/procedures/ref.ts +1305 -0
  767. package/src/procedures/registry.ts +473 -0
  768. package/src/procedures/schema.ts +225 -0
  769. package/src/procedures/types.ts +596 -0
  770. package/src/register.ts +10 -0
  771. package/src/server/browser-guard.ts +147 -0
  772. package/src/server/host-policy.ts +163 -0
  773. package/src/server/index.ts +70 -0
  774. package/src/server/method.ts +33 -0
  775. package/src/server/procedure-server.ts +459 -0
  776. package/src/server/server.ts +364 -0
  777. package/src/server/types.ts +147 -0
@@ -0,0 +1,1229 @@
1
+ /**
2
+ * Universal Client
3
+ *
4
+ * Protocol-agnostic RPC client with middleware composition.
5
+ * Works with any transport: HTTP, gRPC, WebSocket, or local.
6
+ *
7
+ * The Client class is generic over its accumulated context type, enabling
8
+ * compile-time validation of middleware chains. Each call to `use()` returns
9
+ * a new type that includes the middleware's provided context.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Type accumulates as middleware is added
14
+ * const client = new Client(transport)
15
+ * .use(createRetryMiddleware()) // Client<BaseContext & RetryContext>
16
+ * .use(createCacheMiddleware({ methods: ["users.get"] })) // Client<... & CacheContext>
17
+ * .use(createAuthMiddleware(...)) // Client<... & AuthContext>
18
+ *
19
+ * // Middleware requiring context validates at compile time
20
+ * client.use(middlewareThatRequiresAuth); // OK if AuthContext is in chain
21
+ *
22
+ * // Context passing via withContext() and per-call options
23
+ * const authedClient = client.withContext({ auth: { token: "user-token" } });
24
+ * await authedClient.call(method, payload, { context: { retry: { maxAttempts: 5 } } });
25
+ * ```
26
+ */
27
+
28
+ import type {
29
+ Transport,
30
+ Method,
31
+ Metadata,
32
+ Message,
33
+ ClientMiddleware,
34
+ ClientContext,
35
+ ClientRunner,
36
+ ClientOptions,
37
+ TypedClientMiddleware,
38
+ } from "./types.js";
39
+ import { ClientError } from "./types.js";
40
+ import { compose } from "../middleware/compose.js";
41
+ import { pathToMethod } from "../server/method.js";
42
+ import type { CallOptions, ClientContextInput } from "./context.js";
43
+ import { mergeContext, normalizeCallOptions } from "./context.js";
44
+ import type { SchemaDefinition, ZodLike } from "./validation/types.js";
45
+ import { methodToKey } from "./validation/types.js";
46
+ import { SCHEMA_REGISTRY, type ZodMiddleware } from "./validation/middleware.js";
47
+ import type {
48
+ Route,
49
+ CallRequest,
50
+ CallResponse,
51
+ StreamingCallResponse,
52
+ ProcedureCallResult,
53
+ } from "./call-types.js";
54
+ import { buildResponse, toMiddlewareContext } from "./call-types.js";
55
+ import { RouteResolver, type ResolvedRoute, type RouteResolutionResult } from "./route-resolver.js";
56
+ import { BatchExecutor, type ExecutionContext } from "./batch-executor.js";
57
+ import type { ProcedureRegistry } from "../procedures/registry.js";
58
+ import type { EventBus } from "../events/types.js";
59
+ import { TIMEOUT_METADATA_KEY, narrowCapability } from "../procedures/capability.js";
60
+ import type { Capability, ClearanceOrder, NestedCallOptions } from "../procedures/types.js";
61
+ import { PROCEDURE_REGISTRY } from "../procedures/registry.js";
62
+ import { validateSchema } from "../procedures/schema.js";
63
+ import type { AnyProcedure, ProcedureClient, ProcedurePath } from "../procedures/types.js";
64
+ import {
65
+ InvocationError,
66
+ invokeProcedure,
67
+ outputItems,
68
+ outputValue,
69
+ type InvokeOptions,
70
+ type Invocation,
71
+ type Interceptor,
72
+ } from "../procedures/invoke.js";
73
+ import { isHandlerConfig, isStreamConfig, type HandlerCallback, type OutputConfig } from "./consumption.js";
74
+ import {
75
+ isAnyProcedureRef,
76
+ isPlainObject,
77
+ normalizeRef,
78
+ prepareRootCall,
79
+ rawInputRule,
80
+ type ProcedureRef,
81
+ type AnyProcedureRef,
82
+ type HydrationEvent,
83
+ } from "../procedures/ref.js";
84
+
85
+ /** Each element of each array item: the stream form of an `outputMode: "batch"` procedure. */
86
+ async function* batchElements(items: AsyncIterable<unknown>): AsyncGenerator<unknown, void, undefined> {
87
+ for await (const item of items) {
88
+ if (Array.isArray(item)) {
89
+ yield* item;
90
+ } else {
91
+ yield item;
92
+ }
93
+ }
94
+ }
95
+
96
+ /**
97
+ * The items of a source, with up to `size` items read ahead of the reader. With size 0, the
98
+ * source runs only when the reader reads (the source itself is returned).
99
+ */
100
+ function readAhead<T>(source: AsyncIterable<T>, size: number): AsyncIterable<T> {
101
+ if (size <= 0) return source;
102
+ return (async function* () {
103
+ const iterator = source[Symbol.asyncIterator]();
104
+ const buffer: Array<Promise<IteratorResult<T>>> = [];
105
+ let ended = false;
106
+ const pull = (): void => {
107
+ while (!ended && buffer.length < size + 1) {
108
+ const next = iterator.next();
109
+ buffer.push(next);
110
+ // The handler marks the end, and keeps a failure from being unhandled until it is read
111
+ next.then(
112
+ (result) => {
113
+ if (result.done) ended = true;
114
+ },
115
+ () => {
116
+ ended = true;
117
+ }
118
+ );
119
+ }
120
+ };
121
+ let finished = false;
122
+ try {
123
+ // Before each read: the item for the reader, and `size` items ahead
124
+ for (pull(); buffer.length > 0; pull()) {
125
+ const result = await buffer.shift()!;
126
+ if (result.done) break;
127
+ yield result.value;
128
+ }
129
+ finished = true;
130
+ } finally {
131
+ if (!finished) await iterator.return?.();
132
+ }
133
+ })();
134
+ }
135
+
136
+ /** The metadata and the signal of a procedure, for the nested calls that it makes. */
137
+ interface CallerContext {
138
+ metadata?: Record<string, unknown> | undefined;
139
+ signal?: AbortSignal | undefined;
140
+ /** The invocation whose handler makes the call: the interceptors link a nested call to it. */
141
+ parent?: Invocation | undefined;
142
+ /** The hydration observer of the program (`exec(ref, input, { onRef })`). */
143
+ onRef?: ((event: HydrationEvent) => void) | undefined;
144
+ /** The capability of the caller: the nested calls get it, or a narrower one. */
145
+ capability?: Capability | undefined;
146
+ }
147
+
148
+ /** The options of `exec()` and `execStream()`. */
149
+ export interface ExecOptions {
150
+ /**
151
+ * This function gets the hydration events of this program only: the refs that hydration runs,
152
+ * also inside control flow and runners, with the call that gets each result. A trace uses it.
153
+ * (`observeHydration()` gets the events of every program in the process.)
154
+ */
155
+ onRef?: ((event: HydrationEvent) => void) | undefined;
156
+ }
157
+
158
+ /**
159
+ * Generate a unique message ID.
160
+ */
161
+ function generateId(): string {
162
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
163
+ }
164
+
165
+ /**
166
+ * Universal Client for protocol-agnostic RPC.
167
+ *
168
+ * Features:
169
+ * - Works with any transport (HTTP, gRPC, WebSocket, local)
170
+ * - Middleware composition (retry, cache, timeout, custom)
171
+ * - Stream-first API (single response = stream with 1 item)
172
+ * - Type-safe request/response handling
173
+ * - **Type-accumulating middleware**: Context types build through `use()` calls
174
+ *
175
+ * @typeParam TContext - Accumulated context type from applied middleware.
176
+ * Starts as `{}` and grows as middleware is added via `use()`.
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * // HTTP client with type-accumulating middleware
181
+ * const client = new Client({ transport: new HttpTransport({ baseUrl: "/api" }) })
182
+ * .use(createRetryMiddleware()) // Client<{} & RetryContext>
183
+ * .use(createCacheMiddleware({ methods: ["users.get"] })) // Client<{} & RetryContext & CacheContext>
184
+ * .use(createAuthMiddleware({ // Client<... & AuthContext>
185
+ * token: "abc123"
186
+ * }));
187
+ *
188
+ * // The client type now carries all middleware context
189
+ * const user = await client.call(
190
+ * { service: "users", operation: "get" },
191
+ * { id: 123 }
192
+ * );
193
+ *
194
+ * // Streaming
195
+ * for await (const event of client.stream(
196
+ * { service: "events", operation: "watch" },
197
+ * { topic: "orders" }
198
+ * )) {
199
+ * console.log(event);
200
+ * }
201
+ * ```
202
+ */
203
+ export class Client<TContext = {}> {
204
+ private readonly transport: Transport;
205
+ private readonly middleware: ClientMiddleware[] = [];
206
+ private readonly defaultMetadata: Metadata;
207
+ private readonly throwOnError: boolean;
208
+ /** The bus of the local procedures. Undefined: the global bus. */
209
+ private bus: EventBus | undefined;
210
+ /** The interceptors of the local invocations (roadmap 1.2) */
211
+ private interceptors: readonly Interceptor[] = [];
212
+ /** The capability of the local invocations (CAPABILITIES-2026-10). Undefined: no limits. */
213
+ private capability: Capability | undefined;
214
+ /** The order of the clearance values. */
215
+ private clearanceOrder: ClearanceOrder | undefined;
216
+
217
+ /**
218
+ * Context values set via withContext().
219
+ * Merged with parent context when creating child clients.
220
+ */
221
+ private readonly clientContext: Partial<TContext>;
222
+
223
+ /**
224
+ * Parent client reference (for context inheritance).
225
+ * When set, middleware and transport are shared, only context differs.
226
+ */
227
+ private readonly parent?: Client<any>;
228
+
229
+ constructor(options: ClientOptions | Transport) {
230
+ // Support both new Client(transport) and new Client({ transport, ... })
231
+ if ("send" in options && typeof options.send === "function") {
232
+ // Direct transport passed - narrow to Transport type
233
+ const transport = options as Transport;
234
+ this.transport = transport;
235
+ this.defaultMetadata = {};
236
+ this.throwOnError = true;
237
+ } else {
238
+ // Options object - narrow to ClientOptions type
239
+ const opts = options as ClientOptions;
240
+ this.transport = opts.transport;
241
+ this.defaultMetadata = opts.defaultMetadata || {};
242
+ this.throwOnError = opts.throwOnError !== false;
243
+ this.bus = opts.bus;
244
+ this.interceptors = opts.interceptors ?? [];
245
+ this.capability = opts.capability;
246
+ this.clearanceOrder = opts.clearanceOrder;
247
+ }
248
+
249
+ // Initialize empty context (child clients override this)
250
+ this.clientContext = {};
251
+ }
252
+
253
+ /**
254
+ * Create a child client from this client (private, for withContext).
255
+ */
256
+ private static createChild<TParentContext, TChildContext extends TParentContext>(
257
+ parent: Client<TParentContext>,
258
+ additionalContext: Partial<TChildContext>,
259
+ ): Client<TChildContext> {
260
+ // Create a child with shared middleware chain
261
+ const child = Object.create(Client.prototype) as Client<TChildContext>;
262
+
263
+ // Share immutable references (no copying)
264
+ (child as any).transport = parent.transport;
265
+ (child as any).middleware = parent.middleware;
266
+ (child as any).defaultMetadata = parent.defaultMetadata;
267
+ (child as any).throwOnError = parent.throwOnError;
268
+ (child as any).bus = parent.bus;
269
+ (child as any).interceptors = parent.interceptors;
270
+ (child as any).capability = parent.capability;
271
+ (child as any).clearanceOrder = parent.clearanceOrder;
272
+
273
+ // Object.create() bypasses class-field initializers, so procedureRegistry (which normally
274
+ // defaults to PROCEDURE_REGISTRY via a field initializer) would be undefined on the child
275
+ // and exec()/route() would throw "Cannot read properties of undefined (reading 'get')".
276
+ // Inherit the parent's registry; leave the lazy resolver/executor undefined so the child
277
+ // builds its own (batchExecutor binds this.executeProcedure, which must be the child's).
278
+ // See documentation/BUGS-2026-07.md (H1).
279
+ (child as any).procedureRegistry = parent.procedureRegistry;
280
+ (child as any).routeResolver = undefined;
281
+ (child as any).batchExecutor = undefined;
282
+
283
+ // Set parent and additional context
284
+ (child as any).parent = parent;
285
+ (child as any).clientContext = additionalContext;
286
+
287
+ return child;
288
+ }
289
+
290
+ /**
291
+ * Create a child client with additional context.
292
+ *
293
+ * Child clients:
294
+ * - Share the middleware chain (cheap to create)
295
+ * - Inherit parent context (merged recursively)
296
+ * - Can override specific context fields
297
+ *
298
+ * Context priority (lowest to highest):
299
+ * 1. Middleware defaults (e.g., maxRetries: 3 from createRetryMiddleware)
300
+ * 2. Parent client context (full inheritance chain)
301
+ * 3. This client's context
302
+ * 4. Per-call context override
303
+ *
304
+ * @param context - Context to set/override on the child client
305
+ * @returns New client with accumulated context
306
+ *
307
+ * @example
308
+ * ```typescript
309
+ * // Create authenticated child client
310
+ * const authedClient = client.withContext({
311
+ * auth: { token: "user-token" },
312
+ * timeout: { overall: 5000 }
313
+ * });
314
+ *
315
+ * // Nested children inherit and can override
316
+ * const adminClient = authedClient.withContext({
317
+ * auth: { token: "admin-token" }, // Overrides parent token
318
+ * // timeout inherited from parent
319
+ * });
320
+ * ```
321
+ */
322
+ withContext<TAdditional extends object = {}>(
323
+ context: TAdditional & ClientContextInput<TContext>,
324
+ ): Client<TContext & TAdditional> {
325
+ return Client.createChild(this, context) as Client<TContext & TAdditional>;
326
+ }
327
+
328
+ /**
329
+ * Get effective context by merging entire parent chain.
330
+ *
331
+ * @returns Merged context from all ancestors plus this client
332
+ */
333
+ private getEffectiveContext(): Partial<TContext> {
334
+ if (this.parent) {
335
+ return mergeContext(this.parent.getEffectiveContext(), this.clientContext);
336
+ }
337
+ return this.clientContext;
338
+ }
339
+
340
+ /**
341
+ * Add middleware to the client.
342
+ *
343
+ * Middleware is composed in the order added (onion model):
344
+ * - First added = outermost layer
345
+ * - Last added = innermost layer (closest to transport)
346
+ *
347
+ * **Type Accumulation**: When using `TypedClientMiddleware`, the return type
348
+ * accumulates the middleware's provided context. This enables compile-time
349
+ * validation of middleware chains.
350
+ *
351
+ * @typeParam TProvides - Context type this middleware provides
352
+ * @typeParam TRequires - Context type this middleware requires (must be subset of TContext)
353
+ * @param middleware - Middleware function (typed or untyped)
354
+ * @returns Client with accumulated context type
355
+ *
356
+ * @example
357
+ * ```typescript
358
+ * // Type accumulation example
359
+ * const client = new Client(transport)
360
+ * .use(createTimeoutMiddleware({ overall: 5000 })) // Client<TimeoutContext>
361
+ * .use(createRetryMiddleware()) // Client<TimeoutContext & RetryContext>
362
+ * .use(createCacheMiddleware({ methods: ["users.get"] })); // Client<... & CacheContext>
363
+ *
364
+ * // Middleware ordering (onion model)
365
+ * client
366
+ * .use(timeoutMiddleware()) // Outer: handles timeouts
367
+ * .use(retryMiddleware()) // Middle: handles retries
368
+ * .use(cacheMiddleware()); // Inner: handles caching
369
+ * ```
370
+ */
371
+ use<TProvides = {}, TRequires extends TContext = TContext>(
372
+ middleware: TypedClientMiddleware<TProvides, TRequires> | ClientMiddleware,
373
+ ): Client<TContext & TProvides> {
374
+ this.middleware.push(middleware as ClientMiddleware);
375
+ // Cast is safe because we're just adding type information
376
+ // Runtime behavior is unchanged
377
+ return this as unknown as Client<TContext & TProvides>;
378
+ }
379
+
380
+ /**
381
+ * Make a single RPC call (request/response).
382
+ *
383
+ * The result is the last item of the response stream: the one item of a request/response
384
+ * call, or the final item of a streaming procedure. To read each item, use `stream()`.
385
+ *
386
+ * @param method - Method to invoke
387
+ * @param payload - Request payload
388
+ * @param options - Call options (context override, metadata, signal, schema)
389
+ * OR legacy Metadata object for backward compatibility
390
+ * @returns Response payload
391
+ * @throws {ClientError} if response has error status (when throwOnError=true)
392
+ *
393
+ * @example
394
+ * ```typescript
395
+ * // Simple call
396
+ * const user = await client.call(
397
+ * { service: "users", operation: "get" },
398
+ * { id: 123 }
399
+ * );
400
+ *
401
+ * // With context override
402
+ * const user = await client.call(
403
+ * { service: "users", operation: "get" },
404
+ * { id: 123 },
405
+ * { context: { timeout: { overall: 10000 } } }
406
+ * );
407
+ * ```
408
+ */
409
+ async call<TReq, TRes>(
410
+ method: Method,
411
+ payload: TReq,
412
+ options?: CallOptions<TContext> | Metadata,
413
+ ): Promise<TRes> {
414
+ // The result of a stream is its last item (the "sponge" mode of procedures/types.ts). Every
415
+ // request/response transport yields one item, so its result does not change. (Before, the
416
+ // result was the first item, and a falsy first item - 0, false, "" - threw "No response".)
417
+ let last: { value: TRes } | undefined;
418
+ for await (const item of this.stream<TReq, TRes>(method, payload, options)) {
419
+ last = { value: item };
420
+ }
421
+ if (!last) {
422
+ throw new Error("No response received from stream");
423
+ }
424
+ return last.value;
425
+ }
426
+
427
+ // ===========================================================================
428
+ // Procedure Reference Execution (Procedure-as-Data)
429
+ // ===========================================================================
430
+
431
+ /**
432
+ * Execute a procedure reference with automatic input hydration.
433
+ *
434
+ * This method supports procedure-as-data: procedures can be passed as inputs
435
+ * to other procedures, composed declaratively via JSON, or imperatively via TypeScript.
436
+ *
437
+ * **Input Hydration**: Any ProcedureRef or `$proc` objects in the input tree
438
+ * are automatically executed and replaced with their results before the
439
+ * main procedure runs.
440
+ *
441
+ * @param refOrPath - Procedure reference, JSON procedure ref, or procedure path
442
+ * @param input - Input for the procedure. With a reference, its fields go over the fields of the reference's input.
443
+ * @returns Output of the procedure
444
+ *
445
+ * @example
446
+ * ```typescript
447
+ * import { proc } from "@procedures/client";
448
+ *
449
+ * // Using proc() builder
450
+ * const result = await client.exec(
451
+ * proc(["git", "add"]).input({ all: true }).build()
452
+ * );
453
+ *
454
+ * // Using JSON format
455
+ * const result = await client.exec({
456
+ * $proc: ["git", "add"],
457
+ * input: { all: true },
458
+ * });
459
+ *
460
+ * // Using path + input (simple form)
461
+ * const result = await client.exec(["git", "add"], { all: true });
462
+ *
463
+ * // Nested procedure refs (hydrated automatically)
464
+ * const result = await client.exec(
465
+ * proc(["dag", "traverse"]).input({
466
+ * visit: proc(["client", "chain"]).input({
467
+ * steps: [
468
+ * proc(["git", "add"]).input({ all: true }).ref,
469
+ * proc(["git", "commit"]).input({ message: "auto" }).ref,
470
+ * ],
471
+ * }).ref,
472
+ * }).build()
473
+ * );
474
+ * ```
475
+ */
476
+ async exec<TOutput = unknown>(
477
+ refOrPath: AnyProcedureRef | ProcedurePath,
478
+ input?: unknown,
479
+ options: ExecOptions = {}
480
+ ): Promise<TOutput> {
481
+ const caller: CallerContext = options.onRef ? { onRef: options.onRef } : {};
482
+ const { path, input: hydratedInput } = await this.prepareRef(refOrPath, input, caller);
483
+ return this.execInternal<TOutput>(path, hydratedInput, caller);
484
+ }
485
+
486
+ /**
487
+ * Execute a procedure reference and read each output: each item of a streaming procedure, or
488
+ * the one value of another procedure. The input refs run as in `exec()`. Nothing runs until
489
+ * the caller reads the first item.
490
+ *
491
+ * @example
492
+ * ```typescript
493
+ * for await (const line of client.execStream(["logs", "tail"], { file: "app.log" })) {
494
+ * console.log(line);
495
+ * }
496
+ * ```
497
+ */
498
+ execStream<TOutput = unknown>(
499
+ refOrPath: AnyProcedureRef | ProcedurePath,
500
+ input?: unknown,
501
+ options: ExecOptions = {}
502
+ ): AsyncIterable<TOutput> {
503
+ const self = this;
504
+ const caller: CallerContext = options.onRef ? { onRef: options.onRef } : {};
505
+ return (async function* () {
506
+ const { path, input: hydratedInput } = await self.prepareRef(refOrPath, input, caller);
507
+ yield* self.execStreamInternal<TOutput>(path, hydratedInput, caller);
508
+ })();
509
+ }
510
+
511
+ /**
512
+ * The path and the input of a reference, with the refs of the input run (hydrated).
513
+ */
514
+ private async prepareRef(
515
+ refOrPath: AnyProcedureRef | ProcedurePath,
516
+ input: unknown,
517
+ caller: CallerContext = {}
518
+ ): Promise<{ path: ProcedurePath; input: unknown }> {
519
+ // Normalize to ProcedureRef
520
+ let ref: ProcedureRef;
521
+
522
+ if (isAnyProcedureRef(refOrPath)) {
523
+ ref = normalizeRef(refOrPath);
524
+ // The fields of `input` go over the fields of the ref's input (before, `input` was ignored)
525
+ if (input !== undefined) {
526
+ ref = {
527
+ ...ref,
528
+ input: isPlainObject(ref.input) && isPlainObject(input) ? { ...ref.input, ...input } : input,
529
+ };
530
+ }
531
+ } else if (Array.isArray(refOrPath) && refOrPath.every((s) => typeof s === "string")) {
532
+ // Path array provided, use second argument as input
533
+ ref = {
534
+ [Symbol.for("@mark/procedure") as typeof import("../procedures/ref.js").PROCEDURE_SYMBOL]: true,
535
+ path: refOrPath as ProcedurePath,
536
+ input: input ?? {},
537
+ } as ProcedureRef;
538
+ } else {
539
+ throw new Error("exec() requires a ProcedureRef, $proc JSON, or procedure path array");
540
+ }
541
+
542
+ // Create executor function for hydration
543
+ const executor = async <TIn, TOut>(path: ProcedurePath, inp: TIn): Promise<TOut> => {
544
+ return this.execInternal<TOut>(path, inp, caller);
545
+ };
546
+
547
+ // A procedure that takes its input raw (control flow, the `runs-refs` and `raw-input` tags,
548
+ // `procedure.define`) gets its operand refs RAW: it runs them itself, with correct
549
+ // ordering/laziness/error-scoping. Eagerly hydrating here would run the operands up-front
550
+ // and can hijack an all-refs array into an implicit chain that clobbers `steps`. See
551
+ // documentation/BUGS-2026-07.md (C2, H2, H3, M35). The procedure in the registry decides,
552
+ // also for the refs nested in the input (deep dive CORE-5: before, the last path segment did).
553
+ // The body of a defined procedure starts its root call the same way (prepareRootCall, DOC-3)
554
+ return prepareRootCall(ref, executor, { rawInput: rawInputRule(this.procedureRegistry), onRef: caller.onRef });
555
+ }
556
+
557
+ /**
558
+ * The options of a local invocation. The nested calls of the procedure go through this
559
+ * client, so a path without a local handler goes to the transport. The nested calls get the
560
+ * metadata and the signal of the caller: when the caller aborts, its nested work stops. (Before,
561
+ * each nested call started again with no metadata and no signal: deep dive CORE-10.)
562
+ */
563
+ private invokeOptions(caller: CallerContext = {}): InvokeOptions {
564
+ const self = this;
565
+ // The nested calls get the metadata and the signal of the invocation (an interceptor can
566
+ // change them), and name it as their parent
567
+ const client = (invocation: Invocation): ProcedureClient => {
568
+ // The nested calls get the capability of the invocation, or a narrower one on request
569
+ const nested = (options?: NestedCallOptions): CallerContext => ({
570
+ metadata: invocation.metadata,
571
+ signal: invocation.signal,
572
+ parent: invocation,
573
+ onRef: caller.onRef,
574
+ capability: options?.narrow
575
+ ? narrowCapability(invocation.capability, options.narrow, self.clearanceOrder)
576
+ : invocation.capability,
577
+ });
578
+ return {
579
+ call: <TInput, TOutput>(path: ProcedurePath, input: TInput, options?: NestedCallOptions) =>
580
+ self.execInternal<TOutput>(path, input, nested(options)),
581
+ stream: <TInput, TOutput>(path: ProcedurePath, input: TInput, options?: NestedCallOptions) =>
582
+ self.execStreamInternal<TOutput>(path, input, nested(options)),
583
+ };
584
+ };
585
+ return {
586
+ registry: this.procedureRegistry,
587
+ metadata: caller.metadata ?? {},
588
+ signal: caller.signal,
589
+ client,
590
+ bus: this.bus,
591
+ interceptors: this.interceptors,
592
+ parent: caller.parent,
593
+ onRef: caller.onRef,
594
+ capability: caller.capability ?? this.capability,
595
+ clearanceOrder: this.clearanceOrder,
596
+ };
597
+ }
598
+
599
+ /**
600
+ * The call options of a remote call for a caller: its metadata as context, and its signal. A
601
+ * deadline goes as the remaining time (`procedure-timeout`, in milliseconds): the server
602
+ * calculates its own deadline, so a difference between two clocks has no effect.
603
+ */
604
+ private remoteCallOptions(caller: CallerContext): CallOptions<TContext> {
605
+ const deadline = (caller.capability ?? this.capability)?.deadline;
606
+ const metadata =
607
+ deadline === undefined ? caller.metadata ?? {} : { ...caller.metadata, [TIMEOUT_METADATA_KEY]: Math.max(0, deadline - Date.now()) };
608
+ const options: CallOptions<TContext> = { context: metadata as ClientContextInput<TContext> };
609
+ if (caller.signal) {
610
+ options.signal = caller.signal;
611
+ }
612
+ return options;
613
+ }
614
+
615
+ /**
616
+ * The input for a procedure without a local handler: validated with the local schema when
617
+ * the registry has the procedure, then sent to the transport.
618
+ */
619
+ private async remoteInput(procedure: AnyProcedure | undefined, path: ProcedurePath, input: unknown): Promise<unknown> {
620
+ if (!procedure) return input;
621
+ const result = await validateSchema(procedure.input, input);
622
+ if (!result.ok) {
623
+ throw new InvocationError(
624
+ "VALIDATION_ERROR",
625
+ `Input validation failed for ${path.join(".")}: ${result.message}`,
626
+ path
627
+ );
628
+ }
629
+ return result.value;
630
+ }
631
+
632
+ /**
633
+ * Internal procedure execution (no hydration of the top-level input).
634
+ */
635
+ private async execInternal<TOutput>(
636
+ path: ProcedurePath,
637
+ input: unknown,
638
+ caller: CallerContext = {}
639
+ ): Promise<TOutput> {
640
+ const procedure = this.procedureRegistry.get(path);
641
+ if (procedure?.handler) {
642
+ const options = this.invokeOptions(caller);
643
+ return outputValue(await invokeProcedure<TOutput>(procedure, input, options), path);
644
+ }
645
+ // No local handler: the transport runs it (a remote procedure)
646
+ return this.call(
647
+ this.pathToMethod(path),
648
+ await this.remoteInput(procedure, path, input),
649
+ this.remoteCallOptions(caller)
650
+ ) as Promise<TOutput>;
651
+ }
652
+
653
+ /**
654
+ * Internal streaming execution (no hydration of the top-level input).
655
+ */
656
+ private execStreamInternal<TOutput>(
657
+ path: ProcedurePath,
658
+ input: unknown,
659
+ caller: CallerContext = {}
660
+ ): AsyncIterable<TOutput> {
661
+ const self = this;
662
+ return (async function* () {
663
+ const procedure = self.procedureRegistry.get(path);
664
+ if (procedure?.handler) {
665
+ const options = self.invokeOptions(caller);
666
+ yield* outputItems(await invokeProcedure<TOutput>(procedure, input, options));
667
+ return;
668
+ }
669
+ yield* self.stream<unknown, TOutput>(
670
+ self.pathToMethod(path),
671
+ await self.remoteInput(procedure, path, input),
672
+ self.remoteCallOptions(caller)
673
+ );
674
+ })();
675
+ }
676
+
677
+ /**
678
+ * Make a streaming RPC call.
679
+ *
680
+ * Returns an async iterable that yields response payloads.
681
+ * For single request/response, yields exactly one item.
682
+ *
683
+ * @param method - Method to invoke
684
+ * @param payload - Request payload
685
+ * @param options - Call options (context override, metadata, signal, schema)
686
+ * OR legacy Metadata object for backward compatibility
687
+ * @returns Async iterable of response payloads
688
+ * @throws {ClientError} if any response item has error status (when throwOnError=true)
689
+ *
690
+ * @example
691
+ * ```typescript
692
+ * // Streaming response
693
+ * for await (const event of client.stream(
694
+ * { service: "events", operation: "watch" },
695
+ * { topic: "orders" }
696
+ * )) {
697
+ * console.log(event);
698
+ * }
699
+ *
700
+ * // With context and signal
701
+ * const controller = new AbortController();
702
+ * for await (const event of client.stream(
703
+ * { service: "events", operation: "watch" },
704
+ * { topic: "orders" },
705
+ * { context: { timeout: { overall: 30000 } }, signal: controller.signal }
706
+ * )) {
707
+ * console.log(event);
708
+ * }
709
+ * ```
710
+ */
711
+ async *stream<TReq, TRes>(
712
+ method: Method,
713
+ payload: TReq,
714
+ options?: CallOptions<TContext> | Metadata,
715
+ ): AsyncIterable<TRes> {
716
+ // Normalize options (backward compatible with legacy Metadata parameter)
717
+ const opts = normalizeCallOptions(options);
718
+
719
+ // Merge context: parent chain -> client context -> per-call context
720
+ const effectiveContext = mergeContext(
721
+ this.getEffectiveContext() as object,
722
+ (opts.context ?? {}) as object,
723
+ );
724
+
725
+ // Create message with merged context in metadata
726
+ const message: Message<TReq> = {
727
+ id: generateId(),
728
+ method,
729
+ payload,
730
+ metadata: {
731
+ ...this.defaultMetadata,
732
+ ...effectiveContext, // Context flows into metadata
733
+ ...opts.metadata, // Raw metadata last (highest priority)
734
+ },
735
+ };
736
+
737
+ // Set signal if provided
738
+ if (opts.signal) {
739
+ message.signal = opts.signal;
740
+ }
741
+
742
+ // Store schema override in metadata for Zod middleware
743
+ if (opts.schema) {
744
+ (message.metadata as any).__schema = opts.schema;
745
+ }
746
+
747
+ // Compose middleware chain
748
+ const runner = this.composeMiddleware<TReq, TRes>();
749
+
750
+ // Execute through middleware chain
751
+ const context: ClientContext<TReq> = { message };
752
+ const responseStream = runner(context);
753
+
754
+ // Yield payloads, handling errors
755
+ for await (const item of responseStream) {
756
+ if (item.status.type === "error" && this.throwOnError) {
757
+ throw new ClientError(item.status, item.id);
758
+ }
759
+
760
+ yield item.payload;
761
+ }
762
+ }
763
+
764
+ /**
765
+ * Compose middleware chain using universal middleware composition.
766
+ *
767
+ * @returns Composed runner function
768
+ * @private
769
+ */
770
+ private composeMiddleware<TReq, TRes>(): ClientRunner<TReq, TRes> {
771
+ // Innermost function: call transport
772
+ const self = this;
773
+ const transportRunner: ClientRunner<TReq, TRes> = async function* (context: ClientContext<TReq>) {
774
+ yield* self.transport.send<TReq, TRes>(context.message);
775
+ };
776
+
777
+ // Use universal middleware composition
778
+ // compose(...middleware, finalRunner) applies middleware in order (onion model)
779
+ return compose<false>(...(this.middleware as any[]), transportRunner) as ClientRunner<TReq, TRes>;
780
+ }
781
+
782
+ /**
783
+ * Get transport name.
784
+ */
785
+ get transportName(): string {
786
+ return this.transport.name;
787
+ }
788
+
789
+ /**
790
+ * Close client and cleanup transport resources.
791
+ */
792
+ async close(): Promise<void> {
793
+ await this.transport.close();
794
+ }
795
+
796
+ // ===========================================================================
797
+ // Schema Registration (Zod Validation)
798
+ // ===========================================================================
799
+
800
+ /**
801
+ * Cached reference to Zod middleware for schema registration.
802
+ */
803
+ private zodMiddleware: ZodMiddleware | undefined;
804
+
805
+ /**
806
+ * Register a validation schema for a specific method.
807
+ *
808
+ * Requires `createZodMiddleware()` to be added via `.use()` first.
809
+ * Schemas are used to validate request payloads before sending and
810
+ * response payloads after receiving.
811
+ *
812
+ * @param method - Method to register schema for
813
+ * @param schemas - Input and/or output Zod schemas
814
+ * @returns this (for chaining)
815
+ *
816
+ * @example
817
+ * ```typescript
818
+ * import { z } from "zod";
819
+ *
820
+ * const client = new Client({ transport })
821
+ * .use(createZodMiddleware())
822
+ * .schema({ service: "users", operation: "get" }, {
823
+ * input: z.object({ id: z.string() }),
824
+ * output: z.object({ id: z.string(), name: z.string() }),
825
+ * })
826
+ * .schema({ service: "users", operation: "create" }, {
827
+ * input: UserCreateSchema,
828
+ * output: UserSchema,
829
+ * });
830
+ *
831
+ * // Validation happens automatically on call
832
+ * const user = await client.call(
833
+ * { service: "users", operation: "get" },
834
+ * { id: "123" } // Validated against input schema
835
+ * );
836
+ * // Response validated against output schema
837
+ * ```
838
+ */
839
+ schema<TInput extends ZodLike = ZodLike, TOutput extends ZodLike = ZodLike>(
840
+ method: Method,
841
+ schemas: {
842
+ input?: TInput;
843
+ output?: TOutput;
844
+ },
845
+ ): this {
846
+ // Find Zod middleware (lazy lookup, cached)
847
+ if (!this.zodMiddleware) {
848
+ this.zodMiddleware = this.findZodMiddleware();
849
+ }
850
+
851
+ if (!this.zodMiddleware) {
852
+ throw new Error(
853
+ "Cannot register schema: createZodMiddleware() must be added via .use() first",
854
+ );
855
+ }
856
+
857
+ const key = methodToKey(method);
858
+ this.zodMiddleware[SCHEMA_REGISTRY].set(key, schemas as SchemaDefinition);
859
+
860
+ return this;
861
+ }
862
+
863
+ /**
864
+ * Find Zod middleware in the middleware chain.
865
+ */
866
+ private findZodMiddleware(): ZodMiddleware | undefined {
867
+ // Check parent chain first (child clients share middleware)
868
+ if (this.parent) {
869
+ return this.parent.findZodMiddleware();
870
+ }
871
+
872
+ return this.middleware.find(
873
+ (m): m is ZodMiddleware => SCHEMA_REGISTRY in m,
874
+ );
875
+ }
876
+
877
+ // ===========================================================================
878
+ // Nested Route API
879
+ // ===========================================================================
880
+
881
+ /**
882
+ * Procedure registry for route resolution.
883
+ * Uses global registry by default.
884
+ */
885
+ private procedureRegistry: ProcedureRegistry = PROCEDURE_REGISTRY;
886
+
887
+ /**
888
+ * Route resolver instance (lazy initialized).
889
+ */
890
+ private routeResolver: RouteResolver | undefined;
891
+
892
+ /**
893
+ * Batch executor instance (lazy initialized).
894
+ */
895
+ private batchExecutor: BatchExecutor | undefined;
896
+
897
+ /**
898
+ * Set a custom procedure registry for this client.
899
+ *
900
+ * @param registry - Procedure registry to use
901
+ * @returns this (for chaining)
902
+ */
903
+ useRegistry(registry: ProcedureRegistry): this {
904
+ this.procedureRegistry = registry;
905
+ this.routeResolver = undefined; // Reset resolver
906
+ return this;
907
+ }
908
+
909
+ /**
910
+ * Set the event bus of the local procedures of this client (`ctx.bus`).
911
+ *
912
+ * @param bus - Event bus for the procedures
913
+ * @returns this (for chaining)
914
+ */
915
+ useBus(bus: EventBus): this {
916
+ this.bus = bus;
917
+ return this;
918
+ }
919
+
920
+ /**
921
+ * Make a call using the nested route API.
922
+ *
923
+ * This method supports:
924
+ * - Per-call middleware overrides
925
+ * - Batch execution with configurable strategies
926
+ * - Type-safe nested route structures
927
+ *
928
+ * @param request - Call request with route and options
929
+ * @returns Response mirroring the route structure
930
+ *
931
+ * @example
932
+ * ```typescript
933
+ * // Single route call
934
+ * const result = await client.route({
935
+ * route: {
936
+ * collections: {
937
+ * users: {
938
+ * get: { id: "123" }
939
+ * }
940
+ * }
941
+ * }
942
+ * });
943
+ * // result.collections.users.get.data = { id: "123", name: "John" }
944
+ *
945
+ * // Batched call with middleware overrides
946
+ * const results = await client.route({
947
+ * middlewares: {
948
+ * retry: { attempts: 3 },
949
+ * timeout: { ms: 5000 }
950
+ * },
951
+ * batch: { strategy: 'all' },
952
+ * route: {
953
+ * collections: {
954
+ * users: { get: { id: "123" } },
955
+ * orders: { list: { userId: "123" } }
956
+ * },
957
+ * weather: {
958
+ * forecast: { city: "NYC", days: 5 }
959
+ * }
960
+ * }
961
+ * });
962
+ * ```
963
+ */
964
+ async route<TRoute extends Route>(
965
+ request: CallRequest<TRoute>
966
+ ): Promise<CallResponse<TRoute>> {
967
+ const resolver = this.getRouteResolver();
968
+ const executor = this.getBatchExecutor();
969
+
970
+ // Resolve routes to procedures
971
+ const resolution = resolver.resolve(request.route);
972
+
973
+ if (!resolution.success) {
974
+ return buildResponse<TRoute>(this.resolutionFailure(resolution));
975
+ }
976
+
977
+ // Create execution context
978
+ const context = this.createExecutionContext(request);
979
+
980
+ // Execute routes
981
+ const batchConfig = request.batch ?? { strategy: "all" };
982
+ const result = await executor.executeBatch<TRoute>(
983
+ resolution.resolved,
984
+ context,
985
+ batchConfig
986
+ );
987
+
988
+ return result.response;
989
+ }
990
+
991
+ /**
992
+ * Make a streaming call using the nested route API.
993
+ *
994
+ * Returns an async iterator that yields results as they complete,
995
+ * plus a promise for the final complete response.
996
+ *
997
+ * @param request - Call request (batch.strategy should be 'stream')
998
+ * @returns Streaming response with iterator and completion promise
999
+ */
1000
+ routeStream<TRoute extends Route>(
1001
+ request: CallRequest<TRoute>
1002
+ ): StreamingCallResponse<TRoute> {
1003
+ const resolver = this.getRouteResolver();
1004
+ const executor = this.getBatchExecutor();
1005
+
1006
+ const resolution = resolver.resolve(request.route);
1007
+
1008
+ if (!resolution.success) {
1009
+ // Return error response immediately
1010
+ const errorResults = this.resolutionFailure(resolution);
1011
+
1012
+ return {
1013
+ results: (async function* () {
1014
+ for (const [path, result] of errorResults) {
1015
+ yield { path, result };
1016
+ }
1017
+ })(),
1018
+ complete: Promise.resolve(buildResponse<TRoute>(errorResults)),
1019
+ };
1020
+ }
1021
+
1022
+ const context = this.createExecutionContext(request);
1023
+ const streamConfig = request.batch ?? { strategy: "stream" };
1024
+
1025
+ return executor.getStreamingResponse<TRoute>(
1026
+ resolution.resolved,
1027
+ context,
1028
+ streamConfig
1029
+ );
1030
+ }
1031
+
1032
+ /**
1033
+ * The results of a route that did not resolve: an error for each leaf that failed, and
1034
+ * `SKIPPED` for every other leaf, also the leaves after a validation error. (Before, the leaves
1035
+ * after a validation error were missing: deep dive CORE-14.)
1036
+ */
1037
+ private resolutionFailure(resolution: RouteResolutionResult): Array<[ProcedurePath, ProcedureCallResult]> {
1038
+ const skipped = (path: ProcedurePath): ProcedureCallResult => ({
1039
+ success: false,
1040
+ error: { code: "SKIPPED", message: "Skipped due to other route errors", retryable: false, path },
1041
+ });
1042
+ const results: Array<[ProcedurePath, ProcedureCallResult]> = resolution.errors.map((error) => [
1043
+ error.path,
1044
+ {
1045
+ success: false,
1046
+ error: {
1047
+ code: error.type === "not_found" ? "NOT_FOUND" : "VALIDATION_ERROR",
1048
+ message: error.message,
1049
+ retryable: false,
1050
+ path: error.path,
1051
+ },
1052
+ },
1053
+ ]);
1054
+ for (const resolved of resolution.resolved) results.push([resolved.path, skipped(resolved.path)]);
1055
+ for (const path of resolution.skipped) results.push([path, skipped(path)]);
1056
+ return results;
1057
+ }
1058
+
1059
+ /**
1060
+ * Get the route resolver (lazy initialization).
1061
+ */
1062
+ private getRouteResolver(): RouteResolver {
1063
+ if (!this.routeResolver) {
1064
+ this.routeResolver = new RouteResolver(this.procedureRegistry);
1065
+ }
1066
+ return this.routeResolver;
1067
+ }
1068
+
1069
+ /**
1070
+ * Get the batch executor (lazy initialization).
1071
+ */
1072
+ private getBatchExecutor(): BatchExecutor {
1073
+ if (!this.batchExecutor) {
1074
+ this.batchExecutor = new BatchExecutor(this.executeProcedure.bind(this));
1075
+ }
1076
+ return this.batchExecutor;
1077
+ }
1078
+
1079
+ /**
1080
+ * Create execution context from call request.
1081
+ */
1082
+ private createExecutionContext<TRoute extends Route>(
1083
+ request: CallRequest<TRoute>
1084
+ ): ExecutionContext {
1085
+ // Merge context: parent chain -> client context -> middleware overrides. The override keys
1086
+ // become the keys that the middleware reads (deep dive CORE-14). No internal key goes into
1087
+ // the metadata: a handler sees it as ctx.metadata (deep dive CORE-10).
1088
+ const effectiveContext = mergeContext(
1089
+ this.getEffectiveContext() as object,
1090
+ toMiddlewareContext(request.middlewares)
1091
+ );
1092
+
1093
+ const context: ExecutionContext = {
1094
+ metadata: {
1095
+ ...this.defaultMetadata,
1096
+ ...effectiveContext,
1097
+ },
1098
+ };
1099
+
1100
+ // Only set signal if provided (exactOptionalPropertyTypes)
1101
+ if (request.signal) {
1102
+ context.signal = request.signal;
1103
+ }
1104
+
1105
+ return context;
1106
+ }
1107
+
1108
+ /**
1109
+ * Execute a single procedure call.
1110
+ * Used by BatchExecutor.
1111
+ *
1112
+ * The `out` config of the route leaf chooses the result (BUGS-2026-07 H8):
1113
+ * - sponge (the default): the value, or the last item of a stream (or `accumulate` of all items);
1114
+ * - stream: `data` is an AsyncIterable of the items. The procedure starts when the reader reads.
1115
+ * With `bufferSize`, that many items are read ahead of the reader;
1116
+ * - handlers: `progress` gets each item but the last, `complete` gets the last, `error` gets the error.
1117
+ *
1118
+ * A procedure with `outputMode: "batch"` returns an array: sponge gives the array, and stream
1119
+ * gives each element.
1120
+ */
1121
+ private async executeProcedure(
1122
+ resolved: ResolvedRoute,
1123
+ context: ExecutionContext
1124
+ ): Promise<ProcedureCallResult> {
1125
+ const { path, outputConfig } = resolved;
1126
+
1127
+ try {
1128
+ const items = this.routeItems(resolved, context);
1129
+ if (isStreamConfig(outputConfig)) {
1130
+ const elements = resolved.procedure.outputMode === "batch" ? batchElements(items) : items;
1131
+ return { success: true, data: readAhead(elements, outputConfig.bufferSize ?? 0) };
1132
+ }
1133
+ if (isHandlerConfig(outputConfig)) {
1134
+ return { success: true, data: await this.consumeWithHandlers(items, outputConfig, path) };
1135
+ }
1136
+ return { success: true, data: await this.sponge(items, outputConfig, path) };
1137
+ } catch (error) {
1138
+ return {
1139
+ success: false,
1140
+ error: {
1141
+ code: error instanceof ClientError || error instanceof InvocationError ? error.code : "EXECUTION_ERROR",
1142
+ message: error instanceof Error ? error.message : String(error),
1143
+ retryable: error instanceof ClientError ? error.retryable : false,
1144
+ path,
1145
+ },
1146
+ };
1147
+ }
1148
+ }
1149
+
1150
+ /**
1151
+ * The output items of a resolved route: from the local handler, or from the transport.
1152
+ */
1153
+ private routeItems(resolved: ResolvedRoute, context: ExecutionContext): AsyncGenerator<unknown, void, undefined> {
1154
+ const self = this;
1155
+ const { path, procedure, input } = resolved;
1156
+ return (async function* () {
1157
+ if (procedure.handler) {
1158
+ // The resolver validated the input already (not an asynchronous schema: see ResolvedRoute)
1159
+ const options = {
1160
+ ...self.invokeOptions({ metadata: context.metadata, signal: context.signal }),
1161
+ inputValidated: resolved.inputValidated !== false,
1162
+ };
1163
+ yield* outputItems(await invokeProcedure(procedure, input, options));
1164
+ return;
1165
+ }
1166
+ const callOptions: CallOptions<TContext> = { context: context.metadata as ClientContextInput<TContext> };
1167
+ if (context.signal) {
1168
+ callOptions.signal = context.signal;
1169
+ }
1170
+ yield* self.stream(self.pathToMethod(path), input, callOptions);
1171
+ })();
1172
+ }
1173
+
1174
+ /** The sponge mode: the last item, or `accumulate` of all items. */
1175
+ private async sponge(items: AsyncIterable<unknown>, config: OutputConfig, path: ProcedurePath): Promise<unknown> {
1176
+ const accumulate = "type" in config && config.type === "sponge" ? config.accumulate : undefined;
1177
+ const all: unknown[] = [];
1178
+ let last: { value: unknown } | undefined;
1179
+ for await (const item of items) {
1180
+ last = { value: item };
1181
+ if (accumulate) all.push(item);
1182
+ }
1183
+ if (!last) {
1184
+ throw new InvocationError("NO_OUTPUT", `Procedure gave no output: ${path.join(".")}`, path);
1185
+ }
1186
+ return accumulate ? accumulate(all.slice(0, -1), last.value) : last.value;
1187
+ }
1188
+
1189
+ /** The handlers mode: `progress` for each item but the last, then `complete`, or `error`. */
1190
+ private async consumeWithHandlers(
1191
+ items: AsyncIterable<unknown>,
1192
+ config: { progress?: HandlerCallback; complete?: HandlerCallback; error?: HandlerCallback<Error> },
1193
+ path: ProcedurePath
1194
+ ): Promise<unknown> {
1195
+ let previous: { value: unknown } | undefined;
1196
+ try {
1197
+ for await (const item of items) {
1198
+ if (previous) await this.deliver(config.progress, previous.value);
1199
+ previous = { value: item };
1200
+ }
1201
+ } catch (error) {
1202
+ await this.deliver(config.error, error instanceof Error ? error : new Error(String(error)));
1203
+ throw error;
1204
+ }
1205
+ if (!previous) {
1206
+ throw new InvocationError("NO_OUTPUT", `Procedure gave no output: ${path.join(".")}`, path);
1207
+ }
1208
+ await this.deliver(config.complete, previous.value);
1209
+ return previous.value;
1210
+ }
1211
+
1212
+ /** A handler callback gets the data: a function, or a procedure path (the data is its input). */
1213
+ private async deliver<T>(callback: HandlerCallback<T> | undefined, data: T): Promise<void> {
1214
+ if (callback === undefined) return;
1215
+ if (Array.isArray(callback)) {
1216
+ await this.execInternal(callback, data);
1217
+ return;
1218
+ }
1219
+ await callback(data);
1220
+ }
1221
+
1222
+ /**
1223
+ * Convert procedure path to Method object.
1224
+ */
1225
+ private pathToMethod(path: ProcedurePath): Method {
1226
+ // The one mapping of every host (deep dive architecture review 3.3)
1227
+ return pathToMethod(path);
1228
+ }
1229
+ }