iosignal 3.3.0 → 4.0.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.
Files changed (68) hide show
  1. package/.vscode/settings.json +3 -0
  2. package/README.en.md +56 -0
  3. package/README.md +40 -559
  4. package/dist/io.d.ts +5 -0
  5. package/dist/io.js +1 -1
  6. package/dist/io.js.map +1 -1
  7. package/dist/io.min.js +1 -1
  8. package/dist/io.min.js.map +1 -1
  9. package/dist/iosignal.js +80 -45
  10. package/dist/types/client/IOCore.d.ts +5 -0
  11. package/package.json +3 -4
  12. package/src/client/IOCore.js +71 -41
  13. package/src/server/Manager.js +9 -8
  14. package/README.ko.md +0 -566
  15. package/docs/iosignal_architecture.png +0 -0
  16. package/examples/react-chat-js/dist/assets/index-Cy4qaVcJ.js +0 -56
  17. package/examples/react-chat-js/dist/assets/index-NETrjYhz.css +0 -1
  18. package/examples/react-chat-js/dist/assets/index-e2KOTYW8.js +0 -65
  19. package/examples/react-chat-js/dist/index.html +0 -14
  20. package/examples/react-chat-js/index.html +0 -13
  21. package/examples/react-chat-js/package-lock.json +0 -1723
  22. package/examples/react-chat-js/package.json +0 -20
  23. package/examples/react-chat-js/src/App.css +0 -61
  24. package/examples/react-chat-js/src/App.jsx +0 -125
  25. package/examples/react-chat-js/src/index.css +0 -13
  26. package/examples/react-chat-js/src/main.jsx +0 -13
  27. package/examples/react-chat-js/src/shared_io.js +0 -12
  28. package/examples/react-chat-js/vite.config.js +0 -7
  29. package/examples/server/index.js +0 -65
  30. package/examples/server/package-lock.json +0 -878
  31. package/examples/server/package.json +0 -13
  32. package/examples/server/public/index.html +0 -26
  33. package/examples/svelte-chat-js/.devtools +0 -3
  34. package/examples/svelte-chat-js/README.md +0 -38
  35. package/examples/svelte-chat-js/package-lock.json +0 -1421
  36. package/examples/svelte-chat-js/package.json +0 -23
  37. package/examples/svelte-chat-js/src/app.css +0 -105
  38. package/examples/svelte-chat-js/src/app.d.ts +0 -13
  39. package/examples/svelte-chat-js/src/app.html +0 -13
  40. package/examples/svelte-chat-js/src/lib/images/github.svg +0 -1
  41. package/examples/svelte-chat-js/src/lib/images/svelte-logo.svg +0 -1
  42. package/examples/svelte-chat-js/src/lib/images/svelte-welcome.png +0 -0
  43. package/examples/svelte-chat-js/src/lib/images/svelte-welcome.webp +0 -0
  44. package/examples/svelte-chat-js/src/lib/shared_io.js +0 -12
  45. package/examples/svelte-chat-js/src/routes/+layout.svelte +0 -5
  46. package/examples/svelte-chat-js/src/routes/+page.js +0 -3
  47. package/examples/svelte-chat-js/src/routes/+page.svelte +0 -167
  48. package/examples/svelte-chat-js/static/favicon.svg +0 -1
  49. package/examples/svelte-chat-js/static/global.css +0 -19
  50. package/examples/svelte-chat-js/static/robots.txt +0 -3
  51. package/examples/svelte-chat-js/svelte.config.js +0 -23
  52. package/examples/svelte-chat-js/vite.config.js +0 -6
  53. package/test-browser/favicon.ico +0 -0
  54. package/test-browser/index.html +0 -95
  55. package/test-browser/server.js +0 -12
  56. package/test-nodejs/client-playToggle.js +0 -19
  57. package/test-nodejs/client.js +0 -17
  58. package/test-nodejs/client_api_reply.js +0 -15
  59. package/test-nodejs/server-Auth_Env.js +0 -19
  60. package/test-nodejs/server-Auth_File.js +0 -12
  61. package/test-nodejs/server-api_reply.js +0 -6
  62. package/test-nodejs/server-api_sudo.js +0 -7
  63. package/test-nodejs/server.js +0 -20
  64. package/test-nodejs/signalPack.js +0 -34
  65. package/test-nodejs/signaling.js +0 -61
  66. package/test-nodejs/simple-server.js +0 -13
  67. /package/{auth_file.js → auth_file_sample.js} +0 -0
  68. /package/{auth_file.json → auth_file_sample.json} +0 -0
