@tryghost/domain-events 0.1.14 → 1.0.1
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/LICENSE +1 -1
- package/README.md +0 -31
- package/lib/DomainEvents.js +58 -3
- package/package.json +19 -13
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
# Domain Events
|
|
2
2
|
|
|
3
|
-
## Install
|
|
4
|
-
|
|
5
|
-
`npm install @tryghost/domain-events --save`
|
|
6
|
-
|
|
7
|
-
or
|
|
8
|
-
|
|
9
|
-
`yarn add @tryghost/domain-events`
|
|
10
|
-
|
|
11
|
-
|
|
12
3
|
## Usage
|
|
13
4
|
|
|
14
5
|
```js
|
|
@@ -31,25 +22,3 @@ const event = new MyEvent('hello world');
|
|
|
31
22
|
|
|
32
23
|
DomainEvents.dispatch(event);
|
|
33
24
|
```
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
## Develop
|
|
37
|
-
|
|
38
|
-
This is a mono repository, managed with [lerna](https://lernajs.io/).
|
|
39
|
-
|
|
40
|
-
Follow the instructions for the top-level repo.
|
|
41
|
-
1. `git clone` this repo & `cd` into it as usual
|
|
42
|
-
2. Run `yarn` to install top-level dependencies.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
## Run
|
|
46
|
-
|
|
47
|
-
- `yarn dev`
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
## Test
|
|
51
|
-
|
|
52
|
-
- `yarn lint` run just eslint
|
|
53
|
-
- `yarn test` run lint and tests
|
|
54
|
-
|
|
55
|
-
|
package/lib/DomainEvents.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const EventEmitter = require('events').EventEmitter;
|
|
2
|
+
const logging = require('@tryghost/logging');
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* @template T
|
|
@@ -23,12 +24,22 @@ class DomainEvents {
|
|
|
23
24
|
* @template Data
|
|
24
25
|
* @template {IEvent<Data>} EventClass
|
|
25
26
|
* @param {ConstructorOf<EventClass>} Event
|
|
26
|
-
* @param {(event: EventClass) => void} handler
|
|
27
|
+
* @param {(event: EventClass) => Promise<void> | void} handler
|
|
27
28
|
*
|
|
28
29
|
* @returns {void}
|
|
29
30
|
*/
|
|
30
31
|
static subscribe(Event, handler) {
|
|
31
|
-
DomainEvents.ee.on(Event.name,
|
|
32
|
+
DomainEvents.ee.on(Event.name, async (event) => {
|
|
33
|
+
try {
|
|
34
|
+
await handler(event);
|
|
35
|
+
} catch (e) {
|
|
36
|
+
logging.error('Unhandled error in event handler for event: ' + Event.name);
|
|
37
|
+
logging.error(e);
|
|
38
|
+
}
|
|
39
|
+
if (this.#trackingEnabled) {
|
|
40
|
+
this.#onProcessed();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
32
43
|
}
|
|
33
44
|
|
|
34
45
|
/**
|
|
@@ -37,7 +48,51 @@ class DomainEvents {
|
|
|
37
48
|
* @returns {void}
|
|
38
49
|
*/
|
|
39
50
|
static dispatch(event) {
|
|
40
|
-
DomainEvents.
|
|
51
|
+
DomainEvents.dispatchRaw(event.constructor.name, event);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Dispatch an event in case you don't have an instance of the event class, but you do have the event name and event data.
|
|
56
|
+
* @template Data
|
|
57
|
+
* @param {string} name
|
|
58
|
+
* @param {Data} data
|
|
59
|
+
* @returns {void}
|
|
60
|
+
*/
|
|
61
|
+
static dispatchRaw(name, data) {
|
|
62
|
+
if (this.#trackingEnabled) {
|
|
63
|
+
this.#dispatchCount += DomainEvents.ee.listenerCount(name);
|
|
64
|
+
}
|
|
65
|
+
DomainEvents.ee.emit(name, data);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Methods and properties below are only for testing purposes
|
|
69
|
+
static #awaitQueue = [];
|
|
70
|
+
static #dispatchCount = 0;
|
|
71
|
+
static #processedCount = 0;
|
|
72
|
+
static #trackingEnabled = process.env.NODE_ENV?.startsWith('test');
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Waits for all the events in the queue to be dispatched and fully processed (async).
|
|
76
|
+
*/
|
|
77
|
+
static allSettled() {
|
|
78
|
+
return new Promise((resolve) => {
|
|
79
|
+
if (this.#processedCount >= this.#dispatchCount) {
|
|
80
|
+
// Resolve immediately if there are no events in the queue
|
|
81
|
+
resolve();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this.#awaitQueue.push({resolve});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static #onProcessed() {
|
|
89
|
+
this.#processedCount += 1;
|
|
90
|
+
if (this.#processedCount >= this.#dispatchCount) {
|
|
91
|
+
for (const item of this.#awaitQueue) {
|
|
92
|
+
item.resolve();
|
|
93
|
+
}
|
|
94
|
+
this.#awaitQueue = [];
|
|
95
|
+
}
|
|
41
96
|
}
|
|
42
97
|
}
|
|
43
98
|
|
package/package.json
CHANGED
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tryghost/domain-events",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
5
7
|
"author": "Ghost Foundation",
|
|
6
8
|
"license": "MIT",
|
|
7
9
|
"main": "index.js",
|
|
8
10
|
"types": "types",
|
|
9
11
|
"scripts": {
|
|
10
12
|
"dev": "echo \"Implement me!\"",
|
|
11
|
-
"test": "NODE_ENV=testing c8 --all --reporter text --reporter cobertura --check-coverage mocha './test/**/*.test.js'",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
13
|
+
"test:unit": "NODE_ENV=testing c8 --all --reporter text --reporter cobertura --check-coverage --100 -- mocha --reporter dot './test/**/*.test.js'",
|
|
14
|
+
"test": "yarn test:unit",
|
|
15
|
+
"lint:code": "eslint *.js lib/ --ext .js --cache",
|
|
16
|
+
"lint": "yarn lint:code && yarn lint:test",
|
|
17
|
+
"lint:test": "eslint -c test/.eslintrc.js test/ --ext .js --cache"
|
|
14
18
|
},
|
|
15
19
|
"files": [
|
|
16
20
|
"index.js",
|
|
17
21
|
"lib"
|
|
18
22
|
],
|
|
19
|
-
"publishConfig": {
|
|
20
|
-
"access": "public"
|
|
21
|
-
},
|
|
22
23
|
"devDependencies": {
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
24
|
+
"@tryghost/logging": "^2.4.22",
|
|
25
|
+
"c8": "8.0.1",
|
|
26
|
+
"mocha": "10.8.2",
|
|
27
|
+
"should": "13.2.3"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/TryGhost/framework.git",
|
|
32
|
+
"directory": "packages/domain-events"
|
|
27
33
|
},
|
|
28
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "e395f1d79edee4aecc36e572bb402016a8ba9273"
|
|
29
35
|
}
|