actioncable 7.0.8.7 → 7.1.5.1

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +80 -118
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +4 -4
  5. data/app/assets/javascripts/action_cable.js +27 -6
  6. data/app/assets/javascripts/actioncable.esm.js +27 -6
  7. data/app/assets/javascripts/actioncable.js +27 -6
  8. data/lib/action_cable/channel/base.rb +17 -5
  9. data/lib/action_cable/channel/broadcasting.rb +3 -1
  10. data/lib/action_cable/channel/callbacks.rb +37 -0
  11. data/lib/action_cable/channel/naming.rb +4 -2
  12. data/lib/action_cable/channel/streams.rb +2 -0
  13. data/lib/action_cable/channel/test_case.rb +9 -4
  14. data/lib/action_cable/connection/authorization.rb +1 -1
  15. data/lib/action_cable/connection/base.rb +18 -5
  16. data/lib/action_cable/connection/callbacks.rb +55 -0
  17. data/lib/action_cable/connection/internal_channel.rb +3 -1
  18. data/lib/action_cable/connection/stream.rb +1 -3
  19. data/lib/action_cable/connection/stream_event_loop.rb +0 -1
  20. data/lib/action_cable/connection/subscriptions.rb +2 -0
  21. data/lib/action_cable/connection/tagged_logger_proxy.rb +6 -4
  22. data/lib/action_cable/connection/test_case.rb +3 -1
  23. data/lib/action_cable/connection/web_socket.rb +2 -0
  24. data/lib/action_cable/deprecator.rb +7 -0
  25. data/lib/action_cable/engine.rb +13 -5
  26. data/lib/action_cable/gem_version.rb +4 -4
  27. data/lib/action_cable/remote_connections.rb +11 -2
  28. data/lib/action_cable/server/base.rb +3 -0
  29. data/lib/action_cable/server/broadcasting.rb +2 -0
  30. data/lib/action_cable/server/configuration.rb +12 -2
  31. data/lib/action_cable/server/connections.rb +3 -1
  32. data/lib/action_cable/server/worker.rb +0 -1
  33. data/lib/action_cable/subscription_adapter/async.rb +0 -2
  34. data/lib/action_cable/subscription_adapter/postgresql.rb +0 -1
  35. data/lib/action_cable/subscription_adapter/redis.rb +3 -6
  36. data/lib/action_cable/subscription_adapter/test.rb +3 -5
  37. data/lib/action_cable/test_helper.rb +46 -19
  38. data/lib/action_cable/version.rb +1 -1
  39. data/lib/action_cable.rb +24 -12
  40. data/lib/rails/generators/channel/USAGE +14 -8
  41. data/lib/rails/generators/channel/channel_generator.rb +21 -7
  42. metadata +24 -12
  43. data/lib/action_cable/channel.rb +0 -17
  44. data/lib/action_cable/connection.rb +0 -22
  45. data/lib/action_cable/server.rb +0 -16
  46. data/lib/action_cable/subscription_adapter.rb +0 -12
@@ -44,15 +44,14 @@ module ActionCable
44
44
  #
45
45
  def assert_broadcasts(stream, number, &block)
46
46
  if block_given?
47
- original_count = broadcasts_size(stream)
48
- _assert_nothing_raised_or_warn("assert_broadcasts", &block)
49
- new_count = broadcasts_size(stream)
50
- actual_count = new_count - original_count
47
+ new_messages = new_broadcasts_from(broadcasts(stream), stream, "assert_broadcasts", &block)
48
+
49
+ actual_count = new_messages.size
50
+ assert_equal number, actual_count, "#{number} broadcasts to #{stream} expected, but #{actual_count} were sent"
51
51
  else
52
- actual_count = broadcasts_size(stream)
52
+ actual_count = broadcasts(stream).size
53
+ assert_equal number, actual_count, "#{number} broadcasts to #{stream} expected, but #{actual_count} were sent"
53
54
  end
