actioncable 6.1.5 → 7.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
@@ -25,7 +25,7 @@ module ActionCable
25
25
  serialize_broadcasting([ channel_name, model ])
26
26
  end
27
27
 
28
- def serialize_broadcasting(object) #:nodoc:
28
+ def serialize_broadcasting(object) # :nodoc:
29
29
  case
30
30
  when object.is_a?(Array)
31
31
  object.map { |m| serialize_broadcasting(m) }.join(":")
@@ -124,13 +124,11 @@ module ActionCable
124
124
  end.clear
125
125
  end
126
126
 
127
- # Calls stream_for if record is present, otherwise calls reject.
128
- # This method is intended to be called when you're looking
129
- # for a record based on a parameter, if its found it will start
130
- # streaming. If the record is nil then it will reject the connection.
131
- def stream_or_reject_for(record)
132
- if record
133
- stream_for record
127
+ # Calls stream_for with the given <tt>model</tt> if it's present to start streaming,
128
+ # otherwise rejects the subscription.
129
+ def stream_or_reject_for(model)
130
+ if model
131
+ stream_for model
134
132
  else
135
133
  reject
136
134
  end
@@ -246,7 +246,7 @@ module ActionCable
246
246
  # Returns messages transmitted into channel
247
247
  def transmissions
248
248
  # Return only directly sent message (via #transmit)
249
- connection.transmissions.map { |data| data["message"] }.compact
249
+ connection.transmissions.filter_map { |data| data["message"] }
250
250
  end
251
251
 
252
252
  # Enhance TestHelper assertions to handle non-String
@@ -68,7 +68,7 @@ module ActionCable
68
68
 
69
69
  # Called by the server when a new WebSocket connection is established. This configures the callbacks intended for overwriting by the user.
70
70
  # This method should not be called directly -- instead rely upon on the #connect (and #disconnect) callbacks.
71
- def process #:nodoc:
71
+ def process # :nodoc:
72
72
  logger.info started_request_message
73
73
 
74
74
  if websocket.possible? && allow_request_origin?
@@ -80,11 +80,11 @@ module ActionCable
80
80
 
81
81
  # Decodes WebSocket messages and dispatches them to subscribed channels.
82
82
  # WebSocket message transfer encoding is always JSON.
83
- def receive(websocket_message) #:nodoc:
83
+ def receive(websocket_message) # :nodoc:
84
84
  send_async :dispatch_websocket_message, websocket_message
85
85
  end
86
86
 
87
- def dispatch_websocket_message(websocket_message) #:nodoc:
87
+ def dispatch_websocket_message(websocket_message) # :nodoc:
88
88
  if websocket.alive?
89
89
  subscriptions.execute_command decode(websocket_message)
90
90
  else
@@ -26,7 +26,7 @@ module ActionCable
26
26
  # Return a single connection identifier that combines the value of all the registered identifiers into a single gid.
27
27
  def connection_identifier
28
28
  unless defined? @connection_identifier
29
- @connection_identifier = connection_gid identifiers.map { |id| instance_variable_get("@#{id}") }.compact
29
+ @connection_identifier = connection_gid identifiers.filter_map { |id| instance_variable_get("@#{id}") }
30
30
  end
31
31
 
32
32
  @connection_identifier
@@ -33,7 +33,7 @@ module ActionCable
33
33
 
34
34
  subscription_klass = id_options[:channel].safe_constantize
35
35
 
36
- if subscription_klass && ActionCable::Channel::Base >= subscription_klass
36
+ if subscription_klass && ActionCable::Channel::Base > subscription_klass
37
37
  subscription = subscription_klass.new(connection, id_key, id_options)
38
38
  subscriptions[id_key] = subscription
39
39
  subscription.subscribe_to_channel
@@ -18,10 +18,10 @@ module ActionCable
18
18
  @tags = @tags.uniq
19
19
  end
20
20
 
21
- def tag(logger)
21
+ def tag(logger, &block)
22
22
  if logger.respond_to?(:tagged)
23
23
  current_tags = tags - logger.formatter.current_tags
24
- logger.tagged(*current_tags) { yield }
24
+ logger.tagged(*current_tags, &block)
25
25
  else
26
26
  yield
27
27
  end
@@ -9,6 +9,7 @@ module ActionCable
9
9
  class Engine < Rails::Engine # :nodoc:
10
10
  config.action_cable = ActiveSupport::OrderedOptions.new
11
11
  config.action_cable.mount_path = ActionCable::INTERNAL[:default_mount_path]
12
+ config.action_cable.precompile_assets = true
12
13
 
