@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.
package/src/consumer.js CHANGED
@@ -6,7 +6,7 @@ import Subscriptions from "./subscriptions"
6
6
  // The Consumer instance is also the gateway to establishing subscriptions to desired channels through the #createSubscription
7
7
  // method.
8
8
  //
9
- // The following example shows how this can be setup:
9
+ // The following example shows how this can be set up:
10
10
  //
11
11
  // App = {}
12
12
  // App.cable = ActionCable.createConsumer("ws://example.com/accounts/1")
@@ -32,6 +32,7 @@ export default class Consumer {
32
32
  this._url = url
33
33
  this.subscriptions = new Subscriptions(this)
34
34
  this.connection = new Connection(this)
35
+ this.subprotocols = []
35
36
  }
36
37
 
37
38
  get url() {
@@ -55,6 +56,10 @@ export default class Consumer {
55
56
  return this.connection.open()
56
57
  }
57
58
  }
59
+
60
+ addSubProtocol(subprotocol) {
61
+ this.subprotocols = [...this.subprotocols, subprotocol]
62
+ }
58
63
  }
59
64
 
60
65
  export function createWebSocketURL(url) {
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,2 @@
1
+ export * from "./index"
2
+ console.log("DEPRECATION: action_cable.js has been renamed to actioncable.js – please update your reference before Rails 8")
@@ -0,0 +1,20 @@
1
+ export default {
2
+ "message_types": {
3
+ "welcome": "welcome",
4
+ "disconnect": "disconnect",
5
+ "ping": "ping",
6
+ "confirmation": "confirm_subscription",
7
+ "rejection": "reject_subscription"
8
+ },
9
+ "disconnect_reasons": {
10
+ "unauthorized": "unauthorized",
11
+ "invalid_request": "invalid_request",
12
+ "server_restart": "server_restart",
13
+ "remote": "remote"
14
+ },
15
+ "default_mount_path": "/cable",
16
+ "protocols": [
17
+ "actioncable-v1-json",
18
+ "actioncable-unsupported"
19
+ ]
20
+ }
package/src/logger.js CHANGED
@@ -1,5 +1,17 @@
1
1
  import adapters from "./adapters"
2
2
 
3
+ // The logger is disabled by default. You can enable it with:
4
+ //
5
+ // ActionCable.logger.enabled = true
6
+ //
7
+ // Example:
8
+ //
9
+ // import * as ActionCable from '@rails/actioncable'
10
+ //
11
+ // ActionCable.logger.enabled = true
12
+ // ActionCable.logger.log('Connection Established.')
13
+ //
14
+
3
15
  export default {
4
16
  log(...messages) {
5
17
  if (this.enabled) {
@@ -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
@@ -1,7 +1,10 @@
1
1
  import Subscription from "./subscription"
2
+ import SubscriptionGuarantor from "./subscription_guarantor"
3
+ import logger from "./logger"
2
4
 
3
- // Collection class for creating (and internally managing) channel subscriptions. The only method intended to be triggered by the user
4
- // us ActionCable.Subscriptions#create, and it should be called through the consumer like so:
5
+ // Collection class for creating (and internally managing) channel subscriptions.
6
+ // The only method intended to be triggered by the user is ActionCable.Subscriptions#create,
7
+ // and it should be called through the consumer like so:
5
8
  //
6
9
  // App = {}
7
10
  // App.cable = ActionCable.createConsumer("ws://example.com/accounts/1")
@@ -12,6 +15,7 @@ import Subscription from "./subscription"
12
15
  export default class Subscriptions {
13
16
  constructor(consumer) {
14
17
  this.consumer = consumer
18
+ this.guarantor = new SubscriptionGuarantor(this)
15
19
  this.subscriptions = []
16
20
  }
17
21
 
@@ -28,7 +32,7 @@ export default class Subscriptions {
28
32
  this.subscriptions.push(subscription)
29
33
  this.consumer.ensureActiveConnection()
30
34
  this.notify(subscription, "initialized")
31
- this.sendCommand(subscription, "subscribe")
35
+ this.subscribe(subscription)
32
36
  return subscription
33
37
  }
34
38
 
@@ -49,6 +53,7 @@ export default class Subscriptions {
49
53
  }
50
54
 
51
55
  forget(subscription) {
56
+ this.guarantor.forget(subscription)
52
57
  this.subscriptions = (this.subscriptions.filter((s) => s !== subscription))
53
58
  return subscription
54
59
  }
@@ -59,7 +64,7 @@ export default class Subscriptions {
59
64
 
60
65
  reload() {
61
66
  return this.subscriptions.map((subscription) =>
62
- this.sendCommand(subscription, "subscribe"))
67
+ this.subscribe(subscription))
63
68
  }
64
69
 
65
70
  notifyAll(callbackName, ...args) {
@@ -79,6 +84,18 @@ export default class Subscriptions {
79
84
  (typeof subscription[callbackName] === "function" ? subscription[callbackName](...args) : undefined))
80
85
  }
81
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
+
82
99
  sendCommand(subscription, command) {
83
100
  const {identifier} = subscription
84
101
  return this.consumer.send({command, identifier})
package/CHANGELOG.md DELETED
@@ -1,179 +0,0 @@
1
- ## Rails 6.0.2 (December 13, 2019) ##
2
-
3
- * No changes.
4
-
5
-
6
- ## Rails 6.0.1 (November 5, 2019) ##
7
-
8
- * No changes.
9
-
10
-
11
- ## Rails 6.0.0 (August 16, 2019) ##
12
-
13
- * No changes.
14
-
15
-
16
- ## Rails 6.0.0.rc2 (July 22, 2019) ##
17
-
18
- * No changes.
19
-
20
-
21
- ## Rails 6.0.0.rc1 (April 24, 2019) ##
22
-
23
- * No changes.
24
-
25
-
26
- ## Rails 6.0.0.beta3 (March 11, 2019) ##
27
-
28
- * No changes.
29
-
30
-
31
- ## Rails 6.0.0.beta2 (February 25, 2019) ##
32
-
33
- * PostgreSQL subscription adapters now support `channel_prefix` option in cable.yml
34
-
35
- Avoids channel name collisions when multiple apps use the same database for Action Cable.
36
-
37
- *Vladimir Dementyev*
38
-
39
- * Allow passing custom configuration to `ActionCable::Server::Base`.
40
-
41
- You can now create a standalone Action Cable server with a custom configuration
42
- (e.g. to run it in isolation from the default one):
43
-
44
- ```ruby
45
- config = ActionCable::Server::Configuration.new
46
- config.cable = { adapter: "redis", channel_prefix: "custom_" }
47
-
48
- CUSTOM_CABLE = ActionCable::Server::Base.new(config: config)
49
- ```
50
-
51
- Then you can mount it in the `routes.rb` file:
52
-
53
- ```ruby
54
- Rails.application.routes.draw do
55
- mount CUSTOM_CABLE => "/custom_cable"
56
- # ...
57
- end
58
- ```
59
-
60
- *Vladimir Dementyev*
61
-
62
- * Add `:action_cable_connection` and `:action_cable_channel` load hooks.
63
-
64
- You can use them to extend `ActionCable::Connection::Base` and `ActionCable::Channel::Base`
65
- functionality:
66
-
67
- ```ruby
68
- ActiveSupport.on_load(:action_cable_channel) do
69
- # do something in the context of ActionCable::Channel::Base
70
- end
71
- ```
72
-
73
- *Vladimir Dementyev*
74
-
75
- * Add `Channel::Base#broadcast_to`.
76
-
77
- You can now call `broadcast_to` within a channel action, which equals to
78
- the `self.class.broadcast_to`.
79
-
80
- *Vladimir Dementyev*
81
-
82
- * Make `Channel::Base.broadcasting_for` a public API.
83
-
84
- You can use `.broadcasting_for` to generate a unique stream identifier within
85
- a channel for the specified target (e.g. Active Record model):
86
-
87
- ```ruby
88
- ChatChannel.broadcasting_for(model) # => "chat:<model.to_gid_param>"
89
- ```
90
-
91
- *Vladimir Dementyev*
92
-
93
-
94
- ## Rails 6.0.0.beta1 (January 18, 2019) ##
95
-
96
- * [Rename npm package](https://github.com/rails/rails/pull/34905) from
97
- [`actioncable`](https://www.npmjs.com/package/actioncable) to
98
- [`@rails/actioncable`](https://www.npmjs.com/package/@rails/actioncable).
99
-
100
- *Javan Makhmali*
101
-
102
- * Merge [`action-cable-testing`](https://github.com/palkan/action-cable-testing) to Rails.
103
-
104
- *Vladimir Dementyev*
105
-
106
- * The JavaScript WebSocket client will no longer try to reconnect
107
- when you call `reject_unauthorized_connection` on the connection.
108
-
109
- *Mick Staugaard*
110
-
111
- * `ActionCable.Connection#getState` now references the configurable
112
- `ActionCable.adapters.WebSocket` property rather than the `WebSocket` global
113
- variable, matching the behavior of `ActionCable.Connection#open`.
114
-
115
- *Richard Macklin*
116
-
117
- * The ActionCable javascript package has been converted from CoffeeScript
118
- to ES2015, and we now publish the source code in the npm distribution.
119
-
120
- This allows ActionCable users to depend on the javascript source code
121
- rather than the compiled code, which can produce smaller javascript bundles.
122
-
123
- This change includes some breaking changes to optional parts of the
124
- ActionCable javascript API:
125
-
126
- - Configuration of the WebSocket adapter and logger adapter have been moved
127
- from properties of `ActionCable` to properties of `ActionCable.adapters`.
128
- If you are currently configuring these adapters you will need to make
129
- these changes when upgrading:
130
-
131
- ```diff
132
- - ActionCable.WebSocket = MyWebSocket
133
- + ActionCable.adapters.WebSocket = MyWebSocket
134
- ```
135
- ```diff
136
- - ActionCable.logger = myLogger
137
- + ActionCable.adapters.logger = myLogger
138
- ```
139
-
140
- - The `ActionCable.startDebugging()` and `ActionCable.stopDebugging()`
141
- methods have been removed and replaced with the property
142
- `ActionCable.logger.enabled`. If you are currently using these methods you
143
- will need to make these changes when upgrading:
144
-
145
- ```diff
146
- - ActionCable.startDebugging()
147
- + ActionCable.logger.enabled = true
148
- ```
149
- ```diff
150
- - ActionCable.stopDebugging()
151
- + ActionCable.logger.enabled = false
152
- ```
153
-
154
- *Richard Macklin*
155
-
156
- * Add `id` option to redis adapter so now you can distinguish
157
- ActionCable's redis connections among others. Also, you can set
158
- custom id in options.
159
-
160
- Before:
161
- ```
162
- $ redis-cli client list
163
- id=669 addr=127.0.0.1:46442 fd=8 name= age=18 ...
164
- ```
165
-
166
- After:
167
- ```
168
- $ redis-cli client list
169
- id=673 addr=127.0.0.1:46516 fd=8 name=ActionCable-PID-19413 age=2 ...
170
- ```
171
-
172
- *Ilia Kasianenko*
173
-
174
- * Rails 6 requires Ruby 2.5.0 or newer.
175
-
176
- *Jeremy Daer*, *Kasper Timm Hansen*
177
-
178
-
179
- Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/actioncable/CHANGELOG.md) for previous changes.