@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,39 @@
1
+ /**
2
+ * Service Registry Backend Interface
3
+ */
4
+ import { ServiceInstance, ServiceFilter } from '../types';
5
+ export interface RegistryBackend {
6
+ /**
7
+ * Register a service instance
8
+ */
9
+ register(instance: ServiceInstance): Promise<void>;
10
+ /**
11
+ * Deregister a service instance
12
+ */
13
+ deregister(instanceId: string): Promise<void>;
14
+ /**
15
+ * Update service instance heartbeat
16
+ */
17
+ heartbeat(instanceId: string): Promise<void>;
18
+ /**
19
+ * Get all instances of a service
20
+ */
21
+ getInstances(serviceName: string, filter?: ServiceFilter): Promise<ServiceInstance[]>;
22
+ /**
23
+ * Get a specific service instance
24
+ */
25
+ getInstance(instanceId: string): Promise<ServiceInstance | null>;
26
+ /**
27
+ * Get all registered services
28
+ */
29
+ getAllServices(): Promise<string[]>;
30
+ /**
31
+ * Update service instance status
32
+ */
33
+ updateStatus(instanceId: string, status: string): Promise<void>;
34
+ /**
35
+ * Clean up expired instances
36
+ */
37
+ cleanup(): Promise<void>;
38
+ }
39
+ //# sourceMappingURL=registry-backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-backend.d.ts","sourceRoot":"","sources":["../../src/backends/registry-backend.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;OAEG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C;;OAEG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C;;OAEG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAEtF;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAEjE;;OAEG;IACH,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEpC;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ /**
3
+ * Service Registry Backend Interface
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Discovery Client
3
+ * Discovers and retrieves service instances
4
+ */
5
+ import { ServiceInstance, DiscoveryClientConfig, ServiceFilter } from '../types';
6
+ import { RegistryBackend } from '../backends/registry-backend';
7
+ import { LoadBalancerFactory } from '../load-balancer/strategies';
8
+ export declare class DiscoveryClient {
9
+ private config;
10
+ private backend;
11
+ private cache;
12
+ private loadBalancerFactory;
13
+ constructor(config?: DiscoveryClientConfig, backend?: RegistryBackend);
14
+ /**
15
+ * Get all instances of a service
16
+ */
17
+ getInstances(serviceName: string, filter?: ServiceFilter): Promise<ServiceInstance[]>;
18
+ /**
19
+ * Get a single instance using load balancing
20
+ */
21
+ getInstance(serviceName: string, strategy?: string, filter?: ServiceFilter): Promise<ServiceInstance | null>;
22
+ /**
23
+ * Get all registered service names
24
+ */
25
+ getAllServices(): Promise<string[]>;
26
+ /**
27
+ * Clear cache for a specific service or all services
28
+ */
29
+ clearCache(serviceName?: string): void;
30
+ /**
31
+ * Get the backend
32
+ */
33
+ getBackend(): RegistryBackend;
34
+ /**
35
+ * Get load balancer factory
36
+ */
37
+ getLoadBalancerFactory(): LoadBalancerFactory;
38
+ /**
39
+ * Start cache refresh interval
40
+ */
41
+ private startRefreshInterval;
42
+ /**
43
+ * Apply filter to instances
44
+ */
45
+ private applyFilter;
46
+ }
47
+ //# sourceMappingURL=discovery-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery-client.d.ts","sourceRoot":"","sources":["../../src/client/discovery-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE,qBAAa,eAAe;IAMxB,OAAO,CAAC,MAAM;IALhB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,KAAK,CAA0E;IACvF,OAAO,CAAC,mBAAmB,CAAsB;gBAGvC,MAAM,GAAE,qBAA0B,EAC1C,OAAO,CAAC,EAAE,eAAe;IAU3B;;OAEG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IA2B3F;;OAEG;IACG,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,QAAQ,GAAE,MAAsB,EAChC,MAAM,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAQlC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIzC;;OAEG;IACH,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAQtC;;OAEG;IACH,UAAU,IAAI,eAAe;IAI7B;;OAEG;IACH,sBAAsB,IAAI,mBAAmB;IAI7C;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAa5B;;OAEG;IACH,OAAO,CAAC,WAAW;CAepB"}
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ /**
3
+ * Discovery Client
4
+ * Discovers and retrieves service instances
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.DiscoveryClient = void 0;
8
+ const memory_backend_1 = require("../backends/memory-backend");
9
+ const strategies_1 = require("../load-balancer/strategies");
10
+ class DiscoveryClient {
11
+ constructor(config = {}, backend) {
12
+ this.config = config;
13
+ this.cache = new Map();
14
+ this.backend = backend || new memory_backend_1.MemoryRegistryBackend();
15
+ this.loadBalancerFactory = new strategies_1.LoadBalancerFactory();
16
+ if (config.refreshInterval) {
17
+ this.startRefreshInterval();
18
+ }
19
+ }
20
+ /**
21
+ * Get all instances of a service
22
+ */
23
+ async getInstances(serviceName, filter) {
24
+ // Check cache first
25
+ if (this.config.cacheEnabled) {
26
+ const cached = this.cache.get(serviceName);
27
+ if (cached) {
28
+ const age = Date.now() - cached.timestamp;
29
+ const ttl = this.config.cacheTTL || 30000;
30
+ if (age < ttl) {
31
+ return this.applyFilter(cached.instances, filter);
32
+ }
33
+ }
34
+ }
35
+ // Fetch from backend
36
+ const instances = await this.backend.getInstances(serviceName, filter);
37
+ // Update cache
38
+ if (this.config.cacheEnabled) {
39
+ this.cache.set(serviceName, {
40
+ instances,
41
+ timestamp: Date.now(),
42
+ });
43
+ }
44
+ return instances;
45
+ }
46
+ /**
47
+ * Get a single instance using load balancing
48
+ */
49
+ async getInstance(serviceName, strategy = 'round-robin', filter) {
50
+ const instances = await this.getInstances(serviceName, filter);
51
+ if (instances.length === 0)
52
+ return null;
53
+ const loadBalancer = this.loadBalancerFactory.create(strategy);
54
+ return loadBalancer.choose(instances);
55
+ }
56
+ /**
57
+ * Get all registered service names
58
+ */
59
+ async getAllServices() {
60
+ return this.backend.getAllServices();
61
+ }
62
+ /**
63
+ * Clear cache for a specific service or all services
64
+ */
65
+ clearCache(serviceName) {
66
+ if (serviceName) {
67
+ this.cache.delete(serviceName);
68
+ }
69
+ else {
70
+ this.cache.clear();
71
+ }
72
+ }
73
+ /**
74
+ * Get the backend
75
+ */
76
+ getBackend() {
77
+ return this.backend;
78
+ }
79
+ /**
80
+ * Get load balancer factory
81
+ */
82
+ getLoadBalancerFactory() {
83
+ return this.loadBalancerFactory;
84
+ }
85
+ /**
86
+ * Start cache refresh interval
87
+ */
88
+ startRefreshInterval() {
89
+ setInterval(async () => {
90
+ const services = await this.getAllServices();
91
+ for (const service of services) {
92
+ const instances = await this.backend.getInstances(service);
93
+ this.cache.set(service, {
94
+ instances,
95
+ timestamp: Date.now(),
96
+ });
97
+ }
98
+ }, this.config.refreshInterval);
99
+ }
100
+ /**
101
+ * Apply filter to instances
102
+ */
103
+ applyFilter(instances, filter) {
104
+ if (!filter)
105
+ return instances;
106
+ return instances.filter((instance) => {
107
+ if (filter.zone && instance.zone !== filter.zone)
108
+ return false;
109
+ if (filter.status && instance.status !== filter.status)
110
+ return false;
111
+ if (filter.tags && !filter.tags.every((tag) => instance.tags?.includes(tag)))
112
+ return false;
113
+ if (filter.metadata) {
114
+ for (const [key, value] of Object.entries(filter.metadata)) {
115
+ if (instance.metadata?.[key] !== value)
116
+ return false;
117
+ }
118
+ }
119
+ return true;
120
+ });
121
+ }
122
+ }
123
+ exports.DiscoveryClient = DiscoveryClient;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Service Client
3
+ * HTTP client with automatic service discovery and load balancing
4
+ */
5
+ import { DiscoveryClient } from './discovery-client';
6
+ import { ServiceFilter } from '../types';
7
+ import { AxiosRequestConfig, AxiosResponse } from 'axios';
8
+ export interface ServiceClientConfig {
9
+ serviceName: string;
10
+ loadBalancingStrategy?: string;
11
+ filter?: ServiceFilter;
12
+ timeout?: number;
13
+ retries?: number;
14
+ retryDelay?: number;
15
+ }
16
+ export declare class ServiceClient {
17
+ private discoveryClient;
18
+ private config;
19
+ private axiosInstance;
20
+ private retries;
21
+ private retryDelay;
22
+ constructor(discoveryClient: DiscoveryClient, config: ServiceClientConfig);
23
+ /**
24
+ * GET request
25
+ */
26
+ get<T = unknown>(path: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
27
+ /**
28
+ * POST request
29
+ */
30
+ post<T = unknown>(path: string, data?: unknown, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
31
+ /**
32
+ * PUT request
33
+ */
34
+ put<T = unknown>(path: string, data?: unknown, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
35
+ /**
36
+ * DELETE request
37
+ */
38
+ delete<T = unknown>(path: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
39
+ /**
40
+ * PATCH request
41
+ */
42
+ patch<T = unknown>(path: string, data?: unknown, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
43
+ /**
44
+ * Generic request with service discovery
45
+ */
46
+ private request;
47
+ /**
48
+ * Sleep utility
49
+ */
50
+ private sleep;
51
+ }
52
+ //# sourceMappingURL=service-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-client.d.ts","sourceRoot":"","sources":["../../src/client/service-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAc,EAAiB,kBAAkB,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEhF,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAa;IAMtB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;gBAGjB,eAAe,EAAE,eAAe,EAChC,MAAM,EAAE,mBAAmB;IAUrC;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAI5F;;OAEG;IACG,IAAI,CAAC,CAAC,GAAG,OAAO,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAI5B;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EACnB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAI5B;;OAEG;IACG,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAI/F;;OAEG;IACG,KAAK,CAAC,CAAC,GAAG,OAAO,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAI5B;;OAEG;YACW,OAAO;IA2CrB;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ /**
3
+ * Service Client
4
+ * HTTP client with automatic service discovery and load balancing
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.ServiceClient = void 0;
11
+ const axios_1 = __importDefault(require("axios"));
12
+ class ServiceClient {
13
+ constructor(discoveryClient, config) {
14
+ this.discoveryClient = discoveryClient;
15
+ this.config = config;
16
+ this.retries = config.retries || 3;
17
+ this.retryDelay = config.retryDelay || 1000;
18
+ this.axiosInstance = axios_1.default.create({
19
+ timeout: config.timeout || 5000,
20
+ });
21
+ }
22
+ /**
23
+ * GET request
24
+ */
25
+ async get(path, config) {
26
+ return this.request({ ...config, method: 'GET', url: path });
27
+ }
28
+ /**
29
+ * POST request
30
+ */
31
+ async post(path, data, config) {
32
+ return this.request({ ...config, method: 'POST', url: path, data });
33
+ }
34
+ /**
35
+ * PUT request
36
+ */
37
+ async put(path, data, config) {
38
+ return this.request({ ...config, method: 'PUT', url: path, data });
39
+ }
40
+ /**
41
+ * DELETE request
42
+ */
43
+ async delete(path, config) {
44
+ return this.request({ ...config, method: 'DELETE', url: path });
45
+ }
46
+ /**
47
+ * PATCH request
48
+ */
49
+ async patch(path, data, config) {
50
+ return this.request({ ...config, method: 'PATCH', url: path, data });
51
+ }
52
+ /**
53
+ * Generic request with service discovery
54
+ */
55
+ async request(config) {
56
+ let lastError = null;
57
+ for (let attempt = 0; attempt < this.retries; attempt++) {
58
+ try {
59
+ // Discover service instance
60
+ const instance = await this.discoveryClient.getInstance(this.config.serviceName, this.config.loadBalancingStrategy, this.config.filter);
61
+ if (!instance) {
62
+ throw new Error(`No instances available for service: ${this.config.serviceName}`);
63
+ }
64
+ // Build full URL
65
+ const baseURL = `${instance.protocol}://${instance.host}:${instance.port}`;
66
+ const fullConfig = {
67
+ ...config,
68
+ baseURL,
69
+ };
70
+ // Make request
71
+ return await this.axiosInstance.request(fullConfig);
72
+ }
73
+ catch (error) {
74
+ lastError = error;
75
+ // Log error only in development
76
+ if (process.env.NODE_ENV === 'development') {
77
+ // eslint-disable-next-line no-console
78
+ console.error(`Request failed (attempt ${attempt + 1}/${this.retries}):`, error);
79
+ }
80
+ // Wait before retry
81
+ if (attempt < this.retries - 1) {
82
+ await this.sleep(this.retryDelay);
83
+ }
84
+ }
85
+ }
86
+ throw lastError || new Error('Request failed after all retries');
87
+ }
88
+ /**
89
+ * Sleep utility
90
+ */
91
+ sleep(ms) {
92
+ return new Promise((resolve) => setTimeout(resolve, ms));
93
+ }
94
+ }
95
+ exports.ServiceClient = ServiceClient;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * InjectServiceClient Decorator
3
+ * Injects a service client for a specific service
4
+ */
5
+ import 'reflect-metadata';
6
+ type NewableFunction = new (...args: unknown[]) => unknown;
7
+ export interface InjectServiceClientOptions {
8
+ serviceName: string;
9
+ loadBalancingStrategy?: string;
10
+ timeout?: number;
11
+ retries?: number;
12
+ }
13
+ export declare function InjectServiceClient(serviceName: string, options?: Omit<InjectServiceClientOptions, 'serviceName'>): ParameterDecorator;
14
+ export declare function getInjectServiceClientMetadata(target: NewableFunction): InjectServiceClientOptions[] | undefined;
15
+ export {};
16
+ //# sourceMappingURL=inject-service-client.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-service-client.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/inject-service-client.decorator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,kBAAkB,CAAC;AAE1B,KAAK,eAAe,GAAG,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;AAI3D,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,IAAI,CAAC,0BAA0B,EAAE,aAAa,CAAC,GACxD,kBAAkB,CAkBpB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,eAAe,GACtB,0BAA0B,EAAE,GAAG,SAAS,CAE1C"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /**
3
+ * InjectServiceClient Decorator
4
+ * Injects a service client for a specific service
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.InjectServiceClient = InjectServiceClient;
8
+ exports.getInjectServiceClientMetadata = getInjectServiceClientMetadata;
9
+ require("reflect-metadata");
10
+ const INJECT_SERVICE_CLIENT_METADATA = 'hazeljs:inject-service-client';
11
+ function InjectServiceClient(serviceName, options) {
12
+ return function (target, propertyKey, parameterIndex) {
13
+ const config = {
14
+ serviceName,
15
+ ...options,
16
+ };
17
+ const existingParams = Reflect.getMetadata(INJECT_SERVICE_CLIENT_METADATA, target) || [];
18
+ existingParams[parameterIndex] = config;
19
+ Reflect.defineMetadata(INJECT_SERVICE_CLIENT_METADATA, existingParams, target);
20
+ };
21
+ }
22
+ function getInjectServiceClientMetadata(target) {
23
+ return Reflect.getMetadata(INJECT_SERVICE_CLIENT_METADATA, target);
24
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Service Registry Decorator
3
+ * Automatically registers a service on module initialization
4
+ */
5
+ import 'reflect-metadata';
6
+ import { ServiceRegistryConfig } from '../types';
7
+ type NewableFunction = new (...args: unknown[]) => unknown;
8
+ export declare function ServiceRegistry(config: ServiceRegistryConfig): ClassDecorator;
9
+ export declare function getServiceRegistryMetadata(target: NewableFunction): ServiceRegistryConfig | undefined;
10
+ export {};
11
+ //# sourceMappingURL=service-registry.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-registry.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/service-registry.decorator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEjD,KAAK,eAAe,GAAG,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;AAI3D,wBAAgB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,cAAc,CAM7E;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,eAAe,GACtB,qBAAqB,GAAG,SAAS,CAEnC"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ /**
3
+ * Service Registry Decorator
4
+ * Automatically registers a service on module initialization
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ServiceRegistry = ServiceRegistry;
8
+ exports.getServiceRegistryMetadata = getServiceRegistryMetadata;
9
+ require("reflect-metadata");
10
+ const SERVICE_REGISTRY_METADATA = 'hazeljs:service-registry';
11
+ function ServiceRegistry(config) {
12
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
13
+ return function (target) {
14
+ Reflect.defineMetadata(SERVICE_REGISTRY_METADATA, config, target);
15
+ return target;
16
+ };
17
+ }
18
+ function getServiceRegistryMetadata(target) {
19
+ return Reflect.getMetadata(SERVICE_REGISTRY_METADATA, target);
20
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @hazeljs/discovery
3
+ * Service Discovery and Registry for HazelJS Microservices
4
+ */
5
+ export * from './types';
6
+ export * from './registry/service-registry';
7
+ export * from './client/discovery-client';
8
+ export * from './client/service-client';
9
+ export * from './load-balancer/strategies';
10
+ export { RegistryBackend } from './backends/registry-backend';
11
+ export { MemoryRegistryBackend } from './backends/memory-backend';
12
+ export { RedisRegistryBackend, RedisBackendConfig } from './backends/redis-backend';
13
+ export { ConsulRegistryBackend, ConsulBackendConfig } from './backends/consul-backend';
14
+ export { KubernetesRegistryBackend, KubernetesBackendConfig } from './backends/kubernetes-backend';
15
+ export { ServiceRegistry as ServiceRegistryDecorator } from './decorators/service-registry.decorator';
16
+ export { getServiceRegistryMetadata } from './decorators/service-registry.decorator';
17
+ export * from './decorators/inject-service-client.decorator';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,SAAS,CAAC;AAGxB,cAAc,6BAA6B,CAAC;AAG5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AAGxC,cAAc,4BAA4B,CAAC;AAG3C,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACvF,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAGnG,OAAO,EAAE,eAAe,IAAI,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AACtG,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC;AACrF,cAAc,8CAA8C,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /**
3
+ * @hazeljs/discovery
4
+ * Service Discovery and Registry for HazelJS Microservices
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.getServiceRegistryMetadata = exports.ServiceRegistryDecorator = exports.KubernetesRegistryBackend = exports.ConsulRegistryBackend = exports.RedisRegistryBackend = exports.MemoryRegistryBackend = void 0;
22
+ // Types
23
+ __exportStar(require("./types"), exports);
24
+ // Registry
25
+ __exportStar(require("./registry/service-registry"), exports);
26
+ // Client
27
+ __exportStar(require("./client/discovery-client"), exports);
28
+ __exportStar(require("./client/service-client"), exports);
29
+ // Load Balancer
30
+ __exportStar(require("./load-balancer/strategies"), exports);
31
+ var memory_backend_1 = require("./backends/memory-backend");
32
+ Object.defineProperty(exports, "MemoryRegistryBackend", { enumerable: true, get: function () { return memory_backend_1.MemoryRegistryBackend; } });
33
+ var redis_backend_1 = require("./backends/redis-backend");
34
+ Object.defineProperty(exports, "RedisRegistryBackend", { enumerable: true, get: function () { return redis_backend_1.RedisRegistryBackend; } });
35
+ var consul_backend_1 = require("./backends/consul-backend");
36
+ Object.defineProperty(exports, "ConsulRegistryBackend", { enumerable: true, get: function () { return consul_backend_1.ConsulRegistryBackend; } });
37
+ var kubernetes_backend_1 = require("./backends/kubernetes-backend");
38
+ Object.defineProperty(exports, "KubernetesRegistryBackend", { enumerable: true, get: function () { return kubernetes_backend_1.KubernetesRegistryBackend; } });
39
+ // Decorators
40
+ var service_registry_decorator_1 = require("./decorators/service-registry.decorator");
41
+ Object.defineProperty(exports, "ServiceRegistryDecorator", { enumerable: true, get: function () { return service_registry_decorator_1.ServiceRegistry; } });
42
+ var service_registry_decorator_2 = require("./decorators/service-registry.decorator");
43
+ Object.defineProperty(exports, "getServiceRegistryMetadata", { enumerable: true, get: function () { return service_registry_decorator_2.getServiceRegistryMetadata; } });
44
+ __exportStar(require("./decorators/inject-service-client.decorator"), exports);
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Load Balancing Strategies
3
+ */
4
+ import { ServiceInstance, LoadBalancerStrategy } from '../types';
5
+ /**
6
+ * Base strategy that filters healthy instances
7
+ */
8
+ declare abstract class BaseStrategy implements LoadBalancerStrategy {
9
+ abstract name: string;
10
+ protected filterHealthy(instances: ServiceInstance[]): ServiceInstance[];
11
+ abstract choose(instances: ServiceInstance[]): ServiceInstance | null;
12
+ }
13
+ /**
14
+ * Round Robin Strategy
15
+ */
16
+ export declare class RoundRobinStrategy extends BaseStrategy {
17
+ name: string;
18
+ private currentIndex;
19
+ choose(instances: ServiceInstance[]): ServiceInstance | null;
20
+ }
21
+ /**
22
+ * Random Strategy
23
+ */
24
+ export declare class RandomStrategy extends BaseStrategy {
25
+ name: string;
26
+ choose(instances: ServiceInstance[]): ServiceInstance | null;
27
+ }
28
+ /**
29
+ * Least Connections Strategy
30
+ * Tracks active connections per instance
31
+ */
32
+ export declare class LeastConnectionsStrategy extends BaseStrategy {
33
+ name: string;
34
+ private connections;
35
+ choose(instances: ServiceInstance[]): ServiceInstance | null;
36
+ incrementConnections(instanceId: string): void;
37
+ decrementConnections(instanceId: string): void;
38
+ }
39
+ /**
40
+ * Weighted Round Robin Strategy
41
+ * Uses metadata.weight for weighted selection
42
+ */
43
+ export declare class WeightedRoundRobinStrategy extends BaseStrategy {
44
+ name: string;
45
+ private currentIndex;
46
+ private currentWeight;
47
+ choose(instances: ServiceInstance[]): ServiceInstance | null;
48
+ }
49
+ /**
50
+ * IP Hash Strategy
51
+ * Consistent hashing based on client IP
52
+ */
53
+ export declare class IPHashStrategy extends BaseStrategy {
54
+ name: string;
55
+ choose(instances: ServiceInstance[], clientIP?: string): ServiceInstance | null;
56
+ private hashCode;
57
+ }
58
+ /**
59
+ * Zone Aware Strategy
60
+ * Prefers instances in the same zone
61
+ */
62
+ export declare class ZoneAwareStrategy extends BaseStrategy {
63
+ private preferredZone?;
64
+ name: string;
65
+ constructor(preferredZone?: string | undefined);
66
+ choose(instances: ServiceInstance[]): ServiceInstance | null;
67
+ }
68
+ /**
69
+ * Load Balancer Factory
70
+ */
71
+ export declare class LoadBalancerFactory {
72
+ private strategies;
73
+ constructor();
74
+ private registerDefaultStrategies;
75
+ register(strategy: LoadBalancerStrategy): void;
76
+ get(name: string): LoadBalancerStrategy | undefined;
77
+ create(name: string, options?: {
78
+ zone?: string;
79
+ }): LoadBalancerStrategy;
80
+ }
81
+ export {};
82
+ //# sourceMappingURL=strategies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategies.d.ts","sourceRoot":"","sources":["../../src/load-balancer/strategies.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAiB,MAAM,UAAU,CAAC;AAEhF;;GAEG;AACH,uBAAe,YAAa,YAAW,oBAAoB;IACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE;IAIxE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,eAAe,GAAG,IAAI;CACtE;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,IAAI,SAAiB;IACrB,OAAO,CAAC,YAAY,CAAK;IAEzB,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,eAAe,GAAG,IAAI;CAQ7D;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,IAAI,SAAY;IAEhB,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,eAAe,GAAG,IAAI;CAO7D;AAED;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,YAAY;IACxD,IAAI,SAAuB;IAC3B,OAAO,CAAC,WAAW,CAA6B;IAEhD,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,eAAe,GAAG,IAAI;IAmB5D,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAK9C,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;CAI/C;AAED;;;GAGG;AACH,qBAAa,0BAA2B,SAAQ,YAAY;IAC1D,IAAI,SAA0B;IAC9B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,aAAa,CAAK;IAE1B,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,eAAe,GAAG,IAAI;CAoB7D;AAED;;;GAGG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,IAAI,SAAa;IAEjB,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAW/E,OAAO,CAAC,QAAQ;CASjB;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IAGrC,OAAO,CAAC,aAAa,CAAC;IAFlC,IAAI,SAAgB;gBAEA,aAAa,CAAC,EAAE,MAAM,YAAA;IAI1C,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,eAAe,GAAG,IAAI;CAe7D;AAED;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,UAAU,CAA2C;;IAM7D,OAAO,CAAC,yBAAyB;IAQjC,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAI9C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAInD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,oBAAoB;CAWxE"}