@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
package/README.md ADDED
@@ -0,0 +1,281 @@
1
+ # @hazeljs/discovery
2
+
3
+ Service Discovery and Registry for HazelJS microservices - inspired by Netflix Eureka and Consul.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@hazeljs/discovery.svg)](https://www.npmjs.com/package/@hazeljs/discovery)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Features
9
+
10
+ - 🔍 **Service Registration & Discovery** - Automatic service registration with health checks
11
+ - ⚖️ **Load Balancing** - 6 built-in strategies (Round Robin, Random, Least Connections, etc.)
12
+ - 🏥 **Health Checks** - Automatic health monitoring with heartbeat
13
+ - 🎯 **Service Filtering** - Filter by zone, tags, metadata, and status
14
+ - 💾 **Multiple Backends** - Memory (dev), Redis, Consul, etcd, Kubernetes
15
+ - 🎨 **Decorator Support** - Clean integration with HazelJS apps
16
+ - 📊 **Caching** - Built-in service discovery caching
17
+ - 🔄 **Auto-Cleanup** - Automatic removal of expired instances
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @hazeljs/discovery
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ### 1. Register a Service
28
+
29
+ ```typescript
30
+ import { ServiceRegistry } from '@hazeljs/discovery';
31
+
32
+ const registry = new ServiceRegistry({
33
+ name: 'user-service',
34
+ port: 3000,
35
+ host: 'localhost',
36
+ healthCheckPath: '/health',
37
+ healthCheckInterval: 30000,
38
+ metadata: { version: '1.0.0' },
39
+ zone: 'us-east-1',
40
+ tags: ['api', 'users'],
41
+ });
42
+
43
+ await registry.register();
44
+ ```
45
+
46
+ ### 2. Discover Services
47
+
48
+ ```typescript
49
+ import { DiscoveryClient } from '@hazeljs/discovery';
50
+
51
+ const client = new DiscoveryClient({
52
+ cacheEnabled: true,
53
+ cacheTTL: 30000,
54
+ });
55
+
56
+ // Get all instances
57
+ const instances = await client.getInstances('user-service');
58
+
59
+ // Get one instance with load balancing
60
+ const instance = await client.getInstance('user-service', 'round-robin');
61
+ ```
62
+
63
+ ### 3. Call Services
64
+
65
+ ```typescript
66
+ import { ServiceClient } from '@hazeljs/discovery';
67
+
68
+ const serviceClient = new ServiceClient(discoveryClient, {
69
+ serviceName: 'user-service',
70
+ loadBalancingStrategy: 'round-robin',
71
+ timeout: 5000,
72
+ retries: 3,
73
+ });
74
+
75
+ // Automatic service discovery + load balancing
76
+ const user = await serviceClient.get('/users/123');
77
+ ```
78
+
79
+ ### 4. With HazelJS Decorators
80
+
81
+ ```typescript
82
+ import { ServiceRegistryDecorator, InjectServiceClient } from '@hazeljs/discovery';
83
+
84
+ @ServiceRegistryDecorator({
85
+ name: 'order-service',
86
+ port: 3001,
87
+ healthCheckPath: '/health',
88
+ })
89
+ export class AppModule {}
90
+
91
+ @Injectable()
92
+ export class OrderService {
93
+ constructor(
94
+ @InjectServiceClient('user-service')
95
+ private userClient: ServiceClient
96
+ ) {}
97
+
98
+ async createOrder(userId: string) {
99
+ const user = await this.userClient.get(`/users/${userId}`);
100
+ // ... create order
101
+ }
102
+ }
103
+ ```
104
+
105
+ ## Load Balancing Strategies
106
+
107
+ ### Round Robin
108
+ ```typescript
109
+ const instance = await client.getInstance('service-name', 'round-robin');
110
+ ```
111
+
112
+ ### Random
113
+ ```typescript
114
+ const instance = await client.getInstance('service-name', 'random');
115
+ ```
116
+
117
+ ### Least Connections
118
+ ```typescript
119
+ const instance = await client.getInstance('service-name', 'least-connections');
120
+ ```
121
+
122
+ ### Weighted Round Robin
123
+ ```typescript
124
+ // Set weight in service metadata
125
+ const registry = new ServiceRegistry({
126
+ name: 'api-service',
127
+ metadata: { weight: 5 }, // Higher weight = more traffic
128
+ // ...
129
+ });
130
+ ```
131
+
132
+ ### IP Hash (Sticky Sessions)
133
+ ```typescript
134
+ const instance = await client.getInstance('service-name', 'ip-hash');
135
+ ```
136
+
137
+ ### Zone Aware
138
+ ```typescript
139
+ const factory = client.getLoadBalancerFactory();
140
+ const strategy = factory.create('zone-aware', { zone: 'us-east-1' });
141
+ ```
142
+
143
+ ## Service Filtering
144
+
145
+ ```typescript
146
+ const instances = await client.getInstances('user-service', {
147
+ zone: 'us-east-1',
148
+ status: ServiceStatus.UP,
149
+ tags: ['api', 'production'],
150
+ metadata: { version: '2.0.0' },
151
+ });
152
+ ```
153
+
154
+ ## Registry Backends
155
+
156
+ ### Memory (Development)
157
+ ```typescript
158
+ import { MemoryRegistryBackend } from '@hazeljs/discovery';
159
+
160
+ const backend = new MemoryRegistryBackend();
161
+ const registry = new ServiceRegistry(config, backend);
162
+ ```
163
+
164
+ ### Redis (Production)
165
+ ```typescript
166
+ import Redis from 'ioredis';
167
+ import { RedisRegistryBackend } from '@hazeljs/discovery';
168
+
169
+ const redis = new Redis({
170
+ host: 'localhost',
171
+ port: 6379,
172
+ password: 'your-password',
173
+ });
174
+
175
+ const backend = new RedisRegistryBackend(redis, {
176
+ keyPrefix: 'myapp:discovery:',
177
+ ttl: 90, // seconds
178
+ });
179
+
180
+ const registry = new ServiceRegistry(config, backend);
181
+ ```
182
+
183
+ ### Consul
184
+ ```typescript
185
+ import Consul from 'consul';
186
+ import { ConsulRegistryBackend } from '@hazeljs/discovery';
187
+
188
+ const consul = new Consul({
189
+ host: 'localhost',
190
+ port: 8500,
191
+ });
192
+
193
+ const backend = new ConsulRegistryBackend(consul, {
194
+ ttl: '30s',
195
+ datacenter: 'dc1',
196
+ });
197
+
198
+ const registry = new ServiceRegistry(config, backend);
199
+ ```
200
+
201
+ ### Kubernetes
202
+ ```typescript
203
+ import { KubeConfig } from '@kubernetes/client-node';
204
+ import { KubernetesRegistryBackend } from '@hazeljs/discovery';
205
+
206
+ const kubeConfig = new KubeConfig();
207
+ kubeConfig.loadFromDefault();
208
+
209
+ const backend = new KubernetesRegistryBackend(kubeConfig, {
210
+ namespace: 'default',
211
+ labelSelector: 'app.kubernetes.io/managed-by=hazeljs',
212
+ });
213
+
214
+ // In Kubernetes, service registration is handled by the platform
215
+ // Use the backend for service discovery only
216
+ const client = new DiscoveryClient({}, backend);
217
+ ```
218
+
219
+ ## API Reference
220
+
221
+ ### ServiceRegistry
222
+
223
+ ```typescript
224
+ class ServiceRegistry {
225
+ constructor(config: ServiceRegistryConfig, backend?: RegistryBackend);
226
+ register(): Promise<void>;
227
+ deregister(): Promise<void>;
228
+ getInstance(): ServiceInstance | null;
229
+ getBackend(): RegistryBackend;
230
+ }
231
+ ```
232
+
233
+ ### DiscoveryClient
234
+
235
+ ```typescript
236
+ class DiscoveryClient {
237
+ constructor(config?: DiscoveryClientConfig, backend?: RegistryBackend);
238
+ getInstances(serviceName: string, filter?: ServiceFilter): Promise<ServiceInstance[]>;
239
+ getInstance(serviceName: string, strategy?: string, filter?: ServiceFilter): Promise<ServiceInstance | null>;
240
+ getAllServices(): Promise<string[]>;
241
+ clearCache(serviceName?: string): void;
242
+ }
243
+ ```
244
+
245
+ ### ServiceClient
246
+
247
+ ```typescript
248
+ class ServiceClient {
249
+ constructor(discoveryClient: DiscoveryClient, config: ServiceClientConfig);
250
+ get<T>(path: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
251
+ post<T>(path: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
252
+ put<T>(path: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
253
+ delete<T>(path: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
254
+ patch<T>(path: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
255
+ }
256
+ ```
257
+
258
+ ## Examples
259
+
260
+ See the [examples](./examples) directory for complete working examples.
261
+
262
+ ## Testing
263
+
264
+ ```bash
265
+ npm test
266
+ ```
267
+
268
+ ## Contributing
269
+
270
+ Contributions are welcome! Please read our [Contributing Guide](../../CONTRIBUTING.md) for details.
271
+
272
+ ## License
273
+
274
+ MIT © [HazelJS](https://hazeljs.com)
275
+
276
+ ## Links
277
+
278
+ - [Documentation](https://hazeljs.com/docs)
279
+ - [GitHub](https://github.com/hazel-js/hazeljs)
280
+ - [Issues](https://github.com/hazel-js/hazeljs/issues)
281
+ - [Roadmap](../../ROADMAP_2.0.md)
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Decorators Tests
3
+ */
4
+ import 'reflect-metadata';
5
+ //# sourceMappingURL=decorators.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/decorators.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ /**
3
+ * Decorators Tests
4
+ */
5
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
6
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
8
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
10
+ };
11
+ var __metadata = (this && this.__metadata) || function (k, v) {
12
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
13
+ };
14
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
15
+ return function (target, key) { decorator(target, key, paramIndex); }
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ require("reflect-metadata");
19
+ const service_registry_decorator_1 = require("../decorators/service-registry.decorator");
20
+ const inject_service_client_decorator_1 = require("../decorators/inject-service-client.decorator");
21
+ describe('Decorators', () => {
22
+ describe('ServiceRegistry', () => {
23
+ it('should attach metadata to class', () => {
24
+ const config = {
25
+ name: 'test-service',
26
+ port: 3000,
27
+ zone: 'us-east-1',
28
+ };
29
+ let TestService = class TestService {
30
+ };
31
+ TestService = __decorate([
32
+ (0, service_registry_decorator_1.ServiceRegistry)(config)
33
+ ], TestService);
34
+ const metadata = (0, service_registry_decorator_1.getServiceRegistryMetadata)(TestService);
35
+ expect(metadata).toEqual(config);
36
+ });
37
+ it('should return undefined for class without decorator', () => {
38
+ class TestService {
39
+ }
40
+ const metadata = (0, service_registry_decorator_1.getServiceRegistryMetadata)(TestService);
41
+ expect(metadata).toBeUndefined();
42
+ });
43
+ });
44
+ describe('InjectServiceClient', () => {
45
+ it('should attach metadata to parameter', () => {
46
+ let TestService = class TestService {
47
+ constructor(_userClient, _orderClient) { }
48
+ };
49
+ TestService = __decorate([
50
+ __param(0, (0, inject_service_client_decorator_1.InjectServiceClient)('user-service')),
51
+ __param(1, (0, inject_service_client_decorator_1.InjectServiceClient)('order-service', { timeout: 5000 })),
52
+ __metadata("design:paramtypes", [Object, Object])
53
+ ], TestService);
54
+ const metadata = (0, inject_service_client_decorator_1.getInjectServiceClientMetadata)(TestService);
55
+ expect(metadata).toBeDefined();
56
+ expect(metadata?.[0]).toEqual({
57
+ serviceName: 'user-service',
58
+ });
59
+ expect(metadata?.[1]).toEqual({
60
+ serviceName: 'order-service',
61
+ timeout: 5000,
62
+ });
63
+ });
64
+ it('should return undefined for class without decorator', () => {
65
+ class TestService {
66
+ constructor(_client) { }
67
+ }
68
+ const metadata = (0, inject_service_client_decorator_1.getInjectServiceClientMetadata)(TestService);
69
+ expect(metadata).toBeUndefined();
70
+ });
71
+ });
72
+ });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Discovery Client Tests
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=discovery-client.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery-client.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/discovery-client.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ /**
3
+ * Discovery Client Tests
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const discovery_client_1 = require("../client/discovery-client");
7
+ const memory_backend_1 = require("../backends/memory-backend");
8
+ const types_1 = require("../types");
9
+ describe('DiscoveryClient', () => {
10
+ let client;
11
+ let backend;
12
+ beforeEach(() => {
13
+ backend = new memory_backend_1.MemoryRegistryBackend();
14
+ client = new discovery_client_1.DiscoveryClient({}, backend);
15
+ });
16
+ const createInstance = (id, name = 'test-service') => ({
17
+ id,
18
+ name,
19
+ host: 'localhost',
20
+ port: 3000,
21
+ status: types_1.ServiceStatus.UP,
22
+ lastHeartbeat: new Date(),
23
+ registeredAt: new Date(),
24
+ });
25
+ describe('getInstances', () => {
26
+ it('should return instances from backend', async () => {
27
+ const instance1 = createInstance('1', 'service-a');
28
+ const instance2 = createInstance('2', 'service-a');
29
+ await backend.register(instance1);
30
+ await backend.register(instance2);
31
+ const instances = await client.getInstances('service-a');
32
+ expect(instances).toHaveLength(2);
33
+ });
34
+ it('should apply filters', async () => {
35
+ const instance1 = { ...createInstance('1'), zone: 'us-east-1' };
36
+ const instance2 = { ...createInstance('2'), zone: 'us-west-1' };
37
+ await backend.register(instance1);
38
+ await backend.register(instance2);
39
+ const instances = await client.getInstances('test-service', {
40
+ zone: 'us-east-1',
41
+ });
42
+ expect(instances).toHaveLength(1);
43
+ expect(instances[0].id).toBe('1');
44
+ });
45
+ it('should use cache when enabled', async () => {
46
+ const clientWithCache = new discovery_client_1.DiscoveryClient({ cacheEnabled: true, cacheTTL: 1000 }, backend);
47
+ const instance = createInstance('1');
48
+ await backend.register(instance);
49
+ const first = await clientWithCache.getInstances('test-service');
50
+ expect(first).toHaveLength(1);
51
+ // Remove from backend
52
+ await backend.deregister('1');
53
+ // Should still return cached result
54
+ const second = await clientWithCache.getInstances('test-service');
55
+ expect(second).toHaveLength(1);
56
+ });
57
+ it('should refresh cache after TTL expires', async () => {
58
+ const clientWithCache = new discovery_client_1.DiscoveryClient({ cacheEnabled: true, cacheTTL: 50 }, backend);
59
+ const instance = createInstance('1');
60
+ await backend.register(instance);
61
+ await clientWithCache.getInstances('test-service');
62
+ await backend.deregister('1');
63
+ // Wait for cache to expire
64
+ await new Promise((resolve) => setTimeout(resolve, 60));
65
+ const instances = await clientWithCache.getInstances('test-service');
66
+ expect(instances).toHaveLength(0);
67
+ });
68
+ });
69
+ describe('getInstance', () => {
70
+ it('should return a single instance using load balancing', async () => {
71
+ const instance1 = createInstance('1');
72
+ const instance2 = createInstance('2');
73
+ await backend.register(instance1);
74
+ await backend.register(instance2);
75
+ const instance = await client.getInstance('test-service');
76
+ expect(instance).toBeDefined();
77
+ expect(['1', '2']).toContain(instance?.id);
78
+ });
79
+ it('should return null when no instances available', async () => {
80
+ const instance = await client.getInstance('non-existent');
81
+ expect(instance).toBeNull();
82
+ });
83
+ it('should use specified load balancing strategy', async () => {
84
+ const instance1 = createInstance('1');
85
+ const instance2 = createInstance('2');
86
+ await backend.register(instance1);
87
+ await backend.register(instance2);
88
+ // Round robin should cycle
89
+ const first = await client.getInstance('test-service', 'round-robin');
90
+ const second = await client.getInstance('test-service', 'round-robin');
91
+ const third = await client.getInstance('test-service', 'round-robin');
92
+ expect(first?.id).toBe('1');
93
+ expect(second?.id).toBe('2');
94
+ expect(third?.id).toBe('1');
95
+ });
96
+ it('should apply filters', async () => {
97
+ const instance1 = { ...createInstance('1'), zone: 'us-east-1' };
98
+ const instance2 = { ...createInstance('2'), zone: 'us-west-1' };
99
+ await backend.register(instance1);
100
+ await backend.register(instance2);
101
+ const instance = await client.getInstance('test-service', 'round-robin', {
102
+ zone: 'us-east-1',
103
+ });
104
+ expect(instance?.id).toBe('1');
105
+ });
106
+ });
107
+ describe('getAllServices', () => {
108
+ it('should return all service names', async () => {
109
+ await backend.register(createInstance('1', 'service-a'));
110
+ await backend.register(createInstance('2', 'service-b'));
111
+ const services = await client.getAllServices();
112
+ expect(services.sort()).toEqual(['service-a', 'service-b']);
113
+ });
114
+ });
115
+ describe('clearCache', () => {
116
+ it('should clear cache for specific service', () => {
117
+ const clientWithCache = new discovery_client_1.DiscoveryClient({ cacheEnabled: true }, backend);
118
+ clientWithCache.clearCache('service-a');
119
+ // Should not throw
120
+ expect(true).toBe(true);
121
+ });
122
+ it('should clear all cache when no service specified', () => {
123
+ const clientWithCache = new discovery_client_1.DiscoveryClient({ cacheEnabled: true }, backend);
124
+ clientWithCache.clearCache();
125
+ // Should not throw
126
+ expect(true).toBe(true);
127
+ });
128
+ });
129
+ describe('getBackend', () => {
130
+ it('should return the backend instance', () => {
131
+ const backend = client.getBackend();
132
+ expect(backend).toBeInstanceOf(memory_backend_1.MemoryRegistryBackend);
133
+ });
134
+ });
135
+ describe('getLoadBalancerFactory', () => {
136
+ it('should return the load balancer factory', () => {
137
+ const factory = client.getLoadBalancerFactory();
138
+ expect(factory).toBeDefined();
139
+ expect(factory.get('round-robin')).toBeDefined();
140
+ });
141
+ });
142
+ });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Load Balancer Strategies Tests
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=load-balancer-strategies.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-balancer-strategies.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/load-balancer-strategies.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}