stimulus_reflex 3.4.1 → 3.5.0.pre3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +664 -495
  3. data/Gemfile.lock +99 -95
  4. data/LATEST +1 -0
  5. data/README.md +17 -16
  6. data/app/channels/stimulus_reflex/channel.rb +44 -75
  7. data/lib/generators/USAGE +1 -1
  8. data/lib/generators/stimulus_reflex/{config_generator.rb → initializer_generator.rb} +3 -3
  9. data/lib/generators/stimulus_reflex/stimulus_reflex_generator.rb +5 -4
  10. data/lib/generators/stimulus_reflex/templates/app/reflexes/%file_name%_reflex.rb.tt +3 -2
  11. data/lib/generators/stimulus_reflex/templates/app/reflexes/application_reflex.rb.tt +11 -4
  12. data/lib/generators/stimulus_reflex/templates/config/initializers/stimulus_reflex.rb +21 -1
  13. data/lib/stimulus_reflex/broadcasters/broadcaster.rb +22 -18
  14. data/lib/stimulus_reflex/broadcasters/nothing_broadcaster.rb +6 -1
  15. data/lib/stimulus_reflex/broadcasters/page_broadcaster.rb +3 -5
  16. data/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb +22 -16
  17. data/lib/stimulus_reflex/broadcasters/update.rb +23 -0
  18. data/lib/stimulus_reflex/cable_ready_channels.rb +10 -2
  19. data/lib/stimulus_reflex/callbacks.rb +55 -5
  20. data/lib/stimulus_reflex/concern_enhancer.rb +37 -0
  21. data/lib/stimulus_reflex/configuration.rb +4 -1
  22. data/lib/stimulus_reflex/dataset.rb +34 -0
  23. data/lib/stimulus_reflex/element.rb +20 -13
  24. data/lib/stimulus_reflex/policies/reflex_invocation_policy.rb +28 -0
  25. data/lib/stimulus_reflex/reflex.rb +41 -21
  26. data/lib/stimulus_reflex/reflex_data.rb +79 -0
  27. data/lib/stimulus_reflex/reflex_factory.rb +31 -0
  28. data/lib/stimulus_reflex/request_parameters.rb +19 -0
  29. data/lib/stimulus_reflex/utils/attribute_builder.rb +17 -0
  30. data/lib/stimulus_reflex/{logger.rb → utils/logger.rb} +6 -4
  31. data/lib/stimulus_reflex/utils/sanity_checker.rb +210 -0
  32. data/lib/stimulus_reflex/version.rb +1 -1
  33. data/lib/stimulus_reflex.rb +10 -2
  34. data/lib/tasks/stimulus_reflex/install.rake +54 -15
  35. data/test/broadcasters/broadcaster_test.rb +0 -1
  36. data/test/broadcasters/broadcaster_test_case.rb +25 -1
  37. data/test/broadcasters/nothing_broadcaster_test.rb +14 -20
  38. data/test/broadcasters/page_broadcaster_test.rb +31 -29
  39. data/test/broadcasters/selector_broadcaster_test.rb +165 -55
  40. data/test/callbacks_test.rb +652 -0
  41. data/test/concern_enhancer_test.rb +54 -0
  42. data/test/element_test.rb +254 -0
  43. data/test/generators/stimulus_reflex_generator_test.rb +8 -0
  44. data/test/reflex_test.rb +12 -1
  45. data/test/test_helper.rb +25 -1
  46. data/test/tmp/app/reflexes/application_reflex.rb +10 -3
  47. data/test/tmp/app/reflexes/{user_reflex.rb → demo_reflex.rb} +4 -12
  48. metadata +65 -36
  49. data/lib/stimulus_reflex/sanity_checker.rb +0 -154
  50. data/package.json +0 -57
  51. data/stimulus_reflex.gemspec +0 -42
  52. data/tags +0 -156
  53. data/yarn.lock +0 -4687
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- stimulus_reflex (3.4.1)
5
- cable_ready (>= 4.5)
4
+ stimulus_reflex (3.5.0.pre3)
5
+ cable_ready (= 5.0.0.pre4)
6
6
  nokogiri
7
7
  rack
8
8
  rails (>= 5.2)
@@ -11,60 +11,60 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- actioncable (6.1.1)
15
- actionpack (= 6.1.1)
16
- activesupport (= 6.1.1)
14
+ actioncable (6.1.4.1)
15
+ actionpack (= 6.1.4.1)
16
+ activesupport (= 6.1.4.1)
17
17
  nio4r (~> 2.0)
18
18
  websocket-driver (>= 0.6.1)
