Socket
Socket
Sign inDemoInstall

phoenix

Package Overview
Dependencies
0
Maintainers
2
Versions
81
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.7.7 to 1.7.8

2

assets/package.json
{
"name": "phoenix",
"version": "1.7.7",
"version": "1.7.8",
"description": "The official JavaScript client for the Phoenix web framework.",

@@ -5,0 +5,0 @@ "license": "MIT",

{
"name": "phoenix",
"version": "1.7.7",
"version": "1.7.8",
"description": "The official JavaScript client for the Phoenix web framework.",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -86,2 +86,6 @@ var __defProp = Object.defineProperty;

}
/**
*
* @param {number} timeout
*/
resend(timeout) {

@@ -92,2 +96,5 @@ this.timeout = timeout;

}
/**
*
*/
send() {

@@ -107,2 +114,7 @@ if (this.hasReceived("timeout")) {

}
/**
*
* @param {*} status
* @param {*} callback
*/
receive(status, callback) {

@@ -115,2 +127,5 @@ if (this.hasReceived(status)) {

}
/**
* @private
*/
reset() {

@@ -123,5 +138,11 @@ this.cancelRefEvent();

}
/**
* @private
*/
matchReceive({ status, response, _ref }) {
this.recHooks.filter((h) => h.status === status).forEach((h) => h.callback(response));
}
/**
* @private
*/
cancelRefEvent() {

@@ -133,2 +154,5 @@ if (!this.refEvent) {

}
/**
* @private
*/
cancelTimeout() {

@@ -138,2 +162,5 @@ clearTimeout(this.timeoutTimer);

}
/**
* @private
*/
startTimeout() {

@@ -155,5 +182,11 @@ if (this.timeoutTimer) {

}
/**
* @private
*/
hasReceived(status) {
return this.receivedResp && this.receivedResp.status === status;
}
/**
* @private
*/
trigger(status, response) {

@@ -176,2 +209,5 @@ this.channel.trigger(this.refEvent, { status, response });

}
/**
* Cancels any previous scheduleTimeout and schedules callback
*/
scheduleTimeout() {

@@ -206,8 +242,10 @@ clearTimeout(this.timer);

this.stateChangeRefs.push(this.socket.onError(() => this.rejoinTimer.reset()));
this.stateChangeRefs.push(this.socket.onOpen(() => {
this.rejoinTimer.reset();
if (this.isErrored()) {
this.rejoin();
}
}));
this.stateChangeRefs.push(
this.socket.onOpen(() => {
this.rejoinTimer.reset();
if (this.isErrored()) {
this.rejoin();
}
})
);
this.joinPush.receive("ok", () => {

@@ -258,2 +296,7 @@ this.state = CHANNEL_STATES.joined;

}
/**
* Join the channel
* @param {integer} timeout
* @returns {Push}
*/
join(timeout = this.timeout) {

@@ -269,8 +312,33 @@ if (this.joinedOnce) {

}
/**
* Hook into channel close
* @param {Function} callback
*/
onClose(callback) {
this.on(CHANNEL_EVENTS.close, callback);
}
/**
* Hook into channel errors
* @param {Function} callback
*/
onError(callback) {
return this.on(CHANNEL_EVENTS.error, (reason) => callback(reason));
}
/**
* Subscribes on channel events
*
* Subscription returns a ref counter, which can be used later to
* unsubscribe the exact event listener
*
* @example
* const ref1 = channel.on("event", do_stuff)
* const ref2 = channel.on("event", do_other_stuff)
* channel.off("event", ref1)
* // Since unsubscription, do_stuff won't fire,
* // while do_other_stuff will keep firing on the "event"
*
* @param {string} event
* @param {Function} callback
* @returns {integer} ref
*/
on(event, callback) {

@@ -281,2 +349,20 @@ let ref = this.bindingRef++;

}
/**
* Unsubscribes off of channel events
*
* Use the ref returned from a channel.on() to unsubscribe one
* handler, or pass nothing for the ref to unsubscribe all
* handlers for the given event.
*
* @example
* // Unsubscribe the do_stuff handler
* const ref1 = channel.on("event", do_stuff)
* channel.off("event", ref1)
*
* // Unsubscribe all handlers from event
* channel.off("event")
*
* @param {string} event
* @param {integer} ref
*/
off(event, ref) {

@@ -287,5 +373,24 @@ this.bindings = this.bindings.filter((bind) => {

}
/**
* @private
*/
canPush() {
return this.socket.isConnected() && this.isJoined();
}
/**
* Sends a message `event` to phoenix with the payload `payload`.
* Phoenix receives this in the `handle_in(event, payload, socket)`
* function. if phoenix replies or it times out (default 10000ms),
* then optionally the reply can be received.
*
* @example
* channel.push("event")
* .receive("ok", payload => console.log("phoenix replied:", payload))
* .receive("error", err => console.log("phoenix errored", err))
* .receive("timeout", () => console.log("timed out pushing"))
* @param {string} event
* @param {Object} payload
* @param {number} [timeout]
* @returns {Push}
*/
push(event, payload, timeout = this.timeout) {

@@ -307,2 +412,18 @@ payload = payload || {};

}
/** Leaves the channel
*
* Unsubscribes from server events, and
* instructs channel to terminate on server
*
* Triggers onClose() hooks
*
* To receive leave acknowledgements, use the `receive`
* hook to bind to the server ack, ie:
*
* @example
* channel.leave().receive("ok", () => alert("left!") )
*
* @param {integer} timeout
* @returns {Push}
*/
leave(timeout = this.timeout) {

@@ -325,5 +446,20 @@ this.rejoinTimer.reset();

}
/**
* Overridable message hook
*
* Receives all events for specialized message handling
* before dispatching to the channel callbacks.
*
* Must return the payload, modified or unmodified
* @param {string} event
* @param {Object} payload
* @param {integer} ref
* @returns {Object}
*/
onMessage(_event, payload, _ref) {
return payload;
}
/**
* @private
*/
isMember(topic, event, payload, joinRef) {

@@ -341,5 +477,11 @@ if (this.topic !== topic) {

}
/**
* @private
*/
joinRef() {
return this.joinPush.ref;
}
/**
* @private
*/
rejoin(timeout = this.timeout) {

@@ -353,2 +495,5 @@ if (this.isLeaving()) {

}
/**
* @private
*/
trigger(event, payload, ref, joinRef) {

@@ -365,17 +510,35 @@ let handledPayload = this.onMessage(event, payload, ref, joinRef);

}
/**
* @private
*/
replyEventName(ref) {
return `chan_reply_${ref}`;
}
/**
* @private
*/
isClosed() {
return this.state === CHANNEL_STATES.closed;
}
/**
* @private
*/
isErrored() {
return this.state === CHANNEL_STATES.errored;
}
/**
* @private
*/
isJoined() {
return this.state === CHANNEL_STATES.joined;
}
/**
* @private
*/
isJoining() {
return this.state === CHANNEL_STATES.joining;
}
/**
* @private
*/
isLeaving() {

@@ -551,2 +714,5 @@ return this.state === CHANNEL_STATES.leaving;

}
// we collect all pushes within the current event loop by
// setTimeout 0, which optimizes back-to-back procedural
// pushes against an empty buffer
send(body) {

@@ -663,2 +829,11 @@ if (typeof body !== "string") {

}
// lower-level public static API
/**
* Used to sync the list of presences on the server
* with the client's state. An optional `onJoin` and `onLeave` callback can
* be provided to react to changes in the client's local presences across
* disconnects and reconnects with the server.
*
* @returns {Presence}
*/
static syncState(currentState, newState, onJoin, onLeave) {

@@ -694,2 +869,11 @@ let state = this.clone(currentState);

}
/**
*
* Used to sync a diff of presence join and leave
* events from the server, as they happen. Like `syncState`, `syncDiff`
* accepts optional `onJoin` and `onLeave` callbacks to react to a user
* joining or leaving from a device.
*
* @returns {Presence}
*/
static syncDiff(state, diff, onJoin, onLeave) {

@@ -731,2 +915,10 @@ let { joins, leaves } = this.clone(diff);

}
/**
* Returns the array of presences, with selected metadata.
*
* @param {Object} presences
* @param {Function} chooser
*
* @returns {Presence}
*/
static list(presences, chooser) {

@@ -742,2 +934,3 @@ if (!chooser) {

}
// private
static map(obj, func) {

@@ -772,2 +965,3 @@ return Object.getOwnPropertyNames(obj).map((key) => func(key, obj[key]));

},
// private
binaryEncode(message) {

@@ -915,5 +1109,14 @@ let { join_ref, ref, event, topic, payload } = message;

}
/**
* Returns the LongPoll transport reference
*/
getLongPollTransport() {
return LongPoll;
}
/**
* Disconnects and replaces the active transport
*
* @param {Function} newTransport - The new transport class to instantiate
*
*/
replaceTransport(newTransport) {

@@ -930,7 +1133,20 @@ this.connectClock++;

}
/**
* Returns the socket protocol
*
* @returns {string}
*/
protocol() {
return location.protocol.match(/^https/) ? "wss" : "ws";
}
/**
* The fully qualified socket url
*
* @returns {string}
*/
endPointURL() {
let uri = Ajax.appendParams(Ajax.appendParams(this.endPoint, this.params()), { vsn: this.vsn });
let uri = Ajax.appendParams(
Ajax.appendParams(this.endPoint, this.params()),
{ vsn: this.vsn }
);
if (uri.charAt(0) !== "/") {

@@ -944,2 +1160,11 @@ return uri;

}
/**
* Disconnects the socket
*
* See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes for valid status codes.
*
* @param {Function} callback - Optional callback which is called after socket is disconnected.
* @param {integer} code - A status code for disconnection (Optional).
* @param {string} reason - A textual description of the reason to disconnect. (Optional)
*/
disconnect(callback, code, reason) {

@@ -951,2 +1176,9 @@ this.connectClock++;

}
/**
*
* @param {Object} params - The params to send when connecting, for example `{user_id: userToken}`
*
* Passing params to connect is deprecated; pass them in the Socket constructor instead:
* `new Socket("/socket", {params: {user_id: userToken}})`.
*/
connect(params) {

@@ -970,8 +1202,24 @@ if (params) {

}
/**
* Logs the message. Override `this.logger` for specialized logging. noops by default
* @param {string} kind
* @param {string} msg
* @param {Object} data
*/
log(kind, msg, data) {
this.logger(kind, msg, data);
}
/**
* Returns true if a logger has been set on this socket.
*/
hasLogger() {
return this.logger !== null;
}
/**
* Registers callbacks for connection open events
*
* @example socket.onOpen(function(){ console.info("the socket was opened") })
*
* @param {Function} callback
*/
onOpen(callback) {

@@ -982,2 +1230,6 @@ let ref = this.makeRef();

}
/**
* Registers callbacks for connection close events
* @param {Function} callback
*/
onClose(callback) {

@@ -988,2 +1240,9 @@ let ref = this.makeRef();

}
/**
* Registers callbacks for connection error events
*
* @example socket.onError(function(error){ alert("An error occurred") })
*
* @param {Function} callback
*/
onError(callback) {

@@ -994,2 +1253,6 @@ let ref = this.makeRef();

}
/**
* Registers callbacks for connection message events
* @param {Function} callback
*/
onMessage(callback) {

@@ -1000,2 +1263,8 @@ let ref = this.makeRef();

}
/**
* Pings the server and invokes the callback with the RTT in milliseconds
* @param {Function} callback
*
* Returns true if the ping was pushed or false if unable to be pushed.
*/
ping(callback) {

@@ -1016,2 +1285,5 @@ if (!this.isConnected()) {

}
/**
* @private
*/
clearHeartbeats() {

@@ -1031,2 +1303,5 @@ clearTimeout(this.heartbeatTimer);

}
/**
* @private
*/
heartbeatTimeout() {

@@ -1108,2 +1383,5 @@ if (this.pendingHeartbeatRef) {

}
/**
* @private
*/
onConnError(error) {

@@ -1121,2 +1399,5 @@ if (this.hasLogger())

}
/**
* @private
*/
triggerChanError() {

@@ -1129,2 +1410,5 @@ this.channels.forEach((channel) => {

}
/**
* @returns {string}
*/
connectionState() {

@@ -1142,5 +1426,13 @@ switch (this.conn && this.conn.readyState) {

}
/**
* @returns {boolean}
*/
isConnected() {
return this.connectionState() === "open";
}
/**
* @private
*
* @param {Channel}
*/
remove(channel) {

@@ -1150,2 +1442,8 @@ this.off(channel.stateChangeRefs);

}
/**
* Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.
*
* @param {refs} - list of refs returned by calls to
* `onOpen`, `onClose`, `onError,` and `onMessage`
*/
off(refs) {

@@ -1158,2 +1456,9 @@ for (let key in this.stateChangeCallbacks) {

}
/**
* Initiates a new channel for the given topic
*
* @param {string} topic
* @param {Object} chanParams - Parameters for the channel
* @returns {Channel}
*/
channel(topic, chanParams = {}) {

@@ -1164,2 +1469,5 @@ let chan = new Channel(topic, chanParams, this);

}
/**
* @param {Object} data
*/
push(data) {

@@ -1176,2 +1484,6 @@ if (this.hasLogger()) {

}
/**
* Return the next message ref, accounting for overflows
* @returns {string}
*/
makeRef() {

@@ -1178,0 +1490,0 @@ let newRef = this.ref + 1;

@@ -86,2 +86,6 @@ var Phoenix = (() => {

}
/**
*
* @param {number} timeout
*/
resend(timeout) {

@@ -92,2 +96,5 @@ this.timeout = timeout;

}
/**
*
*/
send() {

@@ -107,2 +114,7 @@ if (this.hasReceived("timeout")) {

}
/**
*
* @param {*} status
* @param {*} callback
*/
receive(status, callback) {

@@ -115,2 +127,5 @@ if (this.hasReceived(status)) {

}
/**
* @private
*/
reset() {

@@ -123,5 +138,11 @@ this.cancelRefEvent();

}
/**
* @private
*/
matchReceive({ status, response, _ref }) {
this.recHooks.filter((h) => h.status === status).forEach((h) => h.callback(response));
}
/**
* @private
*/
cancelRefEvent() {

@@ -133,2 +154,5 @@ if (!this.refEvent) {

}
/**
* @private
*/
cancelTimeout() {

@@ -138,2 +162,5 @@ clearTimeout(this.timeoutTimer);

}
/**
* @private
*/
startTimeout() {

@@ -155,5 +182,11 @@ if (this.timeoutTimer) {

}
/**
* @private
*/
hasReceived(status) {
return this.receivedResp && this.receivedResp.status === status;
}
/**
* @private
*/
trigger(status, response) {

@@ -176,2 +209,5 @@ this.channel.trigger(this.refEvent, { status, response });

}
/**
* Cancels any previous scheduleTimeout and schedules callback
*/
scheduleTimeout() {

@@ -206,8 +242,10 @@ clearTimeout(this.timer);

this.stateChangeRefs.push(this.socket.onError(() => this.rejoinTimer.reset()));
this.stateChangeRefs.push(this.socket.onOpen(() => {
this.rejoinTimer.reset();
if (this.isErrored()) {
this.rejoin();
}
}));
this.stateChangeRefs.push(
this.socket.onOpen(() => {
this.rejoinTimer.reset();
if (this.isErrored()) {
this.rejoin();
}
})
);
this.joinPush.receive("ok", () => {

@@ -258,2 +296,7 @@ this.state = CHANNEL_STATES.joined;

}
/**
* Join the channel
* @param {integer} timeout
* @returns {Push}
*/
join(timeout = this.timeout) {

@@ -269,8 +312,33 @@ if (this.joinedOnce) {

}
/**
* Hook into channel close
* @param {Function} callback
*/
onClose(callback) {
this.on(CHANNEL_EVENTS.close, callback);
}
/**
* Hook into channel errors
* @param {Function} callback
*/
onError(callback) {
return this.on(CHANNEL_EVENTS.error, (reason) => callback(reason));
}
/**
* Subscribes on channel events
*
* Subscription returns a ref counter, which can be used later to
* unsubscribe the exact event listener
*
* @example
* const ref1 = channel.on("event", do_stuff)
* const ref2 = channel.on("event", do_other_stuff)
* channel.off("event", ref1)
* // Since unsubscription, do_stuff won't fire,
* // while do_other_stuff will keep firing on the "event"
*
* @param {string} event
* @param {Function} callback
* @returns {integer} ref
*/
on(event, callback) {

@@ -281,2 +349,20 @@ let ref = this.bindingRef++;

}
/**
* Unsubscribes off of channel events
*
* Use the ref returned from a channel.on() to unsubscribe one
* handler, or pass nothing for the ref to unsubscribe all
* handlers for the given event.
*
* @example
* // Unsubscribe the do_stuff handler
* const ref1 = channel.on("event", do_stuff)
* channel.off("event", ref1)
*
* // Unsubscribe all handlers from event
* channel.off("event")
*
* @param {string} event
* @param {integer} ref
*/
off(event, ref) {

@@ -287,5 +373,24 @@ this.bindings = this.bindings.filter((bind) => {

}
/**
* @private
*/
canPush() {
return this.socket.isConnected() && this.isJoined();
}
/**
* Sends a message `event` to phoenix with the payload `payload`.
* Phoenix receives this in the `handle_in(event, payload, socket)`
* function. if phoenix replies or it times out (default 10000ms),
* then optionally the reply can be received.
*
* @example
* channel.push("event")
* .receive("ok", payload => console.log("phoenix replied:", payload))
* .receive("error", err => console.log("phoenix errored", err))
* .receive("timeout", () => console.log("timed out pushing"))
* @param {string} event
* @param {Object} payload
* @param {number} [timeout]
* @returns {Push}
*/
push(event, payload, timeout = this.timeout) {

@@ -307,2 +412,18 @@ payload = payload || {};

}
/** Leaves the channel
*
* Unsubscribes from server events, and
* instructs channel to terminate on server
*
* Triggers onClose() hooks
*
* To receive leave acknowledgements, use the `receive`
* hook to bind to the server ack, ie:
*
* @example
* channel.leave().receive("ok", () => alert("left!") )
*
* @param {integer} timeout
* @returns {Push}
*/
leave(timeout = this.timeout) {

@@ -325,5 +446,20 @@ this.rejoinTimer.reset();

}
/**
* Overridable message hook
*
* Receives all events for specialized message handling
* before dispatching to the channel callbacks.
*
* Must return the payload, modified or unmodified
* @param {string} event
* @param {Object} payload
* @param {integer} ref
* @returns {Object}
*/
onMessage(_event, payload, _ref) {
return payload;
}
/**
* @private
*/
isMember(topic, event, payload, joinRef) {

@@ -341,5 +477,11 @@ if (this.topic !== topic) {

}
/**
* @private
*/
joinRef() {
return this.joinPush.ref;
}
/**
* @private
*/
rejoin(timeout = this.timeout) {

@@ -353,2 +495,5 @@ if (this.isLeaving()) {

}
/**
* @private
*/
trigger(event, payload, ref, joinRef) {

@@ -365,17 +510,35 @@ let handledPayload = this.onMessage(event, payload, ref, joinRef);

}
/**
* @private
*/
replyEventName(ref) {
return `chan_reply_${ref}`;
}
/**
* @private
*/
isClosed() {
return this.state === CHANNEL_STATES.closed;
}
/**
* @private
*/
isErrored() {
return this.state === CHANNEL_STATES.errored;
}
/**
* @private
*/
isJoined() {
return this.state === CHANNEL_STATES.joined;
}
/**
* @private
*/
isJoining() {
return this.state === CHANNEL_STATES.joining;
}
/**
* @private
*/
isLeaving() {

@@ -551,2 +714,5 @@ return this.state === CHANNEL_STATES.leaving;

}
// we collect all pushes within the current event loop by
// setTimeout 0, which optimizes back-to-back procedural
// pushes against an empty buffer
send(body) {

@@ -663,2 +829,11 @@ if (typeof body !== "string") {

}
// lower-level public static API
/**
* Used to sync the list of presences on the server
* with the client's state. An optional `onJoin` and `onLeave` callback can
* be provided to react to changes in the client's local presences across
* disconnects and reconnects with the server.
*
* @returns {Presence}
*/
static syncState(currentState, newState, onJoin, onLeave) {

@@ -694,2 +869,11 @@ let state = this.clone(currentState);

}
/**
*
* Used to sync a diff of presence join and leave
* events from the server, as they happen. Like `syncState`, `syncDiff`
* accepts optional `onJoin` and `onLeave` callbacks to react to a user
* joining or leaving from a device.
*
* @returns {Presence}
*/
static syncDiff(state, diff, onJoin, onLeave) {

@@ -731,2 +915,10 @@ let { joins, leaves } = this.clone(diff);

}
/**
* Returns the array of presences, with selected metadata.
*
* @param {Object} presences
* @param {Function} chooser
*
* @returns {Presence}
*/
static list(presences, chooser) {

@@ -742,2 +934,3 @@ if (!chooser) {

}
// private
static map(obj, func) {

@@ -772,2 +965,3 @@ return Object.getOwnPropertyNames(obj).map((key) => func(key, obj[key]));

},
// private
binaryEncode(message) {

@@ -915,5 +1109,14 @@ let { join_ref, ref, event, topic, payload } = message;

}
/**
* Returns the LongPoll transport reference
*/
getLongPollTransport() {
return LongPoll;
}
/**
* Disconnects and replaces the active transport
*
* @param {Function} newTransport - The new transport class to instantiate
*
*/
replaceTransport(newTransport) {

@@ -930,7 +1133,20 @@ this.connectClock++;

}
/**
* Returns the socket protocol
*
* @returns {string}
*/
protocol() {
return location.protocol.match(/^https/) ? "wss" : "ws";
}
/**
* The fully qualified socket url
*
* @returns {string}
*/
endPointURL() {
let uri = Ajax.appendParams(Ajax.appendParams(this.endPoint, this.params()), { vsn: this.vsn });
let uri = Ajax.appendParams(
Ajax.appendParams(this.endPoint, this.params()),
{ vsn: this.vsn }
);
if (uri.charAt(0) !== "/") {

@@ -944,2 +1160,11 @@ return uri;

}
/**
* Disconnects the socket
*
* See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes for valid status codes.
*
* @param {Function} callback - Optional callback which is called after socket is disconnected.
* @param {integer} code - A status code for disconnection (Optional).
* @param {string} reason - A textual description of the reason to disconnect. (Optional)
*/
disconnect(callback, code, reason) {

@@ -951,2 +1176,9 @@ this.connectClock++;

}
/**
*
* @param {Object} params - The params to send when connecting, for example `{user_id: userToken}`
*
* Passing params to connect is deprecated; pass them in the Socket constructor instead:
* `new Socket("/socket", {params: {user_id: userToken}})`.
*/
connect(params) {

@@ -970,8 +1202,24 @@ if (params) {

}
/**
* Logs the message. Override `this.logger` for specialized logging. noops by default
* @param {string} kind
* @param {string} msg
* @param {Object} data
*/
log(kind, msg, data) {
this.logger(kind, msg, data);
}
/**
* Returns true if a logger has been set on this socket.
*/
hasLogger() {
return this.logger !== null;
}
/**
* Registers callbacks for connection open events
*
* @example socket.onOpen(function(){ console.info("the socket was opened") })
*
* @param {Function} callback
*/
onOpen(callback) {

@@ -982,2 +1230,6 @@ let ref = this.makeRef();

}
/**
* Registers callbacks for connection close events
* @param {Function} callback
*/
onClose(callback) {

@@ -988,2 +1240,9 @@ let ref = this.makeRef();

}
/**
* Registers callbacks for connection error events
*
* @example socket.onError(function(error){ alert("An error occurred") })
*
* @param {Function} callback
*/
onError(callback) {

@@ -994,2 +1253,6 @@ let ref = this.makeRef();

}
/**
* Registers callbacks for connection message events
* @param {Function} callback
*/
onMessage(callback) {

@@ -1000,2 +1263,8 @@ let ref = this.makeRef();

}
/**
* Pings the server and invokes the callback with the RTT in milliseconds
* @param {Function} callback
*
* Returns true if the ping was pushed or false if unable to be pushed.
*/
ping(callback) {

@@ -1016,2 +1285,5 @@ if (!this.isConnected()) {

}
/**
* @private
*/
clearHeartbeats() {

@@ -1031,2 +1303,5 @@ clearTimeout(this.heartbeatTimer);

}
/**
* @private
*/
heartbeatTimeout() {

@@ -1108,2 +1383,5 @@ if (this.pendingHeartbeatRef) {

}
/**
* @private
*/
onConnError(error) {

@@ -1121,2 +1399,5 @@ if (this.hasLogger())

}
/**
* @private
*/
triggerChanError() {

@@ -1129,2 +1410,5 @@ this.channels.forEach((channel) => {

}
/**
* @returns {string}
*/
connectionState() {

@@ -1142,5 +1426,13 @@ switch (this.conn && this.conn.readyState) {

}
/**
* @returns {boolean}
*/
isConnected() {
return this.connectionState() === "open";
}
/**
* @private
*
* @param {Channel}
*/
remove(channel) {

@@ -1150,2 +1442,8 @@ this.off(channel.stateChangeRefs);

}
/**
* Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.
*
* @param {refs} - list of refs returned by calls to
* `onOpen`, `onClose`, `onError,` and `onMessage`
*/
off(refs) {

@@ -1158,2 +1456,9 @@ for (let key in this.stateChangeCallbacks) {

}
/**
* Initiates a new channel for the given topic
*
* @param {string} topic
* @param {Object} chanParams - Parameters for the channel
* @returns {Channel}
*/
channel(topic, chanParams = {}) {

@@ -1164,2 +1469,5 @@ let chan = new Channel(topic, chanParams, this);

}
/**
* @param {Object} data
*/
push(data) {

@@ -1176,2 +1484,6 @@ if (this.hasLogger()) {

}
/**
* Return the next message ref, accounting for overflows
* @returns {string}
*/
makeRef() {

@@ -1178,0 +1490,0 @@ let newRef = this.ref + 1;

@@ -1,2 +0,2 @@

var Phoenix=(()=>{var x=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var M=Object.prototype.hasOwnProperty;var $=(h,e)=>{for(var t in e)x(h,t,{get:e[t],enumerable:!0})},P=(h,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of U(e))!M.call(h,s)&&s!==t&&x(h,s,{get:()=>e[s],enumerable:!(i=D(e,s))||i.enumerable});return h};var J=h=>P(x({},"__esModule",{value:!0}),h);var W={};$(W,{Channel:()=>j,LongPoll:()=>T,Presence:()=>m,Serializer:()=>y,Socket:()=>w});var S=h=>typeof h=="function"?h:function(){return h};var z=typeof self!="undefined"?self:null,A=typeof window!="undefined"?window:null,R=z||A||R,N="2.0.0",d={connecting:0,open:1,closing:2,closed:3},H=1e4,B=1e3,u={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},p={close:"phx_close",error:"phx_error",join:"phx_join",reply:"phx_reply",leave:"phx_leave"},k={longpoll:"longpoll",websocket:"websocket"},O={complete:4};var E=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}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}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=null,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 j=class{constructor(e,t,i){this.state=u.closed,this.topic=e,this.params=S(t||{}),this.socket=i,this.bindings=[],this.bindingRef=0,this.timeout=this.socket.timeout,this.joinedOnce=!1,this.joinPush=new E(this,p.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",()=>{this.state=u.errored,this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.onClose(()=>{this.rejoinTimer.reset(),this.socket.hasLogger()&&this.socket.log("channel",`close ${this.topic} ${this.joinRef()}`),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.joinRef()})`,this.joinPush.timeout),new E(this,p.leave,S({}),this.timeout).send(),this.state=u.errored,this.joinPush.reset(),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.on(p.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}onClose(e){this.on(p.close,e)}onError(e){return this.on(p.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 E(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(p.close,"leave")},i=new E(this,p.leave,S({}),e);return i.receive("ok",()=>t()).receive("timeout",()=>t()),i.send(),this.canPush()||i.trigger("ok",{}),i}onMessage(e,t,i){return t}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 r=this.bindings.filter(n=>n.event===e);for(let n=0;n<r.length;n++)r[n].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 g=class{static request(e,t,i,s,o,r,n){if(R.XDomainRequest){let a=new R.XDomainRequest;return this.xdomainRequest(a,e,t,s,o,r,n)}else{let a=new R.XMLHttpRequest;return this.xhrRequest(a,e,t,i,s,o,r,n)}}static xdomainRequest(e,t,i,s,o,r,n){return e.timeout=o,e.open(t,i),e.onload=()=>{let a=this.parseJSON(e.responseText);n&&n(a)},r&&(e.ontimeout=r),e.onprogress=()=>{},e.send(s),e}static xhrRequest(e,t,i,s,o,r,n,a){return e.open(t,i,!0),e.timeout=r,e.setRequestHeader("Content-Type",s),e.onerror=()=>a&&a(null),e.onreadystatechange=()=>{if(e.readyState===O.complete&&a){let l=this.parseJSON(e.responseText);a(l)}},n&&(e.ontimeout=n),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,r=e[s];typeof r=="object"?i.push(this.serialize(r,o)):i.push(encodeURIComponent(o)+"="+encodeURIComponent(r))}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 I=h=>{let e="",t=new Uint8Array(h),i=t.byteLength;for(let s=0;s<i;s++)e+=String.fromCharCode(t[s]);return btoa(e)},T=class{constructor(e){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=d.connecting,this.poll()}normalizeEndpoint(e){return e.replace("ws://","http://").replace("wss://","https://").replace(new RegExp("(.*)/"+k.websocket),"$1/"+k.longpoll)}endpointURL(){return g.appendParams(this.pollEndpoint,{token:this.token})}closeAndRetry(e,t,i){this.close(e,t,i),this.readyState=d.connecting}ontimeout(){this.onerror("timeout"),this.closeAndRetry(1005,"timeout",!1)}isActive(){return this.readyState===d.open||this.readyState===d.connecting}poll(){this.ajax("GET","application/json",null,()=>this.ontimeout(),e=>{if(e){var{status:t,token:i,messages:s}=e;this.token=i}else t=0;switch(t){case 200:s.forEach(o=>{setTimeout(()=>this.onmessage({data:o}),0)}),this.poll();break;case 204:this.poll();break;case 410:this.readyState=d.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 ${t}`)}})}send(e){typeof e!="string"&&(e=I(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","application/x-ndjson",e.join(`
`),()=>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=d.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 r,n=()=>{this.reqs.delete(r),s()};r=g.request(e,this.endpointURL(),t,i,this.timeout,n,a=>{this.reqs.delete(r),this.isActive()&&o(a)}),this.reqs.add(r)}};var m=class{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:r,onSync:n}=this.caller;this.joinRef=this.channel.joinRef(),this.state=m.syncState(this.state,s,o,r),this.pendingDiffs.forEach(a=>{this.state=m.syncDiff(this.state,a,o,r)}),this.pendingDiffs=[],n()}),this.channel.on(i.diff,s=>{let{onJoin:o,onLeave:r,onSync:n}=this.caller;this.inPendingSyncState()?this.pendingDiffs.push(s):(this.state=m.syncDiff(this.state,s,o,r),n())})}onJoin(e){this.caller.onJoin=e}onLeave(e){this.caller.onLeave=e}onSync(e){this.caller.onSync=e}list(e){return m.list(this.state,e)}inPendingSyncState(){return!this.joinRef||this.joinRef!==this.channel.joinRef()}static syncState(e,t,i,s){let o=this.clone(e),r={},n={};return this.map(o,(a,l)=>{t[a]||(n[a]=l)}),this.map(t,(a,l)=>{let f=o[a];if(f){let c=l.metas.map(v=>v.phx_ref),C=f.metas.map(v=>v.phx_ref),L=l.metas.filter(v=>C.indexOf(v.phx_ref)<0),_=f.metas.filter(v=>c.indexOf(v.phx_ref)<0);L.length>0&&(r[a]=l,r[a].metas=L),_.length>0&&(n[a]=this.clone(f),n[a].metas=_)}else r[a]=l}),this.syncDiff(o,{joins:r,leaves:n},i,s)}static syncDiff(e,t,i,s){let{joins:o,leaves:r}=this.clone(t);return i||(i=function(){}),s||(s=function(){}),this.map(o,(n,a)=>{let l=e[n];if(e[n]=this.clone(a),l){let f=e[n].metas.map(C=>C.phx_ref),c=l.metas.filter(C=>f.indexOf(C.phx_ref)<0);e[n].metas.unshift(...c)}i(n,l,a)}),this.map(r,(n,a)=>{let l=e[n];if(!l)return;let f=a.metas.map(c=>c.phx_ref);l.metas=l.metas.filter(c=>f.indexOf(c.phx_ref)<0),s(n,l,a),l.metas.length===0&&delete e[n]}),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(h,e){if(h.payload.constructor===ArrayBuffer)return e(this.binaryEncode(h));{let t=[h.join_ref,h.ref,h.topic,h.event,h.payload];return e(JSON.stringify(t))}},decode(h,e){if(h.constructor===ArrayBuffer)return e(this.binaryDecode(h));{let[t,i,s,o,r]=JSON.parse(h);return e({join_ref:t,ref:i,topic:s,event:o,payload:r})}},binaryEncode(h){let{join_ref:e,ref:t,event:i,topic:s,payload:o}=h,r=this.META_LENGTH+e.length+t.length+s.length+i.length,n=new ArrayBuffer(this.HEADER_LENGTH+r),a=new DataView(n),l=0;a.setUint8(l++,this.KINDS.push),a.setUint8(l++,e.length),a.setUint8(l++,t.length),a.setUint8(l++,s.length),a.setUint8(l++,i.length),Array.from(e,c=>a.setUint8(l++,c.charCodeAt(0))),Array.from(t,c=>a.setUint8(l++,c.charCodeAt(0))),Array.from(s,c=>a.setUint8(l++,c.charCodeAt(0))),Array.from(i,c=>a.setUint8(l++,c.charCodeAt(0)));var f=new Uint8Array(n.byteLength+o.byteLength);return f.set(new Uint8Array(n),0),f.set(new Uint8Array(o),n.byteLength),f.buffer},binaryDecode(h){let e=new DataView(h),t=e.getUint8(0),i=new TextDecoder;switch(t){case this.KINDS.push:return this.decodePush(h,e,i);case this.KINDS.reply:return this.decodeReply(h,e,i);case this.KINDS.broadcast:return this.decodeBroadcast(h,e,i)}},decodePush(h,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=e.getUint8(3),r=this.HEADER_LENGTH+this.META_LENGTH-1,n=t.decode(h.slice(r,r+i));r=r+i;let a=t.decode(h.slice(r,r+s));r=r+s;let l=t.decode(h.slice(r,r+o));r=r+o;let f=h.slice(r,h.byteLength);return{join_ref:n,ref:null,topic:a,event:l,payload:f}},decodeReply(h,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=e.getUint8(3),r=e.getUint8(4),n=this.HEADER_LENGTH+this.META_LENGTH,a=t.decode(h.slice(n,n+i));n=n+i;let l=t.decode(h.slice(n,n+s));n=n+s;let f=t.decode(h.slice(n,n+o));n=n+o;let c=t.decode(h.slice(n,n+r));n=n+r;let C=h.slice(n,h.byteLength),L={status:c,response:C};return{join_ref:a,ref:l,topic:f,event:p.reply,payload:L}},decodeBroadcast(h,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=this.HEADER_LENGTH+2,r=t.decode(h.slice(o,o+i));o=o+i;let n=t.decode(h.slice(o,o+s));o=o+s;let a=h.slice(o,h.byteLength);return{join_ref:null,ref:null,topic:r,event:n,payload:a}}};var w=class{constructor(e,t={}){this.stateChangeCallbacks={open:[],close:[],error:[],message:[]},this.channels=[],this.sendBuffer=[],this.ref=0,this.timeout=t.timeout||H,this.transport=t.transport||R.WebSocket||T,this.establishedConnections=0,this.defaultEncoder=y.encode.bind(y),this.defaultDecoder=y.decode.bind(y),this.closeWasClean=!1,this.binaryType=t.binaryType||"arraybuffer",this.connectClock=1,this.transport!==T?(this.encode=t.encode||this.defaultEncoder,this.decode=t.decode||this.defaultDecoder):(this.encode=this.defaultEncoder,this.decode=this.defaultDecoder);let i=null;A&&A.addEventListener&&(A.addEventListener("pagehide",s=>{this.conn&&(this.disconnect(),i=this.connectClock)}),A.addEventListener("pageshow",s=>{i===this.connectClock&&(i=null,this.connect())})),this.heartbeatIntervalMs=t.heartbeatIntervalMs||3e4,this.rejoinAfterMs=s=>t.rejoinAfterMs?t.rejoinAfterMs(s):[1e3,2e3,5e3][s-1]||1e4,this.reconnectAfterMs=s=>t.reconnectAfterMs?t.reconnectAfterMs(s):[10,50,100,150,200,250,500,1e3,2e3][s-1]||5e3,this.logger=t.logger||null,this.longpollerTimeout=t.longpollerTimeout||2e4,this.params=S(t.params||{}),this.endPoint=`${e}/${k.websocket}`,this.vsn=t.vsn||N,this.heartbeatTimeoutTimer=null,this.heartbeatTimer=null,this.pendingHeartbeatRef=null,this.reconnectTimer=new b(()=>{this.teardown(()=>this.connect())},this.reconnectAfterMs)}getLongPollTransport(){return T}replaceTransport(e){this.connectClock++,this.closeWasClean=!0,this.reconnectTimer.reset(),this.sendBuffer=[],this.conn&&(this.conn.close(),this.conn=null),this.transport=e}protocol(){return location.protocol.match(/^https/)?"wss":"ws"}endPointURL(){let e=g.appendParams(g.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.closeWasClean=!0,this.reconnectTimer.reset(),this.teardown(e,t,i)}connect(e){e&&(console&&console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor"),this.params=S(e)),!this.conn&&(this.connectClock++,this.closeWasClean=!1,this.conn=new this.transport(this.endPointURL()),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))}log(e,t,i){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}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}clearHeartbeats(){clearTimeout(this.heartbeatTimer),clearTimeout(this.heartbeatTimeoutTimer)}onConnOpen(){this.hasLogger()&&this.log("transport",`connected to ${this.endPointURL()}`),this.closeWasClean=!1,this.establishedConnections++,this.flushSendBuffer(),this.reconnectTimer.reset(),this.resetHeartbeat(),this.stateChangeCallbacks.open.forEach(([,e])=>e())}heartbeatTimeout(){this.pendingHeartbeatRef&&(this.pendingHeartbeatRef=null,this.hasLogger()&&this.log("transport","heartbeat timeout. Attempting to re-establish connection"),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();this.waitForBufferDone(()=>{this.conn&&(t?this.conn.close(t,i||""):this.conn.close()),this.waitForSocketClosed(()=>{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===d.closed){e();return}setTimeout(()=>{this.waitForSocketClosed(e,t+1)},150*t)}onConnClose(e){let t=e&&e.code;this.hasLogger()&&this.log("transport","close",e),this.triggerChanError(),this.clearHeartbeats(),!this.closeWasClean&&t!==1e3&&this.reconnectTimer.scheduleTimeout(),this.stateChangeCallbacks.close.forEach(([,i])=>i(e))}onConnError(e){this.hasLogger()&&this.log("transport",e);let t=this.transport,i=this.establishedConnections;this.stateChangeCallbacks.error.forEach(([,s])=>{s(e,t,i)}),(t===this.transport||i>0)&&this.triggerChanError()}triggerChanError(){this.channels.forEach(e=>{e.isErrored()||e.isLeaving()||e.isClosed()||e.trigger(p.error)})}connectionState(){switch(this.conn&&this.conn.readyState){case d.connecting:return"connecting";case d.open:return"open";case d.closing:return"closing";default:return"closed"}}isConnected(){return this.connectionState()==="open"}remove(e){this.off(e.stateChangeRefs),this.channels=this.channels.filter(t=>t.joinRef()!==e.joinRef())}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 j(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:r}=e;this.log("push",`${t} ${i} (${r}, ${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(){this.pendingHeartbeatRef&&!this.isConnected()||(this.pendingHeartbeatRef=this.makeRef(),this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:this.pendingHeartbeatRef}),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:r,join_ref:n}=t;r&&r===this.pendingHeartbeatRef&&(this.clearHeartbeats(),this.pendingHeartbeatRef=null,this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs)),this.hasLogger()&&this.log("receive",`${o.status||""} ${i} ${s} ${r&&"("+r+")"||""}`,o);for(let a=0;a<this.channels.length;a++){let l=this.channels[a];!l.isMember(i,s,o,n)||l.trigger(s,o,r,n)}for(let a=0;a<this.stateChangeCallbacks.message.length;a++){let[,l]=this.stateChangeCallbacks.message[a];l(t)}})}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(W);})();
var Phoenix=(()=>{var x=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var M=Object.prototype.hasOwnProperty;var $=(h,e)=>{for(var t in e)x(h,t,{get:e[t],enumerable:!0})},P=(h,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of U(e))!M.call(h,s)&&s!==t&&x(h,s,{get:()=>e[s],enumerable:!(i=D(e,s))||i.enumerable});return h};var J=h=>P(x({},"__esModule",{value:!0}),h);var W={};$(W,{Channel:()=>j,LongPoll:()=>T,Presence:()=>m,Serializer:()=>y,Socket:()=>w});var S=h=>typeof h=="function"?h:function(){return h};var z=typeof self!="undefined"?self:null,A=typeof window!="undefined"?window:null,R=z||A||R,N="2.0.0",d={connecting:0,open:1,closing:2,closed:3},H=1e4,B=1e3,u={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},p={close:"phx_close",error:"phx_error",join:"phx_join",reply:"phx_reply",leave:"phx_leave"},k={longpoll:"longpoll",websocket:"websocket"},O={complete:4};var E=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}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}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=null,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 j=class{constructor(e,t,i){this.state=u.closed,this.topic=e,this.params=S(t||{}),this.socket=i,this.bindings=[],this.bindingRef=0,this.timeout=this.socket.timeout,this.joinedOnce=!1,this.joinPush=new E(this,p.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",()=>{this.state=u.errored,this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.onClose(()=>{this.rejoinTimer.reset(),this.socket.hasLogger()&&this.socket.log("channel",`close ${this.topic} ${this.joinRef()}`),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.joinRef()})`,this.joinPush.timeout),new E(this,p.leave,S({}),this.timeout).send(),this.state=u.errored,this.joinPush.reset(),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.on(p.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}onClose(e){this.on(p.close,e)}onError(e){return this.on(p.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 E(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(p.close,"leave")},i=new E(this,p.leave,S({}),e);return i.receive("ok",()=>t()).receive("timeout",()=>t()),i.send(),this.canPush()||i.trigger("ok",{}),i}onMessage(e,t,i){return t}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 r=this.bindings.filter(n=>n.event===e);for(let n=0;n<r.length;n++)r[n].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 g=class{static request(e,t,i,s,o,r,n){if(R.XDomainRequest){let a=new R.XDomainRequest;return this.xdomainRequest(a,e,t,s,o,r,n)}else{let a=new R.XMLHttpRequest;return this.xhrRequest(a,e,t,i,s,o,r,n)}}static xdomainRequest(e,t,i,s,o,r,n){return e.timeout=o,e.open(t,i),e.onload=()=>{let a=this.parseJSON(e.responseText);n&&n(a)},r&&(e.ontimeout=r),e.onprogress=()=>{},e.send(s),e}static xhrRequest(e,t,i,s,o,r,n,a){return e.open(t,i,!0),e.timeout=r,e.setRequestHeader("Content-Type",s),e.onerror=()=>a&&a(null),e.onreadystatechange=()=>{if(e.readyState===O.complete&&a){let l=this.parseJSON(e.responseText);a(l)}},n&&(e.ontimeout=n),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,r=e[s];typeof r=="object"?i.push(this.serialize(r,o)):i.push(encodeURIComponent(o)+"="+encodeURIComponent(r))}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 I=h=>{let e="",t=new Uint8Array(h),i=t.byteLength;for(let s=0;s<i;s++)e+=String.fromCharCode(t[s]);return btoa(e)},T=class{constructor(e){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=d.connecting,this.poll()}normalizeEndpoint(e){return e.replace("ws://","http://").replace("wss://","https://").replace(new RegExp("(.*)/"+k.websocket),"$1/"+k.longpoll)}endpointURL(){return g.appendParams(this.pollEndpoint,{token:this.token})}closeAndRetry(e,t,i){this.close(e,t,i),this.readyState=d.connecting}ontimeout(){this.onerror("timeout"),this.closeAndRetry(1005,"timeout",!1)}isActive(){return this.readyState===d.open||this.readyState===d.connecting}poll(){this.ajax("GET","application/json",null,()=>this.ontimeout(),e=>{if(e){var{status:t,token:i,messages:s}=e;this.token=i}else t=0;switch(t){case 200:s.forEach(o=>{setTimeout(()=>this.onmessage({data:o}),0)}),this.poll();break;case 204:this.poll();break;case 410:this.readyState=d.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 ${t}`)}})}send(e){typeof e!="string"&&(e=I(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","application/x-ndjson",e.join(`
`),()=>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=d.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 r,n=()=>{this.reqs.delete(r),s()};r=g.request(e,this.endpointURL(),t,i,this.timeout,n,a=>{this.reqs.delete(r),this.isActive()&&o(a)}),this.reqs.add(r)}};var m=class{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:r,onSync:n}=this.caller;this.joinRef=this.channel.joinRef(),this.state=m.syncState(this.state,s,o,r),this.pendingDiffs.forEach(a=>{this.state=m.syncDiff(this.state,a,o,r)}),this.pendingDiffs=[],n()}),this.channel.on(i.diff,s=>{let{onJoin:o,onLeave:r,onSync:n}=this.caller;this.inPendingSyncState()?this.pendingDiffs.push(s):(this.state=m.syncDiff(this.state,s,o,r),n())})}onJoin(e){this.caller.onJoin=e}onLeave(e){this.caller.onLeave=e}onSync(e){this.caller.onSync=e}list(e){return m.list(this.state,e)}inPendingSyncState(){return!this.joinRef||this.joinRef!==this.channel.joinRef()}static syncState(e,t,i,s){let o=this.clone(e),r={},n={};return this.map(o,(a,l)=>{t[a]||(n[a]=l)}),this.map(t,(a,l)=>{let f=o[a];if(f){let c=l.metas.map(v=>v.phx_ref),C=f.metas.map(v=>v.phx_ref),L=l.metas.filter(v=>C.indexOf(v.phx_ref)<0),_=f.metas.filter(v=>c.indexOf(v.phx_ref)<0);L.length>0&&(r[a]=l,r[a].metas=L),_.length>0&&(n[a]=this.clone(f),n[a].metas=_)}else r[a]=l}),this.syncDiff(o,{joins:r,leaves:n},i,s)}static syncDiff(e,t,i,s){let{joins:o,leaves:r}=this.clone(t);return i||(i=function(){}),s||(s=function(){}),this.map(o,(n,a)=>{let l=e[n];if(e[n]=this.clone(a),l){let f=e[n].metas.map(C=>C.phx_ref),c=l.metas.filter(C=>f.indexOf(C.phx_ref)<0);e[n].metas.unshift(...c)}i(n,l,a)}),this.map(r,(n,a)=>{let l=e[n];if(!l)return;let f=a.metas.map(c=>c.phx_ref);l.metas=l.metas.filter(c=>f.indexOf(c.phx_ref)<0),s(n,l,a),l.metas.length===0&&delete e[n]}),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(h,e){if(h.payload.constructor===ArrayBuffer)return e(this.binaryEncode(h));{let t=[h.join_ref,h.ref,h.topic,h.event,h.payload];return e(JSON.stringify(t))}},decode(h,e){if(h.constructor===ArrayBuffer)return e(this.binaryDecode(h));{let[t,i,s,o,r]=JSON.parse(h);return e({join_ref:t,ref:i,topic:s,event:o,payload:r})}},binaryEncode(h){let{join_ref:e,ref:t,event:i,topic:s,payload:o}=h,r=this.META_LENGTH+e.length+t.length+s.length+i.length,n=new ArrayBuffer(this.HEADER_LENGTH+r),a=new DataView(n),l=0;a.setUint8(l++,this.KINDS.push),a.setUint8(l++,e.length),a.setUint8(l++,t.length),a.setUint8(l++,s.length),a.setUint8(l++,i.length),Array.from(e,c=>a.setUint8(l++,c.charCodeAt(0))),Array.from(t,c=>a.setUint8(l++,c.charCodeAt(0))),Array.from(s,c=>a.setUint8(l++,c.charCodeAt(0))),Array.from(i,c=>a.setUint8(l++,c.charCodeAt(0)));var f=new Uint8Array(n.byteLength+o.byteLength);return f.set(new Uint8Array(n),0),f.set(new Uint8Array(o),n.byteLength),f.buffer},binaryDecode(h){let e=new DataView(h),t=e.getUint8(0),i=new TextDecoder;switch(t){case this.KINDS.push:return this.decodePush(h,e,i);case this.KINDS.reply:return this.decodeReply(h,e,i);case this.KINDS.broadcast:return this.decodeBroadcast(h,e,i)}},decodePush(h,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=e.getUint8(3),r=this.HEADER_LENGTH+this.META_LENGTH-1,n=t.decode(h.slice(r,r+i));r=r+i;let a=t.decode(h.slice(r,r+s));r=r+s;let l=t.decode(h.slice(r,r+o));r=r+o;let f=h.slice(r,h.byteLength);return{join_ref:n,ref:null,topic:a,event:l,payload:f}},decodeReply(h,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=e.getUint8(3),r=e.getUint8(4),n=this.HEADER_LENGTH+this.META_LENGTH,a=t.decode(h.slice(n,n+i));n=n+i;let l=t.decode(h.slice(n,n+s));n=n+s;let f=t.decode(h.slice(n,n+o));n=n+o;let c=t.decode(h.slice(n,n+r));n=n+r;let C=h.slice(n,h.byteLength),L={status:c,response:C};return{join_ref:a,ref:l,topic:f,event:p.reply,payload:L}},decodeBroadcast(h,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=this.HEADER_LENGTH+2,r=t.decode(h.slice(o,o+i));o=o+i;let n=t.decode(h.slice(o,o+s));o=o+s;let a=h.slice(o,h.byteLength);return{join_ref:null,ref:null,topic:r,event:n,payload:a}}};var w=class{constructor(e,t={}){this.stateChangeCallbacks={open:[],close:[],error:[],message:[]},this.channels=[],this.sendBuffer=[],this.ref=0,this.timeout=t.timeout||H,this.transport=t.transport||R.WebSocket||T,this.establishedConnections=0,this.defaultEncoder=y.encode.bind(y),this.defaultDecoder=y.decode.bind(y),this.closeWasClean=!1,this.binaryType=t.binaryType||"arraybuffer",this.connectClock=1,this.transport!==T?(this.encode=t.encode||this.defaultEncoder,this.decode=t.decode||this.defaultDecoder):(this.encode=this.defaultEncoder,this.decode=this.defaultDecoder);let i=null;A&&A.addEventListener&&(A.addEventListener("pagehide",s=>{this.conn&&(this.disconnect(),i=this.connectClock)}),A.addEventListener("pageshow",s=>{i===this.connectClock&&(i=null,this.connect())})),this.heartbeatIntervalMs=t.heartbeatIntervalMs||3e4,this.rejoinAfterMs=s=>t.rejoinAfterMs?t.rejoinAfterMs(s):[1e3,2e3,5e3][s-1]||1e4,this.reconnectAfterMs=s=>t.reconnectAfterMs?t.reconnectAfterMs(s):[10,50,100,150,200,250,500,1e3,2e3][s-1]||5e3,this.logger=t.logger||null,this.longpollerTimeout=t.longpollerTimeout||2e4,this.params=S(t.params||{}),this.endPoint=`${e}/${k.websocket}`,this.vsn=t.vsn||N,this.heartbeatTimeoutTimer=null,this.heartbeatTimer=null,this.pendingHeartbeatRef=null,this.reconnectTimer=new b(()=>{this.teardown(()=>this.connect())},this.reconnectAfterMs)}getLongPollTransport(){return T}replaceTransport(e){this.connectClock++,this.closeWasClean=!0,this.reconnectTimer.reset(),this.sendBuffer=[],this.conn&&(this.conn.close(),this.conn=null),this.transport=e}protocol(){return location.protocol.match(/^https/)?"wss":"ws"}endPointURL(){let e=g.appendParams(g.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.closeWasClean=!0,this.reconnectTimer.reset(),this.teardown(e,t,i)}connect(e){e&&(console&&console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor"),this.params=S(e)),!this.conn&&(this.connectClock++,this.closeWasClean=!1,this.conn=new this.transport(this.endPointURL()),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))}log(e,t,i){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}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}clearHeartbeats(){clearTimeout(this.heartbeatTimer),clearTimeout(this.heartbeatTimeoutTimer)}onConnOpen(){this.hasLogger()&&this.log("transport",`connected to ${this.endPointURL()}`),this.closeWasClean=!1,this.establishedConnections++,this.flushSendBuffer(),this.reconnectTimer.reset(),this.resetHeartbeat(),this.stateChangeCallbacks.open.forEach(([,e])=>e())}heartbeatTimeout(){this.pendingHeartbeatRef&&(this.pendingHeartbeatRef=null,this.hasLogger()&&this.log("transport","heartbeat timeout. Attempting to re-establish connection"),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();this.waitForBufferDone(()=>{this.conn&&(t?this.conn.close(t,i||""):this.conn.close()),this.waitForSocketClosed(()=>{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===d.closed){e();return}setTimeout(()=>{this.waitForSocketClosed(e,t+1)},150*t)}onConnClose(e){let t=e&&e.code;this.hasLogger()&&this.log("transport","close",e),this.triggerChanError(),this.clearHeartbeats(),!this.closeWasClean&&t!==1e3&&this.reconnectTimer.scheduleTimeout(),this.stateChangeCallbacks.close.forEach(([,i])=>i(e))}onConnError(e){this.hasLogger()&&this.log("transport",e);let t=this.transport,i=this.establishedConnections;this.stateChangeCallbacks.error.forEach(([,s])=>{s(e,t,i)}),(t===this.transport||i>0)&&this.triggerChanError()}triggerChanError(){this.channels.forEach(e=>{e.isErrored()||e.isLeaving()||e.isClosed()||e.trigger(p.error)})}connectionState(){switch(this.conn&&this.conn.readyState){case d.connecting:return"connecting";case d.open:return"open";case d.closing:return"closing";default:return"closed"}}isConnected(){return this.connectionState()==="open"}remove(e){this.off(e.stateChangeRefs),this.channels=this.channels.filter(t=>t.joinRef()!==e.joinRef())}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 j(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:r}=e;this.log("push",`${t} ${i} (${r}, ${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(){this.pendingHeartbeatRef&&!this.isConnected()||(this.pendingHeartbeatRef=this.makeRef(),this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:this.pendingHeartbeatRef}),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:r,join_ref:n}=t;r&&r===this.pendingHeartbeatRef&&(this.clearHeartbeats(),this.pendingHeartbeatRef=null,this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs)),this.hasLogger()&&this.log("receive",`${o.status||""} ${i} ${s} ${r&&"("+r+")"||""}`,o);for(let a=0;a<this.channels.length;a++){let l=this.channels[a];l.isMember(i,s,o,n)&&l.trigger(s,o,r,n)}for(let a=0;a<this.stateChangeCallbacks.message.length;a++){let[,l]=this.stateChangeCallbacks.message[a];l(t)}})}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(W);})();

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc