@rails/actioncable 6.0.2 → 7.1.2

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.
@@ -1,154 +1,115 @@
1
1
  (function(global, factory) {
2
- typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define([ "exports" ], factory) : factory(global.ActionCable = {});
3
- })(this, function(exports) {
2
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define([ "exports" ], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self,
3
+ factory(global.ActionCable = {}));
4
+ })(this, (function(exports) {
4
5
  "use strict";
5
6
  var adapters = {
6
7
  logger: self.console,
7
8
  WebSocket: self.WebSocket
8
9
  };
9
10
  var logger = {
10
- log: function log() {
11
+ log(...messages) {
11
12
  if (this.enabled) {
12
- var _adapters$logger;
13
- for (var _len = arguments.length, messages = Array(_len), _key = 0; _key < _len; _key++) {
14
- messages[_key] = arguments[_key];
15
- }
16
13
  messages.push(Date.now());
17
- (_adapters$logger = adapters.logger).log.apply(_adapters$logger, [ "[ActionCable]" ].concat(messages));
18
- }
19
- }
20
- };
21
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) {
22
- return typeof obj;
23
- } : function(obj) {
24
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
25
- };
26
- var classCallCheck = function(instance, Constructor) {
27
- if (!(instance instanceof Constructor)) {
28
- throw new TypeError("Cannot call a class as a function");
29
- }
30
- };
31
- var createClass = function() {
32
- function defineProperties(target, props) {
33
- for (var i = 0; i < props.length; i++) {
34
- var descriptor = props[i];
35
- descriptor.enumerable = descriptor.enumerable || false;
36
- descriptor.configurable = true;
37
- if ("value" in descriptor) descriptor.writable = true;
38
- Object.defineProperty(target, descriptor.key, descriptor);
14
+ adapters.logger.log("[ActionCable]", ...messages);
39
15
  }
40
16
  }
41
- return function(Constructor, protoProps, staticProps) {
42
- if (protoProps) defineProperties(Constructor.prototype, protoProps);
43
- if (staticProps) defineProperties(Constructor, staticProps);
44
- return Constructor;
45
- };
46
- }();
47
- var now = function now() {
48
- return new Date().getTime();
49
- };
50
- var secondsSince = function secondsSince(time) {
51
- return (now() - time) / 1e3;
52
- };
53
- var clamp = function clamp(number, min, max) {
54
- return Math.max(min, Math.min(max, number));
55
17
  };
56
- var ConnectionMonitor = function() {
57
- function ConnectionMonitor(connection) {
58
- classCallCheck(this, ConnectionMonitor);
18
+ const now = () => (new Date).getTime();
19
+ const secondsSince = time => (now() - time) / 1e3;
20
+ class ConnectionMonitor {
21
+ constructor(connection) {
59
22
  this.visibilityDidChange = this.visibilityDidChange.bind(this);
60
23
  this.connection = connection;
61
24
  this.reconnectAttempts = 0;
62
25
  }
63
- ConnectionMonitor.prototype.start = function start() {
26
+ start() {
64
27
  if (!this.isRunning()) {
65
28
  this.startedAt = now();
66
29
  delete this.stoppedAt;
67
30
  this.startPolling();
68
31
  addEventListener("visibilitychange", this.visibilityDidChange);
69
- logger.log("ConnectionMonitor started. pollInterval = " + this.getPollInterval() + " ms");
32
+ logger.log(`ConnectionMonitor started. stale threshold = ${this.constructor.staleThreshold} s`);
70
33
  }
71
- };
72
- ConnectionMonitor.prototype.stop = function stop() {
34
+ }
35
+ stop() {
73
36
  if (this.isRunning()) {
74
37
  this.stoppedAt = now();
75
38
  this.stopPolling();
76
39
  removeEventListener("visibilitychange", this.visibilityDidChange);
77
40
  logger.log("ConnectionMonitor stopped");
78
41
  }
79
- };
80
- ConnectionMonitor.prototype.isRunning = function isRunning() {
42
+ }
43
+ isRunning() {
81
44
  return this.startedAt && !this.stoppedAt;
82
- };
83
- ConnectionMonitor.prototype.recordPing = function recordPing() {
45
+ }
46
+ recordPing() {
84
47
  this.pingedAt = now();
85
- };
86
- ConnectionMonitor.prototype.recordConnect = function recordConnect() {
48
+ }
49
+ recordConnect() {
87
50
  this.reconnectAttempts = 0;
88
51
  this.recordPing();
89
52
  delete this.disconnectedAt;
90
53
  logger.log("ConnectionMonitor recorded connect");
91
- };
92
- ConnectionMonitor.prototype.recordDisconnect = function recordDisconnect() {
54
+ }
55
+ recordDisconnect() {
93
56
  this.disconnectedAt = now();
94
57
  logger.log("ConnectionMonitor recorded disconnect");
95
- };
96
- ConnectionMonitor.prototype.startPolling = function startPolling() {
58
+ }
59
+ startPolling() {
97
60
  this.stopPolling();
98
61
  this.poll();
99
- };
100
- ConnectionMonitor.prototype.stopPolling = function stopPolling() {
62
+ }
63
+ stopPolling() {
101
64
  clearTimeout(this.pollTimeout);
102
- };
103
- ConnectionMonitor.prototype.poll = function poll() {
104
- var _this = this;
105
- this.pollTimeout = setTimeout(function() {
106
- _this.reconnectIfStale();
107
- _this.poll();
108
- }, this.getPollInterval());
109
- };
110
- ConnectionMonitor.prototype.getPollInterval = function getPollInterval() {
111
- var _constructor$pollInte = this.constructor.pollInterval, min = _constructor$pollInte.min, max = _constructor$pollInte.max, multiplier = _constructor$pollInte.multiplier;
112
- var interval = multiplier * Math.log(this.reconnectAttempts + 1);
113
- return Math.round(clamp(interval, min, max) * 1e3);
114
- };
115
- ConnectionMonitor.prototype.reconnectIfStale = function reconnectIfStale() {
65
+ }
66
+ poll() {
67
+ this.pollTimeout = setTimeout((() => {
68
+ this.reconnectIfStale();
69
+ this.poll();
70
+ }), this.getPollInterval());
71
+ }
72
+ getPollInterval() {
73
+ const {staleThreshold: staleThreshold, reconnectionBackoffRate: reconnectionBackoffRate} = this.constructor;
74
+ const backoff = Math.pow(1 + reconnectionBackoffRate, Math.min(this.reconnectAttempts, 10));
75
+ const jitterMax = this.reconnectAttempts === 0 ? 1 : reconnectionBackoffRate;
76
+ const jitter = jitterMax * Math.random();
77
+ return staleThreshold * 1e3 * backoff * (1 + jitter);
78
+ }
79
+ reconnectIfStale() {
116
80
  if (this.connectionIsStale()) {
117
- logger.log("ConnectionMonitor detected stale connection. reconnectAttempts = " + this.reconnectAttempts + ", pollInterval = " + this.getPollInterval() + " ms, time disconnected = " + secondsSince(this.disconnectedAt) + " s, stale threshold = " + this.constructor.staleThreshold + " s");
81
+ logger.log(`ConnectionMonitor detected stale connection. reconnectAttempts = ${this.reconnectAttempts}, time stale = ${secondsSince(this.refreshedAt)} s, stale threshold = ${this.constructor.staleThreshold} s`);
118
82
  this.reconnectAttempts++;
119
83
  if (this.disconnectedRecently()) {
120
- logger.log("ConnectionMonitor skipping reopening recent disconnect");
84
+ logger.log(`ConnectionMonitor skipping reopening recent disconnect. time disconnected = ${secondsSince(this.disconnectedAt)} s`);
121
85
  } else {
122
86
  logger.log("ConnectionMonitor reopening");
123
87
  this.connection.reopen();
124
88
  }
125
89
  }
126
- };
127
- ConnectionMonitor.prototype.connectionIsStale = function connectionIsStale() {
128
- return secondsSince(this.pingedAt ? this.pingedAt : this.startedAt) > this.constructor.staleThreshold;
129
- };
130
- ConnectionMonitor.prototype.disconnectedRecently = function disconnectedRecently() {
90
+ }
91
+ get refreshedAt() {
92
+ return this.pingedAt ? this.pingedAt : this.startedAt;
93
+ }
94
+ connectionIsStale() {
95
+ return secondsSince(this.refreshedAt) > this.constructor.staleThreshold;
96
+ }
97
+ disconnectedRecently() {
131
98
  return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;
132
- };
133
- ConnectionMonitor.prototype.visibilityDidChange = function visibilityDidChange() {
134
- var _this2 = this;
99
+ }
100
+ visibilityDidChange() {
135
101
  if (document.visibilityState === "visible") {
136
- setTimeout(function() {
137
- if (_this2.connectionIsStale() || !_this2.connection.isOpen()) {
138
- logger.log("ConnectionMonitor reopening stale connection on visibilitychange. visbilityState = " + document.visibilityState);
139
- _this2.connection.reopen();
102
+ setTimeout((() => {
103
+ if (this.connectionIsStale() || !this.connection.isOpen()) {
104
+ logger.log(`ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = ${document.visibilityState}`);
105
+ this.connection.reopen();
140
106
  }
141
- }, 200);
107
+ }), 200);
142
108
  }
143
- };
144
- return ConnectionMonitor;
145
- }();
146
- ConnectionMonitor.pollInterval = {
147
- min: 3,
148
- max: 30,
149
- multiplier: 5
150
- };
109
+ }
110
+ }
151
111
  ConnectionMonitor.staleThreshold = 6;
112
+ ConnectionMonitor.reconnectionBackoffRate = .15;
152
113
  var INTERNAL = {
153
114
  message_types: {
154
115
  welcome: "welcome",
@@ -160,129 +121,131 @@
160
121
  disconnect_reasons: {
161
122
  unauthorized: "unauthorized",
162
123
  invalid_request: "invalid_request",
163
- server_restart: "server_restart"
124
+ server_restart: "server_restart",
125
+ remote: "remote"
164
126
  },
165
127
  default_mount_path: "/cable",
166
128
  protocols: [ "actioncable-v1-json", "actioncable-unsupported" ]
167
129
  };
168
- var message_types = INTERNAL.message_types, protocols = INTERNAL.protocols;
169
- var supportedProtocols = protocols.slice(0, protocols.length - 1);
170
- var indexOf = [].indexOf;
171
- var Connection = function() {
172
- function Connection(consumer) {
173
- classCallCheck(this, Connection);
130
+ const {message_types: message_types, protocols: protocols} = INTERNAL;
131
+ const supportedProtocols = protocols.slice(0, protocols.length - 1);
132
+ const indexOf = [].indexOf;
133
+ class Connection {
134
+ constructor(consumer) {
174
135
  this.open = this.open.bind(this);
175
136
  this.consumer = consumer;
176
137
  this.subscriptions = this.consumer.subscriptions;
177
138
  this.monitor = new ConnectionMonitor(this);
178
139
  this.disconnected = true;
179
140
  }
180
- Connection.prototype.send = function send(data) {
141
+ send(data) {
181
142
  if (this.isOpen()) {
182
143
  this.webSocket.send(JSON.stringify(data));
183
144
  return true;
184
145
  } else {
185
146
  return false;
186
147
  }
187
- };
188
- Connection.prototype.open = function open() {
148
+ }
149
+ open() {
189
150
  if (this.isActive()) {
190
- logger.log("Attempted to open WebSocket, but existing socket is " + this.getState());
151
+ logger.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`);
191
152
  return false;
192
153
  } else {
193
- logger.log("Opening WebSocket, current state is " + this.getState() + ", subprotocols: " + protocols);
154
+ const socketProtocols = [ ...protocols, ...this.consumer.subprotocols || [] ];
155
+ logger.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${socketProtocols}`);
194
156
  if (this.webSocket) {
195
157
  this.uninstallEventHandlers();
196
158
  }
197
- this.webSocket = new adapters.WebSocket(this.consumer.url, protocols);
159
+ this.webSocket = new adapters.WebSocket(this.consumer.url, socketProtocols);
198
160
  this.installEventHandlers();
199
161
  this.monitor.start();
200
162
  return true;
201
163
  }
202
- };
203
- Connection.prototype.close = function close() {
204
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
205
- allowReconnect: true
206
- }, allowReconnect = _ref.allowReconnect;
164
+ }
165
+ close({allowReconnect: allowReconnect} = {
166
+ allowReconnect: true
167
+ }) {
207
168
  if (!allowReconnect) {
208
169
  this.monitor.stop();
209
170
  }
210
- if (this.isActive()) {
171
+ if (this.isOpen()) {
211
172
  return this.webSocket.close();
212
173
  }
213
- };
214
- Connection.prototype.reopen = function reopen() {
215
- logger.log("Reopening WebSocket, current state is " + this.getState());
174
+ }
175
+ reopen() {
176
+ logger.log(`Reopening WebSocket, current state is ${this.getState()}`);
216
177
  if (this.isActive()) {
217
178
  try {
218
179
  return this.close();
219
180
  } catch (error) {
220
181
  logger.log("Failed to reopen WebSocket", error);
221
182
  } finally {
222
- logger.log("Reopening WebSocket in " + this.constructor.reopenDelay + "ms");
183
+ logger.log(`Reopening WebSocket in ${this.constructor.reopenDelay}ms`);
223
184
  setTimeout(this.open, this.constructor.reopenDelay);
224
185
  }
225
186
  } else {
226
187
  return this.open();
227
188
  }
228
- };
229
- Connection.prototype.getProtocol = function getProtocol() {
189
+ }
190
+ getProtocol() {
230
191
  if (this.webSocket) {
231
192
  return this.webSocket.protocol;
232
193
  }
233
- };
234
- Connection.prototype.isOpen = function isOpen() {
194
+ }
195
+ isOpen() {
235
196
  return this.isState("open");
236
- };
237
- Connection.prototype.isActive = function isActive() {
197
+ }
198
+ isActive() {
238
199
  return this.isState("open", "connecting");
239
- };
240
- Connection.prototype.isProtocolSupported = function isProtocolSupported() {
200
+ }
201
+ triedToReconnect() {
202
+ return this.monitor.reconnectAttempts > 0;
203
+ }
204
+ isProtocolSupported() {
241
205
  return indexOf.call(supportedProtocols, this.getProtocol()) >= 0;
242
- };
243
- Connection.prototype.isState = function isState() {
244
- for (var _len = arguments.length, states = Array(_len), _key = 0; _key < _len; _key++) {
245
- states[_key] = arguments[_key];
246
- }
206
+ }
207
+ isState(...states) {
247
208
  return indexOf.call(states, this.getState()) >= 0;
248
- };
249
- Connection.prototype.getState = function getState() {
209
+ }
210
+ getState() {
250
211
  if (this.webSocket) {
251
- for (var state in adapters.WebSocket) {
212
+ for (let state in adapters.WebSocket) {
252
213
  if (adapters.WebSocket[state] === this.webSocket.readyState) {
253
214
  return state.toLowerCase();
254
215
  }
255
216
  }
256
217
  }
257
218
  return null;
258
- };
259
- Connection.prototype.installEventHandlers = function installEventHandlers() {
260
- for (var eventName in this.events) {
261
- var handler = this.events[eventName].bind(this);
262
- this.webSocket["on" + eventName] = handler;
219
+ }
220
+ installEventHandlers() {
221
+ for (let eventName in this.events) {
222
+ const handler = this.events[eventName].bind(this);
223
+ this.webSocket[`on${eventName}`] = handler;
263
224
  }
264
- };
265
- Connection.prototype.uninstallEventHandlers = function uninstallEventHandlers() {
266
- for (var eventName in this.events) {
267
- this.webSocket["on" + eventName] = function() {};
225
+ }
226
+ uninstallEventHandlers() {
227
+ for (let eventName in this.events) {
228
+ this.webSocket[`on${eventName}`] = function() {};
268
229
  }
269
- };
270
- return Connection;
271
- }();
230
+ }
231
+ }
272
232
  Connection.reopenDelay = 500;
273
233
  Connection.prototype.events = {
274
- message: function message(event) {
234
+ message(event) {
275
235
  if (!this.isProtocolSupported()) {
276
236
  return;
277
237
  }
278
- var _JSON$parse = JSON.parse(event.data), identifier = _JSON$parse.identifier, message = _JSON$parse.message, reason = _JSON$parse.reason, reconnect = _JSON$parse.reconnect, type = _JSON$parse.type;
238
+ const {identifier: identifier, message: message, reason: reason, reconnect: reconnect, type: type} = JSON.parse(event.data);
279
239
  switch (type) {
280
240
  case message_types.welcome:
241
+ if (this.triedToReconnect()) {
242
+ this.reconnectAttempted = true;
243
+ }
281
244
  this.monitor.recordConnect();
282
245
  return this.subscriptions.reload();
283
246
 
284
247
  case message_types.disconnect:
285
- logger.log("Disconnecting. Reason: " + reason);
248
+ logger.log(`Disconnecting. Reason: ${reason}`);
286
249
  return this.close({
287
250
  allowReconnect: reconnect
288
251
  });
@@ -291,7 +254,17 @@
291
254
  return this.monitor.recordPing();
292
255
 
293
256
  case message_types.confirmation:
294
- return this.subscriptions.notify(identifier, "connected");
257
+ this.subscriptions.confirmSubscription(identifier);
258
+ if (this.reconnectAttempted) {
259
+ this.reconnectAttempted = false;
260
+ return this.subscriptions.notify(identifier, "connected", {
261
+ reconnected: true
262
+ });
263
+ } else {
264
+ return this.subscriptions.notify(identifier, "connected", {
265
+ reconnected: false
266
+ });
267
+ }
295
268
 
296
269
  case message_types.rejection:
297
270
  return this.subscriptions.reject(identifier);
@@ -300,8 +273,8 @@
300
273
  return this.subscriptions.notify(identifier, "received", message);
301
274
  }
302
275
  },
303
- open: function open() {
304
- logger.log("WebSocket onopen event, using '" + this.getProtocol() + "' subprotocol");
276
+ open() {
277
+ logger.log(`WebSocket onopen event, using '${this.getProtocol()}' subprotocol`);
305
278
  this.disconnected = false;
306
279
  if (!this.isProtocolSupported()) {
307
280
  logger.log("Protocol is unsupported. Stopping monitor and disconnecting.");
@@ -310,7 +283,7 @@
310
283
  });
311
284
  }
312
285
  },
313
- close: function close(event) {
286
+ close(event) {
314
287
  logger.log("WebSocket onclose event");
315
288
  if (this.disconnected) {
316
289
  return;
@@ -321,167 +294,187 @@
321
294
  willAttemptReconnect: this.monitor.isRunning()
322
295
  });
323
296
  },
324
- error: function error() {
297
+ error() {
325
298
  logger.log("WebSocket onerror event");
326
299
  }
327
300
  };
328
- var extend = function extend(object, properties) {
301
+ const extend = function(object, properties) {
329
302
  if (properties != null) {
330
- for (var key in properties) {
331
- var value = properties[key];
303
+ for (let key in properties) {
304
+ const value = properties[key];
332
305
  object[key] = value;
333
306
  }
334
307
  }
335
308
  return object;
336
309
  };
337
- var Subscription = function() {
338
- function Subscription(consumer) {
339
- var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
340
- var mixin = arguments[2];
341
- classCallCheck(this, Subscription);
310
+ class Subscription {
311
+ constructor(consumer, params = {}, mixin) {
342
312
  this.consumer = consumer;
343
313
  this.identifier = JSON.stringify(params);
344
314
  extend(this, mixin);
345
315
  }
346
- Subscription.prototype.perform = function perform(action) {
347
- var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
316
+ perform(action, data = {}) {
348
317
  data.action = action;
349
318
  return this.send(data);
350
- };
351
- Subscription.prototype.send = function send(data) {
319
+ }
320
+ send(data) {
352
321
  return this.consumer.send({
353
322
  command: "message",
354
323
  identifier: this.identifier,
355
324
  data: JSON.stringify(data)
356
325
  });
357
- };
358
- Subscription.prototype.unsubscribe = function unsubscribe() {
326
+ }
327
+ unsubscribe() {
359
328
  return this.consumer.subscriptions.remove(this);
360
- };
361
- return Subscription;
362
- }();
363
- var Subscriptions = function() {
364
- function Subscriptions(consumer) {
365
- classCallCheck(this, Subscriptions);
329
+ }
330
+ }
331
+ class SubscriptionGuarantor {
332
+ constructor(subscriptions) {
333
+ this.subscriptions = subscriptions;
334
+ this.pendingSubscriptions = [];
335
+ }
336
+ guarantee(subscription) {
337
+ if (this.pendingSubscriptions.indexOf(subscription) == -1) {
338
+ logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`);
339
+ this.pendingSubscriptions.push(subscription);
340
+ } else {
341
+ logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`);
342
+ }
343
+ this.startGuaranteeing();
344
+ }
345
+ forget(subscription) {
346
+ logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`);
347
+ this.pendingSubscriptions = this.pendingSubscriptions.filter((s => s !== subscription));
348
+ }
349
+ startGuaranteeing() {
350
+ this.stopGuaranteeing();
351
+ this.retrySubscribing();
352
+ }
353
+ stopGuaranteeing() {
354
+ clearTimeout(this.retryTimeout);
355
+ }
356
+ retrySubscribing() {
357
+ this.retryTimeout = setTimeout((() => {
358
+ if (this.subscriptions && typeof this.subscriptions.subscribe === "function") {
359
+ this.pendingSubscriptions.map((subscription => {
360
+ logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`);
361
+ this.subscriptions.subscribe(subscription);
362
+ }));
363
+ }
364
+ }), 500);
365
+ }
366
+ }
367
+ class Subscriptions {
368
+ constructor(consumer) {
366
369
  this.consumer = consumer;
370
+ this.guarantor = new SubscriptionGuarantor(this);
367
371
  this.subscriptions = [];
368
372
  }
369
- Subscriptions.prototype.create = function create(channelName, mixin) {
370
- var channel = channelName;
371
- var params = (typeof channel === "undefined" ? "undefined" : _typeof(channel)) === "object" ? channel : {
373
+ create(channelName, mixin) {
374
+ const channel = channelName;
375
+ const params = typeof channel === "object" ? channel : {
372
376
  channel: channel
373
377
  };
374
- var subscription = new Subscription(this.consumer, params, mixin);
378
+ const subscription = new Subscription(this.consumer, params, mixin);
375
379
  return this.add(subscription);
376
- };
377
- Subscriptions.prototype.add = function add(subscription) {
380
+ }
381
+ add(subscription) {
378
382
  this.subscriptions.push(subscription);
379
383
  this.consumer.ensureActiveConnection();
380
384
  this.notify(subscription, "initialized");
381
- this.sendCommand(subscription, "subscribe");
385
+ this.subscribe(subscription);
382
386
  return subscription;
383
- };
384
- Subscriptions.prototype.remove = function remove(subscription) {
387
+ }
388
+ remove(subscription) {
385
389
  this.forget(subscription);
386
390
  if (!this.findAll(subscription.identifier).length) {
387
391
  this.sendCommand(subscription, "unsubscribe");
388
392
  }
389
393
  return subscription;
390
- };
391
- Subscriptions.prototype.reject = function reject(identifier) {
392
- var _this = this;
393
- return this.findAll(identifier).map(function(subscription) {
394
- _this.forget(subscription);
395
- _this.notify(subscription, "rejected");
394
+ }
395
+ reject(identifier) {
396
+ return this.findAll(identifier).map((subscription => {
397
+ this.forget(subscription);
398
+ this.notify(subscription, "rejected");
396
399
  return subscription;
397
- });
398
- };
399
- Subscriptions.prototype.forget = function forget(subscription) {
400
- this.subscriptions = this.subscriptions.filter(function(s) {
401
- return s !== subscription;
402
- });
400
+ }));
401
+ }
402
+ forget(subscription) {
403
+ this.guarantor.forget(subscription);
404
+ this.subscriptions = this.subscriptions.filter((s => s !== subscription));
403
405
  return subscription;
404
- };
405
- Subscriptions.prototype.findAll = function findAll(identifier) {
406
- return this.subscriptions.filter(function(s) {
407
- return s.identifier === identifier;
408
- });
409
- };
410
- Subscriptions.prototype.reload = function reload() {
411
- var _this2 = this;
412
- return this.subscriptions.map(function(subscription) {
413
- return _this2.sendCommand(subscription, "subscribe");
414
- });
415
- };
416
- Subscriptions.prototype.notifyAll = function notifyAll(callbackName) {
417
- var _this3 = this;
418
- for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
419
- args[_key - 1] = arguments[_key];
420
- }
421
- return this.subscriptions.map(function(subscription) {
422
- return _this3.notify.apply(_this3, [ subscription, callbackName ].concat(args));
423
- });
424
- };
425
- Subscriptions.prototype.notify = function notify(subscription, callbackName) {
426
- for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
427
- args[_key2 - 2] = arguments[_key2];
428
- }
429
- var subscriptions = void 0;
406
+ }
407
+ findAll(identifier) {
408
+ return this.subscriptions.filter((s => s.identifier === identifier));
409
+ }
410
+ reload() {
411
+ return this.subscriptions.map((subscription => this.subscribe(subscription)));
412
+ }
413
+ notifyAll(callbackName, ...args) {
414
+ return this.subscriptions.map((subscription => this.notify(subscription, callbackName, ...args)));
415
+ }
416
+ notify(subscription, callbackName, ...args) {
417
+ let subscriptions;
430
418
  if (typeof subscription === "string") {
431
419
  subscriptions = this.findAll(subscription);
432
420
  } else {
433
421
  subscriptions = [ subscription ];
434
422
  }
435
- return subscriptions.map(function(subscription) {
436
- return typeof subscription[callbackName] === "function" ? subscription[callbackName].apply(subscription, args) : undefined;
437
- });
438
- };
439
- Subscriptions.prototype.sendCommand = function sendCommand(subscription, command) {
440
- var identifier = subscription.identifier;
423
+ return subscriptions.map((subscription => typeof subscription[callbackName] === "function" ? subscription[callbackName](...args) : undefined));
424
+ }
425
+ subscribe(subscription) {
426
+ if (this.sendCommand(subscription, "subscribe")) {
427
+ this.guarantor.guarantee(subscription);
428
+ }
429
+ }
430
+ confirmSubscription(identifier) {
431
+ logger.log(`Subscription confirmed ${identifier}`);
432
+ this.findAll(identifier).map((subscription => this.guarantor.forget(subscription)));
433
+ }
434
+ sendCommand(subscription, command) {
435
+ const {identifier: identifier} = subscription;
441
436
  return this.consumer.send({
442
437
  command: command,
443
438
  identifier: identifier
444
439
  });
445
- };
446
- return Subscriptions;
447
- }();
448
- var Consumer = function() {
449
- function Consumer(url) {
450
- classCallCheck(this, Consumer);
440
+ }
441
+ }
442
+ class Consumer {
443
+ constructor(url) {
451
444
  this._url = url;
452
445
  this.subscriptions = new Subscriptions(this);
453
446
  this.connection = new Connection(this);
447
+ this.subprotocols = [];
448
+ }
449
+ get url() {
450
+ return createWebSocketURL(this._url);
454
451
  }
455
- Consumer.prototype.send = function send(data) {
452
+ send(data) {
456
453
  return this.connection.send(data);
457
- };
458
- Consumer.prototype.connect = function connect() {
454
+ }
455
+ connect() {
459
456
  return this.connection.open();
460
- };
461
- Consumer.prototype.disconnect = function disconnect() {
457
+ }
458
+ disconnect() {
462
459
  return this.connection.close({
463
460
  allowReconnect: false
464
461
  });
465
- };
466
- Consumer.prototype.ensureActiveConnection = function ensureActiveConnection() {
462
+ }
463
+ ensureActiveConnection() {
467
464
  if (!this.connection.isActive()) {
468
465
  return this.connection.open();
469
466
  }
470
- };
471
- createClass(Consumer, [ {
472
- key: "url",
473
- get: function get$$1() {
474
- return createWebSocketURL(this._url);
475
- }
476
- } ]);
477
- return Consumer;
478
- }();
467
+ }
468
+ addSubProtocol(subprotocol) {
469
+ this.subprotocols = [ ...this.subprotocols, subprotocol ];
470
+ }
471
+ }
479
472
  function createWebSocketURL(url) {
480
473
  if (typeof url === "function") {
481
474
  url = url();
482
475
  }
483
476
  if (url && !/^wss?:/i.test(url)) {
484
- var a = document.createElement("a");
477
+ const a = document.createElement("a");
485
478
  a.href = url;
486
479
  a.href = a.href;
487
480
  a.protocol = a.protocol.replace("http", "ws");
@@ -490,28 +483,29 @@
490
483
  return url;
491
484
  }
492
485
  }
493
- function createConsumer() {
494
- var url = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getConfig("url") || INTERNAL.default_mount_path;
486
+ function createConsumer(url = getConfig("url") || INTERNAL.default_mount_path) {
495
487
  return new Consumer(url);
496
488
  }
497
489
  function getConfig(name) {
498
- var element = document.head.querySelector("meta[name='action-cable-" + name + "']");
490
+ const element = document.head.querySelector(`meta[name='action-cable-${name}']`);
499
491
  if (element) {
500
492
  return element.getAttribute("content");
501
493
  }
502
494
  }
495
+ console.log("DEPRECATION: action_cable.js has been renamed to actioncable.js – please update your reference before Rails 8");
503
496
  exports.Connection = Connection;
504
497
  exports.ConnectionMonitor = ConnectionMonitor;
505
498
  exports.Consumer = Consumer;
506
499
  exports.INTERNAL = INTERNAL;
507
500
  exports.Subscription = Subscription;
501
+ exports.SubscriptionGuarantor = SubscriptionGuarantor;
508
502
  exports.Subscriptions = Subscriptions;
509
503
  exports.adapters = adapters;
510
- exports.createWebSocketURL = createWebSocketURL;
511
- exports.logger = logger;
512
504
  exports.createConsumer = createConsumer;
505
+ exports.createWebSocketURL = createWebSocketURL;
513
506
  exports.getConfig = getConfig;
507
+ exports.logger = logger;
514
508
  Object.defineProperty(exports, "__esModule", {
515
509
  value: true
516
510
  });
517
- });
511
+ }));