@hazeljs/discovery 0.2.0-beta.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 (59) hide show
  1. package/README.md +281 -0
  2. package/dist/__tests__/decorators.test.d.ts +5 -0
  3. package/dist/__tests__/decorators.test.d.ts.map +1 -0
  4. package/dist/__tests__/decorators.test.js +72 -0
  5. package/dist/__tests__/discovery-client.test.d.ts +5 -0
  6. package/dist/__tests__/discovery-client.test.d.ts.map +1 -0
  7. package/dist/__tests__/discovery-client.test.js +142 -0
  8. package/dist/__tests__/load-balancer-strategies.test.d.ts +5 -0
  9. package/dist/__tests__/load-balancer-strategies.test.d.ts.map +1 -0
  10. package/dist/__tests__/load-balancer-strategies.test.js +234 -0
  11. package/dist/__tests__/memory-backend.test.d.ts +5 -0
  12. package/dist/__tests__/memory-backend.test.d.ts.map +1 -0
  13. package/dist/__tests__/memory-backend.test.js +246 -0
  14. package/dist/__tests__/service-client.test.d.ts +5 -0
  15. package/dist/__tests__/service-client.test.d.ts.map +1 -0
  16. package/dist/__tests__/service-client.test.js +215 -0
  17. package/dist/__tests__/service-registry.test.d.ts +5 -0
  18. package/dist/__tests__/service-registry.test.d.ts.map +1 -0
  19. package/dist/__tests__/service-registry.test.js +65 -0
  20. package/dist/backends/consul-backend.d.ts +76 -0
  21. package/dist/backends/consul-backend.d.ts.map +1 -0
  22. package/dist/backends/consul-backend.js +275 -0
  23. package/dist/backends/kubernetes-backend.d.ts +65 -0
  24. package/dist/backends/kubernetes-backend.d.ts.map +1 -0
  25. package/dist/backends/kubernetes-backend.js +174 -0
  26. package/dist/backends/memory-backend.d.ts +22 -0
  27. package/dist/backends/memory-backend.d.ts.map +1 -0
  28. package/dist/backends/memory-backend.js +115 -0
  29. package/dist/backends/redis-backend.d.ts +71 -0
  30. package/dist/backends/redis-backend.d.ts.map +1 -0
  31. package/dist/backends/redis-backend.js +200 -0
  32. package/dist/backends/registry-backend.d.ts +39 -0
  33. package/dist/backends/registry-backend.d.ts.map +1 -0
  34. package/dist/backends/registry-backend.js +5 -0
  35. package/dist/client/discovery-client.d.ts +47 -0
  36. package/dist/client/discovery-client.d.ts.map +1 -0
  37. package/dist/client/discovery-client.js +123 -0
  38. package/dist/client/service-client.d.ts +52 -0
  39. package/dist/client/service-client.d.ts.map +1 -0
  40. package/dist/client/service-client.js +95 -0
  41. package/dist/decorators/inject-service-client.decorator.d.ts +16 -0
  42. package/dist/decorators/inject-service-client.decorator.d.ts.map +1 -0
  43. package/dist/decorators/inject-service-client.decorator.js +24 -0
  44. package/dist/decorators/service-registry.decorator.d.ts +11 -0
  45. package/dist/decorators/service-registry.decorator.d.ts.map +1 -0
  46. package/dist/decorators/service-registry.decorator.js +20 -0
  47. package/dist/index.d.ts +18 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +44 -0
  50. package/dist/load-balancer/strategies.d.ts +82 -0
  51. package/dist/load-balancer/strategies.d.ts.map +1 -0
  52. package/dist/load-balancer/strategies.js +209 -0
  53. package/dist/registry/service-registry.d.ts +51 -0
  54. package/dist/registry/service-registry.d.ts.map +1 -0
  55. package/dist/registry/service-registry.js +148 -0
  56. package/dist/types/index.d.ts +61 -0
  57. package/dist/types/index.d.ts.map +1 -0
  58. package/dist/types/index.js +14 -0
  59. package/package.json +78 -0
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ /**
3
+ * Load Balancing Strategies
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LoadBalancerFactory = exports.ZoneAwareStrategy = exports.IPHashStrategy = exports.WeightedRoundRobinStrategy = exports.LeastConnectionsStrategy = exports.RandomStrategy = exports.RoundRobinStrategy = void 0;
7
+ const types_1 = require("../types");
8
+ /**
9
+ * Base strategy that filters healthy instances
10
+ */
11
+ class BaseStrategy {
12
+ filterHealthy(instances) {
13
+ return instances.filter((instance) => instance.status === types_1.ServiceStatus.UP);
14
+ }
15
+ }
16
+ /**
17
+ * Round Robin Strategy
18
+ */
19
+ class RoundRobinStrategy extends BaseStrategy {
20
+ constructor() {
21
+ super(...arguments);
22
+ this.name = 'round-robin';
23
+ this.currentIndex = 0;
24
+ }
25
+ choose(instances) {
26
+ const healthy = this.filterHealthy(instances);
27
+ if (healthy.length === 0)
28
+ return null;
29
+ const instance = healthy[this.currentIndex % healthy.length];
30
+ this.currentIndex = (this.currentIndex + 1) % healthy.length;
31
+ return instance;
32
+ }
33
+ }
34
+ exports.RoundRobinStrategy = RoundRobinStrategy;
35
+ /**
36
+ * Random Strategy
37
+ */
38
+ class RandomStrategy extends BaseStrategy {
39
+ constructor() {
40
+ super(...arguments);
41
+ this.name = 'random';
42
+ }
43
+ choose(instances) {
44
+ const healthy = this.filterHealthy(instances);
45
+ if (healthy.length === 0)
46
+ return null;
47
+ const randomIndex = Math.floor(Math.random() * healthy.length);
48
+ return healthy[randomIndex];
49
+ }
50
+ }
51
+ exports.RandomStrategy = RandomStrategy;
52
+ /**
53
+ * Least Connections Strategy
54
+ * Tracks active connections per instance
55
+ */
56
+ class LeastConnectionsStrategy extends BaseStrategy {
57
+ constructor() {
58
+ super(...arguments);
59
+ this.name = 'least-connections';
60
+ this.connections = new Map();
61
+ }
62
+ choose(instances) {
63
+ const healthy = this.filterHealthy(instances);
64
+ if (healthy.length === 0)
65
+ return null;
66
+ // Find instance with least connections
67
+ let minConnections = Infinity;
68
+ let selectedInstance = null;
69
+ for (const instance of healthy) {
70
+ const connections = this.connections.get(instance.id) || 0;
71
+ if (connections < minConnections) {
72
+ minConnections = connections;
73
+ selectedInstance = instance;
74
+ }
75
+ }
76
+ return selectedInstance;
77
+ }
78
+ incrementConnections(instanceId) {
79
+ const current = this.connections.get(instanceId) || 0;
80
+ this.connections.set(instanceId, current + 1);
81
+ }
82
+ decrementConnections(instanceId) {
83
+ const current = this.connections.get(instanceId) || 0;
84
+ this.connections.set(instanceId, Math.max(0, current - 1));
85
+ }
86
+ }
87
+ exports.LeastConnectionsStrategy = LeastConnectionsStrategy;
88
+ /**
89
+ * Weighted Round Robin Strategy
90
+ * Uses metadata.weight for weighted selection
91
+ */
92
+ class WeightedRoundRobinStrategy extends BaseStrategy {
93
+ constructor() {
94
+ super(...arguments);
95
+ this.name = 'weighted-round-robin';
96
+ this.currentIndex = 0;
97
+ this.currentWeight = 0;
98
+ }
99
+ choose(instances) {
100
+ const healthy = this.filterHealthy(instances);
101
+ if (healthy.length === 0)
102
+ return null;
103
+ // Build weighted list
104
+ const weighted = [];
105
+ for (const instance of healthy) {
106
+ const weightValue = instance.metadata?.weight;
107
+ const weight = typeof weightValue === 'number' && weightValue > 0 ? weightValue : 1;
108
+ for (let i = 0; i < weight; i++) {
109
+ weighted.push(instance);
110
+ }
111
+ }
112
+ if (weighted.length === 0)
113
+ return null;
114
+ const instance = weighted[this.currentIndex % weighted.length];
115
+ this.currentIndex = (this.currentIndex + 1) % weighted.length;
116
+ return instance;
117
+ }
118
+ }
119
+ exports.WeightedRoundRobinStrategy = WeightedRoundRobinStrategy;
120
+ /**
121
+ * IP Hash Strategy
122
+ * Consistent hashing based on client IP
123
+ */
124
+ class IPHashStrategy extends BaseStrategy {
125
+ constructor() {
126
+ super(...arguments);
127
+ this.name = 'ip-hash';
128
+ }
129
+ choose(instances, clientIP) {
130
+ const healthy = this.filterHealthy(instances);
131
+ if (healthy.length === 0)
132
+ return null;
133
+ if (!clientIP)
134
+ return healthy[0];
135
+ // Simple hash function
136
+ const hash = this.hashCode(clientIP);
137
+ const index = Math.abs(hash) % healthy.length;
138
+ return healthy[index];
139
+ }
140
+ hashCode(str) {
141
+ let hash = 0;
142
+ for (let i = 0; i < str.length; i++) {
143
+ const char = str.charCodeAt(i);
144
+ hash = (hash << 5) - hash + char;
145
+ hash = hash & hash; // Convert to 32bit integer
146
+ }
147
+ return hash;
148
+ }
149
+ }
150
+ exports.IPHashStrategy = IPHashStrategy;
151
+ /**
152
+ * Zone Aware Strategy
153
+ * Prefers instances in the same zone
154
+ */
155
+ class ZoneAwareStrategy extends BaseStrategy {
156
+ constructor(preferredZone) {
157
+ super();
158
+ this.preferredZone = preferredZone;
159
+ this.name = 'zone-aware';
160
+ }
161
+ choose(instances) {
162
+ const healthy = this.filterHealthy(instances);
163
+ if (healthy.length === 0)
164
+ return null;
165
+ // Try to find instance in preferred zone
166
+ if (this.preferredZone) {
167
+ const sameZone = healthy.filter((i) => i.zone === this.preferredZone);
168
+ if (sameZone.length > 0) {
169
+ return sameZone[Math.floor(Math.random() * sameZone.length)];
170
+ }
171
+ }
172
+ // Fallback to random
173
+ return healthy[Math.floor(Math.random() * healthy.length)];
174
+ }
175
+ }
176
+ exports.ZoneAwareStrategy = ZoneAwareStrategy;
177
+ /**
178
+ * Load Balancer Factory
179
+ */
180
+ class LoadBalancerFactory {
181
+ constructor() {
182
+ this.strategies = new Map();
183
+ this.registerDefaultStrategies();
184
+ }
185
+ registerDefaultStrategies() {
186
+ this.register(new RoundRobinStrategy());
187
+ this.register(new RandomStrategy());
188
+ this.register(new LeastConnectionsStrategy());
189
+ this.register(new WeightedRoundRobinStrategy());
190
+ this.register(new IPHashStrategy());
191
+ }
192
+ register(strategy) {
193
+ this.strategies.set(strategy.name, strategy);
194
+ }
195
+ get(name) {
196
+ return this.strategies.get(name);
197
+ }
198
+ create(name, options) {
199
+ if (name === 'zone-aware') {
200
+ return new ZoneAwareStrategy(options?.zone);
201
+ }
202
+ const strategy = this.get(name);
203
+ if (!strategy) {
204
+ throw new Error(`Load balancing strategy '${name}' not found`);
205
+ }
206
+ return strategy;
207
+ }
208
+ }
209
+ exports.LoadBalancerFactory = LoadBalancerFactory;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Service Registry
3
+ * Manages service registration and health checks
4
+ */
5
+ import { ServiceInstance, ServiceRegistryConfig } from '../types';
6
+ import { RegistryBackend } from '../backends/registry-backend';
7
+ export declare class ServiceRegistry {
8
+ private config;
9
+ private backend;
10
+ private instance;
11
+ private heartbeatInterval;
12
+ private cleanupInterval;
13
+ constructor(config: ServiceRegistryConfig, backend?: RegistryBackend);
14
+ /**
15
+ * Register this service instance
16
+ */
17
+ register(): Promise<void>;
18
+ /**
19
+ * Deregister this service instance
20
+ */
21
+ deregister(): Promise<void>;
22
+ /**
23
+ * Get the current service instance
24
+ */
25
+ getInstance(): ServiceInstance | null;
26
+ /**
27
+ * Get the backend
28
+ */
29
+ getBackend(): RegistryBackend;
30
+ /**
31
+ * Start heartbeat interval
32
+ */
33
+ private startHeartbeat;
34
+ /**
35
+ * Start cleanup interval
36
+ */
37
+ private startCleanup;
38
+ /**
39
+ * Perform health check
40
+ */
41
+ private performHealthCheck;
42
+ /**
43
+ * Generate unique instance ID
44
+ */
45
+ private generateInstanceId;
46
+ /**
47
+ * Get local IP address
48
+ */
49
+ private getLocalIP;
50
+ }
51
+ //# sourceMappingURL=service-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-registry.d.ts","sourceRoot":"","sources":["../../src/registry/service-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAiB,MAAM,UAAU,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAI/D,qBAAa,eAAe;IAOxB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,eAAe,CAA+B;gBAG5C,MAAM,EAAE,qBAAqB,EACrC,OAAO,CAAC,EAAE,eAAe;IAK3B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC/B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBjC;;OAEG;IACH,WAAW,IAAI,eAAe,GAAG,IAAI;IAIrC;;OAEG;IACH,UAAU,IAAI,eAAe;IAI7B;;OAEG;IACH,OAAO,CAAC,cAAc;IAYtB;;OAEG;IACH,OAAO,CAAC,YAAY;IAMpB;;OAEG;YACW,kBAAkB;IAoBhC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;OAEG;IACH,OAAO,CAAC,UAAU;CAgBnB"}
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ /**
3
+ * Service Registry
4
+ * Manages service registration and health checks
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ServiceRegistry = void 0;
11
+ const types_1 = require("../types");
12
+ const memory_backend_1 = require("../backends/memory-backend");
13
+ const axios_1 = __importDefault(require("axios"));
14
+ class ServiceRegistry {
15
+ constructor(config, backend) {
16
+ this.config = config;
17
+ this.instance = null;
18
+ this.heartbeatInterval = null;
19
+ this.cleanupInterval = null;
20
+ this.backend = backend || new memory_backend_1.MemoryRegistryBackend();
21
+ }
22
+ /**
23
+ * Register this service instance
24
+ */
25
+ async register() {
26
+ const host = this.config.host || this.getLocalIP();
27
+ const instanceId = this.generateInstanceId(this.config.name, host, this.config.port);
28
+ this.instance = {
29
+ id: instanceId,
30
+ name: this.config.name,
31
+ host,
32
+ port: this.config.port,
33
+ protocol: this.config.protocol || 'http',
34
+ metadata: this.config.metadata || {},
35
+ healthCheckPath: this.config.healthCheckPath || '/health',
36
+ healthCheckInterval: this.config.healthCheckInterval || 30000,
37
+ zone: this.config.zone,
38
+ tags: this.config.tags || [],
39
+ status: types_1.ServiceStatus.STARTING,
40
+ lastHeartbeat: new Date(),
41
+ registeredAt: new Date(),
42
+ };
43
+ await this.backend.register(this.instance);
44
+ // Start heartbeat
45
+ this.startHeartbeat();
46
+ // Start cleanup task
47
+ this.startCleanup();
48
+ // Perform initial health check
49
+ await this.performHealthCheck();
50
+ }
51
+ /**
52
+ * Deregister this service instance
53
+ */
54
+ async deregister() {
55
+ if (this.heartbeatInterval) {
56
+ clearInterval(this.heartbeatInterval);
57
+ this.heartbeatInterval = null;
58
+ }
59
+ if (this.cleanupInterval) {
60
+ clearInterval(this.cleanupInterval);
61
+ this.cleanupInterval = null;
62
+ }
63
+ if (this.instance) {
64
+ await this.backend.deregister(this.instance.id);
65
+ this.instance = null;
66
+ }
67
+ }
68
+ /**
69
+ * Get the current service instance
70
+ */
71
+ getInstance() {
72
+ return this.instance;
73
+ }
74
+ /**
75
+ * Get the backend
76
+ */
77
+ getBackend() {
78
+ return this.backend;
79
+ }
80
+ /**
81
+ * Start heartbeat interval
82
+ */
83
+ startHeartbeat() {
84
+ if (!this.instance)
85
+ return;
86
+ const interval = this.instance.healthCheckInterval || 30000;
87
+ this.heartbeatInterval = setInterval(async () => {
88
+ if (this.instance) {
89
+ await this.performHealthCheck();
90
+ }
91
+ }, interval);
92
+ }
93
+ /**
94
+ * Start cleanup interval
95
+ */
96
+ startCleanup() {
97
+ this.cleanupInterval = setInterval(async () => {
98
+ await this.backend.cleanup();
99
+ }, 60000); // Run every minute
100
+ }
101
+ /**
102
+ * Perform health check
103
+ */
104
+ async performHealthCheck() {
105
+ if (!this.instance)
106
+ return;
107
+ try {
108
+ const url = `${this.instance.protocol}://${this.instance.host}:${this.instance.port}${this.instance.healthCheckPath}`;
109
+ const response = await axios_1.default.get(url, { timeout: 5000 });
110
+ if (response.status === 200) {
111
+ this.instance.status = types_1.ServiceStatus.UP;
112
+ await this.backend.heartbeat(this.instance.id);
113
+ }
114
+ else {
115
+ this.instance.status = types_1.ServiceStatus.DOWN;
116
+ await this.backend.updateStatus(this.instance.id, types_1.ServiceStatus.DOWN);
117
+ }
118
+ }
119
+ catch {
120
+ this.instance.status = types_1.ServiceStatus.DOWN;
121
+ await this.backend.updateStatus(this.instance.id, types_1.ServiceStatus.DOWN);
122
+ }
123
+ }
124
+ /**
125
+ * Generate unique instance ID
126
+ */
127
+ generateInstanceId(name, host, port) {
128
+ return `${name}:${host}:${port}:${Date.now()}`;
129
+ }
130
+ /**
131
+ * Get local IP address
132
+ */
133
+ getLocalIP() {
134
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
135
+ const { networkInterfaces } = require('os');
136
+ const nets = networkInterfaces();
137
+ for (const name of Object.keys(nets)) {
138
+ for (const net of nets[name]) {
139
+ // Skip internal and non-IPv4 addresses
140
+ if (net.family === 'IPv4' && !net.internal) {
141
+ return net.address;
142
+ }
143
+ }
144
+ }
145
+ return 'localhost';
146
+ }
147
+ }
148
+ exports.ServiceRegistry = ServiceRegistry;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Service Discovery Types
3
+ */
4
+ export interface ServiceInstance {
5
+ id: string;
6
+ name: string;
7
+ host: string;
8
+ port: number;
9
+ protocol?: 'http' | 'https' | 'grpc';
10
+ metadata?: Record<string, unknown>;
11
+ healthCheckPath?: string;
12
+ healthCheckInterval?: number;
13
+ zone?: string;
14
+ tags?: string[];
15
+ status: ServiceStatus;
16
+ lastHeartbeat: Date;
17
+ registeredAt: Date;
18
+ }
19
+ export declare enum ServiceStatus {
20
+ UP = "UP",
21
+ DOWN = "DOWN",
22
+ STARTING = "STARTING",
23
+ OUT_OF_SERVICE = "OUT_OF_SERVICE",
24
+ UNKNOWN = "UNKNOWN"
25
+ }
26
+ export interface ServiceRegistryConfig {
27
+ name: string;
28
+ host?: string;
29
+ port: number;
30
+ protocol?: 'http' | 'https' | 'grpc';
31
+ healthCheckPath?: string;
32
+ healthCheckInterval?: number;
33
+ metadata?: Record<string, unknown>;
34
+ zone?: string;
35
+ tags?: string[];
36
+ backend?: 'memory' | 'redis' | 'consul' | 'etcd' | 'kubernetes';
37
+ backendConfig?: Record<string, unknown>;
38
+ }
39
+ export interface DiscoveryClientConfig {
40
+ backend?: 'memory' | 'redis' | 'consul' | 'etcd' | 'kubernetes';
41
+ backendConfig?: Record<string, unknown>;
42
+ cacheEnabled?: boolean;
43
+ cacheTTL?: number;
44
+ refreshInterval?: number;
45
+ }
46
+ export interface LoadBalancerStrategy {
47
+ name: string;
48
+ choose(instances: ServiceInstance[]): ServiceInstance | null;
49
+ }
50
+ export interface HealthCheckResult {
51
+ status: ServiceStatus;
52
+ message?: string;
53
+ timestamp: Date;
54
+ }
55
+ export interface ServiceFilter {
56
+ zone?: string;
57
+ tags?: string[];
58
+ metadata?: Record<string, unknown>;
59
+ status?: ServiceStatus;
60
+ }
61
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,IAAI,CAAC;IACpB,YAAY,EAAE,IAAI,CAAC;CACpB;AAED,oBAAY,aAAa;IACvB,EAAE,OAAO;IACT,IAAI,SAAS;IACb,QAAQ,aAAa;IACrB,cAAc,mBAAmB;IACjC,OAAO,YAAY;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,CAAC;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,CAAC;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,eAAe,GAAG,IAAI,CAAC;CAC9D;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /**
3
+ * Service Discovery Types
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ServiceStatus = void 0;
7
+ var ServiceStatus;
8
+ (function (ServiceStatus) {
9
+ ServiceStatus["UP"] = "UP";
10
+ ServiceStatus["DOWN"] = "DOWN";
11
+ ServiceStatus["STARTING"] = "STARTING";
12
+ ServiceStatus["OUT_OF_SERVICE"] = "OUT_OF_SERVICE";
13
+ ServiceStatus["UNKNOWN"] = "UNKNOWN";
14
+ })(ServiceStatus || (exports.ServiceStatus = ServiceStatus = {}));
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@hazeljs/discovery",
3
+ "version": "0.2.0-beta.1",
4
+ "description": "Service discovery and registry for HazelJS microservices - Eureka-inspired with multiple backend support",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "test": "jest --coverage --passWithNoTests",
13
+ "test:ci": "jest --coverage --coverageReporters=text --coverageReporters=lcov --coverageReporters=clover --no-coverage-threshold",
14
+ "test:watch": "jest --watch",
15
+ "lint": "eslint \"src/**/*.ts\"",
16
+ "lint:fix": "eslint \"src/**/*.ts\" --fix",
17
+ "format": "prettier --write \"src/**/*.ts\"",
18
+ "clean": "rm -rf dist"
19
+ },
20
+ "dependencies": {
21
+ "@hazeljs/core": "file:../core",
22
+ "reflect-metadata": "^0.2.2",
23
+ "axios": "^1.6.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/jest": "^29.5.14",
27
+ "@types/node": "^20.17.50",
28
+ "@typescript-eslint/eslint-plugin": "^8.18.2",
29
+ "@typescript-eslint/parser": "^8.18.2",
30
+ "eslint": "^8.56.0",
31
+ "eslint-config-prettier": "^9.1.0",
32
+ "eslint-plugin-prettier": "^5.1.3",
33
+ "jest": "^29.7.0",
34
+ "prettier": "^3.2.5",
35
+ "ts-jest": "^29.1.2",
36
+ "typescript": "^5.3.3"
37
+ },
38
+ "peerDependencies": {
39
+ "ioredis": "^5.3.0",
40
+ "consul": "^1.2.0",
41
+ "@kubernetes/client-node": "^0.20.0"
42
+ },
43
+ "peerDependenciesMeta": {
44
+ "ioredis": {
45
+ "optional": true
46
+ },
47
+ "consul": {
48
+ "optional": true
49
+ },
50
+ "@kubernetes/client-node": {
51
+ "optional": true
52
+ }
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/hazel-js/hazeljs.git",
60
+ "directory": "packages/discovery"
61
+ },
62
+ "keywords": [
63
+ "hazeljs",
64
+ "microservices",
65
+ "service-discovery",
66
+ "service-registry",
67
+ "load-balancing",
68
+ "eureka",
69
+ "consul",
70
+ "kubernetes"
71
+ ],
72
+ "author": "Muhammad Arslan <marslan@hazeljs.com>",
73
+ "license": "MIT",
74
+ "bugs": {
75
+ "url": "https://github.com/hazeljs/hazel-js/issues"
76
+ },
77
+ "homepage": "https://hazeljs.com"
78
+ }