@supabase/phoenix 0.1.0 → 0.3.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.
@@ -358,7 +358,7 @@ var Phoenix = (() => {
358
358
  this.rejoinTimer.reset();
359
359
  this.joinPush.destroy();
360
360
  this.state = CHANNEL_STATES.closed;
361
- this.bindings = {};
361
+ this.bindings = [];
362
362
  }
363
363
  /**
364
364
  * Hook into channel close
@@ -1230,7 +1230,7 @@ var Phoenix = (() => {
1230
1230
  this.pageHidden = true;
1231
1231
  } else {
1232
1232
  this.pageHidden = false;
1233
- if (!this.isConnected()) {
1233
+ if (!this.isConnected() && !this.closeWasClean) {
1234
1234
  this.teardown(() => this.connect());
1235
1235
  }
1236
1236
  }
@@ -1459,6 +1459,19 @@ var Phoenix = (() => {
1459
1459
  });
1460
1460
  return true;
1461
1461
  }
1462
+ /**
1463
+ * @private
1464
+ *
1465
+ * @param {Function}
1466
+ */
1467
+ transportName(transport) {
1468
+ switch (transport) {
1469
+ case LongPoll:
1470
+ return "LongPoll";
1471
+ default:
1472
+ return transport.name;
1473
+ }
1474
+ }
1462
1475
  /**
1463
1476
  * @private
1464
1477
  */
@@ -1488,14 +1501,15 @@ var Phoenix = (() => {
1488
1501
  let established = false;
1489
1502
  let primaryTransport = true;
1490
1503
  let openRef, errorRef;
1504
+ let fallbackTransportName = this.transportName(fallbackTransport);
1491
1505
  let fallback = (reason) => {
1492
- this.log("transport", `falling back to ${fallbackTransport.name}...`, reason);
1506
+ this.log("transport", `falling back to ${fallbackTransportName}...`, reason);
1493
1507
  this.off([openRef, errorRef]);
1494
1508
  primaryTransport = false;
1495
1509
  this.replaceTransport(fallbackTransport);
1496
1510
  this.transportConnect();
1497
1511
  };
1498
- if (this.getSession(`phx:fallback:${fallbackTransport.name}`)) {
1512
+ if (this.getSession(`phx:fallback:${fallbackTransportName}`)) {
1499
1513
  return fallback("memorized");
1500
1514
  }
1501
1515
  this.fallbackTimer = setTimeout(fallback, fallbackThreshold);
@@ -1512,10 +1526,11 @@ var Phoenix = (() => {
1512
1526
  this.fallbackRef = this.onOpen(() => {
1513
1527
  established = true;
1514
1528
  if (!primaryTransport) {
1529
+ let fallbackTransportName2 = this.transportName(fallbackTransport);
1515
1530
  if (!this.primaryPassedHealthCheck) {
1516
- this.storeSession(`phx:fallback:${fallbackTransport.name}`, "true");
1531
+ this.storeSession(`phx:fallback:${fallbackTransportName2}`, "true");
1517
1532
  }
1518
- return this.log("transport", `established ${fallbackTransport.name} fallback`);
1533
+ return this.log("transport", `established ${fallbackTransportName2} fallback`);
1519
1534
  }
1520
1535
  clearTimeout(this.fallbackTimer);
1521
1536
  this.fallbackTimer = setTimeout(fallback, fallbackThreshold);
@@ -1,2 +1,2 @@
1
- "use strict";var Phoenix=(()=>{var L=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var I=(a,e)=>{for(var t in e)L(a,t,{get:e[t],enumerable:!0})},F=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of U(e))!D.call(a,s)&&s!==t&&L(a,s,{get:()=>e[s],enumerable:!(i=M(e,s))||i.enumerable});return a};var J=a=>F(L({},"__esModule",{value:!0}),a);var N=(a,e,t)=>new Promise((i,s)=>{var o=h=>{try{r(t.next(h))}catch(l){s(l)}},n=h=>{try{r(t.throw(h))}catch(l){s(l)}},r=h=>h.done?i(h.value):Promise.resolve(h.value).then(o,n);r((t=t.apply(a,e)).next())});var K={};I(K,{Channel:()=>v,LongPoll:()=>m,Presence:()=>w,Push:()=>T,Serializer:()=>y,Socket:()=>_,Timer:()=>b});var k=a=>typeof a=="function"?a:function(){return a};var z=typeof self!="undefined"?self:null,R=typeof window!="undefined"?window:null,d=z||R||globalThis,O="2.0.0",B=1e4,P=1e3,p={connecting:0,open:1,closing:2,closed:3},u={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},g={close:"phx_close",error:"phx_error",join:"phx_join",reply:"phx_reply",leave:"phx_leave"},j={longpoll:"longpoll",websocket:"websocket"},$={complete:4},A="base64url.bearer.phx.";var T=class{constructor(e,t,i,s){this.channel=e,this.event=t,this.payload=i||function(){return{}},this.receivedResp=null,this.timeout=s,this.timeoutTimer=null,this.recHooks=[],this.sent=!1,this.ref=void 0}resend(e){this.timeout=e,this.reset(),this.send()}send(){this.hasReceived("timeout")||(this.startTimeout(),this.sent=!0,this.channel.socket.push({topic:this.channel.topic,event:this.event,payload:this.payload(),ref:this.ref,join_ref:this.channel.joinRef()}))}receive(e,t){return this.hasReceived(e)&&t(this.receivedResp.response),this.recHooks.push({status:e,callback:t}),this}reset(){this.cancelRefEvent(),this.ref=null,this.refEvent=null,this.receivedResp=null,this.sent=!1}destroy(){this.cancelRefEvent(),this.cancelTimeout()}matchReceive({status:e,response:t,_ref:i}){this.recHooks.filter(s=>s.status===e).forEach(s=>s.callback(t))}cancelRefEvent(){this.refEvent&&this.channel.off(this.refEvent)}cancelTimeout(){clearTimeout(this.timeoutTimer),this.timeoutTimer=null}startTimeout(){this.timeoutTimer&&this.cancelTimeout(),this.ref=this.channel.socket.makeRef(),this.refEvent=this.channel.replyEventName(this.ref),this.channel.on(this.refEvent,e=>{this.cancelRefEvent(),this.cancelTimeout(),this.receivedResp=e,this.matchReceive(e)}),this.timeoutTimer=setTimeout(()=>{this.trigger("timeout",{})},this.timeout)}hasReceived(e){return this.receivedResp&&this.receivedResp.status===e}trigger(e,t){this.channel.trigger(this.refEvent,{status:e,response:t})}};var b=class{constructor(e,t){this.callback=e,this.timerCalc=t,this.timer=void 0,this.tries=0}reset(){this.tries=0,clearTimeout(this.timer)}scheduleTimeout(){clearTimeout(this.timer),this.timer=setTimeout(()=>{this.tries=this.tries+1,this.callback()},this.timerCalc(this.tries+1))}};var v=class{constructor(e,t,i){this.state=u.closed,this.topic=e,this.params=k(t||{}),this.socket=i,this.bindings=[],this.bindingRef=0,this.timeout=this.socket.timeout,this.joinedOnce=!1,this.joinPush=new T(this,g.join,this.params,this.timeout),this.pushBuffer=[],this.stateChangeRefs=[],this.rejoinTimer=new b(()=>{this.socket.isConnected()&&this.rejoin()},this.socket.rejoinAfterMs),this.stateChangeRefs.push(this.socket.onError(()=>this.rejoinTimer.reset())),this.stateChangeRefs.push(this.socket.onOpen(()=>{this.rejoinTimer.reset(),this.isErrored()&&this.rejoin()})),this.joinPush.receive("ok",()=>{this.state=u.joined,this.rejoinTimer.reset(),this.pushBuffer.forEach(s=>s.send()),this.pushBuffer=[]}),this.joinPush.receive("error",s=>{this.state=u.errored,this.socket.hasLogger()&&this.socket.log("channel",`error ${this.topic}`,s),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.onClose(()=>{this.rejoinTimer.reset(),this.socket.hasLogger()&&this.socket.log("channel",`close ${this.topic}`),this.state=u.closed,this.socket.remove(this)}),this.onError(s=>{this.socket.hasLogger()&&this.socket.log("channel",`error ${this.topic}`,s),this.isJoining()&&this.joinPush.reset(),this.state=u.errored,this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.joinPush.receive("timeout",()=>{this.socket.hasLogger()&&this.socket.log("channel",`timeout ${this.topic}`,this.joinPush.timeout),new T(this,g.leave,k({}),this.timeout).send(),this.state=u.errored,this.joinPush.reset(),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.on(g.reply,(s,o)=>{this.trigger(this.replyEventName(o),s)})}join(e=this.timeout){if(this.joinedOnce)throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance");return this.timeout=e,this.joinedOnce=!0,this.rejoin(),this.joinPush}teardown(){this.pushBuffer.forEach(e=>e.destroy()),this.pushBuffer=[],this.rejoinTimer.reset(),this.joinPush.destroy(),this.state=u.closed,this.bindings={}}onClose(e){this.on(g.close,e)}onError(e){return this.on(g.error,t=>e(t))}on(e,t){let i=this.bindingRef++;return this.bindings.push({event:e,ref:i,callback:t}),i}off(e,t){this.bindings=this.bindings.filter(i=>!(i.event===e&&(typeof t=="undefined"||t===i.ref)))}canPush(){return this.socket.isConnected()&&this.isJoined()}push(e,t,i=this.timeout){if(t=t||{},!this.joinedOnce)throw new Error(`tried to push '${e}' to '${this.topic}' before joining. Use channel.join() before pushing events`);let s=new T(this,e,function(){return t},i);return this.canPush()?s.send():(s.startTimeout(),this.pushBuffer.push(s)),s}leave(e=this.timeout){this.rejoinTimer.reset(),this.joinPush.cancelTimeout(),this.state=u.leaving;let t=()=>{this.socket.hasLogger()&&this.socket.log("channel",`leave ${this.topic}`),this.trigger(g.close,"leave")},i=new T(this,g.leave,k({}),e);return i.receive("ok",()=>t()).receive("timeout",()=>t()),i.send(),this.canPush()||i.trigger("ok",{}),i}onMessage(e,t,i){return t}filterBindings(e,t,i){return!0}isMember(e,t,i,s){return this.topic!==e?!1:s&&s!==this.joinRef()?(this.socket.hasLogger()&&this.socket.log("channel","dropping outdated message",{topic:e,event:t,payload:i,joinRef:s}),!1):!0}joinRef(){return this.joinPush.ref}rejoin(e=this.timeout){this.isLeaving()||(this.socket.leaveOpenTopic(this.topic),this.state=u.joining,this.joinPush.resend(e))}trigger(e,t,i,s){let o=this.onMessage(e,t,i,s);if(t&&!o)throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");let n=this.bindings.filter(r=>r.event===e&&this.filterBindings(r,t,i));for(let r=0;r<n.length;r++)n[r].callback(o,i,s||this.joinRef())}replyEventName(e){return`chan_reply_${e}`}isClosed(){return this.state===u.closed}isErrored(){return this.state===u.errored}isJoined(){return this.state===u.joined}isJoining(){return this.state===u.joining}isLeaving(){return this.state===u.leaving}};var C=class{static request(e,t,i,s,o,n,r){if(d.XDomainRequest){let h=new d.XDomainRequest;return this.xdomainRequest(h,e,t,s,o,n,r)}else if(d.XMLHttpRequest){let h=new d.XMLHttpRequest;return this.xhrRequest(h,e,t,i,s,o,n,r)}else{if(d.fetch&&d.AbortController)return this.fetchRequest(e,t,i,s,o,n,r);throw new Error("No suitable XMLHttpRequest implementation found")}}static fetchRequest(e,t,i,s,o,n,r){let h={method:e,headers:i,body:s},l=null;if(o){l=new AbortController;let c=setTimeout(()=>l.abort(),o);h.signal=l.signal}return d.fetch(t,h).then(c=>c.text()).then(c=>this.parseJSON(c)).then(c=>r&&r(c)).catch(c=>{c.name==="AbortError"&&n?n():r&&r(null)}),l}static xdomainRequest(e,t,i,s,o,n,r){return e.timeout=o,e.open(t,i),e.onload=()=>{let h=this.parseJSON(e.responseText);r&&r(h)},n&&(e.ontimeout=n),e.onprogress=()=>{},e.send(s),e}static xhrRequest(e,t,i,s,o,n,r,h){e.open(t,i,!0),e.timeout=n;for(let[l,c]of Object.entries(s))e.setRequestHeader(l,c);return e.onerror=()=>h&&h(null),e.onreadystatechange=()=>{if(e.readyState===$.complete&&h){let l=this.parseJSON(e.responseText);h(l)}},r&&(e.ontimeout=r),e.send(o),e}static parseJSON(e){if(!e||e==="")return null;try{return JSON.parse(e)}catch(t){return console&&console.log("failed to parse JSON response",e),null}}static serialize(e,t){let i=[];for(var s in e){if(!Object.prototype.hasOwnProperty.call(e,s))continue;let o=t?`${t}[${s}]`:s,n=e[s];typeof n=="object"?i.push(this.serialize(n,o)):i.push(encodeURIComponent(o)+"="+encodeURIComponent(n))}return i.join("&")}static appendParams(e,t){if(Object.keys(t).length===0)return e;let i=e.match(/\?/)?"&":"?";return`${e}${i}${this.serialize(t)}`}};var W=a=>{let e="",t=new Uint8Array(a),i=t.byteLength;for(let s=0;s<i;s++)e+=String.fromCharCode(t[s]);return btoa(e)},m=class{constructor(e,t){t&&t.length===2&&t[1].startsWith(A)&&(this.authToken=atob(t[1].slice(A.length))),this.endPoint=null,this.token=null,this.skipHeartbeat=!0,this.reqs=new Set,this.awaitingBatchAck=!1,this.currentBatch=null,this.currentBatchTimer=null,this.batchBuffer=[],this.onopen=function(){},this.onerror=function(){},this.onmessage=function(){},this.onclose=function(){},this.pollEndpoint=this.normalizeEndpoint(e),this.readyState=p.connecting,setTimeout(()=>this.poll(),0)}normalizeEndpoint(e){return e.replace("ws://","http://").replace("wss://","https://").replace(new RegExp("(.*)/"+j.websocket),"$1/"+j.longpoll)}endpointURL(){return C.appendParams(this.pollEndpoint,{token:this.token})}closeAndRetry(e,t,i){this.close(e,t,i),this.readyState=p.connecting}ontimeout(){this.onerror("timeout"),this.closeAndRetry(1005,"timeout",!1)}isActive(){return this.readyState===p.open||this.readyState===p.connecting}poll(){let e={Accept:"application/json"};this.authToken&&(e["X-Phoenix-AuthToken"]=this.authToken),this.ajax("GET",e,null,()=>this.ontimeout(),t=>{if(t){var{status:i,token:s,messages:o}=t;if(i===410&&this.token!==null){this.onerror(410),this.closeAndRetry(3410,"session_gone",!1);return}this.token=s}else i=0;switch(i){case 200:o.forEach(n=>{setTimeout(()=>this.onmessage({data:n}),0)}),this.poll();break;case 204:this.poll();break;case 410:this.readyState=p.open,this.onopen({}),this.poll();break;case 403:this.onerror(403),this.close(1008,"forbidden",!1);break;case 0:case 500:this.onerror(500),this.closeAndRetry(1011,"internal server error",500);break;default:throw new Error(`unhandled poll status ${i}`)}})}send(e){typeof e!="string"&&(e=W(e)),this.currentBatch?this.currentBatch.push(e):this.awaitingBatchAck?this.batchBuffer.push(e):(this.currentBatch=[e],this.currentBatchTimer=setTimeout(()=>{this.batchSend(this.currentBatch),this.currentBatch=null},0))}batchSend(e){this.awaitingBatchAck=!0,this.ajax("POST",{"Content-Type":"application/x-ndjson"},e.join(`
2
- `),()=>this.onerror("timeout"),t=>{this.awaitingBatchAck=!1,!t||t.status!==200?(this.onerror(t&&t.status),this.closeAndRetry(1011,"internal server error",!1)):this.batchBuffer.length>0&&(this.batchSend(this.batchBuffer),this.batchBuffer=[])})}close(e,t,i){for(let o of this.reqs)o.abort();this.readyState=p.closed;let s=Object.assign({code:1e3,reason:void 0,wasClean:!0},{code:e,reason:t,wasClean:i});this.batchBuffer=[],clearTimeout(this.currentBatchTimer),this.currentBatchTimer=null,typeof CloseEvent!="undefined"?this.onclose(new CloseEvent("close",s)):this.onclose(s)}ajax(e,t,i,s,o){let n,r=()=>{this.reqs.delete(n),s()};n=C.request(e,this.endpointURL(),t,i,this.timeout,r,h=>{this.reqs.delete(n),this.isActive()&&o(h)}),this.reqs.add(n)}};var w=class a{constructor(e,t={}){let i=t.events||{state:"presence_state",diff:"presence_diff"};this.state={},this.pendingDiffs=[],this.channel=e,this.joinRef=null,this.caller={onJoin:function(){},onLeave:function(){},onSync:function(){}},this.channel.on(i.state,s=>{let{onJoin:o,onLeave:n,onSync:r}=this.caller;this.joinRef=this.channel.joinRef(),this.state=a.syncState(this.state,s,o,n),this.pendingDiffs.forEach(h=>{this.state=a.syncDiff(this.state,h,o,n)}),this.pendingDiffs=[],r()}),this.channel.on(i.diff,s=>{let{onJoin:o,onLeave:n,onSync:r}=this.caller;this.inPendingSyncState()?this.pendingDiffs.push(s):(this.state=a.syncDiff(this.state,s,o,n),r())})}onJoin(e){this.caller.onJoin=e}onLeave(e){this.caller.onLeave=e}onSync(e){this.caller.onSync=e}list(e){return a.list(this.state,e)}inPendingSyncState(){return!this.joinRef||this.joinRef!==this.channel.joinRef()}static syncState(e,t,i,s){let o=this.clone(e),n={},r={};return this.map(o,(h,l)=>{t[h]||(r[h]=l)}),this.map(t,(h,l)=>{let c=o[h];if(c){let f=l.metas.map(E=>E.phx_ref),S=c.metas.map(E=>E.phx_ref),x=l.metas.filter(E=>S.indexOf(E.phx_ref)<0),H=c.metas.filter(E=>f.indexOf(E.phx_ref)<0);x.length>0&&(n[h]=l,n[h].metas=x),H.length>0&&(r[h]=this.clone(c),r[h].metas=H)}else n[h]=l}),this.syncDiff(o,{joins:n,leaves:r},i,s)}static syncDiff(e,t,i,s){let{joins:o,leaves:n}=this.clone(t);return i||(i=function(){}),s||(s=function(){}),this.map(o,(r,h)=>{let l=e[r];if(e[r]=this.clone(h),l){let c=e[r].metas.map(S=>S.phx_ref),f=l.metas.filter(S=>c.indexOf(S.phx_ref)<0);e[r].metas.unshift(...f)}i(r,l,h)}),this.map(n,(r,h)=>{let l=e[r];if(!l)return;let c=h.metas.map(f=>f.phx_ref);l.metas=l.metas.filter(f=>c.indexOf(f.phx_ref)<0),s(r,l,h),l.metas.length===0&&delete e[r]}),e}static list(e,t){return t||(t=function(i,s){return s}),this.map(e,(i,s)=>t(i,s))}static map(e,t){return Object.getOwnPropertyNames(e).map(i=>t(i,e[i]))}static clone(e){return JSON.parse(JSON.stringify(e))}};var y={HEADER_LENGTH:1,META_LENGTH:4,KINDS:{push:0,reply:1,broadcast:2},encode(a,e){if(a.payload.constructor===ArrayBuffer)return e(this.binaryEncode(a));{let t=[a.join_ref,a.ref,a.topic,a.event,a.payload];return e(JSON.stringify(t))}},decode(a,e){if(a.constructor===ArrayBuffer)return e(this.binaryDecode(a));{let[t,i,s,o,n]=JSON.parse(a);return e({join_ref:t,ref:i,topic:s,event:o,payload:n})}},binaryEncode(a){let{join_ref:e,ref:t,event:i,topic:s,payload:o}=a,n=this.META_LENGTH+e.length+t.length+s.length+i.length,r=new ArrayBuffer(this.HEADER_LENGTH+n),h=new DataView(r),l=0;h.setUint8(l++,this.KINDS.push),h.setUint8(l++,e.length),h.setUint8(l++,t.length),h.setUint8(l++,s.length),h.setUint8(l++,i.length),Array.from(e,f=>h.setUint8(l++,f.charCodeAt(0))),Array.from(t,f=>h.setUint8(l++,f.charCodeAt(0))),Array.from(s,f=>h.setUint8(l++,f.charCodeAt(0))),Array.from(i,f=>h.setUint8(l++,f.charCodeAt(0)));var c=new Uint8Array(r.byteLength+o.byteLength);return c.set(new Uint8Array(r),0),c.set(new Uint8Array(o),r.byteLength),c.buffer},binaryDecode(a){let e=new DataView(a),t=e.getUint8(0),i=new TextDecoder;switch(t){case this.KINDS.push:return this.decodePush(a,e,i);case this.KINDS.reply:return this.decodeReply(a,e,i);case this.KINDS.broadcast:return this.decodeBroadcast(a,e,i)}},decodePush(a,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=e.getUint8(3),n=this.HEADER_LENGTH+this.META_LENGTH-1,r=t.decode(a.slice(n,n+i));n=n+i;let h=t.decode(a.slice(n,n+s));n=n+s;let l=t.decode(a.slice(n,n+o));n=n+o;let c=a.slice(n,a.byteLength);return{join_ref:r,ref:null,topic:h,event:l,payload:c}},decodeReply(a,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=e.getUint8(3),n=e.getUint8(4),r=this.HEADER_LENGTH+this.META_LENGTH,h=t.decode(a.slice(r,r+i));r=r+i;let l=t.decode(a.slice(r,r+s));r=r+s;let c=t.decode(a.slice(r,r+o));r=r+o;let f=t.decode(a.slice(r,r+n));r=r+n;let S=a.slice(r,a.byteLength),x={status:f,response:S};return{join_ref:h,ref:l,topic:c,event:g.reply,payload:x}},decodeBroadcast(a,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=this.HEADER_LENGTH+2,n=t.decode(a.slice(o,o+i));o=o+i;let r=t.decode(a.slice(o,o+s));o=o+s;let h=a.slice(o,a.byteLength);return{join_ref:null,ref:null,topic:n,event:r,payload:h}}};var _=class{constructor(e,t={}){var s,o;this.stateChangeCallbacks={open:[],close:[],error:[],message:[]},this.channels=[],this.sendBuffer=[],this.ref=0,this.fallbackRef=null,this.timeout=t.timeout||B,this.transport=t.transport||d.WebSocket||m,this.conn=void 0,this.primaryPassedHealthCheck=!1,this.longPollFallbackMs=t.longPollFallbackMs,this.fallbackTimer=null,this.sessionStore=t.sessionStorage||d&&d.sessionStorage,this.establishedConnections=0,this.defaultEncoder=y.encode.bind(y),this.defaultDecoder=y.decode.bind(y),this.closeWasClean=!1,this.disconnecting=!1,this.binaryType=t.binaryType||"arraybuffer",this.connectClock=1,this.pageHidden=!1,this.encode=void 0,this.decode=void 0,this.transport!==m?(this.encode=t.encode||this.defaultEncoder,this.decode=t.decode||this.defaultDecoder):(this.encode=this.defaultEncoder,this.decode=this.defaultDecoder);let i=null;R&&R.addEventListener&&(R.addEventListener("pagehide",n=>{this.conn&&(this.disconnect(),i=this.connectClock)}),R.addEventListener("pageshow",n=>{i===this.connectClock&&(i=null,this.connect())}),R.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?this.pageHidden=!0:(this.pageHidden=!1,this.isConnected()||this.teardown(()=>this.connect()))})),this.heartbeatIntervalMs=t.heartbeatIntervalMs||3e4,this.autoSendHeartbeat=(s=t.autoSendHeartbeat)!=null?s:!0,this.heartbeatCallback=(o=t.heartbeatCallback)!=null?o:()=>{},this.rejoinAfterMs=n=>t.rejoinAfterMs?t.rejoinAfterMs(n):[1e3,2e3,5e3][n-1]||1e4,this.reconnectAfterMs=n=>t.reconnectAfterMs?t.reconnectAfterMs(n):[10,50,100,150,200,250,500,1e3,2e3][n-1]||5e3,this.logger=t.logger||null,!this.logger&&t.debug&&(this.logger=(n,r,h)=>{console.log(`${n}: ${r}`,h)}),this.longpollerTimeout=t.longpollerTimeout||2e4,this.params=k(t.params||{}),this.endPoint=`${e}/${j.websocket}`,this.vsn=t.vsn||O,this.heartbeatTimeoutTimer=null,this.heartbeatTimer=null,this.heartbeatSentAt=null,this.pendingHeartbeatRef=null,this.reconnectTimer=new b(()=>{if(this.pageHidden){this.log("Not reconnecting as page is hidden!"),this.teardown();return}this.teardown(()=>N(this,null,function*(){t.beforeReconnect&&(yield t.beforeReconnect()),this.connect()}))},this.reconnectAfterMs),this.authToken=t.authToken}getLongPollTransport(){return m}replaceTransport(e){this.connectClock++,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.conn&&(this.conn.close(),this.conn=null),this.transport=e}protocol(){return location.protocol.match(/^https/)?"wss":"ws"}endPointURL(){let e=C.appendParams(C.appendParams(this.endPoint,this.params()),{vsn:this.vsn});return e.charAt(0)!=="/"?e:e.charAt(1)==="/"?`${this.protocol()}:${e}`:`${this.protocol()}://${location.host}${e}`}disconnect(e,t,i){this.connectClock++,this.disconnecting=!0,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.teardown(()=>{this.disconnecting=!1,e&&e()},t,i)}connect(e){e&&(console&&console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor"),this.params=k(e)),!(this.conn&&!this.disconnecting)&&(this.longPollFallbackMs&&this.transport!==m?this.connectWithFallback(m,this.longPollFallbackMs):this.transportConnect())}log(e,t,i){this.logger&&this.logger(e,t,i)}hasLogger(){return this.logger!==null}onOpen(e){let t=this.makeRef();return this.stateChangeCallbacks.open.push([t,e]),t}onClose(e){let t=this.makeRef();return this.stateChangeCallbacks.close.push([t,e]),t}onError(e){let t=this.makeRef();return this.stateChangeCallbacks.error.push([t,e]),t}onMessage(e){let t=this.makeRef();return this.stateChangeCallbacks.message.push([t,e]),t}onHeartbeat(e){this.heartbeatCallback=e}ping(e){if(!this.isConnected())return!1;let t=this.makeRef(),i=Date.now();this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:t});let s=this.onMessage(o=>{o.ref===t&&(this.off([s]),e(Date.now()-i))});return!0}transportConnect(){this.connectClock++,this.closeWasClean=!1;let e;this.authToken&&(e=["phoenix",`${A}${btoa(this.authToken).replace(/=/g,"")}`]),this.conn=new this.transport(this.endPointURL(),e),this.conn.binaryType=this.binaryType,this.conn.timeout=this.longpollerTimeout,this.conn.onopen=()=>this.onConnOpen(),this.conn.onerror=t=>this.onConnError(t),this.conn.onmessage=t=>this.onConnMessage(t),this.conn.onclose=t=>this.onConnClose(t)}getSession(e){return this.sessionStore&&this.sessionStore.getItem(e)}storeSession(e,t){this.sessionStore&&this.sessionStore.setItem(e,t)}connectWithFallback(e,t=2500){clearTimeout(this.fallbackTimer);let i=!1,s=!0,o,n,r=h=>{this.log("transport",`falling back to ${e.name}...`,h),this.off([o,n]),s=!1,this.replaceTransport(e),this.transportConnect()};if(this.getSession(`phx:fallback:${e.name}`))return r("memorized");this.fallbackTimer=setTimeout(r,t),n=this.onError(h=>{this.log("transport","error",h),s&&!i&&(clearTimeout(this.fallbackTimer),r(h))}),this.fallbackRef&&this.off([this.fallbackRef]),this.fallbackRef=this.onOpen(()=>{if(i=!0,!s)return this.primaryPassedHealthCheck||this.storeSession(`phx:fallback:${e.name}`,"true"),this.log("transport",`established ${e.name} fallback`);clearTimeout(this.fallbackTimer),this.fallbackTimer=setTimeout(r,t),this.ping(h=>{this.log("transport","connected to primary after",h),this.primaryPassedHealthCheck=!0,clearTimeout(this.fallbackTimer)})}),this.transportConnect()}clearHeartbeats(){clearTimeout(this.heartbeatTimer),clearTimeout(this.heartbeatTimeoutTimer)}onConnOpen(){this.hasLogger()&&this.log("transport",`connected to ${this.endPointURL()}`),this.closeWasClean=!1,this.disconnecting=!1,this.establishedConnections++,this.flushSendBuffer(),this.reconnectTimer.reset(),this.autoSendHeartbeat&&this.resetHeartbeat(),this.triggerStateCallbacks("open")}heartbeatTimeout(){if(this.pendingHeartbeatRef){this.pendingHeartbeatRef=null,this.heartbeatSentAt=null,this.hasLogger()&&this.log("transport","heartbeat timeout. Attempting to re-establish connection");try{this.heartbeatCallback("timeout")}catch(e){this.log("error","error in heartbeat callback",e)}this.triggerChanError(),this.closeWasClean=!1,this.teardown(()=>this.reconnectTimer.scheduleTimeout(),P,"heartbeat timeout")}}resetHeartbeat(){this.conn&&this.conn.skipHeartbeat||(this.pendingHeartbeatRef=null,this.clearHeartbeats(),this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs))}teardown(e,t,i){if(!this.conn)return e&&e();let s=this.connectClock;this.waitForBufferDone(()=>{s===this.connectClock&&(this.conn&&(t?this.conn.close(t,i||""):this.conn.close()),this.waitForSocketClosed(()=>{s===this.connectClock&&(this.conn&&(this.conn.onopen=function(){},this.conn.onerror=function(){},this.conn.onmessage=function(){},this.conn.onclose=function(){},this.conn=null),e&&e())}))})}waitForBufferDone(e,t=1){if(t===5||!this.conn||!this.conn.bufferedAmount){e();return}setTimeout(()=>{this.waitForBufferDone(e,t+1)},150*t)}waitForSocketClosed(e,t=1){if(t===5||!this.conn||this.conn.readyState===p.closed){e();return}setTimeout(()=>{this.waitForSocketClosed(e,t+1)},150*t)}onConnClose(e){this.conn&&(this.conn.onclose=()=>{}),this.hasLogger()&&this.log("transport","close",e),this.triggerChanError(),this.clearHeartbeats(),this.closeWasClean||this.reconnectTimer.scheduleTimeout(),this.triggerStateCallbacks("close",e)}onConnError(e){this.hasLogger()&&this.log("transport",e);let t=this.transport,i=this.establishedConnections;this.triggerStateCallbacks("error",e,t,i),(t===this.transport||i>0)&&this.triggerChanError()}triggerChanError(){this.channels.forEach(e=>{e.isErrored()||e.isLeaving()||e.isClosed()||e.trigger(g.error)})}connectionState(){switch(this.conn&&this.conn.readyState){case p.connecting:return"connecting";case p.open:return"open";case p.closing:return"closing";default:return"closed"}}isConnected(){return this.connectionState()==="open"}remove(e){this.off(e.stateChangeRefs),this.channels=this.channels.filter(t=>t!==e)}off(e){for(let t in this.stateChangeCallbacks)this.stateChangeCallbacks[t]=this.stateChangeCallbacks[t].filter(([i])=>e.indexOf(i)===-1)}channel(e,t={}){let i=new v(e,t,this);return this.channels.push(i),i}push(e){if(this.hasLogger()){let{topic:t,event:i,payload:s,ref:o,join_ref:n}=e;this.log("push",`${t} ${i} (${n}, ${o})`,s)}this.isConnected()?this.encode(e,t=>this.conn.send(t)):this.sendBuffer.push(()=>this.encode(e,t=>this.conn.send(t)))}makeRef(){let e=this.ref+1;return e===this.ref?this.ref=0:this.ref=e,this.ref.toString()}sendHeartbeat(){if(!this.isConnected()){try{this.heartbeatCallback("disconnected")}catch(e){this.log("error","error in heartbeat callback",e)}return}if(this.pendingHeartbeatRef){this.heartbeatTimeout();return}this.pendingHeartbeatRef=this.makeRef(),this.heartbeatSentAt=Date.now(),this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:this.pendingHeartbeatRef});try{this.heartbeatCallback("sent")}catch(e){this.log("error","error in heartbeat callback",e)}this.heartbeatTimeoutTimer=setTimeout(()=>this.heartbeatTimeout(),this.heartbeatIntervalMs)}flushSendBuffer(){this.isConnected()&&this.sendBuffer.length>0&&(this.sendBuffer.forEach(e=>e()),this.sendBuffer=[])}onConnMessage(e){this.decode(e.data,t=>{let{topic:i,event:s,payload:o,ref:n,join_ref:r}=t;if(n&&n===this.pendingHeartbeatRef){let h=this.heartbeatSentAt?Date.now()-this.heartbeatSentAt:void 0;this.clearHeartbeats();try{this.heartbeatCallback(o.status==="ok"?"ok":"error",h)}catch(l){this.log("error","error in heartbeat callback",l)}this.pendingHeartbeatRef=null,this.heartbeatSentAt=null,this.autoSendHeartbeat&&(this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs))}this.hasLogger()&&this.log("receive",`${o.status||""} ${i} ${s} ${n&&"("+n+")"||""}`.trim(),o);for(let h=0;h<this.channels.length;h++){let l=this.channels[h];l.isMember(i,s,o,r)&&l.trigger(s,o,n,r)}this.triggerStateCallbacks("message",t)})}triggerStateCallbacks(e,...t){try{this.stateChangeCallbacks[e].forEach(([i,s])=>{try{s(...t)}catch(o){this.log("error",`error in ${e} callback`,o)}})}catch(i){this.log("error",`error triggering ${e} callbacks`,i)}}leaveOpenTopic(e){let t=this.channels.find(i=>i.topic===e&&(i.isJoined()||i.isJoining()));t&&(this.hasLogger()&&this.log("transport",`leaving duplicate topic "${e}"`),t.leave())}};return J(K);})();
1
+ "use strict";var Phoenix=(()=>{var L=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var I=(a,e)=>{for(var t in e)L(a,t,{get:e[t],enumerable:!0})},F=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of U(e))!D.call(a,s)&&s!==t&&L(a,s,{get:()=>e[s],enumerable:!(i=M(e,s))||i.enumerable});return a};var J=a=>F(L({},"__esModule",{value:!0}),a);var N=(a,e,t)=>new Promise((i,s)=>{var o=h=>{try{r(t.next(h))}catch(l){s(l)}},n=h=>{try{r(t.throw(h))}catch(l){s(l)}},r=h=>h.done?i(h.value):Promise.resolve(h.value).then(o,n);r((t=t.apply(a,e)).next())});var K={};I(K,{Channel:()=>v,LongPoll:()=>m,Presence:()=>w,Push:()=>T,Serializer:()=>y,Socket:()=>_,Timer:()=>b});var k=a=>typeof a=="function"?a:function(){return a};var z=typeof self!="undefined"?self:null,R=typeof window!="undefined"?window:null,d=z||R||globalThis,O="2.0.0",P=1e4,B=1e3,p={connecting:0,open:1,closing:2,closed:3},u={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},g={close:"phx_close",error:"phx_error",join:"phx_join",reply:"phx_reply",leave:"phx_leave"},j={longpoll:"longpoll",websocket:"websocket"},$={complete:4},A="base64url.bearer.phx.";var T=class{constructor(e,t,i,s){this.channel=e,this.event=t,this.payload=i||function(){return{}},this.receivedResp=null,this.timeout=s,this.timeoutTimer=null,this.recHooks=[],this.sent=!1,this.ref=void 0}resend(e){this.timeout=e,this.reset(),this.send()}send(){this.hasReceived("timeout")||(this.startTimeout(),this.sent=!0,this.channel.socket.push({topic:this.channel.topic,event:this.event,payload:this.payload(),ref:this.ref,join_ref:this.channel.joinRef()}))}receive(e,t){return this.hasReceived(e)&&t(this.receivedResp.response),this.recHooks.push({status:e,callback:t}),this}reset(){this.cancelRefEvent(),this.ref=null,this.refEvent=null,this.receivedResp=null,this.sent=!1}destroy(){this.cancelRefEvent(),this.cancelTimeout()}matchReceive({status:e,response:t,_ref:i}){this.recHooks.filter(s=>s.status===e).forEach(s=>s.callback(t))}cancelRefEvent(){this.refEvent&&this.channel.off(this.refEvent)}cancelTimeout(){clearTimeout(this.timeoutTimer),this.timeoutTimer=null}startTimeout(){this.timeoutTimer&&this.cancelTimeout(),this.ref=this.channel.socket.makeRef(),this.refEvent=this.channel.replyEventName(this.ref),this.channel.on(this.refEvent,e=>{this.cancelRefEvent(),this.cancelTimeout(),this.receivedResp=e,this.matchReceive(e)}),this.timeoutTimer=setTimeout(()=>{this.trigger("timeout",{})},this.timeout)}hasReceived(e){return this.receivedResp&&this.receivedResp.status===e}trigger(e,t){this.channel.trigger(this.refEvent,{status:e,response:t})}};var b=class{constructor(e,t){this.callback=e,this.timerCalc=t,this.timer=void 0,this.tries=0}reset(){this.tries=0,clearTimeout(this.timer)}scheduleTimeout(){clearTimeout(this.timer),this.timer=setTimeout(()=>{this.tries=this.tries+1,this.callback()},this.timerCalc(this.tries+1))}};var v=class{constructor(e,t,i){this.state=u.closed,this.topic=e,this.params=k(t||{}),this.socket=i,this.bindings=[],this.bindingRef=0,this.timeout=this.socket.timeout,this.joinedOnce=!1,this.joinPush=new T(this,g.join,this.params,this.timeout),this.pushBuffer=[],this.stateChangeRefs=[],this.rejoinTimer=new b(()=>{this.socket.isConnected()&&this.rejoin()},this.socket.rejoinAfterMs),this.stateChangeRefs.push(this.socket.onError(()=>this.rejoinTimer.reset())),this.stateChangeRefs.push(this.socket.onOpen(()=>{this.rejoinTimer.reset(),this.isErrored()&&this.rejoin()})),this.joinPush.receive("ok",()=>{this.state=u.joined,this.rejoinTimer.reset(),this.pushBuffer.forEach(s=>s.send()),this.pushBuffer=[]}),this.joinPush.receive("error",s=>{this.state=u.errored,this.socket.hasLogger()&&this.socket.log("channel",`error ${this.topic}`,s),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.onClose(()=>{this.rejoinTimer.reset(),this.socket.hasLogger()&&this.socket.log("channel",`close ${this.topic}`),this.state=u.closed,this.socket.remove(this)}),this.onError(s=>{this.socket.hasLogger()&&this.socket.log("channel",`error ${this.topic}`,s),this.isJoining()&&this.joinPush.reset(),this.state=u.errored,this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.joinPush.receive("timeout",()=>{this.socket.hasLogger()&&this.socket.log("channel",`timeout ${this.topic}`,this.joinPush.timeout),new T(this,g.leave,k({}),this.timeout).send(),this.state=u.errored,this.joinPush.reset(),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.on(g.reply,(s,o)=>{this.trigger(this.replyEventName(o),s)})}join(e=this.timeout){if(this.joinedOnce)throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance");return this.timeout=e,this.joinedOnce=!0,this.rejoin(),this.joinPush}teardown(){this.pushBuffer.forEach(e=>e.destroy()),this.pushBuffer=[],this.rejoinTimer.reset(),this.joinPush.destroy(),this.state=u.closed,this.bindings=[]}onClose(e){this.on(g.close,e)}onError(e){return this.on(g.error,t=>e(t))}on(e,t){let i=this.bindingRef++;return this.bindings.push({event:e,ref:i,callback:t}),i}off(e,t){this.bindings=this.bindings.filter(i=>!(i.event===e&&(typeof t=="undefined"||t===i.ref)))}canPush(){return this.socket.isConnected()&&this.isJoined()}push(e,t,i=this.timeout){if(t=t||{},!this.joinedOnce)throw new Error(`tried to push '${e}' to '${this.topic}' before joining. Use channel.join() before pushing events`);let s=new T(this,e,function(){return t},i);return this.canPush()?s.send():(s.startTimeout(),this.pushBuffer.push(s)),s}leave(e=this.timeout){this.rejoinTimer.reset(),this.joinPush.cancelTimeout(),this.state=u.leaving;let t=()=>{this.socket.hasLogger()&&this.socket.log("channel",`leave ${this.topic}`),this.trigger(g.close,"leave")},i=new T(this,g.leave,k({}),e);return i.receive("ok",()=>t()).receive("timeout",()=>t()),i.send(),this.canPush()||i.trigger("ok",{}),i}onMessage(e,t,i){return t}filterBindings(e,t,i){return!0}isMember(e,t,i,s){return this.topic!==e?!1:s&&s!==this.joinRef()?(this.socket.hasLogger()&&this.socket.log("channel","dropping outdated message",{topic:e,event:t,payload:i,joinRef:s}),!1):!0}joinRef(){return this.joinPush.ref}rejoin(e=this.timeout){this.isLeaving()||(this.socket.leaveOpenTopic(this.topic),this.state=u.joining,this.joinPush.resend(e))}trigger(e,t,i,s){let o=this.onMessage(e,t,i,s);if(t&&!o)throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");let n=this.bindings.filter(r=>r.event===e&&this.filterBindings(r,t,i));for(let r=0;r<n.length;r++)n[r].callback(o,i,s||this.joinRef())}replyEventName(e){return`chan_reply_${e}`}isClosed(){return this.state===u.closed}isErrored(){return this.state===u.errored}isJoined(){return this.state===u.joined}isJoining(){return this.state===u.joining}isLeaving(){return this.state===u.leaving}};var C=class{static request(e,t,i,s,o,n,r){if(d.XDomainRequest){let h=new d.XDomainRequest;return this.xdomainRequest(h,e,t,s,o,n,r)}else if(d.XMLHttpRequest){let h=new d.XMLHttpRequest;return this.xhrRequest(h,e,t,i,s,o,n,r)}else{if(d.fetch&&d.AbortController)return this.fetchRequest(e,t,i,s,o,n,r);throw new Error("No suitable XMLHttpRequest implementation found")}}static fetchRequest(e,t,i,s,o,n,r){let h={method:e,headers:i,body:s},l=null;if(o){l=new AbortController;let c=setTimeout(()=>l.abort(),o);h.signal=l.signal}return d.fetch(t,h).then(c=>c.text()).then(c=>this.parseJSON(c)).then(c=>r&&r(c)).catch(c=>{c.name==="AbortError"&&n?n():r&&r(null)}),l}static xdomainRequest(e,t,i,s,o,n,r){return e.timeout=o,e.open(t,i),e.onload=()=>{let h=this.parseJSON(e.responseText);r&&r(h)},n&&(e.ontimeout=n),e.onprogress=()=>{},e.send(s),e}static xhrRequest(e,t,i,s,o,n,r,h){e.open(t,i,!0),e.timeout=n;for(let[l,c]of Object.entries(s))e.setRequestHeader(l,c);return e.onerror=()=>h&&h(null),e.onreadystatechange=()=>{if(e.readyState===$.complete&&h){let l=this.parseJSON(e.responseText);h(l)}},r&&(e.ontimeout=r),e.send(o),e}static parseJSON(e){if(!e||e==="")return null;try{return JSON.parse(e)}catch(t){return console&&console.log("failed to parse JSON response",e),null}}static serialize(e,t){let i=[];for(var s in e){if(!Object.prototype.hasOwnProperty.call(e,s))continue;let o=t?`${t}[${s}]`:s,n=e[s];typeof n=="object"?i.push(this.serialize(n,o)):i.push(encodeURIComponent(o)+"="+encodeURIComponent(n))}return i.join("&")}static appendParams(e,t){if(Object.keys(t).length===0)return e;let i=e.match(/\?/)?"&":"?";return`${e}${i}${this.serialize(t)}`}};var W=a=>{let e="",t=new Uint8Array(a),i=t.byteLength;for(let s=0;s<i;s++)e+=String.fromCharCode(t[s]);return btoa(e)},m=class{constructor(e,t){t&&t.length===2&&t[1].startsWith(A)&&(this.authToken=atob(t[1].slice(A.length))),this.endPoint=null,this.token=null,this.skipHeartbeat=!0,this.reqs=new Set,this.awaitingBatchAck=!1,this.currentBatch=null,this.currentBatchTimer=null,this.batchBuffer=[],this.onopen=function(){},this.onerror=function(){},this.onmessage=function(){},this.onclose=function(){},this.pollEndpoint=this.normalizeEndpoint(e),this.readyState=p.connecting,setTimeout(()=>this.poll(),0)}normalizeEndpoint(e){return e.replace("ws://","http://").replace("wss://","https://").replace(new RegExp("(.*)/"+j.websocket),"$1/"+j.longpoll)}endpointURL(){return C.appendParams(this.pollEndpoint,{token:this.token})}closeAndRetry(e,t,i){this.close(e,t,i),this.readyState=p.connecting}ontimeout(){this.onerror("timeout"),this.closeAndRetry(1005,"timeout",!1)}isActive(){return this.readyState===p.open||this.readyState===p.connecting}poll(){let e={Accept:"application/json"};this.authToken&&(e["X-Phoenix-AuthToken"]=this.authToken),this.ajax("GET",e,null,()=>this.ontimeout(),t=>{if(t){var{status:i,token:s,messages:o}=t;if(i===410&&this.token!==null){this.onerror(410),this.closeAndRetry(3410,"session_gone",!1);return}this.token=s}else i=0;switch(i){case 200:o.forEach(n=>{setTimeout(()=>this.onmessage({data:n}),0)}),this.poll();break;case 204:this.poll();break;case 410:this.readyState=p.open,this.onopen({}),this.poll();break;case 403:this.onerror(403),this.close(1008,"forbidden",!1);break;case 0:case 500:this.onerror(500),this.closeAndRetry(1011,"internal server error",500);break;default:throw new Error(`unhandled poll status ${i}`)}})}send(e){typeof e!="string"&&(e=W(e)),this.currentBatch?this.currentBatch.push(e):this.awaitingBatchAck?this.batchBuffer.push(e):(this.currentBatch=[e],this.currentBatchTimer=setTimeout(()=>{this.batchSend(this.currentBatch),this.currentBatch=null},0))}batchSend(e){this.awaitingBatchAck=!0,this.ajax("POST",{"Content-Type":"application/x-ndjson"},e.join(`
2
+ `),()=>this.onerror("timeout"),t=>{this.awaitingBatchAck=!1,!t||t.status!==200?(this.onerror(t&&t.status),this.closeAndRetry(1011,"internal server error",!1)):this.batchBuffer.length>0&&(this.batchSend(this.batchBuffer),this.batchBuffer=[])})}close(e,t,i){for(let o of this.reqs)o.abort();this.readyState=p.closed;let s=Object.assign({code:1e3,reason:void 0,wasClean:!0},{code:e,reason:t,wasClean:i});this.batchBuffer=[],clearTimeout(this.currentBatchTimer),this.currentBatchTimer=null,typeof CloseEvent!="undefined"?this.onclose(new CloseEvent("close",s)):this.onclose(s)}ajax(e,t,i,s,o){let n,r=()=>{this.reqs.delete(n),s()};n=C.request(e,this.endpointURL(),t,i,this.timeout,r,h=>{this.reqs.delete(n),this.isActive()&&o(h)}),this.reqs.add(n)}};var w=class a{constructor(e,t={}){let i=t.events||{state:"presence_state",diff:"presence_diff"};this.state={},this.pendingDiffs=[],this.channel=e,this.joinRef=null,this.caller={onJoin:function(){},onLeave:function(){},onSync:function(){}},this.channel.on(i.state,s=>{let{onJoin:o,onLeave:n,onSync:r}=this.caller;this.joinRef=this.channel.joinRef(),this.state=a.syncState(this.state,s,o,n),this.pendingDiffs.forEach(h=>{this.state=a.syncDiff(this.state,h,o,n)}),this.pendingDiffs=[],r()}),this.channel.on(i.diff,s=>{let{onJoin:o,onLeave:n,onSync:r}=this.caller;this.inPendingSyncState()?this.pendingDiffs.push(s):(this.state=a.syncDiff(this.state,s,o,n),r())})}onJoin(e){this.caller.onJoin=e}onLeave(e){this.caller.onLeave=e}onSync(e){this.caller.onSync=e}list(e){return a.list(this.state,e)}inPendingSyncState(){return!this.joinRef||this.joinRef!==this.channel.joinRef()}static syncState(e,t,i,s){let o=this.clone(e),n={},r={};return this.map(o,(h,l)=>{t[h]||(r[h]=l)}),this.map(t,(h,l)=>{let c=o[h];if(c){let f=l.metas.map(E=>E.phx_ref),S=c.metas.map(E=>E.phx_ref),x=l.metas.filter(E=>S.indexOf(E.phx_ref)<0),H=c.metas.filter(E=>f.indexOf(E.phx_ref)<0);x.length>0&&(n[h]=l,n[h].metas=x),H.length>0&&(r[h]=this.clone(c),r[h].metas=H)}else n[h]=l}),this.syncDiff(o,{joins:n,leaves:r},i,s)}static syncDiff(e,t,i,s){let{joins:o,leaves:n}=this.clone(t);return i||(i=function(){}),s||(s=function(){}),this.map(o,(r,h)=>{let l=e[r];if(e[r]=this.clone(h),l){let c=e[r].metas.map(S=>S.phx_ref),f=l.metas.filter(S=>c.indexOf(S.phx_ref)<0);e[r].metas.unshift(...f)}i(r,l,h)}),this.map(n,(r,h)=>{let l=e[r];if(!l)return;let c=h.metas.map(f=>f.phx_ref);l.metas=l.metas.filter(f=>c.indexOf(f.phx_ref)<0),s(r,l,h),l.metas.length===0&&delete e[r]}),e}static list(e,t){return t||(t=function(i,s){return s}),this.map(e,(i,s)=>t(i,s))}static map(e,t){return Object.getOwnPropertyNames(e).map(i=>t(i,e[i]))}static clone(e){return JSON.parse(JSON.stringify(e))}};var y={HEADER_LENGTH:1,META_LENGTH:4,KINDS:{push:0,reply:1,broadcast:2},encode(a,e){if(a.payload.constructor===ArrayBuffer)return e(this.binaryEncode(a));{let t=[a.join_ref,a.ref,a.topic,a.event,a.payload];return e(JSON.stringify(t))}},decode(a,e){if(a.constructor===ArrayBuffer)return e(this.binaryDecode(a));{let[t,i,s,o,n]=JSON.parse(a);return e({join_ref:t,ref:i,topic:s,event:o,payload:n})}},binaryEncode(a){let{join_ref:e,ref:t,event:i,topic:s,payload:o}=a,n=this.META_LENGTH+e.length+t.length+s.length+i.length,r=new ArrayBuffer(this.HEADER_LENGTH+n),h=new DataView(r),l=0;h.setUint8(l++,this.KINDS.push),h.setUint8(l++,e.length),h.setUint8(l++,t.length),h.setUint8(l++,s.length),h.setUint8(l++,i.length),Array.from(e,f=>h.setUint8(l++,f.charCodeAt(0))),Array.from(t,f=>h.setUint8(l++,f.charCodeAt(0))),Array.from(s,f=>h.setUint8(l++,f.charCodeAt(0))),Array.from(i,f=>h.setUint8(l++,f.charCodeAt(0)));var c=new Uint8Array(r.byteLength+o.byteLength);return c.set(new Uint8Array(r),0),c.set(new Uint8Array(o),r.byteLength),c.buffer},binaryDecode(a){let e=new DataView(a),t=e.getUint8(0),i=new TextDecoder;switch(t){case this.KINDS.push:return this.decodePush(a,e,i);case this.KINDS.reply:return this.decodeReply(a,e,i);case this.KINDS.broadcast:return this.decodeBroadcast(a,e,i)}},decodePush(a,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=e.getUint8(3),n=this.HEADER_LENGTH+this.META_LENGTH-1,r=t.decode(a.slice(n,n+i));n=n+i;let h=t.decode(a.slice(n,n+s));n=n+s;let l=t.decode(a.slice(n,n+o));n=n+o;let c=a.slice(n,a.byteLength);return{join_ref:r,ref:null,topic:h,event:l,payload:c}},decodeReply(a,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=e.getUint8(3),n=e.getUint8(4),r=this.HEADER_LENGTH+this.META_LENGTH,h=t.decode(a.slice(r,r+i));r=r+i;let l=t.decode(a.slice(r,r+s));r=r+s;let c=t.decode(a.slice(r,r+o));r=r+o;let f=t.decode(a.slice(r,r+n));r=r+n;let S=a.slice(r,a.byteLength),x={status:f,response:S};return{join_ref:h,ref:l,topic:c,event:g.reply,payload:x}},decodeBroadcast(a,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=this.HEADER_LENGTH+2,n=t.decode(a.slice(o,o+i));o=o+i;let r=t.decode(a.slice(o,o+s));o=o+s;let h=a.slice(o,a.byteLength);return{join_ref:null,ref:null,topic:n,event:r,payload:h}}};var _=class{constructor(e,t={}){var s,o;this.stateChangeCallbacks={open:[],close:[],error:[],message:[]},this.channels=[],this.sendBuffer=[],this.ref=0,this.fallbackRef=null,this.timeout=t.timeout||P,this.transport=t.transport||d.WebSocket||m,this.conn=void 0,this.primaryPassedHealthCheck=!1,this.longPollFallbackMs=t.longPollFallbackMs,this.fallbackTimer=null,this.sessionStore=t.sessionStorage||d&&d.sessionStorage,this.establishedConnections=0,this.defaultEncoder=y.encode.bind(y),this.defaultDecoder=y.decode.bind(y),this.closeWasClean=!1,this.disconnecting=!1,this.binaryType=t.binaryType||"arraybuffer",this.connectClock=1,this.pageHidden=!1,this.encode=void 0,this.decode=void 0,this.transport!==m?(this.encode=t.encode||this.defaultEncoder,this.decode=t.decode||this.defaultDecoder):(this.encode=this.defaultEncoder,this.decode=this.defaultDecoder);let i=null;R&&R.addEventListener&&(R.addEventListener("pagehide",n=>{this.conn&&(this.disconnect(),i=this.connectClock)}),R.addEventListener("pageshow",n=>{i===this.connectClock&&(i=null,this.connect())}),R.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?this.pageHidden=!0:(this.pageHidden=!1,!this.isConnected()&&!this.closeWasClean&&this.teardown(()=>this.connect()))})),this.heartbeatIntervalMs=t.heartbeatIntervalMs||3e4,this.autoSendHeartbeat=(s=t.autoSendHeartbeat)!=null?s:!0,this.heartbeatCallback=(o=t.heartbeatCallback)!=null?o:()=>{},this.rejoinAfterMs=n=>t.rejoinAfterMs?t.rejoinAfterMs(n):[1e3,2e3,5e3][n-1]||1e4,this.reconnectAfterMs=n=>t.reconnectAfterMs?t.reconnectAfterMs(n):[10,50,100,150,200,250,500,1e3,2e3][n-1]||5e3,this.logger=t.logger||null,!this.logger&&t.debug&&(this.logger=(n,r,h)=>{console.log(`${n}: ${r}`,h)}),this.longpollerTimeout=t.longpollerTimeout||2e4,this.params=k(t.params||{}),this.endPoint=`${e}/${j.websocket}`,this.vsn=t.vsn||O,this.heartbeatTimeoutTimer=null,this.heartbeatTimer=null,this.heartbeatSentAt=null,this.pendingHeartbeatRef=null,this.reconnectTimer=new b(()=>{if(this.pageHidden){this.log("Not reconnecting as page is hidden!"),this.teardown();return}this.teardown(()=>N(this,null,function*(){t.beforeReconnect&&(yield t.beforeReconnect()),this.connect()}))},this.reconnectAfterMs),this.authToken=t.authToken}getLongPollTransport(){return m}replaceTransport(e){this.connectClock++,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.conn&&(this.conn.close(),this.conn=null),this.transport=e}protocol(){return location.protocol.match(/^https/)?"wss":"ws"}endPointURL(){let e=C.appendParams(C.appendParams(this.endPoint,this.params()),{vsn:this.vsn});return e.charAt(0)!=="/"?e:e.charAt(1)==="/"?`${this.protocol()}:${e}`:`${this.protocol()}://${location.host}${e}`}disconnect(e,t,i){this.connectClock++,this.disconnecting=!0,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.teardown(()=>{this.disconnecting=!1,e&&e()},t,i)}connect(e){e&&(console&&console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor"),this.params=k(e)),!(this.conn&&!this.disconnecting)&&(this.longPollFallbackMs&&this.transport!==m?this.connectWithFallback(m,this.longPollFallbackMs):this.transportConnect())}log(e,t,i){this.logger&&this.logger(e,t,i)}hasLogger(){return this.logger!==null}onOpen(e){let t=this.makeRef();return this.stateChangeCallbacks.open.push([t,e]),t}onClose(e){let t=this.makeRef();return this.stateChangeCallbacks.close.push([t,e]),t}onError(e){let t=this.makeRef();return this.stateChangeCallbacks.error.push([t,e]),t}onMessage(e){let t=this.makeRef();return this.stateChangeCallbacks.message.push([t,e]),t}onHeartbeat(e){this.heartbeatCallback=e}ping(e){if(!this.isConnected())return!1;let t=this.makeRef(),i=Date.now();this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:t});let s=this.onMessage(o=>{o.ref===t&&(this.off([s]),e(Date.now()-i))});return!0}transportName(e){switch(e){case m:return"LongPoll";default:return e.name}}transportConnect(){this.connectClock++,this.closeWasClean=!1;let e;this.authToken&&(e=["phoenix",`${A}${btoa(this.authToken).replace(/=/g,"")}`]),this.conn=new this.transport(this.endPointURL(),e),this.conn.binaryType=this.binaryType,this.conn.timeout=this.longpollerTimeout,this.conn.onopen=()=>this.onConnOpen(),this.conn.onerror=t=>this.onConnError(t),this.conn.onmessage=t=>this.onConnMessage(t),this.conn.onclose=t=>this.onConnClose(t)}getSession(e){return this.sessionStore&&this.sessionStore.getItem(e)}storeSession(e,t){this.sessionStore&&this.sessionStore.setItem(e,t)}connectWithFallback(e,t=2500){clearTimeout(this.fallbackTimer);let i=!1,s=!0,o,n,r=this.transportName(e),h=l=>{this.log("transport",`falling back to ${r}...`,l),this.off([o,n]),s=!1,this.replaceTransport(e),this.transportConnect()};if(this.getSession(`phx:fallback:${r}`))return h("memorized");this.fallbackTimer=setTimeout(h,t),n=this.onError(l=>{this.log("transport","error",l),s&&!i&&(clearTimeout(this.fallbackTimer),h(l))}),this.fallbackRef&&this.off([this.fallbackRef]),this.fallbackRef=this.onOpen(()=>{if(i=!0,!s){let l=this.transportName(e);return this.primaryPassedHealthCheck||this.storeSession(`phx:fallback:${l}`,"true"),this.log("transport",`established ${l} fallback`)}clearTimeout(this.fallbackTimer),this.fallbackTimer=setTimeout(h,t),this.ping(l=>{this.log("transport","connected to primary after",l),this.primaryPassedHealthCheck=!0,clearTimeout(this.fallbackTimer)})}),this.transportConnect()}clearHeartbeats(){clearTimeout(this.heartbeatTimer),clearTimeout(this.heartbeatTimeoutTimer)}onConnOpen(){this.hasLogger()&&this.log("transport",`connected to ${this.endPointURL()}`),this.closeWasClean=!1,this.disconnecting=!1,this.establishedConnections++,this.flushSendBuffer(),this.reconnectTimer.reset(),this.autoSendHeartbeat&&this.resetHeartbeat(),this.triggerStateCallbacks("open")}heartbeatTimeout(){if(this.pendingHeartbeatRef){this.pendingHeartbeatRef=null,this.heartbeatSentAt=null,this.hasLogger()&&this.log("transport","heartbeat timeout. Attempting to re-establish connection");try{this.heartbeatCallback("timeout")}catch(e){this.log("error","error in heartbeat callback",e)}this.triggerChanError(),this.closeWasClean=!1,this.teardown(()=>this.reconnectTimer.scheduleTimeout(),B,"heartbeat timeout")}}resetHeartbeat(){this.conn&&this.conn.skipHeartbeat||(this.pendingHeartbeatRef=null,this.clearHeartbeats(),this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs))}teardown(e,t,i){if(!this.conn)return e&&e();let s=this.connectClock;this.waitForBufferDone(()=>{s===this.connectClock&&(this.conn&&(t?this.conn.close(t,i||""):this.conn.close()),this.waitForSocketClosed(()=>{s===this.connectClock&&(this.conn&&(this.conn.onopen=function(){},this.conn.onerror=function(){},this.conn.onmessage=function(){},this.conn.onclose=function(){},this.conn=null),e&&e())}))})}waitForBufferDone(e,t=1){if(t===5||!this.conn||!this.conn.bufferedAmount){e();return}setTimeout(()=>{this.waitForBufferDone(e,t+1)},150*t)}waitForSocketClosed(e,t=1){if(t===5||!this.conn||this.conn.readyState===p.closed){e();return}setTimeout(()=>{this.waitForSocketClosed(e,t+1)},150*t)}onConnClose(e){this.conn&&(this.conn.onclose=()=>{}),this.hasLogger()&&this.log("transport","close",e),this.triggerChanError(),this.clearHeartbeats(),this.closeWasClean||this.reconnectTimer.scheduleTimeout(),this.triggerStateCallbacks("close",e)}onConnError(e){this.hasLogger()&&this.log("transport",e);let t=this.transport,i=this.establishedConnections;this.triggerStateCallbacks("error",e,t,i),(t===this.transport||i>0)&&this.triggerChanError()}triggerChanError(){this.channels.forEach(e=>{e.isErrored()||e.isLeaving()||e.isClosed()||e.trigger(g.error)})}connectionState(){switch(this.conn&&this.conn.readyState){case p.connecting:return"connecting";case p.open:return"open";case p.closing:return"closing";default:return"closed"}}isConnected(){return this.connectionState()==="open"}remove(e){this.off(e.stateChangeRefs),this.channels=this.channels.filter(t=>t!==e)}off(e){for(let t in this.stateChangeCallbacks)this.stateChangeCallbacks[t]=this.stateChangeCallbacks[t].filter(([i])=>e.indexOf(i)===-1)}channel(e,t={}){let i=new v(e,t,this);return this.channels.push(i),i}push(e){if(this.hasLogger()){let{topic:t,event:i,payload:s,ref:o,join_ref:n}=e;this.log("push",`${t} ${i} (${n}, ${o})`,s)}this.isConnected()?this.encode(e,t=>this.conn.send(t)):this.sendBuffer.push(()=>this.encode(e,t=>this.conn.send(t)))}makeRef(){let e=this.ref+1;return e===this.ref?this.ref=0:this.ref=e,this.ref.toString()}sendHeartbeat(){if(!this.isConnected()){try{this.heartbeatCallback("disconnected")}catch(e){this.log("error","error in heartbeat callback",e)}return}if(this.pendingHeartbeatRef){this.heartbeatTimeout();return}this.pendingHeartbeatRef=this.makeRef(),this.heartbeatSentAt=Date.now(),this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:this.pendingHeartbeatRef});try{this.heartbeatCallback("sent")}catch(e){this.log("error","error in heartbeat callback",e)}this.heartbeatTimeoutTimer=setTimeout(()=>this.heartbeatTimeout(),this.heartbeatIntervalMs)}flushSendBuffer(){this.isConnected()&&this.sendBuffer.length>0&&(this.sendBuffer.forEach(e=>e()),this.sendBuffer=[])}onConnMessage(e){this.decode(e.data,t=>{let{topic:i,event:s,payload:o,ref:n,join_ref:r}=t;if(n&&n===this.pendingHeartbeatRef){let h=this.heartbeatSentAt?Date.now()-this.heartbeatSentAt:void 0;this.clearHeartbeats();try{this.heartbeatCallback(o.status==="ok"?"ok":"error",h)}catch(l){this.log("error","error in heartbeat callback",l)}this.pendingHeartbeatRef=null,this.heartbeatSentAt=null,this.autoSendHeartbeat&&(this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs))}this.hasLogger()&&this.log("receive",`${o.status||""} ${i} ${s} ${n&&"("+n+")"||""}`.trim(),o);for(let h=0;h<this.channels.length;h++){let l=this.channels[h];l.isMember(i,s,o,r)&&l.trigger(s,o,n,r)}this.triggerStateCallbacks("message",t)})}triggerStateCallbacks(e,...t){try{this.stateChangeCallbacks[e].forEach(([i,s])=>{try{s(...t)}catch(o){this.log("error",`error in ${e} callback`,o)}})}catch(i){this.log("error",`error triggering ${e} callbacks`,i)}}leaveOpenTopic(e){let t=this.channels.find(i=>i.topic===e&&(i.isJoined()||i.isJoining()));t&&(this.hasLogger()&&this.log("transport",`leaving duplicate topic "${e}"`),t.leave())}};return J(K);})();
@@ -306,7 +306,7 @@ var Channel = class {
306
306
  this.rejoinTimer.reset();
307
307
  this.joinPush.destroy();
308
308
  this.state = CHANNEL_STATES.closed;
309
- this.bindings = {};
309
+ this.bindings = [];
310
310
  }
311
311
  /**
312
312
  * Hook into channel close
@@ -1177,7 +1177,7 @@ var Socket = class {
1177
1177
  this.pageHidden = true;
1178
1178
  } else {
1179
1179
  this.pageHidden = false;
1180
- if (!this.isConnected()) {
1180
+ if (!this.isConnected() && !this.closeWasClean) {
1181
1181
  this.teardown(() => this.connect());
1182
1182
  }
1183
1183
  }
@@ -1406,6 +1406,19 @@ var Socket = class {
1406
1406
  });
1407
1407
  return true;
1408
1408
  }
1409
+ /**
1410
+ * @private
1411
+ *
1412
+ * @param {Function}
1413
+ */
1414
+ transportName(transport) {
1415
+ switch (transport) {
1416
+ case LongPoll:
1417
+ return "LongPoll";
1418
+ default:
1419
+ return transport.name;
1420
+ }
1421
+ }
1409
1422
  /**
1410
1423
  * @private
1411
1424
  */
@@ -1435,14 +1448,15 @@ var Socket = class {
1435
1448
  let established = false;
1436
1449
  let primaryTransport = true;
1437
1450
  let openRef, errorRef;
1451
+ let fallbackTransportName = this.transportName(fallbackTransport);
1438
1452
  let fallback = (reason) => {
1439
- this.log("transport", `falling back to ${fallbackTransport.name}...`, reason);
1453
+ this.log("transport", `falling back to ${fallbackTransportName}...`, reason);
1440
1454
  this.off([openRef, errorRef]);
1441
1455
  primaryTransport = false;
1442
1456
  this.replaceTransport(fallbackTransport);
1443
1457
  this.transportConnect();
1444
1458
  };
1445
- if (this.getSession(`phx:fallback:${fallbackTransport.name}`)) {
1459
+ if (this.getSession(`phx:fallback:${fallbackTransportName}`)) {
1446
1460
  return fallback("memorized");
1447
1461
  }
1448
1462
  this.fallbackTimer = setTimeout(fallback, fallbackThreshold);
@@ -1459,10 +1473,11 @@ var Socket = class {
1459
1473
  this.fallbackRef = this.onOpen(() => {
1460
1474
  established = true;
1461
1475
  if (!primaryTransport) {
1476
+ let fallbackTransportName2 = this.transportName(fallbackTransport);
1462
1477
  if (!this.primaryPassedHealthCheck) {
1463
- this.storeSession(`phx:fallback:${fallbackTransport.name}`, "true");
1478
+ this.storeSession(`phx:fallback:${fallbackTransportName2}`, "true");
1464
1479
  }
1465
- return this.log("transport", `established ${fallbackTransport.name} fallback`);
1480
+ return this.log("transport", `established ${fallbackTransportName2} fallback`);
1466
1481
  }
1467
1482
  clearTimeout(this.fallbackTimer);
1468
1483
  this.fallbackTimer = setTimeout(fallback, fallbackThreshold);