anycable-rails-core 1.4.0

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 (39) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +203 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +106 -0
  5. data/lib/action_cable/subscription_adapter/any_cable.rb +40 -0
  6. data/lib/action_cable/subscription_adapter/anycable.rb +10 -0
  7. data/lib/anycable/rails/action_cable_ext/channel.rb +51 -0
  8. data/lib/anycable/rails/action_cable_ext/connection.rb +90 -0
  9. data/lib/anycable/rails/action_cable_ext/remote_connections.rb +13 -0
  10. data/lib/anycable/rails/channel_state.rb +108 -0
  11. data/lib/anycable/rails/compatibility/rubocop/config/default.yml +14 -0
  12. data/lib/anycable/rails/compatibility/rubocop/cops/anycable/instance_vars.rb +50 -0
  13. data/lib/anycable/rails/compatibility/rubocop/cops/anycable/periodical_timers.rb +29 -0
  14. data/lib/anycable/rails/compatibility/rubocop/cops/anycable/stream_from.rb +100 -0
  15. data/lib/anycable/rails/compatibility/rubocop.rb +27 -0
  16. data/lib/anycable/rails/compatibility.rb +63 -0
  17. data/lib/anycable/rails/config.rb +19 -0
  18. data/lib/anycable/rails/connection.rb +211 -0
  19. data/lib/anycable/rails/connection_factory.rb +44 -0
  20. data/lib/anycable/rails/connections/persistent_session.rb +40 -0
  21. data/lib/anycable/rails/connections/serializable_identification.rb +46 -0
  22. data/lib/anycable/rails/connections/session_proxy.rb +81 -0
  23. data/lib/anycable/rails/middlewares/executor.rb +31 -0
  24. data/lib/anycable/rails/middlewares/log_tagging.rb +21 -0
  25. data/lib/anycable/rails/rack.rb +56 -0
  26. data/lib/anycable/rails/railtie.rb +92 -0
  27. data/lib/anycable/rails/version.rb +7 -0
  28. data/lib/anycable/rails.rb +76 -0
  29. data/lib/anycable-rails.rb +3 -0
  30. data/lib/generators/anycable/download/USAGE +14 -0
  31. data/lib/generators/anycable/download/download_generator.rb +85 -0
  32. data/lib/generators/anycable/setup/USAGE +2 -0
  33. data/lib/generators/anycable/setup/setup_generator.rb +300 -0
  34. data/lib/generators/anycable/setup/templates/Procfile.dev.tt +6 -0
  35. data/lib/generators/anycable/setup/templates/config/anycable.yml.tt +48 -0
  36. data/lib/generators/anycable/setup/templates/config/cable.yml.tt +11 -0
  37. data/lib/generators/anycable/setup/templates/config/initializers/anycable.rb.tt +9 -0
  38. data/lib/generators/anycable/with_os_helpers.rb +55 -0
  39. metadata +128 -0
