@tryghost/domain-events 0.1.13 → 1.0.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2013-2022 Ghost Foundation
3
+ Copyright (c) 2013-2025 Ghost Foundation
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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
-
@@ -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, handler);
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.ee.emit(event.constructor.name, event);
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,30 @@
1
1
  {
2
2
  "name": "@tryghost/domain-events",
3
- "version": "0.1.13",
4
- "repository": "https://github.com/TryGhost/Members/tree/main/packages/domain-events",
3
+ "version": "1.0.0",
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
- "lint": "eslint . --ext .js --cache",
13
- "posttest": "yarn lint"
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
- "c8": "7.11.2",
24
- "mocha": "10.0.0",
25
- "should": "13.2.3",
26
- "sinon": "14.0.0"
24
+ "@tryghost/logging": "2.4.21",
25
+ "c8": "8.0.1",
26
+ "mocha": "10.8.2",
27
+ "should": "13.2.3"
27
28
  },
28
- "gitHead": "147750850f658077b0bc59162d7508daaed4c589"
29
+ "gitHead": "feac71f0032c5d92f56a8dfa7ccd5a2d883ad53d"
29
30
  }