19
- actionmailbox (6.1.1)
20
- actionpack (= 6.1.1)
21
- activejob (= 6.1.1)
22
- activerecord (= 6.1.1)
23
- activestorage (= 6.1.1)
24
- activesupport (= 6.1.1)
19
+ actionmailbox (6.1.4.1)
20
+ actionpack (= 6.1.4.1)
21
+ activejob (= 6.1.4.1)
22
+ activerecord (= 6.1.4.1)
23
+ activestorage (= 6.1.4.1)
24
+ activesupport (= 6.1.4.1)
25
25
  mail (>= 2.7.1)
26
- actionmailer (6.1.1)
27
- actionpack (= 6.1.1)
28
- actionview (= 6.1.1)
29
- activejob (= 6.1.1)
30
- activesupport (= 6.1.1)
26
+ actionmailer (6.1.4.1)
27
+ actionpack (= 6.1.4.1)
28
+ actionview (= 6.1.4.1)
29
+ activejob (= 6.1.4.1)
30
+ activesupport (= 6.1.4.1)
31
31
  mail (~> 2.5, >= 2.5.4)
32
32
  rails-dom-testing (~> 2.0)
33
- actionpack (6.1.1)
34
- actionview (= 6.1.1)
35
- activesupport (= 6.1.1)
33
+ actionpack (6.1.4.1)
34
+ actionview (= 6.1.4.1)
35
+ activesupport (= 6.1.4.1)
36
36
  rack (~> 2.0, >= 2.0.9)
37
37
  rack-test (>= 0.6.3)
38
38
  rails-dom-testing (~> 2.0)
39
39
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
40
- actiontext (6.1.1)
41
- actionpack (= 6.1.1)
42
- activerecord (= 6.1.1)
43
- activestorage (= 6.1.1)
44
- activesupport (= 6.1.1)
40
+ actiontext (6.1.4.1)
41
+ actionpack (= 6.1.4.1)
42
+ activerecord (= 6.1.4.1)
43
+ activestorage (= 6.1.4.1)
44
+ activesupport (= 6.1.4.1)
45
45
  nokogiri (>= 1.8.5)
46
- actionview (6.1.1)
47
- activesupport (= 6.1.1)
46
+ actionview (6.1.4.1)
47
+ activesupport (= 6.1.4.1)
48
48
  builder (~> 3.1)
49
49
  erubi (~> 1.4)
50
50
  rails-dom-testing (~> 2.0)
51
51
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
52
- activejob (6.1.1)
53
- activesupport (= 6.1.1)
52
+ activejob (6.1.4.1)
53
+ activesupport (= 6.1.4.1)
54
54
  globalid (>= 0.3.6)
55
- activemodel (6.1.1)
56
- activesupport (= 6.1.1)
57
- activerecord (6.1.1)
58
- activemodel (= 6.1.1)
59
- activesupport (= 6.1.1)
60
- activestorage (6.1.1)
61
- actionpack (= 6.1.1)
62
- activejob (= 6.1.1)
63
- activerecord (= 6.1.1)
64
- activesupport (= 6.1.1)
65
- marcel (~> 0.3.1)
66
- mimemagic (~> 0.3.2)
67
- activesupport (6.1.1)
55
+ activemodel (6.1.4.1)
56
+ activesupport (= 6.1.4.1)
57
+ activerecord (6.1.4.1)
58
+ activemodel (= 6.1.4.1)
59
+ activesupport (= 6.1.4.1)
60
+ activestorage (6.1.4.1)
61
+ actionpack (= 6.1.4.1)
62
+ activejob (= 6.1.4.1)
63
+ activerecord (= 6.1.4.1)
64
+ activesupport (= 6.1.4.1)
65
+ marcel (~> 1.0.0)
66
+ mini_mime (>= 1.1.0)
67
+ activesupport (6.1.4.1)
68
68
  concurrent-ruby (~> 1.0, >= 1.0.2)
69
69
  i18n (>= 1.6, < 2)
70
70
  minitest (>= 5.1)
@@ -72,35 +72,36 @@ GEM
72
72
  zeitwerk (~> 2.3)
73
73
  ast (2.4.2)
74
74
  builder (3.2.4)
75
- cable_ready (4.5.0)
75
+ cable_ready (5.0.0.pre4)
76
76
  rails (>= 5.2)
77
77
  thread-local (>= 1.1.0)
78
78
  coderay (1.1.3)
79
- concurrent-ruby (1.1.8)
79
+ concurrent-ruby (1.1.9)
80
80
  crass (1.0.6)
81
81
  erubi (1.10.0)
