@irrelon/emitter 6.0.1 → 6.1.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/dist/cjs/src/Emitter.d.ts +18 -3
- package/dist/cjs/src/Emitter.js +39 -17
- package/dist/cjs/tests/Emitter.test.js +43 -13
- package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/esm/src/Emitter.d.ts +18 -3
- package/dist/esm/src/Emitter.js +37 -15
- package/dist/esm/tests/Emitter.test.js +43 -13
- package/dist/esm/tsconfig-esm.tsbuildinfo +1 -1
- package/eslint.config.mjs +42 -0
- package/jest.config.js +7 -0
- package/package.json +57 -68
- package/src/Emitter.ts +302 -274
- package/tests/Emitter.test.ts +245 -197
- package/.editorconfig +0 -11
- /package/{.eslintrc.json → eslint.json} +0 -0
package/src/Emitter.ts
CHANGED
|
@@ -107,51 +107,57 @@ export type AnyFunction<ReturnType = any> = (...args: any[]) => ReturnType;
|
|
|
107
107
|
export type AnyConstructor = new (...args: any[]) => any;
|
|
108
108
|
|
|
109
109
|
export enum ListenerReturnFlag {
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
none = "!+_NONE",
|
|
111
|
+
cancel = "!+_CANCEL"
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
export type EventListenerCallback<EventCallbackFunctionSignature extends AnyFunction = AnyFunction> = (
|
|
115
|
-
|
|
115
|
+
...args: Parameters<EventCallbackFunctionSignature>
|
|
116
116
|
) => ReturnType<EventCallbackFunctionSignature>;
|
|
117
117
|
|
|
118
118
|
export interface EventStaticEmitterObject<EventCallbackFunctionSignature extends AnyFunction = AnyFunction> {
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
id: string;
|
|
120
|
+
args: Parameters<EventCallbackFunctionSignature>;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
export interface EmitterAnyEventsInterface {
|
|
124
|
-
|
|
124
|
+
[key: string]: AnyFunction;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
export type EmitterEventsInterface<T> = {
|
|
128
|
-
|
|
128
|
+
[K in keyof T]: T[K];
|
|
129
129
|
};
|
|
130
130
|
|
|
131
|
+
interface WithStar {
|
|
132
|
+
"*"?: (eventName: string, ...args: any[]) => void;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export type EmitterEventsWithStar<T> = EmitterEventsInterface<T> & WithStar;
|
|
136
|
+
|
|
131
137
|
/**
|
|
132
138
|
* Creates a new class with the capability to emit events.
|
|
133
139
|
*/
|
|
134
|
-
export class Emitter<EventsInterface extends
|
|
140
|
+
export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterface> = EmitterAnyEventsInterface> {
|
|
135
141
|
_eventsEmitting: boolean = false;
|
|
136
142
|
_eventRemovalQueue: any[] = [];
|
|
137
143
|
_eventListeners?: {
|
|
138
|
-
|
|
139
|
-
|
|
144
|
+
[EventName in keyof EventsInterface]?: Record<string, EventListenerCallback<EventsInterface[EventName]>[]>;
|
|
145
|
+
} = {};
|
|
140
146
|
_eventStaticEmitters: {
|
|
141
|
-
|
|
142
|
-
|
|
147
|
+
[EventName in keyof EventsInterface]?: EventStaticEmitterObject<EventsInterface[EventName]>[];
|
|
148
|
+
} = {};
|
|
143
149
|
_eventsAllowDefer: boolean = false;
|
|
144
150
|
_eventsDeferTimeouts: Record<any, number> = {};
|
|
145
151
|
|
|
146
152
|
/**
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
_on<EventName extends keyof EventsInterface>(
|
|
153
|
+
* Attach an event listener to the passed event only if the passed
|
|
154
|
+
* id matches the id for the event being fired.
|
|
155
|
+
* @param eventName The name of the event to listen for.
|
|
156
|
+
* @param id The id to match against.
|
|
157
|
+
* @param listener The method to call when the event is fired.
|
|
158
|
+
* @returns The emitter instance.
|
|
159
|
+
*/
|
|
160
|
+
_on<EventName extends keyof EventsInterface> (
|
|
155
161
|
eventName: EventName,
|
|
156
162
|
id: string,
|
|
157
163
|
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
@@ -170,8 +176,8 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
170
176
|
// Check for any static emitters, and fire the event if any exist
|
|
171
177
|
if (
|
|
172
178
|
!this._eventStaticEmitters ||
|
|
173
|
-
|
|
174
|
-
|
|
179
|
+
!this._eventStaticEmitters[eventName] ||
|
|
180
|
+
!this._eventStaticEmitters[eventName]!.length
|
|
175
181
|
)
|
|
176
182
|
return this;
|
|
177
183
|
|
|
@@ -191,14 +197,14 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
191
197
|
}
|
|
192
198
|
|
|
193
199
|
/**
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
_once<EventName extends keyof EventsInterface>(
|
|
200
|
+
* Attach an event listener to the passed event only if the passed
|
|
201
|
+
* id matches the document id for the event being fired.
|
|
202
|
+
* @param eventName The name of the event to listen for.
|
|
203
|
+
* @param id The id to match against.
|
|
204
|
+
* @param listener The method to call when the event is fired.
|
|
205
|
+
* @returns The emitter instance.
|
|
206
|
+
*/
|
|
207
|
+
_once<EventName extends keyof EventsInterface> (
|
|
202
208
|
eventName: EventName,
|
|
203
209
|
id: string,
|
|
204
210
|
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
@@ -222,14 +228,14 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
222
228
|
}
|
|
223
229
|
|
|
224
230
|
/**
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
_off<EventName extends keyof EventsInterface>(
|
|
231
|
+
* Cancels an event listener based on an event name, id and listener function.
|
|
232
|
+
* @param eventName The event to cancel listener for.
|
|
233
|
+
* @param id The ID of the event to cancel listening for.
|
|
234
|
+
* @param listener The event listener function used in the on()
|
|
235
|
+
* or once() call to cancel.
|
|
236
|
+
* @returns The emitter instance.
|
|
237
|
+
*/
|
|
238
|
+
_off<EventName extends keyof EventsInterface> (
|
|
233
239
|
eventName: EventName,
|
|
234
240
|
id: string,
|
|
235
241
|
listener?: EventListenerCallback<EventsInterface[EventName]>
|
|
@@ -275,23 +281,31 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
275
281
|
}
|
|
276
282
|
|
|
277
283
|
/**
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
284
|
+
* Creates an event listener that listens for any and all events
|
|
285
|
+
* emitted.
|
|
286
|
+
*/
|
|
287
|
+
onAny (listener: EventListenerCallback) {
|
|
288
|
+
this.on("*", listener);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Attach an event listener to the passed event only if the passed
|
|
293
|
+
* id matches the document id for the event being fired.
|
|
294
|
+
* @param eventName The name of the event to listen for.
|
|
295
|
+
* @param id The id to match against.
|
|
296
|
+
* @param listener The method to call when the event is fired.
|
|
297
|
+
* @returns The emitter instance.
|
|
298
|
+
*/
|
|
290
299
|
on<EventName extends keyof EventsInterface>(
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
300
|
+
eventName: EventName,
|
|
301
|
+
id: string,
|
|
302
|
+
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
303
|
+
): this;
|
|
294
304
|
on<EventName extends keyof EventsInterface>(
|
|
305
|
+
eventName: EventName,
|
|
306
|
+
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
307
|
+
): this;
|
|
308
|
+
on<EventName extends keyof EventsInterface> (
|
|
295
309
|
eventName: EventName,
|
|
296
310
|
idOrListener: string | EventListenerCallback<EventsInterface[EventName]>,
|
|
297
311
|
listener?: EventListenerCallback<EventsInterface[EventName]>
|
|
@@ -304,23 +318,23 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
304
318
|
}
|
|
305
319
|
|
|
306
320
|
/**
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
321
|
+
* Attach an event listener to the passed event only if the passed
|
|
322
|
+
* id matches the document id for the event being fired.
|
|
323
|
+
* @param eventName The name of the event to listen for.
|
|
324
|
+
* @param id The id to match against.
|
|
325
|
+
* @param listener
|
|
326
|
+
* @returns The emitter instance.
|
|
327
|
+
*/
|
|
314
328
|
once<EventName extends keyof EventsInterface>(
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
329
|
+
eventName: EventName,
|
|
330
|
+
id: string,
|
|
331
|
+
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
332
|
+
): this;
|
|
319
333
|
once<EventName extends keyof EventsInterface>(
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
once<EventName extends keyof EventsInterface>(eventName: EventName, ...rest: any[]): this {
|
|
334
|
+
eventName: EventName,
|
|
335
|
+
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
336
|
+
): this;
|
|
337
|
+
once<EventName extends keyof EventsInterface> (eventName: EventName, ...rest: any[]): this {
|
|
324
338
|
const restTypes = rest.map((arg) => typeof arg);
|
|
325
339
|
|
|
326
340
|
if (restTypes[0] === "function") {
|
|
@@ -331,27 +345,27 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
331
345
|
}
|
|
332
346
|
|
|
333
347
|
/**
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
348
|
+
* Overwrites any previous event listeners so that if the event fires, only
|
|
349
|
+
* the listener you pass will be called. If you pass an id along with the
|
|
350
|
+
* listener, only listeners for the id will be overwritten. This is similar
|
|
351
|
+
* to calling `.off(eventName)` then `on(eventName, listener)` since
|
|
352
|
+
* `off(eventName)` will cancel any previous event listeners for the passed
|
|
353
|
+
* event name.
|
|
354
|
+
* @param eventName The name of the event to listen for.
|
|
355
|
+
* @param id The id to match against.
|
|
356
|
+
* @param listener The method to call when the event is fired.
|
|
357
|
+
* @returns The emitter instance.
|
|
358
|
+
*/
|
|
345
359
|
overwrite<EventName extends keyof EventsInterface>(
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
360
|
+
eventName: EventName,
|
|
361
|
+
id: string,
|
|
362
|
+
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
363
|
+
): this;
|
|
350
364
|
overwrite<EventName extends keyof EventsInterface>(
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
overwrite<EventName extends keyof EventsInterface>(eventName: EventName, ...rest: any[]) {
|
|
365
|
+
eventName: EventName,
|
|
366
|
+
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
367
|
+
): this;
|
|
368
|
+
overwrite<EventName extends keyof EventsInterface> (eventName: EventName, ...rest: any[]) {
|
|
355
369
|
const restTypes = rest.map((arg) => typeof arg);
|
|
356
370
|
|
|
357
371
|
if (restTypes[0] === "function") {
|
|
@@ -364,24 +378,32 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
364
378
|
}
|
|
365
379
|
|
|
366
380
|
/**
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
381
|
+
* Removes an event listener that listens for any and all events
|
|
382
|
+
* emitted.
|
|
383
|
+
*/
|
|
384
|
+
offAny (listener: EventListenerCallback) {
|
|
385
|
+
this.off("*", listener);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Cancels an event listener based on an event name, id and listener function.
|
|
390
|
+
* @param eventName The event to cancel listener for.
|
|
391
|
+
* @param id The ID of the event to cancel listening for.
|
|
392
|
+
* @param listener The event listener function used in the on()
|
|
393
|
+
* or once() call to cancel.
|
|
394
|
+
* @returns The emitter instance.
|
|
395
|
+
*/
|
|
374
396
|
off<EventName extends keyof EventsInterface>(
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
397
|
+
eventName: EventName,
|
|
398
|
+
id: string,
|
|
399
|
+
listener?: EventListenerCallback<EventsInterface[EventName]>
|
|
400
|
+
): this;
|
|
379
401
|
off<EventName extends keyof EventsInterface>(
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
402
|
+
eventName: EventName,
|
|
403
|
+
listener?: EventListenerCallback<EventsInterface[EventName]>
|
|
404
|
+
): this;
|
|
383
405
|
off<EventName extends keyof EventsInterface>(eventName: EventName): this;
|
|
384
|
-
off<EventName extends keyof EventsInterface>(eventName: EventName, ...rest: any[]) {
|
|
406
|
+
off<EventName extends keyof EventsInterface> (eventName: EventName, ...rest: any[]) {
|
|
385
407
|
if (rest.length === 0) {
|
|
386
408
|
// Only event was provided, use * as the id to mean "any without"
|
|
387
409
|
// a specific id
|
|
@@ -400,14 +422,14 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
400
422
|
return this._off(eventName, rest[0], rest[1]);
|
|
401
423
|
}
|
|
402
424
|
|
|
403
|
-
_emitToSingleListener<EventName extends keyof EventsInterface>(
|
|
425
|
+
_emitToSingleListener<EventName extends keyof EventsInterface> (
|
|
404
426
|
listener: EventListenerCallback<EventsInterface[EventName]>,
|
|
405
427
|
data: Parameters<EventsInterface[EventName]>
|
|
406
428
|
): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag {
|
|
407
429
|
return listener(...data);
|
|
408
430
|
}
|
|
409
431
|
|
|
410
|
-
_emitToArrayOfListeners<EventName extends keyof EventsInterface>(
|
|
432
|
+
_emitToArrayOfListeners<EventName extends keyof EventsInterface> (
|
|
411
433
|
arr: EventListenerCallback<EventsInterface[EventName]>[],
|
|
412
434
|
data: Parameters<EventsInterface[EventName]>
|
|
413
435
|
): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[] {
|
|
@@ -435,49 +457,49 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
435
457
|
}
|
|
436
458
|
|
|
437
459
|
/**
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
rpc<EventName extends keyof EventsInterface>(
|
|
460
|
+
* Call an event listener by name. The `rpc()` function differs from `emit()` in
|
|
461
|
+
* that it will only call and return data from the first event listener for the
|
|
462
|
+
* event rather than all event listeners. If you have more than one event listener
|
|
463
|
+
* assigned to the event, all others except the first will be ignored and will
|
|
464
|
+
* not receive the event.
|
|
465
|
+
* @param eventName The name of the event to call the listener for.
|
|
466
|
+
* @param {...any} data The arguments to send to the listening method.
|
|
467
|
+
* If you are sending multiple arguments, separate them with a comma so
|
|
468
|
+
* that they are received by the function as separate arguments.
|
|
469
|
+
* @return {number}
|
|
470
|
+
* @example #Call the Event Listener
|
|
471
|
+
* // Emit the event named "hello"
|
|
472
|
+
* myEntity.emit('hello');
|
|
473
|
+
* @example #Call the Event Listener With Data Object
|
|
474
|
+
* // Emit the event named "hello"
|
|
475
|
+
* myEntity.emit('hello', {moo: true});
|
|
476
|
+
* @example #Call the Event Listener With Multiple Data Values
|
|
477
|
+
* // Emit the event named "hello"
|
|
478
|
+
* myEntity.emit('hello', {moo: true}, 'someString');
|
|
479
|
+
* @example #Register the Listener for Event Data
|
|
480
|
+
* // Set a listener to listen for the data (multiple values emitted
|
|
481
|
+
* // from an event are passed as function arguments)
|
|
482
|
+
* myEntity.on('hello', function (arg1, arg2) {
|
|
483
|
+
* console.log("Arguments:", arg1, arg2);
|
|
484
|
+
* return "foo";
|
|
485
|
+
* }
|
|
486
|
+
*
|
|
487
|
+
* // Emit the event named "hello"
|
|
488
|
+
* const result = myEntity.emit('hello', 'data1', 'data2');
|
|
489
|
+
* console.log("Result:", result);
|
|
490
|
+
*
|
|
491
|
+
* // The console output is:
|
|
492
|
+
* // Arguments: data1 data2
|
|
493
|
+
* // Result: "foo"
|
|
494
|
+
*/
|
|
495
|
+
rpc<EventName extends keyof EventsInterface> (
|
|
474
496
|
eventName: EventName,
|
|
475
497
|
...data: Parameters<EventsInterface[EventName]>
|
|
476
498
|
): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag {
|
|
477
499
|
return this.rpcId<EventName>(eventName, "*", ...data);
|
|
478
500
|
}
|
|
479
501
|
|
|
480
|
-
rpcId<EventName extends keyof EventsInterface>(
|
|
502
|
+
rpcId<EventName extends keyof EventsInterface> (
|
|
481
503
|
eventName: EventName,
|
|
482
504
|
id: string,
|
|
483
505
|
...data: Parameters<EventsInterface[EventName]>
|
|
@@ -494,26 +516,18 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
494
516
|
const arr = this._eventListeners[eventName]![id];
|
|
495
517
|
emitterResult = this._emitToSingleListener<EventName>(arr[0], data);
|
|
496
518
|
} else if (id !== "*" && this._eventListeners[eventName]!["*"]) {
|
|
497
|
-
// Handle
|
|
519
|
+
// Handle wildcard emit if the id passed wasn't already a wildcard (*) id
|
|
498
520
|
const arr = this._eventListeners[eventName]!["*"];
|
|
499
521
|
emitterResult = this._emitToSingleListener<EventName>(arr[0], data);
|
|
500
522
|
} else {
|
|
501
523
|
if (id === "*") {
|
|
502
524
|
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 })`
|
|
525
|
+
`Cannot make an rpc call to event "${eventName as string}" without at least one event listener and none were found, register a listener via on("${eventName as string}", () => { ...some listener code })`
|
|
508
526
|
);
|
|
509
527
|
}
|
|
510
528
|
|
|
511
529
|
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 })`
|
|
530
|
+
`Cannot make an rpc call to event "${eventName as string}" and id "${id}" without at least one event listener and none were found, register a listener via on("${eventName as string}", "${id}", () => { ...some listener code })`
|
|
517
531
|
);
|
|
518
532
|
}
|
|
519
533
|
|
|
@@ -524,68 +538,80 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
524
538
|
}
|
|
525
539
|
|
|
526
540
|
/**
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
emit<EventName extends keyof EventsInterface>(
|
|
541
|
+
* Emit an event by name.
|
|
542
|
+
* @param eventName The name of the event to emit.
|
|
543
|
+
* @param {...any} data The arguments to send to any listening methods.
|
|
544
|
+
* If you are sending multiple arguments, separate them with a comma so
|
|
545
|
+
* that they are received by the function as separate arguments.
|
|
546
|
+
* @return {number}
|
|
547
|
+
* @example #Emit an Event
|
|
548
|
+
* // Emit the event named "hello"
|
|
549
|
+
* myEntity.emit('hello');
|
|
550
|
+
* @example #Emit an Event With Data Object
|
|
551
|
+
* // Emit the event named "hello"
|
|
552
|
+
* myEntity.emit('hello', {moo: true});
|
|
553
|
+
* @example #Emit an Event With Multiple Data Values
|
|
554
|
+
* // Emit the event named "hello"
|
|
555
|
+
* myEntity.emit('hello', {moo: true}, 'someString');
|
|
556
|
+
* @example #Listen for Event Data
|
|
557
|
+
* // Set a listener to listen for the data (multiple values emitted
|
|
558
|
+
* // from an event are passed as function arguments)
|
|
559
|
+
* myEntity.on('hello', function (arg1, arg2) {
|
|
560
|
+
* console.log("Arguments:", arg1, arg2);
|
|
561
|
+
* return "foo";
|
|
562
|
+
* }
|
|
563
|
+
*
|
|
564
|
+
* // Emit the event named "hello"
|
|
565
|
+
* // The result is returned as an array of all return values
|
|
566
|
+
* // from all the listeners for the event
|
|
567
|
+
* const result = myEntity.emit('hello', 'data1', 'data2');
|
|
568
|
+
* console.log("Result:", result);
|
|
569
|
+
*
|
|
570
|
+
* // The console output is:
|
|
571
|
+
* // Arguments: data1 data2
|
|
572
|
+
* // Result: ["foo"]
|
|
573
|
+
*/
|
|
574
|
+
emit<EventName extends keyof EventsInterface> (
|
|
561
575
|
eventName: EventName,
|
|
562
576
|
...data: Parameters<EventsInterface[EventName]>
|
|
563
577
|
): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[] {
|
|
564
578
|
return this.emitId<EventName>(eventName, "*", ...data);
|
|
565
579
|
}
|
|
566
580
|
|
|
567
|
-
emitId<EventName extends keyof EventsInterface>(
|
|
581
|
+
emitId<EventName extends keyof EventsInterface> (
|
|
568
582
|
eventName: EventName,
|
|
569
583
|
id: string,
|
|
570
584
|
...data: Parameters<EventsInterface[EventName]>
|
|
571
585
|
): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[] {
|
|
572
|
-
if (!this._eventListeners || !this._eventListeners[eventName]) {
|
|
586
|
+
if (!this._eventListeners || (!this._eventListeners[eventName] && !this._eventListeners["*"])) {
|
|
573
587
|
return [];
|
|
574
588
|
}
|
|
575
589
|
|
|
576
590
|
let emitterResult: (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[] = [];
|
|
577
591
|
this._eventsEmitting = true;
|
|
578
592
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
593
|
+
if (this._eventListeners[eventName]) {
|
|
594
|
+
// Handle id emit
|
|
595
|
+
if (this._eventListeners[eventName]![id]) {
|
|
596
|
+
const arr = this._eventListeners[eventName]![id];
|
|
597
|
+
emitterResult = emitterResult.concat(this._emitToArrayOfListeners<EventName>(arr, data));
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// Handle id wildcard emit if the id passed wasn't already a wildcard (*) id
|
|
601
|
+
if (id !== "*" && this._eventListeners[eventName]!["*"]) {
|
|
602
|
+
const arr = this._eventListeners[eventName]!["*"];
|
|
603
|
+
emitterResult = emitterResult.concat(this._emitToArrayOfListeners<EventName>(arr, data));
|
|
604
|
+
}
|
|
583
605
|
}
|
|
584
606
|
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
607
|
+
if (this._eventListeners["*"]) {
|
|
608
|
+
const arr = this._eventListeners["*"]!["*"];
|
|
609
|
+
emitterResult = emitterResult.concat(
|
|
610
|
+
this._emitToArrayOfListeners<EventName>(
|
|
611
|
+
arr as EventListenerCallback<EventsInterface[EventName]>[],
|
|
612
|
+
[eventName, ...data] as Parameters<EventsInterface[EventName]>
|
|
613
|
+
)
|
|
614
|
+
);
|
|
589
615
|
}
|
|
590
616
|
|
|
591
617
|
this._eventsEmitting = false;
|
|
@@ -595,15 +621,15 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
595
621
|
}
|
|
596
622
|
|
|
597
623
|
/**
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
emitStatic<EventName extends keyof EventsInterface>(
|
|
624
|
+
* Creates a persistent emitter record that will fire a listener if
|
|
625
|
+
* one is added for this event after the emitStatic() call has been
|
|
626
|
+
* made.
|
|
627
|
+
* @param eventName The name of the event to emit.
|
|
628
|
+
* @param {...any} data Optional arguments to emit with the event.
|
|
629
|
+
* @returns The emitter instance.
|
|
630
|
+
* @private
|
|
631
|
+
*/
|
|
632
|
+
emitStatic<EventName extends keyof EventsInterface> (
|
|
607
633
|
eventName: EventName,
|
|
608
634
|
...data: Parameters<EventsInterface[EventName]>
|
|
609
635
|
) {
|
|
@@ -612,7 +638,7 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
612
638
|
this._eventsEmitting = true;
|
|
613
639
|
|
|
614
640
|
if (this._eventListeners[eventName] && this._eventListeners[eventName]![id]) {
|
|
615
|
-
// Handle
|
|
641
|
+
// Handle id wildcard emit
|
|
616
642
|
const arr = this._eventListeners[eventName]![id];
|
|
617
643
|
const arrCount = arr.length;
|
|
618
644
|
|
|
@@ -630,27 +656,27 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
630
656
|
|
|
631
657
|
this._eventStaticEmitters = this._eventStaticEmitters || {};
|
|
632
658
|
this._eventStaticEmitters[eventName] = this._eventStaticEmitters[eventName] || [];
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
659
|
+
this._eventStaticEmitters[eventName]!.push({
|
|
660
|
+
id: "*",
|
|
661
|
+
args: data
|
|
662
|
+
});
|
|
637
663
|
|
|
638
|
-
|
|
664
|
+
this._processRemovalQueue();
|
|
639
665
|
|
|
640
|
-
|
|
666
|
+
return this;
|
|
641
667
|
}
|
|
642
668
|
|
|
643
669
|
/**
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
emitStaticId<EventName extends keyof EventsInterface>(
|
|
670
|
+
* Creates a persistent emitter record that will fire a listener if
|
|
671
|
+
* one is added for this event after the emitStatic() call has been
|
|
672
|
+
* made.
|
|
673
|
+
* @param eventName The name of the event to emit.
|
|
674
|
+
* @param id The id of the event to emit.
|
|
675
|
+
* @param {...any} data Optional arguments to emit with the event.
|
|
676
|
+
* @returns The emitter instance.
|
|
677
|
+
* @private
|
|
678
|
+
*/
|
|
679
|
+
emitStaticId<EventName extends keyof EventsInterface> (
|
|
654
680
|
eventName: EventName,
|
|
655
681
|
id: string,
|
|
656
682
|
...data: Parameters<EventsInterface[EventName]>
|
|
@@ -676,7 +702,7 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
676
702
|
}
|
|
677
703
|
}
|
|
678
704
|
|
|
679
|
-
// Handle
|
|
705
|
+
// Handle wildcard emit
|
|
680
706
|
if (this._eventListeners[eventName]!["*"]) {
|
|
681
707
|
const arr = this._eventListeners[eventName]!["*"];
|
|
682
708
|
const arrCount = arr.length;
|
|
@@ -696,23 +722,23 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
696
722
|
|
|
697
723
|
this._eventStaticEmitters = this._eventStaticEmitters || {};
|
|
698
724
|
this._eventStaticEmitters[eventName] = this._eventStaticEmitters[eventName] || [];
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
725
|
+
this._eventStaticEmitters[eventName]!.push({
|
|
726
|
+
id,
|
|
727
|
+
args: data
|
|
728
|
+
});
|
|
703
729
|
|
|
704
|
-
|
|
730
|
+
this._processRemovalQueue();
|
|
705
731
|
|
|
706
|
-
|
|
732
|
+
return this;
|
|
707
733
|
}
|
|
708
734
|
|
|
709
735
|
/**
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
cancelStatic<EventName extends keyof EventsInterface>(eventName: EventName) {
|
|
736
|
+
* Handles removing emitters, is an internal method not called directly.
|
|
737
|
+
* @param eventName The event to remove static emitter for.
|
|
738
|
+
* @returns The emitter instance.
|
|
739
|
+
* @private
|
|
740
|
+
*/
|
|
741
|
+
cancelStatic<EventName extends keyof EventsInterface> (eventName: EventName) {
|
|
716
742
|
this._eventStaticEmitters = this._eventStaticEmitters || {};
|
|
717
743
|
this._eventStaticEmitters[eventName] = [];
|
|
718
744
|
|
|
@@ -720,12 +746,12 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
720
746
|
}
|
|
721
747
|
|
|
722
748
|
/**
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
willEmit<EventName extends keyof EventsInterface>(eventName: EventName) {
|
|
749
|
+
* Checks if an event has any event listeners or not.
|
|
750
|
+
* @param eventName The name of the event to check for.
|
|
751
|
+
* @returns True if one or more event listeners are registered for
|
|
752
|
+
* the event. False if none are found.
|
|
753
|
+
*/
|
|
754
|
+
willEmit<EventName extends keyof EventsInterface> (eventName: EventName) {
|
|
729
755
|
const id = "*";
|
|
730
756
|
|
|
731
757
|
if (!this._eventListeners || !this._eventListeners[eventName]) {
|
|
@@ -748,13 +774,13 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
748
774
|
}
|
|
749
775
|
|
|
750
776
|
/**
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
willEmitId<EventName extends keyof EventsInterface>(eventName: EventName, id: string) {
|
|
777
|
+
* Checks if an event has any event listeners or not based on the passed id.
|
|
778
|
+
* @param eventName The name of the event to check for.
|
|
779
|
+
* @param id The event ID to check for.
|
|
780
|
+
* @returns True if one or more event listeners are registered for
|
|
781
|
+
* the event. False if none are found.
|
|
782
|
+
*/
|
|
783
|
+
willEmitId<EventName extends keyof EventsInterface> (eventName: EventName, id: string) {
|
|
758
784
|
if (!this._eventListeners || !this._eventListeners[eventName]) {
|
|
759
785
|
return false;
|
|
760
786
|
}
|
|
@@ -774,7 +800,7 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
774
800
|
}
|
|
775
801
|
}
|
|
776
802
|
|
|
777
|
-
// Handle
|
|
803
|
+
// Handle wildcard emit
|
|
778
804
|
if (this._eventListeners[eventName]!["*"]) {
|
|
779
805
|
const arr = this._eventListeners[eventName]!["*"];
|
|
780
806
|
const arrCount = arr.length;
|
|
@@ -793,16 +819,16 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
793
819
|
}
|
|
794
820
|
|
|
795
821
|
/**
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
deferEmit<EventName extends keyof EventsInterface>(
|
|
822
|
+
* Queues an event to be fired. This has automatic de-bouncing so that any
|
|
823
|
+
* events of the same type that occur within 100 milliseconds of a previous
|
|
824
|
+
* one will all be wrapped into a single emit rather than emitting tons of
|
|
825
|
+
* events for lots of chained inserts etc. Only the data from the last
|
|
826
|
+
* de-bounced event will be emitted.
|
|
827
|
+
* @param eventName The name of the event to emit.
|
|
828
|
+
* @param {...any} data Optional arguments to emit with the event.
|
|
829
|
+
* @returns The emitter instance.
|
|
830
|
+
*/
|
|
831
|
+
deferEmit<EventName extends keyof EventsInterface> (
|
|
806
832
|
eventName: EventName,
|
|
807
833
|
...data: Parameters<EventsInterface[EventName]>
|
|
808
834
|
) {
|
|
@@ -826,24 +852,24 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
826
852
|
}
|
|
827
853
|
|
|
828
854
|
/**
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
didCancel(resultArr: (unknown | ListenerReturnFlag)[]) {
|
|
855
|
+
* Returns true if the result from an emit() call passed as the first
|
|
856
|
+
* argument contains a cancellation flag.
|
|
857
|
+
* @param resultArr
|
|
858
|
+
*/
|
|
859
|
+
didCancel (resultArr: (unknown | ListenerReturnFlag)[]) {
|
|
834
860
|
return resultArr.findIndex((result) => result === ListenerReturnFlag.cancel) > -1;
|
|
835
861
|
}
|
|
836
862
|
|
|
837
863
|
/**
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
_processRemovalQueue() {
|
|
864
|
+
* If events are cleared with the off() method while the event emitter is
|
|
865
|
+
* actively processing any events then the off() calls get added to a
|
|
866
|
+
* queue to be executed after the event emitter is finished. This stops
|
|
867
|
+
* errors that might occur by potentially mutating the event listener array
|
|
868
|
+
* while the emitter is running through them. This method is called after
|
|
869
|
+
* the event emitter is finished processing.
|
|
870
|
+
* @private
|
|
871
|
+
*/
|
|
872
|
+
_processRemovalQueue () {
|
|
847
873
|
if (!this._eventRemovalQueue || !this._eventRemovalQueue.length) {
|
|
848
874
|
return;
|
|
849
875
|
}
|
|
@@ -861,7 +887,7 @@ export class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterf
|
|
|
861
887
|
export function makeEmitter(obj: AnyConstructor, prototypeMode: boolean): Emitter;
|
|
862
888
|
export function makeEmitter(obj: boolean): Emitter;
|
|
863
889
|
export function makeEmitter(obj: Record<string, unknown>, prototypeMode: boolean): Emitter;
|
|
864
|
-
export function makeEmitter(obj: any, prototypeMode?: any) {
|
|
890
|
+
export function makeEmitter (obj: any, prototypeMode?: any) {
|
|
865
891
|
let operateOnObject;
|
|
866
892
|
|
|
867
893
|
if (obj === undefined && prototypeMode === undefined) {
|
|
@@ -896,7 +922,9 @@ export function makeEmitter(obj: any, prototypeMode?: any) {
|
|
|
896
922
|
|
|
897
923
|
// Convert the object prototype to have eventing capability
|
|
898
924
|
operateOnObject.on = Emitter.prototype.on;
|
|
925
|
+
operateOnObject.onAny = Emitter.prototype.onAny;
|
|
899
926
|
operateOnObject.off = Emitter.prototype.off;
|
|
927
|
+
operateOnObject.offAny = Emitter.prototype.offAny;
|
|
900
928
|
operateOnObject.once = Emitter.prototype.once;
|
|
901
929
|
operateOnObject.emit = Emitter.prototype.emit;
|
|
902
930
|
operateOnObject.emitId = Emitter.prototype.emitId;
|