stimulus_reflex 3.4.1 → 3.5.0.pre3

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.

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