@irrelon/emitter 4.0.1 → 5.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/.eslintignore +3 -1
- package/.eslintrc.json +8 -2
- package/dist/Emitter.d.ts +205 -0
- package/dist/Emitter.js +295 -657
- package/package.json +54 -52
- package/readme.md +44 -11
- package/src/{Emitter.js → Emitter.ts} +138 -141
- package/tests/Emitter.test.js +26 -6
- package/tsconfig.json +29 -0
|
@@ -25,6 +25,12 @@
|
|
|
25
25
|
Source: https://github.com/irrelon/emitter
|
|
26
26
|
|
|
27
27
|
Changelog:
|
|
28
|
+
Version 5.0.0:
|
|
29
|
+
Added typescript types, switched from mocha to jest for test
|
|
30
|
+
running.
|
|
31
|
+
Breaking change. When using makeEmitter, prototypeMode is now
|
|
32
|
+
false by default. Simply pass makeEmitter(SomeClass.prototype)
|
|
33
|
+
instead of makeEmitter(SomeClass) to modify a prototype.
|
|
28
34
|
Version 4.0.1:
|
|
29
35
|
Updated library to use new ES6 functionality making Overload()
|
|
30
36
|
less useful so it can be removed as a dependency.
|
|
@@ -77,9 +83,49 @@
|
|
|
77
83
|
Version 1.0.0:
|
|
78
84
|
First commit
|
|
79
85
|
*/
|
|
80
|
-
|
|
86
|
+
export interface InternalEventListenersType {
|
|
87
|
+
[eventName: string|symbol]: InternalEventListenersByIdType
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface InternalEventListenersByIdType {
|
|
91
|
+
[idName: string|symbol]: Array<EventListenerType>
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type EventListenerType = (...rest: any[]) => any;
|
|
95
|
+
|
|
96
|
+
export interface InternalEventEmittersType {
|
|
97
|
+
[eventName: string|symbol]: Array<EventEmitterType>
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface EventEmitterType {
|
|
101
|
+
id: string|symbol
|
|
102
|
+
args: any
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @class Emitter
|
|
107
|
+
* @constructor
|
|
108
|
+
*/
|
|
109
|
+
export class Emitter {
|
|
110
|
+
private _emitting: boolean;
|
|
111
|
+
private _noEmitDefer: boolean;
|
|
112
|
+
private _listeners: InternalEventListenersType
|
|
113
|
+
private _emitters: InternalEventEmittersType
|
|
114
|
+
private _eventRemovalQueue: Array<(...rest: any[]) => any>;
|
|
115
|
+
private _deferTimeout: any;
|
|
116
|
+
|
|
117
|
+
constructor (obj?: any) {
|
|
118
|
+
this._noEmitDefer = false;
|
|
119
|
+
this._emitting = false;
|
|
120
|
+
this._listeners = {};
|
|
121
|
+
this._emitters = {};
|
|
122
|
+
this._eventRemovalQueue = [];
|
|
123
|
+
|
|
124
|
+
if (obj !== undefined) {
|
|
125
|
+
return makeEmitter(obj);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
81
128
|
|
|
82
|
-
const EventMainMethods = {
|
|
83
129
|
/**
|
|
84
130
|
* Attach an event listener to the passed event only if the passed
|
|
85
131
|
* id matches the document id for the event being fired.
|
|
@@ -90,10 +136,8 @@ const EventMainMethods = {
|
|
|
90
136
|
* @param {Function} listener The method to call when the event is fired.
|
|
91
137
|
* @returns {Emitter} The emitter instance.
|
|
92
138
|
*/
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
const generateTimeout = (emitter) => {
|
|
139
|
+
_on (event: string|symbol, id: string|symbol, listener: (...rest: any[]) => any) {
|
|
140
|
+
const generateEmitterTimeout = (emitter: EventEmitterType) => {
|
|
97
141
|
setTimeout(() => {
|
|
98
142
|
listener.apply(this, emitter.args);
|
|
99
143
|
}, 1);
|
|
@@ -108,19 +152,17 @@ const EventMainMethods = {
|
|
|
108
152
|
if (!this._emitters || !this._emitters[event] || !this._emitters[event].length) return this;
|
|
109
153
|
|
|
110
154
|
// Emit events for each emitter
|
|
111
|
-
|
|
112
|
-
const emitter = this._emitters[event];
|
|
113
|
-
|
|
155
|
+
this._emitters[event].forEach((emitter: EventEmitterType) => {
|
|
114
156
|
if (id === "*" || emitter.id === id) {
|
|
115
157
|
// Call the listener out of process so that any code that expects a listener
|
|
116
158
|
// to be called at some point in the future rather than immediately on registration
|
|
117
159
|
// will not fail
|
|
118
|
-
|
|
160
|
+
generateEmitterTimeout(emitter);
|
|
119
161
|
}
|
|
120
|
-
}
|
|
162
|
+
});
|
|
121
163
|
|
|
122
164
|
return this;
|
|
123
|
-
}
|
|
165
|
+
}
|
|
124
166
|
|
|
125
167
|
/**
|
|
126
168
|
* Attach an event listener to the passed event only if the passed
|
|
@@ -132,19 +174,19 @@ const EventMainMethods = {
|
|
|
132
174
|
* @param {Function} listener The method to call when the event is fired.
|
|
133
175
|
* @returns {Emitter} The emitter instance.
|
|
134
176
|
*/
|
|
135
|
-
|
|
177
|
+
_once (event:string|symbol, id:string|symbol, listener: EventListenerType) {
|
|
136
178
|
let fired = false;
|
|
137
179
|
|
|
138
|
-
const internalCallback = () => {
|
|
180
|
+
const internalCallback = (...rest: any[]) => {
|
|
139
181
|
if (fired) return;
|
|
140
182
|
|
|
141
183
|
fired = true;
|
|
142
184
|
this.off(event, id, internalCallback);
|
|
143
|
-
listener
|
|
185
|
+
listener(...rest);
|
|
144
186
|
};
|
|
145
187
|
|
|
146
188
|
return this.on(event, id, internalCallback);
|
|
147
|
-
}
|
|
189
|
+
}
|
|
148
190
|
|
|
149
191
|
/**
|
|
150
192
|
* Cancels an event listener based on an event name, id and listener function.
|
|
@@ -156,7 +198,7 @@ const EventMainMethods = {
|
|
|
156
198
|
* or once() call to cancel.
|
|
157
199
|
* @returns {Emitter} The emitter instance.
|
|
158
200
|
*/
|
|
159
|
-
|
|
201
|
+
_off (event: string|symbol, id: string|symbol, listener?: EventListenerType) {
|
|
160
202
|
if (this._emitting) {
|
|
161
203
|
this._eventRemovalQueue = this._eventRemovalQueue || [];
|
|
162
204
|
this._eventRemovalQueue.push(() => {
|
|
@@ -179,20 +221,16 @@ const EventMainMethods = {
|
|
|
179
221
|
return this;
|
|
180
222
|
}
|
|
181
223
|
|
|
182
|
-
|
|
183
|
-
|
|
224
|
+
if (!listener) return this;
|
|
225
|
+
|
|
226
|
+
const arr = this._listeners[event][id] || [];
|
|
227
|
+
const index = arr.indexOf(listener);
|
|
184
228
|
|
|
185
229
|
if (index > -1) {
|
|
186
230
|
arr.splice(index, 1);
|
|
187
231
|
}
|
|
188
232
|
}
|
|
189
|
-
};
|
|
190
233
|
|
|
191
|
-
/**
|
|
192
|
-
* @class Emitter
|
|
193
|
-
* @constructor
|
|
194
|
-
*/
|
|
195
|
-
class Emitter {
|
|
196
234
|
/**
|
|
197
235
|
* Attach an event listener to the passed event only if the passed
|
|
198
236
|
* id matches the document id for the event being fired.
|
|
@@ -203,14 +241,16 @@ class Emitter {
|
|
|
203
241
|
* @param {Function} listener The method to call when the event is fired.
|
|
204
242
|
* @returns {Emitter} The emitter instance.
|
|
205
243
|
*/
|
|
206
|
-
on (event,
|
|
244
|
+
on (event: string|symbol, id: string|symbol, listener: EventListenerType): any;
|
|
245
|
+
on (event: string|symbol, listener: (...rest: any[]) => any): any;
|
|
246
|
+
on (event: string|symbol, ...rest: any[]) {
|
|
207
247
|
const restTypes = rest.map((arg) => typeof arg);
|
|
208
248
|
|
|
209
249
|
if (restTypes[0] === "function") {
|
|
210
|
-
return
|
|
250
|
+
return this._on.call(this, event, "*", rest[0]);
|
|
211
251
|
}
|
|
212
252
|
|
|
213
|
-
return
|
|
253
|
+
return this._on.call(this, event, rest[0], rest[1]);
|
|
214
254
|
}
|
|
215
255
|
|
|
216
256
|
/**
|
|
@@ -223,14 +263,16 @@ class Emitter {
|
|
|
223
263
|
* @param {Function} listener The method to call when the event is fired.
|
|
224
264
|
* @returns {Emitter} The emitter instance.
|
|
225
265
|
*/
|
|
226
|
-
once (event,
|
|
266
|
+
once (event: string, id: string|symbol, listener: EventListenerType): any;
|
|
267
|
+
once (event: string, listener: (...rest: any[]) => any): any;
|
|
268
|
+
once (event: string, ...rest: any[]) {
|
|
227
269
|
const restTypes = rest.map((arg) => typeof arg);
|
|
228
270
|
|
|
229
271
|
if (restTypes[0] === "function") {
|
|
230
|
-
return
|
|
272
|
+
return this._once.call(this, event, "*", rest[0]);
|
|
231
273
|
}
|
|
232
274
|
|
|
233
|
-
return
|
|
275
|
+
return this._once.call(this, event, rest[0], rest[1]);
|
|
234
276
|
}
|
|
235
277
|
|
|
236
278
|
/**
|
|
@@ -243,41 +285,46 @@ class Emitter {
|
|
|
243
285
|
* @param {Function} listener The method to call when the event is fired.
|
|
244
286
|
* @returns {Emitter} The emitter instance.
|
|
245
287
|
*/
|
|
246
|
-
one (event,
|
|
288
|
+
one (event: string, id: string|symbol, listener: EventListenerType): any;
|
|
289
|
+
one (event: string, listener: (...rest: any[]) => any): any;
|
|
290
|
+
one (event: string, ...rest: any[]) {
|
|
247
291
|
const restTypes = rest.map((arg) => typeof arg);
|
|
248
292
|
|
|
249
293
|
if (restTypes[0] === "function") {
|
|
250
294
|
this.off(event);
|
|
251
|
-
return
|
|
295
|
+
return this._on.call(this, event, "*", rest[0]);
|
|
252
296
|
}
|
|
253
297
|
|
|
254
298
|
this.off(event, rest[0]);
|
|
255
|
-
return
|
|
299
|
+
return this._on.call(this, event, rest[0], rest[1]);
|
|
256
300
|
}
|
|
257
301
|
|
|
258
302
|
/**
|
|
259
303
|
* Cancels an event listener based on an event name, id and listener function.
|
|
260
304
|
* @memberOf Emitter
|
|
261
305
|
* @method off
|
|
262
|
-
* @param
|
|
263
|
-
* @param
|
|
264
|
-
* @param
|
|
306
|
+
* @param event The event to cancel listener for.
|
|
307
|
+
* @param id The ID of the event to cancel listening for.
|
|
308
|
+
* @param listener The event listener function used in the on()
|
|
265
309
|
* or once() call to cancel.
|
|
266
310
|
* @returns {Emitter} The emitter instance.
|
|
267
311
|
*/
|
|
268
|
-
off (event,
|
|
312
|
+
off (event: string|symbol, id: string|symbol, listener?: EventListenerType): any;
|
|
313
|
+
off (event: string|symbol, listener: (...rest: any[]) => any): any;
|
|
314
|
+
off (event: string|symbol): any;
|
|
315
|
+
off (event: string|symbol, ...rest: any[]) {
|
|
269
316
|
if (rest.length === 0) {
|
|
270
317
|
// Only event was provided
|
|
271
|
-
return
|
|
318
|
+
return this._off.call(this, event, "*");
|
|
272
319
|
}
|
|
273
320
|
|
|
274
321
|
const restTypes = rest.map((arg) => typeof arg);
|
|
275
322
|
|
|
276
323
|
if (restTypes[0] === "function") {
|
|
277
|
-
return
|
|
324
|
+
return this._off.call(this, event, "*", rest[0]);
|
|
278
325
|
}
|
|
279
326
|
|
|
280
|
-
return
|
|
327
|
+
return this._off.call(this, event, rest[0], rest[1]);
|
|
281
328
|
}
|
|
282
329
|
|
|
283
330
|
/**
|
|
@@ -287,7 +334,7 @@ class Emitter {
|
|
|
287
334
|
* @returns {Emitter} The emitter instance.
|
|
288
335
|
* @private
|
|
289
336
|
*/
|
|
290
|
-
emit (event, ...data) {
|
|
337
|
+
emit (event: string|symbol, ...data: any[]) {
|
|
291
338
|
const id = "*";
|
|
292
339
|
this._listeners = this._listeners || {};
|
|
293
340
|
this._emitting = true;
|
|
@@ -313,11 +360,11 @@ class Emitter {
|
|
|
313
360
|
return this;
|
|
314
361
|
}
|
|
315
362
|
|
|
316
|
-
emitId (event, id, ...data) {
|
|
363
|
+
emitId (event: string|symbol, id: string|symbol, ...data: any[]) {
|
|
317
364
|
this._listeners = this._listeners || {};
|
|
318
365
|
this._emitting = true;
|
|
319
366
|
|
|
320
|
-
if (!this._listeners[event]) {
|
|
367
|
+
if (!this._listeners || !this._listeners[event]) {
|
|
321
368
|
this._emitting = false;
|
|
322
369
|
this._processRemovalQueue();
|
|
323
370
|
|
|
@@ -361,34 +408,13 @@ class Emitter {
|
|
|
361
408
|
}
|
|
362
409
|
|
|
363
410
|
/**
|
|
364
|
-
*
|
|
411
|
+
* Creates a static event emitter that is emitted whenever an
|
|
412
|
+
* event listener is created with the same name.
|
|
365
413
|
* @param {String} event The name of the event to emit.
|
|
366
414
|
* @param {*} data The data to emit with the event.
|
|
367
415
|
* @returns {Emitter} The emitter instance.
|
|
368
|
-
* @private
|
|
369
416
|
*/
|
|
370
|
-
emitStatic (event, ...data) {
|
|
371
|
-
const id = "*";
|
|
372
|
-
this._listeners = this._listeners || {};
|
|
373
|
-
this._emitting = true;
|
|
374
|
-
|
|
375
|
-
if (this._listeners[event] && this._listeners[event][id]) {
|
|
376
|
-
// Handle global emit
|
|
377
|
-
const arr = this._listeners[event][id];
|
|
378
|
-
const arrCount = arr.length;
|
|
379
|
-
|
|
380
|
-
for (let arrIndex = 0; arrIndex < arrCount; arrIndex++) {
|
|
381
|
-
// Check we have a function to execute
|
|
382
|
-
const tmpFunc = arr[arrIndex];
|
|
383
|
-
|
|
384
|
-
if (typeof tmpFunc === "function") {
|
|
385
|
-
tmpFunc.call(this, ...data);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
this._emitting = false;
|
|
391
|
-
|
|
417
|
+
emitStatic (event: string|symbol, ...data: any[]) {
|
|
392
418
|
this._emitters = this._emitters || {};
|
|
393
419
|
this._emitters[event] = this._emitters[event] || [];
|
|
394
420
|
this._emitters[event].push({
|
|
@@ -396,58 +422,23 @@ class Emitter {
|
|
|
396
422
|
"args": data
|
|
397
423
|
});
|
|
398
424
|
|
|
425
|
+
this.emit(event, ...data);
|
|
426
|
+
|
|
399
427
|
this._processRemovalQueue();
|
|
400
428
|
|
|
401
429
|
return this;
|
|
402
430
|
}
|
|
403
431
|
|
|
404
432
|
/**
|
|
405
|
-
*
|
|
433
|
+
* Creates a static event emitter that is emitted whenever an
|
|
434
|
+
* event listener is created with the same name and id.
|
|
406
435
|
* @param {String} event The name of the event to emit.
|
|
407
436
|
* @param {String} id The id of the event to emit.
|
|
408
437
|
* @param {*} data The data to emit with the event.
|
|
409
438
|
* @returns {Emitter} The emitter instance.
|
|
410
|
-
* @private
|
|
411
439
|
*/
|
|
412
|
-
emitStaticId (event, id, ...data) {
|
|
413
|
-
if (!id) throw new Error("Missing id from
|
|
414
|
-
|
|
415
|
-
this._listeners = this._listeners || {};
|
|
416
|
-
this._emitting = true;
|
|
417
|
-
|
|
418
|
-
if (this._listeners[event]) {
|
|
419
|
-
// Handle id emit
|
|
420
|
-
if (this._listeners[event][id]) {
|
|
421
|
-
const arr = this._listeners[event][id];
|
|
422
|
-
const arrCount = arr.length;
|
|
423
|
-
|
|
424
|
-
for (let arrIndex = 0; arrIndex < arrCount; arrIndex++) {
|
|
425
|
-
// Check we have a function to execute
|
|
426
|
-
const tmpFunc = arr[arrIndex];
|
|
427
|
-
|
|
428
|
-
if (typeof tmpFunc === "function") {
|
|
429
|
-
tmpFunc.call(this, ...data);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
// Handle global emit
|
|
435
|
-
if (this._listeners[event]["*"]) {
|
|
436
|
-
const arr = this._listeners[event]["*"];
|
|
437
|
-
const arrCount = arr.length;
|
|
438
|
-
|
|
439
|
-
for (let arrIndex = 0; arrIndex < arrCount; arrIndex++) {
|
|
440
|
-
// Check we have a function to execute
|
|
441
|
-
const tmpFunc = arr[arrIndex];
|
|
442
|
-
|
|
443
|
-
if (typeof tmpFunc === "function") {
|
|
444
|
-
tmpFunc.call(this, ...data);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
this._emitting = false;
|
|
440
|
+
emitStaticId (event: string|symbol, id: string|symbol, ...data: any[]) {
|
|
441
|
+
if (!id) throw new Error("Missing id from emitStaticId call!");
|
|
451
442
|
|
|
452
443
|
this._emitters = this._emitters || {};
|
|
453
444
|
this._emitters[event] = this._emitters[event] || [];
|
|
@@ -456,7 +447,7 @@ class Emitter {
|
|
|
456
447
|
"args": data
|
|
457
448
|
});
|
|
458
449
|
|
|
459
|
-
this.
|
|
450
|
+
this.emitId(event, id, ...data);
|
|
460
451
|
|
|
461
452
|
return this;
|
|
462
453
|
}
|
|
@@ -467,7 +458,7 @@ class Emitter {
|
|
|
467
458
|
* @returns {Emitter} The emitter instance.
|
|
468
459
|
* @private
|
|
469
460
|
*/
|
|
470
|
-
cancelStatic (event) {
|
|
461
|
+
cancelStatic (event: string|symbol) {
|
|
471
462
|
this._emitters = this._emitters || {};
|
|
472
463
|
this._emitters[event] = [];
|
|
473
464
|
|
|
@@ -482,7 +473,7 @@ class Emitter {
|
|
|
482
473
|
* @returns {boolean} True if one or more event listeners are registered for
|
|
483
474
|
* the event. False if none are found.
|
|
484
475
|
*/
|
|
485
|
-
willEmit (event) {
|
|
476
|
+
willEmit (event: string|symbol) {
|
|
486
477
|
const id = "*";
|
|
487
478
|
|
|
488
479
|
if (!this._listeners || !this._listeners[event]) {
|
|
@@ -513,7 +504,7 @@ class Emitter {
|
|
|
513
504
|
* @returns {boolean} True if one or more event listeners are registered for
|
|
514
505
|
* the event. False if none are found.
|
|
515
506
|
*/
|
|
516
|
-
willEmitId (event, id) {
|
|
507
|
+
willEmitId (event: string|symbol, id: string|symbol) {
|
|
517
508
|
if (!this._listeners || !this._listeners[event]) {
|
|
518
509
|
return false;
|
|
519
510
|
}
|
|
@@ -555,31 +546,32 @@ class Emitter {
|
|
|
555
546
|
* Queues an event to be fired. This has automatic de-bouncing so that any
|
|
556
547
|
* events of the same type that occur within 100 milliseconds of a previous
|
|
557
548
|
* one will all be wrapped into a single emit rather than emitting tons of
|
|
558
|
-
* events for
|
|
559
|
-
*
|
|
549
|
+
* events for the same eventName. Only the data from the last de-bounced event
|
|
550
|
+
* will be emitted.
|
|
560
551
|
* @memberOf Emitter
|
|
561
552
|
* @method deferEmit
|
|
562
553
|
* @param {String} eventName The name of the event to emit.
|
|
563
554
|
* @param {*=} data Optional data to emit with the event.
|
|
564
555
|
* @returns {Emitter} The emitter instance.
|
|
565
556
|
*/
|
|
566
|
-
deferEmit (eventName, ...data) {
|
|
567
|
-
if (
|
|
568
|
-
|
|
569
|
-
|
|
557
|
+
deferEmit (eventName: string|symbol, ...data: any[]) {
|
|
558
|
+
if (this._noEmitDefer) {
|
|
559
|
+
this.emit(eventName, ...data);
|
|
560
|
+
return this;
|
|
561
|
+
}
|
|
570
562
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
}
|
|
563
|
+
// Check for an existing timeout
|
|
564
|
+
this._deferTimeout = this._deferTimeout || {};
|
|
574
565
|
|
|
575
|
-
|
|
576
|
-
this._deferTimeout[eventName]
|
|
577
|
-
this.emit.call(this, eventName, ...data);
|
|
578
|
-
}, 1);
|
|
579
|
-
} else {
|
|
580
|
-
this.emit.call(this, eventName, ...data);
|
|
566
|
+
if (this._deferTimeout[eventName]) {
|
|
567
|
+
clearTimeout(this._deferTimeout[eventName]);
|
|
581
568
|
}
|
|
582
569
|
|
|
570
|
+
// Set a timeout
|
|
571
|
+
this._deferTimeout[eventName] = setTimeout(() => {
|
|
572
|
+
this.emit(eventName, ...data);
|
|
573
|
+
}, 100);
|
|
574
|
+
|
|
583
575
|
return this;
|
|
584
576
|
}
|
|
585
577
|
|
|
@@ -591,6 +583,7 @@ class Emitter {
|
|
|
591
583
|
* the emitter is running through them. This method is called after the
|
|
592
584
|
* event emitter is finished processing.
|
|
593
585
|
* @private
|
|
586
|
+
* @returns {undefined}
|
|
594
587
|
*/
|
|
595
588
|
_processRemovalQueue () {
|
|
596
589
|
if (!this._eventRemovalQueue || !this._eventRemovalQueue.length) {
|
|
@@ -610,17 +603,23 @@ class Emitter {
|
|
|
610
603
|
/**
|
|
611
604
|
* Makes the passed class or object into an emitter by modifying either the
|
|
612
605
|
* prototype or the actual object to include event emitter methods.
|
|
613
|
-
* @param
|
|
606
|
+
* @param obj The object / function / class to add event methods to.
|
|
614
607
|
* If none is provided a new object will be created. This allows you to use
|
|
615
608
|
* new Emitter() to generate an event emitter that is not tied to any other
|
|
616
609
|
* object or class.
|
|
617
|
-
* @param
|
|
610
|
+
* @param prototypeMode Defaults to true. Set to true to add emitter
|
|
618
611
|
* methods to the the passed object"s prototype property e.g. obj.prototype.on
|
|
619
612
|
* = emitter.on. Set to false to add emitter methods the object directly e.g.
|
|
620
613
|
* obj.on = emitter.on.
|
|
621
614
|
* @returns {Object} The newly augmented object.
|
|
622
615
|
*/
|
|
623
|
-
|
|
616
|
+
type MakeEmitter = {
|
|
617
|
+
(obj: Record<string, unknown>|boolean|undefined, prototypeMode: boolean): any,
|
|
618
|
+
(obj: boolean): any,
|
|
619
|
+
(obj: undefined): any
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
export const makeEmitter: MakeEmitter = (obj: Record<string, unknown>|boolean|undefined, prototypeMode = false) => {
|
|
624
623
|
let operateOnObject;
|
|
625
624
|
|
|
626
625
|
if (obj === undefined && prototypeMode === undefined) {
|
|
@@ -634,24 +633,24 @@ const makeEmitter = function (obj, prototypeMode) {
|
|
|
634
633
|
}
|
|
635
634
|
|
|
636
635
|
if (prototypeMode === undefined) {
|
|
637
|
-
prototypeMode =
|
|
636
|
+
prototypeMode = false;
|
|
638
637
|
}
|
|
639
638
|
|
|
640
639
|
if (typeof obj !== "object" && typeof obj !== "function") {
|
|
641
|
-
throw new Error("Cannot operate on
|
|
640
|
+
throw new Error("Cannot operate on passed value, it is not an object, function or class!");
|
|
642
641
|
}
|
|
643
642
|
|
|
644
643
|
if (prototypeMode) {
|
|
645
644
|
if (obj.prototype === undefined) {
|
|
646
|
-
throw new Error("Cannot modify prototype of passed object, it has no prototype property!
|
|
645
|
+
throw new Error("Cannot modify prototype of passed object, it has no prototype property!");
|
|
647
646
|
}
|
|
648
647
|
|
|
649
|
-
operateOnObject = obj.prototype
|
|
648
|
+
operateOnObject = obj.prototype as Record<string, unknown>;
|
|
650
649
|
} else {
|
|
651
650
|
operateOnObject = obj;
|
|
652
651
|
}
|
|
653
652
|
|
|
654
|
-
// Convert the object
|
|
653
|
+
// Convert the object to have eventing capability
|
|
655
654
|
operateOnObject.on = Emitter.prototype.on;
|
|
656
655
|
operateOnObject.off = Emitter.prototype.off;
|
|
657
656
|
operateOnObject.one = Emitter.prototype.one;
|
|
@@ -665,11 +664,9 @@ const makeEmitter = function (obj, prototypeMode) {
|
|
|
665
664
|
operateOnObject.willEmit = Emitter.prototype.willEmit;
|
|
666
665
|
operateOnObject.willEmitId = Emitter.prototype.willEmitId;
|
|
667
666
|
operateOnObject._processRemovalQueue = Emitter.prototype._processRemovalQueue;
|
|
667
|
+
operateOnObject._on = Emitter.prototype._on;
|
|
668
|
+
operateOnObject._off = Emitter.prototype._off;
|
|
669
|
+
operateOnObject._once = Emitter.prototype._once;
|
|
668
670
|
|
|
669
671
|
return obj;
|
|
670
|
-
};
|
|
671
|
-
|
|
672
|
-
module.exports = {
|
|
673
|
-
Emitter,
|
|
674
|
-
makeEmitter
|
|
675
672
|
};
|
package/tests/Emitter.test.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const {beforeEach, afterEach, describe, it} = require("mocha");
|
|
2
1
|
const {Emitter, makeEmitter} = require("../dist/Emitter");
|
|
3
2
|
const assert = require("assert");
|
|
4
3
|
|
|
@@ -22,8 +21,7 @@ function check () {
|
|
|
22
21
|
if (expectedAssertions === undefined || expectedAssertions === actualAssertions) {
|
|
23
22
|
return;
|
|
24
23
|
}
|
|
25
|
-
|
|
26
|
-
this.currentTest.emit("error", err);
|
|
24
|
+
throw new Error("expected " + expectedAssertions + " assertions, got " + actualAssertions);
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
beforeEach(reset);
|
|
@@ -44,6 +42,28 @@ describe("Emitter", () => {
|
|
|
44
42
|
assert.strictEqual(!myClass._listeners.moo || !myClass._listeners.moo["*"] || myClass._listeners.moo["*"].length, true, "Listeners all removed from event");
|
|
45
43
|
});
|
|
46
44
|
|
|
45
|
+
it("Augments an object passed to makeEmitter()", (resolve) => {
|
|
46
|
+
const obj = {
|
|
47
|
+
"someExistingProp": "hello"
|
|
48
|
+
};
|
|
49
|
+
makeEmitter(obj);
|
|
50
|
+
|
|
51
|
+
function test () {
|
|
52
|
+
assert.strictEqual(this.someExistingProp, "hello", "Able to access object props via `this`");
|
|
53
|
+
assert.strictEqual(obj._listeners.moo["*"].length, 1, "Listener registered on event");
|
|
54
|
+
|
|
55
|
+
resolve();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
obj.on("moo", test);
|
|
59
|
+
|
|
60
|
+
obj.emit("moo");
|
|
61
|
+
|
|
62
|
+
obj.off("moo");
|
|
63
|
+
|
|
64
|
+
assert.strictEqual(!obj._listeners.moo || !obj._listeners.moo["*"] || obj._listeners.moo["*"].length, true, "Listeners all removed from event");
|
|
65
|
+
});
|
|
66
|
+
|
|
47
67
|
it("Supports extending Emitter as a base class", () => {
|
|
48
68
|
let testFuncCount = 0;
|
|
49
69
|
|
|
@@ -196,7 +216,7 @@ describe("Emitter", () => {
|
|
|
196
216
|
|
|
197
217
|
expect(1);
|
|
198
218
|
|
|
199
|
-
makeEmitter(MyClass);
|
|
219
|
+
makeEmitter(MyClass.prototype);
|
|
200
220
|
|
|
201
221
|
const myClass = new MyClass();
|
|
202
222
|
myClass.emitStatic("moo");
|
|
@@ -215,7 +235,7 @@ describe("Emitter", () => {
|
|
|
215
235
|
|
|
216
236
|
expect(1);
|
|
217
237
|
|
|
218
|
-
makeEmitter(MyClass);
|
|
238
|
+
makeEmitter(MyClass.prototype);
|
|
219
239
|
|
|
220
240
|
const myClass = new MyClass();
|
|
221
241
|
myClass.emitStatic("moo");
|
|
@@ -242,7 +262,7 @@ describe("Emitter", () => {
|
|
|
242
262
|
};
|
|
243
263
|
expect(1);
|
|
244
264
|
|
|
245
|
-
makeEmitter(MyClass);
|
|
265
|
+
makeEmitter(MyClass.prototype);
|
|
246
266
|
|
|
247
267
|
const myClass = new MyClass();
|
|
248
268
|
myClass.on("moo", () => {
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2015",
|
|
4
|
+
"module": "CommonJS",
|
|
5
|
+
"lib": [
|
|
6
|
+
"dom",
|
|
7
|
+
"dom.iterable",
|
|
8
|
+
"esnext"
|
|
9
|
+
],
|
|
10
|
+
"allowJs": false,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"allowSyntheticDefaultImports": true,
|
|
14
|
+
"strict": true,
|
|
15
|
+
"forceConsistentCasingInFileNames": true,
|
|
16
|
+
"suppressImplicitAnyIndexErrors": true,
|
|
17
|
+
"noFallthroughCasesInSwitch": false,
|
|
18
|
+
"moduleResolution": "node",
|
|
19
|
+
"resolveJsonModule": true,
|
|
20
|
+
"isolatedModules": true,
|
|
21
|
+
"noEmit": false,
|
|
22
|
+
"jsx": "react-jsx",
|
|
23
|
+
"outDir": "dist",
|
|
24
|
+
"declaration": true
|
|
25
|
+
},
|
|
26
|
+
"include": [
|
|
27
|
+
"src"
|
|
28
|
+
]
|
|
29
|
+
}
|