@relayplane/proxy 1.2.0 → 1.3.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 (52) hide show
  1. package/README.md +94 -28
  2. package/dist/circuit-breaker.d.ts +39 -0
  3. package/dist/circuit-breaker.d.ts.map +1 -0
  4. package/dist/circuit-breaker.js +97 -0
  5. package/dist/circuit-breaker.js.map +1 -0
  6. package/dist/cli.d.ts +1 -1
  7. package/dist/cli.js +20 -12
  8. package/dist/cli.js.map +1 -1
  9. package/dist/health.d.ts +16 -0
  10. package/dist/health.d.ts.map +1 -0
  11. package/dist/health.js +80 -0
  12. package/dist/health.js.map +1 -0
  13. package/dist/index.d.ts +12 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +19 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/launcher.d.ts +10 -0
  18. package/dist/launcher.d.ts.map +1 -0
  19. package/dist/launcher.js +73 -0
  20. package/dist/launcher.js.map +1 -0
  21. package/dist/logger.d.ts +11 -0
  22. package/dist/logger.d.ts.map +1 -0
  23. package/dist/logger.js +13 -0
  24. package/dist/logger.js.map +1 -0
  25. package/dist/middleware.d.ts +60 -0
  26. package/dist/middleware.d.ts.map +1 -0
  27. package/dist/middleware.js +254 -0
  28. package/dist/middleware.js.map +1 -0
  29. package/dist/process-manager.d.ts +61 -0
  30. package/dist/process-manager.d.ts.map +1 -0
  31. package/dist/process-manager.js +173 -0
  32. package/dist/process-manager.js.map +1 -0
  33. package/dist/relay-config.d.ts +19 -0
  34. package/dist/relay-config.d.ts.map +1 -0
  35. package/dist/relay-config.js +32 -0
  36. package/dist/relay-config.js.map +1 -0
  37. package/dist/standalone-proxy.d.ts.map +1 -1
  38. package/dist/standalone-proxy.js +98 -7
  39. package/dist/standalone-proxy.js.map +1 -1
  40. package/dist/stats.d.ts +49 -0
  41. package/dist/stats.d.ts.map +1 -0
  42. package/dist/stats.js +72 -0
  43. package/dist/stats.js.map +1 -0
  44. package/dist/status.d.ts +46 -0
  45. package/dist/status.d.ts.map +1 -0
  46. package/dist/status.js +78 -0
  47. package/dist/status.js.map +1 -0
  48. package/dist/telemetry.d.ts +6 -0
  49. package/dist/telemetry.d.ts.map +1 -1
  50. package/dist/telemetry.js +14 -2
  51. package/dist/telemetry.js.map +1 -1
  52. package/package.json +1 -1
