UNPKG

pusher-js

Version:

Pusher Channels JavaScript library for browsers, React Native, NodeJS and web workers

1,653 lines (1,578 loc) 131 kB
/*! * Pusher JavaScript Library v8.5.0 * https://pusher.com/ * * Copyright 2020, Pusher * Released under the MIT licence. */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["Pusher"] = factory(); else root["Pusher"] = factory(); })(this, () => { return /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ 594 (__unused_webpack_module, exports) { "use strict"; // Copyright (C) 2016 Dmitry Chestnykh // MIT License. See LICENSE file for details. var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", ({ value: true })); /** * Package base64 implements Base64 encoding and decoding. */ // Invalid character used in decoding to indicate // that the character to decode is out of range of // alphabet and cannot be decoded. var INVALID_BYTE = 256; /** * Implements standard Base64 encoding. * * Operates in constant time. */ var Coder = /** @class */ (function () { // TODO(dchest): methods to encode chunk-by-chunk. function Coder(_paddingCharacter) { if (_paddingCharacter === void 0) { _paddingCharacter = "="; } this._paddingCharacter = _paddingCharacter; } Coder.prototype.encodedLength = function (length) { if (!this._paddingCharacter) { return (length * 8 + 5) / 6 | 0; } return (length + 2) / 3 * 4 | 0; }; Coder.prototype.encode = function (data) { var out = ""; var i = 0; for (; i < data.length - 2; i += 3) { var c = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]); out += this._encodeByte((c >>> 3 * 6) & 63); out += this._encodeByte((c >>> 2 * 6) & 63); out += this._encodeByte((c >>> 1 * 6) & 63); out += this._encodeByte((c >>> 0 * 6) & 63); } var left = data.length - i; if (left > 0) { var c = (data[i] << 16) | (left === 2 ? data[i + 1] << 8 : 0); out += this._encodeByte((c >>> 3 * 6) & 63); out += this._encodeByte((c >>> 2 * 6) & 63); if (left === 2) { out += this._encodeByte((c >>> 1 * 6) & 63); } else { out += this._paddingCharacter || ""; } out += this._paddingCharacter || ""; } return out; }; Coder.prototype.maxDecodedLength = function (length) { if (!this._paddingCharacter) { return (length * 6 + 7) / 8 | 0; } return length / 4 * 3 | 0; }; Coder.prototype.decodedLength = function (s) { return this.maxDecodedLength(s.length - this._getPaddingLength(s)); }; Coder.prototype.decode = function (s) { if (s.length === 0) { return new Uint8Array(0); } var paddingLength = this._getPaddingLength(s); var length = s.length - paddingLength; var out = new Uint8Array(this.maxDecodedLength(length)); var op = 0; var i = 0; var haveBad = 0; var v0 = 0, v1 = 0, v2 = 0, v3 = 0; for (; i < length - 4; i += 4) { v0 = this._decodeChar(s.charCodeAt(i + 0)); v1 = this._decodeChar(s.charCodeAt(i + 1)); v2 = this._decodeChar(s.charCodeAt(i + 2)); v3 = this._decodeChar(s.charCodeAt(i + 3)); out[op++] = (v0 << 2) | (v1 >>> 4); out[op++] = (v1 << 4) | (v2 >>> 2); out[op++] = (v2 << 6) | v3; haveBad |= v0 & INVALID_BYTE; haveBad |= v1 & INVALID_BYTE; haveBad |= v2 & INVALID_BYTE; haveBad |= v3 & INVALID_BYTE; } if (i < length - 1) { v0 = this._decodeChar(s.charCodeAt(i)); v1 = this._decodeChar(s.charCodeAt(i + 1)); out[op++] = (v0 << 2) | (v1 >>> 4); haveBad |= v0 & INVALID_BYTE; haveBad |= v1 & INVALID_BYTE; } if (i < length - 2) { v2 = this._decodeChar(s.charCodeAt(i + 2)); out[op++] = (v1 << 4) | (v2 >>> 2); haveBad |= v2 & INVALID_BYTE; } if (i < length - 3) { v3 = this._decodeChar(s.charCodeAt(i + 3)); out[op++] = (v2 << 6) | v3; haveBad |= v3 & INVALID_BYTE; } if (haveBad !== 0) { throw new Error("Base64Coder: incorrect characters for decoding"); } return out; }; // Standard encoding have the following encoded/decoded ranges, // which we need to convert between. // // ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 + / // Index: 0 - 25 26 - 51 52 - 61 62 63 // ASCII: 65 - 90 97 - 122 48 - 57 43 47 // // Encode 6 bits in b into a new character. Coder.prototype._encodeByte = function (b) { // Encoding uses constant time operations as follows: // // 1. Define comparison of A with B using (A - B) >>> 8: // if A > B, then result is positive integer // if A <= B, then result is 0 // // 2. Define selection of C or 0 using bitwise AND: X & C: // if X == 0, then result is 0 // if X != 0, then result is C // // 3. Start with the smallest comparison (b >= 0), which is always // true, so set the result to the starting ASCII value (65). // // 4. Continue comparing b to higher ASCII values, and selecting // zero if comparison isn't true, otherwise selecting a value // to add to result, which: // // a) undoes the previous addition // b) provides new value to add // var result = b; // b >= 0 result += 65; // b > 25 result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97); // b > 51 result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48); // b > 61 result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 43); // b > 62 result += ((62 - b) >>> 8) & ((62 - 43) - 63 + 47); return String.fromCharCode(result); }; // Decode a character code into a byte. // Must return 256 if character is out of alphabet range. Coder.prototype._decodeChar = function (c) { // Decoding works similar to encoding: using the same comparison // function, but now it works on ranges: result is always incremented // by value, but this value becomes zero if the range is not // satisfied. // // Decoding starts with invalid value, 256, which is then // subtracted when the range is satisfied. If none of the ranges // apply, the function returns 256, which is then checked by // the caller to throw error. var result = INVALID_BYTE; // start with invalid character // c == 43 (c > 42 and c < 44) result += (((42 - c) & (c - 44)) >>> 8) & (-INVALID_BYTE + c - 43 + 62); // c == 47 (c > 46 and c < 48) result += (((46 - c) & (c - 48)) >>> 8) & (-INVALID_BYTE + c - 47 + 63); // c > 47 and c < 58 result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52); // c > 64 and c < 91 result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0); // c > 96 and c < 123 result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26); return result; }; Coder.prototype._getPaddingLength = function (s) { var paddingLength = 0; if (this._paddingCharacter) { for (var i = s.length - 1; i >= 0; i--) { if (s[i] !== this._paddingCharacter) { break; } paddingLength++; } if (s.length < 4 || paddingLength > 2) { throw new Error("Base64Coder: incorrect padding"); } } return paddingLength; }; return Coder; }()); exports.Coder = Coder; var stdCoder = new Coder(); function encode(data) { return stdCoder.encode(data); } exports.encode = encode; function decode(s) { return stdCoder.decode(s); } exports.decode = decode; /** * Implements URL-safe Base64 encoding. * (Same as Base64, but '+' is replaced with '-', and '/' with '_'). * * Operates in constant time. */ var URLSafeCoder = /** @class */ (function (_super) { __extends(URLSafeCoder, _super); function URLSafeCoder() { return _super !== null && _super.apply(this, arguments) || this; } // URL-safe encoding have the following encoded/decoded ranges: // // ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 - _ // Index: 0 - 25 26 - 51 52 - 61 62 63 // ASCII: 65 - 90 97 - 122 48 - 57 45 95 // URLSafeCoder.prototype._encodeByte = function (b) { var result = b; // b >= 0 result += 65; // b > 25 result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97); // b > 51 result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48); // b > 61 result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 45); // b > 62 result += ((62 - b) >>> 8) & ((62 - 45) - 63 + 95); return String.fromCharCode(result); }; URLSafeCoder.prototype._decodeChar = function (c) { var result = INVALID_BYTE; // c == 45 (c > 44 and c < 46) result += (((44 - c) & (c - 46)) >>> 8) & (-INVALID_BYTE + c - 45 + 62); // c == 95 (c > 94 and c < 96) result += (((94 - c) & (c - 96)) >>> 8) & (-INVALID_BYTE + c - 95 + 63); // c > 47 and c < 58 result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52); // c > 64 and c < 91 result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0); // c > 96 and c < 123 result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26); return result; }; return URLSafeCoder; }(Coder)); exports.URLSafeCoder = URLSafeCoder; var urlSafeCoder = new URLSafeCoder(); function encodeURLSafe(data) { return urlSafeCoder.encode(data); } exports.encodeURLSafe = encodeURLSafe; function decodeURLSafe(s) { return urlSafeCoder.decode(s); } exports.decodeURLSafe = decodeURLSafe; exports.encodedLength = function (length) { return stdCoder.encodedLength(length); }; exports.maxDecodedLength = function (length) { return stdCoder.maxDecodedLength(length); }; exports.decodedLength = function (s) { return stdCoder.decodedLength(s); }; /***/ }, /***/ 978 (__unused_webpack_module, exports) { "use strict"; var __webpack_unused_export__; // Copyright (C) 2016 Dmitry Chestnykh // MIT License. See LICENSE file for details. __webpack_unused_export__ = ({ value: true }); /** * Package utf8 implements UTF-8 encoding and decoding. */ var INVALID_UTF16 = "utf8: invalid string"; var INVALID_UTF8 = "utf8: invalid source encoding"; /** * Encodes the given string into UTF-8 byte array. * Throws if the source string has invalid UTF-16 encoding. */ function encode(s) { // Calculate result length and allocate output array. // encodedLength() also validates string and throws errors, // so we don't need repeat validation here. var arr = new Uint8Array(encodedLength(s)); var pos = 0; for (var i = 0; i < s.length; i++) { var c = s.charCodeAt(i); if (c < 0x80) { arr[pos++] = c; } else if (c < 0x800) { arr[pos++] = 0xc0 | c >> 6; arr[pos++] = 0x80 | c & 0x3f; } else if (c < 0xd800) { arr[pos++] = 0xe0 | c >> 12; arr[pos++] = 0x80 | (c >> 6) & 0x3f; arr[pos++] = 0x80 | c & 0x3f; } else { i++; // get one more character c = (c & 0x3ff) << 10; c |= s.charCodeAt(i) & 0x3ff; c += 0x10000; arr[pos++] = 0xf0 | c >> 18; arr[pos++] = 0x80 | (c >> 12) & 0x3f; arr[pos++] = 0x80 | (c >> 6) & 0x3f; arr[pos++] = 0x80 | c & 0x3f; } } return arr; } __webpack_unused_export__ = encode; /** * Returns the number of bytes required to encode the given string into UTF-8. * Throws if the source string has invalid UTF-16 encoding. */ function encodedLength(s) { var result = 0; for (var i = 0; i < s.length; i++) { var c = s.charCodeAt(i); if (c < 0x80) { result += 1; } else if (c < 0x800) { result += 2; } else if (c < 0xd800) { result += 3; } else if (c <= 0xdfff) { if (i >= s.length - 1) { throw new Error(INVALID_UTF16); } i++; // "eat" next character result += 4; } else { throw new Error(INVALID_UTF16); } } return result; } __webpack_unused_export__ = encodedLength; /** * Decodes the given byte array from UTF-8 into a string. * Throws if encoding is invalid. */ function decode(arr) { var chars = []; for (var i = 0; i < arr.length; i++) { var b = arr[i]; if (b & 0x80) { var min = void 0; if (b < 0xe0) { // Need 1 more byte. if (i >= arr.length) { throw new Error(INVALID_UTF8); } var n1 = arr[++i]; if ((n1 & 0xc0) !== 0x80) { throw new Error(INVALID_UTF8); } b = (b & 0x1f) << 6 | (n1 & 0x3f); min = 0x80; } else if (b < 0xf0) { // Need 2 more bytes. if (i >= arr.length - 1) { throw new Error(INVALID_UTF8); } var n1 = arr[++i]; var n2 = arr[++i]; if ((n1 & 0xc0) !== 0x80 || (n2 & 0xc0) !== 0x80) { throw new Error(INVALID_UTF8); } b = (b & 0x0f) << 12 | (n1 & 0x3f) << 6 | (n2 & 0x3f); min = 0x800; } else if (b < 0xf8) { // Need 3 more bytes. if (i >= arr.length - 2) { throw new Error(INVALID_UTF8); } var n1 = arr[++i]; var n2 = arr[++i]; var n3 = arr[++i]; if ((n1 & 0xc0) !== 0x80 || (n2 & 0xc0) !== 0x80 || (n3 & 0xc0) !== 0x80) { throw new Error(INVALID_UTF8); } b = (b & 0x0f) << 18 | (n1 & 0x3f) << 12 | (n2 & 0x3f) << 6 | (n3 & 0x3f); min = 0x10000; } else { throw new Error(INVALID_UTF8); } if (b < min || (b >= 0xd800 && b <= 0xdfff)) { throw new Error(INVALID_UTF8); } if (b >= 0x10000) { // Surrogate pair. if (b > 0x10ffff) { throw new Error(INVALID_UTF8); } b -= 0x10000; chars.push(String.fromCharCode(0xd800 | (b >> 10))); b = 0xdc00 | (b & 0x3ff); } } chars.push(String.fromCharCode(b)); } return chars.join(""); } exports.D4 = decode; /***/ }, /***/ 721 (module, __unused_webpack_exports, __webpack_require__) { // required so we don't have to do require('pusher').default etc. module.exports = __webpack_require__(288)["default"]; /***/ }, /***/ 288 (__unused_webpack_module, __webpack_exports__, __webpack_require__) { "use strict"; // EXPORTS __webpack_require__.d(__webpack_exports__, { "default": () => (/* binding */ pusher) }); ;// ./src/core/base64.ts function encode(s) { return btoa(utob(s)); } var fromCharCode = String.fromCharCode; var b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; var b64tab = {}; for (var i = 0, l = b64chars.length; i < l; i++) { b64tab[b64chars.charAt(i)] = i; } var cb_utob = function (c) { var cc = c.charCodeAt(0); return cc < 0x80 ? c : cc < 0x800 ? fromCharCode(0xc0 | (cc >>> 6)) + fromCharCode(0x80 | (cc & 0x3f)) : fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + fromCharCode(0x80 | (cc & 0x3f)); }; var utob = function (u) { return u.replace(/[^\x00-\x7F]/g, cb_utob); }; var cb_encode = function (ccc) { var padlen = [0, 2, 1][ccc.length % 3]; var ord = (ccc.charCodeAt(0) << 16) | ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8) | (ccc.length > 2 ? ccc.charCodeAt(2) : 0); var chars = [ b64chars.charAt(ord >>> 18), b64chars.charAt((ord >>> 12) & 63), padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63), padlen >= 1 ? '=' : b64chars.charAt(ord & 63), ]; return chars.join(''); }; var btoa = self.btoa || function (b) { return b.replace(/[\s\S]{1,3}/g, cb_encode); }; ;// ./src/core/utils/timers/abstract_timer.ts class Timer { constructor(set, clear, delay, callback) { this.clear = clear; this.timer = set(() => { if (this.timer) { this.timer = callback(this.timer); } }, delay); } isRunning() { return this.timer !== null; } ensureAborted() { if (this.timer) { this.clear(this.timer); this.timer = null; } } } /* harmony default export */ const abstract_timer = (Timer); ;// ./src/core/utils/timers/index.ts function timers_clearTimeout(timer) { self.clearTimeout(timer); } function timers_clearInterval(timer) { self.clearInterval(timer); } class OneOffTimer extends abstract_timer { constructor(delay, callback) { super(setTimeout, timers_clearTimeout, delay, function (timer) { callback(); return null; }); } } class PeriodicTimer extends abstract_timer { constructor(delay, callback) { super(setInterval, timers_clearInterval, delay, function (timer) { callback(); return timer; }); } } ;// ./src/core/util.ts var Util = { now() { if (Date.now) { return Date.now(); } else { return new Date().valueOf(); } }, defer(callback) { return new OneOffTimer(0, callback); }, method(name, ...args) { var boundArguments = Array.prototype.slice.call(arguments, 1); return function (object) { return object[name].apply(object, boundArguments.concat(arguments)); }; }, }; /* harmony default export */ const util = (Util); ;// ./src/core/utils/collections.ts function extend(target, ...sources) { for (var i = 0; i < sources.length; i++) { var extensions = sources[i]; for (var property in extensions) { if (extensions[property] && extensions[property].constructor && extensions[property].constructor === Object) { target[property] = extend(target[property] || {}, extensions[property]); } else { target[property] = extensions[property]; } } } return target; } function stringify() { var m = ['Pusher']; for (var i = 0; i < arguments.length; i++) { if (typeof arguments[i] === 'string') { m.push(arguments[i]); } else { m.push(safeJSONStringify(arguments[i])); } } return m.join(' : '); } function arrayIndexOf(array, item) { var nativeIndexOf = Array.prototype.indexOf; if (array === null) { return -1; } if (nativeIndexOf && array.indexOf === nativeIndexOf) { return array.indexOf(item); } for (var i = 0, l = array.length; i < l; i++) { if (array[i] === item) { return i; } } return -1; } function objectApply(object, f) { for (var key in object) { if (Object.prototype.hasOwnProperty.call(object, key)) { f(object[key], key, object); } } } function keys(object) { var keys = []; objectApply(object, function (_, key) { keys.push(key); }); return keys; } function values(object) { var values = []; objectApply(object, function (value) { values.push(value); }); return values; } function apply(array, f, context) { for (var i = 0; i < array.length; i++) { f.call(context || self, array[i], i, array); } } function map(array, f) { var result = []; for (var i = 0; i < array.length; i++) { result.push(f(array[i], i, array, result)); } return result; } function mapObject(object, f) { var result = {}; objectApply(object, function (value, key) { result[key] = f(value); }); return result; } function filter(array, test) { test = test || function (value) { return !!value; }; var result = []; for (var i = 0; i < array.length; i++) { if (test(array[i], i, array, result)) { result.push(array[i]); } } return result; } function filterObject(object, test) { var result = {}; objectApply(object, function (value, key) { if ((test && test(value, key, object, result)) || Boolean(value)) { result[key] = value; } }); return result; } function flatten(object) { var result = []; objectApply(object, function (value, key) { result.push([key, value]); }); return result; } function any(array, test) { for (var i = 0; i < array.length; i++) { if (test(array[i], i, array)) { return true; } } return false; } function collections_all(array, test) { for (var i = 0; i < array.length; i++) { if (!test(array[i], i, array)) { return false; } } return true; } function encodeParamsObject(data) { return mapObject(data, function (value) { if (typeof value === 'object') { value = safeJSONStringify(value); } return encodeURIComponent(encode(value.toString())); }); } function buildQueryString(data) { var params = filterObject(data, function (value) { return value !== undefined; }); var query = map(flatten(encodeParamsObject(params)), util.method('join', '=')).join('&'); return query; } function decycleObject(object) { var objects = [], paths = []; return (function derez(value, path) { var i, name, nu; switch (typeof value) { case 'object': if (!value) { return null; } for (i = 0; i < objects.length; i += 1) { if (objects[i] === value) { return { $ref: paths[i] }; } } objects.push(value); paths.push(path); if (Object.prototype.toString.apply(value) === '[object Array]') { nu = []; for (i = 0; i < value.length; i += 1) { nu[i] = derez(value[i], path + '[' + i + ']'); } } else { nu = {}; for (name in value) { if (Object.prototype.hasOwnProperty.call(value, name)) { nu[name] = derez(value[name], path + '[' + JSON.stringify(name) + ']'); } } } return nu; case 'number': case 'string': case 'boolean': return value; } })(object, '$'); } function safeJSONStringify(source) { try { return JSON.stringify(source); } catch (e) { return JSON.stringify(decycleObject(source)); } } ;// ./src/core/defaults.ts var Defaults = { VERSION: "8.5.0", PROTOCOL: 7, wsPort: 80, wssPort: 443, wsPath: '', httpHost: 'sockjs.pusher.com', httpPort: 80, httpsPort: 443, httpPath: '/pusher', stats_host: 'stats.pusher.com', authEndpoint: '/pusher/auth', authTransport: 'ajax', activityTimeout: 120000, pongTimeout: 30000, unavailableTimeout: 10000, userAuthentication: { endpoint: '/pusher/user-auth', transport: 'ajax', }, channelAuthorization: { endpoint: '/pusher/auth', transport: 'ajax', }, cdn_http: "http://js.pusher.com", cdn_https: "https://js.pusher.com", dependency_suffix: "", }; /* harmony default export */ const defaults = (Defaults); ;// ./src/core/transports/url_schemes.ts function getGenericURL(baseScheme, params, path) { var scheme = baseScheme + (params.useTLS ? 's' : ''); var host = params.useTLS ? params.hostTLS : params.hostNonTLS; return scheme + '://' + host + path; } function getGenericPath(key, queryString) { var path = '/app/' + key; var query = '?protocol=' + defaults.PROTOCOL + '&client=js' + '&version=' + defaults.VERSION + (queryString ? '&' + queryString : ''); return path + query; } var ws = { getInitial: function (key, params) { var path = (params.httpPath || '') + getGenericPath(key, 'flash=false'); return getGenericURL('ws', params, path); }, }; var http = { getInitial: function (key, params) { var path = (params.httpPath || '/pusher') + getGenericPath(key); return getGenericURL('http', params, path); }, }; var sockjs = { getInitial: function (key, params) { return getGenericURL('http', params, params.httpPath || '/pusher'); }, getPath: function (key, params) { return getGenericPath(key); }, }; ;// ./src/core/events/callback_registry.ts class CallbackRegistry { constructor() { this._callbacks = {}; } get(name) { return this._callbacks[prefix(name)]; } add(name, callback, context) { var prefixedEventName = prefix(name); this._callbacks[prefixedEventName] = this._callbacks[prefixedEventName] || []; this._callbacks[prefixedEventName].push({ fn: callback, context: context, }); } remove(name, callback, context) { if (!name && !callback && !context) { this._callbacks = {}; return; } var names = name ? [prefix(name)] : keys(this._callbacks); if (callback || context) { this.removeCallback(names, callback, context); } else { this.removeAllCallbacks(names); } } removeCallback(names, callback, context) { apply(names, function (name) { this._callbacks[name] = filter(this._callbacks[name] || [], function (binding) { return ((callback && callback !== binding.fn) || (context && context !== binding.context)); }); if (this._callbacks[name].length === 0) { delete this._callbacks[name]; } }, this); } removeAllCallbacks(names) { apply(names, function (name) { delete this._callbacks[name]; }, this); } } function prefix(name) { return '_' + name; } ;// ./src/core/events/dispatcher.ts class Dispatcher { constructor(failThrough) { this.callbacks = new CallbackRegistry(); this.global_callbacks = []; this.failThrough = failThrough; } bind(eventName, callback, context) { this.callbacks.add(eventName, callback, context); return this; } bind_global(callback) { this.global_callbacks.push(callback); return this; } unbind(eventName, callback, context) { this.callbacks.remove(eventName, callback, context); return this; } unbind_global(callback) { if (!callback) { this.global_callbacks = []; return this; } this.global_callbacks = filter(this.global_callbacks || [], (c) => c !== callback); return this; } unbind_all() { this.unbind(); this.unbind_global(); return this; } emit(eventName, data, metadata) { for (var i = 0; i < this.global_callbacks.length; i++) { this.global_callbacks[i](eventName, data); } var callbacks = this.callbacks.get(eventName); var args = []; if (metadata) { args.push(data, metadata); } else if (data) { args.push(data); } if (callbacks && callbacks.length > 0) { for (var i = 0; i < callbacks.length; i++) { callbacks[i].fn.apply(callbacks[i].context || self, args); } } else if (this.failThrough) { this.failThrough(eventName, data); } return this; } } ;// ./src/core/logger.ts class Logger { constructor() { this.globalLog = (message) => { if (self.console && self.console.log) { self.console.log(message); } }; } debug(...args) { this.log(this.globalLog, args); } warn(...args) { this.log(this.globalLogWarn, args); } error(...args) { this.log(this.globalLogError, args); } globalLogWarn(message) { if (self.console && self.console.warn) { self.console.warn(message); } else { this.globalLog(message); } } globalLogError(message) { if (self.console && self.console.error) { self.console.error(message); } else { this.globalLogWarn(message); } } log(defaultLoggingFunction, ...args) { var message = stringify.apply(this, arguments); if (pusher.log) { pusher.log(message); } else if (pusher.logToConsole) { const log = defaultLoggingFunction.bind(this); log(message); } } } /* harmony default export */ const logger = (new Logger()); ;// ./src/core/transports/transport_connection.ts class TransportConnection extends Dispatcher { constructor(hooks, name, priority, key, options) { super(); this.initialize = worker_runtime.transportConnectionInitializer; this.hooks = hooks; this.name = name; this.priority = priority; this.key = key; this.options = options; this.state = 'new'; this.timeline = options.timeline; this.activityTimeout = options.activityTimeout; this.id = this.timeline.generateUniqueID(); } handlesActivityChecks() { return Boolean(this.hooks.handlesActivityChecks); } supportsPing() { return Boolean(this.hooks.supportsPing); } connect() { if (this.socket || this.state !== 'initialized') { return false; } var url = this.hooks.urls.getInitial(this.key, this.options); try { this.socket = this.hooks.getSocket(url, this.options); } catch (e) { util.defer(() => { this.onError(e); this.changeState('closed'); }); return false; } this.bindListeners(); logger.debug('Connecting', { transport: this.name, url }); this.changeState('connecting'); return true; } close() { if (this.socket) { this.socket.close(); return true; } else { return false; } } send(data) { if (this.state === 'open') { util.defer(() => { if (this.socket) { this.socket.send(data); } }); return true; } else { return false; } } ping() { if (this.state === 'open' && this.supportsPing()) { this.socket.ping(); } } onOpen() { if (this.hooks.beforeOpen) { this.hooks.beforeOpen(this.socket, this.hooks.urls.getPath(this.key, this.options)); } this.changeState('open'); this.socket.onopen = undefined; } onError(error) { this.emit('error', { type: 'WebSocketError', error: error }); this.timeline.error(this.buildTimelineMessage({ error: error.toString() })); } onClose(closeEvent) { if (closeEvent) { this.changeState('closed', { code: closeEvent.code, reason: closeEvent.reason, wasClean: closeEvent.wasClean, }); } else { this.changeState('closed'); } this.unbindListeners(); this.socket = undefined; } onMessage(message) { this.emit('message', message); } onActivity() { this.emit('activity'); } bindListeners() { this.socket.onopen = () => { this.onOpen(); }; this.socket.onerror = (error) => { this.onError(error); }; this.socket.onclose = (closeEvent) => { this.onClose(closeEvent); }; this.socket.onmessage = (message) => { this.onMessage(message); }; if (this.supportsPing()) { this.socket.onactivity = () => { this.onActivity(); }; } } unbindListeners() { if (this.socket) { this.socket.onopen = undefined; this.socket.onerror = undefined; this.socket.onclose = undefined; this.socket.onmessage = undefined; if (this.supportsPing()) { this.socket.onactivity = undefined; } } } changeState(state, params) { this.state = state; this.timeline.info(this.buildTimelineMessage({ state: state, params: params, })); this.emit(state, params); } buildTimelineMessage(message) { return extend({ cid: this.id }, message); } } ;// ./src/core/transports/transport.ts class Transport { constructor(hooks) { this.hooks = hooks; } isSupported(environment) { return this.hooks.isSupported(environment); } createConnection(name, priority, key, options) { return new TransportConnection(this.hooks, name, priority, key, options); } } ;// ./src/runtimes/isomorphic/transports/transports.ts var WSTransport = new Transport({ urls: ws, handlesActivityChecks: false, supportsPing: false, isInitialized: function () { return Boolean(worker_runtime.getWebSocketAPI()); }, isSupported: function () { return Boolean(worker_runtime.getWebSocketAPI()); }, getSocket: function (url) { return worker_runtime.createWebSocket(url); }, }); var httpConfiguration = { urls: http, handlesActivityChecks: false, supportsPing: true, isInitialized: function () { return true; }, }; var streamingConfiguration = extend({ getSocket: function (url) { return worker_runtime.HTTPFactory.createStreamingSocket(url); }, }, httpConfiguration); var pollingConfiguration = extend({ getSocket: function (url) { return worker_runtime.HTTPFactory.createPollingSocket(url); }, }, httpConfiguration); var xhrConfiguration = { isSupported: function () { return worker_runtime.isXHRSupported(); }, }; var XHRStreamingTransport = new Transport((extend({}, streamingConfiguration, xhrConfiguration))); var XHRPollingTransport = new Transport((extend({}, pollingConfiguration, xhrConfiguration))); var Transports = { ws: WSTransport, xhr_streaming: XHRStreamingTransport, xhr_polling: XHRPollingTransport, }; /* harmony default export */ const transports = (Transports); ;// ./src/core/transports/assistant_to_the_transport_manager.ts class AssistantToTheTransportManager { constructor(manager, transport, options) { this.manager = manager; this.transport = transport; this.minPingDelay = options.minPingDelay; this.maxPingDelay = options.maxPingDelay; this.pingDelay = undefined; } createConnection(name, priority, key, options) { options = extend({}, options, { activityTimeout: this.pingDelay, }); var connection = this.transport.createConnection(name, priority, key, options); var openTimestamp = null; var onOpen = function () { connection.unbind('open', onOpen); connection.bind('closed', onClosed); openTimestamp = util.now(); }; var onClosed = (closeEvent) => { connection.unbind('closed', onClosed); if (closeEvent.code === 1002 || closeEvent.code === 1003) { this.manager.reportDeath(); } else if (!closeEvent.wasClean && openTimestamp) { var lifespan = util.now() - openTimestamp; if (lifespan < 2 * this.maxPingDelay) { this.manager.reportDeath(); this.pingDelay = Math.max(lifespan / 2, this.minPingDelay); } } }; connection.bind('open', onOpen); return connection; } isSupported(environment) { return this.manager.isAlive() && this.transport.isSupported(environment); } } ;// ./src/core/connection/protocol/protocol.ts const Protocol = { decodeMessage: function (messageEvent) { try { var messageData = JSON.parse(messageEvent.data); var pusherEventData = messageData.data; if (typeof pusherEventData === 'string') { try { pusherEventData = JSON.parse(messageData.data); } catch (e) { } } var pusherEvent = { event: messageData.event, channel: messageData.channel, data: pusherEventData, }; if (messageData.user_id) { pusherEvent.user_id = messageData.user_id; } return pusherEvent; } catch (e) { throw { type: 'MessageParseError', error: e, data: messageEvent.data }; } }, encodeMessage: function (event) { return JSON.stringify(event); }, processHandshake: function (messageEvent) { var message = Protocol.decodeMessage(messageEvent); if (message.event === 'pusher:connection_established') { if (!message.data.activity_timeout) { throw 'No activity timeout specified in handshake'; } return { action: 'connected', id: message.data.socket_id, activityTimeout: message.data.activity_timeout * 1000, }; } else if (message.event === 'pusher:error') { return { action: this.getCloseAction(message.data), error: this.getCloseError(message.data), }; } else { throw 'Invalid handshake'; } }, getCloseAction: function (closeEvent) { if (closeEvent.code < 4000) { if (closeEvent.code >= 1002 && closeEvent.code <= 1004) { return 'backoff'; } else { return null; } } else if (closeEvent.code === 4000) { return 'tls_only'; } else if (closeEvent.code < 4100) { return 'refused'; } else if (closeEvent.code < 4200) { return 'backoff'; } else if (closeEvent.code < 4300) { return 'retry'; } else { return 'refused'; } }, getCloseError: function (closeEvent) { if (closeEvent.code !== 1000 && closeEvent.code !== 1001) { return { type: 'PusherError', data: { code: closeEvent.code, message: closeEvent.reason || closeEvent.message, }, }; } else { return null; } }, }; /* harmony default export */ const protocol = (Protocol); ;// ./src/core/connection/connection.ts class Connection extends Dispatcher { constructor(id, transport) { super(); this.id = id; this.transport = transport; this.activityTimeout = transport.activityTimeout; this.bindListeners(); } handlesActivityChecks() { return this.transport.handlesActivityChecks(); } send(data) { return this.transport.send(data); } send_event(name, data, channel) { var event = { event: name, data: data }; if (channel) { event.channel = channel; } logger.debug('Event sent', event); return this.send(protocol.encodeMessage(event)); } ping() { if (this.transport.supportsPing()) { this.transport.ping(); } else { this.send_event('pusher:ping', {}); } } close() { this.transport.close(); } bindListeners() { var listeners = { message: (messageEvent) => { var pusherEvent; try { pusherEvent = protocol.decodeMessage(messageEvent); } catch (e) { this.emit('error', { type: 'MessageParseError', error: e, data: messageEvent.data, }); } if (pusherEvent !== undefined) { logger.debug('Event recd', pusherEvent); switch (pusherEvent.event) { case 'pusher:error': this.emit('error', { type: 'PusherError', data: pusherEvent.data, }); break; case 'pusher:ping': this.emit('ping'); break; case 'pusher:pong': this.emit('pong'); break; } this.emit('message', pusherEvent); } }, activity: () => { this.emit('activity'); }, error: (error) => { this.emit('error', error); }, closed: (closeEvent) => { unbindListeners(); if (closeEvent && closeEvent.code) { this.handleCloseEvent(closeEvent); } this.transport = null; this.emit('closed'); }, }; var unbindListeners = () => { objectApply(listeners, (listener, event) => { this.transport.unbind(event, listener); }); }; objectApply(listeners, (listener, event) => { this.transport.bind(event, listener); }); } handleCloseEvent(closeEvent) { var action = protocol.getCloseAction(closeEvent); var error = protocol.getCloseError(closeEvent); if (error) { this.emit('error', error); } if (action) { this.emit(action, { action: action, error: error }); } } } ;// ./src/core/connection/handshake/index.ts class Handshake { constructor(transport, callback) { this.transport = transport; this.callback = callback; this.bindListeners(); } close() { this.unbindListeners(); this.transport.close(); } bindListeners() { this.onMessage = (m) => { this.unbindListeners(); var result; try { result = protocol.processHandshake(m); } catch (e) { this.finish('error', { error: e }); this.transport.close(); return; } if (result.action === 'connected') { this.finish('connected', { connection: new Connection(result.id, this.transport), activityTimeout: result.activityTimeout, }); } else { this.finish(result.action, { error: result.error }); this.transport.close(); } }; this.onClosed = (closeEvent) => { this.unbindListeners(); var action = protocol.getCloseAction(closeEvent) || 'backoff'; var error = protocol.getCloseError(closeEvent); this.finish(action, { error: error }); }; this.transport.bind('message', this.onMessage); this.transport.bind('closed', this.onClosed); } unbindListeners() { this.transport.unbind('message', this.onMessage); this.transport.unbind('closed', this.onClosed); } finish(action, params) { this.callback(extend({ transport: this.transport, action: action }, params)); } } ;// ./src/core/timeline/timeline_sender.ts class TimelineSender { constructor(timeline, options) { this.timeline = timeline; this.options = options || {}; } send(useTLS, callback) { if (this.timeline.isEmpty()) { return; } this.timeline.send(worker_runtime.TimelineTransport.getAgent(this, useTLS), callback); } } ;// ./src/core/errors.ts class BadEventName extends Error { constructor(msg) { super(msg); Object.setPrototypeOf(this, new.target.prototype); } } class BadChannelName extends Error { constructor(msg) { super(msg); Object.setPrototypeOf(this, new.target.prototype); } } class RequestTimedOut extends Error { constructor(msg) { super(msg); Object.setPrototypeOf(this, new.target.prototype); } } class TransportPriorityTooLow extends Error { constructor(msg) { super(msg); Object.setPrototypeOf(this, new.target.prototype); } } class TransportClosed extends Error { constructor(msg) { super(msg); Object.setPrototypeOf(this, new.target.prototype); } } class UnsupportedFeature extends Error { constructor(msg) { super(msg); Object.setPrototypeOf(this, new.target.prototype); } } class UnsupportedTransport extends Error { constructor(msg) { super(msg); Object.setPrototypeOf(this, new.target.prototype); } } class UnsupportedStrategy extends Error { constructor(msg) { super(msg); Object.setPrototypeOf(this, new.target.prototype); } } class HTTPAuthError extends Error { constructor(status, msg) { super(msg); this.status = status; Object.setPrototypeOf(this, new.target.prototype); } } ;// ./src/core/utils/url_store.ts const urlStore = { baseUrl: 'https://pusher.com', urls: { authenticationEndpoint: { path: '/docs/channels/server_api/authenticating_users', }, authorizationEndpoint: { path: '/docs/channels/server_api/authorizing-users/', }, javascriptQuickStart: { path: '/docs/javascript_quick_start', }, triggeringClientEvents: { path: '/docs/client_api_guide/client_events#trigger-events', }, encryptedChannelSupport: { fullUrl: 'https://github.com/pusher/pusher-js/tree/cc491015371a4bde5743d1c87a0fbac0feb53195#encrypted-channel-support', }, }, }; const buildLogSuffix = function (key) { const urlPrefix = 'See:'; const urlObj = urlStore.urls[key]; if (!urlObj) return ''; let url; if (urlObj.fullUrl) { url = urlObj.fullUrl; } else if (urlObj.path) { url = urlStore.baseUrl + urlObj.path; } if (!url) return ''; return `${urlPrefix} ${url}`; }; /* harmony default export */ const url_store = ({ buildLogSuffix }); ;// ./src/core/channels/channel.ts class Channel extends Dispatcher { constructor(name, pusher) { super(function (event, data) { logger.debug('No callbacks on ' + name + ' for ' + event); }); this.name = name;