82
- globalid (0.4.2)
83
- activesupport (>= 4.2.0)
84
- i18n (1.8.7)
82
+ globalid (0.5.2)
83
+ activesupport (>= 5.0)
84
+ i18n (1.8.10)
85
85
  concurrent-ruby (~> 1.0)
86
- loofah (2.9.0)
86
+ loofah (2.12.0)
87
87
  crass (~> 1.0.2)
88
88
  nokogiri (>= 1.5.9)
89
89
  mail (2.7.1)
90
90
  mini_mime (>= 0.1.1)
91
- marcel (0.3.3)
92
- mimemagic (~> 0.3.2)
91
+ marcel (1.0.2)
93
92
  method_source (0.9.2)
94
- mimemagic (0.3.5)
95
- mini_mime (1.0.2)
96
- mini_portile2 (2.5.0)
97
- minitest (5.14.3)
98
- nio4r (2.5.4)
99
- nokogiri (1.11.1)
100
- mini_portile2 (~> 2.5.0)
93
+ mini_mime (1.1.1)
94
+ minitest (5.14.4)
95
+ mocha (1.13.0)
96
+ nio4r (2.5.8)
97
+ nokogiri (1.12.5-arm64-darwin)
98
+ racc (~> 1.4)
99
+ nokogiri (1.12.5-x86_64-darwin)
100
+ racc (~> 1.4)
101
+ nokogiri (1.12.5-x86_64-linux)
101
102
  racc (~> 1.4)
102
103
  parallel (1.20.1)
103
- parser (3.0.0.0)
104
+ parser (3.0.2.0)
104
105
  ast (~> 2.4.1)
105
106
  pry (0.12.2)
106
107
  coderay (~> 1.1.0)
@@ -111,50 +112,50 @@ GEM
111
112
  rack (2.2.3)
112
113
  rack-test (1.1.0)
113
114
  rack (>= 1.0, < 3)
114
- rails (6.1.1)
115
- actioncable (= 6.1.1)
116
- actionmailbox (= 6.1.1)
117
- actionmailer (= 6.1.1)
118
- actionpack (= 6.1.1)
119
- actiontext (= 6.1.1)
120
- actionview (= 6.1.1)
121
- activejob (= 6.1.1)
122
- activemodel (= 6.1.1)
123
- activerecord (= 6.1.1)
124
- activestorage (= 6.1.1)
125
- activesupport (= 6.1.1)
115
+ rails (6.1.4.1)
116
+ actioncable (= 6.1.4.1)
117
+ actionmailbox (= 6.1.4.1)
118
+ actionmailer (= 6.1.4.1)
119
+ actionpack (= 6.1.4.1)
120
+ actiontext (= 6.1.4.1)
121
+ actionview (= 6.1.4.1)
122
+ activejob (= 6.1.4.1)
123
+ activemodel (= 6.1.4.1)
124
+ activerecord (= 6.1.4.1)
125
+ activestorage (= 6.1.4.1)
126
+ activesupport (= 6.1.4.1)
126
127
  bundler (>= 1.15.0)
127
- railties (= 6.1.1)
128
+ railties (= 6.1.4.1)
128
129
  sprockets-rails (>= 2.0.0)
129
130
  rails-dom-testing (2.0.3)
130
131
  activesupport (>= 4.2.0)
131
132
  nokogiri (>= 1.6)
132
- rails-html-sanitizer (1.3.0)
133
+ rails-html-sanitizer (1.4.2)
133
134
  loofah (~> 2.3)
134
- railties (6.1.1)
135
- actionpack (= 6.1.1)
136
- activesupport (= 6.1.1)
135
+ railties (6.1.4.1)
136
+ actionpack (= 6.1.4.1)
137
+ activesupport (= 6.1.4.1)
137
138
  method_source
138
- rake (>= 0.8.7)
139
+ rake (>= 0.13)
139
140
  thor (~> 1.0)
140
141
  rainbow (3.0.0)
141
- rake (13.0.3)
142
- redis (4.2.5)
143
- regexp_parser (2.0.3)
144
- rexml (3.2.4)
145
- rubocop (1.7.0)
142
+ rake (13.0.6)
143
+ redis (4.4.0)
144
+ regexp_parser (2.1.1)
145
+ rexml (3.2.5)
146
+ rubocop (1.18.3)
146
147
  parallel (~> 1.10)
147
- parser (>= 2.7.1.5)
148
+ parser (>= 3.0.0.0)
148
149
  rainbow (>= 2.2.2, < 4.0)
149
150
  regexp_parser (>= 1.8, < 3.0)
150
151
  rexml