@@ -0,0 +1,300 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "generators/anycable/with_os_helpers"
4
+
5
+ module AnyCableRailsGenerators
6
+ # Entry point for interactive installation
7
+ class SetupGenerator < ::Rails::Generators::Base
8
+ namespace "anycable:setup"
9
+ source_root File.expand_path("templates", __dir__)
10
+
11
+ DOCS_ROOT = "https://docs.anycable.io"
12
+ DEVELOPMENT_METHODS = %w[skip local docker].freeze
13
+ SERVER_SOURCES = %w[skip brew binary].freeze
14
+
15
+ class_option :devenv,
16
+ type: :string,
17
+ desc: "Select your development environment (options: #{DEVELOPMENT_METHODS.join(", ")})"
18
+ class_option :source,
19
+ type: :string,
20
+ desc: "Choose a way of installing AnyCable-Go server (options: #{SERVER_SOURCES.join(", ")})"
21
+ class_option :skip_heroku,
22
+ type: :boolean,
23
+ desc: "Do not copy Heroku configs"
24
+ class_option :skip_procfile_dev,
25
+ type: :boolean,
26
+ desc: "Do not create Procfile.dev"
27
+ class_option :skip_jwt,
28
+ type: :boolean,
29
+ desc: "Do not install anycable-rails-jwt"
30
+ class_option :skip_install,
31
+ type: :boolean,
32
+ desc: "Do not run bundle install when adding new gems"
33
+
34
+ include WithOSHelpers
35
+
36
+ class_option :bin_path,
37
+ type: :string,
38
+ desc: "Where to download AnyCable-Go server binary (default: #{DEFAULT_BIN_PATH})"
39
+ class_option :version,
40
+ type: :string,
41
+ desc: "Specify the AnyCable-Go version (defaults to latest release)"
42
+
43
+ def welcome
44
+ say "👋 Welcome to AnyCable interactive installer."
45
+ end
46
+
47
+ def configs
48
+ inside("config") do
49
+ template "cable.yml"
50
+ template "anycable.yml"
51
+ end
52
+ end
53
+
54
+ def cable_url
55
+ environment(nil, env: :development) do
56
+ <<~SNIPPET
57
+ # Specify AnyCable WebSocket server URL to use by JS client
58
+ config.after_initialize do
59
+ config.action_cable.url = ActionCable.server.config.url = ENV.fetch("CABLE_URL", "ws://localhost:8080/cable") if AnyCable::Rails.enabled?
60
+ end
61
+ SNIPPET
62
+ end
63
+
64
+ environment(nil, env: :production) do
65
+ <<~SNIPPET
66
+ # Specify AnyCable WebSocket server URL to use by JS client
67
+ config.after_initialize do
68
+ config.action_cable.url = ActionCable.server.config.url = ENV.fetch("CABLE_URL", "/cable") if AnyCable::Rails.enabled?
69
+ end
70
+ SNIPPET
71
+ end
72
+
73
+ say_status :info, "✅ 'config.action_cable.url' has been configured"
74
+ say_status :help, "⚠️ If you're using JS client make sure you have " \
75
+ "`action_cable_meta_tag` included before any <script> tag in your application.html"
76
+ end
77
+
78
+ def development_method
79
+ answer = DEVELOPMENT_METHODS.index(options[:devenv]) || 99
80
+
81
+ until DEVELOPMENT_METHODS[answer.to_i]
82
+ answer = ask "Which environment do you use for development? (1) Local, (2) Docker, (0) Skip"
83
+ end
84
+
85
+ case env = DEVELOPMENT_METHODS[answer.to_i]
86
+ when "skip"
87
+ say_status :help, "⚠️ Please, read this guide on how to install AnyCable-Go server 👉 #{DOCS_ROOT}/anycable-go/getting_started", :yellow
88
+ else
89
+ send "install_for_#{env}"
90
+ end
91
+ end
92
+
93
+ def heroku
94
+ if options[:skip_heroku].nil?
95
+ return unless yes? "Do you use Heroku for deployment? [Yn]"
96
+ elsif options[:skip_heroku]
97
+ return
98
+ end
99
+
100
+ in_root do
101
+ next unless File.file?("Procfile")
102
+
103
+ contents = File.read("Procfile")
104
+ contents.sub!(/^web: (.*)$/, %q(web: [[ "$ANYCABLE_DEPLOYMENT" == "true" ]] && bundle exec anycable --server-command="anycable-go" || \1))
105
+ File.write("Procfile", contents)
106
+ say_status :info, "✅ Procfile updated"
107
+ end
108
+
109
+ say_status :help, "️️⚠️ Please, read the required steps to configure Heroku applications 👉 #{DOCS_ROOT}/deployment/heroku", :yellow
110
+ end
111
+
112
+ def devise
113
+ in_root do
114
+ return unless File.file?("config/initializers/devise.rb")
115
+ end
116
+
117
+ inside("config/initializers") do
118
+ template "anycable.rb"
119
+ end
120
+
121
+ say_status :info, "✅ config/initializers/anycable.rb with Devise configuration has been added"
122
+ end
123
+
124
+ def stimulus_reflex
125
+ return unless stimulus_reflex?
126
+
127
+ say_status :help, "⚠️ Please, check out the documentation on using AnyCable with Stimulus Reflex: #{DOCS_ROOT}/rails/stimulus_reflex"
128
+ end
129
+
130
+ def rubocop_compatibility
131
+ return unless rubocop?
132
+
133
+ say_status :info, "🤖 Running static compatibility checks with RuboCop"
134
+ res = run "bundle exec rubocop -r 'anycable/rails/compatibility/rubocop' --only AnyCable/InstanceVars,AnyCable/PeriodicalTimers,AnyCable/InstanceVars"
135
+ say_status :help, "⚠️ Please, take a look at the icompatibilities above and fix them. See #{DOCS_ROOT}/rails/compatibility" unless res
136
+ end
137
+
138
+ def jwt
139
+ return if options[:skip_jwt]
140
+
141
+ return unless options[:skip_jwt] == false || yes?("Do you want to use JWT for authentication? [Yn]")
142
+
143
+ opts = " --skip-install" if options[:skip_install]
144
+
145
+ run "bundle add anycable-rails-jwt#{opts}"
146
+ end
147
+
148
+ def finish
149
+ say_status :info, "✅ AnyCable has been configured successfully!"
150
+ end
151
+
152
+ private
153
+
154
+ def stimulus_reflex?
155
+ !!gemfile_lock&.match?(/^\s+stimulus_reflex\b/)
156
+ end
157
+
158
+ def redis?
159
+ !!gemfile_lock&.match?(/^\s+redis\b/)
160
+ end
161
+
162
+ def nats?
163
+ !!gemfile_lock&.match?(/^\s+nats-pure\b/)
164
+ end
165
+
166
+ def webpacker?
167
+ !!gemfile_lock&.match?(/^\s+webpacker\b/)
168
+ end
169
+
170
+ def rubocop?
171
+ !!gemfile_lock&.match?(/^\s+rubocop\b/)
172
+ end
173
+
174
+ def gemfile_lock
175
+ @gemfile_lock ||= begin
176
+ res = nil
177
+ in_root do
178
+ next unless File.file?("Gemfile.lock")
179
+ res = File.read("Gemfile.lock")
180
+ end
181
+ res
182
+ end
183
+ end
184
+
185
+ def install_for_docker
186
+ # Remove localhost from configuraiton
187
+ gsub_file "config/anycable.yml", /^.*redis_url:.*localhost[^\n]+\n/, ""
188
+
189
+ say_status :help, "️️⚠️ Docker development configuration could vary", :yellow
190
+
191
+ say "Here is an example snippet for docker-compose.yml:"
192
+ say <<~YML
193
+ ─────────────────────────────────────────
194
+ ws:
195
+ image: anycable/anycable-go:1.2
196
+ ports:
197
+ - '8080:8080'
198
+ environment:
199
+ ANYCABLE_HOST: "0.0.0.0"
200
+ ANYCABLE_REDIS_URL: redis://redis:6379/0
201
+ ANYCABLE_RPC_HOST: anycable:50051
202
+ ANYCABLE_DEBUG: 1
203
+ depends_on:
204
+ redis:
205
+ condition: service_healthy
206
+
207
+ anycable:
208
+ <<: *backend
209
+ command: bundle exec anycable
210
+ environment:
211
+ <<: *backend_environment
212
+ ANYCABLE_REDIS_URL: redis://redis:6379/0
213
+ ANYCABLE_RPC_HOST: 0.0.0.0:50051
214
+ ANYCABLE_DEBUG: 1
215
+ ports:
216
+ - '50051'
217
+ depends_on:
218
+ <<: *backend_depends_on
219
+ ws:
220
+ condition: service_started
221
+ ─────────────────────────────────────────
222
+ YML
223
+ end
224
+
225
+ def install_for_local
226
+ install_server
227
+ template_proc_files
228
+ end
229
+
230
+ def install_server
231
+ answer = SERVER_SOURCES.index(options[:source]) || 99
232
+
233
+ until SERVER_SOURCES[answer.to_i]
234
+ answer = ask "How do you want to install AnyCable-Go WebSocket server? (1) Homebrew, (2) Download binary, (0) Skip"
235
+ end
236
+
237
+ case answer.to_i
238
+ when 0
239
+ say_status :help, "⚠️ Please, read this guide on how to install AnyCable-Go server 👉 #{DOCS_ROOT}/anycable-go/getting_started", :yellow
240
+ return
241
+ else
242
+ return unless send("install_from_#{SERVER_SOURCES[answer.to_i]}")
243
+ end
244
+
245
+ say_status :info, "✅ AnyCable-Go WebSocket server has been successfully installed"
246
+ end
247
+
248
+ def template_proc_files
249
+ file_name = "Procfile.dev"
250
+
251
+ if file_exists?(file_name)
252
+ append_file file_name, "anycable: bundle exec anycable\nws: anycable-go#{anycable_go_options}", force: true
253
+ else
254
+ say_status :help, "💡 We recommend using Hivemind to manage multiple processes in development 👉 https://github.com/DarthSim/hivemind", :yellow
255
+
256
+ if options[:skip_procfile_dev].nil?
257
+ return unless yes? "Do you want to create a '#{file_name}' file?"
258
+ elsif options[:skip_procfile_dev]
259
+ return
260
+ end
261
+
262
+ template file_name
263
+ end
264
+ end
265
+
266
+ def install_from_brew
267
+ run "brew install anycable-go", abort_on_failure: true
268
+ run "anycable-go -v", abort_on_failure: true
269
+ end
270
+
271
+ def install_from_binary
272
+ bin_path ||= DEFAULT_BIN_PATH if options[:devenv] # User don't want interactive mode
273
+ bin_path ||= ask "Please, enter the path to download the AnyCable-Go binary to", default: DEFAULT_BIN_PATH, path: true
274
+
275
+ generate "anycable:download", download_options(bin_path: bin_path)
276
+
277
+ true
278
+ end
279
+
280
+ def download_options(**params)
281
+ opts = options.merge(params)
282
+ [].tap do |args|
283
+ args << "--os #{opts[:os]}" if opts[:os]
284
+ args << "--cpu #{opts[:cpu]}" if opts[:cpu]
285
+ args << "--bin-path=#{opts[:bin_path]}" if opts[:bin_path]
286
+ args << "--version #{opts[:version]}" if opts[:version]
287
+ end.join(" ")
288
+ end
289
+
290
+ def anycable_go_options
291
+ redis? ? " --port=8080" : " --port=8080 --broadcast_adapter=http"
292
+ end
293
+
294
+ def file_exists?(name)
295
+ in_root do
296
+ return File.file?(name)
297
+ end
298
+ end
299
+ end
300
+ end
@@ -0,0 +1,6 @@
1
+ server: bundle exec rails s
2
+ <%- if webpacker? -%>
3
+ assets: bundle exec bin/webpack-dev-server
4
+ <%- end -%>
5
+ anycable: bundle exec anycable
6
+ ws: anycable-go<%= anycable_go_options %>
@@ -0,0 +1,48 @@
1
+ # This file contains per-environment settings for AnyCable.
2
+ #
3
+ # Since AnyCable config is based on anyway_config (https://github.com/palkan/anyway_config), all AnyCable settings
4
+ # can be set or overridden through the corresponding environment variables.
5
+ # E.g., `rpc_host` is overridden by ANYCABLE_RPC_HOST, `debug` by ANYCABLE_DEBUG etc.
6
+ #
7
+ # Note that AnyCable recognizes REDIS_URL env variable for Redis pub/sub adapter. If you want to
8
+ # use another Redis instance for AnyCable, provide ANYCABLE_REDIS_URL variable.
9
+ #
10
+ # Read more about AnyCable configuration here: <%= DOCS_ROOT %>/ruby/configuration
11
+ #
12
+ default: &default
13
+ # Turn on/off access logs ("Started..." and "Finished...")
14
+ access_logs_disabled: false
15
+ # Whether to enable gRPC level logging or not
16
+ log_grpc: false
17
+ <%- if redis? -%>
18
+ # Use Redis to broadcast messages to AnyCable server
19
+ broadcast_adapter: redis
20
+ <%- elsif nats? -%>
21
+ # Use NATS to broadcast messages to AnyCable server
22
+ broadcast_adapter: nats
23
+ <%- else -%>
24
+ # Use HTTP adapter for a quick start (since redis gem is not present in the project)
25
+ broadcast_adapter: http
26
+ <%- end -%>
27
+ # Use the same channel name for WebSocket server, e.g.:
28
+ # $ anycable-go --redis_channel="__anycable__"
29
+ redis_channel: "__anycable__"
30
+ <%- if redis? -%>
31
+ # You can use REDIS_URL env var to configure Redis URL.
32
+ # Localhost is used by default.
33
+ # redis_url: "redis://localhost:6379/1"
34
+ <%- end -%>
35
+
36
+ development:
37
+ <<: *default
38
+
39
+ test:
40
+ <<: *default
41
+
42
+ production:
43
+ <<: *default
44
+ <%- if !redis? && !nats? -%>
45
+ # Use Redis or NATS in production
46
+ broadcast_adapter: redis
47
+ # broadcast_adapter: nats
48
+ <%- end -%>
@@ -0,0 +1,11 @@
1
+ # Make it possible to switch adapters by passing the ACTION_CABLE_ADAPTER env variable.
2
+ # For example, you can use it fallback to the standard Action Cable in staging/review
3
+ # environments (by setting `ACTION_CABLE_ADAPTER=redis`).
4
+ development:
5
+ adapter: <%%= ENV.fetch("ACTION_CABLE_ADAPTER", "any_cable") %>
6
+
7
+ test:
8
+ adapter: test
9
+
10
+ production:
11
+ adapter: <%%= ENV.fetch("ACTION_CABLE_ADAPTER", "any_cable") %>
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Add Warden middleware to AnyCable stack to allow accessing
4
+ # Devise current user via `env["warden"].user`.
5
+ #
6
+ # See <%= DOCS_ROOT %>/ruby/authentication
7
+ AnyCable::Rails::Rack.middleware.use Warden::Manager do |config|
8
+ Devise.warden_config = config
9
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnyCableRailsGenerators
4
+ module WithOSHelpers
5
+ OS_NAMES = %w[linux darwin freebsd win].freeze
6
+ CPU_NAMES = %w[amd64 arm64 386 arm].freeze
7
+ DEFAULT_BIN_PATH = "/usr/local/bin"
8
+
9
+ def self.included(base)
10
+ base.class_option :os,
11
+ type: :string,
12
+ desc: "Specify the OS for AnyCable-Go server binary (options: #{OS_NAMES.join(", ")})"
13
+ base.class_option :cpu,
14
+ type: :string,
15
+ desc: "Specify the CPU architecturefor AnyCable-Go server binary (options: #{CPU_NAMES.join(", ")})"
16
+
17
+ private :current_cpu, :supported_current_cpu, :supported_current_os
18
+ end
19
+
20
+ def current_cpu
21
+ case Gem::Platform.local.cpu
22
+ when "x86_64", "x64"
23
+ "amd64"
24
+ when "x86_32", "x86", "i386", "i486", "i686"
25
+ "i386"
26
+ when "aarch64", "aarch64_be", "arm64", /armv8/
27
+ "arm64"
28
+ when "arm", /armv7/, /armv6/
29
+ "arm"
30
+ else
31
+ "unknown"
32
+ end
33
+ end
34
+
35
+ def os_name
36
+ options[:os] ||
37
+ supported_current_os ||
38
+ ask("What is your OS name?", limited_to: OS_NAMES)
39
+ end
40
+
41
+ def cpu_name
42
+ options[:cpu] ||
43
+ supported_current_cpu ||
44
+ ask("What is your CPU architecture?", limited_to: CPU_NAMES)
45
+ end
46
+
47
+ def supported_current_cpu
48
+ CPU_NAMES.find(&current_cpu.method(:==))
49
+ end
50
+
51
+ def supported_current_os
52
+ OS_NAMES.find(&Gem::Platform.local.os.method(:==))
53
+ end
54
+ end
55
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: anycable-rails-core
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.0
5
+ platform: ruby
6
+ authors:
7
+ - palkan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-07-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: anycable-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: actioncable
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '6.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '6.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: globalid
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: AnyCable integration for Rails (w/o RPC dependencies)
56
+ email:
57
+ - dementiev.vm@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - CHANGELOG.md
63
+ - MIT-LICENSE
64
+ - README.md
65
+ - lib/action_cable/subscription_adapter/any_cable.rb
66
+ - lib/action_cable/subscription_adapter/anycable.rb
67
+ - lib/anycable-rails.rb
68
+ - lib/anycable/rails.rb
69
+ - lib/anycable/rails/action_cable_ext/channel.rb
70
+ - lib/anycable/rails/action_cable_ext/connection.rb
71
+ - lib/anycable/rails/action_cable_ext/remote_connections.rb
72
+ - lib/anycable/rails/channel_state.rb
73
+ - lib/anycable/rails/compatibility.rb
74
+ - lib/anycable/rails/compatibility/rubocop.rb
75
+ - lib/anycable/rails/compatibility/rubocop/config/default.yml
76
+ - lib/anycable/rails/compatibility/rubocop/cops/anycable/instance_vars.rb
77
+ - lib/anycable/rails/compatibility/rubocop/cops/anycable/periodical_timers.rb
78
+ - lib/anycable/rails/compatibility/rubocop/cops/anycable/stream_from.rb
79
+ - lib/anycable/rails/config.rb
80
+ - lib/anycable/rails/connection.rb
81
+ - lib/anycable/rails/connection_factory.rb
82
+ - lib/anycable/rails/connections/persistent_session.rb
83
+ - lib/anycable/rails/connections/serializable_identification.rb
84
+ - lib/anycable/rails/connections/session_proxy.rb
85
+ - lib/anycable/rails/middlewares/executor.rb
86
+ - lib/anycable/rails/middlewares/log_tagging.rb
87
+ - lib/anycable/rails/rack.rb
88
+ - lib/anycable/rails/railtie.rb
89
+ - lib/anycable/rails/version.rb
90
+ - lib/generators/anycable/download/USAGE
91
+ - lib/generators/anycable/download/download_generator.rb
92
+ - lib/generators/anycable/setup/USAGE
93
+ - lib/generators/anycable/setup/setup_generator.rb
94
+ - lib/generators/anycable/setup/templates/Procfile.dev.tt
95
+ - lib/generators/anycable/setup/templates/config/anycable.yml.tt
96
+ - lib/generators/anycable/setup/templates/config/cable.yml.tt
97
+ - lib/generators/anycable/setup/templates/config/initializers/anycable.rb.tt
98
+ - lib/generators/anycable/with_os_helpers.rb
99
+ homepage: http://github.com/anycable/anycable-rails
100
+ licenses:
101
+ - MIT
102
+ metadata:
103
+ bug_tracker_uri: http://github.com/anycable/anycable-rails/issues
104
+ changelog_uri: https://github.com/anycable/anycable-rails/blob/master/CHANGELOG.md
105
+ documentation_uri: https://docs.anycable.io/#/using_with_rails
106
+ homepage_uri: https://anycable.io/
107
+ source_code_uri: http://github.com/anycable/anycable-rails
108
+ funding_uri: https://github.com/sponsors/anycable
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '2.7'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubygems_version: 3.4.8
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: AnyCable integration for Rails (w/o RPC dependencies)
128
+ test_files: []