@hg-ts/events 0.0.15
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/.eslintcache +1 -0
- package/.eslintrc.json +3 -0
- package/.mocharc.cjs +1 -0
- package/README.md +1 -0
- package/dist/base.event.d.ts +11 -0
- package/dist/base.event.d.ts.map +1 -0
- package/dist/base.event.js +15 -0
- package/dist/base.event.js.map +1 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +5 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/listen.decorator.d.ts +7 -0
- package/dist/decorators/listen.decorator.d.ts.map +1 -0
- package/dist/decorators/listen.decorator.js +29 -0
- package/dist/decorators/listen.decorator.js.map +1 -0
- package/dist/empty.event.d.ts +5 -0
- package/dist/empty.event.d.ts.map +1 -0
- package/dist/empty.event.js +11 -0
- package/dist/empty.event.js.map +1 -0
- package/dist/event-handling/base.event-transport.d.ts +5 -0
- package/dist/event-handling/base.event-transport.d.ts.map +1 -0
- package/dist/event-handling/base.event-transport.js +7 -0
- package/dist/event-handling/base.event-transport.js.map +1 -0
- package/dist/event-handling/event-emitter.d.ts +8 -0
- package/dist/event-handling/event-emitter.d.ts.map +1 -0
- package/dist/event-handling/event-emitter.js +14 -0
- package/dist/event-handling/event-emitter.js.map +1 -0
- package/dist/event-handling/event-listener-manager.d.ts +8 -0
- package/dist/event-handling/event-listener-manager.d.ts.map +1 -0
- package/dist/event-handling/event-listener-manager.js +28 -0
- package/dist/event-handling/event-listener-manager.js.map +1 -0
- package/dist/event-handling/event-publisher.d.ts +11 -0
- package/dist/event-handling/event-publisher.d.ts.map +1 -0
- package/dist/event-handling/event-publisher.js +32 -0
- package/dist/event-handling/event-publisher.js.map +1 -0
- package/dist/event-handling/index.d.ts +5 -0
- package/dist/event-handling/index.d.ts.map +1 -0
- package/dist/event-handling/index.js +8 -0
- package/dist/event-handling/index.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/tests/event-listener-manager.test-suite.d.ts +8 -0
- package/dist/tests/event-listener-manager.test-suite.d.ts.map +1 -0
- package/dist/tests/event-listener-manager.test-suite.js +82 -0
- package/dist/tests/event-listener-manager.test-suite.js.map +1 -0
- package/dist/tests/event-publisher.test-suite.d.ts +11 -0
- package/dist/tests/event-publisher.test-suite.d.ts.map +1 -0
- package/dist/tests/event-publisher.test-suite.js +137 -0
- package/dist/tests/event-publisher.test-suite.js.map +1 -0
- package/dist-esm/base.event.d.ts +11 -0
- package/dist-esm/base.event.d.ts.map +1 -0
- package/dist-esm/base.event.js +11 -0
- package/dist-esm/base.event.js.map +1 -0
- package/dist-esm/decorators/index.d.ts +2 -0
- package/dist-esm/decorators/index.d.ts.map +1 -0
- package/dist-esm/decorators/index.js +2 -0
- package/dist-esm/decorators/index.js.map +1 -0
- package/dist-esm/decorators/listen.decorator.d.ts +7 -0
- package/dist-esm/decorators/listen.decorator.d.ts.map +1 -0
- package/dist-esm/decorators/listen.decorator.js +22 -0
- package/dist-esm/decorators/listen.decorator.js.map +1 -0
- package/dist-esm/empty.event.d.ts +5 -0
- package/dist-esm/empty.event.d.ts.map +1 -0
- package/dist-esm/empty.event.js +7 -0
- package/dist-esm/empty.event.js.map +1 -0
- package/dist-esm/event-handling/base.event-transport.d.ts +5 -0
- package/dist-esm/event-handling/base.event-transport.d.ts.map +1 -0
- package/dist-esm/event-handling/base.event-transport.js +3 -0
- package/dist-esm/event-handling/base.event-transport.js.map +1 -0
- package/dist-esm/event-handling/event-emitter.d.ts +8 -0
- package/dist-esm/event-handling/event-emitter.d.ts.map +1 -0
- package/dist-esm/event-handling/event-emitter.js +10 -0
- package/dist-esm/event-handling/event-emitter.js.map +1 -0
- package/dist-esm/event-handling/event-listener-manager.d.ts +8 -0
- package/dist-esm/event-handling/event-listener-manager.d.ts.map +1 -0
- package/dist-esm/event-handling/event-listener-manager.js +24 -0
- package/dist-esm/event-handling/event-listener-manager.js.map +1 -0
- package/dist-esm/event-handling/event-publisher.d.ts +11 -0
- package/dist-esm/event-handling/event-publisher.d.ts.map +1 -0
- package/dist-esm/event-handling/event-publisher.js +27 -0
- package/dist-esm/event-handling/event-publisher.js.map +1 -0
- package/dist-esm/event-handling/index.d.ts +5 -0
- package/dist-esm/event-handling/index.d.ts.map +1 -0
- package/dist-esm/event-handling/index.js +5 -0
- package/dist-esm/event-handling/index.js.map +1 -0
- package/dist-esm/execution-mode.d.ts +28 -0
- package/dist-esm/execution-mode.d.ts.map +1 -0
- package/dist-esm/execution-mode.js +65 -0
- package/dist-esm/execution-mode.js.map +1 -0
- package/dist-esm/execution.mode.d.ts +28 -0
- package/dist-esm/execution.mode.d.ts.map +1 -0
- package/dist-esm/execution.mode.js +65 -0
- package/dist-esm/execution.mode.js.map +1 -0
- package/dist-esm/hg.execution-mode.d.ts +5 -0
- package/dist-esm/hg.execution-mode.d.ts.map +1 -0
- package/dist-esm/hg.execution-mode.js +7 -0
- package/dist-esm/hg.execution-mode.js.map +1 -0
- package/dist-esm/index.d.ts +7 -0
- package/dist-esm/index.d.ts.map +1 -0
- package/dist-esm/index.js +7 -0
- package/dist-esm/index.js.map +1 -0
- package/dist-esm/mock.execution-mode.d.ts +5 -0
- package/dist-esm/mock.execution-mode.d.ts.map +1 -0
- package/dist-esm/mock.execution-mode.js +7 -0
- package/dist-esm/mock.execution-mode.js.map +1 -0
- package/dist-esm/tests/event-listener-manager.test-suite.d.ts +8 -0
- package/dist-esm/tests/event-listener-manager.test-suite.d.ts.map +1 -0
- package/dist-esm/tests/event-listener-manager.test-suite.js +79 -0
- package/dist-esm/tests/event-listener-manager.test-suite.js.map +1 -0
- package/dist-esm/tests/event-publisher.test-suite.d.ts +11 -0
- package/dist-esm/tests/event-publisher.test-suite.d.ts.map +1 -0
- package/dist-esm/tests/event-publisher.test-suite.js +134 -0
- package/dist-esm/tests/event-publisher.test-suite.js.map +1 -0
- package/package.json +38 -0
- package/src/base.event.ts +16 -0
- package/src/decorators/index.ts +1 -0
- package/src/decorators/listen.decorator.ts +39 -0
- package/src/empty.event.ts +7 -0
- package/src/event-handling/base.event-transport.ts +5 -0
- package/src/event-handling/event-emitter.ts +15 -0
- package/src/event-handling/event-listener-manager.ts +37 -0
- package/src/event-handling/event-publisher.ts +40 -0
- package/src/event-handling/index.ts +4 -0
- package/src/index.ts +8 -0
- package/src/tests/event-listener-manager.test-suite.ts +68 -0
- package/src/tests/event-publisher.test-suite.ts +127 -0
- package/tsconfig.esm.json +9 -0
- package/tsconfig.json +10 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hg.execution-mode.d.ts","sourceRoot":"","sources":["../src/hg.execution-mode.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EAEb,MAAM,kBAAkB,CAAC;AAE1B,qBAAa,eAAgB,SAAQ,aAAa;;CAIjD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hg.execution-mode.js","sourceRoot":"","sources":["../src/hg.execution-mode.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,qBAAqB,GACrB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,OAAO,eAAgB,SAAQ,aAAa;IACjD;QACC,KAAK,CAAC,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;CACD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,kBAAkB,CAAC;AAE1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAE9B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,kBAAkB,CAAC;AAE1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAE9B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ExecutionMode, ExecutionModeVariants } from './execution-mode';
|
|
2
|
+
export declare class MockExecutionMode<ValueType extends ExecutionModeVariants = ExecutionModeVariants> extends ExecutionMode<ValueType> {
|
|
3
|
+
constructor(value: ValueType);
|
|
4
|
+
}
|
|
5
|
+
//# sourceMappingURL=mock.execution-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock.execution-mode.d.ts","sourceRoot":"","sources":["../src/mock.execution-mode.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,qBAAqB,EACrB,MAAM,kBAAkB,CAAC;AAE1B,qBAAa,iBAAiB,CAAC,SAAS,SAAS,qBAAqB,GAAG,qBAAqB,CAC7F,SAAQ,aAAa,CAAC,SAAS,CAAC;gBACb,KAAK,EAAE,SAAS;CAGnC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock.execution-mode.js","sourceRoot":"","sources":["../src/mock.execution-mode.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,GAEb,MAAM,kBAAkB,CAAC;AAE1B,MAAM,OAAO,iBACZ,SAAQ,aAAwB;IAChC,YAAmB,KAAgB;QAClC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;CACD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TestSuite } from '@hg-ts/tests';
|
|
2
|
+
export declare class EventPublisherTestSuite extends TestSuite {
|
|
3
|
+
private publisher;
|
|
4
|
+
private eventListenerManager;
|
|
5
|
+
addListener(): Promise<void>;
|
|
6
|
+
beforeEach(): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=event-listener-manager.test-suite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-listener-manager.test-suite.d.ts","sourceRoot":"","sources":["../../src/tests/event-listener-manager.test-suite.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,SAAS,EAAgB,MAAM,cAAc,CAAC;AAQjE,qBACa,uBAAwB,SAAQ,SAAS;IACrD,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,oBAAoB,CAAuB;IAGtC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAgDnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAIjD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
import { Describe, TestSuite, Test, expect } from '@hg-ts/tests';
|
|
3
|
+
import { Listen } from '../decorators';
|
|
4
|
+
import { EventPublisher, EventListenerManager } from '../event-handling';
|
|
5
|
+
import { BaseEvent } from '../base.event';
|
|
6
|
+
import { EmptyEvent } from '../empty.event';
|
|
7
|
+
let EventPublisherTestSuite = class EventPublisherTestSuite extends TestSuite {
|
|
8
|
+
publisher;
|
|
9
|
+
eventListenerManager;
|
|
10
|
+
async addListener() {
|
|
11
|
+
class TestEvent extends BaseEvent {
|
|
12
|
+
constructor() {
|
|
13
|
+
super({ body: {} });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
class ExtendedEvent extends TestEvent {
|
|
17
|
+
}
|
|
18
|
+
class Listener {
|
|
19
|
+
called = new Map();
|
|
20
|
+
async empty(event) {
|
|
21
|
+
this.check(event, EmptyEvent);
|
|
22
|
+
}
|
|
23
|
+
async test(event) {
|
|
24
|
+
this.check(event, TestEvent);
|
|
25
|
+
}
|
|
26
|
+
async extended(event) {
|
|
27
|
+
this.check(event, ExtendedEvent);
|
|
28
|
+
}
|
|
29
|
+
check(event, ctor) {
|
|
30
|
+
let count = this.called.get(ctor) ?? 0;
|
|
31
|
+
expect(event).toBeInstanceOf(ctor);
|
|
32
|
+
count++;
|
|
33
|
+
this.called.set(ctor, count);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
__decorate([
|
|
37
|
+
Listen(EmptyEvent),
|
|
38
|
+
__metadata("design:type", Function),
|
|
39
|
+
__metadata("design:paramtypes", [EmptyEvent]),
|
|
40
|
+
__metadata("design:returntype", Promise)
|
|
41
|
+
], Listener.prototype, "empty", null);
|
|
42
|
+
__decorate([
|
|
43
|
+
Listen(TestEvent),
|
|
44
|
+
__metadata("design:type", Function),
|
|
45
|
+
__metadata("design:paramtypes", [TestEvent]),
|
|
46
|
+
__metadata("design:returntype", Promise)
|
|
47
|
+
], Listener.prototype, "test", null);
|
|
48
|
+
__decorate([
|
|
49
|
+
Listen(ExtendedEvent),
|
|
50
|
+
__metadata("design:type", Function),
|
|
51
|
+
__metadata("design:paramtypes", [ExtendedEvent]),
|
|
52
|
+
__metadata("design:returntype", Promise)
|
|
53
|
+
], Listener.prototype, "extended", null);
|
|
54
|
+
const listener = new Listener();
|
|
55
|
+
this.eventListenerManager.addListener(listener);
|
|
56
|
+
await this.publisher.publish(new EmptyEvent());
|
|
57
|
+
await this.publisher.publish(new TestEvent());
|
|
58
|
+
await this.publisher.publish(new ExtendedEvent());
|
|
59
|
+
expect(listener.called.get(EmptyEvent)).toBe(1);
|
|
60
|
+
expect(listener.called.get(TestEvent)).toBe(2);
|
|
61
|
+
expect(listener.called.get(ExtendedEvent)).toBe(1);
|
|
62
|
+
expect.assertions(7);
|
|
63
|
+
}
|
|
64
|
+
async beforeEach() {
|
|
65
|
+
this.publisher = new EventPublisher();
|
|
66
|
+
this.eventListenerManager = new EventListenerManager(this.publisher);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
__decorate([
|
|
70
|
+
Test(),
|
|
71
|
+
__metadata("design:type", Function),
|
|
72
|
+
__metadata("design:paramtypes", []),
|
|
73
|
+
__metadata("design:returntype", Promise)
|
|
74
|
+
], EventPublisherTestSuite.prototype, "addListener", null);
|
|
75
|
+
EventPublisherTestSuite = __decorate([
|
|
76
|
+
Describe()
|
|
77
|
+
], EventPublisherTestSuite);
|
|
78
|
+
export { EventPublisherTestSuite };
|
|
79
|
+
//# sourceMappingURL=event-listener-manager.test-suite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-listener-manager.test-suite.js","sourceRoot":"","sources":["../../src/tests/event-listener-manager.test-suite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TestSuite } from '@hg-ts/tests';
|
|
2
|
+
export declare class EventPublisherTestSuite extends TestSuite {
|
|
3
|
+
private publisher;
|
|
4
|
+
publish(): Promise<void>;
|
|
5
|
+
multipleListeners(): Promise<void>;
|
|
6
|
+
multipleEvents(): Promise<void>;
|
|
7
|
+
extendingEventsInherited(): Promise<void>;
|
|
8
|
+
extendingEventsParent(): Promise<void>;
|
|
9
|
+
beforeEach(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=event-publisher.test-suite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-publisher.test-suite.d.ts","sourceRoot":"","sources":["../../src/tests/event-publisher.test-suite.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,SAAS,EAAgB,MAAM,cAAc,CAAC;AAOjE,qBACa,uBAAwB,SAAQ,SAAS;IACrD,OAAO,CAAC,SAAS,CAAiB;IAGrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAaxB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBlC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB/B,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;IA2BzC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B7B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAGjD"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
import { Describe, TestSuite, Test, expect } from '@hg-ts/tests';
|
|
3
|
+
import { EventPublisher } from '../event-handling';
|
|
4
|
+
import { BaseEvent } from '../base.event';
|
|
5
|
+
import { EmptyEvent } from '../empty.event';
|
|
6
|
+
let EventPublisherTestSuite = class EventPublisherTestSuite extends TestSuite {
|
|
7
|
+
publisher;
|
|
8
|
+
async publish() {
|
|
9
|
+
const listener = async (event) => {
|
|
10
|
+
expect(event).toBeInstanceOf(EmptyEvent);
|
|
11
|
+
};
|
|
12
|
+
this.publisher['addListener'](EmptyEvent, listener);
|
|
13
|
+
await this.publisher.publish(new EmptyEvent());
|
|
14
|
+
expect.assertions(1);
|
|
15
|
+
}
|
|
16
|
+
async multipleListeners() {
|
|
17
|
+
let callIndex = 1;
|
|
18
|
+
const listener1 = async (event) => {
|
|
19
|
+
expect(event).toBeInstanceOf(EmptyEvent);
|
|
20
|
+
expect(callIndex).toBe(1);
|
|
21
|
+
callIndex++;
|
|
22
|
+
};
|
|
23
|
+
const listener2 = async (event) => {
|
|
24
|
+
expect(event).toBeInstanceOf(EmptyEvent);
|
|
25
|
+
expect(callIndex).toBe(2);
|
|
26
|
+
callIndex++;
|
|
27
|
+
};
|
|
28
|
+
this.publisher['addListener'](EmptyEvent, listener1);
|
|
29
|
+
this.publisher['addListener'](EmptyEvent, listener2);
|
|
30
|
+
await this.publisher.publish(new EmptyEvent());
|
|
31
|
+
expect.assertions(4);
|
|
32
|
+
}
|
|
33
|
+
async multipleEvents() {
|
|
34
|
+
class TestEvent extends BaseEvent {
|
|
35
|
+
constructor() {
|
|
36
|
+
super({ body: {} });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const listener1 = async (event) => {
|
|
40
|
+
expect(event).toBeInstanceOf(EmptyEvent);
|
|
41
|
+
};
|
|
42
|
+
const listener2 = async (event) => {
|
|
43
|
+
expect(event).toBeInstanceOf(TestEvent);
|
|
44
|
+
};
|
|
45
|
+
this.publisher['addListener'](EmptyEvent, listener1);
|
|
46
|
+
this.publisher['addListener'](TestEvent, listener2);
|
|
47
|
+
await this.publisher.publish(new TestEvent());
|
|
48
|
+
expect.assertions(1);
|
|
49
|
+
}
|
|
50
|
+
async extendingEventsInherited() {
|
|
51
|
+
class TestEvent extends BaseEvent {
|
|
52
|
+
constructor() {
|
|
53
|
+
super({ body: {} });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
class ExtendedEvent extends TestEvent {
|
|
57
|
+
}
|
|
58
|
+
const listener1 = async (event) => {
|
|
59
|
+
expect(event).toBeInstanceOf(EmptyEvent);
|
|
60
|
+
};
|
|
61
|
+
const listener2 = async (event) => {
|
|
62
|
+
expect(event).toBeInstanceOf(TestEvent);
|
|
63
|
+
};
|
|
64
|
+
const listener3 = async (event) => {
|
|
65
|
+
expect(event).toBeInstanceOf(ExtendedEvent);
|
|
66
|
+
};
|
|
67
|
+
this.publisher['addListener'](EmptyEvent, listener1);
|
|
68
|
+
this.publisher['addListener'](TestEvent, listener2);
|
|
69
|
+
this.publisher['addListener'](ExtendedEvent, listener3);
|
|
70
|
+
await this.publisher.publish(new ExtendedEvent());
|
|
71
|
+
expect.assertions(2);
|
|
72
|
+
}
|
|
73
|
+
async extendingEventsParent() {
|
|
74
|
+
class TestEvent extends BaseEvent {
|
|
75
|
+
constructor() {
|
|
76
|
+
super({ body: {} });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
class ExtendedEvent extends TestEvent {
|
|
80
|
+
}
|
|
81
|
+
const listener1 = async (event) => {
|
|
82
|
+
expect(event).toBeInstanceOf(EmptyEvent);
|
|
83
|
+
};
|
|
84
|
+
const listener2 = async (event) => {
|
|
85
|
+
expect(event).toBeInstanceOf(TestEvent);
|
|
86
|
+
};
|
|
87
|
+
const listener3 = async (event) => {
|
|
88
|
+
expect(event).toBeInstanceOf(ExtendedEvent);
|
|
89
|
+
};
|
|
90
|
+
this.publisher['addListener'](EmptyEvent, listener1);
|
|
91
|
+
this.publisher['addListener'](TestEvent, listener2);
|
|
92
|
+
this.publisher['addListener'](ExtendedEvent, listener3);
|
|
93
|
+
await this.publisher.publish(new TestEvent());
|
|
94
|
+
expect.assertions(1);
|
|
95
|
+
}
|
|
96
|
+
async beforeEach() {
|
|
97
|
+
this.publisher = new EventPublisher();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
__decorate([
|
|
101
|
+
Test(),
|
|
102
|
+
__metadata("design:type", Function),
|
|
103
|
+
__metadata("design:paramtypes", []),
|
|
104
|
+
__metadata("design:returntype", Promise)
|
|
105
|
+
], EventPublisherTestSuite.prototype, "publish", null);
|
|
106
|
+
__decorate([
|
|
107
|
+
Test(),
|
|
108
|
+
__metadata("design:type", Function),
|
|
109
|
+
__metadata("design:paramtypes", []),
|
|
110
|
+
__metadata("design:returntype", Promise)
|
|
111
|
+
], EventPublisherTestSuite.prototype, "multipleListeners", null);
|
|
112
|
+
__decorate([
|
|
113
|
+
Test(),
|
|
114
|
+
__metadata("design:type", Function),
|
|
115
|
+
__metadata("design:paramtypes", []),
|
|
116
|
+
__metadata("design:returntype", Promise)
|
|
117
|
+
], EventPublisherTestSuite.prototype, "multipleEvents", null);
|
|
118
|
+
__decorate([
|
|
119
|
+
Test(),
|
|
120
|
+
__metadata("design:type", Function),
|
|
121
|
+
__metadata("design:paramtypes", []),
|
|
122
|
+
__metadata("design:returntype", Promise)
|
|
123
|
+
], EventPublisherTestSuite.prototype, "extendingEventsInherited", null);
|
|
124
|
+
__decorate([
|
|
125
|
+
Test(),
|
|
126
|
+
__metadata("design:type", Function),
|
|
127
|
+
__metadata("design:paramtypes", []),
|
|
128
|
+
__metadata("design:returntype", Promise)
|
|
129
|
+
], EventPublisherTestSuite.prototype, "extendingEventsParent", null);
|
|
130
|
+
EventPublisherTestSuite = __decorate([
|
|
131
|
+
Describe()
|
|
132
|
+
], EventPublisherTestSuite);
|
|
133
|
+
export { EventPublisherTestSuite };
|
|
134
|
+
//# sourceMappingURL=event-publisher.test-suite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-publisher.test-suite.js","sourceRoot":"","sources":["../../src/tests/event-publisher.test-suite.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hg-ts/events",
|
|
3
|
+
"version": "0.0.15",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"module": "dist-esm/index.js",
|
|
6
|
+
"repository": "git@gitlab.com:hyper-graph/framework.git",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"prepack": "yarn build && yarn lint",
|
|
9
|
+
"build": "hg build",
|
|
10
|
+
"build:dev": "hg build:dev",
|
|
11
|
+
"lint": "hg lint",
|
|
12
|
+
"lint:fix": "hg lint:fix",
|
|
13
|
+
"test": "hg test",
|
|
14
|
+
"test:dev": "hg test:dev"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@hg-ts-config/eslint-config": "0.0.15",
|
|
18
|
+
"@hg-ts-config/typescript": "0.0.15",
|
|
19
|
+
"@hg-ts/cli": "0.0.15",
|
|
20
|
+
"@hg-ts/tests": "0.0.15",
|
|
21
|
+
"@hg-ts/types": "0.0.15",
|
|
22
|
+
"@types/node": "18.0.3",
|
|
23
|
+
"@typescript-eslint/eslint-plugin": "5.33.1",
|
|
24
|
+
"@typescript-eslint/parser": "5.33.1",
|
|
25
|
+
"eslint": "8.24.0",
|
|
26
|
+
"eslint-formatter-codeframe": "7.32.1",
|
|
27
|
+
"mocha": "10.0.0",
|
|
28
|
+
"mocha-junit-reporter": "2.0.2",
|
|
29
|
+
"reflect-metadata": "0.1.13",
|
|
30
|
+
"tsc-watch": "5.0.3",
|
|
31
|
+
"tslib": "2.4.0",
|
|
32
|
+
"typescript": "4.7.4"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"reflect-metadata": "*",
|
|
36
|
+
"tslib": "*"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type EventParams<Body> = {
|
|
2
|
+
body: Body;
|
|
3
|
+
occurredOn?: Date;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export abstract class BaseEvent<Body = unknown> {
|
|
7
|
+
public readonly occurredOn: Date;
|
|
8
|
+
public readonly name: string;
|
|
9
|
+
public readonly body: Body;
|
|
10
|
+
|
|
11
|
+
public constructor({ body, occurredOn = new Date() }: EventParams<Body>) {
|
|
12
|
+
this.body = body;
|
|
13
|
+
this.occurredOn = occurredOn;
|
|
14
|
+
this.name = this.constructor.name;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './listen.decorator';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { BaseEvent } from '../base.event';
|
|
2
|
+
|
|
3
|
+
const LISTEN_META_KEY = Symbol('LISTEN_META_KEY');
|
|
4
|
+
const LISTEN_METHODS_META_KEY = Symbol('LISTEN_METHODS_META_KEY');
|
|
5
|
+
|
|
6
|
+
export type EventHandler<T extends BaseEvent = BaseEvent> = (event: T) => any;
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type,@typescript-eslint/explicit-module-boundary-types
|
|
9
|
+
export const Listen = <T extends BaseEvent>(eventClass: Class<T, any[]>) => (
|
|
10
|
+
proto: Object,
|
|
11
|
+
propertyKey: string | symbol,
|
|
12
|
+
_descriptor: TypedPropertyDescriptor<EventHandler<T>>,
|
|
13
|
+
) => {
|
|
14
|
+
const eventsToHandle = getEventsToHandle(proto, propertyKey);
|
|
15
|
+
const listenMethods = getListenMethods(proto);
|
|
16
|
+
|
|
17
|
+
eventsToHandle.push(eventClass);
|
|
18
|
+
if (!listenMethods.includes(propertyKey)) {
|
|
19
|
+
listenMethods.push(propertyKey);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
Reflect.defineMetadata(LISTEN_META_KEY, eventsToHandle, proto, propertyKey);
|
|
23
|
+
Reflect.defineMetadata(LISTEN_METHODS_META_KEY, listenMethods, proto);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export function getEventsToHandle(
|
|
27
|
+
proto: Object,
|
|
28
|
+
propertyKey: string | symbol,
|
|
29
|
+
): Class<BaseEvent>[] {
|
|
30
|
+
return Reflect.getMetadata(LISTEN_META_KEY, proto, propertyKey) ?? [];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getListenMethods(proto: Object): (string | symbol)[] {
|
|
34
|
+
return Reflect.getMetadata(LISTEN_METHODS_META_KEY, proto) ?? [];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function isEventListener(proto: Object): boolean {
|
|
38
|
+
return getListenMethods(proto).length > 0;
|
|
39
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BaseEvent } from '../base.event';
|
|
2
|
+
import type { BaseEventTransport } from './base.event-transport';
|
|
3
|
+
import type { EventPublisher } from './event-publisher';
|
|
4
|
+
|
|
5
|
+
export class EventEmitter {
|
|
6
|
+
private readonly transports: BaseEventTransport[];
|
|
7
|
+
|
|
8
|
+
public constructor(eventPublisher: EventPublisher) {
|
|
9
|
+
this.transports = [eventPublisher];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public async emit(event: BaseEvent | BaseEvent[]): Promise<void> {
|
|
13
|
+
await Promise.all(this.transports.map(async transport => transport.publish(event)));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
EventHandler,
|
|
5
|
+
getEventsToHandle,
|
|
6
|
+
getListenMethods,
|
|
7
|
+
isEventListener,
|
|
8
|
+
} from '../decorators';
|
|
9
|
+
|
|
10
|
+
import type { EventPublisher } from './event-publisher';
|
|
11
|
+
|
|
12
|
+
export class EventListenerManager {
|
|
13
|
+
private readonly eventPublisher: EventPublisher;
|
|
14
|
+
|
|
15
|
+
public constructor(eventPublisher: EventPublisher) {
|
|
16
|
+
this.eventPublisher = eventPublisher;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public addListener(instance: unknown): void {
|
|
20
|
+
const proto = Object.getPrototypeOf(instance);
|
|
21
|
+
if (!proto || !isEventListener(proto)) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const listenMethods = getListenMethods(proto);
|
|
26
|
+
const listener: Record<string | symbol, any> = instance as any;
|
|
27
|
+
|
|
28
|
+
listenMethods.forEach(methodName => {
|
|
29
|
+
const method = listener[methodName].bind(listener) as EventHandler;
|
|
30
|
+
const eventsToHandle = getEventsToHandle(proto, methodName);
|
|
31
|
+
|
|
32
|
+
eventsToHandle.forEach(eventCtor => {
|
|
33
|
+
this.eventPublisher['addListener'](eventCtor, method);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
|
|
3
|
+
import { BaseEvent } from '../base.event';
|
|
4
|
+
import type { EventHandler } from '../decorators';
|
|
5
|
+
import type { BaseEventTransport } from './base.event-transport';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export class EventPublisher implements BaseEventTransport {
|
|
9
|
+
private readonly listeners: Map<Class<BaseEvent>, EventHandler[]> = new Map();
|
|
10
|
+
|
|
11
|
+
public async publish(event: BaseEvent | BaseEvent[]): Promise<void> {
|
|
12
|
+
const events = Array.isArray(event) ? event : [event];
|
|
13
|
+
|
|
14
|
+
await Promise.all(events.map(async event => this.publishOne(event)));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
protected async publishOne(event: BaseEvent): Promise<void> {
|
|
18
|
+
assert.ok(event instanceof BaseEvent);
|
|
19
|
+
const listeners = this.findListeners(event);
|
|
20
|
+
|
|
21
|
+
await Promise.all(listeners.map(async listener => listener(event)));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
protected addListener<Event extends BaseEvent>(eventCtor: Class<Event>, listener: EventHandler<Event>): void {
|
|
25
|
+
const listeners: EventHandler<Event>[] = this.listeners.get(eventCtor) ?? [];
|
|
26
|
+
|
|
27
|
+
listeners.push(listener);
|
|
28
|
+
|
|
29
|
+
this.listeners.set(eventCtor, listeners as EventHandler[]);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private findListeners(event: BaseEvent): EventHandler[] {
|
|
33
|
+
const eventCtor = Object.getPrototypeOf(event)!.constructor;
|
|
34
|
+
const listenEvents = [...this.listeners.keys()];
|
|
35
|
+
|
|
36
|
+
return listenEvents
|
|
37
|
+
.filter(ctor => eventCtor.prototype instanceof ctor || eventCtor === ctor)
|
|
38
|
+
.flatMap(ctor => this.listeners.get(ctor) ?? []);
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// eslint-disable-next-line max-classes-per-file
|
|
2
|
+
import { Describe, TestSuite, Test, expect } from '@hg-ts/tests';
|
|
3
|
+
import { Listen } from '../decorators';
|
|
4
|
+
|
|
5
|
+
import { EventPublisher, EventListenerManager } from '../event-handling';
|
|
6
|
+
|
|
7
|
+
import { BaseEvent } from '../base.event';
|
|
8
|
+
import { EmptyEvent } from '../empty.event';
|
|
9
|
+
|
|
10
|
+
@Describe()
|
|
11
|
+
export class EventPublisherTestSuite extends TestSuite {
|
|
12
|
+
private publisher: EventPublisher;
|
|
13
|
+
private eventListenerManager: EventListenerManager;
|
|
14
|
+
|
|
15
|
+
@Test()
|
|
16
|
+
public async addListener(): Promise<void> {
|
|
17
|
+
class TestEvent extends BaseEvent<{}> {
|
|
18
|
+
public constructor() {
|
|
19
|
+
super({ body: {} });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
class ExtendedEvent extends TestEvent {}
|
|
23
|
+
class Listener {
|
|
24
|
+
public called = new Map<Class<BaseEvent>, number>();
|
|
25
|
+
|
|
26
|
+
@Listen(EmptyEvent)
|
|
27
|
+
public async empty(event: EmptyEvent): Promise<void> {
|
|
28
|
+
this.check(event, EmptyEvent);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@Listen(TestEvent)
|
|
32
|
+
public async test(event: TestEvent): Promise<void> {
|
|
33
|
+
this.check(event, TestEvent);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Listen(ExtendedEvent)
|
|
37
|
+
public async extended(event: ExtendedEvent): Promise<void> {
|
|
38
|
+
this.check(event, ExtendedEvent);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private check(event: BaseEvent, ctor: Class<BaseEvent, any[]>): void {
|
|
42
|
+
let count = this.called.get(ctor) ?? 0;
|
|
43
|
+
|
|
44
|
+
expect(event).toBeInstanceOf(ctor);
|
|
45
|
+
count++;
|
|
46
|
+
|
|
47
|
+
this.called.set(ctor, count);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const listener = new Listener();
|
|
51
|
+
|
|
52
|
+
this.eventListenerManager.addListener(listener);
|
|
53
|
+
|
|
54
|
+
await this.publisher.publish(new EmptyEvent());
|
|
55
|
+
await this.publisher.publish(new TestEvent());
|
|
56
|
+
await this.publisher.publish(new ExtendedEvent());
|
|
57
|
+
|
|
58
|
+
expect(listener.called.get(EmptyEvent)).toBe(1);
|
|
59
|
+
expect(listener.called.get(TestEvent)).toBe(2);
|
|
60
|
+
expect(listener.called.get(ExtendedEvent)).toBe(1);
|
|
61
|
+
|
|
62
|
+
expect.assertions(7);
|
|
63
|
+
}
|
|
64
|
+
public override async beforeEach(): Promise<void> {
|
|
65
|
+
this.publisher = new EventPublisher();
|
|
66
|
+
this.eventListenerManager = new EventListenerManager(this.publisher);
|
|
67
|
+
}
|
|
68
|
+
}
|