grpc-resilient 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Gateway gRPC Metrics Tracker
3
+ *
4
+ * Tracks gRPC client metrics for monitoring and OpenTelemetry integration.
5
+ * Designed specifically for API Gateway/Proxy scenarios.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const tracker = new GatewayMetricsTracker();
10
+ *
11
+ * tracker.recordCallStart();
12
+ * const startTime = Date.now();
13
+ * // ... make call ...
14
+ * tracker.recordSuccess(Date.now() - startTime);
15
+ *
16
+ * console.log(tracker.getMetrics());
17
+ * console.log(`Success rate: ${tracker.getSuccessRate()}%`);
18
+ * ```
19
+ *
20
+ * @packageDocumentation
21
+ */
22
+ import { GATEWAY_DEFAULT_METRICS } from './types.js';
23
+ /**
24
+ * Metrics tracker for Gateway gRPC clients
25
+ *
26
+ * Thread-safe metrics collection with:
27
+ * - Call counting (total, success, failure)
28
+ * - Latency tracking (min, max, average)
29
+ * - Retry counting
30
+ * - Success rate calculation
31
+ */
32
+ export class GatewayMetricsTracker {
33
+ metrics;
34
+ latencySum = 0;
35
+ constructor() {
36
+ this.metrics = { ...GATEWAY_DEFAULT_METRICS, lastResetAt: new Date() };
37
+ }
38
+ /**
39
+ * Record a call start
40
+ *
41
+ * Call this at the beginning of each gRPC call attempt.
42
+ */
43
+ recordCallStart() {
44
+ this.metrics.totalCalls++;
45
+ }
46
+ /**
47
+ * Record a successful call with latency
48
+ *
49
+ * @param latencyMs - The call latency in milliseconds
50
+ */
51
+ recordSuccess(latencyMs) {
52
+ this.metrics.successfulCalls++;
53
+ this.updateLatency(latencyMs);
54
+ }
55
+ /**
56
+ * Record a failed call
57
+ *
58
+ * Call this when a gRPC call fails after all retry attempts.
59
+ */
60
+ recordFailure() {
61
+ this.metrics.failedCalls++;
62
+ }
63
+ /**
64
+ * Record a retry attempt
65
+ *
66
+ * Call this for each retry attempt (not the initial attempt).
67
+ */
68
+ recordRetry() {
69
+ this.metrics.totalRetries++;
70
+ }
71
+ /**
72
+ * Update latency metrics
73
+ */
74
+ updateLatency(latencyMs) {
75
+ this.latencySum += latencyMs;
76
+ if (latencyMs > this.metrics.maxLatencyMs) {
77
+ this.metrics.maxLatencyMs = latencyMs;
78
+ }
79
+ if (latencyMs < this.metrics.minLatencyMs) {
80
+ this.metrics.minLatencyMs = latencyMs;
81
+ }
82
+ this.metrics.avgLatencyMs = Math.round(this.latencySum / this.metrics.successfulCalls);
83
+ }
84
+ /**
85
+ * Get current metrics snapshot
86
+ *
87
+ * Returns a copy of the current metrics state.
88
+ *
89
+ * @returns Current metrics
90
+ */
91
+ getMetrics() {
92
+ return { ...this.metrics };
93
+ }
94
+ /**
95
+ * Reset all metrics to initial values
96
+ *
97
+ * Useful for periodic metric collection windows.
98
+ */
99
+ reset() {
100
+ this.metrics = { ...GATEWAY_DEFAULT_METRICS, lastResetAt: new Date() };
101
+ this.latencySum = 0;
102
+ }
103
+ /**
104
+ * Get success rate as a percentage (0-100)
105
+ *
106
+ * @returns Success rate percentage
107
+ */
108
+ getSuccessRate() {
109
+ if (this.metrics.totalCalls === 0) {
110
+ return 100;
111
+ }
112
+ return Math.round((this.metrics.successfulCalls / this.metrics.totalCalls) * 100);
113
+ }
114
+ /**
115
+ * Get failure rate as a percentage (0-100)
116
+ *
117
+ * @returns Failure rate percentage
118
+ */
119
+ getFailureRate() {
120
+ if (this.metrics.totalCalls === 0) {
121
+ return 0;
122
+ }
123
+ return Math.round((this.metrics.failedCalls / this.metrics.totalCalls) * 100);
124
+ }
125
+ /**
126
+ * Check if the client is healthy based on success rate
127
+ *
128
+ * @param threshold - Minimum success rate to be considered healthy (default: 90)
129
+ * @returns true if success rate is above threshold
130
+ */
131
+ isHealthy(threshold = 90) {
132
+ return this.getSuccessRate() >= threshold;
133
+ }
134
+ }
135
+ //# sourceMappingURL=GatewayMetricsTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GatewayMetricsTracker.js","sourceRoot":"","sources":["../../src/gateway/GatewayMetricsTracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,OAAO,qBAAqB;IACxB,OAAO,CAAuB;IAC9B,UAAU,GAAG,CAAC,CAAC;IAEvB;QACE,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,uBAAuB,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;IACzE,CAAC;IAED;;;;OAIG;IACH,eAAe;QACb,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,aAAa,CAAC,SAAiB;QAC7B,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;QAC/B,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACH,aAAa;QACX,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,WAAW;QACT,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,SAAiB;QACrC,IAAI,CAAC,UAAU,IAAI,SAAS,CAAC;QAE7B,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAC1C,IAAI,CAAC,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;QACxC,CAAC;QACD,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAC1C,IAAI,CAAC,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;QACxC,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACzF,CAAC;IAED;;;;;;OAMG;IACH,UAAU;QACR,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,uBAAuB,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;QACvE,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;IACtB,CAAC;IAED;;;;OAIG;IACH,cAAc;QACZ,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,GAAG,CAAC;QACb,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;IACpF,CAAC;IAED;;;;OAIG;IACH,cAAc;QACZ,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;IAChF,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,SAAS,GAAG,EAAE;QACtB,OAAO,IAAI,CAAC,cAAc,EAAE,IAAI,SAAS,CAAC;IAC5C,CAAC;CACF"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Gateway gRPC Retry Handler
3
+ *
4
+ * Handles retry logic for gRPC calls with:
5
+ * - Exponential backoff
6
+ * - Jitter to prevent thundering herd
7
+ * - Retryable error detection
8
+ * - Connection error detection
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import {
13
+ * isRetryableError,
14
+ * isConnectionError,
15
+ * calculateBackoffDelay,
16
+ * sleep,
17
+ * } from 'grpc-resilient/gateway';
18
+ *
19
+ * if (isRetryableError(error)) {
20
+ * const delay = calculateBackoffDelay(1000, attempt);
21
+ * await sleep(delay);
22
+ * // retry...
23
+ * }
24
+ * ```
25
+ *
26
+ * @packageDocumentation
27
+ */
28
+ /**
29
+ * Check if the error is retryable based on gRPC status code
30
+ *
31
+ * @param error - The error to check
32
+ * @returns true if the error is retryable
33
+ */
34
+ export declare function isRetryableError(error: Error): boolean;
35
+ /**
36
+ * Check if the error indicates a connection problem
37
+ *
38
+ * Connection errors trigger reconnection logic in addition to retry.
39
+ *
40
+ * @param error - The error to check
41
+ * @returns true if the error indicates a connection issue
42
+ */
43
+ export declare function isConnectionError(error: Error): boolean;
44
+ /**
45
+ * Calculate delay with exponential backoff and jitter
46
+ *
47
+ * Uses the formula: delay = baseDelay * 2^attempt + jitter
48
+ * Where jitter is +/- 25% of the exponential delay.
49
+ *
50
+ * This prevents the "thundering herd" problem where many clients
51
+ * retry at exactly the same time after a failure.
52
+ *
53
+ * @param baseDelayMs - Base delay in milliseconds
54
+ * @param attempt - Current attempt number (0-indexed)
55
+ * @param maxDelayMs - Maximum delay cap (optional, default: 30000ms)
56
+ * @returns Calculated delay in milliseconds
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * // attempt 0: ~1000ms (base)
61
+ * // attempt 1: ~2000ms
62
+ * // attempt 2: ~4000ms
63
+ * // attempt 3: ~8000ms
64
+ * // etc. (capped at maxDelayMs)
65
+ * const delay = calculateBackoffDelay(1000, attempt, 30000);
66
+ * ```
67
+ */
68
+ export declare function calculateBackoffDelay(baseDelayMs: number, attempt: number, maxDelayMs?: number): number;
69
+ /**
70
+ * Sleep for a specified duration
71
+ *
72
+ * Promisified setTimeout for use with async/await.
73
+ *
74
+ * @param ms - Duration to sleep in milliseconds
75
+ * @returns Promise that resolves after the specified duration
76
+ */
77
+ export declare function sleep(ms: number): Promise<void>;
78
+ /**
79
+ * Get human-readable error description for logging
80
+ *
81
+ * @param error - The gRPC error
82
+ * @returns Human-readable description
83
+ */
84
+ export declare function getErrorDescription(error: Error): string;
85
+ //# sourceMappingURL=GatewayRetryHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GatewayRetryHandler.d.ts","sourceRoot":"","sources":["../../src/gateway/GatewayRetryHandler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAmBH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAGtD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAGvD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,UAAU,SAAQ,GACjB,MAAM,CAOR;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAwBxD"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Gateway gRPC Retry Handler
3
+ *
4
+ * Handles retry logic for gRPC calls with:
5
+ * - Exponential backoff
6
+ * - Jitter to prevent thundering herd
7
+ * - Retryable error detection
8
+ * - Connection error detection
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import {
13
+ * isRetryableError,
14
+ * isConnectionError,
15
+ * calculateBackoffDelay,
16
+ * sleep,
17
+ * } from 'grpc-resilient/gateway';
18
+ *
19
+ * if (isRetryableError(error)) {
20
+ * const delay = calculateBackoffDelay(1000, attempt);
21
+ * await sleep(delay);
22
+ * // retry...
23
+ * }
24
+ * ```
25
+ *
26
+ * @packageDocumentation
27
+ */
28
+ import * as grpc from '@grpc/grpc-js';
29
+ /**
30
+ * gRPC status codes that are considered retryable
31
+ *
32
+ * - UNAVAILABLE: Server is temporarily unavailable
33
+ * - DEADLINE_EXCEEDED: Call timed out
34
+ * - RESOURCE_EXHAUSTED: Rate limiting or resource constraints
35
+ * - ABORTED: Operation was aborted, can be retried
36
+ */
37
+ const RETRYABLE_CODES = [
38
+ grpc.status.UNAVAILABLE,
39
+ grpc.status.DEADLINE_EXCEEDED,
40
+ grpc.status.RESOURCE_EXHAUSTED,
41
+ grpc.status.ABORTED,
42
+ ];
43
+ /**
44
+ * Check if the error is retryable based on gRPC status code
45
+ *
46
+ * @param error - The error to check
47
+ * @returns true if the error is retryable
48
+ */
49
+ export function isRetryableError(error) {
50
+ const grpcError = error;
51
+ return RETRYABLE_CODES.includes(grpcError.code);
52
+ }
53
+ /**
54
+ * Check if the error indicates a connection problem
55
+ *
56
+ * Connection errors trigger reconnection logic in addition to retry.
57
+ *
58
+ * @param error - The error to check
59
+ * @returns true if the error indicates a connection issue
60
+ */
61
+ export function isConnectionError(error) {
62
+ const grpcError = error;
63
+ return grpcError.code === grpc.status.UNAVAILABLE;
64
+ }
65
+ /**
66
+ * Calculate delay with exponential backoff and jitter
67
+ *
68
+ * Uses the formula: delay = baseDelay * 2^attempt + jitter
69
+ * Where jitter is +/- 25% of the exponential delay.
70
+ *
71
+ * This prevents the "thundering herd" problem where many clients
72
+ * retry at exactly the same time after a failure.
73
+ *
74
+ * @param baseDelayMs - Base delay in milliseconds
75
+ * @param attempt - Current attempt number (0-indexed)
76
+ * @param maxDelayMs - Maximum delay cap (optional, default: 30000ms)
77
+ * @returns Calculated delay in milliseconds
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * // attempt 0: ~1000ms (base)
82
+ * // attempt 1: ~2000ms
83
+ * // attempt 2: ~4000ms
84
+ * // attempt 3: ~8000ms
85
+ * // etc. (capped at maxDelayMs)
86
+ * const delay = calculateBackoffDelay(1000, attempt, 30000);
87
+ * ```
88
+ */
89
+ export function calculateBackoffDelay(baseDelayMs, attempt, maxDelayMs = 30000) {
90
+ const exponentialDelay = baseDelayMs * Math.pow(2, attempt);
91
+ // Add jitter (+/- 25% of the delay) to prevent thundering herd
92
+ const jitter = exponentialDelay * 0.25 * (Math.random() * 2 - 1);
93
+ const delay = exponentialDelay + jitter;
94
+ return Math.min(delay, maxDelayMs);
95
+ }
96
+ /**
97
+ * Sleep for a specified duration
98
+ *
99
+ * Promisified setTimeout for use with async/await.
100
+ *
101
+ * @param ms - Duration to sleep in milliseconds
102
+ * @returns Promise that resolves after the specified duration
103
+ */
104
+ export function sleep(ms) {
105
+ return new Promise((resolve) => setTimeout(resolve, ms));
106
+ }
107
+ /**
108
+ * Get human-readable error description for logging
109
+ *
110
+ * @param error - The gRPC error
111
+ * @returns Human-readable description
112
+ */
113
+ export function getErrorDescription(error) {
114
+ const grpcError = error;
115
+ const codeDescriptions = {
116
+ [grpc.status.OK]: 'OK',
117
+ [grpc.status.CANCELLED]: 'Cancelled',
118
+ [grpc.status.UNKNOWN]: 'Unknown error',
119
+ [grpc.status.INVALID_ARGUMENT]: 'Invalid argument',
120
+ [grpc.status.DEADLINE_EXCEEDED]: 'Deadline exceeded',
121
+ [grpc.status.NOT_FOUND]: 'Not found',
122
+ [grpc.status.ALREADY_EXISTS]: 'Already exists',
123
+ [grpc.status.PERMISSION_DENIED]: 'Permission denied',
124
+ [grpc.status.RESOURCE_EXHAUSTED]: 'Resource exhausted',
125
+ [grpc.status.FAILED_PRECONDITION]: 'Failed precondition',
126
+ [grpc.status.ABORTED]: 'Aborted',
127
+ [grpc.status.OUT_OF_RANGE]: 'Out of range',
128
+ [grpc.status.UNIMPLEMENTED]: 'Unimplemented',
129
+ [grpc.status.INTERNAL]: 'Internal error',
130
+ [grpc.status.UNAVAILABLE]: 'Service unavailable',
131
+ [grpc.status.DATA_LOSS]: 'Data loss',
132
+ [grpc.status.UNAUTHENTICATED]: 'Unauthenticated',
133
+ };
134
+ const description = codeDescriptions[grpcError.code] ?? 'Unknown';
135
+ return `${description} (code: ${grpcError.code})`;
136
+ }
137
+ //# sourceMappingURL=GatewayRetryHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GatewayRetryHandler.js","sourceRoot":"","sources":["../../src/gateway/GatewayRetryHandler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Gateway gRPC Client Module
3
+ *
4
+ * Provides resilient gRPC client infrastructure for API Gateway/Proxy services.
5
+ *
6
+ * Use this module when building:
7
+ * - API Gateways that proxy requests to microservices
8
+ * - BFF (Backend for Frontend) services
9
+ * - Service mesh proxies
10
+ * - Load balancers with gRPC support
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import {
15
+ * GatewayGrpcClient,
16
+ * type GatewayClientConfig,
17
+ * type GatewayCallOptions,
18
+ * type GatewayLogger,
19
+ * } from 'grpc-resilient/gateway';
20
+ *
21
+ * class AuthServiceProxy extends GatewayGrpcClient<AuthClient> {
22
+ * constructor(config: GatewayClientConfig, logger: GatewayLogger) {
23
+ * super(config, logger);
24
+ * }
25
+ *
26
+ * async validateToken(request: ValidateRequest) {
27
+ * return this.callWithRetry('ValidateToken', request);
28
+ * }
29
+ * }
30
+ * ```
31
+ *
32
+ * @packageDocumentation
33
+ * @module gateway
34
+ */
35
+ export { GatewayGrpcClient } from './GatewayGrpcClient.js';
36
+ export { GatewayMetricsTracker } from './GatewayMetricsTracker.js';
37
+ export { createGatewayCredentials, validateTlsConfig } from './GatewayCredentialsProvider.js';
38
+ export { isRetryableError, isConnectionError, calculateBackoffDelay, sleep, getErrorDescription, } from './GatewayRetryHandler.js';
39
+ export { GatewayConnectionState, GATEWAY_DEFAULT_CONFIG, GATEWAY_DEFAULT_METRICS, type GatewayClientConfig, type GatewayCallOptions, type GatewayServiceHealth, type GatewayClientMetrics, type GatewayLogger, type TlsCredentialsOptions, } from './types.js';
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gateway/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAC9F,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,EACL,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,qBAAqB,GAC3B,MAAM,YAAY,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Gateway gRPC Client Module
3
+ *
4
+ * Provides resilient gRPC client infrastructure for API Gateway/Proxy services.
5
+ *
6
+ * Use this module when building:
7
+ * - API Gateways that proxy requests to microservices
8
+ * - BFF (Backend for Frontend) services
9
+ * - Service mesh proxies
10
+ * - Load balancers with gRPC support
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import {
15
+ * GatewayGrpcClient,
16
+ * type GatewayClientConfig,
17
+ * type GatewayCallOptions,
18
+ * type GatewayLogger,
19
+ * } from 'grpc-resilient/gateway';
20
+ *
21
+ * class AuthServiceProxy extends GatewayGrpcClient<AuthClient> {
22
+ * constructor(config: GatewayClientConfig, logger: GatewayLogger) {
23
+ * super(config, logger);
24
+ * }
25
+ *
26
+ * async validateToken(request: ValidateRequest) {
27
+ * return this.callWithRetry('ValidateToken', request);
28
+ * }
29
+ * }
30
+ * ```
31
+ *
32
+ * @packageDocumentation
33
+ * @module gateway
34
+ */
35
+ // Main client class
36
+ export { GatewayGrpcClient } from './GatewayGrpcClient.js';
37
+ // Supporting modules
38
+ export { GatewayMetricsTracker } from './GatewayMetricsTracker.js';
39
+ export { createGatewayCredentials, validateTlsConfig } from './GatewayCredentialsProvider.js';
40
+ export { isRetryableError, isConnectionError, calculateBackoffDelay, sleep, getErrorDescription, } from './GatewayRetryHandler.js';
41
+ // Types
42
+ export { GatewayConnectionState, GATEWAY_DEFAULT_CONFIG, GATEWAY_DEFAULT_METRICS, } from './types.js';
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gateway/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,oBAAoB;AACpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,qBAAqB;AACrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAC9F,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,EACL,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAElC,QAAQ;AACR,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,GAOxB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Gateway gRPC Client Types
3
+ *
4
+ * Type definitions for API Gateway/Proxy gRPC client infrastructure.
5
+ * Designed for services that act as reverse proxies to multiple backend services.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import type { Options as ProtoLoaderOptions } from '@grpc/proto-loader';
10
+ /**
11
+ * Connection state for gateway clients
12
+ * @category Gateway
13
+ */
14
+ export declare enum GatewayConnectionState {
15
+ /** Not connected to the backend service */
16
+ DISCONNECTED = "DISCONNECTED",
17
+ /** Initial connection attempt in progress */
18
+ CONNECTING = "CONNECTING",
19
+ /** Successfully connected and ready */
20
+ CONNECTED = "CONNECTED",
21
+ /** Reconnecting after connection loss */
22
+ RECONNECTING = "RECONNECTING"
23
+ }
24
+ /**
25
+ * Metrics for gateway gRPC clients (OpenTelemetry-compatible)
26
+ * @category Gateway
27
+ */
28
+ export interface GatewayClientMetrics {
29
+ /** Total number of calls made */
30
+ totalCalls: number;
31
+ /** Number of successful calls */
32
+ successfulCalls: number;
33
+ /** Number of failed calls */
34
+ failedCalls: number;
35
+ /** Total retry attempts */
36
+ totalRetries: number;
37
+ /** Average latency in milliseconds */
38
+ avgLatencyMs: number;
39
+ /** Maximum latency recorded */
40
+ maxLatencyMs: number;
41
+ /** Minimum latency recorded */
42
+ minLatencyMs: number;
43
+ /** Last metrics reset timestamp */
44
+ lastResetAt: Date;
45
+ }
46
+ /**
47
+ * Configuration for gateway gRPC client
48
+ * @category Gateway
49
+ */
50
+ export interface GatewayClientConfig {
51
+ /** Service name for logging and metrics */
52
+ serviceName: string;
53
+ /** gRPC server URL (host:port) */
54
+ grpcUrl: string;
55
+ /** Proto file name (relative to protosPath) */
56
+ protoFile: string;
57
+ /** Package name in proto file */
58
+ packageName: string;
59
+ /** Service class name in proto file */
60
+ serviceClassName: string;
61
+ /** Absolute path to protos directory */
62
+ protosPath: string;
63
+ /** Call timeout in milliseconds @default 5000 */
64
+ timeoutMs?: number;
65
+ /** Number of retry attempts @default 3 */
66
+ retryCount?: number;
67
+ /** Base delay between retries in ms @default 1000 */
68
+ retryDelayMs?: number;
69
+ /** Maximum reconnection attempts @default Infinity */
70
+ maxReconnectAttempts?: number;
71
+ /** Maximum delay between reconnects in ms @default 30000 */
72
+ maxReconnectDelayMs?: number;
73
+ /** Initial delay for reconnection in ms @default 1000 */
74
+ initialReconnectDelayMs?: number;
75
+ /** Custom proto loader options */
76
+ protoOptions?: ProtoLoaderOptions;
77
+ /** Use TLS for connection @default false */
78
+ useTls?: boolean;
79
+ /** CA certificate path for TLS */
80
+ tlsCaCertPath?: string;
81
+ /** Client certificate path for mutual TLS */
82
+ tlsClientCertPath?: string;
83
+ /** Client key path for mutual TLS */
84
+ tlsClientKeyPath?: string;
85
+ /** Keepalive time in ms @default 30000 */
86
+ keepaliveTimeMs?: number;
87
+ /** Keepalive timeout in ms @default 10000 */
88
+ keepaliveTimeoutMs?: number;
89
+ }
90
+ /**
91
+ * Health status for gateway client
92
+ * @category Gateway
93
+ */
94
+ export interface GatewayServiceHealth {
95
+ /** Current connection state */
96
+ state: GatewayConnectionState;
97
+ /** Whether the service is healthy and connected */
98
+ healthy: boolean;
99
+ /** Last recorded latency in milliseconds */
100
+ latencyMs: number;
101
+ /** Timestamp of last health check */
102
+ lastCheck: Date;
103
+ /** Timestamp of last successful connection */
104
+ lastConnectedAt: Date | null;
105
+ /** Timestamp of last error */
106
+ lastErrorAt: Date | null;
107
+ /** Last error message if any */
108
+ error?: string;
109
+ /** Number of reconnection attempts */
110
+ reconnectAttempts: number;
111
+ /** Current metrics snapshot */
112
+ metrics: GatewayClientMetrics;
113
+ }
114
+ /**
115
+ * Per-call options for gateway gRPC calls
116
+ * @category Gateway
117
+ */
118
+ export interface GatewayCallOptions {
119
+ /** Timeout override for this specific call (in milliseconds) */
120
+ timeoutMs?: number;
121
+ /** Locale for i18n (sent via gRPC metadata as accept-language) */
122
+ locale?: string;
123
+ /** Client URL for callbacks (sent via gRPC metadata as x-client-url) */
124
+ clientUrl?: string;
125
+ /** Skip retry for this call */
126
+ skipRetry?: boolean;
127
+ /** Additional metadata to send with the call */
128
+ metadata?: Record<string, string>;
129
+ }
130
+ /**
131
+ * Logger interface for gateway clients
132
+ * @category Gateway
133
+ */
134
+ export interface GatewayLogger {
135
+ info(obj: object, msg?: string): void;
136
+ warn(obj: object, msg?: string): void;
137
+ error(obj: object, msg?: string): void;
138
+ debug(obj: object, msg?: string): void;
139
+ }
140
+ /**
141
+ * TLS/SSL credential options
142
+ * @category Gateway
143
+ */
144
+ export interface TlsCredentialsOptions {
145
+ /** Service name for logging */
146
+ serviceName: string;
147
+ /** Use TLS encryption */
148
+ useTls: boolean;
149
+ /** CA certificate path */
150
+ caCertPath?: string;
151
+ /** Client certificate path (for mutual TLS) */
152
+ clientCertPath?: string;
153
+ /** Client key path (for mutual TLS) */
154
+ clientKeyPath?: string;
155
+ /** Logger instance */
156
+ logger: GatewayLogger;
157
+ }
158
+ /**
159
+ * Default configuration values for gateway clients
160
+ * @category Gateway
161
+ */
162
+ export declare const GATEWAY_DEFAULT_CONFIG: {
163
+ readonly timeoutMs: 5000;
164
+ readonly retryCount: 3;
165
+ readonly retryDelayMs: 1000;
166
+ readonly maxReconnectAttempts: number;
167
+ readonly maxReconnectDelayMs: 30000;
168
+ readonly initialReconnectDelayMs: 1000;
169
+ readonly useTls: false;
170
+ readonly keepaliveTimeMs: 30000;
171
+ readonly keepaliveTimeoutMs: 10000;
172
+ };
173
+ /**
174
+ * Default metrics values
175
+ * @category Gateway
176
+ */
177
+ export declare const GATEWAY_DEFAULT_METRICS: GatewayClientMetrics;
178
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/gateway/types.ts"],"names":[],"mappings":"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"}