stimulus_reflex 3.4.0.pre3 → 3.4.0.pre4

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.

Potentially problematic release.


This version of stimulus_reflex might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 344e0b60c7f18f467821263a5758cc37843cfae000430754ed89d34214363ff3
4
- data.tar.gz: a49f8d18df8d0e2f4d664a70690fd562fd7d4fcc9db3f22d7821f96f67dee03d
3
+ metadata.gz: 1d3b9110da6cd9d446b19c1bd8ac2978b1d8b0c5ca88d1a1cf9fb849400a1757
4
+ data.tar.gz: 5512ece82357de04c62f9c4fcff9bba59bf6dec9f9234effeb06772084e96d38
5
5
  SHA512:
6
- metadata.gz: cd85f6455c20f2cad48a8e4c7bda0fe6e46e50fa6bb39d2c67c128a899edd96d815798b913b928ae08c75fb8f55421483249f6acec34e26428a7114fa7e3eb67
7
- data.tar.gz: 3fbb2e6be0b867db5c05997aa0727642e0298d0c13ad14e31c3f811ca4e6b4188db5154ea0c7ada5aeca8a3fb456c6998e35d0f4616e3fa03c636fc710b33056
6
+ metadata.gz: 928a0b20cc704cb30a1a9c7ccfe7672cc44c2e8cce2f9387b87ddc531981b2521e926992271233fb18e7787121bcda84e4f90c64823d32f5c2824ad302ba24e4
7
+ data.tar.gz: da166747c83c5dfee363e6a9475826cb32d3ba850f997481539cfdd475e390614e7726083bdf7e18762f410d4b74ff8b031922a66647498937d065479e939002
@@ -2,7 +2,34 @@
2
2
 
3
3
  ## [Unreleased](https://github.com/hopsoft/stimulus_reflex/tree/HEAD)
4
4
 
5
- [Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.4.0.pre2...HEAD)
5
+ [Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.4.0.pre3...HEAD)
6
+
7
+ **Fixed bugs:**
8
+
9
+ - Fix fatal error in `stimulus\_reflex:install` task with Rails 5.2 [\#371](https://github.com/hopsoft/stimulus_reflex/pull/371) ([Matt-Yorkley](https://github.com/Matt-Yorkley))
10
+ - fix nothing morphs and error messages [\#368](https://github.com/hopsoft/stimulus_reflex/pull/368) ([leastbad](https://github.com/leastbad))
11
+
12
+ **Closed issues:**
13
+
14
+ - `stimulus\_reflex:install` fails to complete in Rails 5.2 [\#367](https://github.com/hopsoft/stimulus_reflex/issues/367)
15
+ - Form data still not captured [\#366](https://github.com/hopsoft/stimulus_reflex/issues/366)
16
+ - Console exception when reflex does not update a page that didn't trigger the reflex [\#363](https://github.com/hopsoft/stimulus_reflex/issues/363)
17
+ - Improve server-side logging options [\#264](https://github.com/hopsoft/stimulus_reflex/issues/264)
18
+
19
+ **Merged pull requests:**
20
+
21
+ - use puts instead of ActionCable.logger to sidestep silenced AC logs [\#373](https://github.com/hopsoft/stimulus_reflex/pull/373) ([leastbad](https://github.com/leastbad))
22
+ - Improve logged post\_install.js message [\#372](https://github.com/hopsoft/stimulus_reflex/pull/372) ([forsbergplustwo](https://github.com/forsbergplustwo))
23
+ - Pass additional reflex-related data to reflex from data [\#370](https://github.com/hopsoft/stimulus_reflex/pull/370) ([joshleblanc](https://github.com/joshleblanc))
24
+ - fix: rip out microbundle [\#369](https://github.com/hopsoft/stimulus_reflex/pull/369) ([ParamagicDev](https://github.com/ParamagicDev))
25
+ - Add tests for broadcasters [\#364](https://github.com/hopsoft/stimulus_reflex/pull/364) ([julianrubisch](https://github.com/julianrubisch))
26
+ - Do not run sanity check on `rails generate stimulus\_reflex:config` [\#362](https://github.com/hopsoft/stimulus_reflex/pull/362) ([RolandStuder](https://github.com/RolandStuder))
27
+ - fix: revert CR and @rails/actioncable to dependencies [\#361](https://github.com/hopsoft/stimulus_reflex/pull/361) ([ParamagicDev](https://github.com/ParamagicDev))
28
+ - xpath fix [\#360](https://github.com/hopsoft/stimulus_reflex/pull/360) ([leastbad](https://github.com/leastbad))
29
+
30
+ ## [v3.4.0.pre3](https://github.com/hopsoft/stimulus_reflex/tree/v3.4.0.pre3) (2020-11-11)
31
+
32
+ [Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.4.0.pre2...v3.4.0.pre3)
6
33
 
7
34
  **Merged pull requests:**
8
35
 
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- stimulus_reflex (3.4.0.pre3)
4
+ stimulus_reflex (3.4.0.pre4)
5
+ cable_ready (>= 4.3.0)
5
6
  nokogiri
6
7
  rack
7
8
  rails (>= 5.2)
@@ -72,7 +73,7 @@ GEM
72
73
  coderay (1.1.3)
73
74
  concurrent-ruby (1.1.7)
74
75
  crass (1.0.6)
75
- erubi (1.9.0)
76
+ erubi (1.10.0)
76
77
  globalid (0.4.2)
77
78
  activesupport (>= 4.2.0)
78
79
  i18n (1.8.5)
@@ -131,7 +132,7 @@ GEM
131
132
  thor (>= 0.20.3, < 2.0)
132
133
  rainbow (3.0.0)
133
134
  rake (13.0.1)
134
- redis (4.2.2)
135
+ redis (4.2.4)
135
136
  regexp_parser (1.8.2)
136
137
  rexml (3.2.4)
137
138
  rubocop (1.2.0)
@@ -176,7 +177,6 @@ PLATFORMS
176
177
 
177
178
  DEPENDENCIES
178
179
  bundler (~> 2.0)
179
- cable_ready (>= 4.3.0)
180
180
  pry
181
181
  pry-nav
182
182
  rake
@@ -37,9 +37,14 @@ class StimulusReflex::Channel < StimulusReflex.configuration.parent_channel.cons
37
37
  element: element,
38
38
  selectors: selectors,
39
39
  method_name: method_name,
40
- permanent_attribute_name: permanent_attribute_name,
41
40
  params: params,
42
- reflex_id: data["reflexId"])
41
+ client_attributes: {
42
+ reflex_id: data["reflexId"],
43
+ xpath: data["xpath"],
44
+ c_xpath: data["cXpath"],
45
+ reflex_controller: data["reflexController"],
46
+ permanent_attribute_name: permanent_attribute_name
47
+ })
43
48
  delegate_call_to_reflex reflex, method_name, arguments
44
49
  rescue => invoke_error
45
50
  message = exception_message_with_backtrace(invoke_error)
@@ -48,7 +53,7 @@ class StimulusReflex::Channel < StimulusReflex.configuration.parent_channel.cons
48
53
  reflex.rescue_with_handler(invoke_error)
49
54
  reflex.broadcast_message subject: "error", body: body, data: data, error: invoke_error
50
55
  else
51
- logger.error "\e[31m#{body}\e[0m"
56
+ puts "\e[31m#{body}\e[0m"
52
57
  end
53
58
  return
54
59
  end
@@ -63,10 +68,14 @@ class StimulusReflex::Channel < StimulusReflex.configuration.parent_channel.cons
63
68
  message = exception_message_with_backtrace(render_error)
64
69
  body = "Reflex failed to re-render: #{message} [#{url}]"
65
70
  reflex.broadcast_message subject: "error", body: body, data: data, error: render_error
71
+ puts "\e[31m#{body}\e[0m"
66
72
  end
67
73
  end
68
74
  ensure
69
- commit_session reflex if reflex
75
+ if reflex
76
+ commit_session(reflex)
77
+ reflex.logger.print
78
+ end
70
79
  end
71
80
  end
72
81
 
@@ -101,7 +110,7 @@ class StimulusReflex::Channel < StimulusReflex.configuration.parent_channel.cons
101
110
  store.commit_session reflex.request, reflex.controller.response
102
111
  rescue => e
103
112
  message = "Failed to commit session! #{exception_message_with_backtrace(e)}"
104
- logger.error "\e[31m#{message}\e[0m"
113
+ puts "\e[31m#{message}\e[0m"
105
114
  end
106
115
 
107
116
  def exception_message_with_backtrace(exception)
@@ -3,8 +3,18 @@
3
3
  StimulusReflex.configure do |config|
4
4
  # Enable/disable exiting / warning when the sanity checks fail options:
5
5
  # `:exit` or `:warn` or `:ignore`
6
+
6
7
  # config.on_failed_sanity_checks = :exit
7
8
 
8
9
  # Override the parent class that the StimulusReflex ActionCable channel inherits from
10
+
9
11
  # config.parent_channel = "ApplicationCable::Channel"
12
+
13
+ # Customize server-side Reflex logging format, with optional colorization:
14
+ # Available tokens: session_id, session_id_full, reflex_info, operation, reflex_id, reflex_id_full, mode, selector, operation_counter, connection_id, connection_id_full, timestamp
15
+ # Available colors: green, yellow, blue, magenta, cyan, white
16
+ # You can also use attributes from your ActionCable Connection's identifiers that resolve to valid ActiveRecord models
17
+ # eg. if your connection is `identified_by :current_user` and your User model has an email attribute, you can access r.email (it will display `-` if the user isn't logged in)
18
+
19
+ # config.logging = proc { "[#{session_id}] #{operation_counter.magenta} #{reflex_info.green} -> #{selector.cyan} via #{mode} Morph (#{operation.yellow})" }
10
20
  end
@@ -17,6 +17,8 @@ require "stimulus_reflex/broadcasters/broadcaster"
17
17
  require "stimulus_reflex/broadcasters/nothing_broadcaster"
18
18
  require "stimulus_reflex/broadcasters/page_broadcaster"
19
19
  require "stimulus_reflex/broadcasters/selector_broadcaster"
20
+ require "stimulus_reflex/utils/colorize"
21
+ require "stimulus_reflex/logger"
20
22
 
21
23
  module StimulusReflex
22
24
  class Engine < Rails::Engine
@@ -4,12 +4,13 @@ module StimulusReflex
4
4
  class Broadcaster
5
5
  include CableReady::Broadcaster
6
6
 
7
- attr_reader :reflex, :logger
7
+ attr_reader :reflex, :logger, :operations
8
8
  delegate :permanent_attribute_name, :stream_name, to: :reflex
9
9
 
10
10
  def initialize(reflex)
11
11
  @reflex = reflex
12
- @logger = Rails.logger
12
+ @logger = Rails.logger if defined?(Rails.logger)
13
+ @operations = []
13
14
  end
14
15
 
15
16
  def nothing?
@@ -26,6 +27,7 @@ module StimulusReflex
26
27
 
27
28
  def broadcast_message(subject:, body: nil, data: {}, error: nil)
28
29
  logger.error "\e[31m#{body}\e[0m" if subject == "error"
30
+ @operations << ["document", :dispatch_event]
29
31
  cable_ready[stream_name].dispatch_event(
30
32
  name: "stimulus-reflex:server-message",
31
33
  detail: {
@@ -48,5 +50,10 @@ module StimulusReflex
48
50
  def to_sym
49
51
  raise NotImplementedError
50
52
  end
53
+
54
+ # abstract method to be implemented by subclasses
55
+ def to_s
56
+ raise NotImplementedError
57
+ end
51
58
  end
52
59
  end
@@ -13,5 +13,9 @@ module StimulusReflex
13
13
  def to_sym
14
14
  :nothing
15
15
  end
16
+
17
+ def to_s
18
+ "Nothing"
19
+ end
16
20
  end
17
21
  end
@@ -8,9 +8,10 @@ module StimulusReflex
8
8
 
9
9
  return unless page_html.present?
10
10
 
11
- document = Nokogiri::HTML(page_html)
11
+ document = Nokogiri::HTML.parse(page_html)
12
12
  selectors = selectors.select { |s| document.css(s).present? }
13
13
  selectors.each do |selector|
14
+ @operations << [selector, :morph]
14
15
  html = document.css(selector).inner_html
15
16
  cable_ready[stream_name].morph(
16
17
  selector: selector,
@@ -32,5 +33,9 @@ module StimulusReflex
32
33
  def page?
33
34
  true
34
35
  end
36
+
37
+ def to_s
38
+ "Page"
39
+ end
35
40
  end
36
41
  end
@@ -11,6 +11,7 @@ module StimulusReflex
11
11
  fragment = Nokogiri::HTML.fragment(html)
12
12
  match = fragment.at_css(selector)
13
13
  if match.present?
14
+ @operations << [selector, :morph]
14
15
  cable_ready[stream_name].morph(
15
16
  selector: selector,
16
17
  html: match.inner_html,
@@ -21,6 +22,7 @@ module StimulusReflex
21
22
  })
22
23
  )
23
24
  else
25
+ @operations << [selector, :inner_html]
24
26
  cable_ready[stream_name].inner_html(
25
27
  selector: selector,
26
28
  html: fragment.to_html,
@@ -40,6 +42,10 @@ module StimulusReflex
40
42
  @morphs ||= []
41
43
  end
42
44
 
45
+ def append_morph(selectors, html)
46
+ morphs << [selectors, html]
47
+ end
48
+
43
49
  def to_sym
44
50
  :selector
45
51
  end
@@ -47,5 +53,9 @@ module StimulusReflex
47
53
  def selector?
48
54
  true
49
55
  end
56
+
57
+ def to_s
58
+ "Selector"
59
+ end
50
60
  end
51
61
  end
@@ -14,11 +14,14 @@ module StimulusReflex
14
14
  end
15
15
 
16
16
  class Configuration
17
- attr_accessor :on_failed_sanity_checks, :parent_channel
17
+ attr_accessor :on_failed_sanity_checks, :parent_channel, :logging
18
+
19
+ DEFAULT_LOGGING = proc { "[#{session_id}] #{operation_counter.magenta} #{reflex_info.green} -> #{selector.cyan} via #{mode} Morph (#{operation.yellow})" }
18
20
 
19
21
  def initialize
20
22
  @on_failed_sanity_checks = :exit
21
23
  @parent_channel = "ApplicationCable::Channel"
24
+ @logging = DEFAULT_LOGGING
22
25
  end
23
26
  end
24
27
  end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StimulusReflex
4
+ class Logger
5
+ attr_accessor :reflex, :current_operation
6
+
7
+ def initialize(reflex)
8
+ @reflex = reflex
9
+ @current_operation = 1
10
+ end
11
+
12
+ def print
13
+ return unless config_logging.instance_of?(Proc)
14
+
15
+ puts
16
+ reflex.broadcaster.operations.each do
17
+ puts instance_eval(&config_logging) + "\e[0m"
18
+ @current_operation += 1
19
+ end
20
+ puts
21
+ end
22
+
23
+ private
24
+
25
+ def config_logging
26
+ return @config_logging if @config_logging
27
+
28
+ StimulusReflex.config.logging.binding.eval("using StimulusReflex::Utils::Colorize")
29
+ @config_logging = StimulusReflex.config.logging
30
+ end
31
+
32
+ def session_id_full
33
+ session = reflex.request&.session
34
+ session.nil? ? "-" : session.id
35
+ end
36
+
37
+ def session_id
38
+ session_id_full.to_s[0..7]
39
+ end
40
+
41
+ def reflex_info
42
+ reflex.class.to_s + "#" + reflex.method_name
43
+ end
44
+
45
+ def reflex_id_full
46
+ reflex.reflex_id
47
+ end
48
+
49
+ def reflex_id
50
+ reflex_id_full[0..7]
51
+ end
52
+
53
+ def mode
54
+ reflex.broadcaster.to_s
55
+ end
56
+
57
+ def selector
58
+ reflex.broadcaster.operations[current_operation - 1][0]
59
+ end
60
+
61
+ def operation
62
+ reflex.broadcaster.operations[current_operation - 1][1].to_s
63
+ end
64
+
65
+ def operation_counter
66
+ current_operation.to_s + "/" + reflex.broadcaster.operations.size.to_s
67
+ end
68
+
69
+ def connection_id_full
70
+ identifier = reflex.connection&.connection_identifier
71
+ identifier.empty? ? "-" : identifier
72
+ end
73
+
74
+ def connection_id
75
+ connection_id_full[0..7]
76
+ end
77
+
78
+ def timestamp
79
+ Time.now.strftime("%Y-%m-%d %H:%M:%S")
80
+ end
81
+
82
+ def method_missing method
83
+ return send(method.to_sym) if private_instance_methods.include?(method.to_sym)
84
+
85
+ reflex.connection.identifiers.each do |identifier|
86
+ ident = reflex.connection.send(identifier)
87
+ return ident.send(method) if ident.respond_to?(:attributes) && ident.attributes.key?(method.to_s)
88
+ end
89
+ "-"
90
+ end
91
+
92
+ def respond_to_missing? method
93
+ return true if private_instance_methods.include?(method.to_sym)
94
+
95
+ reflex.connection.identifiers.each do |identifier|
96
+ ident = reflex.connection.send(identifier)
97
+ return true if ident.respond_to?(:attributes) && ident.attributes.key?(method.to_s)
98
+ end
99
+ false
100
+ end
101
+
102
+ def private_instance_methods
103
+ StimulusReflex::Logger.private_instance_methods(false)
104
+ end
105
+ end
106
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ ClientAttributes = Struct.new(:reflex_id, :reflex_controller, :xpath, :c_xpath, :permanent_attribute_name, keyword_init: true)
4
+
3
5
  class StimulusReflex::Reflex
4
6
  include ActiveSupport::Rescuable
5
7
  include ActiveSupport::Callbacks
@@ -43,24 +45,25 @@ class StimulusReflex::Reflex
43
45
  end
44
46
  end
45
47
 
46
- attr_reader :channel, :url, :element, :selectors, :method_name, :broadcaster, :permanent_attribute_name, :reflex_id
48
+ attr_reader :channel, :url, :element, :selectors, :method_name, :broadcaster, :client_attributes, :logger
47
49
 
48
50
  alias_method :action_name, :method_name # for compatibility with controller libraries like Pundit that expect an action name
49
51
 
50
52
  delegate :connection, :stream_name, to: :channel
51
53
  delegate :flash, :session, to: :request
52
54
  delegate :broadcast, :broadcast_message, to: :broadcaster
55
+ delegate :reflex_id, :reflex_controller, :xpath, :c_xpath, :permanent_attribute_name, to: :client_attributes
53
56
 
54
- def initialize(channel, url: nil, element: nil, selectors: [], method_name: nil, permanent_attribute_name: nil, params: {}, reflex_id: nil)
57
+ def initialize(channel, url: nil, element: nil, selectors: [], method_name: nil, params: {}, client_attributes: {})
55
58
  @channel = channel
56
59
  @url = url
57
60
  @element = element
58
61
  @selectors = selectors
59
62
  @method_name = method_name
60
63
  @params = params
61
- @permanent_attribute_name = permanent_attribute_name
62
64
  @broadcaster = StimulusReflex::PageBroadcaster.new(self)
63
- @reflex_id = reflex_id
65
+ @logger = StimulusReflex::Logger.new(self)
66
+ @client_attributes = ClientAttributes.new(client_attributes)
64
67
  self.params
65
68
  end
66
69
 
@@ -105,7 +108,7 @@ class StimulusReflex::Reflex
105
108
  else
106
109
  raise StandardError.new("Cannot call :selector morph after :nothing morph") if broadcaster.nothing?
107
110
  @broadcaster = StimulusReflex::SelectorBroadcaster.new(self) unless broadcaster.selector?
108
- broadcaster.morphs << [selectors, html]
111
+ broadcaster.append_morph(selectors, html)
109
112
  end
110
113
  end
111
114
 
@@ -3,12 +3,21 @@
3
3
  class StimulusReflex::SanityChecker
4
4
  JSON_VERSION_FORMAT = /(\d+\.\d+\.\d+.*)"/
5
5
 
6
- def self.check!
7
- return if StimulusReflex.config.on_failed_sanity_checks == :ignore
6
+ class << self
7
+ def check!
8
+ return if StimulusReflex.config.on_failed_sanity_checks == :ignore
9
+ return if called_by_generate_config?
10
+
11
+ instance = new
12
+ instance.check_caching_enabled
13
+ instance.check_javascript_package_version
14
+ end
15
+
16
+ private
8
17
 
9
- instance = new
10
- instance.check_caching_enabled
11
- instance.check_javascript_package_version
18
+ def called_by_generate_config?
19
+ ARGV.include? "stimulus_reflex:config"
20
+ end
12
21
  end
13
22
 
14
23
  def check_caching_enabled