@irrelon/emitter 6.1.0 → 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 +8 -0
- package/dist/cjs/src/Emitter.d.ts +35 -13
- package/dist/cjs/src/Emitter.js +44 -12
- package/dist/cjs/tests/Emitter.test.js +34 -17
- package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/esm/src/Emitter.d.ts +35 -13
- package/dist/esm/src/Emitter.js +46 -11
- package/dist/esm/tests/Emitter.test.js +34 -17
- 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/package.json +59 -57
- package/readme.md +10 -1
- package/src/Emitter.d.ts +290 -0
- package/src/Emitter.js +600 -0
- package/src/Emitter.ts +307 -329
- package/tests/Emitter.test.d.ts +1 -0
- package/tests/Emitter.test.js +472 -0
- package/tests/Emitter.test.ts +241 -210
- 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/src/Emitter.ts
CHANGED
|
@@ -25,9 +25,31 @@
|
|
|
25
25
|
Source: https://github.com/irrelon/emitter
|
|
26
26
|
|
|
27
27
|
Changelog:
|
|
28
|
-
Version 6.
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
Version 6.2.0:
|
|
29
|
+
Added ability to emit events via both our emitter and via
|
|
30
|
+
`window.dispatchEvent()` so that applications that don't have
|
|
31
|
+
access to an event emitter instance can still listen for events
|
|
32
|
+
when emitted by our emitter. This option can be switched on or
|
|
33
|
+
off via the `dispatchWindowEventsEnabled()` function. The default
|
|
34
|
+
is `false` (off).
|
|
35
|
+
|
|
36
|
+
Added the ability to set a prefix to events which are emitted
|
|
37
|
+
via the window.dispatchEvent() method. For example, if you set
|
|
38
|
+
the prefix to "myCompany.myApp.myEmitterName" then emit an event
|
|
39
|
+
via emit() called "myEvent", the dispatched event name on the
|
|
40
|
+
window object will be "myCompany.myApp.myEmitterName.myEvent".
|
|
41
|
+
Event names using standard Emitter functions are unaffected.
|
|
42
|
+
For instance, you would still listen for `myEvent` via
|
|
43
|
+
`emitter.on("myEvent", ...)` and emit it via
|
|
44
|
+
`emitter.emit("myEvent", ...)`.
|
|
45
|
+
Version 6.1.0:
|
|
46
|
+
Added `onAny()` and `offAny()` methods which are analogous to
|
|
47
|
+
`on("*")` and `off("*")`.
|
|
48
|
+
Version 6.0.0:
|
|
49
|
+
Updated to allow event listeners to return data to the caller of
|
|
50
|
+
the emit() function, e.g.
|
|
51
|
+
|
|
52
|
+
`const results = emitter.emit("myEventName");`
|
|
31
53
|
|
|
32
54
|
The results are an array of all return values from any listener
|
|
33
55
|
functions that were called by the event "myEventName". This is
|
|
@@ -37,9 +59,10 @@
|
|
|
37
59
|
Listeners that return `ListenerReturnFlag.cancel` will cancel
|
|
38
60
|
the event call to any further listeners for that one event
|
|
39
61
|
emit.
|
|
40
|
-
Version 5.0.3 and 5.0.4:
|
|
41
|
-
to
|
|
42
|
-
listeners and emitting
|
|
62
|
+
Version 5.0.3 and 5.0.4:
|
|
63
|
+
Updated to allow specifying an events type to the Emitter to
|
|
64
|
+
allow complete type safety when registering listeners and emitting
|
|
65
|
+
events.
|
|
43
66
|
|
|
44
67
|
Updated the build and package to split between delivery of CJS
|
|
45
68
|
and ESM module types so that this package can be eiter imported
|
|
@@ -99,7 +122,7 @@
|
|
|
99
122
|
Version 1.0.1:
|
|
100
123
|
Added ability to extend any object with eventing capability
|
|
101
124
|
Added AMD / Require.js support
|
|
102
|
-
|
|
125
|
+
Added Node.js support
|
|
103
126
|
Version 1.0.0:
|
|
104
127
|
First commit
|
|
105
128
|
*/
|
|
@@ -107,61 +130,66 @@ export type AnyFunction<ReturnType = any> = (...args: any[]) => ReturnType;
|
|
|
107
130
|
export type AnyConstructor = new (...args: any[]) => any;
|
|
108
131
|
|
|
109
132
|
export enum ListenerReturnFlag {
|
|
110
|
-
|
|
111
|
-
|
|
133
|
+
none = "!+_NONE",
|
|
134
|
+
cancel = "!+_CANCEL"
|
|
112
135
|
}
|
|
113
136
|
|
|
114
|
-
export type EventListenerCallback<EventCallbackFunctionSignature extends AnyFunction = AnyFunction> = (
|
|
115
|
-
...args: Parameters<EventCallbackFunctionSignature>
|
|
116
|
-
) => ReturnType<EventCallbackFunctionSignature>;
|
|
137
|
+
export type EventListenerCallback<EventCallbackFunctionSignature extends AnyFunction = AnyFunction> = (...args: Parameters<EventCallbackFunctionSignature>) => ReturnType<EventCallbackFunctionSignature>;
|
|
117
138
|
|
|
118
139
|
export interface EventStaticEmitterObject<EventCallbackFunctionSignature extends AnyFunction = AnyFunction> {
|
|
119
|
-
|
|
120
|
-
|
|
140
|
+
id: string;
|
|
141
|
+
args: Parameters<EventCallbackFunctionSignature>;
|
|
121
142
|
}
|
|
122
143
|
|
|
123
144
|
export interface EmitterAnyEventsInterface {
|
|
124
|
-
|
|
145
|
+
[key: string]: AnyFunction;
|
|
125
146
|
}
|
|
126
147
|
|
|
127
148
|
export type EmitterEventsInterface<T> = {
|
|
128
|
-
|
|
149
|
+
[K in keyof T]: T[K];
|
|
129
150
|
};
|
|
130
151
|
|
|
131
|
-
interface WithStar {
|
|
132
|
-
|
|
152
|
+
export interface WithStar {
|
|
153
|
+
"*"?: (eventName: string, ...args: any[]) => void;
|
|
133
154
|
}
|
|
134
155
|
|
|
135
156
|
export type EmitterEventsWithStar<T> = EmitterEventsInterface<T> & WithStar;
|
|
136
157
|
|
|
137
158
|
/**
|
|
138
|
-
* Creates a new class with the
|
|
159
|
+
* Creates a new class with the ability to emit events.
|
|
139
160
|
*/
|
|
140
161
|
export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterface> = EmitterAnyEventsInterface> {
|
|
141
162
|
_eventsEmitting: boolean = false;
|
|
142
163
|
_eventRemovalQueue: any[] = [];
|
|
143
164
|
_eventListeners?: {
|
|
144
|
-
|
|
145
|
-
|
|
165
|
+
[EventName in keyof EventsInterface]?: Record<string, EventListenerCallback<EventsInterface[EventName]>[]>;
|
|
166
|
+
} = {};
|
|
146
167
|
_eventStaticEmitters: {
|
|
147
|
-
|
|
148
|
-
|
|
168
|
+
[EventName in keyof EventsInterface]?: EventStaticEmitterObject<EventsInterface[EventName]>[];
|
|
169
|
+
} = {};
|
|
149
170
|
_eventsAllowDefer: boolean = false;
|
|
150
171
|
_eventsDeferTimeouts: Record<any, number> = {};
|
|
172
|
+
_dispatchWindowEventsEnabled: boolean = false;
|
|
173
|
+
_dispatchPrefix?: string;
|
|
174
|
+
|
|
175
|
+
constructor (dispatchPrefix?: string, shouldDispatchWindowEvents: boolean = false) {
|
|
176
|
+
this._dispatchPrefix = dispatchPrefix;
|
|
177
|
+
this._dispatchWindowEventsEnabled = shouldDispatchWindowEvents;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
dispatchWindowEventsEnabled (shouldDispatchWindowEvents: boolean) {
|
|
181
|
+
this._dispatchWindowEventsEnabled = shouldDispatchWindowEvents;
|
|
182
|
+
}
|
|
151
183
|
|
|
152
184
|
/**
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
_on<EventName extends keyof EventsInterface> (
|
|
161
|
-
eventName: EventName,
|
|
162
|
-
id: string,
|
|
163
|
-
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
164
|
-
) {
|
|
185
|
+
* Attach an event listener to the passed event only if the passed
|
|
186
|
+
* id matches the id for the event being fired.
|
|
187
|
+
* @param eventName The name of the event to listen for.
|
|
188
|
+
* @param id The id to match against.
|
|
189
|
+
* @param listener The method to call when the event is fired.
|
|
190
|
+
* @returns The emitter instance.
|
|
191
|
+
*/
|
|
192
|
+
_on<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener: EventListenerCallback<EventsInterface[EventName]>) {
|
|
165
193
|
const generateTimeout = (emitter: EventStaticEmitterObject<EventsInterface[EventName]>) => {
|
|
166
194
|
setTimeout(() => {
|
|
167
195
|
listener(...emitter.args);
|
|
@@ -174,12 +202,7 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
174
202
|
nonNullableEventListeners[id].push(listener);
|
|
175
203
|
|
|
176
204
|
// Check for any static emitters, and fire the event if any exist
|
|
177
|
-
if (
|
|
178
|
-
!this._eventStaticEmitters ||
|
|
179
|
-
!this._eventStaticEmitters[eventName] ||
|
|
180
|
-
!this._eventStaticEmitters[eventName]!.length
|
|
181
|
-
)
|
|
182
|
-
return this;
|
|
205
|
+
if (!this._eventStaticEmitters || !this._eventStaticEmitters[eventName] || !this._eventStaticEmitters[eventName]!.length) return this;
|
|
183
206
|
|
|
184
207
|
// Emit events for each emitter
|
|
185
208
|
for (let i = 0; i < this._eventStaticEmitters[eventName]!.length; i++) {
|
|
@@ -197,24 +220,18 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
197
220
|
}
|
|
198
221
|
|
|
199
222
|
/**
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
_once<EventName extends keyof EventsInterface> (
|
|
208
|
-
eventName: EventName,
|
|
209
|
-
id: string,
|
|
210
|
-
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
211
|
-
) {
|
|
223
|
+
* Attach an event listener to the passed event only if the passed
|
|
224
|
+
* id matches the document id for the event being fired.
|
|
225
|
+
* @param eventName The name of the event to listen for.
|
|
226
|
+
* @param id The id to match against.
|
|
227
|
+
* @param listener The method to call when the event is fired.
|
|
228
|
+
* @returns The emitter instance.
|
|
229
|
+
*/
|
|
230
|
+
_once<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener: EventListenerCallback<EventsInterface[EventName]>) {
|
|
212
231
|
let fired = false;
|
|
213
232
|
let originalReturnData: ReturnType<EventsInterface[EventName]>;
|
|
214
233
|
|
|
215
|
-
const internalCallback: EventListenerCallback<EventsInterface[EventName]> = (
|
|
216
|
-
...args: Parameters<EventsInterface[EventName]>
|
|
217
|
-
): ReturnType<EventsInterface[EventName]> => {
|
|
234
|
+
const internalCallback: EventListenerCallback<EventsInterface[EventName]> = (...args: Parameters<EventsInterface[EventName]>): ReturnType<EventsInterface[EventName]> => {
|
|
218
235
|
if (fired) return originalReturnData;
|
|
219
236
|
|
|
220
237
|
fired = true;
|
|
@@ -228,21 +245,16 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
228
245
|
}
|
|
229
246
|
|
|
230
247
|
/**
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
_off<EventName extends keyof EventsInterface> (
|
|
239
|
-
eventName: EventName,
|
|
240
|
-
id: string,
|
|
241
|
-
listener?: EventListenerCallback<EventsInterface[EventName]>
|
|
242
|
-
): this {
|
|
248
|
+
* Cancels an event listener based on an event name, id and listener function.
|
|
249
|
+
* @param eventName The event to cancel listener for.
|
|
250
|
+
* @param id The ID of the event to cancel listening for.
|
|
251
|
+
* @param listener The event listener function used in the on()
|
|
252
|
+
* or once() call to cancel.
|
|
253
|
+
* @returns The emitter instance.
|
|
254
|
+
*/
|
|
255
|
+
_off<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener?: EventListenerCallback<EventsInterface[EventName]>): this {
|
|
243
256
|
// If the event name doesn't have any listeners, exit early
|
|
244
|
-
if (!this._eventListeners || !this._eventListeners[eventName] || !this._eventListeners[eventName]![id])
|
|
245
|
-
return this;
|
|
257
|
+
if (!this._eventListeners || !this._eventListeners[eventName] || !this._eventListeners[eventName]![id]) return this;
|
|
246
258
|
|
|
247
259
|
// If we are emitting events at the moment, don't remove this listener
|
|
248
260
|
// until the process has completed, so we queue for removal instead
|
|
@@ -281,35 +293,24 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
281
293
|
}
|
|
282
294
|
|
|
283
295
|
/**
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
296
|
+
* Creates an event listener that listens for any and all events
|
|
297
|
+
* emitted.
|
|
298
|
+
*/
|
|
287
299
|
onAny (listener: EventListenerCallback) {
|
|
288
300
|
this.on("*", listener);
|
|
289
301
|
}
|
|
290
302
|
|
|
291
303
|
/**
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
on<EventName extends keyof EventsInterface>(
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
303
|
-
): this;
|
|
304
|
-
on<EventName extends keyof EventsInterface>(
|
|
305
|
-
eventName: EventName,
|
|
306
|
-
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
307
|
-
): this;
|
|
308
|
-
on<EventName extends keyof EventsInterface> (
|
|
309
|
-
eventName: EventName,
|
|
310
|
-
idOrListener: string | EventListenerCallback<EventsInterface[EventName]>,
|
|
311
|
-
listener?: EventListenerCallback<EventsInterface[EventName]>
|
|
312
|
-
): this {
|
|
304
|
+
* Attach an event listener to the passed event only if the passed
|
|
305
|
+
* id matches the document id for the event being fired.
|
|
306
|
+
* @param eventName The name of the event to listen for.
|
|
307
|
+
* @param id The id to match against.
|
|
308
|
+
* @param listener The method to call when the event is fired.
|
|
309
|
+
* @returns The emitter instance.
|
|
310
|
+
*/
|
|
311
|
+
on<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener: EventListenerCallback<EventsInterface[EventName]>): this;
|
|
312
|
+
on<EventName extends keyof EventsInterface> (eventName: EventName, listener: EventListenerCallback<EventsInterface[EventName]>): this;
|
|
313
|
+
on<EventName extends keyof EventsInterface> (eventName: EventName, idOrListener: string | EventListenerCallback<EventsInterface[EventName]>, listener?: EventListenerCallback<EventsInterface[EventName]>): this {
|
|
313
314
|
if (typeof idOrListener === "string") {
|
|
314
315
|
return this._on(eventName, idOrListener, listener as EventListenerCallback<EventsInterface[EventName]>);
|
|
315
316
|
}
|
|
@@ -318,22 +319,15 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
318
319
|
}
|
|
319
320
|
|
|
320
321
|
/**
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
once<EventName extends keyof EventsInterface>(
|
|
329
|
-
|
|
330
|
-
id: string,
|
|
331
|
-
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
332
|
-
): this;
|
|
333
|
-
once<EventName extends keyof EventsInterface>(
|
|
334
|
-
eventName: EventName,
|
|
335
|
-
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
336
|
-
): this;
|
|
322
|
+
* Attach an event listener to the passed event only if the passed
|
|
323
|
+
* id matches the document id for the event being fired.
|
|
324
|
+
* @param eventName The name of the event to listen for.
|
|
325
|
+
* @param id The id to match against.
|
|
326
|
+
* @param listener
|
|
327
|
+
* @returns The emitter instance.
|
|
328
|
+
*/
|
|
329
|
+
once<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener: EventListenerCallback<EventsInterface[EventName]>): this;
|
|
330
|
+
once<EventName extends keyof EventsInterface> (eventName: EventName, listener: EventListenerCallback<EventsInterface[EventName]>): this;
|
|
337
331
|
once<EventName extends keyof EventsInterface> (eventName: EventName, ...rest: any[]): this {
|
|
338
332
|
const restTypes = rest.map((arg) => typeof arg);
|
|
339
333
|
|
|
@@ -345,26 +339,19 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
345
339
|
}
|
|
346
340
|
|
|
347
341
|
/**
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
overwrite<EventName extends keyof EventsInterface>(
|
|
360
|
-
|
|
361
|
-
id: string,
|
|
362
|
-
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
363
|
-
): this;
|
|
364
|
-
overwrite<EventName extends keyof EventsInterface>(
|
|
365
|
-
eventName: EventName,
|
|
366
|
-
listener: EventListenerCallback<EventsInterface[EventName]>
|
|
367
|
-
): this;
|
|
342
|
+
* Overwrites any previous event listeners so that if the event fires, only
|
|
343
|
+
* the listener you pass will be called. If you pass an id along with the
|
|
344
|
+
* listener, only listeners for the id will be overwritten. This is similar
|
|
345
|
+
* to calling `.off(eventName)` then `on(eventName, listener)` since
|
|
346
|
+
* `off(eventName)` will cancel any previous event listeners for the passed
|
|
347
|
+
* event name.
|
|
348
|
+
* @param eventName The name of the event to listen for.
|
|
349
|
+
* @param id The id to match against.
|
|
350
|
+
* @param listener The method to call when the event is fired.
|
|
351
|
+
* @returns The emitter instance.
|
|
352
|
+
*/
|
|
353
|
+
overwrite<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener: EventListenerCallback<EventsInterface[EventName]>): this;
|
|
354
|
+
overwrite<EventName extends keyof EventsInterface> (eventName: EventName, listener: EventListenerCallback<EventsInterface[EventName]>): this;
|
|
368
355
|
overwrite<EventName extends keyof EventsInterface> (eventName: EventName, ...rest: any[]) {
|
|
369
356
|
const restTypes = rest.map((arg) => typeof arg);
|
|
370
357
|
|
|
@@ -378,31 +365,24 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
378
365
|
}
|
|
379
366
|
|
|
380
367
|
/**
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
368
|
+
* Removes an event listener that listens for any and all events
|
|
369
|
+
* emitted.
|
|
370
|
+
*/
|
|
384
371
|
offAny (listener: EventListenerCallback) {
|
|
385
372
|
this.off("*", listener);
|
|
386
373
|
}
|
|
387
374
|
|
|
388
375
|
/**
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
off<EventName extends keyof EventsInterface>(
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
listener?: EventListenerCallback<EventsInterface[EventName]>
|
|
400
|
-
): this;
|
|
401
|
-
off<EventName extends keyof EventsInterface>(
|
|
402
|
-
eventName: EventName,
|
|
403
|
-
listener?: EventListenerCallback<EventsInterface[EventName]>
|
|
404
|
-
): this;
|
|
405
|
-
off<EventName extends keyof EventsInterface>(eventName: EventName): this;
|
|
376
|
+
* Cancels an event listener based on an event name, id and listener function.
|
|
377
|
+
* @param eventName The event to cancel listener for.
|
|
378
|
+
* @param id The ID of the event to cancel listening for.
|
|
379
|
+
* @param listener The event listener function used in the on()
|
|
380
|
+
* or once() call to cancel.
|
|
381
|
+
* @returns The emitter instance.
|
|
382
|
+
*/
|
|
383
|
+
off<EventName extends keyof EventsInterface> (eventName: EventName, id: string, listener?: EventListenerCallback<EventsInterface[EventName]>): this;
|
|
384
|
+
off<EventName extends keyof EventsInterface> (eventName: EventName, listener?: EventListenerCallback<EventsInterface[EventName]>): this;
|
|
385
|
+
off<EventName extends keyof EventsInterface> (eventName: EventName): this;
|
|
406
386
|
off<EventName extends keyof EventsInterface> (eventName: EventName, ...rest: any[]) {
|
|
407
387
|
if (rest.length === 0) {
|
|
408
388
|
// Only event was provided, use * as the id to mean "any without"
|
|
@@ -457,53 +437,63 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
457
437
|
}
|
|
458
438
|
|
|
459
439
|
/**
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
440
|
+
* Dispatches an event originating in our emitter to the browser's
|
|
441
|
+
* window object.
|
|
442
|
+
* @param eventName The name of the event to emit. This gets prefixed with the
|
|
443
|
+
* dispatch prefix if one is set.
|
|
444
|
+
* @param data
|
|
445
|
+
*/
|
|
446
|
+
_emitToWindowDispatch<EventName extends keyof EventsInterface> (eventName: EventName, data: any) {
|
|
447
|
+
if (typeof window === "undefined") return;
|
|
448
|
+
if (!this._dispatchWindowEventsEnabled) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
const finalEventName = (this._dispatchPrefix ? `${this._dispatchPrefix}.${eventName as string}` : eventName) as string;
|
|
453
|
+
window.dispatchEvent(new CustomEvent(finalEventName, { detail: data }));
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Call an event listener by name. The `rpc()` function differs from `emit()` in
|
|
458
|
+
* that it will only call and return data from the first event listener for the
|
|
459
|
+
* event rather than all event listeners. If you have more than one event listener
|
|
460
|
+
* assigned to the event, all others except the first will be ignored and will
|
|
461
|
+
* not receive the event.
|
|
462
|
+
* @param eventName The name of the event to call the listener for.
|
|
463
|
+
* @param {...any} data The arguments to send to the listening method.
|
|
464
|
+
* If you are sending multiple arguments, separate them with a comma so
|
|
465
|
+
* that they are received by the function as separate arguments.
|
|
466
|
+
* @return {number}
|
|
467
|
+
* @example #Call the Event Listener
|
|
468
|
+
* // Emit the event named "hello"
|
|
469
|
+
* myEntity.emit('hello');
|
|
470
|
+
* @example #Call the Event Listener With Data Object
|
|
471
|
+
* // Emit the event named "hello"
|
|
472
|
+
* myEntity.emit('hello', {moo: true});
|
|
473
|
+
* @example #Call the Event Listener With Multiple Data Values
|
|
474
|
+
* // Emit the event named "hello"
|
|
475
|
+
* myEntity.emit('hello', {moo: true}, 'someString');
|
|
476
|
+
* @example #Register the Listener for Event Data
|
|
477
|
+
* // Set a listener to listen for the data (multiple values emitted
|
|
478
|
+
* // from an event are passed as function arguments)
|
|
479
|
+
* myEntity.on('hello', function (arg1, arg2) {
|
|
480
|
+
* console.log("Arguments:", arg1, arg2);
|
|
481
|
+
* return "foo";
|
|
482
|
+
* }
|
|
483
|
+
*
|
|
484
|
+
* // Emit the event named "hello"
|
|
485
|
+
* const result = myEntity.emit('hello', 'data1', 'data2');
|
|
486
|
+
* console.log("Result:", result);
|
|
487
|
+
*
|
|
488
|
+
* // The console output is:
|
|
489
|
+
* // Arguments: data1 data2
|
|
490
|
+
* // Result: "foo"
|
|
491
|
+
*/
|
|
492
|
+
rpc<EventName extends keyof EventsInterface> (eventName: EventName, ...data: Parameters<EventsInterface[EventName]>): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag {
|
|
499
493
|
return this.rpcId<EventName>(eventName, "*", ...data);
|
|
500
494
|
}
|
|
501
495
|
|
|
502
|
-
rpcId<EventName extends keyof EventsInterface> (
|
|
503
|
-
eventName: EventName,
|
|
504
|
-
id: string,
|
|
505
|
-
...data: Parameters<EventsInterface[EventName]>
|
|
506
|
-
): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag {
|
|
496
|
+
rpcId<EventName extends keyof EventsInterface> (eventName: EventName, id: string, ...data: Parameters<EventsInterface[EventName]>): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag {
|
|
507
497
|
if (!this._eventListeners || !this._eventListeners[eventName]) {
|
|
508
498
|
throw new Error("Cannot make an rpc call without at least one event listener and none were found");
|
|
509
499
|
}
|
|
@@ -538,51 +528,54 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
538
528
|
}
|
|
539
529
|
|
|
540
530
|
/**
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
emit<EventName extends keyof EventsInterface> (
|
|
575
|
-
eventName
|
|
576
|
-
...data: Parameters<EventsInterface[EventName]>
|
|
577
|
-
): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[] {
|
|
531
|
+
* Emit an event by name.
|
|
532
|
+
* @param eventName The name of the event to emit.
|
|
533
|
+
* @param {...any} data The arguments to send to any listening methods.
|
|
534
|
+
* If you are sending multiple arguments, separate them with a comma so
|
|
535
|
+
* that they are received by the function as separate arguments.
|
|
536
|
+
* @return {any[]} An array of all return values from all the listeners for the event.
|
|
537
|
+
* @example #Emit an Event
|
|
538
|
+
* // Emit the event named "hello"
|
|
539
|
+
* myEntity.emit('hello');
|
|
540
|
+
* @example #Emit an Event With Data Object
|
|
541
|
+
* // Emit the event named "hello"
|
|
542
|
+
* myEntity.emit('hello', {moo: true});
|
|
543
|
+
* @example #Emit an Event With Multiple Data Values
|
|
544
|
+
* // Emit the event named "hello"
|
|
545
|
+
* myEntity.emit('hello', {moo: true}, 'someString');
|
|
546
|
+
* @example #Listen for Event Data
|
|
547
|
+
* // Set a listener to listen for the data (multiple values emitted
|
|
548
|
+
* // from an event are passed as function arguments)
|
|
549
|
+
* myEntity.on('hello', function (arg1, arg2) {
|
|
550
|
+
* console.log("Arguments:", arg1, arg2);
|
|
551
|
+
* return "foo";
|
|
552
|
+
* }
|
|
553
|
+
*
|
|
554
|
+
* // Emit the event named "hello"
|
|
555
|
+
* // The result is returned as an array of all return values
|
|
556
|
+
* // from all the listeners for the event
|
|
557
|
+
* const result = myEntity.emit('hello', 'data1', 'data2');
|
|
558
|
+
* console.log("Result:", result);
|
|
559
|
+
*
|
|
560
|
+
* // The console output is:
|
|
561
|
+
* // Arguments: data1 data2
|
|
562
|
+
* // Result: ["foo"]
|
|
563
|
+
*/
|
|
564
|
+
emit<EventName extends keyof EventsInterface> (eventName: EventName, ...data: Parameters<EventsInterface[EventName]>): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[] {
|
|
565
|
+
this._emitToWindowDispatch(eventName, data);
|
|
578
566
|
return this.emitId<EventName>(eventName, "*", ...data);
|
|
579
567
|
}
|
|
580
568
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
569
|
+
/**
|
|
570
|
+
* Emits an event by name and id.
|
|
571
|
+
* @param eventName The name of the event to emit.
|
|
572
|
+
* @param id The id of the event to emit.
|
|
573
|
+
* @param {...any} data The arguments to send to any listening methods.
|
|
574
|
+
* If you are sending multiple arguments, separate them with a comma so
|
|
575
|
+
* that they are received by the function as separate arguments.
|
|
576
|
+
* @return {any[]} An array of all return values from all the listeners for the event.
|
|
577
|
+
*/
|
|
578
|
+
emitId<EventName extends keyof EventsInterface> (eventName: EventName, id: string, ...data: Parameters<EventsInterface[EventName]>): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[] {
|
|
586
579
|
if (!this._eventListeners || (!this._eventListeners[eventName] && !this._eventListeners["*"])) {
|
|
587
580
|
return [];
|
|
588
581
|
}
|
|
@@ -606,12 +599,7 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
606
599
|
|
|
607
600
|
if (this._eventListeners["*"]) {
|
|
608
601
|
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
|
-
);
|
|
602
|
+
emitterResult = emitterResult.concat(this._emitToArrayOfListeners<EventName>(arr as EventListenerCallback<EventsInterface[EventName]>[], [eventName, ...data] as Parameters<EventsInterface[EventName]>));
|
|
615
603
|
}
|
|
616
604
|
|
|
617
605
|
this._eventsEmitting = false;
|
|
@@ -621,18 +609,17 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
621
609
|
}
|
|
622
610
|
|
|
623
611
|
/**
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
) {
|
|
612
|
+
* Creates a persistent event. Once emitStatic() has been called, a
|
|
613
|
+
* persistent event is registered. Any existing event listeners will
|
|
614
|
+
* be called just like when you call emit(), however, any new
|
|
615
|
+
* listeners that are registered for this event via on() will also be
|
|
616
|
+
* called as soon as they are added.
|
|
617
|
+
* @param eventName The name of the event to emit.
|
|
618
|
+
* @param {...any} data Optional arguments to emit with the event.
|
|
619
|
+
* @returns The emitter instance.
|
|
620
|
+
* @private
|
|
621
|
+
*/
|
|
622
|
+
emitStatic<EventName extends keyof EventsInterface> (eventName: EventName, ...data: Parameters<EventsInterface[EventName]>) {
|
|
636
623
|
const id = "*";
|
|
637
624
|
this._eventListeners = this._eventListeners || {};
|
|
638
625
|
this._eventsEmitting = true;
|
|
@@ -656,31 +643,27 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
656
643
|
|
|
657
644
|
this._eventStaticEmitters = this._eventStaticEmitters || {};
|
|
658
645
|
this._eventStaticEmitters[eventName] = this._eventStaticEmitters[eventName] || [];
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
646
|
+
this._eventStaticEmitters[eventName]!.push({
|
|
647
|
+
id: "*",
|
|
648
|
+
args: data
|
|
649
|
+
});
|
|
663
650
|
|
|
664
|
-
|
|
651
|
+
this._processRemovalQueue();
|
|
665
652
|
|
|
666
|
-
|
|
653
|
+
return this;
|
|
667
654
|
}
|
|
668
655
|
|
|
669
656
|
/**
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
emitStaticId<EventName extends keyof EventsInterface> (
|
|
680
|
-
eventName: EventName,
|
|
681
|
-
id: string,
|
|
682
|
-
...data: Parameters<EventsInterface[EventName]>
|
|
683
|
-
) {
|
|
657
|
+
* Creates a persistent emitter record that will fire a listener if
|
|
658
|
+
* one is added for this event after the emitStatic() call has been
|
|
659
|
+
* made.
|
|
660
|
+
* @param eventName The name of the event to emit.
|
|
661
|
+
* @param id The id of the event to emit.
|
|
662
|
+
* @param {...any} data Optional arguments to emit with the event.
|
|
663
|
+
* @returns The emitter instance.
|
|
664
|
+
* @private
|
|
665
|
+
*/
|
|
666
|
+
emitStaticId<EventName extends keyof EventsInterface> (eventName: EventName, id: string, ...data: Parameters<EventsInterface[EventName]>) {
|
|
684
667
|
if (!id) throw new Error("Missing id from emitId call!");
|
|
685
668
|
|
|
686
669
|
this._eventListeners = this._eventListeners || {};
|
|
@@ -722,22 +705,22 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
722
705
|
|
|
723
706
|
this._eventStaticEmitters = this._eventStaticEmitters || {};
|
|
724
707
|
this._eventStaticEmitters[eventName] = this._eventStaticEmitters[eventName] || [];
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
708
|
+
this._eventStaticEmitters[eventName]!.push({
|
|
709
|
+
id,
|
|
710
|
+
args: data
|
|
711
|
+
});
|
|
729
712
|
|
|
730
|
-
|
|
713
|
+
this._processRemovalQueue();
|
|
731
714
|
|
|
732
|
-
|
|
715
|
+
return this;
|
|
733
716
|
}
|
|
734
717
|
|
|
735
718
|
/**
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
719
|
+
* Handles removing emitters, is an internal method not called directly.
|
|
720
|
+
* @param eventName The event to remove static emitter for.
|
|
721
|
+
* @returns The emitter instance.
|
|
722
|
+
* @private
|
|
723
|
+
*/
|
|
741
724
|
cancelStatic<EventName extends keyof EventsInterface> (eventName: EventName) {
|
|
742
725
|
this._eventStaticEmitters = this._eventStaticEmitters || {};
|
|
743
726
|
this._eventStaticEmitters[eventName] = [];
|
|
@@ -746,11 +729,11 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
746
729
|
}
|
|
747
730
|
|
|
748
731
|
/**
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
732
|
+
* Checks if an event has any event listeners or not.
|
|
733
|
+
* @param eventName The name of the event to check for.
|
|
734
|
+
* @returns True if one or more event listeners are registered for
|
|
735
|
+
* the event. False if none are found.
|
|
736
|
+
*/
|
|
754
737
|
willEmit<EventName extends keyof EventsInterface> (eventName: EventName) {
|
|
755
738
|
const id = "*";
|
|
756
739
|
|
|
@@ -774,12 +757,12 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
774
757
|
}
|
|
775
758
|
|
|
776
759
|
/**
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
760
|
+
* Checks if an event has any event listeners or not based on the passed id.
|
|
761
|
+
* @param eventName The name of the event to check for.
|
|
762
|
+
* @param id The event ID to check for.
|
|
763
|
+
* @returns True if one or more event listeners are registered for
|
|
764
|
+
* the event. False if none are found.
|
|
765
|
+
*/
|
|
783
766
|
willEmitId<EventName extends keyof EventsInterface> (eventName: EventName, id: string) {
|
|
784
767
|
if (!this._eventListeners || !this._eventListeners[eventName]) {
|
|
785
768
|
return false;
|
|
@@ -819,19 +802,16 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
819
802
|
}
|
|
820
803
|
|
|
821
804
|
/**
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
deferEmit<EventName extends keyof EventsInterface> (
|
|
832
|
-
eventName: EventName,
|
|
833
|
-
...data: Parameters<EventsInterface[EventName]>
|
|
834
|
-
) {
|
|
805
|
+
* Queues an event to be fired. This has automatic de-bouncing so that any
|
|
806
|
+
* events of the same type that occur within 100 milliseconds of a previous
|
|
807
|
+
* one will all be wrapped into a single emit rather than emitting tons of
|
|
808
|
+
* events for lots of chained inserts etc. Only the data from the last
|
|
809
|
+
* de-bounced event will be emitted.
|
|
810
|
+
* @param eventName The name of the event to emit.
|
|
811
|
+
* @param {...any} data Optional arguments to emit with the event.
|
|
812
|
+
* @returns The emitter instance.
|
|
813
|
+
*/
|
|
814
|
+
deferEmit<EventName extends keyof EventsInterface> (eventName: EventName, ...data: Parameters<EventsInterface[EventName]>) {
|
|
835
815
|
if (!this._eventsAllowDefer) {
|
|
836
816
|
// Check for an existing timeout
|
|
837
817
|
this._eventsDeferTimeouts = this._eventsDeferTimeouts || {};
|
|
@@ -852,23 +832,23 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
852
832
|
}
|
|
853
833
|
|
|
854
834
|
/**
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
835
|
+
* Returns true if the result from an emit() call passed as the first
|
|
836
|
+
* argument contains a cancellation flag.
|
|
837
|
+
* @param resultArr
|
|
838
|
+
*/
|
|
859
839
|
didCancel (resultArr: (unknown | ListenerReturnFlag)[]) {
|
|
860
840
|
return resultArr.findIndex((result) => result === ListenerReturnFlag.cancel) > -1;
|
|
861
841
|
}
|
|
862
842
|
|
|
863
843
|
/**
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
844
|
+
* If events are cleared with the off() method while the event emitter is
|
|
845
|
+
* actively processing any events then the off() calls get added to a
|
|
846
|
+
* queue to be executed after the event emitter is finished. This stops
|
|
847
|
+
* errors that might occur by potentially mutating the event listener array
|
|
848
|
+
* while the emitter is running through them. This method is called after
|
|
849
|
+
* the event emitter is finished processing.
|
|
850
|
+
* @private
|
|
851
|
+
*/
|
|
872
852
|
_processRemovalQueue () {
|
|
873
853
|
if (!this._eventRemovalQueue || !this._eventRemovalQueue.length) {
|
|
874
854
|
return;
|
|
@@ -884,10 +864,10 @@ export class Emitter<EventsInterface extends EmitterEventsWithStar<EventsInterfa
|
|
|
884
864
|
}
|
|
885
865
|
}
|
|
886
866
|
|
|
887
|
-
export function makeEmitter(obj:
|
|
888
|
-
export function makeEmitter(obj: boolean): Emitter
|
|
889
|
-
export function makeEmitter
|
|
890
|
-
export function makeEmitter (obj: any, prototypeMode?: any) {
|
|
867
|
+
export function makeEmitter<EventsInterface extends EmitterEventsWithStar<EventsInterface> = EmitterAnyEventsInterface> (obj: boolean): Emitter<EventsInterface>;
|
|
868
|
+
export function makeEmitter<EventsInterface extends EmitterEventsWithStar<EventsInterface> = EmitterAnyEventsInterface> (obj: Record<string, unknown>, prototypeMode: boolean): Emitter<EventsInterface>;
|
|
869
|
+
export function makeEmitter<EventsInterface extends EmitterEventsWithStar<EventsInterface> = EmitterAnyEventsInterface> (obj: AnyConstructor): Emitter<EventsInterface>;
|
|
870
|
+
export function makeEmitter<EventsInterface extends EmitterEventsWithStar<EventsInterface> = EmitterAnyEventsInterface> (obj: any, prototypeMode?: any): Emitter<EventsInterface> {
|
|
891
871
|
let operateOnObject;
|
|
892
872
|
|
|
893
873
|
if (obj === undefined && prototypeMode === undefined) {
|
|
@@ -910,9 +890,7 @@ export function makeEmitter (obj: any, prototypeMode?: any) {
|
|
|
910
890
|
|
|
911
891
|
if (prototypeMode) {
|
|
912
892
|
if (obj.prototype === undefined) {
|
|
913
|
-
throw new Error(
|
|
914
|
-
"Cannot modify prototype of passed object, it has no prototype property! Was it instantiated with the new operator correctly?"
|
|
915
|
-
);
|
|
893
|
+
throw new Error("Cannot modify prototype of passed object, it has no prototype property! Was it instantiated with the new operator correctly?");
|
|
916
894
|
}
|
|
917
895
|
|
|
918
896
|
operateOnObject = obj.prototype;
|
|
@@ -937,4 +915,4 @@ export function makeEmitter (obj: any, prototypeMode?: any) {
|
|
|
937
915
|
operateOnObject._processRemovalQueue = Emitter.prototype._processRemovalQueue;
|
|
938
916
|
|
|
939
917
|
return obj;
|
|
940
|
-
}
|
|
918
|
+
}
|