54
-
55
- assert_equal number, actual_count, "#{number} broadcasts to #{stream} expected, but #{actual_count} were sent"
56
55
  end
57
56
 
58
57
  # Asserts that no messages have been sent to the stream.
@@ -79,6 +78,22 @@ module ActionCable
79
78
  assert_broadcasts stream, 0, &block
80
79
  end
81
80
 
81
+ # Returns the messages that are broadcasted in the block.
82
+ #
83
+ # def test_broadcasts
84
+ # messages = capture_broadcasts('messages') do
85
+ # ActionCable.server.broadcast 'messages', { text: 'hi' }
86
+ # ActionCable.server.broadcast 'messages', { text: 'how are you?' }
87
+ # end
88
+ # assert_equal 2, messages.length
89
+ # assert_equal({ text: 'hi' }, messages.first)
90
+ # assert_equal({ text: 'how are you?' }, messages.last)
91
+ # end
92
+ #
93
+ def capture_broadcasts(stream, &block)
94
+ new_broadcasts_from(broadcasts(stream), stream, "capture_broadcasts", &block).map { |m| ActiveSupport::JSON.decode(m) }
95
+ end
96
+
82
97
  # Asserts that the specified message has been sent to the stream.
83
98
  #
84
99
  # def test_assert_transmitted_message
@@ -103,20 +118,22 @@ module ActionCable
103
118
 
104
119
  new_messages = broadcasts(stream)
105
120
  if block_given?
106
- old_messages = new_messages
107
- clear_messages(stream)
108
-
109
- _assert_nothing_raised_or_warn("assert_broadcast_on", &block)
110
- new_messages = broadcasts(stream)
111
- clear_messages(stream)
112
-
113
- # Restore all sent messages
114
- (old_messages + new_messages).each { |m| pubsub_adapter.broadcast(stream, m) }
121
+ new_messages = new_broadcasts_from(new_messages, stream, "assert_broadcast_on", &block)
115
122
  end
116
123
 
117
124
  message = new_messages.find { |msg| ActiveSupport::JSON.decode(msg) == serialized_msg }
118
125
 
119
- assert message, "No messages sent with #{data} to #{stream}"
126
+ error_message = "No messages sent with #{data} to #{stream}"
127
+
128
+ if new_messages.any?
129
+ error_message = new_messages.inject("#{error_message}\nMessage(s) found:\n") do |error_message, new_message|
130
+ error_message + "#{ActiveSupport::JSON.decode(new_message)}\n"
131
+ end
132
+ else
133
+ error_message = "#{error_message}\nNo message found for #{stream}"
134
+ end
135
+
136
+ assert message, error_message
120
137
  end
121
138
 
122
139
  def pubsub_adapter # :nodoc:
@@ -126,8 +143,18 @@ module ActionCable
126
143
  delegate :broadcasts, :clear_messages, to: :pubsub_adapter
127
144
 
128
145
  private
129
- def broadcasts_size(channel)
130
- broadcasts(channel).size
146
+ def new_broadcasts_from(current_messages, stream, assertion, &block)
147
+ old_messages = current_messages
148
+ clear_messages(stream)
149
+
150
+ _assert_nothing_raised_or_warn(assertion, &block)
151
+ new_messages = broadcasts(stream)
152
+ clear_messages(stream)
153
+
154
+ # Restore all sent messages
155
+ (old_messages + new_messages).each { |m| pubsub_adapter.broadcast(stream, m) }
156
+
157
+ new_messages
131
158
  end
132
159
  end
133
160
  end
@@ -3,7 +3,7 @@
3
3
  require_relative "gem_version"
4
4
 
5
5
  module ActionCable
6
- # Returns the currently loaded version of Action Cable as a <tt>Gem::Version</tt>.
6
+ # Returns the currently loaded version of Action Cable as a +Gem::Version+.
7
7
  def self.version
8
8
  gem_version
9
9
  end
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) 37signals 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
@@ -25,10 +25,29 @@
25
25
 
26
26
  require "active_support"
27
27
  require "active_support/rails"
