@rails/actioncable 7.0.0-alpha2 → 7.0.0-rc1
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/app/assets/javascripts/action_cable.js +51 -2
- package/app/assets/javascripts/actioncable.esm.js +52 -3
- package/app/assets/javascripts/actioncable.js +51 -2
- package/package.json +3 -3
- package/src/connection.js +1 -0
- package/src/index.js +2 -0
- package/src/subscription_guarantor.js +50 -0
- package/src/subscriptions.js +18 -2
- package/CHANGELOG.md +0 -42
@@ -246,6 +246,7 @@
|
|
246
246
|
return this.monitor.recordPing();
|
247
247
|
|
248
248
|
case message_types.confirmation:
|
249
|
+
this.subscriptions.confirmSubscription(identifier);
|
249
250
|
return this.subscriptions.notify(identifier, "connected");
|
250
251
|
|
251
252
|
case message_types.rejection:
|
@@ -310,9 +311,46 @@
|
|
310
311
|
return this.consumer.subscriptions.remove(this);
|
311
312
|
}
|
312
313
|
}
|
314
|
+
class SubscriptionGuarantor {
|
315
|
+
constructor(subscriptions) {
|
316
|
+
this.subscriptions = subscriptions;
|
317
|
+
this.pendingSubscriptions = [];
|
318
|
+
}
|
319
|
+
guarantee(subscription) {
|
320
|
+
if (this.pendingSubscriptions.indexOf(subscription) == -1) {
|
321
|
+
logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`);
|
322
|
+
this.pendingSubscriptions.push(subscription);
|
323
|
+
} else {
|
324
|
+
logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`);
|
325
|
+
}
|
326
|
+
this.startGuaranteeing();
|
327
|
+
}
|
328
|
+
forget(subscription) {
|
329
|
+
logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`);
|
330
|
+
this.pendingSubscriptions = this.pendingSubscriptions.filter((s => s !== subscription));
|
331
|
+
}
|
332
|
+
startGuaranteeing() {
|
333
|
+
this.stopGuaranteeing();
|
334
|
+
this.retrySubscribing();
|
335
|
+
}
|
336
|
+
stopGuaranteeing() {
|
337
|
+
clearTimeout(this.retryTimeout);
|
338
|
+
}
|
339
|
+
retrySubscribing() {
|
340
|
+
this.retryTimeout = setTimeout((() => {
|
341
|
+
if (this.subscriptions && typeof this.subscriptions.subscribe === "function") {
|
342
|
+
this.pendingSubscriptions.map((subscription => {
|
343
|
+
logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`);
|
344
|
+
this.subscriptions.subscribe(subscription);
|
345
|
+
}));
|
346
|
+
}
|
347
|
+
}), 500);
|
348
|
+
}
|
349
|
+
}
|
313
350
|
class Subscriptions {
|
314
351
|
constructor(consumer) {
|
315
352
|
this.consumer = consumer;
|
353
|
+
this.guarantor = new SubscriptionGuarantor(this);
|
316
354
|
this.subscriptions = [];
|
317
355
|
}
|
318
356
|
create(channelName, mixin) {
|
@@ -327,7 +365,7 @@
|
|
327
365
|
this.subscriptions.push(subscription);
|
328
366
|
this.consumer.ensureActiveConnection();
|
329
367
|
this.notify(subscription, "initialized");
|
330
|
-
this.
|
368
|
+
this.subscribe(subscription);
|
331
369
|
return subscription;
|
332
370
|
}
|
333
371
|
remove(subscription) {
|
@@ -345,6 +383,7 @@
|
|
345
383
|
}));
|
346
384
|
}
|
347
385
|
forget(subscription) {
|
386
|
+
this.guarantor.forget(subscription);
|
348
387
|
this.subscriptions = this.subscriptions.filter((s => s !== subscription));
|
349
388
|
return subscription;
|
350
389
|
}
|
@@ -352,7 +391,7 @@
|
|
352
391
|
return this.subscriptions.filter((s => s.identifier === identifier));
|
353
392
|
}
|
354
393
|
reload() {
|
355
|
-
return this.subscriptions.map((subscription => this.
|
394
|
+
return this.subscriptions.map((subscription => this.subscribe(subscription)));
|
356
395
|
}
|
357
396
|
notifyAll(callbackName, ...args) {
|
358
397
|
return this.subscriptions.map((subscription => this.notify(subscription, callbackName, ...args)));
|
@@ -366,6 +405,15 @@
|
|
366
405
|
}
|
367
406
|
return subscriptions.map((subscription => typeof subscription[callbackName] === "function" ? subscription[callbackName](...args) : undefined));
|
368
407
|
}
|
408
|
+
subscribe(subscription) {
|
409
|
+
if (this.sendCommand(subscription, "subscribe")) {
|
410
|
+
this.guarantor.guarantee(subscription);
|
411
|
+
}
|
412
|
+
}
|
413
|
+
confirmSubscription(identifier) {
|
414
|
+
logger.log(`Subscription confirmed ${identifier}`);
|
415
|
+
this.findAll(identifier).map((subscription => this.guarantor.forget(subscription)));
|
416
|
+
}
|
369
417
|
sendCommand(subscription, command) {
|
370
418
|
const {identifier: identifier} = subscription;
|
371
419
|
return this.consumer.send({
|
@@ -429,6 +477,7 @@
|
|
429
477
|
exports.Consumer = Consumer;
|
430
478
|
exports.INTERNAL = INTERNAL;
|
431
479
|
exports.Subscription = Subscription;
|
480
|
+
exports.SubscriptionGuarantor = SubscriptionGuarantor;
|
432
481
|
exports.Subscriptions = Subscriptions;
|
433
482
|
exports.adapters = adapters;
|
434
483
|
exports.createConsumer = createConsumer;
|
@@ -254,6 +254,7 @@ Connection.prototype.events = {
|
|
254
254
|
return this.monitor.recordPing();
|
255
255
|
|
256
256
|
case message_types.confirmation:
|
257
|
+
this.subscriptions.confirmSubscription(identifier);
|
257
258
|
return this.subscriptions.notify(identifier, "connected");
|
258
259
|
|
259
260
|
case message_types.rejection:
|
@@ -321,9 +322,47 @@ class Subscription {
|
|
321
322
|
}
|
322
323
|
}
|
323
324
|
|
325
|
+
class SubscriptionGuarantor {
|
326
|
+
constructor(subscriptions) {
|
327
|
+
this.subscriptions = subscriptions;
|
328
|
+
this.pendingSubscriptions = [];
|
329
|
+
}
|
330
|
+
guarantee(subscription) {
|
331
|
+
if (this.pendingSubscriptions.indexOf(subscription) == -1) {
|
332
|
+
logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`);
|
333
|
+
this.pendingSubscriptions.push(subscription);
|
334
|
+
} else {
|
335
|
+
logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`);
|
336
|
+
}
|
337
|
+
this.startGuaranteeing();
|
338
|
+
}
|
339
|
+
forget(subscription) {
|
340
|
+
logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`);
|
341
|
+
this.pendingSubscriptions = this.pendingSubscriptions.filter((s => s !== subscription));
|
342
|
+
}
|
343
|
+
startGuaranteeing() {
|
344
|
+
this.stopGuaranteeing();
|
345
|
+
this.retrySubscribing();
|
346
|
+
}
|
347
|
+
stopGuaranteeing() {
|
348
|
+
clearTimeout(this.retryTimeout);
|
349
|
+
}
|
350
|
+
retrySubscribing() {
|
351
|
+
this.retryTimeout = setTimeout((() => {
|
352
|
+
if (this.subscriptions && typeof this.subscriptions.subscribe === "function") {
|
353
|
+
this.pendingSubscriptions.map((subscription => {
|
354
|
+
logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`);
|
355
|
+
this.subscriptions.subscribe(subscription);
|
356
|
+
}));
|
357
|
+
}
|
358
|
+
}), 500);
|
359
|
+
}
|
360
|
+
}
|
361
|
+
|
324
362
|
class Subscriptions {
|
325
363
|
constructor(consumer) {
|
326
364
|
this.consumer = consumer;
|
365
|
+
this.guarantor = new SubscriptionGuarantor(this);
|
327
366
|
this.subscriptions = [];
|
328
367
|
}
|
329
368
|
create(channelName, mixin) {
|
@@ -338,7 +377,7 @@ class Subscriptions {
|
|
338
377
|
this.subscriptions.push(subscription);
|
339
378
|
this.consumer.ensureActiveConnection();
|
340
379
|
this.notify(subscription, "initialized");
|
341
|
-
this.
|
380
|
+
this.subscribe(subscription);
|
342
381
|
return subscription;
|
343
382
|
}
|
344
383
|
remove(subscription) {
|
@@ -356,6 +395,7 @@ class Subscriptions {
|
|
356
395
|
}));
|
357
396
|
}
|
358
397
|
forget(subscription) {
|
398
|
+
this.guarantor.forget(subscription);
|
359
399
|
this.subscriptions = this.subscriptions.filter((s => s !== subscription));
|
360
400
|
return subscription;
|
361
401
|
}
|
@@ -363,7 +403,7 @@ class Subscriptions {
|
|
363
403
|
return this.subscriptions.filter((s => s.identifier === identifier));
|
364
404
|
}
|
365
405
|
reload() {
|
366
|
-
return this.subscriptions.map((subscription => this.
|
406
|
+
return this.subscriptions.map((subscription => this.subscribe(subscription)));
|
367
407
|
}
|
368
408
|
notifyAll(callbackName, ...args) {
|
369
409
|
return this.subscriptions.map((subscription => this.notify(subscription, callbackName, ...args)));
|
@@ -377,6 +417,15 @@ class Subscriptions {
|
|
377
417
|
}
|
378
418
|
return subscriptions.map((subscription => typeof subscription[callbackName] === "function" ? subscription[callbackName](...args) : undefined));
|
379
419
|
}
|
420
|
+
subscribe(subscription) {
|
421
|
+
if (this.sendCommand(subscription, "subscribe")) {
|
422
|
+
this.guarantor.guarantee(subscription);
|
423
|
+
}
|
424
|
+
}
|
425
|
+
confirmSubscription(identifier) {
|
426
|
+
logger.log(`Subscription confirmed ${identifier}`);
|
427
|
+
this.findAll(identifier).map((subscription => this.guarantor.forget(subscription)));
|
428
|
+
}
|
380
429
|
sendCommand(subscription, command) {
|
381
430
|
const {identifier: identifier} = subscription;
|
382
431
|
return this.consumer.send({
|
@@ -439,4 +488,4 @@ function getConfig(name) {
|
|
439
488
|
}
|
440
489
|
}
|
441
490
|
|
442
|
-
export { Connection, ConnectionMonitor, Consumer, INTERNAL, Subscription, Subscriptions, adapters, createConsumer, createWebSocketURL, getConfig, logger };
|
491
|
+
export { Connection, ConnectionMonitor, Consumer, INTERNAL, Subscription, SubscriptionGuarantor, Subscriptions, adapters, createConsumer, createWebSocketURL, getConfig, logger };
|
@@ -246,6 +246,7 @@
|
|
246
246
|
return this.monitor.recordPing();
|
247
247
|
|
248
248
|
case message_types.confirmation:
|
249
|
+
this.subscriptions.confirmSubscription(identifier);
|
249
250
|
return this.subscriptions.notify(identifier, "connected");
|
250
251
|
|
251
252
|
case message_types.rejection:
|
@@ -310,9 +311,46 @@
|
|
310
311
|
return this.consumer.subscriptions.remove(this);
|
311
312
|
}
|
312
313
|
}
|
314
|
+
class SubscriptionGuarantor {
|
315
|
+
constructor(subscriptions) {
|
316
|
+
this.subscriptions = subscriptions;
|
317
|
+
this.pendingSubscriptions = [];
|
318
|
+
}
|
319
|
+
guarantee(subscription) {
|
320
|
+
if (this.pendingSubscriptions.indexOf(subscription) == -1) {
|
321
|
+
logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`);
|
322
|
+
this.pendingSubscriptions.push(subscription);
|
323
|
+
} else {
|
324
|
+
logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`);
|
325
|
+
}
|
326
|
+
this.startGuaranteeing();
|
327
|
+
}
|
328
|
+
forget(subscription) {
|
329
|
+
logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`);
|
330
|
+
this.pendingSubscriptions = this.pendingSubscriptions.filter((s => s !== subscription));
|
331
|
+
}
|
332
|
+
startGuaranteeing() {
|
333
|
+
this.stopGuaranteeing();
|
334
|
+
this.retrySubscribing();
|
335
|
+
}
|
336
|
+
stopGuaranteeing() {
|
337
|
+
clearTimeout(this.retryTimeout);
|
338
|
+
}
|
339
|
+
retrySubscribing() {
|
340
|
+
this.retryTimeout = setTimeout((() => {
|
341
|
+
if (this.subscriptions && typeof this.subscriptions.subscribe === "function") {
|
342
|
+
this.pendingSubscriptions.map((subscription => {
|
343
|
+
logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`);
|
344
|
+
this.subscriptions.subscribe(subscription);
|
345
|
+
}));
|
346
|
+
}
|
347
|
+
}), 500);
|
348
|
+
}
|
349
|
+
}
|
313
350
|
class Subscriptions {
|
314
351
|
constructor(consumer) {
|
315
352
|
this.consumer = consumer;
|
353
|
+
this.guarantor = new SubscriptionGuarantor(this);
|
316
354
|
this.subscriptions = [];
|
317
355
|
}
|
318
356
|
create(channelName, mixin) {
|
@@ -327,7 +365,7 @@
|
|
327
365
|
this.subscriptions.push(subscription);
|
328
366
|
this.consumer.ensureActiveConnection();
|
329
367
|
this.notify(subscription, "initialized");
|
330
|
-
this.
|
368
|
+
this.subscribe(subscription);
|
331
369
|
return subscription;
|
332
370
|
}
|
333
371
|
remove(subscription) {
|
@@ -345,6 +383,7 @@
|
|
345
383
|
}));
|
346
384
|
}
|
347
385
|
forget(subscription) {
|
386
|
+
this.guarantor.forget(subscription);
|
348
387
|
this.subscriptions = this.subscriptions.filter((s => s !== subscription));
|
349
388
|
return subscription;
|
350
389
|
}
|
@@ -352,7 +391,7 @@
|
|
352
391
|
return this.subscriptions.filter((s => s.identifier === identifier));
|
353
392
|
}
|
354
393
|
reload() {
|
355
|
-
return this.subscriptions.map((subscription => this.
|
394
|
+
return this.subscriptions.map((subscription => this.subscribe(subscription)));
|
356
395
|
}
|
357
396
|
notifyAll(callbackName, ...args) {
|
358
397
|
return this.subscriptions.map((subscription => this.notify(subscription, callbackName, ...args)));
|
@@ -366,6 +405,15 @@
|
|
366
405
|
}
|
367
406
|
return subscriptions.map((subscription => typeof subscription[callbackName] === "function" ? subscription[callbackName](...args) : undefined));
|
368
407
|
}
|
408
|
+
subscribe(subscription) {
|
409
|
+
if (this.sendCommand(subscription, "subscribe")) {
|
410
|
+
this.guarantor.guarantee(subscription);
|
411
|
+
}
|
412
|
+
}
|
413
|
+
confirmSubscription(identifier) {
|
414
|
+
logger.log(`Subscription confirmed ${identifier}`);
|
415
|
+
this.findAll(identifier).map((subscription => this.guarantor.forget(subscription)));
|
416
|
+
}
|
369
417
|
sendCommand(subscription, command) {
|
370
418
|
const {identifier: identifier} = subscription;
|
371
419
|
return this.consumer.send({
|
@@ -428,6 +476,7 @@
|
|
428
476
|
exports.Consumer = Consumer;
|
429
477
|
exports.INTERNAL = INTERNAL;
|
430
478
|
exports.Subscription = Subscription;
|
479
|
+
exports.SubscriptionGuarantor = SubscriptionGuarantor;
|
431
480
|
exports.Subscriptions = Subscriptions;
|
432
481
|
exports.adapters = adapters;
|
433
482
|
exports.createConsumer = createConsumer;
|
package/package.json
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
{
|
2
2
|
"name": "@rails/actioncable",
|
3
|
-
"version": "7.0.0-
|
3
|
+
"version": "7.0.0-rc1",
|
4
4
|
"description": "WebSocket framework for Ruby on Rails.",
|
5
|
-
"module": "app/
|
6
|
-
"main": "app/assets/javascripts/
|
5
|
+
"module": "app/assets/javascripts/actioncable.esm.js",
|
6
|
+
"main": "app/assets/javascripts/actioncable.js",
|
7
7
|
"files": [
|
8
8
|
"app/assets/javascripts/*.js",
|
9
9
|
"src/*.js"
|
package/src/connection.js
CHANGED
@@ -132,6 +132,7 @@ Connection.prototype.events = {
|
|
132
132
|
case message_types.ping:
|
133
133
|
return this.monitor.recordPing()
|
134
134
|
case message_types.confirmation:
|
135
|
+
this.subscriptions.confirmSubscription(identifier)
|
135
136
|
return this.subscriptions.notify(identifier, "connected")
|
136
137
|
case message_types.rejection:
|
137
138
|
return this.subscriptions.reject(identifier)
|
package/src/index.js
CHANGED
@@ -4,6 +4,7 @@ import Consumer, { createWebSocketURL } from "./consumer"
|
|
4
4
|
import INTERNAL from "./internal"
|
5
5
|
import Subscription from "./subscription"
|
6
6
|
import Subscriptions from "./subscriptions"
|
7
|
+
import SubscriptionGuarantor from "./subscription_guarantor"
|
7
8
|
import adapters from "./adapters"
|
8
9
|
import logger from "./logger"
|
9
10
|
|
@@ -14,6 +15,7 @@ export {
|
|
14
15
|
INTERNAL,
|
15
16
|
Subscription,
|
16
17
|
Subscriptions,
|
18
|
+
SubscriptionGuarantor,
|
17
19
|
adapters,
|
18
20
|
createWebSocketURL,
|
19
21
|
logger,
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import logger from "./logger"
|
2
|
+
|
3
|
+
// Responsible for ensuring channel subscribe command is confirmed, retrying until confirmation is received.
|
4
|
+
// Internal class, not intended for direct user manipulation.
|
5
|
+
|
6
|
+
class SubscriptionGuarantor {
|
7
|
+
constructor(subscriptions) {
|
8
|
+
this.subscriptions = subscriptions
|
9
|
+
this.pendingSubscriptions = []
|
10
|
+
}
|
11
|
+
|
12
|
+
guarantee(subscription) {
|
13
|
+
if(this.pendingSubscriptions.indexOf(subscription) == -1){
|
14
|
+
logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`)
|
15
|
+
this.pendingSubscriptions.push(subscription)
|
16
|
+
}
|
17
|
+
else {
|
18
|
+
logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`)
|
19
|
+
}
|
20
|
+
this.startGuaranteeing()
|
21
|
+
}
|
22
|
+
|
23
|
+
forget(subscription) {
|
24
|
+
logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`)
|
25
|
+
this.pendingSubscriptions = (this.pendingSubscriptions.filter((s) => s !== subscription))
|
26
|
+
}
|
27
|
+
|
28
|
+
startGuaranteeing() {
|
29
|
+
this.stopGuaranteeing()
|
30
|
+
this.retrySubscribing()
|
31
|
+
}
|
32
|
+
|
33
|
+
stopGuaranteeing() {
|
34
|
+
clearTimeout(this.retryTimeout)
|
35
|
+
}
|
36
|
+
|
37
|
+
retrySubscribing() {
|
38
|
+
this.retryTimeout = setTimeout(() => {
|
39
|
+
if (this.subscriptions && typeof(this.subscriptions.subscribe) === "function") {
|
40
|
+
this.pendingSubscriptions.map((subscription) => {
|
41
|
+
logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`)
|
42
|
+
this.subscriptions.subscribe(subscription)
|
43
|
+
})
|
44
|
+
}
|
45
|
+
}
|
46
|
+
, 500)
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
export default SubscriptionGuarantor
|
package/src/subscriptions.js
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
import Subscription from "./subscription"
|
2
|
+
import SubscriptionGuarantor from "./subscription_guarantor"
|
3
|
+
import logger from "./logger"
|
2
4
|
|
3
5
|
// Collection class for creating (and internally managing) channel subscriptions.
|
4
6
|
// The only method intended to be triggered by the user is ActionCable.Subscriptions#create,
|
@@ -13,6 +15,7 @@ import Subscription from "./subscription"
|
|
13
15
|
export default class Subscriptions {
|
14
16
|
constructor(consumer) {
|
15
17
|
this.consumer = consumer
|
18
|
+
this.guarantor = new SubscriptionGuarantor(this)
|
16
19
|
this.subscriptions = []
|
17
20
|
}
|
18
21
|
|
@@ -29,7 +32,7 @@ export default class Subscriptions {
|
|
29
32
|
this.subscriptions.push(subscription)
|
30
33
|
this.consumer.ensureActiveConnection()
|
31
34
|
this.notify(subscription, "initialized")
|
32
|
-
this.
|
35
|
+
this.subscribe(subscription)
|
33
36
|
return subscription
|
34
37
|
}
|
35
38
|
|
@@ -50,6 +53,7 @@ export default class Subscriptions {
|
|
50
53
|
}
|
51
54
|
|
52
55
|
forget(subscription) {
|
56
|
+
this.guarantor.forget(subscription)
|
53
57
|
this.subscriptions = (this.subscriptions.filter((s) => s !== subscription))
|
54
58
|
return subscription
|
55
59
|
}
|
@@ -60,7 +64,7 @@ export default class Subscriptions {
|
|
60
64
|
|
61
65
|
reload() {
|
62
66
|
return this.subscriptions.map((subscription) =>
|
63
|
-
this.
|
67
|
+
this.subscribe(subscription))
|
64
68
|
}
|
65
69
|
|
66
70
|
notifyAll(callbackName, ...args) {
|
@@ -80,6 +84,18 @@ export default class Subscriptions {
|
|
80
84
|
(typeof subscription[callbackName] === "function" ? subscription[callbackName](...args) : undefined))
|
81
85
|
}
|
82
86
|
|
87
|
+
subscribe(subscription) {
|
88
|
+
if (this.sendCommand(subscription, "subscribe")) {
|
89
|
+
this.guarantor.guarantee(subscription)
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
confirmSubscription(identifier) {
|
94
|
+
logger.log(`Subscription confirmed ${identifier}`)
|
95
|
+
this.findAll(identifier).map((subscription) =>
|
96
|
+
this.guarantor.forget(subscription))
|
97
|
+
}
|
98
|
+
|
83
99
|
sendCommand(subscription, command) {
|
84
100
|
const {identifier} = subscription
|
85
101
|
return this.consumer.send({command, identifier})
|
package/CHANGELOG.md
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
## Rails 7.0.0.alpha2 (September 15, 2021) ##
|
2
|
-
|
3
|
-
* No changes.
|
4
|
-
|
5
|
-
|
6
|
-
## Rails 7.0.0.alpha1 (September 15, 2021) ##
|
7
|
-
|
8
|
-
* Compile ESM package that can be used directly in the browser as actioncable.esm.js.
|
9
|
-
|
10
|
-
*DHH*
|
11
|
-
|
12
|
-
* Move action_cable.js to actioncable.js to match naming convention used for other Rails frameworks, and use JS console to communicate the deprecation.
|
13
|
-
|
14
|
-
*DHH*
|
15
|
-
|
16
|
-
* Stop transpiling the UMD package generated as actioncable.js and drop the IE11 testing that relied on that.
|
17
|
-
|
18
|
-
*DHH*
|
19
|
-
|
20
|
-
* Truncate broadcast logging messages.
|
21
|
-
|
22
|
-
*J Smith*
|
23
|
-
|
24
|
-
* OpenSSL constants are now used for Digest computations.
|
25
|
-
|
26
|
-
*Dirkjan Bussink*
|
27
|
-
|
28
|
-
* The Action Cable client now includes safeguards to prevent a "thundering
|
29
|
-
herd" of client reconnects after server connectivity loss:
|
30
|
-
|
31
|
-
* The client will wait a random amount between 1x and 3x of the stale
|
32
|
-
threshold after the server's last ping before making the first
|
33
|
-
reconnection attempt.
|
34
|
-
* Subsequent reconnection attempts now use exponential backoff instead of
|
35
|
-
logarithmic backoff. To allow the delay between reconnection attempts to
|
36
|
-
increase slowly at first, the default exponentiation base is < 2.
|
37
|
-
* Random jitter is applied to each delay between reconnection attempts.
|
38
|
-
|
39
|
-
*Jonathan Hefner*
|
40
|
-
|
41
|
-
|
42
|
-
Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/actioncable/CHANGELOG.md) for previous changes.
|