package/dist/iosignal.js CHANGED
@@ -13,7 +13,7 @@ import require$$2 from 'os';
13
13
  import require$$0$1 from 'buffer';
14
14
  import { memoryUsage } from 'process';
15
15
 
16
- var version$1 = "3.3.0";
16
+ var version$1 = "4.0.0";
17
17
  var pkg = {
18
18
  version: version$1};
19
19
 
@@ -1224,7 +1224,6 @@ class IOCore extends EventEmitter {
1224
1224
  if (jsonInfo.nick) { this.nick = jsonInfo.nick; }
1225
1225
  if (jsonInfo.did) { this.did = jsonInfo.did; }
1226
1226
  if (jsonInfo.uid) { this.uid = jsonInfo.uid; }
1227
- // TIP. cid from [CID_RES], level from [QUOTA_LEVEL]
1228
1227
  this.emit('iam_res', str );
1229
1228
  } catch (error) {
1230
1229
  this.emit('error', new Error('IAM_RES data error'));
@@ -1236,7 +1235,7 @@ class IOCore extends EventEmitter {
1236
1235
  this.cid = cidStr;
1237
1236
 
1238
1237
  // **IMPORTANT** change state before subscribe.
1239
- this.stateChange('ready', 'cid_ready');
1238
+ this.stateChange('ready', 'cid_ready');
1240
1239
  this.subscribe_memory_channels();
1241
1240
  break;
1242
1241
 
@@ -1325,8 +1324,11 @@ class IOCore extends EventEmitter {
1325
1324
  switch (payloadType) {
1326
1325
 
1327
1326
  case PAYLOAD_TYPE.EMPTY:
1328
- if (tag.indexOf('@') === 0) this.emit('@', null, tag);
1329
- else this.emit(tag, null, tag);
1327
+ if (tag.indexOf('@') === 0) this.emit('@', tag, null);
1328
+ else {
1329
+ this.emit(tag, tag, null);
1330
+ this.emit('message', tag, null );
1331
+ }
1330
1332
  break;
1331
1333
 
1332
1334
  case PAYLOAD_TYPE.TEXT:
@@ -1337,33 +1339,48 @@ class IOCore extends EventEmitter {
1337
1339
  payloadStringWithoutNull = payloadBuffer.subarray(0, payloadBuffer.byteLength - 1);
1338
1340
  }
1339
1341
  let oneString = decoder$4.decode(payloadStringWithoutNull);
1340
- if (tag.indexOf('@') === 0) this.emit('@', oneString, tag);
1341
- if (tag !== '@') this.emit(tag, oneString, tag);
1342
+ if (tag.indexOf('@') === 0) this.emit('@', tag, oneString);
1343
+ if (tag !== '@'){
1344
+ this.emit(tag, tag, oneString);
1345
+ this.emit('message', tag, oneString);
1346
+ }
1342
1347
  break;
1343
1348
 
1344
1349
  case PAYLOAD_TYPE.BINARY:
1345
- if (tag.indexOf('@') === 0) this.emit('@', payloadBuffer, tag);
1346
- if (tag !== '@') this.emit(tag, payloadBuffer, tag);
1350
+ if (tag.indexOf('@') === 0) this.emit('@', tag, payloadBuffer);
1351
+ if (tag !== '@'){
1352
+ this.emit(tag, tag, payloadBuffer);
1353
+ this.emit('message', tag, payloadBuffer);
1354
+ }
1347
1355
  break;
1348
1356
 
1349
1357
  case PAYLOAD_TYPE.OBJECT:
1350
1358
  let oneObjectBuffer = decoder$4.decode(payloadBuffer);
1351
1359
  let oneJSONObject = JSON.parse(oneObjectBuffer);
1352
- if (tag.indexOf('@') === 0) this.emit('@', oneJSONObject, tag);
1353
- if (tag !== '@') this.emit(tag, oneJSONObject, tag);
1360
+ if (tag.indexOf('@') === 0) this.emit('@', tag, oneJSONObject);
1361
+ if (tag !== '@'){
1362
+ this.emit(tag, tag, oneJSONObject);
1363
+ this.emit('message', tag, oneJSONObject);
1364
+ }
1354
1365
  break;
1355
1366
 
1356
1367
  case PAYLOAD_TYPE.MJSON:
1357
1368
  let mjsonBuffer = decoder$4.decode(payloadBuffer);
1358
1369
  let mjson = JSON.parse(mjsonBuffer);
1359
- if (tag.indexOf('@') === 0) this.emit('@', ...mjson, tag);
1360
- if (tag !== '@') this.emit(tag, ...mjson, tag);
1370
+ if (tag.indexOf('@') === 0) this.emit('@', tag, ...mjson);
1371
+ if (tag !== '@'){
1372
+ this.emit(tag, tag, ...mjson);
1373
+ this.emit('message', tag, ...mjson);
1374
+ }
1361
1375
  break;
1362
1376
 
1363
1377
  case PAYLOAD_TYPE.MBA:
1364
1378
  let mbaObject = M$1.unpack(payloadBuffer);
1365
- if (tag.indexOf('@') === 0) this.emit('@', ...mbaObject.args, tag);
1366
- if (tag !== '@') this.emit(tag, ...mbaObject.args, tag);
1379
+ if (tag.indexOf('@') === 0) this.emit('@', tag, ...mbaObject.args);
1380
+ if (tag !== '@'){
1381
+ this.emit(tag, tag, ...mbaObject.args);
1382
+ this.emit('message', tag, ...mbaObject.args );
1383
+ }
1367
1384
  break;
1368
1385
 
1369
1386
  default:
@@ -1712,21 +1729,24 @@ class IOCore extends EventEmitter {
1712
1729
  */
1713
1730
  subscribe(tag) {
1714
1731
  if (typeof tag !== 'string') throw TypeError('tag should be string.')
1732
+ if (tag.length > SIZE_LIMIT.TAG_LEN1) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN1)
1715
1733
  if (this.state !== STATES.READY) return
1716
1734
 
1717
- let tagList = tag.split(',');
1718
- tagList.forEach(tag => {
1719
- this.channels.add(tag);
1720
- });
1721
-
1722
- let tagEncoded = encoder$1.encode(tag);
1723
- if (tagEncoded.byteLength > SIZE_LIMIT.TAG_LEN1) throw TypeError('please use tag string bytelength below:' + SIZE_LIMIT.TAG_LEN1)
1735
+ // subscribe 사용시, 사용 'ready' 이벤트시 메뉴얼 등록되므로 여기에 등록하면 2중 호출된다.
1736
+ // 즉, channels 등록은 listen 같은 자동화 구독시만 사용.
1737
+ // let tagList = tag.split(',')
1738
+ // tagList.forEach(tag => {
1739
+ // this.channels.add(tag)
1740
+ // })
1724
1741
 
1725
- this.send_enc_mode(
1726
- Buffer$1.concat([
1727
- M$1.NB('8', IOMsg.SUBSCRIBE),
1728
- M$1.NB('8', tagEncoded.byteLength),
1729
- tagEncoded]));
1742
+ try {
1743
+ let tagEncoded = encoder$1.encode(tag);
1744
+ this.send_enc_mode(
1745
+ Buffer$1.concat([
1746
+ M$1.NB('8', IOMsg.SUBSCRIBE),
1747
+ M$1.NB('8', tagEncoded.byteLength),
1748
+ tagEncoded]));
1749
+ } catch (error) { }
1730
1750
  }
1731
1751
 
1732
1752
  /**
@@ -1737,20 +1757,22 @@ class IOCore extends EventEmitter {
1737
1757
  */
1738
1758
  subscribe_promise(tag) {
1739
1759
  if (typeof tag !== 'string') throw TypeError('tag should be string.')
1760
+ if (tag.length > SIZE_LIMIT.TAG_LEN2) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN2)
1761
+
1740
1762
  if (this.state !== STATES.READY) {
1741
1763
  return Promise.reject('subscribe_promise:: connection is not ready')
1742
1764
  }
1743
1765
 
1744
- let tagEncoded = encoder$1.encode(tag);
1745
- if (tagEncoded.byteLength > SIZE_LIMIT.TAG_LEN2) throw TypeError('please use tag string bytelength: ' + SIZE_LIMIT.TAG_LEN2)
1746
-
1747
- this.send_enc_mode(
1748
- Buffer$1.concat([
1749
- M$1.NB('8', IOMsg.SUBSCRIBE_REQ),
1750
- M$1.NB('16', ++this.mid),
1751
- M$1.NB('16', tagEncoded.byteLength),
1752
- tagEncoded]));
1753
- return this.setMsgPromise(this.mid)
1766
+ try {
1767
+ let tagEncoded = encoder$1.encode(tag);
1768
+ this.send_enc_mode(
1769
+ Buffer$1.concat([
1770
+ M$1.NB('8', IOMsg.SUBSCRIBE_REQ),
1771
+ M$1.NB('16', ++this.mid),
1772
+ M$1.NB('16', tagEncoded.byteLength),
1773
+ tagEncoded]));
1774
+ return this.setMsgPromise(this.mid)
1775
+ } catch (error) { }
1754
1776
  }
1755
1777
 
1756
1778
  /**
@@ -1947,15 +1969,23 @@ class IOCore extends EventEmitter {
1947
1969
  * Changes the connection state and emits events.
1948
1970
  * @param {string} state - The new state name (e.g., 'ready', 'closed').
1949
1971
  * @param {string} [emitEventAndMessage] - Optional message to emit with the state change event.
1972
+ *
1973
+ * 주의.
1974
+ * 1. 상태가 변경 될 때만 'change' 이벤트 호출된다.
1975
+ * 2. emitEventAndMessage 옵션 값이 지정되야 해당 이벤트 이름이 호출된다.
1976
+ * 보통 이벤트 이름과 동일하게 적거나 이벤트 상황 안내문을 넣는다.
1950
1977
  */
1951
1978
  stateChange(state, emitEventAndMessage) {
1952
- // STATES constant name : string upperCase
1953
- // eventName, .stateName : string lowerCase
1954
- // .state : number
1979
+ // STATES constant name <string> upperCase
1980
+ // eventName and .stateName <string> lowerCase
1981
+ // .state <number>
1955
1982
  // console.log('### stateChange reason:', emitEventAndMessage )
1956
1983
  let eventName = state.toLowerCase();
1957
1984
  this.state = STATES[state.toUpperCase()]; // state: number
1958
- if (emitEventAndMessage) this.emit(eventName, emitEventAndMessage);
1985
+
1986
+ if (emitEventAndMessage){
1987
+ this.emit(eventName, emitEventAndMessage);
1988
+ }
1959
1989
 
1960
1990
  if (this.stateName !== eventName) {
1961
1991
  this.stateName = eventName;
@@ -8655,8 +8685,8 @@ class Manager {
8655
8685
  serverSignalTo(tag, ...args) {
8656
8686
  let cid = tag.split('@')[0];
8657
8687
  let topic = tag.split('@')[1];
8658
- let sigPack = getSignalPack('@' + topic, ...args);
8659
8688
  if (cid && this.cid2remote.has(cid)) {
8689
+ let sigPack = getSignalPack('@' + topic, ...args);
8660
8690
  let targetRemote = this.cid2remote.get(cid);
8661
8691
  console.log('target', targetRemote.state, targetRemote.cid);
8662
8692
  targetRemote.send_enc_mode(sigPack);
@@ -8753,13 +8783,18 @@ class Manager {
8753
8783
  // console.log('## null remote' )
8754
8784
  break;
8755
8785
  }
8756
- if (c !== remote) {
8786
+ // change: from v4.x allow receiveSelfMessages.
8787
+ // if (c !== remote) {
8757
8788
  c.send_enc_mode(message);
8758
8789
  sentCounter++;
8759
- }
8790
+ // }
8760
8791
  }
8761
8792
 
8762
- if (serverOption.useQuota.publishCounter) ;
8793
+ // if (serverOption.useQuota.publishCounter) {
8794
+ // // console.log(`pub >> [${tag}] sent: ${sentCounter} [use quota limit: ${remote.quota.publishCounter }] total: ${remotes.size} subscribers. ` )
8795
+ // } else {
8796
+ // // console.log(`pub >> [${tag}] sent: ${sentCounter} [no quota limit] total: ${remotes.size} subscribers. ` )
8797
+ // }
8763
8798
  return ['ok', sentCounter]
8764
8799
  }
8765
8800
  }
@@ -395,6 +395,11 @@ export class IOCore extends EventEmitter<string | symbol, any> {
395
395
  * Changes the connection state and emits events.
396
396
  * @param {string} state - The new state name (e.g., 'ready', 'closed').
397
397
  * @param {string} [emitEventAndMessage] - Optional message to emit with the state change event.
398
+ *
399
+ * 주의.
400
+ * 1. 상태가 변경 될 때만 'change' 이벤트 호출된다.
401
+ * 2. emitEventAndMessage 옵션 값이 지정되야 해당 이벤트 이름이 호출된다.
402
+ * 보통 이벤트 이름과 동일하게 적거나 이벤트 상황 안내문을 넣는다.
398
403
  */
399
404
  stateChange(state: string, emitEventAndMessage?: string): void;
400
405
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iosignal",
3
- "version": "3.3.0",
3
+ "version": "4.0.0",
4
4
  "description": "iosignal",
5
5
  "type": "module",
6
6
  "exports": {
@@ -18,11 +18,10 @@
18
18
  "unpkg": "./dist/io.min.js",
19
19
  "scripts": {
20
20
  "build": "rollup -c && npm run build:types",
21
- "build:types": "tsc --project tsconfig.json",
22
- "start": "node ./test-browser/server.js"
21
+ "build:types": "tsc --project tsconfig.json"
23
22
  },
24
23
  "engines": {
25
- "node": ">=18.0.0"
24
+ "node": ">=22.0.0"
26
25
  },
27
26
  "author": {
28
27
  "name": "Taeo Lee",
@@ -448,7 +448,6 @@ export class IOCore extends EventEmitter {
448
448
  if (jsonInfo.nick) { this.nick = jsonInfo.nick; }
449
449
  if (jsonInfo.did) { this.did = jsonInfo.did; }
450
450
  if (jsonInfo.uid) { this.uid = jsonInfo.uid; }
451
- // TIP. cid from [CID_RES], level from [QUOTA_LEVEL]
452
451
  this.emit('iam_res', str )
453
452
  } catch (error) {
454
453
  this.emit('error', new Error('IAM_RES data error'))
@@ -460,7 +459,7 @@ export class IOCore extends EventEmitter {
460
459
  this.cid = cidStr;
461
460
 
462
461
  // **IMPORTANT** change state before subscribe.
463
- this.stateChange('ready', 'cid_ready')
462
+ this.stateChange('ready', 'cid_ready')
464
463
  this.subscribe_memory_channels()
465
464
  break;
466
465
 
@@ -552,8 +551,11 @@ export class IOCore extends EventEmitter {
552
551
  switch (payloadType) {
553
552
 
554
553
  case PAYLOAD_TYPE.EMPTY:
555
- if (tag.indexOf('@') === 0) this.emit('@', null, tag)
556
- else this.emit(tag, null, tag)
554
+ if (tag.indexOf('@') === 0) this.emit('@', tag, null)
555
+ else {
556
+ this.emit(tag, tag, null)
557
+ this.emit('message', tag, null )
558
+ }
557
559
  break;
558
560
 
559
561
  case PAYLOAD_TYPE.TEXT:
@@ -564,33 +566,48 @@ export class IOCore extends EventEmitter {
564
566
  payloadStringWithoutNull = payloadBuffer.subarray(0, payloadBuffer.byteLength - 1)
565
567
  }
566
568
  let oneString = decoder.decode(payloadStringWithoutNull)
567
- if (tag.indexOf('@') === 0) this.emit('@', oneString, tag)
568
- if (tag !== '@') this.emit(tag, oneString, tag)
569
+ if (tag.indexOf('@') === 0) this.emit('@', tag, oneString)
570
+ if (tag !== '@'){
571
+ this.emit(tag, tag, oneString)
572
+ this.emit('message', tag, oneString)
573
+ }
569
574
  break;
570
575
 
571
576
  case PAYLOAD_TYPE.BINARY:
572
- if (tag.indexOf('@') === 0) this.emit('@', payloadBuffer, tag)
573
- if (tag !== '@') this.emit(tag, payloadBuffer, tag)
577
+ if (tag.indexOf('@') === 0) this.emit('@', tag, payloadBuffer)
578
+ if (tag !== '@'){
579
+ this.emit(tag, tag, payloadBuffer)
580
+ this.emit('message', tag, payloadBuffer)
581
+ }
574
582
  break;
575
583
 
576
584
  case PAYLOAD_TYPE.OBJECT:
577
585
  let oneObjectBuffer = decoder.decode(payloadBuffer)
578
586
  let oneJSONObject = JSON.parse(oneObjectBuffer)
579
- if (tag.indexOf('@') === 0) this.emit('@', oneJSONObject, tag)
580
- if (tag !== '@') this.emit(tag, oneJSONObject, tag)
587
+ if (tag.indexOf('@') === 0) this.emit('@', tag, oneJSONObject)
588
+ if (tag !== '@'){
589
+ this.emit(tag, tag, oneJSONObject)
590
+ this.emit('message', tag, oneJSONObject)
591
+ }
581
592
  break;
582
593
 
583
594
  case PAYLOAD_TYPE.MJSON:
584
595
  let mjsonBuffer = decoder.decode(payloadBuffer)
585
596
  let mjson = JSON.parse(mjsonBuffer)
586
- if (tag.indexOf('@') === 0) this.emit('@', ...mjson, tag)
587
- if (tag !== '@') this.emit(tag, ...mjson, tag)
597
+ if (tag.indexOf('@') === 0) this.emit('@', tag, ...mjson)
598
+ if (tag !== '@'){
599
+ this.emit(tag, tag, ...mjson)
600
+ this.emit('message', tag, ...mjson)
601
+ }
588
602
  break;
589
603
 
590
604
  case PAYLOAD_TYPE.MBA:
591
605
  let mbaObject = MBP.unpack(payloadBuffer)
592
- if (tag.indexOf('@') === 0) this.emit('@', ...mbaObject.args, tag)
593
- if (tag !== '@') this.emit(tag, ...mbaObject.args, tag)
606
+ if (tag.indexOf('@') === 0) this.emit('@', tag, ...mbaObject.args)
607
+ if (tag !== '@'){
608
+ this.emit(tag, tag, ...mbaObject.args)
609
+ this.emit('message', tag, ...mbaObject.args )
610
+ }
594
611
  break;
595
612
 
596
613
  default:
@@ -939,21 +956,24 @@ export class IOCore extends EventEmitter {
939
956
  */
940
957
  subscribe(tag) {
941
958
  if (typeof tag !== 'string') throw TypeError('tag should be string.')
959
+ if (tag.length > SIZE_LIMIT.TAG_LEN1) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN1)
942
960
  if (this.state !== STATES.READY) return
943
961
 
944
- let tagList = tag.split(',')
945
- tagList.forEach(tag => {
946
- this.channels.add(tag)
947
- })
948
-
949
- let tagEncoded = encoder.encode(tag)
950
- if (tagEncoded.byteLength > SIZE_LIMIT.TAG_LEN1) throw TypeError('please use tag string bytelength below:' + SIZE_LIMIT.TAG_LEN1)
951
-
952
- this.send_enc_mode(
953
- Buffer.concat([
954
- MBP.NB('8', IOMsg.SUBSCRIBE),
955
- MBP.NB('8', tagEncoded.byteLength),
956
- tagEncoded]))
962
+ // subscribe 사용시, 사용 'ready' 이벤트시 메뉴얼 등록되므로 여기에 등록하면 2중 호출된다.
963
+ // 즉, channels 등록은 listen 같은 자동화 구독시만 사용.
964
+ // let tagList = tag.split(',')
965
+ // tagList.forEach(tag => {
966
+ // this.channels.add(tag)
967
+ // })
968
+
969
+ try {
970
+ let tagEncoded = encoder.encode(tag)
971
+ this.send_enc_mode(
972
+ Buffer.concat([
973
+ MBP.NB('8', IOMsg.SUBSCRIBE),
974
+ MBP.NB('8', tagEncoded.byteLength),
975
+ tagEncoded]))
976
+ } catch (error) { }
957
977
  }
958
978
 
959
979
  /**
@@ -964,20 +984,22 @@ export class IOCore extends EventEmitter {
964
984
  */
965
985
  subscribe_promise(tag) {
966
986
  if (typeof tag !== 'string') throw TypeError('tag should be string.')
987
+ if (tag.length > SIZE_LIMIT.TAG_LEN2) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN2)
988
+
967
989
  if (this.state !== STATES.READY) {
968
990
  return Promise.reject('subscribe_promise:: connection is not ready')
969
991
  }
970
992
 
971
- let tagEncoded = encoder.encode(tag)
972
- if (tagEncoded.byteLength > SIZE_LIMIT.TAG_LEN2) throw TypeError('please use tag string bytelength: ' + SIZE_LIMIT.TAG_LEN2)
973
-
974
- this.send_enc_mode(
975
- Buffer.concat([
976
- MBP.NB('8', IOMsg.SUBSCRIBE_REQ),
977
- MBP.NB('16', ++this.mid),
978
- MBP.NB('16', tagEncoded.byteLength),
979
- tagEncoded]))
980
- return this.setMsgPromise(this.mid)
993
+ try {
994
+ let tagEncoded = encoder.encode(tag)
995
+ this.send_enc_mode(
996
+ Buffer.concat([
997
+ MBP.NB('8', IOMsg.SUBSCRIBE_REQ),
998
+ MBP.NB('16', ++this.mid),
999
+ MBP.NB('16', tagEncoded.byteLength),
1000
+ tagEncoded]))
1001
+ return this.setMsgPromise(this.mid)
1002
+ } catch (error) { }
981
1003
  }
982
1004
 
983
1005
  /**
@@ -1174,15 +1196,23 @@ export class IOCore extends EventEmitter {
1174
1196
  * Changes the connection state and emits events.
1175
1197
  * @param {string} state - The new state name (e.g., 'ready', 'closed').
1176
1198
  * @param {string} [emitEventAndMessage] - Optional message to emit with the state change event.
1199
+ *
1200
+ * 주의.
1201
+ * 1. 상태가 변경 될 때만 'change' 이벤트 호출된다.
1202
+ * 2. emitEventAndMessage 옵션 값이 지정되야 해당 이벤트 이름이 호출된다.
1203
+ * 보통 이벤트 이름과 동일하게 적거나 이벤트 상황 안내문을 넣는다.
1177
1204
  */
1178
1205
  stateChange(state, emitEventAndMessage) {
1179
- // STATES constant name : string upperCase
1180
- // eventName, .stateName : string lowerCase
1181
- // .state : number
1206
+ // STATES constant name <string> upperCase
1207
+ // eventName and .stateName <string> lowerCase
1208
+ // .state <number>
1182
1209
  // console.log('### stateChange reason:', emitEventAndMessage )
1183
1210
  let eventName = state.toLowerCase()
1184
1211
  this.state = STATES[state.toUpperCase()] // state: number
1185
- if (emitEventAndMessage) this.emit(eventName, emitEventAndMessage)
1212
+
1213
+ if (emitEventAndMessage){
1214
+ this.emit(eventName, emitEventAndMessage)
1215
+ }
1186
1216
 
1187
1217
  if (this.stateName !== eventName) {
1188
1218
  this.stateName = eventName
@@ -181,8 +181,8 @@ export class Manager {
181
181
  serverSignalTo(tag, ...args) {
182
182
  let cid = tag.split('@')[0]
183
183
  let topic = tag.split('@')[1]
184
- let sigPack = getSignalPack('@' + topic, ...args)
185
184
  if (cid && this.cid2remote.has(cid)) {
185
+ let sigPack = getSignalPack('@' + topic, ...args)
186
186
  let targetRemote = this.cid2remote.get(cid)
187
187
  console.log('target', targetRemote.state, targetRemote.cid)
188
188
  targetRemote.send_enc_mode(sigPack)
@@ -284,17 +284,18 @@ export class Manager {
284
284
  // console.log('## null remote' )
285
285
  break;
286
286
  }
287
- if (c !== remote) {
287
+ // change: from v4.x allow receiveSelfMessages.
288
+ // if (c !== remote) {
288
289
  c.send_enc_mode(message);
289
290
  sentCounter++;
290
- }
291
+ // }
291
292
  }
292
293
 
293
- if (serverOption.useQuota.publishCounter) {
294
- // console.log(`pub >> [${tag}] sent: ${sentCounter} [use quota limit: ${remote.quota.publishCounter }] total: ${remotes.size} subscribers. ` )
295
- } else {
296
- // console.log(`pub >> [${tag}] sent: ${sentCounter} [no quota limit] total: ${remotes.size} subscribers. ` )
297
- }
294
+ // if (serverOption.useQuota.publishCounter) {
295
+ // // console.log(`pub >> [${tag}] sent: ${sentCounter} [use quota limit: ${remote.quota.publishCounter }] total: ${remotes.size} subscribers. ` )
296
+ // } else {
297
+ // // console.log(`pub >> [${tag}] sent: ${sentCounter} [no quota limit] total: ${remotes.size} subscribers. ` )
298
+ // }
298
299
  return ['ok', sentCounter]
299
300
  }
300
301
  }