@wireblob/wire 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +293 -0
- package/lib/commonjs/wire.js +53 -0
- package/lib/commonjs/worker.js +9 -0
- package/lib/es/wire.js +48 -0
- package/lib/es/worker.js +2 -0
- package/lib/umd/wire.js +4428 -0
- package/lib/umd/wire.min.js +1 -0
- package/package.json +65 -0
package/lib/umd/wire.js
ADDED
|
@@ -0,0 +1,4428 @@
|
|
|
1
|
+
(function (global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Wire = factory());
|
|
5
|
+
})(this, (function () { 'use strict';
|
|
6
|
+
|
|
7
|
+
function getDefaultExportFromCjs (x) {
|
|
8
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
var pusher = {exports: {}};
|
|
12
|
+
|
|
13
|
+
/*!
|
|
14
|
+
* Pusher JavaScript Library v8.5.0
|
|
15
|
+
* https://pusher.com/
|
|
16
|
+
*
|
|
17
|
+
* Copyright 2020, Pusher
|
|
18
|
+
* Released under the MIT licence.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
var hasRequiredPusher;
|
|
22
|
+
|
|
23
|
+
function requirePusher () {
|
|
24
|
+
if (hasRequiredPusher) return pusher.exports;
|
|
25
|
+
hasRequiredPusher = 1;
|
|
26
|
+
(function (module, exports) {
|
|
27
|
+
(function webpackUniversalModuleDefinition(root, factory) {
|
|
28
|
+
module.exports = factory();
|
|
29
|
+
})(self, () => {
|
|
30
|
+
return /******/ (() => { // webpackBootstrap
|
|
31
|
+
/******/ var __webpack_modules__ = ({
|
|
32
|
+
|
|
33
|
+
/***/ 594
|
|
34
|
+
(__unused_webpack_module, exports) {
|
|
35
|
+
|
|
36
|
+
// Copyright (C) 2016 Dmitry Chestnykh
|
|
37
|
+
// MIT License. See LICENSE file for details.
|
|
38
|
+
var __extends = (this && this.__extends) || (function () {
|
|
39
|
+
var extendStatics = function (d, b) {
|
|
40
|
+
extendStatics = Object.setPrototypeOf ||
|
|
41
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
42
|
+
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
|
43
|
+
return extendStatics(d, b);
|
|
44
|
+
};
|
|
45
|
+
return function (d, b) {
|
|
46
|
+
extendStatics(d, b);
|
|
47
|
+
function __() { this.constructor = d; }
|
|
48
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
49
|
+
};
|
|
50
|
+
})();
|
|
51
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
52
|
+
/**
|
|
53
|
+
* Package base64 implements Base64 encoding and decoding.
|
|
54
|
+
*/
|
|
55
|
+
// Invalid character used in decoding to indicate
|
|
56
|
+
// that the character to decode is out of range of
|
|
57
|
+
// alphabet and cannot be decoded.
|
|
58
|
+
var INVALID_BYTE = 256;
|
|
59
|
+
/**
|
|
60
|
+
* Implements standard Base64 encoding.
|
|
61
|
+
*
|
|
62
|
+
* Operates in constant time.
|
|
63
|
+
*/
|
|
64
|
+
var Coder = /** @class */ (function () {
|
|
65
|
+
// TODO(dchest): methods to encode chunk-by-chunk.
|
|
66
|
+
function Coder(_paddingCharacter) {
|
|
67
|
+
if (_paddingCharacter === void 0) { _paddingCharacter = "="; }
|
|
68
|
+
this._paddingCharacter = _paddingCharacter;
|
|
69
|
+
}
|
|
70
|
+
Coder.prototype.encodedLength = function (length) {
|
|
71
|
+
if (!this._paddingCharacter) {
|
|
72
|
+
return (length * 8 + 5) / 6 | 0;
|
|
73
|
+
}
|
|
74
|
+
return (length + 2) / 3 * 4 | 0;
|
|
75
|
+
};
|
|
76
|
+
Coder.prototype.encode = function (data) {
|
|
77
|
+
var out = "";
|
|
78
|
+
var i = 0;
|
|
79
|
+
for (; i < data.length - 2; i += 3) {
|
|
80
|
+
var c = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
|
|
81
|
+
out += this._encodeByte((c >>> 3 * 6) & 63);
|
|
82
|
+
out += this._encodeByte((c >>> 2 * 6) & 63);
|
|
83
|
+
out += this._encodeByte((c >>> 1 * 6) & 63);
|
|
84
|
+
out += this._encodeByte((c >>> 0 * 6) & 63);
|
|
85
|
+
}
|
|
86
|
+
var left = data.length - i;
|
|
87
|
+
if (left > 0) {
|
|
88
|
+
var c = (data[i] << 16) | (left === 2 ? data[i + 1] << 8 : 0);
|
|
89
|
+
out += this._encodeByte((c >>> 3 * 6) & 63);
|
|
90
|
+
out += this._encodeByte((c >>> 2 * 6) & 63);
|
|
91
|
+
if (left === 2) {
|
|
92
|
+
out += this._encodeByte((c >>> 1 * 6) & 63);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
out += this._paddingCharacter || "";
|
|
96
|
+
}
|
|
97
|
+
out += this._paddingCharacter || "";
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
};
|
|
101
|
+
Coder.prototype.maxDecodedLength = function (length) {
|
|
102
|
+
if (!this._paddingCharacter) {
|
|
103
|
+
return (length * 6 + 7) / 8 | 0;
|
|
104
|
+
}
|
|
105
|
+
return length / 4 * 3 | 0;
|
|
106
|
+
};
|
|
107
|
+
Coder.prototype.decodedLength = function (s) {
|
|
108
|
+
return this.maxDecodedLength(s.length - this._getPaddingLength(s));
|
|
109
|
+
};
|
|
110
|
+
Coder.prototype.decode = function (s) {
|
|
111
|
+
if (s.length === 0) {
|
|
112
|
+
return new Uint8Array(0);
|
|
113
|
+
}
|
|
114
|
+
var paddingLength = this._getPaddingLength(s);
|
|
115
|
+
var length = s.length - paddingLength;
|
|
116
|
+
var out = new Uint8Array(this.maxDecodedLength(length));
|
|
117
|
+
var op = 0;
|
|
118
|
+
var i = 0;
|
|
119
|
+
var haveBad = 0;
|
|
120
|
+
var v0 = 0, v1 = 0, v2 = 0, v3 = 0;
|
|
121
|
+
for (; i < length - 4; i += 4) {
|
|
122
|
+
v0 = this._decodeChar(s.charCodeAt(i + 0));
|
|
123
|
+
v1 = this._decodeChar(s.charCodeAt(i + 1));
|
|
124
|
+
v2 = this._decodeChar(s.charCodeAt(i + 2));
|
|
125
|
+
v3 = this._decodeChar(s.charCodeAt(i + 3));
|
|
126
|
+
out[op++] = (v0 << 2) | (v1 >>> 4);
|
|
127
|
+
out[op++] = (v1 << 4) | (v2 >>> 2);
|
|
128
|
+
out[op++] = (v2 << 6) | v3;
|
|
129
|
+
haveBad |= v0 & INVALID_BYTE;
|
|
130
|
+
haveBad |= v1 & INVALID_BYTE;
|
|
131
|
+
haveBad |= v2 & INVALID_BYTE;
|
|
132
|
+
haveBad |= v3 & INVALID_BYTE;
|
|
133
|
+
}
|
|
134
|
+
if (i < length - 1) {
|
|
135
|
+
v0 = this._decodeChar(s.charCodeAt(i));
|
|
136
|
+
v1 = this._decodeChar(s.charCodeAt(i + 1));
|
|
137
|
+
out[op++] = (v0 << 2) | (v1 >>> 4);
|
|
138
|
+
haveBad |= v0 & INVALID_BYTE;
|
|
139
|
+
haveBad |= v1 & INVALID_BYTE;
|
|
140
|
+
}
|
|
141
|
+
if (i < length - 2) {
|
|
142
|
+
v2 = this._decodeChar(s.charCodeAt(i + 2));
|
|
143
|
+
out[op++] = (v1 << 4) | (v2 >>> 2);
|
|
144
|
+
haveBad |= v2 & INVALID_BYTE;
|
|
145
|
+
}
|
|
146
|
+
if (i < length - 3) {
|
|
147
|
+
v3 = this._decodeChar(s.charCodeAt(i + 3));
|
|
148
|
+
out[op++] = (v2 << 6) | v3;
|
|
149
|
+
haveBad |= v3 & INVALID_BYTE;
|
|
150
|
+
}
|
|
151
|
+
if (haveBad !== 0) {
|
|
152
|
+
throw new Error("Base64Coder: incorrect characters for decoding");
|
|
153
|
+
}
|
|
154
|
+
return out;
|
|
155
|
+
};
|
|
156
|
+
// Standard encoding have the following encoded/decoded ranges,
|
|
157
|
+
// which we need to convert between.
|
|
158
|
+
//
|
|
159
|
+
// ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 + /
|
|
160
|
+
// Index: 0 - 25 26 - 51 52 - 61 62 63
|
|
161
|
+
// ASCII: 65 - 90 97 - 122 48 - 57 43 47
|
|
162
|
+
//
|
|
163
|
+
// Encode 6 bits in b into a new character.
|
|
164
|
+
Coder.prototype._encodeByte = function (b) {
|
|
165
|
+
// Encoding uses constant time operations as follows:
|
|
166
|
+
//
|
|
167
|
+
// 1. Define comparison of A with B using (A - B) >>> 8:
|
|
168
|
+
// if A > B, then result is positive integer
|
|
169
|
+
// if A <= B, then result is 0
|
|
170
|
+
//
|
|
171
|
+
// 2. Define selection of C or 0 using bitwise AND: X & C:
|
|
172
|
+
// if X == 0, then result is 0
|
|
173
|
+
// if X != 0, then result is C
|
|
174
|
+
//
|
|
175
|
+
// 3. Start with the smallest comparison (b >= 0), which is always
|
|
176
|
+
// true, so set the result to the starting ASCII value (65).
|
|
177
|
+
//
|
|
178
|
+
// 4. Continue comparing b to higher ASCII values, and selecting
|
|
179
|
+
// zero if comparison isn't true, otherwise selecting a value
|
|
180
|
+
// to add to result, which:
|
|
181
|
+
//
|
|
182
|
+
// a) undoes the previous addition
|
|
183
|
+
// b) provides new value to add
|
|
184
|
+
//
|
|
185
|
+
var result = b;
|
|
186
|
+
// b >= 0
|
|
187
|
+
result += 65;
|
|
188
|
+
// b > 25
|
|
189
|
+
result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);
|
|
190
|
+
// b > 51
|
|
191
|
+
result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);
|
|
192
|
+
// b > 61
|
|
193
|
+
result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 43);
|
|
194
|
+
// b > 62
|
|
195
|
+
result += ((62 - b) >>> 8) & ((62 - 43) - 63 + 47);
|
|
196
|
+
return String.fromCharCode(result);
|
|
197
|
+
};
|
|
198
|
+
// Decode a character code into a byte.
|
|
199
|
+
// Must return 256 if character is out of alphabet range.
|
|
200
|
+
Coder.prototype._decodeChar = function (c) {
|
|
201
|
+
// Decoding works similar to encoding: using the same comparison
|
|
202
|
+
// function, but now it works on ranges: result is always incremented
|
|
203
|
+
// by value, but this value becomes zero if the range is not
|
|
204
|
+
// satisfied.
|
|
205
|
+
//
|
|
206
|
+
// Decoding starts with invalid value, 256, which is then
|
|
207
|
+
// subtracted when the range is satisfied. If none of the ranges
|
|
208
|
+
// apply, the function returns 256, which is then checked by
|
|
209
|
+
// the caller to throw error.
|
|
210
|
+
var result = INVALID_BYTE; // start with invalid character
|
|
211
|
+
// c == 43 (c > 42 and c < 44)
|
|
212
|
+
result += (((42 - c) & (c - 44)) >>> 8) & (-INVALID_BYTE + c - 43 + 62);
|
|
213
|
+
// c == 47 (c > 46 and c < 48)
|
|
214
|
+
result += (((46 - c) & (c - 48)) >>> 8) & (-INVALID_BYTE + c - 47 + 63);
|
|
215
|
+
// c > 47 and c < 58
|
|
216
|
+
result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);
|
|
217
|
+
// c > 64 and c < 91
|
|
218
|
+
result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);
|
|
219
|
+
// c > 96 and c < 123
|
|
220
|
+
result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);
|
|
221
|
+
return result;
|
|
222
|
+
};
|
|
223
|
+
Coder.prototype._getPaddingLength = function (s) {
|
|
224
|
+
var paddingLength = 0;
|
|
225
|
+
if (this._paddingCharacter) {
|
|
226
|
+
for (var i = s.length - 1; i >= 0; i--) {
|
|
227
|
+
if (s[i] !== this._paddingCharacter) {
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
paddingLength++;
|
|
231
|
+
}
|
|
232
|
+
if (s.length < 4 || paddingLength > 2) {
|
|
233
|
+
throw new Error("Base64Coder: incorrect padding");
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return paddingLength;
|
|
237
|
+
};
|
|
238
|
+
return Coder;
|
|
239
|
+
}());
|
|
240
|
+
exports.Coder = Coder;
|
|
241
|
+
var stdCoder = new Coder();
|
|
242
|
+
function encode(data) {
|
|
243
|
+
return stdCoder.encode(data);
|
|
244
|
+
}
|
|
245
|
+
exports.encode = encode;
|
|
246
|
+
function decode(s) {
|
|
247
|
+
return stdCoder.decode(s);
|
|
248
|
+
}
|
|
249
|
+
exports.decode = decode;
|
|
250
|
+
/**
|
|
251
|
+
* Implements URL-safe Base64 encoding.
|
|
252
|
+
* (Same as Base64, but '+' is replaced with '-', and '/' with '_').
|
|
253
|
+
*
|
|
254
|
+
* Operates in constant time.
|
|
255
|
+
*/
|
|
256
|
+
var URLSafeCoder = /** @class */ (function (_super) {
|
|
257
|
+
__extends(URLSafeCoder, _super);
|
|
258
|
+
function URLSafeCoder() {
|
|
259
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
260
|
+
}
|
|
261
|
+
// URL-safe encoding have the following encoded/decoded ranges:
|
|
262
|
+
//
|
|
263
|
+
// ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 - _
|
|
264
|
+
// Index: 0 - 25 26 - 51 52 - 61 62 63
|
|
265
|
+
// ASCII: 65 - 90 97 - 122 48 - 57 45 95
|
|
266
|
+
//
|
|
267
|
+
URLSafeCoder.prototype._encodeByte = function (b) {
|
|
268
|
+
var result = b;
|
|
269
|
+
// b >= 0
|
|
270
|
+
result += 65;
|
|
271
|
+
// b > 25
|
|
272
|
+
result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);
|
|
273
|
+
// b > 51
|
|
274
|
+
result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);
|
|
275
|
+
// b > 61
|
|
276
|
+
result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 45);
|
|
277
|
+
// b > 62
|
|
278
|
+
result += ((62 - b) >>> 8) & ((62 - 45) - 63 + 95);
|
|
279
|
+
return String.fromCharCode(result);
|
|
280
|
+
};
|
|
281
|
+
URLSafeCoder.prototype._decodeChar = function (c) {
|
|
282
|
+
var result = INVALID_BYTE;
|
|
283
|
+
// c == 45 (c > 44 and c < 46)
|
|
284
|
+
result += (((44 - c) & (c - 46)) >>> 8) & (-INVALID_BYTE + c - 45 + 62);
|
|
285
|
+
// c == 95 (c > 94 and c < 96)
|
|
286
|
+
result += (((94 - c) & (c - 96)) >>> 8) & (-INVALID_BYTE + c - 95 + 63);
|
|
287
|
+
// c > 47 and c < 58
|
|
288
|
+
result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);
|
|
289
|
+
// c > 64 and c < 91
|
|
290
|
+
result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);
|
|
291
|
+
// c > 96 and c < 123
|
|
292
|
+
result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);
|
|
293
|
+
return result;
|
|
294
|
+
};
|
|
295
|
+
return URLSafeCoder;
|
|
296
|
+
}(Coder));
|
|
297
|
+
exports.URLSafeCoder = URLSafeCoder;
|
|
298
|
+
var urlSafeCoder = new URLSafeCoder();
|
|
299
|
+
function encodeURLSafe(data) {
|
|
300
|
+
return urlSafeCoder.encode(data);
|
|
301
|
+
}
|
|
302
|
+
exports.encodeURLSafe = encodeURLSafe;
|
|
303
|
+
function decodeURLSafe(s) {
|
|
304
|
+
return urlSafeCoder.decode(s);
|
|
305
|
+
}
|
|
306
|
+
exports.decodeURLSafe = decodeURLSafe;
|
|
307
|
+
exports.encodedLength = function (length) {
|
|
308
|
+
return stdCoder.encodedLength(length);
|
|
309
|
+
};
|
|
310
|
+
exports.maxDecodedLength = function (length) {
|
|
311
|
+
return stdCoder.maxDecodedLength(length);
|
|
312
|
+
};
|
|
313
|
+
exports.decodedLength = function (s) {
|
|
314
|
+
return stdCoder.decodedLength(s);
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
/***/ },
|
|
319
|
+
|
|
320
|
+
/***/ 978
|
|
321
|
+
(__unused_webpack_module, exports) {
|
|
322
|
+
var INVALID_UTF8 = "utf8: invalid source encoding";
|
|
323
|
+
/**
|
|
324
|
+
* Decodes the given byte array from UTF-8 into a string.
|
|
325
|
+
* Throws if encoding is invalid.
|
|
326
|
+
*/
|
|
327
|
+
function decode(arr) {
|
|
328
|
+
var chars = [];
|
|
329
|
+
for (var i = 0; i < arr.length; i++) {
|
|
330
|
+
var b = arr[i];
|
|
331
|
+
if (b & 0x80) {
|
|
332
|
+
var min = void 0;
|
|
333
|
+
if (b < 0xe0) {
|
|
334
|
+
// Need 1 more byte.
|
|
335
|
+
if (i >= arr.length) {
|
|
336
|
+
throw new Error(INVALID_UTF8);
|
|
337
|
+
}
|
|
338
|
+
var n1 = arr[++i];
|
|
339
|
+
if ((n1 & 0xc0) !== 0x80) {
|
|
340
|
+
throw new Error(INVALID_UTF8);
|
|
341
|
+
}
|
|
342
|
+
b = (b & 0x1f) << 6 | (n1 & 0x3f);
|
|
343
|
+
min = 0x80;
|
|
344
|
+
}
|
|
345
|
+
else if (b < 0xf0) {
|
|
346
|
+
// Need 2 more bytes.
|
|
347
|
+
if (i >= arr.length - 1) {
|
|
348
|
+
throw new Error(INVALID_UTF8);
|
|
349
|
+
}
|
|
350
|
+
var n1 = arr[++i];
|
|
351
|
+
var n2 = arr[++i];
|
|
352
|
+
if ((n1 & 0xc0) !== 0x80 || (n2 & 0xc0) !== 0x80) {
|
|
353
|
+
throw new Error(INVALID_UTF8);
|
|
354
|
+
}
|
|
355
|
+
b = (b & 0x0f) << 12 | (n1 & 0x3f) << 6 | (n2 & 0x3f);
|
|
356
|
+
min = 0x800;
|
|
357
|
+
}
|
|
358
|
+
else if (b < 0xf8) {
|
|
359
|
+
// Need 3 more bytes.
|
|
360
|
+
if (i >= arr.length - 2) {
|
|
361
|
+
throw new Error(INVALID_UTF8);
|
|
362
|
+
}
|
|
363
|
+
var n1 = arr[++i];
|
|
364
|
+
var n2 = arr[++i];
|
|
365
|
+
var n3 = arr[++i];
|
|
366
|
+
if ((n1 & 0xc0) !== 0x80 || (n2 & 0xc0) !== 0x80 || (n3 & 0xc0) !== 0x80) {
|
|
367
|
+
throw new Error(INVALID_UTF8);
|
|
368
|
+
}
|
|
369
|
+
b = (b & 0x0f) << 18 | (n1 & 0x3f) << 12 | (n2 & 0x3f) << 6 | (n3 & 0x3f);
|
|
370
|
+
min = 0x10000;
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
throw new Error(INVALID_UTF8);
|
|
374
|
+
}
|
|
375
|
+
if (b < min || (b >= 0xd800 && b <= 0xdfff)) {
|
|
376
|
+
throw new Error(INVALID_UTF8);
|
|
377
|
+
}
|
|
378
|
+
if (b >= 0x10000) {
|
|
379
|
+
// Surrogate pair.
|
|
380
|
+
if (b > 0x10ffff) {
|
|
381
|
+
throw new Error(INVALID_UTF8);
|
|
382
|
+
}
|
|
383
|
+
b -= 0x10000;
|
|
384
|
+
chars.push(String.fromCharCode(0xd800 | (b >> 10)));
|
|
385
|
+
b = 0xdc00 | (b & 0x3ff);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
chars.push(String.fromCharCode(b));
|
|
389
|
+
}
|
|
390
|
+
return chars.join("");
|
|
391
|
+
}
|
|
392
|
+
exports.D4 = decode;
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
/***/ },
|
|
396
|
+
|
|
397
|
+
/***/ 721
|
|
398
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
399
|
+
|
|
400
|
+
// required so we don't have to do require('pusher').default etc.
|
|
401
|
+
module.exports = __webpack_require__(207)["default"];
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
/***/ },
|
|
405
|
+
|
|
406
|
+
/***/ 207
|
|
407
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
408
|
+
|
|
409
|
+
// EXPORTS
|
|
410
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
411
|
+
"default": () => (/* binding */ pusher)
|
|
412
|
+
});
|
|
413
|
+
class ScriptReceiverFactory {
|
|
414
|
+
constructor(prefix, name) {
|
|
415
|
+
this.lastId = 0;
|
|
416
|
+
this.prefix = prefix;
|
|
417
|
+
this.name = name;
|
|
418
|
+
}
|
|
419
|
+
create(callback) {
|
|
420
|
+
this.lastId++;
|
|
421
|
+
var number = this.lastId;
|
|
422
|
+
var id = this.prefix + number;
|
|
423
|
+
var name = this.name + '[' + number + ']';
|
|
424
|
+
var called = false;
|
|
425
|
+
var callbackWrapper = function () {
|
|
426
|
+
if (!called) {
|
|
427
|
+
callback.apply(null, arguments);
|
|
428
|
+
called = true;
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
this[number] = callbackWrapper;
|
|
432
|
+
return { number: number, id: id, name: name, callback: callbackWrapper };
|
|
433
|
+
}
|
|
434
|
+
remove(receiver) {
|
|
435
|
+
delete this[receiver.number];
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
var ScriptReceivers = new ScriptReceiverFactory('_pusher_script_', 'Pusher.ScriptReceivers');
|
|
439
|
+
var Defaults = {
|
|
440
|
+
VERSION: "8.5.0",
|
|
441
|
+
PROTOCOL: 7,
|
|
442
|
+
wsPort: 80,
|
|
443
|
+
wssPort: 443,
|
|
444
|
+
wsPath: '',
|
|
445
|
+
httpHost: 'sockjs.pusher.com',
|
|
446
|
+
httpPort: 80,
|
|
447
|
+
httpsPort: 443,
|
|
448
|
+
httpPath: '/pusher',
|
|
449
|
+
stats_host: 'stats.pusher.com',
|
|
450
|
+
authEndpoint: '/pusher/auth',
|
|
451
|
+
authTransport: 'ajax',
|
|
452
|
+
activityTimeout: 120000,
|
|
453
|
+
pongTimeout: 30000,
|
|
454
|
+
unavailableTimeout: 10000,
|
|
455
|
+
userAuthentication: {
|
|
456
|
+
endpoint: '/pusher/user-auth',
|
|
457
|
+
transport: 'ajax',
|
|
458
|
+
},
|
|
459
|
+
channelAuthorization: {
|
|
460
|
+
endpoint: '/pusher/auth',
|
|
461
|
+
transport: 'ajax',
|
|
462
|
+
},
|
|
463
|
+
cdn_http: "http://js.pusher.com",
|
|
464
|
+
cdn_https: "https://js.pusher.com",
|
|
465
|
+
dependency_suffix: "",
|
|
466
|
+
};
|
|
467
|
+
/* harmony default export */ const defaults = (Defaults);
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
class DependencyLoader {
|
|
471
|
+
constructor(options) {
|
|
472
|
+
this.options = options;
|
|
473
|
+
this.receivers = options.receivers || ScriptReceivers;
|
|
474
|
+
this.loading = {};
|
|
475
|
+
}
|
|
476
|
+
load(name, options, callback) {
|
|
477
|
+
var self = this;
|
|
478
|
+
if (self.loading[name] && self.loading[name].length > 0) {
|
|
479
|
+
self.loading[name].push(callback);
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
self.loading[name] = [callback];
|
|
483
|
+
var request = runtime.createScriptRequest(self.getPath(name, options));
|
|
484
|
+
var receiver = self.receivers.create(function (error) {
|
|
485
|
+
self.receivers.remove(receiver);
|
|
486
|
+
if (self.loading[name]) {
|
|
487
|
+
var callbacks = self.loading[name];
|
|
488
|
+
delete self.loading[name];
|
|
489
|
+
var successCallback = function (wasSuccessful) {
|
|
490
|
+
if (!wasSuccessful) {
|
|
491
|
+
request.cleanup();
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
for (var i = 0; i < callbacks.length; i++) {
|
|
495
|
+
callbacks[i](error, successCallback);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
request.send(receiver);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
getRoot(options) {
|
|
503
|
+
var cdn;
|
|
504
|
+
var protocol = runtime.getDocument().location.protocol;
|
|
505
|
+
if ((options && options.useTLS) || protocol === 'https:') {
|
|
506
|
+
cdn = this.options.cdn_https;
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
cdn = this.options.cdn_http;
|
|
510
|
+
}
|
|
511
|
+
return cdn.replace(/\/*$/, '') + '/' + this.options.version;
|
|
512
|
+
}
|
|
513
|
+
getPath(name, options) {
|
|
514
|
+
return this.getRoot(options) + '/' + name + this.options.suffix + '.js';
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
var DependenciesReceivers = new ScriptReceiverFactory('_pusher_dependencies', 'Pusher.DependenciesReceivers');
|
|
521
|
+
var Dependencies = new DependencyLoader({
|
|
522
|
+
cdn_http: defaults.cdn_http,
|
|
523
|
+
cdn_https: defaults.cdn_https,
|
|
524
|
+
version: defaults.VERSION,
|
|
525
|
+
suffix: defaults.dependency_suffix,
|
|
526
|
+
receivers: DependenciesReceivers,
|
|
527
|
+
});
|
|
528
|
+
const urlStore = {
|
|
529
|
+
baseUrl: 'https://pusher.com',
|
|
530
|
+
urls: {
|
|
531
|
+
authenticationEndpoint: {
|
|
532
|
+
path: '/docs/channels/server_api/authenticating_users',
|
|
533
|
+
},
|
|
534
|
+
authorizationEndpoint: {
|
|
535
|
+
path: '/docs/channels/server_api/authorizing-users/',
|
|
536
|
+
},
|
|
537
|
+
javascriptQuickStart: {
|
|
538
|
+
path: '/docs/javascript_quick_start',
|
|
539
|
+
},
|
|
540
|
+
triggeringClientEvents: {
|
|
541
|
+
path: '/docs/client_api_guide/client_events#trigger-events',
|
|
542
|
+
},
|
|
543
|
+
encryptedChannelSupport: {
|
|
544
|
+
fullUrl: 'https://github.com/pusher/pusher-js/tree/cc491015371a4bde5743d1c87a0fbac0feb53195#encrypted-channel-support',
|
|
545
|
+
},
|
|
546
|
+
},
|
|
547
|
+
};
|
|
548
|
+
const buildLogSuffix = function (key) {
|
|
549
|
+
const urlPrefix = 'See:';
|
|
550
|
+
const urlObj = urlStore.urls[key];
|
|
551
|
+
if (!urlObj)
|
|
552
|
+
return '';
|
|
553
|
+
let url;
|
|
554
|
+
if (urlObj.fullUrl) {
|
|
555
|
+
url = urlObj.fullUrl;
|
|
556
|
+
}
|
|
557
|
+
else if (urlObj.path) {
|
|
558
|
+
url = urlStore.baseUrl + urlObj.path;
|
|
559
|
+
}
|
|
560
|
+
if (!url)
|
|
561
|
+
return '';
|
|
562
|
+
return `${urlPrefix} ${url}`;
|
|
563
|
+
};
|
|
564
|
+
/* harmony default export */ const url_store = ({ buildLogSuffix });
|
|
565
|
+
var AuthRequestType;
|
|
566
|
+
(function (AuthRequestType) {
|
|
567
|
+
AuthRequestType["UserAuthentication"] = "user-authentication";
|
|
568
|
+
AuthRequestType["ChannelAuthorization"] = "channel-authorization";
|
|
569
|
+
})(AuthRequestType || (AuthRequestType = {}));
|
|
570
|
+
class BadEventName extends Error {
|
|
571
|
+
constructor(msg) {
|
|
572
|
+
super(msg);
|
|
573
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
class BadChannelName extends Error {
|
|
577
|
+
constructor(msg) {
|
|
578
|
+
super(msg);
|
|
579
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
class RequestTimedOut extends Error {
|
|
583
|
+
constructor(msg) {
|
|
584
|
+
super(msg);
|
|
585
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
class TransportPriorityTooLow extends Error {
|
|
589
|
+
constructor(msg) {
|
|
590
|
+
super(msg);
|
|
591
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
class TransportClosed extends Error {
|
|
595
|
+
constructor(msg) {
|
|
596
|
+
super(msg);
|
|
597
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
class UnsupportedFeature extends Error {
|
|
601
|
+
constructor(msg) {
|
|
602
|
+
super(msg);
|
|
603
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
class UnsupportedTransport extends Error {
|
|
607
|
+
constructor(msg) {
|
|
608
|
+
super(msg);
|
|
609
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
class UnsupportedStrategy extends Error {
|
|
613
|
+
constructor(msg) {
|
|
614
|
+
super(msg);
|
|
615
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
class HTTPAuthError extends Error {
|
|
619
|
+
constructor(status, msg) {
|
|
620
|
+
super(msg);
|
|
621
|
+
this.status = status;
|
|
622
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
const ajax = function (context, query, authOptions, authRequestType, callback) {
|
|
630
|
+
const xhr = runtime.createXHR();
|
|
631
|
+
xhr.open('POST', authOptions.endpoint, true);
|
|
632
|
+
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
|
633
|
+
for (var headerName in authOptions.headers) {
|
|
634
|
+
xhr.setRequestHeader(headerName, authOptions.headers[headerName]);
|
|
635
|
+
}
|
|
636
|
+
if (authOptions.headersProvider != null) {
|
|
637
|
+
let dynamicHeaders = authOptions.headersProvider();
|
|
638
|
+
for (var headerName in dynamicHeaders) {
|
|
639
|
+
xhr.setRequestHeader(headerName, dynamicHeaders[headerName]);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
xhr.onreadystatechange = function () {
|
|
643
|
+
if (xhr.readyState === 4) {
|
|
644
|
+
if (xhr.status === 200) {
|
|
645
|
+
let data;
|
|
646
|
+
let parsed = false;
|
|
647
|
+
try {
|
|
648
|
+
data = JSON.parse(xhr.responseText);
|
|
649
|
+
parsed = true;
|
|
650
|
+
}
|
|
651
|
+
catch (e) {
|
|
652
|
+
callback(new HTTPAuthError(200, `JSON returned from ${authRequestType.toString()} endpoint was invalid, yet status code was 200. Data was: ${xhr.responseText}`), null);
|
|
653
|
+
}
|
|
654
|
+
if (parsed) {
|
|
655
|
+
callback(null, data);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
else {
|
|
659
|
+
let suffix = '';
|
|
660
|
+
switch (authRequestType) {
|
|
661
|
+
case AuthRequestType.UserAuthentication:
|
|
662
|
+
suffix = url_store.buildLogSuffix('authenticationEndpoint');
|
|
663
|
+
break;
|
|
664
|
+
case AuthRequestType.ChannelAuthorization:
|
|
665
|
+
suffix = `Clients must be authorized to join private or presence channels. ${url_store.buildLogSuffix('authorizationEndpoint')}`;
|
|
666
|
+
break;
|
|
667
|
+
}
|
|
668
|
+
callback(new HTTPAuthError(xhr.status, `Unable to retrieve auth string from ${authRequestType.toString()} endpoint - ` +
|
|
669
|
+
`received status: ${xhr.status} from ${authOptions.endpoint}. ${suffix}`), null);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
};
|
|
673
|
+
xhr.send(query);
|
|
674
|
+
return xhr;
|
|
675
|
+
};
|
|
676
|
+
/* harmony default export */ const xhr_auth = (ajax);
|
|
677
|
+
function encode(s) {
|
|
678
|
+
return btoa(utob(s));
|
|
679
|
+
}
|
|
680
|
+
var fromCharCode = String.fromCharCode;
|
|
681
|
+
var b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
682
|
+
var cb_utob = function (c) {
|
|
683
|
+
var cc = c.charCodeAt(0);
|
|
684
|
+
return cc < 0x80
|
|
685
|
+
? c
|
|
686
|
+
: cc < 0x800
|
|
687
|
+
? fromCharCode(0xc0 | (cc >>> 6)) + fromCharCode(0x80 | (cc & 0x3f))
|
|
688
|
+
: fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) +
|
|
689
|
+
fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) +
|
|
690
|
+
fromCharCode(0x80 | (cc & 0x3f));
|
|
691
|
+
};
|
|
692
|
+
var utob = function (u) {
|
|
693
|
+
return u.replace(/[^\x00-\x7F]/g, cb_utob);
|
|
694
|
+
};
|
|
695
|
+
var cb_encode = function (ccc) {
|
|
696
|
+
var padlen = [0, 2, 1][ccc.length % 3];
|
|
697
|
+
var ord = (ccc.charCodeAt(0) << 16) |
|
|
698
|
+
((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8) |
|
|
699
|
+
(ccc.length > 2 ? ccc.charCodeAt(2) : 0);
|
|
700
|
+
var chars = [
|
|
701
|
+
b64chars.charAt(ord >>> 18),
|
|
702
|
+
b64chars.charAt((ord >>> 12) & 63),
|
|
703
|
+
padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),
|
|
704
|
+
padlen >= 1 ? '=' : b64chars.charAt(ord & 63),
|
|
705
|
+
];
|
|
706
|
+
return chars.join('');
|
|
707
|
+
};
|
|
708
|
+
var btoa = window.btoa ||
|
|
709
|
+
function (b) {
|
|
710
|
+
return b.replace(/[\s\S]{1,3}/g, cb_encode);
|
|
711
|
+
};
|
|
712
|
+
class Timer {
|
|
713
|
+
constructor(set, clear, delay, callback) {
|
|
714
|
+
this.clear = clear;
|
|
715
|
+
this.timer = set(() => {
|
|
716
|
+
if (this.timer) {
|
|
717
|
+
this.timer = callback(this.timer);
|
|
718
|
+
}
|
|
719
|
+
}, delay);
|
|
720
|
+
}
|
|
721
|
+
isRunning() {
|
|
722
|
+
return this.timer !== null;
|
|
723
|
+
}
|
|
724
|
+
ensureAborted() {
|
|
725
|
+
if (this.timer) {
|
|
726
|
+
this.clear(this.timer);
|
|
727
|
+
this.timer = null;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
/* harmony default export */ const abstract_timer = (Timer);
|
|
732
|
+
|
|
733
|
+
function timers_clearTimeout(timer) {
|
|
734
|
+
window.clearTimeout(timer);
|
|
735
|
+
}
|
|
736
|
+
function timers_clearInterval(timer) {
|
|
737
|
+
window.clearInterval(timer);
|
|
738
|
+
}
|
|
739
|
+
class OneOffTimer extends abstract_timer {
|
|
740
|
+
constructor(delay, callback) {
|
|
741
|
+
super(setTimeout, timers_clearTimeout, delay, function (timer) {
|
|
742
|
+
callback();
|
|
743
|
+
return null;
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
class PeriodicTimer extends abstract_timer {
|
|
748
|
+
constructor(delay, callback) {
|
|
749
|
+
super(setInterval, timers_clearInterval, delay, function (timer) {
|
|
750
|
+
callback();
|
|
751
|
+
return timer;
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
var Util = {
|
|
757
|
+
now() {
|
|
758
|
+
if (Date.now) {
|
|
759
|
+
return Date.now();
|
|
760
|
+
}
|
|
761
|
+
else {
|
|
762
|
+
return new Date().valueOf();
|
|
763
|
+
}
|
|
764
|
+
},
|
|
765
|
+
defer(callback) {
|
|
766
|
+
return new OneOffTimer(0, callback);
|
|
767
|
+
},
|
|
768
|
+
method(name, ...args) {
|
|
769
|
+
var boundArguments = Array.prototype.slice.call(arguments, 1);
|
|
770
|
+
return function (object) {
|
|
771
|
+
return object[name].apply(object, boundArguments.concat(arguments));
|
|
772
|
+
};
|
|
773
|
+
},
|
|
774
|
+
};
|
|
775
|
+
/* harmony default export */ const util = (Util);
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
function extend(target, ...sources) {
|
|
779
|
+
for (var i = 0; i < sources.length; i++) {
|
|
780
|
+
var extensions = sources[i];
|
|
781
|
+
for (var property in extensions) {
|
|
782
|
+
if (extensions[property] &&
|
|
783
|
+
extensions[property].constructor &&
|
|
784
|
+
extensions[property].constructor === Object) {
|
|
785
|
+
target[property] = extend(target[property] || {}, extensions[property]);
|
|
786
|
+
}
|
|
787
|
+
else {
|
|
788
|
+
target[property] = extensions[property];
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
return target;
|
|
793
|
+
}
|
|
794
|
+
function stringify() {
|
|
795
|
+
var m = ['Pusher'];
|
|
796
|
+
for (var i = 0; i < arguments.length; i++) {
|
|
797
|
+
if (typeof arguments[i] === 'string') {
|
|
798
|
+
m.push(arguments[i]);
|
|
799
|
+
}
|
|
800
|
+
else {
|
|
801
|
+
m.push(safeJSONStringify(arguments[i]));
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
return m.join(' : ');
|
|
805
|
+
}
|
|
806
|
+
function arrayIndexOf(array, item) {
|
|
807
|
+
var nativeIndexOf = Array.prototype.indexOf;
|
|
808
|
+
if (array === null) {
|
|
809
|
+
return -1;
|
|
810
|
+
}
|
|
811
|
+
if (nativeIndexOf && array.indexOf === nativeIndexOf) {
|
|
812
|
+
return array.indexOf(item);
|
|
813
|
+
}
|
|
814
|
+
for (var i = 0, l = array.length; i < l; i++) {
|
|
815
|
+
if (array[i] === item) {
|
|
816
|
+
return i;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
return -1;
|
|
820
|
+
}
|
|
821
|
+
function objectApply(object, f) {
|
|
822
|
+
for (var key in object) {
|
|
823
|
+
if (Object.prototype.hasOwnProperty.call(object, key)) {
|
|
824
|
+
f(object[key], key, object);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
function keys(object) {
|
|
829
|
+
var keys = [];
|
|
830
|
+
objectApply(object, function (_, key) {
|
|
831
|
+
keys.push(key);
|
|
832
|
+
});
|
|
833
|
+
return keys;
|
|
834
|
+
}
|
|
835
|
+
function values(object) {
|
|
836
|
+
var values = [];
|
|
837
|
+
objectApply(object, function (value) {
|
|
838
|
+
values.push(value);
|
|
839
|
+
});
|
|
840
|
+
return values;
|
|
841
|
+
}
|
|
842
|
+
function apply(array, f, context) {
|
|
843
|
+
for (var i = 0; i < array.length; i++) {
|
|
844
|
+
f.call(context || window, array[i], i, array);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
function map(array, f) {
|
|
848
|
+
var result = [];
|
|
849
|
+
for (var i = 0; i < array.length; i++) {
|
|
850
|
+
result.push(f(array[i], i, array, result));
|
|
851
|
+
}
|
|
852
|
+
return result;
|
|
853
|
+
}
|
|
854
|
+
function mapObject(object, f) {
|
|
855
|
+
var result = {};
|
|
856
|
+
objectApply(object, function (value, key) {
|
|
857
|
+
result[key] = f(value);
|
|
858
|
+
});
|
|
859
|
+
return result;
|
|
860
|
+
}
|
|
861
|
+
function filter(array, test) {
|
|
862
|
+
test =
|
|
863
|
+
test ||
|
|
864
|
+
function (value) {
|
|
865
|
+
return !!value;
|
|
866
|
+
};
|
|
867
|
+
var result = [];
|
|
868
|
+
for (var i = 0; i < array.length; i++) {
|
|
869
|
+
if (test(array[i], i, array, result)) {
|
|
870
|
+
result.push(array[i]);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
return result;
|
|
874
|
+
}
|
|
875
|
+
function filterObject(object, test) {
|
|
876
|
+
var result = {};
|
|
877
|
+
objectApply(object, function (value, key) {
|
|
878
|
+
if ((test && test(value, key, object, result)) || Boolean(value)) {
|
|
879
|
+
result[key] = value;
|
|
880
|
+
}
|
|
881
|
+
});
|
|
882
|
+
return result;
|
|
883
|
+
}
|
|
884
|
+
function flatten(object) {
|
|
885
|
+
var result = [];
|
|
886
|
+
objectApply(object, function (value, key) {
|
|
887
|
+
result.push([key, value]);
|
|
888
|
+
});
|
|
889
|
+
return result;
|
|
890
|
+
}
|
|
891
|
+
function any(array, test) {
|
|
892
|
+
for (var i = 0; i < array.length; i++) {
|
|
893
|
+
if (test(array[i], i, array)) {
|
|
894
|
+
return true;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
return false;
|
|
898
|
+
}
|
|
899
|
+
function collections_all(array, test) {
|
|
900
|
+
for (var i = 0; i < array.length; i++) {
|
|
901
|
+
if (!test(array[i], i, array)) {
|
|
902
|
+
return false;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
return true;
|
|
906
|
+
}
|
|
907
|
+
function encodeParamsObject(data) {
|
|
908
|
+
return mapObject(data, function (value) {
|
|
909
|
+
if (typeof value === 'object') {
|
|
910
|
+
value = safeJSONStringify(value);
|
|
911
|
+
}
|
|
912
|
+
return encodeURIComponent(encode(value.toString()));
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
function buildQueryString(data) {
|
|
916
|
+
var params = filterObject(data, function (value) {
|
|
917
|
+
return value !== undefined;
|
|
918
|
+
});
|
|
919
|
+
var query = map(flatten(encodeParamsObject(params)), util.method('join', '=')).join('&');
|
|
920
|
+
return query;
|
|
921
|
+
}
|
|
922
|
+
function decycleObject(object) {
|
|
923
|
+
var objects = [], paths = [];
|
|
924
|
+
return (function derez(value, path) {
|
|
925
|
+
var i, name, nu;
|
|
926
|
+
switch (typeof value) {
|
|
927
|
+
case 'object':
|
|
928
|
+
if (!value) {
|
|
929
|
+
return null;
|
|
930
|
+
}
|
|
931
|
+
for (i = 0; i < objects.length; i += 1) {
|
|
932
|
+
if (objects[i] === value) {
|
|
933
|
+
return { $ref: paths[i] };
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
objects.push(value);
|
|
937
|
+
paths.push(path);
|
|
938
|
+
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
|
939
|
+
nu = [];
|
|
940
|
+
for (i = 0; i < value.length; i += 1) {
|
|
941
|
+
nu[i] = derez(value[i], path + '[' + i + ']');
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
else {
|
|
945
|
+
nu = {};
|
|
946
|
+
for (name in value) {
|
|
947
|
+
if (Object.prototype.hasOwnProperty.call(value, name)) {
|
|
948
|
+
nu[name] = derez(value[name], path + '[' + JSON.stringify(name) + ']');
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
return nu;
|
|
953
|
+
case 'number':
|
|
954
|
+
case 'string':
|
|
955
|
+
case 'boolean':
|
|
956
|
+
return value;
|
|
957
|
+
}
|
|
958
|
+
})(object, '$');
|
|
959
|
+
}
|
|
960
|
+
function safeJSONStringify(source) {
|
|
961
|
+
try {
|
|
962
|
+
return JSON.stringify(source);
|
|
963
|
+
}
|
|
964
|
+
catch (e) {
|
|
965
|
+
return JSON.stringify(decycleObject(source));
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
class Logger {
|
|
971
|
+
constructor() {
|
|
972
|
+
this.globalLog = (message) => {
|
|
973
|
+
if (window.console && window.console.log) {
|
|
974
|
+
window.console.log(message);
|
|
975
|
+
}
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
debug(...args) {
|
|
979
|
+
this.log(this.globalLog, args);
|
|
980
|
+
}
|
|
981
|
+
warn(...args) {
|
|
982
|
+
this.log(this.globalLogWarn, args);
|
|
983
|
+
}
|
|
984
|
+
error(...args) {
|
|
985
|
+
this.log(this.globalLogError, args);
|
|
986
|
+
}
|
|
987
|
+
globalLogWarn(message) {
|
|
988
|
+
if (window.console && window.console.warn) {
|
|
989
|
+
window.console.warn(message);
|
|
990
|
+
}
|
|
991
|
+
else {
|
|
992
|
+
this.globalLog(message);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
globalLogError(message) {
|
|
996
|
+
if (window.console && window.console.error) {
|
|
997
|
+
window.console.error(message);
|
|
998
|
+
}
|
|
999
|
+
else {
|
|
1000
|
+
this.globalLogWarn(message);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
log(defaultLoggingFunction, ...args) {
|
|
1004
|
+
var message = stringify.apply(this, arguments);
|
|
1005
|
+
if (pusher.log) {
|
|
1006
|
+
pusher.log(message);
|
|
1007
|
+
}
|
|
1008
|
+
else if (pusher.logToConsole) {
|
|
1009
|
+
const log = defaultLoggingFunction.bind(this);
|
|
1010
|
+
log(message);
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
/* harmony default export */ const logger = (new Logger());
|
|
1015
|
+
|
|
1016
|
+
var jsonp = function (context, query, authOptions, authRequestType, callback) {
|
|
1017
|
+
if (authOptions.headers !== undefined ||
|
|
1018
|
+
authOptions.headersProvider != null) {
|
|
1019
|
+
logger.warn(`To send headers with the ${authRequestType.toString()} request, you must use AJAX, rather than JSONP.`);
|
|
1020
|
+
}
|
|
1021
|
+
var callbackName = context.nextAuthCallbackID.toString();
|
|
1022
|
+
context.nextAuthCallbackID++;
|
|
1023
|
+
var document = context.getDocument();
|
|
1024
|
+
var script = document.createElement('script');
|
|
1025
|
+
context.auth_callbacks[callbackName] = function (data) {
|
|
1026
|
+
callback(null, data);
|
|
1027
|
+
};
|
|
1028
|
+
var callback_name = "Pusher.auth_callbacks['" + callbackName + "']";
|
|
1029
|
+
script.src =
|
|
1030
|
+
authOptions.endpoint +
|
|
1031
|
+
'?callback=' +
|
|
1032
|
+
encodeURIComponent(callback_name) +
|
|
1033
|
+
'&' +
|
|
1034
|
+
query;
|
|
1035
|
+
var head = document.getElementsByTagName('head')[0] || document.documentElement;
|
|
1036
|
+
head.insertBefore(script, head.firstChild);
|
|
1037
|
+
};
|
|
1038
|
+
/* harmony default export */ const jsonp_auth = (jsonp);
|
|
1039
|
+
class ScriptRequest {
|
|
1040
|
+
constructor(src) {
|
|
1041
|
+
this.src = src;
|
|
1042
|
+
}
|
|
1043
|
+
send(receiver) {
|
|
1044
|
+
var self = this;
|
|
1045
|
+
var errorString = 'Error loading ' + self.src;
|
|
1046
|
+
self.script = document.createElement('script');
|
|
1047
|
+
self.script.id = receiver.id;
|
|
1048
|
+
self.script.src = self.src;
|
|
1049
|
+
self.script.type = 'text/javascript';
|
|
1050
|
+
self.script.charset = 'UTF-8';
|
|
1051
|
+
if (self.script.addEventListener) {
|
|
1052
|
+
self.script.onerror = function () {
|
|
1053
|
+
receiver.callback(errorString);
|
|
1054
|
+
};
|
|
1055
|
+
self.script.onload = function () {
|
|
1056
|
+
receiver.callback(null);
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
else {
|
|
1060
|
+
self.script.onreadystatechange = function () {
|
|
1061
|
+
if (self.script.readyState === 'loaded' ||
|
|
1062
|
+
self.script.readyState === 'complete') {
|
|
1063
|
+
receiver.callback(null);
|
|
1064
|
+
}
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1067
|
+
if (self.script.async === undefined &&
|
|
1068
|
+
document.attachEvent &&
|
|
1069
|
+
/opera/i.test(navigator.userAgent)) {
|
|
1070
|
+
self.errorScript = document.createElement('script');
|
|
1071
|
+
self.errorScript.id = receiver.id + '_error';
|
|
1072
|
+
self.errorScript.text = receiver.name + "('" + errorString + "');";
|
|
1073
|
+
self.script.async = self.errorScript.async = false;
|
|
1074
|
+
}
|
|
1075
|
+
else {
|
|
1076
|
+
self.script.async = true;
|
|
1077
|
+
}
|
|
1078
|
+
var head = document.getElementsByTagName('head')[0];
|
|
1079
|
+
head.insertBefore(self.script, head.firstChild);
|
|
1080
|
+
if (self.errorScript) {
|
|
1081
|
+
head.insertBefore(self.errorScript, self.script.nextSibling);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
cleanup() {
|
|
1085
|
+
if (this.script) {
|
|
1086
|
+
this.script.onload = this.script.onerror = null;
|
|
1087
|
+
this.script.onreadystatechange = null;
|
|
1088
|
+
}
|
|
1089
|
+
if (this.script && this.script.parentNode) {
|
|
1090
|
+
this.script.parentNode.removeChild(this.script);
|
|
1091
|
+
}
|
|
1092
|
+
if (this.errorScript && this.errorScript.parentNode) {
|
|
1093
|
+
this.errorScript.parentNode.removeChild(this.errorScript);
|
|
1094
|
+
}
|
|
1095
|
+
this.script = null;
|
|
1096
|
+
this.errorScript = null;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
class JSONPRequest {
|
|
1102
|
+
constructor(url, data) {
|
|
1103
|
+
this.url = url;
|
|
1104
|
+
this.data = data;
|
|
1105
|
+
}
|
|
1106
|
+
send(receiver) {
|
|
1107
|
+
if (this.request) {
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
var query = buildQueryString(this.data);
|
|
1111
|
+
var url = this.url + '/' + receiver.number + '?' + query;
|
|
1112
|
+
this.request = runtime.createScriptRequest(url);
|
|
1113
|
+
this.request.send(receiver);
|
|
1114
|
+
}
|
|
1115
|
+
cleanup() {
|
|
1116
|
+
if (this.request) {
|
|
1117
|
+
this.request.cleanup();
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
|
|
1123
|
+
var getAgent = function (sender, useTLS) {
|
|
1124
|
+
return function (data, callback) {
|
|
1125
|
+
var scheme = 'http' + (useTLS ? 's' : '') + '://';
|
|
1126
|
+
var url = scheme + (sender.host || sender.options.host) + sender.options.path;
|
|
1127
|
+
var request = runtime.createJSONPRequest(url, data);
|
|
1128
|
+
var receiver = runtime.ScriptReceivers.create(function (error, result) {
|
|
1129
|
+
ScriptReceivers.remove(receiver);
|
|
1130
|
+
request.cleanup();
|
|
1131
|
+
if (result && result.host) {
|
|
1132
|
+
sender.host = result.host;
|
|
1133
|
+
}
|
|
1134
|
+
if (callback) {
|
|
1135
|
+
callback(error, result);
|
|
1136
|
+
}
|
|
1137
|
+
});
|
|
1138
|
+
request.send(receiver);
|
|
1139
|
+
};
|
|
1140
|
+
};
|
|
1141
|
+
var jsonp_timeline_jsonp = {
|
|
1142
|
+
name: 'jsonp',
|
|
1143
|
+
getAgent,
|
|
1144
|
+
};
|
|
1145
|
+
/* harmony default export */ const jsonp_timeline = (jsonp_timeline_jsonp);
|
|
1146
|
+
|
|
1147
|
+
function getGenericURL(baseScheme, params, path) {
|
|
1148
|
+
var scheme = baseScheme + (params.useTLS ? 's' : '');
|
|
1149
|
+
var host = params.useTLS ? params.hostTLS : params.hostNonTLS;
|
|
1150
|
+
return scheme + '://' + host + path;
|
|
1151
|
+
}
|
|
1152
|
+
function getGenericPath(key, queryString) {
|
|
1153
|
+
var path = '/app/' + key;
|
|
1154
|
+
var query = '?protocol=' +
|
|
1155
|
+
defaults.PROTOCOL +
|
|
1156
|
+
'&client=js' +
|
|
1157
|
+
'&version=' +
|
|
1158
|
+
defaults.VERSION +
|
|
1159
|
+
(queryString ? '&' + queryString : '');
|
|
1160
|
+
return path + query;
|
|
1161
|
+
}
|
|
1162
|
+
var ws = {
|
|
1163
|
+
getInitial: function (key, params) {
|
|
1164
|
+
var path = (params.httpPath || '') + getGenericPath(key, 'flash=false');
|
|
1165
|
+
return getGenericURL('ws', params, path);
|
|
1166
|
+
},
|
|
1167
|
+
};
|
|
1168
|
+
var http = {
|
|
1169
|
+
getInitial: function (key, params) {
|
|
1170
|
+
var path = (params.httpPath || '/pusher') + getGenericPath(key);
|
|
1171
|
+
return getGenericURL('http', params, path);
|
|
1172
|
+
},
|
|
1173
|
+
};
|
|
1174
|
+
var sockjs = {
|
|
1175
|
+
getInitial: function (key, params) {
|
|
1176
|
+
return getGenericURL('http', params, params.httpPath || '/pusher');
|
|
1177
|
+
},
|
|
1178
|
+
getPath: function (key, params) {
|
|
1179
|
+
return getGenericPath(key);
|
|
1180
|
+
},
|
|
1181
|
+
};
|
|
1182
|
+
|
|
1183
|
+
class CallbackRegistry {
|
|
1184
|
+
constructor() {
|
|
1185
|
+
this._callbacks = {};
|
|
1186
|
+
}
|
|
1187
|
+
get(name) {
|
|
1188
|
+
return this._callbacks[prefix(name)];
|
|
1189
|
+
}
|
|
1190
|
+
add(name, callback, context) {
|
|
1191
|
+
var prefixedEventName = prefix(name);
|
|
1192
|
+
this._callbacks[prefixedEventName] =
|
|
1193
|
+
this._callbacks[prefixedEventName] || [];
|
|
1194
|
+
this._callbacks[prefixedEventName].push({
|
|
1195
|
+
fn: callback,
|
|
1196
|
+
context: context,
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
remove(name, callback, context) {
|
|
1200
|
+
if (!name && !callback && !context) {
|
|
1201
|
+
this._callbacks = {};
|
|
1202
|
+
return;
|
|
1203
|
+
}
|
|
1204
|
+
var names = name ? [prefix(name)] : keys(this._callbacks);
|
|
1205
|
+
if (callback || context) {
|
|
1206
|
+
this.removeCallback(names, callback, context);
|
|
1207
|
+
}
|
|
1208
|
+
else {
|
|
1209
|
+
this.removeAllCallbacks(names);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
removeCallback(names, callback, context) {
|
|
1213
|
+
apply(names, function (name) {
|
|
1214
|
+
this._callbacks[name] = filter(this._callbacks[name] || [], function (binding) {
|
|
1215
|
+
return ((callback && callback !== binding.fn) ||
|
|
1216
|
+
(context && context !== binding.context));
|
|
1217
|
+
});
|
|
1218
|
+
if (this._callbacks[name].length === 0) {
|
|
1219
|
+
delete this._callbacks[name];
|
|
1220
|
+
}
|
|
1221
|
+
}, this);
|
|
1222
|
+
}
|
|
1223
|
+
removeAllCallbacks(names) {
|
|
1224
|
+
apply(names, function (name) {
|
|
1225
|
+
delete this._callbacks[name];
|
|
1226
|
+
}, this);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
function prefix(name) {
|
|
1230
|
+
return '_' + name;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
|
|
1234
|
+
class Dispatcher {
|
|
1235
|
+
constructor(failThrough) {
|
|
1236
|
+
this.callbacks = new CallbackRegistry();
|
|
1237
|
+
this.global_callbacks = [];
|
|
1238
|
+
this.failThrough = failThrough;
|
|
1239
|
+
}
|
|
1240
|
+
bind(eventName, callback, context) {
|
|
1241
|
+
this.callbacks.add(eventName, callback, context);
|
|
1242
|
+
return this;
|
|
1243
|
+
}
|
|
1244
|
+
bind_global(callback) {
|
|
1245
|
+
this.global_callbacks.push(callback);
|
|
1246
|
+
return this;
|
|
1247
|
+
}
|
|
1248
|
+
unbind(eventName, callback, context) {
|
|
1249
|
+
this.callbacks.remove(eventName, callback, context);
|
|
1250
|
+
return this;
|
|
1251
|
+
}
|
|
1252
|
+
unbind_global(callback) {
|
|
1253
|
+
if (!callback) {
|
|
1254
|
+
this.global_callbacks = [];
|
|
1255
|
+
return this;
|
|
1256
|
+
}
|
|
1257
|
+
this.global_callbacks = filter(this.global_callbacks || [], (c) => c !== callback);
|
|
1258
|
+
return this;
|
|
1259
|
+
}
|
|
1260
|
+
unbind_all() {
|
|
1261
|
+
this.unbind();
|
|
1262
|
+
this.unbind_global();
|
|
1263
|
+
return this;
|
|
1264
|
+
}
|
|
1265
|
+
emit(eventName, data, metadata) {
|
|
1266
|
+
for (var i = 0; i < this.global_callbacks.length; i++) {
|
|
1267
|
+
this.global_callbacks[i](eventName, data);
|
|
1268
|
+
}
|
|
1269
|
+
var callbacks = this.callbacks.get(eventName);
|
|
1270
|
+
var args = [];
|
|
1271
|
+
if (metadata) {
|
|
1272
|
+
args.push(data, metadata);
|
|
1273
|
+
}
|
|
1274
|
+
else if (data) {
|
|
1275
|
+
args.push(data);
|
|
1276
|
+
}
|
|
1277
|
+
if (callbacks && callbacks.length > 0) {
|
|
1278
|
+
for (var i = 0; i < callbacks.length; i++) {
|
|
1279
|
+
callbacks[i].fn.apply(callbacks[i].context || window, args);
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
else if (this.failThrough) {
|
|
1283
|
+
this.failThrough(eventName, data);
|
|
1284
|
+
}
|
|
1285
|
+
return this;
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
|
|
1293
|
+
class TransportConnection extends Dispatcher {
|
|
1294
|
+
constructor(hooks, name, priority, key, options) {
|
|
1295
|
+
super();
|
|
1296
|
+
this.initialize = runtime.transportConnectionInitializer;
|
|
1297
|
+
this.hooks = hooks;
|
|
1298
|
+
this.name = name;
|
|
1299
|
+
this.priority = priority;
|
|
1300
|
+
this.key = key;
|
|
1301
|
+
this.options = options;
|
|
1302
|
+
this.state = 'new';
|
|
1303
|
+
this.timeline = options.timeline;
|
|
1304
|
+
this.activityTimeout = options.activityTimeout;
|
|
1305
|
+
this.id = this.timeline.generateUniqueID();
|
|
1306
|
+
}
|
|
1307
|
+
handlesActivityChecks() {
|
|
1308
|
+
return Boolean(this.hooks.handlesActivityChecks);
|
|
1309
|
+
}
|
|
1310
|
+
supportsPing() {
|
|
1311
|
+
return Boolean(this.hooks.supportsPing);
|
|
1312
|
+
}
|
|
1313
|
+
connect() {
|
|
1314
|
+
if (this.socket || this.state !== 'initialized') {
|
|
1315
|
+
return false;
|
|
1316
|
+
}
|
|
1317
|
+
var url = this.hooks.urls.getInitial(this.key, this.options);
|
|
1318
|
+
try {
|
|
1319
|
+
this.socket = this.hooks.getSocket(url, this.options);
|
|
1320
|
+
}
|
|
1321
|
+
catch (e) {
|
|
1322
|
+
util.defer(() => {
|
|
1323
|
+
this.onError(e);
|
|
1324
|
+
this.changeState('closed');
|
|
1325
|
+
});
|
|
1326
|
+
return false;
|
|
1327
|
+
}
|
|
1328
|
+
this.bindListeners();
|
|
1329
|
+
logger.debug('Connecting', { transport: this.name, url });
|
|
1330
|
+
this.changeState('connecting');
|
|
1331
|
+
return true;
|
|
1332
|
+
}
|
|
1333
|
+
close() {
|
|
1334
|
+
if (this.socket) {
|
|
1335
|
+
this.socket.close();
|
|
1336
|
+
return true;
|
|
1337
|
+
}
|
|
1338
|
+
else {
|
|
1339
|
+
return false;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
send(data) {
|
|
1343
|
+
if (this.state === 'open') {
|
|
1344
|
+
util.defer(() => {
|
|
1345
|
+
if (this.socket) {
|
|
1346
|
+
this.socket.send(data);
|
|
1347
|
+
}
|
|
1348
|
+
});
|
|
1349
|
+
return true;
|
|
1350
|
+
}
|
|
1351
|
+
else {
|
|
1352
|
+
return false;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
ping() {
|
|
1356
|
+
if (this.state === 'open' && this.supportsPing()) {
|
|
1357
|
+
this.socket.ping();
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
onOpen() {
|
|
1361
|
+
if (this.hooks.beforeOpen) {
|
|
1362
|
+
this.hooks.beforeOpen(this.socket, this.hooks.urls.getPath(this.key, this.options));
|
|
1363
|
+
}
|
|
1364
|
+
this.changeState('open');
|
|
1365
|
+
this.socket.onopen = undefined;
|
|
1366
|
+
}
|
|
1367
|
+
onError(error) {
|
|
1368
|
+
this.emit('error', { type: 'WebSocketError', error: error });
|
|
1369
|
+
this.timeline.error(this.buildTimelineMessage({ error: error.toString() }));
|
|
1370
|
+
}
|
|
1371
|
+
onClose(closeEvent) {
|
|
1372
|
+
if (closeEvent) {
|
|
1373
|
+
this.changeState('closed', {
|
|
1374
|
+
code: closeEvent.code,
|
|
1375
|
+
reason: closeEvent.reason,
|
|
1376
|
+
wasClean: closeEvent.wasClean,
|
|
1377
|
+
});
|
|
1378
|
+
}
|
|
1379
|
+
else {
|
|
1380
|
+
this.changeState('closed');
|
|
1381
|
+
}
|
|
1382
|
+
this.unbindListeners();
|
|
1383
|
+
this.socket = undefined;
|
|
1384
|
+
}
|
|
1385
|
+
onMessage(message) {
|
|
1386
|
+
this.emit('message', message);
|
|
1387
|
+
}
|
|
1388
|
+
onActivity() {
|
|
1389
|
+
this.emit('activity');
|
|
1390
|
+
}
|
|
1391
|
+
bindListeners() {
|
|
1392
|
+
this.socket.onopen = () => {
|
|
1393
|
+
this.onOpen();
|
|
1394
|
+
};
|
|
1395
|
+
this.socket.onerror = (error) => {
|
|
1396
|
+
this.onError(error);
|
|
1397
|
+
};
|
|
1398
|
+
this.socket.onclose = (closeEvent) => {
|
|
1399
|
+
this.onClose(closeEvent);
|
|
1400
|
+
};
|
|
1401
|
+
this.socket.onmessage = (message) => {
|
|
1402
|
+
this.onMessage(message);
|
|
1403
|
+
};
|
|
1404
|
+
if (this.supportsPing()) {
|
|
1405
|
+
this.socket.onactivity = () => {
|
|
1406
|
+
this.onActivity();
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
unbindListeners() {
|
|
1411
|
+
if (this.socket) {
|
|
1412
|
+
this.socket.onopen = undefined;
|
|
1413
|
+
this.socket.onerror = undefined;
|
|
1414
|
+
this.socket.onclose = undefined;
|
|
1415
|
+
this.socket.onmessage = undefined;
|
|
1416
|
+
if (this.supportsPing()) {
|
|
1417
|
+
this.socket.onactivity = undefined;
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
changeState(state, params) {
|
|
1422
|
+
this.state = state;
|
|
1423
|
+
this.timeline.info(this.buildTimelineMessage({
|
|
1424
|
+
state: state,
|
|
1425
|
+
params: params,
|
|
1426
|
+
}));
|
|
1427
|
+
this.emit(state, params);
|
|
1428
|
+
}
|
|
1429
|
+
buildTimelineMessage(message) {
|
|
1430
|
+
return extend({ cid: this.id }, message);
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
class Transport {
|
|
1435
|
+
constructor(hooks) {
|
|
1436
|
+
this.hooks = hooks;
|
|
1437
|
+
}
|
|
1438
|
+
isSupported(environment) {
|
|
1439
|
+
return this.hooks.isSupported(environment);
|
|
1440
|
+
}
|
|
1441
|
+
createConnection(name, priority, key, options) {
|
|
1442
|
+
return new TransportConnection(this.hooks, name, priority, key, options);
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
|
|
1449
|
+
var WSTransport = new Transport({
|
|
1450
|
+
urls: ws,
|
|
1451
|
+
handlesActivityChecks: false,
|
|
1452
|
+
supportsPing: false,
|
|
1453
|
+
isInitialized: function () {
|
|
1454
|
+
return Boolean(runtime.getWebSocketAPI());
|
|
1455
|
+
},
|
|
1456
|
+
isSupported: function () {
|
|
1457
|
+
return Boolean(runtime.getWebSocketAPI());
|
|
1458
|
+
},
|
|
1459
|
+
getSocket: function (url) {
|
|
1460
|
+
return runtime.createWebSocket(url);
|
|
1461
|
+
},
|
|
1462
|
+
});
|
|
1463
|
+
var httpConfiguration = {
|
|
1464
|
+
urls: http,
|
|
1465
|
+
handlesActivityChecks: false,
|
|
1466
|
+
supportsPing: true,
|
|
1467
|
+
isInitialized: function () {
|
|
1468
|
+
return true;
|
|
1469
|
+
},
|
|
1470
|
+
};
|
|
1471
|
+
var streamingConfiguration = extend({
|
|
1472
|
+
getSocket: function (url) {
|
|
1473
|
+
return runtime.HTTPFactory.createStreamingSocket(url);
|
|
1474
|
+
},
|
|
1475
|
+
}, httpConfiguration);
|
|
1476
|
+
var pollingConfiguration = extend({
|
|
1477
|
+
getSocket: function (url) {
|
|
1478
|
+
return runtime.HTTPFactory.createPollingSocket(url);
|
|
1479
|
+
},
|
|
1480
|
+
}, httpConfiguration);
|
|
1481
|
+
var xhrConfiguration = {
|
|
1482
|
+
isSupported: function () {
|
|
1483
|
+
return runtime.isXHRSupported();
|
|
1484
|
+
},
|
|
1485
|
+
};
|
|
1486
|
+
var XHRStreamingTransport = new Transport((extend({}, streamingConfiguration, xhrConfiguration)));
|
|
1487
|
+
var XHRPollingTransport = new Transport((extend({}, pollingConfiguration, xhrConfiguration)));
|
|
1488
|
+
var Transports = {
|
|
1489
|
+
ws: WSTransport,
|
|
1490
|
+
xhr_streaming: XHRStreamingTransport,
|
|
1491
|
+
xhr_polling: XHRPollingTransport,
|
|
1492
|
+
};
|
|
1493
|
+
/* harmony default export */ const transports = (Transports);
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
var SockJSTransport = new Transport({
|
|
1501
|
+
file: 'sockjs',
|
|
1502
|
+
urls: sockjs,
|
|
1503
|
+
handlesActivityChecks: true,
|
|
1504
|
+
supportsPing: false,
|
|
1505
|
+
isSupported: function () {
|
|
1506
|
+
return true;
|
|
1507
|
+
},
|
|
1508
|
+
isInitialized: function () {
|
|
1509
|
+
return window.SockJS !== undefined;
|
|
1510
|
+
},
|
|
1511
|
+
getSocket: function (url, options) {
|
|
1512
|
+
return new window.SockJS(url, null, {
|
|
1513
|
+
js_path: Dependencies.getPath('sockjs', {
|
|
1514
|
+
useTLS: options.useTLS,
|
|
1515
|
+
}),
|
|
1516
|
+
ignore_null_origin: options.ignoreNullOrigin,
|
|
1517
|
+
});
|
|
1518
|
+
},
|
|
1519
|
+
beforeOpen: function (socket, path) {
|
|
1520
|
+
socket.send(JSON.stringify({
|
|
1521
|
+
path: path,
|
|
1522
|
+
}));
|
|
1523
|
+
},
|
|
1524
|
+
});
|
|
1525
|
+
var xdrConfiguration = {
|
|
1526
|
+
isSupported: function (environment) {
|
|
1527
|
+
var yes = runtime.isXDRSupported(environment.useTLS);
|
|
1528
|
+
return yes;
|
|
1529
|
+
},
|
|
1530
|
+
};
|
|
1531
|
+
var XDRStreamingTransport = new Transport((extend({}, streamingConfiguration, xdrConfiguration)));
|
|
1532
|
+
var XDRPollingTransport = new Transport((extend({}, pollingConfiguration, xdrConfiguration)));
|
|
1533
|
+
transports.xdr_streaming = XDRStreamingTransport;
|
|
1534
|
+
transports.xdr_polling = XDRPollingTransport;
|
|
1535
|
+
transports.sockjs = SockJSTransport;
|
|
1536
|
+
/* harmony default export */ const transports_transports = (transports);
|
|
1537
|
+
|
|
1538
|
+
class NetInfo extends Dispatcher {
|
|
1539
|
+
constructor() {
|
|
1540
|
+
super();
|
|
1541
|
+
var self = this;
|
|
1542
|
+
if (window.addEventListener !== undefined) {
|
|
1543
|
+
window.addEventListener('online', function () {
|
|
1544
|
+
self.emit('online');
|
|
1545
|
+
}, false);
|
|
1546
|
+
window.addEventListener('offline', function () {
|
|
1547
|
+
self.emit('offline');
|
|
1548
|
+
}, false);
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
isOnline() {
|
|
1552
|
+
if (window.navigator.onLine === undefined) {
|
|
1553
|
+
return true;
|
|
1554
|
+
}
|
|
1555
|
+
else {
|
|
1556
|
+
return window.navigator.onLine;
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
var Network = new NetInfo();
|
|
1561
|
+
|
|
1562
|
+
|
|
1563
|
+
class AssistantToTheTransportManager {
|
|
1564
|
+
constructor(manager, transport, options) {
|
|
1565
|
+
this.manager = manager;
|
|
1566
|
+
this.transport = transport;
|
|
1567
|
+
this.minPingDelay = options.minPingDelay;
|
|
1568
|
+
this.maxPingDelay = options.maxPingDelay;
|
|
1569
|
+
this.pingDelay = undefined;
|
|
1570
|
+
}
|
|
1571
|
+
createConnection(name, priority, key, options) {
|
|
1572
|
+
options = extend({}, options, {
|
|
1573
|
+
activityTimeout: this.pingDelay,
|
|
1574
|
+
});
|
|
1575
|
+
var connection = this.transport.createConnection(name, priority, key, options);
|
|
1576
|
+
var openTimestamp = null;
|
|
1577
|
+
var onOpen = function () {
|
|
1578
|
+
connection.unbind('open', onOpen);
|
|
1579
|
+
connection.bind('closed', onClosed);
|
|
1580
|
+
openTimestamp = util.now();
|
|
1581
|
+
};
|
|
1582
|
+
var onClosed = (closeEvent) => {
|
|
1583
|
+
connection.unbind('closed', onClosed);
|
|
1584
|
+
if (closeEvent.code === 1002 || closeEvent.code === 1003) {
|
|
1585
|
+
this.manager.reportDeath();
|
|
1586
|
+
}
|
|
1587
|
+
else if (!closeEvent.wasClean && openTimestamp) {
|
|
1588
|
+
var lifespan = util.now() - openTimestamp;
|
|
1589
|
+
if (lifespan < 2 * this.maxPingDelay) {
|
|
1590
|
+
this.manager.reportDeath();
|
|
1591
|
+
this.pingDelay = Math.max(lifespan / 2, this.minPingDelay);
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
};
|
|
1595
|
+
connection.bind('open', onOpen);
|
|
1596
|
+
return connection;
|
|
1597
|
+
}
|
|
1598
|
+
isSupported(environment) {
|
|
1599
|
+
return this.manager.isAlive() && this.transport.isSupported(environment);
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
const Protocol = {
|
|
1603
|
+
decodeMessage: function (messageEvent) {
|
|
1604
|
+
try {
|
|
1605
|
+
var messageData = JSON.parse(messageEvent.data);
|
|
1606
|
+
var pusherEventData = messageData.data;
|
|
1607
|
+
if (typeof pusherEventData === 'string') {
|
|
1608
|
+
try {
|
|
1609
|
+
pusherEventData = JSON.parse(messageData.data);
|
|
1610
|
+
}
|
|
1611
|
+
catch (e) { }
|
|
1612
|
+
}
|
|
1613
|
+
var pusherEvent = {
|
|
1614
|
+
event: messageData.event,
|
|
1615
|
+
channel: messageData.channel,
|
|
1616
|
+
data: pusherEventData,
|
|
1617
|
+
};
|
|
1618
|
+
if (messageData.user_id) {
|
|
1619
|
+
pusherEvent.user_id = messageData.user_id;
|
|
1620
|
+
}
|
|
1621
|
+
return pusherEvent;
|
|
1622
|
+
}
|
|
1623
|
+
catch (e) {
|
|
1624
|
+
throw { type: 'MessageParseError', error: e, data: messageEvent.data };
|
|
1625
|
+
}
|
|
1626
|
+
},
|
|
1627
|
+
encodeMessage: function (event) {
|
|
1628
|
+
return JSON.stringify(event);
|
|
1629
|
+
},
|
|
1630
|
+
processHandshake: function (messageEvent) {
|
|
1631
|
+
var message = Protocol.decodeMessage(messageEvent);
|
|
1632
|
+
if (message.event === 'pusher:connection_established') {
|
|
1633
|
+
if (!message.data.activity_timeout) {
|
|
1634
|
+
throw 'No activity timeout specified in handshake';
|
|
1635
|
+
}
|
|
1636
|
+
return {
|
|
1637
|
+
action: 'connected',
|
|
1638
|
+
id: message.data.socket_id,
|
|
1639
|
+
activityTimeout: message.data.activity_timeout * 1000,
|
|
1640
|
+
};
|
|
1641
|
+
}
|
|
1642
|
+
else if (message.event === 'pusher:error') {
|
|
1643
|
+
return {
|
|
1644
|
+
action: this.getCloseAction(message.data),
|
|
1645
|
+
error: this.getCloseError(message.data),
|
|
1646
|
+
};
|
|
1647
|
+
}
|
|
1648
|
+
else {
|
|
1649
|
+
throw 'Invalid handshake';
|
|
1650
|
+
}
|
|
1651
|
+
},
|
|
1652
|
+
getCloseAction: function (closeEvent) {
|
|
1653
|
+
if (closeEvent.code < 4000) {
|
|
1654
|
+
if (closeEvent.code >= 1002 && closeEvent.code <= 1004) {
|
|
1655
|
+
return 'backoff';
|
|
1656
|
+
}
|
|
1657
|
+
else {
|
|
1658
|
+
return null;
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
else if (closeEvent.code === 4000) {
|
|
1662
|
+
return 'tls_only';
|
|
1663
|
+
}
|
|
1664
|
+
else if (closeEvent.code < 4100) {
|
|
1665
|
+
return 'refused';
|
|
1666
|
+
}
|
|
1667
|
+
else if (closeEvent.code < 4200) {
|
|
1668
|
+
return 'backoff';
|
|
1669
|
+
}
|
|
1670
|
+
else if (closeEvent.code < 4300) {
|
|
1671
|
+
return 'retry';
|
|
1672
|
+
}
|
|
1673
|
+
else {
|
|
1674
|
+
return 'refused';
|
|
1675
|
+
}
|
|
1676
|
+
},
|
|
1677
|
+
getCloseError: function (closeEvent) {
|
|
1678
|
+
if (closeEvent.code !== 1000 && closeEvent.code !== 1001) {
|
|
1679
|
+
return {
|
|
1680
|
+
type: 'PusherError',
|
|
1681
|
+
data: {
|
|
1682
|
+
code: closeEvent.code,
|
|
1683
|
+
message: closeEvent.reason || closeEvent.message,
|
|
1684
|
+
},
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
else {
|
|
1688
|
+
return null;
|
|
1689
|
+
}
|
|
1690
|
+
},
|
|
1691
|
+
};
|
|
1692
|
+
/* harmony default export */ const protocol = (Protocol);
|
|
1693
|
+
|
|
1694
|
+
|
|
1695
|
+
|
|
1696
|
+
|
|
1697
|
+
class Connection extends Dispatcher {
|
|
1698
|
+
constructor(id, transport) {
|
|
1699
|
+
super();
|
|
1700
|
+
this.id = id;
|
|
1701
|
+
this.transport = transport;
|
|
1702
|
+
this.activityTimeout = transport.activityTimeout;
|
|
1703
|
+
this.bindListeners();
|
|
1704
|
+
}
|
|
1705
|
+
handlesActivityChecks() {
|
|
1706
|
+
return this.transport.handlesActivityChecks();
|
|
1707
|
+
}
|
|
1708
|
+
send(data) {
|
|
1709
|
+
return this.transport.send(data);
|
|
1710
|
+
}
|
|
1711
|
+
send_event(name, data, channel) {
|
|
1712
|
+
var event = { event: name, data: data };
|
|
1713
|
+
if (channel) {
|
|
1714
|
+
event.channel = channel;
|
|
1715
|
+
}
|
|
1716
|
+
logger.debug('Event sent', event);
|
|
1717
|
+
return this.send(protocol.encodeMessage(event));
|
|
1718
|
+
}
|
|
1719
|
+
ping() {
|
|
1720
|
+
if (this.transport.supportsPing()) {
|
|
1721
|
+
this.transport.ping();
|
|
1722
|
+
}
|
|
1723
|
+
else {
|
|
1724
|
+
this.send_event('pusher:ping', {});
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
close() {
|
|
1728
|
+
this.transport.close();
|
|
1729
|
+
}
|
|
1730
|
+
bindListeners() {
|
|
1731
|
+
var listeners = {
|
|
1732
|
+
message: (messageEvent) => {
|
|
1733
|
+
var pusherEvent;
|
|
1734
|
+
try {
|
|
1735
|
+
pusherEvent = protocol.decodeMessage(messageEvent);
|
|
1736
|
+
}
|
|
1737
|
+
catch (e) {
|
|
1738
|
+
this.emit('error', {
|
|
1739
|
+
type: 'MessageParseError',
|
|
1740
|
+
error: e,
|
|
1741
|
+
data: messageEvent.data,
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
if (pusherEvent !== undefined) {
|
|
1745
|
+
logger.debug('Event recd', pusherEvent);
|
|
1746
|
+
switch (pusherEvent.event) {
|
|
1747
|
+
case 'pusher:error':
|
|
1748
|
+
this.emit('error', {
|
|
1749
|
+
type: 'PusherError',
|
|
1750
|
+
data: pusherEvent.data,
|
|
1751
|
+
});
|
|
1752
|
+
break;
|
|
1753
|
+
case 'pusher:ping':
|
|
1754
|
+
this.emit('ping');
|
|
1755
|
+
break;
|
|
1756
|
+
case 'pusher:pong':
|
|
1757
|
+
this.emit('pong');
|
|
1758
|
+
break;
|
|
1759
|
+
}
|
|
1760
|
+
this.emit('message', pusherEvent);
|
|
1761
|
+
}
|
|
1762
|
+
},
|
|
1763
|
+
activity: () => {
|
|
1764
|
+
this.emit('activity');
|
|
1765
|
+
},
|
|
1766
|
+
error: (error) => {
|
|
1767
|
+
this.emit('error', error);
|
|
1768
|
+
},
|
|
1769
|
+
closed: (closeEvent) => {
|
|
1770
|
+
unbindListeners();
|
|
1771
|
+
if (closeEvent && closeEvent.code) {
|
|
1772
|
+
this.handleCloseEvent(closeEvent);
|
|
1773
|
+
}
|
|
1774
|
+
this.transport = null;
|
|
1775
|
+
this.emit('closed');
|
|
1776
|
+
},
|
|
1777
|
+
};
|
|
1778
|
+
var unbindListeners = () => {
|
|
1779
|
+
objectApply(listeners, (listener, event) => {
|
|
1780
|
+
this.transport.unbind(event, listener);
|
|
1781
|
+
});
|
|
1782
|
+
};
|
|
1783
|
+
objectApply(listeners, (listener, event) => {
|
|
1784
|
+
this.transport.bind(event, listener);
|
|
1785
|
+
});
|
|
1786
|
+
}
|
|
1787
|
+
handleCloseEvent(closeEvent) {
|
|
1788
|
+
var action = protocol.getCloseAction(closeEvent);
|
|
1789
|
+
var error = protocol.getCloseError(closeEvent);
|
|
1790
|
+
if (error) {
|
|
1791
|
+
this.emit('error', error);
|
|
1792
|
+
}
|
|
1793
|
+
if (action) {
|
|
1794
|
+
this.emit(action, { action: action, error: error });
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
|
|
1800
|
+
|
|
1801
|
+
class Handshake {
|
|
1802
|
+
constructor(transport, callback) {
|
|
1803
|
+
this.transport = transport;
|
|
1804
|
+
this.callback = callback;
|
|
1805
|
+
this.bindListeners();
|
|
1806
|
+
}
|
|
1807
|
+
close() {
|
|
1808
|
+
this.unbindListeners();
|
|
1809
|
+
this.transport.close();
|
|
1810
|
+
}
|
|
1811
|
+
bindListeners() {
|
|
1812
|
+
this.onMessage = (m) => {
|
|
1813
|
+
this.unbindListeners();
|
|
1814
|
+
var result;
|
|
1815
|
+
try {
|
|
1816
|
+
result = protocol.processHandshake(m);
|
|
1817
|
+
}
|
|
1818
|
+
catch (e) {
|
|
1819
|
+
this.finish('error', { error: e });
|
|
1820
|
+
this.transport.close();
|
|
1821
|
+
return;
|
|
1822
|
+
}
|
|
1823
|
+
if (result.action === 'connected') {
|
|
1824
|
+
this.finish('connected', {
|
|
1825
|
+
connection: new Connection(result.id, this.transport),
|
|
1826
|
+
activityTimeout: result.activityTimeout,
|
|
1827
|
+
});
|
|
1828
|
+
}
|
|
1829
|
+
else {
|
|
1830
|
+
this.finish(result.action, { error: result.error });
|
|
1831
|
+
this.transport.close();
|
|
1832
|
+
}
|
|
1833
|
+
};
|
|
1834
|
+
this.onClosed = (closeEvent) => {
|
|
1835
|
+
this.unbindListeners();
|
|
1836
|
+
var action = protocol.getCloseAction(closeEvent) || 'backoff';
|
|
1837
|
+
var error = protocol.getCloseError(closeEvent);
|
|
1838
|
+
this.finish(action, { error: error });
|
|
1839
|
+
};
|
|
1840
|
+
this.transport.bind('message', this.onMessage);
|
|
1841
|
+
this.transport.bind('closed', this.onClosed);
|
|
1842
|
+
}
|
|
1843
|
+
unbindListeners() {
|
|
1844
|
+
this.transport.unbind('message', this.onMessage);
|
|
1845
|
+
this.transport.unbind('closed', this.onClosed);
|
|
1846
|
+
}
|
|
1847
|
+
finish(action, params) {
|
|
1848
|
+
this.callback(extend({ transport: this.transport, action: action }, params));
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
class TimelineSender {
|
|
1853
|
+
constructor(timeline, options) {
|
|
1854
|
+
this.timeline = timeline;
|
|
1855
|
+
this.options = options || {};
|
|
1856
|
+
}
|
|
1857
|
+
send(useTLS, callback) {
|
|
1858
|
+
if (this.timeline.isEmpty()) {
|
|
1859
|
+
return;
|
|
1860
|
+
}
|
|
1861
|
+
this.timeline.send(runtime.TimelineTransport.getAgent(this, useTLS), callback);
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
|
|
1866
|
+
|
|
1867
|
+
|
|
1868
|
+
|
|
1869
|
+
class Channel extends Dispatcher {
|
|
1870
|
+
constructor(name, pusher) {
|
|
1871
|
+
super(function (event, data) {
|
|
1872
|
+
logger.debug('No callbacks on ' + name + ' for ' + event);
|
|
1873
|
+
});
|
|
1874
|
+
this.name = name;
|
|
1875
|
+
this.pusher = pusher;
|
|
1876
|
+
this.subscribed = false;
|
|
1877
|
+
this.subscriptionPending = false;
|
|
1878
|
+
this.subscriptionCancelled = false;
|
|
1879
|
+
}
|
|
1880
|
+
authorize(socketId, callback) {
|
|
1881
|
+
return callback(null, { auth: '' });
|
|
1882
|
+
}
|
|
1883
|
+
trigger(event, data) {
|
|
1884
|
+
if (event.indexOf('client-') !== 0) {
|
|
1885
|
+
throw new BadEventName("Event '" + event + "' does not start with 'client-'");
|
|
1886
|
+
}
|
|
1887
|
+
if (!this.subscribed) {
|
|
1888
|
+
var suffix = url_store.buildLogSuffix('triggeringClientEvents');
|
|
1889
|
+
logger.warn(`Client event triggered before channel 'subscription_succeeded' event . ${suffix}`);
|
|
1890
|
+
}
|
|
1891
|
+
return this.pusher.send_event(event, data, this.name);
|
|
1892
|
+
}
|
|
1893
|
+
disconnect() {
|
|
1894
|
+
this.subscribed = false;
|
|
1895
|
+
this.subscriptionPending = false;
|
|
1896
|
+
}
|
|
1897
|
+
handleEvent(event) {
|
|
1898
|
+
var eventName = event.event;
|
|
1899
|
+
var data = event.data;
|
|
1900
|
+
if (eventName === 'pusher_internal:subscription_succeeded') {
|
|
1901
|
+
this.handleSubscriptionSucceededEvent(event);
|
|
1902
|
+
}
|
|
1903
|
+
else if (eventName === 'pusher_internal:subscription_count') {
|
|
1904
|
+
this.handleSubscriptionCountEvent(event);
|
|
1905
|
+
}
|
|
1906
|
+
else if (eventName.indexOf('pusher_internal:') !== 0) {
|
|
1907
|
+
var metadata = {};
|
|
1908
|
+
this.emit(eventName, data, metadata);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
handleSubscriptionSucceededEvent(event) {
|
|
1912
|
+
this.subscriptionPending = false;
|
|
1913
|
+
this.subscribed = true;
|
|
1914
|
+
if (this.subscriptionCancelled) {
|
|
1915
|
+
this.pusher.unsubscribe(this.name);
|
|
1916
|
+
}
|
|
1917
|
+
else {
|
|
1918
|
+
this.emit('pusher:subscription_succeeded', event.data);
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
handleSubscriptionCountEvent(event) {
|
|
1922
|
+
if (event.data.subscription_count) {
|
|
1923
|
+
this.subscriptionCount = event.data.subscription_count;
|
|
1924
|
+
}
|
|
1925
|
+
this.emit('pusher:subscription_count', event.data);
|
|
1926
|
+
}
|
|
1927
|
+
subscribe() {
|
|
1928
|
+
if (this.subscribed) {
|
|
1929
|
+
return;
|
|
1930
|
+
}
|
|
1931
|
+
this.subscriptionPending = true;
|
|
1932
|
+
this.subscriptionCancelled = false;
|
|
1933
|
+
this.authorize(this.pusher.connection.socket_id, (error, data) => {
|
|
1934
|
+
if (error) {
|
|
1935
|
+
this.subscriptionPending = false;
|
|
1936
|
+
logger.error(error.toString());
|
|
1937
|
+
this.emit('pusher:subscription_error', Object.assign({}, {
|
|
1938
|
+
type: 'AuthError',
|
|
1939
|
+
error: error.message,
|
|
1940
|
+
}, error instanceof HTTPAuthError ? { status: error.status } : {}));
|
|
1941
|
+
}
|
|
1942
|
+
else {
|
|
1943
|
+
this.pusher.send_event('pusher:subscribe', {
|
|
1944
|
+
auth: data.auth,
|
|
1945
|
+
channel_data: data.channel_data,
|
|
1946
|
+
channel: this.name,
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
});
|
|
1950
|
+
}
|
|
1951
|
+
unsubscribe() {
|
|
1952
|
+
this.subscribed = false;
|
|
1953
|
+
this.pusher.send_event('pusher:unsubscribe', {
|
|
1954
|
+
channel: this.name,
|
|
1955
|
+
});
|
|
1956
|
+
}
|
|
1957
|
+
cancelSubscription() {
|
|
1958
|
+
this.subscriptionCancelled = true;
|
|
1959
|
+
}
|
|
1960
|
+
reinstateSubscription() {
|
|
1961
|
+
this.subscriptionCancelled = false;
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
|
|
1965
|
+
class PrivateChannel extends Channel {
|
|
1966
|
+
authorize(socketId, callback) {
|
|
1967
|
+
return this.pusher.config.channelAuthorizer({
|
|
1968
|
+
channelName: this.name,
|
|
1969
|
+
socketId: socketId,
|
|
1970
|
+
}, callback);
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
class Members {
|
|
1975
|
+
constructor() {
|
|
1976
|
+
this.reset();
|
|
1977
|
+
}
|
|
1978
|
+
get(id) {
|
|
1979
|
+
if (Object.prototype.hasOwnProperty.call(this.members, id)) {
|
|
1980
|
+
return {
|
|
1981
|
+
id: id,
|
|
1982
|
+
info: this.members[id],
|
|
1983
|
+
};
|
|
1984
|
+
}
|
|
1985
|
+
else {
|
|
1986
|
+
return null;
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
each(callback) {
|
|
1990
|
+
objectApply(this.members, (member, id) => {
|
|
1991
|
+
callback(this.get(id));
|
|
1992
|
+
});
|
|
1993
|
+
}
|
|
1994
|
+
setMyID(id) {
|
|
1995
|
+
this.myID = id;
|
|
1996
|
+
}
|
|
1997
|
+
onSubscription(subscriptionData) {
|
|
1998
|
+
this.members = subscriptionData.presence.hash;
|
|
1999
|
+
this.count = subscriptionData.presence.count;
|
|
2000
|
+
this.me = this.get(this.myID);
|
|
2001
|
+
}
|
|
2002
|
+
addMember(memberData) {
|
|
2003
|
+
if (this.get(memberData.user_id) === null) {
|
|
2004
|
+
this.count++;
|
|
2005
|
+
}
|
|
2006
|
+
this.members[memberData.user_id] = memberData.user_info;
|
|
2007
|
+
return this.get(memberData.user_id);
|
|
2008
|
+
}
|
|
2009
|
+
removeMember(memberData) {
|
|
2010
|
+
var member = this.get(memberData.user_id);
|
|
2011
|
+
if (member) {
|
|
2012
|
+
delete this.members[memberData.user_id];
|
|
2013
|
+
this.count--;
|
|
2014
|
+
}
|
|
2015
|
+
return member;
|
|
2016
|
+
}
|
|
2017
|
+
reset() {
|
|
2018
|
+
this.members = {};
|
|
2019
|
+
this.count = 0;
|
|
2020
|
+
this.myID = null;
|
|
2021
|
+
this.me = null;
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
var __awaiter = function (thisArg, _arguments, P, generator) {
|
|
2025
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
2026
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
2027
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
2028
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
2029
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
2030
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
2031
|
+
});
|
|
2032
|
+
};
|
|
2033
|
+
|
|
2034
|
+
|
|
2035
|
+
|
|
2036
|
+
|
|
2037
|
+
class PresenceChannel extends PrivateChannel {
|
|
2038
|
+
constructor(name, pusher) {
|
|
2039
|
+
super(name, pusher);
|
|
2040
|
+
this.members = new Members();
|
|
2041
|
+
}
|
|
2042
|
+
authorize(socketId, callback) {
|
|
2043
|
+
super.authorize(socketId, (error, authData) => __awaiter(this, void 0, void 0, function* () {
|
|
2044
|
+
if (!error) {
|
|
2045
|
+
authData = authData;
|
|
2046
|
+
if (authData.channel_data != null) {
|
|
2047
|
+
var channelData = JSON.parse(authData.channel_data);
|
|
2048
|
+
this.members.setMyID(channelData.user_id);
|
|
2049
|
+
}
|
|
2050
|
+
else {
|
|
2051
|
+
yield this.pusher.user.signinDonePromise;
|
|
2052
|
+
if (this.pusher.user.user_data != null) {
|
|
2053
|
+
this.members.setMyID(this.pusher.user.user_data.id);
|
|
2054
|
+
}
|
|
2055
|
+
else {
|
|
2056
|
+
let suffix = url_store.buildLogSuffix('authorizationEndpoint');
|
|
2057
|
+
logger.error(`Invalid auth response for channel '${this.name}', ` +
|
|
2058
|
+
`expected 'channel_data' field. ${suffix}, ` +
|
|
2059
|
+
`or the user should be signed in.`);
|
|
2060
|
+
callback('Invalid auth response');
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
callback(error, authData);
|
|
2066
|
+
}));
|
|
2067
|
+
}
|
|
2068
|
+
handleEvent(event) {
|
|
2069
|
+
var eventName = event.event;
|
|
2070
|
+
if (eventName.indexOf('pusher_internal:') === 0) {
|
|
2071
|
+
this.handleInternalEvent(event);
|
|
2072
|
+
}
|
|
2073
|
+
else {
|
|
2074
|
+
var data = event.data;
|
|
2075
|
+
var metadata = {};
|
|
2076
|
+
if (event.user_id) {
|
|
2077
|
+
metadata.user_id = event.user_id;
|
|
2078
|
+
}
|
|
2079
|
+
this.emit(eventName, data, metadata);
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
handleInternalEvent(event) {
|
|
2083
|
+
var eventName = event.event;
|
|
2084
|
+
var data = event.data;
|
|
2085
|
+
switch (eventName) {
|
|
2086
|
+
case 'pusher_internal:subscription_succeeded':
|
|
2087
|
+
this.handleSubscriptionSucceededEvent(event);
|
|
2088
|
+
break;
|
|
2089
|
+
case 'pusher_internal:subscription_count':
|
|
2090
|
+
this.handleSubscriptionCountEvent(event);
|
|
2091
|
+
break;
|
|
2092
|
+
case 'pusher_internal:member_added':
|
|
2093
|
+
var addedMember = this.members.addMember(data);
|
|
2094
|
+
this.emit('pusher:member_added', addedMember);
|
|
2095
|
+
break;
|
|
2096
|
+
case 'pusher_internal:member_removed':
|
|
2097
|
+
var removedMember = this.members.removeMember(data);
|
|
2098
|
+
if (removedMember) {
|
|
2099
|
+
this.emit('pusher:member_removed', removedMember);
|
|
2100
|
+
}
|
|
2101
|
+
break;
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
handleSubscriptionSucceededEvent(event) {
|
|
2105
|
+
this.subscriptionPending = false;
|
|
2106
|
+
this.subscribed = true;
|
|
2107
|
+
if (this.subscriptionCancelled) {
|
|
2108
|
+
this.pusher.unsubscribe(this.name);
|
|
2109
|
+
}
|
|
2110
|
+
else {
|
|
2111
|
+
this.members.onSubscription(event.data);
|
|
2112
|
+
this.emit('pusher:subscription_succeeded', this.members);
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
disconnect() {
|
|
2116
|
+
this.members.reset();
|
|
2117
|
+
super.disconnect();
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
// EXTERNAL MODULE: ./node_modules/@stablelib/utf8/lib/utf8.js
|
|
2122
|
+
var utf8 = __webpack_require__(978);
|
|
2123
|
+
// EXTERNAL MODULE: ./node_modules/@stablelib/base64/lib/base64.js
|
|
2124
|
+
var base64 = __webpack_require__(594);
|
|
2125
|
+
|
|
2126
|
+
|
|
2127
|
+
|
|
2128
|
+
|
|
2129
|
+
|
|
2130
|
+
class EncryptedChannel extends PrivateChannel {
|
|
2131
|
+
constructor(name, pusher, nacl) {
|
|
2132
|
+
super(name, pusher);
|
|
2133
|
+
this.key = null;
|
|
2134
|
+
this.nacl = nacl;
|
|
2135
|
+
}
|
|
2136
|
+
authorize(socketId, callback) {
|
|
2137
|
+
super.authorize(socketId, (error, authData) => {
|
|
2138
|
+
if (error) {
|
|
2139
|
+
callback(error, authData);
|
|
2140
|
+
return;
|
|
2141
|
+
}
|
|
2142
|
+
let sharedSecret = authData['shared_secret'];
|
|
2143
|
+
if (!sharedSecret) {
|
|
2144
|
+
callback(new Error(`No shared_secret key in auth payload for encrypted channel: ${this.name}`), null);
|
|
2145
|
+
return;
|
|
2146
|
+
}
|
|
2147
|
+
this.key = (0, base64.decode)(sharedSecret);
|
|
2148
|
+
delete authData['shared_secret'];
|
|
2149
|
+
callback(null, authData);
|
|
2150
|
+
});
|
|
2151
|
+
}
|
|
2152
|
+
trigger(event, data) {
|
|
2153
|
+
throw new UnsupportedFeature('Client events are not currently supported for encrypted channels');
|
|
2154
|
+
}
|
|
2155
|
+
handleEvent(event) {
|
|
2156
|
+
var eventName = event.event;
|
|
2157
|
+
var data = event.data;
|
|
2158
|
+
if (eventName.indexOf('pusher_internal:') === 0 ||
|
|
2159
|
+
eventName.indexOf('pusher:') === 0) {
|
|
2160
|
+
super.handleEvent(event);
|
|
2161
|
+
return;
|
|
2162
|
+
}
|
|
2163
|
+
this.handleEncryptedEvent(eventName, data);
|
|
2164
|
+
}
|
|
2165
|
+
handleEncryptedEvent(event, data) {
|
|
2166
|
+
if (!this.key) {
|
|
2167
|
+
logger.debug('Received encrypted event before key has been retrieved from the authEndpoint');
|
|
2168
|
+
return;
|
|
2169
|
+
}
|
|
2170
|
+
if (!data.ciphertext || !data.nonce) {
|
|
2171
|
+
logger.error('Unexpected format for encrypted event, expected object with `ciphertext` and `nonce` fields, got: ' +
|
|
2172
|
+
data);
|
|
2173
|
+
return;
|
|
2174
|
+
}
|
|
2175
|
+
let cipherText = (0, base64.decode)(data.ciphertext);
|
|
2176
|
+
if (cipherText.length < this.nacl.secretbox.overheadLength) {
|
|
2177
|
+
logger.error(`Expected encrypted event ciphertext length to be ${this.nacl.secretbox.overheadLength}, got: ${cipherText.length}`);
|
|
2178
|
+
return;
|
|
2179
|
+
}
|
|
2180
|
+
let nonce = (0, base64.decode)(data.nonce);
|
|
2181
|
+
if (nonce.length < this.nacl.secretbox.nonceLength) {
|
|
2182
|
+
logger.error(`Expected encrypted event nonce length to be ${this.nacl.secretbox.nonceLength}, got: ${nonce.length}`);
|
|
2183
|
+
return;
|
|
2184
|
+
}
|
|
2185
|
+
let bytes = this.nacl.secretbox.open(cipherText, nonce, this.key);
|
|
2186
|
+
if (bytes === null) {
|
|
2187
|
+
logger.debug('Failed to decrypt an event, probably because it was encrypted with a different key. Fetching a new key from the authEndpoint...');
|
|
2188
|
+
this.authorize(this.pusher.connection.socket_id, (error, authData) => {
|
|
2189
|
+
if (error) {
|
|
2190
|
+
logger.error(`Failed to make a request to the authEndpoint: ${authData}. Unable to fetch new key, so dropping encrypted event`);
|
|
2191
|
+
return;
|
|
2192
|
+
}
|
|
2193
|
+
bytes = this.nacl.secretbox.open(cipherText, nonce, this.key);
|
|
2194
|
+
if (bytes === null) {
|
|
2195
|
+
logger.error(`Failed to decrypt event with new key. Dropping encrypted event`);
|
|
2196
|
+
return;
|
|
2197
|
+
}
|
|
2198
|
+
this.emit(event, this.getDataToEmit(bytes));
|
|
2199
|
+
return;
|
|
2200
|
+
});
|
|
2201
|
+
return;
|
|
2202
|
+
}
|
|
2203
|
+
this.emit(event, this.getDataToEmit(bytes));
|
|
2204
|
+
}
|
|
2205
|
+
getDataToEmit(bytes) {
|
|
2206
|
+
let raw = (0, utf8/* decode */.D4)(bytes);
|
|
2207
|
+
try {
|
|
2208
|
+
return JSON.parse(raw);
|
|
2209
|
+
}
|
|
2210
|
+
catch (_a) {
|
|
2211
|
+
return raw;
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
2215
|
+
|
|
2216
|
+
|
|
2217
|
+
|
|
2218
|
+
|
|
2219
|
+
|
|
2220
|
+
class ConnectionManager extends Dispatcher {
|
|
2221
|
+
constructor(key, options) {
|
|
2222
|
+
super();
|
|
2223
|
+
this.state = 'initialized';
|
|
2224
|
+
this.connection = null;
|
|
2225
|
+
this.key = key;
|
|
2226
|
+
this.options = options;
|
|
2227
|
+
this.timeline = this.options.timeline;
|
|
2228
|
+
this.usingTLS = this.options.useTLS;
|
|
2229
|
+
this.errorCallbacks = this.buildErrorCallbacks();
|
|
2230
|
+
this.connectionCallbacks = this.buildConnectionCallbacks(this.errorCallbacks);
|
|
2231
|
+
this.handshakeCallbacks = this.buildHandshakeCallbacks(this.errorCallbacks);
|
|
2232
|
+
var Network = runtime.getNetwork();
|
|
2233
|
+
Network.bind('online', () => {
|
|
2234
|
+
this.timeline.info({ netinfo: 'online' });
|
|
2235
|
+
if (this.state === 'connecting' || this.state === 'unavailable') {
|
|
2236
|
+
this.retryIn(0);
|
|
2237
|
+
}
|
|
2238
|
+
});
|
|
2239
|
+
Network.bind('offline', () => {
|
|
2240
|
+
this.timeline.info({ netinfo: 'offline' });
|
|
2241
|
+
if (this.connection) {
|
|
2242
|
+
this.sendActivityCheck();
|
|
2243
|
+
}
|
|
2244
|
+
});
|
|
2245
|
+
this.updateStrategy();
|
|
2246
|
+
}
|
|
2247
|
+
switchCluster(key) {
|
|
2248
|
+
this.key = key;
|
|
2249
|
+
this.updateStrategy();
|
|
2250
|
+
this.retryIn(0);
|
|
2251
|
+
}
|
|
2252
|
+
connect() {
|
|
2253
|
+
if (this.connection || this.runner) {
|
|
2254
|
+
return;
|
|
2255
|
+
}
|
|
2256
|
+
if (!this.strategy.isSupported()) {
|
|
2257
|
+
this.updateState('failed');
|
|
2258
|
+
return;
|
|
2259
|
+
}
|
|
2260
|
+
this.updateState('connecting');
|
|
2261
|
+
this.startConnecting();
|
|
2262
|
+
this.setUnavailableTimer();
|
|
2263
|
+
}
|
|
2264
|
+
send(data) {
|
|
2265
|
+
if (this.connection) {
|
|
2266
|
+
return this.connection.send(data);
|
|
2267
|
+
}
|
|
2268
|
+
else {
|
|
2269
|
+
return false;
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
send_event(name, data, channel) {
|
|
2273
|
+
if (this.connection) {
|
|
2274
|
+
return this.connection.send_event(name, data, channel);
|
|
2275
|
+
}
|
|
2276
|
+
else {
|
|
2277
|
+
return false;
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
disconnect() {
|
|
2281
|
+
this.disconnectInternally();
|
|
2282
|
+
this.updateState('disconnected');
|
|
2283
|
+
}
|
|
2284
|
+
isUsingTLS() {
|
|
2285
|
+
return this.usingTLS;
|
|
2286
|
+
}
|
|
2287
|
+
startConnecting() {
|
|
2288
|
+
var callback = (error, handshake) => {
|
|
2289
|
+
if (error) {
|
|
2290
|
+
this.runner = this.strategy.connect(0, callback);
|
|
2291
|
+
}
|
|
2292
|
+
else {
|
|
2293
|
+
if (handshake.action === 'error') {
|
|
2294
|
+
this.emit('error', {
|
|
2295
|
+
type: 'HandshakeError',
|
|
2296
|
+
error: handshake.error,
|
|
2297
|
+
});
|
|
2298
|
+
this.timeline.error({ handshakeError: handshake.error });
|
|
2299
|
+
}
|
|
2300
|
+
else {
|
|
2301
|
+
this.abortConnecting();
|
|
2302
|
+
this.handshakeCallbacks[handshake.action](handshake);
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
};
|
|
2306
|
+
this.runner = this.strategy.connect(0, callback);
|
|
2307
|
+
}
|
|
2308
|
+
abortConnecting() {
|
|
2309
|
+
if (this.runner) {
|
|
2310
|
+
this.runner.abort();
|
|
2311
|
+
this.runner = null;
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
disconnectInternally() {
|
|
2315
|
+
this.abortConnecting();
|
|
2316
|
+
this.clearRetryTimer();
|
|
2317
|
+
this.clearUnavailableTimer();
|
|
2318
|
+
if (this.connection) {
|
|
2319
|
+
var connection = this.abandonConnection();
|
|
2320
|
+
connection.close();
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
updateStrategy() {
|
|
2324
|
+
this.strategy = this.options.getStrategy({
|
|
2325
|
+
key: this.key,
|
|
2326
|
+
timeline: this.timeline,
|
|
2327
|
+
useTLS: this.usingTLS,
|
|
2328
|
+
});
|
|
2329
|
+
}
|
|
2330
|
+
retryIn(delay) {
|
|
2331
|
+
this.timeline.info({ action: 'retry', delay: delay });
|
|
2332
|
+
if (delay > 0) {
|
|
2333
|
+
this.emit('connecting_in', Math.round(delay / 1000));
|
|
2334
|
+
}
|
|
2335
|
+
this.retryTimer = new OneOffTimer(delay || 0, () => {
|
|
2336
|
+
this.disconnectInternally();
|
|
2337
|
+
this.connect();
|
|
2338
|
+
});
|
|
2339
|
+
}
|
|
2340
|
+
clearRetryTimer() {
|
|
2341
|
+
if (this.retryTimer) {
|
|
2342
|
+
this.retryTimer.ensureAborted();
|
|
2343
|
+
this.retryTimer = null;
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
setUnavailableTimer() {
|
|
2347
|
+
this.unavailableTimer = new OneOffTimer(this.options.unavailableTimeout, () => {
|
|
2348
|
+
this.updateState('unavailable');
|
|
2349
|
+
});
|
|
2350
|
+
}
|
|
2351
|
+
clearUnavailableTimer() {
|
|
2352
|
+
if (this.unavailableTimer) {
|
|
2353
|
+
this.unavailableTimer.ensureAborted();
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
sendActivityCheck() {
|
|
2357
|
+
this.stopActivityCheck();
|
|
2358
|
+
this.connection.ping();
|
|
2359
|
+
this.activityTimer = new OneOffTimer(this.options.pongTimeout, () => {
|
|
2360
|
+
this.timeline.error({ pong_timed_out: this.options.pongTimeout });
|
|
2361
|
+
this.retryIn(0);
|
|
2362
|
+
});
|
|
2363
|
+
}
|
|
2364
|
+
resetActivityCheck() {
|
|
2365
|
+
this.stopActivityCheck();
|
|
2366
|
+
if (this.connection && !this.connection.handlesActivityChecks()) {
|
|
2367
|
+
this.activityTimer = new OneOffTimer(this.activityTimeout, () => {
|
|
2368
|
+
this.sendActivityCheck();
|
|
2369
|
+
});
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
stopActivityCheck() {
|
|
2373
|
+
if (this.activityTimer) {
|
|
2374
|
+
this.activityTimer.ensureAborted();
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
buildConnectionCallbacks(errorCallbacks) {
|
|
2378
|
+
return extend({}, errorCallbacks, {
|
|
2379
|
+
message: (message) => {
|
|
2380
|
+
this.resetActivityCheck();
|
|
2381
|
+
this.emit('message', message);
|
|
2382
|
+
},
|
|
2383
|
+
ping: () => {
|
|
2384
|
+
this.send_event('pusher:pong', {});
|
|
2385
|
+
},
|
|
2386
|
+
activity: () => {
|
|
2387
|
+
this.resetActivityCheck();
|
|
2388
|
+
},
|
|
2389
|
+
error: (error) => {
|
|
2390
|
+
this.emit('error', error);
|
|
2391
|
+
},
|
|
2392
|
+
closed: () => {
|
|
2393
|
+
this.abandonConnection();
|
|
2394
|
+
if (this.shouldRetry()) {
|
|
2395
|
+
this.retryIn(1000);
|
|
2396
|
+
}
|
|
2397
|
+
},
|
|
2398
|
+
});
|
|
2399
|
+
}
|
|
2400
|
+
buildHandshakeCallbacks(errorCallbacks) {
|
|
2401
|
+
return extend({}, errorCallbacks, {
|
|
2402
|
+
connected: (handshake) => {
|
|
2403
|
+
this.activityTimeout = Math.min(this.options.activityTimeout, handshake.activityTimeout, handshake.connection.activityTimeout || Infinity);
|
|
2404
|
+
this.clearUnavailableTimer();
|
|
2405
|
+
this.setConnection(handshake.connection);
|
|
2406
|
+
this.socket_id = this.connection.id;
|
|
2407
|
+
this.updateState('connected', { socket_id: this.socket_id });
|
|
2408
|
+
},
|
|
2409
|
+
});
|
|
2410
|
+
}
|
|
2411
|
+
buildErrorCallbacks() {
|
|
2412
|
+
let withErrorEmitted = (callback) => {
|
|
2413
|
+
return (result) => {
|
|
2414
|
+
if (result.error) {
|
|
2415
|
+
this.emit('error', { type: 'WebSocketError', error: result.error });
|
|
2416
|
+
}
|
|
2417
|
+
callback(result);
|
|
2418
|
+
};
|
|
2419
|
+
};
|
|
2420
|
+
return {
|
|
2421
|
+
tls_only: withErrorEmitted(() => {
|
|
2422
|
+
this.usingTLS = true;
|
|
2423
|
+
this.updateStrategy();
|
|
2424
|
+
this.retryIn(0);
|
|
2425
|
+
}),
|
|
2426
|
+
refused: withErrorEmitted(() => {
|
|
2427
|
+
this.disconnect();
|
|
2428
|
+
}),
|
|
2429
|
+
backoff: withErrorEmitted(() => {
|
|
2430
|
+
this.retryIn(1000);
|
|
2431
|
+
}),
|
|
2432
|
+
retry: withErrorEmitted(() => {
|
|
2433
|
+
this.retryIn(0);
|
|
2434
|
+
}),
|
|
2435
|
+
};
|
|
2436
|
+
}
|
|
2437
|
+
setConnection(connection) {
|
|
2438
|
+
this.connection = connection;
|
|
2439
|
+
for (var event in this.connectionCallbacks) {
|
|
2440
|
+
this.connection.bind(event, this.connectionCallbacks[event]);
|
|
2441
|
+
}
|
|
2442
|
+
this.resetActivityCheck();
|
|
2443
|
+
}
|
|
2444
|
+
abandonConnection() {
|
|
2445
|
+
if (!this.connection) {
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
2448
|
+
this.stopActivityCheck();
|
|
2449
|
+
for (var event in this.connectionCallbacks) {
|
|
2450
|
+
this.connection.unbind(event, this.connectionCallbacks[event]);
|
|
2451
|
+
}
|
|
2452
|
+
var connection = this.connection;
|
|
2453
|
+
this.connection = null;
|
|
2454
|
+
return connection;
|
|
2455
|
+
}
|
|
2456
|
+
updateState(newState, data) {
|
|
2457
|
+
var previousState = this.state;
|
|
2458
|
+
this.state = newState;
|
|
2459
|
+
if (previousState !== newState) {
|
|
2460
|
+
var newStateDescription = newState;
|
|
2461
|
+
if (newStateDescription === 'connected') {
|
|
2462
|
+
newStateDescription += ' with new socket ID ' + data.socket_id;
|
|
2463
|
+
}
|
|
2464
|
+
logger.debug('State changed', previousState + ' -> ' + newStateDescription);
|
|
2465
|
+
this.timeline.info({ state: newState, params: data });
|
|
2466
|
+
this.emit('state_change', { previous: previousState, current: newState });
|
|
2467
|
+
this.emit(newState, data);
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
shouldRetry() {
|
|
2471
|
+
return this.state === 'connecting' || this.state === 'connected';
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
|
|
2476
|
+
|
|
2477
|
+
|
|
2478
|
+
class Channels {
|
|
2479
|
+
constructor() {
|
|
2480
|
+
this.channels = {};
|
|
2481
|
+
}
|
|
2482
|
+
add(name, pusher) {
|
|
2483
|
+
if (!this.channels[name]) {
|
|
2484
|
+
this.channels[name] = createChannel(name, pusher);
|
|
2485
|
+
}
|
|
2486
|
+
return this.channels[name];
|
|
2487
|
+
}
|
|
2488
|
+
all() {
|
|
2489
|
+
return values(this.channels);
|
|
2490
|
+
}
|
|
2491
|
+
find(name) {
|
|
2492
|
+
return this.channels[name];
|
|
2493
|
+
}
|
|
2494
|
+
remove(name) {
|
|
2495
|
+
var channel = this.channels[name];
|
|
2496
|
+
delete this.channels[name];
|
|
2497
|
+
return channel;
|
|
2498
|
+
}
|
|
2499
|
+
disconnect() {
|
|
2500
|
+
objectApply(this.channels, function (channel) {
|
|
2501
|
+
channel.disconnect();
|
|
2502
|
+
});
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
function createChannel(name, pusher) {
|
|
2506
|
+
if (name.indexOf('private-encrypted-') === 0) {
|
|
2507
|
+
if (pusher.config.nacl) {
|
|
2508
|
+
return factory.createEncryptedChannel(name, pusher, pusher.config.nacl);
|
|
2509
|
+
}
|
|
2510
|
+
let errMsg = 'Tried to subscribe to a private-encrypted- channel but no nacl implementation available';
|
|
2511
|
+
let suffix = url_store.buildLogSuffix('encryptedChannelSupport');
|
|
2512
|
+
throw new UnsupportedFeature(`${errMsg}. ${suffix}`);
|
|
2513
|
+
}
|
|
2514
|
+
else if (name.indexOf('private-') === 0) {
|
|
2515
|
+
return factory.createPrivateChannel(name, pusher);
|
|
2516
|
+
}
|
|
2517
|
+
else if (name.indexOf('presence-') === 0) {
|
|
2518
|
+
return factory.createPresenceChannel(name, pusher);
|
|
2519
|
+
}
|
|
2520
|
+
else if (name.indexOf('#') === 0) {
|
|
2521
|
+
throw new BadChannelName('Cannot create a channel with name "' + name + '".');
|
|
2522
|
+
}
|
|
2523
|
+
else {
|
|
2524
|
+
return factory.createChannel(name, pusher);
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
|
|
2529
|
+
|
|
2530
|
+
|
|
2531
|
+
|
|
2532
|
+
|
|
2533
|
+
|
|
2534
|
+
|
|
2535
|
+
|
|
2536
|
+
var Factory = {
|
|
2537
|
+
createChannels() {
|
|
2538
|
+
return new Channels();
|
|
2539
|
+
},
|
|
2540
|
+
createConnectionManager(key, options) {
|
|
2541
|
+
return new ConnectionManager(key, options);
|
|
2542
|
+
},
|
|
2543
|
+
createChannel(name, pusher) {
|
|
2544
|
+
return new Channel(name, pusher);
|
|
2545
|
+
},
|
|
2546
|
+
createPrivateChannel(name, pusher) {
|
|
2547
|
+
return new PrivateChannel(name, pusher);
|
|
2548
|
+
},
|
|
2549
|
+
createPresenceChannel(name, pusher) {
|
|
2550
|
+
return new PresenceChannel(name, pusher);
|
|
2551
|
+
},
|
|
2552
|
+
createEncryptedChannel(name, pusher, nacl) {
|
|
2553
|
+
return new EncryptedChannel(name, pusher, nacl);
|
|
2554
|
+
},
|
|
2555
|
+
createTimelineSender(timeline, options) {
|
|
2556
|
+
return new TimelineSender(timeline, options);
|
|
2557
|
+
},
|
|
2558
|
+
createHandshake(transport, callback) {
|
|
2559
|
+
return new Handshake(transport, callback);
|
|
2560
|
+
},
|
|
2561
|
+
createAssistantToTheTransportManager(manager, transport, options) {
|
|
2562
|
+
return new AssistantToTheTransportManager(manager, transport, options);
|
|
2563
|
+
},
|
|
2564
|
+
};
|
|
2565
|
+
/* harmony default export */ const factory = (Factory);
|
|
2566
|
+
|
|
2567
|
+
class TransportManager {
|
|
2568
|
+
constructor(options) {
|
|
2569
|
+
this.options = options || {};
|
|
2570
|
+
this.livesLeft = this.options.lives || Infinity;
|
|
2571
|
+
}
|
|
2572
|
+
getAssistant(transport) {
|
|
2573
|
+
return factory.createAssistantToTheTransportManager(this, transport, {
|
|
2574
|
+
minPingDelay: this.options.minPingDelay,
|
|
2575
|
+
maxPingDelay: this.options.maxPingDelay,
|
|
2576
|
+
});
|
|
2577
|
+
}
|
|
2578
|
+
isAlive() {
|
|
2579
|
+
return this.livesLeft > 0;
|
|
2580
|
+
}
|
|
2581
|
+
reportDeath() {
|
|
2582
|
+
this.livesLeft -= 1;
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
|
|
2586
|
+
|
|
2587
|
+
|
|
2588
|
+
class SequentialStrategy {
|
|
2589
|
+
constructor(strategies, options) {
|
|
2590
|
+
this.strategies = strategies;
|
|
2591
|
+
this.loop = Boolean(options.loop);
|
|
2592
|
+
this.failFast = Boolean(options.failFast);
|
|
2593
|
+
this.timeout = options.timeout;
|
|
2594
|
+
this.timeoutLimit = options.timeoutLimit;
|
|
2595
|
+
}
|
|
2596
|
+
isSupported() {
|
|
2597
|
+
return any(this.strategies, util.method('isSupported'));
|
|
2598
|
+
}
|
|
2599
|
+
connect(minPriority, callback) {
|
|
2600
|
+
var strategies = this.strategies;
|
|
2601
|
+
var current = 0;
|
|
2602
|
+
var timeout = this.timeout;
|
|
2603
|
+
var runner = null;
|
|
2604
|
+
var tryNextStrategy = (error, handshake) => {
|
|
2605
|
+
if (handshake) {
|
|
2606
|
+
callback(null, handshake);
|
|
2607
|
+
}
|
|
2608
|
+
else {
|
|
2609
|
+
current = current + 1;
|
|
2610
|
+
if (this.loop) {
|
|
2611
|
+
current = current % strategies.length;
|
|
2612
|
+
}
|
|
2613
|
+
if (current < strategies.length) {
|
|
2614
|
+
if (timeout) {
|
|
2615
|
+
timeout = timeout * 2;
|
|
2616
|
+
if (this.timeoutLimit) {
|
|
2617
|
+
timeout = Math.min(timeout, this.timeoutLimit);
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2620
|
+
runner = this.tryStrategy(strategies[current], minPriority, { timeout, failFast: this.failFast }, tryNextStrategy);
|
|
2621
|
+
}
|
|
2622
|
+
else {
|
|
2623
|
+
callback(true);
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
};
|
|
2627
|
+
runner = this.tryStrategy(strategies[current], minPriority, { timeout: timeout, failFast: this.failFast }, tryNextStrategy);
|
|
2628
|
+
return {
|
|
2629
|
+
abort: function () {
|
|
2630
|
+
runner.abort();
|
|
2631
|
+
},
|
|
2632
|
+
forceMinPriority: function (p) {
|
|
2633
|
+
minPriority = p;
|
|
2634
|
+
if (runner) {
|
|
2635
|
+
runner.forceMinPriority(p);
|
|
2636
|
+
}
|
|
2637
|
+
},
|
|
2638
|
+
};
|
|
2639
|
+
}
|
|
2640
|
+
tryStrategy(strategy, minPriority, options, callback) {
|
|
2641
|
+
var timer = null;
|
|
2642
|
+
var runner = null;
|
|
2643
|
+
if (options.timeout > 0) {
|
|
2644
|
+
timer = new OneOffTimer(options.timeout, function () {
|
|
2645
|
+
runner.abort();
|
|
2646
|
+
callback(true);
|
|
2647
|
+
});
|
|
2648
|
+
}
|
|
2649
|
+
runner = strategy.connect(minPriority, function (error, handshake) {
|
|
2650
|
+
if (error && timer && timer.isRunning() && !options.failFast) {
|
|
2651
|
+
return;
|
|
2652
|
+
}
|
|
2653
|
+
if (timer) {
|
|
2654
|
+
timer.ensureAborted();
|
|
2655
|
+
}
|
|
2656
|
+
callback(error, handshake);
|
|
2657
|
+
});
|
|
2658
|
+
return {
|
|
2659
|
+
abort: function () {
|
|
2660
|
+
if (timer) {
|
|
2661
|
+
timer.ensureAborted();
|
|
2662
|
+
}
|
|
2663
|
+
runner.abort();
|
|
2664
|
+
},
|
|
2665
|
+
forceMinPriority: function (p) {
|
|
2666
|
+
runner.forceMinPriority(p);
|
|
2667
|
+
},
|
|
2668
|
+
};
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
|
|
2672
|
+
|
|
2673
|
+
class BestConnectedEverStrategy {
|
|
2674
|
+
constructor(strategies) {
|
|
2675
|
+
this.strategies = strategies;
|
|
2676
|
+
}
|
|
2677
|
+
isSupported() {
|
|
2678
|
+
return any(this.strategies, util.method('isSupported'));
|
|
2679
|
+
}
|
|
2680
|
+
connect(minPriority, callback) {
|
|
2681
|
+
return connect(this.strategies, minPriority, function (i, runners) {
|
|
2682
|
+
return function (error, handshake) {
|
|
2683
|
+
runners[i].error = error;
|
|
2684
|
+
if (error) {
|
|
2685
|
+
if (allRunnersFailed(runners)) {
|
|
2686
|
+
callback(true);
|
|
2687
|
+
}
|
|
2688
|
+
return;
|
|
2689
|
+
}
|
|
2690
|
+
apply(runners, function (runner) {
|
|
2691
|
+
runner.forceMinPriority(handshake.transport.priority);
|
|
2692
|
+
});
|
|
2693
|
+
callback(null, handshake);
|
|
2694
|
+
};
|
|
2695
|
+
});
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
function connect(strategies, minPriority, callbackBuilder) {
|
|
2699
|
+
var runners = map(strategies, function (strategy, i, _, rs) {
|
|
2700
|
+
return strategy.connect(minPriority, callbackBuilder(i, rs));
|
|
2701
|
+
});
|
|
2702
|
+
return {
|
|
2703
|
+
abort: function () {
|
|
2704
|
+
apply(runners, abortRunner);
|
|
2705
|
+
},
|
|
2706
|
+
forceMinPriority: function (p) {
|
|
2707
|
+
apply(runners, function (runner) {
|
|
2708
|
+
runner.forceMinPriority(p);
|
|
2709
|
+
});
|
|
2710
|
+
},
|
|
2711
|
+
};
|
|
2712
|
+
}
|
|
2713
|
+
function allRunnersFailed(runners) {
|
|
2714
|
+
return collections_all(runners, function (runner) {
|
|
2715
|
+
return Boolean(runner.error);
|
|
2716
|
+
});
|
|
2717
|
+
}
|
|
2718
|
+
function abortRunner(runner) {
|
|
2719
|
+
if (!runner.error && !runner.aborted) {
|
|
2720
|
+
runner.abort();
|
|
2721
|
+
runner.aborted = true;
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
|
|
2726
|
+
|
|
2727
|
+
|
|
2728
|
+
class WebSocketPrioritizedCachedStrategy {
|
|
2729
|
+
constructor(strategy, transports, options) {
|
|
2730
|
+
this.strategy = strategy;
|
|
2731
|
+
this.transports = transports;
|
|
2732
|
+
this.ttl = options.ttl || 1800 * 1000;
|
|
2733
|
+
this.usingTLS = options.useTLS;
|
|
2734
|
+
this.timeline = options.timeline;
|
|
2735
|
+
}
|
|
2736
|
+
isSupported() {
|
|
2737
|
+
return this.strategy.isSupported();
|
|
2738
|
+
}
|
|
2739
|
+
connect(minPriority, callback) {
|
|
2740
|
+
var usingTLS = this.usingTLS;
|
|
2741
|
+
var info = fetchTransportCache(usingTLS);
|
|
2742
|
+
var cacheSkipCount = info && info.cacheSkipCount ? info.cacheSkipCount : 0;
|
|
2743
|
+
var strategies = [this.strategy];
|
|
2744
|
+
if (info && info.timestamp + this.ttl >= util.now()) {
|
|
2745
|
+
var transport = this.transports[info.transport];
|
|
2746
|
+
if (transport) {
|
|
2747
|
+
if (['ws', 'wss'].includes(info.transport) || cacheSkipCount > 3) {
|
|
2748
|
+
this.timeline.info({
|
|
2749
|
+
cached: true,
|
|
2750
|
+
transport: info.transport,
|
|
2751
|
+
latency: info.latency,
|
|
2752
|
+
});
|
|
2753
|
+
strategies.push(new SequentialStrategy([transport], {
|
|
2754
|
+
timeout: info.latency * 2 + 1000,
|
|
2755
|
+
failFast: true,
|
|
2756
|
+
}));
|
|
2757
|
+
}
|
|
2758
|
+
else {
|
|
2759
|
+
cacheSkipCount++;
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
var startTimestamp = util.now();
|
|
2764
|
+
var runner = strategies
|
|
2765
|
+
.pop()
|
|
2766
|
+
.connect(minPriority, function cb(error, handshake) {
|
|
2767
|
+
if (error) {
|
|
2768
|
+
flushTransportCache(usingTLS);
|
|
2769
|
+
if (strategies.length > 0) {
|
|
2770
|
+
startTimestamp = util.now();
|
|
2771
|
+
runner = strategies.pop().connect(minPriority, cb);
|
|
2772
|
+
}
|
|
2773
|
+
else {
|
|
2774
|
+
callback(error);
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
else {
|
|
2778
|
+
storeTransportCache(usingTLS, handshake.transport.name, util.now() - startTimestamp, cacheSkipCount);
|
|
2779
|
+
callback(null, handshake);
|
|
2780
|
+
}
|
|
2781
|
+
});
|
|
2782
|
+
return {
|
|
2783
|
+
abort: function () {
|
|
2784
|
+
runner.abort();
|
|
2785
|
+
},
|
|
2786
|
+
forceMinPriority: function (p) {
|
|
2787
|
+
minPriority = p;
|
|
2788
|
+
if (runner) {
|
|
2789
|
+
runner.forceMinPriority(p);
|
|
2790
|
+
}
|
|
2791
|
+
},
|
|
2792
|
+
};
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
function getTransportCacheKey(usingTLS) {
|
|
2796
|
+
return 'pusherTransport' + (usingTLS ? 'TLS' : 'NonTLS');
|
|
2797
|
+
}
|
|
2798
|
+
function fetchTransportCache(usingTLS) {
|
|
2799
|
+
var storage = runtime.getLocalStorage();
|
|
2800
|
+
if (storage) {
|
|
2801
|
+
try {
|
|
2802
|
+
var serializedCache = storage[getTransportCacheKey(usingTLS)];
|
|
2803
|
+
if (serializedCache) {
|
|
2804
|
+
return JSON.parse(serializedCache);
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
catch (e) {
|
|
2808
|
+
flushTransportCache(usingTLS);
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2811
|
+
return null;
|
|
2812
|
+
}
|
|
2813
|
+
function storeTransportCache(usingTLS, transport, latency, cacheSkipCount) {
|
|
2814
|
+
var storage = runtime.getLocalStorage();
|
|
2815
|
+
if (storage) {
|
|
2816
|
+
try {
|
|
2817
|
+
storage[getTransportCacheKey(usingTLS)] = safeJSONStringify({
|
|
2818
|
+
timestamp: util.now(),
|
|
2819
|
+
transport: transport,
|
|
2820
|
+
latency: latency,
|
|
2821
|
+
cacheSkipCount: cacheSkipCount,
|
|
2822
|
+
});
|
|
2823
|
+
}
|
|
2824
|
+
catch (e) {
|
|
2825
|
+
}
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
function flushTransportCache(usingTLS) {
|
|
2829
|
+
var storage = runtime.getLocalStorage();
|
|
2830
|
+
if (storage) {
|
|
2831
|
+
try {
|
|
2832
|
+
delete storage[getTransportCacheKey(usingTLS)];
|
|
2833
|
+
}
|
|
2834
|
+
catch (e) {
|
|
2835
|
+
}
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
|
|
2839
|
+
class DelayedStrategy {
|
|
2840
|
+
constructor(strategy, { delay: number }) {
|
|
2841
|
+
this.strategy = strategy;
|
|
2842
|
+
this.options = { delay: number };
|
|
2843
|
+
}
|
|
2844
|
+
isSupported() {
|
|
2845
|
+
return this.strategy.isSupported();
|
|
2846
|
+
}
|
|
2847
|
+
connect(minPriority, callback) {
|
|
2848
|
+
var strategy = this.strategy;
|
|
2849
|
+
var runner;
|
|
2850
|
+
var timer = new OneOffTimer(this.options.delay, function () {
|
|
2851
|
+
runner = strategy.connect(minPriority, callback);
|
|
2852
|
+
});
|
|
2853
|
+
return {
|
|
2854
|
+
abort: function () {
|
|
2855
|
+
timer.ensureAborted();
|
|
2856
|
+
if (runner) {
|
|
2857
|
+
runner.abort();
|
|
2858
|
+
}
|
|
2859
|
+
},
|
|
2860
|
+
forceMinPriority: function (p) {
|
|
2861
|
+
minPriority = p;
|
|
2862
|
+
if (runner) {
|
|
2863
|
+
runner.forceMinPriority(p);
|
|
2864
|
+
}
|
|
2865
|
+
},
|
|
2866
|
+
};
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
class IfStrategy {
|
|
2870
|
+
constructor(test, trueBranch, falseBranch) {
|
|
2871
|
+
this.test = test;
|
|
2872
|
+
this.trueBranch = trueBranch;
|
|
2873
|
+
this.falseBranch = falseBranch;
|
|
2874
|
+
}
|
|
2875
|
+
isSupported() {
|
|
2876
|
+
var branch = this.test() ? this.trueBranch : this.falseBranch;
|
|
2877
|
+
return branch.isSupported();
|
|
2878
|
+
}
|
|
2879
|
+
connect(minPriority, callback) {
|
|
2880
|
+
var branch = this.test() ? this.trueBranch : this.falseBranch;
|
|
2881
|
+
return branch.connect(minPriority, callback);
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
class FirstConnectedStrategy {
|
|
2885
|
+
constructor(strategy) {
|
|
2886
|
+
this.strategy = strategy;
|
|
2887
|
+
}
|
|
2888
|
+
isSupported() {
|
|
2889
|
+
return this.strategy.isSupported();
|
|
2890
|
+
}
|
|
2891
|
+
connect(minPriority, callback) {
|
|
2892
|
+
var runner = this.strategy.connect(minPriority, function (error, handshake) {
|
|
2893
|
+
if (handshake) {
|
|
2894
|
+
runner.abort();
|
|
2895
|
+
}
|
|
2896
|
+
callback(error, handshake);
|
|
2897
|
+
});
|
|
2898
|
+
return runner;
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2902
|
+
|
|
2903
|
+
|
|
2904
|
+
|
|
2905
|
+
|
|
2906
|
+
|
|
2907
|
+
|
|
2908
|
+
function testSupportsStrategy(strategy) {
|
|
2909
|
+
return function () {
|
|
2910
|
+
return strategy.isSupported();
|
|
2911
|
+
};
|
|
2912
|
+
}
|
|
2913
|
+
var getDefaultStrategy = function (config, baseOptions, defineTransport) {
|
|
2914
|
+
var definedTransports = {};
|
|
2915
|
+
function defineTransportStrategy(name, type, priority, options, manager) {
|
|
2916
|
+
var transport = defineTransport(config, name, type, priority, options, manager);
|
|
2917
|
+
definedTransports[name] = transport;
|
|
2918
|
+
return transport;
|
|
2919
|
+
}
|
|
2920
|
+
var ws_options = Object.assign({}, baseOptions, {
|
|
2921
|
+
hostNonTLS: config.wsHost + ':' + config.wsPort,
|
|
2922
|
+
hostTLS: config.wsHost + ':' + config.wssPort,
|
|
2923
|
+
httpPath: config.wsPath,
|
|
2924
|
+
});
|
|
2925
|
+
var wss_options = Object.assign({}, ws_options, {
|
|
2926
|
+
useTLS: true,
|
|
2927
|
+
});
|
|
2928
|
+
var sockjs_options = Object.assign({}, baseOptions, {
|
|
2929
|
+
hostNonTLS: config.httpHost + ':' + config.httpPort,
|
|
2930
|
+
hostTLS: config.httpHost + ':' + config.httpsPort,
|
|
2931
|
+
httpPath: config.httpPath,
|
|
2932
|
+
});
|
|
2933
|
+
var timeouts = {
|
|
2934
|
+
loop: true,
|
|
2935
|
+
timeout: 15000,
|
|
2936
|
+
timeoutLimit: 60000,
|
|
2937
|
+
};
|
|
2938
|
+
var ws_manager = new TransportManager({
|
|
2939
|
+
minPingDelay: 10000,
|
|
2940
|
+
maxPingDelay: config.activityTimeout,
|
|
2941
|
+
});
|
|
2942
|
+
var streaming_manager = new TransportManager({
|
|
2943
|
+
lives: 2,
|
|
2944
|
+
minPingDelay: 10000,
|
|
2945
|
+
maxPingDelay: config.activityTimeout,
|
|
2946
|
+
});
|
|
2947
|
+
var ws_transport = defineTransportStrategy('ws', 'ws', 3, ws_options, ws_manager);
|
|
2948
|
+
var wss_transport = defineTransportStrategy('wss', 'ws', 3, wss_options, ws_manager);
|
|
2949
|
+
var sockjs_transport = defineTransportStrategy('sockjs', 'sockjs', 1, sockjs_options);
|
|
2950
|
+
var xhr_streaming_transport = defineTransportStrategy('xhr_streaming', 'xhr_streaming', 1, sockjs_options, streaming_manager);
|
|
2951
|
+
var xdr_streaming_transport = defineTransportStrategy('xdr_streaming', 'xdr_streaming', 1, sockjs_options, streaming_manager);
|
|
2952
|
+
var xhr_polling_transport = defineTransportStrategy('xhr_polling', 'xhr_polling', 1, sockjs_options);
|
|
2953
|
+
var xdr_polling_transport = defineTransportStrategy('xdr_polling', 'xdr_polling', 1, sockjs_options);
|
|
2954
|
+
var ws_loop = new SequentialStrategy([ws_transport], timeouts);
|
|
2955
|
+
var wss_loop = new SequentialStrategy([wss_transport], timeouts);
|
|
2956
|
+
var sockjs_loop = new SequentialStrategy([sockjs_transport], timeouts);
|
|
2957
|
+
var streaming_loop = new SequentialStrategy([
|
|
2958
|
+
new IfStrategy(testSupportsStrategy(xhr_streaming_transport), xhr_streaming_transport, xdr_streaming_transport),
|
|
2959
|
+
], timeouts);
|
|
2960
|
+
var polling_loop = new SequentialStrategy([
|
|
2961
|
+
new IfStrategy(testSupportsStrategy(xhr_polling_transport), xhr_polling_transport, xdr_polling_transport),
|
|
2962
|
+
], timeouts);
|
|
2963
|
+
var http_loop = new SequentialStrategy([
|
|
2964
|
+
new IfStrategy(testSupportsStrategy(streaming_loop), new BestConnectedEverStrategy([
|
|
2965
|
+
streaming_loop,
|
|
2966
|
+
new DelayedStrategy(polling_loop, { delay: 4000 }),
|
|
2967
|
+
]), polling_loop),
|
|
2968
|
+
], timeouts);
|
|
2969
|
+
var http_fallback_loop = new IfStrategy(testSupportsStrategy(http_loop), http_loop, sockjs_loop);
|
|
2970
|
+
var wsStrategy;
|
|
2971
|
+
if (baseOptions.useTLS) {
|
|
2972
|
+
wsStrategy = new BestConnectedEverStrategy([
|
|
2973
|
+
ws_loop,
|
|
2974
|
+
new DelayedStrategy(http_fallback_loop, { delay: 2000 }),
|
|
2975
|
+
]);
|
|
2976
|
+
}
|
|
2977
|
+
else {
|
|
2978
|
+
wsStrategy = new BestConnectedEverStrategy([
|
|
2979
|
+
ws_loop,
|
|
2980
|
+
new DelayedStrategy(wss_loop, { delay: 2000 }),
|
|
2981
|
+
new DelayedStrategy(http_fallback_loop, { delay: 5000 }),
|
|
2982
|
+
]);
|
|
2983
|
+
}
|
|
2984
|
+
return new WebSocketPrioritizedCachedStrategy(new FirstConnectedStrategy(new IfStrategy(testSupportsStrategy(ws_transport), wsStrategy, http_fallback_loop)), definedTransports, {
|
|
2985
|
+
ttl: 1800000,
|
|
2986
|
+
timeline: baseOptions.timeline,
|
|
2987
|
+
useTLS: baseOptions.useTLS,
|
|
2988
|
+
});
|
|
2989
|
+
};
|
|
2990
|
+
/* harmony default export */ const default_strategy = (getDefaultStrategy);
|
|
2991
|
+
|
|
2992
|
+
/* harmony default export */ function transport_connection_initializer() {
|
|
2993
|
+
var self = this;
|
|
2994
|
+
self.timeline.info(self.buildTimelineMessage({
|
|
2995
|
+
transport: self.name + (self.options.useTLS ? 's' : ''),
|
|
2996
|
+
}));
|
|
2997
|
+
if (self.hooks.isInitialized()) {
|
|
2998
|
+
self.changeState('initialized');
|
|
2999
|
+
}
|
|
3000
|
+
else if (self.hooks.file) {
|
|
3001
|
+
self.changeState('initializing');
|
|
3002
|
+
Dependencies.load(self.hooks.file, { useTLS: self.options.useTLS }, function (error, callback) {
|
|
3003
|
+
if (self.hooks.isInitialized()) {
|
|
3004
|
+
self.changeState('initialized');
|
|
3005
|
+
callback(true);
|
|
3006
|
+
}
|
|
3007
|
+
else {
|
|
3008
|
+
if (error) {
|
|
3009
|
+
self.onError(error);
|
|
3010
|
+
}
|
|
3011
|
+
self.onClose();
|
|
3012
|
+
callback(false);
|
|
3013
|
+
}
|
|
3014
|
+
});
|
|
3015
|
+
}
|
|
3016
|
+
else {
|
|
3017
|
+
self.onClose();
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
|
|
3021
|
+
var hooks = {
|
|
3022
|
+
getRequest: function (socket) {
|
|
3023
|
+
var xdr = new window.XDomainRequest();
|
|
3024
|
+
xdr.ontimeout = function () {
|
|
3025
|
+
socket.emit('error', new RequestTimedOut());
|
|
3026
|
+
socket.close();
|
|
3027
|
+
};
|
|
3028
|
+
xdr.onerror = function (e) {
|
|
3029
|
+
socket.emit('error', e);
|
|
3030
|
+
socket.close();
|
|
3031
|
+
};
|
|
3032
|
+
xdr.onprogress = function () {
|
|
3033
|
+
if (xdr.responseText && xdr.responseText.length > 0) {
|
|
3034
|
+
socket.onChunk(200, xdr.responseText);
|
|
3035
|
+
}
|
|
3036
|
+
};
|
|
3037
|
+
xdr.onload = function () {
|
|
3038
|
+
if (xdr.responseText && xdr.responseText.length > 0) {
|
|
3039
|
+
socket.onChunk(200, xdr.responseText);
|
|
3040
|
+
}
|
|
3041
|
+
socket.emit('finished', 200);
|
|
3042
|
+
socket.close();
|
|
3043
|
+
};
|
|
3044
|
+
return xdr;
|
|
3045
|
+
},
|
|
3046
|
+
abortRequest: function (xdr) {
|
|
3047
|
+
xdr.ontimeout = xdr.onerror = xdr.onprogress = xdr.onload = null;
|
|
3048
|
+
xdr.abort();
|
|
3049
|
+
},
|
|
3050
|
+
};
|
|
3051
|
+
/* harmony default export */ const http_xdomain_request = (hooks);
|
|
3052
|
+
|
|
3053
|
+
|
|
3054
|
+
const MAX_BUFFER_LENGTH = 256 * 1024;
|
|
3055
|
+
class HTTPRequest extends Dispatcher {
|
|
3056
|
+
constructor(hooks, method, url) {
|
|
3057
|
+
super();
|
|
3058
|
+
this.hooks = hooks;
|
|
3059
|
+
this.method = method;
|
|
3060
|
+
this.url = url;
|
|
3061
|
+
}
|
|
3062
|
+
start(payload) {
|
|
3063
|
+
this.position = 0;
|
|
3064
|
+
this.xhr = this.hooks.getRequest(this);
|
|
3065
|
+
this.unloader = () => {
|
|
3066
|
+
this.close();
|
|
3067
|
+
};
|
|
3068
|
+
runtime.addUnloadListener(this.unloader);
|
|
3069
|
+
this.xhr.open(this.method, this.url, true);
|
|
3070
|
+
if (this.xhr.setRequestHeader) {
|
|
3071
|
+
this.xhr.setRequestHeader('Content-Type', 'application/json');
|
|
3072
|
+
}
|
|
3073
|
+
this.xhr.send(payload);
|
|
3074
|
+
}
|
|
3075
|
+
close() {
|
|
3076
|
+
if (this.unloader) {
|
|
3077
|
+
runtime.removeUnloadListener(this.unloader);
|
|
3078
|
+
this.unloader = null;
|
|
3079
|
+
}
|
|
3080
|
+
if (this.xhr) {
|
|
3081
|
+
this.hooks.abortRequest(this.xhr);
|
|
3082
|
+
this.xhr = null;
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
onChunk(status, data) {
|
|
3086
|
+
while (true) {
|
|
3087
|
+
var chunk = this.advanceBuffer(data);
|
|
3088
|
+
if (chunk) {
|
|
3089
|
+
this.emit('chunk', { status: status, data: chunk });
|
|
3090
|
+
}
|
|
3091
|
+
else {
|
|
3092
|
+
break;
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
if (this.isBufferTooLong(data)) {
|
|
3096
|
+
this.emit('buffer_too_long');
|
|
3097
|
+
}
|
|
3098
|
+
}
|
|
3099
|
+
advanceBuffer(buffer) {
|
|
3100
|
+
var unreadData = buffer.slice(this.position);
|
|
3101
|
+
var endOfLinePosition = unreadData.indexOf('\n');
|
|
3102
|
+
if (endOfLinePosition !== -1) {
|
|
3103
|
+
this.position += endOfLinePosition + 1;
|
|
3104
|
+
return unreadData.slice(0, endOfLinePosition);
|
|
3105
|
+
}
|
|
3106
|
+
else {
|
|
3107
|
+
return null;
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3110
|
+
isBufferTooLong(buffer) {
|
|
3111
|
+
return this.position === buffer.length && buffer.length > MAX_BUFFER_LENGTH;
|
|
3112
|
+
}
|
|
3113
|
+
}
|
|
3114
|
+
var State;
|
|
3115
|
+
(function (State) {
|
|
3116
|
+
State[State["CONNECTING"] = 0] = "CONNECTING";
|
|
3117
|
+
State[State["OPEN"] = 1] = "OPEN";
|
|
3118
|
+
State[State["CLOSED"] = 3] = "CLOSED";
|
|
3119
|
+
})(State || (State = {}));
|
|
3120
|
+
/* harmony default export */ const state = (State);
|
|
3121
|
+
|
|
3122
|
+
|
|
3123
|
+
|
|
3124
|
+
var autoIncrement = 1;
|
|
3125
|
+
class HTTPSocket {
|
|
3126
|
+
constructor(hooks, url) {
|
|
3127
|
+
this.hooks = hooks;
|
|
3128
|
+
this.session = randomNumber(1000) + '/' + randomString(8);
|
|
3129
|
+
this.location = getLocation(url);
|
|
3130
|
+
this.readyState = state.CONNECTING;
|
|
3131
|
+
this.openStream();
|
|
3132
|
+
}
|
|
3133
|
+
send(payload) {
|
|
3134
|
+
return this.sendRaw(JSON.stringify([payload]));
|
|
3135
|
+
}
|
|
3136
|
+
ping() {
|
|
3137
|
+
this.hooks.sendHeartbeat(this);
|
|
3138
|
+
}
|
|
3139
|
+
close(code, reason) {
|
|
3140
|
+
this.onClose(code, reason, true);
|
|
3141
|
+
}
|
|
3142
|
+
sendRaw(payload) {
|
|
3143
|
+
if (this.readyState === state.OPEN) {
|
|
3144
|
+
try {
|
|
3145
|
+
runtime.createSocketRequest('POST', getUniqueURL(getSendURL(this.location, this.session))).start(payload);
|
|
3146
|
+
return true;
|
|
3147
|
+
}
|
|
3148
|
+
catch (e) {
|
|
3149
|
+
return false;
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
else {
|
|
3153
|
+
return false;
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
reconnect() {
|
|
3157
|
+
this.closeStream();
|
|
3158
|
+
this.openStream();
|
|
3159
|
+
}
|
|
3160
|
+
onClose(code, reason, wasClean) {
|
|
3161
|
+
this.closeStream();
|
|
3162
|
+
this.readyState = state.CLOSED;
|
|
3163
|
+
if (this.onclose) {
|
|
3164
|
+
this.onclose({
|
|
3165
|
+
code: code,
|
|
3166
|
+
reason: reason,
|
|
3167
|
+
wasClean: wasClean,
|
|
3168
|
+
});
|
|
3169
|
+
}
|
|
3170
|
+
}
|
|
3171
|
+
onChunk(chunk) {
|
|
3172
|
+
if (chunk.status !== 200) {
|
|
3173
|
+
return;
|
|
3174
|
+
}
|
|
3175
|
+
if (this.readyState === state.OPEN) {
|
|
3176
|
+
this.onActivity();
|
|
3177
|
+
}
|
|
3178
|
+
var payload;
|
|
3179
|
+
var type = chunk.data.slice(0, 1);
|
|
3180
|
+
switch (type) {
|
|
3181
|
+
case 'o':
|
|
3182
|
+
payload = JSON.parse(chunk.data.slice(1) || '{}');
|
|
3183
|
+
this.onOpen(payload);
|
|
3184
|
+
break;
|
|
3185
|
+
case 'a':
|
|
3186
|
+
payload = JSON.parse(chunk.data.slice(1) || '[]');
|
|
3187
|
+
for (var i = 0; i < payload.length; i++) {
|
|
3188
|
+
this.onEvent(payload[i]);
|
|
3189
|
+
}
|
|
3190
|
+
break;
|
|
3191
|
+
case 'm':
|
|
3192
|
+
payload = JSON.parse(chunk.data.slice(1) || 'null');
|
|
3193
|
+
this.onEvent(payload);
|
|
3194
|
+
break;
|
|
3195
|
+
case 'h':
|
|
3196
|
+
this.hooks.onHeartbeat(this);
|
|
3197
|
+
break;
|
|
3198
|
+
case 'c':
|
|
3199
|
+
payload = JSON.parse(chunk.data.slice(1) || '[]');
|
|
3200
|
+
this.onClose(payload[0], payload[1], true);
|
|
3201
|
+
break;
|
|
3202
|
+
}
|
|
3203
|
+
}
|
|
3204
|
+
onOpen(options) {
|
|
3205
|
+
if (this.readyState === state.CONNECTING) {
|
|
3206
|
+
if (options && options.hostname) {
|
|
3207
|
+
this.location.base = replaceHost(this.location.base, options.hostname);
|
|
3208
|
+
}
|
|
3209
|
+
this.readyState = state.OPEN;
|
|
3210
|
+
if (this.onopen) {
|
|
3211
|
+
this.onopen();
|
|
3212
|
+
}
|
|
3213
|
+
}
|
|
3214
|
+
else {
|
|
3215
|
+
this.onClose(1006, 'Server lost session', true);
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
onEvent(event) {
|
|
3219
|
+
if (this.readyState === state.OPEN && this.onmessage) {
|
|
3220
|
+
this.onmessage({ data: event });
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
3223
|
+
onActivity() {
|
|
3224
|
+
if (this.onactivity) {
|
|
3225
|
+
this.onactivity();
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
onError(error) {
|
|
3229
|
+
if (this.onerror) {
|
|
3230
|
+
this.onerror(error);
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3233
|
+
openStream() {
|
|
3234
|
+
this.stream = runtime.createSocketRequest('POST', getUniqueURL(this.hooks.getReceiveURL(this.location, this.session)));
|
|
3235
|
+
this.stream.bind('chunk', (chunk) => {
|
|
3236
|
+
this.onChunk(chunk);
|
|
3237
|
+
});
|
|
3238
|
+
this.stream.bind('finished', (status) => {
|
|
3239
|
+
this.hooks.onFinished(this, status);
|
|
3240
|
+
});
|
|
3241
|
+
this.stream.bind('buffer_too_long', () => {
|
|
3242
|
+
this.reconnect();
|
|
3243
|
+
});
|
|
3244
|
+
try {
|
|
3245
|
+
this.stream.start();
|
|
3246
|
+
}
|
|
3247
|
+
catch (error) {
|
|
3248
|
+
util.defer(() => {
|
|
3249
|
+
this.onError(error);
|
|
3250
|
+
this.onClose(1006, 'Could not start streaming', false);
|
|
3251
|
+
});
|
|
3252
|
+
}
|
|
3253
|
+
}
|
|
3254
|
+
closeStream() {
|
|
3255
|
+
if (this.stream) {
|
|
3256
|
+
this.stream.unbind_all();
|
|
3257
|
+
this.stream.close();
|
|
3258
|
+
this.stream = null;
|
|
3259
|
+
}
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
function getLocation(url) {
|
|
3263
|
+
var parts = /([^\?]*)\/*(\??.*)/.exec(url);
|
|
3264
|
+
return {
|
|
3265
|
+
base: parts[1],
|
|
3266
|
+
queryString: parts[2],
|
|
3267
|
+
};
|
|
3268
|
+
}
|
|
3269
|
+
function getSendURL(url, session) {
|
|
3270
|
+
return url.base + '/' + session + '/xhr_send';
|
|
3271
|
+
}
|
|
3272
|
+
function getUniqueURL(url) {
|
|
3273
|
+
var separator = url.indexOf('?') === -1 ? '?' : '&';
|
|
3274
|
+
return url + separator + 't=' + +new Date() + '&n=' + autoIncrement++;
|
|
3275
|
+
}
|
|
3276
|
+
function replaceHost(url, hostname) {
|
|
3277
|
+
var urlParts = /(https?:\/\/)([^\/:]+)((\/|:)?.*)/.exec(url);
|
|
3278
|
+
return urlParts[1] + hostname + urlParts[3];
|
|
3279
|
+
}
|
|
3280
|
+
function randomNumber(max) {
|
|
3281
|
+
return runtime.randomInt(max);
|
|
3282
|
+
}
|
|
3283
|
+
function randomString(length) {
|
|
3284
|
+
var result = [];
|
|
3285
|
+
for (var i = 0; i < length; i++) {
|
|
3286
|
+
result.push(randomNumber(32).toString(32));
|
|
3287
|
+
}
|
|
3288
|
+
return result.join('');
|
|
3289
|
+
}
|
|
3290
|
+
/* harmony default export */ const http_socket = (HTTPSocket);
|
|
3291
|
+
var http_streaming_socket_hooks = {
|
|
3292
|
+
getReceiveURL: function (url, session) {
|
|
3293
|
+
return url.base + '/' + session + '/xhr_streaming' + url.queryString;
|
|
3294
|
+
},
|
|
3295
|
+
onHeartbeat: function (socket) {
|
|
3296
|
+
socket.sendRaw('[]');
|
|
3297
|
+
},
|
|
3298
|
+
sendHeartbeat: function (socket) {
|
|
3299
|
+
socket.sendRaw('[]');
|
|
3300
|
+
},
|
|
3301
|
+
onFinished: function (socket, status) {
|
|
3302
|
+
socket.onClose(1006, 'Connection interrupted (' + status + ')', false);
|
|
3303
|
+
},
|
|
3304
|
+
};
|
|
3305
|
+
/* harmony default export */ const http_streaming_socket = (http_streaming_socket_hooks);
|
|
3306
|
+
var http_polling_socket_hooks = {
|
|
3307
|
+
getReceiveURL: function (url, session) {
|
|
3308
|
+
return url.base + '/' + session + '/xhr' + url.queryString;
|
|
3309
|
+
},
|
|
3310
|
+
onHeartbeat: function () {
|
|
3311
|
+
},
|
|
3312
|
+
sendHeartbeat: function (socket) {
|
|
3313
|
+
socket.sendRaw('[]');
|
|
3314
|
+
},
|
|
3315
|
+
onFinished: function (socket, status) {
|
|
3316
|
+
if (status === 200) {
|
|
3317
|
+
socket.reconnect();
|
|
3318
|
+
}
|
|
3319
|
+
else {
|
|
3320
|
+
socket.onClose(1006, 'Connection interrupted (' + status + ')', false);
|
|
3321
|
+
}
|
|
3322
|
+
},
|
|
3323
|
+
};
|
|
3324
|
+
/* harmony default export */ const http_polling_socket = (http_polling_socket_hooks);
|
|
3325
|
+
|
|
3326
|
+
var http_xhr_request_hooks = {
|
|
3327
|
+
getRequest: function (socket) {
|
|
3328
|
+
var Constructor = runtime.getXHRAPI();
|
|
3329
|
+
var xhr = new Constructor();
|
|
3330
|
+
xhr.onreadystatechange = xhr.onprogress = function () {
|
|
3331
|
+
switch (xhr.readyState) {
|
|
3332
|
+
case 3:
|
|
3333
|
+
if (xhr.responseText && xhr.responseText.length > 0) {
|
|
3334
|
+
socket.onChunk(xhr.status, xhr.responseText);
|
|
3335
|
+
}
|
|
3336
|
+
break;
|
|
3337
|
+
case 4:
|
|
3338
|
+
if (xhr.responseText && xhr.responseText.length > 0) {
|
|
3339
|
+
socket.onChunk(xhr.status, xhr.responseText);
|
|
3340
|
+
}
|
|
3341
|
+
socket.emit('finished', xhr.status);
|
|
3342
|
+
socket.close();
|
|
3343
|
+
break;
|
|
3344
|
+
}
|
|
3345
|
+
};
|
|
3346
|
+
return xhr;
|
|
3347
|
+
},
|
|
3348
|
+
abortRequest: function (xhr) {
|
|
3349
|
+
xhr.onreadystatechange = null;
|
|
3350
|
+
xhr.abort();
|
|
3351
|
+
},
|
|
3352
|
+
};
|
|
3353
|
+
/* harmony default export */ const http_xhr_request = (http_xhr_request_hooks);
|
|
3354
|
+
|
|
3355
|
+
|
|
3356
|
+
|
|
3357
|
+
|
|
3358
|
+
|
|
3359
|
+
var HTTP = {
|
|
3360
|
+
createStreamingSocket(url) {
|
|
3361
|
+
return this.createSocket(http_streaming_socket, url);
|
|
3362
|
+
},
|
|
3363
|
+
createPollingSocket(url) {
|
|
3364
|
+
return this.createSocket(http_polling_socket, url);
|
|
3365
|
+
},
|
|
3366
|
+
createSocket(hooks, url) {
|
|
3367
|
+
return new http_socket(hooks, url);
|
|
3368
|
+
},
|
|
3369
|
+
createXHR(method, url) {
|
|
3370
|
+
return this.createRequest(http_xhr_request, method, url);
|
|
3371
|
+
},
|
|
3372
|
+
createRequest(hooks, method, url) {
|
|
3373
|
+
return new HTTPRequest(hooks, method, url);
|
|
3374
|
+
},
|
|
3375
|
+
};
|
|
3376
|
+
/* harmony default export */ const http_http = (HTTP);
|
|
3377
|
+
|
|
3378
|
+
|
|
3379
|
+
http_http.createXDR = function (method, url) {
|
|
3380
|
+
return this.createRequest(http_xdomain_request, method, url);
|
|
3381
|
+
};
|
|
3382
|
+
/* harmony default export */ const web_http_http = (http_http);
|
|
3383
|
+
|
|
3384
|
+
|
|
3385
|
+
|
|
3386
|
+
|
|
3387
|
+
|
|
3388
|
+
|
|
3389
|
+
|
|
3390
|
+
|
|
3391
|
+
|
|
3392
|
+
|
|
3393
|
+
|
|
3394
|
+
|
|
3395
|
+
var Runtime = {
|
|
3396
|
+
nextAuthCallbackID: 1,
|
|
3397
|
+
auth_callbacks: {},
|
|
3398
|
+
ScriptReceivers: ScriptReceivers,
|
|
3399
|
+
DependenciesReceivers: DependenciesReceivers,
|
|
3400
|
+
getDefaultStrategy: default_strategy,
|
|
3401
|
+
Transports: transports_transports,
|
|
3402
|
+
transportConnectionInitializer: transport_connection_initializer,
|
|
3403
|
+
HTTPFactory: web_http_http,
|
|
3404
|
+
TimelineTransport: jsonp_timeline,
|
|
3405
|
+
getXHRAPI() {
|
|
3406
|
+
return window.XMLHttpRequest;
|
|
3407
|
+
},
|
|
3408
|
+
getWebSocketAPI() {
|
|
3409
|
+
return window.WebSocket || window.MozWebSocket;
|
|
3410
|
+
},
|
|
3411
|
+
setup(PusherClass) {
|
|
3412
|
+
window.Pusher = PusherClass;
|
|
3413
|
+
var initializeOnDocumentBody = () => {
|
|
3414
|
+
this.onDocumentBody(PusherClass.ready);
|
|
3415
|
+
};
|
|
3416
|
+
if (!window.JSON) {
|
|
3417
|
+
Dependencies.load('json2', {}, initializeOnDocumentBody);
|
|
3418
|
+
}
|
|
3419
|
+
else {
|
|
3420
|
+
initializeOnDocumentBody();
|
|
3421
|
+
}
|
|
3422
|
+
},
|
|
3423
|
+
getDocument() {
|
|
3424
|
+
return document;
|
|
3425
|
+
},
|
|
3426
|
+
getProtocol() {
|
|
3427
|
+
return this.getDocument().location.protocol;
|
|
3428
|
+
},
|
|
3429
|
+
getAuthorizers() {
|
|
3430
|
+
return { ajax: xhr_auth, jsonp: jsonp_auth };
|
|
3431
|
+
},
|
|
3432
|
+
onDocumentBody(callback) {
|
|
3433
|
+
if (document.body) {
|
|
3434
|
+
callback();
|
|
3435
|
+
}
|
|
3436
|
+
else {
|
|
3437
|
+
setTimeout(() => {
|
|
3438
|
+
this.onDocumentBody(callback);
|
|
3439
|
+
}, 0);
|
|
3440
|
+
}
|
|
3441
|
+
},
|
|
3442
|
+
createJSONPRequest(url, data) {
|
|
3443
|
+
return new JSONPRequest(url, data);
|
|
3444
|
+
},
|
|
3445
|
+
createScriptRequest(src) {
|
|
3446
|
+
return new ScriptRequest(src);
|
|
3447
|
+
},
|
|
3448
|
+
getLocalStorage() {
|
|
3449
|
+
try {
|
|
3450
|
+
return window.localStorage;
|
|
3451
|
+
}
|
|
3452
|
+
catch (e) {
|
|
3453
|
+
return undefined;
|
|
3454
|
+
}
|
|
3455
|
+
},
|
|
3456
|
+
createXHR() {
|
|
3457
|
+
if (this.getXHRAPI()) {
|
|
3458
|
+
return this.createXMLHttpRequest();
|
|
3459
|
+
}
|
|
3460
|
+
else {
|
|
3461
|
+
return this.createMicrosoftXHR();
|
|
3462
|
+
}
|
|
3463
|
+
},
|
|
3464
|
+
createXMLHttpRequest() {
|
|
3465
|
+
var Constructor = this.getXHRAPI();
|
|
3466
|
+
return new Constructor();
|
|
3467
|
+
},
|
|
3468
|
+
createMicrosoftXHR() {
|
|
3469
|
+
return new ActiveXObject('Microsoft.XMLHTTP');
|
|
3470
|
+
},
|
|
3471
|
+
getNetwork() {
|
|
3472
|
+
return Network;
|
|
3473
|
+
},
|
|
3474
|
+
createWebSocket(url) {
|
|
3475
|
+
var Constructor = this.getWebSocketAPI();
|
|
3476
|
+
return new Constructor(url);
|
|
3477
|
+
},
|
|
3478
|
+
createSocketRequest(method, url) {
|
|
3479
|
+
if (this.isXHRSupported()) {
|
|
3480
|
+
return this.HTTPFactory.createXHR(method, url);
|
|
3481
|
+
}
|
|
3482
|
+
else if (this.isXDRSupported(url.indexOf('https:') === 0)) {
|
|
3483
|
+
return this.HTTPFactory.createXDR(method, url);
|
|
3484
|
+
}
|
|
3485
|
+
else {
|
|
3486
|
+
throw 'Cross-origin HTTP requests are not supported';
|
|
3487
|
+
}
|
|
3488
|
+
},
|
|
3489
|
+
isXHRSupported() {
|
|
3490
|
+
var Constructor = this.getXHRAPI();
|
|
3491
|
+
return (Boolean(Constructor) && new Constructor().withCredentials !== undefined);
|
|
3492
|
+
},
|
|
3493
|
+
isXDRSupported(useTLS) {
|
|
3494
|
+
var protocol = useTLS ? 'https:' : 'http:';
|
|
3495
|
+
var documentProtocol = this.getProtocol();
|
|
3496
|
+
return (Boolean(window['XDomainRequest']) && documentProtocol === protocol);
|
|
3497
|
+
},
|
|
3498
|
+
addUnloadListener(listener) {
|
|
3499
|
+
if (window.addEventListener !== undefined) {
|
|
3500
|
+
window.addEventListener('unload', listener, false);
|
|
3501
|
+
}
|
|
3502
|
+
else if (window.attachEvent !== undefined) {
|
|
3503
|
+
window.attachEvent('onunload', listener);
|
|
3504
|
+
}
|
|
3505
|
+
},
|
|
3506
|
+
removeUnloadListener(listener) {
|
|
3507
|
+
if (window.addEventListener !== undefined) {
|
|
3508
|
+
window.removeEventListener('unload', listener, false);
|
|
3509
|
+
}
|
|
3510
|
+
else if (window.detachEvent !== undefined) {
|
|
3511
|
+
window.detachEvent('onunload', listener);
|
|
3512
|
+
}
|
|
3513
|
+
},
|
|
3514
|
+
randomInt(max) {
|
|
3515
|
+
const random = function () {
|
|
3516
|
+
const crypto = window.crypto || window['msCrypto'];
|
|
3517
|
+
const random = crypto.getRandomValues(new Uint32Array(1))[0];
|
|
3518
|
+
return random / Math.pow(2, 32);
|
|
3519
|
+
};
|
|
3520
|
+
return Math.floor(random() * max);
|
|
3521
|
+
},
|
|
3522
|
+
};
|
|
3523
|
+
/* harmony default export */ const runtime = (Runtime);
|
|
3524
|
+
var TimelineLevel;
|
|
3525
|
+
(function (TimelineLevel) {
|
|
3526
|
+
TimelineLevel[TimelineLevel["ERROR"] = 3] = "ERROR";
|
|
3527
|
+
TimelineLevel[TimelineLevel["INFO"] = 6] = "INFO";
|
|
3528
|
+
TimelineLevel[TimelineLevel["DEBUG"] = 7] = "DEBUG";
|
|
3529
|
+
})(TimelineLevel || (TimelineLevel = {}));
|
|
3530
|
+
/* harmony default export */ const level = (TimelineLevel);
|
|
3531
|
+
|
|
3532
|
+
|
|
3533
|
+
|
|
3534
|
+
class Timeline {
|
|
3535
|
+
constructor(key, session, options) {
|
|
3536
|
+
this.key = key;
|
|
3537
|
+
this.session = session;
|
|
3538
|
+
this.events = [];
|
|
3539
|
+
this.options = options || {};
|
|
3540
|
+
this.sent = 0;
|
|
3541
|
+
this.uniqueID = 0;
|
|
3542
|
+
}
|
|
3543
|
+
log(level, event) {
|
|
3544
|
+
if (level <= this.options.level) {
|
|
3545
|
+
this.events.push(extend({}, event, { timestamp: util.now() }));
|
|
3546
|
+
if (this.options.limit && this.events.length > this.options.limit) {
|
|
3547
|
+
this.events.shift();
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
}
|
|
3551
|
+
error(event) {
|
|
3552
|
+
this.log(level.ERROR, event);
|
|
3553
|
+
}
|
|
3554
|
+
info(event) {
|
|
3555
|
+
this.log(level.INFO, event);
|
|
3556
|
+
}
|
|
3557
|
+
debug(event) {
|
|
3558
|
+
this.log(level.DEBUG, event);
|
|
3559
|
+
}
|
|
3560
|
+
isEmpty() {
|
|
3561
|
+
return this.events.length === 0;
|
|
3562
|
+
}
|
|
3563
|
+
send(sendfn, callback) {
|
|
3564
|
+
var data = extend({
|
|
3565
|
+
session: this.session,
|
|
3566
|
+
bundle: this.sent + 1,
|
|
3567
|
+
key: this.key,
|
|
3568
|
+
lib: 'js',
|
|
3569
|
+
version: this.options.version,
|
|
3570
|
+
cluster: this.options.cluster,
|
|
3571
|
+
features: this.options.features,
|
|
3572
|
+
timeline: this.events,
|
|
3573
|
+
}, this.options.params);
|
|
3574
|
+
this.events = [];
|
|
3575
|
+
sendfn(data, (error, result) => {
|
|
3576
|
+
if (!error) {
|
|
3577
|
+
this.sent++;
|
|
3578
|
+
}
|
|
3579
|
+
if (callback) {
|
|
3580
|
+
callback(error, result);
|
|
3581
|
+
}
|
|
3582
|
+
});
|
|
3583
|
+
return true;
|
|
3584
|
+
}
|
|
3585
|
+
generateUniqueID() {
|
|
3586
|
+
this.uniqueID++;
|
|
3587
|
+
return this.uniqueID;
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
|
|
3591
|
+
|
|
3592
|
+
|
|
3593
|
+
|
|
3594
|
+
class TransportStrategy {
|
|
3595
|
+
constructor(name, priority, transport, options) {
|
|
3596
|
+
this.name = name;
|
|
3597
|
+
this.priority = priority;
|
|
3598
|
+
this.transport = transport;
|
|
3599
|
+
this.options = options || {};
|
|
3600
|
+
}
|
|
3601
|
+
isSupported() {
|
|
3602
|
+
return this.transport.isSupported({
|
|
3603
|
+
useTLS: this.options.useTLS,
|
|
3604
|
+
});
|
|
3605
|
+
}
|
|
3606
|
+
connect(minPriority, callback) {
|
|
3607
|
+
if (!this.isSupported()) {
|
|
3608
|
+
return failAttempt(new UnsupportedStrategy(), callback);
|
|
3609
|
+
}
|
|
3610
|
+
else if (this.priority < minPriority) {
|
|
3611
|
+
return failAttempt(new TransportPriorityTooLow(), callback);
|
|
3612
|
+
}
|
|
3613
|
+
var connected = false;
|
|
3614
|
+
var transport = this.transport.createConnection(this.name, this.priority, this.options.key, this.options);
|
|
3615
|
+
var handshake = null;
|
|
3616
|
+
var onInitialized = function () {
|
|
3617
|
+
transport.unbind('initialized', onInitialized);
|
|
3618
|
+
transport.connect();
|
|
3619
|
+
};
|
|
3620
|
+
var onOpen = function () {
|
|
3621
|
+
handshake = factory.createHandshake(transport, function (result) {
|
|
3622
|
+
connected = true;
|
|
3623
|
+
unbindListeners();
|
|
3624
|
+
callback(null, result);
|
|
3625
|
+
});
|
|
3626
|
+
};
|
|
3627
|
+
var onError = function (error) {
|
|
3628
|
+
unbindListeners();
|
|
3629
|
+
callback(error);
|
|
3630
|
+
};
|
|
3631
|
+
var onClosed = function () {
|
|
3632
|
+
unbindListeners();
|
|
3633
|
+
var serializedTransport;
|
|
3634
|
+
serializedTransport = safeJSONStringify(transport);
|
|
3635
|
+
callback(new TransportClosed(serializedTransport));
|
|
3636
|
+
};
|
|
3637
|
+
var unbindListeners = function () {
|
|
3638
|
+
transport.unbind('initialized', onInitialized);
|
|
3639
|
+
transport.unbind('open', onOpen);
|
|
3640
|
+
transport.unbind('error', onError);
|
|
3641
|
+
transport.unbind('closed', onClosed);
|
|
3642
|
+
};
|
|
3643
|
+
transport.bind('initialized', onInitialized);
|
|
3644
|
+
transport.bind('open', onOpen);
|
|
3645
|
+
transport.bind('error', onError);
|
|
3646
|
+
transport.bind('closed', onClosed);
|
|
3647
|
+
transport.initialize();
|
|
3648
|
+
return {
|
|
3649
|
+
abort: () => {
|
|
3650
|
+
if (connected) {
|
|
3651
|
+
return;
|
|
3652
|
+
}
|
|
3653
|
+
unbindListeners();
|
|
3654
|
+
if (handshake) {
|
|
3655
|
+
handshake.close();
|
|
3656
|
+
}
|
|
3657
|
+
else {
|
|
3658
|
+
transport.close();
|
|
3659
|
+
}
|
|
3660
|
+
},
|
|
3661
|
+
forceMinPriority: (p) => {
|
|
3662
|
+
if (connected) {
|
|
3663
|
+
return;
|
|
3664
|
+
}
|
|
3665
|
+
if (this.priority < p) {
|
|
3666
|
+
if (handshake) {
|
|
3667
|
+
handshake.close();
|
|
3668
|
+
}
|
|
3669
|
+
else {
|
|
3670
|
+
transport.close();
|
|
3671
|
+
}
|
|
3672
|
+
}
|
|
3673
|
+
},
|
|
3674
|
+
};
|
|
3675
|
+
}
|
|
3676
|
+
}
|
|
3677
|
+
function failAttempt(error, callback) {
|
|
3678
|
+
util.defer(function () {
|
|
3679
|
+
callback(error);
|
|
3680
|
+
});
|
|
3681
|
+
return {
|
|
3682
|
+
abort: function () { },
|
|
3683
|
+
forceMinPriority: function () { },
|
|
3684
|
+
};
|
|
3685
|
+
}
|
|
3686
|
+
|
|
3687
|
+
|
|
3688
|
+
|
|
3689
|
+
|
|
3690
|
+
|
|
3691
|
+
const { Transports: strategy_builder_Transports } = runtime;
|
|
3692
|
+
var defineTransport = function (config, name, type, priority, options, manager) {
|
|
3693
|
+
var transportClass = strategy_builder_Transports[type];
|
|
3694
|
+
if (!transportClass) {
|
|
3695
|
+
throw new UnsupportedTransport(type);
|
|
3696
|
+
}
|
|
3697
|
+
var enabled = (!config.enabledTransports ||
|
|
3698
|
+
arrayIndexOf(config.enabledTransports, name) !== -1) &&
|
|
3699
|
+
(!config.disabledTransports ||
|
|
3700
|
+
arrayIndexOf(config.disabledTransports, name) === -1);
|
|
3701
|
+
var transport;
|
|
3702
|
+
if (enabled) {
|
|
3703
|
+
options = Object.assign({ ignoreNullOrigin: config.ignoreNullOrigin }, options);
|
|
3704
|
+
transport = new TransportStrategy(name, priority, manager ? manager.getAssistant(transportClass) : transportClass, options);
|
|
3705
|
+
}
|
|
3706
|
+
else {
|
|
3707
|
+
transport = strategy_builder_UnsupportedStrategy;
|
|
3708
|
+
}
|
|
3709
|
+
return transport;
|
|
3710
|
+
};
|
|
3711
|
+
var strategy_builder_UnsupportedStrategy = {
|
|
3712
|
+
isSupported: function () {
|
|
3713
|
+
return false;
|
|
3714
|
+
},
|
|
3715
|
+
connect: function (_, callback) {
|
|
3716
|
+
var deferred = util.defer(function () {
|
|
3717
|
+
callback(new UnsupportedStrategy());
|
|
3718
|
+
});
|
|
3719
|
+
return {
|
|
3720
|
+
abort: function () {
|
|
3721
|
+
deferred.ensureAborted();
|
|
3722
|
+
},
|
|
3723
|
+
forceMinPriority: function () { },
|
|
3724
|
+
};
|
|
3725
|
+
},
|
|
3726
|
+
};
|
|
3727
|
+
|
|
3728
|
+
function validateOptions(options) {
|
|
3729
|
+
if (options == null) {
|
|
3730
|
+
throw 'You must pass an options object';
|
|
3731
|
+
}
|
|
3732
|
+
if (options.cluster == null) {
|
|
3733
|
+
throw 'Options object must provide a cluster';
|
|
3734
|
+
}
|
|
3735
|
+
if ('disableStats' in options) {
|
|
3736
|
+
logger.warn('The disableStats option is deprecated in favor of enableStats');
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
|
|
3740
|
+
|
|
3741
|
+
const composeChannelQuery = (params, authOptions) => {
|
|
3742
|
+
var query = 'socket_id=' + encodeURIComponent(params.socketId);
|
|
3743
|
+
for (var key in authOptions.params) {
|
|
3744
|
+
query +=
|
|
3745
|
+
'&' +
|
|
3746
|
+
encodeURIComponent(key) +
|
|
3747
|
+
'=' +
|
|
3748
|
+
encodeURIComponent(authOptions.params[key]);
|
|
3749
|
+
}
|
|
3750
|
+
if (authOptions.paramsProvider != null) {
|
|
3751
|
+
let dynamicParams = authOptions.paramsProvider();
|
|
3752
|
+
for (var key in dynamicParams) {
|
|
3753
|
+
query +=
|
|
3754
|
+
'&' +
|
|
3755
|
+
encodeURIComponent(key) +
|
|
3756
|
+
'=' +
|
|
3757
|
+
encodeURIComponent(dynamicParams[key]);
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
return query;
|
|
3761
|
+
};
|
|
3762
|
+
const UserAuthenticator = (authOptions) => {
|
|
3763
|
+
if (typeof runtime.getAuthorizers()[authOptions.transport] === 'undefined') {
|
|
3764
|
+
throw `'${authOptions.transport}' is not a recognized auth transport`;
|
|
3765
|
+
}
|
|
3766
|
+
return (params, callback) => {
|
|
3767
|
+
const query = composeChannelQuery(params, authOptions);
|
|
3768
|
+
runtime.getAuthorizers()[authOptions.transport](runtime, query, authOptions, AuthRequestType.UserAuthentication, callback);
|
|
3769
|
+
};
|
|
3770
|
+
};
|
|
3771
|
+
/* harmony default export */ const user_authenticator = (UserAuthenticator);
|
|
3772
|
+
|
|
3773
|
+
|
|
3774
|
+
const channel_authorizer_composeChannelQuery = (params, authOptions) => {
|
|
3775
|
+
var query = 'socket_id=' + encodeURIComponent(params.socketId);
|
|
3776
|
+
query += '&channel_name=' + encodeURIComponent(params.channelName);
|
|
3777
|
+
for (var key in authOptions.params) {
|
|
3778
|
+
query +=
|
|
3779
|
+
'&' +
|
|
3780
|
+
encodeURIComponent(key) +
|
|
3781
|
+
'=' +
|
|
3782
|
+
encodeURIComponent(authOptions.params[key]);
|
|
3783
|
+
}
|
|
3784
|
+
if (authOptions.paramsProvider != null) {
|
|
3785
|
+
let dynamicParams = authOptions.paramsProvider();
|
|
3786
|
+
for (var key in dynamicParams) {
|
|
3787
|
+
query +=
|
|
3788
|
+
'&' +
|
|
3789
|
+
encodeURIComponent(key) +
|
|
3790
|
+
'=' +
|
|
3791
|
+
encodeURIComponent(dynamicParams[key]);
|
|
3792
|
+
}
|
|
3793
|
+
}
|
|
3794
|
+
return query;
|
|
3795
|
+
};
|
|
3796
|
+
const ChannelAuthorizer = (authOptions) => {
|
|
3797
|
+
if (typeof runtime.getAuthorizers()[authOptions.transport] === 'undefined') {
|
|
3798
|
+
throw `'${authOptions.transport}' is not a recognized auth transport`;
|
|
3799
|
+
}
|
|
3800
|
+
return (params, callback) => {
|
|
3801
|
+
const query = channel_authorizer_composeChannelQuery(params, authOptions);
|
|
3802
|
+
runtime.getAuthorizers()[authOptions.transport](runtime, query, authOptions, AuthRequestType.ChannelAuthorization, callback);
|
|
3803
|
+
};
|
|
3804
|
+
};
|
|
3805
|
+
/* harmony default export */ const channel_authorizer = (ChannelAuthorizer);
|
|
3806
|
+
const ChannelAuthorizerProxy = (pusher, authOptions, channelAuthorizerGenerator) => {
|
|
3807
|
+
const deprecatedAuthorizerOptions = {
|
|
3808
|
+
authTransport: authOptions.transport,
|
|
3809
|
+
authEndpoint: authOptions.endpoint,
|
|
3810
|
+
auth: {
|
|
3811
|
+
params: authOptions.params,
|
|
3812
|
+
headers: authOptions.headers,
|
|
3813
|
+
},
|
|
3814
|
+
};
|
|
3815
|
+
return (params, callback) => {
|
|
3816
|
+
const channel = pusher.channel(params.channelName);
|
|
3817
|
+
const channelAuthorizer = channelAuthorizerGenerator(channel, deprecatedAuthorizerOptions);
|
|
3818
|
+
channelAuthorizer.authorize(params.socketId, callback);
|
|
3819
|
+
};
|
|
3820
|
+
};
|
|
3821
|
+
|
|
3822
|
+
|
|
3823
|
+
|
|
3824
|
+
|
|
3825
|
+
|
|
3826
|
+
function getConfig(opts, pusher) {
|
|
3827
|
+
let config = {
|
|
3828
|
+
activityTimeout: opts.activityTimeout || defaults.activityTimeout,
|
|
3829
|
+
cluster: opts.cluster,
|
|
3830
|
+
httpPath: opts.httpPath || defaults.httpPath,
|
|
3831
|
+
httpPort: opts.httpPort || defaults.httpPort,
|
|
3832
|
+
httpsPort: opts.httpsPort || defaults.httpsPort,
|
|
3833
|
+
pongTimeout: opts.pongTimeout || defaults.pongTimeout,
|
|
3834
|
+
statsHost: opts.statsHost || defaults.stats_host,
|
|
3835
|
+
unavailableTimeout: opts.unavailableTimeout || defaults.unavailableTimeout,
|
|
3836
|
+
wsPath: opts.wsPath || defaults.wsPath,
|
|
3837
|
+
wsPort: opts.wsPort || defaults.wsPort,
|
|
3838
|
+
wssPort: opts.wssPort || defaults.wssPort,
|
|
3839
|
+
enableStats: getEnableStatsConfig(opts),
|
|
3840
|
+
httpHost: getHttpHost(opts),
|
|
3841
|
+
useTLS: shouldUseTLS(opts),
|
|
3842
|
+
wsHost: getWebsocketHost(opts),
|
|
3843
|
+
userAuthenticator: buildUserAuthenticator(opts),
|
|
3844
|
+
channelAuthorizer: buildChannelAuthorizer(opts, pusher),
|
|
3845
|
+
};
|
|
3846
|
+
if ('disabledTransports' in opts)
|
|
3847
|
+
config.disabledTransports = opts.disabledTransports;
|
|
3848
|
+
if ('enabledTransports' in opts)
|
|
3849
|
+
config.enabledTransports = opts.enabledTransports;
|
|
3850
|
+
if ('ignoreNullOrigin' in opts)
|
|
3851
|
+
config.ignoreNullOrigin = opts.ignoreNullOrigin;
|
|
3852
|
+
if ('timelineParams' in opts)
|
|
3853
|
+
config.timelineParams = opts.timelineParams;
|
|
3854
|
+
if ('nacl' in opts) {
|
|
3855
|
+
config.nacl = opts.nacl;
|
|
3856
|
+
}
|
|
3857
|
+
return config;
|
|
3858
|
+
}
|
|
3859
|
+
function getHttpHost(opts) {
|
|
3860
|
+
if (opts.httpHost) {
|
|
3861
|
+
return opts.httpHost;
|
|
3862
|
+
}
|
|
3863
|
+
if (opts.cluster) {
|
|
3864
|
+
return `sockjs-${opts.cluster}.pusher.com`;
|
|
3865
|
+
}
|
|
3866
|
+
return defaults.httpHost;
|
|
3867
|
+
}
|
|
3868
|
+
function getWebsocketHost(opts) {
|
|
3869
|
+
if (opts.wsHost) {
|
|
3870
|
+
return opts.wsHost;
|
|
3871
|
+
}
|
|
3872
|
+
return getWebsocketHostFromCluster(opts.cluster);
|
|
3873
|
+
}
|
|
3874
|
+
function getWebsocketHostFromCluster(cluster) {
|
|
3875
|
+
return `ws-${cluster}.pusher.com`;
|
|
3876
|
+
}
|
|
3877
|
+
function shouldUseTLS(opts) {
|
|
3878
|
+
if (runtime.getProtocol() === 'https:') {
|
|
3879
|
+
return true;
|
|
3880
|
+
}
|
|
3881
|
+
else if (opts.forceTLS === false) {
|
|
3882
|
+
return false;
|
|
3883
|
+
}
|
|
3884
|
+
return true;
|
|
3885
|
+
}
|
|
3886
|
+
function getEnableStatsConfig(opts) {
|
|
3887
|
+
if ('enableStats' in opts) {
|
|
3888
|
+
return opts.enableStats;
|
|
3889
|
+
}
|
|
3890
|
+
if ('disableStats' in opts) {
|
|
3891
|
+
return !opts.disableStats;
|
|
3892
|
+
}
|
|
3893
|
+
return false;
|
|
3894
|
+
}
|
|
3895
|
+
const hasCustomHandler = (auth) => {
|
|
3896
|
+
return 'customHandler' in auth && auth['customHandler'] != null;
|
|
3897
|
+
};
|
|
3898
|
+
function buildUserAuthenticator(opts) {
|
|
3899
|
+
const userAuthentication = Object.assign(Object.assign({}, defaults.userAuthentication), opts.userAuthentication);
|
|
3900
|
+
if (hasCustomHandler(userAuthentication)) {
|
|
3901
|
+
return userAuthentication['customHandler'];
|
|
3902
|
+
}
|
|
3903
|
+
return user_authenticator(userAuthentication);
|
|
3904
|
+
}
|
|
3905
|
+
function buildChannelAuth(opts, pusher) {
|
|
3906
|
+
let channelAuthorization;
|
|
3907
|
+
if ('channelAuthorization' in opts) {
|
|
3908
|
+
channelAuthorization = Object.assign(Object.assign({}, defaults.channelAuthorization), opts.channelAuthorization);
|
|
3909
|
+
}
|
|
3910
|
+
else {
|
|
3911
|
+
channelAuthorization = {
|
|
3912
|
+
transport: opts.authTransport || defaults.authTransport,
|
|
3913
|
+
endpoint: opts.authEndpoint || defaults.authEndpoint,
|
|
3914
|
+
};
|
|
3915
|
+
if ('auth' in opts) {
|
|
3916
|
+
if ('params' in opts.auth)
|
|
3917
|
+
channelAuthorization.params = opts.auth.params;
|
|
3918
|
+
if ('headers' in opts.auth)
|
|
3919
|
+
channelAuthorization.headers = opts.auth.headers;
|
|
3920
|
+
}
|
|
3921
|
+
if ('authorizer' in opts) {
|
|
3922
|
+
return {
|
|
3923
|
+
customHandler: ChannelAuthorizerProxy(pusher, channelAuthorization, opts.authorizer),
|
|
3924
|
+
};
|
|
3925
|
+
}
|
|
3926
|
+
}
|
|
3927
|
+
return channelAuthorization;
|
|
3928
|
+
}
|
|
3929
|
+
function buildChannelAuthorizer(opts, pusher) {
|
|
3930
|
+
const channelAuthorization = buildChannelAuth(opts, pusher);
|
|
3931
|
+
if (hasCustomHandler(channelAuthorization)) {
|
|
3932
|
+
return channelAuthorization['customHandler'];
|
|
3933
|
+
}
|
|
3934
|
+
return channel_authorizer(channelAuthorization);
|
|
3935
|
+
}
|
|
3936
|
+
|
|
3937
|
+
|
|
3938
|
+
class WatchlistFacade extends Dispatcher {
|
|
3939
|
+
constructor(pusher) {
|
|
3940
|
+
super(function (eventName, data) {
|
|
3941
|
+
logger.debug(`No callbacks on watchlist events for ${eventName}`);
|
|
3942
|
+
});
|
|
3943
|
+
this.pusher = pusher;
|
|
3944
|
+
this.bindWatchlistInternalEvent();
|
|
3945
|
+
}
|
|
3946
|
+
handleEvent(pusherEvent) {
|
|
3947
|
+
pusherEvent.data.events.forEach((watchlistEvent) => {
|
|
3948
|
+
this.emit(watchlistEvent.name, watchlistEvent);
|
|
3949
|
+
});
|
|
3950
|
+
}
|
|
3951
|
+
bindWatchlistInternalEvent() {
|
|
3952
|
+
this.pusher.connection.bind('message', (pusherEvent) => {
|
|
3953
|
+
var eventName = pusherEvent.event;
|
|
3954
|
+
if (eventName === 'pusher_internal:watchlist_events') {
|
|
3955
|
+
this.handleEvent(pusherEvent);
|
|
3956
|
+
}
|
|
3957
|
+
});
|
|
3958
|
+
}
|
|
3959
|
+
}
|
|
3960
|
+
function flatPromise() {
|
|
3961
|
+
let resolve, reject;
|
|
3962
|
+
const promise = new Promise((res, rej) => {
|
|
3963
|
+
resolve = res;
|
|
3964
|
+
reject = rej;
|
|
3965
|
+
});
|
|
3966
|
+
return { promise, resolve, reject };
|
|
3967
|
+
}
|
|
3968
|
+
/* harmony default export */ const flat_promise = (flatPromise);
|
|
3969
|
+
|
|
3970
|
+
|
|
3971
|
+
|
|
3972
|
+
|
|
3973
|
+
|
|
3974
|
+
class UserFacade extends Dispatcher {
|
|
3975
|
+
constructor(pusher) {
|
|
3976
|
+
super(function (eventName, data) {
|
|
3977
|
+
logger.debug('No callbacks on user for ' + eventName);
|
|
3978
|
+
});
|
|
3979
|
+
this.signin_requested = false;
|
|
3980
|
+
this.user_data = null;
|
|
3981
|
+
this.serverToUserChannel = null;
|
|
3982
|
+
this.signinDonePromise = null;
|
|
3983
|
+
this._signinDoneResolve = null;
|
|
3984
|
+
this._onAuthorize = (err, authData) => {
|
|
3985
|
+
if (err) {
|
|
3986
|
+
logger.warn(`Error during signin: ${err}`);
|
|
3987
|
+
this._cleanup();
|
|
3988
|
+
return;
|
|
3989
|
+
}
|
|
3990
|
+
this.pusher.send_event('pusher:signin', {
|
|
3991
|
+
auth: authData.auth,
|
|
3992
|
+
user_data: authData.user_data,
|
|
3993
|
+
});
|
|
3994
|
+
};
|
|
3995
|
+
this.pusher = pusher;
|
|
3996
|
+
this.pusher.connection.bind('state_change', ({ previous, current }) => {
|
|
3997
|
+
if (previous !== 'connected' && current === 'connected') {
|
|
3998
|
+
this._signin();
|
|
3999
|
+
}
|
|
4000
|
+
if (previous === 'connected' && current !== 'connected') {
|
|
4001
|
+
this._cleanup();
|
|
4002
|
+
this._newSigninPromiseIfNeeded();
|
|
4003
|
+
}
|
|
4004
|
+
});
|
|
4005
|
+
this.watchlist = new WatchlistFacade(pusher);
|
|
4006
|
+
this.pusher.connection.bind('message', (event) => {
|
|
4007
|
+
var eventName = event.event;
|
|
4008
|
+
if (eventName === 'pusher:signin_success') {
|
|
4009
|
+
this._onSigninSuccess(event.data);
|
|
4010
|
+
}
|
|
4011
|
+
if (this.serverToUserChannel &&
|
|
4012
|
+
this.serverToUserChannel.name === event.channel) {
|
|
4013
|
+
this.serverToUserChannel.handleEvent(event);
|
|
4014
|
+
}
|
|
4015
|
+
});
|
|
4016
|
+
}
|
|
4017
|
+
signin() {
|
|
4018
|
+
if (this.signin_requested) {
|
|
4019
|
+
return;
|
|
4020
|
+
}
|
|
4021
|
+
this.signin_requested = true;
|
|
4022
|
+
this._signin();
|
|
4023
|
+
}
|
|
4024
|
+
_signin() {
|
|
4025
|
+
if (!this.signin_requested) {
|
|
4026
|
+
return;
|
|
4027
|
+
}
|
|
4028
|
+
this._newSigninPromiseIfNeeded();
|
|
4029
|
+
if (this.pusher.connection.state !== 'connected') {
|
|
4030
|
+
return;
|
|
4031
|
+
}
|
|
4032
|
+
this.pusher.config.userAuthenticator({
|
|
4033
|
+
socketId: this.pusher.connection.socket_id,
|
|
4034
|
+
}, this._onAuthorize);
|
|
4035
|
+
}
|
|
4036
|
+
_onSigninSuccess(data) {
|
|
4037
|
+
try {
|
|
4038
|
+
this.user_data = JSON.parse(data.user_data);
|
|
4039
|
+
}
|
|
4040
|
+
catch (e) {
|
|
4041
|
+
logger.error(`Failed parsing user data after signin: ${data.user_data}`);
|
|
4042
|
+
this._cleanup();
|
|
4043
|
+
return;
|
|
4044
|
+
}
|
|
4045
|
+
if (typeof this.user_data.id !== 'string' || this.user_data.id === '') {
|
|
4046
|
+
logger.error(`user_data doesn't contain an id. user_data: ${this.user_data}`);
|
|
4047
|
+
this._cleanup();
|
|
4048
|
+
return;
|
|
4049
|
+
}
|
|
4050
|
+
this._signinDoneResolve();
|
|
4051
|
+
this._subscribeChannels();
|
|
4052
|
+
}
|
|
4053
|
+
_subscribeChannels() {
|
|
4054
|
+
const ensure_subscribed = (channel) => {
|
|
4055
|
+
if (channel.subscriptionPending && channel.subscriptionCancelled) {
|
|
4056
|
+
channel.reinstateSubscription();
|
|
4057
|
+
}
|
|
4058
|
+
else if (!channel.subscriptionPending &&
|
|
4059
|
+
this.pusher.connection.state === 'connected') {
|
|
4060
|
+
channel.subscribe();
|
|
4061
|
+
}
|
|
4062
|
+
};
|
|
4063
|
+
this.serverToUserChannel = new Channel(`#server-to-user-${this.user_data.id}`, this.pusher);
|
|
4064
|
+
this.serverToUserChannel.bind_global((eventName, data) => {
|
|
4065
|
+
if (eventName.indexOf('pusher_internal:') === 0 ||
|
|
4066
|
+
eventName.indexOf('pusher:') === 0) {
|
|
4067
|
+
return;
|
|
4068
|
+
}
|
|
4069
|
+
this.emit(eventName, data);
|
|
4070
|
+
});
|
|
4071
|
+
ensure_subscribed(this.serverToUserChannel);
|
|
4072
|
+
}
|
|
4073
|
+
_cleanup() {
|
|
4074
|
+
this.user_data = null;
|
|
4075
|
+
if (this.serverToUserChannel) {
|
|
4076
|
+
this.serverToUserChannel.unbind_all();
|
|
4077
|
+
this.serverToUserChannel.disconnect();
|
|
4078
|
+
this.serverToUserChannel = null;
|
|
4079
|
+
}
|
|
4080
|
+
if (this.signin_requested) {
|
|
4081
|
+
this._signinDoneResolve();
|
|
4082
|
+
}
|
|
4083
|
+
}
|
|
4084
|
+
_newSigninPromiseIfNeeded() {
|
|
4085
|
+
if (!this.signin_requested) {
|
|
4086
|
+
return;
|
|
4087
|
+
}
|
|
4088
|
+
if (this.signinDonePromise && !this.signinDonePromise.done) {
|
|
4089
|
+
return;
|
|
4090
|
+
}
|
|
4091
|
+
const { promise, resolve} = flat_promise();
|
|
4092
|
+
promise.done = false;
|
|
4093
|
+
const setDone = () => {
|
|
4094
|
+
promise.done = true;
|
|
4095
|
+
};
|
|
4096
|
+
promise.then(setDone).catch(setDone);
|
|
4097
|
+
this.signinDonePromise = promise;
|
|
4098
|
+
this._signinDoneResolve = resolve;
|
|
4099
|
+
}
|
|
4100
|
+
}
|
|
4101
|
+
|
|
4102
|
+
|
|
4103
|
+
|
|
4104
|
+
|
|
4105
|
+
|
|
4106
|
+
|
|
4107
|
+
|
|
4108
|
+
|
|
4109
|
+
|
|
4110
|
+
|
|
4111
|
+
|
|
4112
|
+
|
|
4113
|
+
|
|
4114
|
+
class Pusher {
|
|
4115
|
+
static ready() {
|
|
4116
|
+
Pusher.isReady = true;
|
|
4117
|
+
for (var i = 0, l = Pusher.instances.length; i < l; i++) {
|
|
4118
|
+
Pusher.instances[i].connect();
|
|
4119
|
+
}
|
|
4120
|
+
}
|
|
4121
|
+
static getClientFeatures() {
|
|
4122
|
+
return keys(filterObject({ ws: runtime.Transports.ws }, function (t) {
|
|
4123
|
+
return t.isSupported({});
|
|
4124
|
+
}));
|
|
4125
|
+
}
|
|
4126
|
+
constructor(app_key, options) {
|
|
4127
|
+
checkAppKey(app_key);
|
|
4128
|
+
validateOptions(options);
|
|
4129
|
+
this.key = app_key;
|
|
4130
|
+
this.options = options;
|
|
4131
|
+
this.config = getConfig(this.options, this);
|
|
4132
|
+
this.channels = factory.createChannels();
|
|
4133
|
+
this.global_emitter = new Dispatcher();
|
|
4134
|
+
this.sessionID = runtime.randomInt(1000000000);
|
|
4135
|
+
this.timeline = new Timeline(this.key, this.sessionID, {
|
|
4136
|
+
cluster: this.config.cluster,
|
|
4137
|
+
features: Pusher.getClientFeatures(),
|
|
4138
|
+
params: this.config.timelineParams || {},
|
|
4139
|
+
limit: 50,
|
|
4140
|
+
level: level.INFO,
|
|
4141
|
+
version: defaults.VERSION,
|
|
4142
|
+
});
|
|
4143
|
+
if (this.config.enableStats) {
|
|
4144
|
+
this.timelineSender = factory.createTimelineSender(this.timeline, {
|
|
4145
|
+
host: this.config.statsHost,
|
|
4146
|
+
path: '/timeline/v2/' + runtime.TimelineTransport.name,
|
|
4147
|
+
});
|
|
4148
|
+
}
|
|
4149
|
+
var getStrategy = (options) => {
|
|
4150
|
+
return runtime.getDefaultStrategy(this.config, options, defineTransport);
|
|
4151
|
+
};
|
|
4152
|
+
this.connection = factory.createConnectionManager(this.key, {
|
|
4153
|
+
getStrategy: getStrategy,
|
|
4154
|
+
timeline: this.timeline,
|
|
4155
|
+
activityTimeout: this.config.activityTimeout,
|
|
4156
|
+
pongTimeout: this.config.pongTimeout,
|
|
4157
|
+
unavailableTimeout: this.config.unavailableTimeout,
|
|
4158
|
+
useTLS: Boolean(this.config.useTLS),
|
|
4159
|
+
});
|
|
4160
|
+
this.connection.bind('connected', () => {
|
|
4161
|
+
this.subscribeAll();
|
|
4162
|
+
if (this.timelineSender) {
|
|
4163
|
+
this.timelineSender.send(this.connection.isUsingTLS());
|
|
4164
|
+
}
|
|
4165
|
+
});
|
|
4166
|
+
this.connection.bind('message', (event) => {
|
|
4167
|
+
var eventName = event.event;
|
|
4168
|
+
var internal = eventName.indexOf('pusher_internal:') === 0;
|
|
4169
|
+
if (event.channel) {
|
|
4170
|
+
var channel = this.channel(event.channel);
|
|
4171
|
+
if (channel) {
|
|
4172
|
+
channel.handleEvent(event);
|
|
4173
|
+
}
|
|
4174
|
+
}
|
|
4175
|
+
if (!internal) {
|
|
4176
|
+
this.global_emitter.emit(event.event, event.data);
|
|
4177
|
+
}
|
|
4178
|
+
});
|
|
4179
|
+
this.connection.bind('connecting', () => {
|
|
4180
|
+
this.channels.disconnect();
|
|
4181
|
+
});
|
|
4182
|
+
this.connection.bind('disconnected', () => {
|
|
4183
|
+
this.channels.disconnect();
|
|
4184
|
+
});
|
|
4185
|
+
this.connection.bind('error', (err) => {
|
|
4186
|
+
logger.warn(err);
|
|
4187
|
+
});
|
|
4188
|
+
Pusher.instances.push(this);
|
|
4189
|
+
this.timeline.info({ instances: Pusher.instances.length });
|
|
4190
|
+
this.user = new UserFacade(this);
|
|
4191
|
+
if (Pusher.isReady) {
|
|
4192
|
+
this.connect();
|
|
4193
|
+
}
|
|
4194
|
+
}
|
|
4195
|
+
switchCluster(options) {
|
|
4196
|
+
const { appKey, cluster } = options;
|
|
4197
|
+
this.key = appKey;
|
|
4198
|
+
this.options = Object.assign(Object.assign({}, this.options), { cluster });
|
|
4199
|
+
this.config = getConfig(this.options, this);
|
|
4200
|
+
this.connection.switchCluster(this.key);
|
|
4201
|
+
}
|
|
4202
|
+
channel(name) {
|
|
4203
|
+
return this.channels.find(name);
|
|
4204
|
+
}
|
|
4205
|
+
allChannels() {
|
|
4206
|
+
return this.channels.all();
|
|
4207
|
+
}
|
|
4208
|
+
connect() {
|
|
4209
|
+
this.connection.connect();
|
|
4210
|
+
if (this.timelineSender) {
|
|
4211
|
+
if (!this.timelineSenderTimer) {
|
|
4212
|
+
var usingTLS = this.connection.isUsingTLS();
|
|
4213
|
+
var timelineSender = this.timelineSender;
|
|
4214
|
+
this.timelineSenderTimer = new PeriodicTimer(60000, function () {
|
|
4215
|
+
timelineSender.send(usingTLS);
|
|
4216
|
+
});
|
|
4217
|
+
}
|
|
4218
|
+
}
|
|
4219
|
+
}
|
|
4220
|
+
disconnect() {
|
|
4221
|
+
this.connection.disconnect();
|
|
4222
|
+
if (this.timelineSenderTimer) {
|
|
4223
|
+
this.timelineSenderTimer.ensureAborted();
|
|
4224
|
+
this.timelineSenderTimer = null;
|
|
4225
|
+
}
|
|
4226
|
+
}
|
|
4227
|
+
bind(event_name, callback, context) {
|
|
4228
|
+
this.global_emitter.bind(event_name, callback, context);
|
|
4229
|
+
return this;
|
|
4230
|
+
}
|
|
4231
|
+
unbind(event_name, callback, context) {
|
|
4232
|
+
this.global_emitter.unbind(event_name, callback, context);
|
|
4233
|
+
return this;
|
|
4234
|
+
}
|
|
4235
|
+
bind_global(callback) {
|
|
4236
|
+
this.global_emitter.bind_global(callback);
|
|
4237
|
+
return this;
|
|
4238
|
+
}
|
|
4239
|
+
unbind_global(callback) {
|
|
4240
|
+
this.global_emitter.unbind_global(callback);
|
|
4241
|
+
return this;
|
|
4242
|
+
}
|
|
4243
|
+
unbind_all(callback) {
|
|
4244
|
+
this.global_emitter.unbind_all();
|
|
4245
|
+
return this;
|
|
4246
|
+
}
|
|
4247
|
+
subscribeAll() {
|
|
4248
|
+
var channelName;
|
|
4249
|
+
for (channelName in this.channels.channels) {
|
|
4250
|
+
if (this.channels.channels.hasOwnProperty(channelName)) {
|
|
4251
|
+
this.subscribe(channelName);
|
|
4252
|
+
}
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4255
|
+
subscribe(channel_name) {
|
|
4256
|
+
var channel = this.channels.add(channel_name, this);
|
|
4257
|
+
if (channel.subscriptionPending && channel.subscriptionCancelled) {
|
|
4258
|
+
channel.reinstateSubscription();
|
|
4259
|
+
}
|
|
4260
|
+
else if (!channel.subscriptionPending &&
|
|
4261
|
+
this.connection.state === 'connected') {
|
|
4262
|
+
channel.subscribe();
|
|
4263
|
+
}
|
|
4264
|
+
return channel;
|
|
4265
|
+
}
|
|
4266
|
+
unsubscribe(channel_name) {
|
|
4267
|
+
var channel = this.channels.find(channel_name);
|
|
4268
|
+
if (channel && channel.subscriptionPending) {
|
|
4269
|
+
channel.cancelSubscription();
|
|
4270
|
+
}
|
|
4271
|
+
else {
|
|
4272
|
+
channel = this.channels.remove(channel_name);
|
|
4273
|
+
if (channel && channel.subscribed) {
|
|
4274
|
+
channel.unsubscribe();
|
|
4275
|
+
}
|
|
4276
|
+
}
|
|
4277
|
+
}
|
|
4278
|
+
send_event(event_name, data, channel) {
|
|
4279
|
+
return this.connection.send_event(event_name, data, channel);
|
|
4280
|
+
}
|
|
4281
|
+
shouldUseTLS() {
|
|
4282
|
+
return this.config.useTLS;
|
|
4283
|
+
}
|
|
4284
|
+
signin() {
|
|
4285
|
+
this.user.signin();
|
|
4286
|
+
}
|
|
4287
|
+
}
|
|
4288
|
+
Pusher.instances = [];
|
|
4289
|
+
Pusher.isReady = false;
|
|
4290
|
+
Pusher.logToConsole = false;
|
|
4291
|
+
Pusher.Runtime = runtime;
|
|
4292
|
+
Pusher.ScriptReceivers = runtime.ScriptReceivers;
|
|
4293
|
+
Pusher.DependenciesReceivers = runtime.DependenciesReceivers;
|
|
4294
|
+
Pusher.auth_callbacks = runtime.auth_callbacks;
|
|
4295
|
+
/* harmony default export */ const pusher = (Pusher);
|
|
4296
|
+
function checkAppKey(key) {
|
|
4297
|
+
if (key === null || key === undefined) {
|
|
4298
|
+
throw 'You must pass your app key when you instantiate Pusher.';
|
|
4299
|
+
}
|
|
4300
|
+
}
|
|
4301
|
+
runtime.setup(Pusher);
|
|
4302
|
+
|
|
4303
|
+
|
|
4304
|
+
/***/ }
|
|
4305
|
+
|
|
4306
|
+
/******/ });
|
|
4307
|
+
/************************************************************************/
|
|
4308
|
+
/******/ // The module cache
|
|
4309
|
+
/******/ var __webpack_module_cache__ = {};
|
|
4310
|
+
/******/
|
|
4311
|
+
/******/ // The require function
|
|
4312
|
+
/******/ function __webpack_require__(moduleId) {
|
|
4313
|
+
/******/ // Check if module is in cache
|
|
4314
|
+
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
|
4315
|
+
/******/ if (cachedModule !== undefined) {
|
|
4316
|
+
/******/ return cachedModule.exports;
|
|
4317
|
+
/******/ }
|
|
4318
|
+
/******/ // Create a new module (and put it into the cache)
|
|
4319
|
+
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
4320
|
+
/******/ // no module.id needed
|
|
4321
|
+
/******/ // no module.loaded needed
|
|
4322
|
+
/******/ exports: {}
|
|
4323
|
+
/******/ };
|
|
4324
|
+
/******/
|
|
4325
|
+
/******/ // Execute the module function
|
|
4326
|
+
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
4327
|
+
/******/
|
|
4328
|
+
/******/ // Return the exports of the module
|
|
4329
|
+
/******/ return module.exports;
|
|
4330
|
+
/******/ }
|
|
4331
|
+
/******/
|
|
4332
|
+
/************************************************************************/
|
|
4333
|
+
/******/ /* webpack/runtime/define property getters */
|
|
4334
|
+
/******/ (() => {
|
|
4335
|
+
/******/ // define getter functions for harmony exports
|
|
4336
|
+
/******/ __webpack_require__.d = (exports, definition) => {
|
|
4337
|
+
/******/ for(var key in definition) {
|
|
4338
|
+
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
|
4339
|
+
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
|
4340
|
+
/******/ }
|
|
4341
|
+
/******/ }
|
|
4342
|
+
/******/ };
|
|
4343
|
+
/******/ })();
|
|
4344
|
+
/******/
|
|
4345
|
+
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
4346
|
+
/******/ (() => {
|
|
4347
|
+
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop));
|
|
4348
|
+
/******/ })();
|
|
4349
|
+
/******/
|
|
4350
|
+
/************************************************************************/
|
|
4351
|
+
/******/
|
|
4352
|
+
/******/ // startup
|
|
4353
|
+
/******/ // Load entry module and return exports
|
|
4354
|
+
/******/ // This entry module used 'module' so it can't be inlined
|
|
4355
|
+
/******/ var __webpack_exports__ = __webpack_require__(721);
|
|
4356
|
+
/******/
|
|
4357
|
+
/******/ return __webpack_exports__;
|
|
4358
|
+
/******/ })()
|
|
4359
|
+
;
|
|
4360
|
+
});
|
|
4361
|
+
|
|
4362
|
+
} (pusher));
|
|
4363
|
+
return pusher.exports;
|
|
4364
|
+
}
|
|
4365
|
+
|
|
4366
|
+
var pusherExports = requirePusher();
|
|
4367
|
+
var Pusher = /*@__PURE__*/getDefaultExportFromCjs(pusherExports);
|
|
4368
|
+
|
|
4369
|
+
const DEFAULT_HOST = 'eu-central-1.wireblob.com';
|
|
4370
|
+
|
|
4371
|
+
class Wire {
|
|
4372
|
+
constructor(appKey, options = {}) {
|
|
4373
|
+
if (!appKey || typeof appKey !== 'string') {
|
|
4374
|
+
throw new TypeError('Wire requires a valid appKey string.');
|
|
4375
|
+
}
|
|
4376
|
+
|
|
4377
|
+
const secure = options.secure ?? true;
|
|
4378
|
+
const host = options.host ?? DEFAULT_HOST;
|
|
4379
|
+
|
|
4380
|
+
const pusherOptions = {
|
|
4381
|
+
wsHost: host,
|
|
4382
|
+
forceTLS: secure,
|
|
4383
|
+
wsPort: options.wsPort ?? 80,
|
|
4384
|
+
wssPort: options.wssPort ?? 443,
|
|
4385
|
+
enabledTransports: options.enabledTransports ?? ['ws', 'wss'],
|
|
4386
|
+
cluster: ''
|
|
4387
|
+
};
|
|
4388
|
+
|
|
4389
|
+
if (options.authEndpoint) {
|
|
4390
|
+
pusherOptions.authEndpoint = options.authEndpoint;
|
|
4391
|
+
}
|
|
4392
|
+
|
|
4393
|
+
if (options.auth) {
|
|
4394
|
+
pusherOptions.auth = options.auth;
|
|
4395
|
+
}
|
|
4396
|
+
|
|
4397
|
+
this.pusher = new Pusher(appKey, pusherOptions);
|
|
4398
|
+
this.connection = this.pusher.connection;
|
|
4399
|
+
}
|
|
4400
|
+
|
|
4401
|
+
subscribe(channelName) {
|
|
4402
|
+
return this.pusher.subscribe(channelName);
|
|
4403
|
+
}
|
|
4404
|
+
|
|
4405
|
+
unsubscribe(channelName) {
|
|
4406
|
+
this.pusher.unsubscribe(channelName);
|
|
4407
|
+
}
|
|
4408
|
+
|
|
4409
|
+
connect() {
|
|
4410
|
+
this.pusher.connect();
|
|
4411
|
+
}
|
|
4412
|
+
|
|
4413
|
+
disconnect() {
|
|
4414
|
+
this.pusher.disconnect();
|
|
4415
|
+
}
|
|
4416
|
+
|
|
4417
|
+
static get logToConsole() {
|
|
4418
|
+
return Pusher.logToConsole;
|
|
4419
|
+
}
|
|
4420
|
+
|
|
4421
|
+
static set logToConsole(value) {
|
|
4422
|
+
Pusher.logToConsole = Boolean(value);
|
|
4423
|
+
}
|
|
4424
|
+
}
|
|
4425
|
+
|
|
4426
|
+
return Wire;
|
|
4427
|
+
|
|
4428
|
+
}));
|