stimulus_reflex 1.0.1 → 1.0.2
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +97 -18
- data/README.md +47 -11
- data/README.md.orig +159 -0
- data/bin/console +2 -9
- data/bin/standardize +1 -0
- data/lib/stimulus_reflex.rb +9 -3
- data/lib/stimulus_reflex/channel.rb +48 -66
- data/lib/stimulus_reflex/version.rb +1 -1
- metadata +34 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6798571d8f8229083855114f5f499414f308a47e03c438f1b74b5eb534acd78f
|
4
|
+
data.tar.gz: 62e2d714b2ae14c16bf4435665d339717d9fa99330d3eb604fa6720c15f64f80
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d22087e7519727c787770fb971aa510d2480a5b45e00efa78eb708adcc69d89cf085b3fad6544c9a46bb183240ea452ded9ce665495ca7f5d47bcc021c8a7e0
|
7
|
+
data.tar.gz: 3b0aaf7d1c98ba7281f24f2d96fb1d043e297847837c2ad38028bac114c7ed7fe80c929e0c58491b646533f8d4958921e8e1483d5bc320c4d04d3034ec2e53aa
|
data/Gemfile.lock
CHANGED
@@ -1,67 +1,135 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
stimulus_reflex (1.0.
|
5
|
-
|
6
|
-
actionpack (>= 5.2.3)
|
7
|
-
cable_ready (>= 4.0.1)
|
4
|
+
stimulus_reflex (1.0.2)
|
5
|
+
cable_ready (>= 4.0.3)
|
8
6
|
nokogiri
|
9
7
|
rack
|
8
|
+
rails (>= 5.2)
|
10
9
|
|
11
10
|
GEM
|
12
11
|
remote: https://rubygems.org/
|
13
12
|
specs:
|
14
|
-
actioncable (
|
15
|
-
actionpack (=
|
13
|
+
actioncable (6.0.0)
|
14
|
+
actionpack (= 6.0.0)
|
16
15
|
nio4r (~> 2.0)
|
17
16
|
websocket-driver (>= 0.6.1)
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
actionmailbox (6.0.0)
|
18
|
+
actionpack (= 6.0.0)
|
19
|
+
activejob (= 6.0.0)
|
20
|
+
activerecord (= 6.0.0)
|
21
|
+
activestorage (= 6.0.0)
|
22
|
+
activesupport (= 6.0.0)
|
23
|
+
mail (>= 2.7.1)
|
24
|
+
actionmailer (6.0.0)
|
25
|
+
actionpack (= 6.0.0)
|
26
|
+
actionview (= 6.0.0)
|
27
|
+
activejob (= 6.0.0)
|
28
|
+
mail (~> 2.5, >= 2.5.4)
|
29
|
+
rails-dom-testing (~> 2.0)
|
30
|
+
actionpack (6.0.0)
|
31
|
+
actionview (= 6.0.0)
|
32
|
+
activesupport (= 6.0.0)
|
21
33
|
rack (~> 2.0)
|
22
34
|
rack-test (>= 0.6.3)
|
23
35
|
rails-dom-testing (~> 2.0)
|
24
|
-
rails-html-sanitizer (~> 1.0, >= 1.0
|
25
|
-
|
26
|
-
|
36
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
37
|
+
actiontext (6.0.0)
|
38
|
+
actionpack (= 6.0.0)
|
39
|
+
activerecord (= 6.0.0)
|
40
|
+
activestorage (= 6.0.0)
|
41
|
+
activesupport (= 6.0.0)
|
42
|
+
nokogiri (>= 1.8.5)
|
43
|
+
actionview (6.0.0)
|
44
|
+
activesupport (= 6.0.0)
|
27
45
|
builder (~> 3.1)
|
28
46
|
erubi (~> 1.4)
|
29
47
|
rails-dom-testing (~> 2.0)
|
30
|
-
rails-html-sanitizer (~> 1.
|
31
|
-
|
48
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
49
|
+
activejob (6.0.0)
|
50
|
+
activesupport (= 6.0.0)
|
51
|
+
globalid (>= 0.3.6)
|
52
|
+
activemodel (6.0.0)
|
53
|
+
activesupport (= 6.0.0)
|
54
|
+
activerecord (6.0.0)
|
55
|
+
activemodel (= 6.0.0)
|
56
|
+
activesupport (= 6.0.0)
|
57
|
+
activestorage (6.0.0)
|
58
|
+
actionpack (= 6.0.0)
|
59
|
+
activejob (= 6.0.0)
|
60
|
+
activerecord (= 6.0.0)
|
61
|
+
marcel (~> 0.3.1)
|
62
|
+
activesupport (6.0.0)
|
32
63
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
33
64
|
i18n (>= 0.7, < 2)
|
34
65
|
minitest (~> 5.1)
|
35
66
|
tzinfo (~> 1.1)
|
67
|
+
zeitwerk (~> 2.1, >= 2.1.8)
|
36
68
|
ast (2.4.0)
|
37
69
|
builder (3.2.3)
|
38
|
-
cable_ready (4.0.
|
39
|
-
|
70
|
+
cable_ready (4.0.3)
|
71
|
+
rails (>= 5.2)
|
72
|
+
coderay (1.1.2)
|
40
73
|
concurrent-ruby (1.1.5)
|
41
74
|
crass (1.0.4)
|
42
75
|
erubi (1.8.0)
|
76
|
+
globalid (0.4.2)
|
77
|
+
activesupport (>= 4.2.0)
|
43
78
|
i18n (1.6.0)
|
44
79
|
concurrent-ruby (~> 1.0)
|
45
80
|
jaro_winkler (1.5.3)
|
46
81
|
loofah (2.2.3)
|
47
82
|
crass (~> 1.0.2)
|
48
83
|
nokogiri (>= 1.5.9)
|
84
|
+
mail (2.7.1)
|
85
|
+
mini_mime (>= 0.1.1)
|
86
|
+
marcel (0.3.3)
|
87
|
+
mimemagic (~> 0.3.2)
|
88
|
+
method_source (0.9.2)
|
89
|
+
mimemagic (0.3.3)
|
90
|
+
mini_mime (1.0.2)
|
49
91
|
mini_portile2 (2.4.0)
|
50
92
|
minitest (5.11.3)
|
51
93
|
nio4r (2.4.0)
|
52
|
-
nokogiri (1.10.
|
94
|
+
nokogiri (1.10.4)
|
53
95
|
mini_portile2 (~> 2.4.0)
|
54
96
|
parallel (1.17.0)
|
55
97
|
parser (2.6.3.0)
|
56
98
|
ast (~> 2.4.0)
|
99
|
+
pry (0.12.2)
|
100
|
+
coderay (~> 1.1.0)
|
101
|
+
method_source (~> 0.9.0)
|
102
|
+
pry-nav (0.3.0)
|
103
|
+
pry (>= 0.9.10, < 0.13.0)
|
57
104
|
rack (2.0.7)
|
58
105
|
rack-test (1.1.0)
|
59
106
|
rack (>= 1.0, < 3)
|
107
|
+
rails (6.0.0)
|
108
|
+
actioncable (= 6.0.0)
|
109
|
+
actionmailbox (= 6.0.0)
|
110
|
+
actionmailer (= 6.0.0)
|
111
|
+
actionpack (= 6.0.0)
|
112
|
+
actiontext (= 6.0.0)
|
113
|
+
actionview (= 6.0.0)
|
114
|
+
activejob (= 6.0.0)
|
115
|
+
activemodel (= 6.0.0)
|
116
|
+
activerecord (= 6.0.0)
|
117
|
+
activestorage (= 6.0.0)
|
118
|
+
activesupport (= 6.0.0)
|
119
|
+
bundler (>= 1.3.0)
|
120
|
+
railties (= 6.0.0)
|
121
|
+
sprockets-rails (>= 2.0.0)
|
60
122
|
rails-dom-testing (2.0.3)
|
61
123
|
activesupport (>= 4.2.0)
|
62
124
|
nokogiri (>= 1.6)
|
63
125
|
rails-html-sanitizer (1.2.0)
|
64
126
|
loofah (~> 2.2, >= 2.2.2)
|
127
|
+
railties (6.0.0)
|
128
|
+
actionpack (= 6.0.0)
|
129
|
+
activesupport (= 6.0.0)
|
130
|
+
method_source
|
131
|
+
rake (>= 0.8.7)
|
132
|
+
thor (>= 0.20.3, < 2.0)
|
65
133
|
rainbow (3.0.0)
|
66
134
|
rake (12.3.3)
|
67
135
|
rubocop (0.72.0)
|
@@ -74,11 +142,19 @@ GEM
|
|
74
142
|
rubocop-performance (1.4.1)
|
75
143
|
rubocop (>= 0.71.0)
|
76
144
|
ruby-progressbar (1.10.1)
|
145
|
+
sprockets (3.7.2)
|
146
|
+
concurrent-ruby (~> 1.0)
|
147
|
+
rack (> 1, < 3)
|
148
|
+
sprockets-rails (3.2.1)
|
149
|
+
actionpack (>= 4.0)
|
150
|
+
activesupport (>= 4.0)
|
151
|
+
sprockets (>= 3.0.0)
|
77
152
|
standard (0.1.2)
|
78
153
|
rubocop (~> 0.72.0)
|
79
154
|
rubocop-performance (~> 1.4.0)
|
80
155
|
standardrb (1.0.0)
|
81
156
|
standard
|
157
|
+
thor (0.20.3)
|
82
158
|
thread_safe (0.3.6)
|
83
159
|
tzinfo (1.2.5)
|
84
160
|
thread_safe (~> 0.1)
|
@@ -86,15 +162,18 @@ GEM
|
|
86
162
|
websocket-driver (0.7.1)
|
87
163
|
websocket-extensions (>= 0.1.0)
|
88
164
|
websocket-extensions (0.1.4)
|
165
|
+
zeitwerk (2.1.9)
|
89
166
|
|
90
167
|
PLATFORMS
|
91
168
|
ruby
|
92
169
|
|
93
170
|
DEPENDENCIES
|
94
171
|
bundler (~> 2.0)
|
172
|
+
pry
|
173
|
+
pry-nav
|
95
174
|
rake
|
96
175
|
standardrb
|
97
176
|
stimulus_reflex!
|
98
177
|
|
99
178
|
BUNDLED WITH
|
100
|
-
2.0.
|
179
|
+
2.0.2
|
data/README.md
CHANGED
@@ -1,25 +1,37 @@
|
|
1
|
-
[![Lines of Code](http://img.shields.io/badge/lines_of_code-
|
1
|
+
[![Lines of Code](http://img.shields.io/badge/lines_of_code-159-brightgreen.svg?style=flat)](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)
|
2
2
|
[![Maintainability](https://api.codeclimate.com/v1/badges/2b24fdbd1ae37a24bedb/maintainability)](https://codeclimate.com/github/hopsoft/stimulus_reflex/maintainability)
|
3
3
|
|
4
4
|
# StimulusReflex
|
5
5
|
|
6
|
-
###
|
6
|
+
### Build reactive [Single Page Applications (SPAs)](https://en.wikipedia.org/wiki/Single-page_application) with [Rails](https://rubyonrails.org) and [Stimulus](https://stimulusjs.org)
|
7
7
|
|
8
|
-
|
8
|
+
This project supports building [reactive applications](https://en.wikipedia.org/wiki/Reactive_programming)
|
9
|
+
with the Rails tooling you already know and love.
|
10
|
+
It's designed to work perfectly with [server rendered HTML](https://guides.rubyonrails.org/action_view_overview.html),
|
11
|
+
[Russian doll caching](https://edgeguides.rubyonrails.org/caching_with_rails.html#russian-doll-caching),
|
12
|
+
[Stimulus](https://stimulusjs.org), [Turbolinks](https://www.youtube.com/watch?v=SWEts0rlezA), etc...
|
9
13
|
|
10
|
-
This project aims to support the building of [Single Page Applications (SPAs)](https://en.wikipedia.org/wiki/Single-page_application)
|
11
|
-
with standard Rails tooling. Think server rendered HTML, Stimulus, Turbolinks, etc...
|
12
14
|
|
13
|
-
|
15
|
+
__No need for a complex front-end framework. No need to grow your team or duplicate your efforts.__
|
16
|
+
|
17
|
+
---
|
18
|
+
|
19
|
+
> The lifecycle of a "modern" SPA app is so convoluted, it requires a team to build and support.
|
20
|
+
> The wire size and computation demands of these heavy client sites frequently run slower than the server-rendered pages that they replaced.
|
21
|
+
> With Stimulus Reflex, a Rails developer can build Single Page Applications without the need for client rendering or heavy JS frameworks.
|
22
|
+
|
23
|
+
---
|
24
|
+
|
25
|
+
_Inspired by [Phoenix LiveView](https://youtu.be/Z2DU0qLfPIY?t=670)._ 🙌
|
14
26
|
|
15
27
|
## How it Works
|
16
28
|
|
17
|
-
1.
|
29
|
+
1. Render a standard Rails view template
|
30
|
+
1. Use [Stimulus](https://stimulusjs.org) and [ActionCable](https://edgeguides.rubyonrails.org/action_cable_overview.html) to invoke a method on the server
|
18
31
|
1. Watch the page automatically render updates via fast [DOM diffing](https://github.com/patrick-steele-idem/morphdom)
|
19
32
|
1. That's it...
|
20
33
|
|
21
34
|
__Yes, it really is that simple.__
|
22
|
-
Just create a server rendered HTML page and send RPC calls to the server via web socket.
|
23
35
|
There are no hidden gotchas.
|
24
36
|
|
25
37
|
![How it Works](https://raw.githubusercontent.com/hopsoft/stimulus_reflex/master/docs/diagram.png)
|
@@ -64,7 +76,7 @@ export default class extends Controller {
|
|
64
76
|
}
|
65
77
|
|
66
78
|
increment() {
|
67
|
-
// trigger a server
|
79
|
+
// trigger a server-side reflex and a client-side page update
|
68
80
|
this.stimulate('ExampleReflex#increment', 1);
|
69
81
|
}
|
70
82
|
}
|
@@ -75,7 +87,7 @@ export default class extends Controller {
|
|
75
87
|
```ruby
|
76
88
|
class ExampleReflex < StimulusReflex::Reflex
|
77
89
|
def increment(step = 1)
|
78
|
-
@count = @count.to_i
|
90
|
+
@count = @count.to_i + step
|
79
91
|
end
|
80
92
|
end
|
81
93
|
```
|
@@ -93,12 +105,22 @@ The following happens after the `StimulusReflex::Reflex` method call finishes.
|
|
93
105
|
StimulusReflex will use the ActionCable defaults of `window.App` and `App.cable` if they exist.
|
94
106
|
If these defaults do not exist, StimulusReflex will establish a new socket connection.
|
95
107
|
|
108
|
+
### Performance
|
109
|
+
|
110
|
+
ActionCable emits verbose log messages. Disabling ActionCable logs may improve performance.
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
# config/application.rb
|
114
|
+
|
115
|
+
ActionCable.server.config.logger = Logger.new(nil)
|
116
|
+
```
|
117
|
+
|
96
118
|
### ActionCable Rooms
|
97
119
|
|
98
120
|
You may find the need to restrict notifications to a specific room.
|
99
121
|
This can be accomplished by setting the `data-room` attribute on the StimulusController element.
|
100
122
|
|
101
|
-
```
|
123
|
+
```erb
|
102
124
|
<a href="#" data-controller="example" data-action="click->example#increment" data-room="12345">
|
103
125
|
```
|
104
126
|
|
@@ -118,3 +140,17 @@ export default class extends Controller {
|
|
118
140
|
```
|
119
141
|
|
120
142
|
The default value is `25`.
|
143
|
+
|
144
|
+
## Demo Applications
|
145
|
+
|
146
|
+
Building apps with StimulusReflex should evoke your memories of the original [Rails demo video](https://www.youtube.com/watch?v=Gzj723LkRJY).
|
147
|
+
|
148
|
+
> Look at all the things I'm **not** doing. -DHH
|
149
|
+
|
150
|
+
- [TodoMVC](https://github.com/hopsoft/stimulus_reflex_todomvc)
|
151
|
+
|
152
|
+
## Contributing
|
153
|
+
|
154
|
+
This project uses [Standard](https://github.com/testdouble/standard)
|
155
|
+
and [Prettier](https://github.com/prettier/prettier) to minimize bike shedding related to code formatting.
|
156
|
+
Please run `./bin/standardize` prior submitting pull requests.
|
data/README.md.orig
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
[![Lines of Code](http://img.shields.io/badge/lines_of_code-159-brightgreen.svg?style=flat)](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)
|
2
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/2b24fdbd1ae37a24bedb/maintainability)](https://codeclimate.com/github/hopsoft/stimulus_reflex/maintainability)
|
3
|
+
|
4
|
+
# StimulusReflex
|
5
|
+
|
6
|
+
### Build reactive [Single Page Applications (SPAs)](https://en.wikipedia.org/wiki/Single-page_application) with [Rails](https://rubyonrails.org) and [Stimulus](https://stimulusjs.org)
|
7
|
+
|
8
|
+
This project supports building [reactive applications](https://en.wikipedia.org/wiki/Reactive_programming)
|
9
|
+
with the Rails tooling you already know and love.
|
10
|
+
It's designed to work perfectly with [server rendered HTML](https://guides.rubyonrails.org/action_view_overview.html),
|
11
|
+
[Russian doll caching](https://edgeguides.rubyonrails.org/caching_with_rails.html#russian-doll-caching),
|
12
|
+
[Stimulus](https://stimulusjs.org), [Turbolinks](https://www.youtube.com/watch?v=SWEts0rlezA), etc...
|
13
|
+
|
14
|
+
|
15
|
+
__No need for a complex front-end framework. No need to grow your team or duplicate your efforts.__
|
16
|
+
|
17
|
+
---
|
18
|
+
|
19
|
+
> The lifecycle of a "modern" SPA app is so convoluted, it requires a team to build and support.
|
20
|
+
> The wire size and computation demands of these heavy client sites frequently run slower than the server-rendered pages that they replaced.
|
21
|
+
> With Stimulus Reflex, a Rails developer can build Single Page Applications without the need for client rendering or heavy JS frameworks.
|
22
|
+
|
23
|
+
---
|
24
|
+
|
25
|
+
_Inspired by [Phoenix LiveView](https://youtu.be/Z2DU0qLfPIY?t=670)._ 🙌
|
26
|
+
|
27
|
+
## How it Works
|
28
|
+
|
29
|
+
1. Render a standard Rails view template
|
30
|
+
1. Use [Stimulus](https://stimulusjs.org) and [ActionCable](https://edgeguides.rubyonrails.org/action_cable_overview.html) to invoke a method on the server
|
31
|
+
1. Watch the page automatically render updates via fast [DOM diffing](https://github.com/patrick-steele-idem/morphdom)
|
32
|
+
1. That's it...
|
33
|
+
|
34
|
+
__Yes, it really is that simple.__
|
35
|
+
There are no hidden gotchas.
|
36
|
+
|
37
|
+
![How it Works](https://raw.githubusercontent.com/hopsoft/stimulus_reflex/master/docs/diagram.png)
|
38
|
+
|
39
|
+
## Setup
|
40
|
+
|
41
|
+
### JavaScript
|
42
|
+
|
43
|
+
```
|
44
|
+
yarn add stimulus_reflex
|
45
|
+
```
|
46
|
+
|
47
|
+
### Gemfile
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
gem "stimulus_reflex"
|
51
|
+
```
|
52
|
+
|
53
|
+
## Basic Usage
|
54
|
+
|
55
|
+
### app/views/pages/example.html.erb
|
56
|
+
|
57
|
+
```erb
|
58
|
+
<head></head>
|
59
|
+
<body>
|
60
|
+
<a href="#" data-controller="example" data-action="click->example#increment">
|
61
|
+
Increment <%= @count.to_i %>
|
62
|
+
</a>
|
63
|
+
</body>
|
64
|
+
</html>
|
65
|
+
```
|
66
|
+
|
67
|
+
### app/javascript/controllers/example.js
|
68
|
+
|
69
|
+
```javascript
|
70
|
+
import { Controller } from "stimulus"
|
71
|
+
import StimulusReflex from "stimulus_reflex"
|
72
|
+
|
73
|
+
export default class extends Controller {
|
74
|
+
connect() {
|
75
|
+
StimulusReflex.register(this);
|
76
|
+
}
|
77
|
+
|
78
|
+
increment() {
|
79
|
+
// trigger a server-side reflex and a client-side page update
|
80
|
+
this.stimulate('ExampleReflex#increment', 1);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
```
|
84
|
+
|
85
|
+
### app/reflexes/example_reflex.rb
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
class ExampleReflex < StimulusReflex::Reflex
|
89
|
+
def increment(step = 1)
|
90
|
+
@count = @count.to_i + step
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
The following happens after the `StimulusReflex::Reflex` method call finishes.
|
96
|
+
|
97
|
+
1. The page that triggered the reflex is re-rerendered. _Instance variables created in the reflex are available to both the controller and view templates._
|
98
|
+
2. The re-rendered HTML is sent to the client over the ActionCable socket.
|
99
|
+
3. The page is updated via fast DOM diffing courtesy of morphdom. _While future versions of StimulusReflex might support more granular updates, today the entire body is re-rendered and sent over the socket._
|
100
|
+
|
101
|
+
## Advanced Usage
|
102
|
+
|
103
|
+
### ActionCable
|
104
|
+
|
105
|
+
StimulusReflex will use the ActionCable defaults of `window.App` and `App.cable` if they exist.
|
106
|
+
If these defaults do not exist, StimulusReflex will establish a new socket connection.
|
107
|
+
|
108
|
+
### Performance
|
109
|
+
|
110
|
+
ActionCable emits verbose log messages. Disabling ActionCable logs may improve performance.
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
# config/application.rb
|
114
|
+
|
115
|
+
ActionCable.server.config.logger = Logger.new(nil)
|
116
|
+
```
|
117
|
+
|
118
|
+
### ActionCable Rooms
|
119
|
+
|
120
|
+
You may find the need to restrict notifications to a specific room.
|
121
|
+
This can be accomplished by setting the `data-room` attribute on the StimulusController element.
|
122
|
+
|
123
|
+
```erb
|
124
|
+
<a href="#" data-controller="example" data-action="click->example#increment" data-room="12345">
|
125
|
+
```
|
126
|
+
|
127
|
+
### Render Delay
|
128
|
+
|
129
|
+
An attempt is made to reduce repaint/reflow jitter when users trigger lots of updates.
|
130
|
+
|
131
|
+
You can control how long to wait _(think debounce)_ prior to updating the page.
|
132
|
+
Simply set the `renderDelay` _(milliseconds)_ option when registering the controller.
|
133
|
+
|
134
|
+
```javascript
|
135
|
+
export default class extends Controller {
|
136
|
+
connect() {
|
137
|
+
StimulusReflex.register(this, {renderDelay: 200});
|
138
|
+
}
|
139
|
+
}
|
140
|
+
```
|
141
|
+
|
142
|
+
The default value is `25`.
|
143
|
+
|
144
|
+
## Demo Applications
|
145
|
+
|
146
|
+
Building apps with StimulusReflex should evoke your memories of the original [Rails demo video](https://www.youtube.com/watch?v=Gzj723LkRJY).
|
147
|
+
|
148
|
+
> Look at all the things I'm **not** doing. -DHH
|
149
|
+
|
150
|
+
- [TodoMVC](https://github.com/hopsoft/stimulus_reflex_todomvc)
|
151
|
+
|
152
|
+
<<<<<<< HEAD
|
153
|
+
## Contributing
|
154
|
+
|
155
|
+
This project uses [Standard](https://github.com/testdouble/standard)
|
156
|
+
and [Prettier](https://github.com/prettier/prettier) to minimize bike shedding related to code formatting.
|
157
|
+
Please run `./bin/standardize` prior submitting pull requests.
|
158
|
+
=======
|
159
|
+
>>>>>>> master
|
data/bin/console
CHANGED
@@ -2,13 +2,6 @@
|
|
2
2
|
|
3
3
|
require "bundler/setup"
|
4
4
|
require "stimulus_reflex"
|
5
|
+
require "pry"
|
5
6
|
|
6
|
-
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start(__FILE__)
|
7
|
+
Pry.start
|
data/bin/standardize
CHANGED
data/lib/stimulus_reflex.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
|
+
require "uri"
|
2
|
+
require "rack"
|
3
|
+
require "rails/engine"
|
4
|
+
require "active_support/all"
|
5
|
+
require "action_dispatch"
|
6
|
+
require "action_cable"
|
7
|
+
require "nokogiri"
|
8
|
+
require "cable_ready"
|
1
9
|
require "stimulus_reflex/version"
|
2
10
|
require "stimulus_reflex/reflex"
|
3
11
|
require "stimulus_reflex/channel"
|
4
12
|
|
5
13
|
module StimulusReflex
|
6
|
-
|
7
|
-
class Engine < ::Rails::Engine
|
8
|
-
end
|
14
|
+
class Engine < Rails::Engine
|
9
15
|
end
|
10
16
|
end
|
@@ -1,10 +1,3 @@
|
|
1
|
-
require "uri"
|
2
|
-
require "rack"
|
3
|
-
require "nokogiri"
|
4
|
-
require "active_support/all"
|
5
|
-
require "action_dispatch"
|
6
|
-
require "cable_ready"
|
7
|
-
|
8
1
|
class StimulusReflex::Channel < ActionCable::Channel::Base
|
9
2
|
include CableReady::Broadcaster
|
10
3
|
|
@@ -22,38 +15,33 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
22
15
|
end
|
23
16
|
|
24
17
|
def receive(data)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
arguments = data["args"] || []
|
18
|
+
url = data["url"].to_s
|
19
|
+
target = data["target"].to_s
|
20
|
+
reflex_name, method_name = target.split("#")
|
21
|
+
reflex_name = reflex_name.classify
|
22
|
+
arguments = data["args"] || []
|
31
23
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
24
|
+
begin
|
25
|
+
reflex = reflex_name.constantize.new(self, url: url)
|
26
|
+
delegate_call_to_reflex reflex, method_name, arguments
|
27
|
+
rescue => invoke_error
|
28
|
+
logger.error "StimulusReflex::Channel Failed to invoke #{target}! #{url} #{invoke_error}"
|
29
|
+
end
|
38
30
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
31
|
+
begin
|
32
|
+
render_page_and_broadcast_morph url, reflex
|
33
|
+
rescue => render_error
|
34
|
+
logger.error "StimulusReflex::Channel Failed to rerender #{url} #{render_error}"
|
44
35
|
end
|
45
36
|
end
|
46
37
|
|
47
38
|
private
|
48
39
|
|
49
40
|
def delegate_call_to_reflex(reflex, method_name, arguments = [])
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
else
|
55
|
-
reflex.send method_name
|
56
|
-
end
|
41
|
+
if reflex.method(method_name).arity != 0
|
42
|
+
reflex.send method_name, *arguments
|
43
|
+
else
|
44
|
+
reflex.send method_name
|
57
45
|
end
|
58
46
|
end
|
59
47
|
|
@@ -63,46 +51,40 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
63
51
|
end
|
64
52
|
|
65
53
|
def render_page(url, reflex)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
controller.instance_variable_set
|
73
|
-
|
74
|
-
controller.instance_variable_set name, reflex.instance_variable_get(name)
|
75
|
-
end
|
54
|
+
uri = URI.parse(url)
|
55
|
+
url_params = Rails.application.routes.recognize_path(url)
|
56
|
+
controller_class = "#{url_params[:controller]}_controller".classify.constantize
|
57
|
+
controller = controller_class.new
|
58
|
+
controller.instance_variable_set :"@stimulus_reflex", true
|
59
|
+
reflex.instance_variables.each do |name|
|
60
|
+
controller.instance_variable_set name, reflex.instance_variable_get(name)
|
61
|
+
end
|
76
62
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
63
|
+
query_hash = Rack::Utils.parse_nested_query(uri.query)
|
64
|
+
env = {
|
65
|
+
"action_dispatch.request.path_parameters" => url_params,
|
66
|
+
"action_dispatch.request.query_parameters" => query_hash,
|
67
|
+
"rack.request.query_hash" => query_hash,
|
68
|
+
"rack.request.query_string" => uri.query,
|
69
|
+
"ORIGINAL_SCRIPT_NAME" => "",
|
70
|
+
"ORIGINAL_FULLPATH" => uri.path,
|
71
|
+
Rack::SCRIPT_NAME => "",
|
72
|
+
Rack::PATH_INFO => uri.path,
|
73
|
+
Rack::REQUEST_PATH => uri.path,
|
74
|
+
Rack::QUERY_STRING => uri.query,
|
75
|
+
}
|
90
76
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
97
|
-
html
|
77
|
+
request = ActionDispatch::Request.new(connection.env.merge(env))
|
78
|
+
controller.request = request
|
79
|
+
controller.response = ActionDispatch::Response.new
|
80
|
+
controller.process url_params[:action]
|
81
|
+
controller.response.body
|
98
82
|
end
|
99
83
|
|
100
84
|
def broadcast_morph(url, html)
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
cable_ready.broadcast
|
105
|
-
end
|
85
|
+
html = extract_body_html(html)
|
86
|
+
cable_ready[stream_name].morph selector: "body", html: html, children_only: true
|
87
|
+
cable_ready.broadcast
|
106
88
|
end
|
107
89
|
|
108
90
|
def extract_body_html(html)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stimulus_reflex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Hopkins
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-08-
|
12
|
+
date: 2019-08-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -40,63 +40,77 @@ dependencies:
|
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '0'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
43
|
+
name: rails
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
46
|
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: 5.2
|
48
|
+
version: '5.2'
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: 5.2
|
55
|
+
version: '5.2'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
|
-
name:
|
57
|
+
name: cable_ready
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
60
|
- - ">="
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
62
|
+
version: 4.0.3
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
67
|
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
69
|
+
version: 4.0.3
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
71
|
+
name: bundler
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '2.0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '2.0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rake
|
72
86
|
requirement: !ruby/object:Gem::Requirement
|
73
87
|
requirements:
|
74
88
|
- - ">="
|
75
89
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
77
|
-
type: :
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
78
92
|
prerelease: false
|
79
93
|
version_requirements: !ruby/object:Gem::Requirement
|
80
94
|
requirements:
|
81
95
|
- - ">="
|
82
96
|
- !ruby/object:Gem::Version
|
83
|
-
version:
|
97
|
+
version: '0'
|
84
98
|
- !ruby/object:Gem::Dependency
|
85
|
-
name:
|
99
|
+
name: pry
|
86
100
|
requirement: !ruby/object:Gem::Requirement
|
87
101
|
requirements:
|
88
|
-
- - "
|
102
|
+
- - ">="
|
89
103
|
- !ruby/object:Gem::Version
|
90
|
-
version: '
|
104
|
+
version: '0'
|
91
105
|
type: :development
|
92
106
|
prerelease: false
|
93
107
|
version_requirements: !ruby/object:Gem::Requirement
|
94
108
|
requirements:
|
95
|
-
- - "
|
109
|
+
- - ">="
|
96
110
|
- !ruby/object:Gem::Version
|
97
|
-
version: '
|
111
|
+
version: '0'
|
98
112
|
- !ruby/object:Gem::Dependency
|
99
|
-
name:
|
113
|
+
name: pry-nav
|
100
114
|
requirement: !ruby/object:Gem::Requirement
|
101
115
|
requirements:
|
102
116
|
- - ">="
|
@@ -135,6 +149,7 @@ files:
|
|
135
149
|
- Gemfile.lock
|
136
150
|
- LICENSE.txt
|
137
151
|
- README.md
|
152
|
+
- README.md.orig
|
138
153
|
- Rakefile
|
139
154
|
- bin/console
|
140
155
|
- bin/setup
|
@@ -165,5 +180,5 @@ requirements: []
|
|
165
180
|
rubygems_version: 3.0.3
|
166
181
|
signing_key:
|
167
182
|
specification_version: 4
|
168
|
-
summary: Build
|
183
|
+
summary: Build reactive Single Page Applications (SPAs) with Rails and Stimulus
|
169
184
|
test_files: []
|