iosignal 1.1.0 → 1.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.
@@ -1,24 +1,24 @@
1
- import { MBP ,Buffer} from 'meta-buffer-pack'
1
+ import { MBP, Buffer } from 'meta-buffer-pack'
2
2
  import EventEmitter from "eventemitter3";
3
3
  import { Boho, BohoMsg, MetaSize } from "boho";
4
+ import { IOMsg, PAYLOAD_TYPE, SIZE_LIMIT, ENC_MODE, STATES } from '../common/constants.js'
4
5
  import { quotaTable } from '../common/quotaTable.js'
5
- import { IOMsg , PAYLOAD_TYPE , SIZE_LIMIT , ENC_MODE ,STATES} from '../common/constants.js'
6
+ import { getSignalPack } from '../common/payload.js';
6
7
 
7
8
  const encoder = new TextEncoder()
8
9
  const decoder = new TextDecoder()
9
10
 
10
- function byteToUrl( buffer){
11
+ function byteToUrl(buffer) {
11
12
  //ipv4(4bytes) , port(2bytes)
12
- if(buffer.byteLength != 6 ) return
13
- let address = buffer[0].toString() + "."+ buffer[1].toString()
14
- + "."+ buffer[2].toString() + "."+ buffer[3].toString();
15
- let port = (buffer[4] << 8) + buffer[5]
16
-
17
- return address +':'+ port.toString()
13
+ if (buffer.byteLength != 6) return
14
+ let address = buffer[0].toString() + "." + buffer[1].toString()
15
+ + "." + buffer[2].toString() + "." + buffer[3].toString();
16
+ let port = (buffer[4] << 8) + buffer[5]
17
+ return address + ':' + port.toString()
18
18
  }
19
19
 
20
- export class IOCore extends EventEmitter{
21
- constructor( url) {
20
+ export class IOCore extends EventEmitter {
21
+ constructor(url) {
22
22
  super();
23
23
  this.cid = "" // get from the server CID_RES
24
24
  this.ip = "" // get from the server IAM_RES message.
@@ -31,14 +31,14 @@ export class IOCore extends EventEmitter{
31
31
  this.rxCounter = 0;
32
32
  this.txBytes = 0;
33
33
  this.rxBytes = 0;
34
-
34
+
35
35
  this.lastTxRxTime = Date.now();
36
- this.connectionCheckerPeriod = SIZE_LIMIT.CONNECTION_CHECKER_PERIOD ;
36
+ this.connectionCheckerPeriod = SIZE_LIMIT.CONNECTION_CHECKER_PERIOD;
37
37
  this.connectionCheckerIntervalID = null;
38
38
 
39
39
  this.boho = new Boho()
40
40
  this.TLS = false // true if protocol is wss(TLS)
41
- this.encMode = ENC_MODE.AUTO;
41
+ this.encMode = ENC_MODE.AUTO;
42
42
  this.useAuth = false;
43
43
 
44
44
  this.nick = "";
@@ -48,440 +48,410 @@ export class IOCore extends EventEmitter{
48
48
  this.mid = 0 // promise message id
49
49
 
50
50
  this.level = 0; // also defaultQuotaLevel
51
- this.quota = quotaTable[ this.level ];
51
+ this.quota = quotaTable[this.level];
52
52
  this.serverSet = {}
53
-
54
53
  this.linkMap = new Map()
55
54
 
56
- this.on('open',this.onOpen.bind(this))
57
- this.on('close',this.onClose.bind(this))
58
- this.on('socket_data',this.onData.bind(this))
59
- // this.on('auth_fail',this.onAuthFail.bind(this))
60
- // this.on('server_signal', this.onServerSignal.bind(this))
55
+ this.on('open', this.onOpen.bind(this))
56
+ this.on('close', this.onClose.bind(this))
57
+ this.on('socket_data', this.onData.bind(this))
61
58
  }
62
59
 
63
60
 
64
- // onAuthFail(event, reason){
65
- // }
66
-
67
- // onServerSignal(event, data ){
68
- // console.log('onServerSignal', event, data )
69
- // }
70
-
71
- redirect(url2){
61
+ redirect(url2) {
72
62
  this.close()
73
63
  this.stateChange('redirecting')
74
- this.createConnection( url2)
64
+ this.createConnection(url2)
75
65
  }
76
66
 
77
- open(url ) {
78
- if( !url && !this.url ) return;
67
+ open(url) {
68
+ if (!url && !this.url) return;
79
69
 
80
- if( url ){
81
- if( !this.url ){ // default host url
82
- this.url = url
83
- }else if( url !== this.url ){ // default host url change
84
- this.url = url;
85
- if( this.socket ){
86
- this.close()
87
- return
88
- }
70
+ if (url) {
71
+ if (!this.url) { // default host url
72
+ this.url = url
73
+ } else if (url !== this.url) { // default host url change
74
+ this.url = url;
75
+ if (this.socket) {
76
+ this.close()
77
+ return
89
78
  }
79
+ }
90
80
  }
91
81
 
92
- this.createConnection( this.url )
93
-
94
- if(!this.connectionCheckerIntervalID){
82
+ this.createConnection(this.url)
83
+
84
+ if (!this.connectionCheckerIntervalID) {
95
85
  this.connectionCheckerIntervalID = setInterval(this.keepAlive.bind(this), this.connectionCheckerPeriod);
96
- }
86
+ }
97
87
  }
98
88
 
99
- onOpen( ){
100
- if( this.url.includes("wss://" )){
89
+ onOpen() {
90
+ if (this.url.includes("wss://")) {
101
91
  this.TLS = true;
102
- }else{
92
+ } else {
103
93
  this.TLS = false;
104
94
  }
105
- this.stateChange('open' )
95
+ this.stateChange('open')
106
96
  }
107
97
 
108
- onClose(){
98
+ onClose() {
109
99
  this.boho.isAuthorized = false;
110
100
  this.cid = ""
111
- this.stateChange('closed' )
101
+ this.stateChange('closed')
112
102
  }
113
103
 
114
104
  // manual login
115
- login( id, key){
116
- if( !id && !key){
105
+ login(id, key) {
106
+ if (!id && !key) {
117
107
  console.log('no id and key.')
118
108
  return
119
- }
109
+ }
120
110
  console.log('manual login: ', id)
121
111
 
122
- if( !key && id.includes('.') ){
112
+ if (!key && id.includes('.')) {
123
113
  this.boho.set_id_key(id)
124
- }else if( id && key){
114
+ } else if (id && key) {
125
115
  this.boho.set_id8(id)
126
116
  this.boho.set_key(key)
127
- }else{
117
+ } else {
128
118
  console.log('no id or key.')
129
119
  return
130
120
  }
131
121
  this.useAuth = true
132
122
  let auth_pack = this.boho.auth_req()
133
123
  // console.log('auth_req_pack', auth_pack )
134
- this.send(auth_pack )
124
+ this.send(auth_pack)
135
125
  }
136
126
 
137
127
  // auto login
138
- auth( id, key){
139
- if( !id && !key){
128
+ auth(id, key) {
129
+ if (!id && !key) {
140
130
  console.log('no id and key.')
141
131
  return
142
- }
143
- // console.log('set auto auth: ', id)
132
+ }
144
133
 
145
- if( !key && id.includes('.') ){
134
+ if (!key && id.includes('.')) {
146
135
  this.boho.set_id_key(id)
147
- }else if( id && key){
136
+ } else if (id && key) {
148
137
  this.boho.set_id8(id)
149
138
  this.boho.set_key(key)
150
- }else{
139
+ } else {
151
140
  console.log('no id or key.')
152
141
  return
153
142
  }
154
143
  this.useAuth = true
155
144
  }
156
145
 
157
- onData( buffer ){
146
+ onData(buffer) {
158
147
  // console.log('remote rcv socket_message', buffer )
159
148
  //check first byte (remote message type)
160
- let msgType = buffer[0];
161
- let decoded;
149
+ let msgType = buffer[0];
150
+ let decoded;
162
151
 
163
- if( msgType === BohoMsg.ENC_488 ){
164
- decoded = this.boho.decrypt_488( buffer )
165
- if( decoded ){
166
- // console.log( decoded )
152
+ if (msgType === BohoMsg.ENC_488) {
153
+ decoded = this.boho.decrypt_488(buffer)
154
+ if (decoded) {
155
+ // console.log( decoded )
167
156
  msgType = decoded[0]
168
- buffer = decoded
157
+ buffer = decoded
169
158
  // console.log('DECODED MsgType:', IOMsg[ msgType ] )
170
- }else{
171
- console.log('DEC_FAIL', buffer.byteLength)
172
- }
173
- }else if( msgType === BohoMsg.ENC_E2E ){
159
+ } else {
160
+ // console.log('DEC_FAIL', buffer.byteLength)
161
+ }
162
+ } else if (msgType === BohoMsg.ENC_E2E) {
174
163
  // console.log('rcv ENC_E2E' )
175
164
 
176
- try{
177
- decoded = this.boho.decrypt_488( buffer )
165
+ try {
166
+ decoded = this.boho.decrypt_488(buffer)
178
167
  //헤더를 읽고 헤더크기만큼만 해석한다.
179
- if( decoded ){
168
+ if (decoded) {
180
169
  // console.log( 'ENC_E2E decoded ', decoded )
181
170
  msgType = decoded[0]
182
171
  // decoded has msg_header only.
183
- buffer.set( decoded ,MetaSize.ENC_488) // set decoded signal_e2e headaer.
184
- buffer = buffer.subarray( MetaSize.ENC_488 ) // reset offset.
185
- // console.log('DECODED MsgType:', IOMsg[ msgType ] )
186
- }else{
187
- console.log('488 DEC_FAIL', buffer)
188
- return
189
- }
172
+ buffer.set(decoded, MetaSize.ENC_488) // set decoded signal_e2e headaer.
173
+ buffer = buffer.subarray(MetaSize.ENC_488) // reset offset.
174
+ // console.log('DECODED MsgType:', IOMsg[ msgType ] )
175
+ } else {
176
+ // console.log('488 DEC_FAIL', buffer)
177
+ return
178
+ }
190
179
 
191
- }catch(err){
192
- console.log('E2E DEC_FAIL decryption error', err)
180
+ } catch (err) {
181
+ // console.log('E2E DEC_FAIL decryption error', err)
193
182
  return
194
183
  }
195
184
 
196
- }
185
+ }
197
186
 
198
- let type = IOMsg[ msgType ]
199
- if( !type ) type = BohoMsg[ msgType ]
187
+ let type = IOMsg[msgType]
188
+ if (!type) type = BohoMsg[msgType]
200
189
 
201
- // console.log( "MsgType: ", type , " LEN ", buffer.byteLength)
190
+ // console.log( "MsgType: ", type , " LEN ", buffer.byteLength)
202
191
 
203
- switch( msgType){
204
- case IOMsg.OVER_SIZE :
192
+ switch (msgType) {
193
+ case IOMsg.OVER_SIZE:
205
194
  console.log('## server sent: over_size event.')
206
- this.emit('over_size','over_size')
207
- break;
208
- case IOMsg.PING :
209
- this.pong();
210
- break;
195
+ this.emit('over_size', 'over_size')
196
+ break;
197
+ case IOMsg.PING:
198
+ this.pong();
199
+ break;
211
200
 
212
- case IOMsg.PONG :
213
- break;
201
+ case IOMsg.PONG:
202
+ break;
214
203
 
215
204
  case IOMsg.IAM_RES:
216
- try {
217
- let str = decoder.decode( buffer.subarray(1) )
218
- let jsonInfo = JSON.parse(str)
219
- if( jsonInfo.ip ){
220
- this.ip = jsonInfo.ip;
221
- }
222
- console.log('<IAM_RES>', JSON.stringify(jsonInfo))
223
- // console.log('<IAM_RES>', JSON.stringify(jsonInfo,null,2))
224
- } catch (error) {
225
- console.log('<IAM_RES> data error')
205
+ try {
206
+ let str = decoder.decode(buffer.subarray(1))
207
+ let jsonInfo = JSON.parse(str)
208
+ if (jsonInfo.ip) {
209
+ this.ip = jsonInfo.ip;
226
210
  }
227
- break;
228
-
229
- case IOMsg.CID_RES :
230
- let cidStr = decoder.decode( buffer.subarray(1) )
231
- // console.log( '>> CID_RES: ' ,cidStr )
232
- this.cid = cidStr;
233
- this.stateChange('ready','cid_ready' )
234
- // change state before subscribe.
235
- this.subscribe_memory_channels()
236
- break;
237
-
238
- case IOMsg.QUOTA_LEVEL :
239
- let quotaLevel = buffer[1]
240
- this.level = quotaLevel;
241
- this.quota = quotaTable[ quotaLevel ];
242
- console.log('## QUOTA:', quotaLevel, JSON.stringify(this.quota) )
243
- break;
244
-
245
- case IOMsg.SERVER_CLEAR_AUTH :
246
- this.useAuth = false;
247
- this.boho.clearAuth();
248
- this.stop();
249
- break;
250
-
251
- case IOMsg.SERVER_REDIRECT :
252
- // console.log( buffer.toString('hex'))
253
- let host_port;
254
- let url;
255
- let protocol;
256
- let addressType;
257
- if( buffer.byteLength == 7){ // ipv4 ,port
258
- addressType = 'IPV4:PORT'
259
- host_port = byteToUrl( buffer.subarray(1))
260
- protocol = 'cong://'
261
- }else{ // domain url
262
- addressType= 'URL'
263
- host_port = decoder.decode( buffer.subarray(1))
264
- protocol = '' // must included in url
265
- }
211
+ console.log('<IAM_RES>', JSON.stringify(jsonInfo))
212
+ // console.log('<IAM_RES>', JSON.stringify(jsonInfo,null,2))
213
+ } catch (error) {
214
+ // console.log('<IAM_RES> data error')
215
+ }
216
+ break;
266
217
 
267
- url = protocol + host_port
268
-
269
- console.log(`REDIRECT TO <${addressType}> : ${url}` )
270
- this.redirect(url)
271
- break;
272
-
273
- case IOMsg.SERVER_READY :
274
- // console.log('>> SERVER_READY')
275
- this.stateChange('server_ready','server_ready' )
276
- if(this.useAuth){
277
- this.send( this.boho.auth_req() )
278
- // CID_REQ will be called, after auth_ack.
279
- }else{
280
- // CID_REQ here, if not using auth.
281
- this.send( Buffer.from([IOMsg.CID_REQ]) )
282
- }
283
- break;
284
-
285
- case IOMsg.SERVER_SIGNAL:
218
+ case IOMsg.CID_RES:
219
+ let cidStr = decoder.decode(buffer.subarray(1))
220
+ // console.log( '>> CID_RES: ' ,cidStr )
221
+ this.cid = cidStr;
222
+ // change state before subscribe.
223
+ this.stateChange('ready', 'cid_ready')
224
+ this.subscribe_memory_channels()
225
+ break;
226
+
227
+ case IOMsg.QUOTA_LEVEL:
228
+ let quotaLevel = buffer[1]
229
+ this.level = quotaLevel;
230
+ this.quota = quotaTable[quotaLevel];
231
+ console.log('## QUOTA:', quotaLevel, JSON.stringify(this.quota))
232
+ break;
233
+
234
+ case IOMsg.SERVER_CLEAR_AUTH:
235
+ this.useAuth = false;
236
+ this.boho.clearAuth();
237
+ this.stop();
238
+ break;
239
+
240
+ case IOMsg.SERVER_REDIRECT:
241
+ let host_port;
242
+ let url;
243
+ let protocol;
244
+ let addressType;
245
+ if (buffer.byteLength == 7) { // ipv4 ,port
246
+ addressType = 'IPV4:PORT'
247
+ host_port = byteToUrl(buffer.subarray(1))
248
+ protocol = 'cong://'
249
+ } else { // domain url
250
+ addressType = 'URL'
251
+ host_port = decoder.decode(buffer.subarray(1))
252
+ protocol = ''
253
+ }
254
+
255
+ url = protocol + host_port
256
+ this.redirect(url)
257
+ break;
258
+
259
+ case IOMsg.SERVER_READY:
260
+ this.stateChange('server_ready', 'server_ready')
261
+ if (this.useAuth) {
262
+ this.send(this.boho.auth_req())
263
+ // CID_REQ will be called, after auth_ack.
264
+ } else {
265
+ // CID_REQ here, if not using auth.
266
+ this.send(Buffer.from([IOMsg.CID_REQ]))
267
+ }
268
+ break;
269
+
270
+ case IOMsg.SERVER_SIGNAL:
286
271
  try {
287
- let str = decoder.decode( buffer.subarray(1) )
288
- let ss = JSON.parse(str)
289
- console.log('SERVER_SIGNAL', JSON.stringify(ss))
272
+ let str = decoder.decode(buffer.subarray(1))
273
+ let ss = JSON.parse(str)
274
+ // console.log('SERVER_SIGNAL', JSON.stringify(ss))
290
275
 
291
- if( ss.event && ss.data ){
276
+ if (ss.event && ss.data) {
292
277
  this.serverSet = ss.data;
293
- this.emit( ss.event , ss.data )
278
+ this.emit(ss.event, ss.data)
294
279
  }
295
-
280
+
296
281
  } catch (error) {
297
- console.log('<SERVER_SIGNAL> parsing error')
282
+ // console.log('<SERVER_SIGNAL> parsing error')
298
283
  }
299
- break;
284
+ break;
300
285
 
301
- case IOMsg.SET:
286
+ case IOMsg.SET:
302
287
  try {
303
288
  let setPack = MBP.unpack(buffer)
304
- if(setPack ){
305
- console.log('[SET] topic: ',setPack.topic )
306
- this.emit( setPack.topic, ...setPack.args )
289
+ if (setPack) {
290
+ // console.log('[SET] topic: ', setPack.topic)
291
+ this.emit(setPack.topic, ...setPack.args)
307
292
  }
308
293
  } catch (error) {
309
- console.log('<SET> parsing error')
294
+ // console.log('<SET> parsing error')
310
295
  }
311
- break;
296
+ break;
312
297
 
313
- case IOMsg.SIGNAL_E2E:
314
- case IOMsg.SIGNAL:
315
- try{
298
+ case IOMsg.SIGNAL_E2E:
299
+ case IOMsg.SIGNAL:
300
+ try {
316
301
  let tagLen = buffer.readUint8(1)
317
- let tagBuf = buffer.subarray(2, 2 + tagLen )
302
+ let tagBuf = buffer.subarray(2, 2 + tagLen)
318
303
  let tag = decoder.decode(tagBuf)
319
304
 
320
- let payloadType = buffer.readUint8( 2 + tagLen )
321
- let payloadBuffer = buffer.subarray( 3 + tagLen )
322
-
305
+ let payloadType = buffer.readUint8(2 + tagLen)
306
+ let payloadBuffer = buffer.subarray(3 + tagLen)
307
+
323
308
  /* three types of signal message.
324
309
  > unicast message to me: tag includes @, no cid: '@*'
325
310
  > cid_sub message: tag includes cid and @ both : 'cid@*'
326
311
  > ch_sub message: else.
327
312
  */
328
-
329
-
330
- switch( payloadType ){
313
+ switch (payloadType) {
331
314
 
332
315
  case PAYLOAD_TYPE.EMPTY: // 0
333
- if( tag.indexOf('@') === 0 ) this.emit( '@', null , tag)
334
- else this.emit( tag, null , tag )
316
+ if (tag.indexOf('@') === 0) this.emit('@', null, tag)
317
+ else this.emit(tag, null, tag)
335
318
  break;
336
319
 
337
320
  case PAYLOAD_TYPE.TEXT: // 1
338
- // !! Must remove null char before decode in JS.
339
- // string payload contains null char for the c/cpp devices.
340
- let payloadStringWithoutNull = payloadBuffer.subarray(0,payloadBuffer.byteLength - 1 )
341
- let oneString = decoder.decode( payloadStringWithoutNull )
342
- if( tag.indexOf('@') === 0 ) this.emit( '@', oneString , tag )
343
- if( tag !== '@') this.emit( tag, oneString , tag )
321
+ // !! Must remove null char before decode in JS.
322
+ // string payload contains null char for the c/cpp devices.
323
+ let payloadStringWithoutNull = payloadBuffer.subarray(0, payloadBuffer.byteLength - 1)
324
+ let oneString = decoder.decode(payloadStringWithoutNull)
325
+ if (tag.indexOf('@') === 0) this.emit('@', oneString, tag)
326
+ if (tag !== '@') this.emit(tag, oneString, tag)
344
327
  break;
345
-
328
+
346
329
  case PAYLOAD_TYPE.BINARY: // 2
347
- if( tag.indexOf('@') === 0 ) this.emit( '@', payloadBuffer , tag )
348
- if( tag !== '@') this.emit( tag, payloadBuffer , tag )
330
+ if (tag.indexOf('@') === 0) this.emit('@', payloadBuffer, tag)
331
+ if (tag !== '@') this.emit(tag, payloadBuffer, tag)
349
332
  break;
350
333
 
351
334
  case PAYLOAD_TYPE.OBJECT:
352
- let oneObjectBuffer = decoder.decode( payloadBuffer )
353
- let oneJSONObject = JSON.parse( oneObjectBuffer )
354
- if( tag.indexOf('@') === 0 ) this.emit( '@', oneJSONObject , tag )
355
- if( tag !== '@') this.emit( tag, oneJSONObject , tag )
356
- break;
357
-
358
- case PAYLOAD_TYPE.MJSON:
359
- let mjsonBuffer = decoder.decode( payloadBuffer )
360
- // console.log('raw mjson tag', tag)
361
- // console.log('raw mjson', mjsonBuffer)
362
- let mjson = JSON.parse( mjsonBuffer )
363
- // console.log('parsed mjson', mjson)
364
- if( tag.indexOf('@') === 0 ) this.emit( '@', ...mjson , tag )
365
- if( tag !== '@') this.emit( tag, ...mjson , tag )
335
+ let oneObjectBuffer = decoder.decode(payloadBuffer)
336
+ let oneJSONObject = JSON.parse(oneObjectBuffer)
337
+ if (tag.indexOf('@') === 0) this.emit('@', oneJSONObject, tag)
338
+ if (tag !== '@') this.emit(tag, oneJSONObject, tag)
366
339
  break;
367
340
 
368
- case PAYLOAD_TYPE.MBA:
369
- let mbaObject = MBP.unpack( buffer )
370
- if( tag.indexOf('@') === 0 ) this.emit( '@', ...mbaObject.args , tag )
371
- if( tag !== '@') this.emit( tag, ...mbaObject.args , tag )
341
+ case PAYLOAD_TYPE.MJSON:
342
+ let mjsonBuffer = decoder.decode(payloadBuffer)
343
+ let mjson = JSON.parse(mjsonBuffer)
344
+ if (tag.indexOf('@') === 0) this.emit('@', ...mjson, tag)
345
+ if (tag !== '@') this.emit(tag, ...mjson, tag)
372
346
  break;
373
347
 
374
- default:
375
- console.log('## Unkown payloadtype', payloadType)
348
+ case PAYLOAD_TYPE.MBA:
349
+ let mbaObject = MBP.unpack(buffer)
350
+ if (tag.indexOf('@') === 0) this.emit('@', ...mbaObject.args, tag)
351
+ if (tag !== '@') this.emit(tag, ...mbaObject.args, tag)
352
+ break;
376
353
 
354
+ default:
355
+ // console.log('## Unkown payloadtype', payloadType)
377
356
  }
378
357
 
379
-
380
- }catch(err){
381
- console.log('## signal parse err',err)
358
+ } catch (err) {
359
+ // console.log('## signal parse err', err)
382
360
  }
383
361
  break;
384
362
 
385
-
386
-
387
363
  case IOMsg.RESPONSE_MBP:
388
- this.testPromise( buffer)
364
+ this.testPromise(buffer)
389
365
  break;
390
366
 
391
-
392
-
393
367
  case BohoMsg.AUTH_NONCE:
394
- // console.log('auth_nonce', buffer )
395
- let auth_hmac = this.boho.auth_hmac( buffer )
396
- if(auth_hmac){
397
- this.send( auth_hmac )
398
- }else{
399
- this.stateChange('auth_fail', 'Invalid local auth_hmac.' )
400
- console.log('auth_fail', 'Invalid local auth_hmac.' )
368
+ let auth_hmac = this.boho.auth_hmac(buffer)
369
+ if (auth_hmac) {
370
+ this.send(auth_hmac)
371
+ } else {
372
+ this.stateChange('auth_fail', 'Invalid local auth_hmac.')
401
373
  }
402
374
  break;
403
- case BohoMsg.AUTH_FAIL:
404
- this.stateChange('auth_fail','server reject auth.' )
405
- console.log('auth_fail', 'server reject auth.' )
406
- break;
407
- case BohoMsg.AUTH_ACK:
408
- if(this.boho.check_auth_ack_hmac( buffer ) ){
409
- // this.emit('authorized' );
410
- this.stateChange('auth_ready','server sent auth_ack' )
411
- this.send( Buffer.from([IOMsg.CID_REQ ]) )
412
- }else{
413
- // this.emit('auth_fail','invalid server hmac')
414
- this.stateChange('auth_fail','invalid server_hmac' )
415
- console.log('auth_fail', 'Invalid server hmac.' )
375
+
376
+ case BohoMsg.AUTH_FAIL:
377
+ this.stateChange('auth_fail', 'server reject auth.')
378
+ break;
379
+
380
+ case BohoMsg.AUTH_ACK:
381
+ if (this.boho.check_auth_ack_hmac(buffer)) {
382
+ this.stateChange('auth_ready', 'server sent auth_ack')
383
+ this.send(Buffer.from([IOMsg.CID_REQ]))
384
+ } else {
385
+ this.stateChange('auth_fail', 'invalid server_hmac')
416
386
  }
417
387
  break;
418
-
388
+
419
389
  default:
420
390
  try {
421
- decoded = decoder.decode( buffer )
422
- // console.log('text message:', decoded)
423
- this.emit('text_message', decoded)
391
+ decoded = decoder.decode(buffer)
392
+ // console.log('text message:', decoded)
393
+ this.emit('text_message', decoded)
424
394
  } catch (error) {
425
-
426
- }
395
+
396
+ }
427
397
 
428
398
  break;
429
399
 
430
400
  }
431
401
  }
432
402
 
433
- iam( title ){
403
+ iam(title) {
434
404
  // console.log('iam', title)
435
- if(title ){
436
- this.send_enc_mode( MBP.pack(
437
- MBP.MB('#MsgType','8', IOMsg.IAM ) ,
438
- MBP.MB('#', title )
439
- ))
440
- }else{
441
- this.send_enc_mode( MBP.pack(
442
- MBP.MB('#MsgType','8', IOMsg.IAM )
443
- ))
405
+ if (title) {
406
+ this.send_enc_mode(MBP.pack(
407
+ MBP.MB('#MsgType', '8', IOMsg.IAM),
408
+ MBP.MB('#', title)
409
+ ))
410
+ } else {
411
+ this.send_enc_mode(MBP.pack(
412
+ MBP.MB('#MsgType', '8', IOMsg.IAM)
413
+ ))
444
414
  }
445
415
  }
446
416
 
447
417
 
448
- ping(){
449
- this.send( Buffer.from( [ IOMsg.PING ]))
418
+ ping() {
419
+ this.send(Buffer.from([IOMsg.PING]))
450
420
  }
451
421
 
452
- pong(){
453
- this.send( Buffer.from( [ IOMsg.PONG ]))
422
+ pong() {
423
+ this.send(Buffer.from([IOMsg.PONG]))
454
424
  }
455
425
 
456
426
 
457
427
  // application level ping tool.
458
428
  // simple message sending and reply.
459
- echo( args ){
460
- if(args ){
461
- console.log( 'echo args:', args )
462
- this.send_enc_mode( MBP.pack(
463
- MBP.MB('#MsgType','8', IOMsg.ECHO ) ,
464
- MBP.MB('#msg', args )
429
+ echo(args) {
430
+ if (args) {
431
+ console.log('echo args:', args)
432
+ this.send_enc_mode(MBP.pack(
433
+ MBP.MB('#MsgType', '8', IOMsg.ECHO),
434
+ MBP.MB('#msg', args)
465
435
  ))
466
- }else{
436
+ } else {
467
437
  // # do not encrypt blank echo #
468
- this.send( Buffer.from([ IOMsg.ECHO ]))
438
+ this.send(Buffer.from([IOMsg.ECHO]))
469
439
  }
470
440
  }
471
441
 
472
442
 
473
- bin(...data){
474
- this.send( MBP.U8pack( ...data) )
443
+ bin(...data) {
444
+ this.send(MBP.U8pack(...data))
475
445
  }
476
446
 
477
- send( data ){
478
- if( data.byteLength > this.quota.signalSize ){
447
+ send(data) {
448
+ if (data.byteLength > this.quota.signalSize) {
479
449
  this.emit('over_size')
480
- console.log('## QUOTA LIMIT OVER!! \nsignal message.byteLength: ', data.byteLength )
481
- console.log('## your maximum signalSize(bytes) is:', this.quota.signalSize )
450
+ console.log('## QUOTA LIMIT OVER!! \nsignal message.byteLength: ', data.byteLength)
451
+ console.log('## your maximum signalSize(bytes) is:', this.quota.signalSize)
482
452
  return
483
453
  }
484
- this.socket_send( data );
454
+ this.socket_send(data);
485
455
  }
486
456
 
487
457
  /*
@@ -500,385 +470,307 @@ export class IOCore extends EventEmitter{
500
470
  NO. do not ecnrypt message.
501
471
 
502
472
  */
503
- getEncryptionMode(){
504
- if( this.encMode === ENC_MODE.YES ||
505
- this.encMode === ENC_MODE.AUTO &&
473
+ getEncryptionMode() {
474
+ if (this.encMode === ENC_MODE.YES ||
475
+ this.encMode === ENC_MODE.AUTO &&
506
476
  !this.TLS && this.boho.isAuthorized
507
- ){
508
- return true;
509
- }else{
510
- return false
511
- }
477
+ ) {
478
+ return true;
479
+ } else {
480
+ return false
481
+ }
512
482
  }
513
483
 
514
- send_enc_mode( data ,useEncryption ){
515
-
484
+ send_enc_mode(data, useEncryption) {
485
+
516
486
  // use default policy.
517
- if( useEncryption === undefined){
487
+ if (useEncryption === undefined) {
518
488
  useEncryption = this.getEncryptionMode()
519
489
  }
520
-
521
- if( data[0] == IOMsg.SIGNAL_E2E && useEncryption){
490
+
491
+ if (data[0] == IOMsg.SIGNAL_E2E && useEncryption) {
522
492
  // input data: signal_header + e2ePayload
523
493
  // encrypt signal_header area only. payload is encrypted with e2e key already.
524
494
  let tagLen = data[1]
525
- let encHeader = this.boho.encrypt_488( data.subarray(0, 3 + tagLen))
495
+ let encHeader = this.boho.encrypt_488(data.subarray(0, 3 + tagLen))
526
496
  encHeader[0] = BohoMsg.ENC_E2E
527
- this.send( Buffer.concat([encHeader, data.subarray(3+tagLen) ]))
497
+ this.send(Buffer.concat([encHeader, data.subarray(3 + tagLen)]))
528
498
  // console.log('<< send_enc_mode [ ENC_E2E ]')
529
-
530
- }else if( useEncryption ){
499
+
500
+ } else if (useEncryption) {
531
501
  // console.log('<< send_enc_mode [ ENC_488 ]')
532
- let encPack = this.boho.encrypt_488( data )
533
- this.send( encPack )
534
- }else{
502
+ let encPack = this.boho.encrypt_488(data)
503
+ this.send(encPack)
504
+ } else {
535
505
  // console.log('<< send_enc_mode [ PLAIN ]' )
536
- this.send( data )
506
+ this.send(data)
537
507
  }
538
508
 
539
509
  }
540
510
 
541
-
542
- setMsgPromise(mid ){
543
- return new Promise( (resolve, reject)=>{
544
- this.promiseMap.set( mid, [resolve, reject ] )
511
+
512
+ setMsgPromise(mid) {
513
+ return new Promise((resolve, reject) => {
514
+ this.promiseMap.set(mid, [resolve, reject])
545
515
  // console.log('set promise. mid, size', mid, this.promiseMap.size)
546
- setTimeout( e=>{
547
- if(this.promiseMap.has(mid )){
516
+ setTimeout(e => {
517
+ if (this.promiseMap.has(mid)) {
548
518
  reject('timeout');
549
- this.promiseMap.delete( mid )
519
+ this.promiseMap.delete(mid)
550
520
  // console.log('promise timeout. mid, size:', mid, this.promiseMap.size)
551
521
  }
552
522
  }, this.promiseTimeOut);
553
523
  })
554
524
  }
555
525
 
556
- testPromise( buffer ){
526
+ testPromise(buffer) {
557
527
  // console.log('mbp buffer : ', buffer , buffer.byteLength)
558
528
  // let mbp = ( buffer.byteLength > 4 ) ? buffer.subarray(4) : ""
559
529
 
560
530
  let res = MBP.unpack(buffer)
561
- if( !res ) return
531
+ if (!res) return
562
532
  // console.log( res )
563
533
 
564
534
  // console.log(`RESPONSE_MBP MID: ${mid} status: ${status} ,mbp: ${ buffer.subarray(4)} `)
565
535
 
566
- if( this.promiseMap.has(res.mid)){
536
+ if (this.promiseMap.has(res.mid)) {
567
537
  // console.log('res promise msg', mid)
568
- let [ resolve, reject ] = this.promiseMap.get( res.mid )
569
- this.promiseMap.delete( res.mid )
538
+ let [resolve, reject] = this.promiseMap.get(res.mid)
539
+ this.promiseMap.delete(res.mid)
570
540
 
571
- if(res.status < 128){
541
+ if (res.status < 128) {
572
542
  res.ok = true;
573
543
  // console.log( 'unpack meta:', meta)
574
- resolve( res )
575
- } else{
576
- res.ok = false ;
577
- reject ( res )
578
- }
579
-
580
-
581
- }else{
582
- console.log('no promise id')
583
- }
584
- }
585
-
586
-
587
- publish( ...args ){
588
- this.signal( ...args )
589
- }
590
-
591
-
592
- parsePayload( args ){
593
- // console.log( 'parsePayload args', args )
594
- let type, pack;
595
- if( args.length == 0){
596
- type = PAYLOAD_TYPE.EMPTY
597
- pack = null
598
- }else if( args.length == 1){
599
- if( typeof args[0] === 'string' || typeof args[0] === 'number'){
600
- type = PAYLOAD_TYPE.TEXT
601
- pack = encoder.encode( args[0] + ".") // add null area.
602
- pack[pack.byteLength - 1 ] = 0 // set null.
603
-
604
- }else if( ArrayBuffer.isView( args[0]) || args[0] instanceof ArrayBuffer ){ //one buffer
605
- type = PAYLOAD_TYPE.BINARY
606
- pack = MBP.B8( args[0 ] )
607
- }else if(typeof args[0] === 'object'){
608
- type = PAYLOAD_TYPE.OBJECT
609
- pack = encoder.encode( JSON.stringify( args[0]) )
610
- }else{
611
- //
612
- console.log('unknown type payload arguments')
544
+ resolve(res)
545
+ } else {
546
+ res.ok = false;
547
+ reject(res)
613
548
  }
614
- }else{ // args 2 and more
615
- let containsBuffer = false
616
- args.forEach( item =>{
617
- if( ArrayBuffer.isView( item ) || item instanceof ArrayBuffer ) containsBuffer = true;
618
- // console.log('payload item', item )
619
- })
620
549
 
621
- if( containsBuffer ){
622
- type = PAYLOAD_TYPE.MBA;
623
- // pack
624
- }else{
625
- type = PAYLOAD_TYPE.MJSON;
626
- // args is array
627
- pack = encoder.encode( JSON.stringify( args ) )
628
- }
629
-
630
- }
631
-
632
- return { type: type, buffer: pack }
633
550
 
634
- }
551
+ } else {
552
+ console.log('no promise id')
553
+ }
554
+ }
635
555
 
636
- get_signal_pack( tag, ...args ){
637
- if( typeof tag !== 'string') throw TypeError('tag should be string.')
638
- let tagEncoded = encoder.encode( tag)
639
- let payload = this.parsePayload( args )
640
556
 
641
- let sigPack;
642
- if( payload.type == PAYLOAD_TYPE.EMPTY ){
643
- sigPack = MBP.pack(
644
- MBP.MB('#MsgType','8', IOMsg.SIGNAL) ,
645
- MBP.MB('#tagLen','8', tagEncoded.byteLength),
646
- MBP.MB('#tag', tagEncoded),
647
- MBP.MB('#payloadType', '8', payload.type )
648
- )
649
- }else if( payload.type == PAYLOAD_TYPE.MBA ){
650
- sigPack = MBP.pack(
651
- MBP.MB('#MsgType','8', IOMsg.SIGNAL) ,
652
- MBP.MB('#tagLen','8', tagEncoded.byteLength),
653
- MBP.MB('#tag', tagEncoded),
654
- MBP.MB('#payloadType', '8', payload.type ),
655
- MBP.MBA(...args)
656
- )
657
- }else {
658
- sigPack = MBP.pack(
659
- MBP.MB('#MsgType','8', IOMsg.SIGNAL) ,
660
- MBP.MB('#tagLen','8', tagEncoded.byteLength),
661
- MBP.MB('#tag', tagEncoded),
662
- MBP.MB('#payloadType', '8', payload.type ),
663
- MBP.MB('#payload', payload.buffer )
664
- )
665
- }
666
- return sigPack
557
+ publish(...args) {
558
+ this.signal(...args)
667
559
  }
668
560
 
669
561
 
670
- signal( tag , ...args ){
671
- if( typeof tag !== 'string') throw TypeError('tag should be string.')
562
+ signal(tag, ...args) {
563
+ if (typeof tag !== 'string') throw TypeError('tag should be string.')
672
564
 
673
- let signalPack = this.get_signal_pack(tag, ...args )
674
- this.send_enc_mode( signalPack )
565
+ let signalPack = getSignalPack(tag, ...args)
566
+ this.send_enc_mode(signalPack)
675
567
  }
676
568
 
677
- decrypt_e2e( data, key ){
678
- return this.boho.decrypt_e2e( data, key )
569
+ decrypt_e2e(data, key) {
570
+ return this.boho.decrypt_e2e(data, key)
679
571
  }
680
572
 
681
- signal_e2e( tag , data, key){
573
+ signal_e2e(tag, data, key) {
682
574
 
683
- if( typeof tag !== 'string') throw TypeError('tag should be string.')
684
- let tagEncoded = encoder.encode( tag)
685
- let dataPack = MBP.B8( data )
575
+ if (typeof tag !== 'string') throw TypeError('tag should be string.')
576
+ let tagEncoded = encoder.encode(tag)
577
+ let dataPack = MBP.B8(data)
686
578
 
687
579
  //encrypt payload area with key
688
- let sercretPack = this.boho.encrypt_e2e( dataPack, key )
580
+ let sercretPack = this.boho.encrypt_e2e(dataPack, key)
689
581
 
690
582
  //change signal MsgType header into SIGNAL_E2E
691
- let signalPack = MBP.pack(
692
- MBP.MB('#MsgType','8', IOMsg.SIGNAL_E2E) ,
693
- MBP.MB('#tagLen','8', tagEncoded.byteLength),
583
+ let signalPack = MBP.pack(
584
+ MBP.MB('#MsgType', '8', IOMsg.SIGNAL_E2E),
585
+ MBP.MB('#tagLen', '8', tagEncoded.byteLength),
694
586
  MBP.MB('#tag', tagEncoded),
695
- MBP.MB('#payloadType', '8', PAYLOAD_TYPE.BINARY ),
696
- MBP.MB('#payload', sercretPack )
697
- )
587
+ MBP.MB('#payloadType', '8', PAYLOAD_TYPE.BINARY),
588
+ MBP.MB('#payload', sercretPack)
589
+ )
698
590
 
699
- this.send_enc_mode( signalPack )
591
+ this.send_enc_mode(signalPack)
700
592
  }
701
-
702
-
703
-
704
- set( storeName, ...args ){
705
- if( !storeName || args.length == 0 ){
593
+
594
+
595
+
596
+ set(storeName, ...args) {
597
+ if (!storeName || args.length == 0) {
706
598
  return Promise.reject(new Error('set need storeName and value)'))
707
- }
708
- return this.req('store', 'set', storeName, ...args )
599
+ }
600
+ return this.req('store', 'set', storeName, ...args)
709
601
  }
710
-
711
- async get( storeName ){
712
- if( !storeName ){
602
+
603
+ async get(storeName) {
604
+ if (!storeName) {
713
605
  return Promise.reject(new Error('store get need storeName)'))
714
- }
715
- let pack = await this.req('store', 'get', storeName )
606
+ }
607
+ let pack = await this.req('store', 'get', storeName)
716
608
  let { $ } = MBP.unpack(pack.body)
717
609
  return $
718
610
  }
719
-
720
-
721
- req( target, topic, ...args ){
611
+
612
+
613
+ req(target, topic, ...args) {
722
614
  // console.log('common_req args', args)
723
- if( !target || !topic)
615
+ if (!target || !topic)
724
616
  return Promise.reject(new Error('request need target and topic)'))
725
617
  let sigPack;
726
- if(args.length > 0){
727
- sigPack = MBP.pack(
728
- MBP.MB('#MsgType','8', IOMsg.REQUEST) ,
729
- MBP.MB('mid','16',++this.mid),
730
- MBP.MB('target', target ),
731
- MBP.MB('topic', topic ),
732
- MBP.MBA( ...args )
733
- )
734
- }else{
735
- sigPack = MBP.pack(
736
- MBP.MB('#MsgType','8', IOMsg.REQUEST) ,
737
- MBP.MB('mid','16',++this.mid),
738
- MBP.MB('target', target ),
739
- MBP.MB('topic', topic )
740
- )
618
+ if (args.length > 0) {
619
+ sigPack = MBP.pack(
620
+ MBP.MB('#MsgType', '8', IOMsg.REQUEST),
621
+ MBP.MB('mid', '16', ++this.mid),
622
+ MBP.MB('target', target),
623
+ MBP.MB('topic', topic),
624
+ MBP.MBA(...args)
625
+ )
626
+ } else {
627
+ sigPack = MBP.pack(
628
+ MBP.MB('#MsgType', '8', IOMsg.REQUEST),
629
+ MBP.MB('mid', '16', ++this.mid),
630
+ MBP.MB('target', target),
631
+ MBP.MB('topic', topic)
632
+ )
741
633
  }
742
634
  // console.log('<< adminPack', this.mid, sigPack)
743
- this.send_enc_mode( sigPack )
744
- return this.setMsgPromise( this.mid )
635
+ this.send_enc_mode(sigPack)
636
+ return this.setMsgPromise(this.mid)
745
637
  }
746
638
 
747
639
 
748
- subscribe(tag ){
749
- if( typeof tag !== 'string') throw TypeError('tag should be string.')
750
- if( this.state !== STATES.READY ) return
640
+ subscribe(tag) {
641
+ if (typeof tag !== 'string') throw TypeError('tag should be string.')
642
+ if (this.state !== STATES.READY) return
751
643
 
752
644
  let tagList = tag.split(',')
753
- tagList.forEach( tag=>{
645
+ tagList.forEach(tag => {
754
646
  this.channels.add(tag)
755
647
  })
756
648
 
757
- let tagEncoded = encoder.encode( tag)
758
- if( tagEncoded.byteLength > SIZE_LIMIT.TAG_LEN1 ) throw TypeError('please use tag string bytelength below:' + SIZE_LIMIT.TAG_LEN1 )
649
+ let tagEncoded = encoder.encode(tag)
650
+ if (tagEncoded.byteLength > SIZE_LIMIT.TAG_LEN1) throw TypeError('please use tag string bytelength below:' + SIZE_LIMIT.TAG_LEN1)
759
651
 
760
- this.send_enc_mode(
761
- Buffer.concat( [
762
- MBP.NB('8',IOMsg.SUBSCRIBE),
763
- MBP.NB('8', tagEncoded.byteLength),
764
- tagEncoded ]) )
652
+ this.send_enc_mode(
653
+ Buffer.concat([
654
+ MBP.NB('8', IOMsg.SUBSCRIBE),
655
+ MBP.NB('8', tagEncoded.byteLength),
656
+ tagEncoded]))
765
657
  }
766
658
 
767
- subscribe_promise(tag){
768
- if( typeof tag !== 'string') throw TypeError('tag should be string.')
769
- if( this.state !== STATES.READY ){
659
+ subscribe_promise(tag) {
660
+ if (typeof tag !== 'string') throw TypeError('tag should be string.')
661
+ if (this.state !== STATES.READY) {
770
662
  // console.log('not ready state:', this.state )
771
663
  return Promise.reject('subscribe_promise:: connection is not ready')
772
664
  }
773
665
 
774
- let tagEncoded = encoder.encode( tag)
775
- if( tagEncoded.byteLength > SIZE_LIMIT.TAG_LEN2 ) throw TypeError('please use tag string bytelength: ' + SIZE_LIMIT.TAG_LEN2)
666
+ let tagEncoded = encoder.encode(tag)
667
+ if (tagEncoded.byteLength > SIZE_LIMIT.TAG_LEN2) throw TypeError('please use tag string bytelength: ' + SIZE_LIMIT.TAG_LEN2)
776
668
 
777
- this.send_enc_mode(
778
- Buffer.concat( [
779
- MBP.NB('8',IOMsg.SUBSCRIBE_REQ),
780
- MBP.NB('16', ++this.mid),
781
- MBP.NB('16', tagEncoded.byteLength),
782
- tagEncoded ]) )
783
- return this.setMsgPromise( this.mid )
669
+ this.send_enc_mode(
670
+ Buffer.concat([
671
+ MBP.NB('8', IOMsg.SUBSCRIBE_REQ),
672
+ MBP.NB('16', ++this.mid),
673
+ MBP.NB('16', tagEncoded.byteLength),
674
+ tagEncoded]))
675
+ return this.setMsgPromise(this.mid)
784
676
  }
785
677
 
786
- subscribe_memory_channels( ){ //local cache . auto_resubscribe
787
- if(this.channels.size == 0) return
788
- let chList = Array.from( this.channels).join(',')
678
+ subscribe_memory_channels() { //local cache . auto_resubscribe
679
+ if (this.channels.size == 0) return
680
+ let chList = Array.from(this.channels).join(',')
789
681
  // console.log('<< subscibe memory channels by cid', chList , this.cid )
790
682
 
791
- this.subscribe_promise( chList)
792
- .then( (res )=>{
793
- // console.log('>> SUBSCRIBE_REQ result', res ) // return code == map.size
794
- }).catch( (e)=>{
795
- console.log('>> SUBSCRIBE FAIL:', e)
796
- })
683
+ this.subscribe_promise(chList)
684
+ .then((res) => {
685
+ // console.log('>> SUBSCRIBE_REQ result', res ) // return code == map.size
686
+ }).catch((e) => {
687
+ console.log('>> SUBSCRIBE FAIL:', e)
688
+ })
797
689
 
798
690
  }
799
691
 
800
- unsubscribe(tag = ""){
692
+ unsubscribe(tag = "") {
801
693
  // console.log('unsub', tag)
802
- if( typeof tag !== 'string') throw TypeError('tag should be string.')
803
-
804
- if(tag == ""){
694
+ if (typeof tag !== 'string') throw TypeError('tag should be string.')
695
+
696
+ if (tag == "") {
805
697
  // console.log('unsub all')
806
698
  this.channels.clear();
807
- }else{
699
+ } else {
808
700
  let tagList = tag.split(',')
809
- tagList.forEach( tag=>{
701
+ tagList.forEach(tag => {
810
702
  this.channels.delete(tag)
811
703
  })
812
704
  }
813
705
 
814
- let tagEncoded = encoder.encode( tag)
815
- if( tagEncoded.byteLength > SIZE_LIMIT.TAG_LEN1 ) throw TypeError('please use tag string bytelength below:' + SIZE_LIMIT.TAG_LEN1 )
706
+ let tagEncoded = encoder.encode(tag)
707
+ if (tagEncoded.byteLength > SIZE_LIMIT.TAG_LEN1) throw TypeError('please use tag string bytelength below:' + SIZE_LIMIT.TAG_LEN1)
816
708
 
817
- this.send_enc_mode( Buffer.concat( [
818
- MBP.NB('8',IOMsg.UNSUBSCRIBE),
819
- MBP.NB('8', tagEncoded.byteLength),
820
- tagEncoded ]) )
709
+ this.send_enc_mode(Buffer.concat([
710
+ MBP.NB('8', IOMsg.UNSUBSCRIBE),
711
+ MBP.NB('8', tagEncoded.byteLength),
712
+ tagEncoded]))
821
713
  }
822
714
 
823
715
 
824
- listen(tag , handler){
825
- if( typeof tag !== 'string') throw TypeError('tag should be string.')
826
- if( tag.length > 255 || tag.length == 0 ) throw TypeError('tag string length range: 1~255')
827
- if( typeof handler !== 'function') throw TypeError('handler is not a function.')
828
-
829
- if( tag.indexOf('@') !== 0){
830
- this.channels.add(tag)
716
+ listen(tag, handler) {
717
+ if (typeof tag !== 'string') throw TypeError('tag should be string.')
718
+ if (tag.length > 255 || tag.length == 0) throw TypeError('tag string length range: 1~255')
719
+ if (typeof handler !== 'function') throw TypeError('handler is not a function.')
720
+
721
+ if (tag.indexOf('@') !== 0) {
722
+ this.channels.add(tag)
831
723
  }
832
724
  // console.log('channels:', this.channels )
833
- this.on( tag , handler)
725
+ this.on(tag, handler)
834
726
  // do not subscribe now.
835
727
  // will subscribe when receive CID_RES signal from server.
836
-
728
+
837
729
  }
838
730
 
839
731
 
840
732
 
841
- link( to , tag , handler){
842
- if( typeof to !== 'string') throw TypeError('to(local link target) is not a string.')
843
- if( typeof tag !== 'string') throw TypeError('tag is not a string.')
844
- if( tag.length > 255 || tag.length == 0 ) throw TypeError('tag string length range: 1~255')
845
- if( typeof handler !== 'function') throw TypeError('handler is not a function.')
846
-
847
- if( tag.indexOf('@') !== 0){
848
- this.channels.add(tag)
733
+ link(to, tag, handler) {
734
+ if (typeof to !== 'string') throw TypeError('to(local link target) is not a string.')
735
+ if (typeof tag !== 'string') throw TypeError('tag is not a string.')
736
+ if (tag.length > 255 || tag.length == 0) throw TypeError('tag string length range: 1~255')
737
+ if (typeof handler !== 'function') throw TypeError('handler is not a function.')
738
+
739
+ if (tag.indexOf('@') !== 0) {
740
+ this.channels.add(tag)
849
741
  }
850
-
742
+
851
743
  let linkSet;
852
- if( this.linkMap.has(to) ){
744
+ if (this.linkMap.has(to)) {
853
745
  linkSet = this.linkMap.get(to)
854
- }else {
746
+ } else {
855
747
  linkSet = new Set()
856
748
  }
857
-
858
- linkSet.add(tag )
859
- this.linkMap.set( to, linkSet)
860
- this.on( tag , handler)
861
- this.subscribe( tag )
749
+
750
+ linkSet.add(tag)
751
+ this.linkMap.set(to, linkSet)
752
+ this.on(tag, handler)
753
+ this.subscribe(tag)
862
754
  // console.log('link [to] linkMap:', to, this.linkMap )
863
-
755
+
864
756
  }
865
-
866
757
 
867
- unlink( to, tag){
868
- if( typeof to !== 'string') throw TypeError('to(local link target) is not a string.')
869
- if( typeof tag !== 'string') throw TypeError('tag is not a string.')
870
- if( tag.length > 255 || tag.length == 0 ) throw TypeError('tag string length range: 1~255')
871
-
872
- if( !this.linkMap.has( to ) ) return;
758
+
759
+ unlink(to, tag) {
760
+ if (typeof to !== 'string') throw TypeError('to(local link target) is not a string.')
761
+ if (typeof tag !== 'string') throw TypeError('tag is not a string.')
762
+ if (tag.length > 255 || tag.length == 0) throw TypeError('tag string length range: 1~255')
763
+
764
+ if (!this.linkMap.has(to)) return;
873
765
 
874
766
  let linkSet = this.linkMap.get(to)
875
767
  let tags = Array.from(linkSet)
876
- for(let i=0; i< tags.length; i++){
877
- if( tags[i] == tag ){
878
- this.unsubscribe( tag )
768
+ for (let i = 0; i < tags.length; i++) {
769
+ if (tags[i] == tag) {
770
+ this.unsubscribe(tag)
879
771
  this.removeAllListeners(tag)
880
772
  linkSet.delete(tag)
881
- this.linkMap.set( to , linkSet)
773
+ this.linkMap.set(to, linkSet)
882
774
  break;
883
775
  }
884
776
  }
@@ -886,72 +778,72 @@ export class IOCore extends EventEmitter{
886
778
  // console.log('unlink linkMap result:', this.linkMap )
887
779
  }
888
780
 
889
- unlinkAll( to){
890
- if( typeof to !== 'string') throw TypeError('to(local link target) is not a string.')
891
- if( !this.linkMap.has( to ) ) return;
781
+ unlinkAll(to) {
782
+ if (typeof to !== 'string') throw TypeError('to(local link target) is not a string.')
783
+ if (!this.linkMap.has(to)) return;
892
784
 
893
785
  let linkSet = this.linkMap.get(to)
894
- let tags = Array.from(linkSet)
895
- for(let i=0; i< tags.length; i++){
896
- this.unsubscribe( tags[i] )
897
- this.removeAllListeners(tags[i])
898
- linkSet.delete(tags[i])
786
+ let tags = Array.from(linkSet)
787
+ for (let i = 0; i < tags.length; i++) {
788
+ this.unsubscribe(tags[i])
789
+ this.removeAllListeners(tags[i])
790
+ linkSet.delete(tags[i])
899
791
  }
900
- this.linkMap.delete( to )
792
+ this.linkMap.delete(to)
901
793
 
902
794
  // console.log('unlinkAll linkMap result:', this.linkMap )
903
795
  }
904
796
 
905
797
 
906
798
 
907
- getMetric(){
908
- return {
909
- tx: this.txCounter,
910
- rx: this.rxCounter,
911
- txb: this.txBytes,
799
+ getMetric() {
800
+ return {
801
+ tx: this.txCounter,
802
+ rx: this.rxCounter,
803
+ txb: this.txBytes,
912
804
  rxb: this.rxBytes,
913
- last: ( Date.now() - this.lastTxRxTime) / 1000
805
+ last: (Date.now() - this.lastTxRxTime) / 1000
914
806
  }
915
807
 
916
808
  }
917
809
 
918
- getState(){
810
+ getState() {
919
811
  return this.state
920
812
  }
921
813
 
922
- getStateName(){
814
+ getStateName() {
923
815
  //state <number>
924
816
  //value of constant STATES.NAME < number >
925
817
  //type of constant STATES.NAME name < string uppercase >
926
818
  //stateName,eventName <string lowercase>
927
- return ( STATES[ this.state ]).toLowerCase()
819
+ return (STATES[this.state]).toLowerCase()
928
820
  }
929
821
 
930
- getSecurity(){
822
+ getSecurity() {
931
823
  return {
932
824
  useAuth: this.useAuth,
933
- isTLS: this.TLS,
825
+ isTLS: this.TLS,
934
826
  isAuthorized: this.boho.isAuthorized,
935
827
  encMode: this.encMode,
936
828
  usingEncryption: this.getEncryptionMode()
937
829
  }
938
830
  }
939
831
 
940
- stateChange(state, emitEventAndMessage ){
832
+ stateChange(state, emitEventAndMessage) {
941
833
  // STATES constant name : string upperCase
942
834
  // eventName, .stateName : string lowerCase
943
835
  // .state : number
944
836
  let eventName = state.toLowerCase()
945
- this.state = STATES[ state.toUpperCase() ] // state: number
946
- if(emitEventAndMessage) this.emit(eventName, emitEventAndMessage)
947
-
948
- if( this.stateName !== eventName ){
837
+ this.state = STATES[state.toUpperCase()] // state: number
838
+ if (emitEventAndMessage) this.emit(eventName, emitEventAndMessage)
839
+
840
+ if (this.stateName !== eventName) {
949
841
  // console.log(`state: ${this.stateName} => ${eventName}` )
950
842
  this.stateName = eventName
951
843
  this.emit('change', eventName)
952
- }
844
+ }
953
845
  }
954
-
846
+
955
847
  }
956
848
 
957
849