@irrelon/emitter 5.0.6 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintignore CHANGED
@@ -1 +1,2 @@
1
- node_modules
1
+ node_modules
2
+ readme.md
package/.prettierignore CHANGED
@@ -2,8 +2,9 @@ artifacts
2
2
  cache
3
3
  node_modules
4
4
  .next
5
- yarn.lock
6
5
  package-lock.json
7
6
  public
8
7
  .yarn
9
8
  .yarnrc
9
+ .md
10
+ readme.md
package/.prettierrc.yml CHANGED
@@ -1,9 +1,26 @@
1
1
  trailingComma: "none"
2
2
  tabWidth: 4
3
- printWidth: 140
3
+ printWidth: 120
4
4
  semi: true
5
5
  singleQuote: false
6
6
  arrowParens: always
7
7
  bracketSpacing: true
8
8
  bracketSameLine: false
9
9
  jsxSingleQuote: false
10
+ plugins: ['@trivago/prettier-plugin-sort-imports']
11
+ importOrder: [
12
+ "^react$",
13
+ "chakra-ui",
14
+ "<THIRD_PARTY_MODULES>",
15
+ "interface",
16
+ "context/",
17
+ "config",
18
+ "components/",
19
+ "utils/",
20
+ "services/",
21
+ "enums/",
22
+ "types/",
23
+ ".svg",
24
+ "^../(.*)$",
25
+ "(?=./styles.module.scss)",
26
+ ]
@@ -1,31 +1,31 @@
1
- export declare type AnyFunction<ReturnType = any> = (...args: any[]) => ReturnType;
2
- export declare type AnyConstructor = new (...args: any[]) => any;
3
- export declare enum EventReturnFlag {
4
- none = 0,
5
- cancel = 1
1
+ export type AnyFunction<ReturnType = any> = (...args: any[]) => ReturnType;
2
+ export type AnyConstructor = new (...args: any[]) => any;
3
+ export declare enum ListenerReturnFlag {
4
+ none = "!+_NONE",
5
+ cancel = "!+_CANCEL"
6
6
  }
7
- export declare type EventListenerCallback<EventCallbackFunctionSignature extends AnyFunction = AnyFunction> = (...args: Parameters<EventCallbackFunctionSignature>) => ReturnType<EventCallbackFunctionSignature>;
7
+ export type EventListenerCallback<EventCallbackFunctionSignature extends AnyFunction = AnyFunction> = (...args: Parameters<EventCallbackFunctionSignature>) => ReturnType<EventCallbackFunctionSignature>;
8
8
  export interface EventStaticEmitterObject<EventCallbackFunctionSignature extends AnyFunction = AnyFunction> {
9
9
  id: string;
10
10
  args: Parameters<EventCallbackFunctionSignature>;
11
11
  }
12
- export interface EmitterEventsInterface {
12
+ export interface EmitterAnyEventsInterface {
13
13
  [key: string]: AnyFunction;
14
14
  }
15
- export declare type ConvertInterfaceToDict<T> = {
15
+ export type EmitterEventsInterface<T> = {
16
16
  [K in keyof T]: T[K];
17
17
  };
18
18
  /**
19
19
  * Creates a new class with the capability to emit events.
20
20
  */
21
- export declare class Emitter<EventsInterface extends EmitterEventsInterface = EmitterEventsInterface> {
21
+ export declare class Emitter<EventsInterface extends EmitterEventsInterface<EventsInterface> = EmitterAnyEventsInterface> {
22
22
  _eventsEmitting: boolean;
23
23
  _eventRemovalQueue: any[];
24
24
  _eventListeners?: {
25
- [EventName in (keyof EventsInterface)]?: Record<string, EventListenerCallback<EventsInterface[EventName]>[]>;
25
+ [EventName in keyof EventsInterface]?: Record<string, EventListenerCallback<EventsInterface[EventName]>[]>;
26
26
  };
27
27
  _eventStaticEmitters: {
28
- [EventName in (keyof EventsInterface)]?: EventStaticEmitterObject<EventsInterface[EventName]>[];
28
+ [EventName in keyof EventsInterface]?: EventStaticEmitterObject<EventsInterface[EventName]>[];
29
29
  };
30
30
  _eventsAllowDefer: boolean;
31
31
  _eventsDeferTimeouts: Record<any, number>;
@@ -101,6 +101,46 @@ export declare class Emitter<EventsInterface extends EmitterEventsInterface = Em
101
101
  off<EventName extends keyof EventsInterface>(eventName: EventName, id: string, listener?: EventListenerCallback<EventsInterface[EventName]>): this;
102
102
  off<EventName extends keyof EventsInterface>(eventName: EventName, listener?: EventListenerCallback<EventsInterface[EventName]>): this;
103
103
  off<EventName extends keyof EventsInterface>(eventName: EventName): this;
104
+ _emitToSingleListener<EventName extends keyof EventsInterface>(listener: EventListenerCallback<EventsInterface[EventName]>, data: Parameters<EventsInterface[EventName]>): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag;
105
+ _emitToArrayOfListeners<EventName extends keyof EventsInterface>(arr: EventListenerCallback<EventsInterface[EventName]>[], data: Parameters<EventsInterface[EventName]>): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[];
106
+ /**
107
+ * Call an event listener by name. The `rpc()` function differs from `emit()` in
108
+ * that it will only call and return data from the first event listener for the
109
+ * event rather than all event listeners. If you have more than one event listener
110
+ * assigned to the event, all others except the first will be ignored and will
111
+ * not receive the event.
112
+ * @param eventName The name of the event to call the listener for.
113
+ * @param {...any} data The arguments to send to the listening method.
114
+ * If you are sending multiple arguments, separate them with a comma so
115
+ * that they are received by the function as separate arguments.
116
+ * @return {number}
117
+ * @example #Call the Event Listener
118
+ * // Emit the event named "hello"
119
+ * myEntity.emit('hello');
120
+ * @example #Call the Event Listener With Data Object
121
+ * // Emit the event named "hello"
122
+ * myEntity.emit('hello', {moo: true});
123
+ * @example #Call the Event Listener With Multiple Data Values
124
+ * // Emit the event named "hello"
125
+ * myEntity.emit('hello', {moo: true}, 'someString');
126
+ * @example #Register the Listener for Event Data
127
+ * // Set a listener to listen for the data (multiple values emitted
128
+ * // from an event are passed as function arguments)
129
+ * myEntity.on('hello', function (arg1, arg2) {
130
+ * console.log("Arguments:", arg1, arg2);
131
+ * return "foo";
132
+ * }
133
+ *
134
+ * // Emit the event named "hello"
135
+ * const result = myEntity.emit('hello', 'data1', 'data2');
136
+ * console.log("Result:", result);
137
+ *
138
+ * // The console output is:
139
+ * // Arguments: data1 data2
140
+ * // Result: "foo"
141
+ */
142
+ rpc<EventName extends keyof EventsInterface>(eventName: EventName, ...data: Parameters<EventsInterface[EventName]>): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag;
143
+ rpcId<EventName extends keyof EventsInterface>(eventName: EventName, id: string, ...data: Parameters<EventsInterface[EventName]>): ReturnType<EventsInterface[EventName]> | ListenerReturnFlag;
104
144
  /**
105
145
  * Emit an event by name.
106
146
  * @param eventName The name of the event to emit.
@@ -120,18 +160,23 @@ export declare class Emitter<EventsInterface extends EmitterEventsInterface = Em
120
160
  * @example #Listen for Event Data
121
161
  * // Set a listener to listen for the data (multiple values emitted
122
162
  * // from an event are passed as function arguments)
123
- * myEntity.on('hello', function (arg1, arg2) {
124
- * console.log(arg1, arg2);
163
+ * myEntity.on('hello', function (arg1, arg2) {
164
+ * console.log("Arguments:", arg1, arg2);
165
+ * return "foo";
125
166
  * }
126
167
  *
127
168
  * // Emit the event named "hello"
128
- * myEntity.emit('hello', 'data1', 'data2');
169
+ * // The result is returned as an array of all return values
170
+ * // from all the listeners for the event
171
+ * const result = myEntity.emit('hello', 'data1', 'data2');
172
+ * console.log("Result:", result);
129
173
  *
130
174
  * // The console output is:
131
- * // data1, data2
175
+ * // Arguments: data1 data2
176
+ * // Result: ["foo"]
132
177
  */
133
- emit<EventName extends keyof EventsInterface>(eventName: EventName, ...data: Parameters<EventsInterface[EventName]>): Promise<EventReturnFlag>;
134
- emitId<EventName extends keyof EventsInterface>(eventName: EventName, id: string, ...data: Parameters<EventsInterface[EventName]>): EventReturnFlag;
178
+ emit<EventName extends keyof EventsInterface>(eventName: EventName, ...data: Parameters<EventsInterface[EventName]>): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[];
179
+ emitId<EventName extends keyof EventsInterface>(eventName: EventName, id: string, ...data: Parameters<EventsInterface[EventName]>): (ReturnType<EventsInterface[EventName]> | ListenerReturnFlag)[];
135
180
  /**
136
181
  * Creates a persistent emitter record that will fire a listener if
137
182
  * one is added for this event after the emitStatic() call has been
@@ -186,13 +231,19 @@ export declare class Emitter<EventsInterface extends EmitterEventsInterface = Em
186
231
  * @returns The emitter instance.
187
232
  */
188
233
  deferEmit<EventName extends keyof EventsInterface>(eventName: EventName, ...data: Parameters<EventsInterface[EventName]>): this;
234
+ /**
235
+ * Returns true if the result from an emit() call passed as the first
236
+ * argument contains a cancellation flag.
237
+ * @param resultArr
238
+ */
239
+ didCancel(resultArr: (unknown | ListenerReturnFlag)[]): boolean;
189
240
  /**
190
241
  * If events are cleared with the off() method while the event emitter is
191
242
  * actively processing any events then the off() calls get added to a
192
243
  * queue to be executed after the event emitter is finished. This stops
193
- * errors that might occur by potentially modifying the event queue while
194
- * the emitter is running through them. This method is called after the
195
- * event emitter is finished processing.
244
+ * errors that might occur by potentially mutating the event listener array
245
+ * while the emitter is running through them. This method is called after
246
+ * the event emitter is finished processing.
196
247
  * @private
197
248
  */
198
249
  _processRemovalQueue(): void;
@@ -1,20 +1,11 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.makeEmitter = exports.Emitter = exports.EventReturnFlag = void 0;
13
- var EventReturnFlag;
14
- (function (EventReturnFlag) {
15
- EventReturnFlag[EventReturnFlag["none"] = 0] = "none";
16
- EventReturnFlag[EventReturnFlag["cancel"] = 1] = "cancel";
17
- })(EventReturnFlag = exports.EventReturnFlag || (exports.EventReturnFlag = {}));
3
+ exports.makeEmitter = exports.Emitter = exports.ListenerReturnFlag = void 0;
4
+ var ListenerReturnFlag;
5
+ (function (ListenerReturnFlag) {
6
+ ListenerReturnFlag["none"] = "!+_NONE";
7
+ ListenerReturnFlag["cancel"] = "!+_CANCEL";
8
+ })(ListenerReturnFlag || (exports.ListenerReturnFlag = ListenerReturnFlag = {}));
18
9
  /**
19
10
  * Creates a new class with the capability to emit events.
20
11
  */
@@ -42,11 +33,13 @@ class Emitter {
42
33
  }, 1);
43
34
  };
44
35
  this._eventListeners = this._eventListeners || {};
45
- const nonNullableEventListeners = this._eventListeners[eventName] = this._eventListeners[eventName] || {};
36
+ const nonNullableEventListeners = (this._eventListeners[eventName] = this._eventListeners[eventName] || {});
46
37
  nonNullableEventListeners[id] = nonNullableEventListeners[id] || [];
47
38
  nonNullableEventListeners[id].push(listener);
48
39
  // Check for any static emitters, and fire the event if any exist
49
- if (!this._eventStaticEmitters || !this._eventStaticEmitters[eventName] || !this._eventStaticEmitters[eventName].length)
40
+ if (!this._eventStaticEmitters ||
41
+ !this._eventStaticEmitters[eventName] ||
42
+ !this._eventStaticEmitters[eventName].length)
50
43
  return this;
51
44
  // Emit events for each emitter
52
45
  for (let i = 0; i < this._eventStaticEmitters[eventName].length; i++) {
@@ -159,6 +152,92 @@ class Emitter {
159
152
  // Both id and listener were provided, remove for the specific id
160
153
  return this._off(eventName, rest[0], rest[1]);
161
154
  }
155
+ _emitToSingleListener(listener, data) {
156
+ return listener(...data);
157
+ }
158
+ _emitToArrayOfListeners(arr, data) {
159
+ const arrCount = arr.length;
160
+ const resultArr = [];
161
+ for (let arrIndex = 0; arrIndex < arrCount; arrIndex++) {
162
+ // Check we have a function to execute
163
+ const tmpFunc = arr[arrIndex];
164
+ if (typeof tmpFunc !== "function") {
165
+ continue;
166
+ }
167
+ const eventListenerResponse = tmpFunc(...data);
168
+ resultArr.push(eventListenerResponse);
169
+ if (eventListenerResponse === ListenerReturnFlag.cancel) {
170
+ // Cancel further event processing
171
+ break;
172
+ }
173
+ }
174
+ return resultArr;
175
+ }
176
+ /**
177
+ * Call an event listener by name. The `rpc()` function differs from `emit()` in
178
+ * that it will only call and return data from the first event listener for the
179
+ * event rather than all event listeners. If you have more than one event listener
180
+ * assigned to the event, all others except the first will be ignored and will
181
+ * not receive the event.
182
+ * @param eventName The name of the event to call the listener for.
183
+ * @param {...any} data The arguments to send to the listening method.
184
+ * If you are sending multiple arguments, separate them with a comma so
185
+ * that they are received by the function as separate arguments.
186
+ * @return {number}
187
+ * @example #Call the Event Listener
188
+ * // Emit the event named "hello"
189
+ * myEntity.emit('hello');
190
+ * @example #Call the Event Listener With Data Object
191
+ * // Emit the event named "hello"
192
+ * myEntity.emit('hello', {moo: true});
193
+ * @example #Call the Event Listener With Multiple Data Values
194
+ * // Emit the event named "hello"
195
+ * myEntity.emit('hello', {moo: true}, 'someString');
196
+ * @example #Register the Listener for Event Data
197
+ * // Set a listener to listen for the data (multiple values emitted
198
+ * // from an event are passed as function arguments)
199
+ * myEntity.on('hello', function (arg1, arg2) {
200
+ * console.log("Arguments:", arg1, arg2);
201
+ * return "foo";
202
+ * }
203
+ *
204
+ * // Emit the event named "hello"
205
+ * const result = myEntity.emit('hello', 'data1', 'data2');
206
+ * console.log("Result:", result);
207
+ *
208
+ * // The console output is:
209
+ * // Arguments: data1 data2
210
+ * // Result: "foo"
211
+ */
212
+ rpc(eventName, ...data) {
213
+ return this.rpcId(eventName, "*", ...data);
214
+ }
215
+ rpcId(eventName, id, ...data) {
216
+ if (!this._eventListeners || !this._eventListeners[eventName]) {
217
+ throw new Error("Cannot make an rpc call without at least one event listener and none were found");
218
+ }
219
+ let emitterResult;
220
+ this._eventsEmitting = true;
221
+ if (this._eventListeners[eventName][id]) {
222
+ // Handle id emit
223
+ const arr = this._eventListeners[eventName][id];
224
+ emitterResult = this._emitToSingleListener(arr[0], data);
225
+ }
226
+ else if (id !== "*" && this._eventListeners[eventName]["*"]) {
227
+ // Handle global emit if the id passed wasn't already a global (*) id
228
+ const arr = this._eventListeners[eventName]["*"];
229
+ emitterResult = this._emitToSingleListener(arr[0], data);
230
+ }
231
+ else {
232
+ if (id === "*") {
233
+ throw new Error(`Cannot make an rpc call to event "${eventName}" without at least one event listener and none were found, register a listener via on("${eventName}", () => { ...some listener code })`);
234
+ }
235
+ throw new Error(`Cannot make an rpc call to event "${eventName}" and id "${id}" without at least one event listener and none were found, register a listener via on("${eventName}", "${id}", () => { ...some listener code })`);
236
+ }
237
+ this._eventsEmitting = false;
238
+ this._processRemovalQueue();
239
+ return emitterResult;
240
+ }
162
241
  /**
163
242
  * Emit an event by name.
164
243
  * @param eventName The name of the event to emit.
@@ -178,80 +257,43 @@ class Emitter {
178
257
  * @example #Listen for Event Data
179
258
  * // Set a listener to listen for the data (multiple values emitted
180
259
  * // from an event are passed as function arguments)
181
- * myEntity.on('hello', function (arg1, arg2) {
182
- * console.log(arg1, arg2);
260
+ * myEntity.on('hello', function (arg1, arg2) {
261
+ * console.log("Arguments:", arg1, arg2);
262
+ * return "foo";
183
263
  * }
184
264
  *
185
265
  * // Emit the event named "hello"
186
- * myEntity.emit('hello', 'data1', 'data2');
266
+ * // The result is returned as an array of all return values
267
+ * // from all the listeners for the event
268
+ * const result = myEntity.emit('hello', 'data1', 'data2');
269
+ * console.log("Result:", result);
187
270
  *
188
271
  * // The console output is:
189
- * // data1, data2
272
+ * // Arguments: data1 data2
273
+ * // Result: ["foo"]
190
274
  */
191
275
  emit(eventName, ...data) {
192
- return __awaiter(this, void 0, void 0, function* () {
193
- if (!this._eventListeners) {
194
- return EventReturnFlag.none;
195
- }
196
- const id = "*";
197
- let returnFlag = EventReturnFlag.none;
198
- this._eventsEmitting = true;
199
- if (this._eventListeners[eventName] && this._eventListeners[eventName][id]) {
200
- // Handle global emit
201
- const arr = this._eventListeners[eventName][id];
202
- const promiseArr = arr.map((tmpFunc) => {
203
- if (typeof tmpFunc !== "function")
204
- return;
205
- return tmpFunc(...data);
206
- });
207
- const result = (yield Promise.all(promiseArr)).find((tmpResult) => tmpResult !== EventReturnFlag.none);
208
- if (result) {
209
- returnFlag = EventReturnFlag.cancel;
210
- }
211
- }
212
- this._eventsEmitting = false;
213
- this._processRemovalQueue();
214
- return returnFlag;
215
- });
276
+ return this.emitId(eventName, "*", ...data);
216
277
  }
217
278
  emitId(eventName, id, ...data) {
218
- if (!this._eventListeners) {
219
- return EventReturnFlag.none;
279
+ if (!this._eventListeners || !this._eventListeners[eventName]) {
280
+ return [];
220
281
  }
221
- this._eventListeners = this._eventListeners || {};
282
+ let emitterResult = [];
222
283
  this._eventsEmitting = true;
223
- if (!this._eventListeners[eventName]) {
224
- this._eventsEmitting = false;
225
- this._processRemovalQueue();
226
- return EventReturnFlag.none;
227
- }
228
284
  // Handle id emit
229
285
  if (this._eventListeners[eventName][id]) {
230
286
  const arr = this._eventListeners[eventName][id];
231
- const arrCount = arr.length;
232
- for (let arrIndex = 0; arrIndex < arrCount; arrIndex++) {
233
- // Check we have a function to execute
234
- const tmpFunc = arr[arrIndex];
235
- if (typeof tmpFunc === "function") {
236
- tmpFunc.call(this, ...data);
237
- }
238
- }
287
+ emitterResult = emitterResult.concat(this._emitToArrayOfListeners(arr, data));
239
288
  }
240
- // Handle global emit
241
- if (this._eventListeners[eventName]["*"]) {
289
+ // Handle global emit if the id passed wasn't already a global (*) id
290
+ if (id !== "*" && this._eventListeners[eventName]["*"]) {
242
291
  const arr = this._eventListeners[eventName]["*"];
243
- const arrCount = arr.length;
244
- for (let arrIndex = 0; arrIndex < arrCount; arrIndex++) {
245
- // Check we have a function to execute
246
- const tmpFunc = arr[arrIndex];
247
- if (typeof tmpFunc === "function") {
248
- tmpFunc.call(this, ...data);
249
- }
250
- }
292
+ emitterResult = emitterResult.concat(this._emitToArrayOfListeners(arr, data));
251
293
  }
252
294
  this._eventsEmitting = false;
253
295
  this._processRemovalQueue();
254
- return EventReturnFlag.none;
296
+ return emitterResult;
255
297
  }
256
298
  /**
257
299
  * Creates a persistent emitter record that will fire a listener if
@@ -282,8 +324,8 @@ class Emitter {
282
324
  this._eventStaticEmitters = this._eventStaticEmitters || {};
283
325
  this._eventStaticEmitters[eventName] = this._eventStaticEmitters[eventName] || [];
284
326
  this._eventStaticEmitters[eventName].push({
285
- "id": "*",
286
- "args": data
327
+ id: "*",
328
+ args: data
287
329
  });
288
330
  this._processRemovalQueue();
289
331
  return this;
@@ -334,7 +376,7 @@ class Emitter {
334
376
  this._eventStaticEmitters[eventName] = this._eventStaticEmitters[eventName] || [];
335
377
  this._eventStaticEmitters[eventName].push({
336
378
  id,
337
- "args": data
379
+ args: data
338
380
  });
339
381
  this._processRemovalQueue();
340
382
  return this;
@@ -436,13 +478,21 @@ class Emitter {
436
478
  }
437
479
  return this;
438
480
  }
481
+ /**
482
+ * Returns true if the result from an emit() call passed as the first
483
+ * argument contains a cancellation flag.
484
+ * @param resultArr
485
+ */
486
+ didCancel(resultArr) {
487
+ return resultArr.findIndex((result) => result === ListenerReturnFlag.cancel) > -1;
488
+ }
439
489
  /**
440
490
  * If events are cleared with the off() method while the event emitter is
441
491
  * actively processing any events then the off() calls get added to a
442
492
  * queue to be executed after the event emitter is finished. This stops
443
- * errors that might occur by potentially modifying the event queue while
444
- * the emitter is running through them. This method is called after the
445
- * event emitter is finished processing.
493
+ * errors that might occur by potentially mutating the event listener array
494
+ * while the emitter is running through them. This method is called after
495
+ * the event emitter is finished processing.
446
496
  * @private
447
497
  */
448
498
  _processRemovalQueue() {