@smthrs/gateway 0.34.0 → 1.0.0-rc.3

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 (605) hide show
  1. package/CHANGELOG.md +198 -0
  2. package/LICENSE +1 -1
  3. package/README.md +92 -0
  4. package/dist/cjs/Diagnosis.d.ts +275 -0
  5. package/dist/cjs/Diagnosis.d.ts.map +1 -0
  6. package/dist/cjs/Diagnosis.js +476 -0
  7. package/dist/cjs/Diagnosis.js.map +7 -0
  8. package/dist/cjs/EngineTrace.d.ts +76 -0
  9. package/dist/cjs/EngineTrace.d.ts.map +1 -0
  10. package/dist/cjs/EngineTrace.js +501 -0
  11. package/dist/cjs/EngineTrace.js.map +7 -0
  12. package/dist/cjs/GatewayError.d.ts +54 -0
  13. package/dist/cjs/GatewayError.d.ts.map +1 -0
  14. package/dist/cjs/GatewayError.js +51 -0
  15. package/dist/cjs/GatewayError.js.map +7 -0
  16. package/dist/cjs/GatewayProjection.d.ts +480 -0
  17. package/dist/cjs/GatewayProjection.d.ts.map +1 -0
  18. package/dist/cjs/GatewayProjection.js +462 -0
  19. package/dist/cjs/GatewayProjection.js.map +7 -0
  20. package/dist/cjs/GatewayRpcs.d.ts +1886 -0
  21. package/dist/cjs/GatewayRpcs.d.ts.map +1 -0
  22. package/dist/cjs/GatewayRpcs.js +121 -0
  23. package/dist/cjs/GatewayRpcs.js.map +7 -0
  24. package/dist/cjs/GatewaySchema.d.ts +3274 -0
  25. package/dist/cjs/GatewaySchema.d.ts.map +1 -0
  26. package/dist/cjs/GatewaySchema.js +141 -0
  27. package/dist/cjs/GatewaySchema.js.map +7 -0
  28. package/dist/cjs/GatewayServer.d.ts +427 -0
  29. package/dist/cjs/GatewayServer.d.ts.map +1 -0
  30. package/dist/cjs/GatewayServer.js +428 -0
  31. package/dist/cjs/GatewayServer.js.map +7 -0
  32. package/dist/cjs/HostBranchPresence.d.ts +12 -0
  33. package/dist/cjs/HostBranchPresence.d.ts.map +1 -0
  34. package/dist/cjs/HostBranchPresence.js +82 -0
  35. package/dist/cjs/HostBranchPresence.js.map +7 -0
  36. package/dist/cjs/Projections.d.ts +209 -0
  37. package/dist/cjs/Projections.d.ts.map +1 -0
  38. package/dist/cjs/Projections.js +906 -0
  39. package/dist/cjs/Projections.js.map +7 -0
  40. package/dist/cjs/RunDevTools.d.ts +181 -0
  41. package/dist/cjs/RunDevTools.d.ts.map +1 -0
  42. package/dist/cjs/RunDevTools.js +195 -0
  43. package/dist/cjs/RunDevTools.js.map +7 -0
  44. package/dist/cjs/RunHistory.d.ts +185 -0
  45. package/dist/cjs/RunHistory.d.ts.map +1 -0
  46. package/dist/cjs/RunHistory.js +68 -0
  47. package/dist/cjs/RunHistory.js.map +7 -0
  48. package/dist/cjs/RunTrace.d.ts +753 -0
  49. package/dist/cjs/RunTrace.d.ts.map +1 -0
  50. package/dist/cjs/RunTrace.js +1593 -0
  51. package/dist/cjs/RunTrace.js.map +7 -0
  52. package/dist/cjs/RuntimeBridge.d.ts +1386 -0
  53. package/dist/cjs/RuntimeBridge.d.ts.map +1 -0
  54. package/dist/cjs/RuntimeBridge.js +598 -0
  55. package/dist/cjs/RuntimeBridge.js.map +7 -0
  56. package/dist/cjs/bun/BunGateway.d.ts +20 -0
  57. package/dist/cjs/bun/BunGateway.d.ts.map +1 -0
  58. package/dist/cjs/bun/BunGateway.js +62 -0
  59. package/dist/cjs/bun/BunGateway.js.map +7 -0
  60. package/dist/cjs/index.d.ts +65 -0
  61. package/dist/cjs/index.d.ts.map +1 -0
  62. package/dist/cjs/index.js +59 -0
  63. package/dist/cjs/index.js.map +7 -0
  64. package/dist/cjs/internal/NativeGateway.d.ts +176 -0
  65. package/dist/cjs/internal/NativeGateway.d.ts.map +1 -0
  66. package/dist/cjs/internal/NativeGateway.js +187 -0
  67. package/dist/cjs/internal/NativeGateway.js.map +7 -0
  68. package/dist/cjs/internal/actionRenderings.d.ts +2 -0
  69. package/dist/cjs/internal/actionRenderings.d.ts.map +1 -0
  70. package/dist/cjs/internal/actionRenderings.js +224 -0
  71. package/dist/cjs/internal/actionRenderings.js.map +7 -0
  72. package/dist/cjs/internal/callEvents.d.ts +97 -0
  73. package/dist/cjs/internal/callEvents.d.ts.map +1 -0
  74. package/dist/cjs/internal/callEvents.js +169 -0
  75. package/dist/cjs/internal/callEvents.js.map +7 -0
  76. package/dist/cjs/internal/digestIndex.d.ts +31 -0
  77. package/dist/cjs/internal/digestIndex.d.ts.map +1 -0
  78. package/dist/cjs/internal/digestIndex.js +105 -0
  79. package/dist/cjs/internal/digestIndex.js.map +7 -0
  80. package/dist/cjs/internal/digestMemory.d.ts +19 -0
  81. package/dist/cjs/internal/digestMemory.d.ts.map +1 -0
  82. package/dist/cjs/internal/digestMemory.js +33 -0
  83. package/dist/cjs/internal/digestMemory.js.map +7 -0
  84. package/dist/cjs/internal/inspectLabels.d.ts +8 -0
  85. package/dist/cjs/internal/inspectLabels.d.ts.map +1 -0
  86. package/dist/cjs/internal/inspectLabels.js +29 -0
  87. package/dist/cjs/internal/inspectLabels.js.map +7 -0
  88. package/dist/cjs/internal/nativeResolution.d.ts +41 -0
  89. package/dist/cjs/internal/nativeResolution.d.ts.map +1 -0
  90. package/dist/cjs/internal/nativeResolution.js +62 -0
  91. package/dist/cjs/internal/nativeResolution.js.map +7 -0
  92. package/dist/cjs/internal/nodeEvents.d.ts +47 -0
  93. package/dist/cjs/internal/nodeEvents.d.ts.map +1 -0
  94. package/dist/cjs/internal/nodeEvents.js +60 -0
  95. package/dist/cjs/internal/nodeEvents.js.map +7 -0
  96. package/dist/cjs/node/NodeGateway.d.ts +16 -0
  97. package/dist/cjs/node/NodeGateway.d.ts.map +1 -0
  98. package/dist/cjs/node/NodeGateway.js +48 -0
  99. package/dist/cjs/node/NodeGateway.js.map +7 -0
  100. package/dist/cjs/package.json +1 -0
  101. package/dist/esm/Diagnosis.d.ts +275 -0
  102. package/dist/esm/Diagnosis.d.ts.map +1 -0
  103. package/dist/esm/Diagnosis.js +697 -0
  104. package/dist/esm/Diagnosis.js.map +1 -0
  105. package/dist/esm/EngineTrace.d.ts +76 -0
  106. package/dist/esm/EngineTrace.d.ts.map +1 -0
  107. package/dist/esm/EngineTrace.js +548 -0
  108. package/dist/esm/EngineTrace.js.map +1 -0
  109. package/dist/esm/GatewayError.d.ts +54 -0
  110. package/dist/esm/GatewayError.d.ts.map +1 -0
  111. package/dist/esm/GatewayError.js +60 -0
  112. package/dist/esm/GatewayError.js.map +1 -0
  113. package/dist/esm/GatewayProjection.d.ts +480 -0
  114. package/dist/esm/GatewayProjection.d.ts.map +1 -0
  115. package/dist/esm/GatewayProjection.js +792 -0
  116. package/dist/esm/GatewayProjection.js.map +1 -0
  117. package/dist/esm/GatewayRpcs.d.ts +1886 -0
  118. package/dist/esm/GatewayRpcs.d.ts.map +1 -0
  119. package/dist/esm/GatewayRpcs.js +145 -0
  120. package/dist/esm/GatewayRpcs.js.map +1 -0
  121. package/dist/esm/GatewaySchema.d.ts +3274 -0
  122. package/dist/esm/GatewaySchema.d.ts.map +1 -0
  123. package/dist/esm/GatewaySchema.js +244 -0
  124. package/dist/esm/GatewaySchema.js.map +1 -0
  125. package/dist/esm/GatewayServer.d.ts +427 -0
  126. package/dist/esm/GatewayServer.d.ts.map +1 -0
  127. package/dist/esm/GatewayServer.js +725 -0
  128. package/dist/esm/GatewayServer.js.map +1 -0
  129. package/dist/esm/HostBranchPresence.d.ts +12 -0
  130. package/dist/esm/HostBranchPresence.d.ts.map +1 -0
  131. package/dist/esm/HostBranchPresence.js +54 -0
  132. package/dist/esm/HostBranchPresence.js.map +1 -0
  133. package/dist/esm/Projections.d.ts +209 -0
  134. package/dist/esm/Projections.d.ts.map +1 -0
  135. package/dist/esm/Projections.js +1254 -0
  136. package/dist/esm/Projections.js.map +1 -0
  137. package/dist/esm/RunDevTools.d.ts +181 -0
  138. package/dist/esm/RunDevTools.d.ts.map +1 -0
  139. package/dist/esm/RunDevTools.js +281 -0
  140. package/dist/esm/RunDevTools.js.map +1 -0
  141. package/dist/esm/RunHistory.d.ts +185 -0
  142. package/dist/esm/RunHistory.d.ts.map +1 -0
  143. package/dist/esm/RunHistory.js +109 -0
  144. package/dist/esm/RunHistory.js.map +1 -0
  145. package/dist/esm/RunTrace.d.ts +753 -0
  146. package/dist/esm/RunTrace.d.ts.map +1 -0
  147. package/dist/esm/RunTrace.js +2105 -0
  148. package/dist/esm/RunTrace.js.map +1 -0
  149. package/dist/esm/RuntimeBridge.d.ts +1386 -0
  150. package/dist/esm/RuntimeBridge.d.ts.map +1 -0
  151. package/dist/esm/RuntimeBridge.js +659 -0
  152. package/dist/esm/RuntimeBridge.js.map +1 -0
  153. package/dist/esm/bun/BunGateway.d.ts +20 -0
  154. package/dist/esm/bun/BunGateway.d.ts.map +1 -0
  155. package/dist/esm/bun/BunGateway.js +32 -0
  156. package/dist/esm/bun/BunGateway.js.map +1 -0
  157. package/dist/esm/index.d.ts +65 -0
  158. package/dist/esm/index.d.ts.map +1 -0
  159. package/dist/esm/index.js +65 -0
  160. package/dist/esm/index.js.map +1 -0
  161. package/dist/esm/internal/NativeGateway.d.ts +176 -0
  162. package/dist/esm/internal/NativeGateway.d.ts.map +1 -0
  163. package/dist/esm/internal/NativeGateway.js +268 -0
  164. package/dist/esm/internal/NativeGateway.js.map +1 -0
  165. package/dist/esm/internal/actionRenderings.d.ts +2 -0
  166. package/dist/esm/internal/actionRenderings.d.ts.map +1 -0
  167. package/dist/esm/internal/actionRenderings.js +202 -0
  168. package/dist/esm/internal/actionRenderings.js.map +1 -0
  169. package/dist/esm/internal/callEvents.d.ts +97 -0
  170. package/dist/esm/internal/callEvents.d.ts.map +1 -0
  171. package/dist/esm/internal/callEvents.js +206 -0
  172. package/dist/esm/internal/callEvents.js.map +1 -0
  173. package/dist/esm/internal/digestIndex.d.ts +31 -0
  174. package/dist/esm/internal/digestIndex.d.ts.map +1 -0
  175. package/dist/esm/internal/digestIndex.js +87 -0
  176. package/dist/esm/internal/digestIndex.js.map +1 -0
  177. package/dist/esm/internal/digestMemory.d.ts +19 -0
  178. package/dist/esm/internal/digestMemory.d.ts.map +1 -0
  179. package/dist/esm/internal/digestMemory.js +23 -0
  180. package/dist/esm/internal/digestMemory.js.map +1 -0
  181. package/dist/esm/internal/inspectLabels.d.ts +8 -0
  182. package/dist/esm/internal/inspectLabels.d.ts.map +1 -0
  183. package/dist/esm/internal/inspectLabels.js +12 -0
  184. package/dist/esm/internal/inspectLabels.js.map +1 -0
  185. package/dist/esm/internal/nativeResolution.d.ts +41 -0
  186. package/dist/esm/internal/nativeResolution.d.ts.map +1 -0
  187. package/dist/esm/internal/nativeResolution.js +78 -0
  188. package/dist/esm/internal/nativeResolution.js.map +1 -0
  189. package/dist/esm/internal/nodeEvents.d.ts +47 -0
  190. package/dist/esm/internal/nodeEvents.d.ts.map +1 -0
  191. package/dist/esm/internal/nodeEvents.js +60 -0
  192. package/dist/esm/internal/nodeEvents.js.map +1 -0
  193. package/dist/esm/node/NodeGateway.d.ts +16 -0
  194. package/dist/esm/node/NodeGateway.d.ts.map +1 -0
  195. package/dist/esm/node/NodeGateway.js +13 -0
  196. package/dist/esm/node/NodeGateway.js.map +1 -0
  197. package/dist/vendor/adapters.json +2707 -0
  198. package/dist/vendor/bun/BunChildProcessSpawner.d.ts +7 -0
  199. package/dist/vendor/bun/BunChildProcessSpawner.js +14 -0
  200. package/dist/vendor/bun/BunClusterHttp.d.ts +83 -0
  201. package/dist/vendor/bun/BunClusterHttp.js +39 -0
  202. package/dist/vendor/bun/BunClusterSocket.d.ts +65 -0
  203. package/dist/vendor/bun/BunClusterSocket.js +22 -0
  204. package/dist/vendor/bun/BunCrypto.d.ts +10 -0
  205. package/dist/vendor/bun/BunCrypto.js +8 -0
  206. package/dist/vendor/bun/BunFileSystem.d.ts +10 -0
  207. package/dist/vendor/bun/BunFileSystem.js +9 -0
  208. package/dist/vendor/bun/BunHttpClient.d.ts +9 -0
  209. package/dist/vendor/bun/BunHttpClient.js +1 -0
  210. package/dist/vendor/bun/BunHttpPlatform.d.ts +10 -0
  211. package/dist/vendor/bun/BunHttpPlatform.js +11 -0
  212. package/dist/vendor/bun/BunHttpServer.d.ts +142 -0
  213. package/dist/vendor/bun/BunHttpServer.js +38 -0
  214. package/dist/vendor/bun/BunHttpServerRequest.d.ts +18 -0
  215. package/dist/vendor/bun/BunHttpServerRequest.js +7 -0
  216. package/dist/vendor/bun/BunMultipart.d.ts +31 -0
  217. package/dist/vendor/bun/BunMultipart.js +12 -0
  218. package/dist/vendor/bun/BunPath.d.ts +24 -0
  219. package/dist/vendor/bun/BunPath.js +12 -0
  220. package/dist/vendor/bun/BunRedis.d.ts +49 -0
  221. package/dist/vendor/bun/BunRedis.js +11 -0
  222. package/dist/vendor/bun/BunRuntime.d.ts +85 -0
  223. package/dist/vendor/bun/BunRuntime.js +8 -0
  224. package/dist/vendor/bun/BunServices.d.ts +34 -0
  225. package/dist/vendor/bun/BunServices.js +23 -0
  226. package/dist/vendor/bun/BunSink.d.ts +8 -0
  227. package/dist/vendor/bun/BunSink.js +12 -0
  228. package/dist/vendor/bun/BunSocket.d.ts +40 -0
  229. package/dist/vendor/bun/BunSocket.js +29 -0
  230. package/dist/vendor/bun/BunSocketServer.d.ts +8 -0
  231. package/dist/vendor/bun/BunSocketServer.js +21 -0
  232. package/dist/vendor/bun/BunStdio.d.ts +11 -0
  233. package/dist/vendor/bun/BunStdio.js +10 -0
  234. package/dist/vendor/bun/BunStream.d.ts +19 -0
  235. package/dist/vendor/bun/BunStream.js +30 -0
  236. package/dist/vendor/bun/BunTerminal.d.ts +21 -0
  237. package/dist/vendor/bun/BunTerminal.js +10 -0
  238. package/dist/vendor/bun/BunWorker.d.ts +20 -0
  239. package/dist/vendor/bun/BunWorker.js +9 -0
  240. package/dist/vendor/bun/BunWorkerRunner.d.ts +12 -0
  241. package/dist/vendor/bun/BunWorkerRunner.js +7 -0
  242. package/dist/vendor/bun/LICENSE +21 -0
  243. package/dist/vendor/bun/index.d.ts +92 -0
  244. package/dist/vendor/bun/index.js +107 -0
  245. package/dist/vendor/chunk-2GCOZTTW.js +48 -0
  246. package/dist/vendor/chunk-37CUR3PO.js +81 -0
  247. package/dist/vendor/chunk-3ARKKENZ.js +45 -0
  248. package/dist/vendor/chunk-3NV2UDBI.js +7 -0
  249. package/dist/vendor/chunk-3OSW7CT7.js +143 -0
  250. package/dist/vendor/chunk-62R63L74.js +62 -0
  251. package/dist/vendor/chunk-6AQLBC2I.js +118 -0
  252. package/dist/vendor/chunk-6C5H7S6B.js +18 -0
  253. package/dist/vendor/chunk-6DY5RBZD.js +85 -0
  254. package/dist/vendor/chunk-6UPBD47P.js +53 -0
  255. package/dist/vendor/chunk-AVVVN75Z.js +96 -0
  256. package/dist/vendor/chunk-B4DHEMBB.js +14 -0
  257. package/dist/vendor/chunk-BCK3NJOX.js +15 -0
  258. package/dist/vendor/chunk-BFBIHJ6X.js +0 -0
  259. package/dist/vendor/chunk-CES4OUM4.js +63 -0
  260. package/dist/vendor/chunk-D64L6YND.js +59 -0
  261. package/dist/vendor/chunk-DS2R6WOM.js +18 -0
  262. package/dist/vendor/chunk-DX4Z23DM.js +65 -0
  263. package/dist/vendor/chunk-DZ2VOUDP.js +564 -0
  264. package/dist/vendor/chunk-FOXN6JPJ.js +61 -0
  265. package/dist/vendor/chunk-FPQF7CR5.js +55 -0
  266. package/dist/vendor/chunk-FUTCTCEG.js +20 -0
  267. package/dist/vendor/chunk-GUPAV2YZ.js +18 -0
  268. package/dist/vendor/chunk-H2Z2Y4QH.js +70 -0
  269. package/dist/vendor/chunk-HAEDVSSM.js +129 -0
  270. package/dist/vendor/chunk-HY7BBL3K.js +93 -0
  271. package/dist/vendor/chunk-IFTTT6D5.js +31 -0
  272. package/dist/vendor/chunk-KQDSNB7M.js +26 -0
  273. package/dist/vendor/chunk-LIHLXXGQ.js +26 -0
  274. package/dist/vendor/chunk-LKCGQEE5.js +28 -0
  275. package/dist/vendor/chunk-MH2J3BYB.js +0 -0
  276. package/dist/vendor/chunk-ML2NAFH2.js +131 -0
  277. package/dist/vendor/chunk-MLFIZ5O2.js +0 -0
  278. package/dist/vendor/chunk-MLKGABMK.js +9 -0
  279. package/dist/vendor/chunk-MSCLEMYX.js +71 -0
  280. package/dist/vendor/chunk-OBWXQKVP.js +57 -0
  281. package/dist/vendor/chunk-QR557K66.js +20 -0
  282. package/dist/vendor/chunk-R4QUY7DH.js +18 -0
  283. package/dist/vendor/chunk-RGECXXJS.js +18 -0
  284. package/dist/vendor/chunk-TFY7W6D4.js +36 -0
  285. package/dist/vendor/chunk-TGPIVY4A.js +104 -0
  286. package/dist/vendor/chunk-TGXCX6W3.js +398 -0
  287. package/dist/vendor/chunk-TOHSFXMV.js +437 -0
  288. package/dist/vendor/chunk-UHIDPUFF.js +34 -0
  289. package/dist/vendor/chunk-ULT6CWUI.js +109 -0
  290. package/dist/vendor/chunk-UXBGYQR3.js +18 -0
  291. package/dist/vendor/chunk-V6LUGQ7O.js +21 -0
  292. package/dist/vendor/chunk-W4OASVX6.js +92 -0
  293. package/dist/vendor/chunk-WAII54GA.js +18 -0
  294. package/dist/vendor/chunk-WECQDT36.js +426 -0
  295. package/dist/vendor/chunk-WHKMOC7Z.js +28 -0
  296. package/dist/vendor/chunk-WVFOZ2UL.js +40 -0
  297. package/dist/vendor/chunk-X73E2UPI.js +18 -0
  298. package/dist/vendor/chunk-XCYARUII.js +63 -0
  299. package/dist/vendor/chunk-XFEVTDVD.js +34 -0
  300. package/dist/vendor/chunk-XFZZYSJ4.js +22 -0
  301. package/dist/vendor/chunk-XJWJXLXJ.js +18 -0
  302. package/dist/vendor/chunk-XY3Q62EO.js +18 -0
  303. package/dist/vendor/chunk-YDASSC75.js +394 -0
  304. package/dist/vendor/chunk-Z6C7SO5Z.js +507 -0
  305. package/dist/vendor/chunk-Z7QNPJEB.js +229 -0
  306. package/dist/vendor/chunk-Z7QPP4YH.js +249 -0
  307. package/dist/vendor/chunk-ZCHYLHJH.js +86 -0
  308. package/dist/vendor/chunk-ZIQVYVMA.js +22 -0
  309. package/dist/vendor/chunk-ZPIG2CUA.js +34 -0
  310. package/dist/vendor/cjs/bun/BunChildProcessSpawner.d.ts +7 -0
  311. package/dist/vendor/cjs/bun/BunChildProcessSpawner.js +1 -0
  312. package/dist/vendor/cjs/bun/BunClusterHttp.d.ts +83 -0
  313. package/dist/vendor/cjs/bun/BunClusterHttp.js +1 -0
  314. package/dist/vendor/cjs/bun/BunClusterSocket.d.ts +65 -0
  315. package/dist/vendor/cjs/bun/BunClusterSocket.js +1 -0
  316. package/dist/vendor/cjs/bun/BunCrypto.d.ts +10 -0
  317. package/dist/vendor/cjs/bun/BunCrypto.js +1 -0
  318. package/dist/vendor/cjs/bun/BunFileSystem.d.ts +10 -0
  319. package/dist/vendor/cjs/bun/BunFileSystem.js +1 -0
  320. package/dist/vendor/cjs/bun/BunHttpClient.d.ts +9 -0
  321. package/dist/vendor/cjs/bun/BunHttpClient.js +1 -0
  322. package/dist/vendor/cjs/bun/BunHttpPlatform.d.ts +10 -0
  323. package/dist/vendor/cjs/bun/BunHttpPlatform.js +1 -0
  324. package/dist/vendor/cjs/bun/BunHttpServer.d.ts +142 -0
  325. package/dist/vendor/cjs/bun/BunHttpServer.js +1 -0
  326. package/dist/vendor/cjs/bun/BunHttpServerRequest.d.ts +18 -0
  327. package/dist/vendor/cjs/bun/BunHttpServerRequest.js +1 -0
  328. package/dist/vendor/cjs/bun/BunMultipart.d.ts +31 -0
  329. package/dist/vendor/cjs/bun/BunMultipart.js +1 -0
  330. package/dist/vendor/cjs/bun/BunPath.d.ts +24 -0
  331. package/dist/vendor/cjs/bun/BunPath.js +1 -0
  332. package/dist/vendor/cjs/bun/BunRedis.d.ts +49 -0
  333. package/dist/vendor/cjs/bun/BunRedis.js +1 -0
  334. package/dist/vendor/cjs/bun/BunRuntime.d.ts +85 -0
  335. package/dist/vendor/cjs/bun/BunRuntime.js +1 -0
  336. package/dist/vendor/cjs/bun/BunServices.d.ts +34 -0
  337. package/dist/vendor/cjs/bun/BunServices.js +1 -0
  338. package/dist/vendor/cjs/bun/BunSink.d.ts +8 -0
  339. package/dist/vendor/cjs/bun/BunSink.js +1 -0
  340. package/dist/vendor/cjs/bun/BunSocket.d.ts +40 -0
  341. package/dist/vendor/cjs/bun/BunSocket.js +1 -0
  342. package/dist/vendor/cjs/bun/BunSocketServer.d.ts +8 -0
  343. package/dist/vendor/cjs/bun/BunSocketServer.js +1 -0
  344. package/dist/vendor/cjs/bun/BunStdio.d.ts +11 -0
  345. package/dist/vendor/cjs/bun/BunStdio.js +1 -0
  346. package/dist/vendor/cjs/bun/BunStream.d.ts +19 -0
  347. package/dist/vendor/cjs/bun/BunStream.js +1 -0
  348. package/dist/vendor/cjs/bun/BunTerminal.d.ts +21 -0
  349. package/dist/vendor/cjs/bun/BunTerminal.js +1 -0
  350. package/dist/vendor/cjs/bun/BunWorker.d.ts +20 -0
  351. package/dist/vendor/cjs/bun/BunWorker.js +1 -0
  352. package/dist/vendor/cjs/bun/BunWorkerRunner.d.ts +12 -0
  353. package/dist/vendor/cjs/bun/BunWorkerRunner.js +1 -0
  354. package/dist/vendor/cjs/bun/index.d.ts +92 -0
  355. package/dist/vendor/cjs/bun/index.js +1 -0
  356. package/dist/vendor/cjs/node/NodeChildProcessSpawner.d.ts +7 -0
  357. package/dist/vendor/cjs/node/NodeChildProcessSpawner.js +1 -0
  358. package/dist/vendor/cjs/node/NodeClusterHttp.d.ts +63 -0
  359. package/dist/vendor/cjs/node/NodeClusterHttp.js +1 -0
  360. package/dist/vendor/cjs/node/NodeClusterSocket.d.ts +79 -0
  361. package/dist/vendor/cjs/node/NodeClusterSocket.js +1 -0
  362. package/dist/vendor/cjs/node/NodeCrypto.d.ts +10 -0
  363. package/dist/vendor/cjs/node/NodeCrypto.js +1 -0
  364. package/dist/vendor/cjs/node/NodeFileSystem.d.ts +10 -0
  365. package/dist/vendor/cjs/node/NodeFileSystem.js +1 -0
  366. package/dist/vendor/cjs/node/NodeHttpClient.d.ts +179 -0
  367. package/dist/vendor/cjs/node/NodeHttpClient.js +1 -0
  368. package/dist/vendor/cjs/node/NodeHttpIncomingMessage.d.ts +62 -0
  369. package/dist/vendor/cjs/node/NodeHttpIncomingMessage.js +1 -0
  370. package/dist/vendor/cjs/node/NodeHttpPlatform.d.ts +36 -0
  371. package/dist/vendor/cjs/node/NodeHttpPlatform.js +1 -0
  372. package/dist/vendor/cjs/node/NodeHttpServer.d.ts +120 -0
  373. package/dist/vendor/cjs/node/NodeHttpServer.js +1 -0
  374. package/dist/vendor/cjs/node/NodeHttpServerRequest.d.ts +29 -0
  375. package/dist/vendor/cjs/node/NodeHttpServerRequest.js +1 -0
  376. package/dist/vendor/cjs/node/NodeMultipart.d.ts +46 -0
  377. package/dist/vendor/cjs/node/NodeMultipart.js +1 -0
  378. package/dist/vendor/cjs/node/NodeMultipartParser.d.ts +97 -0
  379. package/dist/vendor/cjs/node/NodeMultipartParser.js +1 -0
  380. package/dist/vendor/cjs/node/NodePath.d.ts +27 -0
  381. package/dist/vendor/cjs/node/NodePath.js +1 -0
  382. package/dist/vendor/cjs/node/NodeRedis.d.ts +74 -0
  383. package/dist/vendor/cjs/node/NodeRedis.js +1 -0
  384. package/dist/vendor/cjs/node/NodeRuntime.d.ts +85 -0
  385. package/dist/vendor/cjs/node/NodeRuntime.js +1 -0
  386. package/dist/vendor/cjs/node/NodeServices.d.ts +34 -0
  387. package/dist/vendor/cjs/node/NodeServices.js +1 -0
  388. package/dist/vendor/cjs/node/NodeSink.d.ts +8 -0
  389. package/dist/vendor/cjs/node/NodeSink.js +1 -0
  390. package/dist/vendor/cjs/node/NodeSocket.d.ts +38 -0
  391. package/dist/vendor/cjs/node/NodeSocket.js +1 -0
  392. package/dist/vendor/cjs/node/NodeSocketServer.d.ts +8 -0
  393. package/dist/vendor/cjs/node/NodeSocketServer.js +1 -0
  394. package/dist/vendor/cjs/node/NodeStdio.d.ts +11 -0
  395. package/dist/vendor/cjs/node/NodeStdio.js +1 -0
  396. package/dist/vendor/cjs/node/NodeStream.d.ts +8 -0
  397. package/dist/vendor/cjs/node/NodeStream.js +1 -0
  398. package/dist/vendor/cjs/node/NodeTerminal.d.ts +21 -0
  399. package/dist/vendor/cjs/node/NodeTerminal.js +1 -0
  400. package/dist/vendor/cjs/node/NodeWorker.d.ts +22 -0
  401. package/dist/vendor/cjs/node/NodeWorker.js +1 -0
  402. package/dist/vendor/cjs/node/NodeWorkerRunner.d.ts +12 -0
  403. package/dist/vendor/cjs/node/NodeWorkerRunner.js +1 -0
  404. package/dist/vendor/cjs/node/Undici.d.ts +28 -0
  405. package/dist/vendor/cjs/node/Undici.js +1 -0
  406. package/dist/vendor/cjs/node/index.d.ts +100 -0
  407. package/dist/vendor/cjs/node/index.js +1 -0
  408. package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.d.ts +57 -0
  409. package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.js +1 -0
  410. package/dist/vendor/cjs/node-shared/NodeClusterSocket.d.ts +22 -0
  411. package/dist/vendor/cjs/node-shared/NodeClusterSocket.js +1 -0
  412. package/dist/vendor/cjs/node-shared/NodeCrypto.d.ts +27 -0
  413. package/dist/vendor/cjs/node-shared/NodeCrypto.js +1 -0
  414. package/dist/vendor/cjs/node-shared/NodeFileSystem.d.ts +11 -0
  415. package/dist/vendor/cjs/node-shared/NodeFileSystem.js +1 -0
  416. package/dist/vendor/cjs/node-shared/NodeHttpCompression.d.ts +36 -0
  417. package/dist/vendor/cjs/node-shared/NodeHttpCompression.js +1 -0
  418. package/dist/vendor/cjs/node-shared/NodePath.d.ts +27 -0
  419. package/dist/vendor/cjs/node-shared/NodePath.js +1 -0
  420. package/dist/vendor/cjs/node-shared/NodeRuntime.d.ts +47 -0
  421. package/dist/vendor/cjs/node-shared/NodeRuntime.js +1 -0
  422. package/dist/vendor/cjs/node-shared/NodeSink.d.ts +69 -0
  423. package/dist/vendor/cjs/node-shared/NodeSink.js +1 -0
  424. package/dist/vendor/cjs/node-shared/NodeSocket.d.ts +134 -0
  425. package/dist/vendor/cjs/node-shared/NodeSocket.js +1 -0
  426. package/dist/vendor/cjs/node-shared/NodeSocketServer.d.ts +80 -0
  427. package/dist/vendor/cjs/node-shared/NodeSocketServer.js +1 -0
  428. package/dist/vendor/cjs/node-shared/NodeStdio.d.ts +12 -0
  429. package/dist/vendor/cjs/node-shared/NodeStdio.js +1 -0
  430. package/dist/vendor/cjs/node-shared/NodeStream.d.ts +179 -0
  431. package/dist/vendor/cjs/node-shared/NodeStream.js +1 -0
  432. package/dist/vendor/cjs/node-shared/NodeTerminal.d.ts +22 -0
  433. package/dist/vendor/cjs/node-shared/NodeTerminal.js +1 -0
  434. package/dist/vendor/cjs/node-shared/index.d.ts +56 -0
  435. package/dist/vendor/cjs/node-shared/index.js +1 -0
  436. package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
  437. package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.js +1 -0
  438. package/dist/vendor/cjs/node-shared/internal/utils.d.ts +2 -0
  439. package/dist/vendor/cjs/node-shared/internal/utils.js +1 -0
  440. package/dist/vendor/cjs/package.json +1 -0
  441. package/dist/vendor/cjs/platform-bun.d.ts +92 -0
  442. package/dist/vendor/cjs/platform-bun.js +1 -0
  443. package/dist/vendor/cjs/platform-node-shared.d.ts +56 -0
  444. package/dist/vendor/cjs/platform-node-shared.js +1 -0
  445. package/dist/vendor/cjs/platform-node.d.ts +100 -0
  446. package/dist/vendor/cjs/platform-node.js +1 -0
  447. package/dist/vendor/node/LICENSE +21 -0
  448. package/dist/vendor/node/NodeChildProcessSpawner.d.ts +7 -0
  449. package/dist/vendor/node/NodeChildProcessSpawner.js +14 -0
  450. package/dist/vendor/node/NodeClusterHttp.d.ts +63 -0
  451. package/dist/vendor/node/NodeClusterHttp.js +43 -0
  452. package/dist/vendor/node/NodeClusterSocket.d.ts +79 -0
  453. package/dist/vendor/node/NodeClusterSocket.js +30 -0
  454. package/dist/vendor/node/NodeCrypto.d.ts +10 -0
  455. package/dist/vendor/node/NodeCrypto.js +8 -0
  456. package/dist/vendor/node/NodeFileSystem.d.ts +10 -0
  457. package/dist/vendor/node/NodeFileSystem.js +9 -0
  458. package/dist/vendor/node/NodeHttpClient.d.ts +179 -0
  459. package/dist/vendor/node/NodeHttpClient.js +46 -0
  460. package/dist/vendor/node/NodeHttpIncomingMessage.d.ts +62 -0
  461. package/dist/vendor/node/NodeHttpIncomingMessage.js +10 -0
  462. package/dist/vendor/node/NodeHttpPlatform.d.ts +36 -0
  463. package/dist/vendor/node/NodeHttpPlatform.js +16 -0
  464. package/dist/vendor/node/NodeHttpServer.d.ts +120 -0
  465. package/dist/vendor/node/NodeHttpServer.js +46 -0
  466. package/dist/vendor/node/NodeHttpServerRequest.d.ts +29 -0
  467. package/dist/vendor/node/NodeHttpServerRequest.js +9 -0
  468. package/dist/vendor/node/NodeMultipart.d.ts +46 -0
  469. package/dist/vendor/node/NodeMultipart.js +15 -0
  470. package/dist/vendor/node/NodeMultipartParser.d.ts +97 -0
  471. package/dist/vendor/node/NodeMultipartParser.js +11 -0
  472. package/dist/vendor/node/NodePath.d.ts +27 -0
  473. package/dist/vendor/node/NodePath.js +12 -0
  474. package/dist/vendor/node/NodeRedis.d.ts +74 -0
  475. package/dist/vendor/node/NodeRedis.js +11 -0
  476. package/dist/vendor/node/NodeRuntime.d.ts +85 -0
  477. package/dist/vendor/node/NodeRuntime.js +8 -0
  478. package/dist/vendor/node/NodeServices.d.ts +34 -0
  479. package/dist/vendor/node/NodeServices.js +23 -0
  480. package/dist/vendor/node/NodeSink.d.ts +8 -0
  481. package/dist/vendor/node/NodeSink.js +12 -0
  482. package/dist/vendor/node/NodeSocket.d.ts +38 -0
  483. package/dist/vendor/node/NodeSocket.js +31 -0
  484. package/dist/vendor/node/NodeSocketServer.d.ts +8 -0
  485. package/dist/vendor/node/NodeSocketServer.js +21 -0
  486. package/dist/vendor/node/NodeStdio.d.ts +11 -0
  487. package/dist/vendor/node/NodeStdio.js +10 -0
  488. package/dist/vendor/node/NodeStream.d.ts +8 -0
  489. package/dist/vendor/node/NodeStream.js +27 -0
  490. package/dist/vendor/node/NodeTerminal.d.ts +21 -0
  491. package/dist/vendor/node/NodeTerminal.js +10 -0
  492. package/dist/vendor/node/NodeWorker.d.ts +22 -0
  493. package/dist/vendor/node/NodeWorker.js +9 -0
  494. package/dist/vendor/node/NodeWorkerRunner.d.ts +12 -0
  495. package/dist/vendor/node/NodeWorkerRunner.js +7 -0
  496. package/dist/vendor/node/Undici.d.ts +28 -0
  497. package/dist/vendor/node/Undici.js +9 -0
  498. package/dist/vendor/node/index.d.ts +100 -0
  499. package/dist/vendor/node/index.js +115 -0
  500. package/dist/vendor/node-shared/LICENSE +21 -0
  501. package/dist/vendor/node-shared/NodeChildProcessSpawner.d.ts +57 -0
  502. package/dist/vendor/node-shared/NodeChildProcessSpawner.js +13 -0
  503. package/dist/vendor/node-shared/NodeClusterSocket.d.ts +22 -0
  504. package/dist/vendor/node-shared/NodeClusterSocket.js +11 -0
  505. package/dist/vendor/node-shared/NodeCrypto.d.ts +27 -0
  506. package/dist/vendor/node-shared/NodeCrypto.js +9 -0
  507. package/dist/vendor/node-shared/NodeFileSystem.d.ts +11 -0
  508. package/dist/vendor/node-shared/NodeFileSystem.js +8 -0
  509. package/dist/vendor/node-shared/NodeHttpCompression.d.ts +36 -0
  510. package/dist/vendor/node-shared/NodeHttpCompression.js +13 -0
  511. package/dist/vendor/node-shared/NodePath.d.ts +27 -0
  512. package/dist/vendor/node-shared/NodePath.js +11 -0
  513. package/dist/vendor/node-shared/NodeRuntime.d.ts +47 -0
  514. package/dist/vendor/node-shared/NodeRuntime.js +7 -0
  515. package/dist/vendor/node-shared/NodeSink.d.ts +69 -0
  516. package/dist/vendor/node-shared/NodeSink.js +11 -0
  517. package/dist/vendor/node-shared/NodeSocket.d.ts +134 -0
  518. package/dist/vendor/node-shared/NodeSocket.js +23 -0
  519. package/dist/vendor/node-shared/NodeSocketServer.d.ts +80 -0
  520. package/dist/vendor/node-shared/NodeSocketServer.js +20 -0
  521. package/dist/vendor/node-shared/NodeStdio.d.ts +12 -0
  522. package/dist/vendor/node-shared/NodeStdio.js +9 -0
  523. package/dist/vendor/node-shared/NodeStream.d.ts +179 -0
  524. package/dist/vendor/node-shared/NodeStream.js +26 -0
  525. package/dist/vendor/node-shared/NodeTerminal.d.ts +22 -0
  526. package/dist/vendor/node-shared/NodeTerminal.js +9 -0
  527. package/dist/vendor/node-shared/index.d.ts +56 -0
  528. package/dist/vendor/node-shared/index.js +58 -0
  529. package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
  530. package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.js +7 -0
  531. package/dist/vendor/node-shared/internal/utils.d.ts +2 -0
  532. package/dist/vendor/node-shared/internal/utils.js +7 -0
  533. package/dist/vendor/platform-bun.d.ts +92 -0
  534. package/dist/vendor/platform-bun.js +107 -0
  535. package/dist/vendor/platform-node-shared.d.ts +56 -0
  536. package/dist/vendor/platform-node-shared.js +58 -0
  537. package/dist/vendor/platform-node.d.ts +100 -0
  538. package/dist/vendor/platform-node.js +115 -0
  539. package/docs/README.md +158 -0
  540. package/docs/api.md +601 -0
  541. package/docs/concepts/projections.md +250 -0
  542. package/docs/concepts/subscriptions.md +204 -0
  543. package/docs/concepts/trust-boundary.md +256 -0
  544. package/docs/guides/diagnose-a-run.md +115 -0
  545. package/docs/guides/follow-a-run.md +150 -0
  546. package/docs/guides/host-the-gateway.md +153 -0
  547. package/docs/guides/read-a-projection.md +138 -0
  548. package/docs/guides/serve-beyond-loopback.md +166 -0
  549. package/docs/guides/submit-an-approval.md +187 -0
  550. package/docs/guides/testing.md +148 -0
  551. package/docs/installation.md +89 -0
  552. package/docs/quickstart.md +200 -0
  553. package/docs/troubleshooting.md +355 -0
  554. package/package.json +264 -32
  555. package/src/Diagnosis.ts +892 -0
  556. package/src/EngineTrace.ts +605 -0
  557. package/src/GatewayError.ts +71 -0
  558. package/src/GatewayProjection.ts +948 -0
  559. package/src/GatewayRpcs.ts +179 -0
  560. package/src/GatewaySchema.ts +516 -0
  561. package/src/GatewayServer.ts +932 -0
  562. package/src/HostBranchPresence.ts +72 -0
  563. package/src/Projections.ts +1735 -0
  564. package/src/RunDevTools.ts +394 -0
  565. package/src/RunHistory.ts +174 -0
  566. package/src/RunTrace.ts +2793 -0
  567. package/src/RuntimeBridge.ts +835 -0
  568. package/src/bun/BunGateway.ts +52 -0
  569. package/src/index.ts +77 -0
  570. package/src/internal/NativeGateway.ts +360 -0
  571. package/src/internal/actionRenderings.ts +201 -0
  572. package/src/internal/callEvents.ts +257 -0
  573. package/src/internal/digestIndex.ts +134 -0
  574. package/src/internal/digestMemory.ts +27 -0
  575. package/src/internal/inspectLabels.ts +13 -0
  576. package/src/internal/nativeResolution.ts +103 -0
  577. package/src/internal/nodeEvents.ts +100 -0
  578. package/src/node/NodeGateway.ts +30 -0
  579. package/openapi.yaml +0 -29182
  580. package/src/README.md +0 -39
  581. package/src/api/README.md +0 -23
  582. package/src/api/apiCollectionNames.js +0 -10
  583. package/src/api/index.d.ts +0 -126
  584. package/src/api/index.js +0 -14
  585. package/src/api/normalizeApiRow.js +0 -36
  586. package/src/api/serializeAccountRow.js +0 -10
  587. package/src/api/serializeApprovalRow.js +0 -53
  588. package/src/api/serializeComparisonScoreRow.js +0 -18
  589. package/src/api/serializeCronRow.js +0 -30
  590. package/src/api/serializeDocRow.js +0 -20
  591. package/src/api/serializeMemoryFactRow.js +0 -21
  592. package/src/api/serializePromptRow.js +0 -10
  593. package/src/api/serializeRunEventRow.js +0 -28
  594. package/src/api/serializeRunRow.js +0 -61
  595. package/src/api/serializeScoreDetailRow.js +0 -25
  596. package/src/api/serializeScoreRow.js +0 -26
  597. package/src/api/serializeTicketRow.js +0 -20
  598. package/src/api/serializeWorkflowRow.js +0 -10
  599. package/src/auth/scopes.d.ts +0 -19
  600. package/src/auth/scopes.js +0 -164
  601. package/src/index.d.ts +0 -316
  602. package/src/index.js +0 -108
  603. package/src/rpc/gatewayRpcTypes.ts +0 -183
  604. package/src/rpc/index.d.ts +0 -221
  605. package/src/rpc/index.js +0 -2431