151
- rubocop-ast (>= 1.2.0, < 2.0)
152
+ rubocop-ast (>= 1.7.0, < 2.0)
152
153
  ruby-progressbar (~> 1.7)
153
- unicode-display_width (>= 1.4.0, < 2.0)
154
- rubocop-ast (1.4.1)
155
- parser (>= 2.7.1.5)
156
- rubocop-performance (1.9.2)
157
- rubocop (>= 0.90.0, < 2.0)
154
+ unicode-display_width (>= 1.4.0, < 3.0)
155
+ rubocop-ast (1.8.0)
156
+ parser (>= 3.0.1.1)
157
+ rubocop-performance (1.11.4)
158
+ rubocop (>= 1.7.0, < 2.0)
158
159
  rubocop-ast (>= 0.4.0)
159
160
  ruby-progressbar (1.11.0)
160
161
  sprockets (4.0.2)
@@ -164,31 +165,34 @@ GEM
164
165
  actionpack (>= 4.0)
165
166
  activesupport (>= 4.0)
166
167
  sprockets (>= 3.0.0)
167
- standard (0.11.0)
168
- rubocop (= 1.7.0)
169
- rubocop-performance (= 1.9.2)
168
+ standard (1.1.5)
169
+ rubocop (= 1.18.3)
170
+ rubocop-performance (= 1.11.4)
170
171
  standardrb (1.0.0)
171
172
  standard
172
173
  thor (1.1.0)
173
174
  thread-local (1.1.0)
174
175
  tzinfo (2.0.4)
175
176
  concurrent-ruby (~> 1.0)
176
- unicode-display_width (1.7.0)
177
- websocket-driver (0.7.3)
177
+ unicode-display_width (2.0.0)
178
+ websocket-driver (0.7.5)
178
179
  websocket-extensions (>= 0.1.0)
179
180
  websocket-extensions (0.1.5)
180
181
  zeitwerk (2.4.2)
181
182
 
182
183
  PLATFORMS
183
- ruby
184
+ arm64-darwin-20
185
+ x86_64-darwin-19
186
+ x86_64-linux
184
187
 
185
188
  DEPENDENCIES
186
189
  bundler (~> 2.0)
190
+ mocha
187
191
  pry
188
192
  pry-nav
189
193
  rake
190
- standardrb
194
+ standardrb (~> 1.0)
191
195
  stimulus_reflex!
192
196
 
193
197
  BUNDLED WITH
194
- 2.1.4
198
+ 2.2.4
data/LATEST ADDED
@@ -0,0 +1 @@
1
+ 3.4.1
data/README.md CHANGED
@@ -7,11 +7,11 @@
7
7
  <a href="https://www.npmjs.com/package/stimulus_reflex">
8
8
  <img alt="downloads" src="https://img.shields.io/npm/dm/stimulus_reflex.svg?color=blue" target="_blank" />
9
9
  </a>
10
- <a href="https://github.com/hopsoft/stimulus_reflex/blob/master/LICENSE">
10
+ <a href="https://github.com/stimulusreflex/stimulus_reflex/blob/master/LICENSE">
11
11
  <img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-brightgreen.svg" target="_blank" />
12
12
  </a>
13
13
  <a href="http://blog.codinghorror.com/the-best-code-is-no-code-at-all/" target="_blank">
14
- <img alt="Lines of Code" src="https://img.shields.io/badge/lines_of_code-1726-brightgreen.svg?style=flat" />
14
+ <img alt="Lines of Code" src="https://img.shields.io/badge/lines_of_code-2190-brightgreen.svg?style=flat" />
15
15
  </a>
16
16
  <a href="https://docs.stimulusreflex.com/" target="_blank">
17
17
  <img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" />
@@ -30,14 +30,14 @@
30
30
  <a href="https://www.codacy.com/manual/hopsoft/stimulus_reflex/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=hopsoft/stimulus_reflex&amp;utm_campaign=Badge_Grade" target="_blank">
31
31
  <img alt="Code Quality" src="https://app.codacy.com/project/badge/Grade/d1d72a7060f5467b8696884351cf477f"/>
32
32
  </a>
33
- <a target="_blank" rel="noopener noreferrer" href="https://github.com/hopsoft/stimulus_reflex/workflows/Prettier-Standard/badge.svg">
34
- <img src="https://github.com/hopsoft/stimulus_reflex/workflows/Prettier-Standard/badge.svg" alt="Prettier-Standard" style="max-width:100%;">
33
+ <a target="_blank" rel="noopener noreferrer" href="https://github.com/stimulusreflex/stimulus_reflex/workflows/Prettier-Standard/badge.svg">
34
+ <img src="https://github.com/stimulusreflex/stimulus_reflex/workflows/Prettier-Standard/badge.svg" alt="Prettier-Standard" style="max-width:100%;">
35
35
  </a>
