threadforge 0.1.1 → 0.2.1

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 (358) hide show
  1. package/README.md +52 -20
  2. package/bin/forge.js +2 -1058
  3. package/bin/host-commands.d.ts +2 -0
  4. package/bin/host-commands.d.ts.map +1 -0
  5. package/bin/host-commands.js +7 -8
  6. package/bin/platform-commands.d.ts +2 -0
  7. package/bin/platform-commands.d.ts.map +1 -0
  8. package/bin/platform-commands.js +118 -36
  9. package/dist/cli/base-command.d.ts +12 -0
  10. package/dist/cli/base-command.d.ts.map +1 -0
  11. package/dist/cli/base-command.js +25 -0
  12. package/dist/cli/base-command.js.map +1 -0
  13. package/dist/cli/commands/build.d.ts +10 -0
  14. package/dist/cli/commands/build.d.ts.map +1 -0
  15. package/dist/cli/commands/build.js +110 -0
  16. package/dist/cli/commands/build.js.map +1 -0
  17. package/dist/cli/commands/deploy.d.ts +12 -0
  18. package/dist/cli/commands/deploy.d.ts.map +1 -0
  19. package/dist/cli/commands/deploy.js +143 -0
  20. package/dist/cli/commands/deploy.js.map +1 -0
  21. package/dist/cli/commands/dev.d.ts +10 -0
  22. package/dist/cli/commands/dev.d.ts.map +1 -0
  23. package/dist/cli/commands/dev.js +138 -0
  24. package/dist/cli/commands/dev.js.map +1 -0
  25. package/dist/cli/commands/generate.d.ts +10 -0
  26. package/dist/cli/commands/generate.d.ts.map +1 -0
  27. package/dist/cli/commands/generate.js +76 -0
  28. package/dist/cli/commands/generate.js.map +1 -0
  29. package/dist/cli/commands/host.d.ts +8 -0
  30. package/dist/cli/commands/host.d.ts.map +1 -0
  31. package/dist/cli/commands/host.js +20 -0
  32. package/dist/cli/commands/host.js.map +1 -0
  33. package/dist/cli/commands/init.d.ts +16 -0
  34. package/dist/cli/commands/init.d.ts.map +1 -0
  35. package/dist/cli/commands/init.js +246 -0
  36. package/dist/cli/commands/init.js.map +1 -0
  37. package/dist/cli/commands/platform.d.ts +8 -0
  38. package/dist/cli/commands/platform.d.ts.map +1 -0
  39. package/dist/cli/commands/platform.js +20 -0
  40. package/dist/cli/commands/platform.js.map +1 -0
  41. package/dist/cli/commands/restart.d.ts +8 -0
  42. package/dist/cli/commands/restart.d.ts.map +1 -0
  43. package/dist/cli/commands/restart.js +13 -0
  44. package/dist/cli/commands/restart.js.map +1 -0
  45. package/dist/cli/commands/scaffold/frontend.d.ts +10 -0
  46. package/dist/cli/commands/scaffold/frontend.d.ts.map +1 -0
  47. package/dist/cli/commands/scaffold/frontend.js +130 -0
  48. package/dist/cli/commands/scaffold/frontend.js.map +1 -0
  49. package/dist/cli/commands/scaffold/react.d.ts +7 -0
  50. package/dist/cli/commands/scaffold/react.d.ts.map +1 -0
  51. package/dist/cli/commands/scaffold/react.js +12 -0
  52. package/dist/cli/commands/scaffold/react.js.map +1 -0
  53. package/dist/cli/commands/scale.d.ts +8 -0
  54. package/dist/cli/commands/scale.d.ts.map +1 -0
  55. package/dist/cli/commands/scale.js +13 -0
  56. package/dist/cli/commands/scale.js.map +1 -0
  57. package/dist/cli/commands/start.d.ts +10 -0
  58. package/dist/cli/commands/start.d.ts.map +1 -0
  59. package/dist/cli/commands/start.js +71 -0
  60. package/dist/cli/commands/start.js.map +1 -0
  61. package/dist/cli/commands/status.d.ts +11 -0
  62. package/dist/cli/commands/status.d.ts.map +1 -0
  63. package/dist/cli/commands/status.js +60 -0
  64. package/dist/cli/commands/status.js.map +1 -0
  65. package/dist/cli/commands/stop.d.ts +10 -0
  66. package/dist/cli/commands/stop.d.ts.map +1 -0
  67. package/dist/cli/commands/stop.js +89 -0
  68. package/dist/cli/commands/stop.js.map +1 -0
  69. package/dist/cli/util/config-discovery.d.ts +8 -0
  70. package/dist/cli/util/config-discovery.d.ts.map +1 -0
  71. package/dist/cli/util/config-discovery.js +70 -0
  72. package/dist/cli/util/config-discovery.js.map +1 -0
  73. package/dist/cli/util/config-patcher.d.ts +17 -0
  74. package/dist/cli/util/config-patcher.d.ts.map +1 -0
  75. package/dist/cli/util/config-patcher.js +439 -0
  76. package/dist/cli/util/config-patcher.js.map +1 -0
  77. package/dist/cli/util/frontend-dev.d.ts +8 -0
  78. package/dist/cli/util/frontend-dev.d.ts.map +1 -0
  79. package/dist/cli/util/frontend-dev.js +117 -0
  80. package/dist/cli/util/frontend-dev.js.map +1 -0
  81. package/dist/cli/util/process.d.ts +5 -0
  82. package/dist/cli/util/process.d.ts.map +1 -0
  83. package/dist/cli/util/process.js +17 -0
  84. package/dist/cli/util/process.js.map +1 -0
  85. package/dist/cli/util/templates.d.ts +10 -0
  86. package/dist/cli/util/templates.d.ts.map +1 -0
  87. package/dist/cli/util/templates.js +157 -0
  88. package/dist/cli/util/templates.js.map +1 -0
  89. package/dist/core/AlertSink.d.ts +83 -0
  90. package/dist/core/AlertSink.d.ts.map +1 -0
  91. package/dist/core/AlertSink.js +126 -0
  92. package/dist/core/AlertSink.js.map +1 -0
  93. package/dist/core/DirectMessageBus.d.ts +88 -0
  94. package/dist/core/DirectMessageBus.d.ts.map +1 -0
  95. package/dist/core/DirectMessageBus.js +352 -0
  96. package/dist/core/DirectMessageBus.js.map +1 -0
  97. package/dist/core/EndpointResolver.d.ts +111 -0
  98. package/dist/core/EndpointResolver.d.ts.map +1 -0
  99. package/dist/core/EndpointResolver.js +336 -0
  100. package/dist/core/EndpointResolver.js.map +1 -0
  101. package/dist/core/ForgeContext.d.ts +221 -0
  102. package/dist/core/ForgeContext.d.ts.map +1 -0
  103. package/dist/core/ForgeContext.js +1169 -0
  104. package/dist/core/ForgeContext.js.map +1 -0
  105. package/dist/core/ForgeEndpoints.d.ts +71 -0
  106. package/dist/core/ForgeEndpoints.d.ts.map +1 -0
  107. package/dist/core/ForgeEndpoints.js +442 -0
  108. package/dist/core/ForgeEndpoints.js.map +1 -0
  109. package/dist/core/ForgeHost.d.ts +82 -0
  110. package/dist/core/ForgeHost.d.ts.map +1 -0
  111. package/dist/core/ForgeHost.js +107 -0
  112. package/dist/core/ForgeHost.js.map +1 -0
  113. package/dist/core/ForgePlatform.d.ts +96 -0
  114. package/dist/core/ForgePlatform.d.ts.map +1 -0
  115. package/dist/core/ForgePlatform.js +136 -0
  116. package/dist/core/ForgePlatform.js.map +1 -0
  117. package/dist/core/ForgeWebSocket.d.ts +56 -0
  118. package/dist/core/ForgeWebSocket.d.ts.map +1 -0
  119. package/dist/core/ForgeWebSocket.js +415 -0
  120. package/dist/core/ForgeWebSocket.js.map +1 -0
  121. package/dist/core/Ingress.d.ts +329 -0
  122. package/dist/core/Ingress.d.ts.map +1 -0
  123. package/dist/core/Ingress.js +694 -0
  124. package/dist/core/Ingress.js.map +1 -0
  125. package/dist/core/Interceptors.d.ts +134 -0
  126. package/dist/core/Interceptors.d.ts.map +1 -0
  127. package/dist/core/Interceptors.js +416 -0
  128. package/dist/core/Interceptors.js.map +1 -0
  129. package/dist/core/Logger.d.ts +20 -0
  130. package/dist/core/Logger.d.ts.map +1 -0
  131. package/dist/core/Logger.js +77 -0
  132. package/dist/core/Logger.js.map +1 -0
  133. package/dist/core/MessageBus.d.ts +15 -0
  134. package/dist/core/MessageBus.d.ts.map +1 -0
  135. package/dist/core/MessageBus.js +18 -0
  136. package/dist/core/MessageBus.js.map +1 -0
  137. package/dist/core/Prometheus.d.ts +80 -0
  138. package/dist/core/Prometheus.d.ts.map +1 -0
  139. package/dist/core/Prometheus.js +332 -0
  140. package/dist/core/Prometheus.js.map +1 -0
  141. package/dist/core/RequestContext.d.ts +214 -0
  142. package/dist/core/RequestContext.d.ts.map +1 -0
  143. package/dist/core/RequestContext.js +556 -0
  144. package/dist/core/RequestContext.js.map +1 -0
  145. package/dist/core/Router.d.ts +45 -0
  146. package/dist/core/Router.d.ts.map +1 -0
  147. package/dist/core/Router.js +285 -0
  148. package/dist/core/Router.js.map +1 -0
  149. package/dist/core/RoutingStrategy.d.ts +116 -0
  150. package/dist/core/RoutingStrategy.d.ts.map +1 -0
  151. package/dist/core/RoutingStrategy.js +306 -0
  152. package/dist/core/RoutingStrategy.js.map +1 -0
  153. package/dist/core/RpcConfig.d.ts +72 -0
  154. package/dist/core/RpcConfig.d.ts.map +1 -0
  155. package/dist/core/RpcConfig.js +127 -0
  156. package/dist/core/RpcConfig.js.map +1 -0
  157. package/dist/core/SignatureCache.d.ts +81 -0
  158. package/dist/core/SignatureCache.d.ts.map +1 -0
  159. package/dist/core/SignatureCache.js +172 -0
  160. package/dist/core/SignatureCache.js.map +1 -0
  161. package/dist/core/StaticFileServer.d.ts +34 -0
  162. package/dist/core/StaticFileServer.d.ts.map +1 -0
  163. package/dist/core/StaticFileServer.js +497 -0
  164. package/dist/core/StaticFileServer.js.map +1 -0
  165. package/dist/core/Supervisor.d.ts +198 -0
  166. package/dist/core/Supervisor.d.ts.map +1 -0
  167. package/dist/core/Supervisor.js +1418 -0
  168. package/dist/core/Supervisor.js.map +1 -0
  169. package/dist/core/ThreadAllocator.d.ts +52 -0
  170. package/dist/core/ThreadAllocator.d.ts.map +1 -0
  171. package/dist/core/ThreadAllocator.js +174 -0
  172. package/dist/core/ThreadAllocator.js.map +1 -0
  173. package/dist/core/WorkerChannelManager.d.ts +130 -0
  174. package/dist/core/WorkerChannelManager.d.ts.map +1 -0
  175. package/dist/core/WorkerChannelManager.js +956 -0
  176. package/dist/core/WorkerChannelManager.js.map +1 -0
  177. package/dist/core/config-enums.d.ts +41 -0
  178. package/dist/core/config-enums.d.ts.map +1 -0
  179. package/dist/core/config-enums.js +59 -0
  180. package/dist/core/config-enums.js.map +1 -0
  181. package/dist/core/config.d.ts +159 -0
  182. package/dist/core/config.d.ts.map +1 -0
  183. package/dist/core/config.js +694 -0
  184. package/dist/core/config.js.map +1 -0
  185. package/dist/core/host-config.d.ts +146 -0
  186. package/dist/core/host-config.d.ts.map +1 -0
  187. package/dist/core/host-config.js +312 -0
  188. package/dist/core/host-config.js.map +1 -0
  189. package/dist/core/ipc-errors.d.ts +27 -0
  190. package/dist/core/ipc-errors.d.ts.map +1 -0
  191. package/dist/core/ipc-errors.js +36 -0
  192. package/dist/core/ipc-errors.js.map +1 -0
  193. package/dist/core/network-utils.d.ts +35 -0
  194. package/dist/core/network-utils.d.ts.map +1 -0
  195. package/dist/core/network-utils.js +145 -0
  196. package/dist/core/network-utils.js.map +1 -0
  197. package/dist/core/platform-config.d.ts +142 -0
  198. package/dist/core/platform-config.d.ts.map +1 -0
  199. package/dist/core/platform-config.js +299 -0
  200. package/dist/core/platform-config.js.map +1 -0
  201. package/dist/decorators/ServiceProxy.d.ts +175 -0
  202. package/dist/decorators/ServiceProxy.d.ts.map +1 -0
  203. package/dist/decorators/ServiceProxy.js +969 -0
  204. package/dist/decorators/ServiceProxy.js.map +1 -0
  205. package/dist/decorators/index.d.ts +146 -0
  206. package/dist/decorators/index.d.ts.map +1 -0
  207. package/dist/decorators/index.js +545 -0
  208. package/dist/decorators/index.js.map +1 -0
  209. package/dist/deploy/NginxGenerator.d.ts +165 -0
  210. package/dist/deploy/NginxGenerator.d.ts.map +1 -0
  211. package/dist/deploy/NginxGenerator.js +781 -0
  212. package/dist/deploy/NginxGenerator.js.map +1 -0
  213. package/dist/deploy/PlatformManifestGenerator.d.ts +43 -0
  214. package/dist/deploy/PlatformManifestGenerator.d.ts.map +1 -0
  215. package/dist/deploy/PlatformManifestGenerator.js +80 -0
  216. package/dist/deploy/PlatformManifestGenerator.js.map +1 -0
  217. package/dist/deploy/RouteManifestGenerator.d.ts +42 -0
  218. package/dist/deploy/RouteManifestGenerator.d.ts.map +1 -0
  219. package/dist/deploy/RouteManifestGenerator.js +105 -0
  220. package/dist/deploy/RouteManifestGenerator.js.map +1 -0
  221. package/dist/deploy/index.d.ts +210 -0
  222. package/dist/deploy/index.d.ts.map +1 -0
  223. package/dist/deploy/index.js +918 -0
  224. package/dist/deploy/index.js.map +1 -0
  225. package/dist/frontend/FrontendDevLifecycle.d.ts +26 -0
  226. package/dist/frontend/FrontendDevLifecycle.d.ts.map +1 -0
  227. package/dist/frontend/FrontendDevLifecycle.js +60 -0
  228. package/dist/frontend/FrontendDevLifecycle.js.map +1 -0
  229. package/dist/frontend/FrontendPluginOrchestrator.d.ts +64 -0
  230. package/dist/frontend/FrontendPluginOrchestrator.d.ts.map +1 -0
  231. package/dist/frontend/FrontendPluginOrchestrator.js +167 -0
  232. package/dist/frontend/FrontendPluginOrchestrator.js.map +1 -0
  233. package/dist/frontend/SiteResolver.d.ts +33 -0
  234. package/dist/frontend/SiteResolver.d.ts.map +1 -0
  235. package/dist/frontend/SiteResolver.js +53 -0
  236. package/dist/frontend/SiteResolver.js.map +1 -0
  237. package/dist/frontend/StaticMountRegistry.d.ts +36 -0
  238. package/dist/frontend/StaticMountRegistry.d.ts.map +1 -0
  239. package/dist/frontend/StaticMountRegistry.js +94 -0
  240. package/dist/frontend/StaticMountRegistry.js.map +1 -0
  241. package/dist/frontend/index.d.ts +7 -0
  242. package/dist/frontend/index.d.ts.map +1 -0
  243. package/{src → dist}/frontend/index.js +4 -2
  244. package/dist/frontend/index.js.map +1 -0
  245. package/dist/frontend/pathUtils.d.ts +8 -0
  246. package/dist/frontend/pathUtils.d.ts.map +1 -0
  247. package/dist/frontend/pathUtils.js +17 -0
  248. package/dist/frontend/pathUtils.js.map +1 -0
  249. package/dist/frontend/plugins/index.d.ts +2 -0
  250. package/dist/frontend/plugins/index.d.ts.map +1 -0
  251. package/{src → dist}/frontend/plugins/index.js +1 -1
  252. package/dist/frontend/plugins/index.js.map +1 -0
  253. package/dist/frontend/plugins/viteFrontend.d.ts +51 -0
  254. package/dist/frontend/plugins/viteFrontend.d.ts.map +1 -0
  255. package/dist/frontend/plugins/viteFrontend.js +134 -0
  256. package/dist/frontend/plugins/viteFrontend.js.map +1 -0
  257. package/dist/frontend/types.d.ts +25 -0
  258. package/dist/frontend/types.d.ts.map +1 -0
  259. package/dist/frontend/types.js +2 -0
  260. package/dist/frontend/types.js.map +1 -0
  261. package/dist/index.d.ts +17 -0
  262. package/dist/index.d.ts.map +1 -0
  263. package/dist/index.js +32 -0
  264. package/dist/index.js.map +1 -0
  265. package/dist/internals.d.ts +21 -0
  266. package/dist/internals.d.ts.map +1 -0
  267. package/{src → dist}/internals.js +12 -14
  268. package/dist/internals.js.map +1 -0
  269. package/dist/plugins/PluginManager.d.ts +209 -0
  270. package/dist/plugins/PluginManager.d.ts.map +1 -0
  271. package/dist/plugins/PluginManager.js +365 -0
  272. package/dist/plugins/PluginManager.js.map +1 -0
  273. package/dist/plugins/ScopedPostgres.d.ts +78 -0
  274. package/dist/plugins/ScopedPostgres.d.ts.map +1 -0
  275. package/dist/plugins/ScopedPostgres.js +190 -0
  276. package/dist/plugins/ScopedPostgres.js.map +1 -0
  277. package/dist/plugins/ScopedRedis.d.ts +88 -0
  278. package/dist/plugins/ScopedRedis.d.ts.map +1 -0
  279. package/dist/plugins/ScopedRedis.js +169 -0
  280. package/dist/plugins/ScopedRedis.js.map +1 -0
  281. package/dist/plugins/index.d.ts +289 -0
  282. package/dist/plugins/index.d.ts.map +1 -0
  283. package/dist/plugins/index.js +1942 -0
  284. package/dist/plugins/index.js.map +1 -0
  285. package/dist/plugins/types.d.ts +59 -0
  286. package/dist/plugins/types.d.ts.map +1 -0
  287. package/dist/plugins/types.js +2 -0
  288. package/dist/plugins/types.js.map +1 -0
  289. package/dist/registry/ServiceRegistry.d.ts +305 -0
  290. package/dist/registry/ServiceRegistry.d.ts.map +1 -0
  291. package/dist/registry/ServiceRegistry.js +735 -0
  292. package/dist/registry/ServiceRegistry.js.map +1 -0
  293. package/dist/scaling/ScaleAdvisor.d.ts +214 -0
  294. package/dist/scaling/ScaleAdvisor.d.ts.map +1 -0
  295. package/dist/scaling/ScaleAdvisor.js +526 -0
  296. package/dist/scaling/ScaleAdvisor.js.map +1 -0
  297. package/dist/services/Service.d.ts +164 -0
  298. package/dist/services/Service.d.ts.map +1 -0
  299. package/dist/services/Service.js +106 -0
  300. package/dist/services/Service.js.map +1 -0
  301. package/dist/services/worker-bootstrap.d.ts +15 -0
  302. package/dist/services/worker-bootstrap.d.ts.map +1 -0
  303. package/dist/services/worker-bootstrap.js +744 -0
  304. package/dist/services/worker-bootstrap.js.map +1 -0
  305. package/dist/templates/auth-service.d.ts +42 -0
  306. package/dist/templates/auth-service.d.ts.map +1 -0
  307. package/dist/templates/auth-service.js +54 -0
  308. package/dist/templates/auth-service.js.map +1 -0
  309. package/dist/templates/identity-service.d.ts +50 -0
  310. package/dist/templates/identity-service.d.ts.map +1 -0
  311. package/dist/templates/identity-service.js +62 -0
  312. package/dist/templates/identity-service.js.map +1 -0
  313. package/dist/types/contract.d.ts +120 -0
  314. package/dist/types/contract.d.ts.map +1 -0
  315. package/dist/types/contract.js +69 -0
  316. package/dist/types/contract.js.map +1 -0
  317. package/package.json +78 -20
  318. package/src/core/DirectMessageBus.js +0 -364
  319. package/src/core/EndpointResolver.js +0 -259
  320. package/src/core/ForgeContext.js +0 -2236
  321. package/src/core/ForgeHost.js +0 -122
  322. package/src/core/ForgePlatform.js +0 -145
  323. package/src/core/Ingress.js +0 -768
  324. package/src/core/Interceptors.js +0 -420
  325. package/src/core/MessageBus.js +0 -321
  326. package/src/core/Prometheus.js +0 -305
  327. package/src/core/RequestContext.js +0 -413
  328. package/src/core/RoutingStrategy.js +0 -330
  329. package/src/core/Supervisor.js +0 -1349
  330. package/src/core/ThreadAllocator.js +0 -196
  331. package/src/core/WorkerChannelManager.js +0 -879
  332. package/src/core/config.js +0 -637
  333. package/src/core/host-config.js +0 -311
  334. package/src/core/network-utils.js +0 -166
  335. package/src/core/platform-config.js +0 -308
  336. package/src/decorators/ServiceProxy.js +0 -904
  337. package/src/decorators/index.js +0 -571
  338. package/src/deploy/NginxGenerator.js +0 -865
  339. package/src/deploy/PlatformManifestGenerator.js +0 -96
  340. package/src/deploy/RouteManifestGenerator.js +0 -112
  341. package/src/deploy/index.js +0 -984
  342. package/src/frontend/FrontendDevLifecycle.js +0 -65
  343. package/src/frontend/FrontendPluginOrchestrator.js +0 -187
  344. package/src/frontend/SiteResolver.js +0 -63
  345. package/src/frontend/StaticMountRegistry.js +0 -90
  346. package/src/frontend/plugins/viteFrontend.js +0 -79
  347. package/src/frontend/types.js +0 -35
  348. package/src/index.js +0 -58
  349. package/src/plugins/PluginManager.js +0 -537
  350. package/src/plugins/ScopedPostgres.js +0 -192
  351. package/src/plugins/ScopedRedis.js +0 -142
  352. package/src/plugins/index.js +0 -1756
  353. package/src/registry/ServiceRegistry.js +0 -797
  354. package/src/scaling/ScaleAdvisor.js +0 -442
  355. package/src/services/Service.js +0 -195
  356. package/src/services/worker-bootstrap.js +0 -679
  357. package/src/templates/auth-service.js +0 -65
  358. package/src/templates/identity-service.js +0 -75
