iosignal 3.0.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/{docs/README.ko.md → README.ko.md} +204 -9
  2. package/README.md +424 -8
  3. package/dist/io.js +1 -1
  4. package/dist/io.js.map +1 -1
  5. package/dist/io.min.js +1 -1
  6. package/dist/io.min.js.map +1 -1
  7. package/dist/iosignal.js +131 -29
  8. package/examples/react-chat-js/package-lock.json +311 -216
  9. package/examples/react-chat-js/package.json +6 -6
  10. package/examples/react-chat-js/src/App.jsx +4 -4
  11. package/examples/server/package-lock.json +47 -0
  12. package/examples/svelte-chat-js/.devtools +3 -0
  13. package/examples/svelte-chat-js/README.md +38 -0
  14. package/examples/svelte-chat-js/package-lock.json +1505 -0
  15. package/examples/svelte-chat-js/package.json +22 -0
  16. package/examples/svelte-chat-js/src/app.css +105 -0
  17. package/examples/svelte-chat-js/src/app.d.ts +13 -0
  18. package/examples/svelte-chat-js/src/app.html +12 -0
  19. package/examples/svelte-chat-js/src/lib/images/github.svg +1 -0
  20. package/examples/svelte-chat-js/src/lib/images/svelte-logo.svg +1 -0
  21. package/examples/svelte-chat-js/src/lib/images/svelte-welcome.png +0 -0
  22. package/examples/svelte-chat-js/src/lib/images/svelte-welcome.webp +0 -0
  23. package/examples/svelte-chat-js/src/lib/shared_io.js +12 -0
  24. package/examples/svelte-chat-js/src/routes/+layout.svelte +9 -0
  25. package/examples/svelte-chat-js/src/routes/+page.js +3 -0
  26. package/examples/svelte-chat-js/src/routes/+page.svelte +162 -0
  27. package/examples/svelte-chat-js/static/favicon.svg +1 -0
  28. package/examples/svelte-chat-js/static/global.css +19 -0
  29. package/examples/svelte-chat-js/static/robots.txt +3 -0
  30. package/examples/svelte-chat-js/svelte.config.js +15 -0
  31. package/examples/svelte-chat-js/vite.config.js +6 -0
  32. package/index.js +2 -1
  33. package/package.json +1 -1
  34. package/src/client/IOCore.js +18 -5
  35. package/src/client/browser/IOWebSocket.js +1 -16
  36. package/src/server/Manager.js +16 -0
  37. package/src/server/Remote.js +5 -0
  38. package/src/server/Server.js +85 -21
  39. package/src/server/serverOption.js +2 -2
  40. package/test-nodejs/client-playToggle.js +19 -0
package/dist/iosignal.js CHANGED
@@ -13,7 +13,9 @@ 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.1";
16
+ var version$1 = "3.2.0";
17
+ var pkg = {
18
+ version: version$1};
17
19
 
18
20
  var t$1,e$1={},r$1={};var n$1,i$1,o$1={};
