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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +664 -495
- data/Gemfile.lock +99 -95
- data/LATEST +1 -0
- data/README.md +17 -16
- data/app/channels/stimulus_reflex/channel.rb +44 -75
- data/lib/generators/USAGE +1 -1
- data/lib/generators/stimulus_reflex/{config_generator.rb → initializer_generator.rb} +3 -3
- data/lib/generators/stimulus_reflex/stimulus_reflex_generator.rb +5 -4
- data/lib/generators/stimulus_reflex/templates/app/reflexes/%file_name%_reflex.rb.tt +3 -2
- data/lib/generators/stimulus_reflex/templates/app/reflexes/application_reflex.rb.tt +11 -4
- data/lib/generators/stimulus_reflex/templates/config/initializers/stimulus_reflex.rb +21 -1
- data/lib/stimulus_reflex/broadcasters/broadcaster.rb +22 -18
- data/lib/stimulus_reflex/broadcasters/nothing_broadcaster.rb +6 -1
- data/lib/stimulus_reflex/broadcasters/page_broadcaster.rb +3 -5
- data/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb +22 -16
- data/lib/stimulus_reflex/broadcasters/update.rb +23 -0
- data/lib/stimulus_reflex/cable_ready_channels.rb +10 -2
- data/lib/stimulus_reflex/callbacks.rb +55 -5
- data/lib/stimulus_reflex/concern_enhancer.rb +37 -0
- data/lib/stimulus_reflex/configuration.rb +4 -1
- data/lib/stimulus_reflex/dataset.rb +34 -0
- data/lib/stimulus_reflex/element.rb +20 -13
- data/lib/stimulus_reflex/policies/reflex_invocation_policy.rb +28 -0
- data/lib/stimulus_reflex/reflex.rb +41 -21
- data/lib/stimulus_reflex/reflex_data.rb +79 -0
- data/lib/stimulus_reflex/reflex_factory.rb +31 -0
- data/lib/stimulus_reflex/request_parameters.rb +19 -0
- data/lib/stimulus_reflex/utils/attribute_builder.rb +17 -0
- data/lib/stimulus_reflex/{logger.rb → utils/logger.rb} +6 -4
- data/lib/stimulus_reflex/utils/sanity_checker.rb +210 -0
- data/lib/stimulus_reflex/version.rb +1 -1
- data/lib/stimulus_reflex.rb +10 -2
- data/lib/tasks/stimulus_reflex/install.rake +54 -15
- data/test/broadcasters/broadcaster_test.rb +0 -1
- data/test/broadcasters/broadcaster_test_case.rb +25 -1
- data/test/broadcasters/nothing_broadcaster_test.rb +14 -20
- data/test/broadcasters/page_broadcaster_test.rb +31 -29
- data/test/broadcasters/selector_broadcaster_test.rb +165 -55
- data/test/callbacks_test.rb +652 -0
- data/test/concern_enhancer_test.rb +54 -0
- data/test/element_test.rb +254 -0
- data/test/generators/stimulus_reflex_generator_test.rb +8 -0
- data/test/reflex_test.rb +12 -1
- data/test/test_helper.rb +25 -1
- data/test/tmp/app/reflexes/application_reflex.rb +10 -3
- data/test/tmp/app/reflexes/{user_reflex.rb → demo_reflex.rb} +4 -12
- metadata +65 -36
- data/lib/stimulus_reflex/sanity_checker.rb +0 -154
- data/package.json +0 -57
- data/stimulus_reflex.gemspec +0 -42
- data/tags +0 -156
- 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.
|
5
|
-
cable_ready (
|
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.
|
66
|
-
|
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 (
|
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.
|
79
|
+
concurrent-ruby (1.1.9)
|
80
80
|
crass (1.0.6)
|
81
81
|
erubi (1.10.0)
|
82
|
-
globalid (0.
|
83
|
-
activesupport (>=
|
84
|
-
i18n (1.8.
|
82
|
+
globalid (0.5.2)
|
83
|
+
activesupport (>= 5.0)
|
84
|
+
i18n (1.8.10)
|
85
85
|
concurrent-ruby (~> 1.0)
|
86
|
-
loofah (2.
|
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.
|
92
|
-
mimemagic (~> 0.3.2)
|
91
|
+
marcel (1.0.2)
|
93
92
|
method_source (0.9.2)
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
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.
|
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.
|
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.
|
139
|
+
rake (>= 0.13)
|
139
140
|
thor (~> 1.0)
|
140
141
|
rainbow (3.0.0)
|
141
|
-
rake (13.0.
|
142
|
-
redis (4.
|
143
|
-
regexp_parser (2.
|
144
|
-
rexml (3.2.
|
145
|
-
rubocop (1.
|
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 (>=
|
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.
|
152
|
+
rubocop-ast (>= 1.7.0, < 2.0)
|
152
153
|
ruby-progressbar (~> 1.7)
|
153
|
-
unicode-display_width (>= 1.4.0, <
|
154
|
-
rubocop-ast (1.
|
155
|
-
parser (>=
|
156
|
-
rubocop-performance (1.
|
157
|
-
rubocop (>=
|
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 (
|
168
|
-
rubocop (= 1.
|
169
|
-
rubocop-performance (= 1.
|
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 (
|
177
|
-
websocket-driver (0.7.
|
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
|
-
|
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.
|
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/
|
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-
|
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&utm_medium=referral&utm_content=hopsoft/stimulus_reflex&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/
|
34
|
-
<img src="https://github.com/
|
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/
|
37
|
-
<img src="https://github.com/
|
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/
|
40
|
-
<img src="https://github.com/
|
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
|
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
|

|
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/
|
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
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
35
|
-
reflex
|
36
|
-
|
37
|
-
|
38
|
-
|
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(
|
55
|
-
reflex.
|
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
|
-
|
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
|
-
|
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.
|
57
|
+
reflex.halted data: data
|
85
58
|
else
|
86
59
|
begin
|
87
|
-
reflex.broadcast(selectors, data)
|
88
|
-
rescue =>
|
89
|
-
reflex.rescue_with_handler(
|
90
|
-
|
91
|
-
|
92
|
-
reflex.
|
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.
|
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
|
107
|
-
|
108
|
-
|
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
|
-
|
84
|
+
policy = StimulusReflex::ReflexMethodInvocationPolicy.new(method, arguments)
|
85
|
+
|
86
|
+
if policy.no_arguments?
|
122
87
|
reflex.process(method_name)
|
123
|
-
elsif
|
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 =>
|
134
|
-
|
135
|
-
|
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
|
139
|
-
|
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
|
143
|
-
|
144
|
-
|
145
|
-
|
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
@@ -3,11 +3,11 @@
|
|
3
3
|
require "rails/generators"
|
4
4
|
|
5
5
|
module StimulusReflex
|
6
|
-
class
|
7
|
-
desc "Creates
|
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
|
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/
|
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
|
-
#
|
6
|
+
# Learn more at: https://docs.stimulusreflex.com/rtfm/reflex-classes
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# If your ActionCable connection is: `identified_by :current_user`
|
9
9
|
# delegate :current_user, to: :connection
|
10
10
|
#
|
11
|
-
#
|
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
|