@irrelon/emitter 5.0.6 → 6.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/src/Emitter.ts CHANGED
@@ -25,12 +25,24 @@
25
25
  Source: https://github.com/irrelon/emitter
26
26
 
27
27
  Changelog:
28
+ Version 6.0.0: Updated to allow event listeners to return data to
29
+ the caller of the emit() function, e.g.
30
+ `const results = emitter.emit("myEventName");`
31
+
32
+ The results are an array of all return values from any listener
33
+ functions that were called by the event "myEventName". This is
34
+ useful if you want event listeners to act as data providers for
35
+ particular events.
36
+
37
+ Listeners that return `ListenerReturnFlag.cancel` will cancel
38
+ the event call to any further listeners for that one event
39
+ emit.
28
40
  Version 5.0.3 and 5.0.4: Updated to allow specifying an events type
29
41
  to the Emitter to allow complete type safety when registering
30
42
  listeners and emitting events.
31
43
 
32
44
  Updated the build and package to split between delivery of CJS
33
- and MJS module types so that this package can be eiter imported
45
+ and ESM module types so that this package can be eiter imported
34
46
  or required without having to jump through any hoops.
35
47
  Version 5.0.2:
36
48
  Removed some unnecessary code, updated to be in step with version
@@ -94,34 +106,40 @@
94
106
  export type AnyFunction<ReturnType = any> = (...args: any[]) => ReturnType;
95
107
  export type AnyConstructor = new (...args: any[]) => any;
96
108
 
