mitmi 1.0.0 → 1.1.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.
@@ -1,15 +1,21 @@
1
+ import { Contact } from "./Contact";
2
+ import { Session } from "./Session";
1
3
  import { Stream } from "./Stream";
2
4
  declare class Conference extends EventTarget {
3
5
  name: string;
4
6
  id: number;
5
7
  knownStreams: Array<Stream | void>;
6
- constructor(name: string);
8
+ knownContact: Array<Contact | void>;
9
+ session: Session;
10
+ constructor(name: string, session: Session);
7
11
  private setupListener;
8
12
  publish(stream: Stream): void;
13
+ unpublish(stream: Stream): void;
9
14
  join(): void;
10
15
  leave(): void;
11
16
  getMembers(): void;
12
17
  private newStream;
13
18
  private peopleLeave;
19
+ private newPeople;
14
20
  }
15
21
  export { Conference };
@@ -0,0 +1,8 @@
1
+ import { ContactInfo } from "./utils";
2
+ declare class Contact {
3
+ id: string;
4
+ name: string;
5
+ constructor(id: string, name: string);
6
+ toString(): ContactInfo;
7
+ }
8
+ export { Contact };
@@ -0,0 +1,12 @@
1
+ import { Contact } from "./Contact";
2
+ import { SocketInteraction } from "./core/SocketInteraction";
3
+ declare class Session {
4
+ name: string;
5
+ socketInteraction: SocketInteraction;
6
+ contact?: Contact;
7
+ private static session;
8
+ private static initializing?;
9
+ private constructor();
10
+ static create(name: string): Promise<Session>;
11
+ }
12
+ export { Session };
package/dist/Stream.d.ts CHANGED
@@ -1,19 +1,42 @@
1
+ import { Conference } from "./Conference";
2
+ export interface StreamParams {
3
+ audio: boolean;
4
+ video: boolean;
5
+ }
1
6
  declare class Stream {
2
7
  mediastream: MediaStream;
3
8
  domElement: undefined | HTMLVideoElement;
4
- owner: string;
9
+ ownerId: string;
10
+ ownerName: string;
5
11
  id: String;
12
+ conferencePublish?: Conference;
13
+ params: StreamParams;
6
14
  /**
7
15
  *
8
16
  * @param mediastream
9
17
  * @param owner "" => ourself, id instead
10
18
  */
11
- constructor(mediastream: MediaStream, owner: string);
19
+ constructor(mediastream: MediaStream, ownerId: string, ownerName: string);
20
+ isLocal(): boolean;
12
21
  static getCamera(video: boolean, audio: boolean): Promise<Stream>;
13
22
  static getScreen(): void;
14
23
  attachToElement(domElement: HTMLVideoElement): void;
15
24
  detachToElement(): void;
25
+ /**
26
+ * If the stream is published (so its yours) :
27
+ * - video will be disabled for everyone
28
+ * If the stream is not published (its yours but not publish, or other ppl stream):
29
+ * - video will be disabled for you only
30
+ */
31
+ muteVideo(): void;
32
+ unmuteVideo(): void;
16
33
  muteAudio(): void;
17
34
  unmuteAudio(): void;
35
+ /**
36
+ * This function exist to avoir Larsen.
37
+ * You need to call here when a localstream is started.
38
+ */
39
+ disableAudio(): void;
40
+ private setListeners;
18
41
  }
19
42
  export { Stream };
