@reldens/utils 0.50.0 → 0.52.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/README.md +101 -1
- package/lib/events-manager.js +324 -64
- package/lib/logger.js +24 -57
- package/lib/shortcuts.js +10 -0
- package/package.json +5 -4
- package/tests/events-manager-test.js +1084 -0
- package/tests/run.js +13 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Reldens - Utils
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
7
|
- Interaction area calculation helper.
|
|
8
8
|
- Page range provider helper.
|
|
@@ -13,6 +13,106 @@
|
|
|
13
13
|
- Error Manager.
|
|
14
14
|
- Events Manager and Events Manager Singleton.
|
|
15
15
|
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Usage examples
|
|
19
|
+
|
|
20
|
+
### EventsManager
|
|
21
|
+
Advanced event emitter with features like event sanitization, memory leak detection, key-based event management, and support for async/sync execution.
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
const { EventsManager } = require('@reldens/utils');
|
|
25
|
+
let eventsManager = new EventsManager();
|
|
26
|
+
|
|
27
|
+
// Listen to events
|
|
28
|
+
eventsManager.on('userLogin', (userData) => {
|
|
29
|
+
console.log('User logged in:', userData.username);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Emit events
|
|
33
|
+
eventsManager.emit('userLogin', { username: 'player1', id: 123 });
|
|
34
|
+
|
|
35
|
+
// Listen with unique keys
|
|
36
|
+
eventsManager.onWithKey('gameStart', callback, 'uniqueKey');
|
|
37
|
+
eventsManager.offWithKey('uniqueKey'); // Remove by key
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### InteractionArea
|
|
41
|
+
Spatial interaction validation helper that determines if objects are within interaction range based on coordinates and area margins.
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
const { InteractionArea } = require('@reldens/utils');
|
|
45
|
+
let interactionArea = new InteractionArea();
|
|
46
|
+
|
|
47
|
+
// Setup interaction area
|
|
48
|
+
interactionArea.setupInteractionArea(50, 100, 200); // margin=50, x=100, y=200
|
|
49
|
+
|
|
50
|
+
// Validate interaction
|
|
51
|
+
let isValid = interactionArea.isValidInteraction(120, 210); // true
|
|
52
|
+
let isInvalid = interactionArea.isValidInteraction(200, 300); // false
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Logger
|
|
56
|
+
Advanced logging utility with multiple log levels, custom levels support, active level filtering, and environment-based configuration.
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
const { Logger } = require('@reldens/utils');
|
|
60
|
+
|
|
61
|
+
// Standard logging
|
|
62
|
+
Logger.info('Application started');
|
|
63
|
+
Logger.error('Database connection failed', errorDetails);
|
|
64
|
+
Logger.debug('Processing user request', requestData);
|
|
65
|
+
|
|
66
|
+
// Custom levels
|
|
67
|
+
Logger.activeLogLevels = [3, 4, 10]; // Only critical, error, and custom level 10
|
|
68
|
+
Logger.customLevels = [10, 11, 12];
|
|
69
|
+
Logger.log(10, 'custom', 'Custom log message');
|
|
70
|
+
|
|
71
|
+
// Configuration
|
|
72
|
+
Logger.setForcedDisabled(false);
|
|
73
|
+
Logger.setAddTimeStamp(true);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### PageRangeProvider
|
|
77
|
+
Pagination helper that calculates page ranges for UI components, handling first/last page navigation and customizable display options.
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
const { PageRangeProvider } = require('@reldens/utils');
|
|
81
|
+
let pageProvider = new PageRangeProvider();
|
|
82
|
+
|
|
83
|
+
// Generate page range
|
|
84
|
+
let range = pageProvider.fetch(5, 20, 7, 'First', 'Last');
|
|
85
|
+
// Returns: [{label: 'First', value: 1}, {label: 2, value: 2}, ...]
|
|
86
|
+
|
|
87
|
+
// Simple range
|
|
88
|
+
let simpleRange = pageProvider.fetch(3, 10, 5);
|
|
89
|
+
// Returns pages around current page 3
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### SchemaValidator
|
|
93
|
+
Object validation utility that validates object properties against defined schemas with support for nested objects and custom validation rules.
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
const { SchemaValidator } = require('@reldens/utils');
|
|
97
|
+
|
|
98
|
+
let schema = {
|
|
99
|
+
username: { type: 'string', min: 3, max: 20 },
|
|
100
|
+
age: { type: 'int', min: 18 },
|
|
101
|
+
profile: {
|
|
102
|
+
type: 'object',
|
|
103
|
+
nested: {
|
|
104
|
+
email: { type: 'string', required: true }
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
let validator = new SchemaValidator(schema);
|
|
110
|
+
let userData = { username: 'player1', age: 25, profile: { email: 'test@example.com' } };
|
|
111
|
+
let isValid = validator.validate(userData);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
16
116
|
Need something specific?
|
|
17
117
|
|
|
18
118
|
[Request a feature here: https://www.reldens.com/features-request](https://www.reldens.com/features-request)
|
package/lib/events-manager.js
CHANGED
|
@@ -2,55 +2,336 @@
|
|
|
2
2
|
*
|
|
3
3
|
* Reldens - EventsManager
|
|
4
4
|
*
|
|
5
|
-
* This extension includes a few new features:
|
|
6
|
-
*
|
|
7
|
-
* - The onWithKey and offWithKey methods will allow you to specify a "group" key for the event listener, the related
|
|
8
|
-
* event will be referenced in a new property called "eventsByRemoveKey" so you can detach multiple listeners at the
|
|
9
|
-
* time.
|
|
10
|
-
*
|
|
11
|
-
* - We override the "on" and "off" aliases override to include a debug check with a log. Using the debug property,
|
|
12
|
-
* you can specify to log "all" the fire and listeners, or just by key. Note the key search will be applied in both
|
|
13
|
-
* directions, it will check if the debug value exists in the event key or if the event key exists in the debug value.
|
|
14
|
-
*
|
|
15
5
|
*/
|
|
16
6
|
|
|
17
|
-
const AwaitEventEmitter = require('await-event-emitter').default;
|
|
18
7
|
const Logger = require('./logger');
|
|
19
8
|
const sc = require('./shortcuts');
|
|
20
9
|
|
|
21
|
-
class
|
|
10
|
+
class EventsManager
|
|
22
11
|
{
|
|
23
12
|
|
|
24
13
|
constructor()
|
|
25
14
|
{
|
|
26
|
-
|
|
15
|
+
this._events = {};
|
|
27
16
|
this.eventsByRemoveKeys = {};
|
|
28
17
|
this.debug = false;
|
|
18
|
+
this._listenersCache = {};
|
|
19
|
+
this._validationCache = new Map();
|
|
20
|
+
this._debugPatterns = null;
|
|
21
|
+
this.maxEventKeyLength = 1000;
|
|
22
|
+
this.maxListeners = 10000;
|
|
23
|
+
this.maxEventArgs = 50;
|
|
24
|
+
this.sensitiveFields = ['password', 'token', 'secret', 'key', 'auth', 'credential'];
|
|
25
|
+
this.hasLoggedMaxListeners = false;
|
|
26
|
+
this.symbolString = '--[[await-event-emitter]]--';
|
|
27
|
+
this.typeKeyName = sc.isFunction(Symbol) ? Symbol.for(this.symbolString) : this.symbolString;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
assertType(type)
|
|
31
|
+
{
|
|
32
|
+
if(!sc.isString(type) && !sc.isSymbol(type)){
|
|
33
|
+
throw new TypeError('type is not type of string or symbol!');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
assertFn(fn)
|
|
38
|
+
{
|
|
39
|
+
if(!sc.isFunction(fn)){
|
|
40
|
+
throw new TypeError('fn is not type of Function!');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
alwaysListener(fn)
|
|
45
|
+
{
|
|
46
|
+
return {
|
|
47
|
+
[this.typeKeyName]: 'always',
|
|
48
|
+
fn
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
onceListener(fn)
|
|
53
|
+
{
|
|
54
|
+
return {
|
|
55
|
+
[this.typeKeyName]: 'once',
|
|
56
|
+
fn
|
|
57
|
+
};
|
|
29
58
|
}
|
|
30
59
|
|
|
31
60
|
validateEventKey(eventKey)
|
|
32
61
|
{
|
|
33
|
-
|
|
62
|
+
if(this._validationCache.has(eventKey)){
|
|
63
|
+
return this._validationCache.get(eventKey);
|
|
64
|
+
}
|
|
65
|
+
if(sc.isString(eventKey) && eventKey.length > this.maxEventKeyLength){
|
|
66
|
+
Logger.critical('Event key exceeds maximum length: '+eventKey.length);
|
|
67
|
+
this._validationCache.set(eventKey, false);
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
let isValid = !sc.hasDangerousKeys(null, eventKey);
|
|
71
|
+
this._validationCache.set(eventKey, isValid);
|
|
72
|
+
return isValid;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
sanitizeEventArgs(args)
|
|
76
|
+
{
|
|
77
|
+
if(!sc.isArray(args)){
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
if(args.length > this.maxEventArgs){
|
|
81
|
+
Logger.warning('Event arguments exceed maximum: '+args.length);
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
return args.map(arg => {
|
|
85
|
+
if(sc.isObject(arg)){
|
|
86
|
+
return this.filterSensitiveData(arg);
|
|
87
|
+
}
|
|
88
|
+
return arg;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
filterSensitiveData(obj)
|
|
93
|
+
{
|
|
94
|
+
if(!sc.isObject(obj)){
|
|
95
|
+
return obj;
|
|
96
|
+
}
|
|
97
|
+
let filtered = {};
|
|
98
|
+
for(let key of Object.keys(obj)){
|
|
99
|
+
if(sc.hasDangerousKeys(null, key)){
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
let isKeywordSensitive = this.sensitiveFields.some(sensitive =>
|
|
103
|
+
key.toLowerCase().includes(sensitive.toLowerCase())
|
|
104
|
+
);
|
|
105
|
+
if(isKeywordSensitive){
|
|
106
|
+
filtered[key] = '[FILTERED]';
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if(sc.isObject(obj[key])){
|
|
110
|
+
filtered[key] = this.filterSensitiveData(obj[key]);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
filtered[key] = obj[key];
|
|
114
|
+
}
|
|
115
|
+
return filtered;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
checkMemoryLeaks()
|
|
119
|
+
{
|
|
120
|
+
if(this.hasLoggedMaxListeners){
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
let totalListeners = 0;
|
|
124
|
+
for(let eventType of Object.keys(this._events)){
|
|
125
|
+
totalListeners += this._events[eventType].length;
|
|
126
|
+
}
|
|
127
|
+
if(totalListeners > this.maxListeners){
|
|
128
|
+
Logger.debug('High listener count detected: '+totalListeners+' total listeners');
|
|
129
|
+
this.hasLoggedMaxListeners = true;
|
|
130
|
+
}
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
addListener(type, fn)
|
|
135
|
+
{
|
|
136
|
+
return this.on(type, fn);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
on(type, fn)
|
|
140
|
+
{
|
|
141
|
+
this.assertType(type);
|
|
142
|
+
this.assertFn(fn);
|
|
143
|
+
if(!this.validateEventKey(type)){
|
|
144
|
+
Logger.critical('Invalid event key detected: '+type);
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
if(false !== this.debug){
|
|
148
|
+
this.logDebugEvent(type, 'Listen');
|
|
149
|
+
}
|
|
150
|
+
this._events[type] = this._events[type] || [];
|
|
151
|
+
this._events[type].push(this.alwaysListener(fn));
|
|
152
|
+
delete this._listenersCache[type];
|
|
153
|
+
this.checkMemoryLeaks();
|
|
154
|
+
return this;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
prependListener(type, fn)
|
|
158
|
+
{
|
|
159
|
+
return this.prepend(type, fn);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
prepend(type, fn)
|
|
163
|
+
{
|
|
164
|
+
this.assertType(type);
|
|
165
|
+
this.assertFn(fn);
|
|
166
|
+
if(!this.validateEventKey(type)){
|
|
167
|
+
Logger.critical('Invalid event key detected: '+type);
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
this._events[type] = this._events[type] || [];
|
|
171
|
+
this._events[type].unshift(this.alwaysListener(fn));
|
|
172
|
+
delete this._listenersCache[type];
|
|
173
|
+
this.checkMemoryLeaks();
|
|
174
|
+
return this;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
prependOnceListener(type, fn)
|
|
178
|
+
{
|
|
179
|
+
return this.prependOnce(type, fn);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
prependOnce(type, fn)
|
|
183
|
+
{
|
|
184
|
+
this.assertType(type);
|
|
185
|
+
this.assertFn(fn);
|
|
186
|
+
if(!this.validateEventKey(type)){
|
|
187
|
+
Logger.critical('Invalid event key detected: '+type);
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
this._events[type] = this._events[type] || [];
|
|
191
|
+
this._events[type].unshift(this.onceListener(fn));
|
|
192
|
+
delete this._listenersCache[type];
|
|
193
|
+
this.checkMemoryLeaks();
|
|
194
|
+
return this;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
listeners(type)
|
|
198
|
+
{
|
|
199
|
+
if(this._listenersCache[type]){
|
|
200
|
+
return this._listenersCache[type];
|
|
201
|
+
}
|
|
202
|
+
let result = (this._events[type] || []).map((x) => x.fn);
|
|
203
|
+
this._listenersCache[type] = result;
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
once(type, fn)
|
|
208
|
+
{
|
|
209
|
+
this.assertType(type);
|
|
210
|
+
this.assertFn(fn);
|
|
211
|
+
if(!this.validateEventKey(type)){
|
|
212
|
+
Logger.critical('Invalid event key detected: '+type);
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
this._events[type] = this._events[type] || [];
|
|
216
|
+
this._events[type].push(this.onceListener(fn));
|
|
217
|
+
delete this._listenersCache[type];
|
|
218
|
+
this.checkMemoryLeaks();
|
|
219
|
+
return this;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
removeAllListeners()
|
|
223
|
+
{
|
|
224
|
+
this._events = {};
|
|
225
|
+
this._listenersCache = {};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
off(type, nullOrFn)
|
|
229
|
+
{
|
|
230
|
+
return this.removeListener(type, nullOrFn);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
removeListener(type, nullOrFn)
|
|
234
|
+
{
|
|
235
|
+
this.assertType(type);
|
|
236
|
+
if(!this.validateEventKey(type)){
|
|
237
|
+
Logger.critical('Invalid event key detected: '+type);
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
let listeners = this.listeners(type);
|
|
241
|
+
if(sc.isFunction(nullOrFn)){
|
|
242
|
+
let index = -1;
|
|
243
|
+
let found = false;
|
|
244
|
+
while(-1 < (index = listeners.indexOf(nullOrFn))){
|
|
245
|
+
listeners.splice(index, 1);
|
|
246
|
+
this._events[type].splice(index, 1);
|
|
247
|
+
found = true;
|
|
248
|
+
}
|
|
249
|
+
delete this._listenersCache[type];
|
|
250
|
+
return found;
|
|
251
|
+
}
|
|
252
|
+
delete this._events[type];
|
|
253
|
+
delete this._listenersCache[type];
|
|
254
|
+
return true;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async emit(type, ...args)
|
|
258
|
+
{
|
|
259
|
+
this.assertType(type);
|
|
260
|
+
if(!this.validateEventKey(type)){
|
|
261
|
+
Logger.critical('Invalid event key detected: '+type);
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
let sanitizedArgs = this.sanitizeEventArgs(args);
|
|
265
|
+
if(false !== this.debug){
|
|
266
|
+
this.logDebugEvent(type, 'Fire', sanitizedArgs);
|
|
267
|
+
}
|
|
268
|
+
this.checkMemoryLeaks();
|
|
269
|
+
let listeners = this.listeners(type);
|
|
270
|
+
let onceListeners = [];
|
|
271
|
+
if(listeners && listeners.length){
|
|
272
|
+
for(let i = 0; i < listeners.length; i++){
|
|
273
|
+
let event = listeners[i];
|
|
274
|
+
let rlt = event.apply(this, sanitizedArgs);
|
|
275
|
+
if(sc.isPromise(rlt)){
|
|
276
|
+
await rlt;
|
|
277
|
+
}
|
|
278
|
+
if(this._events[type] && this._events[type][i] && 'once' === this._events[type][i][this.typeKeyName]){
|
|
279
|
+
onceListeners.push(event);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
for(let event of onceListeners){
|
|
283
|
+
this.removeListener(type, event);
|
|
284
|
+
}
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
emitSync(type, ...args)
|
|
291
|
+
{
|
|
292
|
+
this.assertType(type);
|
|
293
|
+
if(!this.validateEventKey(type)){
|
|
294
|
+
Logger.critical('Invalid event key detected: '+type);
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
let sanitizedArgs = this.sanitizeEventArgs(args);
|
|
298
|
+
let listeners = this.listeners(type);
|
|
299
|
+
let onceListeners = [];
|
|
300
|
+
if(listeners && listeners.length){
|
|
301
|
+
for(let i = 0; i < listeners.length; i++){
|
|
302
|
+
let event = listeners[i];
|
|
303
|
+
event.apply(this, sanitizedArgs);
|
|
304
|
+
if(this._events[type] && this._events[type][i] && 'once' === this._events[type][i][this.typeKeyName]){
|
|
305
|
+
onceListeners.push(event);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
for(let event of onceListeners){
|
|
309
|
+
this.removeListener(type, event);
|
|
310
|
+
}
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
return false;
|
|
34
314
|
}
|
|
35
315
|
|
|
36
316
|
onWithKey(eventName, callback, uniqueRemoveKey, masterKey)
|
|
37
317
|
{
|
|
38
|
-
if(!this.validateEventKey(eventName)
|
|
39
|
-
Logger.critical('Invalid event key detected: '+eventName
|
|
318
|
+
if(!this.validateEventKey(eventName)){
|
|
319
|
+
Logger.critical('Invalid event key detected: '+eventName);
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
if(!this.validateEventKey(uniqueRemoveKey)){
|
|
323
|
+
Logger.critical('Invalid remove key detected: '+uniqueRemoveKey);
|
|
40
324
|
return false;
|
|
41
325
|
}
|
|
42
326
|
if(masterKey && !this.validateEventKey(masterKey)){
|
|
43
327
|
Logger.critical('Invalid master key detected: '+masterKey);
|
|
44
328
|
return false;
|
|
45
329
|
}
|
|
46
|
-
if(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
&& sc.hasOwn(this.eventsByRemoveKeys[masterKey], uniqueRemoveKey)
|
|
52
|
-
)
|
|
53
|
-
){
|
|
330
|
+
if(sc.hasOwn(this.eventsByRemoveKeys, uniqueRemoveKey)){
|
|
331
|
+
Logger.debug('Event "'+eventName+'" exists with key "'+uniqueRemoveKey+'".');
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
if(masterKey && sc.hasOwn(this.eventsByRemoveKeys, masterKey) && sc.hasOwn(this.eventsByRemoveKeys[masterKey], uniqueRemoveKey)){
|
|
54
335
|
Logger.debug('Event "'+eventName+'" exists with key "'+uniqueRemoveKey+'" and masterKey "'+masterKey+'".');
|
|
55
336
|
return false;
|
|
56
337
|
}
|
|
@@ -69,10 +350,6 @@ class AwaitEventEmitterExtended extends AwaitEventEmitter
|
|
|
69
350
|
return currentListener;
|
|
70
351
|
}
|
|
71
352
|
|
|
72
|
-
/**
|
|
73
|
-
* This method will remove a SINGLE event using the unique remove key.
|
|
74
|
-
* If the event listener was assigned using a masterKey then we need to pass it as well to find the event.
|
|
75
|
-
*/
|
|
76
353
|
offWithKey(uniqueRemoveKey, masterKey)
|
|
77
354
|
{
|
|
78
355
|
if(!this.validateEventKey(uniqueRemoveKey)){
|
|
@@ -109,6 +386,7 @@ class AwaitEventEmitterExtended extends AwaitEventEmitter
|
|
|
109
386
|
if(0 === this._events[eventToRemove.eventName].length){
|
|
110
387
|
delete this._events[eventToRemove.eventName];
|
|
111
388
|
}
|
|
389
|
+
delete this._listenersCache[eventToRemove.eventName];
|
|
112
390
|
if(masterKey){
|
|
113
391
|
delete this.eventsByRemoveKeys[masterKey][uniqueRemoveKey];
|
|
114
392
|
Logger.debug('Deleted event by removeKey "'+uniqueRemoveKey+'" and masterKey "'+masterKey+'".');
|
|
@@ -119,9 +397,6 @@ class AwaitEventEmitterExtended extends AwaitEventEmitter
|
|
|
119
397
|
return true;
|
|
120
398
|
}
|
|
121
399
|
|
|
122
|
-
/**
|
|
123
|
-
* This method will remove ALL the events below the specified masterKey.
|
|
124
|
-
*/
|
|
125
400
|
offByMasterKey(masterKey)
|
|
126
401
|
{
|
|
127
402
|
if(!this.validateEventKey(masterKey)){
|
|
@@ -132,14 +407,15 @@ class AwaitEventEmitterExtended extends AwaitEventEmitter
|
|
|
132
407
|
Logger.debug('Events not found by masterKey "'+masterKey+'".');
|
|
133
408
|
return false;
|
|
134
409
|
}
|
|
135
|
-
// @NOTE: we loop all the events related to the masterKey and remove them one by one since the _events property
|
|
136
|
-
// is an object with multiple listeners attached.
|
|
137
410
|
Logger.debug('Removing events by masterKey: '+masterKey, Object.keys(this.eventsByRemoveKeys[masterKey]));
|
|
138
|
-
|
|
411
|
+
let eventsToRemove = Object.keys(this.eventsByRemoveKeys[masterKey]);
|
|
412
|
+
let affectedEvents = new Set();
|
|
413
|
+
for(let uniqueRemoveKey of eventsToRemove){
|
|
139
414
|
let eventToRemove = this.eventsByRemoveKeys[masterKey][uniqueRemoveKey];
|
|
140
415
|
if(!this.validateEventKey(eventToRemove.eventName)){
|
|
141
416
|
continue;
|
|
142
417
|
}
|
|
418
|
+
affectedEvents.add(eventToRemove.eventName);
|
|
143
419
|
let dataArr = this.listeners(eventToRemove.eventName);
|
|
144
420
|
let currentListenerIndex = dataArr.indexOf(eventToRemove.callback);
|
|
145
421
|
if(-1 === currentListenerIndex){
|
|
@@ -150,44 +426,28 @@ class AwaitEventEmitterExtended extends AwaitEventEmitter
|
|
|
150
426
|
delete this._events[eventToRemove.eventName];
|
|
151
427
|
}
|
|
152
428
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
on(key, callback)
|
|
157
|
-
{
|
|
158
|
-
if(!this.validateEventKey(key)){
|
|
159
|
-
Logger.critical('Invalid event key detected: '+key);
|
|
160
|
-
return false;
|
|
161
|
-
}
|
|
162
|
-
if(false !== this.debug){
|
|
163
|
-
this.logDebugEvent(key, 'Listen');
|
|
429
|
+
for(let eventName of affectedEvents){
|
|
430
|
+
delete this._listenersCache[eventName];
|
|
164
431
|
}
|
|
165
|
-
|
|
432
|
+
delete this.eventsByRemoveKeys[masterKey];
|
|
166
433
|
}
|
|
167
434
|
|
|
168
|
-
|
|
435
|
+
logDebugEvent(key, type, args = null)
|
|
169
436
|
{
|
|
170
|
-
if(!this.
|
|
171
|
-
|
|
172
|
-
return false;
|
|
437
|
+
if(!this._debugPatterns){
|
|
438
|
+
this._debugPatterns = new Set(this.debug.split(','));
|
|
173
439
|
}
|
|
174
|
-
if(
|
|
175
|
-
|
|
440
|
+
if(!this._debugPatterns.has('all') && !this._debugPatterns.has(key) && -1 === key.indexOf(this.debug)){
|
|
441
|
+
return;
|
|
176
442
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
{
|
|
182
|
-
if(
|
|
183
|
-
-1 !== this.debug.indexOf('all')
|
|
184
|
-
|| -1 !== this.debug.indexOf(key)
|
|
185
|
-
|| -1 !== key.indexOf(this.debug)
|
|
186
|
-
){
|
|
187
|
-
Logger.debug(type+' Event:', key);
|
|
443
|
+
let logMessage = type+' Event: '+key;
|
|
444
|
+
if(args && 0 < args.length){
|
|
445
|
+
let filteredArgs = args.map(arg => this.filterSensitiveData(arg));
|
|
446
|
+
logMessage += ' with '+filteredArgs.length+' arguments';
|
|
188
447
|
}
|
|
448
|
+
Logger.debug(logMessage);
|
|
189
449
|
}
|
|
190
450
|
|
|
191
451
|
}
|
|
192
452
|
|
|
193
|
-
module.exports =
|
|
453
|
+
module.exports = EventsManager;
|