wspromisify 2.4.3 → 2.5.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 (44) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -2
  3. package/TODO +9 -0
  4. package/dist/bundle.cjs +1 -1
  5. package/dist/bundle.d.ts +7 -2
  6. package/dist/bundle.mjs +1 -1
  7. package/package.json +91 -94
  8. package/rollup.config.js +1 -1
  9. package/src/WSC.ts +271 -0
  10. package/src/config.ts +7 -6
  11. package/src/utils.ts +5 -23
  12. package/test/index.ts +21 -0
  13. package/test/mock/WS.ts +43 -0
  14. package/test/mock/server.ts +17 -0
  15. package/test/specs/close.ts +18 -0
  16. package/test/specs/drops.ts +30 -0
  17. package/test/specs/echo.ts +24 -0
  18. package/test/specs/encode-decode.ts +1 -0
  19. package/test/specs/existing_socket.ts +55 -0
  20. package/test/specs/lazy.ts +22 -0
  21. package/test/specs/lazySendBeforeOpen.ts +19 -0
  22. package/test/specs/no-native-throws.ts +18 -0
  23. package/test/specs/ready.ts +12 -0
  24. package/test/specs/reconnect.ts +23 -0
  25. package/test/specs/socket.ts +13 -0
  26. package/test/suite.ts +3 -0
  27. package/test/utils.ts +27 -0
  28. package/tsconfig.json +3 -2
  29. package/src/WS.ts +0 -166
  30. package/src/connectLib.ts +0 -120
  31. package/test/mock/WS.js +0 -51
  32. package/test/mock/index.js +0 -52
  33. package/test/specs/close.js +0 -25
  34. package/test/specs/drops.js +0 -29
  35. package/test/specs/echo.js +0 -26
  36. package/test/specs/encode-decode.js +0 -3
  37. package/test/specs/existing_socket.js +0 -55
  38. package/test/specs/lazy.js +0 -26
  39. package/test/specs/ready.js +0 -16
  40. package/test/specs/reconnect.js +0 -28
  41. package/test/specs/sendBeforeOpen.js +0 -23
  42. package/test/specs/socket.js +0 -22
  43. package/test/specs/utils_once.js +0 -16
  44. package/test/utils.js +0 -27
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2017 Michael
3
+ Copyright (c) 2025 Michael Akiliev
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,6 +1,5 @@
1
1
  # WebsocketPromisify
