@@ -23,25 +23,15 @@ import {
23
23
24
24
import { NOTIFICATION_TYPES } from './type' ;
25
25
import { NotificationType , NotificationPayload } from './type' ;
26
- import { Consumer } from '../utils/type' ;
26
+ import { Consumer , Fn } from '../utils/type' ;
27
+ import { EventEmitter } from '../utils/event_emitter/event_emitter' ;
27
28
28
29
const MODULE_NAME = 'NOTIFICATION_CENTER' ;
29
30
30
31
interface NotificationCenterOptions {
31
32
logger : LogHandler ;
32
33
errorHandler : ErrorHandler ;
33
34
}
34
-
35
- interface ListenerEntry {
36
- id : number ;
37
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
- callback : ( notificationData : any ) => void ;
39
- }
40
-
41
- type NotificationListeners = {
42
- [ key : string ] : ListenerEntry [ ] ;
43
- }
44
-
45
35
export interface NotificationCenter {
46
36
addNotificationListener < N extends NotificationType > (
47
37
notificationType : N ,
@@ -68,8 +58,11 @@ export interface NotificationSender {
68
58
export class DefaultNotificationCenter implements NotificationCenter , NotificationSender {
69
59
private logger : LogHandler ;
70
60
private errorHandler : ErrorHandler ;
71
- private notificationListeners : NotificationListeners ;
72
- private listenerId : number ;
61
+ private callbacks : Map < Fn , boolean > = new Map ( ) ;
62
+
63
+ private removerId = 1 ;
64
+ private eventEmitter : EventEmitter < NotificationPayload > = new EventEmitter ( ) ;
65
+ private removers : Map < number , Fn > = new Map ( ) ;
73
66
74
67
/**
75
68
* @constructor
@@ -80,13 +73,6 @@ export class DefaultNotificationCenter implements NotificationCenter, Notificati
80
73
constructor ( options : NotificationCenterOptions ) {
81
74
this . logger = options . logger ;
82
75
this . errorHandler = options . errorHandler ;
83
- this . notificationListeners = { } ;
84
- objectValues ( NOTIFICATION_TYPES ) . forEach (
85
- ( notificationTypeEnum ) => {
86
- this . notificationListeners [ notificationTypeEnum ] = [ ] ;
87
- }
88
- ) ;
89
- this . listenerId = 1 ;
90
76
}
91
77
92
78
/**
@@ -103,43 +89,36 @@ export class DefaultNotificationCenter implements NotificationCenter, Notificati
103
89
notificationType : N ,
104
90
callback : Consumer < NotificationPayload [ N ] >
105
91
) : number {
106
- try {
107
- const notificationTypeValues : string [ ] = objectValues ( NOTIFICATION_TYPES ) ;
108
- const isNotificationTypeValid = notificationTypeValues . indexOf ( notificationType ) > - 1 ;
109
- if ( ! isNotificationTypeValid ) {
110
- return - 1 ;
111
- }
112
-
113
- if ( ! this . notificationListeners [ notificationType ] ) {
114
- this . notificationListeners [ notificationType ] = [ ] ;
115
- }
116
-
117
- let callbackAlreadyAdded = false ;
118
- ( this . notificationListeners [ notificationType ] || [ ] ) . forEach (
119
- ( listenerEntry ) => {
120
- if ( listenerEntry . callback === callback ) {
121
- callbackAlreadyAdded = true ;
122
- return ;
123
- }
124
- } ) ;
125
-
126
- if ( callbackAlreadyAdded ) {
127
- return - 1 ;
128
- }
129
-
130
- this . notificationListeners [ notificationType ] . push ( {
131
- id : this . listenerId ,
132
- callback : callback ,
133
- } ) ;
134
-
135
- const returnId = this . listenerId ;
136
- this . listenerId += 1 ;
137
- return returnId ;
138
- } catch ( e : any ) {
139
- this . logger . log ( LOG_LEVEL . ERROR , e . message ) ;
140
- this . errorHandler . handleError ( e ) ;
92
+ const notificationTypeValues : string [ ] = objectValues ( NOTIFICATION_TYPES ) ;
93
+ const isNotificationTypeValid = notificationTypeValues . indexOf ( notificationType ) > - 1 ;
94
+ if ( ! isNotificationTypeValid ) {
141
95
return - 1 ;
142
96
}
97
+
98
+ const returnId = this . removerId ++ ;
99
+ const remover = this . eventEmitter . on (
100
+ notificationType , this . wrapWithErrorHandling ( notificationType , callback ) ) ;
101
+ this . removers . set ( returnId , remover ) ;
102
+ return returnId ;
103
+ }
104
+
105
+ private wrapWithErrorHandling < N extends NotificationType > (
106
+ notificationType : N ,
107
+ callback : Consumer < NotificationPayload [ N ] >
108
+ ) : Consumer < NotificationPayload [ N ] > {
109
+ return ( notificationData : NotificationPayload [ N ] ) => {
110
+ try {
111
+ callback ( notificationData ) ;
112
+ } catch ( ex : any ) {
113
+ this . logger . log (
114
+ LOG_LEVEL . ERROR ,
115
+ LOG_MESSAGES . NOTIFICATION_LISTENER_EXCEPTION ,
116
+ MODULE_NAME ,
117
+ notificationType ,
118
+ ex . message ,
119
+ ) ;
120
+ }
121
+ } ;
143
122
}
144
123
145
124
/**
@@ -149,70 +128,27 @@ export class DefaultNotificationCenter implements NotificationCenter, Notificati
149
128
* otherwise.
150
129
*/
151
130
removeNotificationListener ( listenerId : number ) : boolean {
152
- try {
153
- let indexToRemove : number | undefined ;
154
- let typeToRemove : string | undefined ;
155
-
156
- Object . keys ( this . notificationListeners ) . some (
157
- ( notificationType ) => {
158
- const listenersForType = this . notificationListeners [ notificationType ] ;
159
- ( listenersForType || [ ] ) . every ( ( listenerEntry , i ) => {
160
- if ( listenerEntry . id === listenerId ) {
161
- indexToRemove = i ;
162
- typeToRemove = notificationType ;
163
- return false ;
164
- }
165
-
166
- return true ;
167
- } ) ;
168
-
169
- if ( indexToRemove !== undefined && typeToRemove !== undefined ) {
170
- return true ;
171
- }
172
-
173
- return false ;
174
- }
175
- ) ;
176
-
177
- if ( indexToRemove !== undefined && typeToRemove !== undefined ) {
178
- this . notificationListeners [ typeToRemove ] . splice ( indexToRemove , 1 ) ;
179
- return true ;
180
- }
181
- } catch ( e : any ) {
182
- this . logger . log ( LOG_LEVEL . ERROR , e . message ) ;
183
- this . errorHandler . handleError ( e ) ;
131
+ const remover = this . removers . get ( listenerId ) ;
132
+ if ( remover ) {
133
+ remover ( ) ;
134
+ return true ;
184
135
}
185
-
186
- return false ;
136
+ return false
187
137
}
188
138
189
139
/**
190
140
* Removes all previously added notification listeners, for all notification types
191
141
*/
192
142
clearAllNotificationListeners ( ) : void {
193
- try {
194
- objectValues ( NOTIFICATION_TYPES ) . forEach (
195
- ( notificationTypeEnum ) => {
196
- this . notificationListeners [ notificationTypeEnum ] = [ ] ;
197
- }
198
- ) ;
199
- } catch ( e : any ) {
200
- this . logger . log ( LOG_LEVEL . ERROR , e . message ) ;
201
- this . errorHandler . handleError ( e ) ;
202
- }
143
+ this . eventEmitter . removeAllListeners ( ) ;
203
144
}
204
145
205
146
/**
206
147
* Remove all previously added notification listeners for the argument type
207
148
* @param {NOTIFICATION_TYPES } notificationType One of NOTIFICATION_TYPES
208
149
*/
209
150
clearNotificationListeners ( notificationType : NotificationType ) : void {
210
- try {
211
- this . notificationListeners [ notificationType ] = [ ] ;
212
- } catch ( e : any ) {
213
- this . logger . log ( LOG_LEVEL . ERROR , e . message ) ;
214
- this . errorHandler . handleError ( e ) ;
215
- }
151
+ this . eventEmitter . removeListeners ( notificationType ) ;
216
152
}
217
153
218
154
/**
@@ -225,27 +161,7 @@ export class DefaultNotificationCenter implements NotificationCenter, Notificati
225
161
notificationType : N ,
226
162
notificationData : NotificationPayload [ N ]
227
163
) : void {
228
- try {
229
- ( this . notificationListeners [ notificationType ] || [ ] ) . forEach (
230
- ( listenerEntry ) => {
231
- const callback = listenerEntry . callback ;
232
- try {
233
- callback ( notificationData ) ;
234
- } catch ( ex : any ) {
235
- this . logger . log (
236
- LOG_LEVEL . ERROR ,
237
- LOG_MESSAGES . NOTIFICATION_LISTENER_EXCEPTION ,
238
- MODULE_NAME ,
239
- notificationType ,
240
- ex . message ,
241
- ) ;
242
- }
243
- }
244
- ) ;
245
- } catch ( e : any ) {
246
- this . logger . log ( LOG_LEVEL . ERROR , e . message ) ;
247
- this . errorHandler . handleError ( e ) ;
248
- }
164
+ this . eventEmitter . emit ( notificationType , notificationData ) ;
249
165
}
250
166
}
251
167
0 commit comments