36
- <a target="_blank" rel="noopener noreferrer" href="https://github.com/hopsoft/stimulus_reflex/workflows/StandardRB/badge.svg">
37
- <img src="https://github.com/hopsoft/stimulus_reflex/workflows/StandardRB/badge.svg" alt="StandardRB" style="max-width:100%;">
36
+ <a target="_blank" rel="noopener noreferrer" href="https://github.com/stimulusreflex/stimulus_reflex/workflows/StandardRB/badge.svg">
37
+ <img src="https://github.com/stimulusreflex/stimulus_reflex/workflows/StandardRB/badge.svg" alt="StandardRB" style="max-width:100%;">
38
38
  </a>
39
- <a target="_blank" rel="noopener noreferrer" href="https://github.com/hopsoft/stimulus_reflex/workflows/Tests/badge.svg">
40
- <img src="https://github.com/hopsoft/stimulus_reflex/workflows/Tests/badge.svg" alt="Tests">
39
+ <a target="_blank" rel="noopener noreferrer" href="https://github.com/stimulusreflex/stimulus_reflex/workflows/Tests/badge.svg">
40
+ <img src="https://github.com/stimulusreflex/stimulus_reflex/workflows/Tests/badge.svg" alt="Tests">
41
41
  </a>
42
42
  </p>
43
43
  </p>