2
-
3
- [![Build Status](https://circleci.com/gh/houd1ni/WebsocketPromisify/tree/master.svg?style=shield)](https://circleci.com/gh/houd1ni/WebsocketPromisify/tree/master) [![codecov](https://codecov.io/gh/houd1ni/WebsocketPromisify/branch/master/graph/badge.svg)](https://codecov.io/gh/houd1ni/WebsocketPromisify) [![bundlephobia](https://badgen.net/bundlephobia/minzip/wspromisify)](https://bundlephobia.com/result?p=wspromisify) [![npm](https://badgen.net/npm/v/wspromisify)](https://www.npmjs.com/package/wspromisify) [![Deps](https://david-dm.org/houd1ni/WebsocketPromisify.svg)](https://david-dm.org/houd1ni/WebsocketPromisify) [![DevDeps](https://david-dm.org/houd1ni/WebsocketPromisify/dev-status.svg)](https://david-dm.org/houd1ni/WebsocketPromisify)
2
+ [![Scrutinizer build](https://scrutinizer-ci.com/g/houd1ni/WebsocketPromisify/badges/build.png?b=master)](https://scrutinizer-ci.com/g/houd1ni/WebsocketPromisify/build-status/master) [![Scrutinizer code quality](https://scrutinizer-ci.com/g/houd1ni/WebsocketPromisify/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/houd1ni/WebsocketPromisify/code-structure/master) [![codecov](https://codecov.io/gh/houd1ni/WebsocketPromisify/branch/master/graph/badge.svg)](https://codecov.io/gh/houd1ni/WebsocketPromisify) [![bundlejs](https://deno.bundlejs.com/badge?q=wspromisify@2.4.4&treeshake=[*])](https://deno.bundlejs.com/badge?q=wspromisify@2.4.4&treeshake=[*]) [![npm](https://badgen.net/npm/v/wspromisify)](https://www.npmjs.com/package/wspromisify)
4
3
 
5
4
  A nice-looking this readme version: https://houd1ni.github.io/WebsocketPromisify/
6
5
 
package/TODO CHANGED
@@ -0,0 +1,9 @@
1
+ #v3 at least:
2
+
3
+ [The milestone](https://github.com/houd1ni/WebsocketPromisify/milestone/1)
4
+
5
+ - [x] [close event bug](https://github.com/houd1ni/WebsocketPromisify/issues/38) (fixed in 2.5.0)
6
+ - [ ] [BREAKING] export named WebSocketClient instead of default export.
7
+ - [ ] [ping-pong without id](https://github.com/houd1ni/WebsocketPromisify/issues/39)
8
+ - [ ] [implement prepare](https://github.com/houd1ni/WebsocketPromisify/issues/34)
9
+ - [ ] [wiki](https://github.com/houd1ni/WebsocketPromisify/issues/4)
package/dist/bundle.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";const e=Symbol("Placeholder"),t=t=>{let n=0;for(const s of t)s!==e&&n++;return n},n=(t,n)=>{const s=t.length,o=t.slice(),r=n.length;let i=r,c=0;for(;i&&c<s;c++)o[c]===e&&(o[c]=n[r-i],i--);for(c=s;i;c++,i--)o[c]=n[r-i];return o},s=(e,o,r)=>{const i=e.length-o.length-t(r);if(i<1)return e(...n(o,r));{const t=(...t)=>s(e,n(o,r),t);return t.$args_left=i,t}},o=e=>(...n)=>e.length>t(n)?s(e,[],n):e(...n),r=t=>function(n){return n===e?t:t(n)};function i(t){return function(n,s){const o=n===e,i=arguments.length;if(1===i&&o)throw new Error("Senseless placeholder usage.");return arguments.length>1?o?r((e=>t(e,s))):t(n,s):e=>t(n,e)}}function c(e){return o(e)}const l=void 0,u=1/0,a=e=>typeof e,h=e=>null===e,f={u:"U",b:"B",n:"N",s:"S",f:"F"},d=e=>{const t=a(e);return"object"===t?h(e)?"Null":e.constructor.name:f[t[0]]+t.slice(1)},g=i(((e,t)=>(t.push(e),t))),p=c(((e,t,n)=>n.reduce(e,t))),m=c(((e,t,n)=>{for(let s in n)switch(d(n[s])){case"Array":if(e>1&&"Array"===d(t[s]))switch(e){case 2:const o=t[s],r=n[s];for(const t in r)o[t]?m(e,o[t],r[t]):o[t]=r[t];break;case 3:t[s].push(...n[s])}else t[s]=n[s];break;case"Object":if("Object"===d(t[s])){m(e,t[s],n[s]);break}default:t[s]=n[s]}return t}));m(1),m(2),m(3);const y=i(((e,t)=>{const n=d(e);if(n===d(t)&&("Object"===n||"Array"==n)){if(h(e)||h(t))return e===t;if(e===t)return!0;for(const n of[e,t])for(const s in n)if(!(n===t&&s in e||n===e&&s in t&&y(e[s],t[s])))return!1;return!0}return e===t})),w=o(((e,t,n,s)=>e(s)?t(s):n(s))),b=(...t)=>(...n)=>{let s,o=!0;for(let r=j(t)-1;r>-1;r--)o?(o=!1,s=t[r](...n)):s=s===e?t[r]():t[r](s);return s},_=i(((e,t)=>t[e])),k=i(((e,t)=>{if((e=>"string"===a(e))(t))return t.includes(e);for(const n of t)if(y(n,e))return!0;return!1})),S=c(((e,t,n)=>n.slice(e,(e=>"number"==a(e))(t)?t:u))),v=_(0);S(1,u);const E=e=>h(e)||(e=>e===l)(e),j=e=>e.length,N=e=>()=>e,O=i(((e,t)=>t.split(e))),A=e=>p(((e,t)=>k(t,e)?e:g(t,e)),[],e),P=c(((e,t,n)=>({...n,[e]:t}))),q=i(((e,t)=>t[e])),Q=c(((e,t,n)=>w(j,(()=>E(n)?e:b(w(E,N(e),(n=>Q(e,S(1,u,t),n))),(e=>i(((t,n)=>e(n,t))))(q)(n),v)(t)),N(n),t)));Q(l);const $=/^(.*?)(8|16|32|64)(Clamped)?Array$/,W=(e,t=!1)=>{const n=d(e);switch(n){case"Null":case"String":case"Number":case"Boolean":case"Symbol":return e;case"Array":return t?[...e]:R(b(W,((...e)=>e[0])),e);case"Object":if(t)return{...e};const s={};for(let t in e)s[t]=W(e[t]);return s;default:return $.test(n)?e.constructor.from(e):e}},C=c(((e,t,n)=>p(e,W(t),n))),R=i(((e,t)=>t.map(e))),{floor:z}=Math;let B,D;const I=b((e=>C(((e,t)=>P(...t,e)),{},e)),R(((e,t)=>[e,t])),O(""));(e=>{if(!(e=>b(y(j(e)),j,A,O(""))(e))(e))throw new Error("Not all chars are unique!");B=e,D=B.length,I(B)})("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");const T=(e,t,n)=>e.addEventListener(t,n),U=e=>{let t=!1,n=null;return(...s)=>t?n:(t=!0,n=e(...s))},x=(e,t)=>setTimeout(t,e),F=function(e){const t=this.config;this.open=!0,this.onReadyQueue.forEach((e=>e())),this.onReadyQueue.splice(0);const{id_key:n,data_key:s}=t.server;if(this.handlers.open.forEach((e=>e())),this.messages.forEach((e=>e.send())),null!==this.reconnect_timeout&&(clearInterval(this.reconnect_timeout),this.reconnect_timeout=null),t.ping){const e=setInterval((()=>{this.open&&this.send(t.ping.content),this.forcibly_closed&&clearInterval(e)}),1e3*t.ping.interval)}T(e,"close",(async()=>{this.log("close"),this.open=!1,this.onCloseQueue.forEach((e=>e())),this.onCloseQueue=[];const e=t.reconnect;if("number"!=typeof e||isNaN(e)||this.forcibly_closed)this.ws=null,this.open=null;else{const t=async()=>{this.log("reconnect"),null!==this.ws&&(this.ws.close(),this.ws=null);null!==await this.connect()&&(this.reconnect_timeout=setTimeout(t,1e3*e))};t()}this.forcibly_closed=!1})),T(e,"message",(e=>{try{const o=t.decode(e.data);if(this.handlers.message.forEach((t=>t({...e,data:o}))),o[n]){const e=this.queue[o[n]];if(e){const t=e.sent_time?Date.now()-e.sent_time:null;this.log("message",o[s],t),e.ff(o[s]),clearTimeout(e.timeout),delete this.queue[o[n]]}}}catch(t){console.error(t,`WSP: Decode error. Got: ${e.data}`)}}))};var J=function(e){if(!0===this.open)return e(null);const t=this.config,n=t.socket||t.adapter(t.url,t.protocols);if(this.ws=n,!n||n.readyState>1)return this.ws=null,this.log("error","ready() on closing or closed state! status 2."),e(2);T(n,"error",U((t=>(this.log("error","status 3."),this.handlers.error.forEach((e=>e(t))),this.ws=null,e(3))))),n.readyState?(F.call(this,n),e(null)):T(n,"open",U((()=>(this.log("open"),F.call(this,n),e(null)))))};const L={data_type:"json",log:()=>null,timer:!1,url:"localhost",timeout:1400,reconnect:2,lazy:!1,socket:null,adapter:(e,t)=>new WebSocket(e,t),encode:(e,t,{server:n})=>JSON.stringify({[n.id_key]:e,[n.data_key]:t}),decode:e=>JSON.parse(e),protocols:[],pipes:[],server:{id_key:"id",data_key:"data"},ping:{interval:55,content:{}}},M=Symbol("Placeholder"),G=e=>{let t=0;for(const n of e)n!==M&&t++;return t},H=(e,t)=>{const n=e.length,s=e.slice(),o=t.length;let r=o,i=0;for(;r&&i<n;i++)s[i]===M&&(s[i]=t[o-r],r--);for(i=n;r;i++,r--)s[i]=t[o-r];return s},K=(e,t,n)=>{const s=e.length-t.length-G(n);if(s<1)return e(...H(t,n));{const o=(...s)=>K(e,H(t,n),s);return o.$args_left=s,o}},V=e=>(...t)=>e.length>G(t)?K(e,[],t):e(...t),X=e=>function(t){return t===M?e:e(t)};function Y(e){return function(t,n){const s=t===M,o=arguments.length;if(1===o&&s)throw new Error("Senseless placeholder usage.");return arguments.length>1?s?X((t=>e(t,n))):e(t,n):n=>e(t,n)}}function Z(e){return V(e)}const ee=void 0,te=1/0,ne=e=>typeof e,se=e=>null===e,oe={u:"U",b:"B",n:"N",s:"S",f:"F"},re=e=>{const t=ne(e);return"object"===t?se(e)?"Null":e.constructor.name:oe[t[0]]+t.slice(1)},ie=Z(((e,t,n)=>{for(let s in n)switch(re(n[s])){case"Array":if(e>1&&"Array"===re(t[s]))switch(e){case 2:const o=t[s],r=n[s];for(const t in r)o[t]?ie(e,o[t],r[t]):o[t]=r[t];break;case 3:t[s].push(...n[s])}else t[s]=n[s];break;case"Object":if("Object"===re(t[s])){ie(e,t[s],n[s]);break}default:t[s]=n[s]}return t}));ie(1),ie(2),ie(3);const ce=V(((e,t,n,s)=>e(s)?t(s):n(s))),le=(...e)=>(...t)=>{let n,s=!0;for(let o=de(e)-1;o>-1;o--)s?(s=!1,n=e[o](...t)):n=n===M?e[o]():e[o](n);return n},ue=Y(((e,t)=>t[e])),ae=Z(((e,t,n)=>n.slice(e,(e=>"number"==ne(e))(t)?t:te))),he=ue(0);ae(1,te);const fe=e=>se(e)||(e=>e===ee)(e),de=e=>e.length,ge=e=>()=>e,pe=ge(!0),me=Y(((e,t)=>t[e])),ye=Z(((e,t,n)=>ce(de,(()=>fe(n)?e:le(ce(fe,ge(e),(n=>ye(e,ae(1,te,t),n))),(e=>Y(((t,n)=>e(n,t))))(me)(n),he)(t)),ge(n),t)));ye(ee);module.exports=class{open=!1;ws=null;forcibly_closed=!1;reconnect_timeout=null;queue={};messages=[];onReadyQueue=[];onCloseQueue=[];handlers={open:[],message:[],close:[],error:[]};config={};init_flush(){this.queue={},this.messages=[]}log(e,t=null,n=null){const s=this.config;null!==n?s.log(e,n,t):s.timer?s.log(e,null,t):s.log(e,t)}async connect(){return new Promise((e=>{J.call(this,e)}))}get socket(){return this.ws}async ready(){return new Promise((e=>{this.open?e():this.onReadyQueue.push(e)}))}on(e,t,n=pe,s=!1){const o=e=>n(e)&&t(e);return s?T(this.ws,e,o):this.handlers[e].push(o)}async close(){return new Promise(((e,t)=>{null===this.ws?t("WSP: closing a non-inited socket!"):(this.open=!1,this.onCloseQueue.push((()=>{this.init_flush(),this.ws=null,this.forcibly_closed=!0,e(null)})),this.ws.close())}))}async send(e,t={}){this.log("send",e);const n=this.config,s={},o=n.server.data_key,r=n.lazy&&!this.open,i=(e=>{let t="";for(;e>0;)t=B[e%D]+t,e=z(e/D);return t||"0"})(2147483637*Math.random()|0);if("object"==typeof t.top){if(t.top[o])throw new Error("Attempting to set data key/token via send() options!");Object.assign(s,t.top)}if(n.pipes.forEach((t=>e=t(e))),!0===this.open)this.ws.send(n.encode(i,e,n));else if(!1===this.open||r)this.messages.push({send:()=>this.ws.send(n.encode(i,e,n))}),r&&this.connect();else if(null===this.open)throw new Error("Attempting to send via closed WebSocket connection!");return new Promise(((t,s)=>{this.queue[i]={ff:t,data_type:n.data_type,sent_time:n.timer?Date.now():null,timeout:x(n.timeout,(()=>{this.queue[i]&&(s({"Websocket timeout expired: ":n.timeout,"for the message ":e}),delete this.queue[i])}))}}))}constructor(e={}){this.config=(e=>{const t=Object.assign({},L,e),n=t.url;if("/"==n[0])try{const e=location.protocol.includes("s:")?"wss":"ws";t.url=`${e}://${location.hostname}:${location.port}${n}`}catch(e){throw new Error("WSP: URL starting with / in non-browser environment!")}return t})(e),this.init_flush(),this.open=!1,this.reconnect_timeout=null,this.forcibly_closed=!1,this.config.lazy||this.connect()}};
1
+ "use strict";const e=Symbol("Placeholder"),t=t=>{let n=0;for(const s of t)s!==e&&n++;return n},n=(t,n)=>{const s=t.length,o=t.slice(),r=n.length;let i=r,c=0;for(;i&&c<s;c++)o[c]===e&&(o[c]=n[r-i],i--);for(c=s;i;c++,i--)o[c]=n[r-i];return o},s=(e,o,r)=>{const i=e.length-o.length-t(r);if(i<1)return e(...n(o,r));{const t=(...t)=>s(e,n(o,r),t);return t.$args_left=i,t}},o=e=>(...n)=>e.length>t(n)?s(e,[],n):e(...n);function r(t){return function(n,s){const o=n===e,r=arguments.length;if(1===r&&o)throw new Error("Senseless placeholder usage.");return r>1?o?(t=>function(n){return n===e?t:t(n)})((e=>t(e,s))):t(n,s):e=>t(n,e)}}function i(e){return o(e)}const c=void 0,l=1/0,u=e=>typeof e,a=e=>null===e,h={u:"U",b:"B",n:"N",s:"S",f:"F"},f=Symbol(),d=e=>{const t=u(e);return"object"===t?a(e)?"Null":e.constructor.name:h[t[0]]+t.slice(1)},p=e=>e.length,g=r(((e,t)=>e===t)),m=r(((e,t)=>{const n=d(e);if(g(n,d(t))&&(g(n,"Object")||g(n,"Array"))){if(a(e)||a(t))return g(e,t);if(g(e,t))return!0;for(const n of[e,t])for(const s in n)if(!(g(n,t)&&s in e||g(n,e)&&s in t&&m(e[s],t[s])))return!1;return!0}return g(e,t)})),y=r(((e,t)=>(t.push(e),t))),w=i(((e,t,n)=>n.reduce(e,t))),b=o(((e,t,n,s)=>e(s)?t(s):n(s))),_=(...t)=>(...n)=>{let s,o=!0;for(let r=p(t)-1;r>-1;r--)o?(o=!1,s=t[r](...n)):s=s===e?t[r]():t[r](s);return s},k=r(((e,t)=>t[e])),S=i(((e,t,n)=>n.slice(e,(e=>"number"==u(e))(t)?t:l))),v=k(0);S(1,l);const E=r(((e,t)=>t.find(e))),P=e=>()=>e,W=r(((e,t)=>t.split(e))),j=P(!0),N=P(!1),q=r(((e,t)=>w(((t,n)=>E((t=>e(n,t)),t)?t:y(n,t)),[],t)))(m),z=i(((e,t,n)=>p(t)?(e=>a(e)||(e=>e===c)(e))(n)?e:_((s=>s in n?z(e,S(1,l,t),n[s]):e),v)(t):n));z(c),_(b(m(f),N,j),z(f));const Q=r(((e,t)=>t.map(e))),{floor:A}=Math,C="0123456789abcdefghijklmnopqrstuvwxyz",O=_((e=>Object.fromEntries(e)),Q(((e,t)=>[e,t])),W(""));class ${abc;abclen;c2pos;standard;setABC(e){if(!_(m(p(t=e)),p,q,W(""))(t))throw new Error("Not all chars are unique!");var t;this.abc=e,this.abclen=e.length,this.standard=C.startsWith(e),this.c2pos=O(e)}zip(e){const{abc:t,abclen:n}=this;let s="";for(;e>0;)s=t[e%n]+s,e=A(e/n);return s||"0"}unzip(e){const{standard:t,abclen:n,c2pos:s}=this;if(t)return parseInt(e,n);const o=e.length;let r=0;for(let t=0;t<o;t++)r+=s[e[t]]*n**(o-t-1);return r}constructor(e){this.setABC(e||C+"ABCDEFGHIJKLMNOPQRSTUVWXYZ")}}const B=new $;B.setABC.bind(B),B.zip.bind(B),B.unzip.bind(B);const R=(()=>{try{return WebSocket||null}catch{return null}})(),I=(e,t,n)=>e.addEventListener(t,n),T=(e,t)=>setTimeout(t,e),D={data_type:"json",log:()=>null,timer:!1,url:"localhost",timeout:1400,reconnect:2,lazy:!1,socket:null,adapter:(e,t)=>new WebSocket(e,t),encode:(e,t,{server:n})=>JSON.stringify({[n.id_key]:e,[n.data_key]:t}),decode:e=>JSON.parse(e),protocols:[],pipes:[],server:{id_key:"id",data_key:"data"},ping:{interval:55,content:{}}},U=Symbol("Placeholder"),x=e=>{let t=0;for(const n of e)n!==U&&t++;return t},F=(e,t)=>{const n=e.length,s=e.slice(),o=t.length;let r=o,i=0;for(;r&&i<n;i++)s[i]===U&&(s[i]=t[o-r],r--);for(i=n;r;i++,r--)s[i]=t[o-r];return s},J=(e,t,n)=>{const s=e.length-t.length-x(n);if(s<1)return e(...F(t,n));{const o=(...s)=>J(e,F(t,n),s);return o.$args_left=s,o}},L=e=>(...t)=>e.length>x(t)?J(e,[],t):e(...t);function M(e){return function(t,n){const s=t===U,o=arguments.length;if(1===o&&s)throw new Error("Senseless placeholder usage.");return o>1?s?(e=>function(t){return t===U?e:e(t)})((t=>e(t,n))):e(t,n):n=>e(t,n)}}function G(e){return L(e)}const H=void 0,K=1/0,V=e=>typeof e,X=e=>null===e,Y=e=>"number"==V(e),Z={u:"U",b:"B",n:"N",s:"S",f:"F"},ee=Symbol(),te=e=>{const t=V(e);return"object"===t?X(e)?"Null":e.constructor.name:Z[t[0]]+t.slice(1)},ne=e=>e.length,se=e=>X(e)||(e=>e===H)(e),oe=M(((e,t)=>e===t)),re=M(((e,t)=>{const n=te(e);if(oe(n,te(t))&&(oe(n,"Object")||oe(n,"Array"))){if(X(e)||X(t))return oe(e,t);if(oe(e,t))return!0;for(const n of[e,t])for(const s in n)if(!(oe(n,t)&&s in e||oe(n,e)&&s in t&&re(e[s],t[s])))return!1;return!0}return oe(e,t)})),ie=M(((e,t)=>(t.push(e),t))),ce=G(((e,t,n)=>n.reduce(e,t))),le=L(((e,t,n,s)=>e(s)?t(s):n(s))),ue=(...e)=>(...t)=>{let n,s=!0;for(let o=ne(e)-1;o>-1;o--)s?(s=!1,n=e[o](...t)):n=n===U?e[o]():e[o](n);return n},ae=M(((e,t)=>t[e])),he=G(((e,t,n)=>n.slice(e,Y(t)?t:K))),fe=ae(0);he(1,K);const de=M(((e,t)=>t.find(e))),pe=e=>()=>e,ge=pe(!0),me=pe(!1),ye=M(((e,t)=>ce(((t,n)=>de((t=>e(n,t)),t)?t:ie(n,t)),[],t)));ye(re);const we=e=>{let t,n=!1;return(...s)=>n?t:(n=!0,t=e(...s))},be=G(((e,t,n)=>ne(t)?se(n)?e:ue((s=>s in n?be(e,he(1,K,t),n[s]):e),fe)(t):n));be(H),ue(le(re(ee),me,ge),be(ee));const _e=new $;module.exports=class{open=!1;ws=null;forcibly_closed=!1;reconnect_timeout=null;queue={};messages=[];onReadyQueue=[];onCloseQueue=[];handlers={open:[],close:[],message:[],error:[]};config={};init_flush(){this.queue={},this.messages=[]}log(e,t=null,n=null){const s=this.config;null!==n?s.log(e,n,t):s.timer?s.log(e,null,t):s.log(e,t)}initSocket(e){const t=this.config;this.open=!0,this.onReadyQueue.forEach((e=>e())),this.onReadyQueue.splice(0);const{id_key:n,data_key:s}=t.server;if(this.handlers.open.forEach((t=>t(e))),this.messages.forEach((e=>e.send())),null!==this.reconnect_timeout&&(clearInterval(this.reconnect_timeout),this.reconnect_timeout=null),t.ping){const e=setInterval((()=>{this.open&&this.send(t.ping.content),this.forcibly_closed&&clearInterval(e)}),1e3*t.ping.interval)}I(e,"close",(async(...e)=>{this.log("close"),this.open=!1,this.onCloseQueue.forEach((e=>e())),this.onCloseQueue.splice(0),this.handlers.close.forEach((t=>t(...e)));const n=t.reconnect;if("number"!=typeof n||isNaN(n)||this.forcibly_closed)this.ws=null,this.open=!1;else{const e=async()=>{this.log("reconnect"),null!==this.ws&&(this.ws.close(),this.ws=null);null!==await this.connect()&&(this.reconnect_timeout=setTimeout(e,1e3*n))};e()}this.forcibly_closed=!1})),I(e,"message",(e=>{try{const o=t.decode(e.data);if(this.handlers.message.forEach((t=>t({...e,data:o}))),o[n]){const e=this.queue[o[n]];if(e){const t=e.sent_time?Date.now()-e.sent_time:null;this.log("message",o[s],t),e.ff(o[s]),clearTimeout(e.timeout),delete this.queue[o[n]]}}}catch(t){console.error(t,`WSP: Decode error. Got: ${e.data}`)}}))}async connect(){return new Promise((e=>{if(!0===this.open)return e(null);const t=this.config,n=t.socket||t.adapter(t.url,t.protocols);if(this.ws=n,!n||n.readyState>1)return this.ws=null,this.log("error","ready() on closing or closed state! status 2."),e(2);I(n,"error",we((t=>(this.log("error","status 3."),this.handlers.error.forEach((e=>e(t))),this.ws=null,e(3))))),n.readyState?(this.initSocket(n),e(null)):I(n,"open",we((()=>(this.log("open"),this.initSocket(n),e(null)))))}))}get socket(){return this.ws}async ready(){return new Promise((e=>{this.open?e():this.onReadyQueue.push(e)}))}on(e,t,n=ge,s=!1){const o=e=>n(e)&&t(e);return s?I(this.ws,e,o):this.handlers[e].push(o)}async close(){return new Promise(((e,t)=>{null===this.ws?t("WSP: closing a non-inited socket!"):(this.open=!1,this.onCloseQueue.push((()=>{this.init_flush(),this.ws=null,this.forcibly_closed=!0,e(null)})),this.ws.close())}))}async send(e,t={}){this.log("send",e);const n=this.config,s={},o=n.server.data_key,r=n.lazy&&!this.open,i=_e.zip(2147483637*Math.random()|0);if("object"==typeof t.top){if(t.top[o])throw new Error("Attempting to set data key/token via send() options!");Object.assign(s,t.top)}if(n.pipes.forEach((t=>e=t(e))),!0===this.open)this.ws.send(n.encode(i,e,n));else if(!1===this.open||r)this.messages.push({send:()=>this.ws.send(n.encode(i,e,n))}),r&&this.connect();else if(null===this.open)throw new Error("Attempting to send via closed WebSocket connection!");return new Promise(((t,s)=>{this.queue[i]={ff:t,data_type:n.data_type,sent_time:n.timer?Date.now():null,timeout:T(n.timeout,(()=>{this.queue[i]&&(s({"Websocket timeout expired: ":n.timeout,"for the message ":e}),delete this.queue[i])}))}}))}constructor(e={}){this.config=(e=>{if(null===R&&!("adapter"in e))throw new Error("\n This platform has no native WebSocket implementation.\n Please use 'ws' package as an adapter.\n See https://github.com/houd1ni/WebsocketPromisify/issues/23\n ");const t=Object.assign({},D,e),n=t.url;if("/"==n[0])try{const e=location.protocol.includes("s:")?"wss":"ws";t.url=`${e}://${location.hostname}:${location.port}${n}`}catch(e){throw new Error("WSP: URL starting with / in non-browser environment!")}return t})(e),this.init_flush(),this.open=!1,this.reconnect_timeout=null,this.forcibly_closed=!1,this.config.lazy||this.connect()}};
package/dist/bundle.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- // Generated by dts-bundle-generator v7.1.0
1
+ // Generated by dts-bundle-generator v9.5.1
2
2
 
3
- export declare namespace wsc {
3
+ declare namespace wsc {
4
4
  interface DataObject {
5
5
  [key: string]: any;
6
6
  }
@@ -61,11 +61,16 @@ declare class WebSocketClient {
61
61
  private config;
62
62
  private init_flush;
63
63
  private log;
64
+ private initSocket;
64
65
  private connect;
65
66
  get socket(): wsc.Socket | null;
66
67
  ready(): Promise<void>;
67
68
  on(event_name: wsc.WSEvent, handler: (data: any) => any, predicate?: (data: any) => boolean, raw?: boolean): number | void;
68
69
  close(): wsc.AsyncErrCode;
70
+ /** .send(your_data) wraps request to server with {id: `hash`, data: `actually your data`},
71
+ returns a Promise that will be rejected after a timeout or
72
+ resolved if server returns the same signature: {id: `same_hash`, data: `response data`}.
73
+ */
69
74
  send<RequestDataType = any, ResponseDataType = any>(message_data: RequestDataType, opts?: wsc.SendOptions): Promise<ResponseDataType>;
70
75
  constructor(user_config?: wsc.UserConfig);
71
76
  }
package/dist/bundle.mjs CHANGED
@@ -1 +1 @@
1
- const e=Symbol("Placeholder"),t=t=>{let n=0;for(const s of t)s!==e&&n++;return n},n=(t,n)=>{const s=t.length,o=t.slice(),r=n.length;let i=r,c=0;for(;i&&c<s;c++)o[c]===e&&(o[c]=n[r-i],i--);for(c=s;i;c++,i--)o[c]=n[r-i];return o},s=(e,o,r)=>{const i=e.length-o.length-t(r);if(i<1)return e(...n(o,r));{const t=(...t)=>s(e,n(o,r),t);return t.$args_left=i,t}},o=e=>(...n)=>e.length>t(n)?s(e,[],n):e(...n),r=t=>function(n){return n===e?t:t(n)};function i(t){return function(n,s){const o=n===e,i=arguments.length;if(1===i&&o)throw new Error("Senseless placeholder usage.");return arguments.length>1?o?r((e=>t(e,s))):t(n,s):e=>t(n,e)}}function c(e){return o(e)}const l=void 0,u=1/0,a=e=>typeof e,h=e=>null===e,f={u:"U",b:"B",n:"N",s:"S",f:"F"},d=e=>{const t=a(e);return"object"===t?h(e)?"Null":e.constructor.name:f[t[0]]+t.slice(1)},g=i(((e,t)=>(t.push(e),t))),p=c(((e,t,n)=>n.reduce(e,t))),m=c(((e,t,n)=>{for(let s in n)switch(d(n[s])){case"Array":if(e>1&&"Array"===d(t[s]))switch(e){case 2:const o=t[s],r=n[s];for(const t in r)o[t]?m(e,o[t],r[t]):o[t]=r[t];break;case 3:t[s].push(...n[s])}else t[s]=n[s];break;case"Object":if("Object"===d(t[s])){m(e,t[s],n[s]);break}default:t[s]=n[s]}return t}));m(1),m(2),m(3);const y=i(((e,t)=>{const n=d(e);if(n===d(t)&&("Object"===n||"Array"==n)){if(h(e)||h(t))return e===t;if(e===t)return!0;for(const n of[e,t])for(const s in n)if(!(n===t&&s in e||n===e&&s in t&&y(e[s],t[s])))return!1;return!0}return e===t})),w=o(((e,t,n,s)=>e(s)?t(s):n(s))),b=(...t)=>(...n)=>{let s,o=!0;for(let r=j(t)-1;r>-1;r--)o?(o=!1,s=t[r](...n)):s=s===e?t[r]():t[r](s);return s},_=i(((e,t)=>t[e])),k=i(((e,t)=>{if((e=>"string"===a(e))(t))return t.includes(e);for(const n of t)if(y(n,e))return!0;return!1})),S=c(((e,t,n)=>n.slice(e,(e=>"number"==a(e))(t)?t:u))),v=_(0);S(1,u);const E=e=>h(e)||(e=>e===l)(e),j=e=>e.length,N=e=>()=>e,O=i(((e,t)=>t.split(e))),A=e=>p(((e,t)=>k(t,e)?e:g(t,e)),[],e),P=c(((e,t,n)=>({...n,[e]:t}))),q=i(((e,t)=>t[e])),Q=c(((e,t,n)=>w(j,(()=>E(n)?e:b(w(E,N(e),(n=>Q(e,S(1,u,t),n))),(e=>i(((t,n)=>e(n,t))))(q)(n),v)(t)),N(n),t)));Q(l);const $=/^(.*?)(8|16|32|64)(Clamped)?Array$/,W=(e,t=!1)=>{const n=d(e);switch(n){case"Null":case"String":case"Number":case"Boolean":case"Symbol":return e;case"Array":return t?[...e]:R(b(W,((...e)=>e[0])),e);case"Object":if(t)return{...e};const s={};for(let t in e)s[t]=W(e[t]);return s;default:return $.test(n)?e.constructor.from(e):e}},C=c(((e,t,n)=>p(e,W(t),n))),R=i(((e,t)=>t.map(e))),{floor:z}=Math;let B,D;const I=b((e=>C(((e,t)=>P(...t,e)),{},e)),R(((e,t)=>[e,t])),O(""));(e=>{if(!(e=>b(y(j(e)),j,A,O(""))(e))(e))throw new Error("Not all chars are unique!");B=e,D=B.length,I(B)})("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");const T=(e,t,n)=>e.addEventListener(t,n),U=e=>{let t=!1,n=null;return(...s)=>t?n:(t=!0,n=e(...s))},x=(e,t)=>setTimeout(t,e),F=function(e){const t=this.config;this.open=!0,this.onReadyQueue.forEach((e=>e())),this.onReadyQueue.splice(0);const{id_key:n,data_key:s}=t.server;if(this.handlers.open.forEach((e=>e())),this.messages.forEach((e=>e.send())),null!==this.reconnect_timeout&&(clearInterval(this.reconnect_timeout),this.reconnect_timeout=null),t.ping){const e=setInterval((()=>{this.open&&this.send(t.ping.content),this.forcibly_closed&&clearInterval(e)}),1e3*t.ping.interval)}T(e,"close",(async()=>{this.log("close"),this.open=!1,this.onCloseQueue.forEach((e=>e())),this.onCloseQueue=[];const e=t.reconnect;if("number"!=typeof e||isNaN(e)||this.forcibly_closed)this.ws=null,this.open=null;else{const t=async()=>{this.log("reconnect"),null!==this.ws&&(this.ws.close(),this.ws=null);null!==await this.connect()&&(this.reconnect_timeout=setTimeout(t,1e3*e))};t()}this.forcibly_closed=!1})),T(e,"message",(e=>{try{const o=t.decode(e.data);if(this.handlers.message.forEach((t=>t({...e,data:o}))),o[n]){const e=this.queue[o[n]];if(e){const t=e.sent_time?Date.now()-e.sent_time:null;this.log("message",o[s],t),e.ff(o[s]),clearTimeout(e.timeout),delete this.queue[o[n]]}}}catch(t){console.error(t,`WSP: Decode error. Got: ${e.data}`)}}))};var J=function(e){if(!0===this.open)return e(null);const t=this.config,n=t.socket||t.adapter(t.url,t.protocols);if(this.ws=n,!n||n.readyState>1)return this.ws=null,this.log("error","ready() on closing or closed state! status 2."),e(2);T(n,"error",U((t=>(this.log("error","status 3."),this.handlers.error.forEach((e=>e(t))),this.ws=null,e(3))))),n.readyState?(F.call(this,n),e(null)):T(n,"open",U((()=>(this.log("open"),F.call(this,n),e(null)))))};const L={data_type:"json",log:()=>null,timer:!1,url:"localhost",timeout:1400,reconnect:2,lazy:!1,socket:null,adapter:(e,t)=>new WebSocket(e,t),encode:(e,t,{server:n})=>JSON.stringify({[n.id_key]:e,[n.data_key]:t}),decode:e=>JSON.parse(e),protocols:[],pipes:[],server:{id_key:"id",data_key:"data"},ping:{interval:55,content:{}}},M=Symbol("Placeholder"),G=e=>{let t=0;for(const n of e)n!==M&&t++;return t},H=(e,t)=>{const n=e.length,s=e.slice(),o=t.length;let r=o,i=0;for(;r&&i<n;i++)s[i]===M&&(s[i]=t[o-r],r--);for(i=n;r;i++,r--)s[i]=t[o-r];return s},K=(e,t,n)=>{const s=e.length-t.length-G(n);if(s<1)return e(...H(t,n));{const o=(...s)=>K(e,H(t,n),s);return o.$args_left=s,o}},V=e=>(...t)=>e.length>G(t)?K(e,[],t):e(...t),X=e=>function(t){return t===M?e:e(t)};function Y(e){return function(t,n){const s=t===M,o=arguments.length;if(1===o&&s)throw new Error("Senseless placeholder usage.");return arguments.length>1?s?X((t=>e(t,n))):e(t,n):n=>e(t,n)}}function Z(e){return V(e)}const ee=void 0,te=1/0,ne=e=>typeof e,se=e=>null===e,oe={u:"U",b:"B",n:"N",s:"S",f:"F"},re=e=>{const t=ne(e);return"object"===t?se(e)?"Null":e.constructor.name:oe[t[0]]+t.slice(1)},ie=Z(((e,t,n)=>{for(let s in n)switch(re(n[s])){case"Array":if(e>1&&"Array"===re(t[s]))switch(e){case 2:const o=t[s],r=n[s];for(const t in r)o[t]?ie(e,o[t],r[t]):o[t]=r[t];break;case 3:t[s].push(...n[s])}else t[s]=n[s];break;case"Object":if("Object"===re(t[s])){ie(e,t[s],n[s]);break}default:t[s]=n[s]}return t}));ie(1),ie(2),ie(3);const ce=V(((e,t,n,s)=>e(s)?t(s):n(s))),le=(...e)=>(...t)=>{let n,s=!0;for(let o=de(e)-1;o>-1;o--)s?(s=!1,n=e[o](...t)):n=n===M?e[o]():e[o](n);return n},ue=Y(((e,t)=>t[e])),ae=Z(((e,t,n)=>n.slice(e,(e=>"number"==ne(e))(t)?t:te))),he=ue(0);ae(1,te);const fe=e=>se(e)||(e=>e===ee)(e),de=e=>e.length,ge=e=>()=>e,pe=ge(!0),me=Y(((e,t)=>t[e])),ye=Z(((e,t,n)=>ce(de,(()=>fe(n)?e:le(ce(fe,ge(e),(n=>ye(e,ae(1,te,t),n))),(e=>Y(((t,n)=>e(n,t))))(me)(n),he)(t)),ge(n),t)));ye(ee);class we{open=!1;ws=null;forcibly_closed=!1;reconnect_timeout=null;queue={};messages=[];onReadyQueue=[];onCloseQueue=[];handlers={open:[],message:[],close:[],error:[]};config={};init_flush(){this.queue={},this.messages=[]}log(e,t=null,n=null){const s=this.config;null!==n?s.log(e,n,t):s.timer?s.log(e,null,t):s.log(e,t)}async connect(){return new Promise((e=>{J.call(this,e)}))}get socket(){return this.ws}async ready(){return new Promise((e=>{this.open?e():this.onReadyQueue.push(e)}))}on(e,t,n=pe,s=!1){const o=e=>n(e)&&t(e);return s?T(this.ws,e,o):this.handlers[e].push(o)}async close(){return new Promise(((e,t)=>{null===this.ws?t("WSP: closing a non-inited socket!"):(this.open=!1,this.onCloseQueue.push((()=>{this.init_flush(),this.ws=null,this.forcibly_closed=!0,e(null)})),this.ws.close())}))}async send(e,t={}){this.log("send",e);const n=this.config,s={},o=n.server.data_key,r=n.lazy&&!this.open,i=(e=>{let t="";for(;e>0;)t=B[e%D]+t,e=z(e/D);return t||"0"})(2147483637*Math.random()|0);if("object"==typeof t.top){if(t.top[o])throw new Error("Attempting to set data key/token via send() options!");Object.assign(s,t.top)}if(n.pipes.forEach((t=>e=t(e))),!0===this.open)this.ws.send(n.encode(i,e,n));else if(!1===this.open||r)this.messages.push({send:()=>this.ws.send(n.encode(i,e,n))}),r&&this.connect();else if(null===this.open)throw new Error("Attempting to send via closed WebSocket connection!");return new Promise(((t,s)=>{this.queue[i]={ff:t,data_type:n.data_type,sent_time:n.timer?Date.now():null,timeout:x(n.timeout,(()=>{this.queue[i]&&(s({"Websocket timeout expired: ":n.timeout,"for the message ":e}),delete this.queue[i])}))}}))}constructor(e={}){this.config=(e=>{const t=Object.assign({},L,e),n=t.url;if("/"==n[0])try{const e=location.protocol.includes("s:")?"wss":"ws";t.url=`${e}://${location.hostname}:${location.port}${n}`}catch(e){throw new Error("WSP: URL starting with / in non-browser environment!")}return t})(e),this.init_flush(),this.open=!1,this.reconnect_timeout=null,this.forcibly_closed=!1,this.config.lazy||this.connect()}}export{we as default};
1
+ const e=Symbol("Placeholder"),t=t=>{let n=0;for(const s of t)s!==e&&n++;return n},n=(t,n)=>{const s=t.length,o=t.slice(),r=n.length;let i=r,l=0;for(;i&&l<s;l++)o[l]===e&&(o[l]=n[r-i],i--);for(l=s;i;l++,i--)o[l]=n[r-i];return o},s=(e,o,r)=>{const i=e.length-o.length-t(r);if(i<1)return e(...n(o,r));{const t=(...t)=>s(e,n(o,r),t);return t.$args_left=i,t}},o=e=>(...n)=>e.length>t(n)?s(e,[],n):e(...n);function r(t){return function(n,s){const o=n===e,r=arguments.length;if(1===r&&o)throw new Error("Senseless placeholder usage.");return r>1?o?(t=>function(n){return n===e?t:t(n)})((e=>t(e,s))):t(n,s):e=>t(n,e)}}function i(e){return o(e)}const l=void 0,c=1/0,u=e=>typeof e,a=e=>null===e,h={u:"U",b:"B",n:"N",s:"S",f:"F"},f=Symbol(),d=e=>{const t=u(e);return"object"===t?a(e)?"Null":e.constructor.name:h[t[0]]+t.slice(1)},p=e=>e.length,g=r(((e,t)=>e===t)),m=r(((e,t)=>{const n=d(e);if(g(n,d(t))&&(g(n,"Object")||g(n,"Array"))){if(a(e)||a(t))return g(e,t);if(g(e,t))return!0;for(const n of[e,t])for(const s in n)if(!(g(n,t)&&s in e||g(n,e)&&s in t&&m(e[s],t[s])))return!1;return!0}return g(e,t)})),y=r(((e,t)=>(t.push(e),t))),w=i(((e,t,n)=>n.reduce(e,t))),b=o(((e,t,n,s)=>e(s)?t(s):n(s))),_=(...t)=>(...n)=>{let s,o=!0;for(let r=p(t)-1;r>-1;r--)o?(o=!1,s=t[r](...n)):s=s===e?t[r]():t[r](s);return s},k=r(((e,t)=>t[e])),S=i(((e,t,n)=>n.slice(e,(e=>"number"==u(e))(t)?t:c))),v=k(0);S(1,c);const E=r(((e,t)=>t.find(e))),P=e=>()=>e,W=r(((e,t)=>t.split(e))),j=P(!0),N=P(!1),q=r(((e,t)=>w(((t,n)=>E((t=>e(n,t)),t)?t:y(n,t)),[],t)))(m),z=i(((e,t,n)=>p(t)?(e=>a(e)||(e=>e===l)(e))(n)?e:_((s=>s in n?z(e,S(1,c,t),n[s]):e),v)(t):n));z(l),_(b(m(f),N,j),z(f));const Q=r(((e,t)=>t.map(e))),{floor:A}=Math,C="0123456789abcdefghijklmnopqrstuvwxyz",O=_((e=>Object.fromEntries(e)),Q(((e,t)=>[e,t])),W(""));class ${abc;abclen;c2pos;standard;setABC(e){if(!_(m(p(t=e)),p,q,W(""))(t))throw new Error("Not all chars are unique!");var t;this.abc=e,this.abclen=e.length,this.standard=C.startsWith(e),this.c2pos=O(e)}zip(e){const{abc:t,abclen:n}=this;let s="";for(;e>0;)s=t[e%n]+s,e=A(e/n);return s||"0"}unzip(e){const{standard:t,abclen:n,c2pos:s}=this;if(t)return parseInt(e,n);const o=e.length;let r=0;for(let t=0;t<o;t++)r+=s[e[t]]*n**(o-t-1);return r}constructor(e){this.setABC(e||C+"ABCDEFGHIJKLMNOPQRSTUVWXYZ")}}const B=new $;B.setABC.bind(B),B.zip.bind(B),B.unzip.bind(B);const R=(()=>{try{return WebSocket||null}catch{return null}})(),I=(e,t,n)=>e.addEventListener(t,n),T=(e,t)=>setTimeout(t,e),D={data_type:"json",log:()=>null,timer:!1,url:"localhost",timeout:1400,reconnect:2,lazy:!1,socket:null,adapter:(e,t)=>new WebSocket(e,t),encode:(e,t,{server:n})=>JSON.stringify({[n.id_key]:e,[n.data_key]:t}),decode:e=>JSON.parse(e),protocols:[],pipes:[],server:{id_key:"id",data_key:"data"},ping:{interval:55,content:{}}},U=Symbol("Placeholder"),x=e=>{let t=0;for(const n of e)n!==U&&t++;return t},F=(e,t)=>{const n=e.length,s=e.slice(),o=t.length;let r=o,i=0;for(;r&&i<n;i++)s[i]===U&&(s[i]=t[o-r],r--);for(i=n;r;i++,r--)s[i]=t[o-r];return s},J=(e,t,n)=>{const s=e.length-t.length-x(n);if(s<1)return e(...F(t,n));{const o=(...s)=>J(e,F(t,n),s);return o.$args_left=s,o}},L=e=>(...t)=>e.length>x(t)?J(e,[],t):e(...t);function M(e){return function(t,n){const s=t===U,o=arguments.length;if(1===o&&s)throw new Error("Senseless placeholder usage.");return o>1?s?(e=>function(t){return t===U?e:e(t)})((t=>e(t,n))):e(t,n):n=>e(t,n)}}function G(e){return L(e)}const H=void 0,K=1/0,V=e=>typeof e,X=e=>null===e,Y=e=>"number"==V(e),Z={u:"U",b:"B",n:"N",s:"S",f:"F"},ee=Symbol(),te=e=>{const t=V(e);return"object"===t?X(e)?"Null":e.constructor.name:Z[t[0]]+t.slice(1)},ne=e=>e.length,se=e=>X(e)||(e=>e===H)(e),oe=M(((e,t)=>e===t)),re=M(((e,t)=>{const n=te(e);if(oe(n,te(t))&&(oe(n,"Object")||oe(n,"Array"))){if(X(e)||X(t))return oe(e,t);if(oe(e,t))return!0;for(const n of[e,t])for(const s in n)if(!(oe(n,t)&&s in e||oe(n,e)&&s in t&&re(e[s],t[s])))return!1;return!0}return oe(e,t)})),ie=M(((e,t)=>(t.push(e),t))),le=G(((e,t,n)=>n.reduce(e,t))),ce=L(((e,t,n,s)=>e(s)?t(s):n(s))),ue=(...e)=>(...t)=>{let n,s=!0;for(let o=ne(e)-1;o>-1;o--)s?(s=!1,n=e[o](...t)):n=n===U?e[o]():e[o](n);return n},ae=M(((e,t)=>t[e])),he=G(((e,t,n)=>n.slice(e,Y(t)?t:K))),fe=ae(0);he(1,K);const de=M(((e,t)=>t.find(e))),pe=e=>()=>e,ge=pe(!0),me=pe(!1),ye=M(((e,t)=>le(((t,n)=>de((t=>e(n,t)),t)?t:ie(n,t)),[],t)));ye(re);const we=e=>{let t,n=!1;return(...s)=>n?t:(n=!0,t=e(...s))},be=G(((e,t,n)=>ne(t)?se(n)?e:ue((s=>s in n?be(e,he(1,K,t),n[s]):e),fe)(t):n));be(H),ue(ce(re(ee),me,ge),be(ee));const _e=new $;class ke{open=!1;ws=null;forcibly_closed=!1;reconnect_timeout=null;queue={};messages=[];onReadyQueue=[];onCloseQueue=[];handlers={open:[],close:[],message:[],error:[]};config={};init_flush(){this.queue={},this.messages=[]}log(e,t=null,n=null){const s=this.config;null!==n?s.log(e,n,t):s.timer?s.log(e,null,t):s.log(e,t)}initSocket(e){const t=this.config;this.open=!0,this.onReadyQueue.forEach((e=>e())),this.onReadyQueue.splice(0);const{id_key:n,data_key:s}=t.server;if(this.handlers.open.forEach((t=>t(e))),this.messages.forEach((e=>e.send())),null!==this.reconnect_timeout&&(clearInterval(this.reconnect_timeout),this.reconnect_timeout=null),t.ping){const e=setInterval((()=>{this.open&&this.send(t.ping.content),this.forcibly_closed&&clearInterval(e)}),1e3*t.ping.interval)}I(e,"close",(async(...e)=>{this.log("close"),this.open=!1,this.onCloseQueue.forEach((e=>e())),this.onCloseQueue.splice(0),this.handlers.close.forEach((t=>t(...e)));const n=t.reconnect;if("number"!=typeof n||isNaN(n)||this.forcibly_closed)this.ws=null,this.open=!1;else{const e=async()=>{this.log("reconnect"),null!==this.ws&&(this.ws.close(),this.ws=null);null!==await this.connect()&&(this.reconnect_timeout=setTimeout(e,1e3*n))};e()}this.forcibly_closed=!1})),I(e,"message",(e=>{try{const o=t.decode(e.data);if(this.handlers.message.forEach((t=>t({...e,data:o}))),o[n]){const e=this.queue[o[n]];if(e){const t=e.sent_time?Date.now()-e.sent_time:null;this.log("message",o[s],t),e.ff(o[s]),clearTimeout(e.timeout),delete this.queue[o[n]]}}}catch(t){console.error(t,`WSP: Decode error. Got: ${e.data}`)}}))}async connect(){return new Promise((e=>{if(!0===this.open)return e(null);const t=this.config,n=t.socket||t.adapter(t.url,t.protocols);if(this.ws=n,!n||n.readyState>1)return this.ws=null,this.log("error","ready() on closing or closed state! status 2."),e(2);I(n,"error",we((t=>(this.log("error","status 3."),this.handlers.error.forEach((e=>e(t))),this.ws=null,e(3))))),n.readyState?(this.initSocket(n),e(null)):I(n,"open",we((()=>(this.log("open"),this.initSocket(n),e(null)))))}))}get socket(){return this.ws}async ready(){return new Promise((e=>{this.open?e():this.onReadyQueue.push(e)}))}on(e,t,n=ge,s=!1){const o=e=>n(e)&&t(e);return s?I(this.ws,e,o):this.handlers[e].push(o)}async close(){return new Promise(((e,t)=>{null===this.ws?t("WSP: closing a non-inited socket!"):(this.open=!1,this.onCloseQueue.push((()=>{this.init_flush(),this.ws=null,this.forcibly_closed=!0,e(null)})),this.ws.close())}))}async send(e,t={}){this.log("send",e);const n=this.config,s={},o=n.server.data_key,r=n.lazy&&!this.open,i=_e.zip(2147483637*Math.random()|0);if("object"==typeof t.top){if(t.top[o])throw new Error("Attempting to set data key/token via send() options!");Object.assign(s,t.top)}if(n.pipes.forEach((t=>e=t(e))),!0===this.open)this.ws.send(n.encode(i,e,n));else if(!1===this.open||r)this.messages.push({send:()=>this.ws.send(n.encode(i,e,n))}),r&&this.connect();else if(null===this.open)throw new Error("Attempting to send via closed WebSocket connection!");return new Promise(((t,s)=>{this.queue[i]={ff:t,data_type:n.data_type,sent_time:n.timer?Date.now():null,timeout:T(n.timeout,(()=>{this.queue[i]&&(s({"Websocket timeout expired: ":n.timeout,"for the message ":e}),delete this.queue[i])}))}}))}constructor(e={}){this.config=(e=>{if(null===R&&!("adapter"in e))throw new Error("\n This platform has no native WebSocket implementation.\n Please use 'ws' package as an adapter.\n See https://github.com/houd1ni/WebsocketPromisify/issues/23\n ");const t=Object.assign({},D,e),n=t.url;if("/"==n[0])try{const e=location.protocol.includes("s:")?"wss":"ws";t.url=`${e}://${location.hostname}:${location.port}${n}`}catch(e){throw new Error("WSP: URL starting with / in non-browser environment!")}return t})(e),this.init_flush(),this.open=!1,this.reconnect_timeout=null,this.forcibly_closed=!1,this.config.lazy||this.connect()}}export{ke as default};
package/package.json CHANGED
@@ -1,94 +1,91 @@
1
- {
2
- "author": {
3
- "name": "Michael Akiliev"
4
- },
5
- "bugs": {
6
- "url": "https://github.com/houd1ni/WebsocketPromisify/issues"
7
- },
8
- "bundleDependencies": [],
9
- "deprecated": false,
10
- "description": "Wraps your WebSockets into Promise-based class with full d.ts typings on client & server",
11
- "homepage": "https://github.com/houd1ni/WebsocketPromisify#readme",
12
- "keywords": [
13
- "WebSockets",
14
- "WS",
15
- "Promise",
16
- "Socket",
17
- "REST",
18
- "Ajax",
19
- "Easy",
20
- "realtime",
21
- "Middleware",
22
- "JSON",
23
- "Data",
24
- "transport",
25
- "API",
26
- "async"
27
- ],
28
- "license": "MIT",
29
- "name": "wspromisify",
30
- "repository": {
31
- "type": "git",
32
- "url": "git+https://github.com/houd1ni/WebsocketPromisify.git"
33
- },
34
- "scripts": {
35
- "lint": "tslint src/*.ts",
36
- "test": "npm run gentypes && npm run prod:es && ava",
37
- "test:report": "nyc npm test && nyc report --reporter=text-lcov > coverage.lcov && codecov",
38
- "test:lazy": "ava",
39
- "gentypes": "dts-bundle-generator --no-check -o dist/bundle.d.ts src/WS.ts",
40
- "dev": "cross-env NODE_ENV=development BUILD=es rollup -c",
41
- "prod:cjs": "cross-env NODE_ENV=production BUILD=cjs rollup -c",
42
- "prod:es": "cross-env NODE_ENV=production BUILD=es rollup -c",
43
- "prod": "npm run gentypes && npm run prod:es && npm run prod:cjs",
44
- "all": "npm run dev && npm run prod"
45
- },
46
- "version": "2.4.3",
47
- "type": "module",
48
- "exports": {
49
- ".": {
50
- "import": "./dist/bundle.mjs",
51
- "require": "./dist/bundle.cjs"
52
- }
53
- },
54
- "ava": {
55
- "files": [
56
- "./test/specs/*.js"
57
- ],
58
- "failFast": true,
59
- "timeout": "2m",
60
- "nodeArguments": [
61
- "--experimental-specifier-resolution=node"
62
- ]
63
- },
64
- "devDependencies": {
65
- "@babel/core": "^7.20.12",
66
- "@babel/polyfill": "^7.12.1",
67
- "@babel/register": "^7.18.9",
68
- "@rollup/plugin-commonjs": "^23.0.3",
69
- "@rollup/plugin-node-resolve": "^15.0.1",
70
- "@rollup/plugin-replace": "^5.0.1",
71
- "@rollup/plugin-terser": "^0.1.0",
72
- "@types/node": "^18.11.18",
73
- "@types/ws": "^8.5.4",
74
- "ava": "^5.1.1",
75
- "axios": "^1.2.2",
76
- "codecov": "^3.8.3",
77
- "cross-env": "^7.0.3",
78
- "dts-bundle-generator": "^7.1.0",
79
- "express": "^4.18.2",
80
- "nyc": "^15.1.0",
81
- "randomatic": "^3.1.1",
82
- "rollup": "^3.10.0",
83
- "rollup-plugin-typescript2": "^0.34.1",
84
- "ts-node": "^10.9.1",
85
- "tslint": "^6.1.3",
86
- "typescript": "^4.9.4",
87
- "ws": "^8.12.0"
88
- },
89
- "types": "./dist/bundle.d.ts",
90
- "dependencies": {
91
- "pepka": "^1.0.0-beta.1",
92
- "zipnum": "^1.0.0"
93
- }
94
- }
1
+ {
2
+ "author": {
3
+ "name": "Michael Akiliev"
4
+ },
5
+ "bugs": {
6
+ "url": "https://github.com/houd1ni/WebsocketPromisify/issues"
7
+ },
8
+ "deprecated": false,
9
+ "description": "Wraps your WebSockets into Promise-based class with full d.ts typings on client & server",
10
+ "homepage": "https://github.com/houd1ni/WebsocketPromisify#readme",
11
+ "keywords": [
12
+ "WebSockets",
13
+ "WS",
14
+ "Promise",
15
+ "Socket",
16
+ "REST",
17
+ "Ajax",
18
+ "Easy",
19
+ "realtime",
20
+ "Middleware",
21
+ "JSON",
22
+ "Data",
23
+ "transport",
24
+ "API",
25
+ "async"
26
+ ],
27
+ "license": "MIT",
28
+ "name": "wspromisify",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/houd1ni/WebsocketPromisify.git"
32
+ },
33
+ "scripts": {
34
+ "lint": "tslint src/*.ts",
35
+ "test": "tsx test/index",
36
+ "test:report": "nyc npm test && nyc report --reporter=text-lcov > coverage.lcov && codecov",
37
+ "gentypes": "dts-bundle-generator --no-check -o dist/bundle.d.ts src/WSC.ts",
38
+ "dev": "cross-env NODE_ENV=development BUILD=es rollup -c",
39
+ "prod:cjs": "cross-env NODE_ENV=production BUILD=cjs rollup -c",
40
+ "prod:es": "cross-env NODE_ENV=production BUILD=es rollup -c",
41
+ "prod": "npm run gentypes && npm run prod:es && npm run prod:cjs",
42
+ "all": "npm run dev && npm run prod"
43
+ },
44
+ "version": "2.5.0",
45
+ "type": "module",
46
+ "exports": {
47
+ ".": {
48
+ "import": "./dist/bundle.mjs",
49
+ "require": "./dist/bundle.cjs"
50
+ }
51
+ },
52
+ "ava": {
53
+ "extensions": {
54
+ "js": true,
55
+ "ts": "module"
56
+ },
57
+ "files": [
58
+ "./test/specs/*.ts"
59
+ ],
60
+ "failFast": true,
61
+ "timeout": "2m",
62
+ "nodeArguments": [
63
+ "--import=tsimp"
64
+ ]
65
+ },
66
+ "devDependencies": {
67
+ "@rollup/plugin-commonjs": "^28.0.2",
68
+ "@rollup/plugin-node-resolve": "^16.0.0",
69
+ "@rollup/plugin-replace": "^6.0.2",
70
+ "@rollup/plugin-terser": "^0.4.4",
71
+ "@types/express": "^5.0.0",
72
+ "@types/node": "^22.13.1",
73
+ "@types/ws": "^8.5.14",
74
+ "codecov": "^3.8.3",
75
+ "cross-env": "^7.0.3",
76
+ "dts-bundle-generator": "^9.5.1",
77
+ "nyc": "^17.1.0",
78
+ "pepka": "^1.6.2",
79
+ "rollup": "^4.34.2",
80
+ "rollup-plugin-typescript2": "^0.36.0",
81
+ "ts-node": "^10.9.2",
82
+ "tsx": "^4.19.2",
83
+ "typescript": "^5.7.3",
84
+ "uvu": "^0.5.6",
85
+ "ws": "^8.18.0"
86
+ },
87
+ "types": "./dist/bundle.d.ts",
88
+ "dependencies": {
89
+ "zipnum": "^2.0.0"
90
+ }
91
+ }
package/rollup.config.js CHANGED
@@ -6,7 +6,7 @@ import replace from '@rollup/plugin-replace'
6
6
  import tsc from 'typescript'
7
7
 
8
8
  export default {
9
- input: 'src/WS.ts',
9
+ input: 'src/WSC.ts',
10
10
  output: {
11
11
  file: process.env.NODE_ENV=='development'
12
12
  ? 'dist/bundle.dev.js'