refactor: server emit events (#11780)

This commit is contained in:
Jason Rasmussen
2024-08-15 16:12:41 -04:00
committed by GitHub
parent 32c05ea950
commit 433c7ab01d
27 changed files with 222 additions and 182 deletions

View File

@@ -1,33 +1,57 @@
import { ModuleRef, Reflector } from '@nestjs/core';
import _ from 'lodash';
import { HandlerOptions } from 'src/decorators';
import { EmitEvent, EmitEventHandler, IEventRepository, OnEvents, events } from 'src/interfaces/event.interface';
import { EmitConfig } from 'src/decorators';
import { EmitEvent, EmitHandler, IEventRepository } from 'src/interfaces/event.interface';
import { Metadata } from 'src/middleware/auth.guard';
import { services } from 'src/services';
type Item<T extends EmitEvent> = {
event: T;
handler: EmitHandler<T>;
priority: number;
label: string;
};
export const setupEventHandlers = (moduleRef: ModuleRef) => {
const reflector = moduleRef.get(Reflector, { strict: false });
const repository = moduleRef.get<IEventRepository>(IEventRepository);
const handlers: Array<{ event: EmitEvent; handler: EmitEventHandler<EmitEvent>; priority: number }> = [];
const items: Item<EmitEvent>[] = [];
// discovery
for (const Service of services) {
const instance = moduleRef.get<OnEvents>(Service);
for (const event of events) {
const handler = instance[event] as EmitEventHandler<typeof event>;
const instance = moduleRef.get<any>(Service);
const ctx = Object.getPrototypeOf(instance);
for (const property of Object.getOwnPropertyNames(ctx)) {
const descriptor = Object.getOwnPropertyDescriptor(ctx, property);
if (!descriptor || descriptor.get || descriptor.set) {
continue;
}
const handler = instance[property];
if (typeof handler !== 'function') {
continue;
}
const options = reflector.get<HandlerOptions>(Metadata.EVENT_HANDLER_OPTIONS, handler);
const priority = options?.priority || 0;
const options = reflector.get<EmitConfig>(Metadata.ON_EMIT_CONFIG, handler);
if (!options) {
continue;
}
handlers.push({ event, handler: handler.bind(instance), priority });
items.push({
event: options.event,
priority: options.priority || 0,
handler: handler.bind(instance),
label: `${Service.name}.${handler.name}`,
});
}
}
const handlers = _.orderBy(items, ['priority'], ['asc']);
// register by priority
for (const { event, handler } of _.orderBy(handlers, ['priority'], ['asc'])) {
repository.on(event, handler);
for (const { event, handler } of handlers) {
repository.on(event as EmitEvent, handler);
}
return handlers;
};