iosignal 3.0.0 → 3.0.1
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 +144 -1
- package/dist/io.d.ts +481 -0
- package/dist/io.js +3 -3
- package/dist/io.js.map +1 -1
- package/dist/io.min.js +3 -3
- package/dist/io.min.js.map +1 -1
- package/dist/iosignal.js +543 -102
- package/dist/types/client/IOCore.d.ts +408 -0
- package/dist/types/client/browser/IOWebSocket.d.ts +75 -0
- package/dist/types/common/constants.d.ts +169 -0
- package/dist/types/common/payload.d.ts +6 -0
- package/dist/types/common/quotaTable.d.ts +47 -0
- package/docs/{README.kr.md → README.ko.md} +143 -2
- package/examples/react-chat-js/dist/assets/index-Cy4qaVcJ.js +56 -0
- package/examples/react-chat-js/dist/assets/index-NETrjYhz.css +1 -0
- package/examples/react-chat-js/dist/index.html +14 -0
- package/examples/react-chat-js/index.html +13 -0
- package/examples/react-chat-js/package-lock.json +1628 -0
- package/examples/react-chat-js/package.json +20 -0
- package/examples/react-chat-js/src/App.css +61 -0
- package/examples/react-chat-js/src/App.jsx +125 -0
- package/examples/react-chat-js/src/index.css +13 -0
- package/examples/react-chat-js/src/main.jsx +13 -0
- package/examples/react-chat-js/src/shared_io.js +12 -0
- package/examples/react-chat-js/vite.config.js +7 -0
- package/examples/server/index.js +12 -0
- package/examples/server/package.json +12 -0
- package/package.json +9 -3
- package/rollup.config.js +11 -4
- package/src/client/IOCongSocket.js +20 -9
- package/src/client/IOCore.js +422 -77
- package/src/client/IOWS.js +12 -15
- package/src/client/browser/IOWebSocket.js +112 -13
- package/src/common/constants.js +91 -1
- package/tsconfig.json +24 -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 = "3.0.
|
|
16
|
+
var version = "3.0.1";
|
|
17
17
|
|
|
18
18
|
var t$1,e$1={},r$1={};var n$1,i$1,o$1={};
|
|
19
19
|
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */function f$1(){return n$1||(n$1=1,o$1.read=function(t,e,r,n,i){var o,f,u=8*i-n-1,s=(1<<u)-1,h=s>>1,a=-7,c=r?i-1:0,l=r?-1:1,p=t[e+c];for(c+=l,o=p&(1<<-a)-1,p>>=-a,a+=u;a>0;o=256*o+t[e+c],c+=l,a-=8);for(f=o&(1<<-a)-1,o>>=-a,a+=n;a>0;f=256*f+t[e+c],c+=l,a-=8);if(0===o)o=1-h;else {if(o===s)return f?NaN:1/0*(p?-1:1);f+=Math.pow(2,n),o-=h;}return (p?-1:1)*f*Math.pow(2,o-n)},o$1.write=function(t,e,r,n,i,o){var f,u,s,h=8*o-i-1,a=(1<<h)-1,c=a>>1,l=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:o-1,y=n?1:-1,g=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(u=isNaN(e)?1:0,f=a):(f=Math.floor(Math.log(e)/Math.LN2),e*(s=Math.pow(2,-f))<1&&(f--,s*=2),(e+=f+c>=1?l/s:l*Math.pow(2,1-c))*s>=2&&(f++,s/=2),f+c>=a?(u=0,f=a):f+c>=1?(u=(e*s-1)*Math.pow(2,i),f+=c):(u=e*Math.pow(2,c-1)*Math.pow(2,i),f=0));i>=8;t[r+p]=255&u,p+=y,u/=256,i-=8);for(f=f<<i|u,h+=i;h>0;t[r+p]=255&f,p+=y,f/=256,h-=8);t[r+p-y]|=128*g;}),o$1}
|
|
@@ -378,6 +378,18 @@ function requireEventemitter3 () {
|
|
|
378
378
|
var eventemitter3Exports = requireEventemitter3();
|
|
379
379
|
var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
|
|
380
380
|
|
|
381
|
+
/**
|
|
382
|
+
* @typedef {object} STATES
|
|
383
|
+
* @property {number} OPENING
|
|
384
|
+
* @property {number} OPEN
|
|
385
|
+
* @property {number} CLOSING
|
|
386
|
+
* @property {number} CLOSED
|
|
387
|
+
* @property {number} SERVER_READY
|
|
388
|
+
* @property {number} AUTH_FAIL
|
|
389
|
+
* @property {number} AUTH_READY
|
|
390
|
+
* @property {number} READY
|
|
391
|
+
* @property {number} REDIRECTING
|
|
392
|
+
*/
|
|
381
393
|
// Client STATES: name and number
|
|
382
394
|
const STATES = {
|
|
383
395
|
OPENING: 0,
|
|
@@ -392,7 +404,17 @@ const STATES = {
|
|
|
392
404
|
};
|
|
393
405
|
for (let c in STATES) { STATES[STATES[c]] = c; }
|
|
394
406
|
|
|
395
|
-
|
|
407
|
+
/**
|
|
408
|
+
* @typedef {object} CLIENT_STATE
|
|
409
|
+
* @property {number} INIT
|
|
410
|
+
* @property {number} SENT_SERVER_READY
|
|
411
|
+
* @property {number} RECV_AUTH_REQ
|
|
412
|
+
* @property {number} SENT_SERVER_NONCE
|
|
413
|
+
* @property {number} RECV_AUTH_HMAC
|
|
414
|
+
* @property {number} AUTH_FAIL
|
|
415
|
+
* @property {number} AUTH_READY
|
|
416
|
+
* @property {number} CID_READY
|
|
417
|
+
*/
|
|
396
418
|
const CLIENT_STATE = {
|
|
397
419
|
INIT: 0,
|
|
398
420
|
SENT_SERVER_READY: 1,
|
|
@@ -405,6 +427,12 @@ const CLIENT_STATE = {
|
|
|
405
427
|
};
|
|
406
428
|
for (let c in CLIENT_STATE) { CLIENT_STATE[CLIENT_STATE[c]] = c; }
|
|
407
429
|
|
|
430
|
+
/**
|
|
431
|
+
* @typedef {object} ENC_MODE
|
|
432
|
+
* @property {number} NO
|
|
433
|
+
* @property {number} YES
|
|
434
|
+
* @property {number} AUTO
|
|
435
|
+
*/
|
|
408
436
|
let ENC_MODE = {
|
|
409
437
|
NO: 0,
|
|
410
438
|
YES: 1,
|
|
@@ -414,6 +442,15 @@ let ENC_MODE = {
|
|
|
414
442
|
for (let c in ENC_MODE) { ENC_MODE[ENC_MODE[c]] = c; }
|
|
415
443
|
|
|
416
444
|
|
|
445
|
+
/**
|
|
446
|
+
* @typedef {object} SIZE_LIMIT
|
|
447
|
+
* @property {number} TAG_LEN1
|
|
448
|
+
* @property {number} TAG_LEN2
|
|
449
|
+
* @property {number} CONNECTION_CHECKER_PERIOD
|
|
450
|
+
* @property {number} PROMISE_TIMEOUT
|
|
451
|
+
* @property {number} DID
|
|
452
|
+
* @property {number} CID
|
|
453
|
+
*/
|
|
417
454
|
const SIZE_LIMIT = {
|
|
418
455
|
TAG_LEN1: 255,
|
|
419
456
|
TAG_LEN2: 65535,
|
|
@@ -423,6 +460,15 @@ const SIZE_LIMIT = {
|
|
|
423
460
|
CID: 12
|
|
424
461
|
};
|
|
425
462
|
|
|
463
|
+
/**
|
|
464
|
+
* @typedef {object} PAYLOAD_TYPE
|
|
465
|
+
* @property {number} EMPTY
|
|
466
|
+
* @property {number} TEXT
|
|
467
|
+
* @property {number} BINARY
|
|
468
|
+
* @property {number} OBJECT
|
|
469
|
+
* @property {number} MJSON
|
|
470
|
+
* @property {number} MBA
|
|
471
|
+
*/
|
|
426
472
|
let PAYLOAD_TYPE = {
|
|
427
473
|
EMPTY: 0,
|
|
428
474
|
TEXT: 1,
|
|
@@ -434,6 +480,40 @@ let PAYLOAD_TYPE = {
|
|
|
434
480
|
for (let c in PAYLOAD_TYPE) { PAYLOAD_TYPE[PAYLOAD_TYPE[c]] = c; }
|
|
435
481
|
|
|
436
482
|
|
|
483
|
+
/**
|
|
484
|
+
* @typedef {object} IOMsg
|
|
485
|
+
* @property {number} SERVER_READY
|
|
486
|
+
* @property {number} CID_REQ
|
|
487
|
+
* @property {number} CID_RES
|
|
488
|
+
* @property {number} QUOTA_LEVEL
|
|
489
|
+
* @property {number} SERVER_CLEAR_AUTH
|
|
490
|
+
* @property {number} SERVER_REDIRECT
|
|
491
|
+
* @property {number} LOOP
|
|
492
|
+
* @property {number} ECHO
|
|
493
|
+
* @property {number} PING
|
|
494
|
+
* @property {number} PONG
|
|
495
|
+
* @property {number} CLOSE
|
|
496
|
+
* @property {number} SIGNAL
|
|
497
|
+
* @property {number} SIGNAL_REQ
|
|
498
|
+
* @property {number} SIGNAL_E2E
|
|
499
|
+
* @property {number} SUBSCRIBE
|
|
500
|
+
* @property {number} SUBSCRIBE_REQ
|
|
501
|
+
* @property {number} UNSUBSCRIBE
|
|
502
|
+
* @property {number} SERVER_SIGNAL
|
|
503
|
+
* @property {number} IAM
|
|
504
|
+
* @property {number} IAM_RES
|
|
505
|
+
* @property {number} SET
|
|
506
|
+
* @property {number} RESPONSE_CODE
|
|
507
|
+
* @property {number} RESPONSE_MBP
|
|
508
|
+
* @property {number} REQUEST
|
|
509
|
+
* @property {number} RESPONSE
|
|
510
|
+
* @property {number} FLOW_MODE
|
|
511
|
+
* @property {number} WAIT
|
|
512
|
+
* @property {number} RESUME
|
|
513
|
+
* @property {number} TIME_OUT
|
|
514
|
+
* @property {number} OVER_SIZE
|
|
515
|
+
* @property {number} OVER_FLOW
|
|
516
|
+
*/
|
|
437
517
|
// IO message's one-byte headers.
|
|
438
518
|
let IOMsg = {
|
|
439
519
|
|
|
@@ -513,11 +593,21 @@ let IOMsg = {
|
|
|
513
593
|
for (let c in IOMsg) { IOMsg[IOMsg[c]] = c; }
|
|
514
594
|
// console.log( IOMsg );
|
|
515
595
|
|
|
596
|
+
/**
|
|
597
|
+
* @typedef {object} API_TYPE
|
|
598
|
+
* @property {string} REQUEST_RESPONSE
|
|
599
|
+
* @property {string} ONE_WAY
|
|
600
|
+
*/
|
|
516
601
|
const API_TYPE = {
|
|
517
602
|
'REQUEST_RESPONSE': 'requet_response',
|
|
518
603
|
'ONE_WAY': 'one_way'
|
|
519
604
|
};
|
|
520
605
|
|
|
606
|
+
/**
|
|
607
|
+
* @typedef {object} STATUS
|
|
608
|
+
* @property {number} OK
|
|
609
|
+
* @property {number} ERROR
|
|
610
|
+
*/
|
|
521
611
|
// api response status code
|
|
522
612
|
const STATUS$1 = {
|
|
523
613
|
OK: 0,
|
|
@@ -691,6 +781,19 @@ const t=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1
|
|
|
691
781
|
* @license MIT
|
|
692
782
|
*/var V=(K||(K=1,function(t){const e=function(){if(j)return D;j=1,D.byteLength=function(t){var e=o(t),r=e[0],n=e[1];return 3*(r+n)/4-n},D.toByteArray=function(t){var n,i,f=o(t),s=f[0],u=f[1],h=new r(function(t,e,r){return 3*(e+r)/4-r}(0,s,u)),a=0,c=u>0?s-4:s;for(i=0;i<c;i+=4)n=e[t.charCodeAt(i)]<<18|e[t.charCodeAt(i+1)]<<12|e[t.charCodeAt(i+2)]<<6|e[t.charCodeAt(i+3)],h[a++]=n>>16&255,h[a++]=n>>8&255,h[a++]=255&n;return 2===u&&(n=e[t.charCodeAt(i)]<<2|e[t.charCodeAt(i+1)]>>4,h[a++]=255&n),1===u&&(n=e[t.charCodeAt(i)]<<10|e[t.charCodeAt(i+1)]<<4|e[t.charCodeAt(i+2)]>>2,h[a++]=n>>8&255,h[a++]=255&n),h},D.fromByteArray=function(e){for(var r,n=e.length,i=n%3,o=[],s=16383,u=0,h=n-i;u<h;u+=s)o.push(f(e,u,u+s>h?h:u+s));return 1===i?(r=e[n-1],o.push(t[r>>2]+t[r<<4&63]+"==")):2===i&&(r=(e[n-2]<<8)+e[n-1],o.push(t[r>>10]+t[r>>4&63]+t[r<<2&63]+"=")),o.join("")};for(var t=[],e=[],r="undefined"!=typeof Uint8Array?Uint8Array:Array,n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0;i<64;++i)t[i]=n[i],e[n.charCodeAt(i)]=i;function o(t){var e=t.length;if(e%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var r=t.indexOf("=");return -1===r&&(r=e),[r,r===e?0:4-r%4]}function f(e,r,n){for(var i,o,f=[],s=r;s<n;s+=3)i=(e[s]<<16&16711680)+(e[s+1]<<8&65280)+(255&e[s+2]),f.push(t[(o=i)>>18&63]+t[o>>12&63]+t[o>>6&63]+t[63&o]);return f.join("")}return e["-".charCodeAt(0)]=62,e["_".charCodeAt(0)]=63,D}(),r=G(),n="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;t.Buffer=f,t.SlowBuffer=function(t){return +t!=t&&(t=0),f.alloc(+t)},t.INSPECT_MAX_BYTES=50;const i=2147483647;function o(t){if(t>i)throw new RangeError('The value "'+t+'" is invalid for option "size"');const e=new Uint8Array(t);return Object.setPrototypeOf(e,f.prototype),e}function f(t,e,r){if("number"==typeof t){if("string"==typeof e)throw new TypeError('The "string" argument must be of type string. Received type number');return h(t)}return s(t,e,r)}function s(t,e,r){if("string"==typeof t)return function(t,e){if("string"==typeof e&&""!==e||(e="utf8"),!f.isEncoding(e))throw new TypeError("Unknown encoding: "+e);const r=0|p(t,e);let n=o(r);const i=n.write(t,e);return i!==r&&(n=n.slice(0,i)),n}(t,e);if(ArrayBuffer.isView(t))return function(t){if(Q(t,Uint8Array)){const e=new Uint8Array(t);return c(e.buffer,e.byteOffset,e.byteLength)}return a(t)}(t);if(null==t)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof t);if(Q(t,ArrayBuffer)||t&&Q(t.buffer,ArrayBuffer))return c(t,e,r);if("undefined"!=typeof SharedArrayBuffer&&(Q(t,SharedArrayBuffer)||t&&Q(t.buffer,SharedArrayBuffer)))return c(t,e,r);if("number"==typeof t)throw new TypeError('The "value" argument must not be of type number. Received type number');const n=t.valueOf&&t.valueOf();if(null!=n&&n!==t)return f.from(n,e,r);const i=function(t){if(f.isBuffer(t)){const e=0|l(t.length),r=o(e);return 0===r.length||t.copy(r,0,0,e),r}return void 0!==t.length?"number"!=typeof t.length||X(t.length)?o(0):a(t):"Buffer"===t.type&&Array.isArray(t.data)?a(t.data):void 0}(t);if(i)return i;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof t[Symbol.toPrimitive])return f.from(t[Symbol.toPrimitive]("string"),e,r);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof t)}function u(t){if("number"!=typeof t)throw new TypeError('"size" argument must be of type number');if(t<0)throw new RangeError('The value "'+t+'" is invalid for option "size"')}function h(t){return u(t),o(t<0?0:0|l(t))}function a(t){const e=t.length<0?0:0|l(t.length),r=o(e);for(let n=0;n<e;n+=1)r[n]=255&t[n];return r}function c(t,e,r){if(e<0||t.byteLength<e)throw new RangeError('"offset" is outside of buffer bounds');if(t.byteLength<e+(r||0))throw new RangeError('"length" is outside of buffer bounds');let n;return n=void 0===e&&void 0===r?new Uint8Array(t):void 0===r?new Uint8Array(t,e):new Uint8Array(t,e,r),Object.setPrototypeOf(n,f.prototype),n}function l(t){if(t>=i)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i.toString(16)+" bytes");return 0|t}function p(t,e){if(f.isBuffer(t))return t.length;if(ArrayBuffer.isView(t)||Q(t,ArrayBuffer))return t.byteLength;if("string"!=typeof t)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof t);const r=t.length,n=arguments.length>2&&true===arguments[2];if(!n&&0===r)return 0;let i=false;for(;;)switch(e){case "ascii":case "latin1":case "binary":return r;case "utf8":case "utf-8":return q(t).length;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":return 2*r;case "hex":return r>>>1;case "base64":return V(t).length;default:if(i)return n?-1:q(t).length;e=(""+e).toLowerCase(),i=true;}}function y(t,e,r){let n=false;if((void 0===e||e<0)&&(e=0),e>this.length)return "";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return "";if((r>>>=0)<=(e>>>=0))return "";for(t||(t="utf8");;)switch(t){case "hex":return T(this,e,r);case "utf8":case "utf-8":return U(this,e,r);case "ascii":return L(this,e,r);case "latin1":case "binary":return v(this,e,r);case "base64":return _(this,e,r);case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":return S(this,e,r);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=true;}}function g(t,e,r){const n=t[e];t[e]=t[r],t[r]=n;}function d(t,e,r,n,i){if(0===t.length)return -1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),X(r=+r)&&(r=i?0:t.length-1),r<0&&(r=t.length+r),r>=t.length){if(i)return -1;r=t.length-1;}else if(r<0){if(!i)return -1;r=0;}if("string"==typeof e&&(e=f.from(e,n)),f.isBuffer(e))return 0===e.length?-1:b(t,e,r,n,i);if("number"==typeof e)return e&=255,"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(t,e,r):Uint8Array.prototype.lastIndexOf.call(t,e,r):b(t,[e],r,n,i);throw new TypeError("val must be string, number or Buffer")}function b(t,e,r,n,i){let o,f=1,s=t.length,u=e.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||e.length<2)return -1;f=2,s/=2,u/=2,r/=2;}function h(t,e){return 1===f?t[e]:t.readUInt16BE(e*f)}if(i){let n=-1;for(o=r;o<s;o++)if(h(t,o)===h(e,-1===n?0:o-n)){if(-1===n&&(n=o),o-n+1===u)return n*f}else -1!==n&&(o-=o-n),n=-1;}else for(r+u>s&&(r=s-u),o=r;o>=0;o--){let r=true;for(let n=0;n<u;n++)if(h(t,o+n)!==h(e,n)){r=false;break}if(r)return o}return -1}function w(t,e,r,n){r=Number(r)||0;const i=t.length-r;n?(n=Number(n))>i&&(n=i):n=i;const o=e.length;let f;for(n>o/2&&(n=o/2),f=0;f<n;++f){const n=parseInt(e.substr(2*f,2),16);if(X(n))return f;t[r+f]=n;}return f}function B(t,e,r,n){return J(q(e,t.length-r),t,r,n)}function m(t,e,r,n){return J(function(t){const e=[];for(let r=0;r<t.length;++r)e.push(255&t.charCodeAt(r));return e}(e),t,r,n)}function E(t,e,r,n){return J(V(e),t,r,n)}function A(t,e,r,n){return J(function(t,e){let r,n,i;const o=[];for(let f=0;f<t.length&&!((e-=2)<0);++f)r=t.charCodeAt(f),n=r>>8,i=r%256,o.push(i),o.push(n);return o}(e,t.length-r),t,r,n)}function _(t,r,n){return 0===r&&n===t.length?e.fromByteArray(t):e.fromByteArray(t.slice(r,n))}function U(t,e,r){r=Math.min(t.length,r);const n=[];let i=e;for(;i<r;){const e=t[i];let o=null,f=e>239?4:e>223?3:e>191?2:1;if(i+f<=r){let r,n,s,u;switch(f){case 1:e<128&&(o=e);break;case 2:r=t[i+1],128==(192&r)&&(u=(31&e)<<6|63&r,u>127&&(o=u));break;case 3:r=t[i+1],n=t[i+2],128==(192&r)&&128==(192&n)&&(u=(15&e)<<12|(63&r)<<6|63&n,u>2047&&(u<55296||u>57343)&&(o=u));break;case 4:r=t[i+1],n=t[i+2],s=t[i+3],128==(192&r)&&128==(192&n)&&128==(192&s)&&(u=(15&e)<<18|(63&r)<<12|(63&n)<<6|63&s,u>65535&&u<1114112&&(o=u));}}null===o?(o=65533,f=1):o>65535&&(o-=65536,n.push(o>>>10&1023|55296),o=56320|1023&o),n.push(o),i+=f;}return function(t){const e=t.length;if(e<=I)return String.fromCharCode.apply(String,t);let r="",n=0;for(;n<e;)r+=String.fromCharCode.apply(String,t.slice(n,n+=I));return r}(n)}t.kMaxLength=i,f.TYPED_ARRAY_SUPPORT=function(){try{const t=new Uint8Array(1),e={foo:function(){return 42}};return Object.setPrototypeOf(e,Uint8Array.prototype),Object.setPrototypeOf(t,e),42===t.foo()}catch(t){return false}}(),f.TYPED_ARRAY_SUPPORT||"undefined"==typeof console||"function"!=typeof console.error||console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support."),Object.defineProperty(f.prototype,"parent",{enumerable:true,get:function(){if(f.isBuffer(this))return this.buffer}}),Object.defineProperty(f.prototype,"offset",{enumerable:true,get:function(){if(f.isBuffer(this))return this.byteOffset}}),f.poolSize=8192,f.from=function(t,e,r){return s(t,e,r)},Object.setPrototypeOf(f.prototype,Uint8Array.prototype),Object.setPrototypeOf(f,Uint8Array),f.alloc=function(t,e,r){return function(t,e,r){return u(t),t<=0?o(t):void 0!==e?"string"==typeof r?o(t).fill(e,r):o(t).fill(e):o(t)}(t,e,r)},f.allocUnsafe=function(t){return h(t)},f.allocUnsafeSlow=function(t){return h(t)},f.isBuffer=function(t){return null!=t&&true===t._isBuffer&&t!==f.prototype},f.compare=function(t,e){if(Q(t,Uint8Array)&&(t=f.from(t,t.offset,t.byteLength)),Q(e,Uint8Array)&&(e=f.from(e,e.offset,e.byteLength)),!f.isBuffer(t)||!f.isBuffer(e))throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if(t===e)return 0;let r=t.length,n=e.length;for(let i=0,o=Math.min(r,n);i<o;++i)if(t[i]!==e[i]){r=t[i],n=e[i];break}return r<n?-1:n<r?1:0},f.isEncoding=function(t){switch(String(t).toLowerCase()){case "hex":case "utf8":case "utf-8":case "ascii":case "latin1":case "binary":case "base64":case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":return true;default:return false}},f.concat=function(t,e){if(!Array.isArray(t))throw new TypeError('"list" argument must be an Array of Buffers');if(0===t.length)return f.alloc(0);let r;if(void 0===e)for(e=0,r=0;r<t.length;++r)e+=t[r].length;const n=f.allocUnsafe(e);let i=0;for(r=0;r<t.length;++r){let e=t[r];if(Q(e,Uint8Array))i+e.length>n.length?(f.isBuffer(e)||(e=f.from(e)),e.copy(n,i)):Uint8Array.prototype.set.call(n,e,i);else {if(!f.isBuffer(e))throw new TypeError('"list" argument must be an Array of Buffers');e.copy(n,i);}i+=e.length;}return n},f.byteLength=p,f.prototype._isBuffer=true,f.prototype.swap16=function(){const t=this.length;if(t%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(let e=0;e<t;e+=2)g(this,e,e+1);return this},f.prototype.swap32=function(){const t=this.length;if(t%4!=0)throw new RangeError("Buffer size must be a multiple of 32-bits");for(let e=0;e<t;e+=4)g(this,e,e+3),g(this,e+1,e+2);return this},f.prototype.swap64=function(){const t=this.length;if(t%8!=0)throw new RangeError("Buffer size must be a multiple of 64-bits");for(let e=0;e<t;e+=8)g(this,e,e+7),g(this,e+1,e+6),g(this,e+2,e+5),g(this,e+3,e+4);return this},f.prototype.toString=function(){const t=this.length;return 0===t?"":0===arguments.length?U(this,0,t):y.apply(this,arguments)},f.prototype.toLocaleString=f.prototype.toString,f.prototype.equals=function(t){if(!f.isBuffer(t))throw new TypeError("Argument must be a Buffer");return this===t||0===f.compare(this,t)},f.prototype.inspect=function(){let e="";const r=t.INSPECT_MAX_BYTES;return e=this.toString("hex",0,r).replace(/(.{2})/g,"$1 ").trim(),this.length>r&&(e+=" ... "),"<Buffer "+e+">"},n&&(f.prototype[n]=f.prototype.inspect),f.prototype.compare=function(t,e,r,n,i){if(Q(t,Uint8Array)&&(t=f.from(t,t.offset,t.byteLength)),!f.isBuffer(t))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof t);if(void 0===e&&(e=0),void 0===r&&(r=t?t.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),e<0||r>t.length||n<0||i>this.length)throw new RangeError("out of range index");if(n>=i&&e>=r)return 0;if(n>=i)return -1;if(e>=r)return 1;if(this===t)return 0;let o=(i>>>=0)-(n>>>=0),s=(r>>>=0)-(e>>>=0);const u=Math.min(o,s),h=this.slice(n,i),a=t.slice(e,r);for(let t=0;t<u;++t)if(h[t]!==a[t]){o=h[t],s=a[t];break}return o<s?-1:s<o?1:0},f.prototype.includes=function(t,e,r){return -1!==this.indexOf(t,e,r)},f.prototype.indexOf=function(t,e,r){return d(this,t,e,r,true)},f.prototype.lastIndexOf=function(t,e,r){return d(this,t,e,r,false)},f.prototype.write=function(t,e,r,n){if(void 0===e)n="utf8",r=this.length,e=0;else if(void 0===r&&"string"==typeof e)n=e,r=this.length,e=0;else {if(!isFinite(e))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");e>>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n="utf8")):(n=r,r=void 0);}const i=this.length-e;if((void 0===r||r>i)&&(r=i),t.length>0&&(r<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");let o=false;for(;;)switch(n){case "hex":return w(this,t,e,r);case "utf8":case "utf-8":return B(this,t,e,r);case "ascii":case "latin1":case "binary":return m(this,t,e,r);case "base64":return E(this,t,e,r);case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":return A(this,t,e,r);default:if(o)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),o=true;}},f.prototype.toJSON=function(){return {type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};const I=4096;function L(t,e,r){let n="";r=Math.min(t.length,r);for(let i=e;i<r;++i)n+=String.fromCharCode(127&t[i]);return n}function v(t,e,r){let n="";r=Math.min(t.length,r);for(let i=e;i<r;++i)n+=String.fromCharCode(t[i]);return n}function T(t,e,r){const n=t.length;(!e||e<0)&&(e=0),(!r||r<0||r>n)&&(r=n);let i="";for(let n=e;n<r;++n)i+=W[t[n]];return i}function S(t,e,r){const n=t.slice(e,r);let i="";for(let t=0;t<n.length-1;t+=2)i+=String.fromCharCode(n[t]+256*n[t+1]);return i}function R(t,e,r){if(t%1!=0||t<0)throw new RangeError("offset is not uint");if(t+e>r)throw new RangeError("Trying to access beyond buffer length")}function O(t,e,r,n,i,o){if(!f.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(e>i||e<o)throw new RangeError('"value" argument is out of bounds');if(r+n>t.length)throw new RangeError("Index out of range")}function M(t,e,r,n,i){F(e,n,i,t,r,7);let o=Number(e&BigInt(4294967295));t[r++]=o,o>>=8,t[r++]=o,o>>=8,t[r++]=o,o>>=8,t[r++]=o;let f=Number(e>>BigInt(32)&BigInt(4294967295));return t[r++]=f,f>>=8,t[r++]=f,f>>=8,t[r++]=f,f>>=8,t[r++]=f,r}function C(t,e,r,n,i){F(e,n,i,t,r,7);let o=Number(e&BigInt(4294967295));t[r+7]=o,o>>=8,t[r+6]=o,o>>=8,t[r+5]=o,o>>=8,t[r+4]=o;let f=Number(e>>BigInt(32)&BigInt(4294967295));return t[r+3]=f,f>>=8,t[r+2]=f,f>>=8,t[r+1]=f,f>>=8,t[r]=f,r+8}function N(t,e,r,n,i,o){if(r+n>t.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function x(t,e,n,i,o){return e=+e,n>>>=0,o||N(t,0,n,4),r.write(t,e,n,i,23,4),n+4}function k(t,e,n,i,o){return e=+e,n>>>=0,o||N(t,0,n,8),r.write(t,e,n,i,52,8),n+8}f.prototype.slice=function(t,e){const r=this.length;(t=~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),(e=void 0===e?r:~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),e<t&&(e=t);const n=this.subarray(t,e);return Object.setPrototypeOf(n,f.prototype),n},f.prototype.readUintLE=f.prototype.readUIntLE=function(t,e,r){t>>>=0,e>>>=0,r||R(t,e,this.length);let n=this[t],i=1,o=0;for(;++o<e&&(i*=256);)n+=this[t+o]*i;return n},f.prototype.readUintBE=f.prototype.readUIntBE=function(t,e,r){t>>>=0,e>>>=0,r||R(t,e,this.length);let n=this[t+--e],i=1;for(;e>0&&(i*=256);)n+=this[t+--e]*i;return n},f.prototype.readUint8=f.prototype.readUInt8=function(t,e){return t>>>=0,e||R(t,1,this.length),this[t]},f.prototype.readUint16LE=f.prototype.readUInt16LE=function(t,e){return t>>>=0,e||R(t,2,this.length),this[t]|this[t+1]<<8},f.prototype.readUint16BE=f.prototype.readUInt16BE=function(t,e){return t>>>=0,e||R(t,2,this.length),this[t]<<8|this[t+1]},f.prototype.readUint32LE=f.prototype.readUInt32LE=function(t,e){return t>>>=0,e||R(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},f.prototype.readUint32BE=f.prototype.readUInt32BE=function(t,e){return t>>>=0,e||R(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},f.prototype.readBigUInt64LE=Z((function(t){z(t>>>=0,"offset");const e=this[t],r=this[t+7];void 0!==e&&void 0!==r||Y(t,this.length-8);const n=e+256*this[++t]+65536*this[++t]+this[++t]*2**24,i=this[++t]+256*this[++t]+65536*this[++t]+r*2**24;return BigInt(n)+(BigInt(i)<<BigInt(32))})),f.prototype.readBigUInt64BE=Z((function(t){z(t>>>=0,"offset");const e=this[t],r=this[t+7];void 0!==e&&void 0!==r||Y(t,this.length-8);const n=e*2**24+65536*this[++t]+256*this[++t]+this[++t],i=this[++t]*2**24+65536*this[++t]+256*this[++t]+r;return (BigInt(n)<<BigInt(32))+BigInt(i)})),f.prototype.readIntLE=function(t,e,r){t>>>=0,e>>>=0,r||R(t,e,this.length);let n=this[t],i=1,o=0;for(;++o<e&&(i*=256);)n+=this[t+o]*i;return i*=128,n>=i&&(n-=Math.pow(2,8*e)),n},f.prototype.readIntBE=function(t,e,r){t>>>=0,e>>>=0,r||R(t,e,this.length);let n=e,i=1,o=this[t+--n];for(;n>0&&(i*=256);)o+=this[t+--n]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*e)),o},f.prototype.readInt8=function(t,e){return t>>>=0,e||R(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},f.prototype.readInt16LE=function(t,e){t>>>=0,e||R(t,2,this.length);const r=this[t]|this[t+1]<<8;return 32768&r?4294901760|r:r},f.prototype.readInt16BE=function(t,e){t>>>=0,e||R(t,2,this.length);const r=this[t+1]|this[t]<<8;return 32768&r?4294901760|r:r},f.prototype.readInt32LE=function(t,e){return t>>>=0,e||R(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},f.prototype.readInt32BE=function(t,e){return t>>>=0,e||R(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},f.prototype.readBigInt64LE=Z((function(t){z(t>>>=0,"offset");const e=this[t],r=this[t+7];void 0!==e&&void 0!==r||Y(t,this.length-8);const n=this[t+4]+256*this[t+5]+65536*this[t+6]+(r<<24);return (BigInt(n)<<BigInt(32))+BigInt(e+256*this[++t]+65536*this[++t]+this[++t]*2**24)})),f.prototype.readBigInt64BE=Z((function(t){z(t>>>=0,"offset");const e=this[t],r=this[t+7];void 0!==e&&void 0!==r||Y(t,this.length-8);const n=(e<<24)+65536*this[++t]+256*this[++t]+this[++t];return (BigInt(n)<<BigInt(32))+BigInt(this[++t]*2**24+65536*this[++t]+256*this[++t]+r)})),f.prototype.readFloatLE=function(t,e){return t>>>=0,e||R(t,4,this.length),r.read(this,t,true,23,4)},f.prototype.readFloatBE=function(t,e){return t>>>=0,e||R(t,4,this.length),r.read(this,t,false,23,4)},f.prototype.readDoubleLE=function(t,e){return t>>>=0,e||R(t,8,this.length),r.read(this,t,true,52,8)},f.prototype.readDoubleBE=function(t,e){return t>>>=0,e||R(t,8,this.length),r.read(this,t,false,52,8)},f.prototype.writeUintLE=f.prototype.writeUIntLE=function(t,e,r,n){t=+t,e>>>=0,r>>>=0,n||O(this,t,e,r,Math.pow(2,8*r)-1,0);let i=1,o=0;for(this[e]=255&t;++o<r&&(i*=256);)this[e+o]=t/i&255;return e+r},f.prototype.writeUintBE=f.prototype.writeUIntBE=function(t,e,r,n){t=+t,e>>>=0,r>>>=0,n||O(this,t,e,r,Math.pow(2,8*r)-1,0);let i=r-1,o=1;for(this[e+i]=255&t;--i>=0&&(o*=256);)this[e+i]=t/o&255;return e+r},f.prototype.writeUint8=f.prototype.writeUInt8=function(t,e,r){return t=+t,e>>>=0,r||O(this,t,e,1,255,0),this[e]=255&t,e+1},f.prototype.writeUint16LE=f.prototype.writeUInt16LE=function(t,e,r){return t=+t,e>>>=0,r||O(this,t,e,2,65535,0),this[e]=255&t,this[e+1]=t>>>8,e+2},f.prototype.writeUint16BE=f.prototype.writeUInt16BE=function(t,e,r){return t=+t,e>>>=0,r||O(this,t,e,2,65535,0),this[e]=t>>>8,this[e+1]=255&t,e+2},f.prototype.writeUint32LE=f.prototype.writeUInt32LE=function(t,e,r){return t=+t,e>>>=0,r||O(this,t,e,4,4294967295,0),this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t,e+4},f.prototype.writeUint32BE=f.prototype.writeUInt32BE=function(t,e,r){return t=+t,e>>>=0,r||O(this,t,e,4,4294967295,0),this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t,e+4},f.prototype.writeBigUInt64LE=Z((function(t,e=0){return M(this,t,e,BigInt(0),BigInt("0xffffffffffffffff"))})),f.prototype.writeBigUInt64BE=Z((function(t,e=0){return C(this,t,e,BigInt(0),BigInt("0xffffffffffffffff"))})),f.prototype.writeIntLE=function(t,e,r,n){if(t=+t,e>>>=0,!n){const n=Math.pow(2,8*r-1);O(this,t,e,r,n-1,-n);}let i=0,o=1,f=0;for(this[e]=255&t;++i<r&&(o*=256);)t<0&&0===f&&0!==this[e+i-1]&&(f=1),this[e+i]=(t/o|0)-f&255;return e+r},f.prototype.writeIntBE=function(t,e,r,n){if(t=+t,e>>>=0,!n){const n=Math.pow(2,8*r-1);O(this,t,e,r,n-1,-n);}let i=r-1,o=1,f=0;for(this[e+i]=255&t;--i>=0&&(o*=256);)t<0&&0===f&&0!==this[e+i+1]&&(f=1),this[e+i]=(t/o|0)-f&255;return e+r},f.prototype.writeInt8=function(t,e,r){return t=+t,e>>>=0,r||O(this,t,e,1,127,-128),t<0&&(t=255+t+1),this[e]=255&t,e+1},f.prototype.writeInt16LE=function(t,e,r){return t=+t,e>>>=0,r||O(this,t,e,2,32767,-32768),this[e]=255&t,this[e+1]=t>>>8,e+2},f.prototype.writeInt16BE=function(t,e,r){return t=+t,e>>>=0,r||O(this,t,e,2,32767,-32768),this[e]=t>>>8,this[e+1]=255&t,e+2},f.prototype.writeInt32LE=function(t,e,r){return t=+t,e>>>=0,r||O(this,t,e,4,2147483647,-2147483648),this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24,e+4},f.prototype.writeInt32BE=function(t,e,r){return t=+t,e>>>=0,r||O(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t,e+4},f.prototype.writeBigInt64LE=Z((function(t,e=0){return M(this,t,e,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),f.prototype.writeBigInt64BE=Z((function(t,e=0){return C(this,t,e,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),f.prototype.writeFloatLE=function(t,e,r){return x(this,t,e,true,r)},f.prototype.writeFloatBE=function(t,e,r){return x(this,t,e,false,r)},f.prototype.writeDoubleLE=function(t,e,r){return k(this,t,e,true,r)},f.prototype.writeDoubleBE=function(t,e,r){return k(this,t,e,false,r)},f.prototype.copy=function(t,e,r,n){if(!f.isBuffer(t))throw new TypeError("argument should be a Buffer");if(r||(r=0),n||0===n||(n=this.length),e>=t.length&&(e=t.length),e||(e=0),n>0&&n<r&&(n=r),n===r)return 0;if(0===t.length||0===this.length)return 0;if(e<0)throw new RangeError("targetStart out of bounds");if(r<0||r>=this.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),t.length-e<n-r&&(n=t.length-e+r);const i=n-r;return this===t&&"function"==typeof Uint8Array.prototype.copyWithin?this.copyWithin(e,r,n):Uint8Array.prototype.set.call(t,this.subarray(r,n),e),i},f.prototype.fill=function(t,e,r,n){if("string"==typeof t){if("string"==typeof e?(n=e,e=0,r=this.length):"string"==typeof r&&(n=r,r=this.length),void 0!==n&&"string"!=typeof n)throw new TypeError("encoding must be a string");if("string"==typeof n&&!f.isEncoding(n))throw new TypeError("Unknown encoding: "+n);if(1===t.length){const e=t.charCodeAt(0);("utf8"===n&&e<128||"latin1"===n)&&(t=e);}}else "number"==typeof t?t&=255:"boolean"==typeof t&&(t=Number(t));if(e<0||this.length<e||this.length<r)throw new RangeError("Out of range index");if(r<=e)return this;let i;if(e>>>=0,r=void 0===r?this.length:r>>>0,t||(t=0),"number"==typeof t)for(i=e;i<r;++i)this[i]=t;else {const o=f.isBuffer(t)?t:f.from(t,n),s=o.length;if(0===s)throw new TypeError('The value "'+t+'" is invalid for argument "value"');for(i=0;i<r-e;++i)this[i+e]=o[i%s];}return this};const P={};function $(t,e,r){P[t]=class extends r{constructor(){super(),Object.defineProperty(this,"message",{value:e.apply(this,arguments),writable:true,configurable:true}),this.name=`${this.name} [${t}]`,this.stack,delete this.name;}get code(){return t}set code(t){Object.defineProperty(this,"code",{configurable:true,enumerable:true,value:t,writable:true});}toString(){return `${this.name} [${t}]: ${this.message}`}};}function H(t){let e="",r=t.length;const n="-"===t[0]?1:0;for(;r>=n+4;r-=3)e=`_${t.slice(r-3,r)}${e}`;return `${t.slice(0,r)}${e}`}function F(t,e,r,n,i,o){if(t>r||t<e){const r="bigint"==typeof e?"n":"";let n;throw n=0===e||e===BigInt(0)?`>= 0${r} and < 2${r} ** ${8*(o+1)}${r}`:`>= -(2${r} ** ${8*(o+1)-1}${r}) and < 2 ** ${8*(o+1)-1}${r}`,new P.ERR_OUT_OF_RANGE("value",n,t)}!function(t,e,r){z(e,"offset"),void 0!==t[e]&&void 0!==t[e+r]||Y(e,t.length-(r+1));}(n,i,o);}function z(t,e){if("number"!=typeof t)throw new P.ERR_INVALID_ARG_TYPE(e,"number",t)}function Y(t,e,r){if(Math.floor(t)!==t)throw z(t,r),new P.ERR_OUT_OF_RANGE("offset","an integer",t);if(e<0)throw new P.ERR_BUFFER_OUT_OF_BOUNDS;throw new P.ERR_OUT_OF_RANGE("offset",`>= 0 and <= ${e}`,t)}$("ERR_BUFFER_OUT_OF_BOUNDS",(function(t){return t?`${t} is outside of buffer bounds`:"Attempt to access memory outside buffer bounds"}),RangeError),$("ERR_INVALID_ARG_TYPE",(function(t,e){return `The "${t}" argument must be of type number. Received type ${typeof e}`}),TypeError),$("ERR_OUT_OF_RANGE",(function(t,e,r){let n=`The value of "${t}" is out of range.`,i=r;return Number.isInteger(r)&&Math.abs(r)>2**32?i=H(String(r)):"bigint"==typeof r&&(i=String(r),(r>BigInt(2)**BigInt(32)||r<-(BigInt(2)**BigInt(32)))&&(i=H(i)),i+="n"),n+=` It must be ${e}. Received ${i}`,n}),RangeError);const K=/[^+/0-9A-Za-z-_]/g;function q(t,e){let r;e=e||1/0;const n=t.length;let i=null;const o=[];for(let f=0;f<n;++f){if(r=t.charCodeAt(f),r>55295&&r<57344){if(!i){if(r>56319){(e-=3)>-1&&o.push(239,191,189);continue}if(f+1===n){(e-=3)>-1&&o.push(239,191,189);continue}i=r;continue}if(r<56320){(e-=3)>-1&&o.push(239,191,189),i=r;continue}r=65536+(i-55296<<10|r-56320);}else i&&(e-=3)>-1&&o.push(239,191,189);if(i=null,r<128){if((e-=1)<0)break;o.push(r);}else if(r<2048){if((e-=2)<0)break;o.push(r>>6|192,63&r|128);}else if(r<65536){if((e-=3)<0)break;o.push(r>>12|224,r>>6&63|128,63&r|128);}else {if(!(r<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;o.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128);}}return o}function V(t){return e.toByteArray(function(t){if((t=(t=t.split("=")[0]).trim().replace(K,"")).length<2)return "";for(;t.length%4!=0;)t+="=";return t}(t))}function J(t,e,r,n){let i;for(i=0;i<n&&!(i+r>=e.length||i>=t.length);++i)e[i+r]=t[i];return i}function Q(t,e){return t instanceof e||null!=t&&null!=t.constructor&&null!=t.constructor.name&&t.constructor.name===e.name}function X(t){return t!=t}const W=function(){const t="0123456789abcdef",e=new Array(256);for(let r=0;r<16;++r){const n=16*r;for(let i=0;i<16;++i)e[n+i]=t[r]+t[i];}return e}();function Z(t){return "undefined"==typeof BigInt?tt:t}function tt(){throw new Error("BigInt not supported")}}(z)),z);let J={AUTH_REQ:176,AUTH_NONCE:177,AUTH_HMAC:178,AUTH_ACK:179,AUTH_FAIL:180,AUTH_EXT:181,ENC_PACK:182,ENC_E2E:183,ENC_488:184};for(let t in J)J[J[t]]=t;const Q={AUTH_REQ:H.meta(H.MB("header","8",0),H.MB("reserved","8",0)),AUTH_NONCE:H.meta(H.MB("header","8",0),H.MB("unixTime","32L",0),H.MB("milTime","32L",0),H.MB("nonce",V.Buffer.alloc(4))),AUTH_HMAC:H.meta(H.MB("header","8",0),H.MB("id8",V.Buffer.alloc(8)),H.MB("nonce",V.Buffer.alloc(4)),H.MB("hmac32",V.Buffer.alloc(32))),AUTH_ACK:H.meta(H.MB("header","8",0),H.MB("hmac32",V.Buffer.alloc(32))),ENC_PACK:H.meta(H.MB("type","8",0),H.MB("len","32L",0),H.MB("salt12",V.Buffer.alloc(12)),H.MB("hmac",8,0)),ENC_488:H.meta(H.MB("type","8",0),H.MB("len","32L",0),H.MB("otpSrc8",V.Buffer.alloc(8)),H.MB("hmac8",V.Buffer.alloc(8)))};function X(t){let e=t[t.length-1];return e[2]+e[3]}const W={AUTH_REQ:X(Q.AUTH_REQ),AUTH_NONCE:X(Q.AUTH_NONCE),AUTH_HMAC:X(Q.AUTH_HMAC),AUTH_ACK:X(Q.AUTH_ACK),ENC_PACK:X(Q.ENC_PACK),ENC_488:X(Q.ENC_488)};function Z(t){return globalThis.crypto.getRandomValues(V.Buffer.alloc(t))}class tt{constructor(){this._id8=V.Buffer.alloc(8),this._otpSrc44=V.Buffer.alloc(44),this._otp36=V.Buffer.alloc(36),this._hmac=V.Buffer.alloc(32),this.auth_salt12=V.Buffer.alloc(12),this.localNonce=V.Buffer.alloc(4),this.remoteNonce=V.Buffer.alloc(4),this.isAuthorized=false;}clearAuth(){this._id8.fill(0),this._otpSrc44.fill(0),this._otp36.fill(0),this._hmac.fill(0),this.auth_salt12.fill(0),this.localNonce.fill(0),this.remoteNonce.fill(0),this.isAuthorized=false;}set_hash_id8(t){H.B8(F.hash(t)).copy(this._id8,0,0,8);}set_id8(t){let e=H.B8(t);this._id8.fill(0),e.copy(this._id8,0,0,8);}set_key(t){H.B8(F.hash(t)).copy(this._otpSrc44,0,0,32);}set_id_key(t){let e=t.indexOf(".");if(-1==e)return;let r=t.substring(0,e),n=t.substring(e+1);this.set_id8(r),this.set_key(n);}copy_id8(t){t.copy(this._id8,0,0,8);}copy_key(t){t.copy(this._otpSrc44,0,0,32);}sha256_n(t,e){let r=F.hash(t);for(let t=0;t<e;t++)r=F.hash(r);return r}set_clock_rand(){let t=Date.now(),e=parseInt(t/1e3);t%=4294967295;V.Buffer.concat([H.NB("32L",e),H.NB("32L",t),Z(4)]).copy(this._otpSrc44,32);}set_clock_nonce(t){let e=Date.now(),r=parseInt(e/1e3);e%=4294967295;V.Buffer.concat([H.NB("32L",r),H.NB("32L",e),t]).copy(this._otpSrc44,32);}set_salt12(t){t.copy(this._otpSrc44,32);}resetOTP(){H.B8(F.hash(this._otpSrc44)).copy(this._otp36,0,0,32);}getIndexOTP(t){return this._otp36.writeUInt32LE(t,32),F.hash(this._otp36)}generateHMAC(t){let e=V.Buffer.concat([this._otpSrc44,t]);this._hmac=H.B8(F.hash(e));}getHMAC8(t){let e=V.Buffer.concat([this._otpSrc44,t]);return this._hmac=H.B8(F.hash(e)),this._hmac.subarray(0,8)}xotp(t,e=0,r=false){let n=(t=H.B8(t,r)).byteLength,i=e,o=0,f=0;for(;n>0;){f=n<32?n:32;let e=this.getIndexOTP(++i);for(let r=0;r<f;r++)t[o++]^=e[r];n-=32;}return t}auth_req(){return H.pack(H.MB("#type","8",J.AUTH_REQ),H.MB("#reserved","8",0))}auth_nonce(){let t=Date.now(),e=Math.floor(t/1e3),r=t%1e3;return this.localNonce=Z(4),this.auth_salt12=V.Buffer.concat([H.NB("32L",e),H.NB("32L",r),this.localNonce]),V.Buffer.concat([H.NB("8",J.AUTH_NONCE),this.auth_salt12])}auth_hmac(t){let e=H.unpack(t,Q.AUTH_NONCE);if(e){let t=V.Buffer.concat([H.NB("32L",e.unixTime),H.NB("32L",e.milTime),e.nonce]);return this.set_salt12(t),this.localNonce=Z(4),this.generateHMAC(this.localNonce),this.remoteNonce=e.nonce,H.pack(H.MB("#header","8",J.AUTH_HMAC),H.MB("#id8",this._id8),H.MB("#nonce",this.localNonce),H.MB("#hmac32",this._hmac))}return false}check_auth_hmac(t){let e;if(t instanceof Uint8Array){if(e=H.unpack(t,Q.AUTH_HMAC),!e)return}else e=t;this.set_salt12(this.auth_salt12),this.generateHMAC(e.nonce);let r=this._hmac;if(H.equal(e.hmac32,r)){this.remoteNonce=e.nonce;let t=V.Buffer.concat([this.localNonce,this.remoteNonce,this.localNonce]);this.set_salt12(t),this.generateHMAC(e.nonce);let r=this._hmac,n=H.rawPack(H.MB("header","8",J.AUTH_ACK),H.MB("hmac32",r));return this.isAuthorized=true,n}return false}check_auth_ack_hmac(t){let e=H.unpack(t,Q.AUTH_ACK);if(e){let t=V.Buffer.concat([this.remoteNonce,this.localNonce,this.remoteNonce]);this.set_salt12(t),this.generateHMAC(this.localNonce);let r=this._hmac;if(H.equal(r,e.hmac32))return this.isAuthorized=true,true}}encrypt_488(t){if(!this.isAuthorized)return;t=H.B8(t),this.set_clock_nonce(this.remoteNonce),this.resetOTP();let e=this.getHMAC8(t),r=this.xotp(t);return H.pack(H.MB("#type","8",J.ENC_488),H.MB("#len","32L",t.byteLength),H.MB("#otpSrc8",this._otpSrc44.subarray(32,40)),H.MB("#hmac8",e),H.MB("#xdata",r))}decrypt_488(t){t=H.B8(t);let e=H.unpack(t,Q.ENC_488);if(e){let t=V.Buffer.concat([e.otpSrc8,this.localNonce]);this.set_salt12(t),this.resetOTP();let r=e.$OTHERS.subarray(0,e.len),n=this.xotp(r),i=this.getHMAC8(n);if(H.equal(i,e.hmac8))return n}}encryptPack(t){t=H.B8(t),this.set_clock_rand(),this.resetOTP();let e=this.getHMAC8(t),r=this.xotp(t);return H.pack(H.MB("#type","8",J.ENC_PACK),H.MB("#len","32L",t.byteLength),H.MB("#salt12",this._otpSrc44.subarray(32)),H.MB("#hmac8",e),H.MB("#xdata",r))}decryptPack(t){if(t[0]!==J.ENC_PACK)return;if(t.readUint32LE(1)==t.byteLength-W.ENC_PACK)try{let e=H.unpack(t,Q.ENC_PACK);if(!e)return;this.set_salt12(e.salt12),this.resetOTP();let r=e.$OTHERS,n=this.xotp(r),i=this.getHMAC8(n);if(H.equal(e.hmac,i))return e.data=n,e}catch(t){}}encrypt_e2e(t,e){let r=V.Buffer.alloc(32);r.set(this._otpSrc44.subarray(0,32)),this.set_key(e);let n=this.encryptPack(t);return this._otpSrc44.set(r),n}decrypt_e2e(t,e){let r=V.Buffer.alloc(32);r.set(this._otpSrc44.subarray(0,32)),this.set_key(e);let n=this.decryptPack(t);return this._otpSrc44.set(r),n}}tt.RAND=Z,tt.BohoMsg=J,tt.Meta=Q,tt.MetaSize=W,tt.sha256=F,tt.MBP=H,tt.Buffer=V.Buffer;
|
|
693
783
|
|
|
784
|
+
/**
|
|
785
|
+
* @typedef {import('meta-buffer-pack').MBP} MBP
|
|
786
|
+
* @typedef {import('../common/constants.js').IOMsg} IOMsg
|
|
787
|
+
* @typedef {import('../common/constants.js').PAYLOAD_TYPE} PAYLOAD_TYPE
|
|
788
|
+
* @typedef {import('../common/constants.js').SIZE_LIMIT} SIZE_LIMIT
|
|
789
|
+
* @typedef {import('../common/constants.js').ENC_MODE} ENC_MODE
|
|
790
|
+
* @typedef {import('../common/constants.js').STATES} STATES
|
|
791
|
+
* @typedef {import('../common/quotaTable.js').quotaTable} quotaTable
|
|
792
|
+
|
|
793
|
+
* @typedef {import('boho').Boho} Boho
|
|
794
|
+
* @typedef {import('boho').Buffer} Buffer
|
|
795
|
+
*/
|
|
796
|
+
|
|
694
797
|
const Buffer$1 = M$1.Buffer;
|
|
695
798
|
const encoder$1 = new TextEncoder();
|
|
696
799
|
const decoder$4 = new TextDecoder();
|
|
@@ -704,76 +807,279 @@ function byteToUrl(buffer) {
|
|
|
704
807
|
return address + ':' + port.toString()
|
|
705
808
|
}
|
|
706
809
|
|
|
810
|
+
/**
|
|
811
|
+
* Core class for handling WebSocket communication.
|
|
812
|
+
* @augments {EventEmitter}
|
|
813
|
+
*/
|
|
707
814
|
class IOCore extends EventEmitter {
|
|
815
|
+
/**
|
|
816
|
+
* @param {string} url - The WebSocket URL to connect to.
|
|
817
|
+
*/
|
|
708
818
|
constructor(url) {
|
|
709
819
|
super();
|
|
820
|
+
/**
|
|
821
|
+
* Client ID received from the server.
|
|
822
|
+
* @type {string}
|
|
823
|
+
*/
|
|
710
824
|
this.cid = ""; // get from the server CID_RES
|
|
825
|
+
/**
|
|
826
|
+
* IP address received from the server.
|
|
827
|
+
* @type {string}
|
|
828
|
+
*/
|
|
711
829
|
this.ip = ""; // get from the server IAM_RES message.
|
|
830
|
+
/**
|
|
831
|
+
* The WebSocket instance.
|
|
832
|
+
* @type {WebSocket | null}
|
|
833
|
+
*/
|
|
712
834
|
this.socket = null;
|
|
835
|
+
/**
|
|
836
|
+
* The default server URL.
|
|
837
|
+
* @type {string}
|
|
838
|
+
*/
|
|
713
839
|
this.url = url; // init default server url
|
|
840
|
+
/**
|
|
841
|
+
* Current connection state (number).
|
|
842
|
+
* @type {number}
|
|
843
|
+
*/
|
|
714
844
|
this.state = STATES.CLOSED; // Number type
|
|
845
|
+
/**
|
|
846
|
+
* Current connection state (string).
|
|
847
|
+
* @type {string}
|
|
848
|
+
*/
|
|
715
849
|
this.stateName = this.getStateName(); // String type
|
|
716
850
|
|
|
851
|
+
/**
|
|
852
|
+
* Transmitted message counter.
|
|
853
|
+
* @type {number}
|
|
854
|
+
*/
|
|
717
855
|
this.txCounter = 0;
|
|
856
|
+
/**
|
|
857
|
+
* Received message counter.
|
|
858
|
+
* @type {number}
|
|
859
|
+
*/
|
|
718
860
|
this.rxCounter = 0;
|
|
861
|
+
/**
|
|
862
|
+
* Transmitted bytes counter.
|
|
863
|
+
* @type {number}
|
|
864
|
+
*/
|
|
719
865
|
this.txBytes = 0;
|
|
866
|
+
/**
|
|
867
|
+
* Received bytes counter.
|
|
868
|
+
* @type {number}
|
|
869
|
+
*/
|
|
720
870
|
this.rxBytes = 0;
|
|
721
871
|
|
|
872
|
+
/**
|
|
873
|
+
* Last transmit/receive time.
|
|
874
|
+
* @type {number}
|
|
875
|
+
*/
|
|
722
876
|
this.lastTxRxTime = Date.now();
|
|
877
|
+
/**
|
|
878
|
+
* Period for connection checker.
|
|
879
|
+
* @type {number}
|
|
880
|
+
*/
|
|
723
881
|
this.connectionCheckerPeriod = SIZE_LIMIT.CONNECTION_CHECKER_PERIOD;
|
|
882
|
+
/**
|
|
883
|
+
* Interval ID for connection checker.
|
|
884
|
+
* @type {NodeJS.Timeout | null}
|
|
885
|
+
*/
|
|
724
886
|
this.connectionCheckerIntervalID = null;
|
|
725
887
|
|
|
888
|
+
/**
|
|
889
|
+
* Boho instance for encryption/decryption.
|
|
890
|
+
* @type {Boho}
|
|
891
|
+
*/
|
|
726
892
|
this.boho = new tt();
|
|
893
|
+
/**
|
|
894
|
+
* Indicates if the connection is TLS (wss).
|
|
895
|
+
* @type {boolean}
|
|
896
|
+
*/
|
|
727
897
|
this.TLS = false; // true if protocol is wss(TLS)
|
|
898
|
+
/**
|
|
899
|
+
* Encryption mode.
|
|
900
|
+
* @type {number}
|
|
901
|
+
*/
|
|
728
902
|
this.encMode = ENC_MODE.AUTO;
|
|
903
|
+
/**
|
|
904
|
+
* Indicates if authentication is used.
|
|
905
|
+
* @type {boolean}
|
|
906
|
+
*/
|
|
729
907
|
this.useAuth = false;
|
|
730
908
|
|
|
909
|
+
/**
|
|
910
|
+
* Nickname.
|
|
911
|
+
* @type {string}
|
|
912
|
+
*/
|
|
731
913
|
this.nick = "";
|
|
914
|
+
/**
|
|
915
|
+
* Set of subscribed channels.
|
|
916
|
+
* @type {Set<string>}
|
|
917
|
+
*/
|
|
732
918
|
this.channels = new Set();
|
|
919
|
+
/**
|
|
920
|
+
* Map of promises for message responses.
|
|
921
|
+
* @type {Map<number, Array<Function>>}
|
|
922
|
+
*/
|
|
733
923
|
this.promiseMap = new Map();
|
|
924
|
+
/**
|
|
925
|
+
* Timeout for message promises.
|
|
926
|
+
* @type {number}
|
|
927
|
+
*/
|
|
734
928
|
this.promiseTimeOut = SIZE_LIMIT.PROMISE_TIMEOUT;
|
|
929
|
+
/**
|
|
930
|
+
* Message ID for promises.
|
|
931
|
+
* @type {number}
|
|
932
|
+
*/
|
|
735
933
|
this.mid = 0; // promise message id
|
|
736
934
|
|
|
935
|
+
/**
|
|
936
|
+
* Quota level.
|
|
937
|
+
* @type {number}
|
|
938
|
+
*/
|
|
737
939
|
this.level = 3; // also defaultQuotaLevel
|
|
940
|
+
/**
|
|
941
|
+
* Quota table for current level.
|
|
942
|
+
* @type {object}
|
|
943
|
+
*/
|
|
738
944
|
this.quota = quotaTable[this.level];
|
|
945
|
+
/**
|
|
946
|
+
* Server settings.
|
|
947
|
+
* @type {object}
|
|
948
|
+
*/
|
|
739
949
|
this.serverSet = {};
|
|
950
|
+
/**
|
|
951
|
+
* Map of linked channels.
|
|
952
|
+
* @type {Map<string, Set<string>>}
|
|
953
|
+
*/
|
|
740
954
|
this.linkMap = new Map();
|
|
741
955
|
|
|
956
|
+
/**
|
|
957
|
+
* Indicates if auto-reconnect is enabled.
|
|
958
|
+
* @type {boolean}
|
|
959
|
+
* @default true
|
|
960
|
+
* */
|
|
961
|
+
this.autoReconnect = true; // default true
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* A flag to prevent duplicate close operations.
|
|
965
|
+
* @type {boolean}
|
|
966
|
+
* @private
|
|
967
|
+
*/
|
|
968
|
+
this._closed = false; // 중복 close 방지
|
|
969
|
+
|
|
742
970
|
this.on('open', this.onOpen.bind(this));
|
|
743
971
|
this.on('close', this.onClose.bind(this));
|
|
744
972
|
this.on('socket_data', this.onData.bind(this));
|
|
745
973
|
}
|
|
746
974
|
|
|
747
975
|
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* Performs common cleanup for the connection. It clears pending promises,
|
|
979
|
+
* resets the socket reference, and sets the state to closed.
|
|
980
|
+
* This method is guarded to only run once.
|
|
981
|
+
* If autoReconnect is false, it also clears the keep-alive timer.
|
|
982
|
+
*/
|
|
983
|
+
close() {
|
|
984
|
+
if (this._closed) return;
|
|
985
|
+
this._closed = true;
|
|
986
|
+
|
|
987
|
+
// If auto-reconnect is disabled, we must stop the keep-alive timer.
|
|
988
|
+
if (this.autoReconnect === false) {
|
|
989
|
+
clearInterval(this.connectionCheckerIntervalID);
|
|
990
|
+
this.connectionCheckerIntervalID = null;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
// socket clean
|
|
994
|
+
if (this.socket) {
|
|
995
|
+
try {
|
|
996
|
+
this.socket.close?.();
|
|
997
|
+
} catch {}
|
|
998
|
+
this.socket = null;
|
|
999
|
+
}
|
|
1000
|
+
this.promiseMap.clear();
|
|
1001
|
+
this.emit('closed');
|
|
1002
|
+
this.stateChange('closed');
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* Disables auto-reconnect and closes the current connection.
|
|
1007
|
+
* The instance can be re-opened manually later. For complete cleanup, use destroy().
|
|
1008
|
+
*/
|
|
1009
|
+
stop() {
|
|
1010
|
+
this.autoReconnect = false;
|
|
1011
|
+
this.close();
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* Permanently destroys the instance, cleaning up all resources.
|
|
1016
|
+
* The instance will not be usable after this.
|
|
1017
|
+
*/
|
|
1018
|
+
destroy() {
|
|
1019
|
+
this.stop();
|
|
1020
|
+
this.removeAllListeners();
|
|
1021
|
+
|
|
1022
|
+
this.channels.clear();
|
|
1023
|
+
this.linkMap.clear();
|
|
1024
|
+
|
|
1025
|
+
// Help GC
|
|
1026
|
+
this.boho = null;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
/**
|
|
1030
|
+
* The core keep-alive logic. It checks if auto-reconnect is enabled.
|
|
1031
|
+
* The actual check for the socket's state is implemented in the child classes.
|
|
1032
|
+
*/
|
|
1033
|
+
keepAlive() {
|
|
1034
|
+
if (!this.autoReconnect) return;
|
|
1035
|
+
// The specific logic for checking the socket's state and reconnecting
|
|
1036
|
+
// is implemented in the child classes (IOWS, IOCongSocket, etc.).
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
/**
|
|
1040
|
+
* Redirects the connection to a new URL.
|
|
1041
|
+
* @param {string} url2 - The new URL to redirect to.
|
|
1042
|
+
*/
|
|
748
1043
|
redirect(url2) {
|
|
749
1044
|
this.close();
|
|
750
1045
|
this.stateChange('redirecting');
|
|
751
1046
|
this.createConnection(url2);
|
|
752
1047
|
}
|
|
753
1048
|
|
|
1049
|
+
/**
|
|
1050
|
+
* Opens the WebSocket connection.
|
|
1051
|
+
* @param {string} [url] - Optional URL to connect to. If not provided, uses the instance's URL.
|
|
1052
|
+
*/
|
|
754
1053
|
open(url) {
|
|
755
|
-
|
|
1054
|
+
// If a connection is already active or in progress, calling open() implies a reconnect.
|
|
1055
|
+
// Close the existing socket first to ensure a clean state.
|
|
1056
|
+
if (this.socket) {
|
|
1057
|
+
this.close();
|
|
1058
|
+
}
|
|
756
1059
|
|
|
757
1060
|
if (url) {
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
return
|
|
765
|
-
}
|
|
766
|
-
}
|
|
1061
|
+
this.url = url;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
if (!this.url) {
|
|
1065
|
+
this.emit('error', new Error('URL is not set.'));
|
|
1066
|
+
return;
|
|
767
1067
|
}
|
|
768
1068
|
|
|
1069
|
+
// The actual connection is created here.
|
|
769
1070
|
this.createConnection(this.url);
|
|
770
1071
|
|
|
1072
|
+
// Ensure the keep-alive timer is running.
|
|
771
1073
|
if (!this.connectionCheckerIntervalID) {
|
|
772
1074
|
this.connectionCheckerIntervalID = setInterval(this.keepAlive.bind(this), this.connectionCheckerPeriod);
|
|
773
1075
|
}
|
|
774
1076
|
}
|
|
775
1077
|
|
|
1078
|
+
/**
|
|
1079
|
+
* Handles the 'open' event of the WebSocket. Resets the closed flag and sets the state to open.
|
|
1080
|
+
*/
|
|
776
1081
|
onOpen() {
|
|
1082
|
+
this._closed = false;
|
|
777
1083
|
if (this.url.includes("wss://")) {
|
|
778
1084
|
this.TLS = true;
|
|
779
1085
|
} else {
|
|
@@ -782,39 +1088,40 @@ class IOCore extends EventEmitter {
|
|
|
782
1088
|
this.stateChange('open');
|
|
783
1089
|
}
|
|
784
1090
|
|
|
1091
|
+
/**
|
|
1092
|
+
* Handles the 'close' event of the WebSocket.
|
|
1093
|
+
*/
|
|
785
1094
|
onClose() {
|
|
786
1095
|
this.boho.isAuthorized = false;
|
|
787
1096
|
this.cid = "";
|
|
788
1097
|
this.stateChange('closed');
|
|
789
1098
|
}
|
|
790
1099
|
|
|
791
|
-
|
|
1100
|
+
/**
|
|
1101
|
+
* Manually logs in with provided ID and key.
|
|
1102
|
+
* @param {string} id - The user ID.
|
|
1103
|
+
* @param {string} key - The user key.
|
|
1104
|
+
* @returns {boolean}
|
|
1105
|
+
*/
|
|
792
1106
|
login(id, key) {
|
|
793
|
-
if (!id
|
|
794
|
-
console.log('no id and key.');
|
|
795
|
-
return
|
|
796
|
-
}
|
|
797
|
-
console.log('manual login: ', id);
|
|
1107
|
+
if (!this.auth(id, key)) return false;
|
|
798
1108
|
|
|
799
|
-
if (!key && id.includes('.')) {
|
|
800
|
-
this.boho.set_id_key(id);
|
|
801
|
-
} else if (id && key) {
|
|
802
|
-
this.boho.set_id8(id);
|
|
803
|
-
this.boho.set_key(key);
|
|
804
|
-
} else {
|
|
805
|
-
console.log('no id or key.');
|
|
806
|
-
return
|
|
807
|
-
}
|
|
808
1109
|
this.useAuth = true;
|
|
809
1110
|
let auth_pack = this.boho.auth_req();
|
|
810
1111
|
this.send(auth_pack);
|
|
1112
|
+
return true
|
|
811
1113
|
}
|
|
812
1114
|
|
|
813
|
-
|
|
1115
|
+
/**
|
|
1116
|
+
* Sets up authentication for auto-login.
|
|
1117
|
+
* @param {string} id - The user ID.
|
|
1118
|
+
* @param {string} key - The user key.
|
|
1119
|
+
* @returns {boolean}
|
|
1120
|
+
*/
|
|
814
1121
|
auth(id, key) {
|
|
815
1122
|
if (!id && !key) {
|
|
816
|
-
|
|
817
|
-
return
|
|
1123
|
+
this.emit('error', new Error('auth failed. no id and key.'));
|
|
1124
|
+
return false
|
|
818
1125
|
}
|
|
819
1126
|
|
|
820
1127
|
if (!key && id.includes('.')) {
|
|
@@ -823,12 +1130,17 @@ class IOCore extends EventEmitter {
|
|
|
823
1130
|
this.boho.set_id8(id);
|
|
824
1131
|
this.boho.set_key(key);
|
|
825
1132
|
} else {
|
|
826
|
-
|
|
827
|
-
return
|
|
1133
|
+
this.emit('error', new Error('auth failed. no id or key.'));
|
|
1134
|
+
return false
|
|
828
1135
|
}
|
|
829
1136
|
this.useAuth = true;
|
|
1137
|
+
return true
|
|
830
1138
|
}
|
|
831
1139
|
|
|
1140
|
+
/**
|
|
1141
|
+
* Handles incoming data from the WebSocket.
|
|
1142
|
+
* @param {Buffer} buffer - The incoming data buffer.
|
|
1143
|
+
*/
|
|
832
1144
|
onData(buffer) {
|
|
833
1145
|
let msgType = buffer[0];
|
|
834
1146
|
let decoded;
|
|
@@ -886,10 +1198,8 @@ class IOCore extends EventEmitter {
|
|
|
886
1198
|
if (jsonInfo.ip) {
|
|
887
1199
|
this.ip = jsonInfo.ip;
|
|
888
1200
|
}
|
|
889
|
-
console.log('<IAM_RES>', JSON.stringify(jsonInfo));
|
|
890
|
-
// console.log('<IAM_RES>', JSON.stringify(jsonInfo,null,2))
|
|
891
1201
|
} catch (error) {
|
|
892
|
-
|
|
1202
|
+
this.emit('error', new Error('IAM_RES data error'));
|
|
893
1203
|
}
|
|
894
1204
|
break;
|
|
895
1205
|
|
|
@@ -953,7 +1263,7 @@ class IOCore extends EventEmitter {
|
|
|
953
1263
|
}
|
|
954
1264
|
|
|
955
1265
|
} catch (error) {
|
|
956
|
-
|
|
1266
|
+
this.emit('error', new Error('SERVER_SIGNAL parsing error'));
|
|
957
1267
|
}
|
|
958
1268
|
break;
|
|
959
1269
|
|
|
@@ -964,7 +1274,7 @@ class IOCore extends EventEmitter {
|
|
|
964
1274
|
this.emit(setPack.topic, ...setPack.args);
|
|
965
1275
|
}
|
|
966
1276
|
} catch (error) {
|
|
967
|
-
|
|
1277
|
+
this.emit('error', new Error('SET parsing error'));
|
|
968
1278
|
}
|
|
969
1279
|
break;
|
|
970
1280
|
|
|
@@ -993,7 +1303,10 @@ class IOCore extends EventEmitter {
|
|
|
993
1303
|
case PAYLOAD_TYPE.TEXT:
|
|
994
1304
|
// !! Must remove null char before decode in JS.
|
|
995
1305
|
// string payload contains null char for the c/cpp devices.
|
|
996
|
-
let payloadStringWithoutNull = payloadBuffer
|
|
1306
|
+
let payloadStringWithoutNull = payloadBuffer;
|
|
1307
|
+
if (payloadBuffer[payloadBuffer.byteLength - 1] === 0) {
|
|
1308
|
+
payloadStringWithoutNull = payloadBuffer.subarray(0, payloadBuffer.byteLength - 1);
|
|
1309
|
+
}
|
|
997
1310
|
let oneString = decoder$4.decode(payloadStringWithoutNull);
|
|
998
1311
|
if (tag.indexOf('@') === 0) this.emit('@', oneString, tag);
|
|
999
1312
|
if (tag !== '@') this.emit(tag, oneString, tag);
|
|
@@ -1029,7 +1342,7 @@ class IOCore extends EventEmitter {
|
|
|
1029
1342
|
}
|
|
1030
1343
|
|
|
1031
1344
|
} catch (err) {
|
|
1032
|
-
|
|
1345
|
+
this.emit('error', new Error('signal parse err'));
|
|
1033
1346
|
}
|
|
1034
1347
|
break;
|
|
1035
1348
|
|
|
@@ -1073,6 +1386,10 @@ class IOCore extends EventEmitter {
|
|
|
1073
1386
|
}
|
|
1074
1387
|
}
|
|
1075
1388
|
|
|
1389
|
+
/**
|
|
1390
|
+
* Sends an IAM (I Am) message to the server.
|
|
1391
|
+
* @param {string} [title] - Optional title for the IAM message.
|
|
1392
|
+
*/
|
|
1076
1393
|
iam(title) {
|
|
1077
1394
|
// console.log('iam', title)
|
|
1078
1395
|
if (title) {
|
|
@@ -1088,17 +1405,25 @@ class IOCore extends EventEmitter {
|
|
|
1088
1405
|
}
|
|
1089
1406
|
|
|
1090
1407
|
|
|
1408
|
+
/**
|
|
1409
|
+
* Sends a PING message to the server.
|
|
1410
|
+
*/
|
|
1091
1411
|
ping() {
|
|
1092
1412
|
this.send(Buffer$1.from([IOMsg.PING]));
|
|
1093
1413
|
}
|
|
1094
1414
|
|
|
1415
|
+
/**
|
|
1416
|
+
* Sends a PONG message to the server.
|
|
1417
|
+
*/
|
|
1095
1418
|
pong() {
|
|
1096
1419
|
this.send(Buffer$1.from([IOMsg.PONG]));
|
|
1097
1420
|
}
|
|
1098
1421
|
|
|
1099
1422
|
|
|
1100
|
-
|
|
1101
|
-
|
|
1423
|
+
/**
|
|
1424
|
+
* Sends an ECHO message to the server.
|
|
1425
|
+
* @param {*} [args] - Optional arguments to echo.
|
|
1426
|
+
*/
|
|
1102
1427
|
echo(args) {
|
|
1103
1428
|
if (args) {
|
|
1104
1429
|
console.log('echo args:', args);
|
|
@@ -1113,10 +1438,18 @@ class IOCore extends EventEmitter {
|
|
|
1113
1438
|
}
|
|
1114
1439
|
|
|
1115
1440
|
|
|
1441
|
+
/**
|
|
1442
|
+
* Sends binary data.
|
|
1443
|
+
* @param {...any} data - Data to send.
|
|
1444
|
+
*/
|
|
1116
1445
|
bin(...data) {
|
|
1117
1446
|
this.send(M$1.U8pack(...data));
|
|
1118
1447
|
}
|
|
1119
1448
|
|
|
1449
|
+
/**
|
|
1450
|
+
* Sends data over the WebSocket.
|
|
1451
|
+
* @param {Buffer} data - The data buffer to send.
|
|
1452
|
+
*/
|
|
1120
1453
|
send(data) {
|
|
1121
1454
|
if (data.byteLength > this.quota.signalSize) {
|
|
1122
1455
|
this.emit('over_size');
|
|
@@ -1127,22 +1460,10 @@ class IOCore extends EventEmitter {
|
|
|
1127
1460
|
this.socket_send(data);
|
|
1128
1461
|
}
|
|
1129
1462
|
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
NO. if connection using TLS line.
|
|
1135
|
-
// ex. wss://url connection.
|
|
1136
|
-
YES. if no TLS line.
|
|
1137
|
-
// ex. ws://url connection.
|
|
1138
|
-
|
|
1139
|
-
if encMode == YES
|
|
1140
|
-
YES. encrypt the message.
|
|
1141
|
-
|
|
1142
|
-
if encMode == NO
|
|
1143
|
-
NO. do not ecnrypt message.
|
|
1144
|
-
|
|
1145
|
-
*/
|
|
1463
|
+
/**
|
|
1464
|
+
* Determines if encryption should be used based on current mode and TLS status.
|
|
1465
|
+
* @returns {boolean}
|
|
1466
|
+
*/
|
|
1146
1467
|
getEncryptionMode() {
|
|
1147
1468
|
if (this.encMode === ENC_MODE.YES ||
|
|
1148
1469
|
this.encMode === ENC_MODE.AUTO &&
|
|
@@ -1154,6 +1475,11 @@ class IOCore extends EventEmitter {
|
|
|
1154
1475
|
}
|
|
1155
1476
|
}
|
|
1156
1477
|
|
|
1478
|
+
/**
|
|
1479
|
+
* Sends data with encryption based on the encryption mode.
|
|
1480
|
+
* @param {Buffer} data - The data buffer to send.
|
|
1481
|
+
* @param {boolean} [useEncryption] - Optional. Force encryption or not. If undefined, uses default policy.
|
|
1482
|
+
*/
|
|
1157
1483
|
send_enc_mode(data, useEncryption) {
|
|
1158
1484
|
|
|
1159
1485
|
// use default policy.
|
|
@@ -1182,6 +1508,11 @@ class IOCore extends EventEmitter {
|
|
|
1182
1508
|
}
|
|
1183
1509
|
|
|
1184
1510
|
|
|
1511
|
+
/**
|
|
1512
|
+
* Sets a message promise for a given message ID.
|
|
1513
|
+
* @param {number} mid - The message ID.
|
|
1514
|
+
* @returns {Promise<any>}
|
|
1515
|
+
*/
|
|
1185
1516
|
setMsgPromise(mid) {
|
|
1186
1517
|
return new Promise((resolve, reject) => {
|
|
1187
1518
|
this.promiseMap.set(mid, [resolve, reject]);
|
|
@@ -1194,6 +1525,10 @@ class IOCore extends EventEmitter {
|
|
|
1194
1525
|
})
|
|
1195
1526
|
}
|
|
1196
1527
|
|
|
1528
|
+
/**
|
|
1529
|
+
* Tests and resolves/rejects a promise based on the incoming buffer.
|
|
1530
|
+
* @param {Buffer} buffer - The incoming data buffer.
|
|
1531
|
+
*/
|
|
1197
1532
|
testPromise(buffer) {
|
|
1198
1533
|
|
|
1199
1534
|
let res = M$1.unpack(buffer);
|
|
@@ -1218,11 +1553,21 @@ class IOCore extends EventEmitter {
|
|
|
1218
1553
|
}
|
|
1219
1554
|
|
|
1220
1555
|
|
|
1556
|
+
/**
|
|
1557
|
+
* Publishes a signal.
|
|
1558
|
+
* @param {...any} args - Arguments for the signal.
|
|
1559
|
+
*/
|
|
1221
1560
|
publish(...args) {
|
|
1222
1561
|
this.signal(...args);
|
|
1223
1562
|
}
|
|
1224
1563
|
|
|
1225
1564
|
|
|
1565
|
+
/**
|
|
1566
|
+
* Sends a signal with a tag and arguments.
|
|
1567
|
+
* @param {string} tag - The signal tag.
|
|
1568
|
+
* @param {...any} args - Arguments for the signal.
|
|
1569
|
+
* @throws {TypeError} If tag is not a string.
|
|
1570
|
+
*/
|
|
1226
1571
|
signal(tag, ...args) {
|
|
1227
1572
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
1228
1573
|
|
|
@@ -1230,10 +1575,23 @@ class IOCore extends EventEmitter {
|
|
|
1230
1575
|
this.send_enc_mode(signalPack);
|
|
1231
1576
|
}
|
|
1232
1577
|
|
|
1578
|
+
/**
|
|
1579
|
+
* Decrypts E2E data.
|
|
1580
|
+
* @param {Buffer} data - The encrypted data.
|
|
1581
|
+
* @param {string} key - The decryption key.
|
|
1582
|
+
* @returns {Buffer}
|
|
1583
|
+
*/
|
|
1233
1584
|
decrypt_e2e(data, key) {
|
|
1234
1585
|
return this.boho.decrypt_e2e(data, key)
|
|
1235
1586
|
}
|
|
1236
1587
|
|
|
1588
|
+
/**
|
|
1589
|
+
* Sends an E2E (End-to-End) encrypted signal.
|
|
1590
|
+
* @param {string} tag - The signal tag.
|
|
1591
|
+
* @param {Buffer} data - The data to encrypt and send.
|
|
1592
|
+
* @param {string} key - The encryption key.
|
|
1593
|
+
* @throws {TypeError} If tag is not a string.
|
|
1594
|
+
*/
|
|
1237
1595
|
signal_e2e(tag, data, key) {
|
|
1238
1596
|
|
|
1239
1597
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
@@ -1257,6 +1615,12 @@ class IOCore extends EventEmitter {
|
|
|
1257
1615
|
|
|
1258
1616
|
|
|
1259
1617
|
|
|
1618
|
+
/**
|
|
1619
|
+
* Sets a value in the store.
|
|
1620
|
+
* @param {string} storeName - The name of the store.
|
|
1621
|
+
* @param {...any} args - Arguments to set.
|
|
1622
|
+
* @returns {Promise<any>}
|
|
1623
|
+
*/
|
|
1260
1624
|
set(storeName, ...args) {
|
|
1261
1625
|
if (!storeName || args.length == 0) {
|
|
1262
1626
|
return Promise.reject(new Error('set need storeName and value)'))
|
|
@@ -1264,6 +1628,11 @@ class IOCore extends EventEmitter {
|
|
|
1264
1628
|
return this.req('store', 'set', storeName, ...args)
|
|
1265
1629
|
}
|
|
1266
1630
|
|
|
1631
|
+
/**
|
|
1632
|
+
* Gets a value from the store.
|
|
1633
|
+
* @param {string} storeName - The name of the store.
|
|
1634
|
+
* @returns {Promise<any>}
|
|
1635
|
+
*/
|
|
1267
1636
|
async get(storeName) {
|
|
1268
1637
|
if (!storeName) {
|
|
1269
1638
|
return Promise.reject(new Error('store get need storeName)'))
|
|
@@ -1274,6 +1643,13 @@ class IOCore extends EventEmitter {
|
|
|
1274
1643
|
}
|
|
1275
1644
|
|
|
1276
1645
|
|
|
1646
|
+
/**
|
|
1647
|
+
* Sends a request to a target and topic.
|
|
1648
|
+
* @param {string} target - The target of the request.
|
|
1649
|
+
* @param {string} topic - The topic of the request.
|
|
1650
|
+
* @param {...any} args - Optional arguments for the request.
|
|
1651
|
+
* @returns {Promise<any>}
|
|
1652
|
+
*/
|
|
1277
1653
|
req(target, topic, ...args) {
|
|
1278
1654
|
if (!target || !topic)
|
|
1279
1655
|
return Promise.reject(new Error('request need target and topic)'))
|
|
@@ -1299,6 +1675,11 @@ class IOCore extends EventEmitter {
|
|
|
1299
1675
|
}
|
|
1300
1676
|
|
|
1301
1677
|
|
|
1678
|
+
/**
|
|
1679
|
+
* Subscribes to a channel or channels.
|
|
1680
|
+
* @param {string} tag - The tag(s) of the channel(s) to subscribe to (comma-separated).
|
|
1681
|
+
* @throws {TypeError} If tag is not a string or exceeds length limit.
|
|
1682
|
+
*/
|
|
1302
1683
|
subscribe(tag) {
|
|
1303
1684
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
1304
1685
|
if (this.state !== STATES.READY) return
|
|
@@ -1318,6 +1699,12 @@ class IOCore extends EventEmitter {
|
|
|
1318
1699
|
tagEncoded]));
|
|
1319
1700
|
}
|
|
1320
1701
|
|
|
1702
|
+
/**
|
|
1703
|
+
* Subscribes to a channel or channels with a promise.
|
|
1704
|
+
* @param {string} tag - The tag(s) of the channel(s) to subscribe to (comma-separated).
|
|
1705
|
+
* @returns {Promise<any>}
|
|
1706
|
+
* @throws {TypeError} If tag is not a string or exceeds length limit.
|
|
1707
|
+
*/
|
|
1321
1708
|
subscribe_promise(tag) {
|
|
1322
1709
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
1323
1710
|
if (this.state !== STATES.READY) {
|
|
@@ -1336,6 +1723,9 @@ class IOCore extends EventEmitter {
|
|
|
1336
1723
|
return this.setMsgPromise(this.mid)
|
|
1337
1724
|
}
|
|
1338
1725
|
|
|
1726
|
+
/**
|
|
1727
|
+
* Subscribes to channels stored in memory (local cache).
|
|
1728
|
+
*/
|
|
1339
1729
|
subscribe_memory_channels() { //local cache . auto_resubscribe
|
|
1340
1730
|
if (this.channels.size == 0) return
|
|
1341
1731
|
let chList = Array.from(this.channels).join(',');
|
|
@@ -1349,6 +1739,11 @@ class IOCore extends EventEmitter {
|
|
|
1349
1739
|
|
|
1350
1740
|
}
|
|
1351
1741
|
|
|
1742
|
+
/**
|
|
1743
|
+
* Unsubscribes from a channel or channels.
|
|
1744
|
+
* @param {string} [tag=""] - The tag(s) of the channel(s) to unsubscribe from (comma-separated). If empty, unsubscribes from all.
|
|
1745
|
+
* @throws {TypeError} If tag is not a string or exceeds length limit.
|
|
1746
|
+
*/
|
|
1352
1747
|
unsubscribe(tag = "") {
|
|
1353
1748
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
1354
1749
|
|
|
@@ -1371,6 +1766,12 @@ class IOCore extends EventEmitter {
|
|
|
1371
1766
|
}
|
|
1372
1767
|
|
|
1373
1768
|
|
|
1769
|
+
/**
|
|
1770
|
+
* Listens for signals on a specific tag.
|
|
1771
|
+
* @param {string} tag - The tag to listen on.
|
|
1772
|
+
* @param {Function} handler - The callback function to handle the signal.
|
|
1773
|
+
* @throws {TypeError} If tag is not a string, handler is not a function, or tag length is invalid.
|
|
1774
|
+
*/
|
|
1374
1775
|
listen(tag, handler) {
|
|
1375
1776
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
1376
1777
|
if (tag.length > 255 || tag.length == 0) throw TypeError('tag string length range: 1~255')
|
|
@@ -1387,6 +1788,13 @@ class IOCore extends EventEmitter {
|
|
|
1387
1788
|
|
|
1388
1789
|
|
|
1389
1790
|
|
|
1791
|
+
/**
|
|
1792
|
+
* Links a local target to a remote tag and sets up a handler.
|
|
1793
|
+
* @param {string} to - The local link target.
|
|
1794
|
+
* @param {string} tag - The remote tag.
|
|
1795
|
+
* @param {Function} handler - The callback function to handle the signal.
|
|
1796
|
+
* @throws {TypeError} If 'to' or 'tag' are not strings, handler is not a function, or tag length is invalid.
|
|
1797
|
+
*/
|
|
1390
1798
|
link(to, tag, handler) {
|
|
1391
1799
|
if (typeof to !== 'string') throw TypeError('to(local link target) is not a string.')
|
|
1392
1800
|
if (typeof tag !== 'string') throw TypeError('tag is not a string.')
|
|
@@ -1412,44 +1820,54 @@ class IOCore extends EventEmitter {
|
|
|
1412
1820
|
}
|
|
1413
1821
|
|
|
1414
1822
|
|
|
1823
|
+
/**
|
|
1824
|
+
* Unlinks a specific tag from a local target.
|
|
1825
|
+
* @param {string} to - The local link target.
|
|
1826
|
+
* @param {string} tag - The tag to unlink.
|
|
1827
|
+
* @throws {TypeError} If 'to' or 'tag' are not strings or tag length is invalid.
|
|
1828
|
+
*/
|
|
1415
1829
|
unlink(to, tag) {
|
|
1416
1830
|
if (typeof to !== 'string') throw TypeError('to(local link target) is not a string.')
|
|
1417
1831
|
if (typeof tag !== 'string') throw TypeError('tag is not a string.')
|
|
1418
1832
|
if (tag.length > 255 || tag.length == 0) throw TypeError('tag string length range: 1~255')
|
|
1419
1833
|
|
|
1420
|
-
|
|
1834
|
+
const linkSet = this.linkMap.get(to);
|
|
1835
|
+
if (!linkSet || !linkSet.has(tag)) return;
|
|
1421
1836
|
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
if (tags[i] == tag) {
|
|
1426
|
-
this.unsubscribe(tag);
|
|
1427
|
-
this.removeAllListeners(tag);
|
|
1428
|
-
linkSet.delete(tag);
|
|
1429
|
-
this.linkMap.set(to, linkSet);
|
|
1430
|
-
break;
|
|
1431
|
-
}
|
|
1432
|
-
}
|
|
1837
|
+
this.unsubscribe(tag);
|
|
1838
|
+
this.removeAllListeners(tag);
|
|
1839
|
+
linkSet.delete(tag);
|
|
1433
1840
|
|
|
1841
|
+
if (linkSet.size === 0) {
|
|
1842
|
+
this.linkMap.delete(to);
|
|
1843
|
+
}
|
|
1434
1844
|
}
|
|
1435
1845
|
|
|
1846
|
+
/**
|
|
1847
|
+
* Unlinks all tags from a local target.
|
|
1848
|
+
* @param {string} to - The local link target.
|
|
1849
|
+
* @throws {TypeError} If 'to' is not a string.
|
|
1850
|
+
*/
|
|
1436
1851
|
unlinkAll(to) {
|
|
1437
1852
|
if (typeof to !== 'string') throw TypeError('to(local link target) is not a string.')
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
for (
|
|
1443
|
-
this.unsubscribe(
|
|
1444
|
-
this.removeAllListeners(
|
|
1445
|
-
linkSet.delete(tags[i]);
|
|
1853
|
+
|
|
1854
|
+
const linkSet = this.linkMap.get(to);
|
|
1855
|
+
if (!linkSet) return;
|
|
1856
|
+
|
|
1857
|
+
for (const tag of linkSet) {
|
|
1858
|
+
this.unsubscribe(tag);
|
|
1859
|
+
this.removeAllListeners(tag);
|
|
1446
1860
|
}
|
|
1447
|
-
this.linkMap.delete(to);
|
|
1448
1861
|
|
|
1862
|
+
this.linkMap.delete(to);
|
|
1449
1863
|
}
|
|
1450
1864
|
|
|
1451
1865
|
|
|
1452
1866
|
|
|
1867
|
+
/**
|
|
1868
|
+
* Gets connection metrics.
|
|
1869
|
+
* @returns {{tx: number, rx: number, txb: number, rxb: number, last: number}}
|
|
1870
|
+
*/
|
|
1453
1871
|
getMetric() {
|
|
1454
1872
|
return {
|
|
1455
1873
|
tx: this.txCounter,
|
|
@@ -1461,10 +1879,18 @@ class IOCore extends EventEmitter {
|
|
|
1461
1879
|
|
|
1462
1880
|
}
|
|
1463
1881
|
|
|
1882
|
+
/**
|
|
1883
|
+
* Gets the current connection state.
|
|
1884
|
+
* @returns {number}
|
|
1885
|
+
*/
|
|
1464
1886
|
getState() {
|
|
1465
1887
|
return this.state
|
|
1466
1888
|
}
|
|
1467
1889
|
|
|
1890
|
+
/**
|
|
1891
|
+
* Gets the current connection state name.
|
|
1892
|
+
* @returns {string}
|
|
1893
|
+
*/
|
|
1468
1894
|
getStateName() {
|
|
1469
1895
|
//state <number>
|
|
1470
1896
|
//value of constant STATES.NAME < number >
|
|
@@ -1473,6 +1899,10 @@ class IOCore extends EventEmitter {
|
|
|
1473
1899
|
return (STATES[this.state]).toLowerCase()
|
|
1474
1900
|
}
|
|
1475
1901
|
|
|
1902
|
+
/**
|
|
1903
|
+
* Gets security-related information.
|
|
1904
|
+
* @returns {{useAuth: boolean, isTLS: boolean, isAuthorized: boolean, encMode: number, usingEncryption: boolean}}
|
|
1905
|
+
*/
|
|
1476
1906
|
getSecurity() {
|
|
1477
1907
|
return {
|
|
1478
1908
|
useAuth: this.useAuth,
|
|
@@ -1483,6 +1913,11 @@ class IOCore extends EventEmitter {
|
|
|
1483
1913
|
}
|
|
1484
1914
|
}
|
|
1485
1915
|
|
|
1916
|
+
/**
|
|
1917
|
+
* Changes the connection state and emits events.
|
|
1918
|
+
* @param {string} state - The new state name (e.g., 'ready', 'closed').
|
|
1919
|
+
* @param {string} [emitEventAndMessage] - Optional message to emit with the state change event.
|
|
1920
|
+
*/
|
|
1486
1921
|
stateChange(state, emitEventAndMessage) {
|
|
1487
1922
|
// STATES constant name : string upperCase
|
|
1488
1923
|
// eventName, .stateName : string lowerCase
|
|
@@ -1642,20 +2077,30 @@ class IOCongSocket extends IOCore {
|
|
|
1642
2077
|
if (url) this.open();
|
|
1643
2078
|
}
|
|
1644
2079
|
|
|
2080
|
+
/**
|
|
2081
|
+
* Closes TCP socket and cleans resources.
|
|
2082
|
+
*/
|
|
1645
2083
|
close() {
|
|
1646
|
-
this.socket
|
|
1647
|
-
|
|
2084
|
+
if (this.socket) {
|
|
2085
|
+
if (this.congRx) {
|
|
2086
|
+
this.socket.unpipe(this.congRx);
|
|
2087
|
+
this.congRx.destroy(); // Use destroy() for complete stream cleanup
|
|
2088
|
+
this.congRx = null;
|
|
2089
|
+
}
|
|
2090
|
+
this.socket.removeAllListeners();
|
|
2091
|
+
if (!this.socket.destroyed) {
|
|
2092
|
+
this.socket.destroy(); // destroy() is sufficient for forceful closing
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
super.close();
|
|
1648
2096
|
}
|
|
1649
2097
|
|
|
1650
|
-
|
|
1651
|
-
this.close();
|
|
1652
|
-
clearInterval(this.connectionCheckerIntervalID);
|
|
1653
|
-
this.connectionCheckerIntervalID = null;
|
|
1654
|
-
}
|
|
2098
|
+
|
|
1655
2099
|
|
|
1656
2100
|
keepAlive() {
|
|
1657
|
-
|
|
1658
|
-
if
|
|
2101
|
+
if (!this.autoReconnect) return;
|
|
2102
|
+
// Reconnect only if the socket is fully destroyed and the state is closed.
|
|
2103
|
+
if ((!this.socket || this.socket.destroyed) && this.state === STATES.CLOSED) {
|
|
1659
2104
|
this.open();
|
|
1660
2105
|
}
|
|
1661
2106
|
}
|
|
@@ -7065,32 +7510,28 @@ class IOWS extends IOCore {
|
|
|
7065
7510
|
|
|
7066
7511
|
|
|
7067
7512
|
|
|
7513
|
+
/**
|
|
7514
|
+
* Closes ws WebSocket and cleans resources.
|
|
7515
|
+
*/
|
|
7068
7516
|
close() {
|
|
7069
7517
|
if (this.socket) {
|
|
7070
|
-
this.socket.
|
|
7071
|
-
this.socket.
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
this.socket = null;
|
|
7518
|
+
this.socket.removeAllListeners();
|
|
7519
|
+
if (this.socket.readyState !== WebSocket.CLOSED) {
|
|
7520
|
+
this.socket.close();
|
|
7521
|
+
}
|
|
7075
7522
|
}
|
|
7076
|
-
|
|
7523
|
+
super.close();
|
|
7077
7524
|
}
|
|
7078
7525
|
|
|
7079
7526
|
|
|
7080
|
-
|
|
7081
|
-
stop() {
|
|
7082
|
-
this.close();
|
|
7083
|
-
clearInterval(this.connectionCheckerIntervalID);
|
|
7084
|
-
this.connectionCheckerIntervalID = null;
|
|
7085
|
-
}
|
|
7086
|
-
|
|
7087
7527
|
keepAlive() {
|
|
7088
|
-
if (!this.
|
|
7528
|
+
if (!this.autoReconnect) return;
|
|
7529
|
+
// Reconnect only if the socket is closed and the state reflects that.
|
|
7530
|
+
if ((!this.socket || this.socket.readyState === WebSocket.CLOSED) && this.state === STATES.CLOSED) {
|
|
7089
7531
|
this.open();
|
|
7090
7532
|
}
|
|
7091
7533
|
}
|
|
7092
7534
|
|
|
7093
|
-
|
|
7094
7535
|
createConnection(url) {
|
|
7095
7536
|
// node WebSocket
|
|
7096
7537
|
this.socket = new WebSocket(url);
|