@@ -3,11 +3,22 @@ export declare class SocketInteraction extends EventTarget {
3
3
  private socket;
4
4
  private _userId?;
5
5
  private _confId?;
6
- private publishStream?;
6
+ private localStream?;
7
+ private senders;
7
8
  private peerConnections;
8
- init(): Promise<void>;
9
+ init(): Promise<string>;
9
10
  get userId(): string;
10
11
  publish(stream: Stream): void;
12
+ unpublish(stream: Stream): void;
13
+ /**
14
+ *
15
+ * @param stream Stream have stream.params, use to set constraint on the peer
16
+ */
17
+ setConstraint(stream: Stream): void;
18
+ private attachStreamToPeer;
19
+ private removeStreamToPeer;
20
+ private disableTrackToPeer;
21
+ private enableTrackToPeer;
11
22
  register(confId: number): void;
12
23
  unregister(): void;
13
24
  private setupSocketListeners;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export { Contact } from "./Contact";
2
+ export { Session } from "./Session";
1
3
  export { HelloWorld } from "./HelloWorld";
2
4
  export { Stream } from "./Stream";
3
5
  export { Conference } from "./Conference";
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- var t={d:(e,s)=>{for(var n in s)t.o(s,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:s[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{Decoder:()=>gt,Encoder:()=>ft,PacketType:()=>lt,protocol:()=>dt});class s{printHello(){console.log("Hello from my-ts-package!")}}class n{constructor(t,e){this.mediastream=t,this.owner=e,this.id=e+"_usermedia"}static getCamera(t,e){return s=this,i=void 0,o=function*(){let s=yield navigator.mediaDevices.getUserMedia({video:t,audio:e});return new n(s,"")},new((r=void 0)||(r=Promise))(function(t,e){function n(t){try{c(o.next(t))}catch(t){e(t)}}function a(t){try{c(o.throw(t))}catch(t){e(t)}}function c(e){e.done?t(e.value):function(t){return t instanceof r?t:new r(function(e){e(t)})}(e.value).then(n,a)}c((o=o.apply(s,i||[])).next())});var s,i,r,o}static getScreen(){}attachToElement(t){this.domElement=t,t.srcObject=this.mediastream}detachToElement(){this.domElement&&(this.domElement.srcObject=null)}muteAudio(){this.mediastream.getAudioTracks()[0].enabled=!1}unmuteAudio(){this.mediastream.getAudioTracks()[0].enabled=!0}}const i=Object.create(null);i.open="0",i.close="1",i.ping="2",i.pong="3",i.message="4",i.upgrade="5",i.noop="6";const r=Object.create(null);Object.keys(i).forEach(t=>{r[i[t]]=t});const o={type:"error",data:"parser error"},a="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===Object.prototype.toString.call(Blob),c="function"==typeof ArrayBuffer,h=t=>"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t&&t.buffer instanceof ArrayBuffer,u=({type:t,data:e},s,n)=>a&&e instanceof Blob?s?n(e):p(e,n):c&&(e instanceof ArrayBuffer||h(e))?s?n(e):p(new Blob([e]),n):n(i[t]+(e||"")),p=(t,e)=>{const s=new FileReader;return s.onload=function(){const t=s.result.split(",")[1];e("b"+(t||""))},s.readAsDataURL(t)};function d(t){return t instanceof Uint8Array?t:t instanceof ArrayBuffer?new Uint8Array(t):new Uint8Array(t.buffer,t.byteOffset,t.byteLength)}let l;const f="undefined"==typeof Uint8Array?[]:new Uint8Array(256);for(let t=0;t<64;t++)f["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charCodeAt(t)]=t;const y="function"==typeof ArrayBuffer,g=(t,e)=>{if("string"!=typeof t)return{type:"message",data:_(t,e)};const s=t.charAt(0);return"b"===s?{type:"message",data:m(t.substring(1),e)}:r[s]?t.length>1?{type:r[s],data:t.substring(1)}:{type:r[s]}:o},m=(t,e)=>{if(y){const s=(t=>{let e,s,n,i,r,o=.75*t.length,a=t.length,c=0;"="===t[t.length-1]&&(o--,"="===t[t.length-2]&&o--);const h=new ArrayBuffer(o),u=new Uint8Array(h);for(e=0;e<a;e+=4)s=f[t.charCodeAt(e)],n=f[t.charCodeAt(e+1)],i=f[t.charCodeAt(e+2)],r=f[t.charCodeAt(e+3)],u[c++]=s<<2|n>>4,u[c++]=(15&n)<<4|i>>2,u[c++]=(3&i)<<6|63&r;return h})(t);return _(s,e)}return{base64:!0,data:t}},_=(t,e)=>"blob"===e?t instanceof Blob?t:new Blob([t]):t instanceof ArrayBuffer?t:t.buffer,b=String.fromCharCode(30);let v;function w(t){return t.reduce((t,e)=>t+e.length,0)}function k(t,e){if(t[0].length===e)return t.shift();const s=new Uint8Array(e);let n=0;for(let i=0;i<e;i++)s[i]=t[0][n++],n===t[0].length&&(t.shift(),n=0);return t.length&&n<t[0].length&&(t[0]=t[0].slice(n)),s}function E(t){if(t)return function(t){for(var e in E.prototype)t[e]=E.prototype[e];return t}(t)}E.prototype.on=E.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},E.prototype.once=function(t,e){function s(){this.off(t,s),e.apply(this,arguments)}return s.fn=e,this.on(t,s),this},E.prototype.off=E.prototype.removeListener=E.prototype.removeAllListeners=E.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var s,n=this._callbacks["$"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var i=0;i<n.length;i++)if((s=n[i])===e||s.fn===e){n.splice(i,1);break}return 0===n.length&&delete this._callbacks["$"+t],this},E.prototype.emit=function(t){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),s=this._callbacks["$"+t],n=1;n<arguments.length;n++)e[n-1]=arguments[n];if(s){n=0;for(var i=(s=s.slice(0)).length;n<i;++n)s[n].apply(this,e)}return this},E.prototype.emitReserved=E.prototype.emit,E.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks["$"+t]||[]},E.prototype.hasListeners=function(t){return!!this.listeners(t).length};const C="function"==typeof Promise&&"function"==typeof Promise.resolve?t=>Promise.resolve().then(t):(t,e)=>e(t,0),T="undefined"!=typeof self?self:"undefined"!=typeof window?window:Function("return this")();function A(t,...e){return e.reduce((e,s)=>(t.hasOwnProperty(s)&&(e[s]=t[s]),e),{})}const O=T.setTimeout,R=T.clearTimeout;function S(t,e){e.useNativeTimers?(t.setTimeoutFn=O.bind(T),t.clearTimeoutFn=R.bind(T)):(t.setTimeoutFn=T.setTimeout.bind(T),t.clearTimeoutFn=T.clearTimeout.bind(T))}function B(t){return"string"==typeof t?function(t){let e=0,s=0;for(let n=0,i=t.length;n<i;n++)e=t.charCodeAt(n),e<128?s+=1:e<2048?s+=2:e<55296||e>=57344?s+=3:(n++,s+=4);return s}(t):Math.ceil(1.33*(t.byteLength||t.size))}function x(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}class L extends Error{constructor(t,e,s){super(t),this.description=e,this.context=s,this.type="TransportError"}}class N extends E{constructor(t){super(),this.writable=!1,S(this,t),this.opts=t,this.query=t.query,this.socket=t.socket,this.supportsBinary=!t.forceBase64}onError(t,e,s){return super.emitReserved("error",new L(t,e,s)),this}open(){return this.readyState="opening",this.doOpen(),this}close(){return"opening"!==this.readyState&&"open"!==this.readyState||(this.doClose(),this.onClose()),this}send(t){"open"===this.readyState&&this.write(t)}onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("open")}onData(t){const e=g(t,this.socket.binaryType);this.onPacket(e)}onPacket(t){super.emitReserved("packet",t)}onClose(t){this.readyState="closed",super.emitReserved("close",t)}pause(t){}createUri(t,e={}){return t+"://"+this._hostname()+this._port()+this.opts.path+this._query(e)}_hostname(){const t=this.opts.hostname;return-1===t.indexOf(":")?t:"["+t+"]"}_port(){return this.opts.port&&(this.opts.secure&&Number(443!==this.opts.port)||!this.opts.secure&&80!==Number(this.opts.port))?":"+this.opts.port:""}_query(t){const e=function(t){let e="";for(let s in t)t.hasOwnProperty(s)&&(e.length&&(e+="&"),e+=encodeURIComponent(s)+"="+encodeURIComponent(t[s]));return e}(t);return e.length?"?"+e:""}}class P extends N{constructor(){super(...arguments),this._polling=!1}get name(){return"polling"}doOpen(){this._poll()}pause(t){this.readyState="pausing";const e=()=>{this.readyState="paused",t()};if(this._polling||!this.writable){let t=0;this._polling&&(t++,this.once("pollComplete",function(){--t||e()})),this.writable||(t++,this.once("drain",function(){--t||e()}))}else e()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved("poll")}onData(t){((t,e)=>{const s=t.split(b),n=[];for(let t=0;t<s.length;t++){const i=g(s[t],e);if(n.push(i),"error"===i.type)break}return n})(t,this.socket.binaryType).forEach(t=>{if("opening"===this.readyState&&"open"===t.type&&this.onOpen(),"close"===t.type)return this.onClose({description:"transport closed by the server"}),!1;this.onPacket(t)}),"closed"!==this.readyState&&(this._polling=!1,this.emitReserved("pollComplete"),"open"===this.readyState&&this._poll())}doClose(){const t=()=>{this.write([{type:"close"}])};"open"===this.readyState?t():this.once("open",t)}write(t){this.writable=!1,((t,e)=>{const s=t.length,n=new Array(s);let i=0;t.forEach((t,r)=>{u(t,!1,t=>{n[r]=t,++i===s&&e(n.join(b))})})})(t,t=>{this.doWrite(t,()=>{this.writable=!0,this.emitReserved("drain")})})}uri(){const t=this.opts.secure?"https":"http",e=this.query||{};return!1!==this.opts.timestampRequests&&(e[this.opts.timestampParam]=x()),this.supportsBinary||e.sid||(e.b64=1),this.createUri(t,e)}}let q=!1;try{q="undefined"!=typeof XMLHttpRequest&&"withCredentials"in new XMLHttpRequest}catch(t){}const j=q;function I(){}class D extends P{constructor(t){if(super(t),"undefined"!=typeof location){const e="https:"===location.protocol;let s=location.port;s||(s=e?"443":"80"),this.xd="undefined"!=typeof location&&t.hostname!==location.hostname||s!==t.port}}doWrite(t,e){const s=this.request({method:"POST",data:t});s.on("success",e),s.on("error",(t,e)=>{this.onError("xhr post error",t,e)})}doPoll(){const t=this.request();t.on("data",this.onData.bind(this)),t.on("error",(t,e)=>{this.onError("xhr poll error",t,e)}),this.pollXhr=t}}class U extends E{constructor(t,e,s){super(),this.createRequest=t,S(this,s),this._opts=s,this._method=s.method||"GET",this._uri=e,this._data=void 0!==s.data?s.data:null,this._create()}_create(){var t;const e=A(this._opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");e.xdomain=!!this._opts.xd;const s=this._xhr=this.createRequest(e);try{s.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){s.setDisableHeaderCheck&&s.setDisableHeaderCheck(!0);for(let t in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(t)&&s.setRequestHeader(t,this._opts.extraHeaders[t])}}catch(t){}if("POST"===this._method)try{s.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch(t){}try{s.setRequestHeader("Accept","*/*")}catch(t){}null===(t=this._opts.cookieJar)||void 0===t||t.addCookies(s),"withCredentials"in s&&(s.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(s.timeout=this._opts.requestTimeout),s.onreadystatechange=()=>{var t;3===s.readyState&&(null===(t=this._opts.cookieJar)||void 0===t||t.parseCookies(s.getResponseHeader("set-cookie"))),4===s.readyState&&(200===s.status||1223===s.status?this._onLoad():this.setTimeoutFn(()=>{this._onError("number"==typeof s.status?s.status:0)},0))},s.send(this._data)}catch(t){return void this.setTimeoutFn(()=>{this._onError(t)},0)}"undefined"!=typeof document&&(this._index=U.requestsCount++,U.requests[this._index]=this)}_onError(t){this.emitReserved("error",t,this._xhr),this._cleanup(!0)}_cleanup(t){if(void 0!==this._xhr&&null!==this._xhr){if(this._xhr.onreadystatechange=I,t)try{this._xhr.abort()}catch(t){}"undefined"!=typeof document&&delete U.requests[this._index],this._xhr=null}}_onLoad(){const t=this._xhr.responseText;null!==t&&(this.emitReserved("data",t),this.emitReserved("success"),this._cleanup())}abort(){this._cleanup()}}function M(){for(let t in U.requests)U.requests.hasOwnProperty(t)&&U.requests[t].abort()}U.requestsCount=0,U.requests={},"undefined"!=typeof document&&("function"==typeof attachEvent?attachEvent("onunload",M):"function"==typeof addEventListener&&addEventListener("onpagehide"in T?"pagehide":"unload",M,!1));const F=function(){const t=V({xdomain:!1});return t&&null!==t.responseType}();function V(t){const e=t.xdomain;try{if("undefined"!=typeof XMLHttpRequest&&(!e||j))return new XMLHttpRequest}catch(t){}if(!e)try{return new(T[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(t){}}const H="undefined"!=typeof navigator&&"string"==typeof navigator.product&&"reactnative"===navigator.product.toLowerCase();class K extends N{get name(){return"websocket"}doOpen(){const t=this.uri(),e=this.opts.protocols,s=H?{}:A(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(s.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(t,e,s)}catch(t){return this.emitReserved("error",t)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=t=>this.onClose({description:"websocket connection closed",context:t}),this.ws.onmessage=t=>this.onData(t.data),this.ws.onerror=t=>this.onError("websocket error",t)}write(t){this.writable=!1;for(let e=0;e<t.length;e++){const s=t[e],n=e===t.length-1;u(s,this.supportsBinary,t=>{try{this.doWrite(s,t)}catch(t){}n&&C(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){void 0!==this.ws&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){const t=this.opts.secure?"wss":"ws",e=this.query||{};return this.opts.timestampRequests&&(e[this.opts.timestampParam]=x()),this.supportsBinary||(e.b64=1),this.createUri(t,e)}}const $=T.WebSocket||T.MozWebSocket,W={websocket:class extends K{createSocket(t,e,s){return H?new $(t,e,s):e?new $(t,e):new $(t)}doWrite(t,e){this.ws.send(e)}},webtransport:class extends N{get name(){return"webtransport"}doOpen(){try{this._transport=new WebTransport(this.createUri("https"),this.opts.transportOptions[this.name])}catch(t){return this.emitReserved("error",t)}this._transport.closed.then(()=>{this.onClose()}).catch(t=>{this.onError("webtransport error",t)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(t=>{const e=function(t,e){v||(v=new TextDecoder);const s=[];let n=0,i=-1,r=!1;return new TransformStream({transform(a,c){for(s.push(a);;){if(0===n){if(w(s)<1)break;const t=k(s,1);r=!(128&~t[0]),i=127&t[0],n=i<126?3:126===i?1:2}else if(1===n){if(w(s)<2)break;const t=k(s,2);i=new DataView(t.buffer,t.byteOffset,t.length).getUint16(0),n=3}else if(2===n){if(w(s)<8)break;const t=k(s,8),e=new DataView(t.buffer,t.byteOffset,t.length),r=e.getUint32(0);if(r>Math.pow(2,21)-1){c.enqueue(o);break}i=r*Math.pow(2,32)+e.getUint32(4),n=3}else{if(w(s)<i)break;const t=k(s,i);c.enqueue(g(r?t:v.decode(t),e)),n=0}if(0===i||i>t){c.enqueue(o);break}}}})}(Number.MAX_SAFE_INTEGER,this.socket.binaryType),s=t.readable.pipeThrough(e).getReader(),n=new TransformStream({transform(t,e){!function(t,e){a&&t.data instanceof Blob?t.data.arrayBuffer().then(d).then(e):c&&(t.data instanceof ArrayBuffer||h(t.data))?e(d(t.data)):u(t,!1,t=>{l||(l=new TextEncoder),e(l.encode(t))})}(t,s=>{const n=s.length;let i;if(n<126)i=new Uint8Array(1),new DataView(i.buffer).setUint8(0,n);else if(n<65536){i=new Uint8Array(3);const t=new DataView(i.buffer);t.setUint8(0,126),t.setUint16(1,n)}else{i=new Uint8Array(9);const t=new DataView(i.buffer);t.setUint8(0,127),t.setBigUint64(1,BigInt(n))}t.data&&"string"!=typeof t.data&&(i[0]|=128),e.enqueue(i),e.enqueue(s)})}});n.readable.pipeTo(t.writable),this._writer=n.writable.getWriter();const i=()=>{s.read().then(({done:t,value:e})=>{t||(this.onPacket(e),i())}).catch(t=>{})};i();const r={type:"open"};this.query.sid&&(r.data=`{"sid":"${this.query.sid}"}`),this._writer.write(r).then(()=>this.onOpen())})})}write(t){this.writable=!1;for(let e=0;e<t.length;e++){const s=t[e],n=e===t.length-1;this._writer.write(s).then(()=>{n&&C(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var t;null===(t=this._transport)||void 0===t||t.close()}},polling:class extends D{constructor(t){super(t);const e=t&&t.forceBase64;this.supportsBinary=F&&!e}request(t={}){return Object.assign(t,{xd:this.xd},this.opts),new U(V,this.uri(),t)}}},Y=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,z=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function J(t){if(t.length>8e3)throw"URI too long";const e=t,s=t.indexOf("["),n=t.indexOf("]");-1!=s&&-1!=n&&(t=t.substring(0,s)+t.substring(s,n).replace(/:/g,";")+t.substring(n,t.length));let i=Y.exec(t||""),r={},o=14;for(;o--;)r[z[o]]=i[o]||"";return-1!=s&&-1!=n&&(r.source=e,r.host=r.host.substring(1,r.host.length-1).replace(/;/g,":"),r.authority=r.authority.replace("[","").replace("]","").replace(/;/g,":"),r.ipv6uri=!0),r.pathNames=function(t,e){const s=e.replace(/\/{2,9}/g,"/").split("/");return"/"!=e.slice(0,1)&&0!==e.length||s.splice(0,1),"/"==e.slice(-1)&&s.splice(s.length-1,1),s}(0,r.path),r.queryKey=function(t,e){const s={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(t,e,n){e&&(s[e]=n)}),s}(0,r.query),r}const Q="function"==typeof addEventListener&&"function"==typeof removeEventListener,X=[];Q&&addEventListener("offline",()=>{X.forEach(t=>t())},!1);class G extends E{constructor(t,e){if(super(),this.binaryType="arraybuffer",this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,t&&"object"==typeof t&&(e=t,t=null),t){const s=J(t);e.hostname=s.host,e.secure="https"===s.protocol||"wss"===s.protocol,e.port=s.port,s.query&&(e.query=s.query)}else e.host&&(e.hostname=J(e.host).host);S(this,e),this.secure=null!=e.secure?e.secure:"undefined"!=typeof location&&"https:"===location.protocol,e.hostname&&!e.port&&(e.port=this.secure?"443":"80"),this.hostname=e.hostname||("undefined"!=typeof location?location.hostname:"localhost"),this.port=e.port||("undefined"!=typeof location&&location.port?location.port:this.secure?"443":"80"),this.transports=[],this._transportsByName={},e.transports.forEach(t=>{const e=t.prototype.name;this.transports.push(e),this._transportsByName[e]=t}),this.opts=Object.assign({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},e),this.opts.path=this.opts.path.replace(/\/$/,"")+(this.opts.addTrailingSlash?"/":""),"string"==typeof this.opts.query&&(this.opts.query=function(t){let e={},s=t.split("&");for(let t=0,n=s.length;t<n;t++){let n=s[t].split("=");e[decodeURIComponent(n[0])]=decodeURIComponent(n[1])}return e}(this.opts.query)),Q&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener("beforeunload",this._beforeunloadEventListener,!1)),"localhost"!==this.hostname&&(this._offlineEventListener=()=>{this._onClose("transport close",{description:"network connection lost"})},X.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(t){const e=Object.assign({},this.opts.query);e.EIO=4,e.transport=t,this.id&&(e.sid=this.id);const s=Object.assign({},this.opts,{query:e,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[t]);return new this._transportsByName[t](s)}_open(){if(0===this.transports.length)return void this.setTimeoutFn(()=>{this.emitReserved("error","No transports available")},0);const t=this.opts.rememberUpgrade&&G.priorWebsocketSuccess&&-1!==this.transports.indexOf("websocket")?"websocket":this.transports[0];this.readyState="opening";const e=this.createTransport(t);e.open(),this.setTransport(e)}setTransport(t){this.transport&&this.transport.removeAllListeners(),this.transport=t,t.on("drain",this._onDrain.bind(this)).on("packet",this._onPacket.bind(this)).on("error",this._onError.bind(this)).on("close",t=>this._onClose("transport close",t))}onOpen(){this.readyState="open",G.priorWebsocketSuccess="websocket"===this.transport.name,this.emitReserved("open"),this.flush()}_onPacket(t){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState)switch(this.emitReserved("packet",t),this.emitReserved("heartbeat"),t.type){case"open":this.onHandshake(JSON.parse(t.data));break;case"ping":this._sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong"),this._resetPingTimeout();break;case"error":const e=new Error("server error");e.code=t.data,this._onError(e);break;case"message":this.emitReserved("data",t.data),this.emitReserved("message",t.data)}}onHandshake(t){this.emitReserved("handshake",t),this.id=t.sid,this.transport.query.sid=t.sid,this._pingInterval=t.pingInterval,this._pingTimeout=t.pingTimeout,this._maxPayload=t.maxPayload,this.onOpen(),"closed"!==this.readyState&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);const t=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+t,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose("ping timeout")},t),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,0===this.writeBuffer.length?this.emitReserved("drain"):this.flush()}flush(){if("closed"!==this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){const t=this._getWritablePackets();this.transport.send(t),this._prevBufferLen=t.length,this.emitReserved("flush")}}_getWritablePackets(){if(!(this._maxPayload&&"polling"===this.transport.name&&this.writeBuffer.length>1))return this.writeBuffer;let t=1;for(let e=0;e<this.writeBuffer.length;e++){const s=this.writeBuffer[e].data;if(s&&(t+=B(s)),e>0&&t>this._maxPayload)return this.writeBuffer.slice(0,e);t+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;const t=Date.now()>this._pingTimeoutTime;return t&&(this._pingTimeoutTime=0,C(()=>{this._onClose("ping timeout")},this.setTimeoutFn)),t}write(t,e,s){return this._sendPacket("message",t,e,s),this}send(t,e,s){return this._sendPacket("message",t,e,s),this}_sendPacket(t,e,s,n){if("function"==typeof e&&(n=e,e=void 0),"function"==typeof s&&(n=s,s=null),"closing"===this.readyState||"closed"===this.readyState)return;(s=s||{}).compress=!1!==s.compress;const i={type:t,data:e,options:s};this.emitReserved("packetCreate",i),this.writeBuffer.push(i),n&&this.once("flush",n),this.flush()}close(){const t=()=>{this._onClose("forced close"),this.transport.close()},e=()=>{this.off("upgrade",e),this.off("upgradeError",e),t()},s=()=>{this.once("upgrade",e),this.once("upgradeError",e)};return"opening"!==this.readyState&&"open"!==this.readyState||(this.readyState="closing",this.writeBuffer.length?this.once("drain",()=>{this.upgrading?s():t()}):this.upgrading?s():t()),this}_onError(t){if(G.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&"opening"===this.readyState)return this.transports.shift(),this._open();this.emitReserved("error",t),this._onClose("transport error",t)}_onClose(t,e){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),Q&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){const t=X.indexOf(this._offlineEventListener);-1!==t&&X.splice(t,1)}this.readyState="closed",this.id=null,this.emitReserved("close",t,e),this.writeBuffer=[],this._prevBufferLen=0}}}G.protocol=4;class Z extends G{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),"open"===this.readyState&&this.opts.upgrade)for(let t=0;t<this._upgrades.length;t++)this._probe(this._upgrades[t])}_probe(t){let e=this.createTransport(t),s=!1;G.priorWebsocketSuccess=!1;const n=()=>{s||(e.send([{type:"ping",data:"probe"}]),e.once("packet",t=>{if(!s)if("pong"===t.type&&"probe"===t.data){if(this.upgrading=!0,this.emitReserved("upgrading",e),!e)return;G.priorWebsocketSuccess="websocket"===e.name,this.transport.pause(()=>{s||"closed"!==this.readyState&&(h(),this.setTransport(e),e.send([{type:"upgrade"}]),this.emitReserved("upgrade",e),e=null,this.upgrading=!1,this.flush())})}else{const t=new Error("probe error");t.transport=e.name,this.emitReserved("upgradeError",t)}}))};function i(){s||(s=!0,h(),e.close(),e=null)}const r=t=>{const s=new Error("probe error: "+t);s.transport=e.name,i(),this.emitReserved("upgradeError",s)};function o(){r("transport closed")}function a(){r("socket closed")}function c(t){e&&t.name!==e.name&&i()}const h=()=>{e.removeListener("open",n),e.removeListener("error",r),e.removeListener("close",o),this.off("close",a),this.off("upgrading",c)};e.once("open",n),e.once("error",r),e.once("close",o),this.once("close",a),this.once("upgrading",c),-1!==this._upgrades.indexOf("webtransport")&&"webtransport"!==t?this.setTimeoutFn(()=>{s||e.open()},200):e.open()}onHandshake(t){this._upgrades=this._filterUpgrades(t.upgrades),super.onHandshake(t)}_filterUpgrades(t){const e=[];for(let s=0;s<t.length;s++)~this.transports.indexOf(t[s])&&e.push(t[s]);return e}}class tt extends Z{constructor(t,e={}){const s="object"==typeof t?t:e;(!s.transports||s.transports&&"string"==typeof s.transports[0])&&(s.transports=(s.transports||["polling","websocket","webtransport"]).map(t=>W[t]).filter(t=>!!t)),super(t,s)}}const et="function"==typeof ArrayBuffer,st=Object.prototype.toString,nt="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===st.call(Blob),it="function"==typeof File||"undefined"!=typeof File&&"[object FileConstructor]"===st.call(File);function rt(t){return et&&(t instanceof ArrayBuffer||(t=>"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t.buffer instanceof ArrayBuffer)(t))||nt&&t instanceof Blob||it&&t instanceof File}function ot(t,e){if(!t||"object"!=typeof t)return!1;if(Array.isArray(t)){for(let e=0,s=t.length;e<s;e++)if(ot(t[e]))return!0;return!1}if(rt(t))return!0;if(t.toJSON&&"function"==typeof t.toJSON&&1===arguments.length)return ot(t.toJSON(),!0);for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)&&ot(t[e]))return!0;return!1}function at(t){const e=[],s=t.data,n=t;return n.data=ct(s,e),n.attachments=e.length,{packet:n,buffers:e}}function ct(t,e){if(!t)return t;if(rt(t)){const s={_placeholder:!0,num:e.length};return e.push(t),s}if(Array.isArray(t)){const s=new Array(t.length);for(let n=0;n<t.length;n++)s[n]=ct(t[n],e);return s}if("object"==typeof t&&!(t instanceof Date)){const s={};for(const n in t)Object.prototype.hasOwnProperty.call(t,n)&&(s[n]=ct(t[n],e));return s}return t}function ht(t,e){return t.data=ut(t.data,e),delete t.attachments,t}function ut(t,e){if(!t)return t;if(t&&!0===t._placeholder){if("number"==typeof t.num&&t.num>=0&&t.num<e.length)return e[t.num];throw new Error("illegal attachments")}if(Array.isArray(t))for(let s=0;s<t.length;s++)t[s]=ut(t[s],e);else if("object"==typeof t)for(const s in t)Object.prototype.hasOwnProperty.call(t,s)&&(t[s]=ut(t[s],e));return t}const pt=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"],dt=5;var lt;!function(t){t[t.CONNECT=0]="CONNECT",t[t.DISCONNECT=1]="DISCONNECT",t[t.EVENT=2]="EVENT",t[t.ACK=3]="ACK",t[t.CONNECT_ERROR=4]="CONNECT_ERROR",t[t.BINARY_EVENT=5]="BINARY_EVENT",t[t.BINARY_ACK=6]="BINARY_ACK"}(lt||(lt={}));class ft{constructor(t){this.replacer=t}encode(t){return t.type!==lt.EVENT&&t.type!==lt.ACK||!ot(t)?[this.encodeAsString(t)]:this.encodeAsBinary({type:t.type===lt.EVENT?lt.BINARY_EVENT:lt.BINARY_ACK,nsp:t.nsp,data:t.data,id:t.id})}encodeAsString(t){let e=""+t.type;return t.type!==lt.BINARY_EVENT&&t.type!==lt.BINARY_ACK||(e+=t.attachments+"-"),t.nsp&&"/"!==t.nsp&&(e+=t.nsp+","),null!=t.id&&(e+=t.id),null!=t.data&&(e+=JSON.stringify(t.data,this.replacer)),e}encodeAsBinary(t){const e=at(t),s=this.encodeAsString(e.packet),n=e.buffers;return n.unshift(s),n}}function yt(t){return"[object Object]"===Object.prototype.toString.call(t)}class gt extends E{constructor(t){super(),this.reviver=t}add(t){let e;if("string"==typeof t){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");e=this.decodeString(t);const s=e.type===lt.BINARY_EVENT;s||e.type===lt.BINARY_ACK?(e.type=s?lt.EVENT:lt.ACK,this.reconstructor=new mt(e),0===e.attachments&&super.emitReserved("decoded",e)):super.emitReserved("decoded",e)}else{if(!rt(t)&&!t.base64)throw new Error("Unknown type: "+t);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");e=this.reconstructor.takeBinaryData(t),e&&(this.reconstructor=null,super.emitReserved("decoded",e))}}decodeString(t){let e=0;const s={type:Number(t.charAt(0))};if(void 0===lt[s.type])throw new Error("unknown packet type "+s.type);if(s.type===lt.BINARY_EVENT||s.type===lt.BINARY_ACK){const n=e+1;for(;"-"!==t.charAt(++e)&&e!=t.length;);const i=t.substring(n,e);if(i!=Number(i)||"-"!==t.charAt(e))throw new Error("Illegal attachments");s.attachments=Number(i)}if("/"===t.charAt(e+1)){const n=e+1;for(;++e&&","!==t.charAt(e)&&e!==t.length;);s.nsp=t.substring(n,e)}else s.nsp="/";const n=t.charAt(e+1);if(""!==n&&Number(n)==n){const n=e+1;for(;++e;){const s=t.charAt(e);if(null==s||Number(s)!=s){--e;break}if(e===t.length)break}s.id=Number(t.substring(n,e+1))}if(t.charAt(++e)){const n=this.tryParse(t.substr(e));if(!gt.isPayloadValid(s.type,n))throw new Error("invalid payload");s.data=n}return s}tryParse(t){try{return JSON.parse(t,this.reviver)}catch(t){return!1}}static isPayloadValid(t,e){switch(t){case lt.CONNECT:return yt(e);case lt.DISCONNECT:return void 0===e;case lt.CONNECT_ERROR:return"string"==typeof e||yt(e);case lt.EVENT:case lt.BINARY_EVENT:return Array.isArray(e)&&("number"==typeof e[0]||"string"==typeof e[0]&&-1===pt.indexOf(e[0]));case lt.ACK:case lt.BINARY_ACK:return Array.isArray(e)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class mt{constructor(t){this.packet=t,this.buffers=[],this.reconPack=t}takeBinaryData(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){const t=ht(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}function _t(t,e,s){return t.on(e,s),function(){t.off(e,s)}}const bt=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class vt extends E{constructor(t,e,s){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=t,this.nsp=e,s&&s.auth&&(this.auth=s.auth),this._opts=Object.assign({},s),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;const t=this.io;this.subs=[_t(t,"open",this.onopen.bind(this)),_t(t,"packet",this.onpacket.bind(this)),_t(t,"error",this.onerror.bind(this)),_t(t,"close",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected||(this.subEvents(),this.io._reconnecting||this.io.open(),"open"===this.io._readyState&&this.onopen()),this}open(){return this.connect()}send(...t){return t.unshift("message"),this.emit.apply(this,t),this}emit(t,...e){var s,n,i;if(bt.hasOwnProperty(t))throw new Error('"'+t.toString()+'" is a reserved event name');if(e.unshift(t),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(e),this;const r={type:lt.EVENT,data:e,options:{}};if(r.options.compress=!1!==this.flags.compress,"function"==typeof e[e.length-1]){const t=this.ids++,s=e.pop();this._registerAckCallback(t,s),r.id=t}const o=null===(n=null===(s=this.io.engine)||void 0===s?void 0:s.transport)||void 0===n?void 0:n.writable,a=this.connected&&!(null===(i=this.io.engine)||void 0===i?void 0:i._hasPingExpired());return this.flags.volatile&&!o||(a?(this.notifyOutgoingListeners(r),this.packet(r)):this.sendBuffer.push(r)),this.flags={},this}_registerAckCallback(t,e){var s;const n=null!==(s=this.flags.timeout)&&void 0!==s?s:this._opts.ackTimeout;if(void 0===n)return void(this.acks[t]=e);const i=this.io.setTimeoutFn(()=>{delete this.acks[t];for(let e=0;e<this.sendBuffer.length;e++)this.sendBuffer[e].id===t&&this.sendBuffer.splice(e,1);e.call(this,new Error("operation has timed out"))},n),r=(...t)=>{this.io.clearTimeoutFn(i),e.apply(this,t)};r.withError=!0,this.acks[t]=r}emitWithAck(t,...e){return new Promise((s,n)=>{const i=(t,e)=>t?n(t):s(e);i.withError=!0,e.push(i),this.emit(t,...e)})}_addToQueue(t){let e;"function"==typeof t[t.length-1]&&(e=t.pop());const s={id:this._queueSeq++,tryCount:0,pending:!1,args:t,flags:Object.assign({fromQueue:!0},this.flags)};t.push((t,...n)=>{if(s===this._queue[0])return null!==t?s.tryCount>this._opts.retries&&(this._queue.shift(),e&&e(t)):(this._queue.shift(),e&&e(null,...n)),s.pending=!1,this._drainQueue()}),this._queue.push(s),this._drainQueue()}_drainQueue(t=!1){if(!this.connected||0===this._queue.length)return;const e=this._queue[0];e.pending&&!t||(e.pending=!0,e.tryCount++,this.flags=e.flags,this.emit.apply(this,e.args))}packet(t){t.nsp=this.nsp,this.io._packet(t)}onopen(){"function"==typeof this.auth?this.auth(t=>{this._sendConnectPacket(t)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(t){this.packet({type:lt.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},t):t})}onerror(t){this.connected||this.emitReserved("connect_error",t)}onclose(t,e){this.connected=!1,delete this.id,this.emitReserved("disconnect",t,e),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(t=>{if(!this.sendBuffer.some(e=>String(e.id)===t)){const e=this.acks[t];delete this.acks[t],e.withError&&e.call(this,new Error("socket has been disconnected"))}})}onpacket(t){if(t.nsp===this.nsp)switch(t.type){case lt.CONNECT:t.data&&t.data.sid?this.onconnect(t.data.sid,t.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case lt.EVENT:case lt.BINARY_EVENT:this.onevent(t);break;case lt.ACK:case lt.BINARY_ACK:this.onack(t);break;case lt.DISCONNECT:this.ondisconnect();break;case lt.CONNECT_ERROR:this.destroy();const e=new Error(t.data.message);e.data=t.data.data,this.emitReserved("connect_error",e)}}onevent(t){const e=t.data||[];null!=t.id&&e.push(this.ack(t.id)),this.connected?this.emitEvent(e):this.receiveBuffer.push(Object.freeze(e))}emitEvent(t){if(this._anyListeners&&this._anyListeners.length){const e=this._anyListeners.slice();for(const s of e)s.apply(this,t)}super.emit.apply(this,t),this._pid&&t.length&&"string"==typeof t[t.length-1]&&(this._lastOffset=t[t.length-1])}ack(t){const e=this;let s=!1;return function(...n){s||(s=!0,e.packet({type:lt.ACK,id:t,data:n}))}}onack(t){const e=this.acks[t.id];"function"==typeof e&&(delete this.acks[t.id],e.withError&&t.data.unshift(null),e.apply(this,t.data))}onconnect(t,e){this.id=t,this.recovered=e&&this._pid===e,this._pid=e,this.connected=!0,this.emitBuffered(),this.emitReserved("connect"),this._drainQueue(!0)}emitBuffered(){this.receiveBuffer.forEach(t=>this.emitEvent(t)),this.receiveBuffer=[],this.sendBuffer.forEach(t=>{this.notifyOutgoingListeners(t),this.packet(t)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose("io server disconnect")}destroy(){this.subs&&(this.subs.forEach(t=>t()),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:lt.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}close(){return this.disconnect()}compress(t){return this.flags.compress=t,this}get volatile(){return this.flags.volatile=!0,this}timeout(t){return this.flags.timeout=t,this}onAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(t),this}prependAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(t),this}offAny(t){if(!this._anyListeners)return this;if(t){const e=this._anyListeners;for(let s=0;s<e.length;s++)if(t===e[s])return e.splice(s,1),this}else this._anyListeners=[];return this}listenersAny(){return this._anyListeners||[]}onAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(t),this}prependAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(t),this}offAnyOutgoing(t){if(!this._anyOutgoingListeners)return this;if(t){const e=this._anyOutgoingListeners;for(let s=0;s<e.length;s++)if(t===e[s])return e.splice(s,1),this}else this._anyOutgoingListeners=[];return this}listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}notifyOutgoingListeners(t){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){const e=this._anyOutgoingListeners.slice();for(const s of e)s.apply(this,t.data)}}}function wt(t){t=t||{},this.ms=t.min||100,this.max=t.max||1e4,this.factor=t.factor||2,this.jitter=t.jitter>0&&t.jitter<=1?t.jitter:0,this.attempts=0}wt.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),s=Math.floor(e*this.jitter*t);t=1&Math.floor(10*e)?t+s:t-s}return 0|Math.min(t,this.max)},wt.prototype.reset=function(){this.attempts=0},wt.prototype.setMin=function(t){this.ms=t},wt.prototype.setMax=function(t){this.max=t},wt.prototype.setJitter=function(t){this.jitter=t};class kt extends E{constructor(t,s){var n;super(),this.nsps={},this.subs=[],t&&"object"==typeof t&&(s=t,t=void 0),(s=s||{}).path=s.path||"/socket.io",this.opts=s,S(this,s),this.reconnection(!1!==s.reconnection),this.reconnectionAttempts(s.reconnectionAttempts||1/0),this.reconnectionDelay(s.reconnectionDelay||1e3),this.reconnectionDelayMax(s.reconnectionDelayMax||5e3),this.randomizationFactor(null!==(n=s.randomizationFactor)&&void 0!==n?n:.5),this.backoff=new wt({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(null==s.timeout?2e4:s.timeout),this._readyState="closed",this.uri=t;const i=s.parser||e;this.encoder=new i.Encoder,this.decoder=new i.Decoder,this._autoConnect=!1!==s.autoConnect,this._autoConnect&&this.open()}reconnection(t){return arguments.length?(this._reconnection=!!t,t||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(t){return void 0===t?this._reconnectionAttempts:(this._reconnectionAttempts=t,this)}reconnectionDelay(t){var e;return void 0===t?this._reconnectionDelay:(this._reconnectionDelay=t,null===(e=this.backoff)||void 0===e||e.setMin(t),this)}randomizationFactor(t){var e;return void 0===t?this._randomizationFactor:(this._randomizationFactor=t,null===(e=this.backoff)||void 0===e||e.setJitter(t),this)}reconnectionDelayMax(t){var e;return void 0===t?this._reconnectionDelayMax:(this._reconnectionDelayMax=t,null===(e=this.backoff)||void 0===e||e.setMax(t),this)}timeout(t){return arguments.length?(this._timeout=t,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&0===this.backoff.attempts&&this.reconnect()}open(t){if(~this._readyState.indexOf("open"))return this;this.engine=new tt(this.uri,this.opts);const e=this.engine,s=this;this._readyState="opening",this.skipReconnect=!1;const n=_t(e,"open",function(){s.onopen(),t&&t()}),i=e=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",e),t?t(e):this.maybeReconnectOnOpen()},r=_t(e,"error",i);if(!1!==this._timeout){const t=this._timeout,s=this.setTimeoutFn(()=>{n(),i(new Error("timeout")),e.close()},t);this.opts.autoUnref&&s.unref(),this.subs.push(()=>{this.clearTimeoutFn(s)})}return this.subs.push(n),this.subs.push(r),this}connect(t){return this.open(t)}onopen(){this.cleanup(),this._readyState="open",this.emitReserved("open");const t=this.engine;this.subs.push(_t(t,"ping",this.onping.bind(this)),_t(t,"data",this.ondata.bind(this)),_t(t,"error",this.onerror.bind(this)),_t(t,"close",this.onclose.bind(this)),_t(this.decoder,"decoded",this.ondecoded.bind(this)))}onping(){this.emitReserved("ping")}ondata(t){try{this.decoder.add(t)}catch(t){this.onclose("parse error",t)}}ondecoded(t){C(()=>{this.emitReserved("packet",t)},this.setTimeoutFn)}onerror(t){this.emitReserved("error",t)}socket(t,e){let s=this.nsps[t];return s?this._autoConnect&&!s.active&&s.connect():(s=new vt(this,t,e),this.nsps[t]=s),s}_destroy(t){const e=Object.keys(this.nsps);for(const t of e)if(this.nsps[t].active)return;this._close()}_packet(t){const e=this.encoder.encode(t);for(let s=0;s<e.length;s++)this.engine.write(e[s],t.options)}cleanup(){this.subs.forEach(t=>t()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close")}disconnect(){return this._close()}onclose(t,e){var s;this.cleanup(),null===(s=this.engine)||void 0===s||s.close(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",t,e),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;const t=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{const e=this.backoff.duration();this._reconnecting=!0;const s=this.setTimeoutFn(()=>{t.skipReconnect||(this.emitReserved("reconnect_attempt",t.backoff.attempts),t.skipReconnect||t.open(e=>{e?(t._reconnecting=!1,t.reconnect(),this.emitReserved("reconnect_error",e)):t.onreconnect()}))},e);this.opts.autoUnref&&s.unref(),this.subs.push(()=>{this.clearTimeoutFn(s)})}}onreconnect(){const t=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",t)}}const Et={};function Ct(t,e){"object"==typeof t&&(e=t,t=void 0);const s=function(t,e="",s){let n=t;s=s||"undefined"!=typeof location&&location,null==t&&(t=s.protocol+"//"+s.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?s.protocol+t:s.host+t),/^(https?|wss?):\/\//.test(t)||(t=void 0!==s?s.protocol+"//"+t:"https://"+t),n=J(t)),n.port||(/^(http|ws)$/.test(n.protocol)?n.port="80":/^(http|ws)s$/.test(n.protocol)&&(n.port="443")),n.path=n.path||"/";const i=-1!==n.host.indexOf(":")?"["+n.host+"]":n.host;return n.id=n.protocol+"://"+i+":"+n.port+e,n.href=n.protocol+"://"+i+(s&&s.port===n.port?"":":"+n.port),n}(t,(e=e||{}).path||"/socket.io"),n=s.source,i=s.id,r=s.path,o=Et[i]&&r in Et[i].nsps;let a;return e.forceNew||e["force new connection"]||!1===e.multiplex||o?a=new kt(n,e):(Et[i]||(Et[i]=new kt(n,e)),a=Et[i]),s.query&&!e.query&&(e.query=s.queryKey),a.socket(s.path,e)}Object.assign(Ct,{Manager:kt,Socket:vt,io:Ct,connect:Ct});var Tt=function(t,e,s,n){return new(s||(s=Promise))(function(i,r){function o(t){try{c(n.next(t))}catch(t){r(t)}}function a(t){try{c(n.throw(t))}catch(t){r(t)}}function c(t){t.done?i(t.value):function(t){return t instanceof s?t:new s(function(e){e(t)})}(t.value).then(o,a)}c((n=n.apply(t,e||[])).next())})};class At extends EventTarget{constructor(){super(...arguments),this.peerConnections={}}init(){return Tt(this,void 0,void 0,function*(){return this.socket=Ct("http://localhost:3030"),new Promise((t,e)=>{this.socket.once("connect",()=>{var e;this._userId=this.socket.id,e=this.socket.id,Rt=e,this.setupSocketListeners(),t()}),this.socket.once("connect_error",e),this.socket.once("error",e)})})}get userId(){if(!this._userId)throw new Error("User not connected yet");return this._userId}publish(t){this.publishStream=t}register(t){if(!this.publishStream)throw new Error("Call publish() before register()");this._confId=t,this.sendMessage({from:this.userId,payload:{action:"join"}}),console.log(`[CONF] Join request sent for room ${t}`)}unregister(){Object.values(this.peerConnections).forEach(t=>t.close()),this.peerConnections={},this._confId=void 0,this.socket.disconnect(),console.log("[CONF] Unregistered and socket closed")}setupSocketListeners(){this.socket.on("message",t=>Tt(this,void 0,void 0,function*(){if(!this._confId)return;const{from:e,payload:s}=t;switch(s.action){case"join":console.log(`[RTC] Join received from ${e}`),yield this.createPeerConnection(e,!0);break;case"offer":console.log(`[RTC] Offer received from ${e}`),yield this.handleOffer(e,s.sdp);break;case"answer":console.log(`[RTC] Answer received from ${e}`),yield this.handleAnswer(e,s.sdp);break;case"ice":console.log(`[RTC] ICE received from ${e}`),yield this.handleIce(e,s.candidate);break;case"close":console.log(`[RTC] Peer ${s.disconnect} disconnected`),this.removePeer(s.disconnect),this.dispatchEvent(new CustomEvent("peopleLeave",{detail:{leaveId:s.disconnect}})),console.log("[Socket] leave"+s.disconnect)}}))}createPeerConnection(t,e){return Tt(this,void 0,void 0,function*(){var s;if(this.peerConnections[t])return;const i=new RTCPeerConnection;if(this.peerConnections[t]=i,null===(s=this.publishStream)||void 0===s||s.mediastream.getTracks().forEach(t=>{i.addTrack(t,this.publishStream.mediastream)}),i.ontrack=e=>{console.log("[RTC] Track received"),this.dispatchEvent(new CustomEvent("stream",{detail:{stream:new n(e.streams[0],t)}}))},i.onicecandidate=e=>{e.candidate&&this.sendMessage({from:this.userId,target:t,payload:{action:"ice",candidate:e.candidate}})},e){const e=yield i.createOffer();yield i.setLocalDescription(e),this.sendMessage({from:this.userId,target:t,payload:{action:"offer",sdp:e}})}})}handleOffer(t,e){return Tt(this,void 0,void 0,function*(){yield this.createPeerConnection(t,!1);const s=this.peerConnections[t];yield s.setRemoteDescription(new RTCSessionDescription(e));const n=yield s.createAnswer();yield s.setLocalDescription(n),this.sendMessage({from:this.userId,target:t,payload:{action:"answer",sdp:n}}),this.dispatchEvent(new CustomEvent("newPeople"))})}handleAnswer(t,e){return Tt(this,void 0,void 0,function*(){const s=this.peerConnections[t];s&&(yield s.setRemoteDescription(new RTCSessionDescription(e)),this.dispatchEvent(new CustomEvent("newPeople")))})}handleIce(t,e){return Tt(this,void 0,void 0,function*(){const s=this.peerConnections[t];s&&(yield s.addIceCandidate(e))})}removePeer(t){var e;null===(e=this.peerConnections[t])||void 0===e||e.close(),delete this.peerConnections[t]}sendMessage(t){this.socket.emit("message",t)}}const Ot=new At;Ot.init();let Rt=null;class St extends EventTarget{constructor(t){super(),this.name=t,this.id=2,this.knownStreams=[],this.setupListener()}setupListener(){Ot.addEventListener("stream",t=>{this.newStream(t)}),Ot.addEventListener("peopleLeave",t=>{this.peopleLeave(t)})}publish(t){Ot.publish(t)}join(){Ot.register(this.id)}leave(){Ot.unregister()}getMembers(){}newStream(t){if(this.knownStreams.includes(t.detail.stream))return;this.knownStreams.push(t.detail.stream);const e=new CustomEvent("newstream",{detail:{stream:t.detail.stream}});this.dispatchEvent(e)}peopleLeave(t){const e=new CustomEvent("peopleLeave",{detail:{leaveId:t.detail.leaveId}});console.log("[Conf] leave"+t.detail.leaveId),this.dispatchEvent(e)}}export{St as Conference,s as HelloWorld,n as Stream};
1
+ var t={d:(e,s)=>{for(var n in s)t.o(s,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:s[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{Decoder:()=>mt,Encoder:()=>pt,PacketType:()=>dt,protocol:()=>lt});class s{constructor(t,e){this.name=e,this.id=t}toString(){return{id:this.id,name:this.name}}}const n=Object.create(null);n.open="0",n.close="1",n.ping="2",n.pong="3",n.message="4",n.upgrade="5",n.noop="6";const i=Object.create(null);Object.keys(n).forEach(t=>{i[n[t]]=t});const r={type:"error",data:"parser error"},o="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===Object.prototype.toString.call(Blob),a="function"==typeof ArrayBuffer,c=t=>"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t&&t.buffer instanceof ArrayBuffer,h=({type:t,data:e},s,i)=>o&&e instanceof Blob?s?i(e):u(e,i):a&&(e instanceof ArrayBuffer||c(e))?s?i(e):u(new Blob([e]),i):i(n[t]+(e||"")),u=(t,e)=>{const s=new FileReader;return s.onload=function(){const t=s.result.split(",")[1];e("b"+(t||""))},s.readAsDataURL(t)};function l(t){return t instanceof Uint8Array?t:t instanceof ArrayBuffer?new Uint8Array(t):new Uint8Array(t.buffer,t.byteOffset,t.byteLength)}let d;const p="undefined"==typeof Uint8Array?[]:new Uint8Array(256);for(let t=0;t<64;t++)p["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charCodeAt(t)]=t;const f="function"==typeof ArrayBuffer,m=(t,e)=>{if("string"!=typeof t)return{type:"message",data:g(t,e)};const s=t.charAt(0);return"b"===s?{type:"message",data:y(t.substring(1),e)}:i[s]?t.length>1?{type:i[s],data:t.substring(1)}:{type:i[s]}:r},y=(t,e)=>{if(f){const s=(t=>{let e,s,n,i,r,o=.75*t.length,a=t.length,c=0;"="===t[t.length-1]&&(o--,"="===t[t.length-2]&&o--);const h=new ArrayBuffer(o),u=new Uint8Array(h);for(e=0;e<a;e+=4)s=p[t.charCodeAt(e)],n=p[t.charCodeAt(e+1)],i=p[t.charCodeAt(e+2)],r=p[t.charCodeAt(e+3)],u[c++]=s<<2|n>>4,u[c++]=(15&n)<<4|i>>2,u[c++]=(3&i)<<6|63&r;return h})(t);return g(s,e)}return{base64:!0,data:t}},g=(t,e)=>"blob"===e?t instanceof Blob?t:new Blob([t]):t instanceof ArrayBuffer?t:t.buffer,b=String.fromCharCode(30);let v;function _(t){return t.reduce((t,e)=>t+e.length,0)}function w(t,e){if(t[0].length===e)return t.shift();const s=new Uint8Array(e);let n=0;for(let i=0;i<e;i++)s[i]=t[0][n++],n===t[0].length&&(t.shift(),n=0);return t.length&&n<t[0].length&&(t[0]=t[0].slice(n)),s}function k(t){if(t)return function(t){for(var e in k.prototype)t[e]=k.prototype[e];return t}(t)}k.prototype.on=k.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},k.prototype.once=function(t,e){function s(){this.off(t,s),e.apply(this,arguments)}return s.fn=e,this.on(t,s),this},k.prototype.off=k.prototype.removeListener=k.prototype.removeAllListeners=k.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var s,n=this._callbacks["$"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var i=0;i<n.length;i++)if((s=n[i])===e||s.fn===e){n.splice(i,1);break}return 0===n.length&&delete this._callbacks["$"+t],this},k.prototype.emit=function(t){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),s=this._callbacks["$"+t],n=1;n<arguments.length;n++)e[n-1]=arguments[n];if(s){n=0;for(var i=(s=s.slice(0)).length;n<i;++n)s[n].apply(this,e)}return this},k.prototype.emitReserved=k.prototype.emit,k.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks["$"+t]||[]},k.prototype.hasListeners=function(t){return!!this.listeners(t).length};const E="function"==typeof Promise&&"function"==typeof Promise.resolve?t=>Promise.resolve().then(t):(t,e)=>e(t,0),T="undefined"!=typeof self?self:"undefined"!=typeof window?window:Function("return this")();function C(t,...e){return e.reduce((e,s)=>(t.hasOwnProperty(s)&&(e[s]=t[s]),e),{})}const A=T.setTimeout,O=T.clearTimeout;function S(t,e){e.useNativeTimers?(t.setTimeoutFn=A.bind(T),t.clearTimeoutFn=O.bind(T)):(t.setTimeoutFn=T.setTimeout.bind(T),t.clearTimeoutFn=T.clearTimeout.bind(T))}function R(t){return"string"==typeof t?function(t){let e=0,s=0;for(let n=0,i=t.length;n<i;n++)e=t.charCodeAt(n),e<128?s+=1:e<2048?s+=2:e<55296||e>=57344?s+=3:(n++,s+=4);return s}(t):Math.ceil(1.33*(t.byteLength||t.size))}function L(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}class B extends Error{constructor(t,e,s){super(t),this.description=e,this.context=s,this.type="TransportError"}}class P extends k{constructor(t){super(),this.writable=!1,S(this,t),this.opts=t,this.query=t.query,this.socket=t.socket,this.supportsBinary=!t.forceBase64}onError(t,e,s){return super.emitReserved("error",new B(t,e,s)),this}open(){return this.readyState="opening",this.doOpen(),this}close(){return"opening"!==this.readyState&&"open"!==this.readyState||(this.doClose(),this.onClose()),this}send(t){"open"===this.readyState&&this.write(t)}onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("open")}onData(t){const e=m(t,this.socket.binaryType);this.onPacket(e)}onPacket(t){super.emitReserved("packet",t)}onClose(t){this.readyState="closed",super.emitReserved("close",t)}pause(t){}createUri(t,e={}){return t+"://"+this._hostname()+this._port()+this.opts.path+this._query(e)}_hostname(){const t=this.opts.hostname;return-1===t.indexOf(":")?t:"["+t+"]"}_port(){return this.opts.port&&(this.opts.secure&&Number(443!==this.opts.port)||!this.opts.secure&&80!==Number(this.opts.port))?":"+this.opts.port:""}_query(t){const e=function(t){let e="";for(let s in t)t.hasOwnProperty(s)&&(e.length&&(e+="&"),e+=encodeURIComponent(s)+"="+encodeURIComponent(t[s]));return e}(t);return e.length?"?"+e:""}}class x extends P{constructor(){super(...arguments),this._polling=!1}get name(){return"polling"}doOpen(){this._poll()}pause(t){this.readyState="pausing";const e=()=>{this.readyState="paused",t()};if(this._polling||!this.writable){let t=0;this._polling&&(t++,this.once("pollComplete",function(){--t||e()})),this.writable||(t++,this.once("drain",function(){--t||e()}))}else e()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved("poll")}onData(t){((t,e)=>{const s=t.split(b),n=[];for(let t=0;t<s.length;t++){const i=m(s[t],e);if(n.push(i),"error"===i.type)break}return n})(t,this.socket.binaryType).forEach(t=>{if("opening"===this.readyState&&"open"===t.type&&this.onOpen(),"close"===t.type)return this.onClose({description:"transport closed by the server"}),!1;this.onPacket(t)}),"closed"!==this.readyState&&(this._polling=!1,this.emitReserved("pollComplete"),"open"===this.readyState&&this._poll())}doClose(){const t=()=>{this.write([{type:"close"}])};"open"===this.readyState?t():this.once("open",t)}write(t){this.writable=!1,((t,e)=>{const s=t.length,n=new Array(s);let i=0;t.forEach((t,r)=>{h(t,!1,t=>{n[r]=t,++i===s&&e(n.join(b))})})})(t,t=>{this.doWrite(t,()=>{this.writable=!0,this.emitReserved("drain")})})}uri(){const t=this.opts.secure?"https":"http",e=this.query||{};return!1!==this.opts.timestampRequests&&(e[this.opts.timestampParam]=L()),this.supportsBinary||e.sid||(e.b64=1),this.createUri(t,e)}}let N=!1;try{N="undefined"!=typeof XMLHttpRequest&&"withCredentials"in new XMLHttpRequest}catch(t){}const I=N;function q(){}class j extends x{constructor(t){if(super(t),"undefined"!=typeof location){const e="https:"===location.protocol;let s=location.port;s||(s=e?"443":"80"),this.xd="undefined"!=typeof location&&t.hostname!==location.hostname||s!==t.port}}doWrite(t,e){const s=this.request({method:"POST",data:t});s.on("success",e),s.on("error",(t,e)=>{this.onError("xhr post error",t,e)})}doPoll(){const t=this.request();t.on("data",this.onData.bind(this)),t.on("error",(t,e)=>{this.onError("xhr poll error",t,e)}),this.pollXhr=t}}class D extends k{constructor(t,e,s){super(),this.createRequest=t,S(this,s),this._opts=s,this._method=s.method||"GET",this._uri=e,this._data=void 0!==s.data?s.data:null,this._create()}_create(){var t;const e=C(this._opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");e.xdomain=!!this._opts.xd;const s=this._xhr=this.createRequest(e);try{s.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){s.setDisableHeaderCheck&&s.setDisableHeaderCheck(!0);for(let t in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(t)&&s.setRequestHeader(t,this._opts.extraHeaders[t])}}catch(t){}if("POST"===this._method)try{s.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch(t){}try{s.setRequestHeader("Accept","*/*")}catch(t){}null===(t=this._opts.cookieJar)||void 0===t||t.addCookies(s),"withCredentials"in s&&(s.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(s.timeout=this._opts.requestTimeout),s.onreadystatechange=()=>{var t;3===s.readyState&&(null===(t=this._opts.cookieJar)||void 0===t||t.parseCookies(s.getResponseHeader("set-cookie"))),4===s.readyState&&(200===s.status||1223===s.status?this._onLoad():this.setTimeoutFn(()=>{this._onError("number"==typeof s.status?s.status:0)},0))},s.send(this._data)}catch(t){return void this.setTimeoutFn(()=>{this._onError(t)},0)}"undefined"!=typeof document&&(this._index=D.requestsCount++,D.requests[this._index]=this)}_onError(t){this.emitReserved("error",t,this._xhr),this._cleanup(!0)}_cleanup(t){if(void 0!==this._xhr&&null!==this._xhr){if(this._xhr.onreadystatechange=q,t)try{this._xhr.abort()}catch(t){}"undefined"!=typeof document&&delete D.requests[this._index],this._xhr=null}}_onLoad(){const t=this._xhr.responseText;null!==t&&(this.emitReserved("data",t),this.emitReserved("success"),this._cleanup())}abort(){this._cleanup()}}function U(){for(let t in D.requests)D.requests.hasOwnProperty(t)&&D.requests[t].abort()}D.requestsCount=0,D.requests={},"undefined"!=typeof document&&("function"==typeof attachEvent?attachEvent("onunload",U):"function"==typeof addEventListener&&addEventListener("onpagehide"in T?"pagehide":"unload",U,!1));const M=function(){const t=F({xdomain:!1});return t&&null!==t.responseType}();function F(t){const e=t.xdomain;try{if("undefined"!=typeof XMLHttpRequest&&(!e||I))return new XMLHttpRequest}catch(t){}if(!e)try{return new(T[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(t){}}const V="undefined"!=typeof navigator&&"string"==typeof navigator.product&&"reactnative"===navigator.product.toLowerCase();class H extends P{get name(){return"websocket"}doOpen(){const t=this.uri(),e=this.opts.protocols,s=V?{}:C(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(s.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(t,e,s)}catch(t){return this.emitReserved("error",t)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=t=>this.onClose({description:"websocket connection closed",context:t}),this.ws.onmessage=t=>this.onData(t.data),this.ws.onerror=t=>this.onError("websocket error",t)}write(t){this.writable=!1;for(let e=0;e<t.length;e++){const s=t[e],n=e===t.length-1;h(s,this.supportsBinary,t=>{try{this.doWrite(s,t)}catch(t){}n&&E(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){void 0!==this.ws&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){const t=this.opts.secure?"wss":"ws",e=this.query||{};return this.opts.timestampRequests&&(e[this.opts.timestampParam]=L()),this.supportsBinary||(e.b64=1),this.createUri(t,e)}}const z=T.WebSocket||T.MozWebSocket,K={websocket:class extends H{createSocket(t,e,s){return V?new z(t,e,s):e?new z(t,e):new z(t)}doWrite(t,e){this.ws.send(e)}},webtransport:class extends P{get name(){return"webtransport"}doOpen(){try{this._transport=new WebTransport(this.createUri("https"),this.opts.transportOptions[this.name])}catch(t){return this.emitReserved("error",t)}this._transport.closed.then(()=>{this.onClose()}).catch(t=>{this.onError("webtransport error",t)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(t=>{const e=function(t,e){v||(v=new TextDecoder);const s=[];let n=0,i=-1,o=!1;return new TransformStream({transform(a,c){for(s.push(a);;){if(0===n){if(_(s)<1)break;const t=w(s,1);o=!(128&~t[0]),i=127&t[0],n=i<126?3:126===i?1:2}else if(1===n){if(_(s)<2)break;const t=w(s,2);i=new DataView(t.buffer,t.byteOffset,t.length).getUint16(0),n=3}else if(2===n){if(_(s)<8)break;const t=w(s,8),e=new DataView(t.buffer,t.byteOffset,t.length),o=e.getUint32(0);if(o>Math.pow(2,21)-1){c.enqueue(r);break}i=o*Math.pow(2,32)+e.getUint32(4),n=3}else{if(_(s)<i)break;const t=w(s,i);c.enqueue(m(o?t:v.decode(t),e)),n=0}if(0===i||i>t){c.enqueue(r);break}}}})}(Number.MAX_SAFE_INTEGER,this.socket.binaryType),s=t.readable.pipeThrough(e).getReader(),n=new TransformStream({transform(t,e){!function(t,e){o&&t.data instanceof Blob?t.data.arrayBuffer().then(l).then(e):a&&(t.data instanceof ArrayBuffer||c(t.data))?e(l(t.data)):h(t,!1,t=>{d||(d=new TextEncoder),e(d.encode(t))})}(t,s=>{const n=s.length;let i;if(n<126)i=new Uint8Array(1),new DataView(i.buffer).setUint8(0,n);else if(n<65536){i=new Uint8Array(3);const t=new DataView(i.buffer);t.setUint8(0,126),t.setUint16(1,n)}else{i=new Uint8Array(9);const t=new DataView(i.buffer);t.setUint8(0,127),t.setBigUint64(1,BigInt(n))}t.data&&"string"!=typeof t.data&&(i[0]|=128),e.enqueue(i),e.enqueue(s)})}});n.readable.pipeTo(t.writable),this._writer=n.writable.getWriter();const i=()=>{s.read().then(({done:t,value:e})=>{t||(this.onPacket(e),i())}).catch(t=>{})};i();const u={type:"open"};this.query.sid&&(u.data=`{"sid":"${this.query.sid}"}`),this._writer.write(u).then(()=>this.onOpen())})})}write(t){this.writable=!1;for(let e=0;e<t.length;e++){const s=t[e],n=e===t.length-1;this._writer.write(s).then(()=>{n&&E(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var t;null===(t=this._transport)||void 0===t||t.close()}},polling:class extends j{constructor(t){super(t);const e=t&&t.forceBase64;this.supportsBinary=M&&!e}request(t={}){return Object.assign(t,{xd:this.xd},this.opts),new D(F,this.uri(),t)}}},$=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,W=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function Y(t){if(t.length>8e3)throw"URI too long";const e=t,s=t.indexOf("["),n=t.indexOf("]");-1!=s&&-1!=n&&(t=t.substring(0,s)+t.substring(s,n).replace(/:/g,";")+t.substring(n,t.length));let i=$.exec(t||""),r={},o=14;for(;o--;)r[W[o]]=i[o]||"";return-1!=s&&-1!=n&&(r.source=e,r.host=r.host.substring(1,r.host.length-1).replace(/;/g,":"),r.authority=r.authority.replace("[","").replace("]","").replace(/;/g,":"),r.ipv6uri=!0),r.pathNames=function(t,e){const s=e.replace(/\/{2,9}/g,"/").split("/");return"/"!=e.slice(0,1)&&0!==e.length||s.splice(0,1),"/"==e.slice(-1)&&s.splice(s.length-1,1),s}(0,r.path),r.queryKey=function(t,e){const s={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(t,e,n){e&&(s[e]=n)}),s}(0,r.query),r}const J="function"==typeof addEventListener&&"function"==typeof removeEventListener,Q=[];J&&addEventListener("offline",()=>{Q.forEach(t=>t())},!1);class X extends k{constructor(t,e){if(super(),this.binaryType="arraybuffer",this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,t&&"object"==typeof t&&(e=t,t=null),t){const s=Y(t);e.hostname=s.host,e.secure="https"===s.protocol||"wss"===s.protocol,e.port=s.port,s.query&&(e.query=s.query)}else e.host&&(e.hostname=Y(e.host).host);S(this,e),this.secure=null!=e.secure?e.secure:"undefined"!=typeof location&&"https:"===location.protocol,e.hostname&&!e.port&&(e.port=this.secure?"443":"80"),this.hostname=e.hostname||("undefined"!=typeof location?location.hostname:"localhost"),this.port=e.port||("undefined"!=typeof location&&location.port?location.port:this.secure?"443":"80"),this.transports=[],this._transportsByName={},e.transports.forEach(t=>{const e=t.prototype.name;this.transports.push(e),this._transportsByName[e]=t}),this.opts=Object.assign({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},e),this.opts.path=this.opts.path.replace(/\/$/,"")+(this.opts.addTrailingSlash?"/":""),"string"==typeof this.opts.query&&(this.opts.query=function(t){let e={},s=t.split("&");for(let t=0,n=s.length;t<n;t++){let n=s[t].split("=");e[decodeURIComponent(n[0])]=decodeURIComponent(n[1])}return e}(this.opts.query)),J&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener("beforeunload",this._beforeunloadEventListener,!1)),"localhost"!==this.hostname&&(this._offlineEventListener=()=>{this._onClose("transport close",{description:"network connection lost"})},Q.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(t){const e=Object.assign({},this.opts.query);e.EIO=4,e.transport=t,this.id&&(e.sid=this.id);const s=Object.assign({},this.opts,{query:e,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[t]);return new this._transportsByName[t](s)}_open(){if(0===this.transports.length)return void this.setTimeoutFn(()=>{this.emitReserved("error","No transports available")},0);const t=this.opts.rememberUpgrade&&X.priorWebsocketSuccess&&-1!==this.transports.indexOf("websocket")?"websocket":this.transports[0];this.readyState="opening";const e=this.createTransport(t);e.open(),this.setTransport(e)}setTransport(t){this.transport&&this.transport.removeAllListeners(),this.transport=t,t.on("drain",this._onDrain.bind(this)).on("packet",this._onPacket.bind(this)).on("error",this._onError.bind(this)).on("close",t=>this._onClose("transport close",t))}onOpen(){this.readyState="open",X.priorWebsocketSuccess="websocket"===this.transport.name,this.emitReserved("open"),this.flush()}_onPacket(t){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState)switch(this.emitReserved("packet",t),this.emitReserved("heartbeat"),t.type){case"open":this.onHandshake(JSON.parse(t.data));break;case"ping":this._sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong"),this._resetPingTimeout();break;case"error":const e=new Error("server error");e.code=t.data,this._onError(e);break;case"message":this.emitReserved("data",t.data),this.emitReserved("message",t.data)}}onHandshake(t){this.emitReserved("handshake",t),this.id=t.sid,this.transport.query.sid=t.sid,this._pingInterval=t.pingInterval,this._pingTimeout=t.pingTimeout,this._maxPayload=t.maxPayload,this.onOpen(),"closed"!==this.readyState&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);const t=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+t,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose("ping timeout")},t),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,0===this.writeBuffer.length?this.emitReserved("drain"):this.flush()}flush(){if("closed"!==this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){const t=this._getWritablePackets();this.transport.send(t),this._prevBufferLen=t.length,this.emitReserved("flush")}}_getWritablePackets(){if(!(this._maxPayload&&"polling"===this.transport.name&&this.writeBuffer.length>1))return this.writeBuffer;let t=1;for(let e=0;e<this.writeBuffer.length;e++){const s=this.writeBuffer[e].data;if(s&&(t+=R(s)),e>0&&t>this._maxPayload)return this.writeBuffer.slice(0,e);t+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;const t=Date.now()>this._pingTimeoutTime;return t&&(this._pingTimeoutTime=0,E(()=>{this._onClose("ping timeout")},this.setTimeoutFn)),t}write(t,e,s){return this._sendPacket("message",t,e,s),this}send(t,e,s){return this._sendPacket("message",t,e,s),this}_sendPacket(t,e,s,n){if("function"==typeof e&&(n=e,e=void 0),"function"==typeof s&&(n=s,s=null),"closing"===this.readyState||"closed"===this.readyState)return;(s=s||{}).compress=!1!==s.compress;const i={type:t,data:e,options:s};this.emitReserved("packetCreate",i),this.writeBuffer.push(i),n&&this.once("flush",n),this.flush()}close(){const t=()=>{this._onClose("forced close"),this.transport.close()},e=()=>{this.off("upgrade",e),this.off("upgradeError",e),t()},s=()=>{this.once("upgrade",e),this.once("upgradeError",e)};return"opening"!==this.readyState&&"open"!==this.readyState||(this.readyState="closing",this.writeBuffer.length?this.once("drain",()=>{this.upgrading?s():t()}):this.upgrading?s():t()),this}_onError(t){if(X.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&"opening"===this.readyState)return this.transports.shift(),this._open();this.emitReserved("error",t),this._onClose("transport error",t)}_onClose(t,e){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),J&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){const t=Q.indexOf(this._offlineEventListener);-1!==t&&Q.splice(t,1)}this.readyState="closed",this.id=null,this.emitReserved("close",t,e),this.writeBuffer=[],this._prevBufferLen=0}}}X.protocol=4;class G extends X{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),"open"===this.readyState&&this.opts.upgrade)for(let t=0;t<this._upgrades.length;t++)this._probe(this._upgrades[t])}_probe(t){let e=this.createTransport(t),s=!1;X.priorWebsocketSuccess=!1;const n=()=>{s||(e.send([{type:"ping",data:"probe"}]),e.once("packet",t=>{if(!s)if("pong"===t.type&&"probe"===t.data){if(this.upgrading=!0,this.emitReserved("upgrading",e),!e)return;X.priorWebsocketSuccess="websocket"===e.name,this.transport.pause(()=>{s||"closed"!==this.readyState&&(h(),this.setTransport(e),e.send([{type:"upgrade"}]),this.emitReserved("upgrade",e),e=null,this.upgrading=!1,this.flush())})}else{const t=new Error("probe error");t.transport=e.name,this.emitReserved("upgradeError",t)}}))};function i(){s||(s=!0,h(),e.close(),e=null)}const r=t=>{const s=new Error("probe error: "+t);s.transport=e.name,i(),this.emitReserved("upgradeError",s)};function o(){r("transport closed")}function a(){r("socket closed")}function c(t){e&&t.name!==e.name&&i()}const h=()=>{e.removeListener("open",n),e.removeListener("error",r),e.removeListener("close",o),this.off("close",a),this.off("upgrading",c)};e.once("open",n),e.once("error",r),e.once("close",o),this.once("close",a),this.once("upgrading",c),-1!==this._upgrades.indexOf("webtransport")&&"webtransport"!==t?this.setTimeoutFn(()=>{s||e.open()},200):e.open()}onHandshake(t){this._upgrades=this._filterUpgrades(t.upgrades),super.onHandshake(t)}_filterUpgrades(t){const e=[];for(let s=0;s<t.length;s++)~this.transports.indexOf(t[s])&&e.push(t[s]);return e}}class Z extends G{constructor(t,e={}){const s="object"==typeof t?t:e;(!s.transports||s.transports&&"string"==typeof s.transports[0])&&(s.transports=(s.transports||["polling","websocket","webtransport"]).map(t=>K[t]).filter(t=>!!t)),super(t,s)}}const tt="function"==typeof ArrayBuffer,et=Object.prototype.toString,st="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===et.call(Blob),nt="function"==typeof File||"undefined"!=typeof File&&"[object FileConstructor]"===et.call(File);function it(t){return tt&&(t instanceof ArrayBuffer||(t=>"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t.buffer instanceof ArrayBuffer)(t))||st&&t instanceof Blob||nt&&t instanceof File}function rt(t,e){if(!t||"object"!=typeof t)return!1;if(Array.isArray(t)){for(let e=0,s=t.length;e<s;e++)if(rt(t[e]))return!0;return!1}if(it(t))return!0;if(t.toJSON&&"function"==typeof t.toJSON&&1===arguments.length)return rt(t.toJSON(),!0);for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)&&rt(t[e]))return!0;return!1}function ot(t){const e=[],s=t.data,n=t;return n.data=at(s,e),n.attachments=e.length,{packet:n,buffers:e}}function at(t,e){if(!t)return t;if(it(t)){const s={_placeholder:!0,num:e.length};return e.push(t),s}if(Array.isArray(t)){const s=new Array(t.length);for(let n=0;n<t.length;n++)s[n]=at(t[n],e);return s}if("object"==typeof t&&!(t instanceof Date)){const s={};for(const n in t)Object.prototype.hasOwnProperty.call(t,n)&&(s[n]=at(t[n],e));return s}return t}function ct(t,e){return t.data=ht(t.data,e),delete t.attachments,t}function ht(t,e){if(!t)return t;if(t&&!0===t._placeholder){if("number"==typeof t.num&&t.num>=0&&t.num<e.length)return e[t.num];throw new Error("illegal attachments")}if(Array.isArray(t))for(let s=0;s<t.length;s++)t[s]=ht(t[s],e);else if("object"==typeof t)for(const s in t)Object.prototype.hasOwnProperty.call(t,s)&&(t[s]=ht(t[s],e));return t}const ut=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"],lt=5;var dt;!function(t){t[t.CONNECT=0]="CONNECT",t[t.DISCONNECT=1]="DISCONNECT",t[t.EVENT=2]="EVENT",t[t.ACK=3]="ACK",t[t.CONNECT_ERROR=4]="CONNECT_ERROR",t[t.BINARY_EVENT=5]="BINARY_EVENT",t[t.BINARY_ACK=6]="BINARY_ACK"}(dt||(dt={}));class pt{constructor(t){this.replacer=t}encode(t){return t.type!==dt.EVENT&&t.type!==dt.ACK||!rt(t)?[this.encodeAsString(t)]:this.encodeAsBinary({type:t.type===dt.EVENT?dt.BINARY_EVENT:dt.BINARY_ACK,nsp:t.nsp,data:t.data,id:t.id})}encodeAsString(t){let e=""+t.type;return t.type!==dt.BINARY_EVENT&&t.type!==dt.BINARY_ACK||(e+=t.attachments+"-"),t.nsp&&"/"!==t.nsp&&(e+=t.nsp+","),null!=t.id&&(e+=t.id),null!=t.data&&(e+=JSON.stringify(t.data,this.replacer)),e}encodeAsBinary(t){const e=ot(t),s=this.encodeAsString(e.packet),n=e.buffers;return n.unshift(s),n}}function ft(t){return"[object Object]"===Object.prototype.toString.call(t)}class mt extends k{constructor(t){super(),this.reviver=t}add(t){let e;if("string"==typeof t){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");e=this.decodeString(t);const s=e.type===dt.BINARY_EVENT;s||e.type===dt.BINARY_ACK?(e.type=s?dt.EVENT:dt.ACK,this.reconstructor=new yt(e),0===e.attachments&&super.emitReserved("decoded",e)):super.emitReserved("decoded",e)}else{if(!it(t)&&!t.base64)throw new Error("Unknown type: "+t);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");e=this.reconstructor.takeBinaryData(t),e&&(this.reconstructor=null,super.emitReserved("decoded",e))}}decodeString(t){let e=0;const s={type:Number(t.charAt(0))};if(void 0===dt[s.type])throw new Error("unknown packet type "+s.type);if(s.type===dt.BINARY_EVENT||s.type===dt.BINARY_ACK){const n=e+1;for(;"-"!==t.charAt(++e)&&e!=t.length;);const i=t.substring(n,e);if(i!=Number(i)||"-"!==t.charAt(e))throw new Error("Illegal attachments");s.attachments=Number(i)}if("/"===t.charAt(e+1)){const n=e+1;for(;++e&&","!==t.charAt(e)&&e!==t.length;);s.nsp=t.substring(n,e)}else s.nsp="/";const n=t.charAt(e+1);if(""!==n&&Number(n)==n){const n=e+1;for(;++e;){const s=t.charAt(e);if(null==s||Number(s)!=s){--e;break}if(e===t.length)break}s.id=Number(t.substring(n,e+1))}if(t.charAt(++e)){const n=this.tryParse(t.substr(e));if(!mt.isPayloadValid(s.type,n))throw new Error("invalid payload");s.data=n}return s}tryParse(t){try{return JSON.parse(t,this.reviver)}catch(t){return!1}}static isPayloadValid(t,e){switch(t){case dt.CONNECT:return ft(e);case dt.DISCONNECT:return void 0===e;case dt.CONNECT_ERROR:return"string"==typeof e||ft(e);case dt.EVENT:case dt.BINARY_EVENT:return Array.isArray(e)&&("number"==typeof e[0]||"string"==typeof e[0]&&-1===ut.indexOf(e[0]));case dt.ACK:case dt.BINARY_ACK:return Array.isArray(e)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class yt{constructor(t){this.packet=t,this.buffers=[],this.reconPack=t}takeBinaryData(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){const t=ct(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}function gt(t,e,s){return t.on(e,s),function(){t.off(e,s)}}const bt=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class vt extends k{constructor(t,e,s){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=t,this.nsp=e,s&&s.auth&&(this.auth=s.auth),this._opts=Object.assign({},s),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;const t=this.io;this.subs=[gt(t,"open",this.onopen.bind(this)),gt(t,"packet",this.onpacket.bind(this)),gt(t,"error",this.onerror.bind(this)),gt(t,"close",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected||(this.subEvents(),this.io._reconnecting||this.io.open(),"open"===this.io._readyState&&this.onopen()),this}open(){return this.connect()}send(...t){return t.unshift("message"),this.emit.apply(this,t),this}emit(t,...e){var s,n,i;if(bt.hasOwnProperty(t))throw new Error('"'+t.toString()+'" is a reserved event name');if(e.unshift(t),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(e),this;const r={type:dt.EVENT,data:e,options:{}};if(r.options.compress=!1!==this.flags.compress,"function"==typeof e[e.length-1]){const t=this.ids++,s=e.pop();this._registerAckCallback(t,s),r.id=t}const o=null===(n=null===(s=this.io.engine)||void 0===s?void 0:s.transport)||void 0===n?void 0:n.writable,a=this.connected&&!(null===(i=this.io.engine)||void 0===i?void 0:i._hasPingExpired());return this.flags.volatile&&!o||(a?(this.notifyOutgoingListeners(r),this.packet(r)):this.sendBuffer.push(r)),this.flags={},this}_registerAckCallback(t,e){var s;const n=null!==(s=this.flags.timeout)&&void 0!==s?s:this._opts.ackTimeout;if(void 0===n)return void(this.acks[t]=e);const i=this.io.setTimeoutFn(()=>{delete this.acks[t];for(let e=0;e<this.sendBuffer.length;e++)this.sendBuffer[e].id===t&&this.sendBuffer.splice(e,1);e.call(this,new Error("operation has timed out"))},n),r=(...t)=>{this.io.clearTimeoutFn(i),e.apply(this,t)};r.withError=!0,this.acks[t]=r}emitWithAck(t,...e){return new Promise((s,n)=>{const i=(t,e)=>t?n(t):s(e);i.withError=!0,e.push(i),this.emit(t,...e)})}_addToQueue(t){let e;"function"==typeof t[t.length-1]&&(e=t.pop());const s={id:this._queueSeq++,tryCount:0,pending:!1,args:t,flags:Object.assign({fromQueue:!0},this.flags)};t.push((t,...n)=>{if(s===this._queue[0])return null!==t?s.tryCount>this._opts.retries&&(this._queue.shift(),e&&e(t)):(this._queue.shift(),e&&e(null,...n)),s.pending=!1,this._drainQueue()}),this._queue.push(s),this._drainQueue()}_drainQueue(t=!1){if(!this.connected||0===this._queue.length)return;const e=this._queue[0];e.pending&&!t||(e.pending=!0,e.tryCount++,this.flags=e.flags,this.emit.apply(this,e.args))}packet(t){t.nsp=this.nsp,this.io._packet(t)}onopen(){"function"==typeof this.auth?this.auth(t=>{this._sendConnectPacket(t)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(t){this.packet({type:dt.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},t):t})}onerror(t){this.connected||this.emitReserved("connect_error",t)}onclose(t,e){this.connected=!1,delete this.id,this.emitReserved("disconnect",t,e),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(t=>{if(!this.sendBuffer.some(e=>String(e.id)===t)){const e=this.acks[t];delete this.acks[t],e.withError&&e.call(this,new Error("socket has been disconnected"))}})}onpacket(t){if(t.nsp===this.nsp)switch(t.type){case dt.CONNECT:t.data&&t.data.sid?this.onconnect(t.data.sid,t.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case dt.EVENT:case dt.BINARY_EVENT:this.onevent(t);break;case dt.ACK:case dt.BINARY_ACK:this.onack(t);break;case dt.DISCONNECT:this.ondisconnect();break;case dt.CONNECT_ERROR:this.destroy();const e=new Error(t.data.message);e.data=t.data.data,this.emitReserved("connect_error",e)}}onevent(t){const e=t.data||[];null!=t.id&&e.push(this.ack(t.id)),this.connected?this.emitEvent(e):this.receiveBuffer.push(Object.freeze(e))}emitEvent(t){if(this._anyListeners&&this._anyListeners.length){const e=this._anyListeners.slice();for(const s of e)s.apply(this,t)}super.emit.apply(this,t),this._pid&&t.length&&"string"==typeof t[t.length-1]&&(this._lastOffset=t[t.length-1])}ack(t){const e=this;let s=!1;return function(...n){s||(s=!0,e.packet({type:dt.ACK,id:t,data:n}))}}onack(t){const e=this.acks[t.id];"function"==typeof e&&(delete this.acks[t.id],e.withError&&t.data.unshift(null),e.apply(this,t.data))}onconnect(t,e){this.id=t,this.recovered=e&&this._pid===e,this._pid=e,this.connected=!0,this.emitBuffered(),this.emitReserved("connect"),this._drainQueue(!0)}emitBuffered(){this.receiveBuffer.forEach(t=>this.emitEvent(t)),this.receiveBuffer=[],this.sendBuffer.forEach(t=>{this.notifyOutgoingListeners(t),this.packet(t)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose("io server disconnect")}destroy(){this.subs&&(this.subs.forEach(t=>t()),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:dt.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}close(){return this.disconnect()}compress(t){return this.flags.compress=t,this}get volatile(){return this.flags.volatile=!0,this}timeout(t){return this.flags.timeout=t,this}onAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(t),this}prependAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(t),this}offAny(t){if(!this._anyListeners)return this;if(t){const e=this._anyListeners;for(let s=0;s<e.length;s++)if(t===e[s])return e.splice(s,1),this}else this._anyListeners=[];return this}listenersAny(){return this._anyListeners||[]}onAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(t),this}prependAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(t),this}offAnyOutgoing(t){if(!this._anyOutgoingListeners)return this;if(t){const e=this._anyOutgoingListeners;for(let s=0;s<e.length;s++)if(t===e[s])return e.splice(s,1),this}else this._anyOutgoingListeners=[];return this}listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}notifyOutgoingListeners(t){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){const e=this._anyOutgoingListeners.slice();for(const s of e)s.apply(this,t.data)}}}function _t(t){t=t||{},this.ms=t.min||100,this.max=t.max||1e4,this.factor=t.factor||2,this.jitter=t.jitter>0&&t.jitter<=1?t.jitter:0,this.attempts=0}_t.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),s=Math.floor(e*this.jitter*t);t=1&Math.floor(10*e)?t+s:t-s}return 0|Math.min(t,this.max)},_t.prototype.reset=function(){this.attempts=0},_t.prototype.setMin=function(t){this.ms=t},_t.prototype.setMax=function(t){this.max=t},_t.prototype.setJitter=function(t){this.jitter=t};class wt extends k{constructor(t,s){var n;super(),this.nsps={},this.subs=[],t&&"object"==typeof t&&(s=t,t=void 0),(s=s||{}).path=s.path||"/socket.io",this.opts=s,S(this,s),this.reconnection(!1!==s.reconnection),this.reconnectionAttempts(s.reconnectionAttempts||1/0),this.reconnectionDelay(s.reconnectionDelay||1e3),this.reconnectionDelayMax(s.reconnectionDelayMax||5e3),this.randomizationFactor(null!==(n=s.randomizationFactor)&&void 0!==n?n:.5),this.backoff=new _t({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(null==s.timeout?2e4:s.timeout),this._readyState="closed",this.uri=t;const i=s.parser||e;this.encoder=new i.Encoder,this.decoder=new i.Decoder,this._autoConnect=!1!==s.autoConnect,this._autoConnect&&this.open()}reconnection(t){return arguments.length?(this._reconnection=!!t,t||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(t){return void 0===t?this._reconnectionAttempts:(this._reconnectionAttempts=t,this)}reconnectionDelay(t){var e;return void 0===t?this._reconnectionDelay:(this._reconnectionDelay=t,null===(e=this.backoff)||void 0===e||e.setMin(t),this)}randomizationFactor(t){var e;return void 0===t?this._randomizationFactor:(this._randomizationFactor=t,null===(e=this.backoff)||void 0===e||e.setJitter(t),this)}reconnectionDelayMax(t){var e;return void 0===t?this._reconnectionDelayMax:(this._reconnectionDelayMax=t,null===(e=this.backoff)||void 0===e||e.setMax(t),this)}timeout(t){return arguments.length?(this._timeout=t,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&0===this.backoff.attempts&&this.reconnect()}open(t){if(~this._readyState.indexOf("open"))return this;this.engine=new Z(this.uri,this.opts);const e=this.engine,s=this;this._readyState="opening",this.skipReconnect=!1;const n=gt(e,"open",function(){s.onopen(),t&&t()}),i=e=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",e),t?t(e):this.maybeReconnectOnOpen()},r=gt(e,"error",i);if(!1!==this._timeout){const t=this._timeout,s=this.setTimeoutFn(()=>{n(),i(new Error("timeout")),e.close()},t);this.opts.autoUnref&&s.unref(),this.subs.push(()=>{this.clearTimeoutFn(s)})}return this.subs.push(n),this.subs.push(r),this}connect(t){return this.open(t)}onopen(){this.cleanup(),this._readyState="open",this.emitReserved("open");const t=this.engine;this.subs.push(gt(t,"ping",this.onping.bind(this)),gt(t,"data",this.ondata.bind(this)),gt(t,"error",this.onerror.bind(this)),gt(t,"close",this.onclose.bind(this)),gt(this.decoder,"decoded",this.ondecoded.bind(this)))}onping(){this.emitReserved("ping")}ondata(t){try{this.decoder.add(t)}catch(t){this.onclose("parse error",t)}}ondecoded(t){E(()=>{this.emitReserved("packet",t)},this.setTimeoutFn)}onerror(t){this.emitReserved("error",t)}socket(t,e){let s=this.nsps[t];return s?this._autoConnect&&!s.active&&s.connect():(s=new vt(this,t,e),this.nsps[t]=s),s}_destroy(t){const e=Object.keys(this.nsps);for(const t of e)if(this.nsps[t].active)return;this._close()}_packet(t){const e=this.encoder.encode(t);for(let s=0;s<e.length;s++)this.engine.write(e[s],t.options)}cleanup(){this.subs.forEach(t=>t()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close")}disconnect(){return this._close()}onclose(t,e){var s;this.cleanup(),null===(s=this.engine)||void 0===s||s.close(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",t,e),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;const t=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{const e=this.backoff.duration();this._reconnecting=!0;const s=this.setTimeoutFn(()=>{t.skipReconnect||(this.emitReserved("reconnect_attempt",t.backoff.attempts),t.skipReconnect||t.open(e=>{e?(t._reconnecting=!1,t.reconnect(),this.emitReserved("reconnect_error",e)):t.onreconnect()}))},e);this.opts.autoUnref&&s.unref(),this.subs.push(()=>{this.clearTimeoutFn(s)})}}onreconnect(){const t=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",t)}}const kt={};function Et(t,e){"object"==typeof t&&(e=t,t=void 0);const s=function(t,e="",s){let n=t;s=s||"undefined"!=typeof location&&location,null==t&&(t=s.protocol+"//"+s.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?s.protocol+t:s.host+t),/^(https?|wss?):\/\//.test(t)||(t=void 0!==s?s.protocol+"//"+t:"https://"+t),n=Y(t)),n.port||(/^(http|ws)$/.test(n.protocol)?n.port="80":/^(http|ws)s$/.test(n.protocol)&&(n.port="443")),n.path=n.path||"/";const i=-1!==n.host.indexOf(":")?"["+n.host+"]":n.host;return n.id=n.protocol+"://"+i+":"+n.port+e,n.href=n.protocol+"://"+i+(s&&s.port===n.port?"":":"+n.port),n}(t,(e=e||{}).path||"/socket.io"),n=s.source,i=s.id,r=s.path,o=kt[i]&&r in kt[i].nsps;let a;return e.forceNew||e["force new connection"]||!1===e.multiplex||o?a=new wt(n,e):(kt[i]||(kt[i]=new wt(n,e)),a=kt[i]),s.query&&!e.query&&(e.query=s.queryKey),a.socket(s.path,e)}Object.assign(Et,{Manager:wt,Socket:vt,io:Et,connect:Et});let Tt,Ct=null;function At(t){Tt=t}function Ot(){return Tt}class St{constructor(t,e,s){this.mediastream=t,this.ownerId=e,this.ownerName=s,this.id=e+"_usermedia",this.params={audio:!0,video:!1},this.setListeners()}isLocal(){return""===this.ownerId}static getCamera(t,e){return s=this,n=void 0,r=function*(){let s=yield navigator.mediaDevices.getUserMedia({video:t,audio:e});return new St(s,"","")},new((i=void 0)||(i=Promise))(function(t,e){function o(t){try{c(r.next(t))}catch(t){e(t)}}function a(t){try{c(r.throw(t))}catch(t){e(t)}}function c(e){e.done?t(e.value):function(t){return t instanceof i?t:new i(function(e){e(t)})}(e.value).then(o,a)}c((r=r.apply(s,n||[])).next())});var s,n,i,r}static getScreen(){}attachToElement(t){this.domElement=t,t.srcObject=this.mediastream,this.isLocal()&&this.disableAudio()}detachToElement(){this.domElement&&(this.domElement.srcObject=null)}muteVideo(){this.params.video=!1,this.conferencePublish&&this.conferencePublish.session.socketInteraction.setConstraint(this),this.mediastream.getVideoTracks()[0].enabled=!1}unmuteVideo(){this.params.video=!0,this.conferencePublish&&this.conferencePublish.session.socketInteraction.setConstraint(this),this.mediastream.getVideoTracks()[0].enabled=!0}muteAudio(){this.params.audio=!1,this.conferencePublish&&this.conferencePublish.session.socketInteraction.setConstraint(this),this.mediastream.getAudioTracks()[0].enabled=!1}unmuteAudio(){this.params.audio=!0,this.conferencePublish&&this.conferencePublish.session.socketInteraction.setConstraint(this),this.mediastream.getAudioTracks()[0].enabled=!0}disableAudio(){this.isLocal()&&this.domElement&&(this.domElement.muted=!0,this.domElement.volume=0,console.warn("disable audio for stream : ",this.ownerId,this.ownerName))}setListeners(){console.warn("ready to mute"),this.mediastream.getVideoTracks().forEach(t=>{t.addEventListener("mute",()=>{console.warn("MUTE")})})}}var Rt=function(t,e,s,n){return new(s||(s=Promise))(function(i,r){function o(t){try{c(n.next(t))}catch(t){r(t)}}function a(t){try{c(n.throw(t))}catch(t){r(t)}}function c(t){t.done?i(t.value):function(t){return t instanceof s?t:new s(function(e){e(t)})}(t.value).then(o,a)}c((n=n.apply(t,e||[])).next())})};class Lt extends EventTarget{constructor(){super(...arguments),this.senders=[],this.peerConnections={}}init(){return Rt(this,void 0,void 0,function*(){return this.socket=Et("http://localhost:3030"),new Promise((t,e)=>{this.socket.once("connect",()=>{var e;this._userId=this.socket.id,e=this.socket.id,Ct=e,this.setupSocketListeners(),t(this._userId)}),this.socket.once("connect_error",e),this.socket.once("error",e)})})}get userId(){if(!this._userId)throw new Error("Socket not connected yet");return this._userId}publish(t){this.localStream=t,Object.values(this.peerConnections).forEach(t=>{this.attachStreamToPeer(t)}),console.log("[RTC] Stream published to all peers")}unpublish(t){if(this.localStream!=t)throw new Error("this is not your stream");this.localStream=void 0,Object.values(this.peerConnections).forEach(t=>{this.removeStreamToPeer(t)}),console.log("[RTC] Unpublish stream")}setConstraint(t){if(this.localStream!=t)throw new Error("this is not your stream");Object.values(this.peerConnections).forEach(e=>{t.params.audio?this.enableTrackToPeer(e,t.mediastream.getAudioTracks()[0]):this.disableTrackToPeer(e,t.mediastream.getAudioTracks()[0]),t.params.video?this.enableTrackToPeer(e,t.mediastream.getVideoTracks()[0]):this.disableTrackToPeer(e,t.mediastream.getVideoTracks()[0])}),console.log("[RTC] Set constraint")}attachStreamToPeer(t){this.localStream&&this.localStream.mediastream.getTracks().forEach(e=>{const s=t.addTrack(e,this.localStream.mediastream);this.senders.push(s)})}removeStreamToPeer(t){this.localStream&&this.senders.forEach(e=>{t.removeTrack(e)})}disableTrackToPeer(t,e){this.localStream&&this.senders.forEach(s=>{s.track==e&&(t.getTransceivers()[1].direction="recvonly")})}enableTrackToPeer(t,e){this.localStream&&this.senders.forEach(s=>{s.track==e&&(t.getTransceivers()[1].direction="sendrecv")})}register(t){var e;this._confId=t;const s=null===(e=Ot())||void 0===e?void 0:e.contact;this.sendMessage({from:s.toString(),payload:{action:"join"}}),console.log(`[CONF] Join request sent for room ${t}`)}unregister(){Object.values(this.peerConnections).forEach(t=>t.close()),this.peerConnections={},this._confId=void 0,this.socket.disconnect(),console.log("[CONF] Unregistered and socket closed")}setupSocketListeners(){this.socket.on("message",t=>Rt(this,void 0,void 0,function*(){if(!this._confId)return;const{from:e,payload:s}=t;switch(s.action){case"join":console.log(`[RTC] Join received from ${e}`),yield this.createPeerConnection(e,!0);break;case"offer":console.log(`[RTC] Offer received from ${e}`),yield this.handleOffer(e,s.sdp);break;case"answer":console.log(`[RTC] Answer received from ${e}`),yield this.handleAnswer(e,s.sdp);break;case"ice":console.log(`[RTC] ICE received from ${e}`),yield this.handleIce(e,s.candidate);break;case"close":console.log(`[RTC] Peer ${s.disconnect} disconnected`),this.removePeer(s.disconnect),this.dispatchEvent(new CustomEvent("peopleLeave",{detail:{leaveId:s.disconnect}})),console.log("[Socket] leave"+s.disconnect)}}))}createPeerConnection(t,e){return Rt(this,void 0,void 0,function*(){var s;const n=t.id,i=t.name;if(this.peerConnections[n])return;const r=new RTCPeerConnection;this.peerConnections[n]=r,this.localStream&&this.attachStreamToPeer(r);const o=null===(s=Ot())||void 0===s?void 0:s.contact;if(r.ontrack=t=>{console.log("[RTC] Track received"),this.dispatchEvent(new CustomEvent("stream",{detail:{stream:new St(t.streams[0],n,i)}}))},r.onicecandidate=t=>{t.candidate&&this.sendMessage({from:o.toString(),target:n,payload:{action:"ice",candidate:t.candidate}})},e){const t=yield r.createOffer();yield r.setLocalDescription(t),this.sendMessage({from:o.toString(),target:n,payload:{action:"offer",sdp:t}})}})}handleOffer(t,e){return Rt(this,void 0,void 0,function*(){var s;const n=t.id;yield this.createPeerConnection(t,!1);const i=this.peerConnections[n];yield i.setRemoteDescription(new RTCSessionDescription(e));const r=yield i.createAnswer();yield i.setLocalDescription(r);let o=null===(s=Ot())||void 0===s?void 0:s.contact;this.sendMessage({from:o.toString(),target:n,payload:{action:"answer",sdp:r}});const a=new CustomEvent("newPeople",{detail:{contact:t}});this.dispatchEvent(a)})}handleAnswer(t,e){return Rt(this,void 0,void 0,function*(){const s=t.id,n=this.peerConnections[s];if(!n)return;yield n.setRemoteDescription(new RTCSessionDescription(e));const i=new CustomEvent("newPeople",{detail:{contact:t}});this.dispatchEvent(i)})}handleIce(t,e){return Rt(this,void 0,void 0,function*(){const s=t.id,n=this.peerConnections[s];n&&(yield n.addIceCandidate(e))})}removePeer(t){var e;null===(e=this.peerConnections[t])||void 0===e||e.close(),delete this.peerConnections[t]}sendMessage(t){this.socket.emit("message",t)}}var Bt=function(t,e,s,n){return new(s||(s=Promise))(function(i,r){function o(t){try{c(n.next(t))}catch(t){r(t)}}function a(t){try{c(n.throw(t))}catch(t){r(t)}}function c(t){t.done?i(t.value):function(t){return t instanceof s?t:new s(function(e){e(t)})}(t.value).then(o,a)}c((n=n.apply(t,e||[])).next())})};class Pt{constructor(t){this.name=t,this.socketInteraction=new Lt,this.contact=void 0}static create(t){return Bt(this,void 0,void 0,function*(){return Pt.session&&Pt.session.contact?(At(Pt.session),Pt.session):(Pt.initializing||(Pt.initializing=(()=>Bt(this,void 0,void 0,function*(){const e=new Pt(t);Pt.session=e;const n=yield e.socketInteraction.init();return e.contact=new s(n,t),At(e),Pt.initializing=void 0,e}))()),yield Pt.initializing)})}}class xt{printHello(){console.log("Hello from my-ts-package!")}}class Nt extends EventTarget{constructor(t,e){super(),this.session=e,this.name=t,this.id=2,this.knownStreams=[],this.knownContact=[],this.setupListener()}setupListener(){this.session.socketInteraction.addEventListener("stream",t=>{this.newStream(t)}),this.session.socketInteraction.addEventListener("peopleLeave",t=>{this.peopleLeave(t)}),this.session.socketInteraction.addEventListener("newPeople",t=>{this.newPeople(t)})}publish(t){this.knownStreams.includes(t)||(this.knownStreams.push(t),t.conferencePublish=this,this.session.socketInteraction.publish(t))}unpublish(t){if(this.knownStreams.includes(t)){try{this.session.socketInteraction.unpublish(t),t.conferencePublish=void 0}catch(t){return}this.knownStreams.push(t)}}join(){this.session.socketInteraction.register(this.id)}leave(){this.session.socketInteraction.unregister()}getMembers(){}newStream(t){if(this.knownStreams.includes(t.detail.stream))return;this.knownStreams.push(t.detail.stream);const e=new CustomEvent("newstream",{detail:{stream:t.detail.stream}});this.dispatchEvent(e)}peopleLeave(t){const e=new CustomEvent("peopleLeave",{detail:{leaveId:t.detail.leaveId}});console.log("[Conf] leave"+t.detail.leaveId),this.dispatchEvent(e)}newPeople(t){const e=new CustomEvent("newPeople",{detail:{contact:t.detail.contact}});console.log("[Conf] join"+t.detail.contact.name),this.dispatchEvent(e)}}export{Nt as Conference,s as Contact,xt as HelloWorld,Pt as Session,St as Stream};
package/dist/utils.d.ts CHANGED
@@ -1,9 +1,16 @@
1
- import { SocketInteraction } from "./core/SocketInteraction";
2
- declare const socketInteraction: SocketInteraction;
1
+ import { Session } from "./Session";
3
2
  declare function uidGenerator(): String;
4
3
  declare function setUserId(newId: string): void;
5
4
  declare function getId(): string | undefined;
5
+ declare function setCurrentSession(newSession: undefined | Session): void;
6
+ declare function getCurrentSession(): Session | undefined;
7
+ interface ContactInfo {
8
+ id: string;
9
+ name: string;
10
+ }
11
+ export { ContactInfo };
12
+ export { setCurrentSession };
13
+ export { getCurrentSession };
6
14
  export { setUserId };
7
15
  export { getId };
8
- export { socketInteraction };
9
16
  export { uidGenerator };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mitmi",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/Conference.ts CHANGED
@@ -1,37 +1,64 @@
1
+ import { Contact } from "./Contact";
2
+ import { Session } from "./Session";
1
3
  import { Stream } from "./Stream";
2
- import { socketInteraction } from "./utils";
4
+ import { getCurrentSession } from "./utils";
3
5
 
4
6
  class Conference extends EventTarget {
5
7
  name: string;
6
8
  id: number;
7
9
  knownStreams: Array<Stream | void>;
8
- constructor(name: string) {
10
+ knownContact: Array<Contact | void>;
11
+ session: Session;
12
+
13
+ constructor(name: string, session: Session) {
9
14
  super();
15
+ this.session = session;
16
+
10
17
  this.name = name;
11
18
  this.id = 2; //TODO change later for a random
12
19
  this.knownStreams = [];
20
+ this.knownContact = [];
13
21
  this.setupListener();
14
22
  }
15
23
 
16
24
  private setupListener() {
17
- socketInteraction.addEventListener("stream", (e) => {
25
+ this.session.socketInteraction.addEventListener("stream", (e) => {
18
26
  this.newStream(e);
19
27
  });
20
- socketInteraction.addEventListener("peopleLeave", (e) => {
28
+ this.session.socketInteraction.addEventListener("peopleLeave", (e) => {
21
29
  this.peopleLeave(e);
22
30
  });
31
+ this.session.socketInteraction.addEventListener("newPeople", (e) => {
32
+ this.newPeople(e);
33
+ });
23
34
  }
24
35
 
25
36
  publish(stream: Stream) {
26
- socketInteraction.publish(stream);
37
+ if (this.knownStreams.includes(stream)) return;
38
+
39
+ this.knownStreams.push(stream);
40
+ stream.conferencePublish = this;
41
+ this.session.socketInteraction.publish(stream);
42
+ }
43
+
44
+ unpublish(stream: Stream) {
45
+ if (!this.knownStreams.includes(stream)) return;
46
+
47
+ try {
48
+ this.session.socketInteraction.unpublish(stream);
49
+ stream.conferencePublish = undefined;
50
+ } catch (error) {
51
+ return;
52
+ }
53
+ this.knownStreams.push(stream);
27
54
  }
28
55
 
29
56
  join() {
30
- socketInteraction.register(this.id);
57
+ this.session.socketInteraction.register(this.id);
31
58
  }
32
59
 
33
60
  leave() {
34
- socketInteraction.unregister();
61
+ this.session.socketInteraction.unregister();
35
62
  }
36
63
  getMembers() {}
37
64
 
@@ -55,6 +82,16 @@ class Conference extends EventTarget {
55
82
  console.log("[Conf] leave" + e.detail.leaveId);
56
83
  this.dispatchEvent(newevent);
57
84
  }
85
+
86
+ private newPeople(e: any) {
87
+ const newevent = new CustomEvent("newPeople", {
88
+ detail: {
89
+ contact: e.detail.contact,
90
+ },
91
+ });
92
+ console.log("[Conf] join" + e.detail.contact.name);
93
+ this.dispatchEvent(newevent);
94
+ }
58
95
  }
59
96
 
60
97
  export { Conference };
package/src/Contact.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { ContactInfo } from "./utils";
2
+
3
+ class Contact {
4
+ id: string;
5
+ name: string;
6
+
7
+ constructor(id: string, name: string) {
8
+ this.name = name;
9
+ this.id = id;
10
+ }
11
+
12
+ toString(): ContactInfo {
13
+ return {
14
+ id: this.id,
15
+ name: this.name,
16
+ };
17
+ }
18
+ }
19
+
20
+ export { Contact };
package/src/Session.ts ADDED
@@ -0,0 +1,48 @@
1
+ import { Contact } from "./Contact";
2
+ import { Conference } from "./Conference";
3
+ import { SocketInteraction } from "./core/SocketInteraction";
4
+ import { setCurrentSession } from "./utils";
5
+
6
+ class Session {
7
+ name: string;
8
+ socketInteraction: SocketInteraction;
9
+ contact?: Contact;
10
+ private static session: Session;
11
+ private static initializing?: Promise<Session>;
12
+
13
+ private constructor(name: string) {
14
+ this.name = name;
15
+ this.socketInteraction = new SocketInteraction();
16
+ this.contact = undefined;
17
+ }
18
+
19
+ static async create(name: string): Promise<Session> {
20
+ // tout le tralala ici c'est pour eviter que React appel 2 fois create et cree 2 socket
21
+ // Dans un cas de Singleton classique, Session est bien retourné mais pas la bonne car la socket et donc le contact ne sont pas bien initialisés
22
+ if (Session.session && Session.session.contact) {
23
+ setCurrentSession(Session.session);
24
+ return Session.session;
25
+ }
26
+
27
+ if (Session.initializing) {
28
+ return await Session.initializing;
29
+ }
30
+
31
+ Session.initializing = (async () => {
32
+ const session = new Session(name);
33
+ Session.session = session;
34
+
35
+ const socketId = await session.socketInteraction.init();
36
+ session.contact = new Contact(socketId, name);
37
+
38
+ setCurrentSession(session);
39
+ Session.initializing = undefined;
40
+
41
+ return session;
42
+ })();
43
+
44
+ return await Session.initializing;
45
+ }
46
+ }
47
+
48
+ export { Session };
package/src/Stream.ts CHANGED
@@ -1,20 +1,37 @@
1
+ import { Conference } from "./Conference";
1
2
  import { uidGenerator, getId } from "./utils";
2
3
 
4
+ export interface StreamParams {
5
+ audio: boolean;
6
+ video: boolean;
7
+ }
8
+
3
9
  class Stream {
4
10
  mediastream: MediaStream;
5
11
  domElement: undefined | HTMLVideoElement;
6
- owner: string;
12
+ ownerId: string;
13
+ ownerName: string;
7
14
  id: String;
15
+ //If undefined, its a localstream otherwise the stream is publish
16
+ conferencePublish?: Conference;
17
+ params: StreamParams;
8
18
 
9
19
  /**
10
20
  *
11
21
  * @param mediastream
12
22
  * @param owner "" => ourself, id instead
13
23
  */
14
- constructor(mediastream: MediaStream, owner: string) {
24
+ constructor(mediastream: MediaStream, ownerId: string, ownerName: string) {
15
25
  this.mediastream = mediastream;
16
- this.owner = owner;
17
- this.id = owner + "_usermedia";
26
+ this.ownerId = ownerId;
27
+ this.ownerName = ownerName;
28
+ this.id = ownerId + "_usermedia";
29
+ this.params = { audio: true, video: false };
30
+ this.setListeners();
31
+ }
32
+
33
+ isLocal(): boolean {
34
+ return this.ownerId === "";
18
35
  }
19
36
 
20
37
  static async getCamera(video: boolean, audio: boolean): Promise<Stream> {
@@ -22,7 +39,7 @@ class Stream {
22
39
  video: video,
23
40
  audio: audio,
24
41
  });
25
- let newStream = new Stream(mediastream, "");
42
+ let newStream = new Stream(mediastream, "", "");
26
43
  return newStream;
27
44
  }
28
45
  static getScreen() {}
@@ -30,6 +47,10 @@ class Stream {
30
47
  attachToElement(domElement: HTMLVideoElement): void {
31
48
  this.domElement = domElement;
32
49
  domElement.srcObject = this.mediastream;
50
+
51
+ if (this.isLocal()) {
52
+ this.disableAudio();
53
+ }
33
54
  }
34
55
 
35
56
  detachToElement(): void {
@@ -37,13 +58,69 @@ class Stream {
37
58
  this.domElement.srcObject = null;
38
59
  }
39
60
 
61
+ /**
62
+ * If the stream is published (so its yours) :
63
+ * - video will be disabled for everyone
64
+ * If the stream is not published (its yours but not publish, or other ppl stream):
65
+ * - video will be disabled for you only
66
+ */
67
+ muteVideo() {
68
+ this.params.video = false;
69
+ if (this.conferencePublish) {
70
+ //your publish stream
71
+ this.conferencePublish.session.socketInteraction.setConstraint(this);
72
+ }
73
+ this.mediastream.getVideoTracks()[0].enabled = false;
74
+ }
75
+
76
+ unmuteVideo() {
77
+ this.params.video = true;
78
+ if (this.conferencePublish) {
79
+ //your publish stream
80
+ this.conferencePublish.session.socketInteraction.setConstraint(this);
81
+ }
82
+ this.mediastream.getVideoTracks()[0].enabled = true;
83
+ }
84
+
40
85
  muteAudio(): void {
86
+ this.params.audio = false;
87
+ if (this.conferencePublish) {
88
+ this.conferencePublish.session.socketInteraction.setConstraint(this);
89
+ }
41
90
  this.mediastream.getAudioTracks()[0].enabled = false;
42
91
  }
43
92
 
44
93
  unmuteAudio(): void {
94
+ this.params.audio = true;
95
+ if (this.conferencePublish) {
96
+ this.conferencePublish.session.socketInteraction.setConstraint(this);
97
+ }
45
98
  this.mediastream.getAudioTracks()[0].enabled = true;
46
99
  }
100
+
101
+ /**
102
+ * This function exist to avoir Larsen.
103
+ * You need to call here when a localstream is started.
104
+ */
105
+ disableAudio(): void {
106
+ if (!this.isLocal()) return;
107
+ if (!this.domElement) return;
108
+
109
+ // Important: cette ligne n'affecte pas l'envoi audio
110
+ this.domElement.muted = true;
111
+ this.domElement.volume = 0;
112
+
113
+ console.warn("disable audio for stream : ", this.ownerId, this.ownerName);
114
+ }
115
+
116
+ private setListeners() {
117
+ console.warn("ready to mute");
118
+ this.mediastream.getVideoTracks().forEach((track) => {
119
+ track.addEventListener("mute", () => {
120
+ console.warn("MUTE");
121
+ });
122
+ });
123
+ }
47
124
  }
48
125
 
49
126
  export { Stream };
@@ -1,10 +1,11 @@
1
1
  import { io, Socket } from "socket.io-client";
2
2
  import { localServerUrl, serverUrl } from "../constants";
3
- import { setUserId } from "../utils";
4
- import { Stream } from "../Stream";
3
+ import { getCurrentSession, setUserId } from "../utils";
4
+ import { Stream, StreamParams } from "../Stream";
5
+ import { ContactInfo } from "../utils";
5
6
 
6
7
  interface SocketMessage {
7
- from: string;
8
+ from: ContactInfo;
8
9
  target?: string;
9
10
  payload: {
10
11
  action: "join" | "offer" | "answer" | "ice" | "close";
@@ -19,11 +20,12 @@ export class SocketInteraction extends EventTarget {
19
20
  private socket!: Socket;
20
21
  private _userId?: string;
21
22
  private _confId?: number;
22
- private publishStream?: Stream;
23
+ private localStream?: Stream;
24
+ private senders: Array<RTCRtpSender> = [];
23
25
 
24
26
  private peerConnections: Record<string, RTCPeerConnection> = {};
25
27
 
26
- async init(): Promise<void> {
28
+ async init(): Promise<string> {
27
29
  this.socket = io(serverUrl);
28
30
 
29
31
  return new Promise((resolve, reject) => {
@@ -31,7 +33,7 @@ export class SocketInteraction extends EventTarget {
31
33
  this._userId = this.socket.id;
32
34
  setUserId(this.socket.id!);
33
35
  this.setupSocketListeners();
34
- resolve();
36
+ resolve(this._userId!);
35
37
  });
36
38
 
37
39
  this.socket.once("connect_error", reject);
@@ -40,23 +42,106 @@ export class SocketInteraction extends EventTarget {
40
42
  }
41
43
 
42
44
  get userId(): string {
43
- if (!this._userId) throw new Error("User not connected yet");
45
+ if (!this._userId) throw new Error("Socket not connected yet");
44
46
  return this._userId;
45
47
  }
46
48
 
47
49
  publish(stream: Stream) {
48
- this.publishStream = stream;
50
+ this.localStream = stream;
51
+
52
+ Object.values(this.peerConnections).forEach((pc) => {
53
+ this.attachStreamToPeer(pc);
54
+ });
55
+
56
+ console.log("[RTC] Stream published to all peers");
57
+ }
58
+
59
+ unpublish(stream: Stream) {
60
+ if (this.localStream != stream) throw new Error("this is not your stream");
61
+ this.localStream = undefined;
62
+
63
+ Object.values(this.peerConnections).forEach((pc) => {
64
+ this.removeStreamToPeer(pc);
65
+ });
66
+
67
+ console.log("[RTC] Unpublish stream");
68
+ }
69
+
70
+ /**
71
+ *
72
+ * @param stream Stream have stream.params, use to set constraint on the peer
73
+ */
74
+ setConstraint(stream: Stream) {
75
+ if (this.localStream != stream) throw new Error("this is not your stream");
76
+
77
+ Object.values(this.peerConnections).forEach((pc) => {
78
+ if (!stream.params.audio) {
79
+ // si false on desactive
80
+ this.disableTrackToPeer(pc, stream.mediastream.getAudioTracks()[0]);
81
+ } else {
82
+ // si true on reactive
83
+ this.enableTrackToPeer(pc, stream.mediastream.getAudioTracks()[0]);
84
+ }
85
+ if (!stream.params.video) {
86
+ this.disableTrackToPeer(pc, stream.mediastream.getVideoTracks()[0]);
87
+ } else {
88
+ this.enableTrackToPeer(pc, stream.mediastream.getVideoTracks()[0]);
89
+ }
90
+ });
91
+
92
+ console.log("[RTC] Set constraint");
93
+ }
94
+
95
+ private attachStreamToPeer(pc: RTCPeerConnection) {
96
+ if (!this.localStream) return;
97
+
98
+ this.localStream.mediastream.getTracks().forEach((track) => {
99
+ const sender = pc.addTrack(track, this.localStream!.mediastream);
100
+ this.senders.push(sender);
101
+ });
102
+ }
103
+
104
+ private removeStreamToPeer(pc: RTCPeerConnection) {
105
+ if (!this.localStream) return;
106
+
107
+ this.senders.forEach((sender) => {
108
+ pc.removeTrack(sender);
109
+ });
110
+ }
111
+
112
+ private disableTrackToPeer(pc: RTCPeerConnection, track: MediaStreamTrack) {
113
+ if (!this.localStream) return;
114
+
115
+ this.senders.forEach((sender) => {
116
+ if (sender.track == track) {
117
+ const transceivers = pc.getTransceivers();
118
+ const videoTrack = transceivers[1];
119
+ videoTrack.direction = "recvonly";
120
+ }
121
+ });
122
+ }
123
+
124
+ private enableTrackToPeer(pc: RTCPeerConnection, track: MediaStreamTrack) {
125
+ if (!this.localStream) return;
126
+
127
+ this.senders.forEach((sender) => {
128
+ if (sender.track == track) {
129
+ const transceivers = pc.getTransceivers();
130
+ const videoTrack = transceivers[1];
131
+ videoTrack.direction = "sendrecv";
132
+ }
133
+ });
49
134
  }
50
135
 
51
136
  register(confId: number) {
52
- if (!this.publishStream) {
137
+ /*if (!this.publishStream) {
53
138
  throw new Error("Call publish() before register()");
54
- }
139
+ }*/
55
140
 
56
141
  this._confId = confId;
57
-
142
+ const sender = getCurrentSession()?.contact!;
58
143
  this.sendMessage({
59
- from: this.userId,
144
+ from: sender.toString(),
60
145
  payload: { action: "join" },
61
146
  });
62
147
 
@@ -115,22 +200,27 @@ export class SocketInteraction extends EventTarget {
115
200
  });
116
201
  }
117
202
 
118
- private async createPeerConnection(remoteUserId: string, initiator: boolean) {
203
+ private async createPeerConnection(from: ContactInfo, initiator: boolean) {
204
+ const remoteUserId = from.id;
205
+ const remoteUserName = from.name;
119
206
  if (this.peerConnections[remoteUserId]) return; //existe deja
120
207
 
121
208
  const pc = new RTCPeerConnection();
122
209
  this.peerConnections[remoteUserId] = pc;
123
210
 
124
- // add local tracks
125
- this.publishStream?.mediastream.getTracks().forEach((track) => {
126
- pc.addTrack(track, this.publishStream!.mediastream);
127
- });
211
+ if (this.localStream) {
212
+ this.attachStreamToPeer(pc);
213
+ }
214
+
215
+ const sender = getCurrentSession()?.contact!;
128
216
 
129
217
  pc.ontrack = (event) => {
130
218
  console.log("[RTC] Track received");
131
219
  this.dispatchEvent(
132
220
  new CustomEvent("stream", {
133
- detail: { stream: new Stream(event.streams[0], remoteUserId) },
221
+ detail: {
222
+ stream: new Stream(event.streams[0], remoteUserId, remoteUserName),
223
+ },
134
224
  })
135
225
  );
136
226
  };
@@ -138,7 +228,7 @@ export class SocketInteraction extends EventTarget {
138
228
  pc.onicecandidate = (event) => {
139
229
  if (event.candidate) {
140
230
  this.sendMessage({
141
- from: this.userId,
231
+ from: sender.toString(),
142
232
  target: remoteUserId,
143
233
  payload: { action: "ice", candidate: event.candidate },
144
234
  });
@@ -150,41 +240,64 @@ export class SocketInteraction extends EventTarget {
150
240
  await pc.setLocalDescription(offer);
151
241
 
152
242
  this.sendMessage({
153
- from: this.userId,
243
+ from: sender.toString(),
154
244
  target: remoteUserId,
155
- payload: { action: "offer", sdp: offer },
245
+ payload: {
246
+ action: "offer",
247
+ sdp: offer,
248
+ },
156
249
  });
157
250
  }
158
251
  }
159
252
 
160
- private async handleOffer(from: string, sdp: RTCSessionDescriptionInit) {
253
+ private async handleOffer(from: ContactInfo, sdp: RTCSessionDescriptionInit) {
254
+ const remoteUserId = from.id;
161
255
  await this.createPeerConnection(from, false);
162
256
 
163
- const pc = this.peerConnections[from];
257
+ const pc = this.peerConnections[remoteUserId];
164
258
  await pc.setRemoteDescription(new RTCSessionDescription(sdp));
165
259
 
166
260
  const answer = await pc.createAnswer();
167
261
  await pc.setLocalDescription(answer);
262
+ let sender = getCurrentSession()?.contact!;
168
263
 
169
264
  this.sendMessage({
170
- from: this.userId,
171
- target: from,
172
- payload: { action: "answer", sdp: answer },
265
+ from: sender.toString(),
266
+ target: remoteUserId,
267
+ payload: {
268
+ action: "answer",
269
+ sdp: answer,
270
+ },
173
271
  });
174
272
 
175
- this.dispatchEvent(new CustomEvent("newPeople"));
273
+ const event: CustomEvent = new CustomEvent("newPeople", {
274
+ detail: {
275
+ contact: from,
276
+ },
277
+ });
278
+ this.dispatchEvent(event);
176
279
  }
177
280
 
178
- private async handleAnswer(from: string, sdp: RTCSessionDescriptionInit) {
179
- const pc = this.peerConnections[from];
281
+ private async handleAnswer(
282
+ from: ContactInfo,
283
+ sdp: RTCSessionDescriptionInit
284
+ ) {
285
+ const remoteUserId = from.id;
286
+ const pc = this.peerConnections[remoteUserId];
180
287
  if (!pc) return;
181
288
 
182
289
  await pc.setRemoteDescription(new RTCSessionDescription(sdp));
183
- this.dispatchEvent(new CustomEvent("newPeople"));
290
+ const event: CustomEvent = new CustomEvent("newPeople", {
291
+ detail: {
292
+ contact: from,
293
+ },
294
+ });
295
+ this.dispatchEvent(event);
184
296
  }
185
297
 
186
- private async handleIce(from: string, candidate: RTCIceCandidate) {
187
- const pc = this.peerConnections[from];
298
+ private async handleIce(from: ContactInfo, candidate: RTCIceCandidate) {
299
+ const remoteUserId = from.id;
300
+ const pc = this.peerConnections[remoteUserId];
188
301
  if (!pc) return;
189
302
 
190
303
  await pc.addIceCandidate(candidate);
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export { Contact } from "./Contact";
2
+ export { Session } from "./Session";
1
3
  export { HelloWorld } from "./HelloWorld";
2
4
  export { Stream } from "./Stream";
3
5
  export { Conference } from "./Conference";
package/src/utils.ts CHANGED
@@ -1,7 +1,4 @@
1
- import { SocketInteraction } from "./core/SocketInteraction";
2
-
3
- const socketInteraction = new SocketInteraction();
4
- socketInteraction.init();
1
+ import { Session } from "./Session";
5
2
 
6
3
  function uidGenerator(): String {
7
4
  var S4 = function () {
@@ -31,7 +28,22 @@ function getId() {
31
28
  return userId;
32
29
  }
33
30
 
31
+ let currentSession: Session | undefined = undefined;
32
+ function setCurrentSession(newSession: undefined | Session) {
33
+ currentSession = newSession;
34
+ }
35
+ function getCurrentSession() {
36
+ return currentSession;
37
+ }
38
+
39
+ interface ContactInfo {
40
+ id: string;
41
+ name: string;
42
+ }
43
+
44
+ export { ContactInfo };
45
+ export { setCurrentSession };
46
+ export { getCurrentSession };
34
47
  export { setUserId };
35
48
  export { getId };
36
- export { socketInteraction };
37
49
  export { uidGenerator };