@@ -0,0 +1,336 @@
1
+ /**
2
+ * EndpointResolver
3
+ *
4
+ * Resolves service names to { host, port, remote } endpoints.
5
+ * Supports:
6
+ * - Single endpoints (one instance per service)
7
+ * - Multi-instance arrays (round-robin selection)
8
+ * - Dynamic updates via set/remove (used by ServiceRegistry)
9
+ * - Fallback from FORGE_SERVICE_ENDPOINTS to FORGE_SERVICE_PORTS
10
+ * - C3: File fallback via FORGE_SERVICE_ENDPOINTS_FILE for large maps
11
+ */
12
+ import { readFileSync } from "node:fs";
13
+ /** Validate that an endpoint has the expected shape */
14
+ function validateEndpoint(ep) {
15
+ if (!ep || typeof ep !== "object")
16
+ return false;
17
+ const obj = ep;
18
+ if (typeof obj.host !== "string" || !obj.host)
19
+ return false;
20
+ if (obj.port !== undefined && (typeof obj.port !== "number" || obj.port < 1 || obj.port > 65535))
21
+ return false;
22
+ return true;
23
+ }
24
+ export class EndpointResolver {
25
+ _endpoints;
26
+ _counters;
27
+ _strategies;
28
+ // P-10: Cache wrapped endpoint entries to avoid per-resolve() allocation
29
+ _wrappedCache;
30
+ // REG-H2/M1: Health status per endpoint (key: "host:port")
31
+ _healthStatus;
32
+ // REG-M2: Consecutive failure counts per endpoint for passive health checking
33
+ _failureCounts;
34
+ // REG-M2: Configurable threshold for marking endpoint unhealthy
35
+ _failureThreshold;
36
+ constructor() {
37
+ this._endpoints = new Map();
38
+ this._counters = new Map();
39
+ this._strategies = new Map();
40
+ this._wrappedCache = new Map();
41
+ this._healthStatus = new Map();
42
+ this._failureCounts = new Map();
43
+ this._failureThreshold = 3;
44
+ }
45
+ /**
46
+ * Set a routing strategy for a specific service.
47
+ * When set, resolve() delegates to the strategy's pick() method
48
+ * instead of using built-in round-robin.
49
+ *
50
+ * The strategy must implement pick(entries, callContext) where entries
51
+ * are wrapped as { key: "host:port", host, port, remote }.
52
+ */
53
+ setStrategy(serviceName, strategy) {
54
+ if (!strategy || typeof strategy.pick !== "function") {
55
+ throw new Error(`Strategy for "${serviceName}" must have a pick() method`);
56
+ }
57
+ this._strategies.set(serviceName, strategy);
58
+ }
59
+ /**
60
+ * Create an EndpointResolver from environment variables.
61
+ *
62
+ * Parses FORGE_SERVICE_ENDPOINTS first (full endpoint map with host/port/remote).
63
+ * Falls back to FORGE_SERVICE_PORTS (localhost-only port map) when endpoints
64
+ * aren't available.
65
+ */
66
+ static fromEnv() {
67
+ const resolver = new EndpointResolver();
68
+ // C3: Support file fallback for large endpoint maps (written by Supervisor)
69
+ let endpointsJson = process.env.FORGE_SERVICE_ENDPOINTS;
70
+ if (!endpointsJson && process.env.FORGE_SERVICE_ENDPOINTS_FILE) {
71
+ try {
72
+ endpointsJson = readFileSync(process.env.FORGE_SERVICE_ENDPOINTS_FILE, "utf8");
73
+ }
74
+ catch (e) {
75
+ const msg = e instanceof Error ? e.message : String(e);
76
+ console.error("[EndpointResolver] Failed to read FORGE_SERVICE_ENDPOINTS_FILE:", msg);
77
+ }
78
+ }
79
+ if (endpointsJson) {
80
+ try {
81
+ const parsed = JSON.parse(endpointsJson);
82
+ for (const [name, value] of Object.entries(parsed)) {
83
+ if (Array.isArray(value)) {
84
+ const valid = value.filter((ep) => validateEndpoint(ep));
85
+ if (valid.length > 0)
86
+ resolver._endpoints.set(name, valid);
87
+ }
88
+ else if (validateEndpoint(value)) {
89
+ resolver._endpoints.set(name, [value]);
90
+ }
91
+ }
92
+ }
93
+ catch (e) {
94
+ const msg = e instanceof Error ? e.message : String(e);
95
+ console.error("[EndpointResolver] Failed to parse FORGE_SERVICE_ENDPOINTS:", msg);
96
+ }
97
+ }
98
+ // Merge FORGE_SERVICE_PORTS as fallback for any services not in endpoints
99
+ const portsJson = process.env.FORGE_SERVICE_PORTS;
100
+ if (portsJson) {
101
+ try {
102
+ const ports = JSON.parse(portsJson);
103
+ for (const [name, port] of Object.entries(ports)) {
104
+ const p = Number(port);
105
+ if (!resolver._endpoints.has(name) && Number.isInteger(p) && p >= 1 && p <= 65535) {
106
+ resolver._endpoints.set(name, [{ host: "127.0.0.1", port: p, remote: false }]);
107
+ }
108
+ }
109
+ }
110
+ catch (e) {
111
+ const msg = e instanceof Error ? e.message : String(e);
112
+ console.error("[EndpointResolver] Failed to parse FORGE_SERVICE_PORTS:", msg);
113
+ }
114
+ }
115
+ return resolver;
116
+ }
117
+ /**
118
+ * Resolve an endpoint for a service.
119
+ * Delegates to a configured RoutingStrategy when available,
120
+ * otherwise round-robins across instances.
121
+ */
122
+ resolve(serviceName, callContext) {
123
+ const endpoints = this._endpoints.get(serviceName);
124
+ if (!endpoints || endpoints.length === 0)
125
+ return null;
126
+ // REG-H2: Filter out unhealthy/draining endpoints if health data is available
127
+ const healthy = this._healthStatus.size > 0
128
+ ? endpoints.filter(ep => {
129
+ const key = `${ep.host}:${ep.port}`;
130
+ const status = this._healthStatus.get(key);
131
+ return !status || (status !== 'unhealthy' && status !== 'draining');
132
+ })
133
+ : endpoints;
134
+ // Fall back to all endpoints if all are unhealthy (avoid total blackout)
135
+ const available = healthy.length > 0 ? healthy : endpoints;
136
+ if (available.length === 1)
137
+ return available[0];
138
+ // Delegate to configured strategy if present
139
+ const strategy = this._strategies.get(serviceName);
140
+ if (strategy) {
141
+ // P-10: Use cached wrapped entries to avoid per-call allocation
142
+ // REG-H2: Invalidate cache when health filtering changes the available set
143
+ let entries = this._wrappedCache.get(serviceName);
144
+ if (!entries || entries.length !== available.length) {
145
+ entries = available.map((ep) => ({
146
+ key: `${ep.host}:${ep.port}`,
147
+ host: ep.host,
148
+ port: ep.port,
149
+ remote: ep.remote,
150
+ }));
151
+ this._wrappedCache.set(serviceName, entries);
152
+ }
153
+ const picked = strategy.pick(entries, callContext);
154
+ if (picked) {
155
+ // Handle broadcast (returns array) — return all endpoints for fan-out
156
+ if (Array.isArray(picked)) {
157
+ return picked.map((p) => ({ host: p.host, port: p.port, remote: p.remote }));
158
+ }
159
+ return { host: picked.host, port: picked.port, remote: picked.remote };
160
+ }
161
+ // Strategy returned null — fall through to round-robin
162
+ }
163
+ // Round-robin: read-then-write is atomic in single-threaded Node.js
164
+ // (no microtask or I/O can interleave between get and set)
165
+ const idx = this._counters.get(serviceName) ?? 0;
166
+ this._counters.set(serviceName, (idx + 1) % 1_000_000_000);
167
+ const endpoint = available[idx % available.length];
168
+ return endpoint;
169
+ }
170
+ /**
171
+ * Get all endpoints for a service (used for broadcast/event delivery).
172
+ */
173
+ all(serviceName) {
174
+ return (this._endpoints.get(serviceName) ?? []).map((e) => ({ ...e }));
175
+ }
176
+ /**
177
+ * Add or update an endpoint for a service.
178
+ * Used by dynamic registry discovery.
179
+ */
180
+ set(serviceName, endpoint) {
181
+ if (endpoint.port !== undefined &&
182
+ (!Number.isInteger(endpoint.port) || endpoint.port < 1 || endpoint.port > 65535)) {
183
+ throw new Error(`Invalid port for service "${serviceName}": ${endpoint.port}`);
184
+ }
185
+ const ep = { remote: true, ...endpoint };
186
+ const existing = this._endpoints.get(serviceName) ?? [];
187
+ // Replace if same host:port exists, otherwise append
188
+ const idx = existing.findIndex((e) => e.host === ep.host && e.port === ep.port);
189
+ if (idx !== -1) {
190
+ existing[idx] = ep;
191
+ }
192
+ else {
193
+ existing.push(ep);
194
+ }
195
+ this._endpoints.set(serviceName, existing);
196
+ // P-10: Invalidate wrapped cache when endpoints change
197
+ this._wrappedCache.delete(serviceName);
198
+ }
199
+ /**
200
+ * Remove a specific instance of a service.
201
+ * Used when a remote node goes down.
202
+ */
203
+ remove(serviceName, host, port) {
204
+ const existing = this._endpoints.get(serviceName);
205
+ if (!existing)
206
+ return;
207
+ const filtered = existing.filter((e) => !(e.host === host && e.port === port));
208
+ // P-10: Invalidate wrapped cache when endpoints change
209
+ this._wrappedCache.delete(serviceName);
210
+ if (filtered.length === 0) {
211
+ this._endpoints.delete(serviceName);
212
+ // CR-IPC-7: Clean up counter when all endpoints removed
213
+ this._counters.delete(serviceName);
214
+ }
215
+ else {
216
+ this._endpoints.set(serviceName, filtered);
217
+ // Let counter naturally wrap via modulo in resolve()
218
+ }
219
+ }
220
+ /**
221
+ * COR-C1: Acquire a pending slot for a resolved endpoint.
222
+ * Delegates to the service's routing strategy if it supports acquire().
223
+ * Must be paired with releaseEndpoint() in a finally block.
224
+ */
225
+ acquireEndpoint(serviceName, endpointKey) {
226
+ const strategy = this._strategies.get(serviceName);
227
+ if (strategy && typeof strategy.acquire === "function") {
228
+ strategy.acquire(endpointKey);
229
+ }
230
+ }
231
+ /**
232
+ * COR-C1: Release a pending slot for a resolved endpoint.
233
+ * Delegates to the service's routing strategy if it supports release().
234
+ */
235
+ releaseEndpoint(serviceName, endpointKey) {
236
+ const strategy = this._strategies.get(serviceName);
237
+ if (strategy && typeof strategy.release === "function") {
238
+ strategy.release(endpointKey);
239
+ }
240
+ }
241
+ /**
242
+ * REG-H2: Update health status for a specific endpoint.
243
+ * Called when the Supervisor pushes health updates or on connection failure feedback.
244
+ */
245
+ setHealthStatus(host, port, status) {
246
+ const key = `${host}:${port}`;
247
+ if (status === 'healthy') {
248
+ this._healthStatus.delete(key);
249
+ }
250
+ else {
251
+ this._healthStatus.set(key, status);
252
+ }
253
+ // Invalidate wrapped caches since health filtering may change available set
254
+ this._wrappedCache.clear();
255
+ }
256
+ /**
257
+ * REG-H2: Get the health status of a specific endpoint.
258
+ */
259
+ getHealthStatus(host, port) {
260
+ return this._healthStatus.get(`${host}:${port}`) ?? 'healthy';
261
+ }
262
+ /**
263
+ * REG-M2: Record a connection failure for an endpoint.
264
+ * After _failureThreshold consecutive failures, the endpoint is marked unhealthy.
265
+ * Returns the current consecutive failure count.
266
+ */
267
+ recordFailure(host, port) {
268
+ const key = `${host}:${port}`;
269
+ const count = (this._failureCounts.get(key) ?? 0) + 1;
270
+ this._failureCounts.set(key, count);
271
+ if (count >= this._failureThreshold) {
272
+ this.setHealthStatus(host, port, 'unhealthy');
273
+ }
274
+ return count;
275
+ }
276
+ /**
277
+ * REG-M2: Record a successful connection to an endpoint.
278
+ * Resets the consecutive failure counter and marks the endpoint healthy.
279
+ */
280
+ recordSuccess(host, port) {
281
+ const key = `${host}:${port}`;
282
+ if (this._failureCounts.has(key)) {
283
+ this._failureCounts.delete(key);
284
+ const status = this._healthStatus.get(key);
285
+ if (status === 'unhealthy') {
286
+ this.setHealthStatus(host, port, 'healthy');
287
+ }
288
+ }
289
+ }
290
+ /**
291
+ * Check if a service has any known endpoints.
292
+ */
293
+ has(serviceName) {
294
+ const eps = this._endpoints.get(serviceName);
295
+ return eps != null && eps.length > 0;
296
+ }
297
+ /**
298
+ * REG-H1: Apply a full endpoint map update (pushed from Supervisor).
299
+ * Merges new/updated endpoints and removes stale ones not present in the update.
300
+ * Only updates remote endpoints to avoid overwriting local colocated/UDS entries.
301
+ */
302
+ applyEndpointUpdate(endpointMap) {
303
+ if (!endpointMap || typeof endpointMap !== 'object')
304
+ return;
305
+ for (const [name, value] of Object.entries(endpointMap)) {
306
+ if (Array.isArray(value)) {
307
+ const valid = value.filter((ep) => validateEndpoint(ep));
308
+ if (valid.length > 0) {
309
+ // Merge: replace remote entries, keep local ones
310
+ const existing = this._endpoints.get(name) ?? [];
311
+ const localEntries = existing.filter(e => !e.remote);
312
+ const merged = [...localEntries, ...valid.filter(e => e.remote)];
313
+ if (merged.length > 0) {
314
+ this._endpoints.set(name, merged);
315
+ this._wrappedCache.delete(name);
316
+ }
317
+ }
318
+ }
319
+ else if (validateEndpoint(value)) {
320
+ const ep = value;
321
+ if (ep.remote) {
322
+ const existing = this._endpoints.get(name) ?? [];
323
+ const localEntries = existing.filter(e => !e.remote);
324
+ this._endpoints.set(name, [...localEntries, ep]);
325
+ this._wrappedCache.delete(name);
326
+ }
327
+ else if (!this._endpoints.has(name)) {
328
+ // Only set non-remote if no existing entry
329
+ this._endpoints.set(name, [ep]);
330
+ this._wrappedCache.delete(name);
331
+ }
332
+ }
333
+ }
334
+ }
335
+ }
336
+ //# sourceMappingURL=EndpointResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EndpointResolver.js","sourceRoot":"","sources":["../../src/core/EndpointResolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,221 @@
1
+ import { type IncomingMessage, type Server, type ServerResponse } from "node:http";
2
+ import type { Socket } from "node:net";
3
+ import type { StaticMountInput } from "../frontend/StaticMountRegistry.js";
4
+ import { StaticMountRegistry } from "../frontend/StaticMountRegistry.js";
5
+ import type { EndpointResolver } from "./EndpointResolver.js";
6
+ import { ForgeEndpoints, type ForgeEndpointResult, type ServiceInstance } from "./ForgeEndpoints.js";
7
+ import { ForgeWebSocket, type WsOptions } from "./ForgeWebSocket.js";
8
+ import { IngressProtection } from "./Ingress.js";
9
+ import { Logger } from "./Logger.js";
10
+ import { isPrivateNetwork, isTrustedProxy } from "./network-utils.js";
11
+ import { PrometheusMetrics } from "./Prometheus.js";
12
+ import { RequestContext } from "./RequestContext.js";
13
+ import { Router } from "./Router.js";
14
+ import { StaticFileServer } from "./StaticFileServer.js";
15
+ import { WorkerChannelManager } from "./WorkerChannelManager.js";
16
+ import { type ServiceMode as ServiceModeValue, type ServiceType as ServiceTypeValue } from "./config-enums.js";
17
+ export { isPrivateNetwork, isTrustedProxy };
18
+ export declare const NOT_HANDLED: unique symbol;
19
+ interface ForgeRequest extends IncomingMessage {
20
+ body?: unknown;
21
+ ctx?: RequestContext;
22
+ auth?: Record<string, unknown> | null;
23
+ tenantId?: string | null;
24
+ projectId?: string | null;
25
+ userId?: string | null;
26
+ correlationId?: string;
27
+ params?: Record<string, string>;
28
+ query?: Record<string, string | string[]>;
29
+ }
30
+ interface ForgeResponse extends ServerResponse {
31
+ json?: (data: unknown, statusCode?: number) => void;
32
+ status?: (code: number) => ForgeResponse;
33
+ stream?: (statusCode?: number, headers?: Record<string, string>) => ForgeResponse;
34
+ _forgeTracked?: boolean;
35
+ }
36
+ interface IPCMessage {
37
+ type: string;
38
+ from?: string;
39
+ payload?: unknown;
40
+ requestId?: string;
41
+ timestamp?: number;
42
+ error?: string | null;
43
+ [key: string]: unknown;
44
+ }
45
+ interface WsHandlerEntry {
46
+ handler: WsHandler;
47
+ options: WsOptions;
48
+ }
49
+ type WsHandler = (ws: ForgeWebSocket, req: ForgeRequest) => void;
50
+ interface WsPluginHook {
51
+ name: string;
52
+ onWsUpgrade?: (payload: Record<string, unknown>) => unknown | Promise<unknown>;
53
+ onWsConnect?: (payload: Record<string, unknown>) => unknown | Promise<unknown>;
54
+ onWsMessage?: (payload: Record<string, unknown>) => unknown | Promise<unknown>;
55
+ onWsClose?: (payload: Record<string, unknown>) => unknown | Promise<unknown>;
56
+ [key: string]: unknown;
57
+ }
58
+ interface WsPluginResult {
59
+ plugin: string;
60
+ ok: boolean;
61
+ result?: unknown;
62
+ error?: Error;
63
+ }
64
+ interface IngressConfig {
65
+ [key: string]: unknown;
66
+ }
67
+ interface ForgeContextOptions {
68
+ serviceName: string;
69
+ port: number;
70
+ workerId: number;
71
+ threadCount: number;
72
+ mode: ServiceModeValue;
73
+ serviceType?: ServiceTypeValue;
74
+ sendIPC: (msg: Record<string, unknown>) => void;
75
+ localSend?: ((target: string, payload: unknown) => boolean) | null;
76
+ localRequest?: ((target: string, payload: unknown) => Promise<unknown>) | null;
77
+ staticMounts?: StaticMountInput[];
78
+ ingress?: IngressConfig;
79
+ forgeProxy?: string | null;
80
+ }
81
+ /**
82
+ * ForgeContext
83
+ *
84
+ * Injected into every Service instance. Provides:
85
+ * - HTTP router
86
+ * - IPC messaging helpers (direct worker-to-worker when available)
87
+ * - Metrics collection
88
+ * - Structured logger
89
+ * - Runtime metadata (service name, thread count, worker id, etc.)
90
+ */
91
+ export declare class ForgeContext {
92
+ serviceName: string;
93
+ port: number;
94
+ workerId: number;
95
+ threadCount: number;
96
+ mode: ServiceModeValue;
97
+ serviceType: ServiceTypeValue;
98
+ router: Router<ForgeRequest, ForgeResponse>;
99
+ logger: Logger;
100
+ metrics: PrometheusMetrics;
101
+ channels: WorkerChannelManager;
102
+ ingress?: IngressProtection;
103
+ _sendIPC: (msg: Record<string, unknown>) => void;
104
+ _localSend: ((target: string, payload: unknown) => boolean) | null;
105
+ _localRequest: ((target: string, payload: unknown) => Promise<unknown>) | null;
106
+ _ingressConfig: IngressConfig;
107
+ _ingressApplied: boolean;
108
+ _forgeProxy: string | null;
109
+ _serviceInstance: ServiceInstance | null;
110
+ _servicePorts: Record<string, number>;
111
+ _endpointResolver: EndpointResolver | null;
112
+ _staticMounts: StaticMountInput[];
113
+ _staticRegistry: StaticMountRegistry;
114
+ _staticFileServer: StaticFileServer;
115
+ _forgeEndpoints: ForgeEndpoints<ForgeRequest, ForgeResponse>;
116
+ _wsConnections: Set<ForgeWebSocket>;
117
+ _wsPerIpCounts: Map<string, number>;
118
+ _wsMaxPerIp: number;
119
+ _wsPerIpCleanupTimer: ReturnType<typeof setInterval>;
120
+ _wsHandlers: Map<string, WsHandlerEntry>;
121
+ _wsPluginHooks: WsPluginHook[];
122
+ _server: Server | null;
123
+ _needsHttpServer: boolean;
124
+ _activeRequests: number;
125
+ _messageHandlers: Map<string, (msg: IPCMessage) => void>;
126
+ _onMessage?: (from: string, payload: unknown) => void;
127
+ _onRequest?: (from: string, payload: unknown) => unknown | Promise<unknown>;
128
+ _projectId?: string;
129
+ _projectSchema?: string | null;
130
+ _projectKeyPrefix?: string | null;
131
+ _emitEvent?: (eventName: string, data: unknown) => void;
132
+ constructor(options: ForgeContextOptions);
133
+ setStaticMounts(mounts?: StaticMountInput[]): void;
134
+ /**
135
+ * Send a message to another service.
136
+ *
137
+ * Resolution order:
138
+ * 1. Local dispatch (colocated service in same process) — zero overhead
139
+ * 2. Direct UDS connection — bypasses supervisor
140
+ * 3. Supervisor IPC fallback — only during startup
141
+ */
142
+ send(target: string, payload: unknown): Promise<void>;
143
+ /**
144
+ * Broadcast to all workers of a target service.
145
+ * Note: channels.broadcast delivers to all workers including local via UDS.
146
+ * We only use _localSend for colocated services that share this process
147
+ * (no UDS needed), then broadcast to remote workers via channels.
148
+ */
149
+ broadcast(target: string, payload: unknown): Promise<void>;
150
+ /**
151
+ * Send a request to another service and await a response.
152
+ *
153
+ * If the target is colocated, this is a direct async function call
154
+ * with zero serialization overhead.
155
+ */
156
+ request(target: string, payload: unknown, timeoutMs?: number): Promise<unknown>;
157
+ /**
158
+ * Start the HTTP server for this service.
159
+ */
160
+ startServer(): Promise<void>;
161
+ /**
162
+ * Route an incoming HTTP request.
163
+ * Creates a RequestContext that flows through the entire call chain.
164
+ */
165
+ _handleRequest(req: ForgeRequest, res: ForgeResponse, start: number): void;
166
+ /**
167
+ * Wire message/request handlers to both the direct channel manager
168
+ * AND the supervisor fallback IPC path.
169
+ */
170
+ _wireMessageHandlers(): void;
171
+ /**
172
+ * Handle an incoming IPC message from the supervisor.
173
+ * This is the FALLBACK path — only used during startup before
174
+ * direct MessagePorts are established, and for supervisor-level
175
+ * commands (health checks, shutdown, etc.)
176
+ */
177
+ _handleIPCMessage(msg: IPCMessage): void;
178
+ _isMethodAllowed(method: string | undefined): boolean;
179
+ _executeForgeEndpoint(res: ForgeResponse, rctx: RequestContext, handler: (...args: unknown[]) => unknown, method: string, { args, logPrefix }: {
180
+ args: unknown[];
181
+ logPrefix: string;
182
+ }): Promise<ForgeEndpointResult | null>;
183
+ /**
184
+ * Gracefully shut down.
185
+ */
186
+ stop(): Promise<void>;
187
+ /**
188
+ * Register a WebSocket handler for a path.
189
+ *
190
+ * ctx.ws('/ws', (socket, req) => {
191
+ * socket.on('message', (data) => {
192
+ * const msg = JSON.parse(data);
193
+ * // req.ctx has the RequestContext with auth, correlationId
194
+ * socket.send(JSON.stringify({ echo: msg }));
195
+ * });
196
+ * });
197
+ */
198
+ ws(path: string, handlerOrOptions: WsHandler | WsOptions, maybeHandler?: WsHandler): void;
199
+ /**
200
+ * Write a short HTTP response over a raw upgrade socket and close it.
201
+ */
202
+ _writeWsUpgradeError(socket: Socket, statusCode: number, reason: string, headers?: Record<string, string>): void;
203
+ /**
204
+ * Run websocket plugin hooks for a lifecycle stage.
205
+ */
206
+ _runWsPluginHooks(stage: "upgrade" | "connect" | "message" | "close", payload: Record<string, unknown>): Promise<WsPluginResult[]>;
207
+ /**
208
+ * Handle HTTP→WebSocket upgrade.
209
+ * Implements RFC 6455 handshake without external dependencies.
210
+ */
211
+ _handleWsUpgrade(req: ForgeRequest, socket: Socket, head: Buffer): Promise<void>;
212
+ _proxyWsUpgradeToDevServer(req: ForgeRequest, socket: Socket, head: Buffer, url: URL): Promise<boolean>;
213
+ /**
214
+ * Register this service with ForgeProxy.
215
+ * ForgeProxy then routes external traffic to us.
216
+ */
217
+ _registerWithForgeProxy(): Promise<void>;
218
+ _getHost(): string;
219
+ }
220
+ export { ForgeWebSocket };
221
+ //# sourceMappingURL=ForgeContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgeContext.d.ts","sourceRoot":"","sources":["../../src/core/ForgeContext.ts"],"names":[],"mappings":"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"}