@@ -0,0 +1,10 @@
1
+ /**
2
+ * RelayPlane Proxy Launcher
3
+ *
4
+ * Entry point spawned as a child process by ProcessManager.
5
+ * Starts a standalone HTTP server with /health endpoint.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=launcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ /**
3
+ * RelayPlane Proxy Launcher
4
+ *
5
+ * Entry point spawned as a child process by ProcessManager.
6
+ * Starts a standalone HTTP server with /health endpoint.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ const http = __importStar(require("node:http"));
45
+ const health_js_1 = require("./health.js");
46
+ const port = parseInt(process.env['RELAYPLANE_PROXY_PORT'] ?? '4100', 10);
47
+ const host = process.env['RELAYPLANE_PROXY_HOST'] ?? '127.0.0.1';
48
+ const server = http.createServer((req, res) => {
49
+ const pathname = (req.url ?? '').split('?')[0] ?? '';
50
+ if (req.method === 'GET' && (pathname === '/health' || pathname === '/healthz')) {
51
+ (0, health_js_1.handleHealthRequest)(res);
52
+ return;
53
+ }
54
+ // For now, all other requests get a minimal response.
55
+ // The full proxy logic (standalone-proxy.ts) can be wired in later.
56
+ res.writeHead(404, { 'Content-Type': 'application/json' });
57
+ res.end(JSON.stringify({ error: 'Not found' }));
58
+ });
59
+ server.listen(port, host, () => {
60
+ console.log(`RelayPlane proxy launcher listening on http://${host}:${port}`);
61
+ });
62
+ // Graceful shutdown
63
+ function shutdown() {
64
+ console.log('RelayPlane proxy launcher shutting down...');
65
+ server.close(() => {
66
+ process.exit(0);
67
+ });
68
+ // Force exit after 5s
69
+ setTimeout(() => process.exit(1), 5000).unref();
70
+ }
71
+ process.on('SIGTERM', shutdown);
72
+ process.on('SIGINT', shutdown);
73
+ //# sourceMappingURL=launcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher.js","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,gDAAkC;AAClC,2CAAkD;AAElD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAC1E,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,WAAW,CAAC;AAEjE,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IAC5C,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAErD,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,UAAU,CAAC,EAAE,CAAC;QAChF,IAAA,+BAAmB,EAAC,GAAG,CAAC,CAAC;QACzB,OAAO;IACT,CAAC;IAED,sDAAsD;IACtD,oEAAoE;IACpE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;IAC7B,OAAO,CAAC,GAAG,CAAC,iDAAiD,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;AAC/E,CAAC,CAAC,CAAC;AAEH,oBAAoB;AACpB,SAAS,QAAQ;IACf,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC1D,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,sBAAsB;IACtB,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;AAClD,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Simple logger interface for RelayPlane Proxy.
3
+ * @packageDocumentation
4
+ */
5
+ export interface Logger {
6
+ info(msg: string, ...args: unknown[]): void;
7
+ warn(msg: string, ...args: unknown[]): void;
8
+ error(msg: string, ...args: unknown[]): void;
9
+ }
10
+ export declare const defaultLogger: Logger;
11
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC5C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAC9C;AAED,eAAO,MAAM,aAAa,EAAE,MAI3B,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * Simple logger interface for RelayPlane Proxy.
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.defaultLogger = void 0;
8
+ exports.defaultLogger = {
9
+ info: (msg, ...args) => console.log(`[relayplane] ${msg}`, ...args),
10
+ warn: (msg, ...args) => console.warn(`[relayplane] ${msg}`, ...args),
11
+ error: (msg, ...args) => console.error(`[relayplane] ${msg}`, ...args),
12
+ };
13
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAQU,QAAA,aAAa,GAAW;IACnC,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;IACnE,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;IACpE,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;CACvE,CAAC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * RelayPlane Proxy Middleware
3
+ *
4
+ * Wraps provider requests: tries proxy first (when circuit is healthy),
5
+ * falls back to direct on failure. This is the key integration point.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import { CircuitBreaker } from './circuit-breaker.js';
10
+ import { type RelayPlaneConfig } from './relay-config.js';
11
+ import { ProcessManager, type ProcessManagerOptions } from './process-manager.js';
12
+ import { StatsCollector } from './stats.js';
13
+ import { type ProxyStatus } from './status.js';
14
+ import { type Logger } from './logger.js';
15
+ export interface MiddlewareRequest {
16
+ method: string;
17
+ path: string;
18
+ headers: Record<string, string>;
19
+ body?: string | Buffer;
20
+ }
21
+ export interface MiddlewareResponse {
22
+ status: number;
23
+ headers: Record<string, string>;
24
+ body: string;
25
+ viaProxy: boolean;
26
+ }
27
+ export interface DirectSendFn {
28
+ (req: MiddlewareRequest): Promise<MiddlewareResponse>;
29
+ }
30
+ export interface MiddlewareOptions {
31
+ config?: Partial<RelayPlaneConfig>;
32
+ processManager?: ProcessManager;
33
+ processManagerOptions?: ProcessManagerOptions;
34
+ logger?: Logger;
35
+ }
36
+ export declare class RelayPlaneMiddleware {
37
+ readonly circuitBreaker: CircuitBreaker;
38
+ readonly stats: StatsCollector;
39
+ private readonly statusReporter;
40
+ private readonly proxyUrl;
41
+ private readonly enabled;
42
+ private readonly autoStart;
43
+ private readonly logger;
44
+ private probeInterval;
45
+ private processManager;
46
+ constructor(config?: Partial<RelayPlaneConfig>);
47
+ constructor(opts?: MiddlewareOptions);
48
+ getProcessManager(): ProcessManager | null;
49
+ getStatus(): ProxyStatus;
50
+ formatStatus(): string;
51
+ /**
52
+ * Route a request: proxy if healthy, direct otherwise.
53
+ */
54
+ route(req: MiddlewareRequest, directSend: DirectSendFn): Promise<MiddlewareResponse>;
55
+ private sendViaProxy;
56
+ private startProbing;
57
+ private stopProbing;
58
+ destroy(): void;
59
+ }
60
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,aAAa,CAAC;AAEzD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,oBAAoB;IAC/B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,aAAa,CAA+C;IACpE,OAAO,CAAC,cAAc,CAA+B;gBAEzC,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC;gBAClC,IAAI,CAAC,EAAE,iBAAiB;IA4EpC,iBAAiB,IAAI,cAAc,GAAG,IAAI;IAI1C,SAAS,IAAI,WAAW;IAIxB,YAAY,IAAI,MAAM;IAItB;;OAEG;IACG,KAAK,CAAC,GAAG,EAAE,iBAAiB,EAAE,UAAU,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA6C1F,OAAO,CAAC,YAAY;IAoCpB,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,WAAW;IAOnB,OAAO,IAAI,IAAI;CAQhB"}
@@ -0,0 +1,254 @@
1
+ "use strict";
2
+ /**
3
+ * RelayPlane Proxy Middleware
4
+ *
5
+ * Wraps provider requests: tries proxy first (when circuit is healthy),
6
+ * falls back to direct on failure. This is the key integration point.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.RelayPlaneMiddleware = void 0;
45
+ const http = __importStar(require("node:http"));
46
+ const circuit_breaker_js_1 = require("./circuit-breaker.js");
47
+ const health_js_1 = require("./health.js");
48
+ const relay_config_js_1 = require("./relay-config.js");
49
+ const process_manager_js_1 = require("./process-manager.js");
50
+ const stats_js_1 = require("./stats.js");
51
+ const status_js_1 = require("./status.js");
52
+ const logger_js_1 = require("./logger.js");
53
+ class RelayPlaneMiddleware {
54
+ circuitBreaker;
55
+ stats;
56
+ statusReporter;
57
+ proxyUrl;
58
+ enabled;
59
+ autoStart;
60
+ logger;
61
+ probeInterval = null;
62
+ processManager = null;
63
+ constructor(configOrOpts) {
64
+ let config;
65
+ let pm;
66
+ let pmOpts;
67
+ let logger;
68
+ if (configOrOpts && 'config' in configOrOpts) {
69
+ const opts = configOrOpts;
70
+ config = opts.config;
71
+ pm = opts.processManager;
72
+ pmOpts = opts.processManagerOptions;
73
+ logger = opts.logger;
74
+ }
75
+ else {
76
+ config = configOrOpts;
77
+ }
78
+ const resolved = (0, relay_config_js_1.resolveConfig)(config);
79
+ this.enabled = resolved.enabled;
80
+ this.proxyUrl = resolved.proxyUrl;
81
+ this.autoStart = resolved.autoStart;
82
+ this.logger = logger ?? logger_js_1.defaultLogger;
83
+ this.circuitBreaker = new circuit_breaker_js_1.CircuitBreaker(resolved.circuitBreaker);
84
+ this.stats = new stats_js_1.StatsCollector();
85
+ // Set up process manager
86
+ if (pm) {
87
+ this.processManager = pm;
88
+ }
89
+ else if (this.autoStart && this.enabled) {
90
+ this.processManager = new process_manager_js_1.ProcessManager({
91
+ ...pmOpts,
92
+ circuitBreaker: this.circuitBreaker,
93
+ });
94
+ }
95
+ // Status reporter
96
+ this.statusReporter = new status_js_1.StatusReporter({
97
+ enabled: this.enabled,
98
+ proxyUrl: this.proxyUrl,
99
+ circuitBreaker: this.circuitBreaker,
100
+ statsCollector: this.stats,
101
+ processManager: this.processManager,
102
+ });
103
+ // Wire circuit breaker state changes → stats + logging + probing
104
+ this.circuitBreaker.on('stateChange', ({ from, to }) => {
105
+ this.stats.recordStateTransition(from, to);
106
+ if (to === 'OPEN') {
107
+ this.logger.error(`Circuit breaker tripped OPEN (was ${from})`);
108
+ this.startProbing();
109
+ }
110
+ else if (to === 'CLOSED') {
111
+ this.logger.info(`Circuit breaker recovered: ${from} → CLOSED`);
112
+ this.stopProbing();
113
+ }
114
+ else {
115
+ this.stopProbing();
116
+ }
117
+ });
118
+ // Wire process manager events
119
+ if (this.processManager) {
120
+ this.processManager.on('crash', ({ code, signal }) => {
121
+ this.statusReporter.incrementRestarts();
122
+ this.statusReporter.setLastError(`Process crashed (code=${code}, signal=${signal})`);
123
+ });
124
+ this.processManager.on('error', (err) => {
125
+ this.statusReporter.setLastError(err.message);
126
+ });
127
+ }
128
+ // Auto-start
129
+ if (this.processManager && this.autoStart && this.enabled) {
130
+ this.processManager.start();
131
+ }
132
+ }
133
+ getProcessManager() {
134
+ return this.processManager;
135
+ }
136
+ getStatus() {
137
+ return this.statusReporter.getStatus();
138
+ }
139
+ formatStatus() {
140
+ return this.statusReporter.formatStatus();
141
+ }
142
+ /**
143
+ * Route a request: proxy if healthy, direct otherwise.
144
+ */
145
+ async route(req, directSend) {
146
+ if (!this.enabled || !this.circuitBreaker.isHealthy()) {
147
+ const reason = !this.enabled ? 'proxy disabled' : 'circuit breaker OPEN';
148
+ this.logger.warn(`Falling back to direct: ${reason}`);
149
+ const start = Date.now();
150
+ const resp = await directSend(req);
151
+ this.stats.recordRequest({
152
+ timestamp: start,
153
+ latencyMs: Date.now() - start,
154
+ viaProxy: false,
155
+ success: resp.status < 500,
156
+ });
157
+ return resp;
158
+ }
159
+ const start = Date.now();
160
+ try {
161
+ const resp = await this.sendViaProxy(req);
162
+ this.circuitBreaker.recordSuccess();
163
+ this.stats.recordRequest({
164
+ timestamp: start,
165
+ latencyMs: Date.now() - start,
166
+ viaProxy: true,
167
+ success: true,
168
+ });
169
+ return resp;
170
+ }
171
+ catch (err) {
172
+ this.circuitBreaker.recordFailure();
173
+ const errMsg = err instanceof Error ? err.message : String(err);
174
+ this.logger.warn(`Falling back to direct: proxy error (${errMsg})`);
175
+ this.statusReporter.setLastError(errMsg);
176
+ const directStart = Date.now();
177
+ const resp = await directSend(req);
178
+ this.stats.recordRequest({
179
+ timestamp: start,
180
+ latencyMs: Date.now() - start,
181
+ viaProxy: false,
182
+ success: resp.status < 500,
183
+ });
184
+ return resp;
185
+ }
186
+ }
187
+ sendViaProxy(req) {
188
+ const url = new URL(req.path, this.proxyUrl);
189
+ const timeoutMs = this.circuitBreaker.requestTimeoutMs;
190
+ return new Promise((resolve, reject) => {
191
+ const proxyReq = http.request(url, {
192
+ method: req.method,
193
+ headers: req.headers,
194
+ timeout: timeoutMs,
195
+ }, (res) => {
196
+ let data = '';
197
+ res.on('data', (chunk) => (data += chunk));
198
+ res.on('end', () => {
199
+ if (res.statusCode && res.statusCode >= 500) {
200
+ reject(new Error(`Proxy returned ${res.statusCode}`));
201
+ return;
202
+ }
203
+ const headers = {};
204
+ for (const [k, v] of Object.entries(res.headers)) {
205
+ if (typeof v === 'string')
206
+ headers[k] = v;
207
+ }
208
+ resolve({ status: res.statusCode ?? 200, headers, body: data, viaProxy: true });
209
+ });
210
+ });
211
+ proxyReq.on('error', reject);
212
+ proxyReq.on('timeout', () => {
213
+ proxyReq.destroy();
214
+ reject(new Error('Proxy request timeout'));
215
+ });
216
+ if (req.body)
217
+ proxyReq.write(req.body);
218
+ proxyReq.end();
219
+ });
220
+ }
221
+ startProbing() {
222
+ this.stopProbing();
223
+ this.probeInterval = setInterval(async () => {
224
+ if (this.circuitBreaker.getState() !== 'OPEN') {
225
+ this.stopProbing();
226
+ return;
227
+ }
228
+ const ok = await (0, health_js_1.probeHealth)(this.proxyUrl);
229
+ if (ok) {
230
+ this.logger.info('Health probe succeeded, transitioning to HALF-OPEN');
231
+ this.circuitBreaker.recordSuccess();
232
+ }
233
+ }, 15_000);
234
+ if (this.probeInterval && typeof this.probeInterval === 'object' && 'unref' in this.probeInterval) {
235
+ this.probeInterval.unref();
236
+ }
237
+ }
238
+ stopProbing() {
239
+ if (this.probeInterval) {
240
+ clearInterval(this.probeInterval);
241
+ this.probeInterval = null;
242
+ }
243
+ }
244
+ destroy() {
245
+ this.stopProbing();
246
+ if (this.processManager) {
247
+ this.processManager.destroy();
248
+ this.processManager = null;
249
+ }
250
+ this.circuitBreaker.destroy();
251
+ }
252
+ }
253
+ exports.RelayPlaneMiddleware = RelayPlaneMiddleware;
254
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Process Manager for RelayPlane Proxy
3
+ *
4
+ * Spawns the proxy as a child process, monitors health,
5
+ * handles crashes with exponential backoff restarts.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import { EventEmitter } from 'node:events';
10
+ import { type CircuitBreaker } from './circuit-breaker.js';
11
+ export interface ProcessManagerOptions {
12
+ /** Command to spawn (default: process.execPath) */
13
+ command?: string;
14
+ /** Arguments for the command (default: launcher path) */
15
+ args?: string[];
16
+ /** Environment variables for the child process */
17
+ env?: Record<string, string>;
18
+ /** Initial restart delay in ms (default: 60000) */
19
+ restartDelayMs?: number;
20
+ /** Max restart delay in ms (default: 300000 = 5 min) */
21
+ maxRestartDelayMs?: number;
22
+ /** Max restart attempts within the window (default: 5) */
23
+ maxRestartAttempts?: number;
24
+ /** Window for counting restart attempts in ms (default: 600000 = 10 min) */
25
+ restartWindowMs?: number;
26
+ /** Circuit breaker instance to mark OPEN on crash */
27
+ circuitBreaker?: CircuitBreaker;
28
+ }
29
+ export declare class ProcessManager extends EventEmitter {
30
+ private child;
31
+ private readonly command;
32
+ private readonly args;
33
+ private readonly env;
34
+ private readonly restartDelayMs;
35
+ private readonly maxRestartDelayMs;
36
+ private readonly maxRestartAttempts;
37
+ private readonly restartWindowMs;
38
+ private readonly circuitBreaker?;
39
+ private restartTimestamps;
40
+ private currentDelay;
41
+ private restartTimer;
42
+ private stopping;
43
+ private started;
44
+ constructor(opts?: ProcessManagerOptions);
45
+ /** Start the proxy child process. */
46
+ start(): void;
47
+ /** Stop the proxy child process. */
48
+ stop(): void;
49
+ /** Restart the proxy (stop then start). */
50
+ restart(): void;
51
+ /** Whether the child process is currently running. */
52
+ isRunning(): boolean;
53
+ /** Get the PID of the child process, or null if not running. */
54
+ getPid(): number | null;
55
+ /** Clean up resources. */
56
+ destroy(): void;
57
+ private spawnChild;
58
+ private scheduleRestart;
59
+ private clearRestartTimer;
60
+ }
61
+ //# sourceMappingURL=process-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../src/process-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,WAAW,qBAAqB;IACpC,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,kDAAkD;IAClD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAW;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAiB;IAEjD,OAAO,CAAC,iBAAiB,CAAgB;IACzC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAA8C;IAClE,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEZ,IAAI,GAAE,qBAA0B;IAa5C,qCAAqC;IACrC,KAAK,IAAI,IAAI;IAOb,oCAAoC;IACpC,IAAI,IAAI,IAAI;IAYZ,2CAA2C;IAC3C,OAAO,IAAI,IAAI;IAKf,sDAAsD;IACtD,SAAS,IAAI,OAAO;IAIpB,gEAAgE;IAChE,MAAM,IAAI,MAAM,GAAG,IAAI;IAIvB,0BAA0B;IAC1B,OAAO,IAAI,IAAI;IAKf,OAAO,CAAC,UAAU;IA4DlB,OAAO,CAAC,eAAe;IAmCvB,OAAO,CAAC,iBAAiB;CAQ1B"}