@@ -10,17 +10,39 @@ const STATE = {
1010 CONNECTED : 2 ,
1111} ;
1212
13+ class RemovableListener {
14+ /**
15+ * @param {import("react-native").EmitterSubscription } listener
16+ * @param {import("react-native").NativeEventEmitter } eventEmitter
17+ */
18+ constructor ( listener , eventEmitter ) {
19+ this . _listener = listener ;
20+ this . _eventEmitter = eventEmitter ;
21+ this . _removed = false ;
22+ }
23+
24+ isRemoved ( ) {
25+ return this . _removed ;
26+ }
27+
28+ remove ( ) {
29+ this . _eventEmitter . removeSubscription ( this . _listener ) ;
30+ this . _removed = true ;
31+ }
32+ }
33+
1334export default class TcpSocket {
1435 /**
1536 * Initialices a TcpSocket.
1637 *
17- * @param {Number } id
38+ * @param {number } id
1839 * @param {import('react-native').NativeEventEmitter } eventEmitter
1940 */
2041 constructor ( id , eventEmitter ) {
2142 this . _id = id ;
2243 this . _eventEmitter = eventEmitter ;
2344 this . _state = STATE . DISCONNECTED ;
45+ /** @type {RemovableListener[] } */
2446 this . _listeners = [ ] ;
2547 }
2648
@@ -35,10 +57,16 @@ export default class TcpSocket {
3557 */
3658 on ( event , callback , context ) {
3759 const newListener = this . _selectListener ( event , callback , context ) ;
38- this . _listeners . push ( newListener ) ;
39- return newListener ;
60+ const removableListener = new RemovableListener ( newListener , this . _eventEmitter ) ;
61+ this . _listeners . push ( removableListener ) ;
62+ return removableListener ;
4063 }
4164
65+ /**
66+ * @param {string } event
67+ * @param {function(any):void } callback
68+ * @param {any } [context]
69+ */
4270 _selectListener ( event , callback , context ) {
4371 switch ( event ) {
4472 case 'data' :
@@ -78,6 +106,10 @@ export default class TcpSocket {
78106 ) ;
79107 }
80108
109+ /**
110+ * @param {{ host: string; port: number; timeout: number; } } options
111+ * @param {(address: string) => void } [callback]
112+ */
81113 connect ( options , callback ) {
82114 this . _registerEvents ( ) ;
83115 // Normalize args
@@ -95,6 +127,10 @@ export default class TcpSocket {
95127 return this ;
96128 }
97129
130+ /**
131+ * @param {number } msecs
132+ * @param {() => void } [wrapper]
133+ */
98134 _activeTimer ( msecs , wrapper ) {
99135 if ( this . _timeout && this . _timeout . handle ) clearTimeout ( this . _timeout . handle ) ;
100136
@@ -120,12 +156,16 @@ export default class TcpSocket {
120156 }
121157 }
122158
159+ /**
160+ * @param {number } msecs
161+ * @param {{ (...args: any[]): any; (...args: any[]): any; } } [callback]
162+ */
123163 setTimeout ( msecs , callback ) {
124164 if ( msecs === 0 ) {
125165 this . _clearTimeout ( ) ;
126166 if ( callback ) this . _eventEmitter . removeListener ( 'timeout' , callback ) ;
127167 } else {
128- if ( callback ) this . _eventEmitter . once ( 'timeout' , callback ) ;
168+ if ( callback ) this . _eventEmitter . once ( 'timeout' , callback , this ) ;
129169
130170 this . _activeTimer ( msecs ) ;
131171 }
@@ -136,6 +176,10 @@ export default class TcpSocket {
136176 return this . _address ;
137177 }
138178
179+ /**
180+ * @param {string | Buffer | Uint8Array } data
181+ * @param {BufferEncoding } [encoding]
182+ */
139183 end ( data , encoding ) {
140184 if ( this . _destroyed ) return ;
141185 if ( data ) this . write ( data , encoding ) ;
@@ -153,14 +197,18 @@ export default class TcpSocket {
153197
154198 _registerEvents ( ) {
155199 this . on ( 'connect' , ( ev ) => this . _onConnect ( ev . address ) ) ;
156- this . on ( 'close' , ( ev ) => this . _onClose ( ev . hadError ) ) ;
157- this . on ( 'error' , ( ev ) => this . _onError ( ev . error ) ) ;
200+ this . on ( 'close' , ( ) => this . _onClose ( ) ) ;
201+ this . on ( 'error' , ( ) => this . _onError ( ) ) ;
158202 }
159203
160204 _unregisterEvents ( ) {
161- this . _listeners . forEach ( ( listener ) => listener . remove ( ) ) ;
205+ this . _listeners . forEach ( ( listener ) => ( listener . isRemoved ( ) ? listener . remove ( ) : null ) ) ;
206+ this . _listeners = [ ] ;
162207 }
163208
209+ /**
210+ * @param {string } address
211+ */
164212 _onConnect ( address ) {
165213 this . setConnected ( address ) ;
166214 }
@@ -176,8 +224,8 @@ export default class TcpSocket {
176224 /**
177225 *
178226 * @param {string | Buffer | Uint8Array } buffer
179- * @param {string } encoding
180- * @param {Function } callback
227+ * @param {BufferEncoding } [ encoding]
228+ * @param {(error?: string) => void } [ callback]
181229 */
182230 write ( buffer , encoding , callback ) {
183231 const self = this ;
@@ -193,13 +241,23 @@ export default class TcpSocket {
193241 `Invalid data, chunk must be a string or buffer, not ${ typeof buffer } `
194242 ) ;
195243
196- Sockets . write ( this . _id , str , function ( err ) {
197- if ( self . _timeout ) self . _activeTimer ( self . _timeout . msecs ) ;
198- if ( err ) return callback ( err ) ;
199- callback ( ) ;
200- } ) ;
244+ Sockets . write (
245+ this . _id ,
246+ str ,
247+ /**
248+ * @param {string } err
249+ */
250+ function ( err ) {
251+ if ( self . _timeout ) self . _activeTimer ( self . _timeout . msecs ) ;
252+ if ( err ) return callback ( err ) ;
253+ callback ( ) ;
254+ }
255+ ) ;
201256 }
202257
258+ /**
259+ * @param {string } address
260+ */
203261 setConnected ( address ) {
204262 this . _state = STATE . CONNECTED ;
205263 this . _address = address ;
0 commit comments