aboutsummaryrefslogtreecommitdiffstats
path: root/actioncable/app/javascript/action_cable/index.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/index.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/index.js')
-rw-r--r--actioncable/app/javascript/action_cable/index.js58
1 files changed, 58 insertions, 0 deletions
diff --git a/actioncable/app/javascript/action_cable/index.js b/actioncable/app/javascript/action_cable/index.js
new file mode 100644
index 0000000000..eb0c4844df
--- /dev/null
+++ b/actioncable/app/javascript/action_cable/index.js
@@ -0,0 +1,58 @@
+import Connection from "./connection"
+import ConnectionMonitor from "./connection_monitor"
+import Consumer from "./consumer"
+import INTERNAL from "./internal"
+import Subscription from "./subscription"
+import Subscriptions from "./subscriptions"
+
+export default {
+ Connection,
+ ConnectionMonitor,
+ Consumer,
+ INTERNAL,
+ Subscription,
+ Subscriptions,
+ WebSocket: window.WebSocket,
+ logger: window.console,
+
+ createConsumer(url) {
+ if (url == null) {
+ const urlConfig = this.getConfig("url")
+ url = (urlConfig ? urlConfig : this.INTERNAL.default_mount_path)
+ }
+ return new Consumer(this.createWebSocketURL(url))
+ },
+
+ getConfig(name) {
+ const element = document.head.querySelector(`meta[name='action-cable-${name}']`)
+ return (element ? element.getAttribute("content") : undefined)
+ },
+
+ createWebSocketURL(url) {
+ if (url && !/^wss?:/i.test(url)) {
+ const a = document.createElement("a")
+ a.href = url
+ // Fix populating Location properties in IE. Otherwise, protocol will be blank.
+ a.href = a.href
+ a.protocol = a.protocol.replace("http", "ws")
+ return a.href
+ } else {
+ return url
+ }
+ },
+
+ startDebugging() {
+ this.debugging = true
+ },
+
+ stopDebugging() {
+ this.debugging = null
+ },
+
+ log(...messages) {
+ if (this.debugging) {
+ messages.push(Date.now())
+ this.logger.log("[ActionCable]", ...messages)
+ }
+ }
+}