97
- export enum EventReturnFlag {
98
- none,
99
- cancel
109
+ export enum ListenerReturnFlag {
110
+ none = "!+_NONE",
111
+ cancel = "!+_CANCEL"
100
112
  }
101
113
 
102
- export type EventListenerCallback<EventCallbackFunctionSignature extends AnyFunction = AnyFunction> = (...args: Parameters<EventCallbackFunctionSignature>) => ReturnType<EventCallbackFunctionSignature>;
114
+ export type EventListenerCallback<EventCallbackFunctionSignature extends AnyFunction = AnyFunction> = (
115
+ ...args: Parameters<EventCallbackFunctionSignature>
116
+ ) => ReturnType<EventCallbackFunctionSignature>;
103
117
 
104
118
  export interface EventStaticEmitterObject<EventCallbackFunctionSignature extends AnyFunction = AnyFunction> {
105
119
  id: string;
106
120
  args: Parameters<EventCallbackFunctionSignature>;
107
121
  }
108
122
 
109
- export interface EmitterEventsInterface {
110
- [key: string]: AnyFunction
123
+ export interface EmitterAnyEventsInterface {
124
+ [key: string]: AnyFunction;
111
125
  }
112
126
 
113
- export type ConvertInterfaceToDict<T> = {
127
+ export type EmitterEventsInterface<T> = {
114
128
  [K in keyof T]: T[K];
115
129
  };
116
130
 
117
131
  /**
118
132
  * Creates a new class with the capability to emit events.
119
133
  */
120
- export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEventsInterface> {
134
+ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterface> = EmitterAnyEventsInterface> {
121
135
  _eventsEmitting: boolean = false;
122
136
  _eventRemovalQueue: any[] = [];
123
- _eventListeners?: { [EventName in (keyof EventsInterface)]?: Record<string, EventListenerCallback<EventsInterface[EventName]>[]> } = {};
124
- _eventStaticEmitters: {[EventName in (keyof EventsInterface)]?: EventStaticEmitterObject<EventsInterface[EventName]>[] } = {};
137
+ _eventListeners?: {
138
+ [EventName in keyof EventsInterface]?: Record<string, EventListenerCallback<EventsInterface[EventName]>[]>;
139
+ } = {};
140
+ _eventStaticEmitters: {
141
+ [EventName in keyof EventsInterface]?: EventStaticEmitterObject<EventsInterface[EventName]>[];
142
+ } = {};
125
143
  _eventsAllowDefer: boolean = false;
126
144
  _eventsDeferTimeouts: Record<any, number> = {};
127
145
 
@@ -133,7 +151,11 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
133
151
  * @param listener The method to call when the event is fired.
134
152
  * @returns The emitter instance.
135
153
  */
136
- _on<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener: EventListenerCallback<EventsInterface[EventName]>) {
154
+ _on<EventName extends keyof EventsInterface>(
155
+ eventName: EventName,
156
+ id: string,
157
+ listener: EventListenerCallback<EventsInterface[EventName]>
158
+ ) {
137
159
  const generateTimeout = (emitter: EventStaticEmitterObject<EventsInterface[EventName]>) => {
138
160
  setTimeout(() => {
139
161
  listener(...emitter.args);
@@ -141,12 +163,17 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
141
163
  };
142
164
 
143
165
  this._eventListeners = this._eventListeners || {};
144
- const nonNullableEventListeners = this._eventListeners[eventName] = this._eventListeners[eventName] || {};
166
+ const nonNullableEventListeners = (this._eventListeners[eventName] = this._eventListeners[eventName] || {});
145
167
  nonNullableEventListeners[id] = nonNullableEventListeners[id] || [];
146
168
  nonNullableEventListeners[id].push(listener);
147
169
 
148
170
  // Check for any static emitters, and fire the event if any exist
149
- if (!this._eventStaticEmitters || !this._eventStaticEmitters[eventName] || !this._eventStaticEmitters[eventName]!.length) return this;
171
+ if (
172
+ !this._eventStaticEmitters ||
173
+ !this._eventStaticEmitters[eventName] ||
174
+ !this._eventStaticEmitters[eventName]!.length
175
+ )
176
+ return this;
150
177
 
151
178
  // Emit events for each emitter
152
179
  for (let i = 0; i < this._eventStaticEmitters[eventName]!.length; i++) {
@@ -171,11 +198,17 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
171
198
  * @param listener The method to call when the event is fired.
172
199
  * @returns The emitter instance.
173
200
  */
174
- _once<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener: EventListenerCallback<EventsInterface[EventName]>) {
201
+ _once<EventName extends keyof EventsInterface>(
202
+ eventName: EventName,
203
+ id: string,
204
+ listener: EventListenerCallback<EventsInterface[EventName]>
205
+ ) {
175
206
  let fired = false;
176
207
  let originalReturnData: ReturnType<EventsInterface[EventName]>;
177
208
 
178
- const internalCallback: EventListenerCallback<EventsInterface[EventName]> = (...args: Parameters<EventsInterface[EventName]>): ReturnType<EventsInterface[EventName]> => {
209
+ const internalCallback: EventListenerCallback<EventsInterface[EventName]> = (
210
+ ...args: Parameters<EventsInterface[EventName]>
211
+ ): ReturnType<EventsInterface[EventName]> => {
179
212
  if (fired) return originalReturnData;
180
213
 
181
214
  fired = true;
@@ -196,9 +229,14 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
196
229
  * or once() call to cancel.
197
230
  * @returns The emitter instance.
198
231
  */
199
- _off<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener?: EventListenerCallback<EventsInterface[EventName]>): this {
232
+ _off<EventName extends keyof EventsInterface>(
233
+ eventName: EventName,
234
+ id: string,
235
+ listener?: EventListenerCallback<EventsInterface[EventName]>
236
+ ): this {
200
237
  // If the event name doesn't have any listeners, exit early
201
- if (!this._eventListeners || !this._eventListeners[eventName] || !this._eventListeners[eventName]![id]) return this;
238
+ if (!this._eventListeners || !this._eventListeners[eventName] || !this._eventListeners[eventName]![id])
239
+ return this;
202
240
 
203
241
  // If we are emitting events at the moment, don't remove this listener
204
242
  // until the process has completed, so we queue for removal instead
@@ -244,9 +282,20 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
244
282
  * @param listener The method to call when the event is fired.
245
283
  * @returns The emitter instance.
246
284
  */
247
- on<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener: EventListenerCallback<EventsInterface[EventName]>): this;
248
- on<EventName extends keyof EventsInterface> (eventName: EventName, listener: EventListenerCallback<EventsInterface[EventName]>): this;
249
- on<EventName extends keyof EventsInterface> (eventName: EventName, idOrListener: string | EventListenerCallback<EventsInterface[EventName]>, listener?: EventListenerCallback<EventsInterface[EventName]>): this {
285
+ on<EventName extends keyof EventsInterface>(
286
+ eventName: EventName,
287
+ id: string,
288
+ listener: EventListenerCallback<EventsInterface[EventName]>
289
+ ): this;
290
+ on<EventName extends keyof EventsInterface>(
291
+ eventName: EventName,
292
+ listener: EventListenerCallback<EventsInterface[EventName]>
293
+ ): this;
294
+ on<EventName extends keyof EventsInterface>(
295
+ eventName: EventName,
296
+ idOrListener: string | EventListenerCallback<EventsInterface[EventName]>,
297
+ listener?: EventListenerCallback<EventsInterface[EventName]>
298
+ ): this {
250
299
  if (typeof idOrListener === "string") {
251
300
  return this._on(eventName, idOrListener, listener as EventListenerCallback<EventsInterface[EventName]>);
252
301
  }
@@ -262,9 +311,16 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
262
311
  * @param listener
263
312
  * @returns The emitter instance.
264
313
  */
265
- once<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener: EventListenerCallback<EventsInterface[EventName]>): this;
266
- once<EventName extends keyof EventsInterface> (eventName: EventName, listener: EventListenerCallback<EventsInterface[EventName]>): this;
267
- once<EventName extends keyof EventsInterface> (eventName: EventName, ...rest: any[]): this {
314
+ once<EventName extends keyof EventsInterface>(
315
+ eventName: EventName,
316
+ id: string,
317
+ listener: EventListenerCallback<EventsInterface[EventName]>
318
+ ): this;
319
+ once<EventName extends keyof EventsInterface>(
320
+ eventName: EventName,
321
+ listener: EventListenerCallback<EventsInterface[EventName]>
322
+ ): this;
323
+ once<EventName extends keyof EventsInterface>(eventName: EventName, ...rest: any[]): this {
268
324
  const restTypes = rest.map((arg) => typeof arg);
269
325
 
270
326
  if (restTypes[0] === "function") {
@@ -286,9 +342,16 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
286
342
  * @param listener The method to call when the event is fired.
287
343
  * @returns The emitter instance.
288
344
  */
289
- overwrite<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener: EventListenerCallback<EventsInterface[EventName]>): this;
290
- overwrite<EventName extends keyof EventsInterface> (eventName: EventName, listener: EventListenerCallback<EventsInterface[EventName]>): this;
291
- overwrite<EventName extends keyof EventsInterface> (eventName: EventName, ...rest: any[]) {
345
+ overwrite<EventName extends keyof EventsInterface>(
346
+ eventName: EventName,
347
+ id: string,
348
+ listener: EventListenerCallback<EventsInterface[EventName]>
349
+ ): this;
350
+ overwrite<EventName extends keyof EventsInterface>(
351
+ eventName: EventName,
352
+ listener: EventListenerCallback<EventsInterface[EventName]>
353
+ ): this;
354
+ overwrite<EventName extends keyof EventsInterface>(eventName: EventName, ...rest: any[]) {
292
355
  const restTypes = rest.map((arg) => typeof arg);
293
356
 
294
357
  if (restTypes[0] === "function") {
@@ -308,10 +371,17 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
308
371
  * or once() call to cancel.
309
372
  * @returns The emitter instance.
310
373
  */
311
- off<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener?: EventListenerCallback<EventsInterface[EventName]>): this;
312
- off<EventName extends keyof EventsInterface> (eventName: EventName, listener?: EventListenerCallback<EventsInterface[EventName]>): this;
313
- off<EventName extends keyof EventsInterface> (eventName: EventName): this;
314
- off<EventName extends keyof EventsInterface> (eventName: EventName, ...rest: any[]) {
374
+ off<EventName extends keyof EventsInterface>(
375
+ eventName: EventName,
376
+ id: string,
377
+ listener?: EventListenerCallback<EventsInterface[EventName]>
378
+ ): this;
379
+ off<EventName extends keyof EventsInterface>(
380
+ eventName: EventName,
381
+ listener?: EventListenerCallback<EventsInterface[EventName]>
382
+ ): this;
383
+ off<EventName extends keyof EventsInterface>(eventName: EventName): this;
384
+ off<EventName extends keyof EventsInterface>(eventName: EventName, ...rest: any[]) {
315
385
  if (rest.length === 0) {
316
386
  // Only event was provided, use * as the id to mean "any without"
317
387
  // a specific id
@@ -330,116 +400,198 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
330
400
  return this._off(eventName, rest[0], rest[1]);
331
401
  }
332
402
 
403
+ _emitToSingleListener<EventName extends keyof EventsInterface>(
404
+ listener: EventListenerCallback<EventsInterface[EventName]>,
405
+ data: Parameters<EventsInterface[EventName]>
406
+ ): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag {
407
+ return listener(...data);
408
+ }
409
+
410
+ _emitToArrayOfListeners<EventName extends keyof EventsInterface>(
411
+ arr: EventListenerCallback<EventsInterface[EventName]>[],
412
+ data: Parameters<EventsInterface[EventName]>
413
+ ): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[] {
414
+ const arrCount = arr.length;
415
+ const resultArr: (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[] = [];
416
+
417
+ for (let arrIndex = 0; arrIndex < arrCount; arrIndex++) {
418
+ // Check we have a function to execute
419
+ const tmpFunc = arr[arrIndex];
420
+
421
+ if (typeof tmpFunc !== "function") {
422
+ continue;
423
+ }
424
+
425
+ const eventListenerResponse = tmpFunc(...data);
426
+ resultArr.push(eventListenerResponse);
427
+
428
+ if (eventListenerResponse === ListenerReturnFlag.cancel) {
429
+ // Cancel further event processing
430
+ break;
431
+ }
432
+ }
433
+
434
+ return resultArr;
435
+ }
436
+
333
437
  /**
334
- * Emit an event by name.
335
- * @param eventName The name of the event to emit.
336
- * @param {...any} data The arguments to send to any listening methods.
438
+ * Call an event listener by name. The `rpc()` function differs from `emit()` in
439
+ * that it will only call and return data from the first event listener for the
440
+ * event rather than all event listeners. If you have more than one event listener
441
+ * assigned to the event, all others except the first will be ignored and will
442
+ * not receive the event.
443
+ * @param eventName The name of the event to call the listener for.
444
+ * @param {...any} data The arguments to send to the listening method.
337
445
  * If you are sending multiple arguments, separate them with a comma so
338
446
  * that they are received by the function as separate arguments.
339
447
  * @return {number}
340
- * @example #Emit an Event
448
+ * @example #Call the Event Listener
341
449
  * // Emit the event named "hello"
342
450
  * myEntity.emit('hello');
343
- * @example #Emit an Event With Data Object
451
+ * @example #Call the Event Listener With Data Object
344
452
  * // Emit the event named "hello"
345
453
  * myEntity.emit('hello', {moo: true});
346
- * @example #Emit an Event With Multiple Data Values
454
+ * @example #Call the Event Listener With Multiple Data Values
347
455
  * // Emit the event named "hello"
348
456
  * myEntity.emit('hello', {moo: true}, 'someString');
349
- * @example #Listen for Event Data
457
+ * @example #Register the Listener for Event Data
350
458
  * // Set a listener to listen for the data (multiple values emitted
351
459
  * // from an event are passed as function arguments)
352
- * myEntity.on('hello', function (arg1, arg2) {
353
- * console.log(arg1, arg2);
460
+ * myEntity.on('hello', function (arg1, arg2) {
461
+ * console.log("Arguments:", arg1, arg2);
462
+ * return "foo";
354
463
  * }
355
464
  *
356
465
  * // Emit the event named "hello"
357
- * myEntity.emit('hello', 'data1', 'data2');
466
+ * const result = myEntity.emit('hello', 'data1', 'data2');
467
+ * console.log("Result:", result);
358
468
  *
359
469
  * // The console output is:
360
- * // data1, data2
470
+ * // Arguments: data1 data2
471
+ * // Result: "foo"
361
472
  */
362
- async emit<EventName extends keyof EventsInterface> (eventName: EventName, ...data: Parameters<EventsInterface[EventName]>): Promise<EventReturnFlag> {
363
- if (!this._eventListeners) {
364
- return EventReturnFlag.none;
365
- }
473
+ rpc<EventName extends keyof EventsInterface>(
474
+ eventName: EventName,
475
+ ...data: Parameters<EventsInterface[EventName]>
476
+ ): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag {
477
+ return this.rpcId<EventName>(eventName, "*", ...data);
478
+ }
366
479
 
367
- const id = "*";
480
+ rpcId<EventName extends keyof EventsInterface>(
481
+ eventName: EventName,
482
+ id: string,
483
+ ...data: Parameters<EventsInterface[EventName]>
484
+ ): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag {
485
+ if (!this._eventListeners || !this._eventListeners[eventName]) {
486
+ throw new Error("Cannot make an rpc call without at least one event listener and none were found");
487
+ }
368
488
 
369
- let returnFlag: EventReturnFlag = EventReturnFlag.none;
489
+ let emitterResult: ReturnType<EventsInterface[EventName]> | ListenerReturnFlag;
370
490
  this._eventsEmitting = true;
371
491
 
372
- if (this._eventListeners[eventName] && this._eventListeners[eventName]![id]) {
373
- // Handle global emit
492
+ if (this._eventListeners[eventName]![id]) {
493
+ // Handle id emit
374
494
  const arr = this._eventListeners[eventName]![id];
375
-
376
- const promiseArr = arr.map((tmpFunc) => {
377
- if (typeof tmpFunc !== "function") return;
378
- return tmpFunc(...data);
379
- });
380
-
381
- const result = (await Promise.all(promiseArr)).find((tmpResult) => tmpResult !== EventReturnFlag.none);
382
-
383
- if (result) {
384
- returnFlag = EventReturnFlag.cancel;
495
+ emitterResult = this._emitToSingleListener<EventName>(arr[0], data);
496
+ } else if (id !== "*" && this._eventListeners[eventName]!["*"]) {
497
+ // Handle global emit if the id passed wasn't already a global (*) id
498
+ const arr = this._eventListeners[eventName]!["*"];
499
+ emitterResult = this._emitToSingleListener<EventName>(arr[0], data);
500
+ } else {
501
+ if (id === "*") {
502
+ throw new Error(
503
+ `Cannot make an rpc call to event "${
504
+ eventName as string
505
+ }" without at least one event listener and none were found, register a listener via on("${
506
+ eventName as string
507
+ }", () => { ...some listener code })`
508
+ );
385
509
  }
510
+
511
+ throw new Error(
512
+ `Cannot make an rpc call to event "${
513
+ eventName as string
514
+ }" and id "${id}" without at least one event listener and none were found, register a listener via on("${
515
+ eventName as string
516
+ }", "${id}", () => { ...some listener code })`
517
+ );
386
518
  }
387
519
 
388
520
  this._eventsEmitting = false;
389
521
  this._processRemovalQueue();
390
522
 
391
- return returnFlag;
523
+ return emitterResult;
392
524
  }
393
525
 
394
- emitId<EventName extends keyof EventsInterface> (eventName: EventName, id: string, ...data: Parameters<EventsInterface[EventName]>): EventReturnFlag {
395
- if (!this._eventListeners) {
396
- return EventReturnFlag.none;
526
+ /**
527
+ * Emit an event by name.
528
+ * @param eventName The name of the event to emit.
529
+ * @param {...any} data The arguments to send to any listening methods.
530
+ * If you are sending multiple arguments, separate them with a comma so
531
+ * that they are received by the function as separate arguments.
532
+ * @return {number}
533
+ * @example #Emit an Event
534
+ * // Emit the event named "hello"
535
+ * myEntity.emit('hello');
536
+ * @example #Emit an Event With Data Object
537
+ * // Emit the event named "hello"
538
+ * myEntity.emit('hello', {moo: true});
539
+ * @example #Emit an Event With Multiple Data Values
540
+ * // Emit the event named "hello"
541
+ * myEntity.emit('hello', {moo: true}, 'someString');
542
+ * @example #Listen for Event Data
543
+ * // Set a listener to listen for the data (multiple values emitted
544
+ * // from an event are passed as function arguments)
545
+ * myEntity.on('hello', function (arg1, arg2) {
546
+ * console.log("Arguments:", arg1, arg2);
547
+ * return "foo";
548
+ * }
549
+ *
550
+ * // Emit the event named "hello"
551
+ * // The result is returned as an array of all return values
552
+ * // from all the listeners for the event
553
+ * const result = myEntity.emit('hello', 'data1', 'data2');
554
+ * console.log("Result:", result);
555
+ *
556
+ * // The console output is:
557
+ * // Arguments: data1 data2
558
+ * // Result: ["foo"]
559
+ */
560
+ emit<EventName extends keyof EventsInterface>(
561
+ eventName: EventName,
562
+ ...data: Parameters<EventsInterface[EventName]>
563
+ ): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[] {
564
+ return this.emitId<EventName>(eventName, "*", ...data);
565
+ }
566
+
567
+ emitId<EventName extends keyof EventsInterface>(
568
+ eventName: EventName,
569
+ id: string,
570
+ ...data: Parameters<EventsInterface[EventName]>
571
+ ): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[] {
572
+ if (!this._eventListeners || !this._eventListeners[eventName]) {
573
+ return [];
397
574
  }
398
575
 
399
- this._eventListeners = this._eventListeners || {};
576
+ let emitterResult: (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[] = [];
400
577
  this._eventsEmitting = true;
401
578
 
402
- if (!this._eventListeners[eventName]) {
403
- this._eventsEmitting = false;
404
- this._processRemovalQueue();
405
-
406
- return EventReturnFlag.none;
407
- }
408
-
409
579
  // Handle id emit
410
580
  if (this._eventListeners[eventName]![id]) {
411
581
  const arr = this._eventListeners[eventName]![id];
412
- const arrCount = arr.length;
413
-
414
- for (let arrIndex = 0; arrIndex < arrCount; arrIndex++) {
415
- // Check we have a function to execute
416
- const tmpFunc = arr[arrIndex];
417
-
418
- if (typeof tmpFunc === "function") {
419
- tmpFunc.call(this, ...data);
420
- }
421
- }
582
+ emitterResult = emitterResult.concat(this._emitToArrayOfListeners<EventName>(arr, data));
422
583
  }
423
584
 
424
- // Handle global emit
425
- if (this._eventListeners[eventName]!["*"]) {
585
+ // Handle global emit if the id passed wasn't already a global (*) id
586
+ if (id !== "*" && this._eventListeners[eventName]!["*"]) {
426
587
  const arr = this._eventListeners[eventName]!["*"];
427
- const arrCount = arr.length;
428
-
429
- for (let arrIndex = 0; arrIndex < arrCount; arrIndex++) {
430
- // Check we have a function to execute
431
- const tmpFunc = arr[arrIndex];
432
-
433
- if (typeof tmpFunc === "function") {
434
- tmpFunc.call(this, ...data);
435
- }
436
- }
588
+ emitterResult = emitterResult.concat(this._emitToArrayOfListeners<EventName>(arr, data));
437
589
  }
438
590
 
439
591
  this._eventsEmitting = false;
440
592
  this._processRemovalQueue();
441
593
 
442
- return EventReturnFlag.none;
594
+ return emitterResult;
443
595
  }
444
596
 
445
597
  /**
@@ -451,7 +603,10 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
451
603
  * @returns The emitter instance.
452
604
  * @private
453
605
  */
454
- emitStatic<EventName extends keyof EventsInterface> (eventName: EventName, ...data: Parameters<EventsInterface[EventName]>) {
606
+ emitStatic<EventName extends keyof EventsInterface>(
607
+ eventName: EventName,
608
+ ...data: Parameters<EventsInterface[EventName]>
609
+ ) {
455
610
  const id = "*";
456
611
  this._eventListeners = this._eventListeners || {};
457
612
  this._eventsEmitting = true;
@@ -476,8 +631,8 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
476
631
  this._eventStaticEmitters = this._eventStaticEmitters || {};
477
632
  this._eventStaticEmitters[eventName] = this._eventStaticEmitters[eventName] || [];
478
633
  this._eventStaticEmitters[eventName]!.push({
479
- "id": "*",
480
- "args": data
634
+ id: "*",
635
+ args: data
481
636
  });
482
637
 
483
638
  this._processRemovalQueue();
@@ -495,7 +650,11 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
495
650
  * @returns The emitter instance.
496
651
  * @private
497
652
  */
498
- emitStaticId<EventName extends keyof EventsInterface> (eventName: EventName, id: string, ...data: Parameters<EventsInterface[EventName]>) {
653
+ emitStaticId<EventName extends keyof EventsInterface>(
654
+ eventName: EventName,
655
+ id: string,
656
+ ...data: Parameters<EventsInterface[EventName]>
657
+ ) {
499
658
  if (!id) throw new Error("Missing id from emitId call!");
500
659
 
501
660
  this._eventListeners = this._eventListeners || {};
@@ -539,7 +698,7 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
539
698
  this._eventStaticEmitters[eventName] = this._eventStaticEmitters[eventName] || [];
540
699
  this._eventStaticEmitters[eventName]!.push({
541
700
  id,
542
- "args": data
701
+ args: data
543
702
  });
544
703
 
545
704
  this._processRemovalQueue();
@@ -553,7 +712,7 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
553
712
  * @returns The emitter instance.
554
713
  * @private
555
714
  */
556
- cancelStatic<EventName extends keyof EventsInterface> (eventName: EventName) {
715
+ cancelStatic<EventName extends keyof EventsInterface>(eventName: EventName) {
557
716
  this._eventStaticEmitters = this._eventStaticEmitters || {};
558
717
  this._eventStaticEmitters[eventName] = [];
559
718
 
@@ -566,7 +725,7 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
566
725
  * @returns True if one or more event listeners are registered for
567
726
  * the event. False if none are found.
568
727
  */
569
- willEmit<EventName extends keyof EventsInterface> (eventName: EventName) {
728
+ willEmit<EventName extends keyof EventsInterface>(eventName: EventName) {
570
729
  const id = "*";
571
730
 
572
731
  if (!this._eventListeners || !this._eventListeners[eventName]) {
@@ -595,7 +754,7 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
595
754
  * @returns True if one or more event listeners are registered for
596
755
  * the event. False if none are found.
597
756
  */
598
- willEmitId<EventName extends keyof EventsInterface> (eventName: EventName, id: string) {
757
+ willEmitId<EventName extends keyof EventsInterface>(eventName: EventName, id: string) {
599
758
  if (!this._eventListeners || !this._eventListeners[eventName]) {
600
759
  return false;
601
760
  }
@@ -643,7 +802,10 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
643
802
  * @param {...any} data Optional arguments to emit with the event.
644
803
  * @returns The emitter instance.
645
804
  */
646
- deferEmit<EventName extends keyof EventsInterface> (eventName: EventName, ...data: Parameters<EventsInterface[EventName]>) {
805
+ deferEmit<EventName extends keyof EventsInterface>(
806
+ eventName: EventName,
807
+ ...data: Parameters<EventsInterface[EventName]>
808
+ ) {
647
809
  if (!this._eventsAllowDefer) {
648
810
  // Check for an existing timeout
649
811
  this._eventsDeferTimeouts = this._eventsDeferTimeouts || {};
@@ -663,16 +825,25 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
663
825
  return this;
664
826
  }
665
827
 
828
+ /**
829
+ * Returns true if the result from an emit() call passed as the first
830
+ * argument contains a cancellation flag.
831
+ * @param resultArr
832
+ */
833
+ didCancel(resultArr: (unknown | ListenerReturnFlag)[]) {
834
+ return resultArr.findIndex((result) => result === ListenerReturnFlag.cancel) > -1;
835
+ }
836
+
666
837
  /**
667
838
  * If events are cleared with the off() method while the event emitter is
668
839
  * actively processing any events then the off() calls get added to a
669
840
  * queue to be executed after the event emitter is finished. This stops
670
- * errors that might occur by potentially modifying the event queue while
671
- * the emitter is running through them. This method is called after the
672
- * event emitter is finished processing.
841
+ * errors that might occur by potentially mutating the event listener array
842
+ * while the emitter is running through them. This method is called after
843
+ * the event emitter is finished processing.
673
844
  * @private
674
845
  */
675
- _processRemovalQueue () {
846
+ _processRemovalQueue() {
676
847
  if (!this._eventRemovalQueue || !this._eventRemovalQueue.length) {
677
848
  return;
678
849
  }
@@ -687,10 +858,10 @@ export class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEve
687
858
  }
688
859
  }
689
860
 
690
- export function makeEmitter (obj: AnyConstructor, prototypeMode: boolean): Emitter;
691
- export function makeEmitter (obj: boolean): Emitter;
692
- export function makeEmitter (obj: Record<string, unknown>, prototypeMode: boolean): Emitter;
693
- export function makeEmitter (obj: any, prototypeMode?: any) {
861
+ export function makeEmitter(obj: AnyConstructor, prototypeMode: boolean): Emitter;
862
+ export function makeEmitter(obj: boolean): Emitter;
863
+ export function makeEmitter(obj: Record<string, unknown>, prototypeMode: boolean): Emitter;
864
+ export function makeEmitter(obj: any, prototypeMode?: any) {
694
865
  let operateOnObject;
695
866
 
696
867
  if (obj === undefined && prototypeMode === undefined) {
@@ -713,7 +884,9 @@ export function makeEmitter (obj: any, prototypeMode?: any) {
713
884
 
714
885
  if (prototypeMode) {
715
886
  if (obj.prototype === undefined) {
716
- throw new Error("Cannot modify prototype of passed object, it has no prototype property! Was it instantiated with the new operator correctly?");
887
+ throw new Error(
888
+ "Cannot modify prototype of passed object, it has no prototype property! Was it instantiated with the new operator correctly?"
889
+ );
717
890
  }
718
891
 
719
892
  operateOnObject = obj.prototype;
@@ -736,4 +909,4 @@ export function makeEmitter (obj: any, prototypeMode?: any) {
736
909
  operateOnObject._processRemovalQueue = Emitter.prototype._processRemovalQueue;
737
910
 
738
911
  return obj;
739
- }
912
+ }