@@ -0,0 +1,725 @@
1
+ /**
2
+ * The assembled workspace gateway: one HTTP surface carrying the control
3
+ * plane, the sync read path, the served projections, and a health probe.
4
+ *
5
+ * Mounts:
6
+ *
7
+ * | Path | Protocol | Serves |
8
+ * | --- | --- | --- |
9
+ * | `POST /rpc` | RPC over HTTP | `@smthrs/control` `ControlRpcs` |
10
+ * | `/rpc/ws` | RPC over WebSocket | `ControlRpcs`, including a kept-alive `Watch` |
11
+ * | `POST /projections` | RPC over HTTP | `GatewayRpcs` |
12
+ * | `/projections/ws` | RPC over WebSocket | `GatewayRpcs`, including `Projection.Subscribe` |
13
+ * | `POST /sync` | RPC over HTTP | `@smthrs/sync` `SyncRpcs` |
14
+ * | `/sync/ws` | RPC over WebSocket | `SyncRpcs` |
15
+ * | `GET /health` | JSON | `GatewaySchema.GatewayHealth` plus the package version |
16
+ * | `POST /auth/ticket` | JSON | A single-use {@link Ticket} that opens one protected socket |
17
+ *
18
+ * `/health` is deliberately unauthenticated: a supervisor decides whether to
19
+ * keep or replace a gateway process by asking which workspace it belongs to,
20
+ * and a probe that needed a credential could not answer that question about a
21
+ * gateway it did not start. The response carries identity only: the
22
+ * workspace hash, the gateway id, the protocol version, and the package
23
+ * version. It never carries a token, a run, or a path.
24
+ *
25
+ * @since 1.0.0
26
+ */
27
+ import { Control } from "@smthrs/control/Control";
28
+ import * as ControlError from "@smthrs/control/ControlError";
29
+ import * as ControlExecutor from "@smthrs/control/ControlExecutor";
30
+ import { ControlPrincipal } from "@smthrs/control/ControlRpcs";
31
+ import * as ControlServer from "@smthrs/control/ControlServer";
32
+ import { SyncRpcs } from "@smthrs/sync/SyncRpcs";
33
+ import * as SyncServer from "@smthrs/sync/SyncServer";
34
+ import { Effect, Layer, Option, Schema, Stream } from "effect";
35
+ import * as ByteSize from "effect/ByteSize";
36
+ import { Headers, HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
37
+ import { RpcSerialization, RpcServer } from "effect/unstable/rpc";
38
+ import { GatewayError, settingRefusal } from "./GatewayError.js";
39
+ import { GatewayRpcs } from "./GatewayRpcs.js";
40
+ import * as GatewaySchema from "./GatewaySchema.js";
41
+ import * as HostBranchPresence from "./HostBranchPresence.js";
42
+ import { heartbeatIntervalMillis, Projections } from "./Projections.js";
43
+ import * as RunHistory from "./RunHistory.js";
44
+ import * as RuntimeBridge from "./RuntimeBridge.js";
45
+ /**
46
+ * What `GET /health` answers: the `GatewaySchema.GatewayHealth` identity plus
47
+ * the version of the package serving it.
48
+ *
49
+ * @since 1.0.0
50
+ * @category models
51
+ */
52
+ export const Health = Schema.Struct({
53
+ ...GatewaySchema.GatewayHealth.fields,
54
+ version: Schema.String,
55
+ runtimeBridge: Schema.optional(RuntimeBridge.Identity)
56
+ });
57
+ const encodeHealth = Schema.encodeUnknownSync(Health);
58
+ /**
59
+ * Mounts the unauthenticated health probe.
60
+ *
61
+ * @param health the identity this process serves under
62
+ * @since 1.0.0
63
+ * @category layers
64
+ */
65
+ export const layerHealth = (health) => HttpRouter.add("GET", "/health", HttpServerResponse.jsonUnsafe(encodeHealth(health)));
66
+ /**
67
+ * The gateway's own RPC handlers over the read path and the control plane.
68
+ *
69
+ * @since 1.0.0
70
+ * @category layers
71
+ */
72
+ export const layerHandlers = GatewayRpcs.toLayer(Effect.gen(function* () {
73
+ const projections = yield* Projections;
74
+ const control = yield* Control;
75
+ // Only a host that owns the project's stores can fork or verify its runs.
76
+ const history = yield* Effect.serviceOption(RunHistory.RunHistory);
77
+ const historyHost = Option.match(history, {
78
+ onNone: () => Effect.fail(new ControlError.Unavailable({ feature: "run history", ticket: "smithers#3242" })),
79
+ onSome: Effect.succeed
80
+ });
81
+ // Forking writes a durable run and verifying drives the project's flow
82
+ // code, so neither is an anonymous loopback read.
83
+ const operator = Effect.gen(function* () {
84
+ const principal = yield* ControlPrincipal;
85
+ if (principal.id === "loopback" && principal.kind === "anonymous") {
86
+ return yield* new ControlError.Unauthorized({ message: "An operator credential is required" });
87
+ }
88
+ });
89
+ return GatewayRpcs.of({
90
+ "Projection.Snapshot": Effect.fn("Gateway.snapshot")(({ selector, after }) => projections.snapshot(selector, after), Effect.tapCause(ControlServer.logDefect)),
91
+ "Projection.Subscribe": ({ after, selector }) => Stream.tapCause(projections.subscribe(selector, after), ControlServer.logDefect),
92
+ /* One operator command. Control owns the atomic decision plus durable
93
+ * resume delegation; the gateway is only a transport adapter. */
94
+ "Approval.Submit": Effect.fn("Gateway.submitApproval")((input) => Effect.gen(function* () {
95
+ // The identity the shared `ControlAuth` middleware authenticated, as
96
+ // `ControlServer` stamps it on `Approve` and `Deny`. This mount is
97
+ // the same decision under a different payload, so it is answerable
98
+ // to the same operator, and a decision journaled under the
99
+ // composition's default operator names the wrong one.
100
+ const principal = yield* ControlPrincipal;
101
+ // Answering a human wait uses signal rather than the approval policy.
102
+ // Do not let that alternate mutation path bypass loopback authentication.
103
+ if (principal.id === "loopback" && principal.kind === "anonymous") {
104
+ return yield* new ControlError.Unauthorized({ message: "An operator credential is required" });
105
+ }
106
+ const payload = {
107
+ target: input.target,
108
+ scope: input.scope,
109
+ idempotencyKey: input.idempotencyKey,
110
+ principal
111
+ };
112
+ // A gate that asked a question is answered, not granted, and the
113
+ // PAYLOAD says which kind it is: a human wait carries its durable
114
+ // wait token as the target's digest, and nothing else does. Reading
115
+ // it here rather than trusting the client to have sent `answer` is
116
+ // the difference between a clear refusal and the one an operator
117
+ // actually saw — a client that forgot the answer fell through to
118
+ // `Control.approve`, which looked for a registered approval token,
119
+ // found none, and reported `/control/RunNotFound` for a run that was
120
+ // listed, rendered, and waiting (workspace 4bb93306, run-1).
121
+ //
122
+ // `target.runId` is the run the person opened and `wait.name` the
123
+ // wait point's own name; `Control.signal` routes the pair into the
124
+ // run tree, to whichever execution is holding it.
125
+ const wait = ControlExecutor.answerableWait(input.target);
126
+ if (wait !== undefined && input.target._tag === "Node") {
127
+ // Neither half of a grant answers a question. A denial has nowhere
128
+ // to go — the run is parked on a value, and refusing to supply one
129
+ // leaves it parked until its own attempt budget or deadline ends
130
+ // it — and an approval with no value supplies none.
131
+ if (input.decision === "deny") {
132
+ return yield* new ControlError.InvalidInput({
133
+ issue: `decision: "${wait.name}" asks a question, which is answered rather than denied`
134
+ });
135
+ }
136
+ if (input.answer === undefined) {
137
+ return yield* new ControlError.InvalidInput({
138
+ issue: `answer: "${wait.name}" asks a question, so a decision alone does not answer it`
139
+ });
140
+ }
141
+ const decision = yield* control.signal({
142
+ runId: input.target.runId,
143
+ signal: { name: wait.name, payload: input.answer },
144
+ idempotencyKey: input.idempotencyKey,
145
+ principal
146
+ });
147
+ return { decision };
148
+ }
149
+ const decision = input.decision === "approve"
150
+ ? yield* control.approve(payload)
151
+ : yield* control.deny(payload);
152
+ return { decision };
153
+ }), Effect.tapCause(ControlServer.logDefect)),
154
+ "Run.Fork": Effect.fn("Gateway.fork")((input) => Effect.andThen(operator, Effect.flatMap(historyHost, (host) => host.fork(input))), Effect.tapCause(ControlServer.logDefect)),
155
+ "Run.Verify": Effect.fn("Gateway.verify")((input) => Effect.andThen(operator, Effect.flatMap(historyHost, (host) => host.verify(input))), Effect.tapCause(ControlServer.logDefect))
156
+ });
157
+ }));
158
+ /**
159
+ * The kind a `Watch` keepalive carries.
160
+ *
161
+ * `ControlRpcs.Watch` answers `ControlSchema.ControlEvent` and has no frame of
162
+ * its own for a keepalive, so the gateway publishes one as an event whose kind
163
+ * no emitter uses. A fold that does not know the kind ignores it, which is
164
+ * what every fold in this package and in `@smthrs/cli` `Forensics` already
165
+ * does with an unknown kind.
166
+ *
167
+ * @since 1.0.0
168
+ * @category models
169
+ */
170
+ export const watchHeartbeatKind = "control.gateway.heartbeat";
171
+ /**
172
+ * Merges a keepalive into a followed `Watch` stream.
173
+ *
174
+ * A followed stream is silent while a run is thinking, and a relay cuts an
175
+ * idle tunnel at 600 s. The Effect RPC client
176
+ * sends its own `Ping` every 5 s, but a non-Effect consumer behind a relay
177
+ * sends nothing, so the keepalive has to come from the server.
178
+ *
179
+ * The keepalive repeats the last delivered sequence and run-scoped cursor,
180
+ * including an expansion offset, so it cannot advance or rewind a checkpoint.
181
+ * It carries the watched run id so a client routing by run keeps routing.
182
+ * A snapshot read (`follow: false`) is left alone: it has to end.
183
+ */
184
+ const keptAlive = (millis, filter, events) => {
185
+ if (filter.follow === false)
186
+ return events;
187
+ let cursor = filter.afterCursor ??
188
+ (filter.afterSequence === undefined ? undefined : { sequence: filter.afterSequence });
189
+ let sequence = cursor?.sequence ?? 0;
190
+ const tracked = Stream.map(events, (event) => {
191
+ sequence = event.sequence;
192
+ cursor = event.cursor ?? { sequence };
193
+ return event;
194
+ });
195
+ const beats = Stream.tick(millis).pipe(Stream.drop(1), Stream.mapEffect(() => Effect.map(Effect.clockWith((clock) => clock.currentTimeMillis), (occurredAt) => ({
196
+ sequence,
197
+ ...(filter.runId === undefined || cursor === undefined ? {} : { cursor }),
198
+ kind: watchHeartbeatKind,
199
+ ...(filter.runId === undefined ? {} : { runId: filter.runId }),
200
+ occurredAt,
201
+ payload: null
202
+ }))));
203
+ return Stream.merge(tracked, beats, { haltStrategy: "left" });
204
+ };
205
+ /**
206
+ * The control service the `/rpc` mounts read through: the ambient one, with
207
+ * the keepalive merged into `watch`.
208
+ *
209
+ * Wrapping the service rather than re-declaring the handlers keeps
210
+ * `@smthrs/control` `ControlServer` the single definition of what every
211
+ * procedure does, including the principal it stamps on every mutation that
212
+ * records who asked. Only `watch` behaves differently, and only in what it
213
+ * adds.
214
+ *
215
+ * @since 1.0.0
216
+ * @category layers
217
+ */
218
+ export const layerKeepAlive = (millis = heartbeatIntervalMillis) => Layer.effect(Control)(Effect.map(Control, (control) => Control.of({ ...control, watch: (filter) => keptAlive(millis, filter, control.watch(filter)) })));
219
+ /**
220
+ * The read path the `/projections` mounts serve through: the ambient one, with
221
+ * a followed subscription's keepalive re-timed to the bind's cadence.
222
+ *
223
+ * `Projections.make` already merges a `heartbeat` frame at the cadence it was
224
+ * built with. A host that supplies `Projections.layer` and sets the cadence at
225
+ * the bind expects one option to govern both keepalives, so this replaces the
226
+ * service's beats with beats at the bind's cadence rather than adding a second
227
+ * channel. Snapshot reads are left alone: they have to end.
228
+ *
229
+ * @param millis how often an idle followed subscription emits a keepalive
230
+ * @since 1.0.0
231
+ * @category layers
232
+ */
233
+ export const layerProjectionsKeepAlive = (millis) => Layer.effect(Projections)(Effect.map(Projections, (projections) => Projections.of({
234
+ ...projections,
235
+ subscribe: (selector, after) => keptAliveSubscription(millis, projections.subscribe(selector, after))
236
+ })));
237
+ /** Replaces a subscription's keepalive channel with one at the given cadence. */
238
+ const keptAliveSubscription = (millis, frames) => {
239
+ // The first tick is dropped for the same reason `Projections` drops it: an
240
+ // immediate keepalive would arrive before the snapshot it keeps alive.
241
+ const beats = Stream.tick(millis).pipe(Stream.drop(1), Stream.mapEffect(() => Effect.map(Effect.clockWith((clock) => clock.currentTimeMillis), (atMs) => ({ _tag: "heartbeat", atMs }))));
242
+ return Stream.merge(Stream.filter(frames, (frame) => frame._tag !== "heartbeat"), beats, { haltStrategy: "left" });
243
+ };
244
+ /**
245
+ * Mounts the control plane on `POST /rpc` and `/rpc/ws`, with the keepalive.
246
+ *
247
+ * @param millis how often an idle followed watch emits one, defaulting to
248
+ * `Projections.heartbeatIntervalMillis`
249
+ * @since 1.0.0
250
+ * @category layers
251
+ */
252
+ export const layerControlHttp = (millis) => ControlServer.layerHttp.pipe(Layer.provide(layerKeepAlive(millis)));
253
+ const gateway = RpcServer.layer(GatewayRpcs, { disableFatalDefects: true });
254
+ const sync = RpcServer.layer(SyncRpcs, { disableFatalDefects: true });
255
+ /**
256
+ * Mounts the gateway's projections on `POST /projections` and
257
+ * `/projections/ws`.
258
+ *
259
+ * Both protocols are mounted together because a client reads a snapshot over
260
+ * the request/response path and follows deltas over the socket, and pointing
261
+ * those at two different servers would let them disagree.
262
+ *
263
+ * @since 1.0.0
264
+ * @category layers
265
+ */
266
+ export const layerProjectionsHttp = Layer.mergeAll(gateway.pipe(Layer.provide(layerHandlers), Layer.provideMerge(RpcServer.layerProtocolHttp({ path: "/projections" })), Layer.fresh), gateway.pipe(Layer.provide(layerHandlers), Layer.provideMerge(RpcServer.layerProtocolWebsocket({ path: "/projections/ws" })), Layer.fresh));
267
+ /**
268
+ * Mounts the sync read path on `POST /sync` and `/sync/ws`.
269
+ *
270
+ * @since 1.0.0
271
+ * @category layers
272
+ */
273
+ export const layerSyncHttp = Layer.mergeAll(sync.pipe(Layer.provide(SyncServer.layerHandlers), Layer.provideMerge(RpcServer.layerProtocolHttp({ path: "/sync" })), Layer.fresh), sync.pipe(Layer.provide(SyncServer.layerHandlers), Layer.provideMerge(RpcServer.layerProtocolWebsocket({ path: "/sync/ws" })), Layer.fresh));
274
+ /**
275
+ * The POST mounts that carry RPC request messages and nothing else.
276
+ *
277
+ * @since 1.0.0
278
+ * @category constants
279
+ */
280
+ export const rpcPaths = ["/rpc", "/projections", "/sync", "/branch"];
281
+ /**
282
+ * POST mounts whose request bodies are bounded before their handlers read.
283
+ *
284
+ * @since 1.0.0
285
+ * @category constants
286
+ */
287
+ export const boundedPostPaths = [
288
+ ...rpcPaths,
289
+ "/runtime/v1/command",
290
+ "/runtime/v1/observe"
291
+ ];
292
+ /**
293
+ * RPC paths whose upgrade or request must pass edge authentication.
294
+ *
295
+ * `POST /rpc` is deliberately not one of them. The control mount authenticates
296
+ * in band through `@smthrs/control` `ControlRpcs.ControlAuth`, whose declared
297
+ * error is `ControlError.Unauthorized`, and that typed control error is the
298
+ * refusal the control plane publishes: "Missing, malformed, empty, and
299
+ * incorrect credentials all return the same typed `Unauthorized` control
300
+ * error" (`packages/smithers/gateway/docs/guides/serve-beyond-loopback.md`). An edge 401 answered
301
+ * ahead of the mount, and `ControlClient` filters a non-2xx status, so every
302
+ * refusal reached a caller as a `TransportError`, the one error class
303
+ * `@smthrs/control` reserves for a request that failed *before* a declared
304
+ * control response reached it. It also made the gateway refuse a call
305
+ * differently from `NodeControl.layerServer` hosting the very same
306
+ * `ControlRpcs`. The body limit below still applies to `/rpc`, so an
307
+ * unauthenticated caller buys one bounded body read and nothing else.
308
+ *
309
+ * The `/rpc/ws` upgrade stays here. A socket is a resource the server holds
310
+ * open, the RPC middleware can only refuse frames on a socket that already
311
+ * exists, and a refused handshake has no RPC channel to answer a typed error
312
+ * on, so its refusal is a transport fact either way.
313
+ *
314
+ * @category constants
315
+ * @since 1.0.0
316
+ */
317
+ export const protectedPaths = [
318
+ "/projections",
319
+ "/branch",
320
+ "/sync",
321
+ "/rpc/ws",
322
+ "/projections/ws",
323
+ "/sync/ws",
324
+ "/runtime/v1/command",
325
+ "/runtime/v1/observe"
326
+ ];
327
+ /**
328
+ * The mount a request target reaches, spelled the way {@link rpcPaths} and
329
+ * {@link protectedPaths} spell it.
330
+ *
331
+ * The guard runs before the router and has to reach the router's verdict, or
332
+ * an alias walks past the credential check and the body limit and is answered
333
+ * by the mount anyway. Measured against `HttpRouter` on this tree, all of
334
+ * `/%72pc`, `/rpc;transport-parameter`, `/rpc/`, `//rpc`, `///rpc`, `/rpc//`,
335
+ * `/RPC`, `/./rpc`, and `/foo/../rpc` reach the `/rpc` handler, while
336
+ * `/rpc%2f`, `/rpc%3Bp`, `/%2frpc`, and `/rpc%20` do not. This is not only
337
+ * about crafted aliases: `@smthrs/control` `ControlClient`'s HTTP protocol
338
+ * posts every call to `/rpc/`, so a literal comparison skipped the body limit
339
+ * on the path the product's own client uses.
340
+ *
341
+ * Each segment is therefore taken without its `;` parameter, empty segments are
342
+ * dropped, and what is left is decoded with `decodeURI` and compared without
343
+ * regard to case. `decodeURI` is the decoder rather than `decodeURIComponent`
344
+ * because it leaves a reserved character encoded, which is what keeps
345
+ * `/rpc%2f` a different path here exactly as it is to the router. An invalid
346
+ * escape is left as written, since it names no mount either way.
347
+ *
348
+ * Dot segments are resolved by `URL` before the split. The normalization errs
349
+ * toward matching: a spelling this resolves to a mount that the router then
350
+ * refuses is answered 401 rather than 404, which costs an unauthenticated
351
+ * caller nothing it was entitled to.
352
+ *
353
+ * @param url the request target, origin-relative or absolute
354
+ * @since 1.0.0
355
+ * @category constructors
356
+ */
357
+ export const routedPath = (url) => {
358
+ // An empty leading segment is a protocol-relative URL to `URL`, so `//rpc`
359
+ // would parse as the host `rpc` and lose the path entirely. Anchoring an
360
+ // origin-relative target on the origin keeps every segment. An absolute
361
+ // target that does not parse at all names no mount, so it is compared as
362
+ // written and reaches the router as the unknown route it is.
363
+ const target = url.startsWith("/") ? `http://gateway.invalid${url}` : url;
364
+ const parsed = URL.parse(target, "http://gateway.invalid");
365
+ if (parsed === null)
366
+ return url;
367
+ const segments = [];
368
+ for (const segment of parsed.pathname.split("/")) {
369
+ const parameter = segment.indexOf(";");
370
+ const named = parameter < 0 ? segment : segment.slice(0, parameter);
371
+ if (named === "")
372
+ continue;
373
+ try {
374
+ segments.push(decodeURI(named));
375
+ }
376
+ catch {
377
+ segments.push(named);
378
+ }
379
+ }
380
+ return `/${segments.join("/")}`.toLowerCase();
381
+ };
382
+ /**
383
+ * The mount that exchanges a bearer credential for a WebSocket {@link Ticket}.
384
+ *
385
+ * @since 1.0.0
386
+ * @category constants
387
+ */
388
+ export const ticketPath = "/auth/ticket";
389
+ /**
390
+ * The protected socket mounts a {@link Ticket} opens.
391
+ *
392
+ * @since 1.0.0
393
+ * @category constants
394
+ */
395
+ export const ticketPaths = ["/rpc/ws", "/projections/ws", "/sync/ws"];
396
+ /**
397
+ * How long an unredeemed {@link Ticket} stays valid (thirty seconds).
398
+ *
399
+ * @since 1.0.0
400
+ * @category constants
401
+ */
402
+ export const defaultTicketMillis = 30_000;
403
+ /** Outstanding tickets kept at once; the oldest is dropped past this. */
404
+ const maxOutstandingTickets = 1024;
405
+ /**
406
+ * What `POST /auth/ticket` answers.
407
+ *
408
+ * A browser `WebSocket` cannot set an `Authorization` header, so a browser
409
+ * client first posts its bearer to `/auth/ticket`, then opens a protected
410
+ * socket as `<mount>?ticket=<ticket>` within `expiresInMs`. The first upgrade
411
+ * that presents the ticket consumes it, whether or not the upgrade completes;
412
+ * a replay or a late one is refused 401. The socket then runs under the
413
+ * bearer the ticket was issued for, so every frame authenticates as it would
414
+ * with the header.
415
+ *
416
+ * @since 1.0.0
417
+ * @category models
418
+ */
419
+ export const Ticket = Schema.Struct({
420
+ ticket: Schema.String,
421
+ expiresInMs: Schema.Number
422
+ });
423
+ const encodeTicket = Schema.encodeUnknownSync(Ticket);
424
+ /** 256 random bits, hex-encoded so a query string carries them unescaped. */
425
+ const newTicket = () => Array.from(crypto.getRandomValues(new Uint8Array(32)), (byte) => byte.toString(16).padStart(2, "0")).join("");
426
+ /** The `ticket` query parameter of a request target, when it has one. */
427
+ const presentedTicket = (url) => {
428
+ const parsed = URL.parse(url, "http://gateway.invalid");
429
+ const ticket = parsed?.searchParams.get("ticket");
430
+ return ticket === null || ticket === undefined || ticket === "" ? undefined : ticket;
431
+ };
432
+ /**
433
+ * Default maximum request body accepted by an RPC mount (one MiB).
434
+ *
435
+ * @category constants
436
+ * @since 1.0.0
437
+ */
438
+ export const defaultMaxRequestBodyBytes = 1024 * 1024;
439
+ const encodeGatewayError = Schema.encodeUnknownSync(GatewayError);
440
+ /** Host parsing stays strict so URL normalization cannot admit a rebinding name. */
441
+ const requestAuthority = (host) => {
442
+ if (host === undefined || !/^(?:[a-zA-Z0-9.-]+|\[[a-fA-F0-9:]+\])(?::[0-9]+)?$/.test(host))
443
+ return undefined;
444
+ const parsed = URL.parse(`http://${host}`);
445
+ return parsed === null ? undefined : parsed;
446
+ };
447
+ const browserRequestRefusal = (headers, allowedHosts, loopbackOnly) => {
448
+ const authority = requestAuthority(headers.host);
449
+ if (authority === undefined || !allowedHosts.includes(authority.hostname) ||
450
+ (loopbackOnly && !loopbackHost.test(headers.host)))
451
+ return { error: invalidHostRequest(), status: 421 };
452
+ const origin = headers.origin;
453
+ // CLI clients do not send Origin. Browsers must prove they came from this
454
+ // exact authority, including the port, on HTTP requests AND WS upgrades.
455
+ if (origin === undefined)
456
+ return undefined;
457
+ const parsed = URL.parse(origin);
458
+ return parsed !== null && (parsed.protocol === "http:" || parsed.protocol === "https:") &&
459
+ parsed.origin === origin && parsed.host === authority.host
460
+ ? undefined
461
+ : { error: invalidOriginRequest(), status: 403 };
462
+ };
463
+ /** One refusal on the wire: the typed error, under the status it answers. */
464
+ const refuse = (error, status) => HttpServerResponse.jsonUnsafe(encodeGatewayError(error), { status });
465
+ const malformedRequest = (path) => new GatewayError({ code: "malformed_request", message: `POST ${path} carries no RPC request message` });
466
+ const unauthorizedRequest = () => new GatewayError({ code: "unauthorized", message: "A valid bearer credential is required" });
467
+ const invalidHostRequest = () => new GatewayError({ code: "invalid_host", message: "This gateway does not allow the supplied Host value" });
468
+ const invalidOriginRequest = () => new GatewayError({ code: "invalid_origin", message: "The browser Origin must match an allowed gateway Host" });
469
+ const requestTooLarge = (path, maxBytes) => new GatewayError({
470
+ code: "request_too_large",
471
+ message: `POST ${path} exceeds the ${maxBytes}-byte request limit`
472
+ });
473
+ /** The message `@effect/platform-node-shared` `NodeStream` gives a size overflow. */
474
+ const maxBytesExceeded = "maxBytes exceeded";
475
+ /**
476
+ * The names that mean this machine only, as a bind address is spelled.
477
+ *
478
+ * This is a list of spellings a person types, not a subnet test: `127.0.0.2`
479
+ * is loopback to the kernel and is not on it. The Node host's
480
+ * `isLoopbackHost`, the Host-header names below, and the ingress regex all
481
+ * derive from this one list so widening it is one edit.
482
+ *
483
+ * @since 1.0.0
484
+ * @category constants
485
+ */
486
+ export const loopbackHostNames = ["127.0.0.1", "localhost", "::1"];
487
+ /**
488
+ * {@link loopbackHostNames} as a Host header spells them: an IPv6 address is
489
+ * bracketed as a URL authority. This is the default `allowedHosts`.
490
+ *
491
+ * @since 1.0.0
492
+ * @category constants
493
+ */
494
+ export const loopbackHostHeaderNames = loopbackHostNames.map((name) => name.includes(":") ? `[${name}]` : name);
495
+ const escapeRegExp = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
496
+ const loopbackHost = new RegExp(`^(?:${loopbackHostHeaderNames.map(escapeRegExp).join("|")})(?::\\d{1,5})?$`, "i");
497
+ /**
498
+ * Whether a failed request-body read hit the configured size limit rather than
499
+ * failing for another reason.
500
+ *
501
+ * `@effect/platform-node` raises the limit as an `HttpServerError` whose
502
+ * `reason` is a `RequestParseError` carrying the `Error("maxBytes exceeded")`
503
+ * that `@effect/platform-node-shared` `NodeStream.toString` throws
504
+ * (`NodeHttpIncomingMessage.text` passes `MaxBodySize` in as `maxBytes`, and
505
+ * `NodeHttpServer`'s `ServerRequestImpl` wraps whatever it throws). Nothing on
506
+ * the wire distinguishes it otherwise, so the check is that exact shape and a
507
+ * version bump of those packages is the thing to re-read it against.
508
+ *
509
+ * Every other read failure, a transport reset among them, is not a size
510
+ * overflow. Answering 413 for all of them told a client to shrink a request
511
+ * that was never too big.
512
+ *
513
+ * @param error the failure a body read produced
514
+ * @since 1.0.0
515
+ * @category predicates
516
+ */
517
+ export const exceededBodyLimit = (error) => {
518
+ const reason = typeof error === "object" && error !== null
519
+ ? error.reason
520
+ : undefined;
521
+ const cause = typeof reason === "object" && reason !== null
522
+ ? reason.cause
523
+ : undefined;
524
+ return cause instanceof Error && cause.message === maxBytesExceeded;
525
+ };
526
+ /**
527
+ * The refusal a failed request-body read earns, and the status it answers
528
+ * under.
529
+ *
530
+ * A body over the limit is 413 `request_too_large`. Every other read failure,
531
+ * a truncated body or a reset transport among them, is 400
532
+ * `malformed_request`: the request cannot be retried smaller, because its size
533
+ * was never the problem.
534
+ *
535
+ * @param path the mount the request was made to
536
+ * @param maxBytes the configured limit
537
+ * @param error the failure the body read produced
538
+ * @since 1.0.0
539
+ * @category constructors
540
+ */
541
+ export const bodyRefusal = (path, maxBytes, error) => exceededBodyLimit(error)
542
+ ? { error: requestTooLarge(path, maxBytes), status: 413 }
543
+ : {
544
+ error: new GatewayError({
545
+ code: "malformed_request",
546
+ message: `POST ${path} carries a body the server could not read`
547
+ }),
548
+ status: 400
549
+ };
550
+ /**
551
+ * Whether a request body carries at least one RPC message the server can act
552
+ * on.
553
+ *
554
+ * The transport's own parser answers, not a second reading of the wire
555
+ * format: whatever `RpcSerialization` the host composed decodes the body, and
556
+ * the answer is no only when that decode throws or yields no tagged message.
557
+ * A body naming a procedure that does not exist is a yes — that is an
558
+ * RPC-level defect the protocol itself reports.
559
+ *
560
+ * A binary framing is always a yes. Its body is not text, so there is nothing
561
+ * to read here, and the mount owns it.
562
+ *
563
+ * @since 1.0.0
564
+ * @category predicates
565
+ */
566
+ export const carriesRpcRequest = (serialization, body) => {
567
+ if (!serialization.contentType.includes("json"))
568
+ return true;
569
+ try {
570
+ const decoded = serialization.makeUnsafe().decode(body);
571
+ return decoded.length > 0 && decoded.every((message) => typeof message === "object" && message !== null &&
572
+ typeof message._tag === "string");
573
+ }
574
+ catch {
575
+ return false;
576
+ }
577
+ };
578
+ /**
579
+ * Enforces local Host/Origin policy and edge authentication before reading a
580
+ * body or upgrading a socket, then validates RPC body size and framing.
581
+ *
582
+ * `effect/unstable/rpc` hands every decoded message to the server loop, and a
583
+ * body that decodes to something else — `{}`, `[]`, prose, nothing at all —
584
+ * reached it as a message with no tag and died there, so the gateway answered
585
+ * `500 Internal Server Error` with an empty body (release validation). That is the
586
+ * wrong half of the contract twice over: it tells an operator the gateway
587
+ * broke, and it tells a client to retry a request that can never succeed.
588
+ *
589
+ * The body reader is cached per request, so reading the body here does not
590
+ * consume the body the mount reads. It is read through the reader the mount
591
+ * uses, `text` under a JSON serialization and `arrayBuffer` under a binary
592
+ * one, so the bytes the mount decodes are the bytes the client sent.
593
+ *
594
+ * @since 1.0.0
595
+ * @category layers
596
+ */
597
+ export const layerIngress = (options = {}) => {
598
+ const refusal = settingRefusal("The gateway request body limit", options.maxRequestBodyBytes) ??
599
+ settingRefusal("The gateway ticket lifetime", options.ticketMillis);
600
+ if (refusal !== undefined)
601
+ return Layer.effectDiscard(Effect.fail(refusal));
602
+ const maxBytes = options.maxRequestBodyBytes ?? defaultMaxRequestBodyBytes;
603
+ const allowedHosts = options.allowedHosts ?? loopbackHostHeaderNames;
604
+ const ticketMillis = options.ticketMillis ?? defaultTicketMillis;
605
+ return HttpRouter.middleware(Effect.gen(function* () {
606
+ const serialization = yield* RpcSerialization.RpcSerialization;
607
+ const binary = !serialization.contentType.includes("json");
608
+ /** Outstanding tickets: the Authorization header each was issued under, and when it lapses. */
609
+ const tickets = new Map();
610
+ const issue = (authorization, now) => {
611
+ for (const [ticket, entry] of tickets) {
612
+ if (entry.expiresAt <= now)
613
+ tickets.delete(ticket);
614
+ }
615
+ if (tickets.size >= maxOutstandingTickets)
616
+ tickets.delete(tickets.keys().next().value);
617
+ const ticket = newTicket();
618
+ tickets.set(ticket, { authorization, expiresAt: now + ticketMillis });
619
+ return { ticket, expiresInMs: ticketMillis };
620
+ };
621
+ // Lookup and delete run without yielding, so of two upgrades presenting
622
+ // one ticket exactly one gets its header.
623
+ const redeem = (url, now) => {
624
+ const ticket = presentedTicket(url);
625
+ const entry = ticket === undefined ? undefined : tickets.get(ticket);
626
+ if (entry === undefined)
627
+ return undefined;
628
+ tickets.delete(ticket);
629
+ return entry.expiresAt > now ? entry.authorization : undefined;
630
+ };
631
+ return (httpEffect) => Effect.gen(function* () {
632
+ const request = yield* HttpServerRequest.HttpServerRequest;
633
+ const browserRefusal = browserRequestRefusal(request.headers, allowedHosts, options.loopbackOnly === true);
634
+ if (browserRefusal !== undefined)
635
+ return refuse(browserRefusal.error, browserRefusal.status);
636
+ const path = routedPath(request.url);
637
+ if (path === ticketPath && request.method === "POST" && options.authorize !== undefined) {
638
+ const authorization = request.headers.authorization;
639
+ if (authorization === undefined || !(yield* options.authorize(request.headers, path))) {
640
+ return refuse(unauthorizedRequest(), 401);
641
+ }
642
+ const now = yield* Effect.clockWith((clock) => clock.currentTimeMillis);
643
+ return HttpServerResponse.jsonUnsafe(encodeTicket(issue(authorization, now)), {
644
+ headers: { "cache-control": "no-store" }
645
+ });
646
+ }
647
+ if (protectedPaths.includes(path) && options.authorize !== undefined) {
648
+ const authorized = yield* options.authorize(request.headers, path);
649
+ if (!authorized) {
650
+ const now = yield* Effect.clockWith((clock) => clock.currentTimeMillis);
651
+ const authorization = ticketPaths.includes(path) ? redeem(request.url, now) : undefined;
652
+ if (authorization === undefined)
653
+ return refuse(unauthorizedRequest(), 401);
654
+ // A ticket stands for the credential it was issued under, which
655
+ // may not reach every mount a ticket can open.
656
+ const headers = Headers.set(request.headers, "authorization", authorization);
657
+ if (!(yield* options.authorize(headers, path)))
658
+ return refuse(unauthorizedRequest(), 401);
659
+ // The socket protocol stamps the upgrade's headers on every
660
+ // frame, so the redeemed bearer authenticates each one.
661
+ return yield* Effect.provideService(httpEffect, HttpServerRequest.HttpServerRequest, request.modify({ headers }));
662
+ }
663
+ }
664
+ if (request.method !== "POST" || !boundedPostPaths.includes(path))
665
+ return yield* httpEffect;
666
+ // A declared length is a hint that saves reading a body already
667
+ // known to be too big. It is never trusted the other way: a body
668
+ // that declares less than it sends is still measured by the read,
669
+ // and a chunked body declares nothing at all.
670
+ const declaredLength = Number(request.headers["content-length"]);
671
+ if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
672
+ return refuse(requestTooLarge(path, maxBytes), 413);
673
+ }
674
+ // The body is read through the reader the mount will use. The Node
675
+ // adapter caches whichever reader ran first and derives the other
676
+ // from it, so a text read here would hand a binary mount a UTF-8
677
+ // re-encoding of its MessagePack bytes, with every invalid sequence
678
+ // replaced. A binary body is bounded here and framed by the mount.
679
+ const read = yield* (binary ? Effect.as(request.arrayBuffer, undefined) : request.text).pipe(Effect.provideService(HttpServerRequest.MaxBodySize, ByteSize.bytes(maxBytes)), Effect.match({
680
+ onFailure: (error) => ({
681
+ body: undefined,
682
+ error
683
+ }),
684
+ onSuccess: (body) => ({ body, error: undefined })
685
+ }));
686
+ if (read.error !== undefined) {
687
+ const answer = bodyRefusal(path, maxBytes, read.error);
688
+ return refuse(answer.error, answer.status);
689
+ }
690
+ if (read.body === undefined)
691
+ return yield* httpEffect;
692
+ return !rpcPaths.includes(path) || carriesRpcRequest(serialization, read.body)
693
+ ? yield* httpEffect
694
+ : refuse(malformedRequest(path), 400);
695
+ });
696
+ }), { global: true });
697
+ };
698
+ /**
699
+ * The whole gateway surface, as one application layer a host serves.
700
+ *
701
+ * The caller supplies the transport serialization, the authentication
702
+ * middleware for both RPC groups, and the services the mounts read through
703
+ * (`Control`, `Projections`, `SyncServer`). `@smthrs/gateway/node/NodeGateway`
704
+ * is the Node host that binds this to a socket.
705
+ *
706
+ * A keepalive cadence or a body limit that is not a positive safe integer is
707
+ * refused here, before anything binds, through the layer's typed
708
+ * `GatewayError` channel.
709
+ *
710
+ * @param health the identity `GET /health` answers with
711
+ * @param options the keepalive cadence and the ingress policy
712
+ * @since 1.0.0
713
+ * @category layers
714
+ */
715
+ export const layer = (health, options = {}) => {
716
+ const refusal = settingRefusal("The gateway keepalive cadence", options.heartbeatMillis);
717
+ if (refusal !== undefined)
718
+ return Layer.effectDiscard(Effect.fail(refusal));
719
+ return Layer.mergeAll(layerControlHttp(options.heartbeatMillis), options.heartbeatMillis === undefined
720
+ ? layerProjectionsHttp
721
+ : layerProjectionsHttp.pipe(Layer.provide(layerProjectionsKeepAlive(options.heartbeatMillis))), layerSyncHttp, layerHealth(health), ...(options.runtimeBridge === undefined
722
+ ? []
723
+ : [RuntimeBridge.layer(options.runtimeBridge), HostBranchPresence.layer(options.runtimeBridge)]), layerIngress(options.ingress));
724
+ };
725
+ //# sourceMappingURL=GatewayServer.js.map