wspromisify 2.6.2 → 2.6.4
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 +1 -1
- package/dist/bundle.cjs +1 -1
- package/dist/bundle.d.ts +4 -2
- package/dist/bundle.mjs +1 -1
- package/package.json +5 -5
- package/src/WSC.ts +15 -5
- package/src/types.ts +2 -1
- package/src/utils.ts +3 -0
- package/test/index.ts +2 -2
- package/test/specs/{lazySendBeforeOpen.ts → lazy-send-before-open.ts} +2 -2
- /package/test/specs/{existing_socket.ts → existing-socket.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# WebsocketPromisify
|
|
2
|
-
[](https://scrutinizer-ci.com/g/houd1ni/WebsocketPromisify/build-status/master) [](https://scrutinizer-ci.com/g/houd1ni/WebsocketPromisify/code-structure/master) [](https://codecov.io/gh/houd1ni/WebsocketPromisify) [](https://scrutinizer-ci.com/g/houd1ni/WebsocketPromisify/build-status/master) [](https://scrutinizer-ci.com/g/houd1ni/WebsocketPromisify/code-structure/master) [](https://codecov.io/gh/houd1ni/WebsocketPromisify) [](https://deno.bundlejs.com/badge?q=wspromisify@2.6.2&treeshake=[*]) [](https://www.npmjs.com/package/wspromisify)
|
|
3
3
|
|
|
4
4
|
A nice-looking this readme version: https://houd1ni.github.io/WebsocketPromisify/
|
|
5
5
|
|
package/dist/bundle.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const t=Symbol("Placeholder"),e=e=>{let n=0;for(const
|
|
1
|
+
"use strict";const t=Symbol("Placeholder"),e=e=>{let n=0;for(const s of e)s!==t&&n++;return n},n=(e,n)=>{const s=e.length,o=e.slice(),r=n.length;let i=r,l=0;for(;i&&l<s;l++)o[l]===t&&(o[l]=n[r-i],i--);for(l=s;i;l++,i--)o[l]=n[r-i];return o},s=(t,o,r)=>{const i=t.length-o.length-e(r);if(i<1)return t(...n(o,r));{const e=(...e)=>s(t,n(o,r),e);return e.$args_left=i,e}},o=t=>(...n)=>t.length>e(n)?s(t,[],n):t(...n);function r(e){return function(n,s){const o=n===t,r=arguments.length;if(1===r&&o)throw new Error("Senseless placeholder usage.");return r>1?o?(e=>function(n){return n===t?e:e(n)})((t=>e(t,s))):e(n,s):t=>e(n,t)}}function i(t){return o(t)}const l=void 0,c=1/0,u=t=>typeof t,a=t=>null===t,h={u:"U",b:"B",n:"N",s:"S",f:"F"},f=Symbol(),d=t=>{const e=u(t);return"object"===e?a(t)?"Null":t.constructor.name:h[e[0]]+e.slice(1)},p=t=>t.length,g=r(((t,e)=>t===e)),m=r(((t,e)=>{const n=d(t);if(g(n,d(e))&&(g(n,"Object")||g(n,"Array"))){if(a(t)||a(e))return g(t,e);if(g(t,e))return!0;for(const n of[t,e])for(const s in n)if(!(g(n,e)&&s in t||g(n,t)&&s in e&&m(t[s],e[s])))return!1;return!0}return g(t,e)})),y=r(((t,e)=>(e.push(t),e))),w=i(((t,e,n)=>n.reduce(t,e))),b=o(((t,e,n,s)=>t(s)?e(s):n(s))),_=(...e)=>(...n)=>{let s,o=!0;for(let r=p(e)-1;r>-1;r--)o?(o=!1,s=e[r](...n)):s=s===t?e[r]():e[r](s);return s},S=r(((t,e)=>e[t])),k=i(((t,e,n)=>n.slice(t,(t=>"number"==u(t))(e)?e:c))),v=S(0);k(1,c);const E=r(((t,e)=>e.find(t))),P=t=>()=>t,W=r(((t,e)=>e.split(t))),j=P(!0),A=P(!1),N=r(((t,e)=>w(((e,n)=>E((e=>t(n,e)),e)?e:y(n,e)),[],e)))(m),q=i(((t,e,n)=>p(e)?(t=>a(t)||(t=>t===l)(t))(n)?t:_((s=>s in n?q(t,k(1,c,e),n[s]):t),v)(e):n));q(l),_(b(m(f),A,j),q(f));const O=r(((t,e)=>e.map(t))),{floor:Q}=Math,z="0123456789abcdefghijklmnopqrstuvwxyz",C=_((t=>Object.fromEntries(t)),O(((t,e)=>[t,e])),W(""));class ${abc;abclen;c2pos;standard;setABC(t){if(!_(m(p(e=t)),p,N,W(""))(e))throw new Error("Not all chars are unique!");var e;this.abc=t,this.abclen=t.length,this.standard=z.startsWith(t),this.c2pos=C(t)}zip(t){const{abc:e,abclen:n}=this;let s="";for(;t>0;)s=e[t%n]+s,t=Q(t/n);return s||"0"}unzip(t){const{standard:e,abclen:n,c2pos:s}=this;if(e)return parseInt(t,n);const o=t.length;let r=0;for(let e=0;e<o;e++)r+=s[t[e]]*n**(o-e-1);return r}constructor(t){this.setABC(t||z+"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=(t,e,n)=>t.addEventListener(e,n),T=(t,e)=>setTimeout(e,t),x={data_type:"json",log:()=>null,timer:!1,url:"localhost",timeout:1400,reconnect:2,lazy:!1,socket:null,adapter:(t,e)=>new WebSocket(t,e),encode:(t,e,{server:n})=>JSON.stringify({[n.id_key]:t,[n.data_key]:e}),decode:t=>JSON.parse(t),protocols:[],pipes:[],server:{id_key:"id",data_key:"data"},ping:{interval:55,content:{}}},D=Symbol("Placeholder"),L=t=>{let e=0;for(const n of t)n!==D&&e++;return e},U=(t,e)=>{const n=t.length,s=t.slice(),o=e.length;let r=o,i=0;for(;r&&i<n;i++)s[i]===D&&(s[i]=e[o-r],r--);for(i=n;r;i++,r--)s[i]=e[o-r];return s},F=(t,e,n)=>{const s=t.length-e.length-L(n);if(s<1)return t(...U(e,n));{const o=(...s)=>F(t,U(e,n),s);return o.$args_left=s,o}},J=t=>(...e)=>t.length>L(e)?F(t,[],e):t(...e);function M(t){return function(e,n){const s=e===D,o=arguments.length;if(1===o&&s)throw new Error("Senseless placeholder usage.");return o>1?s?(t=>function(e){return e===D?t:t(e)})((e=>t(e,n))):t(e,n):n=>t(e,n)}}function G(t){return J(t)}const H=void 0,K=1/0,V=t=>typeof t,X=t=>null===t,Y=t=>"number"==V(t),Z={u:"U",b:"B",n:"N",s:"S",f:"F"},tt=Symbol(),et=t=>{const e=V(t);return"object"===e?X(t)?"Null":t.constructor.name:Z[e[0]]+e.slice(1)},nt=t=>t.length,st=t=>X(t)||(t=>t===H)(t),ot=M(((t,e)=>t===e)),rt=M(((t,e)=>{const n=et(t);if(ot(n,et(e))&&(ot(n,"Object")||ot(n,"Array"))){if(X(t)||X(e))return ot(t,e);if(ot(t,e))return!0;for(const n of[t,e])for(const s in n)if(!(ot(n,e)&&s in t||ot(n,t)&&s in e&&rt(t[s],e[s])))return!1;return!0}return ot(t,e)})),it=M(((t,e)=>(e.push(t),e))),lt=G(((t,e,n)=>n.reduce(t,e))),ct=M(((t,e)=>{const n=(t=>Array.isArray(t))(e);let s,o;n&&(s=0,o=[]);for(let s in e)t(e[s],s)||(n?o.push(+s):delete e[s]);if(n)for(const t of o)e.splice(t-s++,1);return e})),ut=J(((t,e,n,s)=>t(s)?e(s):n(s))),at=(...t)=>(...e)=>{let n,s=!0;for(let o=nt(t)-1;o>-1;o--)s?(s=!1,n=t[o](...e)):n=n===D?t[o]():t[o](n);return n},ht=M(((t,e)=>e[t])),ft=G(((t,e,n)=>n.slice(t,Y(e)?e:K))),dt=ht(0);ft(1,K);const pt=M(((t,e)=>e.find(t))),gt=t=>()=>t,mt=gt(!0),yt=gt(!1),wt=M(((t,e)=>lt(((e,n)=>pt((e=>t(n,e)),e)?e:it(n,e)),[],e)));wt(rt);const bt=t=>{let e,n=!1;return(...s)=>n?e:(n=!0,e=t(...s))},_t=G(((t,e,n)=>nt(e)?st(n)?t:at((s=>s in n?_t(t,ft(1,K,e),n[s]):t),dt)(e):n));_t(H),at(ut(rt(tt),yt,mt),_t(tt));const St=new $;module.exports=class{open=!1;ws=null;forcibly_closed=!1;reconnect_timeout=null;queue={};onReadyQueue=[];onCloseQueue=[];handlers={open:[],close:[],message:[],error:[],timeout:[]};config={};init_flush(){ct(yt,this.queue)}call(t,...e){for(const n of this.handlers[t])n(...e)}log(t,e=null,n=null){const s=this.config;null!==n?s.log(t,n,e):s.timer?s.log(t,null,e):s.log(t,e)}initSocket(t){const{queue:e,config:n}=this;this.open=!0,this.ws=t,this.onReadyQueue.forEach((t=>t())),this.onReadyQueue.splice(0);const{id_key:s,data_key:o}=n.server;this.call("open",t);for(const n in e)t.send(e[n].msg);if(null!==this.reconnect_timeout&&(clearInterval(this.reconnect_timeout),this.reconnect_timeout=null),n.ping){const t=setInterval((()=>{this.open&&this.send(n.ping.content),this.forcibly_closed&&clearInterval(t)}),1e3*n.ping.interval)}I(t,"close",(async(...t)=>{this.log("close"),this.open=!1,this.ws=null,this.onCloseQueue.forEach((t=>t())),this.onCloseQueue.splice(0),this.call("close",...t);const e=n.reconnect;if("number"==typeof e&&!isNaN(e)&&!this.forcibly_closed){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})),I(t,"message",(t=>{try{const e=n.decode(t.data);if(this.call("message",{...t,data:e}),e[s]){const t=this.queue[e[s]];if(t){const n=t.sent_time?Date.now()-t.sent_time:null;this.log("message",e[o],n),t.ff(e[o])}}}catch(e){console.error(e,`WSP: Decode error. Got: ${t.data}`)}}))}connect(){return new Promise((t=>{if(!0===this.open)return t(null);const e=this.config,n=e.socket||e.adapter(e.url,e.protocols);if(!n||n.readyState>1)return this.ws=null,this.log("error","ready() on closing or closed state! status 2."),t(2);const s=bt(t);I(n,"error",bt((t=>{this.log("error","status 3. Err: "+t.message),this.call("error",t),this.ws=null,s(3)}))),n.readyState?(this.initSocket(n),s(null)):I(n,"open",bt((()=>{this.log("open"),this.initSocket(n),s(null)})))}))}get socket(){return this.ws}async ready(){return new Promise((t=>{this.open?t():this.onReadyQueue.push(t)}))}on(t,e,n=mt,s=!1){const o=t=>n(t)&&e(t);return s?I(this.ws,t,o):this.handlers[t].push(o),o}off(t,e,n=!1){if(n)return((t,e,n)=>t.removeEventListener(e,n))(this.ws,t,e);const s=this.handlers[t],o=s.indexOf(e);~o&&s.splice(o,1)}async close(){return new Promise(((t,e)=>{null===this.ws?e("WSP: closing a non-inited socket!"):(this.open=!1,this.onCloseQueue.push((()=>{this.init_flush(),this.ws=null,this.forcibly_closed=!0,t(null)})),this.ws.close())}))}async send(t,e={}){this.log("send",t);const{config:n,ws:s,forcibly_closed:o,queue:r}=this,i={},l=n.server.data_key,c=St.zip(2147483637*Math.random()|0);if("object"==typeof e.top){if(e.top[l])throw new Error("Attempting to set data key/token via send() options!");Object.assign(i,e.top)}if(n.pipes.forEach((e=>t=e(t))),o)throw new Error("Attempting to send via closed WebSocket connection!");this.open||this.connect();const u=await n.encode(c,t,n);return 1===s?.readyState&&s.send(u),new Promise(((e,s)=>{this.queue[c]={msg:u,ff(t){e(t),clearTimeout(this.timeout),delete r[c]},data_type:n.data_type,sent_time:n.timer?Date.now():null,timeout:T(n.timeout,(()=>{this.queue[c]&&(this.call("timeout",t),s({"Websocket timeout expired: ":n.timeout,"for the message ":t}),delete r[c])}))}}))}constructor(t={}){this.config=(t=>{if(null===R&&!("adapter"in t))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 e=Object.assign({},x,t),n=e.url;if("/"==n[0])try{const t=location.protocol.includes("s:")?"wss":"ws";e.url=`${t}://${location.hostname}:${location.port}${n}`}catch(t){throw new Error("WSP: URL starting with / in non-browser environment!")}return e})(t),this.init_flush(),this.config.lazy||this.connect()}};
|
package/dist/bundle.d.ts
CHANGED
|
@@ -10,7 +10,8 @@ declare namespace wsc {
|
|
|
10
10
|
readyState: number;
|
|
11
11
|
send(...any: any[]): void;
|
|
12
12
|
close(): void;
|
|
13
|
-
addEventListener
|
|
13
|
+
addEventListener: WebSocket["addEventListener"];
|
|
14
|
+
removeEventListener: WebSocket["removeEventListener"];
|
|
14
15
|
}
|
|
15
16
|
type AsyncErrCode = Promise<number | null | {}>;
|
|
16
17
|
type EventHandler = (e: any) => void;
|
|
@@ -72,7 +73,8 @@ declare class WebSocketClient {
|
|
|
72
73
|
private connect;
|
|
73
74
|
get socket(): wsc.Socket | null;
|
|
74
75
|
ready(): Promise<void>;
|
|
75
|
-
on(event_name: wsc.WSEvent, handler: (data: any) => any, predicate?: (data: any) => boolean, raw?: boolean):
|
|
76
|
+
on(event_name: wsc.WSEvent, handler: (data: any) => any, predicate?: (data: any) => boolean, raw?: boolean): wsc.EventHandler;
|
|
77
|
+
off(event_name: wsc.WSEvent, handler: (data: any) => any, raw?: boolean): void;
|
|
76
78
|
close(): wsc.AsyncErrCode;
|
|
77
79
|
/** .send(your_data) wraps request to server with {id: `hash`, data: `actually your data`},
|
|
78
80
|
returns a Promise that will be rejected after a timeout or
|
package/dist/bundle.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const t=Symbol("Placeholder"),e=e=>{let n=0;for(const o of e)o!==t&&n++;return n},n=(e,n)=>{const o=e.length,s=e.slice(),r=n.length;let i=r,l=0;for(;i&&l<o;l++)s[l]===t&&(s[l]=n[r-i],i--);for(l=o;i;l++,i--)s[l]=n[r-i];return s},o=(t,s,r)=>{const i=t.length-s.length-e(r);if(i<1)return t(...n(s,r));{const e=(...e)=>o(t,n(s,r),e);return e.$args_left=i,e}},s=t=>(...n)=>t.length>e(n)?o(t,[],n):t(...n);function r(e){return function(n,o){const s=n===t,r=arguments.length;if(1===r&&s)throw new Error("Senseless placeholder usage.");return r>1?s?(e=>function(n){return n===t?e:e(n)})((t=>e(t,o))):e(n,o):t=>e(n,t)}}function i(t){return s(t)}const l=void 0,c=1/0,u=t=>typeof t,a=t=>null===t,h={u:"U",b:"B",n:"N",s:"S",f:"F"},f=Symbol(),d=t=>{const e=u(t);return"object"===e?a(t)?"Null":t.constructor.name:h[e[0]]+e.slice(1)},p=t=>t.length,g=r(((t,e)=>t===e)),m=r(((t,e)=>{const n=d(t);if(g(n,d(e))&&(g(n,"Object")||g(n,"Array"))){if(a(t)||a(e))return g(t,e);if(g(t,e))return!0;for(const n of[t,e])for(const o in n)if(!(g(n,e)&&o in t||g(n,t)&&o in e&&m(t[o],e[o])))return!1;return!0}return g(t,e)})),y=r(((t,e)=>(e.push(t),e))),w=i(((t,e,n)=>n.reduce(t,e))),b=s(((t,e,n,o)=>t(o)?e(o):n(o))),_=(...e)=>(...n)=>{let o,s=!0;for(let r=p(e)-1;r>-1;r--)s?(s=!1,o=e[r](...n)):o=o===t?e[r]():e[r](o);return o},S=r(((t,e)=>e[t])),k=i(((t,e,n)=>n.slice(t,(t=>"number"==u(t))(e)?e:c))),v=S(0);k(1,c);const E=r(((t,e)=>e.find(t))),P=t=>()=>t,W=r(((t,e)=>e.split(t))),j=P(!0),A=P(!1),N=r(((t,e)=>w(((e,n)=>E((e=>t(n,e)),e)?e:y(n,e)),[],e)))(m),q=i(((t,e,n)=>p(e)?(t=>a(t)||(t=>t===l)(t))(n)?t:_((o=>o in n?q(t,k(1,c,e),n[o]):t),v)(e):n));q(l),_(b(m(f),A,j),q(f));const
|
|
1
|
+
const t=Symbol("Placeholder"),e=e=>{let n=0;for(const o of e)o!==t&&n++;return n},n=(e,n)=>{const o=e.length,s=e.slice(),r=n.length;let i=r,l=0;for(;i&&l<o;l++)s[l]===t&&(s[l]=n[r-i],i--);for(l=o;i;l++,i--)s[l]=n[r-i];return s},o=(t,s,r)=>{const i=t.length-s.length-e(r);if(i<1)return t(...n(s,r));{const e=(...e)=>o(t,n(s,r),e);return e.$args_left=i,e}},s=t=>(...n)=>t.length>e(n)?o(t,[],n):t(...n);function r(e){return function(n,o){const s=n===t,r=arguments.length;if(1===r&&s)throw new Error("Senseless placeholder usage.");return r>1?s?(e=>function(n){return n===t?e:e(n)})((t=>e(t,o))):e(n,o):t=>e(n,t)}}function i(t){return s(t)}const l=void 0,c=1/0,u=t=>typeof t,a=t=>null===t,h={u:"U",b:"B",n:"N",s:"S",f:"F"},f=Symbol(),d=t=>{const e=u(t);return"object"===e?a(t)?"Null":t.constructor.name:h[e[0]]+e.slice(1)},p=t=>t.length,g=r(((t,e)=>t===e)),m=r(((t,e)=>{const n=d(t);if(g(n,d(e))&&(g(n,"Object")||g(n,"Array"))){if(a(t)||a(e))return g(t,e);if(g(t,e))return!0;for(const n of[t,e])for(const o in n)if(!(g(n,e)&&o in t||g(n,t)&&o in e&&m(t[o],e[o])))return!1;return!0}return g(t,e)})),y=r(((t,e)=>(e.push(t),e))),w=i(((t,e,n)=>n.reduce(t,e))),b=s(((t,e,n,o)=>t(o)?e(o):n(o))),_=(...e)=>(...n)=>{let o,s=!0;for(let r=p(e)-1;r>-1;r--)s?(s=!1,o=e[r](...n)):o=o===t?e[r]():e[r](o);return o},S=r(((t,e)=>e[t])),k=i(((t,e,n)=>n.slice(t,(t=>"number"==u(t))(e)?e:c))),v=S(0);k(1,c);const E=r(((t,e)=>e.find(t))),P=t=>()=>t,W=r(((t,e)=>e.split(t))),j=P(!0),A=P(!1),N=r(((t,e)=>w(((e,n)=>E((e=>t(n,e)),e)?e:y(n,e)),[],e)))(m),q=i(((t,e,n)=>p(e)?(t=>a(t)||(t=>t===l)(t))(n)?t:_((o=>o in n?q(t,k(1,c,e),n[o]):t),v)(e):n));q(l),_(b(m(f),A,j),q(f));const O=r(((t,e)=>e.map(t))),{floor:Q}=Math,z="0123456789abcdefghijklmnopqrstuvwxyz",C=_((t=>Object.fromEntries(t)),O(((t,e)=>[t,e])),W(""));class ${abc;abclen;c2pos;standard;setABC(t){if(!_(m(p(e=t)),p,N,W(""))(e))throw new Error("Not all chars are unique!");var e;this.abc=t,this.abclen=t.length,this.standard=z.startsWith(t),this.c2pos=C(t)}zip(t){const{abc:e,abclen:n}=this;let o="";for(;t>0;)o=e[t%n]+o,t=Q(t/n);return o||"0"}unzip(t){const{standard:e,abclen:n,c2pos:o}=this;if(e)return parseInt(t,n);const s=t.length;let r=0;for(let e=0;e<s;e++)r+=o[t[e]]*n**(s-e-1);return r}constructor(t){this.setABC(t||z+"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=(t,e,n)=>t.addEventListener(e,n),T=(t,e)=>setTimeout(e,t),x={data_type:"json",log:()=>null,timer:!1,url:"localhost",timeout:1400,reconnect:2,lazy:!1,socket:null,adapter:(t,e)=>new WebSocket(t,e),encode:(t,e,{server:n})=>JSON.stringify({[n.id_key]:t,[n.data_key]:e}),decode:t=>JSON.parse(t),protocols:[],pipes:[],server:{id_key:"id",data_key:"data"},ping:{interval:55,content:{}}},D=Symbol("Placeholder"),L=t=>{let e=0;for(const n of t)n!==D&&e++;return e},U=(t,e)=>{const n=t.length,o=t.slice(),s=e.length;let r=s,i=0;for(;r&&i<n;i++)o[i]===D&&(o[i]=e[s-r],r--);for(i=n;r;i++,r--)o[i]=e[s-r];return o},F=(t,e,n)=>{const o=t.length-e.length-L(n);if(o<1)return t(...U(e,n));{const s=(...o)=>F(t,U(e,n),o);return s.$args_left=o,s}},J=t=>(...e)=>t.length>L(e)?F(t,[],e):t(...e);function M(t){return function(e,n){const o=e===D,s=arguments.length;if(1===s&&o)throw new Error("Senseless placeholder usage.");return s>1?o?(t=>function(e){return e===D?t:t(e)})((e=>t(e,n))):t(e,n):n=>t(e,n)}}function G(t){return J(t)}const H=void 0,K=1/0,V=t=>typeof t,X=t=>null===t,Y=t=>"number"==V(t),Z={u:"U",b:"B",n:"N",s:"S",f:"F"},tt=Symbol(),et=t=>{const e=V(t);return"object"===e?X(t)?"Null":t.constructor.name:Z[e[0]]+e.slice(1)},nt=t=>t.length,ot=t=>X(t)||(t=>t===H)(t),st=M(((t,e)=>t===e)),rt=M(((t,e)=>{const n=et(t);if(st(n,et(e))&&(st(n,"Object")||st(n,"Array"))){if(X(t)||X(e))return st(t,e);if(st(t,e))return!0;for(const n of[t,e])for(const o in n)if(!(st(n,e)&&o in t||st(n,t)&&o in e&&rt(t[o],e[o])))return!1;return!0}return st(t,e)})),it=M(((t,e)=>(e.push(t),e))),lt=G(((t,e,n)=>n.reduce(t,e))),ct=M(((t,e)=>{const n=(t=>Array.isArray(t))(e);let o,s;n&&(o=0,s=[]);for(let o in e)t(e[o],o)||(n?s.push(+o):delete e[o]);if(n)for(const t of s)e.splice(t-o++,1);return e})),ut=J(((t,e,n,o)=>t(o)?e(o):n(o))),at=(...t)=>(...e)=>{let n,o=!0;for(let s=nt(t)-1;s>-1;s--)o?(o=!1,n=t[s](...e)):n=n===D?t[s]():t[s](n);return n},ht=M(((t,e)=>e[t])),ft=G(((t,e,n)=>n.slice(t,Y(e)?e:K))),dt=ht(0);ft(1,K);const pt=M(((t,e)=>e.find(t))),gt=t=>()=>t,mt=gt(!0),yt=gt(!1),wt=M(((t,e)=>lt(((e,n)=>pt((e=>t(n,e)),e)?e:it(n,e)),[],e)));wt(rt);const bt=t=>{let e,n=!1;return(...o)=>n?e:(n=!0,e=t(...o))},_t=G(((t,e,n)=>nt(e)?ot(n)?t:at((o=>o in n?_t(t,ft(1,K,e),n[o]):t),dt)(e):n));_t(H),at(ut(rt(tt),yt,mt),_t(tt));const St=new $;class kt{open=!1;ws=null;forcibly_closed=!1;reconnect_timeout=null;queue={};onReadyQueue=[];onCloseQueue=[];handlers={open:[],close:[],message:[],error:[],timeout:[]};config={};init_flush(){ct(yt,this.queue)}call(t,...e){for(const n of this.handlers[t])n(...e)}log(t,e=null,n=null){const o=this.config;null!==n?o.log(t,n,e):o.timer?o.log(t,null,e):o.log(t,e)}initSocket(t){const{queue:e,config:n}=this;this.open=!0,this.ws=t,this.onReadyQueue.forEach((t=>t())),this.onReadyQueue.splice(0);const{id_key:o,data_key:s}=n.server;this.call("open",t);for(const n in e)t.send(e[n].msg);if(null!==this.reconnect_timeout&&(clearInterval(this.reconnect_timeout),this.reconnect_timeout=null),n.ping){const t=setInterval((()=>{this.open&&this.send(n.ping.content),this.forcibly_closed&&clearInterval(t)}),1e3*n.ping.interval)}I(t,"close",(async(...t)=>{this.log("close"),this.open=!1,this.ws=null,this.onCloseQueue.forEach((t=>t())),this.onCloseQueue.splice(0),this.call("close",...t);const e=n.reconnect;if("number"==typeof e&&!isNaN(e)&&!this.forcibly_closed){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})),I(t,"message",(t=>{try{const e=n.decode(t.data);if(this.call("message",{...t,data:e}),e[o]){const t=this.queue[e[o]];if(t){const n=t.sent_time?Date.now()-t.sent_time:null;this.log("message",e[s],n),t.ff(e[s])}}}catch(e){console.error(e,`WSP: Decode error. Got: ${t.data}`)}}))}connect(){return new Promise((t=>{if(!0===this.open)return t(null);const e=this.config,n=e.socket||e.adapter(e.url,e.protocols);if(!n||n.readyState>1)return this.ws=null,this.log("error","ready() on closing or closed state! status 2."),t(2);const o=bt(t);I(n,"error",bt((t=>{this.log("error","status 3. Err: "+t.message),this.call("error",t),this.ws=null,o(3)}))),n.readyState?(this.initSocket(n),o(null)):I(n,"open",bt((()=>{this.log("open"),this.initSocket(n),o(null)})))}))}get socket(){return this.ws}async ready(){return new Promise((t=>{this.open?t():this.onReadyQueue.push(t)}))}on(t,e,n=mt,o=!1){const s=t=>n(t)&&e(t);return o?I(this.ws,t,s):this.handlers[t].push(s),s}off(t,e,n=!1){if(n)return((t,e,n)=>t.removeEventListener(e,n))(this.ws,t,e);const o=this.handlers[t],s=o.indexOf(e);~s&&o.splice(s,1)}async close(){return new Promise(((t,e)=>{null===this.ws?e("WSP: closing a non-inited socket!"):(this.open=!1,this.onCloseQueue.push((()=>{this.init_flush(),this.ws=null,this.forcibly_closed=!0,t(null)})),this.ws.close())}))}async send(t,e={}){this.log("send",t);const{config:n,ws:o,forcibly_closed:s,queue:r}=this,i={},l=n.server.data_key,c=St.zip(2147483637*Math.random()|0);if("object"==typeof e.top){if(e.top[l])throw new Error("Attempting to set data key/token via send() options!");Object.assign(i,e.top)}if(n.pipes.forEach((e=>t=e(t))),s)throw new Error("Attempting to send via closed WebSocket connection!");this.open||this.connect();const u=await n.encode(c,t,n);return 1===o?.readyState&&o.send(u),new Promise(((e,o)=>{this.queue[c]={msg:u,ff(t){e(t),clearTimeout(this.timeout),delete r[c]},data_type:n.data_type,sent_time:n.timer?Date.now():null,timeout:T(n.timeout,(()=>{this.queue[c]&&(this.call("timeout",t),o({"Websocket timeout expired: ":n.timeout,"for the message ":t}),delete r[c])}))}}))}constructor(t={}){this.config=(t=>{if(null===R&&!("adapter"in t))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 e=Object.assign({},x,t),n=e.url;if("/"==n[0])try{const t=location.protocol.includes("s:")?"wss":"ws";e.url=`${t}://${location.hostname}:${location.port}${n}`}catch(t){throw new Error("WSP: URL starting with / in non-browser environment!")}return e})(t),this.init_flush(),this.config.lazy||this.connect()}}export{kt as default};
|
package/package.json
CHANGED
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"prod": "npm run gentypes && npm run prod:es && npm run prod:cjs",
|
|
42
42
|
"all": "npm run dev && npm run prod"
|
|
43
43
|
},
|
|
44
|
-
"version": "2.6.
|
|
44
|
+
"version": "2.6.4",
|
|
45
45
|
"type": "module",
|
|
46
46
|
"exports": {
|
|
47
47
|
".": {
|
|
@@ -57,19 +57,19 @@
|
|
|
57
57
|
"@rollup/plugin-replace": "^6.0.2",
|
|
58
58
|
"@rollup/plugin-terser": "^0.4.4",
|
|
59
59
|
"@types/express": "^5.0.1",
|
|
60
|
-
"@types/node": "^22.15.
|
|
60
|
+
"@types/node": "^22.15.17",
|
|
61
61
|
"@types/ws": "^8.18.1",
|
|
62
62
|
"codecov": "^3.8.3",
|
|
63
63
|
"cross-env": "^7.0.3",
|
|
64
64
|
"dts-bundle-generator": "^9.5.1",
|
|
65
65
|
"nyc": "^17.1.0",
|
|
66
|
-
"rollup": "^4.40.
|
|
66
|
+
"rollup": "^4.40.2",
|
|
67
67
|
"rollup-plugin-typescript2": "^0.36.0",
|
|
68
68
|
"ts-node": "^10.9.2",
|
|
69
|
-
"tsx": "^4.19.
|
|
69
|
+
"tsx": "^4.19.4",
|
|
70
70
|
"typescript": "^5.8.3",
|
|
71
71
|
"uvu": "^0.5.6",
|
|
72
|
-
"ws": "^8.18.
|
|
72
|
+
"ws": "^8.18.2"
|
|
73
73
|
},
|
|
74
74
|
"types": "./dist/bundle.d.ts",
|
|
75
75
|
"dependencies": {
|
package/src/WSC.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import './types'
|
|
2
2
|
import { Zipnum } from 'zipnum'
|
|
3
|
-
import { add_event, sett } from './utils'
|
|
3
|
+
import { add_event, rm_event, sett } from './utils'
|
|
4
4
|
import { processConfig } from './config'
|
|
5
5
|
import { AnyFunc, F, once, qfilter, T } from 'pepka'
|
|
6
6
|
|
|
@@ -52,6 +52,7 @@ class WebSocketClient {
|
|
|
52
52
|
private initSocket(ws: wsc.Socket) {
|
|
53
53
|
const {queue, config} = this
|
|
54
54
|
this.open = true
|
|
55
|
+
this.ws = ws
|
|
55
56
|
this.onReadyQueue.forEach((fn: Function) => fn())
|
|
56
57
|
this.onReadyQueue.splice(0)
|
|
57
58
|
const {id_key, data_key} = config.server
|
|
@@ -126,7 +127,6 @@ class WebSocketClient {
|
|
|
126
127
|
}
|
|
127
128
|
const config = this.config
|
|
128
129
|
const ws = config.socket || config.adapter(config.url, config.protocols)
|
|
129
|
-
this.ws = ws
|
|
130
130
|
if(!ws || ws.readyState > 1) {
|
|
131
131
|
this.ws = null
|
|
132
132
|
this.log('error', 'ready() on closing or closed state! status 2.')
|
|
@@ -168,9 +168,19 @@ class WebSocketClient {
|
|
|
168
168
|
) {
|
|
169
169
|
const _handler: wsc.EventHandler = (event) =>
|
|
170
170
|
predicate(event) && handler(event)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
171
|
+
if(raw) add_event(this.ws as wsc.Socket, event_name, _handler)
|
|
172
|
+
else this.handlers[event_name].push(_handler)
|
|
173
|
+
return _handler
|
|
174
|
+
}
|
|
175
|
+
public off(
|
|
176
|
+
event_name: wsc.WSEvent,
|
|
177
|
+
handler: (data: any) => any,
|
|
178
|
+
raw = false
|
|
179
|
+
) {
|
|
180
|
+
if(raw) return rm_event(this.ws as wsc.Socket, event_name, handler)
|
|
181
|
+
const handlers = this.handlers[event_name]
|
|
182
|
+
const i = handlers.indexOf(handler)
|
|
183
|
+
if(~i) handlers.splice(i, 1)
|
|
174
184
|
}
|
|
175
185
|
|
|
176
186
|
public async close(): wsc.AsyncErrCode {
|
package/src/types.ts
CHANGED
|
@@ -11,7 +11,8 @@ declare namespace wsc {
|
|
|
11
11
|
readyState: number
|
|
12
12
|
send(...any: any[]): void
|
|
13
13
|
close(): void
|
|
14
|
-
addEventListener
|
|
14
|
+
addEventListener: WebSocket["addEventListener"]
|
|
15
|
+
removeEventListener: WebSocket["removeEventListener"]
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export type AsyncErrCode = Promise<number | null | {}>
|
package/src/utils.ts
CHANGED
|
@@ -5,6 +5,9 @@ export const native_ws = (() => {try {return WebSocket||null}catch { return null
|
|
|
5
5
|
export const add_event = (o: wsc.Socket, e: string, handler: wsc.EventHandler) => {
|
|
6
6
|
return o.addEventListener(e, handler)
|
|
7
7
|
}
|
|
8
|
+
export const rm_event = (o: wsc.Socket, e: string, handler: wsc.EventHandler) => {
|
|
9
|
+
return o.removeEventListener(e, handler)
|
|
10
|
+
}
|
|
8
11
|
|
|
9
12
|
export const sett = (
|
|
10
13
|
a: number,
|
package/test/index.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import './specs/close'
|
|
2
2
|
import './specs/drops'
|
|
3
3
|
import './specs/echo'
|
|
4
|
-
import './specs/
|
|
4
|
+
import './specs/existing-socket'
|
|
5
5
|
import './specs/lazy'
|
|
6
6
|
import './specs/ready'
|
|
7
7
|
import './specs/reconnect'
|
|
8
|
-
import './specs/
|
|
8
|
+
import './specs/lazy-send-before-open'
|
|
9
9
|
import './specs/socket'
|
|
10
10
|
import './specs/no-native-throws'
|
|
11
11
|
import mockServer from './mock/server'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createNew } from '../utils.js'
|
|
2
|
-
import mockServer from '../mock/server'
|
|
2
|
+
import mockServer from '../mock/server.js'
|
|
3
3
|
import { equals } from 'pepka'
|
|
4
|
-
import { test } from '../suite'
|
|
4
|
+
import { test } from '../suite.js'
|
|
5
5
|
|
|
6
6
|
/** Sends massages if they were .send() before connection is estabilished. */
|
|
7
7
|
test('lazy send before open queued.', () => new Promise(async (ff, rj) => {
|
|
File without changes
|