120 lines
5.7 KiB
JavaScript
120 lines
5.7 KiB
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);
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.EventSubscribersLoader = void 0;
|
|
const common_1 = require("@nestjs/common");
|
|
const core_1 = require("@nestjs/core");
|
|
const injector_1 = require("@nestjs/core/injector/injector");
|
|
const eventemitter2_1 = require("eventemitter2");
|
|
const event_emitter_readiness_watcher_1 = require("./event-emitter-readiness.watcher");
|
|
const events_metadata_accessor_1 = require("./events-metadata.accessor");
|
|
let EventSubscribersLoader = class EventSubscribersLoader {
|
|
constructor(discoveryService, eventEmitter, metadataAccessor, metadataScanner, moduleRef, eventEmitterReadinessWatcher) {
|
|
this.discoveryService = discoveryService;
|
|
this.eventEmitter = eventEmitter;
|
|
this.metadataAccessor = metadataAccessor;
|
|
this.metadataScanner = metadataScanner;
|
|
this.moduleRef = moduleRef;
|
|
this.eventEmitterReadinessWatcher = eventEmitterReadinessWatcher;
|
|
this.injector = new injector_1.Injector();
|
|
this.logger = new common_1.Logger('Event');
|
|
}
|
|
onApplicationBootstrap() {
|
|
try {
|
|
this.loadEventListeners();
|
|
this.eventEmitterReadinessWatcher.setReady();
|
|
}
|
|
catch (e) {
|
|
this.eventEmitterReadinessWatcher.setErrored(e);
|
|
}
|
|
}
|
|
onApplicationShutdown() {
|
|
this.eventEmitter.removeAllListeners();
|
|
}
|
|
loadEventListeners() {
|
|
const providers = this.discoveryService.getProviders();
|
|
const controllers = this.discoveryService.getControllers();
|
|
[...providers, ...controllers]
|
|
.filter(wrapper => wrapper.instance && !wrapper.isAlias)
|
|
.forEach((wrapper) => {
|
|
const { instance } = wrapper;
|
|
const prototype = Object.getPrototypeOf(instance) || {};
|
|
const isRequestScoped = !wrapper.isDependencyTreeStatic();
|
|
this.metadataScanner.scanFromPrototype(instance, prototype, (methodKey) => this.subscribeToEventIfListener(instance, methodKey, isRequestScoped, wrapper.host));
|
|
});
|
|
}
|
|
subscribeToEventIfListener(instance, methodKey, isRequestScoped, moduleRef) {
|
|
const eventListenerMetadatas = this.metadataAccessor.getEventHandlerMetadata(instance[methodKey]);
|
|
if (!eventListenerMetadatas) {
|
|
return;
|
|
}
|
|
for (const eventListenerMetadata of eventListenerMetadatas) {
|
|
const { event, options } = eventListenerMetadata;
|
|
const listenerMethod = this.getRegisterListenerMethodBasedOn(options);
|
|
if (isRequestScoped) {
|
|
this.registerRequestScopedListener({
|
|
event,
|
|
eventListenerInstance: instance,
|
|
listenerMethod,
|
|
listenerMethodKey: methodKey,
|
|
moduleRef,
|
|
options,
|
|
});
|
|
}
|
|
else {
|
|
listenerMethod(event, (...args) => this.wrapFunctionInTryCatchBlocks(instance, methodKey, args, options), options);
|
|
}
|
|
}
|
|
}
|
|
getRegisterListenerMethodBasedOn(options) {
|
|
return options?.prependListener
|
|
? this.eventEmitter.prependListener.bind(this.eventEmitter)
|
|
: this.eventEmitter.on.bind(this.eventEmitter);
|
|
}
|
|
registerRequestScopedListener(eventListenerContext) {
|
|
const { listenerMethod, event, eventListenerInstance, moduleRef, listenerMethodKey, options, } = eventListenerContext;
|
|
listenerMethod(event, async (...args) => {
|
|
const request = this.getRequestFromEventPayload(args);
|
|
const contextId = core_1.ContextIdFactory.getByRequest({ payload: request });
|
|
this.moduleRef.registerRequestByContextId(request, contextId);
|
|
const contextInstance = await this.injector.loadPerContext(eventListenerInstance, moduleRef, moduleRef.providers, contextId);
|
|
return this.wrapFunctionInTryCatchBlocks(contextInstance, listenerMethodKey, args, options);
|
|
}, options);
|
|
}
|
|
getRequestFromEventPayload(eventPayload) {
|
|
return eventPayload.length > 1 ? eventPayload : eventPayload[0];
|
|
}
|
|
async wrapFunctionInTryCatchBlocks(instance, methodKey, args, options) {
|
|
try {
|
|
return await instance[methodKey].call(instance, ...args);
|
|
}
|
|
catch (e) {
|
|
if (options?.suppressErrors ?? true) {
|
|
const error = e;
|
|
this.logger.error(error.message, error.stack);
|
|
}
|
|
else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
exports.EventSubscribersLoader = EventSubscribersLoader;
|
|
exports.EventSubscribersLoader = EventSubscribersLoader = __decorate([
|
|
(0, common_1.Injectable)(),
|
|
__metadata("design:paramtypes", [core_1.DiscoveryService,
|
|
eventemitter2_1.EventEmitter2,
|
|
events_metadata_accessor_1.EventsMetadataAccessor,
|
|
core_1.MetadataScanner,
|
|
core_1.ModuleRef,
|
|
event_emitter_readiness_watcher_1.EventEmitterReadinessWatcher])
|
|
], EventSubscribersLoader);
|
|
//# sourceMappingURL=event-subscribers.loader.js.map
|