directus

Форк
0
/
emitter.ts 
120 строк · 3.2 Кб
1
import type { ActionHandler, EventContext, FilterHandler, InitHandler } from '@directus/types';
2
import ee2 from 'eventemitter2';
3
import getDatabase from './database/index.js';
4
import { useLogger } from './logger.js';
5

6
export class Emitter {
7
	private filterEmitter;
8
	private actionEmitter;
9
	private initEmitter;
10

11
	constructor() {
12
		const emitterOptions = {
13
			wildcard: true,
14
			verboseMemoryLeak: true,
15
			delimiter: '.',
16

17
			// This will ignore the "unspecified event" error
18
			ignoreErrors: true,
19
		};
20

21
		this.filterEmitter = new ee2.EventEmitter2(emitterOptions);
22
		this.actionEmitter = new ee2.EventEmitter2(emitterOptions);
23
		this.initEmitter = new ee2.EventEmitter2(emitterOptions);
24
	}
25

26
	private getDefaultContext(): EventContext {
27
		return {
28
			database: getDatabase(),
29
			accountability: null,
30
			schema: null,
31
		};
32
	}
33

34
	public async emitFilter<T>(
35
		event: string | string[],
36
		payload: T,
37
		meta: Record<string, any>,
38
		context: EventContext | null = null,
39
	): Promise<T> {
40
		const events = Array.isArray(event) ? event : [event];
41

42
		const eventListeners = events.map((event) => ({
43
			event,
44
			listeners: this.filterEmitter.listeners(event) as FilterHandler<T>[],
45
		}));
46

47
		let updatedPayload = payload;
48

49
		for (const { event, listeners } of eventListeners) {
50
			for (const listener of listeners) {
51
				const result = await listener(updatedPayload, { event, ...meta }, context ?? this.getDefaultContext());
52

53
				if (result !== undefined) {
54
					updatedPayload = result;
55
				}
56
			}
57
		}
58

59
		return updatedPayload;
60
	}
61

62
	public emitAction(event: string | string[], meta: Record<string, any>, context: EventContext | null = null): void {
63
		const logger = useLogger();
64
		const events = Array.isArray(event) ? event : [event];
65

66
		for (const event of events) {
67
			this.actionEmitter.emitAsync(event, { event, ...meta }, context ?? this.getDefaultContext()).catch((err) => {
68
				logger.warn(`An error was thrown while executing action "${event}"`);
69
				logger.warn(err);
70
			});
71
		}
72
	}
73

74
	public async emitInit(event: string, meta: Record<string, any>): Promise<void> {
75
		const logger = useLogger();
76

77
		try {
78
			await this.initEmitter.emitAsync(event, { event, ...meta });
79
		} catch (err: any) {
80
			logger.warn(`An error was thrown while executing init "${event}"`);
81
			logger.warn(err);
82
		}
83
	}
84

85
	public onFilter<T = unknown>(event: string, handler: FilterHandler<T>): void {
86
		this.filterEmitter.on(event, handler);
87
	}
88

89
	public onAction(event: string, handler: ActionHandler): void {
90
		this.actionEmitter.on(event, handler);
91
	}
92

93
	public onInit(event: string, handler: InitHandler): void {
94
		this.initEmitter.on(event, handler);
95
	}
96

97
	public offFilter<T = unknown>(event: string, handler: FilterHandler<T>): void {
98
		this.filterEmitter.off(event, handler);
99
	}
100

101
	public offAction(event: string, handler: ActionHandler): void {
102
		this.actionEmitter.off(event, handler);
103
	}
104

105
	public offInit(event: string, handler: InitHandler): void {
106
		this.initEmitter.off(event, handler);
107
	}
108

109
	public offAll(): void {
110
		this.filterEmitter.removeAllListeners();
111
		this.actionEmitter.removeAllListeners();
112
		this.initEmitter.removeAllListeners();
113
	}
114
}
115

116
const emitter = new Emitter();
117

118
export const useEmitter = () => emitter;
119

120
export default emitter;
121

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.