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';
12
const emitterOptions = {
14
verboseMemoryLeak: true,
17
// This will ignore the "unspecified event" error
21
this.filterEmitter = new ee2.EventEmitter2(emitterOptions);
22
this.actionEmitter = new ee2.EventEmitter2(emitterOptions);
23
this.initEmitter = new ee2.EventEmitter2(emitterOptions);
26
private getDefaultContext(): EventContext {
28
database: getDatabase(),
34
public async emitFilter<T>(
35
event: string | string[],
37
meta: Record<string, any>,
38
context: EventContext | null = null,
40
const events = Array.isArray(event) ? event : [event];
42
const eventListeners = events.map((event) => ({
44
listeners: this.filterEmitter.listeners(event) as FilterHandler<T>[],
47
let updatedPayload = payload;
49
for (const { event, listeners } of eventListeners) {
50
for (const listener of listeners) {
51
const result = await listener(updatedPayload, { event, ...meta }, context ?? this.getDefaultContext());
53
if (result !== undefined) {
54
updatedPayload = result;
59
return updatedPayload;
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];
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}"`);
74
public async emitInit(event: string, meta: Record<string, any>): Promise<void> {
75
const logger = useLogger();
78
await this.initEmitter.emitAsync(event, { event, ...meta });
80
logger.warn(`An error was thrown while executing init "${event}"`);
85
public onFilter<T = unknown>(event: string, handler: FilterHandler<T>): void {
86
this.filterEmitter.on(event, handler);
89
public onAction(event: string, handler: ActionHandler): void {
90
this.actionEmitter.on(event, handler);
93
public onInit(event: string, handler: InitHandler): void {
94
this.initEmitter.on(event, handler);
97
public offFilter<T = unknown>(event: string, handler: FilterHandler<T>): void {
98
this.filterEmitter.off(event, handler);
101
public offAction(event: string, handler: ActionHandler): void {
102
this.actionEmitter.off(event, handler);
105
public offInit(event: string, handler: InitHandler): void {
106
this.initEmitter.off(event, handler);
109
public offAll(): void {
110
this.filterEmitter.removeAllListeners();
111
this.actionEmitter.removeAllListeners();
112
this.initEmitter.removeAllListeners();
116
const emitter = new Emitter();
118
export const useEmitter = () => emitter;
120
export default emitter;