bb-inspired
Version:
Core library for BB-inspired NestJS backend
111 lines • 4.96 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var EventBusService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventBusService = void 0;
const common_1 = require("@nestjs/common");
const core_1 = require("@nestjs/core");
const rxjs_1 = require("rxjs");
const logger_1 = require("../../utils/logger");
let EventBusService = EventBusService_1 = class EventBusService {
constructor(moduleRef) {
this.moduleRef = moduleRef;
this.logger = new logger_1.AppLogger(EventBusService_1.name);
this.eventStream = new rxjs_1.Subject();
this.subscriptions = new Map();
this.handlerClassMap = new Map();
}
register(eventName, handler) {
if (!this.subscriptions.has(eventName)) {
this.subscriptions.set(eventName, new Set());
}
this.subscriptions.get(eventName).add(handler);
this.logger.verbose(`Registered handler for event: ${eventName}`);
}
unregister(eventName, handler) {
if (!this.subscriptions.has(eventName)) {
return;
}
this.subscriptions.get(eventName).delete(handler);
if (this.subscriptions.get(eventName).size === 0) {
this.subscriptions.delete(eventName);
}
this.logger.verbose(`Unregistered handler for event: ${eventName}`);
}
registerHandlers(instance, prefix = '') {
const prototype = Object.getPrototypeOf(instance);
const handlerMethods = Object.getOwnPropertyNames(prototype)
.filter(prop => typeof instance[prop] === 'function' &&
prop.endsWith('Handler'));
const instanceType = instance.constructor;
if (!this.handlerClassMap.has(instanceType)) {
this.handlerClassMap.set(instanceType, new Set());
}
for (const method of handlerMethods) {
const eventName = prefix + method.replace('Handler', '');
const handler = instance[method].bind(instance);
this.register(eventName, handler);
this.handlerClassMap.get(instanceType).add(eventName);
}
this.logger.verbose(`Registered ${handlerMethods.length} handlers from ${instanceType.name}`, { metadata: { events: Array.from(this.handlerClassMap.get(instanceType)) } });
}
unregisterHandlers(instance) {
const instanceType = instance.constructor;
if (!this.handlerClassMap.has(instanceType)) {
return;
}
const events = this.handlerClassMap.get(instanceType);
for (const eventName of events) {
if (this.subscriptions.has(eventName)) {
const handlers = this.subscriptions.get(eventName);
for (const handler of handlers) {
if (handler.toString().includes(instanceType.name)) {
this.unregister(eventName, handler);
}
}
}
}
this.handlerClassMap.delete(instanceType);
this.logger.verbose(`Unregistered all handlers from ${instanceType.name}`);
}
publish(event) {
const fullEvent = {
...event,
timestamp: new Date(),
};
this.eventStream.next(fullEvent);
this.notifyHandlers(fullEvent);
this.logger.verbose(`Published event: ${event.name}`, { metadata: { event: event.name, payload: event.payload } });
}
ofType(eventName) {
return this.eventStream.pipe((0, rxjs_1.filter)(event => event.name === eventName));
}
notifyHandlers(event) {
if (!this.subscriptions.has(event.name)) {
return;
}
const handlers = this.subscriptions.get(event.name);
for (const handler of handlers) {
try {
handler(event);
}
catch (error) {
this.logger.error(`Error handling event ${event.name}: ${error.message}`, error.stack);
}
}
}
};
exports.EventBusService = EventBusService;
exports.EventBusService = EventBusService = EventBusService_1 = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [core_1.ModuleRef])
], EventBusService);
//# sourceMappingURL=event-bus.service.js.map