13
14
  config.eager_load_namespaces << ActionCable
14
15
 
@@ -22,6 +23,14 @@ module ActionCable
22
23
  ActiveSupport.on_load(:action_cable) { self.logger ||= ::Rails.logger }
23
24
  end
24
25
 
26
+ initializer "action_cable.asset" do
27
+ config.after_initialize do |app|
28
+ if Rails.application.config.respond_to?(:assets) && app.config.action_cable.precompile_assets
29
+ Rails.application.config.assets.precompile += %w( actioncable.js actioncable.esm.js )
30
+ end
31
+ end
32
+ end
33
+
25
34
  initializer "action_cable.set_configs" do |app|
26
35
  options = app.config.action_cable
27
36
  options.allowed_request_origins ||= /https?:\/\/localhost:\d+/ if ::Rails.env.development?
@@ -7,10 +7,10 @@ module ActionCable
7
7
  end
8
8
 
9
9
  module VERSION
10
- MAJOR = 6
11
- MINOR = 1
12
- TINY = 5
13
- PRE = nil
10
+ MAJOR = 7
11
+ MINOR = 0
12
+ TINY = 0
13
+ PRE = "alpha1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -8,14 +8,15 @@ module ActionCable
8
8
  #
9
9
  # <head>
10
10
  # <%= action_cable_meta_tag %>
11
- # <%= javascript_include_tag 'application', 'data-turbolinks-track' => 'reload' %>
11
+ # <%= javascript_include_tag 'application', 'data-turbo-track' => 'reload' %>
12
12
  # </head>
13
13
  #
14
14
  # This is then used by Action Cable to determine the URL of your WebSocket server.
15
15
  # Your JavaScript can then connect to the server without needing to specify the
16
16
  # URL directly:
17
17
  #
18
- # window.Cable = require("@rails/actioncable")
18
+ # import Cable from "@rails/actioncable"
19
+ # window.Cable = Cable
19
20
  # window.App = {}
20
21
  # App.cable = Cable.createConsumer()
21
22
  #
@@ -9,6 +9,7 @@ module ActionCable
9
9
  attr_accessor :connection_class, :worker_pool_size
10
10
  attr_accessor :disable_request_forgery_protection, :allowed_request_origins, :allow_same_origin_as_host
11
11
  attr_accessor :cable, :url, :mount_path
12
+ attr_accessor :precompile_assets
12
13
 
13
14
  def initialize
14
15
  @log_tags = []
@@ -12,8 +12,8 @@ module ActionCable
12
12
  end
13
13
  end
14
14
 
15
- def with_database_connections
16
- connection.logger.tag(ActiveRecord::Base.logger) { yield }
15
+ def with_database_connections(&block)
16
+ connection.logger.tag(ActiveRecord::Base.logger, &block)
17
17
  end
18
18
  end
19
19
  end
@@ -19,6 +19,7 @@ module ActionCable
19
19
 
20
20
  def initialize(max_size: 5)
