Skip to content

Commit e488dca

Browse files
authored
Merge pull request #26 from cb1kenobi/nested
Support nested linked emitters
2 parents ffc70d4 + 2625df8 commit e488dca

File tree

7 files changed

+737
-437
lines changed

7 files changed

+737
-437
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# 4.1.2 (Feb 23, 2021)
2+
3+
* fix: Support nested linked emitters. ([#25](https://github.com/cb1kenobi/hook-emitter/issues/25))
4+
* chore: Updated dependencies.
5+
16
# 4.1.1 (Nov 20, 2020)
27

38
* fix: `emit()` should not throw on error, but rather return a rejected promise.

gulpfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ async function runTests(cover) {
131131
args.push(path.join(mocha, 'bin', 'mocha'));
132132

133133
// add --inspect
134-
if (process.argv.indexOf('--inspect') !== -1 || process.argv.indexOf('--inspect-brk') !== -1) {
134+
if (process.argv.indexOf('--debug') !== -1 || process.argv.indexOf('--inspect') !== -1 || process.argv.indexOf('--inspect-brk') !== -1) {
135135
args.push('--inspect-brk');
136136
}
137137

package.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hook-emitter",
3-
"version": "4.1.1",
3+
"version": "4.1.2",
44
"description": "Event emitter with support for asynchronous handlers and a sweet function hook mechanism.",
55
"main": "./dist/index.js",
66
"author": "Chris Barber <chris@cb1inc.com> (https://github.com/cb1kenobi)",
@@ -28,34 +28,34 @@
2828
"source-map-support": "^0.5.19"
2929
},
3030
"devDependencies": {
31-
"@babel/core": "^7.12.3",
32-
"@babel/plugin-transform-modules-commonjs": "^7.12.1",
33-
"@babel/register": "^7.12.1",
31+
"@babel/core": "^7.13.1",
32+
"@babel/plugin-transform-modules-commonjs": "^7.13.0",
33+
"@babel/register": "^7.13.0",
3434
"ansi-colors": "^4.1.1",
3535
"babel-eslint": "^10.1.0",
36-
"babel-loader": "^8.2.1",
36+
"babel-loader": "^8.2.2",
3737
"babel-plugin-istanbul": "^6.0.0",
38-
"chai": "^4.2.0",
38+
"chai": "^4.3.0",
3939
"chai-as-promised": "^7.1.1",
4040
"coveralls": "^3.1.0",
4141
"esdoc": "^1.1.0",
4242
"esdoc-ecmascript-proposal-plugin": "^1.0.0",
4343
"esdoc-standard-plugin": "^1.0.0",
44-
"eslint": "^7.13.0",
44+
"eslint": "^7.20.0",
4545
"eslint-plugin-chai-expect": "^2.2.0",
4646
"eslint-plugin-mocha": "^8.0.0",
47-
"eslint-plugin-promise": "^4.2.1",
47+
"eslint-plugin-promise": "^4.3.1",
4848
"eslint-plugin-security": "^1.4.0",
4949
"fancy-log": "^1.3.3",
50-
"fs-extra": "^9.0.1",
50+
"fs-extra": "^9.1.0",
5151
"gulp": "^4.0.2",
5252
"gulp-babel": "^8.0.0",
5353
"gulp-debug": "^4.0.0",
5454
"gulp-eslint": "^6.0.0",
55-
"gulp-load-plugins": "^2.0.5",
55+
"gulp-load-plugins": "^2.0.6",
5656
"gulp-plumber": "^1.2.1",
5757
"gulp-sourcemaps": "^3.0.0",
58-
"mocha": "^8.2.1",
58+
"mocha": "^8.3.0",
5959
"nyc": "^15.1.0"
6060
},
6161
"homepage": "https://github.com/cb1kenobi/hook-emitter",

src/index.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -192,24 +192,31 @@ export class HookEmitter {
192192
// listener in the chain
193193
transform = (result, payload) => ({
194194
type: payload.type,
195-
args: result || payload.args
195+
args: result !== undefined ? result : payload.args
196196
});
197197
}
198198

199199
// create the function that fetches the events since the list of
200200
// listeners may change before the hook is called
201201
const getListeners = () => {
202-
const listeners = this._events.get(type) || [];
202+
let listeners = this._events.get(type) || [];
203203
if (!Array.isArray(listeners)) {
204204
throw new TypeError('Expected listeners to be an array.');
205205
}
206206

207-
const linkedListeners = this._links.map(link => {
208-
return link.emitter.events.get((link.prefix || '') + type) || [];
209-
});
207+
// clone the listeners
208+
listeners = [ ...listeners ];
209+
210+
for (const link of this._links) {
211+
listeners.push({
212+
listener: link.emitter.compose({
213+
type: (link.prefix || '') + type
214+
}),
215+
priority: 0
216+
});
217+
}
210218

211219
return listeners
212-
.concat.apply(listeners, linkedListeners)
213220
.sort((a, b) => b.priority - a.priority)
214221
.map(p => {
215222
if (typeof p.listener !== 'function') {
@@ -255,7 +262,7 @@ export class HookEmitter {
255262
// if somebody mixes paradigms and calls next().then(),
256263
// at least their function will wait for the next listener
257264
return dispatch(result || payload, i + 1)
258-
.then(result => (innerResult = result || payload))
265+
.then(result => (innerResult = result !== undefined ? result : payload))
259266
.catch(reject);
260267
} ];
261268

@@ -269,7 +276,7 @@ export class HookEmitter {
269276
if (result instanceof Promise) {
270277
return result
271278
.then(result => {
272-
result = transform(fired && innerResult || result, payload);
279+
result = transform(fired && innerResult !== undefined ? innerResult : result, payload);
273280
return fired ? result : dispatch(result, i + 1);
274281
})
275282
.then(resolve)
@@ -345,7 +352,7 @@ export class HookEmitter {
345352
this.result = await this.fn.apply(this.ctx, this.args);
346353
return this;
347354
},
348-
transform: (result, data) => result || data
355+
transform: (result, data) => result !== undefined ? result : data
349356
});
350357

351358
return chain.apply(data, data.args).then(data => data.result);

test/.eslintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"sinon": false
1414
},
1515
"rules": {
16+
"no-debugger": "warn",
1617
"no-unused-vars": 0
1718
}
1819
}

test/test-hookemitter.js

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,4 +1294,125 @@ describe('link', () => {
12941294
emitter.unlink('foo');
12951295
}).to.throw('Expected argument to be a HookEmitter.');
12961296
});
1297+
1298+
it('should link nested emitted events', async () => {
1299+
let aCount = 0;
1300+
let bCount = 0;
1301+
let cCount = 0;
1302+
1303+
const a = new HookEmitter().on('foo', () => aCount++);
1304+
const b = new HookEmitter().on('foo', () => bCount++);
1305+
const c = new HookEmitter().on('foo', () => cCount++);
1306+
1307+
await a.emit('foo');
1308+
expect(aCount).to.equal(1);
1309+
expect(bCount).to.equal(0);
1310+
expect(cCount).to.equal(0);
1311+
1312+
a.link(b);
1313+
1314+
await a.emit('foo');
1315+
expect(aCount).to.equal(2);
1316+
expect(bCount).to.equal(1);
1317+
expect(cCount).to.equal(0);
1318+
1319+
await b.emit('foo');
1320+
expect(aCount).to.equal(2);
1321+
expect(bCount).to.equal(2);
1322+
expect(cCount).to.equal(0);
1323+
1324+
b.link(c);
1325+
1326+
await a.emit('foo');
1327+
expect(aCount).to.equal(3);
1328+
expect(bCount).to.equal(3);
1329+
expect(cCount).to.equal(1);
1330+
1331+
await b.emit('foo');
1332+
expect(aCount).to.equal(3);
1333+
expect(bCount).to.equal(4);
1334+
expect(cCount).to.equal(2);
1335+
});
1336+
1337+
it('should link nested emitted hooks', async () => {
1338+
let aCount = 0;
1339+
let bCount = 0;
1340+
let cCount = 0;
1341+
1342+
let ahCount = 0;
1343+
let bhCount = 0;
1344+
let chCount = 0;
1345+
1346+
const a = new HookEmitter().on('foo', () => aCount++);
1347+
const b = new HookEmitter().on('foo', () => bCount++);
1348+
const c = new HookEmitter().on('foo', () => cCount++);
1349+
1350+
a.name = 'a';
1351+
b.name = 'b';
1352+
c.name = 'c';
1353+
1354+
const afn = a.hook('foo', () => ahCount++);
1355+
const bfn = b.hook('foo', () => bhCount++);
1356+
const cfn = c.hook('foo', () => chCount++);
1357+
1358+
await afn();
1359+
expect(ahCount).to.equal(1);
1360+
expect(bhCount).to.equal(0);
1361+
expect(chCount).to.equal(0);
1362+
expect(aCount).to.equal(1);
1363+
expect(bCount).to.equal(0);
1364+
expect(cCount).to.equal(0);
1365+
1366+
await bfn();
1367+
expect(ahCount).to.equal(1);
1368+
expect(bhCount).to.equal(1);
1369+
expect(chCount).to.equal(0);
1370+
expect(aCount).to.equal(1);
1371+
expect(bCount).to.equal(1);
1372+
expect(cCount).to.equal(0);
1373+
1374+
a.link(b);
1375+
1376+
await afn();
1377+
expect(ahCount).to.equal(2);
1378+
expect(bhCount).to.equal(1);
1379+
expect(chCount).to.equal(0);
1380+
expect(aCount).to.equal(2);
1381+
expect(bCount).to.equal(2);
1382+
expect(cCount).to.equal(0);
1383+
1384+
await bfn();
1385+
expect(ahCount).to.equal(2);
1386+
expect(bhCount).to.equal(2);
1387+
expect(chCount).to.equal(0);
1388+
expect(aCount).to.equal(2);
1389+
expect(bCount).to.equal(3);
1390+
expect(cCount).to.equal(0);
1391+
1392+
b.link(c);
1393+
1394+
await afn();
1395+
expect(ahCount).to.equal(3);
1396+
expect(bhCount).to.equal(2);
1397+
expect(chCount).to.equal(0);
1398+
expect(aCount).to.equal(3);
1399+
expect(bCount).to.equal(4);
1400+
expect(cCount).to.equal(1);
1401+
1402+
await bfn();
1403+
expect(ahCount).to.equal(3);
1404+
expect(bhCount).to.equal(3);
1405+
expect(chCount).to.equal(0);
1406+
expect(aCount).to.equal(3);
1407+
expect(bCount).to.equal(5);
1408+
expect(cCount).to.equal(2);
1409+
1410+
await cfn();
1411+
expect(ahCount).to.equal(3);
1412+
expect(bhCount).to.equal(3);
1413+
expect(chCount).to.equal(1);
1414+
expect(aCount).to.equal(3);
1415+
expect(bCount).to.equal(5);
1416+
expect(cCount).to.equal(3);
1417+
});
12971418
});

0 commit comments

Comments
 (0)