28
- require "action_cable/version"
28
+ require "zeitwerk"
29
29
 
30
+ Zeitwerk::Loader.for_gem.tap do |loader|
31
+ loader.ignore(
32
+ "#{__dir__}/rails", # Contains generators, templates, docs, etc.
33
+ "#{__dir__}/action_cable/gem_version.rb",
34
+ "#{__dir__}/action_cable/deprecator.rb",
35
+ )
36
+
37
+ loader.do_not_eager_load(
38
+ "#{__dir__}/action_cable/subscription_adapter", # Adapters are required and loaded on demand.
39
+ "#{__dir__}/action_cable/test_helper.rb",
40
+ Dir["#{__dir__}/action_cable/**/test_case.rb"]
41
+ )
42
+
43
+ loader.inflector.inflect("postgresql" => "PostgreSQL")
44
+ end.setup
45
+
46
+ # :markup: markdown
47
+ # :include: ../README.md
30
48
  module ActionCable
31
- extend ActiveSupport::Autoload
49
+ require_relative "action_cable/version"
50
+ require_relative "action_cable/deprecator"
32
51
 
33
52
  INTERNAL = {
34
53
  message_types: {
@@ -41,7 +60,8 @@ module ActionCable
41
60
  disconnect_reasons: {
42
61
  unauthorized: "unauthorized",
43
62
  invalid_request: "invalid_request",
44
- server_restart: "server_restart"
63
+ server_restart: "server_restart",
64
+ remote: "remote"
45
65
  },
46
66
  default_mount_path: "/cable",
47
67
  protocols: ["actioncable-v1-json", "actioncable-unsupported"].freeze
@@ -51,12 +71,4 @@ module ActionCable
51
71
  module_function def server
52
72
  @server ||= ActionCable::Server::Base.new
53
73
  end
54
-
55
- autoload :Server
56
- autoload :Connection
57
- autoload :Channel
58
- autoload :RemoteConnections
59
- autoload :SubscriptionAdapter
60
- autoload :TestHelper
61
- autoload :TestCase
62
74
  end
@@ -1,13 +1,19 @@
1
1
  Description:
2
- ============
3
2
  Generates a new cable channel for the server (in Ruby) and client (in JavaScript).
4
3
  Pass the channel name, either CamelCased or under_scored, and an optional list of channel actions as arguments.
5
4
 
6
- Example:
7
- ========
8
- bin/rails generate channel Chat speak
5
+ Examples:
6
+ `bin/rails generate channel notification`
9
7
 
10
- creates a Chat channel class, test and JavaScript asset:
11
- Channel: app/channels/chat_channel.rb
12
- Test: test/channels/chat_channel_test.rb
13
- Assets: $JAVASCRIPT_PATH/channels/chat_channel.js
8
+ creates a notification channel class, test and JavaScript asset:
9
+ Channel: app/channels/notification_channel.rb
10
+ Test: test/channels/notification_channel_test.rb
11
+ Assets: $JAVASCRIPT_PATH/channels/notification_channel.js
12
+
13
+ `bin/rails generate channel chat speak`
14
+
15
+ creates a chat channel with a speak action.
16
+
17
+ `bin/rails generate channel comments --no-assets`
18
+
19
+ creates a comments channel without JavaScript assets.
@@ -24,7 +24,7 @@ module Rails
24
24
 
25
25
  if using_importmap?
26
26
  pin_javascript_dependencies
27
- elsif using_node?
27
+ elsif using_js_runtime?
28
28
  install_javascript_dependencies
29
29
  end
30
30
  end
@@ -57,22 +57,26 @@ module Rails
57
57
  def create_channel_javascript_file
58
58
  channel_js_path = File.join("app/javascript/channels", class_path, "#{file_name}_channel")
59
59
  js_template "javascript/channel", channel_js_path
60
- gsub_file "#{channel_js_path}.js", /\.\/consumer/, "channels/consumer" unless using_node?
60
+ gsub_file "#{channel_js_path}.js", /\.\/consumer/, "channels/consumer" unless using_js_runtime?
61
61
  end
62
62
 
63
63
  def import_channels_in_javascript_entrypoint
64
64
  append_to_file "app/javascript/application.js",
65
- using_node? ? %(import "./channels"\n) : %(import "channels"\n)
65
+ using_js_runtime? ? %(import "./channels"\n) : %(import "channels"\n)
66
66
  end
67
67
 
68
68
  def import_channel_in_javascript_entrypoint
69
69
  append_to_file "app/javascript/channels/index.js",
70
- using_node? ? %(import "./#{file_name}_channel"\n) : %(import "channels/#{file_name}_channel"\n)
70
+ using_js_runtime? ? %(import "./#{file_name}_channel"\n) : %(import "channels/#{file_name}_channel"\n)
71
71
  end
72
72
 
73
73
  def install_javascript_dependencies
74
74
  say "Installing JavaScript dependencies", :green
75
- run "yarn add @rails/actioncable"
75
+ if using_bun?
76
+ run "bun add @rails/actioncable"
77
+ elsif using_node?
78
+ run "yarn add @rails/actioncable"
79
+ end
76
80
  end
77
81
 
78
82
  def pin_javascript_dependencies
@@ -82,7 +86,6 @@ pin_all_from "app/javascript/channels", under: "channels"
82
86
  RUBY
83
87
  end
84
88
 
85
-
86
89
  def file_name
87
90
  @_file_name ||= super.sub(/_channel\z/i, "")
88
91
  end
@@ -95,8 +98,19 @@ pin_all_from "app/javascript/channels", under: "channels"
95
98
  @using_javascript ||= options[:assets] && root.join("app/javascript").exist?
96
99
  end
97
100
 
101
+ def using_js_runtime?
102
+ @using_js_runtime ||= root.join("package.json").exist?
103
+ end
104
+
105
+ def using_bun?
106
+ # Cannot assume bun.lockb has been generated yet so we look for
107
+ # a file known to be generated by the jsbundling-rails gem
108
+ @using_bun ||= using_js_runtime? && root.join("bun.config.js").exist?
109
+ end
110
+
98
111
  def using_node?
99
- @using_node ||= root.join("package.json").exist?
112
+ # Bun is the only runtime that _isn't_ node.
113
+ @using_node ||= using_js_runtime? && !root.join("bun.config.js").exist?
100
114
  end
101
115
 
102
116
  def using_importmap?
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: 7.0.8.7
4
+ version: 7.1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pratik Naik
@@ -17,28 +17,28 @@ dependencies:
17
17
  requirements:
18
18
  - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 7.0.8.7
20
+ version: 7.1.5.1
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: 7.0.8.7
27
+ version: 7.1.5.1
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: 7.0.8.7
34
+ version: 7.1.5.1
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: 7.0.8.7
41
+ version: 7.1.5.1
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: nio4r
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -67,6 +67,20 @@ dependencies:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: 0.6.1
70
+ - !ruby/object:Gem::Dependency
71
+ name: zeitwerk
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '2.6'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '2.6'
70
84
  description: Structure many real-time application concerns into channels over a single
71
85
  WebSocket connection.
72
86
  email:
@@ -83,7 +97,6 @@ files:
83
97
  - app/assets/javascripts/actioncable.esm.js
84
98
  - app/assets/javascripts/actioncable.js
85
99
  - lib/action_cable.rb
86
- - lib/action_cable/channel.rb
87
100
  - lib/action_cable/channel/base.rb
88
101
  - lib/action_cable/channel/broadcasting.rb
89
102
  - lib/action_cable/channel/callbacks.rb
@@ -91,9 +104,9 @@ files:
91
104
  - lib/action_cable/channel/periodic_timers.rb
92
105
  - lib/action_cable/channel/streams.rb
93
106
  - lib/action_cable/channel/test_case.rb
94
- - lib/action_cable/connection.rb
95
107
  - lib/action_cable/connection/authorization.rb
96
108
  - lib/action_cable/connection/base.rb
109
+ - lib/action_cable/connection/callbacks.rb
97
110
  - lib/action_cable/connection/client_socket.rb
98
111
  - lib/action_cable/connection/identification.rb
99
112
  - lib/action_cable/connection/internal_channel.rb
@@ -104,18 +117,17 @@ files:
104
117
  - lib/action_cable/connection/tagged_logger_proxy.rb
105
118
  - lib/action_cable/connection/test_case.rb
106
119
  - lib/action_cable/connection/web_socket.rb
120
+ - lib/action_cable/deprecator.rb
107
121
  - lib/action_cable/engine.rb
108
122
  - lib/action_cable/gem_version.rb
109
123
  - lib/action_cable/helpers/action_cable_helper.rb
110
124
  - lib/action_cable/remote_connections.rb
111
- - lib/action_cable/server.rb
112
125
  - lib/action_cable/server/base.rb
113
126
  - lib/action_cable/server/broadcasting.rb
114
127
  - lib/action_cable/server/configuration.rb
115
128
  - lib/action_cable/server/connections.rb
116
129
  - lib/action_cable/server/worker.rb
117
130
  - lib/action_cable/server/worker/active_record_connection_management.rb
118
- - lib/action_cable/subscription_adapter.rb
119
131
  - lib/action_cable/subscription_adapter/async.rb
120
132
  - lib/action_cable/subscription_adapter/base.rb
121
133
  - lib/action_cable/subscription_adapter/channel_prefix.rb
@@ -142,10 +154,10 @@ licenses:
142
154
  - MIT
143
155
  metadata:
144
156
  bug_tracker_uri: https://github.com/rails/rails/issues
145
- changelog_uri: https://github.com/rails/rails/blob/v7.0.8.7/actioncable/CHANGELOG.md
146
- documentation_uri: https://api.rubyonrails.org/v7.0.8.7/
157
+ changelog_uri: https://github.com/rails/rails/blob/v7.1.5.1/actioncable/CHANGELOG.md
158
+ documentation_uri: https://api.rubyonrails.org/v7.1.5.1/
147
159
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
148
- source_code_uri: https://github.com/rails/rails/tree/v7.0.8.7/actioncable
160
+ source_code_uri: https://github.com/rails/rails/tree/v7.1.5.1/actioncable
149
161
  rubygems_mfa_required: 'true'
150
162
  post_install_message:
151
163
  rdoc_options: []
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActionCable
4
- module Channel
5
- extend ActiveSupport::Autoload
6
-
7
- eager_autoload do
8
- autoload :Base
9
- autoload :Broadcasting
10
- autoload :Callbacks
11
- autoload :Naming
12
- autoload :PeriodicTimers
13
- autoload :Streams
14
- autoload :TestCase
15
- end
16
- end
17
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActionCable
4
- module Connection
5
- extend ActiveSupport::Autoload
6
-
7
- eager_autoload do
8
- autoload :Authorization
9
- autoload :Base
10
- autoload :ClientSocket
11
- autoload :Identification
12
- autoload :InternalChannel
13
- autoload :MessageBuffer
14
- autoload :Stream
15
- autoload :StreamEventLoop
16
- autoload :Subscriptions
17
- autoload :TaggedLoggerProxy
18
- autoload :TestCase
19
- autoload :WebSocket
20
- end
21
- end
22
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActionCable
4
- module Server
5
- extend ActiveSupport::Autoload
6
-
7
- eager_autoload do
8
- autoload :Base
9
- autoload :Broadcasting
10
- autoload :Connections
11
- autoload :Configuration
12
-
13
- autoload :Worker
14
- end
15
- end
16
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActionCable
4
- module SubscriptionAdapter
5
- extend ActiveSupport::Autoload
6
-
7
- autoload :Base
8
- autoload :Test
9
- autoload :SubscriberMap
10
- autoload :ChannelPrefix
11
- end
12
- end