21
21
  @executor = Concurrent::ThreadPoolExecutor.new(
22
+ name: "ActionCable",
22
23
  min_threads: 1,
23
24
  max_threads: max_size,
24
25
  max_queue: 0,
@@ -35,12 +36,10 @@ module ActionCable
35
36
  @executor.shuttingdown?
36
37
  end
37
38
 
38
- def work(connection)
39
+ def work(connection, &block)
39
40
  self.connection = connection
40
41
 
41
- run_callbacks :work do
42
- yield
43
- end
42
+ run_callbacks :work, &block
44
43
  ensure
45
44
  self.connection = nil
46
45
  end
@@ -3,7 +3,7 @@
3
3
  gem "pg", "~> 1.1"
4
4
  require "pg"
5
5
  require "thread"
6
- require "digest/sha1"
6
+ require "openssl"
7
7
 
8
8
  module ActionCable
9
9
  module SubscriptionAdapter
@@ -58,7 +58,7 @@ module ActionCable
58
58
 
59
59
  private
60
60
  def channel_identifier(channel)
61
- channel.size > 63 ? Digest::SHA1.hexdigest(channel) : channel
61
+ channel.size > 63 ? OpenSSL::Digest::SHA1.hexdigest(channel) : channel
62
62
  end
63
63
 
64
64
  def listener
@@ -45,7 +45,7 @@ module ActionCable
45
45
  def assert_broadcasts(stream, number, &block)
46
46
  if block_given?
47
47
  original_count = broadcasts_size(stream)
48
- assert_nothing_raised(&block)
48
+ _assert_nothing_raised_or_warn("assert_broadcasts", &block)
49
49
  new_count = broadcasts_size(stream)
50
50
  actual_count = new_count - original_count
51
51
  else
@@ -106,7 +106,7 @@ module ActionCable
106
106
  old_messages = new_messages
107
107
  clear_messages(stream)
108
108
 
109
- assert_nothing_raised(&block)
109
+ _assert_nothing_raised_or_warn("assert_broadcast_on", &block)
110
110
  new_messages = broadcasts(stream)
111
111
  clear_messages(stream)
112
112
 
data/lib/action_cable.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2015-2022 Basecamp, LLC
4
+ # Copyright (c) 2015-2021 Basecamp, LLC
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
@@ -10,4 +10,4 @@ Example:
10
10
  creates a Chat channel class, test and JavaScript asset:
11
11
  Channel: app/channels/chat_channel.rb
12
12
  Test: test/channels/chat_channel_test.rb
13
- Assets: app/javascript/channels/chat_channel.js
13
+ Assets: $JAVASCRIPT_PATH/channels/chat_channel.js
@@ -13,39 +13,98 @@ module Rails
13
13
 
14
14
  hook_for :test_framework
15
15
 
16
- def create_channel_file
17
- template "channel.rb", File.join("app/channels", class_path, "#{file_name}_channel.rb")
16
+ def create_channel_files
17
+ create_shared_channel_files
18
+ create_channel_file
18
19
 
19
- if options[:assets]
20
- if behavior == :invoke
21
- template "javascript/index.js", "app/javascript/channels/index.js"
22
- template "javascript/consumer.js", "app/javascript/channels/consumer.js"
20
+ if using_javascript?
21
+ if first_setup_required?
22
+ create_shared_channel_javascript_files
23
+ import_channels_in_javascript_entrypoint
24
+
25
+ if using_importmap?
26
+ pin_javascript_dependencies
27
+ elsif using_node?
28
+ install_javascript_dependencies
29
+ end
23
30
  end
24
31
 
25
- js_template "javascript/channel", File.join("app/javascript/channels", class_path, "#{file_name}_channel")
32
+ create_channel_javascript_file
33
+ import_channel_in_javascript_entrypoint
26
34
  end
27
-
28
- generate_application_cable_files
29
35
  end
30
36
 
31
37
  private
38
+ def create_shared_channel_files
39
+ return if behavior != :invoke
40
+
41
+ copy_file "#{__dir__}/templates/application_cable/channel.rb",
42
+ "app/channels/application_cable/channel.rb"
43
+ copy_file "#{__dir__}/templates/application_cable/connection.rb",
44
+ "app/channels/application_cable/connection.rb"
45
+ end
46
+
47
+ def create_channel_file
48
+ template "channel.rb",
49
+ File.join("app/channels", class_path, "#{file_name}_channel.rb")
50
+ end
51
+
52
+ def create_shared_channel_javascript_files
53
+ template "javascript/index.js", "app/javascript/channels/index.js"
54
+ template "javascript/consumer.js", "app/javascript/channels/consumer.js"
55
+ end
56
+
57
+ def create_channel_javascript_file
58
+ channel_js_path = File.join("app/javascript/channels", class_path, "#{file_name}_channel")
59
+ js_template "javascript/channel", channel_js_path
60
+ gsub_file "#{channel_js_path}.js", /\.\/consumer/, "channels/consumer" unless using_node?
61
+ end
62
+
63
+ def import_channels_in_javascript_entrypoint
64
+ append_to_file "app/javascript/application.js",
65
+ using_node? ? %(import "./channels"\n) : %(import "channels"\n)
66
+ end
67
+
68
+ def import_channel_in_javascript_entrypoint
69
+ append_to_file "app/javascript/channels/index.js",
70
+ using_node? ? %(import "./#{file_name}_channel"\n) : %(import "channels/#{file_name}_channel"\n)
71
+ end
72
+
73
+ def install_javascript_dependencies
74
+ say "Installing JavaScript dependencies", :green
75
+ run "yarn add @rails/actioncable"
76
+ end
77
+
78
+ def pin_javascript_dependencies
79
+ append_to_file "config/importmap.rb", <<-RUBY
80
+ pin "@rails/actioncable", to: "actioncable.esm.js"
81
+ pin_all_from "app/javascript/channels", under: "channels"
82
+ RUBY
83
+ end
84
+
85
+
32
86
  def file_name
33
87
  @_file_name ||= super.sub(/_channel\z/i, "")
34
88
  end
35
89
 
36
- # FIXME: Change these files to symlinks once RubyGems 2.5.0 is required.
37
- def generate_application_cable_files
38
- return if behavior != :invoke
90
+ def first_setup_required?
91
+ !root.join("app/javascript/channels/index.js").exist?
92
+ end
39
93
 
40
- files = [
41
- "application_cable/channel.rb",
42
- "application_cable/connection.rb"
43
- ]
94
+ def using_javascript?
95
+ @using_javascript ||= options[:assets] && root.join("app/javascript").exist?
96
+ end
44
97
 
45
- files.each do |name|
46
- path = File.join("app/channels/", name)
47
- template(name, path) if !File.exist?(path)
48
- end
98
+ def using_node?
99
+ @using_node ||= root.join("package.json").exist?
100
+ end
101
+
102
+ def using_importmap?
103
+ @using_importmap ||= root.join("config/importmap.rb").exist?
104
+ end
105
+
106
+ def root
107
+ @root ||= Pathname(destination_root)
49
108
  end
50
109
  end
51
110
  end
@@ -1,5 +1 @@
1
- // Load all the channels within this directory and all subdirectories.
2
- // Channel files must be named *_channel.js.
3
-
4
- const channels = require.context('.', true, /_channel\.js$/)
5
- channels.keys().forEach(channels)
1
+ // Import all the channels to be used by Action Cable
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actioncable
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.5
4
+ version: 7.0.0.alpha1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pratik Naik
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-03-10 00:00:00.000000000 Z
12
+ date: 2021-09-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -17,28 +17,28 @@ dependencies:
17
17
  requirements:
18
18
  - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 6.1.5
20
+ version: 7.0.0.alpha1
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - '='
26
26
  - !ruby/object:Gem::Version
27
- version: 6.1.5
27
+ version: 7.0.0.alpha1
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: actionpack
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - '='
33
33
  - !ruby/object:Gem::Version
34
- version: 6.1.5
34
+ version: 7.0.0.alpha1
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - '='
40
40
  - !ruby/object:Gem::Version
41
- version: 6.1.5
41
+ version: 7.0.0.alpha1
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: nio4r
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -127,8 +127,8 @@ files:
127
127
  - lib/action_cable/version.rb
128
128
  - lib/rails/generators/channel/USAGE
129
129
  - lib/rails/generators/channel/channel_generator.rb
130
- - lib/rails/generators/channel/templates/application_cable/channel.rb.tt
131
- - lib/rails/generators/channel/templates/application_cable/connection.rb.tt
130
+ - lib/rails/generators/channel/templates/application_cable/channel.rb
131
+ - lib/rails/generators/channel/templates/application_cable/connection.rb
132
132
  - lib/rails/generators/channel/templates/channel.rb.tt
133
133
  - lib/rails/generators/channel/templates/javascript/channel.js.tt
134
134
  - lib/rails/generators/channel/templates/javascript/consumer.js.tt
@@ -140,11 +140,10 @@ licenses:
140
140
  - MIT
141
141
  metadata:
142
142
  bug_tracker_uri: https://github.com/rails/rails/issues
143
- changelog_uri: https://github.com/rails/rails/blob/v6.1.5/actioncable/CHANGELOG.md
144
- documentation_uri: https://api.rubyonrails.org/v6.1.5/
143
+ changelog_uri: https://github.com/rails/rails/blob/v7.0.0.alpha1/actioncable/CHANGELOG.md
144
+ documentation_uri: https://api.rubyonrails.org/v7.0.0.alpha1/
145
145
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
146
- source_code_uri: https://github.com/rails/rails/tree/v6.1.5/actioncable
147
- rubygems_mfa_required: 'true'
146
+ source_code_uri: https://github.com/rails/rails/tree/v7.0.0.alpha1/actioncable
148
147
  post_install_message:
149
148
  rdoc_options: []
150
149
  require_paths:
@@ -153,14 +152,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
153
152
  requirements:
154
153
  - - ">="
155
154
  - !ruby/object:Gem::Version
156
- version: 2.5.0
155
+ version: 2.7.0
157
156
  required_rubygems_version: !ruby/object:Gem::Requirement
158
157
  requirements:
159
- - - ">="
158
+ - - ">"
160
159
  - !ruby/object:Gem::Version
161
- version: '0'
160
+ version: 1.3.1
162
161
  requirements: []
163
- rubygems_version: 3.3.7
162
+ rubygems_version: 3.1.6
164
163
  signing_key:
165
164
  specification_version: 4
166
165
  summary: WebSocket framework for Rails.