19
21
  /*! 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}
@@ -992,9 +994,22 @@ class IOCore extends EventEmitter {
992
994
 
993
995
  // socket clean
994
996
  if (this.socket) {
995
- try {
996
- this.socket.close?.();
997
- } catch {}
997
+ // For WebSockets, readyState are: 0-CONNECTING, 1-OPEN, 2-CLOSING, 3-CLOSED
998
+ // Calling close() on a CONNECTING socket will cause a browser error.
999
+ if (this.socket.readyState === 0) { // 0 is WebSocket.CONNECTING
1000
+ // To avoid the error, we wait for the connection to open, then immediately close it.
1001
+ // We also clear other handlers to prevent any other logic from running.
1002
+ const socket = this.socket;
1003
+ socket.onopen = () => { if(socket) socket.close(); };
1004
+ socket.onmessage = null;
1005
+ socket.onerror = null;
1006
+ socket.onclose = null;
1007
+ } else {
1008
+ try {
1009
+ // For other sockets (like TCP) or other WebSocket states, close directly.
1010
+ this.socket.close?.();
1011
+ } catch {}
1012
+ }
998
1013
  this.socket = null;
999
1014
  }
1000
1015
  this.promiseMap.clear();
@@ -1159,8 +1174,8 @@ class IOCore extends EventEmitter {
1159
1174
  // console.log( 'ENC_E2E decoded ', decoded )
1160
1175
  msgType = decoded[0];
1161
1176
  // decoded has msg_header only.
1162
- buffer.set(decoded, tt.MetaSize.ENC_488); // set decoded signal_e2e headaer.
1163
- buffer = buffer.subarray(tt.MetaSize.ENC_488); // reset offset.
1177
+ buffer.set(decoded, tt.MetaSize.ENC_488); // set decoded signal_e2e headaer.
1178
+ buffer = buffer.subarray(tt.MetaSize.ENC_488); // reset offset.
1164
1179
  // console.log('DECODED MsgType:', IOMsg[ msgType ] )
1165
1180
  } else {
1166
1181
  // console.log('488 DEC_FAIL', buffer)
@@ -7573,9 +7588,9 @@ class IOWS extends IOCore {
7573
7588
 
7574
7589
  let serverOption = {
7575
7590
  clientTracking: false,
7576
- port: 0, //wsPort
7591
+ port: null, // WebSocket
7592
+ congPort: null, // CongSocket
7577
7593
  httpServer: null,
7578
- congPort: 0,
7579
7594
  timeout: 50000,
7580
7595
  showMessage: 'none',
7581
7596
  showMetric: 0,
@@ -8118,6 +8133,8 @@ class Remote extends RemoteCore {
8118
8133
  socket.on("ping", this.receiveMonitor.bind(this));
8119
8134
  socket.on("error", (e) => { console.log('Websocket error', e, e.code); });
8120
8135
  socket.onclose = (e) => {
8136
+ // Clean up all listeners on the socket to prevent leaks
8137
+ socket.removeAllListeners();
8121
8138
  this.manager.removeRemote(this);
8122
8139
  };
8123
8140
  } else { // TCP else
@@ -8137,6 +8154,9 @@ class Remote extends RemoteCore {
8137
8154
 
8138
8155
  socket.on('error', e => { console.log('TCP Socket error', e); });
8139
8156
  socket.on('close', e => {
8157
+ // Clean up listeners on both the socket and the parser
8158
+ socket.removeAllListeners();
8159
+ this.congRx.removeAllListeners();
8140
8160
  this.manager.removeRemote(this);
8141
8161
  });
8142
8162
 
@@ -8860,7 +8880,23 @@ class Manager {
8860
8880
  }
8861
8881
  }
8862
8882
 
8883
+ close() {
8884
+ clearInterval(this.pingIntervalID);
8885
+ if (this.monitIntervalID) {
8886
+ clearInterval(this.monitIntervalID);
8887
+ }
8888
+
8889
+ this.remotes.forEach(remote => {
8890
+ remote.close();
8891
+ });
8892
+
8893
+ this.remotes.clear();
8894
+ this.cid2remote.clear();
8895
+ this.retain_messages.clear();
8896
+ this.channel_map.clear();
8863
8897
 
8898
+ console.log('Manager closed');
8899
+ }
8864
8900
  }
8865
8901
 
8866
8902
  const STATUS = {
@@ -8876,6 +8912,8 @@ class Server extends require$$0$3 {
8876
8912
  super();
8877
8913
  this.apiNames = new Set();
8878
8914
  this.wss = {};
8915
+ this.port = null;
8916
+ this.congPort = null;
8879
8917
 
8880
8918
  if (options.timeout) {
8881
8919
  let pingT = parseInt(options.timeout);
@@ -8896,38 +8934,44 @@ class Server extends require$$0$3 {
8896
8934
  serverOption.showMetric = options.showMetric;
8897
8935
  }
8898
8936
 
8899
- if (options.timeout) {
8900
- serverOption.timeout = options.timeout;
8901
- }
8902
-
8903
- if (options.port) {
8904
- serverOption.port = parseInt(options.port);
8937
+ if (options.port || options.port == 0) {
8938
+ this.port = parseInt(options.port);
8905
8939
  }
8906
8940
 
8907
8941
  if (options.httpServer) {
8908
- serverOption.httpServer = options.httpServer;
8942
+ this.httpServer = options.httpServer;
8909
8943
  }
8910
8944
 
8911
- if (options.congPort) {
8912
- serverOption.congPort = parseInt(options.congPort);
8945
+ if (options.congPort || options.congPort == 0) {
8946
+ this.congPort = parseInt(options.congPort);
8913
8947
  }
8914
8948
 
8915
8949
  this.manager = new Manager(this, authManager);
8916
8950
 
8917
- if (serverOption.port || serverOption.httpServer) this.startWSServer(serverOption);
8918
- if (serverOption.congPort) this.startCongServer(serverOption.congPort);
8951
+ this.serverCountToListen = 0;
8952
+ this.listeningServerCount = 0;
8953
+ if (this.port || this.port == 0 || this.httpServer) this.serverCountToListen++;
8954
+ if (this.congPort || this.congPort == 0) this.serverCountToListen++;
8955
+
8956
+ if (this.serverCountToListen === 0) {
8957
+ process.nextTick(() => this.emit('ready'));
8958
+ } else {
8959
+ if (this.port || this.port == 0 || this.httpServer) this.startWSServer();
8960
+ if (this.congPort || this.congPort == 0) this.startCongServer();
8961
+ }
8919
8962
 
8920
8963
  }
8921
8964
 
8922
8965
 
8923
- startWSServer(serverOption) {
8966
+ startWSServer() {
8924
8967
 
8925
- if (serverOption.port) {
8926
- console.log('opening WebSocket Server port:', serverOption.port);
8927
- this.wss = new WebSocketServer({ port: serverOption.port });
8928
- } else if (serverOption.httpServer) {
8968
+ // console.log('optoins', options )
8969
+ if (this.port || this.port == 0) {
8970
+ console.log('opening WebSocket Server port:', this.port);
8971
+ this.wss = new WebSocketServer({ port: this.port });
8972
+ } else if (this.httpServer) {
8929
8973
  console.log('opening WebSocket Server external httpServer:');
8930
- this.wss = new WebSocketServer({ server: serverOption.httpServer });
8974
+ this.wss = new WebSocketServer({ server: this.httpServer });
8931
8975
  } else {
8932
8976
  throw new TypeError(
8933
8977
  'One and only one of the "port", "httpServer"' +
@@ -8936,6 +8980,15 @@ class Server extends require$$0$3 {
8936
8980
  }
8937
8981
 
8938
8982
 
8983
+ this.wss.once('listening', () => {
8984
+ this.port = this.wss.address().port;
8985
+ console.log('wss server bound port:', this.port );
8986
+ this.listeningServerCount++;
8987
+ if (this.listeningServerCount === this.serverCountToListen) {
8988
+ this.emit('ready');
8989
+ }
8990
+ });
8991
+
8939
8992
  // this.wss.setMaxListeners(0)
8940
8993
 
8941
8994
  this.wss.on('error', (err) => {
@@ -8957,8 +9010,8 @@ class Server extends require$$0$3 {
8957
9010
 
8958
9011
  }
8959
9012
 
8960
- startCongServer(congPort) {
8961
- console.log('opening CongSocket Server:', congPort);
9013
+ startCongServer() {
9014
+ console.log('opening CongSocket Server port:', this.congPort);
8962
9015
 
8963
9016
  this.congServer = net.createServer((socket) => {
8964
9017
  this.manager.addRemote(socket);
@@ -8968,8 +9021,15 @@ class Server extends require$$0$3 {
8968
9021
  if (err.code == 'EADDRINUSE') {
8969
9022
  process.exit();
8970
9023
  }
8971
- }).listen(congPort, () => {
8972
- // console.log('congsocket server bound' );
9024
+ }).on('close', () => {
9025
+ console.log('### cong server closed.');
9026
+ }).listen(this.congPort, () => {
9027
+ this.congPort = this.congServer.address().port;
9028
+ console.log('congsocket server bound port:', this.congPort );
9029
+ this.listeningServerCount++;
9030
+ if (this.listeningServerCount === this.serverCountToListen) {
9031
+ this.emit('ready');
9032
+ }
8973
9033
  });
8974
9034
  }
8975
9035
 
@@ -9025,6 +9085,46 @@ class Server extends require$$0$3 {
9025
9085
  return this
9026
9086
  }
9027
9087
 
9088
+ close(callback) {
9089
+ console.log('closing io-signal server...');
9090
+ if (this.manager) {
9091
+ this.manager.close();
9092
+ }
9093
+
9094
+ let serverCount = 0;
9095
+ if (this.wss) serverCount++;
9096
+ if (this.congServer) serverCount++;
9097
+
9098
+ if (serverCount === 0) {
9099
+ if (callback) process.nextTick(callback);
9100
+ return;
9101
+ }
9102
+
9103
+ let closedCount = 0;
9104
+ const onClosed = () => {
9105
+ closedCount++;
9106
+ if (closedCount === serverCount) {
9107
+ console.log('io-signal server closed.');
9108
+ if (callback) callback();
9109
+ }
9110
+ };
9111
+
9112
+ if (this.wss) {
9113
+ this.wss.close(() => {
9114
+ console.log('wss server closed.');
9115
+ onClosed();
9116
+ });
9117
+ }
9118
+
9119
+ if (this.congServer) {
9120
+ this.congServer.close((err) => {
9121
+ if (err) console.error('congServer close error', err);
9122
+ console.log('cong server closed.');
9123
+ onClosed();
9124
+ });
9125
+ }
9126
+ }
9127
+
9028
9128
  }
9029
9129
 
9030
9130
  const decoder = new TextDecoder();
@@ -9556,4 +9656,6 @@ class RedisAPI {
9556
9656
 
9557
9657
  }
9558
9658
 
9659
+ const version = pkg.version;
9660
+
9559
9661
  export { API_TYPE, Auth_Env, Auth_File, Auth_Redis, tt as Boho, BohoAuth, CLIENT_STATE, CongRx, ENC_MODE, FileLogger, IOWS as IO, IOCongSocket, IOMsg, M$1 as MBP, PAYLOAD_TYPE, RedisAPI, SIZE_LIMIT, STATES, STATUS$1 as STATUS, Server, api_reply, api_sudo, getPayloadFromSignalPack, getSignalPack, pack, parsePayload, serverOption, version };