@riaskov/nevo-messaging 1.0.0 → 1.1.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 (64) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +241 -56
  3. package/dist/common/access-control.d.ts +15 -0
  4. package/dist/common/access-control.js +94 -0
  5. package/dist/common/base.client.d.ts +7 -2
  6. package/dist/common/base.client.js +16 -2
  7. package/dist/common/base.controller.d.ts +6 -1
  8. package/dist/common/base.controller.js +68 -4
  9. package/dist/common/constants.d.ts +4 -0
  10. package/dist/common/constants.js +7 -0
  11. package/dist/common/discovery.d.ts +8 -0
  12. package/dist/common/discovery.js +35 -0
  13. package/dist/common/error-code.d.ts +2 -1
  14. package/dist/common/error-code.js +1 -0
  15. package/dist/common/error-messages.js +2 -1
  16. package/dist/common/index.d.ts +3 -0
  17. package/dist/common/index.js +3 -0
  18. package/dist/common/service-utils.d.ts +2 -0
  19. package/dist/common/service-utils.js +8 -0
  20. package/dist/common/types.d.ts +62 -0
  21. package/dist/signal-router.utils.d.ts +3 -1
  22. package/dist/signal-router.utils.js +70 -6
  23. package/dist/transports/http/http.client-base.d.ts +13 -0
  24. package/dist/transports/http/http.client-base.js +33 -0
  25. package/dist/transports/http/http.config.d.ts +8 -0
  26. package/dist/transports/http/http.config.js +16 -0
  27. package/dist/transports/http/http.signal-router.decorator.d.ts +3 -0
  28. package/dist/transports/http/http.signal-router.decorator.js +18 -0
  29. package/dist/transports/http/http.transport.controller.d.ts +21 -0
  30. package/dist/transports/http/http.transport.controller.js +114 -0
  31. package/dist/transports/http/index.d.ts +5 -0
  32. package/dist/transports/http/index.js +21 -0
  33. package/dist/transports/http/nevo-http.client.d.ts +54 -0
  34. package/dist/transports/http/nevo-http.client.js +280 -0
  35. package/dist/transports/index.d.ts +3 -0
  36. package/dist/transports/index.js +3 -0
  37. package/dist/transports/kafka/kafka.client-base.d.ts +5 -0
  38. package/dist/transports/kafka/kafka.client-base.js +15 -0
  39. package/dist/transports/kafka/kafka.config.d.ts +7 -0
  40. package/dist/transports/kafka/kafka.config.js +48 -2
  41. package/dist/transports/kafka/kafka.signal-router.decorator.js +2 -1
  42. package/dist/transports/kafka/nevo-kafka.client.d.ts +42 -0
  43. package/dist/transports/kafka/nevo-kafka.client.js +210 -4
  44. package/dist/transports/nats/index.d.ts +4 -0
  45. package/dist/transports/nats/index.js +20 -0
  46. package/dist/transports/nats/nats.client-base.d.ts +13 -0
  47. package/dist/transports/nats/nats.client-base.js +33 -0
  48. package/dist/transports/nats/nats.config.d.ts +8 -0
  49. package/dist/transports/nats/nats.config.js +16 -0
  50. package/dist/transports/nats/nats.signal-router.decorator.d.ts +6 -0
  51. package/dist/transports/nats/nats.signal-router.decorator.js +49 -0
  52. package/dist/transports/nats/nevo-nats.client.d.ts +55 -0
  53. package/dist/transports/nats/nevo-nats.client.js +210 -0
  54. package/dist/transports/socket-io/index.d.ts +4 -0
  55. package/dist/transports/socket-io/index.js +20 -0
  56. package/dist/transports/socket-io/nevo-socket.client.d.ts +50 -0
  57. package/dist/transports/socket-io/nevo-socket.client.js +202 -0
  58. package/dist/transports/socket-io/socket.client-base.d.ts +13 -0
  59. package/dist/transports/socket-io/socket.client-base.js +33 -0
  60. package/dist/transports/socket-io/socket.config.d.ts +8 -0
  61. package/dist/transports/socket-io/socket.config.js +16 -0
  62. package/dist/transports/socket-io/socket.signal-router.decorator.d.ts +13 -0
  63. package/dist/transports/socket-io/socket.signal-router.decorator.js +109 -0
  64. package/package.json +12 -6
