aboutsummaryrefslogtreecommitdiffstats
path: root/actioncable/app/javascript/action_cable/subscription.js
diff options
context:
space:
mode:
authorRichard Macklin <richard.github@nrm.com>2018-01-20 23:33:32 -0800
committerRichard Macklin <richard.github@nrm.com>2018-11-02 08:41:05 -0700
commitc96139af71e6f7c36e25bccea6b05ccd9523531a (patch)
tree119448211713b6a172b301ab164dd54dd5718654 /actioncable/app/javascript/action_cable/subscription.js
parent0eb6b86e9606cace49afba0b35ec18916c73646e (diff)
downloadrails-c96139af71e6f7c36e25bccea6b05ccd9523531a.tar.gz
rails-c96139af71e6f7c36e25bccea6b05ccd9523531a.tar.bz2
rails-c96139af71e6f7c36e25bccea6b05ccd9523531a.zip
Convert ActionCable javascript to ES2015 modules with modern build environment
We've replaced the sprockets `//= require` directives with ES2015 imports. As a result, the ActionCable javascript can now be compiled with rollup (like ActiveStorage already is). - Rename action_cable/index.js.erb -> action_cable/index.js - Add rake task to generate a javascript module of the ActionCable::INTERNAL ruby hash This will allow us to get rid of ERB from the actioncable javascript, since it is only used to interpolate ActionCable::INTERNAL.to_json. - Import INTERNAL directly in ActionCable Connection module This is necessary to remove a load-order dependency conflict in the rollup-compiled build. Using ActionCable.INTERNAL would result in a runtime error: ``` TypeError: Cannot read property 'INTERNAL' of undefined ``` because ActionCable.INTERNAL is not set before the Connection module is executed. All other ActionCable.* references are executed inside of the body of a function, so there is no load-order dependency there. - Add eslint and eslint-plugin-import devDependencies to actioncable These will be used to add a linting setup to actioncable like the one in activestorage. - Add .eslintrc to actioncable This lint configuration was copied from activestorage - Add lint script to actioncable This is the same as the lint script in activestorage - Add babel-core, babel-plugin-external-helpers, and babel-preset-env devDependencies to actioncable These will be used to add ES2015 transpilation support to actioncable like we have in activestorage. - Add .babelrc to actioncable This configuration was copied from activestorage - Enable loose mode in ActionCable's babel config This generates a smaller bundle when compiled - Add rollup devDependencies to actioncable These will be used to add a modern build pipeline to actioncable like the one in activestorage. - Add rollup config to actioncable This is essentially the same as the rollup config from activestorage - Add prebuild and build scripts to actioncable package These scripts were copied from activestorage - Invoke code generation task as part of actioncable's prebuild script This will guarantee that the action_cable/internal.js module is available at build time (which is important, because two other modules now depend on it). - Update actioncable package to reference the rollup-compiled files Now that we have a fully functional rollup pipeline in actioncable, we can use the compiled output in our npm package. - Remove build section from ActionCable blade config Now that rollup is responsible for building ActionCable, we can remove that responsibility from Blade. - Remove assets:compile and assets:verify tasks from ActionCable Now that we've added a compiled ActionCable bundle to version control, we don't need to compile and verify it at publish-time. (We're following the pattern set in ActiveStorage.) - Include compiled ActionCable javascript bundle in published gem This is necessary to maintain support for depending on the ActionCable javascript through the Sprockets asset pipeline. - Add compiled ActionCable bundle to version control This mirrors what we do in ActiveStorage, and allows ActionCable to continue to be consumed via the sprockets-based asset pipeline when using a git source instead of a published version of the gem.
Diffstat (limited to 'actioncable/app/javascript/action_cable/subscription.js')
-rw-r--r--actioncable/app/javascript/action_cable/subscription.js53
1 files changed, 25 insertions, 28 deletions
diff --git a/actioncable/app/javascript/action_cable/subscription.js b/actioncable/app/javascript/action_cable/subscription.js
index 95b9ff6042..7de08f93b3 100644
--- a/actioncable/app/javascript/action_cable/subscription.js
+++ b/actioncable/app/javascript/action_cable/subscription.js
@@ -55,38 +55,35 @@
//
// The "AppearanceChannel" name is automatically mapped between the client-side subscription creation and the server-side Ruby class name.
// The AppearanceChannel#appear/away public methods are exposed automatically to client-side invocation through the perform method.
-ActionCable.Subscription = (function() {
- const extend = function(object, properties) {
- if (properties != null) {
- for (let key in properties) {
- const value = properties[key]
- object[key] = value
- }
- }
- return object
- }
- class Subscription {
- constructor(consumer, params = {}, mixin) {
- this.consumer = consumer
- this.identifier = JSON.stringify(params)
- extend(this, mixin)
+const extend = function(object, properties) {
+ if (properties != null) {
+ for (let key in properties) {
+ const value = properties[key]
+ object[key] = value
}
+ }
+ return object
+}
- // Perform a channel action with the optional data passed as an attribute
- perform(action, data = {}) {
- data.action = action
- return this.send(data)
- }
+export default class Subscription {
+ constructor(consumer, params = {}, mixin) {
+ this.consumer = consumer
+ this.identifier = JSON.stringify(params)
+ extend(this, mixin)
+ }
- send(data) {
- return this.consumer.send({command: "message", identifier: this.identifier, data: JSON.stringify(data)})
- }
+ // Perform a channel action with the optional data passed as an attribute
+ perform(action, data = {}) {
+ data.action = action
+ return this.send(data)
+ }
- unsubscribe() {
- return this.consumer.subscriptions.remove(this)
- }
+ send(data) {
+ return this.consumer.send({command: "message", identifier: this.identifier, data: JSON.stringify(data)})
}
- return Subscription
-})()
+ unsubscribe() {
+ return this.consumer.subscriptions.remove(this)
+ }
+}