@@ -69,13 +69,14 @@ This project strives to live up to the vision outlined in [The Rails Doctrine](h
69
69
 
70
70
  ## ✨ Demos
71
71
 
72
- - [StimulusReflex Expo](http://expo.stimulusreflex.com) - part showcase, part learning tool
73
72
  - [Build a Twitter Clone in 10 Minutes](https://youtu.be/F5hA79vKE_E) (video)
73
+ - [BeastMode](https://beastmode.leastbad.com/) - faceted search, with filtering, sorting and pagination
74
+ - [StimulusReflex Patterns](https://www.stimulusreflexpatterns.com/patterns/) - single-file SR apps hosted on Glitch
74
75
  - [BoxDrop](https://dropbox-clone-rails.herokuapp.com/) - a Dropbox-inspired [concept demo](https://github.com/marcoroth/boxdrop/)
75
76
 
76
77
  ## 👩‍👩‍👧 Discord Community
77
78
 
78
- Please join over 1000 of us on [Discord](https://discord.gg/XveN625) for support getting started, as well as active discussions around Rails, StimulusJS and CableReady.
79
+ Please join over 1500 of us on [Discord](https://discord.gg/stimulus-reflex) for support getting started, as well as active discussions around Rails, StimulusJS and CableReady.
79
80
 
80
81
  ![](https://img.shields.io/discord/629472241427415060)
81
82
 
@@ -89,7 +90,7 @@ Please note that we are not actively providing support on Stack Overflow. If you
89
90
 
90
91
  ## 🚀 Installation and upgrading
91
92
 
92
- CLI and manual setup procedures are fully detailed in the [official docs](https://docs.stimulusreflex.com/setup). For information on upgrading existing projects to v3.4, read [this](https://docs.stimulusreflex.com/setup#upgrading-to-v-3-4-0).
93
+ CLI and manual setup procedures are fully detailed in the [official docs](https://docs.stimulusreflex.com/setup). For information on upgrading existing projects to v3.4, read [this](https://docs.stimulusreflex.com/hello-world/setup#upgrading-to-v-3-4-0).
93
94
 
94
95
  ## 🙏 Contributing
95
96
 
@@ -104,15 +105,15 @@ and [Prettier-Standard](https://github.com/sheerun/prettier-standard) for JavaSc
104
105
 
105
106
  Please run `./bin/standardize` prior to submitting pull requests.
106
107
 
107
- View the [wiki](https://github.com/hopsoft/stimulus_reflex/wiki/Editor-Configuration) to see recommendations for configuring your editor to work best with the project.
108
+ View the [wiki](https://github.com/stimulusreflex/stimulus_reflex/wiki/Editor-Configuration) to see recommendations for configuring your editor to work best with the project.
108
109
 
109
110
  ## 📦 Releasing
110
111
 
111
112
  1. Bump version number at `lib/stimulus_reflex/version.rb`
112
- 1. Run `rake build`
113
- 1. Run `rake release`
114
- 1. Run `yarn publish --no-git-tag-version`
115
- 1. Commit and push changes to the `package.json` file
113
+ 2. Run `rake build`
114
+ 3. Run `rake release`
115
+ 4. Run `yarn publish --no-git-tag-version`
116
+ 5. Commit and push changes to the `package.json` file
116
117
 
117
118
  ## 📝 License
118
119
 
@@ -1,65 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class StimulusReflex::Channel < StimulusReflex.configuration.parent_channel.constantize
4
+ attr_reader :reflex_data
5
+
4
6
  def stream_name
5
- ids = connection.identifiers.map { |identifier| send(identifier).try(:id) || send(identifier) }
6
- [
7
- params[:channel],
8
- ids.select(&:present?).join(";")
9
- ].select(&:present?).join(":")
7
+ [params[:channel], connection.connection_identifier].join(":")
10
8
  end
11
9
 
12
10
  def subscribed
13
11
  super
14
- fix_environment!
15
12
  stream_from stream_name
16
13
  end
17
14
 
18
15
  def receive(data)
19
- url = data["url"].to_s
20
- selectors = (data["selectors"] || []).select(&:present?)
21
- selectors = data["selectors"] = ["body"] if selectors.blank?
22
- target = data["target"].to_s
23
- reflex_name, method_name = target.split("#")
24
- reflex_name = reflex_name.camelize
25
- reflex_name = reflex_name.end_with?("Reflex") ? reflex_name : "#{reflex_name}Reflex"
26
- arguments = (data["args"] || []).map { |arg| object_with_indifferent_access arg }
27
- element = StimulusReflex::Element.new(data)
28
- permanent_attribute_name = data["permanentAttributeName"]
29
- form_data = Rack::Utils.parse_nested_query(data["formData"])
30
- params = form_data.deep_merge(data["params"] || {})
31
-
16
+ @reflex_data = StimulusReflex::ReflexData.new(data)
32
17
  begin
33
18
  begin
34
- reflex_class = reflex_name.constantize.tap { |klass| raise ArgumentError.new("#{reflex_name} is not a StimulusReflex::Reflex") unless is_reflex?(klass) }
35
- reflex = reflex_class.new(self,
36
- url: url,
37
- element: element,
38
- selectors: selectors,
39
- method_name: method_name,
40
- params: params,
41
- client_attributes: {
42
- reflex_id: data["reflexId"],
43
- xpath_controller: data["xpathController"],
44
- xpath_element: data["xpathElement"],
45
- reflex_controller: data["reflexController"],
46
- permanent_attribute_name: permanent_attribute_name
47
- })
48
- delegate_call_to_reflex reflex, method_name, arguments
49
- rescue => invoke_error
50
- message = exception_message_with_backtrace(invoke_error)
51
- body = "Reflex #{target} failed: #{message} [#{url}]"
19
+ reflex = StimulusReflex::ReflexFactory.create_reflex_from_data(self, @reflex_data)
20
+ delegate_call_to_reflex reflex
21
+ rescue => exception
22
+ error = exception_with_backtrace(exception)
23
+ error_message = "\e[31mReflex #{reflex_data.target} failed: #{error[:message]} [#{reflex_data.url}]\e[0m\n#{error[:stack]}"
52
24
 
53
25
  if reflex
54
- reflex.rescue_with_handler(invoke_error)
55
- reflex.broadcast_message subject: "error", body: body, data: data, error: invoke_error
26
+ reflex.rescue_with_handler(exception)
27
+ reflex.logger&.error error_message
28
+ reflex.error data: data, body: "#{exception} #{exception.backtrace.first.split(":in ")[0] if Rails.env.development?}"
56
29
  else
57
- puts "\e[31m#{body}\e[0m"
30
+ reflex.logger&.error error_message
58
31
 
59
32
  if body.to_s.include? "No route matches"
60
33
  initializer_path = Rails.root.join("config", "initializers", "stimulus_reflex.rb")
61
34
 
62
- puts <<~NOTE
35
+ reflex.logger&.warn <<~NOTE
63
36
  \e[33mNOTE: StimulusReflex failed to locate a matching route and could not re-render the page.
64
37
 
65
38
  If your app uses Rack middleware to rewrite part of the request path, you must enable those middleware modules in StimulusReflex.
@@ -81,67 +54,63 @@ class StimulusReflex::Channel < StimulusReflex.configuration.parent_channel.cons
81
54
  end
82
55
 
83
56
  if reflex.halted?
84
- reflex.broadcast_message subject: "halted", data: data
57
+ reflex.halted data: data
85
58
  else
86
59
  begin
87
- reflex.broadcast(selectors, data)
88
- rescue => render_error
89
- reflex.rescue_with_handler(render_error)
90
- message = exception_message_with_backtrace(render_error)
91
- body = "Reflex failed to re-render: #{message} [#{url}]"
92
- reflex.broadcast_message subject: "error", body: body, data: data, error: render_error
93
- puts "\e[31m#{body}\e[0m"
60
+ reflex.broadcast(reflex_data.selectors, data)
61
+ rescue => exception
62
+ reflex.rescue_with_handler(exception)
63
+ error = exception_with_backtrace(exception)
64
+ reflex.error data: data, body: "#{exception} #{exception.backtrace.first.split(":in ")[0] if Rails.env.development?}"
65
+ reflex.logger&.error "\e[31mReflex failed to re-render: #{error[:message]} [#{reflex_data.url}]\e[0m\n#{error[:stack]}"
94
66
  end
95
67
  end
96
68
  ensure
97
69
  if reflex
98
70
  commit_session(reflex)
99
- reflex.logger.print
71
+ report_failed_basic_auth(reflex) if reflex.controller?
72
+ reflex.logger&.log_all_operations
100
73
  end
101
74
  end
102
75
  end
103
76
 
104
77
  private
105
78
 
106
- def object_with_indifferent_access(object)
107
- return object.with_indifferent_access if object.respond_to?(:with_indifferent_access)
108
- object.map! { |obj| object_with_indifferent_access obj } if object.is_a?(Array)
109
- object
110
- end
111
-
112
- def is_reflex?(reflex_class)
113
- reflex_class.ancestors.include? StimulusReflex::Reflex
114
- end
115
-
116
- def delegate_call_to_reflex(reflex, method_name, arguments = [])
79
+ def delegate_call_to_reflex(reflex)
80
+ method_name = reflex_data.method_name
81
+ arguments = reflex_data.arguments
117
82
  method = reflex.method(method_name)
118
- required_params = method.parameters.select { |(kind, _)| kind == :req }
119
- optional_params = method.parameters.select { |(kind, _)| kind == :opt }
120
83
 
121
- if arguments.size == 0 && required_params.size == 0
84
+ policy = StimulusReflex::ReflexMethodInvocationPolicy.new(method, arguments)
85
+
86
+ if policy.no_arguments?
122
87
  reflex.process(method_name)
123
- elsif arguments.size >= required_params.size && arguments.size <= required_params.size + optional_params.size
88
+ elsif policy.arguments?
124
89
  reflex.process(method_name, *arguments)
125
90
  else
126
- raise ArgumentError.new("wrong number of arguments (given #{arguments.inspect}, expected #{required_params.inspect}, optional #{optional_params.inspect})")
91
+ raise ArgumentError.new("wrong number of arguments (given #{arguments.inspect}, expected #{policy.required_params.inspect}, optional #{policy.optional_params.inspect})")
127
92
  end
128
93
  end
129
94
 
130
95
  def commit_session(reflex)
131
96
  store = reflex.request.session.instance_variable_get("@by")
132
97
  store.commit_session reflex.request, reflex.controller.response
133
- rescue => e
134
- message = "Failed to commit session! #{exception_message_with_backtrace(e)}"
135
- puts "\e[31m#{message}\e[0m"
98
+ rescue => exception
99
+ error = exception_with_backtrace(exception)
100
+ reflex.logger&.error "\e[31mFailed to commit session! #{error[:message]}\e[0m\n#{error[:backtrace]}"
136
101
  end
137
102
 
138
- def exception_message_with_backtrace(exception)
139
- "#{exception}\n#{exception.backtrace.first}"
103
+ def report_failed_basic_auth(reflex)
104
+ if reflex.controller.response.status == 401
105
+ reflex.logger&.error "\e[31mReflex failed to process controller action \"#{reflex.controller.class}##{reflex.controller.action_name}\" due to HTTP basic auth. Consider adding \"unless: -> { @stimulus_reflex }\" to the before_action or method responible for authentication.\e[0m"
106
+ end
140
107
  end
141
108
 
142
- def fix_environment!
143
- ([ApplicationController] + ApplicationController.descendants).each do |controller|
144
- controller.renderer.instance_variable_set(:@env, connection.env.merge(controller.renderer.instance_variable_get(:@env)))
145
- end
109
+ def exception_with_backtrace(exception)
110
+ {
111
+ message: exception.to_s,
112
+ backtrace: exception.backtrace.first.split(":in ")[0],
113
+ stack: exception.backtrace.join("\n")
114
+ }
146
115
  end
147
116
  end
data/lib/generators/USAGE CHANGED
@@ -11,4 +11,4 @@ Example:
11
11
  app/reflexes/application_reflex.rb
12
12
  app/reflexes/user_reflex.rb
13
13
 
14
- Don't forget to setup the application: https://docs.stimulusreflex.com/setup
14
+ Don't forget to setup the application: https://docs.stimulusreflex.com/hello-world/setup
@@ -3,11 +3,11 @@
3
3
  require "rails/generators"
4
4
 
5
5
  module StimulusReflex
6
- class ConfigGenerator < Rails::Generators::Base
7
- desc "Creates an StimulusReflex configuration file in config/initializers"
6
+ class InitializerGenerator < Rails::Generators::Base
7
+ desc "Creates a StimulusReflex initializer in config/initializers"
8
8
  source_root File.expand_path("templates", __dir__)
9
9
 
10
- def copy_config_file
10
+ def copy_initializer_file
11
11
  copy_file "config/initializers/stimulus_reflex.rb"
12
12
  end
13
13
  end
@@ -7,20 +7,21 @@ class StimulusReflexGenerator < Rails::Generators::NamedBase
7
7
 
8
8
  argument :name, type: :string, required: true, banner: "NAME"
9
9
  argument :actions, type: :array, default: [], banner: "action action"
10
+ class_options skip_stimulus: false, skip_app_reflex: false, skip_reflex: false, skip_app_controller: false
10
11
 
11
12
  def execute
12
13
  actions.map!(&:underscore)
13
14
 
14
15
  copy_application_files if behavior == :invoke
15
16
 
16
- template "app/reflexes/%file_name%_reflex.rb"
17
- template "app/javascript/controllers/%file_name%_controller.js"
17
+ template "app/reflexes/%file_name%_reflex.rb" unless options[:skip_reflex]
18
+ template "app/javascript/controllers/%file_name%_controller.js" unless options[:skip_stimulus]
18
19
  end
19
20
 
20
21
  private
21
22
 
22
23
  def copy_application_files
23
- template "app/reflexes/application_reflex.rb"
24
- template "app/javascript/controllers/application_controller.js"
24
+ template "app/reflexes/application_reflex.rb" unless options[:skip_app_reflex]
25
+ template "app/javascript/controllers/application_controller.js" unless options[:skip_app_controller]
25
26
  end
26
27
  end
@@ -17,12 +17,13 @@ class <%= class_name %>Reflex < ApplicationReflex
17
17
  # - unsigned - use an unsigned Global ID to map dataset attribute to a model eg. element.unsigned[:foo]
18
18
  # - cable_ready - a special cable_ready that can broadcast to the current visitor (no brackets needed)
19
19
  # - reflex_id - a UUIDv4 that uniquely identies each Reflex
20
+ # - tab_id - a UUIDv4 that uniquely identifies the browser tab
20
21
  #
21
22
  # Example:
22
23
  #
23
24
  # before_reflex do
24
25
  # # throw :abort # this will prevent the Reflex from continuing
25
- # # learn more about callbacks at https://docs.stimulusreflex.com/lifecycle
26
+ # # learn more about callbacks at https://docs.stimulusreflex.com/rtfm/lifecycle
26
27
  # end
27
28
  #
28
29
  # def example(argument=true)
@@ -30,7 +31,7 @@ class <%= class_name %>Reflex < ApplicationReflex
30
31
  # # Any declared instance variables will be made available to the Rails controller and view.
31
32
  # end
32
33
  #
33
- # Learn more at: https://docs.stimulusreflex.com/reflexes#reflex-classes
34
+ # Learn more at: https://docs.stimulusreflex.com/rtfm/reflex-classes
34
35
 
35
36
  <% actions.each do |action| -%>
36
37
  def <%= action %>
@@ -1,12 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ApplicationReflex < StimulusReflex::Reflex
4
- # Put application-wide Reflex behavior and callbacks in this file.
4
+ # Put application-wide Reflex behavior and callbacks in this file.
5
5
  #
6
- # Example:
6
+ # Learn more at: https://docs.stimulusreflex.com/rtfm/reflex-classes
7
7
  #
8
- # # If your ActionCable connection is: `identified_by :current_user`
8
+ # If your ActionCable connection is: `identified_by :current_user`
9
9
  # delegate :current_user, to: :connection
10
10
  #
11
- # Learn more at: https://docs.stimulusreflex.com/reflexes#reflex-classes
11
+ # If you need to localize your Reflexes, you can set the I18n locale here:
12
+ #
13
+ # before_reflex do
14
+ # I18n.locale = :fr
15
+ # end
16
+ #
17
+ # For code examples, considerations and caveats, see:
18
+ # https://docs.stimulusreflex.com/rtfm/patterns#internationalization
12
19
  end