@tsed/event-emitter 8.0.1 → 8.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@tsed/event-emitter",
3
3
  "description": "EventEmitter package for Ts.ED framework",
4
4
  "type": "module",
5
- "version": "8.0.1",
5
+ "version": "8.0.3",
6
6
  "source": "./src/index.ts",
7
7
  "main": "./lib/esm/index.js",
8
8
  "module": "./lib/esm/index.js",
@@ -10,6 +10,7 @@
10
10
  "browser": "./lib/browser/event-emitter.umd.min.js",
11
11
  "exports": {
12
12
  ".": {
13
+ "@tsed/source": "./src/index.ts",
13
14
  "types": "./lib/types/index.d.ts",
14
15
  "browser": "./lib/browser/event-emitter.umd.min.js",
15
16
  "import": "./lib/esm/index.js",
@@ -28,11 +29,11 @@
28
29
  "tslib": "2.7.0"
29
30
  },
30
31
  "devDependencies": {
31
- "@tsed/barrels": "8.0.1",
32
- "@tsed/core": "8.0.1",
33
- "@tsed/di": "8.0.1",
34
- "@tsed/platform-http": "8.0.1",
35
- "@tsed/typescript": "8.0.1",
32
+ "@tsed/barrels": "8.0.3",
33
+ "@tsed/core": "8.0.3",
34
+ "@tsed/di": "8.0.3",
35
+ "@tsed/platform-http": "8.0.3",
36
+ "@tsed/typescript": "8.0.3",
36
37
  "eslint": "9.12.0",
37
38
  "eventemitter2": "^6.4.9",
38
39
  "typescript": "5.4.5",
@@ -0,0 +1,94 @@
1
+ import {Constant, Inject, InjectorService, LOGGER, Module, Provider} from "@tsed/di";
2
+ import type {ListenerFn} from "eventemitter2";
3
+
4
+ import {EventEmitterStore} from "./interfaces/EventEmitterStore.js";
5
+ import {EventEmitterService} from "./services/EventEmitterFactory.js";
6
+
7
+ @Module()
8
+ export class EventEmitterModule {
9
+ @Inject(LOGGER)
10
+ protected logger: LOGGER;
11
+
12
+ @Inject()
13
+ protected injector: InjectorService;
14
+
15
+ @Inject()
16
+ protected eventEmitter: EventEmitterService;
17
+
18
+ @Constant("eventEmitter.disableSummary", false)
19
+ private disableSummary: boolean;
20
+
21
+ @Constant("eventEmitter.enabled", false)
22
+ private loadEventEmitter: boolean;
23
+
24
+ $onInit() {
25
+ if (this.loadEventEmitter) {
26
+ const providers = this.injector.getProviders();
27
+ providers.forEach((provider) => this.bindEventListeners(provider));
28
+ }
29
+ }
30
+
31
+ $onReady() {
32
+ if (this.loadEventEmitter) {
33
+ if (!this.disableSummary) {
34
+ this.printEvents();
35
+ }
36
+ this.logger.info("EventEmitter listening...");
37
+ } else {
38
+ this.logger.info("EventEmitter disabled...");
39
+ }
40
+ }
41
+
42
+ public printEvents() {
43
+ const list = this.eventEmitter.eventNames().map((eventName) => {
44
+ const listenerCount = this.eventEmitter.listenerCount(eventName).toString();
45
+
46
+ return {
47
+ eventName,
48
+ listenerCount
49
+ };
50
+ });
51
+
52
+ this.logger.info("EventEmitter events mounted:");
53
+
54
+ const str = this.logger.drawTable(list, {
55
+ padding: 1,
56
+ header: {
57
+ eventName: "Event name",
58
+ listenerCount: "Number of listener"
59
+ }
60
+ });
61
+
62
+ this.logger.info("\n" + str.trim());
63
+ }
64
+
65
+ private bindEventListeners(provider: Provider<any>) {
66
+ this.bindOn(provider);
67
+ this.bindOnAny(provider);
68
+ }
69
+
70
+ private getListener(provider: Provider<any>, propertyKey: string) {
71
+ const instance = this.injector.get(provider.token);
72
+ return instance[propertyKey].bind(instance) as ListenerFn;
73
+ }
74
+
75
+ private bindOn(provider: Provider) {
76
+ const store = provider.store.get<EventEmitterStore | undefined>("eventEmitter");
77
+
78
+ Object.entries(store?.onEvent || {}).forEach(([propertyKey, {event, options}]) => {
79
+ const listenerFn = this.getListener(provider, propertyKey);
80
+
81
+ this.eventEmitter.on(event, listenerFn, options);
82
+ });
83
+ }
84
+
85
+ private bindOnAny(provider: Provider) {
86
+ const store = provider.store.get<EventEmitterStore | undefined>("eventEmitter");
87
+
88
+ Object.keys(store?.onAny || {}).forEach((propertyKey) => {
89
+ const listenerFn = this.getListener(provider, propertyKey);
90
+
91
+ this.eventEmitter.onAny(listenerFn);
92
+ });
93
+ }
94
+ }
@@ -0,0 +1,22 @@
1
+ import {Store} from "@tsed/core";
2
+
3
+ import {OnAny} from "./onAny.js";
4
+
5
+ describe("@OnAny()", () => {
6
+ it("should set metadata", () => {
7
+ class Test {
8
+ @OnAny()
9
+ testAnyEventListener() {
10
+ // test
11
+ }
12
+ }
13
+
14
+ const store = Store.from(Test);
15
+
16
+ expect(store.get("eventEmitter")).toEqual({
17
+ onAny: {
18
+ testAnyEventListener: {}
19
+ }
20
+ });
21
+ });
22
+ });
@@ -0,0 +1,15 @@
1
+ import {Store} from "@tsed/core";
2
+
3
+ import {EventEmitterStore} from "../interfaces/EventEmitterStore.js";
4
+
5
+ export function OnAny(): MethodDecorator {
6
+ return (target: any, propertyKey: string) => {
7
+ const store: EventEmitterStore = {
8
+ onAny: {
9
+ [propertyKey]: {}
10
+ }
11
+ };
12
+
13
+ Store.from(target).merge("eventEmitter", store);
14
+ };
15
+ }
@@ -0,0 +1,36 @@
1
+ import {Store} from "@tsed/core";
2
+
3
+ import {OnEvent} from "../decorators/onEvent.js";
4
+
5
+ describe("@OnEvent()", () => {
6
+ it("should set metadata", () => {
7
+ class Test {
8
+ @OnEvent("testEvent")
9
+ testEventListener1() {
10
+ // test
11
+ }
12
+
13
+ @OnEvent("testEvent2", {async: true})
14
+ async testEventListener2() {
15
+ // test
16
+ }
17
+ }
18
+
19
+ const store = Store.from(Test);
20
+
21
+ expect(store.get("eventEmitter")).toEqual({
22
+ onEvent: {
23
+ testEventListener1: {
24
+ event: "testEvent",
25
+ options: undefined
26
+ },
27
+ testEventListener2: {
28
+ event: "testEvent2",
29
+ options: {
30
+ async: true
31
+ }
32
+ }
33
+ }
34
+ });
35
+ });
36
+ });
@@ -0,0 +1,16 @@
1
+ import {Store} from "@tsed/core";
2
+ import {event, eventNS, OnOptions} from "eventemitter2";
3
+
4
+ import {EventEmitterStore} from "../interfaces/EventEmitterStore.js";
5
+
6
+ export function OnEvent(event: event | eventNS, options?: boolean | OnOptions): MethodDecorator {
7
+ return (target: any, propertyKey: string) => {
8
+ const store: EventEmitterStore = {
9
+ onEvent: {
10
+ [propertyKey]: {event, options}
11
+ }
12
+ };
13
+
14
+ Store.from(target).merge("eventEmitter", store);
15
+ };
16
+ }
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @file Automatically generated by @tsed/barrels.
3
+ */
4
+ export * from "./decorators/onAny.js";
5
+ export * from "./decorators/onEvent.js";
6
+ export * from "./EventEmitterModule.js";
7
+ export * from "./interfaces/EventEmitterStore.js";
8
+ export * from "./interfaces/interfaces.js";
9
+ export * from "./services/EventEmitterFactory.js";
@@ -0,0 +1,6 @@
1
+ import type {event, eventNS, OnOptions} from "eventemitter2";
2
+
3
+ export interface EventEmitterStore {
4
+ onEvent?: {[propertyKey: string]: {event: event | eventNS; options?: boolean | OnOptions}};
5
+ onAny?: {[propertyKey: string]: {}};
6
+ }
@@ -0,0 +1,18 @@
1
+ import {ConstructorOptions} from "eventemitter2";
2
+
3
+ declare global {
4
+ namespace TsED {
5
+ interface Configuration {
6
+ eventEmitter?: {
7
+ /**
8
+ * Enable Event Emitter. Default `false`.
9
+ */
10
+ enabled?: boolean;
11
+ /**
12
+ * Disable event table displayed in the logger. Default `false`.
13
+ */
14
+ disableSummary?: boolean;
15
+ } & ConstructorOptions;
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,15 @@
1
+ import {Configuration, registerProvider} from "@tsed/di";
2
+ import type {ConstructorOptions} from "eventemitter2";
3
+ import eventEmitter2 from "eventemitter2";
4
+
5
+ export const EventEmitterService = eventEmitter2.EventEmitter2;
6
+ export type EventEmitterService = eventEmitter2.EventEmitter2;
7
+
8
+ registerProvider({
9
+ token: eventEmitter2.EventEmitter2,
10
+ deps: [Configuration],
11
+ useFactory(settings: Configuration) {
12
+ const opts = settings.get<ConstructorOptions & {enabled: boolean}>("eventEmitter", {enabled: false});
13
+ return opts.enabled ? new eventEmitter2.EventEmitter2(opts) : {};
14
+ }
15
+ });