laravel-echo-api-gateway 0.5.8 → 0.5.9
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/.eslintrc.js +1 -0
- package/.github/workflows/ci.yml +49 -45
- package/README.md +93 -17
- package/dist/Channel.d.ts +89 -0
- package/dist/Connector.d.ts +92 -0
- package/dist/EventFormatter.d.ts +10 -0
- package/dist/Websocket.d.ts +78 -0
- package/dist/laravel-echo-api-gateway.common.js +403 -762
- package/dist/laravel-echo-api-gateway.iife.js +487 -846
- package/dist/laravel-echo-api-gateway.js +401 -760
- package/jest.config.js +3 -7
- package/js-src/Channel.ts +74 -62
- package/js-src/Connector.ts +100 -40
- package/js-src/EventFormatter.ts +24 -0
- package/js-src/Websocket.ts +217 -168
- package/js-tests/Connector.test.ts +295 -60
- package/js-tests/EchoCompatibility.test.ts +96 -0
- package/js-tests/helpers.ts +37 -0
- package/package.json +23 -30
- package/phpstan.neon.dist +3 -12
- package/phpunit.xml +2 -2
- package/rollup.config.mjs +14 -0
- package/tsconfig.json +6 -6
- package/dist/js-src/Channel.d.ts +0 -68
- package/dist/js-src/Connector.d.ts +0 -49
- package/dist/js-src/Websocket.d.ts +0 -38
- package/rollup.config.js +0 -31
|
@@ -1,875 +1,516 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (!(instance instanceof Constructor)) {
|
|
7
|
-
throw new TypeError("Cannot call a class as a function");
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function _defineProperties(target, props) {
|
|
12
|
-
for (var i = 0; i < props.length; i++) {
|
|
13
|
-
var descriptor = props[i];
|
|
14
|
-
descriptor.enumerable = descriptor.enumerable || false;
|
|
15
|
-
descriptor.configurable = true;
|
|
16
|
-
if ("value" in descriptor) descriptor.writable = true;
|
|
17
|
-
Object.defineProperty(target, descriptor.key, descriptor);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function _createClass(Constructor, protoProps, staticProps) {
|
|
22
|
-
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
23
|
-
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
24
|
-
Object.defineProperty(Constructor, "prototype", {
|
|
25
|
-
writable: false
|
|
26
|
-
});
|
|
27
|
-
return Constructor;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function _extends() {
|
|
31
|
-
_extends = Object.assign || function (target) {
|
|
32
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
33
|
-
var source = arguments[i];
|
|
34
|
-
|
|
35
|
-
for (var key in source) {
|
|
36
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
37
|
-
target[key] = source[key];
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return target;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
return _extends.apply(this, arguments);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function _inherits(subClass, superClass) {
|
|
49
|
-
if (typeof superClass !== "function" && superClass !== null) {
|
|
50
|
-
throw new TypeError("Super expression must either be null or a function");
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
Object.defineProperty(subClass, "prototype", {
|
|
54
|
-
value: Object.create(superClass && superClass.prototype, {
|
|
55
|
-
constructor: {
|
|
56
|
-
value: subClass,
|
|
57
|
-
writable: true,
|
|
58
|
-
configurable: true
|
|
59
|
-
}
|
|
60
|
-
}),
|
|
61
|
-
writable: false
|
|
62
|
-
});
|
|
63
|
-
if (superClass) _setPrototypeOf(subClass, superClass);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function _getPrototypeOf(o) {
|
|
67
|
-
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
|
|
68
|
-
return o.__proto__ || Object.getPrototypeOf(o);
|
|
69
|
-
};
|
|
70
|
-
return _getPrototypeOf(o);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function _setPrototypeOf(o, p) {
|
|
74
|
-
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
|
|
75
|
-
o.__proto__ = p;
|
|
76
|
-
return o;
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
return _setPrototypeOf(o, p);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function _isNativeReflectConstruct() {
|
|
83
|
-
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
|
|
84
|
-
if (Reflect.construct.sham) return false;
|
|
85
|
-
if (typeof Proxy === "function") return true;
|
|
86
|
-
|
|
87
|
-
try {
|
|
88
|
-
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
|
|
89
|
-
return true;
|
|
90
|
-
} catch (e) {
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function _assertThisInitialized(self) {
|
|
96
|
-
if (self === void 0) {
|
|
97
|
-
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return self;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function _possibleConstructorReturn(self, call) {
|
|
104
|
-
if (call && (typeof call === "object" || typeof call === "function")) {
|
|
105
|
-
return call;
|
|
106
|
-
} else if (call !== void 0) {
|
|
107
|
-
throw new TypeError("Derived constructors may only return object or undefined");
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return _assertThisInitialized(self);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function _createSuper(Derived) {
|
|
114
|
-
var hasNativeReflectConstruct = _isNativeReflectConstruct();
|
|
115
|
-
|
|
116
|
-
return function _createSuperInternal() {
|
|
117
|
-
var Super = _getPrototypeOf(Derived),
|
|
118
|
-
result;
|
|
119
|
-
|
|
120
|
-
if (hasNativeReflectConstruct) {
|
|
121
|
-
var NewTarget = _getPrototypeOf(this).constructor;
|
|
122
|
-
|
|
123
|
-
result = Reflect.construct(Super, arguments, NewTarget);
|
|
124
|
-
} else {
|
|
125
|
-
result = Super.apply(this, arguments);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return _possibleConstructorReturn(this, result);
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function _unsupportedIterableToArray(o, minLen) {
|
|
133
|
-
if (!o) return;
|
|
134
|
-
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
135
|
-
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
136
|
-
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
137
|
-
if (n === "Map" || n === "Set") return Array.from(o);
|
|
138
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function _arrayLikeToArray(arr, len) {
|
|
142
|
-
if (len == null || len > arr.length) len = arr.length;
|
|
143
|
-
|
|
144
|
-
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
|
145
|
-
|
|
146
|
-
return arr2;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function _createForOfIteratorHelper(o, allowArrayLike) {
|
|
150
|
-
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
|
|
151
|
-
|
|
152
|
-
if (!it) {
|
|
153
|
-
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
|
|
154
|
-
if (it) o = it;
|
|
155
|
-
var i = 0;
|
|
156
|
-
|
|
157
|
-
var F = function () {};
|
|
158
|
-
|
|
159
|
-
return {
|
|
160
|
-
s: F,
|
|
161
|
-
n: function () {
|
|
162
|
-
if (i >= o.length) return {
|
|
163
|
-
done: true
|
|
164
|
-
};
|
|
165
|
-
return {
|
|
166
|
-
done: false,
|
|
167
|
-
value: o[i++]
|
|
168
|
-
};
|
|
169
|
-
},
|
|
170
|
-
e: function (e) {
|
|
171
|
-
throw e;
|
|
172
|
-
},
|
|
173
|
-
f: F
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
var normalCompletion = true,
|
|
181
|
-
didErr = false,
|
|
182
|
-
err;
|
|
183
|
-
return {
|
|
184
|
-
s: function () {
|
|
185
|
-
it = it.call(o);
|
|
186
|
-
},
|
|
187
|
-
n: function () {
|
|
188
|
-
var step = it.next();
|
|
189
|
-
normalCompletion = step.done;
|
|
190
|
-
return step;
|
|
191
|
-
},
|
|
192
|
-
e: function (e) {
|
|
193
|
-
didErr = true;
|
|
194
|
-
err = e;
|
|
195
|
-
},
|
|
196
|
-
f: function () {
|
|
197
|
-
try {
|
|
198
|
-
if (!normalCompletion && it.return != null) it.return();
|
|
199
|
-
} finally {
|
|
200
|
-
if (didErr) throw err;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
class Connector {
|
|
207
|
-
/**
|
|
208
|
-
* Create a new class instance.
|
|
209
|
-
*/
|
|
3
|
+
const LOG_PREFIX$2 = '[LE-AG-Websocket]';
|
|
4
|
+
const OPEN = 1;
|
|
5
|
+
class Websocket {
|
|
210
6
|
constructor(options) {
|
|
7
|
+
this.buffer = [];
|
|
211
8
|
/**
|
|
212
|
-
*
|
|
9
|
+
* Every channel that should be subscribed, re-subscribed each time a new connection is identified.
|
|
213
10
|
*/
|
|
214
|
-
this.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
11
|
+
this.channels = new Map();
|
|
12
|
+
this.listeners = {};
|
|
13
|
+
this.closing = false;
|
|
14
|
+
this.reconnectAttempts = 0;
|
|
15
|
+
this.options = options;
|
|
16
|
+
if (this.options.host) {
|
|
17
|
+
this.connect();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
connect() {
|
|
21
|
+
const host = this.options.host;
|
|
22
|
+
this.debug(`Trying to connect to ${host}...`);
|
|
23
|
+
const websocket = new WebSocket(host);
|
|
24
|
+
this.websocket = websocket;
|
|
25
|
+
websocket.onopen = () => {
|
|
26
|
+
this.debug('Connected !');
|
|
27
|
+
this.reconnectAttempts = 0;
|
|
28
|
+
this.send({ event: 'whoami' });
|
|
29
|
+
while (this.buffer.length) {
|
|
30
|
+
this.send(this.buffer.shift());
|
|
31
|
+
}
|
|
32
|
+
this.startPing();
|
|
33
|
+
};
|
|
34
|
+
websocket.onmessage = (messageEvent) => {
|
|
35
|
+
this.handleMessage(messageEvent.data);
|
|
36
|
+
};
|
|
37
|
+
websocket.onerror = () => {
|
|
38
|
+
// A close event always follows an error, so reconnecting is handled in onclose.
|
|
39
|
+
this.debug('Connection error.');
|
|
40
|
+
};
|
|
41
|
+
websocket.onclose = () => {
|
|
42
|
+
if (this.websocket !== websocket) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.debug('Connection closed.');
|
|
46
|
+
this.stopPing();
|
|
47
|
+
this.socketId = undefined;
|
|
48
|
+
if (!this.closing) {
|
|
49
|
+
this.scheduleReconnect();
|
|
50
|
+
}
|
|
224
51
|
};
|
|
225
|
-
this.setOptions(options);
|
|
226
|
-
this.connect();
|
|
227
52
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
53
|
+
scheduleReconnect() {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
const baseDelay = (_a = this.options.reconnectDelay) !== null && _a !== void 0 ? _a : 1000;
|
|
56
|
+
const maxDelay = (_b = this.options.maxReconnectDelay) !== null && _b !== void 0 ? _b : 30000;
|
|
57
|
+
const delay = Math.min(baseDelay * 2 ** this.reconnectAttempts, maxDelay);
|
|
58
|
+
this.reconnectAttempts++;
|
|
59
|
+
this.debug(`Connection lost, reconnecting in ${delay}ms...`);
|
|
60
|
+
clearTimeout(this.reconnectTimer);
|
|
61
|
+
this.reconnectTimer = setTimeout(() => this.connect(), delay);
|
|
62
|
+
}
|
|
63
|
+
startPing() {
|
|
64
|
+
var _a;
|
|
65
|
+
this.stopPing();
|
|
66
|
+
this.pingTimer = setInterval(() => {
|
|
67
|
+
if (this.socketIsReady()) {
|
|
68
|
+
this.debug('Sending ping');
|
|
69
|
+
this.send({ event: 'ping' });
|
|
70
|
+
}
|
|
71
|
+
}, (_a = this.options.pingInterval) !== null && _a !== void 0 ? _a : 60 * 1000);
|
|
237
72
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
73
|
+
stopPing() {
|
|
74
|
+
clearInterval(this.pingTimer);
|
|
75
|
+
this.pingTimer = undefined;
|
|
76
|
+
}
|
|
77
|
+
handleMessage(body) {
|
|
78
|
+
var _a;
|
|
79
|
+
const message = this.parseMessage(body);
|
|
80
|
+
if (!message) {
|
|
81
|
+
return;
|
|
245
82
|
}
|
|
246
|
-
|
|
247
|
-
|
|
83
|
+
this.debug('onmessage', body);
|
|
84
|
+
if (message.channel) {
|
|
85
|
+
this.dispatch(message.channel, message.event, message.data);
|
|
86
|
+
return;
|
|
248
87
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
(
|
|
252
|
-
|
|
88
|
+
if (message.event === 'whoami') {
|
|
89
|
+
this.socketId = (_a = message.data) === null || _a === void 0 ? void 0 : _a.socket_id;
|
|
90
|
+
this.debug(`Just set socketId to ${this.socketId}`);
|
|
91
|
+
this.channels.forEach((channel) => this.actuallySubscribe(channel));
|
|
253
92
|
}
|
|
254
|
-
return null;
|
|
255
93
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
this.listeners = {};
|
|
265
|
-
this.internalListeners = {};
|
|
266
|
-
this.channelBacklog = [];
|
|
267
|
-
this.closing = false;
|
|
268
|
-
this.hasConnected = false;
|
|
269
|
-
this.options = options;
|
|
270
|
-
this.connect(this.options.host);
|
|
271
|
-
return this;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
_createClass(Websocket, [{
|
|
275
|
-
key: "connect",
|
|
276
|
-
value: function connect(host) {
|
|
277
|
-
var _this = this;
|
|
278
|
-
|
|
279
|
-
if (!host) {
|
|
280
|
-
this.options.debug && console.error(LOG_PREFIX + "Cannont connect without host !");
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
this.options.debug && console.log(LOG_PREFIX + "Trying to connect to ".concat(host, "..."));
|
|
285
|
-
this.websocket = new WebSocket(host);
|
|
286
|
-
|
|
287
|
-
this.websocket.onerror = function () {
|
|
288
|
-
if (!_this.hasConnected) {
|
|
289
|
-
setTimeout(function () {
|
|
290
|
-
_this.socketId = undefined;
|
|
291
|
-
|
|
292
|
-
_this.connect(host);
|
|
293
|
-
}, 3000);
|
|
94
|
+
dispatch(channelName, event, data) {
|
|
95
|
+
var _a, _b;
|
|
96
|
+
const callbacks = (_b = (_a = this.listeners[channelName]) === null || _a === void 0 ? void 0 : _a[event]) !== null && _b !== void 0 ? _b : [];
|
|
97
|
+
callbacks.slice().forEach((callback) => callback(data));
|
|
98
|
+
}
|
|
99
|
+
parseMessage(body) {
|
|
100
|
+
try {
|
|
101
|
+
return JSON.parse(body);
|
|
294
102
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
_this.buffer.splice(0, 1);
|
|
311
|
-
} // Register events only once connected, or they won't be registered if connection failed/lost
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
_this.websocket.onmessage = function (messageEvent) {
|
|
315
|
-
var message = _this.parseMessage(messageEvent.data);
|
|
316
|
-
|
|
317
|
-
_this.options.debug && console.log(LOG_PREFIX + ' onmessage', messageEvent.data);
|
|
318
|
-
|
|
319
|
-
if (!message) {
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (message.channel) {
|
|
324
|
-
_this.options.debug && console.log("".concat(LOG_PREFIX, " Received event ").concat(message.event, " on channel ").concat(message.channel));
|
|
325
|
-
|
|
326
|
-
if (_this.listeners[message.channel] && _this.listeners[message.channel][message.event]) {
|
|
327
|
-
_this.listeners[message.channel][message.event](message.data);
|
|
328
|
-
}
|
|
329
|
-
|
|
103
|
+
catch (error) {
|
|
104
|
+
this.options.debug && console.error(error);
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
getSocketId() {
|
|
109
|
+
return this.socketId;
|
|
110
|
+
}
|
|
111
|
+
socketIsReady() {
|
|
112
|
+
var _a;
|
|
113
|
+
return ((_a = this.websocket) === null || _a === void 0 ? void 0 : _a.readyState) === OPEN;
|
|
114
|
+
}
|
|
115
|
+
send(message) {
|
|
116
|
+
if (this.socketIsReady()) {
|
|
117
|
+
this.websocket.send(JSON.stringify(message));
|
|
330
118
|
return;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
if (_this.internalListeners[message.event]) {
|
|
334
|
-
_this.internalListeners[message.event](message.data);
|
|
335
|
-
}
|
|
336
|
-
}; // send ping every 60 seconds to keep connection alive
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
_this.pingInterval = setInterval(function () {
|
|
340
|
-
if (_this.websocket.readyState === _this.websocket.OPEN) {
|
|
341
|
-
_this.options.debug && console.log(LOG_PREFIX + ' Sending ping');
|
|
342
|
-
|
|
343
|
-
_this.send({
|
|
344
|
-
event: 'ping'
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
}, 60 * 1000);
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
this.websocket.onclose = function () {
|
|
351
|
-
_this.options.debug && console.info('Connection closed.');
|
|
352
|
-
|
|
353
|
-
if (_this.closing) {
|
|
354
|
-
return;
|
|
355
119
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
_this.options.debug && console.log("".concat(LOG_PREFIX, " Just set socketId to ").concat(socketId)); // Handle the backlog and don't empty it, we'll need it if we lose connection
|
|
370
|
-
|
|
371
|
-
var channel;
|
|
372
|
-
|
|
373
|
-
var _iterator = _createForOfIteratorHelper(_this.channelBacklog),
|
|
374
|
-
_step;
|
|
375
|
-
|
|
376
|
-
try {
|
|
377
|
-
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
378
|
-
channel = _step.value;
|
|
379
|
-
|
|
380
|
-
_this.actuallySubscribe(channel);
|
|
381
|
-
}
|
|
382
|
-
} catch (err) {
|
|
383
|
-
_iterator.e(err);
|
|
384
|
-
} finally {
|
|
385
|
-
_iterator.f();
|
|
120
|
+
this.buffer.push(message);
|
|
121
|
+
}
|
|
122
|
+
close() {
|
|
123
|
+
var _a;
|
|
124
|
+
this.closing = true;
|
|
125
|
+
clearTimeout(this.reconnectTimer);
|
|
126
|
+
this.stopPing();
|
|
127
|
+
(_a = this.websocket) === null || _a === void 0 ? void 0 : _a.close();
|
|
128
|
+
}
|
|
129
|
+
subscribe(channel) {
|
|
130
|
+
this.channels.set(channel.name, channel);
|
|
131
|
+
if (this.socketId && this.socketIsReady()) {
|
|
132
|
+
this.actuallySubscribe(channel);
|
|
386
133
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
}, {
|
|
390
|
-
key: "parseMessage",
|
|
391
|
-
value: function parseMessage(body) {
|
|
392
|
-
try {
|
|
393
|
-
return JSON.parse(body);
|
|
394
|
-
} catch (error) {
|
|
395
|
-
this.options.debug && console.error(error);
|
|
396
|
-
return undefined;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}, {
|
|
400
|
-
key: "getSocketId",
|
|
401
|
-
value: function getSocketId() {
|
|
402
|
-
return this.socketId;
|
|
403
|
-
}
|
|
404
|
-
}, {
|
|
405
|
-
key: "socketIsReady",
|
|
406
|
-
value: function socketIsReady() {
|
|
407
|
-
return this.websocket.readyState === this.websocket.OPEN;
|
|
408
|
-
}
|
|
409
|
-
}, {
|
|
410
|
-
key: "send",
|
|
411
|
-
value: function send(message) {
|
|
412
|
-
if (this.socketIsReady()) {
|
|
413
|
-
this.websocket.send(JSON.stringify(message));
|
|
414
|
-
return;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
this.buffer.push(message);
|
|
418
|
-
}
|
|
419
|
-
}, {
|
|
420
|
-
key: "close",
|
|
421
|
-
value: function close() {
|
|
422
|
-
this.closing = true;
|
|
423
|
-
this.internalListeners = {};
|
|
424
|
-
clearInterval(this.pingInterval);
|
|
425
|
-
this.pingInterval = undefined;
|
|
426
|
-
this.websocket.close();
|
|
427
|
-
}
|
|
428
|
-
}, {
|
|
429
|
-
key: "subscribe",
|
|
430
|
-
value: function subscribe(channel) {
|
|
431
|
-
if (this.getSocketId()) {
|
|
432
|
-
this.actuallySubscribe(channel);
|
|
433
|
-
} else {
|
|
434
|
-
this.options.debug && console.log("".concat(LOG_PREFIX, " subscribe - push channel backlog for channel ").concat(channel.name));
|
|
435
|
-
this.channelBacklog.push(channel);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
}, {
|
|
439
|
-
key: "actuallySubscribe",
|
|
440
|
-
value: function actuallySubscribe(channel) {
|
|
441
|
-
var _this2 = this;
|
|
442
|
-
|
|
443
|
-
if (channel.name.startsWith('private-') || channel.name.startsWith('presence-')) {
|
|
444
|
-
this.options.debug && console.log("".concat(LOG_PREFIX, " Sending auth request for channel ").concat(channel.name));
|
|
445
|
-
|
|
446
|
-
if (this.options.bearerToken) {
|
|
447
|
-
this.options.auth.headers['Authorization'] = 'Bearer ' + this.options.bearerToken;
|
|
134
|
+
else {
|
|
135
|
+
this.debug(`Channel ${channel.name} will be subscribed once connected`);
|
|
448
136
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
'
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
}).
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
_this2.send({
|
|
469
|
-
event: 'subscribe',
|
|
470
|
-
data: _extends({
|
|
471
|
-
channel: channel.name
|
|
472
|
-
}, data)
|
|
473
|
-
});
|
|
474
|
-
})["catch"](function (error) {
|
|
475
|
-
_this2.options.debug && console.log("".concat(LOG_PREFIX, " Auth request for channel ").concat(channel.name, " failed"));
|
|
476
|
-
_this2.options.debug && console.error(error);
|
|
137
|
+
}
|
|
138
|
+
actuallySubscribe(channel) {
|
|
139
|
+
if (!channel.name.startsWith('private-') && !channel.name.startsWith('presence-')) {
|
|
140
|
+
this.debug(`Subscribing to channel ${channel.name}`);
|
|
141
|
+
this.send({ event: 'subscribe', data: { channel: channel.name } });
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const socketId = this.socketId;
|
|
145
|
+
this.debug(`Sending auth request for channel ${channel.name}`);
|
|
146
|
+
this.authorize(channel.name, socketId).then((data) => {
|
|
147
|
+
// Skip outdated authorizations: the connection changed or the channel was left meanwhile.
|
|
148
|
+
if (socketId !== this.socketId || this.channels.get(channel.name) !== channel) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
this.debug(`Subscribing to private channel ${channel.name}`);
|
|
152
|
+
this.send({ event: 'subscribe', data: Object.assign({ channel: channel.name }, data) });
|
|
153
|
+
}).catch((error) => {
|
|
154
|
+
this.debug(`Auth request for channel ${channel.name} failed`, error);
|
|
155
|
+
this.dispatch(channel.name, 'error', error);
|
|
477
156
|
});
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
157
|
+
}
|
|
158
|
+
authorize(channelName, socketId) {
|
|
159
|
+
var _a, _b, _c;
|
|
160
|
+
const channelAuthorization = (_a = this.options.channelAuthorization) !== null && _a !== void 0 ? _a : {};
|
|
161
|
+
if (typeof channelAuthorization.customHandler === 'function') {
|
|
162
|
+
return new Promise((resolve, reject) => {
|
|
163
|
+
channelAuthorization.customHandler({ socketId, channelName }, (error, data) => {
|
|
164
|
+
var _a;
|
|
165
|
+
if (error) {
|
|
166
|
+
reject(this.authorizationError(error, (_a = error === null || error === void 0 ? void 0 : error.status) !== null && _a !== void 0 ? _a : null));
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
resolve(data);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return fetch((_b = channelAuthorization.endpoint) !== null && _b !== void 0 ? _b : this.options.authEndpoint, {
|
|
175
|
+
method: 'POST',
|
|
176
|
+
headers: Object.assign(Object.assign({ 'Content-Type': 'application/json', 'Accept': 'application/json' }, (_c = this.options.auth) === null || _c === void 0 ? void 0 : _c.headers), channelAuthorization.headers),
|
|
177
|
+
body: JSON.stringify({
|
|
178
|
+
socket_id: socketId,
|
|
179
|
+
channel_name: channelName,
|
|
180
|
+
}),
|
|
181
|
+
}).then((response) => {
|
|
182
|
+
if (!response.ok) {
|
|
183
|
+
throw this.authorizationError(new Error(`Auth request failed: ${response.status}`), response.status);
|
|
184
|
+
}
|
|
185
|
+
return response.json();
|
|
186
|
+
}, (error) => {
|
|
187
|
+
throw this.authorizationError(error, null);
|
|
485
188
|
});
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
189
|
+
}
|
|
190
|
+
authorizationError(error, status) {
|
|
191
|
+
return { type: 'AuthError', status, error };
|
|
192
|
+
}
|
|
193
|
+
unsubscribe(channel) {
|
|
194
|
+
this.debug(`unsubscribe for channel ${channel.name}`);
|
|
195
|
+
if (this.channels.get(channel.name) === channel) {
|
|
196
|
+
this.channels.delete(channel.name);
|
|
197
|
+
delete this.listeners[channel.name];
|
|
198
|
+
}
|
|
199
|
+
if (this.socketId && this.socketIsReady()) {
|
|
200
|
+
this.send({ event: 'unsubscribe', data: { channel: channel.name } });
|
|
496
201
|
}
|
|
497
|
-
});
|
|
498
|
-
|
|
499
|
-
if (this.listeners[channel.name]) {
|
|
500
|
-
delete this.listeners[channel.name];
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
}, {
|
|
504
|
-
key: "on",
|
|
505
|
-
value: function on(event) {
|
|
506
|
-
var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
507
|
-
this.options.debug && console.log("".concat(LOG_PREFIX, " on event ").concat(event, " ..."));
|
|
508
|
-
this.internalListeners[event] = callback;
|
|
509
|
-
}
|
|
510
|
-
}, {
|
|
511
|
-
key: "bind",
|
|
512
|
-
value: function bind(channel, event, callback) {
|
|
513
|
-
this.options.debug && console.log("".concat(LOG_PREFIX, " bind event ").concat(event, " for channel ").concat(channel.name, " ..."));
|
|
514
|
-
|
|
515
|
-
if (!this.listeners[channel.name]) {
|
|
516
|
-
this.listeners[channel.name] = {};
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
this.listeners[channel.name][event] = callback;
|
|
520
202
|
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
203
|
+
bind(channel, event, callback) {
|
|
204
|
+
var _a, _b;
|
|
205
|
+
var _c, _d, _e;
|
|
206
|
+
this.debug(`bind event ${event} for channel ${channel.name} ...`);
|
|
207
|
+
(_a = (_c = this.listeners)[_d = channel.name]) !== null && _a !== void 0 ? _a : (_c[_d] = {});
|
|
208
|
+
(_b = (_e = this.listeners[channel.name])[event]) !== null && _b !== void 0 ? _b : (_e[event] = []);
|
|
209
|
+
this.listeners[channel.name][event].push(callback);
|
|
210
|
+
}
|
|
211
|
+
unbind(channel, event, callback) {
|
|
212
|
+
var _a;
|
|
213
|
+
this.debug(`unbind event ${event} for channel ${channel.name} ...`);
|
|
214
|
+
const callbacks = (_a = this.listeners[channel.name]) === null || _a === void 0 ? void 0 : _a[event];
|
|
215
|
+
if (!callbacks) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (callback) {
|
|
219
|
+
this.listeners[channel.name][event] = callbacks.filter((existing) => existing !== callback);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
delete this.listeners[channel.name][event];
|
|
223
|
+
}
|
|
530
224
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
}
|
|
225
|
+
debug(...messages) {
|
|
226
|
+
this.options.debug && console.log(LOG_PREFIX$2, ...messages);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
535
229
|
|
|
536
230
|
/**
|
|
537
|
-
*
|
|
231
|
+
* Formats event names the same way laravel-echo does, so `listen('OrderCreated')` matches
|
|
232
|
+
* `App\Events\OrderCreated` and `listen('.custom-name')` matches `custom-name`.
|
|
538
233
|
*/
|
|
539
234
|
class EventFormatter {
|
|
540
|
-
/**
|
|
541
|
-
* Create a new class instance.
|
|
542
|
-
*/
|
|
543
235
|
constructor(namespace) {
|
|
544
|
-
this.
|
|
236
|
+
this.namespace = namespace;
|
|
545
237
|
}
|
|
546
|
-
/**
|
|
547
|
-
* Format the given event name.
|
|
548
|
-
*/
|
|
549
238
|
format(event) {
|
|
550
|
-
if (
|
|
551
|
-
return event.
|
|
239
|
+
if (['.', '\\'].includes(event.charAt(0))) {
|
|
240
|
+
return event.substring(1);
|
|
552
241
|
}
|
|
553
|
-
|
|
242
|
+
if (this.namespace) {
|
|
554
243
|
event = this.namespace + '.' + event;
|
|
555
244
|
}
|
|
556
245
|
return event.replace(/\./g, '\\');
|
|
557
246
|
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
*/
|
|
561
|
-
setNamespace(value) {
|
|
562
|
-
this.namespace = value;
|
|
247
|
+
setNamespace(namespace) {
|
|
248
|
+
this.namespace = namespace;
|
|
563
249
|
}
|
|
564
250
|
}
|
|
565
251
|
|
|
252
|
+
const LOG_PREFIX$1 = '[LE-AG-Channel]';
|
|
253
|
+
const NOTIFICATION_EVENT = '.Illuminate\\Notifications\\Events\\BroadcastNotificationCreated';
|
|
566
254
|
/**
|
|
567
|
-
*
|
|
255
|
+
* A channel on the API Gateway websocket. It implements the public, private and presence channel
|
|
256
|
+
* interfaces of laravel-echo (v1 and v2) without extending its internal classes.
|
|
568
257
|
*/
|
|
569
258
|
class Channel {
|
|
259
|
+
/**
|
|
260
|
+
* Create a new class instance.
|
|
261
|
+
*/
|
|
262
|
+
constructor(socket, name, options) {
|
|
263
|
+
this.name = name;
|
|
264
|
+
this.socket = socket;
|
|
265
|
+
this.options = options;
|
|
266
|
+
this.eventFormatter = new EventFormatter(this.options.namespace);
|
|
267
|
+
this.subscribe();
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Subscribe to the channel.
|
|
271
|
+
*/
|
|
272
|
+
subscribe() {
|
|
273
|
+
this.options.debug && console.log(`${LOG_PREFIX$1} subscribe for channel ${this.name} ...`);
|
|
274
|
+
this.socket.subscribe(this);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Unsubscribe from the channel.
|
|
278
|
+
*/
|
|
279
|
+
unsubscribe() {
|
|
280
|
+
this.options.debug && console.log(`${LOG_PREFIX$1} unsubscribe for channel ${this.name} ...`);
|
|
281
|
+
this.socket.unsubscribe(this);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Listen for an event on the channel instance.
|
|
285
|
+
*/
|
|
286
|
+
listen(event, callback) {
|
|
287
|
+
this.options.debug && console.log(`${LOG_PREFIX$1} listen to ${event} for channel ${this.name} ...`);
|
|
288
|
+
return this.on(this.eventFormatter.format(event), callback);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Stop listening for an event on the channel instance. Without a callback, every listener of the event is removed.
|
|
292
|
+
*/
|
|
293
|
+
stopListening(event, callback) {
|
|
294
|
+
this.options.debug && console.log(`${LOG_PREFIX$1} stop listening to ${event} for channel ${this.name} ...`);
|
|
295
|
+
this.socket.unbind(this, this.eventFormatter.format(event), callback);
|
|
296
|
+
return this;
|
|
297
|
+
}
|
|
570
298
|
/**
|
|
571
299
|
* Listen for a whisper event on the channel instance.
|
|
572
300
|
*/
|
|
573
301
|
listenForWhisper(event, callback) {
|
|
574
302
|
return this.listen('.client-' + event, callback);
|
|
575
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Stop listening for a whisper event on the channel instance.
|
|
306
|
+
*/
|
|
307
|
+
stopListeningForWhisper(event, callback) {
|
|
308
|
+
return this.stopListening('.client-' + event, callback);
|
|
309
|
+
}
|
|
576
310
|
/**
|
|
577
311
|
* Listen for an event on the channel instance.
|
|
578
312
|
*/
|
|
579
313
|
notification(callback) {
|
|
580
|
-
return this.listen(
|
|
314
|
+
return this.listen(NOTIFICATION_EVENT, callback);
|
|
581
315
|
}
|
|
582
316
|
/**
|
|
583
|
-
* Stop listening for
|
|
317
|
+
* Stop listening for notification events on the channel instance.
|
|
584
318
|
*/
|
|
585
|
-
|
|
586
|
-
return this.stopListening(
|
|
319
|
+
stopListeningForNotification(callback) {
|
|
320
|
+
return this.stopListening(NOTIFICATION_EVENT, callback);
|
|
587
321
|
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
var Channel$1 = /*#__PURE__*/function (_BaseChannel) {
|
|
596
|
-
_inherits(Channel, _BaseChannel);
|
|
597
|
-
|
|
598
|
-
var _super = _createSuper(Channel);
|
|
599
|
-
|
|
600
|
-
/**
|
|
601
|
-
* Create a new class instance.
|
|
602
|
-
*/
|
|
603
|
-
function Channel(socket, name, options) {
|
|
604
|
-
var _this;
|
|
605
|
-
|
|
606
|
-
_classCallCheck(this, Channel);
|
|
607
|
-
|
|
608
|
-
_this = _super.call(this);
|
|
609
|
-
_this.name = name;
|
|
610
|
-
_this.socket = socket;
|
|
611
|
-
_this.options = options;
|
|
612
|
-
_this.eventFormatter = new EventFormatter(_this.options["namespace"]);
|
|
613
|
-
|
|
614
|
-
_this.subscribe();
|
|
615
|
-
|
|
616
|
-
return _this;
|
|
617
|
-
}
|
|
618
|
-
/**
|
|
619
|
-
* Subscribe to a Pusher channel.
|
|
620
|
-
*/
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
_createClass(Channel, [{
|
|
624
|
-
key: "subscribe",
|
|
625
|
-
value: function subscribe() {
|
|
626
|
-
this.options["debug"] && console.log("".concat(LOG_PREFIX$1, " subscribe for channel ").concat(this.name, " ..."));
|
|
627
|
-
this.socket.subscribe(this);
|
|
322
|
+
/**
|
|
323
|
+
* Register a callback to be called anytime a subscription succeeds.
|
|
324
|
+
*/
|
|
325
|
+
subscribed(callback) {
|
|
326
|
+
return this.on('subscription_succeeded', () => {
|
|
327
|
+
callback();
|
|
328
|
+
});
|
|
628
329
|
}
|
|
629
330
|
/**
|
|
630
|
-
*
|
|
331
|
+
* Register a callback to be called anytime a subscription or authorization error occurs.
|
|
631
332
|
*/
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
key: "unsubscribe",
|
|
635
|
-
value: function unsubscribe() {
|
|
636
|
-
this.options["debug"] && console.log("".concat(LOG_PREFIX$1, " unsubscribe for channel ").concat(this.name, " ..."));
|
|
637
|
-
this.socket.unsubscribe(this);
|
|
333
|
+
error(callback) {
|
|
334
|
+
return this.on('error', callback);
|
|
638
335
|
}
|
|
639
336
|
/**
|
|
640
|
-
*
|
|
337
|
+
* Bind a channel to an event.
|
|
641
338
|
*/
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
this.options["debug"] && console.log("".concat(LOG_PREFIX$1, " listen to ").concat(event, " for channel ").concat(this.name, " ..."));
|
|
647
|
-
this.on(this.eventFormatter.format(event), callback);
|
|
648
|
-
return this;
|
|
339
|
+
on(event, callback) {
|
|
340
|
+
this.options.debug && console.log(`${LOG_PREFIX$1} on ${event} for channel ${this.name} ...`);
|
|
341
|
+
this.socket.bind(this, event, callback);
|
|
342
|
+
return this;
|
|
649
343
|
}
|
|
650
344
|
/**
|
|
651
|
-
*
|
|
345
|
+
* Send a client event to the other members of the channel.
|
|
652
346
|
*/
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
347
|
+
whisper(event, data) {
|
|
348
|
+
this.socket.send({
|
|
349
|
+
event: 'client-' + event,
|
|
350
|
+
channel: this.name,
|
|
351
|
+
data,
|
|
352
|
+
});
|
|
353
|
+
return this;
|
|
660
354
|
}
|
|
661
355
|
/**
|
|
662
|
-
*
|
|
356
|
+
* Presence channels are not supported yet: member tracking is not implemented on the server.
|
|
663
357
|
*/
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
key: "subscribed",
|
|
667
|
-
value: function subscribed(callback) {
|
|
668
|
-
this.options["debug"] && console.log("".concat(LOG_PREFIX$1, " subscribed for channel ").concat(this.name, " ..."));
|
|
669
|
-
this.on('subscription_succeeded', function () {
|
|
670
|
-
callback();
|
|
671
|
-
});
|
|
672
|
-
return this;
|
|
358
|
+
here(_callback) {
|
|
359
|
+
return this;
|
|
673
360
|
}
|
|
674
361
|
/**
|
|
675
|
-
*
|
|
362
|
+
* Presence channels are not supported yet: member tracking is not implemented on the server.
|
|
676
363
|
*/
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
key: "error",
|
|
680
|
-
value: function error(callback) {
|
|
681
|
-
this.options["debug"] && console.log("".concat(LOG_PREFIX$1, " error for channel ").concat(this.name, " ..."));
|
|
682
|
-
this.on('error', function (status) {
|
|
683
|
-
callback(status);
|
|
684
|
-
});
|
|
685
|
-
return this;
|
|
364
|
+
joining(_callback) {
|
|
365
|
+
return this;
|
|
686
366
|
}
|
|
687
367
|
/**
|
|
688
|
-
*
|
|
368
|
+
* Presence channels are not supported yet: member tracking is not implemented on the server.
|
|
689
369
|
*/
|
|
370
|
+
leaving(_callback) {
|
|
371
|
+
return this;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
690
374
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
}, {
|
|
711
|
-
key: "here",
|
|
712
|
-
value: function here(callback) {
|
|
713
|
-
// TODO: implement
|
|
714
|
-
return this;
|
|
375
|
+
const LOG_PREFIX = '[LE-AG-Connector]';
|
|
376
|
+
/**
|
|
377
|
+
* Laravel Echo connector for API Gateway websockets.
|
|
378
|
+
*
|
|
379
|
+
* It does not extend laravel-echo's internal classes, so it works with laravel-echo v1 and v2:
|
|
380
|
+
* both create custom connectors with `new options.broadcaster(options)`.
|
|
381
|
+
*/
|
|
382
|
+
class Connector {
|
|
383
|
+
/**
|
|
384
|
+
* Create a new class instance. Without a host no connection is opened, which keeps
|
|
385
|
+
* laravel-echo v2's `new broadcaster()` capability check free of side effects.
|
|
386
|
+
*/
|
|
387
|
+
constructor(options = {}) {
|
|
388
|
+
/**
|
|
389
|
+
* All of the subscribed channel names.
|
|
390
|
+
*/
|
|
391
|
+
this.channels = {};
|
|
392
|
+
this.setOptions(options);
|
|
393
|
+
this.connect();
|
|
715
394
|
}
|
|
716
395
|
/**
|
|
717
|
-
*
|
|
396
|
+
* Merge the custom options with the defaults and add the CSRF and bearer token headers.
|
|
718
397
|
*/
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
398
|
+
setOptions(options) {
|
|
399
|
+
var _a, _b;
|
|
400
|
+
this.options = Object.assign(Object.assign(Object.assign({}, Connector._defaultOptions), options), { auth: {
|
|
401
|
+
headers: Object.assign({}, ((_b = (_a = options.auth) === null || _a === void 0 ? void 0 : _a.headers) !== null && _b !== void 0 ? _b : {})),
|
|
402
|
+
} });
|
|
403
|
+
const csrfToken = this.csrfToken();
|
|
404
|
+
if (csrfToken) {
|
|
405
|
+
this.options.auth.headers['X-CSRF-TOKEN'] = csrfToken;
|
|
406
|
+
}
|
|
407
|
+
if (this.options.bearerToken) {
|
|
408
|
+
this.options.auth.headers['Authorization'] = 'Bearer ' + this.options.bearerToken;
|
|
409
|
+
}
|
|
725
410
|
}
|
|
726
411
|
/**
|
|
727
|
-
*
|
|
412
|
+
* Extract the CSRF token from the page.
|
|
728
413
|
*/
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
414
|
+
csrfToken() {
|
|
415
|
+
var _a, _b, _c;
|
|
416
|
+
if (typeof window !== 'undefined' && ((_a = window.Laravel) === null || _a === void 0 ? void 0 : _a.csrfToken)) {
|
|
417
|
+
return window.Laravel.csrfToken;
|
|
418
|
+
}
|
|
419
|
+
if (this.options.csrfToken) {
|
|
420
|
+
return this.options.csrfToken;
|
|
421
|
+
}
|
|
422
|
+
if (typeof document !== 'undefined' && typeof document.querySelector === 'function') {
|
|
423
|
+
return (_c = (_b = document.querySelector('meta[name="csrf-token"]')) === null || _b === void 0 ? void 0 : _b.getAttribute('content')) !== null && _c !== void 0 ? _c : null;
|
|
424
|
+
}
|
|
425
|
+
return null;
|
|
735
426
|
}
|
|
736
|
-
}]);
|
|
737
|
-
|
|
738
|
-
return Channel;
|
|
739
|
-
}(Channel);
|
|
740
|
-
|
|
741
|
-
var broadcaster = function broadcaster(options) {
|
|
742
|
-
return new Connector$1(options);
|
|
743
|
-
};
|
|
744
|
-
var LOG_PREFIX$2 = '[LE-AG-Connector]';
|
|
745
|
-
var Connector$1 = /*#__PURE__*/function (_BaseConnector) {
|
|
746
|
-
_inherits(Connector, _BaseConnector);
|
|
747
|
-
|
|
748
|
-
var _super = _createSuper(Connector);
|
|
749
|
-
|
|
750
|
-
/**
|
|
751
|
-
* Create a new class instance.
|
|
752
|
-
*/
|
|
753
|
-
function Connector(options) {
|
|
754
|
-
var _this;
|
|
755
|
-
|
|
756
|
-
_classCallCheck(this, Connector);
|
|
757
|
-
|
|
758
|
-
_this = _super.call(this, options);
|
|
759
427
|
/**
|
|
760
|
-
*
|
|
428
|
+
* Create a fresh websocket connection.
|
|
761
429
|
*/
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
_createClass(Connector, [{
|
|
772
|
-
key: "connect",
|
|
773
|
-
value: function connect() {
|
|
774
|
-
this.options.debug && console.log(LOG_PREFIX$2 + 'Connect ...');
|
|
775
|
-
this.socket = new Websocket(this.options);
|
|
776
|
-
return; //
|
|
777
|
-
// this.socket.on('reconnect', () => {
|
|
778
|
-
// Object.values(this.channels).forEach((channel) => {
|
|
779
|
-
// channel.subscribe();
|
|
780
|
-
// });
|
|
781
|
-
// });
|
|
782
|
-
//
|
|
783
|
-
// return this.socket;
|
|
430
|
+
connect() {
|
|
431
|
+
this.options.debug && console.log(LOG_PREFIX + ' Connect ...');
|
|
432
|
+
this.socket = new Websocket(this.options);
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Listen for an event on a channel instance.
|
|
436
|
+
*/
|
|
437
|
+
listen(name, event, callback) {
|
|
438
|
+
return this.channel(name).listen(event, callback);
|
|
784
439
|
}
|
|
785
440
|
/**
|
|
786
441
|
* Get a channel instance by name.
|
|
787
442
|
*/
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
this.channels[name] = new Channel$1(this.socket, name, this.options);
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
return this.channels[name];
|
|
443
|
+
channel(name) {
|
|
444
|
+
if (!this.channels[name]) {
|
|
445
|
+
this.channels[name] = new Channel(this.socket, name, this.options);
|
|
446
|
+
}
|
|
447
|
+
return this.channels[name];
|
|
797
448
|
}
|
|
798
449
|
/**
|
|
799
450
|
* Get a private channel instance by name.
|
|
800
451
|
*/
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
key: "privateChannel",
|
|
804
|
-
value: function privateChannel(name) {
|
|
805
|
-
if (!this.channels['private-' + name]) {
|
|
806
|
-
this.channels['private-' + name] = new Channel$1(this.socket, 'private-' + name, this.options);
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
return this.channels['private-' + name];
|
|
452
|
+
privateChannel(name) {
|
|
453
|
+
return this.channel('private-' + name);
|
|
810
454
|
}
|
|
811
455
|
/**
|
|
812
456
|
* Get a presence channel instance by name.
|
|
813
457
|
*/
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
key: "presenceChannel",
|
|
817
|
-
value: function presenceChannel(name) {
|
|
818
|
-
if (!this.channels['presence-' + name]) {
|
|
819
|
-
this.channels['presence-' + name] = new Channel$1(this.socket, 'presence-' + name, this.options);
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
return this.channels['presence-' + name];
|
|
458
|
+
presenceChannel(name) {
|
|
459
|
+
return this.channel('presence-' + name);
|
|
823
460
|
}
|
|
824
461
|
/**
|
|
825
462
|
* Leave the given channel, as well as its private and presence variants.
|
|
826
463
|
*/
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
var _this2 = this;
|
|
832
|
-
|
|
833
|
-
var channels = [name, 'private-' + name, 'presence-' + name];
|
|
834
|
-
channels.forEach(function (name) {
|
|
835
|
-
_this2.leaveChannel(name);
|
|
836
|
-
});
|
|
464
|
+
leave(name) {
|
|
465
|
+
[name, 'private-' + name, 'presence-' + name].forEach((channelName) => {
|
|
466
|
+
this.leaveChannel(channelName);
|
|
467
|
+
});
|
|
837
468
|
}
|
|
838
469
|
/**
|
|
839
470
|
* Leave the given channel.
|
|
840
471
|
*/
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
this.channels[name].unsubscribe();
|
|
847
|
-
delete this.channels[name];
|
|
848
|
-
}
|
|
472
|
+
leaveChannel(name) {
|
|
473
|
+
if (this.channels[name]) {
|
|
474
|
+
this.channels[name].unsubscribe();
|
|
475
|
+
delete this.channels[name];
|
|
476
|
+
}
|
|
849
477
|
}
|
|
850
478
|
/**
|
|
851
479
|
* Get the socket ID for the connection.
|
|
852
480
|
*/
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
key: "socketId",
|
|
856
|
-
value: function socketId() {
|
|
857
|
-
return this.socket.getSocketId();
|
|
481
|
+
socketId() {
|
|
482
|
+
return this.socket.getSocketId();
|
|
858
483
|
}
|
|
859
484
|
/**
|
|
860
485
|
* Disconnect socket connection.
|
|
861
486
|
*/
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
value: function disconnect() {
|
|
866
|
-
this.options.debug && console.log(LOG_PREFIX$2 + 'Disconnect ...');
|
|
867
|
-
this.socket.close();
|
|
487
|
+
disconnect() {
|
|
488
|
+
this.options.debug && console.log(LOG_PREFIX + ' Disconnect ...');
|
|
489
|
+
this.socket.close();
|
|
868
490
|
}
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Default connector options, matching laravel-echo's defaults.
|
|
494
|
+
*/
|
|
495
|
+
Connector._defaultOptions = {
|
|
496
|
+
auth: {
|
|
497
|
+
headers: {},
|
|
498
|
+
},
|
|
499
|
+
authEndpoint: '/broadcasting/auth',
|
|
500
|
+
csrfToken: null,
|
|
501
|
+
bearerToken: null,
|
|
502
|
+
host: null,
|
|
503
|
+
namespace: 'App.Events',
|
|
504
|
+
};
|
|
505
|
+
/**
|
|
506
|
+
* Kept for backwards compatibility: `new Echo({ broadcaster })`. A function declaration (not an arrow
|
|
507
|
+
* function) so laravel-echo can call it with `new`.
|
|
508
|
+
*/
|
|
509
|
+
function broadcaster(options) {
|
|
510
|
+
return new Connector(options);
|
|
511
|
+
}
|
|
873
512
|
|
|
874
|
-
exports.
|
|
513
|
+
exports.Channel = Channel;
|
|
514
|
+
exports.Connector = Connector;
|
|
515
|
+
exports.EventFormatter = EventFormatter;
|
|
875
516
|
exports.broadcaster = broadcaster;
|