@irrelon/emitter 6.0.1 → 6.2.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/.editorconfig +4 -7
- package/dist/cjs/src/Emitter.d.ts +51 -14
- package/dist/cjs/src/Emitter.js +83 -29
- package/dist/cjs/tests/Emitter.test.js +77 -30
- package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/esm/src/Emitter.d.ts +51 -14
- package/dist/esm/src/Emitter.js +83 -26
- package/dist/esm/tests/Emitter.test.js +77 -30
- package/dist/esm/tsconfig-esm.tsbuildinfo +1 -1
- package/doc/Emitter.html +451 -1551
- package/doc/Emitter.js.html +601 -850
- package/doc/index.html +1 -1
- package/doc/scripts/linenumber.js +9 -9
- package/doc/styles/jsdoc-default.css +2 -2
- package/eslint.config.mjs +42 -0
- package/jest.config.js +7 -0
- package/package.json +18 -27
- package/readme.md +10 -1
- package/src/Emitter.d.ts +290 -0
- package/src/Emitter.js +600 -0
- package/src/Emitter.ts +167 -161
- package/tests/Emitter.test.d.ts +1 -0
- package/tests/Emitter.test.js +472 -0
- package/tests/Emitter.test.ts +143 -64
- package/tsconfig.json +8 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/.prettierrc.yml +0 -26
- package/doc/deferEmit.html +0 -258
- package/doc/emitStatic.html +0 -444
- package/doc/emitStaticId.html +0 -685
- package/doc/global.html +0 -991
- package/doc/global.html#emit +0 -442
- package/doc/off.html +0 -857
- package/doc/on.html +0 -453
- package/doc/once.html +0 -453
- package/doc/willEmit.html +0 -234
- package/doc/willEmitId.html +0 -257
- /package/{.eslintrc.json → eslint.json} +0 -0
package/.editorconfig
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
# EditorConfig is awesome: http://EditorConfig.org
|
|
2
|
-
|
|
3
|
-
# top-most EditorConfig file
|
|
4
1
|
root = true
|
|
5
2
|
|
|
6
|
-
# Unix-style newlines with a newline ending every file
|
|
7
3
|
[*]
|
|
8
|
-
end_of_line = lf
|
|
9
|
-
insert_final_newline = false
|
|
10
4
|
indent_style = tab
|
|
11
|
-
|
|
5
|
+
end_of_line = lf
|
|
6
|
+
charset = utf-8
|
|
7
|
+
trim_trailing_whitespace = true
|
|
8
|
+
insert_final_newline = false
|
|
@@ -15,10 +15,14 @@ export interface EmitterAnyEventsInterface {
|
|
|
15
15
|
export type EmitterEventsInterface<T> = {
|
|
16
16
|
[K in keyof T]: T[K];
|
|
17
17
|
};
|
|
18
|
+
export interface WithStar {
|
|
19
|
+
"*"?: (eventName: string, ...args: any[]) => void;
|
|
20
|
+
}
|
|
21
|
+
export type EmitterEventsWithStar<T> = EmitterEventsInterface<T> & WithStar;
|
|
18
22
|
/**
|
|
19
|
-
* Creates a new class with the
|
|
23
|
+
* Creates a new class with the ability to emit events.
|
|
20
24
|
*/
|
|
21
|
-
export declare class Emitter<EventsInterface extends
|
|
25
|
+
export declare class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterface> = EmitterAnyEventsInterface> {
|
|
22
26
|
_eventsEmitting: boolean;
|
|
23
27
|
_eventRemovalQueue: any[];
|
|
24
28
|
_eventListeners?: {
|
|
@@ -29,6 +33,10 @@ export declare class Emitter<EventsInterface extends EmitterEventsInterface<Even
|
|
|
29
33
|
};
|
|
30
34
|
_eventsAllowDefer: boolean;
|
|
31
35
|
_eventsDeferTimeouts: Record<any, number>;
|
|
36
|
+
_dispatchWindowEventsEnabled: boolean;
|
|
37
|
+
_dispatchPrefix?: string;
|
|
38
|
+
constructor(dispatchPrefix?: string, shouldDispatchWindowEvents?: boolean);
|
|
39
|
+
dispatchWindowEventsEnabled(shouldDispatchWindowEvents: boolean): void;
|
|
32
40
|
/**
|
|
33
41
|
* Attach an event listener to the passed event only if the passed
|
|
34
42
|
* id matches the id for the event being fired.
|
|
@@ -56,6 +64,11 @@ export declare class Emitter<EventsInterface extends EmitterEventsInterface<Even
|
|
|
56
64
|
* @returns The emitter instance.
|
|
57
65
|
*/
|
|
58
66
|
_off<EventName extends keyof EventsInterface>(eventName: EventName, id: string, listener?: EventListenerCallback<EventsInterface[EventName]>): this;
|
|
67
|
+
/**
|
|
68
|
+
* Creates an event listener that listens for any and all events
|
|
69
|
+
* emitted.
|
|
70
|
+
*/
|
|
71
|
+
onAny(listener: EventListenerCallback): void;
|
|
59
72
|
/**
|
|
60
73
|
* Attach an event listener to the passed event only if the passed
|
|
61
74
|
* id matches the document id for the event being fired.
|
|
@@ -90,6 +103,11 @@ export declare class Emitter<EventsInterface extends EmitterEventsInterface<Even
|
|
|
90
103
|
*/
|
|
91
104
|
overwrite<EventName extends keyof EventsInterface>(eventName: EventName, id: string, listener: EventListenerCallback<EventsInterface[EventName]>): this;
|
|
92
105
|
overwrite<EventName extends keyof EventsInterface>(eventName: EventName, listener: EventListenerCallback<EventsInterface[EventName]>): this;
|
|
106
|
+
/**
|
|
107
|
+
* Removes an event listener that listens for any and all events
|
|
108
|
+
* emitted.
|
|
109
|
+
*/
|
|
110
|
+
offAny(listener: EventListenerCallback): void;
|
|
93
111
|
/**
|
|
94
112
|
* Cancels an event listener based on an event name, id and listener function.
|
|
95
113
|
* @param eventName The event to cancel listener for.
|
|
@@ -103,6 +121,14 @@ export declare class Emitter<EventsInterface extends EmitterEventsInterface<Even
|
|
|
103
121
|
off<EventName extends keyof EventsInterface>(eventName: EventName): this;
|
|
104
122
|
_emitToSingleListener<EventName extends keyof EventsInterface>(listener: EventListenerCallback<EventsInterface[EventName]>, data: Parameters<EventsInterface[EventName]>): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag;
|
|
105
123
|
_emitToArrayOfListeners<EventName extends keyof EventsInterface>(arr: EventListenerCallback<EventsInterface[EventName]>[], data: Parameters<EventsInterface[EventName]>): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[];
|
|
124
|
+
/**
|
|
125
|
+
* Dispatches an event originating in our emitter to the browser's
|
|
126
|
+
* window object.
|
|
127
|
+
* @param eventName The name of the event to emit. This gets prefixed with the
|
|
128
|
+
* dispatch prefix if one is set.
|
|
129
|
+
* @param data
|
|
130
|
+
*/
|
|
131
|
+
_emitToWindowDispatch<EventName extends keyof EventsInterface>(eventName: EventName, data: any): void;
|
|
106
132
|
/**
|
|
107
133
|
* Call an event listener by name. The `rpc()` function differs from `emit()` in
|
|
108
134
|
* that it will only call and return data from the first event listener for the
|
|
@@ -133,10 +159,10 @@ export declare class Emitter<EventsInterface extends EmitterEventsInterface<Even
|
|
|
133
159
|
*
|
|
134
160
|
* // Emit the event named "hello"
|
|
135
161
|
* const result = myEntity.emit('hello', 'data1', 'data2');
|
|
136
|
-
*
|
|
162
|
+
* console.log("Result:", result);
|
|
137
163
|
*
|
|
138
164
|
* // The console output is:
|
|
139
|
-
* //
|
|
165
|
+
* // Arguments: data1 data2
|
|
140
166
|
* // Result: "foo"
|
|
141
167
|
*/
|
|
142
168
|
rpc<EventName extends keyof EventsInterface>(eventName: EventName, ...data: Parameters<EventsInterface[EventName]>): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag;
|
|
@@ -147,7 +173,7 @@ export declare class Emitter<EventsInterface extends EmitterEventsInterface<Even
|
|
|
147
173
|
* @param {...any} data The arguments to send to any listening methods.
|
|
148
174
|
* If you are sending multiple arguments, separate them with a comma so
|
|
149
175
|
* that they are received by the function as separate arguments.
|
|
150
|
-
* @return {
|
|
176
|
+
* @return {any[]} An array of all return values from all the listeners for the event.
|
|
151
177
|
* @example #Emit an Event
|
|
152
178
|
* // Emit the event named "hello"
|
|
153
179
|
* myEntity.emit('hello');
|
|
@@ -160,7 +186,7 @@ export declare class Emitter<EventsInterface extends EmitterEventsInterface<Even
|
|
|
160
186
|
* @example #Listen for Event Data
|
|
161
187
|
* // Set a listener to listen for the data (multiple values emitted
|
|
162
188
|
* // from an event are passed as function arguments)
|
|
163
|
-
*
|
|
189
|
+
* myEntity.on('hello', function (arg1, arg2) {
|
|
164
190
|
* console.log("Arguments:", arg1, arg2);
|
|
165
191
|
* return "foo";
|
|
166
192
|
* }
|
|
@@ -169,18 +195,29 @@ export declare class Emitter<EventsInterface extends EmitterEventsInterface<Even
|
|
|
169
195
|
* // The result is returned as an array of all return values
|
|
170
196
|
* // from all the listeners for the event
|
|
171
197
|
* const result = myEntity.emit('hello', 'data1', 'data2');
|
|
172
|
-
*
|
|
198
|
+
* console.log("Result:", result);
|
|
173
199
|
*
|
|
174
200
|
* // The console output is:
|
|
175
|
-
* //
|
|
201
|
+
* // Arguments: data1 data2
|
|
176
202
|
* // Result: ["foo"]
|
|
177
203
|
*/
|
|
178
204
|
emit<EventName extends keyof EventsInterface>(eventName: EventName, ...data: Parameters<EventsInterface[EventName]>): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[];
|
|
205
|
+
/**
|
|
206
|
+
* Emits an event by name and id.
|
|
207
|
+
* @param eventName The name of the event to emit.
|
|
208
|
+
* @param id The id of the event to emit.
|
|
209
|
+
* @param {...any} data The arguments to send to any listening methods.
|
|
210
|
+
* If you are sending multiple arguments, separate them with a comma so
|
|
211
|
+
* that they are received by the function as separate arguments.
|
|
212
|
+
* @return {any[]} An array of all return values from all the listeners for the event.
|
|
213
|
+
*/
|
|
179
214
|
emitId<EventName extends keyof EventsInterface>(eventName: EventName, id: string, ...data: Parameters<EventsInterface[EventName]>): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[];
|
|
180
215
|
/**
|
|
181
|
-
* Creates a persistent
|
|
182
|
-
*
|
|
183
|
-
*
|
|
216
|
+
* Creates a persistent event. Once emitStatic() has been called, a
|
|
217
|
+
* persistent event is registered. Any existing event listeners will
|
|
218
|
+
* be called just like when you call emit(), however, any new
|
|
219
|
+
* listeners that are registered for this event via on() will also be
|
|
220
|
+
* called as soon as they are added.
|
|
184
221
|
* @param eventName The name of the event to emit.
|
|
185
222
|
* @param {...any} data Optional arguments to emit with the event.
|
|
186
223
|
* @returns The emitter instance.
|
|
@@ -248,6 +285,6 @@ export declare class Emitter<EventsInterface extends EmitterEventsInterface<Even
|
|
|
248
285
|
*/
|
|
249
286
|
_processRemovalQueue(): void;
|
|
250
287
|
}
|
|
251
|
-
export declare function makeEmitter(obj:
|
|
252
|
-
export declare function makeEmitter(obj: boolean): Emitter
|
|
253
|
-
export declare function makeEmitter
|
|
288
|
+
export declare function makeEmitter<EventsInterface extends EmitterEventsWithStar<EventsInterface> = EmitterAnyEventsInterface>(obj: boolean): Emitter<EventsInterface>;
|
|
289
|
+
export declare function makeEmitter<EventsInterface extends EmitterEventsWithStar<EventsInterface> = EmitterAnyEventsInterface>(obj: Record<string, unknown>, prototypeMode: boolean): Emitter<EventsInterface>;
|
|
290
|
+
export declare function makeEmitter<EventsInterface extends EmitterEventsWithStar<EventsInterface> = EmitterAnyEventsInterface>(obj: AnyConstructor): Emitter<EventsInterface>;
|
package/dist/cjs/src/Emitter.js
CHANGED
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.Emitter = exports.ListenerReturnFlag = void 0;
|
|
4
|
+
exports.makeEmitter = makeEmitter;
|
|
4
5
|
var ListenerReturnFlag;
|
|
5
6
|
(function (ListenerReturnFlag) {
|
|
6
7
|
ListenerReturnFlag["none"] = "!+_NONE";
|
|
7
8
|
ListenerReturnFlag["cancel"] = "!+_CANCEL";
|
|
8
9
|
})(ListenerReturnFlag || (exports.ListenerReturnFlag = ListenerReturnFlag = {}));
|
|
9
10
|
/**
|
|
10
|
-
* Creates a new class with the
|
|
11
|
+
* Creates a new class with the ability to emit events.
|
|
11
12
|
*/
|
|
12
13
|
class Emitter {
|
|
13
|
-
constructor() {
|
|
14
|
+
constructor(dispatchPrefix, shouldDispatchWindowEvents = false) {
|
|
14
15
|
this._eventsEmitting = false;
|
|
15
16
|
this._eventRemovalQueue = [];
|
|
16
17
|
this._eventListeners = {};
|
|
17
18
|
this._eventStaticEmitters = {};
|
|
18
19
|
this._eventsAllowDefer = false;
|
|
19
20
|
this._eventsDeferTimeouts = {};
|
|
21
|
+
this._dispatchWindowEventsEnabled = false;
|
|
22
|
+
this._dispatchPrefix = dispatchPrefix;
|
|
23
|
+
this._dispatchWindowEventsEnabled = shouldDispatchWindowEvents;
|
|
24
|
+
}
|
|
25
|
+
dispatchWindowEventsEnabled(shouldDispatchWindowEvents) {
|
|
26
|
+
this._dispatchWindowEventsEnabled = shouldDispatchWindowEvents;
|
|
20
27
|
}
|
|
21
28
|
/**
|
|
22
29
|
* Attach an event listener to the passed event only if the passed
|
|
@@ -37,9 +44,7 @@ class Emitter {
|
|
|
37
44
|
nonNullableEventListeners[id] = nonNullableEventListeners[id] || [];
|
|
38
45
|
nonNullableEventListeners[id].push(listener);
|
|
39
46
|
// Check for any static emitters, and fire the event if any exist
|
|
40
|
-
if (!this._eventStaticEmitters ||
|
|
41
|
-
!this._eventStaticEmitters[eventName] ||
|
|
42
|
-
!this._eventStaticEmitters[eventName].length)
|
|
47
|
+
if (!this._eventStaticEmitters || !this._eventStaticEmitters[eventName] || !this._eventStaticEmitters[eventName].length)
|
|
43
48
|
return this;
|
|
44
49
|
// Emit events for each emitter
|
|
45
50
|
for (let i = 0; i < this._eventStaticEmitters[eventName].length; i++) {
|
|
@@ -115,6 +120,13 @@ class Emitter {
|
|
|
115
120
|
}
|
|
116
121
|
return this;
|
|
117
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Creates an event listener that listens for any and all events
|
|
125
|
+
* emitted.
|
|
126
|
+
*/
|
|
127
|
+
onAny(listener) {
|
|
128
|
+
this.on("*", listener);
|
|
129
|
+
}
|
|
118
130
|
on(eventName, idOrListener, listener) {
|
|
119
131
|
if (typeof idOrListener === "string") {
|
|
120
132
|
return this._on(eventName, idOrListener, listener);
|
|
@@ -137,6 +149,13 @@ class Emitter {
|
|
|
137
149
|
this.off(eventName, rest[0]);
|
|
138
150
|
return this._on(eventName, rest[0], rest[1]);
|
|
139
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Removes an event listener that listens for any and all events
|
|
154
|
+
* emitted.
|
|
155
|
+
*/
|
|
156
|
+
offAny(listener) {
|
|
157
|
+
this.off("*", listener);
|
|
158
|
+
}
|
|
140
159
|
off(eventName, ...rest) {
|
|
141
160
|
if (rest.length === 0) {
|
|
142
161
|
// Only event was provided, use * as the id to mean "any without"
|
|
@@ -173,6 +192,22 @@ class Emitter {
|
|
|
173
192
|
}
|
|
174
193
|
return resultArr;
|
|
175
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Dispatches an event originating in our emitter to the browser's
|
|
197
|
+
* window object.
|
|
198
|
+
* @param eventName The name of the event to emit. This gets prefixed with the
|
|
199
|
+
* dispatch prefix if one is set.
|
|
200
|
+
* @param data
|
|
201
|
+
*/
|
|
202
|
+
_emitToWindowDispatch(eventName, data) {
|
|
203
|
+
if (typeof window === "undefined")
|
|
204
|
+
return;
|
|
205
|
+
if (!this._dispatchWindowEventsEnabled) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const finalEventName = (this._dispatchPrefix ? `${this._dispatchPrefix}.${eventName}` : eventName);
|
|
209
|
+
window.dispatchEvent(new CustomEvent(finalEventName, { detail: data }));
|
|
210
|
+
}
|
|
176
211
|
/**
|
|
177
212
|
* Call an event listener by name. The `rpc()` function differs from `emit()` in
|
|
178
213
|
* that it will only call and return data from the first event listener for the
|
|
@@ -203,10 +238,10 @@ class Emitter {
|
|
|
203
238
|
*
|
|
204
239
|
* // Emit the event named "hello"
|
|
205
240
|
* const result = myEntity.emit('hello', 'data1', 'data2');
|
|
206
|
-
*
|
|
241
|
+
* console.log("Result:", result);
|
|
207
242
|
*
|
|
208
243
|
* // The console output is:
|
|
209
|
-
* //
|
|
244
|
+
* // Arguments: data1 data2
|
|
210
245
|
* // Result: "foo"
|
|
211
246
|
*/
|
|
212
247
|
rpc(eventName, ...data) {
|
|
@@ -224,7 +259,7 @@ class Emitter {
|
|
|
224
259
|
emitterResult = this._emitToSingleListener(arr[0], data);
|
|
225
260
|
}
|
|
226
261
|
else if (id !== "*" && this._eventListeners[eventName]["*"]) {
|
|
227
|
-
// Handle
|
|
262
|
+
// Handle wildcard emit if the id passed wasn't already a wildcard (*) id
|
|
228
263
|
const arr = this._eventListeners[eventName]["*"];
|
|
229
264
|
emitterResult = this._emitToSingleListener(arr[0], data);
|
|
230
265
|
}
|
|
@@ -244,7 +279,7 @@ class Emitter {
|
|
|
244
279
|
* @param {...any} data The arguments to send to any listening methods.
|
|
245
280
|
* If you are sending multiple arguments, separate them with a comma so
|
|
246
281
|
* that they are received by the function as separate arguments.
|
|
247
|
-
* @return {
|
|
282
|
+
* @return {any[]} An array of all return values from all the listeners for the event.
|
|
248
283
|
* @example #Emit an Event
|
|
249
284
|
* // Emit the event named "hello"
|
|
250
285
|
* myEntity.emit('hello');
|
|
@@ -257,7 +292,7 @@ class Emitter {
|
|
|
257
292
|
* @example #Listen for Event Data
|
|
258
293
|
* // Set a listener to listen for the data (multiple values emitted
|
|
259
294
|
* // from an event are passed as function arguments)
|
|
260
|
-
*
|
|
295
|
+
* myEntity.on('hello', function (arg1, arg2) {
|
|
261
296
|
* console.log("Arguments:", arg1, arg2);
|
|
262
297
|
* return "foo";
|
|
263
298
|
* }
|
|
@@ -266,39 +301,57 @@ class Emitter {
|
|
|
266
301
|
* // The result is returned as an array of all return values
|
|
267
302
|
* // from all the listeners for the event
|
|
268
303
|
* const result = myEntity.emit('hello', 'data1', 'data2');
|
|
269
|
-
*
|
|
304
|
+
* console.log("Result:", result);
|
|
270
305
|
*
|
|
271
306
|
* // The console output is:
|
|
272
|
-
* //
|
|
307
|
+
* // Arguments: data1 data2
|
|
273
308
|
* // Result: ["foo"]
|
|
274
309
|
*/
|
|
275
310
|
emit(eventName, ...data) {
|
|
311
|
+
this._emitToWindowDispatch(eventName, data);
|
|
276
312
|
return this.emitId(eventName, "*", ...data);
|
|
277
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* Emits an event by name and id.
|
|
316
|
+
* @param eventName The name of the event to emit.
|
|
317
|
+
* @param id The id of the event to emit.
|
|
318
|
+
* @param {...any} data The arguments to send to any listening methods.
|
|
319
|
+
* If you are sending multiple arguments, separate them with a comma so
|
|
320
|
+
* that they are received by the function as separate arguments.
|
|
321
|
+
* @return {any[]} An array of all return values from all the listeners for the event.
|
|
322
|
+
*/
|
|
278
323
|
emitId(eventName, id, ...data) {
|
|
279
|
-
if (!this._eventListeners || !this._eventListeners[eventName]) {
|
|
324
|
+
if (!this._eventListeners || (!this._eventListeners[eventName] && !this._eventListeners["*"])) {
|
|
280
325
|
return [];
|
|
281
326
|
}
|
|
282
327
|
let emitterResult = [];
|
|
283
328
|
this._eventsEmitting = true;
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
329
|
+
if (this._eventListeners[eventName]) {
|
|
330
|
+
// Handle id emit
|
|
331
|
+
if (this._eventListeners[eventName][id]) {
|
|
332
|
+
const arr = this._eventListeners[eventName][id];
|
|
333
|
+
emitterResult = emitterResult.concat(this._emitToArrayOfListeners(arr, data));
|
|
334
|
+
}
|
|
335
|
+
// Handle id wildcard emit if the id passed wasn't already a wildcard (*) id
|
|
336
|
+
if (id !== "*" && this._eventListeners[eventName]["*"]) {
|
|
337
|
+
const arr = this._eventListeners[eventName]["*"];
|
|
338
|
+
emitterResult = emitterResult.concat(this._emitToArrayOfListeners(arr, data));
|
|
339
|
+
}
|
|
288
340
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
emitterResult = emitterResult.concat(this._emitToArrayOfListeners(arr, data));
|
|
341
|
+
if (this._eventListeners["*"]) {
|
|
342
|
+
const arr = this._eventListeners["*"]["*"];
|
|
343
|
+
emitterResult = emitterResult.concat(this._emitToArrayOfListeners(arr, [eventName, ...data]));
|
|
293
344
|
}
|
|
294
345
|
this._eventsEmitting = false;
|
|
295
346
|
this._processRemovalQueue();
|
|
296
347
|
return emitterResult;
|
|
297
348
|
}
|
|
298
349
|
/**
|
|
299
|
-
* Creates a persistent
|
|
300
|
-
*
|
|
301
|
-
*
|
|
350
|
+
* Creates a persistent event. Once emitStatic() has been called, a
|
|
351
|
+
* persistent event is registered. Any existing event listeners will
|
|
352
|
+
* be called just like when you call emit(), however, any new
|
|
353
|
+
* listeners that are registered for this event via on() will also be
|
|
354
|
+
* called as soon as they are added.
|
|
302
355
|
* @param eventName The name of the event to emit.
|
|
303
356
|
* @param {...any} data Optional arguments to emit with the event.
|
|
304
357
|
* @returns The emitter instance.
|
|
@@ -309,7 +362,7 @@ class Emitter {
|
|
|
309
362
|
this._eventListeners = this._eventListeners || {};
|
|
310
363
|
this._eventsEmitting = true;
|
|
311
364
|
if (this._eventListeners[eventName] && this._eventListeners[eventName][id]) {
|
|
312
|
-
// Handle
|
|
365
|
+
// Handle id wildcard emit
|
|
313
366
|
const arr = this._eventListeners[eventName][id];
|
|
314
367
|
const arrCount = arr.length;
|
|
315
368
|
for (let arrIndex = 0; arrIndex < arrCount; arrIndex++) {
|
|
@@ -358,7 +411,7 @@ class Emitter {
|
|
|
358
411
|
}
|
|
359
412
|
}
|
|
360
413
|
}
|
|
361
|
-
// Handle
|
|
414
|
+
// Handle wildcard emit
|
|
362
415
|
if (this._eventListeners[eventName]["*"]) {
|
|
363
416
|
const arr = this._eventListeners[eventName]["*"];
|
|
364
417
|
const arrCount = arr.length;
|
|
@@ -437,7 +490,7 @@ class Emitter {
|
|
|
437
490
|
}
|
|
438
491
|
}
|
|
439
492
|
}
|
|
440
|
-
// Handle
|
|
493
|
+
// Handle wildcard emit
|
|
441
494
|
if (this._eventListeners[eventName]["*"]) {
|
|
442
495
|
const arr = this._eventListeners[eventName]["*"];
|
|
443
496
|
const arrCount = arr.length;
|
|
@@ -535,7 +588,9 @@ function makeEmitter(obj, prototypeMode) {
|
|
|
535
588
|
}
|
|
536
589
|
// Convert the object prototype to have eventing capability
|
|
537
590
|
operateOnObject.on = Emitter.prototype.on;
|
|
591
|
+
operateOnObject.onAny = Emitter.prototype.onAny;
|
|
538
592
|
operateOnObject.off = Emitter.prototype.off;
|
|
593
|
+
operateOnObject.offAny = Emitter.prototype.offAny;
|
|
539
594
|
operateOnObject.once = Emitter.prototype.once;
|
|
540
595
|
operateOnObject.emit = Emitter.prototype.emit;
|
|
541
596
|
operateOnObject.emitId = Emitter.prototype.emitId;
|
|
@@ -548,4 +603,3 @@ function makeEmitter(obj, prototypeMode) {
|
|
|
548
603
|
operateOnObject._processRemovalQueue = Emitter.prototype._processRemovalQueue;
|
|
549
604
|
return obj;
|
|
550
605
|
}
|
|
551
|
-
exports.makeEmitter = makeEmitter;
|
|
@@ -12,34 +12,36 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const globals_1 = require("@jest/globals");
|
|
15
16
|
const assert_1 = __importDefault(require("assert"));
|
|
16
17
|
const Emitter_1 = require("../src/Emitter");
|
|
17
18
|
let expectedAssertions = 0;
|
|
18
19
|
let actualAssertions = 0;
|
|
19
|
-
function
|
|
20
|
+
function expectAssertionCount(val) {
|
|
20
21
|
expectedAssertions = val;
|
|
21
22
|
}
|
|
22
|
-
function
|
|
23
|
+
function resetAssertionCount() {
|
|
23
24
|
expectedAssertions = 0;
|
|
24
25
|
actualAssertions = 0;
|
|
25
26
|
}
|
|
26
27
|
function countAssertion() {
|
|
27
28
|
actualAssertions++;
|
|
28
29
|
}
|
|
29
|
-
function
|
|
30
|
+
function checkAssertionCount() {
|
|
30
31
|
if (expectedAssertions === undefined || expectedAssertions === actualAssertions) {
|
|
31
32
|
return;
|
|
32
33
|
}
|
|
33
34
|
throw new Error("expected " + expectedAssertions + " assertions, got " + actualAssertions);
|
|
34
35
|
}
|
|
35
|
-
beforeEach(
|
|
36
|
-
afterEach(
|
|
36
|
+
beforeEach(resetAssertionCount);
|
|
37
|
+
afterEach(checkAssertionCount);
|
|
37
38
|
describe("Emitter", () => {
|
|
38
39
|
describe("new Emitter()", () => {
|
|
39
40
|
it("Creates emitter instance by instantiation", () => {
|
|
40
41
|
var _a, _b;
|
|
41
42
|
const myClass = new Emitter_1.Emitter();
|
|
42
|
-
myClass.on("moo", () => {
|
|
43
|
+
myClass.on("moo", () => {
|
|
44
|
+
});
|
|
43
45
|
assert_1.default.strictEqual((_a = myClass._eventListeners) === null || _a === void 0 ? void 0 : _a.moo["*"].length, 1, "Listener registered on event");
|
|
44
46
|
myClass.off("moo");
|
|
45
47
|
assert_1.default.strictEqual(!((_b = myClass._eventListeners) === null || _b === void 0 ? void 0 : _b.moo) ||
|
|
@@ -48,12 +50,8 @@ describe("Emitter", () => {
|
|
|
48
50
|
});
|
|
49
51
|
it("Supports extending Emitter as a base class", () => {
|
|
50
52
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
51
|
-
let testFuncCount = 0;
|
|
52
53
|
// Test extending Emitter and modifying base functionality
|
|
53
54
|
class MyClass extends Emitter_1.Emitter {
|
|
54
|
-
testFunc() {
|
|
55
|
-
testFuncCount++;
|
|
56
|
-
}
|
|
57
55
|
on(eventName, ...rest) {
|
|
58
56
|
const restTypes = rest.map((arg) => typeof arg);
|
|
59
57
|
if (restTypes[0] === "function") {
|
|
@@ -166,6 +164,7 @@ describe("Emitter", () => {
|
|
|
166
164
|
yield Promise.all(emitter.emit("foo"));
|
|
167
165
|
const delta = new Date().getTime() - time;
|
|
168
166
|
assert_1.default.ok(delta > 900, "Delta was not correct, await may not have paused?");
|
|
167
|
+
assert_1.default.strictEqual(listenerFiredCount, 2, "Listener fire count was incorect");
|
|
169
168
|
}));
|
|
170
169
|
it("Supports awaiting async and non-async listener return data", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
171
170
|
const emitter = new Emitter_1.Emitter();
|
|
@@ -243,11 +242,15 @@ describe("Emitter", () => {
|
|
|
243
242
|
it("Cancels all listeners (event)", () => {
|
|
244
243
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
245
244
|
const myClass = new Emitter_1.Emitter();
|
|
246
|
-
const listener1 = () => {
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
const listener1 = () => {
|
|
246
|
+
};
|
|
247
|
+
const listener2 = () => {
|
|
248
|
+
};
|
|
249
|
+
myClass.on("moo", () => {
|
|
250
|
+
});
|
|
249
251
|
assert_1.default.strictEqual((_a = myClass._eventListeners) === null || _a === void 0 ? void 0 : _a.moo["*"].length, 1, "Listeners registered on event");
|
|
250
|
-
myClass.on("moo", "testId", () => {
|
|
252
|
+
myClass.on("moo", "testId", () => {
|
|
253
|
+
});
|
|
251
254
|
assert_1.default.strictEqual((_b = myClass._eventListeners) === null || _b === void 0 ? void 0 : _b.moo["testId"].length, 1, "Listeners registered on event");
|
|
252
255
|
myClass.on("moo", listener1);
|
|
253
256
|
assert_1.default.strictEqual((_c = myClass._eventListeners) === null || _c === void 0 ? void 0 : _c.moo["*"].length, 2, "Listeners registered on event");
|
|
@@ -261,11 +264,15 @@ describe("Emitter", () => {
|
|
|
261
264
|
it("Cancels id-based listeners (event, id)", () => {
|
|
262
265
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
263
266
|
const myClass = new Emitter_1.Emitter();
|
|
264
|
-
const listener1 = () => {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
+
const listener1 = () => {
|
|
268
|
+
};
|
|
269
|
+
const listener2 = () => {
|
|
270
|
+
};
|
|
271
|
+
myClass.on("moo", () => {
|
|
272
|
+
});
|
|
267
273
|
assert_1.default.strictEqual((_a = myClass._eventListeners) === null || _a === void 0 ? void 0 : _a.moo["*"].length, 1, "Listeners registered on event");
|
|
268
|
-
myClass.on("moo", "testId", () => {
|
|
274
|
+
myClass.on("moo", "testId", () => {
|
|
275
|
+
});
|
|
269
276
|
assert_1.default.strictEqual((_b = myClass._eventListeners) === null || _b === void 0 ? void 0 : _b.moo["testId"].length, 1, "Listeners registered on event");
|
|
270
277
|
myClass.on("moo", listener1);
|
|
271
278
|
assert_1.default.strictEqual((_c = myClass._eventListeners) === null || _c === void 0 ? void 0 : _c.moo["*"].length, 2, "Listeners registered on event");
|
|
@@ -278,11 +285,15 @@ describe("Emitter", () => {
|
|
|
278
285
|
it("Cancels listener-based listeners (event, listener)", () => {
|
|
279
286
|
var _a, _b, _c, _d, _e, _f;
|
|
280
287
|
const myClass = new Emitter_1.Emitter();
|
|
281
|
-
const listener1 = () => {
|
|
282
|
-
|
|
283
|
-
|
|
288
|
+
const listener1 = () => {
|
|
289
|
+
};
|
|
290
|
+
const listener2 = () => {
|
|
291
|
+
};
|
|
292
|
+
myClass.on("moo", () => {
|
|
293
|
+
});
|
|
284
294
|
assert_1.default.strictEqual((_a = myClass._eventListeners) === null || _a === void 0 ? void 0 : _a.moo["*"].length, 1, "Listeners registered on event");
|
|
285
|
-
myClass.on("moo", "testId", () => {
|
|
295
|
+
myClass.on("moo", "testId", () => {
|
|
296
|
+
});
|
|
286
297
|
assert_1.default.strictEqual((_b = myClass._eventListeners) === null || _b === void 0 ? void 0 : _b.moo["testId"].length, 1, "Listeners registered on event");
|
|
287
298
|
myClass.on("moo", listener1);
|
|
288
299
|
assert_1.default.strictEqual((_c = myClass._eventListeners) === null || _c === void 0 ? void 0 : _c.moo["*"].length, 2, "Listeners registered on event");
|
|
@@ -295,11 +306,15 @@ describe("Emitter", () => {
|
|
|
295
306
|
it("Cancels id-based + listener-based listeners (event, id, listener)", () => {
|
|
296
307
|
var _a, _b, _c, _d, _e, _f;
|
|
297
308
|
const myClass = new Emitter_1.Emitter();
|
|
298
|
-
const listener1 = () => {
|
|
299
|
-
|
|
300
|
-
|
|
309
|
+
const listener1 = () => {
|
|
310
|
+
};
|
|
311
|
+
const listener2 = () => {
|
|
312
|
+
};
|
|
313
|
+
myClass.on("moo", () => {
|
|
314
|
+
});
|
|
301
315
|
assert_1.default.strictEqual((_a = myClass._eventListeners) === null || _a === void 0 ? void 0 : _a.moo["*"].length, 1, "Listeners registered on event");
|
|
302
|
-
myClass.on("moo", "testId", () => {
|
|
316
|
+
myClass.on("moo", "testId", () => {
|
|
317
|
+
});
|
|
303
318
|
assert_1.default.strictEqual((_b = myClass._eventListeners) === null || _b === void 0 ? void 0 : _b.moo["testId"].length, 1, "Listeners registered on event");
|
|
304
319
|
myClass.on("moo", listener1);
|
|
305
320
|
assert_1.default.strictEqual((_c = myClass._eventListeners) === null || _c === void 0 ? void 0 : _c.moo["*"].length, 2, "Listeners registered on event");
|
|
@@ -314,7 +329,7 @@ describe("Emitter", () => {
|
|
|
314
329
|
it("Static emitter will emit when a new listener is added", (resolve) => {
|
|
315
330
|
class MyClass extends Emitter_1.Emitter {
|
|
316
331
|
}
|
|
317
|
-
|
|
332
|
+
expectAssertionCount(1);
|
|
318
333
|
const myClass = new MyClass();
|
|
319
334
|
myClass.emitStatic("moo");
|
|
320
335
|
myClass.on("moo", () => {
|
|
@@ -328,7 +343,7 @@ describe("Emitter", () => {
|
|
|
328
343
|
it("Removes static emitter", (resolve) => {
|
|
329
344
|
class MyClass extends Emitter_1.Emitter {
|
|
330
345
|
}
|
|
331
|
-
|
|
346
|
+
expectAssertionCount(1);
|
|
332
347
|
const myClass = new MyClass();
|
|
333
348
|
myClass.emitStatic("moo");
|
|
334
349
|
myClass.on("moo", () => {
|
|
@@ -349,7 +364,7 @@ describe("Emitter", () => {
|
|
|
349
364
|
it("Only fires the last listener added, cancelling all other listeners before it", (resolve) => {
|
|
350
365
|
class MyClass extends Emitter_1.Emitter {
|
|
351
366
|
}
|
|
352
|
-
|
|
367
|
+
expectAssertionCount(1);
|
|
353
368
|
const myClass = new MyClass();
|
|
354
369
|
myClass.on("moo", () => {
|
|
355
370
|
countAssertion();
|
|
@@ -371,7 +386,7 @@ describe("Emitter", () => {
|
|
|
371
386
|
it("Only fires the last listener added (with id), cancelling all other listeners before it", (resolve) => {
|
|
372
387
|
class MyClass extends Emitter_1.Emitter {
|
|
373
388
|
}
|
|
374
|
-
|
|
389
|
+
expectAssertionCount(2);
|
|
375
390
|
const myClass = new MyClass();
|
|
376
391
|
// Define a listener without an id, this should not be overwritten
|
|
377
392
|
myClass.on("moo", () => {
|
|
@@ -427,4 +442,36 @@ describe("Emitter", () => {
|
|
|
427
442
|
((_k = myClass._eventListeners) === null || _k === void 0 ? void 0 : _k.moo["*"].length) === 0, true, "Listeners all removed from event");
|
|
428
443
|
});
|
|
429
444
|
});
|
|
445
|
+
describe("Global listener functionality", () => {
|
|
446
|
+
it("Listens for any event emitted and fires the listener with the onAny() function", () => {
|
|
447
|
+
const emitter = new Emitter_1.Emitter();
|
|
448
|
+
const spy = globals_1.jest.fn();
|
|
449
|
+
emitter.onAny(spy);
|
|
450
|
+
emitter.emit("someEvent", "someArg1", true, false);
|
|
451
|
+
expect(spy).toHaveBeenCalledWith("someEvent", "someArg1", true, false);
|
|
452
|
+
});
|
|
453
|
+
it(`Listens for any event emitted and fires the listener with the on("*") function`, () => {
|
|
454
|
+
const emitter = new Emitter_1.Emitter();
|
|
455
|
+
const spy = globals_1.jest.fn();
|
|
456
|
+
emitter.on("*", spy);
|
|
457
|
+
emitter.emit("someEvent", "someArg1", true, false);
|
|
458
|
+
expect(spy).toHaveBeenCalledWith("someEvent", "someArg1", true, false);
|
|
459
|
+
});
|
|
460
|
+
it(`Cancels an event listener for any event emitted with the offAny() function`, () => {
|
|
461
|
+
const emitter = new Emitter_1.Emitter();
|
|
462
|
+
const spy = globals_1.jest.fn();
|
|
463
|
+
emitter.on("*", spy);
|
|
464
|
+
emitter.offAny(spy);
|
|
465
|
+
emitter.emit("someEvent", "someArg1", true, false);
|
|
466
|
+
expect(spy).toHaveBeenCalledTimes(0);
|
|
467
|
+
});
|
|
468
|
+
it(`Cancels an event listener for any event emitted with the off("*") function`, () => {
|
|
469
|
+
const emitter = new Emitter_1.Emitter();
|
|
470
|
+
const spy = globals_1.jest.fn();
|
|
471
|
+
emitter.on("*", spy);
|
|
472
|
+
emitter.off("*", spy);
|
|
473
|
+
emitter.emit("someEvent", "someArg1", true, false);
|
|
474
|
+
expect(spy).toHaveBeenCalledTimes(0);
|
|
475
|
+
});
|
|
476
|
+
});
|
|
430
477
|
});
|