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.
- package/README.md +52 -20
- package/bin/forge.js +2 -1058
- package/bin/host-commands.d.ts +2 -0
- package/bin/host-commands.d.ts.map +1 -0
- package/bin/host-commands.js +7 -8
- package/bin/platform-commands.d.ts +2 -0
- package/bin/platform-commands.d.ts.map +1 -0
- package/bin/platform-commands.js +118 -36
- package/dist/cli/base-command.d.ts +12 -0
- package/dist/cli/base-command.d.ts.map +1 -0
- package/dist/cli/base-command.js +25 -0
- package/dist/cli/base-command.js.map +1 -0
- package/dist/cli/commands/build.d.ts +10 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +110 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/deploy.d.ts +12 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -0
- package/dist/cli/commands/deploy.js +143 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +10 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +138 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +10 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +76 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/host.d.ts +8 -0
- package/dist/cli/commands/host.d.ts.map +1 -0
- package/dist/cli/commands/host.js +20 -0
- package/dist/cli/commands/host.js.map +1 -0
- package/dist/cli/commands/init.d.ts +16 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +246 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/platform.d.ts +8 -0
- package/dist/cli/commands/platform.d.ts.map +1 -0
- package/dist/cli/commands/platform.js +20 -0
- package/dist/cli/commands/platform.js.map +1 -0
- package/dist/cli/commands/restart.d.ts +8 -0
- package/dist/cli/commands/restart.d.ts.map +1 -0
- package/dist/cli/commands/restart.js +13 -0
- package/dist/cli/commands/restart.js.map +1 -0
- package/dist/cli/commands/scaffold/frontend.d.ts +10 -0
- package/dist/cli/commands/scaffold/frontend.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/frontend.js +130 -0
- package/dist/cli/commands/scaffold/frontend.js.map +1 -0
- package/dist/cli/commands/scaffold/react.d.ts +7 -0
- package/dist/cli/commands/scaffold/react.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/react.js +12 -0
- package/dist/cli/commands/scaffold/react.js.map +1 -0
- package/dist/cli/commands/scale.d.ts +8 -0
- package/dist/cli/commands/scale.d.ts.map +1 -0
- package/dist/cli/commands/scale.js +13 -0
- package/dist/cli/commands/scale.js.map +1 -0
- package/dist/cli/commands/start.d.ts +10 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +71 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +11 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +60 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +10 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +89 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/util/config-discovery.d.ts +8 -0
- package/dist/cli/util/config-discovery.d.ts.map +1 -0
- package/dist/cli/util/config-discovery.js +70 -0
- package/dist/cli/util/config-discovery.js.map +1 -0
- package/dist/cli/util/config-patcher.d.ts +17 -0
- package/dist/cli/util/config-patcher.d.ts.map +1 -0
- package/dist/cli/util/config-patcher.js +439 -0
- package/dist/cli/util/config-patcher.js.map +1 -0
- package/dist/cli/util/frontend-dev.d.ts +8 -0
- package/dist/cli/util/frontend-dev.d.ts.map +1 -0
- package/dist/cli/util/frontend-dev.js +117 -0
- package/dist/cli/util/frontend-dev.js.map +1 -0
- package/dist/cli/util/process.d.ts +5 -0
- package/dist/cli/util/process.d.ts.map +1 -0
- package/dist/cli/util/process.js +17 -0
- package/dist/cli/util/process.js.map +1 -0
- package/dist/cli/util/templates.d.ts +10 -0
- package/dist/cli/util/templates.d.ts.map +1 -0
- package/dist/cli/util/templates.js +157 -0
- package/dist/cli/util/templates.js.map +1 -0
- package/dist/core/AlertSink.d.ts +83 -0
- package/dist/core/AlertSink.d.ts.map +1 -0
- package/dist/core/AlertSink.js +126 -0
- package/dist/core/AlertSink.js.map +1 -0
- package/dist/core/DirectMessageBus.d.ts +88 -0
- package/dist/core/DirectMessageBus.d.ts.map +1 -0
- package/dist/core/DirectMessageBus.js +352 -0
- package/dist/core/DirectMessageBus.js.map +1 -0
- package/dist/core/EndpointResolver.d.ts +111 -0
- package/dist/core/EndpointResolver.d.ts.map +1 -0
- package/dist/core/EndpointResolver.js +336 -0
- package/dist/core/EndpointResolver.js.map +1 -0
- package/dist/core/ForgeContext.d.ts +221 -0
- package/dist/core/ForgeContext.d.ts.map +1 -0
- package/dist/core/ForgeContext.js +1169 -0
- package/dist/core/ForgeContext.js.map +1 -0
- package/dist/core/ForgeEndpoints.d.ts +71 -0
- package/dist/core/ForgeEndpoints.d.ts.map +1 -0
- package/dist/core/ForgeEndpoints.js +442 -0
- package/dist/core/ForgeEndpoints.js.map +1 -0
- package/dist/core/ForgeHost.d.ts +82 -0
- package/dist/core/ForgeHost.d.ts.map +1 -0
- package/dist/core/ForgeHost.js +107 -0
- package/dist/core/ForgeHost.js.map +1 -0
- package/dist/core/ForgePlatform.d.ts +96 -0
- package/dist/core/ForgePlatform.d.ts.map +1 -0
- package/dist/core/ForgePlatform.js +136 -0
- package/dist/core/ForgePlatform.js.map +1 -0
- package/dist/core/ForgeWebSocket.d.ts +56 -0
- package/dist/core/ForgeWebSocket.d.ts.map +1 -0
- package/dist/core/ForgeWebSocket.js +415 -0
- package/dist/core/ForgeWebSocket.js.map +1 -0
- package/dist/core/Ingress.d.ts +329 -0
- package/dist/core/Ingress.d.ts.map +1 -0
- package/dist/core/Ingress.js +694 -0
- package/dist/core/Ingress.js.map +1 -0
- package/dist/core/Interceptors.d.ts +134 -0
- package/dist/core/Interceptors.d.ts.map +1 -0
- package/dist/core/Interceptors.js +416 -0
- package/dist/core/Interceptors.js.map +1 -0
- package/dist/core/Logger.d.ts +20 -0
- package/dist/core/Logger.d.ts.map +1 -0
- package/dist/core/Logger.js +77 -0
- package/dist/core/Logger.js.map +1 -0
- package/dist/core/MessageBus.d.ts +15 -0
- package/dist/core/MessageBus.d.ts.map +1 -0
- package/dist/core/MessageBus.js +18 -0
- package/dist/core/MessageBus.js.map +1 -0
- package/dist/core/Prometheus.d.ts +80 -0
- package/dist/core/Prometheus.d.ts.map +1 -0
- package/dist/core/Prometheus.js +332 -0
- package/dist/core/Prometheus.js.map +1 -0
- package/dist/core/RequestContext.d.ts +214 -0
- package/dist/core/RequestContext.d.ts.map +1 -0
- package/dist/core/RequestContext.js +556 -0
- package/dist/core/RequestContext.js.map +1 -0
- package/dist/core/Router.d.ts +45 -0
- package/dist/core/Router.d.ts.map +1 -0
- package/dist/core/Router.js +285 -0
- package/dist/core/Router.js.map +1 -0
- package/dist/core/RoutingStrategy.d.ts +116 -0
- package/dist/core/RoutingStrategy.d.ts.map +1 -0
- package/dist/core/RoutingStrategy.js +306 -0
- package/dist/core/RoutingStrategy.js.map +1 -0
- package/dist/core/RpcConfig.d.ts +72 -0
- package/dist/core/RpcConfig.d.ts.map +1 -0
- package/dist/core/RpcConfig.js +127 -0
- package/dist/core/RpcConfig.js.map +1 -0
- package/dist/core/SignatureCache.d.ts +81 -0
- package/dist/core/SignatureCache.d.ts.map +1 -0
- package/dist/core/SignatureCache.js +172 -0
- package/dist/core/SignatureCache.js.map +1 -0
- package/dist/core/StaticFileServer.d.ts +34 -0
- package/dist/core/StaticFileServer.d.ts.map +1 -0
- package/dist/core/StaticFileServer.js +497 -0
- package/dist/core/StaticFileServer.js.map +1 -0
- package/dist/core/Supervisor.d.ts +198 -0
- package/dist/core/Supervisor.d.ts.map +1 -0
- package/dist/core/Supervisor.js +1418 -0
- package/dist/core/Supervisor.js.map +1 -0
- package/dist/core/ThreadAllocator.d.ts +52 -0
- package/dist/core/ThreadAllocator.d.ts.map +1 -0
- package/dist/core/ThreadAllocator.js +174 -0
- package/dist/core/ThreadAllocator.js.map +1 -0
- package/dist/core/WorkerChannelManager.d.ts +130 -0
- package/dist/core/WorkerChannelManager.d.ts.map +1 -0
- package/dist/core/WorkerChannelManager.js +956 -0
- package/dist/core/WorkerChannelManager.js.map +1 -0
- package/dist/core/config-enums.d.ts +41 -0
- package/dist/core/config-enums.d.ts.map +1 -0
- package/dist/core/config-enums.js +59 -0
- package/dist/core/config-enums.js.map +1 -0
- package/dist/core/config.d.ts +159 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +694 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/host-config.d.ts +146 -0
- package/dist/core/host-config.d.ts.map +1 -0
- package/dist/core/host-config.js +312 -0
- package/dist/core/host-config.js.map +1 -0
- package/dist/core/ipc-errors.d.ts +27 -0
- package/dist/core/ipc-errors.d.ts.map +1 -0
- package/dist/core/ipc-errors.js +36 -0
- package/dist/core/ipc-errors.js.map +1 -0
- package/dist/core/network-utils.d.ts +35 -0
- package/dist/core/network-utils.d.ts.map +1 -0
- package/dist/core/network-utils.js +145 -0
- package/dist/core/network-utils.js.map +1 -0
- package/dist/core/platform-config.d.ts +142 -0
- package/dist/core/platform-config.d.ts.map +1 -0
- package/dist/core/platform-config.js +299 -0
- package/dist/core/platform-config.js.map +1 -0
- package/dist/decorators/ServiceProxy.d.ts +175 -0
- package/dist/decorators/ServiceProxy.d.ts.map +1 -0
- package/dist/decorators/ServiceProxy.js +969 -0
- package/dist/decorators/ServiceProxy.js.map +1 -0
- package/dist/decorators/index.d.ts +146 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +545 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/deploy/NginxGenerator.d.ts +165 -0
- package/dist/deploy/NginxGenerator.d.ts.map +1 -0
- package/dist/deploy/NginxGenerator.js +781 -0
- package/dist/deploy/NginxGenerator.js.map +1 -0
- package/dist/deploy/PlatformManifestGenerator.d.ts +43 -0
- package/dist/deploy/PlatformManifestGenerator.d.ts.map +1 -0
- package/dist/deploy/PlatformManifestGenerator.js +80 -0
- package/dist/deploy/PlatformManifestGenerator.js.map +1 -0
- package/dist/deploy/RouteManifestGenerator.d.ts +42 -0
- package/dist/deploy/RouteManifestGenerator.d.ts.map +1 -0
- package/dist/deploy/RouteManifestGenerator.js +105 -0
- package/dist/deploy/RouteManifestGenerator.js.map +1 -0
- package/dist/deploy/index.d.ts +210 -0
- package/dist/deploy/index.d.ts.map +1 -0
- package/dist/deploy/index.js +918 -0
- package/dist/deploy/index.js.map +1 -0
- package/dist/frontend/FrontendDevLifecycle.d.ts +26 -0
- package/dist/frontend/FrontendDevLifecycle.d.ts.map +1 -0
- package/dist/frontend/FrontendDevLifecycle.js +60 -0
- package/dist/frontend/FrontendDevLifecycle.js.map +1 -0
- package/dist/frontend/FrontendPluginOrchestrator.d.ts +64 -0
- package/dist/frontend/FrontendPluginOrchestrator.d.ts.map +1 -0
- package/dist/frontend/FrontendPluginOrchestrator.js +167 -0
- package/dist/frontend/FrontendPluginOrchestrator.js.map +1 -0
- package/dist/frontend/SiteResolver.d.ts +33 -0
- package/dist/frontend/SiteResolver.d.ts.map +1 -0
- package/dist/frontend/SiteResolver.js +53 -0
- package/dist/frontend/SiteResolver.js.map +1 -0
- package/dist/frontend/StaticMountRegistry.d.ts +36 -0
- package/dist/frontend/StaticMountRegistry.d.ts.map +1 -0
- package/dist/frontend/StaticMountRegistry.js +94 -0
- package/dist/frontend/StaticMountRegistry.js.map +1 -0
- package/dist/frontend/index.d.ts +7 -0
- package/dist/frontend/index.d.ts.map +1 -0
- package/{src → dist}/frontend/index.js +4 -2
- package/dist/frontend/index.js.map +1 -0
- package/dist/frontend/pathUtils.d.ts +8 -0
- package/dist/frontend/pathUtils.d.ts.map +1 -0
- package/dist/frontend/pathUtils.js +17 -0
- package/dist/frontend/pathUtils.js.map +1 -0
- package/dist/frontend/plugins/index.d.ts +2 -0
- package/dist/frontend/plugins/index.d.ts.map +1 -0
- package/{src → dist}/frontend/plugins/index.js +1 -1
- package/dist/frontend/plugins/index.js.map +1 -0
- package/dist/frontend/plugins/viteFrontend.d.ts +51 -0
- package/dist/frontend/plugins/viteFrontend.d.ts.map +1 -0
- package/dist/frontend/plugins/viteFrontend.js +134 -0
- package/dist/frontend/plugins/viteFrontend.js.map +1 -0
- package/dist/frontend/types.d.ts +25 -0
- package/dist/frontend/types.d.ts.map +1 -0
- package/dist/frontend/types.js +2 -0
- package/dist/frontend/types.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/internals.d.ts +21 -0
- package/dist/internals.d.ts.map +1 -0
- package/{src → dist}/internals.js +12 -14
- package/dist/internals.js.map +1 -0
- package/dist/plugins/PluginManager.d.ts +209 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -0
- package/dist/plugins/PluginManager.js +365 -0
- package/dist/plugins/PluginManager.js.map +1 -0
- package/dist/plugins/ScopedPostgres.d.ts +78 -0
- package/dist/plugins/ScopedPostgres.d.ts.map +1 -0
- package/dist/plugins/ScopedPostgres.js +190 -0
- package/dist/plugins/ScopedPostgres.js.map +1 -0
- package/dist/plugins/ScopedRedis.d.ts +88 -0
- package/dist/plugins/ScopedRedis.d.ts.map +1 -0
- package/dist/plugins/ScopedRedis.js +169 -0
- package/dist/plugins/ScopedRedis.js.map +1 -0
- package/dist/plugins/index.d.ts +289 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +1942 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/types.d.ts +59 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +2 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/registry/ServiceRegistry.d.ts +305 -0
- package/dist/registry/ServiceRegistry.d.ts.map +1 -0
- package/dist/registry/ServiceRegistry.js +735 -0
- package/dist/registry/ServiceRegistry.js.map +1 -0
- package/dist/scaling/ScaleAdvisor.d.ts +214 -0
- package/dist/scaling/ScaleAdvisor.d.ts.map +1 -0
- package/dist/scaling/ScaleAdvisor.js +526 -0
- package/dist/scaling/ScaleAdvisor.js.map +1 -0
- package/dist/services/Service.d.ts +164 -0
- package/dist/services/Service.d.ts.map +1 -0
- package/dist/services/Service.js +106 -0
- package/dist/services/Service.js.map +1 -0
- package/dist/services/worker-bootstrap.d.ts +15 -0
- package/dist/services/worker-bootstrap.d.ts.map +1 -0
- package/dist/services/worker-bootstrap.js +744 -0
- package/dist/services/worker-bootstrap.js.map +1 -0
- package/dist/templates/auth-service.d.ts +42 -0
- package/dist/templates/auth-service.d.ts.map +1 -0
- package/dist/templates/auth-service.js +54 -0
- package/dist/templates/auth-service.js.map +1 -0
- package/dist/templates/identity-service.d.ts +50 -0
- package/dist/templates/identity-service.d.ts.map +1 -0
- package/dist/templates/identity-service.js +62 -0
- package/dist/templates/identity-service.js.map +1 -0
- package/dist/types/contract.d.ts +120 -0
- package/dist/types/contract.d.ts.map +1 -0
- package/dist/types/contract.js +69 -0
- package/dist/types/contract.js.map +1 -0
- package/package.json +78 -20
- package/src/core/DirectMessageBus.js +0 -364
- package/src/core/EndpointResolver.js +0 -259
- package/src/core/ForgeContext.js +0 -2236
- package/src/core/ForgeHost.js +0 -122
- package/src/core/ForgePlatform.js +0 -145
- package/src/core/Ingress.js +0 -768
- package/src/core/Interceptors.js +0 -420
- package/src/core/MessageBus.js +0 -321
- package/src/core/Prometheus.js +0 -305
- package/src/core/RequestContext.js +0 -413
- package/src/core/RoutingStrategy.js +0 -330
- package/src/core/Supervisor.js +0 -1349
- package/src/core/ThreadAllocator.js +0 -196
- package/src/core/WorkerChannelManager.js +0 -879
- package/src/core/config.js +0 -637
- package/src/core/host-config.js +0 -311
- package/src/core/network-utils.js +0 -166
- package/src/core/platform-config.js +0 -308
- package/src/decorators/ServiceProxy.js +0 -904
- package/src/decorators/index.js +0 -571
- package/src/deploy/NginxGenerator.js +0 -865
- package/src/deploy/PlatformManifestGenerator.js +0 -96
- package/src/deploy/RouteManifestGenerator.js +0 -112
- package/src/deploy/index.js +0 -984
- package/src/frontend/FrontendDevLifecycle.js +0 -65
- package/src/frontend/FrontendPluginOrchestrator.js +0 -187
- package/src/frontend/SiteResolver.js +0 -63
- package/src/frontend/StaticMountRegistry.js +0 -90
- package/src/frontend/plugins/viteFrontend.js +0 -79
- package/src/frontend/types.js +0 -35
- package/src/index.js +0 -58
- package/src/plugins/PluginManager.js +0 -537
- package/src/plugins/ScopedPostgres.js +0 -192
- package/src/plugins/ScopedRedis.js +0 -142
- package/src/plugins/index.js +0 -1756
- package/src/registry/ServiceRegistry.js +0 -797
- package/src/scaling/ScaleAdvisor.js +0 -442
- package/src/services/Service.js +0 -195
- package/src/services/worker-bootstrap.js +0 -679
- package/src/templates/auth-service.js +0 -65
- 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":"AACA,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,MAAM,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACjG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,KAAK,eAAe,EAAa,MAAM,qBAAqB,CAAC;AAChH,OAAO,EAAE,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAqB,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAGL,KAAK,WAAW,IAAI,gBAAgB,EACpC,KAAK,WAAW,IAAI,gBAAgB,EACrC,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,CAAC;AAO5C,eAAO,MAAM,WAAW,EAAE,OAAO,MAA8B,CAAC;AAWhE,UAAU,YAAa,SAAQ,eAAe;IAC5C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;CAC3C;AAED,UAAU,aAAc,SAAQ,cAAc;IAC5C,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,aAAa,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,aAAa,CAAC;IAClF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,UAAU,cAAc;IACtB,OAAO,EAAE,SAAS,CAAC;IACnB,OAAO,EAAE,SAAS,CAAC;CACpB;AAED,KAAK,SAAS,GAAG,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;AAEjE,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/E,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/E,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/E,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7E,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,UAAU,aAAa;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,UAAU,mBAAmB;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,gBAAgB,CAAC;IACvB,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAChD,SAAS,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,GAAG,IAAI,CAAC;IACnE,YAAY,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAC/E,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAClC,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,qBAAa,YAAY;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,gBAAgB,CAAC;IACvB,WAAW,EAAE,gBAAgB,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAE5B,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACjD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,GAAG,IAAI,CAAC;IACnE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAC/E,cAAc,EAAE,aAAa,CAAC;IAC9B,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,iBAAiB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC3C,aAAa,EAAE,gBAAgB,EAAE,CAAC;IAClC,eAAe,EAAE,mBAAmB,CAAC;IACrC,iBAAiB,EAAE,gBAAgB,CAAC;IACpC,eAAe,EAAE,cAAc,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IAC7D,cAAc,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IACpC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IACrD,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACzC,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC,CAAC;IACzD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;gBAE5C,OAAO,EAAE,mBAAmB;IAuFxC,eAAe,CAAC,MAAM,GAAE,gBAAgB,EAAO,GAAG,IAAI;IAKtD;;;;;;;OAOG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAS3D;;;;;OAKG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhE;;;;;OAKG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,GAAE,MAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAU3F;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAwNlC;;;OAGG;IACH,cAAc,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAyM1E;;;OAGG;IACH,oBAAoB,IAAI,IAAI;IAW5B;;;;;OAKG;IACH,iBAAiB,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IA8CxC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO;IAI/C,qBAAqB,CACzB,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,EACxC,MAAM,EAAE,MAAM,EACd,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;QAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAC1D,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAItC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuE3B;;;;;;;;;;OAUG;IACH,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,gBAAgB,EAAE,SAAS,GAAG,SAAS,EAAE,YAAY,CAAC,EAAE,SAAS,GAAG,IAAI;IAiBzF;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,IAAI;IAapH;;OAEG;IACG,iBAAiB,CACrB,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,EAClD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,cAAc,EAAE,CAAC;IA8B5B;;;OAGG;IACG,gBAAgB,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkPhF,0BAA0B,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;IA0G7G;;;OAGG;IACG,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B9C,QAAQ,IAAI,MAAM;CAGnB;AACD,OAAO,EAAE,cAAc,EAAE,CAAC"}
|