@@ -0,0 +1,4 @@
1
+ export declare const DEFAULT_SUBSCRIPTION_SUFFIX = "-events.sub";
2
+ export declare const DEFAULT_EVENTS_SUFFIX = "-events";
3
+ export declare const DEFAULT_BROADCAST_TOPIC = "__broadcast";
4
+ export declare const DEFAULT_DISCOVERY_TOPIC = "__nevo.discovery";
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_DISCOVERY_TOPIC = exports.DEFAULT_BROADCAST_TOPIC = exports.DEFAULT_EVENTS_SUFFIX = exports.DEFAULT_SUBSCRIPTION_SUFFIX = void 0;
4
+ exports.DEFAULT_SUBSCRIPTION_SUFFIX = "-events.sub";
5
+ exports.DEFAULT_EVENTS_SUFFIX = "-events";
6
+ exports.DEFAULT_BROADCAST_TOPIC = "__broadcast";
7
+ exports.DEFAULT_DISCOVERY_TOPIC = "__nevo.discovery";
@@ -0,0 +1,8 @@
1
+ import { DiscoveryAnnouncement, DiscoveryEntry } from "./types";
2
+ export declare class DiscoveryRegistry {
3
+ private readonly services;
4
+ update(announcement: DiscoveryAnnouncement): void;
5
+ prune(ttlMs: number): void;
6
+ list(): DiscoveryEntry[];
7
+ isAvailable(serviceName: string, ttlMs: number): boolean;
8
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DiscoveryRegistry = void 0;
4
+ class DiscoveryRegistry {
5
+ constructor() {
6
+ this.services = new Map();
7
+ }
8
+ update(announcement) {
9
+ const now = Date.now();
10
+ const entry = {
11
+ ...announcement,
12
+ lastSeen: now
13
+ };
14
+ this.services.set(announcement.serviceName, entry);
15
+ }
16
+ prune(ttlMs) {
17
+ const now = Date.now();
18
+ for (const [serviceName, entry] of this.services.entries()) {
19
+ if (now - entry.lastSeen > ttlMs) {
20
+ this.services.delete(serviceName);
21
+ }
22
+ }
23
+ }
24
+ list() {
25
+ return [...this.services.values()];
26
+ }
27
+ isAvailable(serviceName, ttlMs) {
28
+ const entry = this.services.get(serviceName);
29
+ if (!entry) {
30
+ return false;
31
+ }
32
+ return Date.now() - entry.lastSeen <= ttlMs;
33
+ }
34
+ }
35
+ exports.DiscoveryRegistry = DiscoveryRegistry;
@@ -1,3 +1,4 @@
1
1
  export declare enum ErrorCode {
2
- UNKNOWN = 0
2
+ UNKNOWN = 0,
3
+ UNAUTHORIZED = 1
3
4
  }
@@ -4,4 +4,5 @@ exports.ErrorCode = void 0;
4
4
  var ErrorCode;
5
5
  (function (ErrorCode) {
6
6
  ErrorCode[ErrorCode["UNKNOWN"] = 0] = "UNKNOWN";
7
+ ErrorCode[ErrorCode["UNAUTHORIZED"] = 1] = "UNAUTHORIZED";
7
8
  })(ErrorCode || (exports.ErrorCode = ErrorCode = {}));
@@ -3,5 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ErrorMessages = void 0;
4
4
  const _1 = require("./");
5
5
  exports.ErrorMessages = {
6
- [_1.ErrorCode.UNKNOWN]: "An unknown error occurred"
6
+ [_1.ErrorCode.UNKNOWN]: "An unknown error occurred",
7
+ [_1.ErrorCode.UNAUTHORIZED]: "Access denied"
7
8
  };
@@ -6,3 +6,6 @@ export * from "./service-utils";
6
6
  export * from "./error-code";
7
7
  export * from "./error-messages";
8
8
  export * from "./bigint.utils";
9
+ export * from "./constants";
10
+ export * from "./access-control";
11
+ export * from "./discovery";
@@ -22,3 +22,6 @@ __exportStar(require("./service-utils"), exports);
22
22
  __exportStar(require("./error-code"), exports);
23
23
  __exportStar(require("./error-messages"), exports);
24
24
  __exportStar(require("./bigint.utils"), exports);
25
+ __exportStar(require("./constants"), exports);
26
+ __exportStar(require("./access-control"), exports);
27
+ __exportStar(require("./discovery"), exports);
@@ -17,5 +17,7 @@ export declare function mapServiceMethods<T>(service: T, customMappings?: Record
17
17
  export declare const createServiceClient: <T extends ServiceMethodMap>(serviceName: string) => {
18
18
  query: <M extends keyof T & string>(method: M, params: T[M]["params"]) => Promise<T[M]["result"]>;
19
19
  emit: <M extends keyof T & string>(method: M, params: T[M]["params"]) => Promise<void>;
20
+ publish: <M extends keyof T & string>(method: M, params: T[M]["params"]) => Promise<void>;
21
+ subscribe: <M extends keyof T & string>(method: M, handler: (data: T[M]["result"]) => void) => Promise<void>;
20
22
  };
21
23
  export declare function createMethodHandlers(mappings: Record<string, [string, ((params: unknown) => unknown[])?, ((result: unknown) => unknown)?]>): ServiceMethodMapping;
@@ -38,6 +38,14 @@ const createServiceClient = (serviceName) => ({
38
38
  // @ts-ignore
39
39
  emit: (method, params) => {
40
40
  throw new Error("Implementation required in subclass");
41
+ },
42
+ // @ts-ignore
43
+ publish: (method, params) => {
44
+ throw new Error("Implementation required in subclass");
45
+ },
46
+ // @ts-ignore
47
+ subscribe: (method, handler) => {
48
+ throw new Error("Implementation required in subclass");
41
49
  }
42
50
  });
43
51
  exports.createServiceClient = createServiceClient;
@@ -6,10 +6,20 @@ export interface MessagePayload {
6
6
  key: string;
7
7
  value: string;
8
8
  }
9
+ export type MessageType = "query" | "emit" | "sub" | "broadcast" | "discovery";
10
+ export interface MessageMeta {
11
+ type?: MessageType;
12
+ service?: string;
13
+ ts?: number;
14
+ auth?: {
15
+ token?: string;
16
+ };
17
+ }
9
18
  export interface MessageRequest<T = unknown> {
10
19
  uuid: string;
11
20
  method: string;
12
21
  params: T;
22
+ meta?: MessageMeta;
13
23
  }
14
24
  export interface MessageResponse<T = unknown> {
15
25
  uuid: string;
@@ -18,6 +28,7 @@ export interface MessageResponse<T = unknown> {
18
28
  result: T | "error";
19
29
  error?: ErrorDetails;
20
30
  };
31
+ meta?: MessageMeta;
21
32
  }
22
33
  export interface ErrorDetails {
23
34
  code: number;
@@ -31,6 +42,7 @@ export interface HookContext {
31
42
  serviceName: string;
32
43
  uuid: string;
33
44
  rawData: unknown;
45
+ meta?: MessageMeta;
34
46
  }
35
47
  export interface BeforeHookContext extends HookContext {
36
48
  params: unknown;
@@ -57,16 +69,66 @@ export interface ServiceMethodMapping {
57
69
  }
58
70
  export interface TransportClientOptions {
59
71
  clientId?: string;
72
+ serviceName?: string;
73
+ authToken?: string;
60
74
  timeout?: number;
61
75
  debug?: boolean;
76
+ backoff?: {
77
+ enabled?: boolean;
78
+ baseMs?: number;
79
+ maxMs?: number;
80
+ maxAttempts?: number;
81
+ jitter?: boolean;
82
+ };
83
+ discovery?: {
84
+ enabled?: boolean;
85
+ heartbeatIntervalMs?: number;
86
+ ttlMs?: number;
87
+ };
62
88
  [key: string]: any;
63
89
  }
64
90
  export interface TransportServerOptions {
65
91
  serviceName: string;
66
92
  debug?: boolean;
93
+ authToken?: string;
67
94
  [key: string]: any;
68
95
  }
69
96
  export interface MicroserviceConfig {
70
97
  serviceName: string;
71
98
  clientName: string;
72
99
  }
100
+ export interface SubscriptionOptions {
101
+ ack?: boolean;
102
+ durableKey?: string;
103
+ groupId?: string;
104
+ fromBeginning?: boolean;
105
+ }
106
+ export interface SubscriptionContext {
107
+ ack(): Promise<void>;
108
+ nack?(reason?: string): Promise<void>;
109
+ meta: MessageMeta;
110
+ }
111
+ export interface Subscription {
112
+ unsubscribe(): Promise<void>;
113
+ }
114
+ export interface AccessRule {
115
+ topic?: string;
116
+ method?: string;
117
+ allow?: string[];
118
+ deny?: string[];
119
+ }
120
+ export interface AccessControlConfig {
121
+ rules?: AccessRule[];
122
+ allowAllByDefault?: boolean;
123
+ logDenied?: boolean;
124
+ }
125
+ export interface DiscoveryAnnouncement {
126
+ serviceName: string;
127
+ clientId?: string;
128
+ transport: string;
129
+ ts: number;
130
+ meta?: Record<string, unknown>;
131
+ }
132
+ export interface DiscoveryEntry extends DiscoveryAnnouncement {
133
+ lastSeen: number;
134
+ }
@@ -1,15 +1,17 @@
1
1
  import { Type } from "@nestjs/common";
2
- import { BeforeHook, AfterHook } from "./common";
2
+ import { BeforeHook, AfterHook, AccessControlConfig, MessageMeta } from "./common";
3
3
  export interface SignalRouterOptions {
4
4
  before?: BeforeHook;
5
5
  after?: AfterHook;
6
6
  debug?: boolean;
7
7
  eventPattern?: string;
8
+ accessControl?: AccessControlConfig;
8
9
  }
9
10
  export interface MessageData {
10
11
  method: string;
11
12
  params: any;
12
13
  uuid: string;
14
+ meta?: MessageMeta;
13
15
  }
14
16
  export type MessageExtractor = (data: any) => MessageData;
15
17
  export declare function findPropertyByType(obj: any, type: Type<any>): string | null;
@@ -5,6 +5,8 @@ exports.findServiceInstances = findServiceInstances;
5
5
  exports.createErrorResponse = createErrorResponse;
6
6
  exports.createSignalRouterDecorator = createSignalRouterDecorator;
7
7
  const common_1 = require("./common");
8
+ const access_control_1 = require("./common/access-control");
9
+ const common_2 = require("./common");
8
10
  const signal_decorator_1 = require("./signal.decorator");
9
11
  function findPropertyByType(obj, type) {
10
12
  for (const prop in obj) {
@@ -34,6 +36,49 @@ function createErrorResponse(message, uuid, method, code = 0) {
34
36
  }
35
37
  };
36
38
  }
39
+ function levenshteinDistance(a, b) {
40
+ if (a === b) {
41
+ return 0;
42
+ }
43
+ if (!a.length) {
44
+ return b.length;
45
+ }
46
+ if (!b.length) {
47
+ return a.length;
48
+ }
49
+ const matrix = Array.from({ length: a.length + 1 }, () => []);
50
+ for (let i = 0; i <= a.length; i++) {
51
+ matrix[i][0] = i;
52
+ }
53
+ for (let j = 0; j <= b.length; j++) {
54
+ matrix[0][j] = j;
55
+ }
56
+ for (let i = 1; i <= a.length; i++) {
57
+ for (let j = 1; j <= b.length; j++) {
58
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
59
+ matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + cost);
60
+ }
61
+ }
62
+ return matrix[a.length][b.length];
63
+ }
64
+ function suggestClosestMethod(method, candidates) {
65
+ if (!candidates.length) {
66
+ return null;
67
+ }
68
+ const normalized = method.toLowerCase();
69
+ let best = null;
70
+ for (const candidate of candidates) {
71
+ const score = levenshteinDistance(normalized, candidate.toLowerCase());
72
+ if (!best || score < best.score) {
73
+ best = { name: candidate, score };
74
+ }
75
+ }
76
+ if (!best) {
77
+ return null;
78
+ }
79
+ const threshold = Math.max(2, Math.floor(method.length * 0.4));
80
+ return best.score <= threshold ? best.name : null;
81
+ }
37
82
  function createSignalRouterDecorator(serviceType, options = {}, messageExtractor, registerHandler) {
38
83
  const debug = options?.debug || process.env["NODE_ENV"] !== "production";
39
84
  return function (target) {
@@ -45,7 +90,7 @@ function createSignalRouterDecorator(serviceType, options = {}, messageExtractor
45
90
  console.log(`[${eventPattern}] Received message:`, (0, common_1.stringifyWithBigInt)(data));
46
91
  }
47
92
  const messageData = messageExtractor(data);
48
- const { method, params, uuid } = messageData;
93
+ const { method, params, uuid, meta } = messageData;
49
94
  if (!method) {
50
95
  console.error("Missing 'method' field in message");
51
96
  return createErrorResponse("Invalid message format");
@@ -58,6 +103,20 @@ function createSignalRouterDecorator(serviceType, options = {}, messageExtractor
58
103
  console.error(`No service instances found for:`, serviceType);
59
104
  return createErrorResponse("Service not found", uuid, method);
60
105
  }
106
+ const callerService = (0, access_control_1.extractCallerService)(meta);
107
+ const topic = eventPattern;
108
+ if (!(0, access_control_1.isAccessAllowed)(options.accessControl, topic, method, callerService)) {
109
+ (0, access_control_1.logAccessDenied)(options.accessControl, { topic, method, serviceName: eventPattern, callerService });
110
+ return {
111
+ uuid,
112
+ method,
113
+ params: {
114
+ result: "error",
115
+ error: (0, access_control_1.createAccessDeniedError)(method, eventPattern, callerService)
116
+ },
117
+ meta
118
+ };
119
+ }
61
120
  let processedParams = params;
62
121
  if (options.before) {
63
122
  const hookResult = await options.before({
@@ -65,7 +124,8 @@ function createSignalRouterDecorator(serviceType, options = {}, messageExtractor
65
124
  serviceName: eventPattern,
66
125
  uuid,
67
126
  rawData: data,
68
- params
127
+ params,
128
+ meta
69
129
  });
70
130
  if (hookResult !== undefined) {
71
131
  processedParams = hookResult;
@@ -75,7 +135,9 @@ function createSignalRouterDecorator(serviceType, options = {}, messageExtractor
75
135
  const signalHandler = signals.find((s) => s.signalName === method);
76
136
  if (!signalHandler) {
77
137
  console.error(`No handler found for method:`, method);
78
- return createErrorResponse(`Method ${method} not found`, uuid, method);
138
+ const suggestion = suggestClosestMethod(method, signals.map((s) => s.signalName));
139
+ const message = suggestion ? `Invalid method name '${method}', did you mean '${suggestion}'?` : `Method ${method} not found`;
140
+ return createErrorResponse(message, uuid, method);
79
141
  }
80
142
  let serviceInstance = null;
81
143
  const serviceMethod = signalHandler.methodName;
@@ -101,7 +163,8 @@ function createSignalRouterDecorator(serviceType, options = {}, messageExtractor
101
163
  let response = {
102
164
  uuid,
103
165
  method,
104
- params: { result: serializedResult }
166
+ params: { result: serializedResult },
167
+ meta
105
168
  };
106
169
  if (options.after) {
107
170
  const hookResponse = await options.after({
@@ -111,7 +174,8 @@ function createSignalRouterDecorator(serviceType, options = {}, messageExtractor
111
174
  rawData: data,
112
175
  params: processedParams,
113
176
  result: serializedResult,
114
- response
177
+ response,
178
+ meta
115
179
  });
116
180
  if (hookResponse !== undefined) {
117
181
  response = hookResponse;
@@ -122,7 +186,7 @@ function createSignalRouterDecorator(serviceType, options = {}, messageExtractor
122
186
  catch (error) {
123
187
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
124
188
  console.error(`[${eventPattern}] Processing error:`, error);
125
- return createErrorResponse(errorMessage, data.uuid, data.method, error.code);
189
+ return createErrorResponse(errorMessage, data.uuid, data.method, error.code || common_2.ErrorCode.UNKNOWN);
126
190
  }
127
191
  };
128
192
  registerHandler(target, eventPattern, handlerName);
@@ -0,0 +1,13 @@
1
+ import { NevoHttpClient } from "./nevo-http.client";
2
+ export declare abstract class HttpClientBase {
3
+ protected readonly universalClient: NevoHttpClient;
4
+ protected constructor(universalClient: NevoHttpClient);
5
+ protected query<T = any>(serviceName: string, method: string, params: any): Promise<T>;
6
+ protected emit(serviceName: string, method: string, params: any): Promise<void>;
7
+ protected publish(serviceName: string, method: string, params: any): Promise<void>;
8
+ protected broadcast(method: string, params: any): Promise<void>;
9
+ protected subscribe<T = any>(serviceName: string, method: string, options: Parameters<NevoHttpClient["subscribe"]>[2], handler: Parameters<NevoHttpClient["subscribe"]>[3]): Promise<import("../..").Subscription>;
10
+ protected getAvailableServices(): string[];
11
+ protected getDiscoveredServices(): import("../..").DiscoveryEntry[];
12
+ protected isServiceAvailable(serviceName: string): boolean;
13
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpClientBase = void 0;
4
+ class HttpClientBase {
5
+ constructor(universalClient) {
6
+ this.universalClient = universalClient;
7
+ }
8
+ async query(serviceName, method, params) {
9
+ return this.universalClient.query(serviceName, method, params);
10
+ }
11
+ async emit(serviceName, method, params) {
12
+ return this.universalClient.emit(serviceName, method, params);
13
+ }
14
+ async publish(serviceName, method, params) {
15
+ return this.universalClient.publish(serviceName, method, params);
16
+ }
17
+ async broadcast(method, params) {
18
+ return this.universalClient.broadcast(method, params);
19
+ }
20
+ async subscribe(serviceName, method, options, handler) {
21
+ return this.universalClient.subscribe(serviceName, method, options, handler);
22
+ }
23
+ getAvailableServices() {
24
+ return this.universalClient.getAvailableServices();
25
+ }
26
+ getDiscoveredServices() {
27
+ return this.universalClient.getDiscoveredServices();
28
+ }
29
+ isServiceAvailable(serviceName) {
30
+ return this.universalClient.isServiceAvailable(serviceName);
31
+ }
32
+ }
33
+ exports.HttpClientBase = HttpClientBase;
@@ -0,0 +1,8 @@
1
+ import { NevoHttpClient, NevoHttpClientOptions } from "./nevo-http.client";
2
+ export interface HttpClientFactoryOptions extends NevoHttpClientOptions {
3
+ clientIdPrefix: string;
4
+ }
5
+ export declare const createNevoHttpClient: (serviceUrls: Record<string, string>, options: HttpClientFactoryOptions) => {
6
+ provide: string;
7
+ useFactory: () => Promise<NevoHttpClient>;
8
+ };
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNevoHttpClient = void 0;
4
+ const nevo_http_client_1 = require("./nevo-http.client");
5
+ const createNevoHttpClient = (serviceUrls, options) => {
6
+ return {
7
+ provide: "NEVO_HTTP_CLIENT",
8
+ useFactory: async () => {
9
+ return new nevo_http_client_1.NevoHttpClient(serviceUrls, {
10
+ ...options,
11
+ serviceName: options.serviceName || options.clientIdPrefix
12
+ });
13
+ }
14
+ };
15
+ };
16
+ exports.createNevoHttpClient = createNevoHttpClient;
@@ -0,0 +1,3 @@
1
+ import { Type } from "@nestjs/common";
2
+ import { SignalRouterOptions } from "../../signal-router.utils";
3
+ export declare function HttpSignalRouter(serviceType: Type<any> | Type<any>[], options?: SignalRouterOptions): (target: any) => any;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpSignalRouter = HttpSignalRouter;
4
+ const common_1 = require("@nestjs/common");
5
+ const signal_router_utils_1 = require("../../signal-router.utils");
6
+ function HttpSignalRouter(serviceType, options) {
7
+ return (0, signal_router_utils_1.createSignalRouterDecorator)(serviceType, options, (data) => {
8
+ const messageData = data || {};
9
+ return {
10
+ method: messageData.method,
11
+ params: messageData.params,
12
+ uuid: messageData.uuid,
13
+ meta: messageData.meta
14
+ };
15
+ }, (target, eventPattern, handlerName) => {
16
+ (0, common_1.Post)(`/${eventPattern}`)(target.prototype, handlerName, Object.getOwnPropertyDescriptor(target.prototype, handlerName));
17
+ });
18
+ }
@@ -0,0 +1,21 @@
1
+ import { Observable } from "rxjs";
2
+ export declare class HttpTransportController {
3
+ streamDiscovery(): Observable<{
4
+ data: string;
5
+ }>;
6
+ publishDiscovery(payload: any): {
7
+ ok: boolean;
8
+ };
9
+ streamSubscription(service: string): Observable<{
10
+ data: string;
11
+ }>;
12
+ publishSubscription(payload: any): {
13
+ ok: boolean;
14
+ };
15
+ streamBroadcast(): Observable<{
16
+ data: string;
17
+ }>;
18
+ publishBroadcast(payload: any): {
19
+ ok: boolean;
20
+ };
21
+ }
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.HttpTransportController = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const rxjs_1 = require("rxjs");
18
+ const operators_1 = require("rxjs/operators");
19
+ const common_2 = require("../../common");
20
+ class HttpSseBroker {
21
+ constructor() {
22
+ this.channels = new Map();
23
+ }
24
+ stream(channel) {
25
+ const subject = this.getChannel(channel);
26
+ return subject.asObservable().pipe((0, operators_1.map)((data) => ({ data })));
27
+ }
28
+ publish(channel, payload) {
29
+ const subject = this.getChannel(channel);
30
+ subject.next((0, common_2.stringifyWithBigInt)(payload));
31
+ }
32
+ getChannel(channel) {
33
+ let subject = this.channels.get(channel);
34
+ if (!subject) {
35
+ subject = new rxjs_1.Subject();
36
+ this.channels.set(channel, subject);
37
+ }
38
+ return subject;
39
+ }
40
+ }
41
+ const broker = new HttpSseBroker();
42
+ let HttpTransportController = class HttpTransportController {
43
+ streamDiscovery() {
44
+ return broker.stream(common_2.DEFAULT_DISCOVERY_TOPIC);
45
+ }
46
+ publishDiscovery(payload) {
47
+ broker.publish(common_2.DEFAULT_DISCOVERY_TOPIC, payload);
48
+ return { ok: true };
49
+ }
50
+ streamSubscription(service) {
51
+ const channel = `${service.toLowerCase()}${common_2.DEFAULT_SUBSCRIPTION_SUFFIX}`;
52
+ return broker.stream(channel);
53
+ }
54
+ publishSubscription(payload) {
55
+ const serviceName = payload?.serviceName;
56
+ if (!serviceName) {
57
+ return { ok: false };
58
+ }
59
+ const channel = `${serviceName.toLowerCase()}${common_2.DEFAULT_SUBSCRIPTION_SUFFIX}`;
60
+ broker.publish(channel, payload);
61
+ return { ok: true };
62
+ }
63
+ streamBroadcast() {
64
+ return broker.stream(common_2.DEFAULT_BROADCAST_TOPIC);
65
+ }
66
+ publishBroadcast(payload) {
67
+ broker.publish(common_2.DEFAULT_BROADCAST_TOPIC, payload);
68
+ return { ok: true };
69
+ }
70
+ };
71
+ exports.HttpTransportController = HttpTransportController;
72
+ __decorate([
73
+ (0, common_1.Sse)(`/${common_2.DEFAULT_DISCOVERY_TOPIC}`),
74
+ __metadata("design:type", Function),
75
+ __metadata("design:paramtypes", []),
76
+ __metadata("design:returntype", rxjs_1.Observable)
77
+ ], HttpTransportController.prototype, "streamDiscovery", null);
78
+ __decorate([
79
+ (0, common_1.Post)(`/${common_2.DEFAULT_DISCOVERY_TOPIC}`),
80
+ __param(0, (0, common_1.Body)()),
81
+ __metadata("design:type", Function),
82
+ __metadata("design:paramtypes", [Object]),
83
+ __metadata("design:returntype", void 0)
84
+ ], HttpTransportController.prototype, "publishDiscovery", null);
85
+ __decorate([
86
+ (0, common_1.Sse)(`/__nevo/subscribe`),
87
+ __param(0, (0, common_1.Query)("service")),
88
+ __metadata("design:type", Function),
89
+ __metadata("design:paramtypes", [String]),
90
+ __metadata("design:returntype", rxjs_1.Observable)
91
+ ], HttpTransportController.prototype, "streamSubscription", null);
92
+ __decorate([
93
+ (0, common_1.Post)(`/__nevo/publish`),
94
+ __param(0, (0, common_1.Body)()),
95
+ __metadata("design:type", Function),
96
+ __metadata("design:paramtypes", [Object]),
97
+ __metadata("design:returntype", void 0)
98
+ ], HttpTransportController.prototype, "publishSubscription", null);
99
+ __decorate([
100
+ (0, common_1.Sse)(`/${common_2.DEFAULT_BROADCAST_TOPIC}`),
101
+ __metadata("design:type", Function),
102
+ __metadata("design:paramtypes", []),
103
+ __metadata("design:returntype", rxjs_1.Observable)
104
+ ], HttpTransportController.prototype, "streamBroadcast", null);
105
+ __decorate([
106
+ (0, common_1.Post)(`/${common_2.DEFAULT_BROADCAST_TOPIC}`),
107
+ __param(0, (0, common_1.Body)()),
108
+ __metadata("design:type", Function),
109
+ __metadata("design:paramtypes", [Object]),
110
+ __metadata("design:returntype", void 0)
111
+ ], HttpTransportController.prototype, "publishBroadcast", null);
112
+ exports.HttpTransportController = HttpTransportController = __decorate([
113
+ (0, common_1.Controller)()
114
+ ], HttpTransportController);
@@ -0,0 +1,5 @@
1
+ export * from "./nevo-http.client";
2
+ export * from "./http.client-base";
3
+ export * from "./http.signal-router.decorator";
4
+ export * from "./http.transport.controller";
5
+ export * from "./http.config";
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./nevo-http.client"), exports);
18
+ __exportStar(require("./http.client-base"), exports);
19
+ __exportStar(require("./http.signal-router.decorator"), exports);
20
+ __exportStar(require("./http.transport.controller"), exports);
21
+ __exportStar(require("./http.config"), exports);