anycable-rails 1.0.1 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2c1f822cbb79135290b3c404544d937f0f083751657057b7bdd4445a33a95f1
4
- data.tar.gz: ae4f5e42da49c8f668ee2cf56a434e30872d04cee9bc3596f914fb2e48404ac1
3
+ metadata.gz: 474cfd55dac8443341c7717845af042cd80889e3d865cdef3a6e41d089f02348
4
+ data.tar.gz: e744ee509ebc1ee82cb112150f346970fe52b55dfb134745b927f94c5670198e
5
5
  SHA512:
6
- metadata.gz: 55bb99bacfdbd2b29120e29598aedc467f56325096602c7713bc2bfee9c4c40f826089ee4dd4d76e80d7171bdd1989db0d21c002edae0e429174509d24f8d836
7
- data.tar.gz: 2ee8318ebd5c27dd95b21bd784c75d0d78da08538f1dd466235b889485d2229a4f35202b036a422466f38422905fbda16f84a028ecb3772e0669ce2bfc203dda
6
+ metadata.gz: 4092bd45059bbb6062df44dc78b4ba2ff1bf8a2f3ef65448f7baf3886c35b91b4e0feb315e86e92cf746735f945b007d7550bd01c5bdd1a0dc6b32178d1a1c68
7
+ data.tar.gz: e63aa37233adf6f31eff249c2b9f1beeb1ea41d7f50152061cb8b3769cefc9be863c380df710dcf6715c4b2070fda26a569f3a2b7d8bca63cecc5fc8c3b0c97f
data/CHANGELOG.md CHANGED
@@ -2,6 +2,36 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.0.7 (2021-03-05)
6
+
7
+ - Ruby 3 compatibility. ([@palkan][])
8
+
9
+ ## 1.0.6 (2021-02-25)
10
+
11
+ - Keep an explicit list of instance vars to ignore in compatibility checks. ([@palkan][])
12
+
13
+ You can ignore custom vars by adding them to the list: `AnyCable::Compatibility::IGNORE_INSTANCE_VARS << :@my_var`.
14
+
15
+ ## 1.0.5 (2021-02-24)
16
+
17
+ - Fixed bug with compatibility false negatives in development. ([@palkan][])
18
+
19
+ See [#151](https://github.com/anycable/anycable-rails/issues/151).
20
+
21
+ ## 1.0.4 (2020-10-02)
22
+
23
+ - Relax Rails dependencies. ([@palkan][])
24
+
25
+ Only add `actioncable` and `globalid` as runtime dependencies, not the whole `rails`.
26
+
27
+ ## 1.0.3 (2020-09-16)
28
+
29
+ - Fixed bug with building a request object when session store is absent. ([@palkan][])
30
+
31
+ ## 1.0.2 (2020-09-08)
32
+
33
+ - Added missing channel state support to `#unsubscribed` callbacks. ([@palkan][])
34
+
5
35
  ## 1.0.1 (2020-07-07)
6
36
 
7
37
  - Fixed patching Action Cable testing classes. ([@palkan][])
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2017-2020 palkan
1
+ Copyright 2017-2021 palkan
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
- [![GitPitch](https://gitpitch.com/assets/badge.svg)](https://gitpitch.com/anycable/anycable/master?grs=github)
2
1
  [![Gem Version](https://badge.fury.io/rb/anycable-rails.svg)](https://rubygems.org/gems/anycable-rails)
3
2
  [![Build](https://github.com/anycable/anycable-rails/workflows/Build/badge.svg)](https://github.com/anycable/anycable-rails/actions)
4
3
  [![Gitter](https://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg)](https://gitter.im/anycable/Lobby)
5
- [![Documentation](https://img.shields.io/badge/docs-link-brightgreen.svg)](https://docs.anycable.io/v1/#/ruby/rails)
4
+ [![Documentation](https://img.shields.io/badge/docs-link-brightgreen.svg)](https://docs.anycable.io/#/rails/getting_started)
6
5
 
7
6
  # AnyCable Rails
8
7
 
@@ -14,9 +13,9 @@ You can even use Action Cable in development and not be afraid of [compatibility
14
13
 
15
14
  **Important** This is a readme for the upcoming v1.0 release. For v0.6.x see the readme from the [0-6-stable](https://github.com/anycable/anycable-rails/tree/0-6-stable) branch.
16
15
 
17
- <!-- 💾 [Example Application](https://github.com/anycable/anycable_demo) -->
16
+ 💾 [Example Application](https://github.com/anycable/anycable_rails_demo)
18
17
 
19
- 📑 [Documentation](https://docs.anycable.io/v1/#/ruby/rails).
18
+ 📑 [Documentation](https://docs.anycable.io/#/rails/getting_started).
20
19
 
21
20
  <a href="https://evilmartians.com/">
22
21
  <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
@@ -83,26 +82,22 @@ $ bundle exec anycable
83
82
  $ RAILS_ENV=production bundle exec anycable
84
83
  ```
85
84
 
86
- And, finally, run AnyCable WebSocket server, e.g. [anycable-go](https://docs.anycable.io/v1/#/anycable-go/getting_started):
85
+ And, finally, run AnyCable WebSocket server, e.g. [anycable-go](https://docs.anycable.io/#/v1/anycable-go/getting_started):
87
86
 
88
87
  ```sh
89
88
  anycable-go --host=localhost --port=3334
90
89
  ```
91
90
 
92
- See [documentation](https://docs.anycable.io/v1/#/ruby/rails) for more information on AnyCable + Rails usage.
91
+ See [documentation](https://docs.anycable.io/#/rails/getting_started) for more information on AnyCable + Rails usage.
93
92
 
94
93
  ## Action Cable Compatibility
95
94
 
96
- See [documentation](https://docs.anycable.io/v1/#/ruby/compatibility).
95
+ See [documentation](https://docs.anycable.io/#/rails/compatibility).
97
96
 
98
97
  ## Contributing
99
98
 
100
99
  Bug reports and pull requests are welcome on GitHub at [https://github.com/anycable/anycable-rails](https://github.com/anycable/anycable-rails).
101
100
 
102
- ## Development
103
-
104
- If you are familiar with Docker, you can use [DIP](https://github.com/bibendi/dip) to start developing the gem quickly.
105
-
106
101
  ## License
107
102
 
108
103
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -5,7 +5,7 @@ require "action_cable/channel"
5
5
  module ActionCable
6
6
  module Channel
7
7
  class Base # :nodoc:
8
- alias handle_subscribe subscribe_to_channel
8
+ alias_method :handle_subscribe, :subscribe_to_channel
9
9
 
10
10
  public :handle_subscribe, :subscription_rejected?
11
11
 
@@ -21,17 +21,17 @@ module ActionCable
21
21
 
22
22
  attr_reader :socket
23
23
 
24
- alias anycable_socket socket
24
+ alias_method :anycable_socket, :socket
25
25
 
26
26
  delegate :env, :session, to: :request
27
27
 
28
28
  class << self
29
29
  def call(socket, **options)
30
- new(socket, nil, options)
30
+ new(socket, nil, **options)
31
31
  end
32
32
  end
33
33
 
34
- def initialize(socket, env, identifiers: "{}", subscriptions: [])
34
+ def initialize(socket, env, identifiers: "{}", subscriptions: nil)
35
35
  if env
36
36
  # If env is set, then somehow we're in the context of Action Cable
37
37
  # Return and print a warning in #process
@@ -51,8 +51,15 @@ module ActionCable
51
51
  @socket = socket
52
52
  @subscriptions = ActionCable::Connection::Subscriptions.new(self)
53
53
 
54
- # Initialize channels if any
55
- subscriptions.each { |id| @subscriptions.fetch(id) }
54
+ return unless subscriptions
55
+
56
+ # Initialize channels (for disconnect)
57
+ subscriptions.each do |id|
58
+ channel = @subscriptions.fetch(id)
59
+ next unless socket.istate[id]
60
+
61
+ channel.__istate__ = ActiveSupport::JSON.decode(socket.istate[id])
62
+ end
56
63
  end
57
64
 
58
65
  def process
@@ -64,7 +71,7 @@ module ActionCable
64
71
 
65
72
  def invalid_request_message
66
73
  "You're trying to connect to Action Cable server while using AnyCable. " \
67
- "See https://docs.anycable.io/v1/#/troubleshooting?id=server-raises-an-argumenterror-exception-when-client-tries-to-connect"
74
+ "See https://docs.anycable.io/#/troubleshooting?id=server-raises-an-argumenterror-exception-when-client-tries-to-connect"
68
75
  end
69
76
 
70
77
  def handle_open
@@ -12,8 +12,6 @@ end
12
12
 
13
13
  ActionCable::Channel::ChannelStub.prepend(Module.new do
14
14
  def subscribe_to_channel
15
- # allocate @streams
16
- streams
17
15
  handle_subscribe
18
16
  end
19
17
  end)
@@ -10,11 +10,11 @@ module AnyCable
10
10
  class_eval <<~RUBY, __FILE__, __LINE__ + 1
11
11
  def #{name}
12
12
  return @#{name} if instance_variable_defined?(:@#{name})
13
- @#{name} = AnyCable::Rails.deserialize(connection.socket.istate["#{name}"], json: true) if connection.anycable_socket
13
+ @#{name} = AnyCable::Rails.deserialize(__istate__["#{name}"], json: true) if connection.anycable_socket
14
14
  end
15
15
 
16
16
  def #{name}=(val)
17
- connection.socket.istate["#{name}"] = AnyCable::Rails.serialize(val, json: true) if connection.anycable_socket
17
+ __istate__["#{name}"] = AnyCable::Rails.serialize(val, json: true) if connection.anycable_socket
18
18
  instance_variable_set(:@#{name}, val)
19
19
  end
20
20
  RUBY
@@ -36,6 +36,13 @@ module AnyCable
36
36
  def self.included(base)
37
37
  base.extend ClassMethods
38
38
  end
39
+
40
+ # Make it possible to provide istate explicitly for a channel instance
41
+ attr_writer :__istate__
42
+
43
+ def __istate__
44
+ @__istate__ ||= connection.socket.istate
45
+ end
39
46
  end
40
47
  end
41
48
  end
@@ -4,6 +4,11 @@ module AnyCable
4
4
  class CompatibilityError < StandardError; end
5
5
 
6
6
  module Compatibility # :nodoc:
7
+ IGNORE_INSTANCE_VARS = %i[
8
+ @active_periodic_timers
9
+ @_streams
10
+ ]
11
+
7
12
  ActionCable::Channel::Base.prepend(Module.new do
8
13
  def stream_from(broadcasting, callback = nil, coder: nil)
9
14
  if coder.present? && coder != ActiveSupport::JSON
@@ -31,9 +36,10 @@ module AnyCable
31
36
  def __anycable_check_ivars__
32
37
  was_ivars = instance_variables
33
38
  res = yield
34
- diff = instance_variables - was_ivars
39
+ diff = instance_variables - was_ivars - IGNORE_INSTANCE_VARS
35
40
 
36
41
  if self.class.respond_to?(:channel_state_attributes)
42
+ diff.delete(:@__istate__)
37
43
  diff.delete_if { |ivar| self.class.channel_state_attributes.include?(:"#{ivar.to_s.sub(/^@/, "")}") }
38
44
  end
39
45
 
@@ -38,16 +38,16 @@ module AnyCable
38
38
  config = ::Rails.application.config
39
39
 
40
40
  ActionDispatch::MiddlewareStack.new do |middleware|
41
- middleware.use(config.session_store, config.session_options)
41
+ middleware.use(config.session_store, config.session_options) if config.session_store
42
42
  end
43
43
  end
44
44
 
45
45
  def self.app
46
46
  @rack_app || app_build_lock.synchronize do
47
- @rack_app ||= begin
48
- stack = default_middleware_stack
49
- @middleware = middleware.merge_into(stack)
50
- middleware.build { [-1, {}, []] }
47
+ @rack_app ||= default_middleware_stack.yield_self do |stack|
48
+ middleware.merge_into(stack)
49
+ end.yield_self do |stack|
50
+ stack.build { [-1, {}, []] }
51
51
  end
52
52
  end
53
53
  end
@@ -18,8 +18,8 @@ module AnyCable
18
18
  AnyCable.logger = ActiveSupport::TaggedLogging.new(::ActionCable.server.config.logger)
19
19
  # Broadcast server logs to STDOUT in development
20
20
  if ::Rails.env.development? &&
21
- !ActiveSupport::Logger.logger_outputs_to?(::Rails.logger, STDOUT)
22
- console = ActiveSupport::Logger.new(STDOUT)
21
+ !ActiveSupport::Logger.logger_outputs_to?(::Rails.logger, $stdout)
22
+ console = ActiveSupport::Logger.new($stdout)
23
23
  console.formatter = ::Rails.logger.formatter
24
24
  console.level = ::Rails.logger.level
25
25
  AnyCable.logger.extend(ActiveSupport::Logger.broadcast(console))
@@ -21,8 +21,8 @@ module AnyCable
21
21
  CODE
22
22
  end
23
23
 
24
- alias include? has_key?
25
- alias key? has_key?
24
+ alias_method :include?, :has_key?
25
+ alias_method :key?, :has_key?
26
26
 
27
27
  %i[update merge! to_hash].each do |mid|
28
28
  class_eval <<~CODE, __FILE__, __LINE__ + 1
@@ -33,7 +33,7 @@ module AnyCable
33
33
  CODE
34
34
  end
35
35
 
36
- alias to_h to_hash
36
+ alias_method :to_h, :to_hash
37
37
 
38
38
  def keys
39
39
  rack_session.keys + socket_session.keys
@@ -2,6 +2,6 @@
2
2
 
3
3
  module AnyCable
4
4
  module Rails
5
- VERSION = "1.0.1"
5
+ VERSION = "1.0.7"
6
6
  end
7
7
  end
@@ -8,7 +8,7 @@ module AnyCableRailsGenerators
8
8
  namespace "anycable:setup"
9
9
  source_root File.expand_path("templates", __dir__)
10
10
 
11
- DOCS_ROOT = "https://docs.anycable.io/v1/#"
11
+ DOCS_ROOT = "https://docs.anycable.io/#"
12
12
  DEVELOPMENT_METHODS = %w[skip local docker].freeze
13
13
  SERVER_SOURCES = %w[skip brew binary].freeze
14
14
 
@@ -118,7 +118,7 @@ module AnyCableRailsGenerators
118
118
  def stimulus_reflex
119
119
  return unless stimulus_reflex?
120
120
 
121
- say_status :help, "⚠️ Please, check out the documentation on using AnyCable with Stimulus Reflex: https://docs.anycable.io/v1/#/ruby/stimulus_reflex"
121
+ say_status :help, "⚠️ Please, check out the documentation on using AnyCable with Stimulus Reflex: https://docs.anycable.io/#/rails/stimulus_reflex"
122
122
  end
123
123
 
124
124
  def rubocop_compatibility
@@ -126,7 +126,7 @@ module AnyCableRailsGenerators
126
126
 
127
127
  say_status :info, "🤖 Running static compatibility checks with RuboCop"
128
128
  res = run "bundle exec rubocop -r 'anycable/rails/compatibility/rubocop' --only AnyCable/InstanceVars,AnyCable/PeriodicalTimers,AnyCable/InstanceVars"
129
- say_status :help, "⚠️ Please, take a look at the icompatibilities above and fix them. See https://docs.anycable.io/v1/#/ruby/compatibility" unless res
129
+ say_status :help, "⚠️ Please, take a look at the icompatibilities above and fix them. See https://docs.anycable.io/#/rails/compatibility" unless res
130
130
  end
131
131
 
132
132
  def finish
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Add Warden middkeware to AnyCable stack to allow accessing
3
+ # Add Warden middleware to AnyCable stack to allow accessing
4
4
  # Devise current user via `env["warden"].user`.
5
5
  #
6
6
  # See <%= DOCS_ROOT %>/ruby/authentication
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anycable-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-07 00:00:00.000000000 Z
11
+ date: 2021-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anycable
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.0.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: rails
28
+ name: actioncable
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '5'
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
+ - !ruby/object:Gem::Dependency
56
+ name: activerecord
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: ammeter
43
71
  requirement: !ruby/object:Gem::Requirement